From 9c565a97c0ab27a1bce9419c9cc070987bc5ebe2 Mon Sep 17 00:00:00 2001 From: Gennady Lipenkov Date: Thu, 16 Jul 2020 17:10:22 +0300 Subject: [PATCH] Add new property 'min_disk_size' of built image --- CHANGELOG.md | 1 + builder/yandex/config.go | 13 +++++ builder/yandex/config.hcl2spec.go | 2 + builder/yandex/config_test.go | 56 +++++++++++++++++++ builder/yandex/step_create_image.go | 1 + .../builder/yandex/Config-not-required.mdx | 3 + 6 files changed, 76 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4950034fe..f8adf7f40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ default for the http server IP [GH-9441] * builder/yandex: Support authentication by Service Account on instance [GH-9383] +* builder/yandex: Allow set `min_disk_size` for an image. * communicator/ssh: Add support for OpenSSH certificate signing [GH-9521] * communicator/ssh: Allow users to provide a list of ciphers that they want Packer to support. [GH-9453] diff --git a/builder/yandex/config.go b/builder/yandex/config.go index ab6fbe6ec..c32eaf49c 100644 --- a/builder/yandex/config.go +++ b/builder/yandex/config.go @@ -62,6 +62,9 @@ type Config struct { // Key/value pair labels to // apply to the created image. ImageLabels map[string]string `mapstructure:"image_labels" required:"false"` + // Minimum size of the disk that will be created from built image, specified in gigabytes. + // Should be more or equal to `disk_size_gb`. + ImageMinDiskSize int `mapstructure:"image_min_disk_size" required:"false"` // The unique name of the resulting image. Defaults to // `packer-{{timestamp}}`. ImageName string `mapstructure:"image_name" required:"false"` @@ -164,6 +167,16 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { c.DiskType = "network-hdd" } + if c.ImageMinDiskSize == 0 { + c.ImageMinDiskSize = c.DiskSizeGb + } + + if c.ImageMinDiskSize <= c.DiskSizeGb { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Invalid image_min_disk_size value (%d): Must be equal or greate than disk_size_gb (%d)", + c.ImageMinDiskSize, c.DiskSizeGb)) + } + if c.ImageDescription == "" { c.ImageDescription = "Created by Packer" } diff --git a/builder/yandex/config.hcl2spec.go b/builder/yandex/config.hcl2spec.go index 189717ba0..65f47aba0 100644 --- a/builder/yandex/config.hcl2spec.go +++ b/builder/yandex/config.hcl2spec.go @@ -73,6 +73,7 @@ type FlatConfig struct { ImageDescription *string `mapstructure:"image_description" required:"false" cty:"image_description" hcl:"image_description"` ImageFamily *string `mapstructure:"image_family" required:"false" cty:"image_family" hcl:"image_family"` ImageLabels map[string]string `mapstructure:"image_labels" required:"false" cty:"image_labels" hcl:"image_labels"` + ImageMinDiskSize *int `mapstructure:"image_min_disk_size" required:"false" cty:"image_min_disk_size" hcl:"image_min_disk_size"` ImageName *string `mapstructure:"image_name" required:"false" cty:"image_name" hcl:"image_name"` ImageProductIDs []string `mapstructure:"image_product_ids" required:"false" cty:"image_product_ids" hcl:"image_product_ids"` InstanceCores *int `mapstructure:"instance_cores" required:"false" cty:"instance_cores" hcl:"instance_cores"` @@ -175,6 +176,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "image_description": &hcldec.AttrSpec{Name: "image_description", Type: cty.String, Required: false}, "image_family": &hcldec.AttrSpec{Name: "image_family", Type: cty.String, Required: false}, "image_labels": &hcldec.AttrSpec{Name: "image_labels", Type: cty.Map(cty.String), Required: false}, + "image_min_disk_size": &hcldec.AttrSpec{Name: "image_min_disk_size", Type: cty.Number, Required: false}, "image_name": &hcldec.AttrSpec{Name: "image_name", Type: cty.String, Required: false}, "image_product_ids": &hcldec.AttrSpec{Name: "image_product_ids", Type: cty.List(cty.String), Required: false}, "instance_cores": &hcldec.AttrSpec{Name: "instance_cores", Type: cty.Number, Required: false}, diff --git a/builder/yandex/config_test.go b/builder/yandex/config_test.go index 829a2033a..d836daf70 100644 --- a/builder/yandex/config_test.go +++ b/builder/yandex/config_test.go @@ -166,6 +166,62 @@ func TestConfigPrepareStartupScriptFile(t *testing.T) { } } +func TestConfigImageMinDiskSize(t *testing.T) { + cases := []struct { + Name string + Config map[string]interface{} + Err bool + }{ + { + Name: "image_min_disk_size lower than disk_size (default value)", + Config: map[string]interface{}{ + "image_min_disk_size": 2, + }, + Err: true, + }, + { + Name: "image_min_disk_size greater than disk_size (default value)", + Config: map[string]interface{}{ + "image_min_disk_size": 20, + }, + Err: false, + }, + { + Name: "image_min_disk_size lower than disk_size (custom value)", + Config: map[string]interface{}{ + "disk_size_gb": 50, + "image_min_disk_size": 20, + }, + Err: true, + }, + { + Name: "image_min_disk_size greate than disk_size (custom value)", + Config: map[string]interface{}{ + "disk_size_gb": 50, + "image_min_disk_size": 55, + }, + Err: false, + }, + } + + for _, tc := range cases { + raw := testConfig(t) + + for k, v := range tc.Config { + raw[k] = v + } + + var c Config + warns, errs := c.Prepare(raw) + + if tc.Err { + testConfigErr(t, warns, errs, tc.Name) + } else { + testConfigOk(t, warns, errs) + } + } +} + func TestConfigDefaults(t *testing.T) { cases := []struct { Read func(c *Config) interface{} diff --git a/builder/yandex/step_create_image.go b/builder/yandex/step_create_image.go index 12d617354..2d1f236ee 100644 --- a/builder/yandex/step_create_image.go +++ b/builder/yandex/step_create_image.go @@ -34,6 +34,7 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul Family: c.ImageFamily, Description: c.ImageDescription, Labels: c.ImageLabels, + MinDiskSize: toBytes(c.ImageMinDiskSize), ProductIds: c.ImageProductIDs, Source: &compute.CreateImageRequest_DiskId{ DiskId: diskID, diff --git a/website/pages/partials/builder/yandex/Config-not-required.mdx b/website/pages/partials/builder/yandex/Config-not-required.mdx index 9a57f9e77..0c1bf61d0 100644 --- a/website/pages/partials/builder/yandex/Config-not-required.mdx +++ b/website/pages/partials/builder/yandex/Config-not-required.mdx @@ -22,6 +22,9 @@ - `image_labels` (map[string]string) - Key/value pair labels to apply to the created image. +- `image_min_disk_size` (int) - Minimum size of the disk that will be created from built image, specified in gigabytes. + Should be more or equal to `disk_size_gb`. + - `image_name` (string) - The unique name of the resulting image. Defaults to `packer-{{timestamp}}`.