Skip to content

Commit ae1bb80

Browse files
author
Wilken Rivera
committed
Add validate method to Image type
1 parent 0d4ac6e commit ae1bb80

3 files changed

Lines changed: 81 additions & 75 deletions

File tree

packer/registry/image/fromartifact_example_test.go

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,34 @@ import (
66
"github.com/hashicorp/packer-plugin-sdk/packer/registry/image"
77
)
88

9+
type simpleArtifact struct {
10+
image_id string
11+
}
12+
13+
func (a *simpleArtifact) BuilderId() string {
14+
return "example.happycloud"
15+
}
16+
17+
func (a *simpleArtifact) Files() []string {
18+
return nil
19+
}
20+
21+
func (a *simpleArtifact) Id() string {
22+
return a.image_id
23+
}
24+
25+
func (a *simpleArtifact) String() string {
26+
return fmt.Sprintf("Imported image URL: %s", a.Id())
27+
}
28+
29+
func (a *simpleArtifact) State(name string) interface{} {
30+
return nil
31+
}
32+
33+
func (a *simpleArtifact) Destroy() error {
34+
return nil
35+
}
36+
937
func ExampleFromArtifact() {
1038

1139
a := &simpleArtifact{
@@ -35,37 +63,8 @@ func ExampleSetLabels() {
3563
image_id: "service-id-123",
3664
}
3765

38-
// This example also includes an override for the ProviderRegion to illustrate how ArtifactOverrideFunc(s) can be chained.
3966
hcimage, _ := image.FromArtifact(a, image.SetLabels(map[string]interface{}{"kernel": "4.0", "python": "3.5"}))
4067
fmt.Printf("%v", hcimage.Labels)
4168
// Unordered output:
4269
// map[kernel:4.0 python:3.5]
4370
}
44-
45-
type simpleArtifact struct {
46-
image_id string
47-
}
48-
49-
func (a *simpleArtifact) BuilderId() string {
50-
return "example.happycloud"
51-
}
52-
53-
func (a *simpleArtifact) Files() []string {
54-
return nil
55-
}
56-
57-
func (a *simpleArtifact) Id() string {
58-
return a.image_id
59-
}
60-
61-
func (a *simpleArtifact) String() string {
62-
return fmt.Sprintf("Imported image URL: %s", a.Id())
63-
}
64-
65-
func (a *simpleArtifact) State(name string) interface{} {
66-
return nil
67-
}
68-
69-
func (a *simpleArtifact) Destroy() error {
70-
return nil
71-
}

packer/registry/image/frommappeddata_example_test.go

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,41 +9,6 @@ import (
99
"github.com/hashicorp/packer-plugin-sdk/packer/registry/image"
1010
)
1111

12-
func ExampleFromMappedData() {
13-
14-
a := &artifact{
15-
images: map[string]string{
16-
"west": "happycloud-1",
17-
"east": "happycloud-2",
18-
},
19-
}
20-
21-
f := func(key, value interface{}) (*image.Image, error) {
22-
v, ok := value.(string)
23-
if !ok {
24-
return nil, errors.New("for happycloud maps value should always be string")
25-
}
26-
k, ok := key.(string)
27-
if !ok {
28-
return nil, errors.New("for happycloud maps key should always be string")
29-
}
30-
31-
img := image.Image{ProviderName: "happycloud", ProviderRegion: k, ImageID: v}
32-
return &img, nil
33-
}
34-
35-
hcimages, _ := image.FromMappedData(a.images, f)
36-
fmt.Println("Image count:", len(hcimages))
37-
for _, hcimage := range hcimages {
38-
fmt.Printf("%#v\n", *hcimage)
39-
}
40-
// Unordered output:
41-
// Image count: 2
42-
// image.Image{ImageID:"happycloud-1", ProviderName:"happycloud", ProviderRegion:"west", Labels:map[string]string(nil)}
43-
// image.Image{ImageID:"happycloud-2", ProviderName:"happycloud", ProviderRegion:"east", Labels:map[string]string(nil)}
44-
45-
}
46-
4712
type artifact struct {
4813
images map[string]string
4914
}
@@ -76,3 +41,34 @@ func (a *artifact) State(name string) interface{} {
7641
func (a *artifact) Destroy() error {
7742
return nil
7843
}
44+
45+
func ExampleFromMappedData() {
46+
a := &artifact{
47+
images: map[string]string{
48+
"west": "happycloud-1",
49+
"east": "happycloud-2",
50+
},
51+
}
52+
53+
f := func(key, value interface{}) (*image.Image, error) {
54+
v, ok := value.(string)
55+
if !ok {
56+
return nil, errors.New("for happycloud maps value should always be string")
57+
}
58+
k, ok := key.(string)
59+
if !ok {
60+
return nil, errors.New("for happycloud maps key should always be string")
61+
}
62+
63+
img := image.Image{ProviderName: "happycloud", ProviderRegion: k, ImageID: v}
64+
return &img, nil
65+
}
66+
67+
hcimages, _ := image.FromMappedData(a.images, f)
68+
for _, hcimage := range hcimages {
69+
fmt.Printf("%#v\n", *hcimage)
70+
}
71+
// Unordered output:
72+
// image.Image{ImageID:"happycloud-1", ProviderName:"happycloud", ProviderRegion:"west", Labels:map[string]string(nil)}
73+
// image.Image{ImageID:"happycloud-2", ProviderName:"happycloud", ProviderRegion:"east", Labels:map[string]string(nil)}
74+
}

packer/registry/image/image.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* Package image allows for the management of image metadata that can be stored in a HCP Packer registry.
2+
*/
13
package image
24

35
import (
@@ -7,7 +9,7 @@ import (
79
"github.com/hashicorp/packer-plugin-sdk/packer"
810
)
911

10-
// ArtifactStateURI represents the key used by Packer when querying an packersdk.Artifact
12+
// ArtifactStateURI represents the key used by Packer when querying a packersdk.Artifact
1113
// for Image metadata that a particular component would like to have stored on the HCP Packer Registry.
1214
const ArtifactStateURI = "par.artifact.metadata"
1315

@@ -19,20 +21,30 @@ type ArtifactOverrideFunc func(*Image) error
1921
type Image struct {
2022
// ImageID is a unique reference identifier stored on the HCP Packer registry
2123
// that can be used to get back the built artifact of a builder or post-processor.
22-
ImageID string
24+
ImageID string `mapstructure:"image_id"`
2325
// ProviderName represents the name of the top level cloud or service where the built artifact resides.
2426
// For example "aws, azure, docker, gcp, and vsphere".
27+
ProviderName string `mapstructure:"provider_name"`
2528
// ProviderRegion represents the location of the built artifact.
2629
// For cloud providers region usually maps to a cloud region or zone, but for things like the file builder,
2730
// S3 bucket or vsphere cluster region can represent a path on the upstream datastore, or cluster.
28-
ProviderName, ProviderRegion string
31+
ProviderRegion string `mapstructure:"provider_region"`
2932
// Labels represents additional details about an image that a builder or post-processor may with to provide for a given build.
3033
// Any additional metadata will be made available as build labels within a HCP Packer registry iteration.
3134
Labels map[string]string `mapstructure:"labels"`
3235
}
3336

34-
func New() *Image {
35-
return &Image{}
37+
// Validate checks that the Image i contains a non-empty ImageID and ProviderName.
38+
func (i *Image) Validate() error {
39+
if i.ImageID == "" {
40+
return errors.New("error registry image does not contain a valid ImageId")
41+
}
42+
43+
if i.ProviderName == "" {
44+
return errors.New("error registry image does not contain a valid ProviderName")
45+
}
46+
47+
return nil
3648
}
3749

3850
// FromMappedData calls f sequentially for each key and value present in mappedData to create a []*Image
@@ -63,29 +75,28 @@ func FromMappedData(mappedData interface{}, f func(key, value interface{}) (*Ima
6375
}
6476

6577
// FromArtifact returns an *Image that can be used by Packer core for publishing to the HCP Packer Registry.
66-
// By default FromArtifact will use the a.BuilderID as the Image Provider, and the a.Id() as the ImageID that
67-
// should be tracked within the HCP Packer Registry. No Region is selected by default as region varies per build.
78+
// By default FromArtifact will use the a.BuilderID() as the ProviderName, and the a.Id() as the ImageID that
79+
// should be tracked within the HCP Packer Registry. No Region is selected by default as region varies per builder.
6880
// The use of one or more ArtifactOverrideFunc can be used to override any of the defaults used.
6981
func FromArtifact(a packer.Artifact, opts ...ArtifactOverrideFunc) (*Image, error) {
7082
if a == nil {
7183
return nil, errors.New("unable to create Image from nil artifact")
7284
}
7385

74-
img := &Image{
86+
img := Image{
7587
ProviderName: a.BuilderId(),
7688
ImageID: a.Id(),
7789
Labels: make(map[string]string),
7890
}
7991

80-
// Let's grab some state data
8192
for _, opt := range opts {
82-
err := opt(img)
93+
err := opt(&img)
8394
if err != nil {
8495
return nil, err
8596
}
8697
}
8798

88-
return img, nil
99+
return &img, nil
89100
}
90101

91102
// WithProvider takes a name, and returns a ArtifactOverrideFunc that can be

0 commit comments

Comments
 (0)