diff --git a/datasource/hcp-packer-image/data.go b/datasource/hcp-packer-image/data.go index 7e36fca34..9a7f714b6 100644 --- a/datasource/hcp-packer-image/data.go +++ b/datasource/hcp-packer-image/data.go @@ -17,7 +17,6 @@ import ( "github.com/hashicorp/packer-plugin-sdk/hcl2helper" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" "github.com/hashicorp/packer-plugin-sdk/template/config" - "github.com/hashicorp/packer/internal/registry" packerregistry "github.com/hashicorp/packer/internal/registry" ) @@ -99,7 +98,7 @@ func (d *Datasource) Configure(raws ...interface{}) error { return nil } -// Information from []*models.HashicorpCloudPackerImage with some information +// DatasourceOutput Information from []*models.HashicorpCloudPackerImage with some information // from the parent []*models.HashicorpCloudPackerBuild included where it seemed // like it might be relevant. Need to copy so we can generate type DatasourceOutput struct { @@ -118,6 +117,9 @@ type DatasourceOutput struct { // to a UUID. It is created by the HCP Packer Registry when an iteration is // first created, and is unique to this iteration. IterationID string `mapstructure:"iteration_id"` + // The ID of the channel used to query the image iteration. This value will be empty if the `iteration_id` was used + // directly instead of a channel. + ChannelID string `mapstructure:"channel_id"` // The UUID associated with the Packer run that created this image. PackerRunUUID string `mapstructure:"packer_run_uuid"` // ID or URL of the remote cloud image as given by a build. @@ -134,31 +136,6 @@ func (d *Datasource) OutputSpec() hcldec.ObjectSpec { return (&DatasourceOutput{}).FlatMapstructure().HCL2Spec() } -func (d *Datasource) getIteration( - ctx context.Context, - cli *registry.Client, -) (*models.HashicorpCloudPackerIteration, error) { - if d.config.IterationID != "" { - iter, err := cli.GetIteration(ctx, d.config.Bucket, packerregistry.GetIteration_byID(d.config.IterationID)) - if err != nil { - return nil, fmt.Errorf( - "error retrieving image iteration from HCP Packer registry: %s", - err) - } - - return iter, nil - } - - iter, err := cli.GetIterationFromChannel(ctx, d.config.Bucket, d.config.Channel) - if err != nil { - return nil, fmt.Errorf( - "error retrieving iteration from HCP Packer registry: %s", - err) - } - - return iter, nil -} - func (d *Datasource) Execute() (cty.Value, error) { ctx := context.TODO() @@ -167,13 +144,35 @@ func (d *Datasource) Execute() (cty.Value, error) { return cty.NullVal(cty.EmptyObject), err } - // Load channel. - log.Printf("[INFO] Reading info from HCP Packer registry (%s) [project_id=%s, organization_id=%s, iteration_id=%s]", - d.config.Bucket, cli.ProjectID, cli.OrganizationID, d.config.IterationID) + var iteration *models.HashicorpCloudPackerIteration + var channelID string + if d.config.IterationID != "" { + log.Printf("[INFO] Reading info from HCP Packer registry (%s) [project_id=%s, organization_id=%s, iteration_id=%s]", + d.config.Bucket, cli.ProjectID, cli.OrganizationID, d.config.IterationID) - iteration, err := d.getIteration(ctx, cli) - if err != nil { - return cty.NullVal(cty.EmptyObject), err + iter, err := cli.GetIteration(ctx, d.config.Bucket, packerregistry.GetIteration_byID(d.config.IterationID)) + if err != nil { + return cty.NullVal(cty.EmptyObject), fmt.Errorf( + "error retrieving image iteration from HCP Packer registry: %s", + err) + } + iteration = iter + } else { + log.Printf("[INFO] Reading info from HCP Packer registry (%s) [project_id=%s, organization_id=%s, channel=%s]", + d.config.Bucket, cli.ProjectID, cli.OrganizationID, d.config.Channel) + + channel, err := cli.GetChannel(ctx, d.config.Bucket, d.config.Channel) + if err != nil { + return cty.NullVal(cty.EmptyObject), fmt.Errorf("error retrieving "+ + "channel from HCP Packer registry: %s", err.Error()) + } + + if channel.Iteration == nil { + return cty.NullVal(cty.EmptyObject), fmt.Errorf("there is no iteration associated with the channel %s", + d.config.Channel) + } + channelID = channel.ID + iteration = channel.Iteration } revokeAt := time.Time(iteration.RevokeAt) @@ -201,6 +200,7 @@ func (d *Datasource) Execute() (cty.Value, error) { CreatedAt: image.CreatedAt.String(), BuildID: build.ID, IterationID: build.IterationID, + ChannelID: channelID, PackerRunUUID: build.PackerRunUUID, ID: image.ImageID, Region: image.Region, diff --git a/datasource/hcp-packer-image/data.hcl2spec.go b/datasource/hcp-packer-image/data.hcl2spec.go index 8cfe1f620..2bae3fe70 100644 --- a/datasource/hcp-packer-image/data.hcl2spec.go +++ b/datasource/hcp-packer-image/data.hcl2spec.go @@ -64,6 +64,7 @@ type FlatDatasourceOutput struct { CreatedAt *string `mapstructure:"created_at" cty:"created_at" hcl:"created_at"` BuildID *string `mapstructure:"build_id" cty:"build_id" hcl:"build_id"` IterationID *string `mapstructure:"iteration_id" cty:"iteration_id" hcl:"iteration_id"` + ChannelID *string `mapstructure:"channel_id" cty:"channel_id" hcl:"channel_id"` PackerRunUUID *string `mapstructure:"packer_run_uuid" cty:"packer_run_uuid" hcl:"packer_run_uuid"` ID *string `mapstructure:"id" cty:"id" hcl:"id"` Region *string `mapstructure:"region" cty:"region" hcl:"region"` @@ -87,6 +88,7 @@ func (*FlatDatasourceOutput) HCL2Spec() map[string]hcldec.Spec { "created_at": &hcldec.AttrSpec{Name: "created_at", Type: cty.String, Required: false}, "build_id": &hcldec.AttrSpec{Name: "build_id", Type: cty.String, Required: false}, "iteration_id": &hcldec.AttrSpec{Name: "iteration_id", Type: cty.String, Required: false}, + "channel_id": &hcldec.AttrSpec{Name: "channel_id", Type: cty.String, Required: false}, "packer_run_uuid": &hcldec.AttrSpec{Name: "packer_run_uuid", Type: cty.String, Required: false}, "id": &hcldec.AttrSpec{Name: "id", Type: cty.String, Required: false}, "region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false}, diff --git a/datasource/hcp-packer-iteration/data.go b/datasource/hcp-packer-iteration/data.go index b3264a604..f2664f0d7 100644 --- a/datasource/hcp-packer-iteration/data.go +++ b/datasource/hcp-packer-iteration/data.go @@ -58,7 +58,7 @@ func (d *Datasource) Configure(raws ...interface{}) error { return nil } -// Essentially a copy of []*models.HashicorpCloudPackerIteration, but without the +// DatasourceOutput is essentially a copy of []*models.HashicorpCloudPackerIteration, but without the // []Builds or ancestor id. type DatasourceOutput struct { // who created the iteration @@ -88,6 +88,8 @@ type DatasourceOutput struct { IncrementalVersion int32 `mapstructure:"incremental_version"` // The date when this iteration was last updated. UpdatedAt string `mapstructure:"updated_at"` + // The ID of the channel used to query the image iteration. + ChannelID string `mapstructure:"channel_id"` } func (d *Datasource) OutputSpec() hcldec.ObjectSpec { @@ -105,11 +107,17 @@ func (d *Datasource) Execute() (cty.Value, error) { log.Printf("[INFO] Reading iteration info from HCP Packer registry (%s) [project_id=%s, organization_id=%s, channel=%s]", d.config.Bucket, cli.ProjectID, cli.OrganizationID, d.config.Channel) - iteration, err := cli.GetIterationFromChannel(ctx, d.config.Bucket, d.config.Channel) + channel, err := cli.GetChannel(ctx, d.config.Bucket, d.config.Channel) if err != nil { return cty.NullVal(cty.EmptyObject), fmt.Errorf("error retrieving "+ "iteration from HCP Packer registry: %s", err.Error()) } + if channel.Iteration == nil { + return cty.NullVal(cty.EmptyObject), fmt.Errorf("there is no iteration associated with the channel %s", + d.config.Channel) + } + + iteration := channel.Iteration revokeAt := time.Time(iteration.RevokeAt) if !revokeAt.IsZero() && revokeAt.Before(time.Now().UTC()) { @@ -128,6 +136,7 @@ func (d *Datasource) Execute() (cty.Value, error) { ID: iteration.ID, IncrementalVersion: iteration.IncrementalVersion, UpdatedAt: iteration.UpdatedAt.String(), + ChannelID: channel.ID, } return hcl2helper.HCL2ValueFromConfig(output, d.OutputSpec()), nil diff --git a/datasource/hcp-packer-iteration/data.hcl2spec.go b/datasource/hcp-packer-iteration/data.hcl2spec.go index 6fe9249f4..512331f3e 100644 --- a/datasource/hcp-packer-iteration/data.hcl2spec.go +++ b/datasource/hcp-packer-iteration/data.hcl2spec.go @@ -59,6 +59,7 @@ type FlatDatasourceOutput struct { ID *string `mapstructure:"id" cty:"id" hcl:"id"` IncrementalVersion *int32 `mapstructure:"incremental_version" cty:"incremental_version" hcl:"incremental_version"` UpdatedAt *string `mapstructure:"updated_at" cty:"updated_at" hcl:"updated_at"` + ChannelID *string `mapstructure:"channel_id" cty:"channel_id" hcl:"channel_id"` } // FlatMapstructure returns a new FlatDatasourceOutput. @@ -81,6 +82,7 @@ func (*FlatDatasourceOutput) HCL2Spec() map[string]hcldec.Spec { "id": &hcldec.AttrSpec{Name: "id", Type: cty.String, Required: false}, "incremental_version": &hcldec.AttrSpec{Name: "incremental_version", Type: cty.Number, Required: false}, "updated_at": &hcldec.AttrSpec{Name: "updated_at", Type: cty.String, Required: false}, + "channel_id": &hcldec.AttrSpec{Name: "channel_id", Type: cty.String, Required: false}, } return s } diff --git a/datasource/packer-image-iteration/data.go b/datasource/packer-image-iteration/data.go index e369ca159..5e94f9e12 100644 --- a/datasource/packer-image-iteration/data.go +++ b/datasource/packer-image-iteration/data.go @@ -144,10 +144,19 @@ func (d *DeactivatedDatasource) Execute() (cty.Value, error) { log.Printf("[INFO] Reading info from HCP Packer registry (%s) [project_id=%s, organization_id=%s, channel=%s]", d.config.Bucket, cli.ProjectID, cli.OrganizationID, d.config.Channel) - iteration, err := cli.GetIterationFromChannel(ctx, d.config.Bucket, d.config.Channel) + channel, err := cli.GetChannel(ctx, d.config.Bucket, d.config.Channel) if err != nil { return cty.NullVal(cty.EmptyObject), fmt.Errorf("error retrieving "+ - "image iteration from HCP Packer registry: %s", err.Error()) + "channel from HCP Packer registry: %s", err.Error()) + } + + var iteration *models.HashicorpCloudPackerIteration + if channel != nil { + if channel.Iteration != nil { + iteration = channel.Iteration + } + return cty.NullVal(cty.EmptyObject), fmt.Errorf("there is no iteration associated with the channel %s", + d.config.Channel) } revokeAt := time.Time(iteration.RevokeAt) diff --git a/go.mod b/go.mod index bc20233b6..17fdc8b48 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/hashicorp/go-uuid v1.0.2 github.com/hashicorp/go-version v1.4.0 github.com/hashicorp/hcl/v2 v2.13.0 - github.com/hashicorp/hcp-sdk-go v0.19.0 + github.com/hashicorp/hcp-sdk-go v0.20.1-0.20220726131832-34fbcf69a746 github.com/hashicorp/packer-plugin-amazon v1.1.0 github.com/hashicorp/packer-plugin-sdk v0.3.1 github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 @@ -96,6 +96,7 @@ require ( github.com/hashicorp/packer-plugin-vmware v1.0.7 github.com/hashicorp/packer-plugin-vsphere v1.0.5 github.com/hashicorp/packer-plugin-yandex v1.1.1 + github.com/prometheus/common v0.9.1 github.com/scaleway/packer-plugin-scaleway v1.0.4 ) @@ -126,6 +127,8 @@ require ( github.com/Telmate/proxmox-api-go v0.0.0-20220107223401-b9c909d83a3b // indirect github.com/acomagu/bufpipe v1.0.3 // indirect github.com/agext/levenshtein v1.2.3 // indirect + github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect + github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 // indirect github.com/aliyun/alibaba-cloud-sdk-go v1.61.1028 // indirect github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible // indirect github.com/antihax/optional v1.0.0 // indirect @@ -162,7 +165,6 @@ require ( github.com/go-openapi/strfmt v0.20.0 // indirect github.com/go-openapi/swag v0.19.14 // indirect github.com/go-openapi/validate v0.20.2 // indirect - github.com/go-ozzo/ozzo-validation v3.6.0+incompatible // indirect github.com/go-resty/resty/v2 v2.6.0 // indirect github.com/go-stack/stack v1.8.0 // indirect github.com/gofrs/uuid v4.0.0+incompatible // indirect @@ -258,6 +260,7 @@ require ( google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20211021150943-2b146023228c // indirect google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect gopkg.in/ini.v1 v1.62.0 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect diff --git a/go.sum b/go.sum index ca77658c3..82c58d08b 100644 --- a/go.sum +++ b/go.sum @@ -139,8 +139,10 @@ github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7l github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1028 h1:lBif3zUMR6sjgfONVqfnjjjdXIK09S4Lvkze20ApE8w= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1028/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA= @@ -430,8 +432,6 @@ github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9G github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= github.com/go-openapi/validate v0.20.2 h1:AhqDegYV3J3iQkMPJSXkvzymHKMTw0BST3RK3hTT4ts= github.com/go-openapi/validate v0.20.2/go.mod h1:e7OJoKNgd0twXZwIn0A43tHbvIcr/rZIVCbJBpTUoY0= -github.com/go-ozzo/ozzo-validation v3.6.0+incompatible h1:msy24VGS42fKO9K1vLz82/GeYW1cILu7Nuuj1N3BBkE= -github.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= github.com/go-resty/resty/v2 v2.3.0/go.mod h1:UpN9CgLZNsv4e9XG50UU8xdI0F43UQ4HmxLBDwaroHU= github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4= @@ -700,8 +700,8 @@ github.com/hashicorp/hcl/v2 v2.10.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oay github.com/hashicorp/hcl/v2 v2.12.0/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc= github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0= -github.com/hashicorp/hcp-sdk-go v0.19.0 h1:uaM2YlL84yLz2m9WyeK9HOUmcVkgw1u32aUJx7L64zw= -github.com/hashicorp/hcp-sdk-go v0.19.0/go.mod h1:z0I0eZ+TVJJ7pycnCzMM/ouOw5D5Qnp/zylNXkqGEX0= +github.com/hashicorp/hcp-sdk-go v0.20.1-0.20220726131832-34fbcf69a746 h1:rj2Hgrs5ZEqn5dXbj0ZIC6z+jFWkB0EoxOAD3JNWrms= +github.com/hashicorp/hcp-sdk-go v0.20.1-0.20220726131832-34fbcf69a746/go.mod h1:R44DJFnWufG+C89Ozlg/7ILrK3Ulh8g4zT8t8Ioe0KQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= @@ -1050,6 +1050,7 @@ github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7q github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -1732,6 +1733,7 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/hcl2template/types.build.go b/hcl2template/types.build.go index 1c1600f2b..c930a894e 100644 --- a/hcl2template/types.build.go +++ b/hcl2template/types.build.go @@ -254,16 +254,29 @@ func (p *Parser) decodeBuildConfig(block *hcl.Block, cfg *PackerConfig) (*BuildB cfg.bucket.RegisterBuildForComponent(source.String()) } - // Known HCP Packer Image Datasource, whose id is the SourceImageId for some build. - const hcpDatasourceType string = "hcp-packer-image" + // Known HCP Packer Image Datasource, whose id is the SourceImageId and ChannelID for some build. values := ectx.Variables[dataAccessor].AsValueMap() - dsValues, ok := values[hcpDatasourceType] + const hcpImageDatasourceType string = "hcp-packer-image" + imageDatasourceValues, ok := values[hcpImageDatasourceType] if !ok { return build, diags } - for _, value := range dsValues.AsValueMap() { + const hcpIterationDatasourceType string = "hcp-packer-iteration" + iterationToChannel := make(map[string]string) + if iterationDatasourceValues, ok := values[hcpIterationDatasourceType]; ok { + for _, itValue := range iterationDatasourceValues.AsValueMap() { + if !itValue.IsKnown() { + continue + } + itValues := itValue.AsValueMap() + iterationID, channelID := itValues["id"].AsString(), itValues["channel_id"].AsString() + iterationToChannel[iterationID] = channelID + } + } + + for _, value := range imageDatasourceValues.AsValueMap() { // Only try to check ancestry if we have fetched the // data from HCP for the data source. // @@ -278,8 +291,17 @@ func (p *Parser) decodeBuildConfig(block *hcl.Block, cfg *PackerConfig) (*BuildB } values := value.AsValueMap() - imgID, itID := values["id"], values["iteration_id"] - cfg.bucket.SourceImagesToParentIterations[imgID.AsString()] = itID.AsString() + imgID, itID, channelID := values["id"], values["iteration_id"], values["channel_id"] + sourceIteration := packerregistry.ParentIteration{ + IterationID: itID.AsString(), + ChannelID: channelID.AsString(), + } + + if sourceIteration.ChannelID == "" { + sourceIteration.ChannelID = iterationToChannel[itID.AsString()] + } + + cfg.bucket.SourceImagesToParentIterations[imgID.AsString()] = sourceIteration } } diff --git a/internal/registry/service.go b/internal/registry/service.go index e10d07faf..c8f99304f 100644 --- a/internal/registry/service.go +++ b/internal/registry/service.go @@ -193,6 +193,7 @@ func (client *Client) UpdateBuild( cloudProvider, sourceImageID string, sourceIterationID string, + sourceChannelID string, labels map[string]string, status models.HashicorpCloudPackerBuildStatus, images []*models.HashicorpCloudPackerImageCreateBody, @@ -213,6 +214,7 @@ func (client *Client) UpdateBuild( CloudProvider: cloudProvider, SourceImageID: sourceImageID, SourceIterationID: sourceIterationID, + SourceChannelID: sourceChannelID, }, } @@ -228,14 +230,9 @@ func (client *Client) UpdateBuild( return resp.Payload.Build.ID, nil } -// GetIterationFromChannel loads the iterationId associated with a current channel. If the +// GetChannel loads the named channel that is associated to the bucket slug . If the // channel does not exist in HCP Packer, GetChannel returns an error. -func (client *Client) GetIterationFromChannel( - ctx context.Context, - bucketSlug string, - channelName string, -) (*models.HashicorpCloudPackerIteration, error) { - +func (client *Client) GetChannel(ctx context.Context, bucketSlug string, channelName string) (*models.HashicorpCloudPackerChannel, error) { params := packer_service.NewPackerServiceGetChannelParamsWithContext(ctx) params.LocationOrganizationID = client.OrganizationID params.LocationProjectID = client.ProjectID @@ -247,14 +244,10 @@ func (client *Client) GetIterationFromChannel( return nil, err } - if resp.Payload.Channel != nil { - if resp.Payload.Channel.Iteration != nil { - return resp.Payload.Channel.Iteration, nil - } - return nil, fmt.Errorf("there is no iteration associated with the channel %s", - channelName) + if resp.Payload.Channel == nil { + return nil, fmt.Errorf("there is no channel with the name %s associated with the bucket %s", + channelName, bucketSlug) } - return nil, fmt.Errorf("there is no channel with the name %s associated with the bucket %s", - channelName, bucketSlug) + return resp.Payload.Channel, nil } diff --git a/internal/registry/types.bucket.go b/internal/registry/types.bucket.go index 25dc56ecd..7fb866011 100644 --- a/internal/registry/types.bucket.go +++ b/internal/registry/types.bucket.go @@ -27,18 +27,23 @@ type Bucket struct { Destination string BucketLabels map[string]string BuildLabels map[string]string - SourceImagesToParentIterations map[string]string + SourceImagesToParentIterations map[string]ParentIteration Iteration *Iteration client *Client } +type ParentIteration struct { + IterationID string + ChannelID string +} + // NewBucketWithIteration initializes a simple Bucket that can be used publishing Packer build // images to the HCP Packer registry. func NewBucketWithIteration(opts IterationOptions) (*Bucket, error) { b := Bucket{ BucketLabels: make(map[string]string), BuildLabels: make(map[string]string), - SourceImagesToParentIterations: make(map[string]string), + SourceImagesToParentIterations: make(map[string]ParentIteration), } i, err := NewIteration(opts) @@ -169,6 +174,7 @@ func (b *Bucket) UpdateBuildStatus(ctx context.Context, name string, status mode "", "", "", + "", nil, status, nil, @@ -205,7 +211,7 @@ func (b *Bucket) CompleteBuild(ctx context.Context, name string) error { return fmt.Errorf("setting a build to DONE with no published images is not currently supported.") } - var providerName, sourceID, sourceIterationID string + var providerName, sourceID, sourceIterationID, sourceChannelID string images := make([]*models.HashicorpCloudPackerImageCreateBody, 0, len(buildToUpdate.Images)) for _, image := range buildToUpdate.Images { // These values will always be the same for all images in a single build, @@ -219,7 +225,8 @@ func (b *Bucket) CompleteBuild(ctx context.Context, name string) error { // Check if image is using some other HCP Packer image if v, ok := b.SourceImagesToParentIterations[image.SourceImageID]; ok { - sourceIterationID = v + sourceIterationID = v.IterationID + sourceChannelID = v.ChannelID } images = append(images, &models.HashicorpCloudPackerImageCreateBody{ImageID: image.ImageID, Region: image.ProviderRegion}) @@ -231,6 +238,7 @@ func (b *Bucket) CompleteBuild(ctx context.Context, name string) error { buildToUpdate.CloudProvider, sourceID, sourceIterationID, + sourceChannelID, buildToUpdate.Labels, status, images, @@ -447,6 +455,7 @@ func (b *Bucket) HeartbeatBuild(ctx context.Context, build string) (func(), erro "", "", "", + "", nil, models.HashicorpCloudPackerBuildStatusRUNNING, nil, diff --git a/website/content/partials/datasource/hcp-packer-image/DatasourceOutput.mdx b/website/content/partials/datasource/hcp-packer-image/DatasourceOutput.mdx index 5b5ec7c70..54949cb5c 100644 --- a/website/content/partials/datasource/hcp-packer-image/DatasourceOutput.mdx +++ b/website/content/partials/datasource/hcp-packer-image/DatasourceOutput.mdx @@ -15,6 +15,9 @@ to a UUID. It is created by the HCP Packer Registry when an iteration is first created, and is unique to this iteration. +- `channel_id` (string) - The ID of the channel used to query the image iteration. This value will be empty if the `iteration_id` was used + directly instead of a channel. + - `packer_run_uuid` (string) - The UUID associated with the Packer run that created this image. - `id` (string) - ID or URL of the remote cloud image as given by a build. diff --git a/website/content/partials/datasource/hcp-packer-iteration/DatasourceOutput.mdx b/website/content/partials/datasource/hcp-packer-iteration/DatasourceOutput.mdx index 7e8050f3c..10e5ac30e 100644 --- a/website/content/partials/datasource/hcp-packer-iteration/DatasourceOutput.mdx +++ b/website/content/partials/datasource/hcp-packer-iteration/DatasourceOutput.mdx @@ -27,4 +27,6 @@ - `updated_at` (string) - The date when this iteration was last updated. +- `channel_id` (string) - The ID of the channel used to query the image iteration. +