From 4b531de0ffd7363e588618bee01589ff5ed0614e Mon Sep 17 00:00:00 2001 From: BryceTech122 Date: Thu, 12 Jan 2023 11:46:10 -0700 Subject: [PATCH 01/35] add step to remove disks param from other-config --- builder/xenserver/iso/step_create_instance.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/builder/xenserver/iso/step_create_instance.go b/builder/xenserver/iso/step_create_instance.go index 5c35268..df6702a 100644 --- a/builder/xenserver/iso/step_create_instance.go +++ b/builder/xenserver/iso/step_create_instance.go @@ -101,6 +101,12 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa } } + err = c.GetClient().VM.RemoveFromOtherConfig(c.GetSessionRef(), instance, "disks") + if err != nil { + ui.Error(fmt.Sprintf("Error removing disks from VM other-config: %s", err.Error())) + return multistep.ActionHalt + } + // Create VDI for the instance sr, err := config.GetSR(c) From 8a823a13eb6486fb697327b840bce957547a9766 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Sat, 21 Jan 2023 00:09:12 -0800 Subject: [PATCH 02/35] Update the ubuntu example to use an available 20.04 iso and proper clone_template default --- examples/ubuntu/ubuntu-2004.pkr.hcl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/ubuntu/ubuntu-2004.pkr.hcl b/examples/ubuntu/ubuntu-2004.pkr.hcl index 9879dcd..67238ff 100644 --- a/examples/ubuntu/ubuntu-2004.pkr.hcl +++ b/examples/ubuntu/ubuntu-2004.pkr.hcl @@ -48,9 +48,9 @@ locals { source "xenserver-iso" "ubuntu-2004" { - iso_checksum = "d1f2bf834bbe9bb43faf16f9be992a6f3935e65be0edece1dee2aa6eb1767423" + iso_checksum = "5035be37a7e9abbdc09f0d257f3e33416c1a0fb322ba860d42d74aa75c3468d4" iso_checksum_type = "sha256" - iso_url = "http://releases.ubuntu.com/20.04/ubuntu-20.04.2-live-server-amd64.iso" + iso_url = "http://releases.ubuntu.com/20.04/ubuntu-20.04.5-live-server-amd64.iso" sr_iso_name = var.sr_iso_name sr_name = var.sr_name @@ -60,6 +60,8 @@ source "xenserver-iso" "ubuntu-2004" { remote_password = var.remote_password remote_username = var.remote_username + # Change this to match the ISO of ubuntu you are using in the iso_url variable + clone_template = "Ubuntu Focal Fossa 20.04" vm_name = "packer-ubuntu-2004-${local.timestamp}" vm_description = "Build started: ${local.timestamp}" vm_memory = 4096 From 4df2465c067303c829ddb0d386ff8186008267ac Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Sat, 21 Jan 2023 00:22:04 -0800 Subject: [PATCH 03/35] Remove hashicorps gpg github action to one that doesn't collide with GitHub's gpg agent --- .github/workflows/release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ba31367..186f7f1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,10 +31,10 @@ jobs: run: echo "::set-output name=api_version::$(go run . describe | jq -r '.api_version')" - name: Import GPG key id: import_gpg - uses: hashicorp/ghaction-import-gpg@v2.1.0 + uses: crazy-max/ghaction-import-gpg@v5.0.0 env: - GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} - name: Run GoReleaser uses: goreleaser/goreleaser-action@v2 with: From f7a8fa495975d0f27ef32cfdd29e39e03d772bb6 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Sun, 22 Jan 2023 22:42:23 -0800 Subject: [PATCH 04/35] Ensure gpg github action has parameters passed properly (cherry picked from commit 2b2ba8540d1acfa0884e8db1367b32495bc39259) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 186f7f1..2dfde89 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: - name: Import GPG key id: import_gpg uses: crazy-max/ghaction-import-gpg@v5.0.0 - env: + with: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.GPG_PASSPHRASE }} - name: Run GoReleaser From 88e52b581f8ce5b6dd3b898f084770b9693e1570 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Sun, 26 Feb 2023 19:57:21 -0800 Subject: [PATCH 05/35] Update the ubuntu example to be resilient to ISO releases --- README.md | 2 +- examples/ubuntu/ubuntu-2004.pkr.hcl | 25 ++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bd6511d..ccb31f0 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ If you are using an older version of packer or are still using json templates yo ## Developing the builder ### Dependencies -* Packer >= v1.7.1 (https://packer.io) +* Packer >= v1.8.x (https://packer.io) * XenServer / Citrix Hypervisor > 7.6 * Golang 1.16 diff --git a/examples/ubuntu/ubuntu-2004.pkr.hcl b/examples/ubuntu/ubuntu-2004.pkr.hcl index 67238ff..d4b03ff 100644 --- a/examples/ubuntu/ubuntu-2004.pkr.hcl +++ b/examples/ubuntu/ubuntu-2004.pkr.hcl @@ -7,6 +7,25 @@ packer { } } +# This local determines what Ubuntu iso URL and sha256 hash we lookup. Updating +# this will allow a new version to be pulled in. +local "ubuntu_version" { + expression = "22.04" +} + + +data "http" "ubuntu_sha_and_release" { + url = "https://releases.ubuntu.com/22.04/SHA256SUMS" +} + +local "ubuntu_sha256" { + expression = regex("([A-Za-z0-9]+)[\\s\\*]+ubuntu-.*server", data.http.ubuntu_sha_and_release.body) +} + +local "ubuntu_url_path" { + expression = regex("[A-Za-z0-9]+[\\s\\*]+ubuntu-${local.ubuntu_version}.(\\d+)-live-server-amd64.iso", data.http.ubuntu_sha_and_release.body) +} + variable "remote_host" { type = string description = "The ip or fqdn of your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_HOST'" @@ -48,9 +67,9 @@ locals { source "xenserver-iso" "ubuntu-2004" { - iso_checksum = "5035be37a7e9abbdc09f0d257f3e33416c1a0fb322ba860d42d74aa75c3468d4" + iso_checksum = local.ubuntu_sha256.0 iso_checksum_type = "sha256" - iso_url = "http://releases.ubuntu.com/20.04/ubuntu-20.04.5-live-server-amd64.iso" + iso_url = "https://releases.ubuntu.com/22.04/ubuntu-22.04.${local.ubuntu_url_path.0}-live-server-amd64.iso" sr_iso_name = var.sr_iso_name sr_name = var.sr_name @@ -65,7 +84,7 @@ source "xenserver-iso" "ubuntu-2004" { vm_name = "packer-ubuntu-2004-${local.timestamp}" vm_description = "Build started: ${local.timestamp}" vm_memory = 4096 - disk_size = 20000 + disk_size = 30720 floppy_files = [ "examples/http/ubuntu-2004/meta-data", From 69bae007b670566bb874bee04b98e03266cf620d Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Sun, 26 Feb 2023 20:04:39 -0800 Subject: [PATCH 06/35] Update the correct README doc with the packer 1.8 requirement --- README.md | 2 +- examples/README.md | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ccb31f0..bd6511d 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ If you are using an older version of packer or are still using json templates yo ## Developing the builder ### Dependencies -* Packer >= v1.8.x (https://packer.io) +* Packer >= v1.7.1 (https://packer.io) * XenServer / Citrix Hypervisor > 7.6 * Golang 1.16 diff --git a/examples/README.md b/examples/README.md index ede7545..c19d589 100644 --- a/examples/README.md +++ b/examples/README.md @@ -7,7 +7,8 @@ In order to see an exhaustive list of configuration options for the packer build ### Running the examples In order to run the examples you will need to perform the following steps: -1. Export those vars: +1. Install packer 1.8 or later (the Ubuntu example requires the `http` data source) +2. Export those vars: ``` PKR_VAR_remote_host PKR_VAR_remote_password @@ -17,9 +18,9 @@ PKR_VAR_sr_iso_name ``` `PKR_VAR_remote_host` must be the resource pool primary, aka the master. -2. Run `packer init path/to/defenition.pkr.hcl` to download the xenserver plugin +3. Run `packer init path/to/defenition.pkr.hcl` to download the xenserver plugin -2. Run `packer build path/to/defenition.pkr.hcl` +4. Run `packer build path/to/defenition.pkr.hcl` so for example: `packer build examples/centos/centos8-netinstall.pkr.hcl` From 752bd52f61caeb3734a27de02df3184f88b0bea4 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Sun, 26 Feb 2023 21:09:29 -0800 Subject: [PATCH 07/35] Revert "Update the ubuntu example to be resilient to ISO releases" --- examples/README.md | 7 +++---- examples/ubuntu/ubuntu-2004.pkr.hcl | 25 +++---------------------- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/examples/README.md b/examples/README.md index c19d589..ede7545 100644 --- a/examples/README.md +++ b/examples/README.md @@ -7,8 +7,7 @@ In order to see an exhaustive list of configuration options for the packer build ### Running the examples In order to run the examples you will need to perform the following steps: -1. Install packer 1.8 or later (the Ubuntu example requires the `http` data source) -2. Export those vars: +1. Export those vars: ``` PKR_VAR_remote_host PKR_VAR_remote_password @@ -18,9 +17,9 @@ PKR_VAR_sr_iso_name ``` `PKR_VAR_remote_host` must be the resource pool primary, aka the master. -3. Run `packer init path/to/defenition.pkr.hcl` to download the xenserver plugin +2. Run `packer init path/to/defenition.pkr.hcl` to download the xenserver plugin -4. Run `packer build path/to/defenition.pkr.hcl` +2. Run `packer build path/to/defenition.pkr.hcl` so for example: `packer build examples/centos/centos8-netinstall.pkr.hcl` diff --git a/examples/ubuntu/ubuntu-2004.pkr.hcl b/examples/ubuntu/ubuntu-2004.pkr.hcl index d4b03ff..67238ff 100644 --- a/examples/ubuntu/ubuntu-2004.pkr.hcl +++ b/examples/ubuntu/ubuntu-2004.pkr.hcl @@ -7,25 +7,6 @@ packer { } } -# This local determines what Ubuntu iso URL and sha256 hash we lookup. Updating -# this will allow a new version to be pulled in. -local "ubuntu_version" { - expression = "22.04" -} - - -data "http" "ubuntu_sha_and_release" { - url = "https://releases.ubuntu.com/22.04/SHA256SUMS" -} - -local "ubuntu_sha256" { - expression = regex("([A-Za-z0-9]+)[\\s\\*]+ubuntu-.*server", data.http.ubuntu_sha_and_release.body) -} - -local "ubuntu_url_path" { - expression = regex("[A-Za-z0-9]+[\\s\\*]+ubuntu-${local.ubuntu_version}.(\\d+)-live-server-amd64.iso", data.http.ubuntu_sha_and_release.body) -} - variable "remote_host" { type = string description = "The ip or fqdn of your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_HOST'" @@ -67,9 +48,9 @@ locals { source "xenserver-iso" "ubuntu-2004" { - iso_checksum = local.ubuntu_sha256.0 + iso_checksum = "5035be37a7e9abbdc09f0d257f3e33416c1a0fb322ba860d42d74aa75c3468d4" iso_checksum_type = "sha256" - iso_url = "https://releases.ubuntu.com/22.04/ubuntu-22.04.${local.ubuntu_url_path.0}-live-server-amd64.iso" + iso_url = "http://releases.ubuntu.com/20.04/ubuntu-20.04.5-live-server-amd64.iso" sr_iso_name = var.sr_iso_name sr_name = var.sr_name @@ -84,7 +65,7 @@ source "xenserver-iso" "ubuntu-2004" { vm_name = "packer-ubuntu-2004-${local.timestamp}" vm_description = "Build started: ${local.timestamp}" vm_memory = 4096 - disk_size = 30720 + disk_size = 20000 floppy_files = [ "examples/http/ubuntu-2004/meta-data", From 0ccc53b8b5ac9bf4fba8f8517853a314f524b521 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Sun, 26 Feb 2023 23:23:28 -0800 Subject: [PATCH 08/35] Prevent ISO used in iso builder from being uploaded if it already exists --- .../common/step_find_or_upload_vdi.go | 44 +++++++++++++++++++ builder/xenserver/common/step_upload_vdi.go | 10 +++-- builder/xenserver/iso/builder.go | 29 ++++++------ 3 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 builder/xenserver/common/step_find_or_upload_vdi.go diff --git a/builder/xenserver/common/step_find_or_upload_vdi.go b/builder/xenserver/common/step_find_or_upload_vdi.go new file mode 100644 index 0000000..37b8453 --- /dev/null +++ b/builder/xenserver/common/step_find_or_upload_vdi.go @@ -0,0 +1,44 @@ +package common + +import ( + "context" + "fmt" + + "github.com/hashicorp/packer-plugin-sdk/multistep" + "github.com/hashicorp/packer-plugin-sdk/packer" +) + +type StepFindOrUploadVdi struct { + StepUploadVdi +} + +func (self *StepFindOrUploadVdi) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + c := state.Get("client").(*Connection) + vdiName := self.VdiNameFunc() + + ui.Say(fmt.Sprintf("Attemping to find VDI '%s'", vdiName)) + + vdis, err := c.client.VDI.GetByNameLabel(c.session, vdiName) + if err != nil { + ui.Error(fmt.Sprintf("Failed to find VDI '%s' by name label: %s", vdiName, err.Error())) + return multistep.ActionHalt + } + + if len(vdis) > 1 { + ui.Error(fmt.Sprintf("Found more than one VDI with name '%s'. Name must be unique", vdiName)) + return multistep.ActionHalt + } else if len(vdis) == 1 { + + vdi := vdis[0] + + vdiUuid, err := c.client.VDI.GetUUID(c.session, vdi) + if err != nil { + ui.Error(fmt.Sprintf("Unable to get UUID of VDI '%s': %s", vdiName, err.Error())) + return multistep.ActionHalt + } + state.Put(self.VdiUuidKey, vdiUuid) + return multistep.ActionContinue + } + return self.uploadVdi(ctx, state) +} diff --git a/builder/xenserver/common/step_upload_vdi.go b/builder/xenserver/common/step_upload_vdi.go index 67a00f3..006e919 100644 --- a/builder/xenserver/common/step_upload_vdi.go +++ b/builder/xenserver/common/step_upload_vdi.go @@ -18,7 +18,7 @@ type StepUploadVdi struct { VdiUuidKey string } -func (self *StepUploadVdi) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { +func (self *StepUploadVdi) uploadVdi(ctx context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("commonconfig").(CommonConfig) ui := state.Get("ui").(packer.Ui) c := state.Get("client").(*Connection) @@ -33,10 +33,8 @@ func (self *StepUploadVdi) Run(ctx context.Context, state multistep.StateBag) mu ui.Say(fmt.Sprintf("Step: Upload VDI '%s'", vdiName)) // Create VDI for the image - srs, err := c.client.SR.GetAll(c.session) - ui.Say(fmt.Sprintf("Step: Found SRs '%v'", srs)) - sr, err := config.GetISOSR(c) + ui.Say(fmt.Sprintf("Step: Found SR for upload '%v'", sr)) if err != nil { ui.Error(fmt.Sprintf("Unable to get SR: %v", err)) @@ -96,6 +94,10 @@ func (self *StepUploadVdi) Run(ctx context.Context, state multistep.StateBag) mu return multistep.ActionContinue } +func (self *StepUploadVdi) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + return self.uploadVdi(ctx, state) +} + func (self *StepUploadVdi) Cleanup(state multistep.StateBag) { config := state.Get("commonconfig").(CommonConfig) ui := state.Get("ui").(packer.Ui) diff --git a/builder/xenserver/iso/builder.go b/builder/xenserver/iso/builder.go index a9e37f1..e31b0d9 100644 --- a/builder/xenserver/iso/builder.go +++ b/builder/xenserver/iso/builder.go @@ -187,7 +187,6 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p Url: self.config.ISOUrls, }, } - steps := []multistep.Step{ &xscommon.StepPrepareOutputDir{ Force: self.config.PackerForce, @@ -212,20 +211,22 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p }, VdiUuidKey: "floppy_vdi_uuid", }, - &xscommon.StepUploadVdi{ - VdiNameFunc: func() string { - if len(self.config.ISOUrls) > 0 { - return path.Base(self.config.ISOUrls[0]) - } - return "" + &xscommon.StepFindOrUploadVdi{ + xscommon.StepUploadVdi{ + VdiNameFunc: func() string { + if len(self.config.ISOUrls) > 0 { + return path.Base(self.config.ISOUrls[0]) + } + return "" + }, + ImagePathFunc: func() string { + if isoPath, ok := state.GetOk("iso_path"); ok { + return isoPath.(string) + } + return "" + }, + VdiUuidKey: "iso_vdi_uuid", }, - ImagePathFunc: func() string { - if isoPath, ok := state.GetOk("iso_path"); ok { - return isoPath.(string) - } - return "" - }, - VdiUuidKey: "iso_vdi_uuid", }, &xscommon.StepFindVdi{ VdiName: self.config.ToolsIsoName, From 73e173370a507236f6bab78e74ed03d91a1e0d51 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Mon, 27 Feb 2023 21:20:11 -0800 Subject: [PATCH 09/35] Update ubuntu example to be resilient to upstream minor releases --- examples/ubuntu/ubuntu-2004.pkr.hcl | 36 ++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/examples/ubuntu/ubuntu-2004.pkr.hcl b/examples/ubuntu/ubuntu-2004.pkr.hcl index 67238ff..3106e6a 100644 --- a/examples/ubuntu/ubuntu-2004.pkr.hcl +++ b/examples/ubuntu/ubuntu-2004.pkr.hcl @@ -1,12 +1,37 @@ packer { required_plugins { xenserver= { - version = ">= v0.3.2" + version = ">= v0.5.2" source = "github.com/ddelnano/xenserver" } } } +# The ubuntu_version value determines what Ubuntu iso URL and sha256 hash we lookup. Updating +# this will allow a new version to be pulled in. +data "null" "ubuntu_version" { + input = "20.04" +} + +locals { + timestamp = regex_replace(timestamp(), "[- TZ:]", "") + ubuntu_version = data.null.ubuntu_version.output +} + +# TODO(ddelnano): Update this to use a local once https://github.com/hashicorp/packer/issues/11011 +# is fixed. +data "http" "ubuntu_sha_and_release" { + url = "https://releases.ubuntu.com/${data.null.ubuntu_version.output}/SHA256SUMS" +} + +local "ubuntu_sha256" { + expression = regex("([A-Za-z0-9]+)[\\s\\*]+ubuntu-.*server", data.http.ubuntu_sha_and_release.body) +} + +local "ubuntu_url_path" { + expression = regex("[A-Za-z0-9]+[\\s\\*]+ubuntu-${local.ubuntu_version}.(\\d+)-live-server-amd64.iso", data.http.ubuntu_sha_and_release.body) +} + variable "remote_host" { type = string description = "The ip or fqdn of your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_HOST'" @@ -42,15 +67,10 @@ variable "sr_name" { description = "The name of the SR to packer will use" } -locals { - timestamp = regex_replace(timestamp(), "[- TZ:]", "") -} - - source "xenserver-iso" "ubuntu-2004" { - iso_checksum = "5035be37a7e9abbdc09f0d257f3e33416c1a0fb322ba860d42d74aa75c3468d4" + iso_checksum = local.ubuntu_sha256.0 iso_checksum_type = "sha256" - iso_url = "http://releases.ubuntu.com/20.04/ubuntu-20.04.5-live-server-amd64.iso" + iso_url = "https://releases.ubuntu.com/${local.ubuntu_version}/ubuntu-${local.ubuntu_version}.${local.ubuntu_url_path.0}-live-server-amd64.iso" sr_iso_name = var.sr_iso_name sr_name = var.sr_name From 52cd604a9be40f51aab5b3c113a878a6ad446aad Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Mon, 27 Feb 2023 21:37:07 -0800 Subject: [PATCH 10/35] Refactor template name to use a map lookup on Ubuntu version --- examples/ubuntu/ubuntu-2004.pkr.hcl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/ubuntu/ubuntu-2004.pkr.hcl b/examples/ubuntu/ubuntu-2004.pkr.hcl index 3106e6a..8b0fb0d 100644 --- a/examples/ubuntu/ubuntu-2004.pkr.hcl +++ b/examples/ubuntu/ubuntu-2004.pkr.hcl @@ -16,6 +16,12 @@ data "null" "ubuntu_version" { locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") ubuntu_version = data.null.ubuntu_version.output + + # Update this map to support future releases. At this time, the Ubuntu + # jammy template is not available yet. + ubuntu_template_name = { + 20.04 = "Ubuntu Focal Fossa 20.04" + } } # TODO(ddelnano): Update this to use a local once https://github.com/hashicorp/packer/issues/11011 @@ -81,8 +87,8 @@ source "xenserver-iso" "ubuntu-2004" { remote_username = var.remote_username # Change this to match the ISO of ubuntu you are using in the iso_url variable - clone_template = "Ubuntu Focal Fossa 20.04" - vm_name = "packer-ubuntu-2004-${local.timestamp}" + clone_template = local.ubuntu_template_name[data.null.ubuntu_version.output] + vm_name = "packer-ubuntu-${data.null.ubuntu_version.output}-${local.timestamp}" vm_description = "Build started: ${local.timestamp}" vm_memory = 4096 disk_size = 20000 From 6eeea7dc649652138fbf280b80e0eeaff4053687 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Mon, 27 Feb 2023 21:37:21 -0800 Subject: [PATCH 11/35] Use 30 GiB root volume --- examples/ubuntu/ubuntu-2004.pkr.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ubuntu/ubuntu-2004.pkr.hcl b/examples/ubuntu/ubuntu-2004.pkr.hcl index 8b0fb0d..3373c46 100644 --- a/examples/ubuntu/ubuntu-2004.pkr.hcl +++ b/examples/ubuntu/ubuntu-2004.pkr.hcl @@ -91,7 +91,7 @@ source "xenserver-iso" "ubuntu-2004" { vm_name = "packer-ubuntu-${data.null.ubuntu_version.output}-${local.timestamp}" vm_description = "Build started: ${local.timestamp}" vm_memory = 4096 - disk_size = 20000 + disk_size = 30720 floppy_files = [ "examples/http/ubuntu-2004/meta-data", From dcb839e131d491f682a293cf4352db10be258383 Mon Sep 17 00:00:00 2001 From: Arnaud Charles Date: Fri, 3 Mar 2023 12:48:55 +0100 Subject: [PATCH 12/35] Fixing main md links and doc links --- README.md | 2 +- docs/builders/iso/xenserver-iso.html.markdown | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bd6511d..8e8d594 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ $ cp builder-xenserver-iso ~/.packer.d/plugins/packer-builder-xenserver-iso # Documentation For complete documentation on configuration commands, see [the -xenserver-iso docs](docs/builders/xenserver-iso.html.markdown) +xenserver-iso docs](docs/builders/iso/xenserver-iso.html.markdown) ## Support diff --git a/docs/builders/iso/xenserver-iso.html.markdown b/docs/builders/iso/xenserver-iso.html.markdown index 9c62c3f..c931c77 100644 --- a/docs/builders/iso/xenserver-iso.html.markdown +++ b/docs/builders/iso/xenserver-iso.html.markdown @@ -43,7 +43,7 @@ each category, the available options are alphabetized and described. If this is an HTTP URL, Packer will download it and cache it between runs. -* `remote_host` (string) - The host of the Xenserver / XCP-ng pool primary. Typically these will be specified through environment variables as seen in the [examples](../../examples/centos8.json). +* `remote_host` (string) - The host of the Xenserver / XCP-ng pool primary. Typically these will be specified through environment variables as seen in the [examples](../../examples). * `remote_username` (string) - The XenServer username used to access the remote machine. @@ -59,7 +59,7 @@ each category, the available options are alphabetized and described. be to type just enough to initialize the operating system installer. Special keys can be typed as well, and are covered in the section below on the boot command. If this is not specified, it is assumed the installer will start - itself. See the [Ubuntu](../../examples/ubuntu-2004.json) and [centos](../../examples/centos8.json) examples to see how these are used to launch autoinstall and kickstart respectively. + itself. See the [Ubuntu](../../examples/ubuntu) and [centos](../../examples/centos) examples to see how these are used to launch autoinstall and kickstart respectively. * `boot_wait` (string) - The time to wait after booting the initial virtual machine before typing the `boot_command`. The value of this should be @@ -252,4 +252,4 @@ The available variables are: configuration parameter. If `http_directory` isn't specified, these will be blank! -See the [examples](../../examples/) for working boot commands. +See the [examples](../../examples) for working boot commands. From d15616c1d218086ad11cf69d2bcd9d4aa5b50d36 Mon Sep 17 00:00:00 2001 From: Arnaud Charles Date: Fri, 3 Mar 2023 12:53:23 +0100 Subject: [PATCH 13/35] Fixing main md links and doc links --- docs/builders/iso/xenserver-iso.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/builders/iso/xenserver-iso.html.markdown b/docs/builders/iso/xenserver-iso.html.markdown index c931c77..38fe369 100644 --- a/docs/builders/iso/xenserver-iso.html.markdown +++ b/docs/builders/iso/xenserver-iso.html.markdown @@ -43,7 +43,7 @@ each category, the available options are alphabetized and described. If this is an HTTP URL, Packer will download it and cache it between runs. -* `remote_host` (string) - The host of the Xenserver / XCP-ng pool primary. Typically these will be specified through environment variables as seen in the [examples](../../examples). +* `remote_host` (string) - The host of the Xenserver / XCP-ng pool primary. Typically these will be specified through environment variables as seen in the [examples](https://github.com/ddelnano/packer-plugin-xenserver/tree/master/examples). * `remote_username` (string) - The XenServer username used to access the remote machine. @@ -59,7 +59,7 @@ each category, the available options are alphabetized and described. be to type just enough to initialize the operating system installer. Special keys can be typed as well, and are covered in the section below on the boot command. If this is not specified, it is assumed the installer will start - itself. See the [Ubuntu](../../examples/ubuntu) and [centos](../../examples/centos) examples to see how these are used to launch autoinstall and kickstart respectively. + itself. See the [Ubuntu](https://github.com/ddelnano/packer-plugin-xenserver/tree/master/examples/ubuntu) and [centos](https://github.com/ddelnano/packer-plugin-xenserver/tree/master/examples/centos) examples to see how these are used to launch autoinstall and kickstart respectively. * `boot_wait` (string) - The time to wait after booting the initial virtual machine before typing the `boot_command`. The value of this should be @@ -252,4 +252,4 @@ The available variables are: configuration parameter. If `http_directory` isn't specified, these will be blank! -See the [examples](../../examples) for working boot commands. +See the [examples](https://github.com/ddelnano/packer-plugin-xenserver/tree/master/examples) for working boot commands. From 479e16a2c1eabc3c48e907b34c8fbe1f852f1cbb Mon Sep 17 00:00:00 2001 From: Arnaud Charles Date: Fri, 3 Mar 2023 12:56:34 +0100 Subject: [PATCH 14/35] Fixing main md links and doc links --- docs/builders/iso/xenserver-iso.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/builders/iso/xenserver-iso.html.markdown b/docs/builders/iso/xenserver-iso.html.markdown index 38fe369..ddbe4b0 100644 --- a/docs/builders/iso/xenserver-iso.html.markdown +++ b/docs/builders/iso/xenserver-iso.html.markdown @@ -43,7 +43,7 @@ each category, the available options are alphabetized and described. If this is an HTTP URL, Packer will download it and cache it between runs. -* `remote_host` (string) - The host of the Xenserver / XCP-ng pool primary. Typically these will be specified through environment variables as seen in the [examples](https://github.com/ddelnano/packer-plugin-xenserver/tree/master/examples). +* `remote_host` (string) - The host of the Xenserver / XCP-ng pool primary. Typically these will be specified through environment variables as seen in the [examples](examples). * `remote_username` (string) - The XenServer username used to access the remote machine. @@ -59,7 +59,7 @@ each category, the available options are alphabetized and described. be to type just enough to initialize the operating system installer. Special keys can be typed as well, and are covered in the section below on the boot command. If this is not specified, it is assumed the installer will start - itself. See the [Ubuntu](https://github.com/ddelnano/packer-plugin-xenserver/tree/master/examples/ubuntu) and [centos](https://github.com/ddelnano/packer-plugin-xenserver/tree/master/examples/centos) examples to see how these are used to launch autoinstall and kickstart respectively. + itself. See the [Ubuntu](examples/ubuntu) and [centos](examples/centos) examples to see how these are used to launch autoinstall and kickstart respectively. * `boot_wait` (string) - The time to wait after booting the initial virtual machine before typing the `boot_command`. The value of this should be @@ -252,4 +252,4 @@ The available variables are: configuration parameter. If `http_directory` isn't specified, these will be blank! -See the [examples](https://github.com/ddelnano/packer-plugin-xenserver/tree/master/examples) for working boot commands. +See the [examples](../../../examples) for working boot commands. From 5d0cff3fc65153f7ba8c3f74e79e1cc44d64a10a Mon Sep 17 00:00:00 2001 From: Arnaud Charles Date: Fri, 3 Mar 2023 12:57:19 +0100 Subject: [PATCH 15/35] Fixing main md links and doc links --- docs/builders/iso/xenserver-iso.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/builders/iso/xenserver-iso.html.markdown b/docs/builders/iso/xenserver-iso.html.markdown index ddbe4b0..5f4bd08 100644 --- a/docs/builders/iso/xenserver-iso.html.markdown +++ b/docs/builders/iso/xenserver-iso.html.markdown @@ -43,7 +43,7 @@ each category, the available options are alphabetized and described. If this is an HTTP URL, Packer will download it and cache it between runs. -* `remote_host` (string) - The host of the Xenserver / XCP-ng pool primary. Typically these will be specified through environment variables as seen in the [examples](examples). +* `remote_host` (string) - The host of the Xenserver / XCP-ng pool primary. Typically these will be specified through environment variables as seen in the [examples](../../../examples). * `remote_username` (string) - The XenServer username used to access the remote machine. @@ -59,7 +59,7 @@ each category, the available options are alphabetized and described. be to type just enough to initialize the operating system installer. Special keys can be typed as well, and are covered in the section below on the boot command. If this is not specified, it is assumed the installer will start - itself. See the [Ubuntu](examples/ubuntu) and [centos](examples/centos) examples to see how these are used to launch autoinstall and kickstart respectively. + itself. See the [Ubuntu](../../../examples/ubuntu) and [centos](../../../examples/centos) examples to see how these are used to launch autoinstall and kickstart respectively. * `boot_wait` (string) - The time to wait after booting the initial virtual machine before typing the `boot_command`. The value of this should be From b4d83eb5331b730fcbdab9fb62e4d8612949d090 Mon Sep 17 00:00:00 2001 From: AtaxyaNetwork Date: Thu, 6 Apr 2023 18:27:24 +0200 Subject: [PATCH 16/35] s/SrName/SrISOName Signed-off-by: AtaxyaNetwork --- builder/xenserver/common/common_config.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/xenserver/common/common_config.go b/builder/xenserver/common/common_config.go index 6907e18..4ae5edd 100644 --- a/builder/xenserver/common/common_config.go +++ b/builder/xenserver/common/common_config.go @@ -271,7 +271,7 @@ func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) { } else { // Use the provided name label to find the SR to use - srs, err := c.GetClient().SR.GetByNameLabel(c.session, config.SrName) + srs, err := c.GetClient().SR.GetByNameLabel(c.session, config.SrISOName) if err != nil { return srRef, err @@ -279,9 +279,9 @@ func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) { switch { case len(srs) == 0: - return srRef, fmt.Errorf("Couldn't find a SR with the specified name-label '%s'", config.SrName) + return srRef, fmt.Errorf("Couldn't find a SR with the specified name-label '%s'", config.SrISOName) case len(srs) > 1: - return srRef, fmt.Errorf("Found more than one SR with the name '%s'. The name must be unique", config.SrName) + return srRef, fmt.Errorf("Found more than one SR with the name '%s'. The name must be unique", config.SrISOName) } return srs[0], nil From 880d12c66fe6cdd471591381e5e64bdfd90cab2b Mon Sep 17 00:00:00 2001 From: somerandomqaguy <76200225+somerandomqaguy@users.noreply.github.com> Date: Tue, 27 Sep 2022 23:00:57 -0600 Subject: [PATCH 17/35] Get the tests compiling again. Looks like the consts got moved into common --- builder/xenserver/iso/builder_test.go | 4 +++- builder/xenserver/xva/builder_test.go | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/builder/xenserver/iso/builder_test.go b/builder/xenserver/iso/builder_test.go index dd4df15..92e6aac 100644 --- a/builder/xenserver/iso/builder_test.go +++ b/builder/xenserver/iso/builder_test.go @@ -5,8 +5,10 @@ import ( "testing" "github.com/hashicorp/packer-plugin-sdk/packer" + "github.com/hashicorp/packer-plugin-sdk/common" ) + func testConfig() map[string]interface{} { return map[string]interface{}{ "remote_host": "localhost", @@ -19,7 +21,7 @@ func testConfig() map[string]interface{} { "shutdown_command": "yes", "ssh_username": "foo", - packer.BuildNameConfigKey: "foo", + common.BuildNameConfigKey: "foo", } } diff --git a/builder/xenserver/xva/builder_test.go b/builder/xenserver/xva/builder_test.go index 03e029f..e5a5f96 100644 --- a/builder/xenserver/xva/builder_test.go +++ b/builder/xenserver/xva/builder_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/hashicorp/packer-plugin-sdk/packer" + "github.com/hashicorp/packer-plugin-sdk/common" ) func testConfig() map[string]interface{} { @@ -16,7 +17,7 @@ func testConfig() map[string]interface{} { "ssh_username": "foo", "source_path": ".", - packer.BuildNameConfigKey: "foo", + common.BuildNameConfigKey: "foo", } } From c49d4ebf1293b190291777073cf3f238165e91cb Mon Sep 17 00:00:00 2001 From: somerandomqaguy <76200225+somerandomqaguy@users.noreply.github.com> Date: Tue, 27 Sep 2022 23:05:02 -0600 Subject: [PATCH 18/35] Capture actual errors from Prepare Solves TestBuilderPrepare_InvalidKey failing, since we weren't capturing it's errors before. --- builder/xenserver/iso/builder.go | 2 +- builder/xenserver/xva/builder.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/xenserver/iso/builder.go b/builder/xenserver/iso/builder.go index e31b0d9..e1903d4 100644 --- a/builder/xenserver/iso/builder.go +++ b/builder/xenserver/iso/builder.go @@ -40,7 +40,7 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri }, raws...) if err != nil { - packer.MultiErrorAppend(errs, err) + errs = packer.MultiErrorAppend(errs, err) } errs = packer.MultiErrorAppend( diff --git a/builder/xenserver/xva/builder.go b/builder/xenserver/xva/builder.go index 00235d2..4eee1c4 100644 --- a/builder/xenserver/xva/builder.go +++ b/builder/xenserver/xva/builder.go @@ -38,7 +38,7 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri }, raws...) if err != nil { - packer.MultiErrorAppend(errs, err) + errs = packer.MultiErrorAppend(errs, err) } errs = packer.MultiErrorAppend( From 6b0b4baf2ff9d1fd452af2f33b68071d825d772f Mon Sep 17 00:00:00 2001 From: somerandomqaguy <76200225+somerandomqaguy@users.noreply.github.com> Date: Tue, 27 Sep 2022 23:25:52 -0600 Subject: [PATCH 19/35] Remove iso_checksum_type checks This aligns the Xenserver plugin to being a bit more inline with what Packer > 1.6.0 is expecting, since packer now simply ignores the iso_checksum_type (it's supposed to error out but that code path isn't working right now because we don't set PluginType in the configs. The unit tests have been altered to reflect this reality. Note that this isn't a comprehensive change; the config still has the inert ISOChecksumType, and there's probably a laundry list of other things that needs to be looked at, For now though, we have working unit tests again. Documentation from SDK has been aligned for iso_checksum --- builder/xenserver/iso/builder.go | 34 ++++---- builder/xenserver/iso/builder_test.go | 87 +++---------------- docs/builders/iso/xenserver-iso.html.markdown | 27 ++++-- 3 files changed, 50 insertions(+), 98 deletions(-) diff --git a/builder/xenserver/iso/builder.go b/builder/xenserver/iso/builder.go index e1903d4..7ef6950 100644 --- a/builder/xenserver/iso/builder.go +++ b/builder/xenserver/iso/builder.go @@ -115,35 +115,35 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri } if self.config.ISOName == "" { - // If ISO name is not specified, assume a URL and checksum has been provided. - - if self.config.ISOChecksumType == "" { - errs = packer.MultiErrorAppend( - errs, errors.New("The iso_checksum_type must be specified.")) - } else { - self.config.ISOChecksumType = strings.ToLower(self.config.ISOChecksumType) - if self.config.ISOChecksumType != "none" { - if self.config.ISOChecksum == "" { - errs = packer.MultiErrorAppend( - errs, errors.New("Due to the file size being large, an iso_checksum is required.")) - } else { - self.config.ISOChecksum = strings.ToLower(self.config.ISOChecksum) - } - } - } + self.config.ISOChecksum = strings.ToLower(self.config.ISOChecksum) if len(self.config.ISOUrls) == 0 { if self.config.ISOUrl == "" { errs = packer.MultiErrorAppend( - errs, errors.New("One of iso_url or iso_urls must be specified.")) + errs, errors.New("One of iso_url or iso_urls must be specified.")) } else { self.config.ISOUrls = []string{self.config.ISOUrl} } + } else if self.config.ISOUrl != "" { errs = packer.MultiErrorAppend( errs, errors.New("Only one of iso_url or iso_urls may be specified.")) } + + //The SDK can validate the ISO checksum and other sanity checks on the url. + iso_config := commonsteps.ISOConfig { + ISOChecksum: self.config.ISOChecksum, + ISOUrls: self.config.ISOUrls, + } + + _, iso_errs := iso_config.Prepare(nil) + if iso_errs != nil { + for _, this_err := range iso_errs { + errs = packer.MultiErrorAppend(errs, this_err) + } + } + } else { // An ISO name has been provided. It should be attached from an available SR. diff --git a/builder/xenserver/iso/builder_test.go b/builder/xenserver/iso/builder_test.go index 92e6aac..c77d6dd 100644 --- a/builder/xenserver/iso/builder_test.go +++ b/builder/xenserver/iso/builder_test.go @@ -15,8 +15,7 @@ func testConfig() map[string]interface{} { "remote_username": "admin", "remote_password": "admin", "vm_name": "foo", - "iso_checksum": "foo", - "iso_checksum_type": "md5", + "iso_checksum": "md5:A221725EE181A44C67E25BD6A2516742", "iso_url": "http://www.google.com/", "shutdown_command": "yes", "ssh_username": "foo", @@ -181,9 +180,20 @@ func TestBuilderPrepare_ISOChecksum(t *testing.T) { var b Builder config := testConfig() + // Test good + + b = Builder{} + _, warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + // Test bad config["iso_checksum"] = "" - _, warns, err := b.Prepare(config) + _, warns, err = b.Prepare(config) if len(warns) > 0 { t.Fatalf("bad: %#v", warns) } @@ -191,80 +201,9 @@ func TestBuilderPrepare_ISOChecksum(t *testing.T) { t.Fatal("should have error") } - // Test good - config["iso_checksum"] = "FOo" - b = Builder{} - _, warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("should not have error: %s", err) - } - if b.config.ISOChecksum != "foo" { - t.Fatalf("should've lowercased: %s", b.config.ISOChecksum) - } } -func TestBuilderPrepare_ISOChecksumType(t *testing.T) { - var b Builder - config := testConfig() - - // Test bad - config["iso_checksum_type"] = "" - _, warns, err := b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatal("should have error") - } - - // Test good - config["iso_checksum_type"] = "mD5" - b = Builder{} - _, warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("should not have error: %s", err) - } - - if b.config.ISOChecksumType != "md5" { - t.Fatalf("should've lowercased: %s", b.config.ISOChecksumType) - } - - // Test unknown - config["iso_checksum_type"] = "fake" - b = Builder{} - _, warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatal("should have error") - } - - // Test none - config["iso_checksum_type"] = "none" - b = Builder{} - _, warns, err = b.Prepare(config) - // @todo: give warning in this case? - /* - if len(warns) == 0 { - t.Fatalf("bad: %#v", warns) - } - */ - if err != nil { - t.Fatalf("should not have error: %s", err) - } - - if b.config.ISOChecksumType != "none" { - t.Fatalf("should've lowercased: %s", b.config.ISOChecksumType) - } -} func TestBuilderPrepare_ISOUrl(t *testing.T) { var b Builder diff --git a/docs/builders/iso/xenserver-iso.html.markdown b/docs/builders/iso/xenserver-iso.html.markdown index 5f4bd08..c452add 100644 --- a/docs/builders/iso/xenserver-iso.html.markdown +++ b/docs/builders/iso/xenserver-iso.html.markdown @@ -29,14 +29,27 @@ each category, the available options are alphabetized and described. * `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO files are so large, this is required and Packer will verify it prior - to booting a virtual machine with the ISO attached. The type of the - checksum is specified with `iso_checksum_type`, documented below. + to booting a virtual machine with the ISO attached. The type of + the checksum is specified within the checksum field as a prefix, ex: + "md5:{$checksum}". The type of the checksum can also be omitted and + Packer will try to infer it based on string length. Valid values are + "none", "{$checksum}", "md5:{$checksum}", "sha1:{$checksum}", + "sha256:{$checksum}", "sha512:{$checksum}" or "file:{$path}". Here is a + list of valid checksum values: + * md5:090992ba9fd140077b0661cb75f7ce13 + * 090992ba9fd140077b0661cb75f7ce13 + * sha1:ebfb681885ddf1234c18094a45bbeafd91467911 + * ebfb681885ddf1234c18094a45bbeafd91467911 + * sha256:ed363350696a726b7932db864dda019bd2017365c9e299627830f06954643f93 + * ed363350696a726b7932db864dda019bd2017365c9e299627830f06954643f93 + * file:http://releases.ubuntu.com/20.04/SHA256SUMS + * file:file://./local/path/file.sum + * file:./local/path/file.sum + * none + Although the checksum will not be verified when it is set to "none", + this is not recommended since these files can be very large and + corruption does happen from time to time. -* `iso_checksum_type` (string) - The type of the checksum specified in - `iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or - "sha512" currently. While "none" will skip checksumming, this is not - recommended since ISO files are generally large and corruption does happen - from time to time. * `iso_url` (string) - A URL to the ISO containing the installation image. This URL can be either an HTTP URL or a file URL (or path to a file). From 6c808da03834135445b0688d71f84261be73e631 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Thu, 6 Apr 2023 23:23:51 -0700 Subject: [PATCH 20/35] Remove remaining usages of iso_checksum_type, fix config.hcl2spec.go generation and re-run it --- builder/xenserver/common/config.go | 11 +++++----- builder/xenserver/common/config.hcl2spec.go | 6 +++--- builder/xenserver/iso/builder.go | 23 ++++++++++----------- examples/centos/centos8-local.pkr.hcl | 3 +-- examples/centos/centos8-netinstall.pkr.hcl | 3 +-- examples/ubuntu/ubuntu-2004.pkr.hcl | 3 +-- 6 files changed, 22 insertions(+), 27 deletions(-) diff --git a/builder/xenserver/common/config.go b/builder/xenserver/common/config.go index 53e76b7..fdd31b5 100644 --- a/builder/xenserver/common/config.go +++ b/builder/xenserver/common/config.go @@ -1,4 +1,4 @@ -//go:generate mapstructure-to-hcl2 -type Config +//go:generate packer-sdc mapstructure-to-hcl2 -type Config package common import ( @@ -21,11 +21,10 @@ type Config struct { CloneTemplate string `mapstructure:"clone_template"` VMOtherConfig map[string]string `mapstructure:"vm_other_config"` - ISOChecksum string `mapstructure:"iso_checksum"` - ISOChecksumType string `mapstructure:"iso_checksum_type"` - ISOUrls []string `mapstructure:"iso_urls"` - ISOUrl string `mapstructure:"iso_url"` - ISOName string `mapstructure:"iso_name"` + ISOChecksum string `mapstructure:"iso_checksum"` + ISOUrls []string `mapstructure:"iso_urls"` + ISOUrl string `mapstructure:"iso_url"` + ISOName string `mapstructure:"iso_name"` PlatformArgs map[string]string `mapstructure:"platform_args"` diff --git a/builder/xenserver/common/config.hcl2spec.go b/builder/xenserver/common/config.hcl2spec.go index 65644ea..04d4479 100644 --- a/builder/xenserver/common/config.hcl2spec.go +++ b/builder/xenserver/common/config.hcl2spec.go @@ -1,4 +1,4 @@ -// Code generated by "mapstructure-to-hcl2 -type Config"; DO NOT EDIT. +// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT. package common @@ -12,6 +12,7 @@ import ( type FlatConfig struct { PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"` PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"` + PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"` PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"` PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"` PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"` @@ -100,7 +101,6 @@ type FlatConfig struct { CloneTemplate *string `mapstructure:"clone_template" cty:"clone_template" hcl:"clone_template"` VMOtherConfig map[string]string `mapstructure:"vm_other_config" cty:"vm_other_config" hcl:"vm_other_config"` ISOChecksum *string `mapstructure:"iso_checksum" cty:"iso_checksum" hcl:"iso_checksum"` - ISOChecksumType *string `mapstructure:"iso_checksum_type" cty:"iso_checksum_type" hcl:"iso_checksum_type"` ISOUrls []string `mapstructure:"iso_urls" cty:"iso_urls" hcl:"iso_urls"` ISOUrl *string `mapstructure:"iso_url" cty:"iso_url" hcl:"iso_url"` ISOName *string `mapstructure:"iso_name" cty:"iso_name" hcl:"iso_name"` @@ -124,6 +124,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { s := map[string]hcldec.Spec{ "packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false}, "packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false}, + "packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false}, "packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false}, "packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false}, "packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false}, @@ -212,7 +213,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "clone_template": &hcldec.AttrSpec{Name: "clone_template", Type: cty.String, Required: false}, "vm_other_config": &hcldec.AttrSpec{Name: "vm_other_config", Type: cty.Map(cty.String), Required: false}, "iso_checksum": &hcldec.AttrSpec{Name: "iso_checksum", Type: cty.String, Required: false}, - "iso_checksum_type": &hcldec.AttrSpec{Name: "iso_checksum_type", Type: cty.String, Required: false}, "iso_urls": &hcldec.AttrSpec{Name: "iso_urls", Type: cty.List(cty.String), Required: false}, "iso_url": &hcldec.AttrSpec{Name: "iso_url", Type: cty.String, Required: false}, "iso_name": &hcldec.AttrSpec{Name: "iso_name", Type: cty.String, Required: false}, diff --git a/builder/xenserver/iso/builder.go b/builder/xenserver/iso/builder.go index 7ef6950..9a0d1d1 100644 --- a/builder/xenserver/iso/builder.go +++ b/builder/xenserver/iso/builder.go @@ -95,12 +95,11 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri // Template substitution templates := map[string]*string{ - "clone_template": &self.config.CloneTemplate, - "iso_checksum": &self.config.ISOChecksum, - "iso_checksum_type": &self.config.ISOChecksumType, - "iso_url": &self.config.ISOUrl, - "iso_name": &self.config.ISOName, - "install_timeout": &self.config.RawInstallTimeout, + "clone_template": &self.config.CloneTemplate, + "iso_checksum": &self.config.ISOChecksum, + "iso_url": &self.config.ISOUrl, + "iso_name": &self.config.ISOName, + "install_timeout": &self.config.RawInstallTimeout, } for i := range self.config.ISOUrls { templates[fmt.Sprintf("iso_urls[%d]", i)] = &self.config.ISOUrls[i] @@ -121,7 +120,7 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri if len(self.config.ISOUrls) == 0 { if self.config.ISOUrl == "" { errs = packer.MultiErrorAppend( - errs, errors.New("One of iso_url or iso_urls must be specified.")) + errs, errors.New("One of iso_url or iso_urls must be specified.")) } else { self.config.ISOUrls = []string{self.config.ISOUrl} } @@ -132,16 +131,16 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri } //The SDK can validate the ISO checksum and other sanity checks on the url. - iso_config := commonsteps.ISOConfig { + iso_config := commonsteps.ISOConfig{ ISOChecksum: self.config.ISOChecksum, - ISOUrls: self.config.ISOUrls, + ISOUrls: self.config.ISOUrls, } _, iso_errs := iso_config.Prepare(nil) if iso_errs != nil { - for _, this_err := range iso_errs { - errs = packer.MultiErrorAppend(errs, this_err) - } + for _, this_err := range iso_errs { + errs = packer.MultiErrorAppend(errs, this_err) + } } } else { diff --git a/examples/centos/centos8-local.pkr.hcl b/examples/centos/centos8-local.pkr.hcl index c21eb8f..5dc693e 100644 --- a/examples/centos/centos8-local.pkr.hcl +++ b/examples/centos/centos8-local.pkr.hcl @@ -47,8 +47,7 @@ locals { } source "xenserver-iso" "centos8-local" { - iso_checksum = "aaf9d4b3071c16dbbda01dfe06085e5d0fdac76df323e3bbe87cce4318052247" - iso_checksum_type = "sha1" + iso_checksum = "sha1:aaf9d4b3071c16dbbda01dfe06085e5d0fdac76df323e3bbe87cce4318052247" iso_url = "http://mirrors.ocf.berkeley.edu/centos/8.3.2011/isos/x86_64/CentOS-8.3.2011-x86_64-dvd1.iso" sr_iso_name = var.sr_iso_name diff --git a/examples/centos/centos8-netinstall.pkr.hcl b/examples/centos/centos8-netinstall.pkr.hcl index e34d369..c2abbfe 100644 --- a/examples/centos/centos8-netinstall.pkr.hcl +++ b/examples/centos/centos8-netinstall.pkr.hcl @@ -47,8 +47,7 @@ locals { } source "xenserver-iso" "centos8-netinstall" { - iso_checksum = "07a8e59c42cc086ec4c49bdce4fae5a17b077dea" - iso_checksum_type = "sha1" + iso_checksum = "sha1:07a8e59c42cc086ec4c49bdce4fae5a17b077dea" iso_url = "http://mirrors.ocf.berkeley.edu/centos/8.3.2011/isos/x86_64/CentOS-8.3.2011-x86_64-boot.iso" sr_iso_name = var.sr_iso_name diff --git a/examples/ubuntu/ubuntu-2004.pkr.hcl b/examples/ubuntu/ubuntu-2004.pkr.hcl index 3373c46..c9ebfa8 100644 --- a/examples/ubuntu/ubuntu-2004.pkr.hcl +++ b/examples/ubuntu/ubuntu-2004.pkr.hcl @@ -74,8 +74,7 @@ variable "sr_name" { } source "xenserver-iso" "ubuntu-2004" { - iso_checksum = local.ubuntu_sha256.0 - iso_checksum_type = "sha256" + iso_checksum = "sha256:${local.ubuntu_sha256.0}" iso_url = "https://releases.ubuntu.com/${local.ubuntu_version}/ubuntu-${local.ubuntu_version}.${local.ubuntu_url_path.0}-live-server-amd64.iso" sr_iso_name = var.sr_iso_name From 416c734853d6b6c59edd5b85163475846f3c782b Mon Sep 17 00:00:00 2001 From: Heinrich Kruger Date: Wed, 25 May 2022 15:21:38 +0100 Subject: [PATCH 21/35] Use default SR if `sr_iso_name` is not specified --- builder/xenserver/common/common_config.go | 49 +++++++++++++---------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/builder/xenserver/common/common_config.go b/builder/xenserver/common/common_config.go index 4ae5edd..4b8e46e 100644 --- a/builder/xenserver/common/common_config.go +++ b/builder/xenserver/common/common_config.go @@ -223,29 +223,11 @@ func (c CommonConfig) ShouldKeepVM(state multistep.StateBag) bool { } func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRef, error) { - var srRef xenapi.SRRef if config.SrName == "" { - hostRef, err := c.GetClient().Session.GetThisHost(c.session, c.session) - - if err != nil { - return srRef, err - } - - pools, err := c.GetClient().Pool.GetAllRecords(c.session) - - if err != nil { - return srRef, err - } - - for _, pool := range pools { - if pool.Master == hostRef { - return pool.DefaultSR, nil - } - } - - return srRef, errors.New(fmt.Sprintf("failed to find default SR on host '%s'", hostRef)) - + return getDefaultSR(c) } else { + var srRef xenapi.SRRef + // Use the provided name label to find the SR to use srs, err := c.GetClient().SR.GetByNameLabel(c.session, config.SrName) @@ -267,7 +249,7 @@ func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRef, error) { func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) { var srRef xenapi.SRRef if config.SrISOName == "" { - return srRef, errors.New("sr_iso_name must be specified in the packer configuration") + return getDefaultSR(c) } else { // Use the provided name label to find the SR to use @@ -287,3 +269,26 @@ func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) { return srs[0], nil } } + +func getDefaultSR(c *Connection) (xenapi.SRRef, error) { + var srRef xenapi.SRRef + hostRef, err := c.GetClient().Session.GetThisHost(c.session, c.session) + + if err != nil { + return srRef, err + } + + pools, err := c.GetClient().Pool.GetAllRecords(c.session) + + if err != nil { + return srRef, err + } + + for _, pool := range pools { + if pool.Master == hostRef { + return pool.DefaultSR, nil + } + } + + return srRef, errors.New(fmt.Sprintf("failed to find default SR on host '%s'", hostRef)) +} From ffc0ffb5cdfc32e35d4163905dc26073fed395f2 Mon Sep 17 00:00:00 2001 From: Heinrich Kruger Date: Thu, 26 May 2022 10:15:40 +0100 Subject: [PATCH 22/35] Work around XenAPI compatibility issue to get default SR --- builder/xenserver/common/common_config.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/builder/xenserver/common/common_config.go b/builder/xenserver/common/common_config.go index 4b8e46e..6a5105c 100644 --- a/builder/xenserver/common/common_config.go +++ b/builder/xenserver/common/common_config.go @@ -272,21 +272,29 @@ func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) { func getDefaultSR(c *Connection) (xenapi.SRRef, error) { var srRef xenapi.SRRef - hostRef, err := c.GetClient().Session.GetThisHost(c.session, c.session) + client := c.GetClient() + hostRef, err := client.Session.GetThisHost(c.session, c.session) if err != nil { return srRef, err } - pools, err := c.GetClient().Pool.GetAllRecords(c.session) + // The current version of the go-xen-api-client does not fully support XenAPI version 8.2 + // In particular, some values for the pool `allowed_operations` are not recognised, resulting + // in a parse error when retrieving pool records. As a workaround, we only fetch pool refs. + pool_refs, err := client.Pool.GetAll(c.session) if err != nil { return srRef, err } - for _, pool := range pools { - if pool.Master == hostRef { - return pool.DefaultSR, nil + for _, pool_ref := range pool_refs { + pool_master, err := client.Pool.GetMaster(c.session, pool_ref) + if err != nil { + return srRef, err + } + if pool_master == hostRef { + return client.Pool.GetDefaultSR(c.session, pool_ref) } } From d8294d3ccd6ec35d56417ec62adb45967bd9f67a Mon Sep 17 00:00:00 2001 From: Heinrich Kruger Date: Wed, 25 May 2022 15:21:38 +0100 Subject: [PATCH 23/35] Use default SR if `sr_iso_name` is not specified --- builder/xenserver/common/common_config.go | 49 +++++++++++++---------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/builder/xenserver/common/common_config.go b/builder/xenserver/common/common_config.go index 4ae5edd..4b8e46e 100644 --- a/builder/xenserver/common/common_config.go +++ b/builder/xenserver/common/common_config.go @@ -223,29 +223,11 @@ func (c CommonConfig) ShouldKeepVM(state multistep.StateBag) bool { } func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRef, error) { - var srRef xenapi.SRRef if config.SrName == "" { - hostRef, err := c.GetClient().Session.GetThisHost(c.session, c.session) - - if err != nil { - return srRef, err - } - - pools, err := c.GetClient().Pool.GetAllRecords(c.session) - - if err != nil { - return srRef, err - } - - for _, pool := range pools { - if pool.Master == hostRef { - return pool.DefaultSR, nil - } - } - - return srRef, errors.New(fmt.Sprintf("failed to find default SR on host '%s'", hostRef)) - + return getDefaultSR(c) } else { + var srRef xenapi.SRRef + // Use the provided name label to find the SR to use srs, err := c.GetClient().SR.GetByNameLabel(c.session, config.SrName) @@ -267,7 +249,7 @@ func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRef, error) { func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) { var srRef xenapi.SRRef if config.SrISOName == "" { - return srRef, errors.New("sr_iso_name must be specified in the packer configuration") + return getDefaultSR(c) } else { // Use the provided name label to find the SR to use @@ -287,3 +269,26 @@ func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) { return srs[0], nil } } + +func getDefaultSR(c *Connection) (xenapi.SRRef, error) { + var srRef xenapi.SRRef + hostRef, err := c.GetClient().Session.GetThisHost(c.session, c.session) + + if err != nil { + return srRef, err + } + + pools, err := c.GetClient().Pool.GetAllRecords(c.session) + + if err != nil { + return srRef, err + } + + for _, pool := range pools { + if pool.Master == hostRef { + return pool.DefaultSR, nil + } + } + + return srRef, errors.New(fmt.Sprintf("failed to find default SR on host '%s'", hostRef)) +} From 70fd83e8033752682358aa0bf1869344fe663986 Mon Sep 17 00:00:00 2001 From: Heinrich Kruger Date: Thu, 26 May 2022 10:15:40 +0100 Subject: [PATCH 24/35] Work around XenAPI compatibility issue to get default SR --- builder/xenserver/common/common_config.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/builder/xenserver/common/common_config.go b/builder/xenserver/common/common_config.go index 4b8e46e..6a5105c 100644 --- a/builder/xenserver/common/common_config.go +++ b/builder/xenserver/common/common_config.go @@ -272,21 +272,29 @@ func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) { func getDefaultSR(c *Connection) (xenapi.SRRef, error) { var srRef xenapi.SRRef - hostRef, err := c.GetClient().Session.GetThisHost(c.session, c.session) + client := c.GetClient() + hostRef, err := client.Session.GetThisHost(c.session, c.session) if err != nil { return srRef, err } - pools, err := c.GetClient().Pool.GetAllRecords(c.session) + // The current version of the go-xen-api-client does not fully support XenAPI version 8.2 + // In particular, some values for the pool `allowed_operations` are not recognised, resulting + // in a parse error when retrieving pool records. As a workaround, we only fetch pool refs. + pool_refs, err := client.Pool.GetAll(c.session) if err != nil { return srRef, err } - for _, pool := range pools { - if pool.Master == hostRef { - return pool.DefaultSR, nil + for _, pool_ref := range pool_refs { + pool_master, err := client.Pool.GetMaster(c.session, pool_ref) + if err != nil { + return srRef, err + } + if pool_master == hostRef { + return client.Pool.GetDefaultSR(c.session, pool_ref) } } From 3c5fc29b364079f8b09d26de3da9935007856421 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Fri, 14 Apr 2023 00:02:58 -0700 Subject: [PATCH 25/35] Ensure that SrISOName is no longer a required field --- builder/xenserver/common/common_config.go | 2 +- builder/xenserver/common/config.hcl2spec.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/xenserver/common/common_config.go b/builder/xenserver/common/common_config.go index 6a5105c..bf63ae2 100644 --- a/builder/xenserver/common/common_config.go +++ b/builder/xenserver/common/common_config.go @@ -20,7 +20,7 @@ type CommonConfig struct { VMName string `mapstructure:"vm_name"` VMDescription string `mapstructure:"vm_description"` SrName string `mapstructure:"sr_name"` - SrISOName string `mapstructure:"sr_iso_name"` + SrISOName string `mapstructure:"sr_iso_name" required:"false"` FloppyFiles []string `mapstructure:"floppy_files"` NetworkNames []string `mapstructure:"network_names"` ExportNetworkNames []string `mapstructure:"export_network_names"` diff --git a/builder/xenserver/common/config.hcl2spec.go b/builder/xenserver/common/config.hcl2spec.go index 04d4479..9b3fcb7 100644 --- a/builder/xenserver/common/config.hcl2spec.go +++ b/builder/xenserver/common/config.hcl2spec.go @@ -24,7 +24,7 @@ type FlatConfig struct { VMName *string `mapstructure:"vm_name" cty:"vm_name" hcl:"vm_name"` VMDescription *string `mapstructure:"vm_description" cty:"vm_description" hcl:"vm_description"` SrName *string `mapstructure:"sr_name" cty:"sr_name" hcl:"sr_name"` - SrISOName *string `mapstructure:"sr_iso_name" cty:"sr_iso_name" hcl:"sr_iso_name"` + SrISOName *string `mapstructure:"sr_iso_name" required:"false" cty:"sr_iso_name" hcl:"sr_iso_name"` FloppyFiles []string `mapstructure:"floppy_files" cty:"floppy_files" hcl:"floppy_files"` NetworkNames []string `mapstructure:"network_names" cty:"network_names" hcl:"network_names"` ExportNetworkNames []string `mapstructure:"export_network_names" cty:"export_network_names" hcl:"export_network_names"` From 3f0a2186bfb9fa899737e8d5d0c1b33bfeecac18 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Fri, 14 Apr 2023 06:43:21 -0700 Subject: [PATCH 26/35] Revert "Allow ISO Storage repository to fallback to default SR if unspecified" --- builder/xenserver/common/common_config.go | 57 +++++++++-------------- 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/builder/xenserver/common/common_config.go b/builder/xenserver/common/common_config.go index 6a5105c..4ae5edd 100644 --- a/builder/xenserver/common/common_config.go +++ b/builder/xenserver/common/common_config.go @@ -223,11 +223,29 @@ func (c CommonConfig) ShouldKeepVM(state multistep.StateBag) bool { } func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRef, error) { + var srRef xenapi.SRRef if config.SrName == "" { - return getDefaultSR(c) - } else { - var srRef xenapi.SRRef + hostRef, err := c.GetClient().Session.GetThisHost(c.session, c.session) + if err != nil { + return srRef, err + } + + pools, err := c.GetClient().Pool.GetAllRecords(c.session) + + if err != nil { + return srRef, err + } + + for _, pool := range pools { + if pool.Master == hostRef { + return pool.DefaultSR, nil + } + } + + return srRef, errors.New(fmt.Sprintf("failed to find default SR on host '%s'", hostRef)) + + } else { // Use the provided name label to find the SR to use srs, err := c.GetClient().SR.GetByNameLabel(c.session, config.SrName) @@ -249,7 +267,7 @@ func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRef, error) { func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) { var srRef xenapi.SRRef if config.SrISOName == "" { - return getDefaultSR(c) + return srRef, errors.New("sr_iso_name must be specified in the packer configuration") } else { // Use the provided name label to find the SR to use @@ -269,34 +287,3 @@ func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) { return srs[0], nil } } - -func getDefaultSR(c *Connection) (xenapi.SRRef, error) { - var srRef xenapi.SRRef - client := c.GetClient() - hostRef, err := client.Session.GetThisHost(c.session, c.session) - - if err != nil { - return srRef, err - } - - // The current version of the go-xen-api-client does not fully support XenAPI version 8.2 - // In particular, some values for the pool `allowed_operations` are not recognised, resulting - // in a parse error when retrieving pool records. As a workaround, we only fetch pool refs. - pool_refs, err := client.Pool.GetAll(c.session) - - if err != nil { - return srRef, err - } - - for _, pool_ref := range pool_refs { - pool_master, err := client.Pool.GetMaster(c.session, pool_ref) - if err != nil { - return srRef, err - } - if pool_master == hostRef { - return client.Pool.GetDefaultSR(c.session, pool_ref) - } - } - - return srRef, errors.New(fmt.Sprintf("failed to find default SR on host '%s'", hostRef)) -} From 17c58e8d243fbac79c28260a0174fbf2187bd9d0 Mon Sep 17 00:00:00 2001 From: Heinrich Kruger Date: Thu, 26 May 2022 16:21:49 +0100 Subject: [PATCH 27/35] Enable xva builder to create VM from existing template --- builder/xenserver/xva/builder.go | 10 +- .../xva/step_create_from_template.go | 191 ++++++++++++++++++ builder/xenserver/xva/step_import_instance.go | 6 + 3 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 builder/xenserver/xva/step_create_from_template.go diff --git a/builder/xenserver/xva/builder.go b/builder/xenserver/xva/builder.go index 4eee1c4..f64cafc 100644 --- a/builder/xenserver/xva/builder.go +++ b/builder/xenserver/xva/builder.go @@ -3,7 +3,6 @@ package xva import ( "context" "errors" - "fmt" "time" "github.com/hashicorp/hcl/v2/hcldec" @@ -74,8 +73,12 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri // Validation - if self.config.SourcePath == "" { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("A source_path must be specified")) + if self.config.SourcePath == "" && self.config.CloneTemplate == "" { + errs = packer.MultiErrorAppend( + errs, errors.New("Either source_path or clone_template must be specified")) + } else if self.config.SourcePath != "" && self.config.CloneTemplate != "" { + errs = packer.MultiErrorAppend( + errs, errors.New("Only one of source_path and clone_template must be specified")) } if len(errs.Errors) > 0 { @@ -134,6 +137,7 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p VdiName: self.config.ToolsIsoName, VdiUuidKey: "tools_vdi_uuid", }, + new(stepCreateFromTemplate), new(stepImportInstance), &xscommon.StepAttachVdi{ VdiUuidKey: "floppy_vdi_uuid", diff --git a/builder/xenserver/xva/step_create_from_template.go b/builder/xenserver/xva/step_create_from_template.go new file mode 100644 index 0000000..a4bd436 --- /dev/null +++ b/builder/xenserver/xva/step_create_from_template.go @@ -0,0 +1,191 @@ +package xva + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/packer-plugin-sdk/multistep" + "github.com/hashicorp/packer-plugin-sdk/packer" + xsclient "github.com/terra-farm/go-xen-api-client" + xscommon "github.com/xenserver/packer-builder-xenserver/builder/xenserver/common" +) + +type stepCreateFromTemplate struct { + instance *xsclient.VMRef +} + +func (self *stepCreateFromTemplate) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + + c := state.Get("client").(*xscommon.Connection) + config := state.Get("config").(xscommon.Config) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Step: Create Instance from Template") + + if config.CloneTemplate == "" { + log.Println("Skipping creation from template - no `clone_template` configured.") + return multistep.ActionContinue + } + + // Get the template to clone from + + vms, err := c.GetClient().VM.GetByNameLabel(c.GetSessionRef(), config.CloneTemplate) + + switch { + case len(vms) == 0: + ui.Error(fmt.Sprintf("Couldn't find a template with the name-label '%s'. Aborting.", config.CloneTemplate)) + return multistep.ActionHalt + case len(vms) > 1: + ui.Error(fmt.Sprintf("Found more than one template with the name '%s'. The name must be unique. Aborting.", config.CloneTemplate)) + return multistep.ActionHalt + } + + template := vms[0] + + // Clone that VM template + instance, err := c.GetClient().VM.Clone(c.GetSessionRef(), template, config.VMName) + if err != nil { + ui.Error(fmt.Sprintf("Error cloning VM: %s", err.Error())) + return multistep.ActionHalt + } + self.instance = &instance + + err = c.GetClient().VM.SetIsATemplate(c.GetSessionRef(), instance, false) + if err != nil { + ui.Error(fmt.Sprintf("Error setting is_a_template=false: %s", err.Error())) + return multistep.ActionHalt + } + + err = c.GetClient().VM.SetVCPUsMax(c.GetSessionRef(), instance, int(config.VCPUsMax)) + if err != nil { + ui.Error(fmt.Sprintf("Error setting VM VCPUs Max=%d: %s", config.VCPUsMax, err.Error())) + return multistep.ActionHalt + } + + err = c.GetClient().VM.SetVCPUsAtStartup(c.GetSessionRef(), instance, int(config.VCPUsAtStartup)) + if err != nil { + ui.Error(fmt.Sprintf("Error setting VM VCPUs At Startup=%d: %s", config.VCPUsAtStartup, err.Error())) + return multistep.ActionHalt + } + + memory := int(config.VMMemory * 1024 * 1024) + err = c.GetClient().VM.SetMemoryLimits(c.GetSessionRef(), instance, memory, memory, memory, memory) + if err != nil { + ui.Error(fmt.Sprintf("Error setting VM memory=%d: %s", memory, err.Error())) + return multistep.ActionHalt + } + + err = c.GetClient().VM.SetPlatform(c.GetSessionRef(), instance, config.PlatformArgs) + if err != nil { + ui.Error(fmt.Sprintf("Error setting VM platform: %s", err.Error())) + return multistep.ActionHalt + } + + err = c.GetClient().VM.SetNameDescription(c.GetSessionRef(), instance, config.VMDescription) + if err != nil { + ui.Error(fmt.Sprintf("Error setting VM description: %s", err.Error())) + return multistep.ActionHalt + } + + // Connect Network + + var network xsclient.NetworkRef + + if len(config.NetworkNames) == 0 { + // No network has be specified. Use the management interface + log.Println("No network name given, attempting to use management interface") + pifs, err := c.GetClient().PIF.GetAll(c.GetSessionRef()) + + if err != nil { + ui.Error(fmt.Sprintf("Error getting PIFs: %s", err.Error())) + return multistep.ActionHalt + } + + for _, pif := range pifs { + pif_rec, err := c.GetClient().PIF.GetRecord(c.GetSessionRef(), pif) + + if err != nil { + ui.Error(fmt.Sprintf("Error getting PIF record: %s", err.Error())) + return multistep.ActionHalt + } + + if pif_rec.Management { + network = pif_rec.Network + } + + } + + if string(network) == "" { + ui.Error("Error: couldn't find management network. Aborting.") + return multistep.ActionHalt + } + + log.Printf("Creating VIF on network '%s' on VM '%s'\n", network, instance) + _, err = xscommon.ConnectNetwork(c, network, instance, "0") + + if err != nil { + ui.Error(fmt.Sprintf("Failed to create VIF with error: %v", err)) + return multistep.ActionHalt + } + + } else { + log.Printf("Using provided network names: %v\n", config.NetworkNames) + // Look up each network by it's name label + for i, networkNameLabel := range config.NetworkNames { + networks, err := c.GetClient().Network.GetByNameLabel(c.GetSessionRef(), networkNameLabel) + + if err != nil { + ui.Error(fmt.Sprintf("Error occured getting Network by name-label: %s", err.Error())) + return multistep.ActionHalt + } + + switch { + case len(networks) == 0: + ui.Error(fmt.Sprintf("Couldn't find a network with the specified name-label '%s'. Aborting.", networkNameLabel)) + return multistep.ActionHalt + case len(networks) > 1: + ui.Error(fmt.Sprintf("Found more than one network with the name '%s'. The name must be unique. Aborting.", networkNameLabel)) + return multistep.ActionHalt + } + + //we need the VIF index string + vifIndexString := fmt.Sprintf("%d", i) + _, err = xscommon.ConnectNetwork(c, networks[0], instance, vifIndexString) + + if err != nil { + ui.Say(fmt.Sprintf("Failed to connect VIF with error: %v", err.Error())) + } + } + } + + instanceId, err := c.GetClient().VM.GetUUID(c.GetSessionRef(), instance) + if err != nil { + ui.Error(fmt.Sprintf("Unable to get VM UUID: %s", err.Error())) + return multistep.ActionHalt + } + + state.Put("instance_uuid", instanceId) + ui.Say(fmt.Sprintf("Created instance '%s'", instanceId)) + + return multistep.ActionContinue +} + +func (self *stepCreateFromTemplate) Cleanup(state multistep.StateBag) { + config := state.Get("config").(xscommon.Config) + if config.ShouldKeepVM(state) { + return + } + + ui := state.Get("ui").(packer.Ui) + c := state.Get("client").(*xscommon.Connection) + + if self.instance != nil { + ui.Say("Destroying VM") + _ = c.GetClient().VM.HardShutdown(c.GetSessionRef(), *self.instance) // redundant, just in case + err := c.GetClient().VM.Destroy(c.GetSessionRef(), *self.instance) + if err != nil { + ui.Error(err.Error()) + } + } +} diff --git a/builder/xenserver/xva/step_import_instance.go b/builder/xenserver/xva/step_import_instance.go index 54215fa..ecc53a8 100644 --- a/builder/xenserver/xva/step_import_instance.go +++ b/builder/xenserver/xva/step_import_instance.go @@ -3,6 +3,7 @@ package xva import ( "context" "fmt" + "log" "os" "github.com/hashicorp/packer-plugin-sdk/multistep" @@ -24,6 +25,11 @@ func (self *stepImportInstance) Run(ctx context.Context, state multistep.StateBa ui.Say("Step: Import Instance") + if config.SourcePath == "" { + log.Println("Skipping imporing instance - no `source_path` configured.") + return multistep.ActionContinue + } + // find the SR srs, err := c.GetClient().SR.GetAll(c.GetSessionRef()) sr := srs[0] From 0bb70e89572fe3ebf6b69bd700e15abd0d4b0173 Mon Sep 17 00:00:00 2001 From: Heinrich Kruger Date: Thu, 26 May 2022 16:25:17 +0100 Subject: [PATCH 28/35] Update XVA builder to match ISO builder --- builder/xenserver/xva/builder.go | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/builder/xenserver/xva/builder.go b/builder/xenserver/xva/builder.go index f64cafc..0477172 100644 --- a/builder/xenserver/xva/builder.go +++ b/builder/xenserver/xva/builder.go @@ -42,6 +42,7 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri errs = packer.MultiErrorAppend( errs, self.config.CommonConfig.Prepare(self.config.GetInterpContext(), &self.config.PackerConfig)...) + errs = packer.MultiErrorAppend(errs, self.config.SSHConfig.Prepare(self.config.GetInterpContext())...) // Set default values if self.config.VCPUsMax == 0 { @@ -104,7 +105,7 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p //Share state between the other steps using a statebag state := new(multistep.BasicStateBag) state.Put("client", c) - // state.Put("config", self.config) + state.Put("config", self.config) state.Put("commonconfig", self.config.CommonConfig) state.Put("hook", hook) state.Put("ui", ui) @@ -119,8 +120,11 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p }, &commonsteps.StepCreateFloppy{ Files: self.config.FloppyFiles, + Label: "cidata", + }, + &xscommon.StepHTTPServer{ + Chan: httpReqChan, }, - new(xscommon.StepHTTPServer), &xscommon.StepUploadVdi{ VdiNameFunc: func() string { return "Packer-floppy-disk" @@ -157,20 +161,28 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p Chan: httpReqChan, Timeout: 300 * time.Minute, /*self.config.InstallTimeout*/ // @todo change this }, + &xscommon.StepForwardPortOverSSH{ + RemotePort: xscommon.InstanceSSHPort, + RemoteDest: xscommon.InstanceSSHIP, + HostPortMin: self.config.HostPortMin, + HostPortMax: self.config.HostPortMax, + ResultKey: "local_ssh_port", + }, &communicator.StepConnect{ Config: &self.config.SSHConfig.Comm, - Host: xscommon.CommHost, - SSHConfig: xscommon.SSHConfigFunc(self.config.CommonConfig.SSHConfig), - SSHPort: xscommon.SSHPort, + Host: xscommon.InstanceSSHIP, + SSHConfig: self.config.Comm.SSHConfigFunc(), + SSHPort: xscommon.InstanceSSHPort, }, new(commonsteps.StepProvision), new(xscommon.StepShutdown), - &xscommon.StepDetachVdi{ - VdiUuidKey: "floppy_vdi_uuid", - }, + new(xscommon.StepSetVmToTemplate), &xscommon.StepDetachVdi{ VdiUuidKey: "tools_vdi_uuid", }, + &xscommon.StepDetachVdi{ + VdiUuidKey: "floppy_vdi_uuid", + }, new(xscommon.StepExport), } From 461367ad1cbaa7ac7d97432f599ff51073d3bb1b Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Sat, 15 Apr 2023 14:49:11 -0700 Subject: [PATCH 29/35] Move create instance step to common directory --- .../{iso => common}/step_create_instance.go | 23 +++++++++---------- builder/xenserver/iso/builder.go | 2 +- 2 files changed, 12 insertions(+), 13 deletions(-) rename builder/xenserver/{iso => common}/step_create_instance.go (91%) diff --git a/builder/xenserver/iso/step_create_instance.go b/builder/xenserver/common/step_create_instance.go similarity index 91% rename from builder/xenserver/iso/step_create_instance.go rename to builder/xenserver/common/step_create_instance.go index df6702a..8f3611a 100644 --- a/builder/xenserver/iso/step_create_instance.go +++ b/builder/xenserver/common/step_create_instance.go @@ -1,4 +1,4 @@ -package iso +package common import ( "context" @@ -9,18 +9,17 @@ import ( "github.com/hashicorp/packer-plugin-sdk/packer" xenapi "github.com/terra-farm/go-xen-api-client" xsclient "github.com/terra-farm/go-xen-api-client" - xscommon "github.com/xenserver/packer-builder-xenserver/builder/xenserver/common" ) -type stepCreateInstance struct { +type StepCreateInstance struct { instance *xsclient.VMRef vdi *xsclient.VDIRef } -func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { +func (self *StepCreateInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - c := state.Get("client").(*xscommon.Connection) - config := state.Get("config").(xscommon.Config) + c := state.Get("client").(*Connection) + config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) ui.Say("Step: Create Instance") @@ -134,7 +133,7 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa } self.vdi = &vdi - err = xscommon.ConnectVdi(c, instance, vdi, xsclient.VbdTypeDisk) + err = ConnectVdi(c, instance, vdi, xsclient.VbdTypeDisk) if err != nil { ui.Error(fmt.Sprintf("Unable to connect packer disk VDI: %s", err.Error())) return multistep.ActionHalt @@ -174,7 +173,7 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa } log.Printf("Creating VIF on network '%s' on VM '%s'\n", network, instance) - _, err = xscommon.ConnectNetwork(c, network, instance, "0") + _, err = ConnectNetwork(c, network, instance, "0") if err != nil { ui.Error(fmt.Sprintf("Failed to create VIF with error: %v", err)) @@ -203,7 +202,7 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa //we need the VIF index string vifIndexString := fmt.Sprintf("%d", i) - _, err = xscommon.ConnectNetwork(c, networks[0], instance, vifIndexString) + _, err = ConnectNetwork(c, networks[0], instance, vifIndexString) if err != nil { ui.Say(fmt.Sprintf("Failed to connect VIF with error: %v", err.Error())) @@ -223,14 +222,14 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa return multistep.ActionContinue } -func (self *stepCreateInstance) Cleanup(state multistep.StateBag) { - config := state.Get("config").(xscommon.Config) +func (self *StepCreateInstance) Cleanup(state multistep.StateBag) { + config := state.Get("config").(Config) if config.ShouldKeepVM(state) { return } ui := state.Get("ui").(packer.Ui) - c := state.Get("client").(*xscommon.Connection) + c := state.Get("client").(*Connection) if self.instance != nil { ui.Say("Destroying VM") diff --git a/builder/xenserver/iso/builder.go b/builder/xenserver/iso/builder.go index 9a0d1d1..055d001 100644 --- a/builder/xenserver/iso/builder.go +++ b/builder/xenserver/iso/builder.go @@ -235,7 +235,7 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p VdiName: self.config.ISOName, VdiUuidKey: "isoname_vdi_uuid", }, - new(stepCreateInstance), + new(xscommon.StepCreateInstance), &xscommon.StepAttachVdi{ VdiUuidKey: "floppy_vdi_uuid", VdiType: xsclient.VbdTypeFloppy, From 7c4b652c17fbef51d61624d9fe5cea153011fed4 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Sat, 15 Apr 2023 14:58:13 -0700 Subject: [PATCH 30/35] Update StepCreateInstance to accommodate both ISO and XVA builders --- .../xenserver/common/step_create_instance.go | 70 ++++++++++--------- builder/xenserver/iso/builder.go | 4 +- 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/builder/xenserver/common/step_create_instance.go b/builder/xenserver/common/step_create_instance.go index 8f3611a..7ceba97 100644 --- a/builder/xenserver/common/step_create_instance.go +++ b/builder/xenserver/common/step_create_instance.go @@ -12,6 +12,10 @@ import ( ) type StepCreateInstance struct { + // The XVA builder assumes it will boot an instance with an OS installed on its disks + // while the ISO builder needs packer to create a disk for an OS to be installed on. + AssumePreInstalledOS bool + instance *xsclient.VMRef vdi *xsclient.VDIRef } @@ -100,43 +104,45 @@ func (self *StepCreateInstance) Run(ctx context.Context, state multistep.StateBa } } - err = c.GetClient().VM.RemoveFromOtherConfig(c.GetSessionRef(), instance, "disks") - if err != nil { - ui.Error(fmt.Sprintf("Error removing disks from VM other-config: %s", err.Error())) - return multistep.ActionHalt - } + if !self.AssumePreInstalledOS { + err = c.GetClient().VM.RemoveFromOtherConfig(c.GetSessionRef(), instance, "disks") + if err != nil { + ui.Error(fmt.Sprintf("Error removing disks from VM other-config: %s", err.Error())) + return multistep.ActionHalt + } - // Create VDI for the instance - sr, err := config.GetSR(c) + // Create VDI for the instance + sr, err := config.GetSR(c) - if err != nil { - ui.Error(fmt.Sprintf("Unable to get SR: %s", err.Error())) - return multistep.ActionHalt - } + if err != nil { + ui.Error(fmt.Sprintf("Unable to get SR: %s", err.Error())) + return multistep.ActionHalt + } - ui.Say(fmt.Sprintf("Using the following SR for the VM: %s", sr)) + ui.Say(fmt.Sprintf("Using the following SR for the VM: %s", sr)) - vdi, err := c.GetClient().VDI.Create(c.GetSessionRef(), xenapi.VDIRecord{ - NameLabel: "Packer-disk", - VirtualSize: int(config.DiskSize * 1024 * 1024), - Type: "user", - Sharable: false, - ReadOnly: false, - SR: sr, - OtherConfig: map[string]string{ - "temp": "temp", - }, - }) - if err != nil { - ui.Error(fmt.Sprintf("Unable to create packer disk VDI: %s", err.Error())) - return multistep.ActionHalt - } - self.vdi = &vdi + vdi, err := c.GetClient().VDI.Create(c.GetSessionRef(), xenapi.VDIRecord{ + NameLabel: "Packer-disk", + VirtualSize: int(config.DiskSize * 1024 * 1024), + Type: "user", + Sharable: false, + ReadOnly: false, + SR: sr, + OtherConfig: map[string]string{ + "temp": "temp", + }, + }) + if err != nil { + ui.Error(fmt.Sprintf("Unable to create packer disk VDI: %s", err.Error())) + return multistep.ActionHalt + } + self.vdi = &vdi - err = ConnectVdi(c, instance, vdi, xsclient.VbdTypeDisk) - if err != nil { - ui.Error(fmt.Sprintf("Unable to connect packer disk VDI: %s", err.Error())) - return multistep.ActionHalt + err = ConnectVdi(c, instance, vdi, xsclient.VbdTypeDisk) + if err != nil { + ui.Error(fmt.Sprintf("Unable to connect packer disk VDI: %s", err.Error())) + return multistep.ActionHalt + } } // Connect Network diff --git a/builder/xenserver/iso/builder.go b/builder/xenserver/iso/builder.go index 055d001..7a3c5cc 100644 --- a/builder/xenserver/iso/builder.go +++ b/builder/xenserver/iso/builder.go @@ -235,7 +235,9 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p VdiName: self.config.ISOName, VdiUuidKey: "isoname_vdi_uuid", }, - new(xscommon.StepCreateInstance), + &xscommon.StepCreateInstance{ + AssumePreInstalledOS: false, + }, &xscommon.StepAttachVdi{ VdiUuidKey: "floppy_vdi_uuid", VdiType: xsclient.VbdTypeFloppy, From 2fe14d14ac8ff4c09f4fe9031cef080bf02dbf18 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Sat, 15 Apr 2023 15:01:00 -0700 Subject: [PATCH 31/35] Update XVA builder to use shared StepCreateInstance step --- builder/xenserver/xva/builder.go | 4 +- .../xva/step_create_from_template.go | 191 ------------------ 2 files changed, 3 insertions(+), 192 deletions(-) delete mode 100644 builder/xenserver/xva/step_create_from_template.go diff --git a/builder/xenserver/xva/builder.go b/builder/xenserver/xva/builder.go index 0477172..e948413 100644 --- a/builder/xenserver/xva/builder.go +++ b/builder/xenserver/xva/builder.go @@ -141,7 +141,9 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p VdiName: self.config.ToolsIsoName, VdiUuidKey: "tools_vdi_uuid", }, - new(stepCreateFromTemplate), + &xscommon.StepCreateInstance{ + AssumePreInstalledOS: true, + }, new(stepImportInstance), &xscommon.StepAttachVdi{ VdiUuidKey: "floppy_vdi_uuid", diff --git a/builder/xenserver/xva/step_create_from_template.go b/builder/xenserver/xva/step_create_from_template.go deleted file mode 100644 index a4bd436..0000000 --- a/builder/xenserver/xva/step_create_from_template.go +++ /dev/null @@ -1,191 +0,0 @@ -package xva - -import ( - "context" - "fmt" - "log" - - "github.com/hashicorp/packer-plugin-sdk/multistep" - "github.com/hashicorp/packer-plugin-sdk/packer" - xsclient "github.com/terra-farm/go-xen-api-client" - xscommon "github.com/xenserver/packer-builder-xenserver/builder/xenserver/common" -) - -type stepCreateFromTemplate struct { - instance *xsclient.VMRef -} - -func (self *stepCreateFromTemplate) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - - c := state.Get("client").(*xscommon.Connection) - config := state.Get("config").(xscommon.Config) - ui := state.Get("ui").(packer.Ui) - - ui.Say("Step: Create Instance from Template") - - if config.CloneTemplate == "" { - log.Println("Skipping creation from template - no `clone_template` configured.") - return multistep.ActionContinue - } - - // Get the template to clone from - - vms, err := c.GetClient().VM.GetByNameLabel(c.GetSessionRef(), config.CloneTemplate) - - switch { - case len(vms) == 0: - ui.Error(fmt.Sprintf("Couldn't find a template with the name-label '%s'. Aborting.", config.CloneTemplate)) - return multistep.ActionHalt - case len(vms) > 1: - ui.Error(fmt.Sprintf("Found more than one template with the name '%s'. The name must be unique. Aborting.", config.CloneTemplate)) - return multistep.ActionHalt - } - - template := vms[0] - - // Clone that VM template - instance, err := c.GetClient().VM.Clone(c.GetSessionRef(), template, config.VMName) - if err != nil { - ui.Error(fmt.Sprintf("Error cloning VM: %s", err.Error())) - return multistep.ActionHalt - } - self.instance = &instance - - err = c.GetClient().VM.SetIsATemplate(c.GetSessionRef(), instance, false) - if err != nil { - ui.Error(fmt.Sprintf("Error setting is_a_template=false: %s", err.Error())) - return multistep.ActionHalt - } - - err = c.GetClient().VM.SetVCPUsMax(c.GetSessionRef(), instance, int(config.VCPUsMax)) - if err != nil { - ui.Error(fmt.Sprintf("Error setting VM VCPUs Max=%d: %s", config.VCPUsMax, err.Error())) - return multistep.ActionHalt - } - - err = c.GetClient().VM.SetVCPUsAtStartup(c.GetSessionRef(), instance, int(config.VCPUsAtStartup)) - if err != nil { - ui.Error(fmt.Sprintf("Error setting VM VCPUs At Startup=%d: %s", config.VCPUsAtStartup, err.Error())) - return multistep.ActionHalt - } - - memory := int(config.VMMemory * 1024 * 1024) - err = c.GetClient().VM.SetMemoryLimits(c.GetSessionRef(), instance, memory, memory, memory, memory) - if err != nil { - ui.Error(fmt.Sprintf("Error setting VM memory=%d: %s", memory, err.Error())) - return multistep.ActionHalt - } - - err = c.GetClient().VM.SetPlatform(c.GetSessionRef(), instance, config.PlatformArgs) - if err != nil { - ui.Error(fmt.Sprintf("Error setting VM platform: %s", err.Error())) - return multistep.ActionHalt - } - - err = c.GetClient().VM.SetNameDescription(c.GetSessionRef(), instance, config.VMDescription) - if err != nil { - ui.Error(fmt.Sprintf("Error setting VM description: %s", err.Error())) - return multistep.ActionHalt - } - - // Connect Network - - var network xsclient.NetworkRef - - if len(config.NetworkNames) == 0 { - // No network has be specified. Use the management interface - log.Println("No network name given, attempting to use management interface") - pifs, err := c.GetClient().PIF.GetAll(c.GetSessionRef()) - - if err != nil { - ui.Error(fmt.Sprintf("Error getting PIFs: %s", err.Error())) - return multistep.ActionHalt - } - - for _, pif := range pifs { - pif_rec, err := c.GetClient().PIF.GetRecord(c.GetSessionRef(), pif) - - if err != nil { - ui.Error(fmt.Sprintf("Error getting PIF record: %s", err.Error())) - return multistep.ActionHalt - } - - if pif_rec.Management { - network = pif_rec.Network - } - - } - - if string(network) == "" { - ui.Error("Error: couldn't find management network. Aborting.") - return multistep.ActionHalt - } - - log.Printf("Creating VIF on network '%s' on VM '%s'\n", network, instance) - _, err = xscommon.ConnectNetwork(c, network, instance, "0") - - if err != nil { - ui.Error(fmt.Sprintf("Failed to create VIF with error: %v", err)) - return multistep.ActionHalt - } - - } else { - log.Printf("Using provided network names: %v\n", config.NetworkNames) - // Look up each network by it's name label - for i, networkNameLabel := range config.NetworkNames { - networks, err := c.GetClient().Network.GetByNameLabel(c.GetSessionRef(), networkNameLabel) - - if err != nil { - ui.Error(fmt.Sprintf("Error occured getting Network by name-label: %s", err.Error())) - return multistep.ActionHalt - } - - switch { - case len(networks) == 0: - ui.Error(fmt.Sprintf("Couldn't find a network with the specified name-label '%s'. Aborting.", networkNameLabel)) - return multistep.ActionHalt - case len(networks) > 1: - ui.Error(fmt.Sprintf("Found more than one network with the name '%s'. The name must be unique. Aborting.", networkNameLabel)) - return multistep.ActionHalt - } - - //we need the VIF index string - vifIndexString := fmt.Sprintf("%d", i) - _, err = xscommon.ConnectNetwork(c, networks[0], instance, vifIndexString) - - if err != nil { - ui.Say(fmt.Sprintf("Failed to connect VIF with error: %v", err.Error())) - } - } - } - - instanceId, err := c.GetClient().VM.GetUUID(c.GetSessionRef(), instance) - if err != nil { - ui.Error(fmt.Sprintf("Unable to get VM UUID: %s", err.Error())) - return multistep.ActionHalt - } - - state.Put("instance_uuid", instanceId) - ui.Say(fmt.Sprintf("Created instance '%s'", instanceId)) - - return multistep.ActionContinue -} - -func (self *stepCreateFromTemplate) Cleanup(state multistep.StateBag) { - config := state.Get("config").(xscommon.Config) - if config.ShouldKeepVM(state) { - return - } - - ui := state.Get("ui").(packer.Ui) - c := state.Get("client").(*xscommon.Connection) - - if self.instance != nil { - ui.Say("Destroying VM") - _ = c.GetClient().VM.HardShutdown(c.GetSessionRef(), *self.instance) // redundant, just in case - err := c.GetClient().VM.Destroy(c.GetSessionRef(), *self.instance) - if err != nil { - ui.Error(err.Error()) - } - } -} From 5c090071a94f197c2f69cd9d2c50eb35de10512d Mon Sep 17 00:00:00 2001 From: Heinrich Kruger Date: Thu, 26 May 2022 17:28:05 +0100 Subject: [PATCH 32/35] Allow tagging VMs (cherry picked from commit 4200795cf05ad6dcf3ad3b8c1a368fae053c922b) --- builder/xenserver/common/client.go | 11 +++++++++++ builder/xenserver/common/common_config.go | 1 + builder/xenserver/common/config.go | 1 + builder/xenserver/common/step_create_instance.go | 6 ++++++ builder/xenserver/xva/step_import_instance.go | 6 ++++++ 5 files changed, 25 insertions(+) diff --git a/builder/xenserver/common/client.go b/builder/xenserver/common/client.go index 6341986..c3abff3 100644 --- a/builder/xenserver/common/client.go +++ b/builder/xenserver/common/client.go @@ -624,6 +624,17 @@ func ConnectNetwork(c *Connection, networkRef xenapi.NetworkRef, vmRef xenapi.VM return &vif, nil } +func AddVMTags(c *Connection, vmRef xenapi.VMRef, tags []string) error { + for _, tag := range tags { + log.Printf("Adding tag %s to VM %s\n", tag, vmRef) + err := c.GetClient().VM.AddTags(c.session, vmRef, tag) + if err != nil { + return err + } + } + return nil +} + // Setters func (self *VM) SetIsATemplate(is_a_template bool) (err error) { diff --git a/builder/xenserver/common/common_config.go b/builder/xenserver/common/common_config.go index bf63ae2..a8062d5 100644 --- a/builder/xenserver/common/common_config.go +++ b/builder/xenserver/common/common_config.go @@ -24,6 +24,7 @@ type CommonConfig struct { FloppyFiles []string `mapstructure:"floppy_files"` NetworkNames []string `mapstructure:"network_names"` ExportNetworkNames []string `mapstructure:"export_network_names"` + VMTags []string `mapstructure:"vm_tags"` HostPortMin uint `mapstructure:"host_port_min"` HostPortMax uint `mapstructure:"host_port_max"` diff --git a/builder/xenserver/common/config.go b/builder/xenserver/common/config.go index fdd31b5..67c7f18 100644 --- a/builder/xenserver/common/config.go +++ b/builder/xenserver/common/config.go @@ -20,6 +20,7 @@ type Config struct { DiskSize uint `mapstructure:"disk_size"` CloneTemplate string `mapstructure:"clone_template"` VMOtherConfig map[string]string `mapstructure:"vm_other_config"` + VMTags []string `mapstructure:"vm_tags"` ISOChecksum string `mapstructure:"iso_checksum"` ISOUrls []string `mapstructure:"iso_urls"` diff --git a/builder/xenserver/common/step_create_instance.go b/builder/xenserver/common/step_create_instance.go index 7ceba97..54aede4 100644 --- a/builder/xenserver/common/step_create_instance.go +++ b/builder/xenserver/common/step_create_instance.go @@ -216,6 +216,12 @@ func (self *StepCreateInstance) Run(ctx context.Context, state multistep.StateBa } } + err = AddVMTags(c, instance, config.VMTags) + if err != nil { + ui.Error(fmt.Sprintf("Failed to add tags: %s", err.Error())) + return multistep.ActionHalt + } + instanceId, err := c.GetClient().VM.GetUUID(c.GetSessionRef(), instance) if err != nil { ui.Error(fmt.Sprintf("Unable to get VM UUID: %s", err.Error())) diff --git a/builder/xenserver/xva/step_import_instance.go b/builder/xenserver/xva/step_import_instance.go index ecc53a8..d7c314e 100644 --- a/builder/xenserver/xva/step_import_instance.go +++ b/builder/xenserver/xva/step_import_instance.go @@ -86,6 +86,12 @@ func (self *stepImportInstance) Run(ctx context.Context, state multistep.StateBa return multistep.ActionHalt } + err = xscommon.AddVMTags(c, instance, config.VMTags) + if err != nil { + ui.Error(fmt.Sprintf("Failed to add tags: %s", err.Error())) + return multistep.ActionHalt + } + ui.Say(fmt.Sprintf("Imported instance '%s'", instanceId)) return multistep.ActionContinue From ea70f903c79e6d9a88694aa41eb6a28ffeaaa64d Mon Sep 17 00:00:00 2001 From: Heinrich Kruger Date: Mon, 30 May 2022 10:13:42 +0100 Subject: [PATCH 33/35] Update docs (cherry picked from commit 2961af413e5c371c2501f5e09112a581022e6438) --- docs/builders/iso/xenserver-iso.html.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/builders/iso/xenserver-iso.html.markdown b/docs/builders/iso/xenserver-iso.html.markdown index c452add..d8638c0 100644 --- a/docs/builders/iso/xenserver-iso.html.markdown +++ b/docs/builders/iso/xenserver-iso.html.markdown @@ -207,6 +207,8 @@ each category, the available options are alphabetized and described. * `vm_memory` (integer) - The size, in megabytes, of the amount of memory to allocate for the VM. By default, this is 1024 (1 GB). +* `vm_tags` (array of strings) - A list of tags to add to the VM + ## Differences with other Packer builders Currently the XenServer builder has some quirks when compared with other Packer builders. From de1a62d88cc98034f5199b694e451323b4ef66d6 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Sat, 15 Apr 2023 15:47:56 -0700 Subject: [PATCH 34/35] Update config.hcl2spec.go with go generate --- builder/xenserver/common/config.hcl2spec.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/builder/xenserver/common/config.hcl2spec.go b/builder/xenserver/common/config.hcl2spec.go index 9b3fcb7..288c308 100644 --- a/builder/xenserver/common/config.hcl2spec.go +++ b/builder/xenserver/common/config.hcl2spec.go @@ -28,6 +28,7 @@ type FlatConfig struct { FloppyFiles []string `mapstructure:"floppy_files" cty:"floppy_files" hcl:"floppy_files"` NetworkNames []string `mapstructure:"network_names" cty:"network_names" hcl:"network_names"` ExportNetworkNames []string `mapstructure:"export_network_names" cty:"export_network_names" hcl:"export_network_names"` + VMTags []string `mapstructure:"vm_tags" cty:"vm_tags" hcl:"vm_tags"` HostPortMin *uint `mapstructure:"host_port_min" cty:"host_port_min" hcl:"host_port_min"` HostPortMax *uint `mapstructure:"host_port_max" cty:"host_port_max" hcl:"host_port_max"` BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"` @@ -140,6 +141,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "floppy_files": &hcldec.AttrSpec{Name: "floppy_files", Type: cty.List(cty.String), Required: false}, "network_names": &hcldec.AttrSpec{Name: "network_names", Type: cty.List(cty.String), Required: false}, "export_network_names": &hcldec.AttrSpec{Name: "export_network_names", Type: cty.List(cty.String), Required: false}, + "vm_tags": &hcldec.AttrSpec{Name: "vm_tags", Type: cty.List(cty.String), Required: false}, "host_port_min": &hcldec.AttrSpec{Name: "host_port_min", Type: cty.Number, Required: false}, "host_port_max": &hcldec.AttrSpec{Name: "host_port_max", Type: cty.Number, Required: false}, "boot_command": &hcldec.AttrSpec{Name: "boot_command", Type: cty.List(cty.String), Required: false}, From bea09bb3ed27aa2cad29e130b1849649646fd927 Mon Sep 17 00:00:00 2001 From: Dom Del Nano Date: Sat, 15 Apr 2023 16:15:03 -0700 Subject: [PATCH 35/35] Add depndabot and ci job for running go tests. Ensure go versions are consistent --- .github/dependabot.yml | 6 ++++++ .github/workflows/go-test.yml | 24 ++++++++++++++++++++++++ .github/workflows/release.yml | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/go-test.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..2fa7d77 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "gomod" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "daily" diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml new file mode 100644 index 0000000..88c1220 --- /dev/null +++ b/.github/workflows/go-test.yml @@ -0,0 +1,24 @@ +name: go-test +on: + push: + branches: + - 'main' + pull_request: + +permissions: + contents: read + +jobs: + go-tests: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Unshallow + run: git fetch --prune --unshallow + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.16 + - name: Run go tests + run: go test -race -count 1 ./... -timeout=3m diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2dfde89..5f1061c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.17 + go-version: 1.16 - name: Describe plugin id: plugin_describe run: echo "::set-output name=api_version::$(go run . describe | jq -r '.api_version')"