diff --git a/internal/hcp/api/mock_service.go b/internal/hcp/api/mock_service.go index d8d09220f..8ab149f3b 100644 --- a/internal/hcp/api/mock_service.go +++ b/internal/hcp/api/mock_service.go @@ -98,7 +98,8 @@ func (svc *MockPackerClientService) PackerServiceCreateIteration(params *packerS } payload := &models.HashicorpCloudPackerCreateIterationResponse{ Iteration: &models.HashicorpCloudPackerIteration{ - ID: "iteration-id", + ID: "iteration-id", + TemplateType: params.Body.TemplateType, }, } @@ -131,8 +132,9 @@ func (svc *MockPackerClientService) PackerServiceGetIteration(params *packerSvc. payload := &models.HashicorpCloudPackerGetIterationResponse{ Iteration: &models.HashicorpCloudPackerIteration{ - ID: "iteration-id", - Builds: make([]*models.HashicorpCloudPackerBuild, 0), + ID: "iteration-id", + Builds: make([]*models.HashicorpCloudPackerBuild, 0), + TemplateType: models.HashicorpCloudPackerIterationTemplateTypeTEMPLATETYPEUNSET.Pointer(), }, } diff --git a/internal/hcp/api/service.go b/internal/hcp/api/service.go index e717523e8..41a20ccc2 100644 --- a/internal/hcp/api/service.go +++ b/internal/hcp/api/service.go @@ -80,6 +80,7 @@ func (client *Client) CreateIteration( ctx context.Context, bucketSlug, fingerprint string, + templateType models.HashicorpCloudPackerIterationTemplateType, ) (*packer_service.PackerServiceCreateIterationOK, error) { params := packer_service.NewPackerServiceCreateIterationParamsWithContext(ctx) @@ -88,6 +89,7 @@ func (client *Client) CreateIteration( params.BucketSlug = bucketSlug params.Body = packer_service.PackerServiceCreateIterationBody{ Fingerprint: fingerprint, + TemplateType: templateType.Pointer(), } return client.Packer.PackerServiceCreateIteration(params, nil) diff --git a/internal/hcp/registry/hcl.go b/internal/hcp/registry/hcl.go index 0773c2368..ccbc1f577 100644 --- a/internal/hcp/registry/hcl.go +++ b/internal/hcp/registry/hcl.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcp-sdk-go/clients/cloud-packer-service/stable/2021-04-30/models" sdkpacker "github.com/hashicorp/packer-plugin-sdk/packer" "github.com/hashicorp/packer/hcl2template" "github.com/zclconf/go-cty/cty" @@ -26,7 +27,7 @@ const ( // PopulateIteration creates the metadata on HCP for a build func (h *HCLMetadataRegistry) PopulateIteration(ctx context.Context) error { - err := h.bucket.Initialize(ctx) + err := h.bucket.Initialize(ctx, models.HashicorpCloudPackerIterationTemplateTypeHCL2) if err != nil { return err } diff --git a/internal/hcp/registry/json.go b/internal/hcp/registry/json.go index a5aced955..20e1f808e 100644 --- a/internal/hcp/registry/json.go +++ b/internal/hcp/registry/json.go @@ -5,6 +5,7 @@ import ( "path/filepath" "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcp-sdk-go/clients/cloud-packer-service/stable/2021-04-30/models" sdkpacker "github.com/hashicorp/packer-plugin-sdk/packer" "github.com/hashicorp/packer/packer" ) @@ -42,7 +43,7 @@ func (h *JSONMetadataRegistry) PopulateIteration(ctx context.Context) error { if err != nil { return err } - err = h.bucket.Initialize(ctx) + err = h.bucket.Initialize(ctx, models.HashicorpCloudPackerIterationTemplateTypeJSON) if err != nil { return err } diff --git a/internal/hcp/registry/types.bucket.go b/internal/hcp/registry/types.bucket.go index 81e412af7..59114999c 100644 --- a/internal/hcp/registry/types.bucket.go +++ b/internal/hcp/registry/types.bucket.go @@ -106,7 +106,7 @@ func (b *Bucket) connect() error { // // b.Initialize() must be called before any data can be published to the configured HCP Packer Registry. // TODO ensure initialize can only be called once -func (b *Bucket) Initialize(ctx context.Context) error { +func (b *Bucket) Initialize(ctx context.Context, templateType models.HashicorpCloudPackerIterationTemplateType) error { if err := b.connect(); err != nil { return err @@ -119,7 +119,7 @@ func (b *Bucket) Initialize(ctx context.Context) error { return fmt.Errorf("failed to initialize bucket %q: %w", b.Slug, err) } - return b.initializeIteration(ctx) + return b.initializeIteration(ctx, templateType) } func (b *Bucket) RegisterBuildForComponent(sourceName string) { @@ -302,10 +302,14 @@ func (b *Bucket) LoadDefaultSettingsFromEnv() { // createIteration creates an empty iteration for a give bucket on the HCP Packer registry. // The iteration can then be stored locally and used for tracking build status and images for a running // Packer build. -func (b *Bucket) createIteration() (*models.HashicorpCloudPackerIteration, error) { +func (b *Bucket) createIteration(templateType models.HashicorpCloudPackerIterationTemplateType) (*models.HashicorpCloudPackerIteration, error) { ctx := context.Background() - createIterationResp, err := b.client.CreateIteration(ctx, b.Slug, b.Iteration.Fingerprint) + if templateType == models.HashicorpCloudPackerIterationTemplateTypeTEMPLATETYPEUNSET { + return nil, fmt.Errorf("packer error: template type should not be unset when creating an iteration. This is a Packer internal bug which should be reported to the development team for a fix.") + } + + createIterationResp, err := b.client.CreateIteration(ctx, b.Slug, b.Iteration.Fingerprint, templateType) if err != nil { return nil, fmt.Errorf("failed to create Iteration for Bucket %s with error: %w", b.Slug, err) } @@ -318,12 +322,12 @@ func (b *Bucket) createIteration() (*models.HashicorpCloudPackerIteration, error return createIterationResp.Payload.Iteration, nil } -func (b *Bucket) initializeIteration(ctx context.Context) error { +func (b *Bucket) initializeIteration(ctx context.Context, templateType models.HashicorpCloudPackerIterationTemplateType) error { // load existing iteration using fingerprint. iteration, err := b.client.GetIteration(ctx, b.Slug, api.GetIteration_byFingerprint(b.Iteration.Fingerprint)) if api.CheckErrorCode(err, codes.Aborted) { // probably means Iteration doesn't exist need a way to check the error - iteration, err = b.createIteration() + iteration, err = b.createIteration(templateType) } if err != nil { diff --git a/internal/hcp/registry/types.bucket_service_test.go b/internal/hcp/registry/types.bucket_service_test.go index 154447011..603174437 100644 --- a/internal/hcp/registry/types.bucket_service_test.go +++ b/internal/hcp/registry/types.bucket_service_test.go @@ -27,7 +27,7 @@ func TestInitialize_NewBucketNewIteration(t *testing.T) { b.Iteration.expectedBuilds = append(b.Iteration.expectedBuilds, "happycloud.image") - err = b.Initialize(context.TODO()) + err = b.Initialize(context.TODO(), models.HashicorpCloudPackerIterationTemplateTypeHCL2) if err != nil { t.Errorf("unexpected failure: %v", err) } @@ -59,7 +59,32 @@ func TestInitialize_NewBucketNewIteration(t *testing.T) { if ok := b.Iteration.HasBuild("happycloud.image"); !ok { t.Errorf("expected a basic build entry to be created but it didn't") } +} + +func TestInitialize_UnsetTemplateTypeError(t *testing.T) { + t.Setenv("HCP_PACKER_BUILD_FINGERPRINT", "testunsettemplate") + mockService := api.NewMockPackerClientService() + mockService.BucketAlreadyExist = true + + b := &Bucket{ + Slug: "TestBucket", + client: &api.Client{ + Packer: mockService, + }, + } + + b.Iteration = NewIteration() + err := b.Iteration.Initialize(IterationOptions{}) + if err != nil { + t.Errorf("unexpected failure: %v", err) + } + + err = b.Initialize(context.TODO(), models.HashicorpCloudPackerIterationTemplateTypeTEMPLATETYPEUNSET) + if err == nil { + t.Fatalf("unexpected success") + } + t.Logf("iteration creating failed as expected: %s", err) } func TestInitialize_ExistingBucketNewIteration(t *testing.T) { @@ -81,7 +106,7 @@ func TestInitialize_ExistingBucketNewIteration(t *testing.T) { } b.Iteration.expectedBuilds = append(b.Iteration.expectedBuilds, "happycloud.image") - err = b.Initialize(context.TODO()) + err = b.Initialize(context.TODO(), models.HashicorpCloudPackerIterationTemplateTypeHCL2) if err != nil { t.Errorf("unexpected failure: %v", err) } @@ -138,7 +163,7 @@ func TestInitialize_ExistingBucketExistingIteration(t *testing.T) { b.Iteration.expectedBuilds = append(b.Iteration.expectedBuilds, "happycloud.image") mockService.ExistingBuilds = append(mockService.ExistingBuilds, "happycloud.image") - err = b.Initialize(context.TODO()) + err = b.Initialize(context.TODO(), models.HashicorpCloudPackerIterationTemplateTypeHCL2) if err != nil { t.Errorf("unexpected failure: %v", err) } @@ -210,7 +235,7 @@ func TestInitialize_ExistingBucketCompleteIteration(t *testing.T) { b.Iteration.expectedBuilds = append(b.Iteration.expectedBuilds, "happycloud.image") mockService.ExistingBuilds = append(mockService.ExistingBuilds, "happycloud.image") - err = b.Initialize(context.TODO()) + err = b.Initialize(context.TODO(), models.HashicorpCloudPackerIterationTemplateTypeHCL2) if err == nil { t.Errorf("unexpected failure: %v", err) } @@ -253,7 +278,7 @@ func TestUpdateBuildStatus(t *testing.T) { b.Iteration.expectedBuilds = append(b.Iteration.expectedBuilds, "happycloud.image") mockService.ExistingBuilds = append(mockService.ExistingBuilds, "happycloud.image") - err = b.Initialize(context.TODO()) + err = b.Initialize(context.TODO(), models.HashicorpCloudPackerIterationTemplateTypeHCL2) if err != nil { t.Errorf("unexpected failure: %v", err) } @@ -308,7 +333,7 @@ func TestUpdateBuildStatus_DONENoImages(t *testing.T) { b.Iteration.expectedBuilds = append(b.Iteration.expectedBuilds, "happycloud.image") mockService.ExistingBuilds = append(mockService.ExistingBuilds, "happycloud.image") - err = b.Initialize(context.TODO()) + err = b.Initialize(context.TODO(), models.HashicorpCloudPackerIterationTemplateTypeHCL2) if err != nil { t.Errorf("unexpected failure: %v", err) }