diff --git a/.web-docs/components/builder/openstack/README.md b/.web-docs/components/builder/openstack/README.md index 5fc83fb..ac45b89 100644 --- a/.web-docs/components/builder/openstack/README.md +++ b/.web-docs/components/builder/openstack/README.md @@ -453,9 +453,13 @@ builder. useful if, for example, packer hangs on a connection after a reboot. Example: `5m`. Disabled by default. -- `ssh_remote_tunnels` ([]string) - +- `ssh_remote_tunnels` ([]string) - Remote tunnels forward a port from your local machine to the instance. + Format: ["REMOTE_PORT:LOCAL_HOST:LOCAL_PORT"] + Example: "9090:localhost:80" forwards localhost:9090 on your machine to port 80 on the instance. -- `ssh_local_tunnels` ([]string) - +- `ssh_local_tunnels` ([]string) - Local tunnels forward a port from the instance to your local machine. + Format: ["LOCAL_PORT:REMOTE_HOST:REMOTE_PORT"] + Example: "8080:localhost:3000" allows the instance to access your local machine’s port 3000 via localhost:8080. diff --git a/builder/openstack/artifact.go b/builder/openstack/artifact.go index f78c844..ac54661 100644 --- a/builder/openstack/artifact.go +++ b/builder/openstack/artifact.go @@ -9,6 +9,8 @@ import ( "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + + registryimage "github.com/hashicorp/packer-plugin-sdk/packer/registry/image" ) // Artifact is an artifact implementation that contains built images. @@ -22,9 +24,16 @@ type Artifact struct { // OpenStack connection for performing API stuff. Client *gophercloud.ServiceClient + // SourceImage ID of the created image this is actually resolved + // based on a few configured config attributes + SourceImage string + + // The region is read from the env OS_REGION_NAME if not provided + Region string + // StateData should store data such as GeneratedData // to be shared with post-processors - StateData map[string]interface{} + StateData map[string]any } func (a *Artifact) BuilderId() string { @@ -44,7 +53,21 @@ func (a *Artifact) String() string { return fmt.Sprintf("An image was created: %v", a.ImageId) } -func (a *Artifact) State(name string) interface{} { +func (a *Artifact) State(name string) any { + + if name == registryimage.ArtifactStateURI { + img, err := registryimage.FromArtifact(a, + registryimage.WithRegion(a.Region), + registryimage.WithSourceID(a.SourceImage), + ) + + if err != nil { + log.Printf("[DEBUG] error encountered when creating a registry image %v", err) + return nil + } + return img + + } return a.StateData[name] } diff --git a/builder/openstack/artifact_test.go b/builder/openstack/artifact_test.go index 967ac1b..c629ed2 100644 --- a/builder/openstack/artifact_test.go +++ b/builder/openstack/artifact_test.go @@ -4,9 +4,12 @@ package openstack import ( + "reflect" "testing" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" + registryimage "github.com/hashicorp/packer-plugin-sdk/packer/registry/image" + "github.com/mitchellh/mapstructure" ) func TestArtifact_Impl(t *testing.T) { @@ -63,3 +66,35 @@ func TestArtifactState_StateData(t *testing.T) { t.Fatalf("Bad: State should be nil for nil StateData") } } + +func TestArtifactState_hcpPackerRegistryMetadata(t *testing.T) { + artifact := &Artifact{ + ImageId: "foo", + BuilderIdValue: "openstack", + SourceImage: "bar", + Region: "mordor-7", + } + + result := artifact.State(registryimage.ArtifactStateURI) + if result == nil { + t.Fatalf("Bad: HCP Packer registry image data was nil") + } + + var image registryimage.Image + err := mapstructure.Decode(result, &image) + if err != nil { + t.Errorf("Bad: unexpected error when trying to decode state into registryimage.Image %v", err) + } + + expected := registryimage.Image{ + ImageID: "foo", + ProviderName: "openstack", + ProviderRegion: "mordor-7", + SourceImageID: "bar", + Labels: map[string]string{}, + } + + if !reflect.DeepEqual(image, expected) { + t.Fatalf("bad: \ngot:\n%#v,\nexpected: \n%#v", image, expected) + } +} diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go index 4bf2502..8b8b56f 100644 --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -200,7 +200,9 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook) ImageId: state.Get("image").(string), BuilderIdValue: BuilderId, Client: imageClient, - StateData: map[string]interface{}{"generated_data": state.Get("generated_data")}, + SourceImage: state.Get("source_image").(string), + Region: b.config.AccessConfig.Region, + StateData: map[string]any{"generated_data": state.Get("generated_data")}, } return artifact, nil