hcp packer registry build labels (#11401)

* Add basic support for build_labels argument

* Update support for build_labels configuration argument

* Update complete test-fixture with a build_labels configuration
* Add test for deprecated labels argument
* Add deprecation for hcp_packer_registry.labels

When using the now deprecated labels argument of the new bucket_labels a
Warning will be presented to the user.

```
~>  HCP_PACKER_BUILD_FINGERPRINT=356786543567865456789656789 packer
build source.pkr.hcl
Warning: the argument hcp_packer_registry.labels has been deprecated and will be removed in a future release; please use hcp_packer_registry.bucket_labels
```

When trying to use both bucket_labels and labels together an error is
presented to the user.
```
~>  HCP_PACKER_BUILD_FINGERPRINT=ss6786543567865456789656789 packer
build source.pkr.hcl
Error: hcp_packer_registry.labels and hcp_packer_registry.bucket_labels are mutely exclusive; please use the recommended argument hcp_packer_registry.bucket_labels

  on source.pkr.hcl line 17:
    (source code not available)

```

* Update documentation for build_labels

* Apply suggestions from code review

Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>

* Update hcl2template/types.build.hcp_packer_registry.go

Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
This commit is contained in:
Wilken Rivera 2021-11-18 03:40:08 -05:00 committed by GitHub
parent acd67d5ba0
commit 06b35c39de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 182 additions and 53 deletions

View file

@ -5,9 +5,12 @@ build {
description = <<EOT
Some description
EOT
labels = {
bucket_labels = {
"foo" = "bar"
}
build_labels = {
"python_version" = "3.0"
}
}
sources = [

View file

@ -0,0 +1,18 @@
build {
hcp_packer_registry {
bucket_name = "bucket-slug"
labels = {
"foo" = "bar"
}
}
sources = [
"source.virtualbox-iso.ubuntu-1204",
]
}
source "virtualbox-iso" "ubuntu-1204" {
}

View file

@ -2,7 +2,7 @@ build {
name = "bucket-slug"
hcp_packer_registry {
description = ""
labels = {
bucket_labels = {
"foo" = "bar"
}
}

View file

@ -6,7 +6,7 @@ build {
description = <<EOT
Some description
EOT
labels = {
bucket_labels = {
"foo" = "bar"
}
}

View file

@ -14,7 +14,9 @@ type HCPPackerRegistryBlock struct {
// Bucket description
Description string
// Bucket labels
Labels map[string]string
BucketLabels map[string]string
// Build labels
BuildLabels map[string]string
HCL2Ref
}
@ -24,7 +26,8 @@ func (b *HCPPackerRegistryBlock) WriteToBucketConfig(bucket *packerregistry.Buck
return
}
bucket.Description = b.Description
bucket.Labels = b.Labels
bucket.BucketLabels = b.BucketLabels
bucket.BuildLabels = b.BuildLabels
// If there's already a Slug this was set from env variable.
// In Packer, env variable overrides config values so we keep it that way for consistency.
if bucket.Slug == "" && b.Slug != "" {
@ -37,10 +40,13 @@ func (p *Parser) decodeHCPRegistry(block *hcl.Block) (*HCPPackerRegistryBlock, h
body := block.Body
var b struct {
Slug string `hcl:"bucket_name,optional"`
Description string `hcl:"description,optional"`
Labels map[string]string `hcl:"labels,optional"`
Config hcl.Body `hcl:",remain"`
Slug string `hcl:"bucket_name,optional"`
Description string `hcl:"description,optional"`
//Deprecated labels for bucket_labels
Labels map[string]string `hcl:"labels,optional"`
BucketLabels map[string]string `hcl:"bucket_labels,optional"`
BuildLabels map[string]string `hcl:"build_labels,optional"`
Config hcl.Body `hcl:",remain"`
}
diags := gohcl.DecodeBody(body, nil, &b)
if diags.HasErrors() {
@ -58,7 +64,27 @@ func (p *Parser) decodeHCPRegistry(block *hcl.Block) (*HCPPackerRegistryBlock, h
par.Slug = b.Slug
par.Description = b.Description
par.Labels = b.Labels
if len(b.Labels) > 0 && len(b.BucketLabels) > 0 {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: fmt.Sprintf("%s.labels and %[1]s.bucket_labels are mutually exclusive; please use the recommended argument %[1]s.bucket_labels", buildHCPPackerRegistryLabel),
Subject: block.DefRange.Ptr(),
})
return nil, diags
}
if len(b.Labels) > 0 {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagWarning,
Summary: fmt.Sprintf("the argument %s.labels has been deprecated and will be removed in the next minor release; please use %[1]s.bucket_labels", buildHCPPackerRegistryLabel),
})
b.BucketLabels = b.Labels
}
par.BucketLabels = b.BucketLabels
par.BuildLabels = b.BuildLabels
return par, diags
}

View file

@ -27,8 +27,9 @@ func Test_ParseHCPPackerRegistryBlock(t *testing.T) {
&BuildBlock{
Name: "bucket-slug",
HCPPackerRegistry: &HCPPackerRegistryBlock{
Description: "Some description\n",
Labels: map[string]string{"foo": "bar"},
Description: "Some description\n",
BucketLabels: map[string]string{"foo": "bar"},
BuildLabels: map[string]string{"python_version": "3.0"},
},
Sources: []SourceUseBlock{
{
@ -52,9 +53,10 @@ func Test_ParseHCPPackerRegistryBlock(t *testing.T) {
Name: "virtualbox-iso.ubuntu-1204",
Builder: emptyMockBuilder,
ArtifactMetadataPublisher: &packer_registry.Bucket{
Slug: "bucket-slug",
Description: "Some description\n",
Labels: map[string]string{"foo": "bar"},
Slug: "bucket-slug",
Description: "Some description\n",
BucketLabels: map[string]string{"foo": "bar"},
BuildLabels: map[string]string{"python_version": "3.0"},
Iteration: &packer_registry.Iteration{
Fingerprint: "ignored-fingerprint", // this will be different everytime so it's ignored
},
@ -67,9 +69,10 @@ func Test_ParseHCPPackerRegistryBlock(t *testing.T) {
PostProcessor: &packer.RegistryPostProcessor{
BuilderType: "virtualbox-iso.ubuntu-1204",
ArtifactMetadataPublisher: &packer_registry.Bucket{
Slug: "bucket-slug",
Description: "Some description\n",
Labels: map[string]string{"foo": "bar"},
Slug: "bucket-slug",
Description: "Some description\n",
BucketLabels: map[string]string{"foo": "bar"},
BuildLabels: map[string]string{"python_version": "3.0"},
Iteration: &packer_registry.Iteration{
Fingerprint: "ignored-fingerprint",
},
@ -87,9 +90,10 @@ func Test_ParseHCPPackerRegistryBlock(t *testing.T) {
Name: "amazon-ebs.aws-ubuntu-16.04",
Builder: emptyMockBuilder,
ArtifactMetadataPublisher: &packer_registry.Bucket{
Slug: "bucket-slug",
Description: "Some description\n",
Labels: map[string]string{"foo": "bar"},
Slug: "bucket-slug",
Description: "Some description\n",
BucketLabels: map[string]string{"foo": "bar"},
BuildLabels: map[string]string{"python_version": "3.0"},
Iteration: &packer_registry.Iteration{
Fingerprint: "ignored-fingerprint", // this will be different everytime so it's ignored
},
@ -102,9 +106,10 @@ func Test_ParseHCPPackerRegistryBlock(t *testing.T) {
PostProcessor: &packer.RegistryPostProcessor{
BuilderType: "amazon-ebs.aws-ubuntu-16.04",
ArtifactMetadataPublisher: &packer_registry.Bucket{
Slug: "bucket-slug",
Description: "Some description\n",
Labels: map[string]string{"foo": "bar"},
Slug: "bucket-slug",
Description: "Some description\n",
BucketLabels: map[string]string{"foo": "bar"},
BuildLabels: map[string]string{"python_version": "3.0"},
Iteration: &packer_registry.Iteration{
Fingerprint: "ignored-fingerprint",
},
@ -130,9 +135,9 @@ func Test_ParseHCPPackerRegistryBlock(t *testing.T) {
&BuildBlock{
Name: "bucket-slug",
HCPPackerRegistry: &HCPPackerRegistryBlock{
Slug: "real-bucket-slug",
Description: "Some description\n",
Labels: map[string]string{"foo": "bar"},
Slug: "real-bucket-slug",
Description: "Some description\n",
BucketLabels: map[string]string{"foo": "bar"},
},
Sources: []SourceUseBlock{
{
@ -152,9 +157,9 @@ func Test_ParseHCPPackerRegistryBlock(t *testing.T) {
Name: "virtualbox-iso.ubuntu-1204",
Builder: emptyMockBuilder,
ArtifactMetadataPublisher: &packer_registry.Bucket{
Slug: "real-bucket-slug",
Description: "Some description\n",
Labels: map[string]string{"foo": "bar"},
Slug: "real-bucket-slug",
Description: "Some description\n",
BucketLabels: map[string]string{"foo": "bar"},
Iteration: &packer_registry.Iteration{
Fingerprint: "ignored-fingerprint", // this will be different everytime so it's ignored
},
@ -167,9 +172,9 @@ func Test_ParseHCPPackerRegistryBlock(t *testing.T) {
PostProcessor: &packer.RegistryPostProcessor{
BuilderType: "virtualbox-iso.ubuntu-1204",
ArtifactMetadataPublisher: &packer_registry.Bucket{
Slug: "real-bucket-slug",
Description: "Some description\n",
Labels: map[string]string{"foo": "bar"},
Slug: "real-bucket-slug",
Description: "Some description\n",
BucketLabels: map[string]string{"foo": "bar"},
Iteration: &packer_registry.Iteration{
Fingerprint: "ignored-fingerprint",
},
@ -371,6 +376,66 @@ func Test_ParseHCPPackerRegistryBlock(t *testing.T) {
},
false,
},
{"deprecated labels in hcp_packer_registry block",
defaultParser,
parseTestArgs{"testdata/hcp_par/deprecated_labels.pkr.hcl", nil, nil},
&PackerConfig{
CorePackerVersionString: lockedVersion,
Basedir: filepath.Join("testdata", "hcp_par"),
Sources: map[SourceRef]SourceBlock{
refVBIsoUbuntu1204: {Type: "virtualbox-iso", Name: "ubuntu-1204"},
},
Builds: Builds{
&BuildBlock{
HCPPackerRegistry: &HCPPackerRegistryBlock{
Slug: "bucket-slug",
BucketLabels: map[string]string{"foo": "bar"},
},
Sources: []SourceUseBlock{
{
SourceRef: refVBIsoUbuntu1204,
},
},
},
},
},
true, false,
[]packersdk.Build{
&packer.CoreBuild{
Type: "virtualbox-iso.ubuntu-1204",
Prepared: true,
Builder: &packer.RegistryBuilder{
Name: "virtualbox-iso.ubuntu-1204",
Builder: emptyMockBuilder,
ArtifactMetadataPublisher: &packer_registry.Bucket{
Slug: "bucket-slug",
BucketLabels: map[string]string{"foo": "bar"},
Iteration: &packer_registry.Iteration{
Fingerprint: "ignored-fingerprint", // this will be different everytime so it's ignored
},
},
},
Provisioners: []packer.CoreBuildProvisioner{},
PostProcessors: [][]packer.CoreBuildPostProcessor{
{
{
PostProcessor: &packer.RegistryPostProcessor{
BuilderType: "virtualbox-iso.ubuntu-1204",
ArtifactMetadataPublisher: &packer_registry.Bucket{
Slug: "bucket-slug",
BucketLabels: map[string]string{"foo": "bar"},
Iteration: &packer_registry.Iteration{
Fingerprint: "ignored-fingerprint",
},
},
},
},
},
},
},
},
false,
},
{"invalid hcp_packer_registry config",
defaultParser,
parseTestArgs{"testdata/hcp_par/invalid.pkr.hcl", nil, nil},

View file

@ -17,12 +17,13 @@ import (
// Bucket represents a single Image bucket on the HCP Packer registry.
type Bucket struct {
Slug string
Description string
Destination string
Labels map[string]string
Iteration *Iteration
client *Client
Slug string
Description string
Destination string
BucketLabels map[string]string
BuildLabels map[string]string
Iteration *Iteration
client *Client
}
// NewBucketWithIteration initializes a simple Bucket that can be used publishing Packer build
@ -79,7 +80,7 @@ func (b *Bucket) Initialize(ctx context.Context) error {
bucketInput := &models.HashicorpCloudPackerCreateBucketRequest{
BucketSlug: b.Slug,
Description: b.Description,
Labels: b.Labels,
Labels: b.BucketLabels,
}
err := UpsertBucket(ctx, b.client, bucketInput)
@ -121,12 +122,16 @@ func (b *Bucket) CreateInitialBuildForIteration(ctx context.Context, componentTy
return err
}
if b.BuildLabels == nil {
b.BuildLabels = make(map[string]string)
}
build := &Build{
ID: id,
ComponentType: componentType,
RunUUID: b.Iteration.RunUUID,
Status: status,
Labels: make(map[string]string),
Labels: b.BuildLabels,
Images: make(map[string]registryimage.Image),
}

View file

@ -31,26 +31,29 @@ builders (source blocks) and the HCP Packer registry.
```hcl
# file: builds.pkr.hcl
source "file" "basic-example" {
content = "Lorem ipsum dolor sit amet"
target = "sample_artifact"
source "happycloud" "macos" {
os = "macos_amd64"
}
build {
hcp_packer_registry {
bucket_name = "sample-artifact"
bucket_name = "ios-dev"
description = <<EOT
Some nice description about the image which artifact is being published to HCP Packer Registry. =D
EOT
labels = {
"foo-version" = "3.4.0",
"foo" = "bar",
bucket_labels = {
"team" = "ios-development",
"os" = "macos"
}
build_labels = {
"xcode" = "11.3.0"
"version" = "Big Sur"
}
sources = ["sources.file.basic-example"]
sources = ["source.happycloud.macos"]
}
```
@ -59,13 +62,22 @@ Some nice description about the image which artifact is being published to HCP P
Defaults to `build.name` if not set. Will be overwritten if
`HCP_PACKER_BUCKET_NAME` is set.
- `bucket_labels` (map[string]string) - Map of labels. Can provide any information,
such as tools versions (e.g. go 1.17, python 3.5, etc...). The bucket labels will
appear at the image's main page and will be updated whenever it is changed
and a new iteration for the bucket is pushed to the HCP Packer registry.
- `build_labels` (map[string]string) - Map of labels. Can provide any information,
such as tools versions (e.g. go 1.17, python 3.5, etc...). The build labels will
appear in the build section of an iteration. Build labels are specific to an iteration
and will be added to a build when is pushed to the HCP Packer registry.
Updates to build labels on a completed iteration is not allowed.
- `description` (string) - The image description. Useful to provide a summary
about the image. The description will appear at the image's main page and
will be updated whenever it is changed and a new build is pushed to the HCP
Packer registry. Should contain a maximum of 255 characters. Defaults to
`build.description` if not set.
- `labels` (map[string]string) - Map of labels. Can provide any information,
such as tools versions (e.g. go 1.17, python 3.5, etc...). The labels will
appear at the image's main page and will be updated whenever it is changed
and a new build is pushed to the HCP Packer registry.
- `labels` (map[string]string) - Deprecated in Packer 1.7.9. See [`bucket_labels`](#bucket_labels) for details.