diff --git a/post-processor/googlecompute-import/post-processor.go b/post-processor/googlecompute-import/post-processor.go index 2379e3e3c..7b326d9da 100644 --- a/post-processor/googlecompute-import/post-processor.go +++ b/post-processor/googlecompute-import/post-processor.go @@ -1,3 +1,4 @@ +//go:generate struct-markdown //go:generate mapstructure-to-hcl2 -type Config package googlecomputeimport @@ -27,19 +28,38 @@ import ( type Config struct { common.PackerConfig `mapstructure:",squash"` - AccountFile string `mapstructure:"account_file"` - ProjectId string `mapstructure:"project_id"` - IAP bool `mapstructure:"iap"` - - Bucket string `mapstructure:"bucket"` - GCSObjectName string `mapstructure:"gcs_object_name"` - ImageDescription string `mapstructure:"image_description"` - ImageFamily string `mapstructure:"image_family"` - ImageGuestOsFeatures []string `mapstructure:"image_guest_os_features"` - ImageLabels map[string]string `mapstructure:"image_labels"` - ImageName string `mapstructure:"image_name"` - SkipClean bool `mapstructure:"skip_clean"` - VaultGCPOauthEngine string `mapstructure:"vault_gcp_oauth_engine"` + //The JSON file containing your account credentials. + //If specified, the account file will take precedence over any `googlecompute` builder authentication method. + AccountFile string `mapstructure:"account_file" required:"true"` + //The project ID where the GCS bucket exists and where the GCE image is stored. + ProjectId string `mapstructure:"project_id" required:"true"` + IAP bool `mapstructure-to-hcl:",skip"` + //The name of the GCS bucket where the raw disk image will be uploaded. + Bucket string `mapstructure:"bucket" required:"true"` + //The name of the GCS object in `bucket` where + //the RAW disk image will be copied for import. This is treated as a + //[template engine](/docs/templates/engine). Therefore, you + //may use user variables and template functions in this field. Defaults to + //`packer-import-{{timestamp}}.tar.gz`. + GCSObjectName string `mapstructure:"gcs_object_name"` + //The description of the resulting image. + ImageDescription string `mapstructure:"image_description"` + //The name of the image family to which the resulting image belongs. + ImageFamily string `mapstructure:"image_family"` + //A list of features to enable on the guest operating system. Applicable only for bootable images. Valid + //values are `MULTI_IP_SUBNET`, `SECURE_BOOT`, `UEFI_COMPATIBLE`, + //`VIRTIO_SCSI_MULTIQUEUE` and `WINDOWS` currently. + ImageGuestOsFeatures []string `mapstructure:"image_guest_os_features"` + //Key/value pair labels to apply to the created image. + ImageLabels map[string]string `mapstructure:"image_labels"` + //The unique name of the resulting image. + ImageName string `mapstructure:"image_name" required:"true"` + //Skip removing the TAR file uploaded to the GCS + //bucket after the import process has completed. "true" means that we should + //leave it in the GCS bucket, "false" means to clean it out. Defaults to + //`false`. + SkipClean bool `mapstructure:"skip_clean"` + VaultGCPOauthEngine string `mapstructure:"vault_gcp_oauth_engine"` account *jwt.Config ctx interpolate.Context diff --git a/post-processor/googlecompute-import/post-processor.hcl2spec.go b/post-processor/googlecompute-import/post-processor.hcl2spec.go index 7e719e356..4f2ed37e4 100644 --- a/post-processor/googlecompute-import/post-processor.hcl2spec.go +++ b/post-processor/googlecompute-import/post-processor.hcl2spec.go @@ -16,16 +16,16 @@ type FlatConfig struct { PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"` PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"` PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"` - AccountFile *string `mapstructure:"account_file" cty:"account_file" hcl:"account_file"` - ProjectId *string `mapstructure:"project_id" cty:"project_id" hcl:"project_id"` - IAP *bool `mapstructure:"iap" cty:"iap" hcl:"iap"` - Bucket *string `mapstructure:"bucket" cty:"bucket" hcl:"bucket"` + AccountFile *string `mapstructure:"account_file" required:"true" cty:"account_file" hcl:"account_file"` + ProjectId *string `mapstructure:"project_id" required:"true" cty:"project_id" hcl:"project_id"` + IAP *bool `mapstructure-to-hcl:",skip" cty:"iap" hcl:"iap"` + Bucket *string `mapstructure:"bucket" required:"true" cty:"bucket" hcl:"bucket"` GCSObjectName *string `mapstructure:"gcs_object_name" cty:"gcs_object_name" hcl:"gcs_object_name"` ImageDescription *string `mapstructure:"image_description" cty:"image_description" hcl:"image_description"` ImageFamily *string `mapstructure:"image_family" cty:"image_family" hcl:"image_family"` ImageGuestOsFeatures []string `mapstructure:"image_guest_os_features" cty:"image_guest_os_features" hcl:"image_guest_os_features"` ImageLabels map[string]string `mapstructure:"image_labels" cty:"image_labels" hcl:"image_labels"` - ImageName *string `mapstructure:"image_name" cty:"image_name" hcl:"image_name"` + ImageName *string `mapstructure:"image_name" required:"true" cty:"image_name" hcl:"image_name"` SkipClean *bool `mapstructure:"skip_clean" cty:"skip_clean" hcl:"skip_clean"` VaultGCPOauthEngine *string `mapstructure:"vault_gcp_oauth_engine" cty:"vault_gcp_oauth_engine" hcl:"vault_gcp_oauth_engine"` } diff --git a/website/pages/docs/post-processors/googlecompute-import.mdx b/website/pages/docs/post-processors/googlecompute-import.mdx index 71635b893..874b51d66 100644 --- a/website/pages/docs/post-processors/googlecompute-import.mdx +++ b/website/pages/docs/post-processors/googlecompute-import.mdx @@ -29,49 +29,18 @@ Google Cloud has very specific requirements for images being imported. Please see the [GCE import documentation](https://cloud.google.com/compute/docs/images/import-existing-image) for details. +~> **Note**: To prevent Packer from deleting the compressed RAW disk image set the `keep_input_artifact` configuration option to `true`. +See [Post-Processor Input Artifacts](https://www.packer.io/docs/templates/post-processors#input-artifacts) for more details. + ## Configuration ### Required -- `account_file` (string) - The JSON file containing your account - credentials. - -- `bucket` (string) - The name of the GCS bucket where the raw disk image - will be uploaded. - -- `image_name` (string) - The unique name of the resulting image. - -- `project_id` (string) - The project ID where the GCS bucket exists and - where the GCE image is stored. +@include 'post-processor/googlecompute-import/Config-required.mdx' ### Optional -- `gcs_object_name` (string) - The name of the GCS object in `bucket` where - the RAW disk image will be copied for import. This is treated as a - [template engine](/docs/templates/engine). Therefore, you - may use user variables and template functions in this field. Defaults to - `packer-import-{{timestamp}}.tar.gz`. - -- `image_description` (string) - The description of the resulting image. - -- `image_family` (string) - The name of the image family to which the - resulting image belongs. - -- `image_labels` (object of key/value strings) - Key/value pair labels to - apply to the created image. - -- `image_guest_os_features` (array of strings) - A list of features to enable - on the guest operating system. Applicable only for bootable images. Valid - values are `MULTI_IP_SUBNET`, `SECURE_BOOT`, `UEFI_COMPATIBLE`, - `VIRTIO_SCSI_MULTIQUEUE` and `WINDOWS` currently. - -- `keep_input_artifact` (boolean) - if true, do not delete the compressed RAW - disk image. Defaults to false. - -- `skip_clean` (boolean) - Skip removing the TAR file uploaded to the GCS - bucket after the import process has completed. "true" means that we should - leave it in the GCS bucket, "false" means to clean it out. Defaults to - `false`. +@include 'post-processor/googlecompute-import/Config-not-required.mdx' ## Basic Example @@ -79,6 +48,9 @@ Here is a basic example. This assumes that the builder has produced an compressed raw disk image artifact for us to work with, and that the GCS bucket has been created. + + + ```json { "type": "googlecompute-import", @@ -89,39 +61,62 @@ has been created. } ``` + + + + +```hcl +post-processor "googlecompute-import"{ + account_file = "account.json" + bucket = "my-bucket" + project_id = "my-project" + image_name = "my-gce-image" +} +``` + + + + ## QEMU Builder Example -Here is a complete example for building a Fedora 28 server GCE image. For this -example packer was run from a CentOS 7 server with KVM installed. The CentOS 7 -server was running in GCE with the nested hypervisor feature enabled. +Here is a complete example for building a Fedora 31 server GCE image. For this +example Packer was run from a Debian Linux host with KVM installed. $ packer build -var serial=$(tty) build.json + + + ```json { "variables": { + "account_file": "account.json", + "bucket": "my-bucket", + "project": "my-project", "serial": "" }, "builders": [ { "type": "qemu", "accelerator": "kvm", - "communicator": "none", "boot_command": [ - " console=ttyS0,115200n8 inst.text inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/fedora-28-ks.cfg rd.live.check=0" + " console=ttyS0,115200n8 inst.text inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/fedora-31-ks.cfg rd.live.check=0" ], "disk_size": "15000", "format": "raw", - "iso_checksum": "sha256:ea1efdc692356b3346326f82e2f468903e8da59324fdee8b10eac4fea83f23fe", - "iso_url": "https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/28/Server/x86_64/iso/Fedora-Server-netinst-x86_64-28-1.1.iso", + "iso_checksum": "sha256:225ebc160e40bb43c5de28bad9680e3a78a9db40c9e3f4f42f3ee3f10f95dbeb", + "iso_url": "https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/31/Server/x86_64/iso/Fedora-Server-dvd-x86_64-31-1.9.iso", "headless": "true", "http_directory": "http", "http_port_max": "10089", "http_port_min": "10082", "output_directory": "output", "shutdown_timeout": "30m", + "shutdown_command": "echo 'vagrant'|sudo -S shutdown -P now", + "ssh_username": "vagrant", + "ssh_password": "vagrant", "vm_name": "disk.raw", - "qemu_binary": "/usr/libexec/qemu-kvm", + "qemu_binary": "/usr/bin/kvm", "qemuargs": [ ["-m", "1024"], ["-cpu", "host"], @@ -139,14 +134,76 @@ server was running in GCE with the nested hypervisor feature enabled. }, { "type": "googlecompute-import", - "project_id": "my-project", - "account_file": "account.json", - "bucket": "my-bucket", - "image_name": "fedora28-server-{{timestamp}}", - "image_description": "Fedora 28 Server", - "image_family": "fedora28-server" + "project_id": "{{user `project`}}", + "account_file": "{{user `account_file`}}", + "bucket": "{{user `bucket`}}", + "image_name": "fedora31-server-packertest", + "image_description": "Fedora 31 Server", + "image_family": "fedora31-server" } ] ] } ``` + + + + +```hcl +variables { + account_file = "account.json" + bucket = "my-bucket" + project = "my-project" + serial = "" +} + +source "qemu" "example" { + accelerator = "kvm" + boot_command = [ + " console=ttyS0,115200n8 inst.text inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/fedora-31-ks.cfg rd.live.check=0" + ] + disk_size = "15000" + format = "raw" + iso_checksum = "sha256:225ebc160e40bb43c5de28bad9680e3a78a9db40c9e3f4f42f3ee3f10f95dbeb" + iso_url = "https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/31/Server/x86_64/iso/Fedora-Server-dvd-x86_64-31-1.9.iso" + headless = "true" + http_directory = "http" + http_port_max = "10089" + http_port_min = "10082" + output_directory = "output" + shutdown_timeout = "30m" + shutdown_command = "echo 'vagrant'|sudo -S shutdown -P now" + ssh_username = "vagrant" + ssh_password = "vagrant" + vm_name = "disk.raw" + qemu_binary = "/usr/bin/kvm" + qemuargs = [ + ["-m", "1024"], + ["-cpu", "host"], + ["-chardev", "tty,id=pts,path=${var.serial}"], + ["-device", "isa-serial,chardev=pts"], + ["-device", "virtio-net,netdev=user.0"] + ] +} + +build { + sources = ["source.qemu.example"] + + post-processors { + post-processor "compress" { + output = "output/disk.raw.tar.gz" + } + post-processor "googlecompute-import" { + account_file = var.account_file + bucket = var.bucket + project_id = var.project + image_name = "fedora31-server-packertest" + image_description = "Fedora 31 Server" + image_family = "fedora31-server" + } + } +} +``` + + + diff --git a/website/pages/partials/post-processor/googlecompute-import/Config-not-required.mdx b/website/pages/partials/post-processor/googlecompute-import/Config-not-required.mdx new file mode 100644 index 000000000..1e03f0174 --- /dev/null +++ b/website/pages/partials/post-processor/googlecompute-import/Config-not-required.mdx @@ -0,0 +1,24 @@ + + +- `gcs_object_name` (string) - The name of the GCS object in `bucket` where + the RAW disk image will be copied for import. This is treated as a + [template engine](/docs/templates/engine). Therefore, you + may use user variables and template functions in this field. Defaults to + `packer-import-{{timestamp}}.tar.gz`. + +- `image_description` (string) - The description of the resulting image. + +- `image_family` (string) - The name of the image family to which the resulting image belongs. + +- `image_guest_os_features` ([]string) - A list of features to enable on the guest operating system. Applicable only for bootable images. Valid + values are `MULTI_IP_SUBNET`, `SECURE_BOOT`, `UEFI_COMPATIBLE`, + `VIRTIO_SCSI_MULTIQUEUE` and `WINDOWS` currently. + +- `image_labels` (map[string]string) - Key/value pair labels to apply to the created image. + +- `skip_clean` (bool) - Skip removing the TAR file uploaded to the GCS + bucket after the import process has completed. "true" means that we should + leave it in the GCS bucket, "false" means to clean it out. Defaults to + `false`. + +- `vault_gcp_oauth_engine` (string) - Vault GCP Oauth Engine diff --git a/website/pages/partials/post-processor/googlecompute-import/Config-required.mdx b/website/pages/partials/post-processor/googlecompute-import/Config-required.mdx new file mode 100644 index 000000000..7e1d84835 --- /dev/null +++ b/website/pages/partials/post-processor/googlecompute-import/Config-required.mdx @@ -0,0 +1,10 @@ + + +- `account_file` (string) - The JSON file containing your account credentials. + If specified, the account file will take precedence over any `googlecompute` builder authentication method. + +- `project_id` (string) - The project ID where the GCS bucket exists and where the GCE image is stored. + +- `bucket` (string) - The name of the GCS bucket where the raw disk image will be uploaded. + +- `image_name` (string) - The unique name of the resulting image.