Compare commits

...

132 Commits

Author SHA1 Message Date
Dom Delnano
756f4d7e1a
Merge pull request #141 from ddelnano/ddelnano/fix-gob-export-fields-issue
Fix issues related to packer-plugin-sdk#187
2024-06-14 07:29:08 -04:00
Dom Del Nano
4894eca5d3 Use packer-sdc fix to address go-cty issues
Signed-off-by: Dom Del Nano <ddelnano@gmail.com>
2024-06-14 04:27:51 -07:00
Dom Delnano
d111a01612
Merge pull request #139 from ddelnano/dependabot/go_modules/golang.org/x/crypto-0.24.0
Bump golang.org/x/crypto from 0.21.0 to 0.24.0
2024-06-11 16:40:31 -07:00
dependabot[bot]
fc6694679c
Bump golang.org/x/crypto from 0.21.0 to 0.24.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.21.0 to 0.24.0.
- [Commits](https://github.com/golang/crypto/compare/v0.21.0...v0.24.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-11 07:05:56 +00:00
Dom Delnano
36658a7875
Merge pull request #126 from ddelnano/dependabot/go_modules/github.com/hashicorp/hcl/v2-2.20.1
Bump github.com/hashicorp/hcl/v2 from 2.12.0 to 2.20.1
2024-06-10 07:13:48 -07:00
dependabot[bot]
deba45ef3a
Bump github.com/hashicorp/hcl/v2 from 2.12.0 to 2.20.1
Bumps [github.com/hashicorp/hcl/v2](https://github.com/hashicorp/hcl) from 2.12.0 to 2.20.1.
- [Release notes](https://github.com/hashicorp/hcl/releases)
- [Changelog](https://github.com/hashicorp/hcl/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/hcl/compare/v2.12.0...v2.20.1)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/hcl/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-10 14:05:46 +00:00
Dom Delnano
1e9c3eb66a
Merge pull request #124 from ddelnano/dependabot/go_modules/google.golang.org/protobuf-1.33.0
Bump google.golang.org/protobuf from 1.30.0 to 1.33.0
2024-06-10 07:03:58 -07:00
Dom Delnano
7077d1e374
Merge pull request #125 from ddelnano/dependabot/go_modules/github.com/zclconf/go-cty-1.14.4
Bump github.com/zclconf/go-cty from 1.10.0 to 1.14.4
2024-06-10 07:03:42 -07:00
Dom Delnano
54738803d5
Merge pull request #129 from melck/feat-vnc-debug
[FEATURE] Disable exclusive VNC connection when packer in debug mode
2024-06-10 07:02:36 -07:00
Dom Delnano
0ff8fa1e77
Merge pull request #132 from ddelnano/dependabot/go_modules/golang.org/x/net-0.23.0
Bump golang.org/x/net from 0.21.0 to 0.23.0
2024-06-04 23:28:15 -07:00
Dom Del Nano
4b07607b11 Validate .goreleaser.yml file with 'goreleaser check'
Signed-off-by: Dom Del Nano <ddelnano@gmail.com>
2024-06-04 23:20:13 -07:00
Dom Del Nano
bf1383d1e8 Use packer-plugin-skaffolding goreleaser action version
Signed-off-by: Dom Del Nano <ddelnano@gmail.com>
2024-06-04 23:15:17 -07:00
Dom Del Nano
13c2a1d78a Replace deprecated --rm-dist goreleaser flag with --clean 2024-06-04 23:04:25 -07:00
Dom Delnano
2a36fae810
Merge pull request #137 from ddelnano/ddelnano/ensure-version-is-set-via-linker-on-releases
Fix plugin installation on 1.11.0 and later by fixing release version detection
2024-06-04 22:57:01 -07:00
Dom Del Nano
c411df4b02 Use correct version package from the main package
Signed-off-by: Dom Del Nano <ddelnano@gmail.com>
2024-06-04 22:54:42 -07:00
Dom Del Nano
cc03e4a10c Ensure version package exists and matches existing linker variable on release
Signed-off-by: Dom Del Nano <ddelnano@gmail.com>
2024-06-04 22:46:35 -07:00
dependabot[bot]
7147cb4592
Bump golang.org/x/net from 0.21.0 to 0.23.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.21.0 to 0.23.0.
- [Commits](https://github.com/golang/net/compare/v0.21.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-19 13:13:36 +00:00
Melchior NOGUES
1b20fbac99
Disable exclusive VNC connection when packer in debug mode 2024-04-10 14:00:36 +02:00
dependabot[bot]
6c9ee9dc94
Bump github.com/zclconf/go-cty from 1.10.0 to 1.14.4
Bumps [github.com/zclconf/go-cty](https://github.com/zclconf/go-cty) from 1.10.0 to 1.14.4.
- [Release notes](https://github.com/zclconf/go-cty/releases)
- [Changelog](https://github.com/zclconf/go-cty/blob/main/CHANGELOG.md)
- [Commits](https://github.com/zclconf/go-cty/compare/v1.10.0...v1.14.4)

---
updated-dependencies:
- dependency-name: github.com/zclconf/go-cty
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-21 07:23:16 +00:00
dependabot[bot]
b38a3b67bc
Bump google.golang.org/protobuf from 1.30.0 to 1.33.0
Bumps google.golang.org/protobuf from 1.30.0 to 1.33.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-13 22:51:32 +00:00
Dom Delnano
a776a46e1e
Merge pull request #122 from ddelnano/dependabot/go_modules/golang.org/x/crypto-0.21.0
Bump golang.org/x/crypto from 0.19.0 to 0.21.0
2024-03-05 21:48:52 -08:00
dependabot[bot]
d11786a294
Bump golang.org/x/crypto from 0.19.0 to 0.21.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.19.0 to 0.21.0.
- [Commits](https://github.com/golang/crypto/compare/v0.19.0...v0.21.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-06 05:46:40 +00:00
Dom Delnano
7a9e710071
Merge pull request #123 from ddelnano/upgrade-go-1-20
Upgrade go to 1.20 to reflect latest packer-plugins-sdk go version an…
2024-03-05 21:44:08 -08:00
Dom Del Nano
88e56ca729 Upgrade go to 1.20 to reflect latest packer-plugins-sdk go version and unblock gomod upgrades
Signed-off-by: Dom Del Nano <ddelnano@gmail.com>
2024-03-05 21:35:34 -08:00
Dom Delnano
81c1ea03ee
Merge pull request #118 from ddelnano/dependabot/go_modules/golang.org/x/crypto-0.19.0
Bump golang.org/x/crypto from 0.18.0 to 0.19.0
2024-02-08 06:33:00 -08:00
dependabot[bot]
5a826dfbce
Bump golang.org/x/crypto from 0.18.0 to 0.19.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.18.0 to 0.19.0.
- [Commits](https://github.com/golang/crypto/compare/v0.18.0...v0.19.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-08 07:30:09 +00:00
Dom Del Nano
bc21b3cfac
Merge pull request #92 from mmahnic/remote_ssh_port
Add remote_ssh_port packer option
2024-01-17 06:52:46 -08:00
Marko Mahnič
e62c1a1373 Apply HostSshPort in ssh port forwarding 2024-01-17 06:49:43 -08:00
Marko Mahnič
30498d8258 Add a new setting HostSshPort
A XenServer host may accept SSH connections on port other than
22. This commit adds a packer option 'remote_ssh_port' to connect
to a custom port.
2024-01-17 06:49:43 -08:00
Dom Del Nano
e460d5bd58
Merge pull request #114 from ddelnano/dependabot/go_modules/golang.org/x/crypto-0.18.0
Bump golang.org/x/crypto from 0.17.0 to 0.18.0
2024-01-17 06:45:54 -08:00
Dom Del Nano
eac40a8976
Merge pull request #116 from AtaxyaNetwork/main
Add documentation for disk_name
2024-01-17 06:45:20 -08:00
Cécile MORANGE
5dc6c311f0 Add documentation for disk_name 2024-01-17 11:52:36 +01:00
dependabot[bot]
af169dfed0
Bump golang.org/x/crypto from 0.17.0 to 0.18.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.17.0 to 0.18.0.
- [Commits](https://github.com/golang/crypto/compare/v0.17.0...v0.18.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-17 07:34:11 +00:00
Dom Del Nano
3a92c96509
Merge pull request #103 from ddelnano/dependabot/go_modules/golang.org/x/net-0.17.0
Bump golang.org/x/net from 0.10.0 to 0.17.0
2024-01-16 12:05:11 -08:00
dependabot[bot]
ac530c5628
Bump golang.org/x/net from 0.10.0 to 0.17.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.10.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.10.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-16 20:03:21 +00:00
Dom Del Nano
dc743791d9
Merge pull request #113 from ddelnano/dependabot/go_modules/golang.org/x/crypto-0.17.0
Bump golang.org/x/crypto from 0.11.0 to 0.17.0
2024-01-16 12:00:38 -08:00
dependabot[bot]
3b40f051bb
Bump golang.org/x/crypto from 0.11.0 to 0.17.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.11.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.11.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-16 19:55:03 +00:00
Dom Del Nano
8f73b0d338
Merge pull request #106 from ddelnano/dependabot/go_modules/google.golang.org/grpc-1.56.3
Bump google.golang.org/grpc from 1.40.0 to 1.56.3
2024-01-16 11:52:52 -08:00
Dom Del Nano
6bf1ad468c
Merge pull request #111 from Shackelford-Arden/compile-notes
Compile Notes / General Documentation
2024-01-16 11:51:31 -08:00
Dom Del Nano
e64dd4897f
Merge pull request #112 from AtaxyaNetwork/main
Allow user to set VDI name
2024-01-16 11:44:28 -08:00
Cécile MORANGE
23fdf2286d Allow user to set VDI name 2024-01-16 17:29:22 +01:00
Arden Shackelford
3a07cb9e0a
Adding specific compile notes for Windows; 2024-01-09 20:53:25 -06:00
Arden Shackelford
84a3a2389a
Adding a few more config items to docs; Adjusting compile script to be consistent; 2024-01-09 20:33:52 -06:00
dependabot[bot]
5194dec899
Bump google.golang.org/grpc from 1.40.0 to 1.56.3
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.40.0 to 1.56.3.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.40.0...v1.56.3)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-25 21:58:04 +00:00
Dom Del Nano
9d57d14f3e
Merge pull request #94 from AtaxyaNetwork/main
Allow user to have a template or a full VM
2023-09-25 20:04:12 -07:00
Cécile MORANGE
a9e5f30a55 Converting to template is now the default behavior + add docs
Signed-off-by: Cécile MORANGE <contact@ataxya.net>
2023-09-04 18:25:16 +02:00
Cécile MORANGE
4438cdce28
remove file 2023-08-07 12:13:01 +02:00
Cécile MORANGE
757529e20b
typo 2023-08-07 12:12:33 +02:00
Cécile MORANGE
8fe24bddcd
Allow having a template or a full VM 2023-08-07 11:56:14 +02:00
Dom Del Nano
6af6320f8a
Merge pull request #86 from ddelnano/ddelnano/ugrade-go-1-17
Update go to 1.17 and upgrade some dependencies
2023-07-12 00:06:35 -07:00
Dom Del Nano
3cd902b9b6 Upgrade go to 1.17 and update deps 2023-07-07 23:10:14 -07:00
Dom Del Nano
2379ca3afc
Merge pull request #85 from ddelnano/ddelnano/add-github-release-note-autogeneration
Add configuration for github release generation
2023-07-07 08:18:20 -07:00
Dom Del Nano
58fc1930bc Allow goreleaser to publish the github release and have it run go tests 2023-07-07 08:17:23 -07:00
Dom Del Nano
02280e60e4 Add configuration for github release generation 2023-07-07 08:13:27 -07:00
Dom Del Nano
524ef18847
Merge pull request #84 from ddelnano/ddelnano/allow-not-specifying-xs-tools
Allow users to specify if xs tools should be managed by packer or not
2023-07-07 08:08:21 -07:00
Dom Del Nano
dac47c649b Fix tests
Signed-off-by: Dom Del Nano <ddelnano@gmail.com>
2023-07-07 07:59:05 -07:00
Cécile MORANGE
8ef30c26e4
remove ToolsIsoName 2023-07-07 09:08:24 +02:00
Cécile MORANGE
609ef7317e
remove packer.json 2023-07-07 09:00:17 +02:00
Cécile MORANGE
7841481ee0
add tools_iso_name in the doc 2023-06-21 17:21:22 +02:00
Cécile MORANGE
0b9d7be27e
don't use tools by default 2023-06-21 17:16:18 +02:00
Dom Del Nano
767809c80f
Merge pull request #78 from AtaxyaNetwork/patch-1
Add xva_compressed to the documentation
2023-05-15 07:15:40 -07:00
Cécile Morange
785b62ad24
Update xenserver-iso.html.markdown
Add xva_compressed to documentation
2023-05-15 09:06:08 +02:00
Dom Del Nano
5759ecea09
Merge pull request #70 from ddelnano/include-firmware-in-documentation
Add the firmware argument to the builder documentation since it was missing
2023-04-24 05:50:18 -07:00
Dom Del Nano
4646bde57c Add the firmware argument to the builder documentation since it was missing 2023-04-23 05:46:20 -07:00
Dom Del Nano
a7ec448ce6
Merge pull request #68 from ddelnano/ddelnano/add-dependabot-and-pr-testing
Add dependabot and ci job for running go tests. Ensure go versions are consistent
2023-04-15 16:17:52 -07:00
Dom Del Nano
bea09bb3ed Add depndabot and ci job for running go tests. Ensure go versions are consistent 2023-04-15 16:15:03 -07:00
Dom Del Nano
83b1052bb4
Merge pull request #67 from ddelnano/ddelnano/add-tags-to-vms
Allow support for adding tags to VMs
2023-04-15 16:01:17 -07:00
Dom Del Nano
de1a62d88c Update config.hcl2spec.go with go generate 2023-04-15 16:00:27 -07:00
Heinrich Kruger
ea70f903c7 Update docs
(cherry picked from commit 2961af413e)
2023-04-15 16:00:27 -07:00
Heinrich Kruger
5c090071a9 Allow tagging VMs
(cherry picked from commit 4200795cf0)
2023-04-15 16:00:27 -07:00
Dom Del Nano
f6a317cb41
Merge pull request #66 from ddelnano/ddelnano/sohonetlabs/xva-create-template
Fix XVA builder
2023-04-15 15:59:52 -07:00
Dom Del Nano
2fe14d14ac Update XVA builder to use shared StepCreateInstance step 2023-04-15 15:33:08 -07:00
Dom Del Nano
7c4b652c17 Update StepCreateInstance to accommodate both ISO and XVA builders 2023-04-15 15:32:58 -07:00
Dom Del Nano
461367ad1c Move create instance step to common directory 2023-04-15 14:49:11 -07:00
Heinrich Kruger
0bb70e8957 Update XVA builder to match ISO builder 2023-04-14 21:16:31 -07:00
Heinrich Kruger
17c58e8d24 Enable xva builder to create VM from existing template 2023-04-14 21:16:31 -07:00
Dom Del Nano
de46bb8b2f
Merge pull request #65 from ddelnano/ddelnano/sohonetlabs/iso-sr
Allow ISO Storage repository to fallback to default SR if unspecified
2023-04-14 06:47:05 -07:00
Dom Del Nano
bb64b86619
Merge pull request #64 from ddelnano/revert-63-ddelnano/sohonetlabs/iso-sr
Revert "Allow ISO Storage repository to fallback to default SR if unspecified"
2023-04-14 06:44:58 -07:00
Dom Del Nano
3f0a2186bf
Revert "Allow ISO Storage repository to fallback to default SR if unspecified" 2023-04-14 06:43:21 -07:00
Dom Del Nano
cda48bd66e
Merge pull request #63 from ddelnano/ddelnano/sohonetlabs/iso-sr
Allow ISO Storage repository to fallback to default SR if unspecified
2023-04-14 00:35:25 -07:00
Dom Del Nano
3c5fc29b36 Ensure that SrISOName is no longer a required field 2023-04-14 00:34:32 -07:00
Heinrich Kruger
70fd83e803 Work around XenAPI compatibility issue to get default SR 2023-04-14 00:03:51 -07:00
Heinrich Kruger
d8294d3ccd Use default SR if sr_iso_name is not specified 2023-04-14 00:03:51 -07:00
Heinrich Kruger
ffc0ffb5cd Work around XenAPI compatibility issue to get default SR 2023-04-13 23:27:34 -07:00
Heinrich Kruger
416c734853 Use default SR if sr_iso_name is not specified 2023-04-13 23:27:34 -07:00
Dom Del Nano
b55b096836
Merge pull request #60 from ddelnano/ddelnano/remove_iso_checksum_type_and_fix_tests
Remove iso checksum type and fix tests
2023-04-06 23:28:46 -07:00
Dom Del Nano
6c808da038 Remove remaining usages of iso_checksum_type, fix config.hcl2spec.go generation and re-run it 2023-04-06 23:23:51 -07:00
somerandomqaguy
6b0b4baf2f 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
2023-04-06 23:12:25 -07:00
somerandomqaguy
c49d4ebf12 Capture actual errors from Prepare
Solves TestBuilderPrepare_InvalidKey failing, since we weren't capturing
it's errors before.
2023-04-06 23:12:25 -07:00
somerandomqaguy
880d12c66f Get the tests compiling again.
Looks like the consts got moved into common
2023-04-06 23:12:25 -07:00
Dom Del Nano
9cc7249127
Merge pull request #59 from AtaxyaNetwork/FixIsoSR
s/SrName/SrISOName
2023-04-06 22:48:06 -07:00
AtaxyaNetwork
b4d83eb533 s/SrName/SrISOName
Signed-off-by: AtaxyaNetwork <contact@ataxya.net>
2023-04-06 18:27:24 +02:00
Dom Del Nano
a267698fad
Merge pull request #58 from arnaudcharles/fixing-documentation
Fixing documentation
2023-03-30 23:34:41 -07:00
Arnaud Charles
5d0cff3fc6 Fixing main md links and doc links 2023-03-03 12:57:19 +01:00
Arnaud Charles
479e16a2c1 Fixing main md links and doc links 2023-03-03 12:56:34 +01:00
Arnaud Charles
d15616c1d2 Fixing main md links and doc links 2023-03-03 12:53:23 +01:00
Arnaud Charles
dcb839e131 Fixing main md links and doc links 2023-03-03 12:48:55 +01:00
Dom Del Nano
8c58db3504
Merge pull request #57 from ddelnano/ddelnano/add-dynamic-ubuntu-example
Update ubuntu example to be resilient to upstream minor releases
2023-02-27 21:42:01 -08:00
Dom Del Nano
6eeea7dc64 Use 30 GiB root volume 2023-02-27 21:37:21 -08:00
Dom Del Nano
52cd604a9b Refactor template name to use a map lookup on Ubuntu version 2023-02-27 21:37:07 -08:00
Dom Del Nano
73e173370a Update ubuntu example to be resilient to upstream minor releases 2023-02-27 21:20:11 -08:00
Dom Del Nano
4f90bf5f17
Merge pull request #56 from ddelnano/ddelnano/prevent-iso-from-being-uploaded-each-time
Prevent ISO used in iso builder from being uploaded if it already exists
2023-02-27 07:24:34 -08:00
Dom Del Nano
0ccc53b8b5 Prevent ISO used in iso builder from being uploaded if it already exists 2023-02-26 23:23:28 -08:00
Dom Del Nano
55e3b071e3
Merge pull request #55 from ddelnano/revert-54-ddelnano/update-ubuntu-example-to-be-resilent-to-new-releases
Revert "Update the ubuntu example to be resilient to ISO releases"
2023-02-26 23:05:12 -08:00
Dom Del Nano
752bd52f61
Revert "Update the ubuntu example to be resilient to ISO releases" 2023-02-26 21:09:29 -08:00
Dom Del Nano
f72f00341c
Merge pull request #54 from ddelnano/ddelnano/update-ubuntu-example-to-be-resilent-to-new-releases
Update the ubuntu example to be resilient to ISO releases
2023-02-26 20:06:18 -08:00
Dom Del Nano
69bae007b6 Update the correct README doc with the packer 1.8 requirement 2023-02-26 20:04:39 -08:00
Dom Del Nano
88e52b581f Update the ubuntu example to be resilient to ISO releases 2023-02-26 19:57:21 -08:00
Dom Del Nano
f7a8fa4959 Ensure gpg github action has parameters passed properly
(cherry picked from commit 2b2ba8540d1acfa0884e8db1367b32495bc39259)
2023-01-22 22:43:57 -08:00
Dom Del Nano
e9f55883e3
Merge pull request #52 from ddelnano/fix-release-github-actions-job
Remove hashicorps gpg github action to one that doesn't collide with Github's
2023-01-21 00:24:25 -08:00
Dom Del Nano
4df2465c06 Remove hashicorps gpg github action to one that doesn't collide with GitHub's gpg agent 2023-01-21 00:22:04 -08:00
Dom Del Nano
8a823a13eb Update the ubuntu example to use an available 20.04 iso and proper clone_template default 2023-01-21 00:09:12 -08:00
Dom Del Nano
79c6b508a4
Merge pull request #51 from BryceTech122/master
Fix cloudinit ready template generation
2023-01-21 00:06:16 -08:00
BryceTech122
4b531de0ff add step to remove disks param from other-config 2023-01-12 11:46:10 -07:00
Dom Del Nano
f7de8aace4 Add missing Makefile 2022-06-12 15:43:17 -07:00
Dom Del Nano
1e35a0da41
Merge pull request #41 from ddelnano/upgrade-terraform-sdk-go-version-and-release-process
Upgrade packer-plugin-sdk, go version and release process
2022-06-12 15:26:04 -07:00
Dom Del Nano
88e403f87c Upgrade packer-plugin-sdk to v0.3.0 and update release process and go version accordingly 2022-06-09 21:53:51 -07:00
Dom Del Nano
6fc83b9e4b Add goreleaser config back 2022-06-07 23:44:22 -07:00
Dom Del Nano
7b40fd4424
Merge pull request #39 from mboutet/feature/configurable-firmware
feat: Make firmware configurable
2022-06-07 21:42:53 -07:00
Maxence Boutet
c6147b13c9
feat: Make firmware configurable
I extracted the changes as-is from https://github.com/ddelnano/packer-plugin-xenserver/pull/28.
2022-06-05 11:28:23 -04:00
Dom Del Nano
c5e5a86607
Merge pull request #37 from ddelnano/ddelnano-add-buymeacoffee
Update README.md
2022-03-19 00:09:39 -07:00
Dom Del Nano
38ef07516e
Update README.md 2022-03-19 00:09:17 -07:00
Dom Del Nano
ac90dec7ea Remove unused files 2022-03-03 23:13:24 -08:00
Dom Del Nano
f4a161e806
Merge pull request #33 from liath/fix-xen-tools-ip-resolution
Fix XenServer tools guest IP address resolution
2021-12-18 17:13:44 -08:00
Dom Del Nano
5525b73b73
Merge pull request #32 from liath/more-reliable-cloud-init
More reliable cloud-init startup
2021-12-18 17:13:17 -08:00
John Jones
8b8bd284f5
Add Xen guest utilities to ubuntu user-data example 2021-12-16 15:25:18 -08:00
John Jones
509b6b3c25
Fix XenServer tools guest IP address resolution 2021-12-14 19:00:09 -08:00
John Jones
7a4a1d0b9b
update ubuntu example to use floppy_files for cloud-config 2021-12-14 18:57:22 -08:00
John Jones
d9cb44c847
add example of needed cloud-config 2021-12-14 18:54:13 -08:00
John Jones
aa4ea9d5c8
More reliable cloud-init startup 2021-12-14 18:50:15 -08:00
Dom Del Nano
31683d2758
Merge pull request #31 from ringods/bump-xen-api-client
Small dependency refresh on Xen API client
2021-11-22 19:37:29 -08:00
Ringo De Smet
ac62f77e36
Small dependency refresh on Xen API client
Signed-off-by: Ringo De Smet <ringo@de-smet.name>
2021-11-22 21:17:21 +01:00
37 changed files with 1055 additions and 819 deletions

6
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "gomod" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"

14
.github/release.yml vendored Normal file
View File

@ -0,0 +1,14 @@
changelog:
categories:
- title: Breaking Changes 🛠
labels:
- breaking-change
- title: New Features 🎉
labels:
- enhancement
- title: Bug fixes
labels:
- bug
- title: Other Changes
labels:
- "*"

24
.github/workflows/go-test.yml vendored Normal file
View File

@ -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.20"
- name: Run go tests
run: go test -race -count 1 ./... -timeout=3m

View File

@ -1,12 +1,12 @@
# This GitHub action can publish assets for release when a tag is created. # This GitHub action can publish assets for release when a tag is created.
# Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0). # Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0).
# #
# This uses an action (paultyng/ghaction-import-gpg) that assumes you set your # This uses an action (hashicorp/ghaction-import-gpg) that assumes you set your
# private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE` # private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `GPG_PASSPHRASE`
# secret. If you would rather own your own GPG handling, please fork this action # secret. If you would rather own your own GPG handling, please fork this action
# or use an alternative one for key handling. # or use an alternative one for key handling.
# #
# You will need to pass the `--batch` flag to `gpg` in your signing step # You will need to pass the `--batch` flag to `gpg` in your signing step
# in `goreleaser` to indicate this is being used in a non-interactive mode. # in `goreleaser` to indicate this is being used in a non-interactive mode.
# #
name: release name: release
@ -25,21 +25,21 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: 1.16 go-version: "1.20"
- name: Describe plugin - name: Describe plugin
id: plugin_describe id: plugin_describe
run: echo "::set-output name=api_version::$(go run . describe | jq -r '.api_version')" run: echo "::set-output name=api_version::$(go run . describe | jq -r '.api_version')"
- name: Import GPG key - name: Import GPG key
id: import_gpg id: import_gpg
uses: paultyng/ghaction-import-gpg@v2.1.0 uses: crazy-max/ghaction-import-gpg@v5.0.0
env: with:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
PASSPHRASE: ${{ secrets.PASSPHRASE }} passphrase: ${{ secrets.GPG_PASSPHRASE }}
- name: Run GoReleaser - name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2 uses: goreleaser/goreleaser-action@f82d6c1c344bcacabba2c841718984797f664a6b # v4.2.0
with: with:
version: latest version: latest
args: release --rm-dist args: release --clean
env: env:
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

1
.go-version Normal file
View File

@ -0,0 +1 @@
1.20.11

View File

@ -1,41 +1,36 @@
version: 2
# This is an example goreleaser.yaml file with some sane defaults. # This is an example goreleaser.yaml file with some sane defaults.
# Make sure to check the documentation at http://goreleaser.com # Make sure to check the documentation at http://goreleaser.com
env: env:
- CGO_ENABLED=0 - CGO_ENABLED=0
before: before:
hooks: hooks:
# We strongly recommend running tests to catch any regression before release. - go test ./...
# Even though, this an optional step. # As part of the release doc files are included as a separate deliverable for
# - go test ./... # consumption by Packer.io. To include a separate docs.zip uncomment the following command.
#- make ci-release-docs
# Check plugin compatibility with required version of the Packer SDK
- make plugin-check
builds: builds:
# A separated build to run the packer-plugins-check only once for a linux_amd64 binary # A separated build to run the packer-plugins-check only once for a linux_amd64 binary
- -
id: plugin-check id: plugin-check
mod_timestamp: '{{ .CommitTimestamp }}' mod_timestamp: '{{ .CommitTimestamp }}'
hooks:
post:
# This will check plugin compatibility against latest version of Packer
- cmd: |
go install github.com/hashicorp/packer/cmd/packer-plugins-check@latest &&
packer-plugins-check -load={{ .Name }}
dir: "{{ dir .Path}}"
flags: flags:
- -trimpath #removes all file system paths from the compiled executable - -trimpath #removes all file system paths from the compiled executable
ldflags: ldflags:
- '-s -w -X main.Version={{.Version}} -X main.VersionPrerelease= ' - '-s -w -X {{ .ModulePath }}/version.Version={{.Version}} -X {{ .ModulePath }}/version.VersionPrerelease= '
goos: goos:
- linux - linux
goarch: goarch:
- amd64 - amd64
binary: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' binary: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}'
- -
mod_timestamp: '{{ .CommitTimestamp }}' mod_timestamp: '{{ .CommitTimestamp }}'
flags: flags:
- -trimpath #removes all file system paths from the compiled executable - -trimpath #removes all file system paths from the compiled executable
ldflags: ldflags:
- '-s -w -X main.version={{.Version}} -X main.VersionPrerelease= ' - '-s -w -X {{ .ModulePath }}/version.Version={{.Version}} -X {{ .ModulePath }}/version.VersionPrerelease= '
goos: goos:
- freebsd - freebsd
- windows - windows
@ -51,10 +46,11 @@ builds:
goarch: '386' goarch: '386'
- goos: linux - goos: linux
goarch: amd64 goarch: amd64
binary: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' binary: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}'
archives: archives:
- format: zip - format: zip
files:
- none*
name_template: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' name_template: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}'
checksum: checksum:
name_template: '{{ .ProjectName }}_v{{ .Version }}_SHA256SUMS' name_template: '{{ .ProjectName }}_v{{ .Version }}_SHA256SUMS'
@ -62,7 +58,7 @@ checksum:
signs: signs:
- artifacts: checksum - artifacts: checksum
args: args:
# if you are using this is in a GitHub action or some other automated pipeline, you # if you are using this is in a GitHub action or some other automated pipeline, you
# need to pass the batch flag to indicate its not interactive. # need to pass the batch flag to indicate its not interactive.
- "--batch" - "--batch"
- "--local-user" - "--local-user"
@ -72,7 +68,7 @@ signs:
- "--detach-sign" - "--detach-sign"
- "${artifact}" - "${artifact}"
release: release:
# If you want to manually examine the release before its live, uncomment this line: draft: false
draft: true
changelog: changelog:
skip: true disable: true

View File

@ -1,7 +0,0 @@
language: go
go:
# Test with the first and the latest go release - to ensure compatibility
- 1.6
- tip
script:
- gofmtresult=$(gofmt -s -l .); if [[ -n $gofmtresult ]]; then echo -e "Please run \"gofmt -s -w .\" before committing for the below:\n$gofmtresult"; false; fi

34
GNUmakefile Normal file
View File

@ -0,0 +1,34 @@
NAME=xenserver
BINARY=packer-plugin-${NAME}
COUNT?=1
TEST?=$(shell go list ./...)
HASHICORP_PACKER_PLUGIN_SDK_VERSION?=$(shell go list -m github.com/hashicorp/packer-plugin-sdk | cut -d " " -f2)
.PHONY: dev
build:
@go build -o ${BINARY}
dev: build
@mkdir -p ~/.packer.d/plugins/
@mv ${BINARY} ~/.packer.d/plugins/${BINARY}
test:
@go test -race -count $(COUNT) $(TEST) -timeout=3m
install-packer-sdc: ## Install packer sofware development command
@go install github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc@${HASHICORP_PACKER_PLUGIN_SDK_VERSION}
ci-release-docs: install-packer-sdc
@packer-sdc renderdocs -src docs -partials docs-partials/ -dst docs/
@/bin/sh -c "[ -d docs ] && zip -r docs.zip docs/"
plugin-check: install-packer-sdc build
@packer-sdc plugin-check ${BINARY}
testacc: dev
@PACKER_ACC=1 go test -count $(COUNT) -v $(TEST) -timeout=120m
generate: install-packer-sdc
@go generate ./...

View File

@ -2,7 +2,7 @@
This builder plugin extends packer.io to support building images for XenServer. This builder plugin extends packer.io to support building images for XenServer.
This is a fork of the original builder since the original project was abandoned and no longer compilied with recent versions of Go or worked with Xenserver 7.6 and later. This is a fork of the original builder since the original project was abandoned and no longer compiled with recent versions of Go or worked with Xenserver 7.6 and later.
It improves the original project in the following ways: It improves the original project in the following ways:
1. Developed alongside the [Xenorchestra terraform provider](https://github.com/ddelnano/terraform-provider-xenorchestra) to ensure the hashicorp ecosystem is interoperable. 1. Developed alongside the [Xenorchestra terraform provider](https://github.com/ddelnano/terraform-provider-xenorchestra) to ensure the hashicorp ecosystem is interoperable.
@ -13,6 +13,7 @@ It improves the original project in the following ways:
At the time of this writing the packer builder has been verified to work with Xenserver 7.6 and can launch VMs with the packer output through the xenorchestra terraform provider. At the time of this writing the packer builder has been verified to work with Xenserver 7.6 and can launch VMs with the packer output through the xenorchestra terraform provider.
The following list contains things that are incomplete but will be worked on soon: The following list contains things that are incomplete but will be worked on soon:
- The documentation is still in an inconsistent state with upstream - The documentation is still in an inconsistent state with upstream
- XVA builder is untested - XVA builder is untested
- Lots of dead code to remove from upstream - Lots of dead code to remove from upstream
@ -24,7 +25,7 @@ The packer builder can be installed via `packer init` as long as the packer temp
packer { packer {
required_plugins { required_plugins {
xenserver= { xenserver= {
version = ">= v0.3.2" version = ">= v0.6.0"
source = "github.com/ddelnano/xenserver" source = "github.com/ddelnano/xenserver"
} }
} }
@ -44,26 +45,43 @@ If you are using an older version of packer or are still using json templates yo
### Dependencies ### Dependencies
* Packer >= v1.7.1 (https://packer.io) * Packer >= v1.7.1 (https://packer.io)
* XenServer / Citrix Hypervisor > 7.6 * XenServer / Citrix Hypervisor > 7.6
* Golang 1.16 * Golang 1.20
## Compile the plugin ## Compile the plugin
Once you have installed Packer, you must compile this plugin and install the Once you have installed Packer, you must compile this plugin and install the
resulting binary. resulting binary.
```shell Documentation for Plugins directory: [Official Docs](https://developer.hashicorp.com/packer/docs/configure#packer-s-plugin-directory)
$ go build -o packer-plugin-xenserver
# Add the builder to the location packer expects it to be installed in ### Linux/MacOS
$ mkdir -p ~/.packer.d/plugins/
$ cp builder-xenserver-iso ~/.packer.d/plugins/packer-builder-xenserver-iso ```shell
go build -o packer-plugin-xenserver
# Add the plugin to the location packer expects it to be installed in
mkdir -p ~/.packer.d/plugins/
cp packer-plugin-xenserver ~/.packer.d/plugins
```
### Windows (Powershell)
```powershell
go build -o packer-plugin-xenserver
mkdir "%APPDATA%\packer.d\plugins"
cp packer-plugin-xenserver "%APPDATA%\packer.d\plugins"
``` ```
# Documentation # Documentation
For complete documentation on configuration commands, see [the 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 ## Support
You can discuss any issues you have or feature requests in [Discord](https://discord.gg/ZpNq8ez). You can discuss any issues you have or feature requests in [Discord](https://discord.gg/ZpNq8ez).
If you'd like to support my effort on the project, please consider buying me a coffee
[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/ddelnano)

View File

@ -624,6 +624,17 @@ func ConnectNetwork(c *Connection, networkRef xenapi.NetworkRef, vmRef xenapi.VM
return &vif, nil 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 // Setters
func (self *VM) SetIsATemplate(is_a_template bool) (err error) { func (self *VM) SetIsATemplate(is_a_template bool) (err error) {

View File

@ -13,17 +13,19 @@ import (
) )
type CommonConfig struct { type CommonConfig struct {
Username string `mapstructure:"remote_username"` Username string `mapstructure:"remote_username"`
Password string `mapstructure:"remote_password"` Password string `mapstructure:"remote_password"`
HostIp string `mapstructure:"remote_host"` HostIp string `mapstructure:"remote_host"`
HostSshPort uint `mapstructure:"remote_ssh_port"`
VMName string `mapstructure:"vm_name"` VMName string `mapstructure:"vm_name"`
VMDescription string `mapstructure:"vm_description"` VMDescription string `mapstructure:"vm_description"`
SrName string `mapstructure:"sr_name"` SrName string `mapstructure:"sr_name"`
SrISOName string `mapstructure:"sr_iso_name"` SrISOName string `mapstructure:"sr_iso_name" required:"false"`
FloppyFiles []string `mapstructure:"floppy_files"` FloppyFiles []string `mapstructure:"floppy_files"`
NetworkNames []string `mapstructure:"network_names"` NetworkNames []string `mapstructure:"network_names"`
ExportNetworkNames []string `mapstructure:"export_network_names"` ExportNetworkNames []string `mapstructure:"export_network_names"`
VMTags []string `mapstructure:"vm_tags"`
HostPortMin uint `mapstructure:"host_port_min"` HostPortMin uint `mapstructure:"host_port_min"`
HostPortMax uint `mapstructure:"host_port_max"` HostPortMax uint `mapstructure:"host_port_max"`
@ -63,6 +65,10 @@ func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig
// Set default values // Set default values
if c.HostSshPort == 0 {
c.HostSshPort = 22
}
if c.HostPortMin == 0 { if c.HostPortMin == 0 {
c.HostPortMin = 5900 c.HostPortMin = 5900
} }
@ -75,10 +81,6 @@ func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig
c.RawBootWait = "5s" c.RawBootWait = "5s"
} }
if c.ToolsIsoName == "" {
c.ToolsIsoName = "xs-tools.iso"
}
if c.HTTPPortMin == 0 { if c.HTTPPortMin == 0 {
c.HTTPPortMin = 8000 c.HTTPPortMin = 8000
} }
@ -223,29 +225,11 @@ func (c CommonConfig) ShouldKeepVM(state multistep.StateBag) bool {
} }
func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRef, error) { func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRef, error) {
var srRef xenapi.SRRef
if config.SrName == "" { if config.SrName == "" {
hostRef, err := c.GetClient().Session.GetThisHost(c.session, c.session) return getDefaultSR(c)
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 { } else {
var srRef xenapi.SRRef
// Use the provided name label to find the SR to use // 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.SrName)
@ -267,11 +251,11 @@ func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRef, error) {
func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) { func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) {
var srRef xenapi.SRRef var srRef xenapi.SRRef
if config.SrISOName == "" { if config.SrISOName == "" {
return srRef, errors.New("sr_iso_name must be specified in the packer configuration") return getDefaultSR(c)
} else { } else {
// Use the provided name label to find the SR to use // 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 { if err != nil {
return srRef, err return srRef, err
@ -279,11 +263,42 @@ func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) {
switch { switch {
case len(srs) == 0: 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: 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 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))
}

View File

@ -1,4 +1,4 @@
//go:generate mapstructure-to-hcl2 -type Config //go:generate packer-sdc mapstructure-to-hcl2 -type Config
package common package common
import ( import (
@ -17,15 +17,16 @@ type Config struct {
VCPUsMax uint `mapstructure:"vcpus_max"` VCPUsMax uint `mapstructure:"vcpus_max"`
VCPUsAtStartup uint `mapstructure:"vcpus_atstartup"` VCPUsAtStartup uint `mapstructure:"vcpus_atstartup"`
VMMemory uint `mapstructure:"vm_memory"` VMMemory uint `mapstructure:"vm_memory"`
DiskName string `mapstructure:"disk_name"`
DiskSize uint `mapstructure:"disk_size"` DiskSize uint `mapstructure:"disk_size"`
CloneTemplate string `mapstructure:"clone_template"` CloneTemplate string `mapstructure:"clone_template"`
VMOtherConfig map[string]string `mapstructure:"vm_other_config"` VMOtherConfig map[string]string `mapstructure:"vm_other_config"`
VMTags []string `mapstructure:"vm_tags"`
ISOChecksum string `mapstructure:"iso_checksum"` ISOChecksum string `mapstructure:"iso_checksum"`
ISOChecksumType string `mapstructure:"iso_checksum_type"` ISOUrls []string `mapstructure:"iso_urls"`
ISOUrls []string `mapstructure:"iso_urls"` ISOUrl string `mapstructure:"iso_url"`
ISOUrl string `mapstructure:"iso_url"` ISOName string `mapstructure:"iso_name"`
ISOName string `mapstructure:"iso_name"`
PlatformArgs map[string]string `mapstructure:"platform_args"` PlatformArgs map[string]string `mapstructure:"platform_args"`
@ -33,6 +34,9 @@ type Config struct {
InstallTimeout time.Duration `` InstallTimeout time.Duration ``
SourcePath string `mapstructure:"source_path"` SourcePath string `mapstructure:"source_path"`
Firmware string `mapstructure:"firmware"`
SkipSetTemplate bool `mapstructure:"skip_set_template"`
ctx interpolate.Context ctx interpolate.Context
} }

View File

@ -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 package common
@ -12,6 +12,7 @@ import (
type FlatConfig struct { type FlatConfig struct {
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"` 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"` 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"` PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"` 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"` PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
@ -20,13 +21,15 @@ type FlatConfig struct {
Username *string `mapstructure:"remote_username" cty:"remote_username" hcl:"remote_username"` Username *string `mapstructure:"remote_username" cty:"remote_username" hcl:"remote_username"`
Password *string `mapstructure:"remote_password" cty:"remote_password" hcl:"remote_password"` Password *string `mapstructure:"remote_password" cty:"remote_password" hcl:"remote_password"`
HostIp *string `mapstructure:"remote_host" cty:"remote_host" hcl:"remote_host"` HostIp *string `mapstructure:"remote_host" cty:"remote_host" hcl:"remote_host"`
HostSshPort *uint `mapstructure:"remote_ssh_port" cty:"remote_ssh_port" hcl:"remote_ssh_port"`
VMName *string `mapstructure:"vm_name" cty:"vm_name" hcl:"vm_name"` VMName *string `mapstructure:"vm_name" cty:"vm_name" hcl:"vm_name"`
VMDescription *string `mapstructure:"vm_description" cty:"vm_description" hcl:"vm_description"` VMDescription *string `mapstructure:"vm_description" cty:"vm_description" hcl:"vm_description"`
SrName *string `mapstructure:"sr_name" cty:"sr_name" hcl:"sr_name"` 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"` FloppyFiles []string `mapstructure:"floppy_files" cty:"floppy_files" hcl:"floppy_files"`
NetworkNames []string `mapstructure:"network_names" cty:"network_names" hcl:"network_names"` 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"` 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"` 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"` 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"` BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"`
@ -96,17 +99,19 @@ type FlatConfig struct {
VCPUsMax *uint `mapstructure:"vcpus_max" cty:"vcpus_max" hcl:"vcpus_max"` VCPUsMax *uint `mapstructure:"vcpus_max" cty:"vcpus_max" hcl:"vcpus_max"`
VCPUsAtStartup *uint `mapstructure:"vcpus_atstartup" cty:"vcpus_atstartup" hcl:"vcpus_atstartup"` VCPUsAtStartup *uint `mapstructure:"vcpus_atstartup" cty:"vcpus_atstartup" hcl:"vcpus_atstartup"`
VMMemory *uint `mapstructure:"vm_memory" cty:"vm_memory" hcl:"vm_memory"` VMMemory *uint `mapstructure:"vm_memory" cty:"vm_memory" hcl:"vm_memory"`
DiskName *string `mapstructure:"disk_name" cty:"disk_name" hcl:"disk_name"`
DiskSize *uint `mapstructure:"disk_size" cty:"disk_size" hcl:"disk_size"` DiskSize *uint `mapstructure:"disk_size" cty:"disk_size" hcl:"disk_size"`
CloneTemplate *string `mapstructure:"clone_template" cty:"clone_template" hcl:"clone_template"` 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"` 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"` 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"` ISOUrls []string `mapstructure:"iso_urls" cty:"iso_urls" hcl:"iso_urls"`
ISOUrl *string `mapstructure:"iso_url" cty:"iso_url" hcl:"iso_url"` ISOUrl *string `mapstructure:"iso_url" cty:"iso_url" hcl:"iso_url"`
ISOName *string `mapstructure:"iso_name" cty:"iso_name" hcl:"iso_name"` ISOName *string `mapstructure:"iso_name" cty:"iso_name" hcl:"iso_name"`
PlatformArgs map[string]string `mapstructure:"platform_args" cty:"platform_args" hcl:"platform_args"` PlatformArgs map[string]string `mapstructure:"platform_args" cty:"platform_args" hcl:"platform_args"`
RawInstallTimeout *string `mapstructure:"install_timeout" cty:"install_timeout" hcl:"install_timeout"` RawInstallTimeout *string `mapstructure:"install_timeout" cty:"install_timeout" hcl:"install_timeout"`
SourcePath *string `mapstructure:"source_path" cty:"source_path" hcl:"source_path"` SourcePath *string `mapstructure:"source_path" cty:"source_path" hcl:"source_path"`
Firmware *string `mapstructure:"firmware" cty:"firmware" hcl:"firmware"`
SkipSetTemplate *bool `mapstructure:"skip_set_template" cty:"skip_set_template" hcl:"skip_set_template"`
} }
// FlatMapstructure returns a new FlatConfig. // FlatMapstructure returns a new FlatConfig.
@ -123,6 +128,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{ s := map[string]hcldec.Spec{
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false}, "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_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_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
"packer_force": &hcldec.AttrSpec{Name: "packer_force", 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}, "packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
@ -131,6 +137,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"remote_username": &hcldec.AttrSpec{Name: "remote_username", Type: cty.String, Required: false}, "remote_username": &hcldec.AttrSpec{Name: "remote_username", Type: cty.String, Required: false},
"remote_password": &hcldec.AttrSpec{Name: "remote_password", Type: cty.String, Required: false}, "remote_password": &hcldec.AttrSpec{Name: "remote_password", Type: cty.String, Required: false},
"remote_host": &hcldec.AttrSpec{Name: "remote_host", Type: cty.String, Required: false}, "remote_host": &hcldec.AttrSpec{Name: "remote_host", Type: cty.String, Required: false},
"remote_ssh_port": &hcldec.AttrSpec{Name: "remote_ssh_port", Type: cty.Number, Required: false},
"vm_name": &hcldec.AttrSpec{Name: "vm_name", Type: cty.String, Required: false}, "vm_name": &hcldec.AttrSpec{Name: "vm_name", Type: cty.String, Required: false},
"vm_description": &hcldec.AttrSpec{Name: "vm_description", Type: cty.String, Required: false}, "vm_description": &hcldec.AttrSpec{Name: "vm_description", Type: cty.String, Required: false},
"sr_name": &hcldec.AttrSpec{Name: "sr_name", Type: cty.String, Required: false}, "sr_name": &hcldec.AttrSpec{Name: "sr_name", Type: cty.String, Required: false},
@ -138,6 +145,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"floppy_files": &hcldec.AttrSpec{Name: "floppy_files", Type: cty.List(cty.String), Required: false}, "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}, "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}, "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_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}, "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}, "boot_command": &hcldec.AttrSpec{Name: "boot_command", Type: cty.List(cty.String), Required: false},
@ -207,17 +215,19 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"vcpus_max": &hcldec.AttrSpec{Name: "vcpus_max", Type: cty.Number, Required: false}, "vcpus_max": &hcldec.AttrSpec{Name: "vcpus_max", Type: cty.Number, Required: false},
"vcpus_atstartup": &hcldec.AttrSpec{Name: "vcpus_atstartup", Type: cty.Number, Required: false}, "vcpus_atstartup": &hcldec.AttrSpec{Name: "vcpus_atstartup", Type: cty.Number, Required: false},
"vm_memory": &hcldec.AttrSpec{Name: "vm_memory", Type: cty.Number, Required: false}, "vm_memory": &hcldec.AttrSpec{Name: "vm_memory", Type: cty.Number, Required: false},
"disk_name": &hcldec.AttrSpec{Name: "disk_name", Type: cty.String, Required: false},
"disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, Required: false}, "disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, Required: false},
"clone_template": &hcldec.AttrSpec{Name: "clone_template", Type: cty.String, Required: false}, "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}, "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": &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_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_url": &hcldec.AttrSpec{Name: "iso_url", Type: cty.String, Required: false},
"iso_name": &hcldec.AttrSpec{Name: "iso_name", Type: cty.String, Required: false}, "iso_name": &hcldec.AttrSpec{Name: "iso_name", Type: cty.String, Required: false},
"platform_args": &hcldec.AttrSpec{Name: "platform_args", Type: cty.Map(cty.String), Required: false}, "platform_args": &hcldec.AttrSpec{Name: "platform_args", Type: cty.Map(cty.String), Required: false},
"install_timeout": &hcldec.AttrSpec{Name: "install_timeout", Type: cty.String, Required: false}, "install_timeout": &hcldec.AttrSpec{Name: "install_timeout", Type: cty.String, Required: false},
"source_path": &hcldec.AttrSpec{Name: "source_path", Type: cty.String, Required: false}, "source_path": &hcldec.AttrSpec{Name: "source_path", Type: cty.String, Required: false},
"firmware": &hcldec.AttrSpec{Name: "firmware", Type: cty.String, Required: false},
"skip_set_template": &hcldec.AttrSpec{Name: "skip_set_template", Type: cty.Bool, Required: false},
} }
return s return s
} }

View File

@ -17,7 +17,7 @@ import (
func SSHAddress(state multistep.StateBag) (string, error) { func SSHAddress(state multistep.StateBag) (string, error) {
sshIP := state.Get("ssh_address").(string) sshIP := state.Get("ssh_address").(string)
sshHostPort := 22 sshHostPort := state.Get("ssh_port").(uint)
return fmt.Sprintf("%s:%d", sshIP, sshHostPort), nil return fmt.Sprintf("%s:%d", sshIP, sshHostPort), nil
} }
@ -114,10 +114,10 @@ func ExecuteGuestSSHCmd(state multistep.StateBag, cmd string) (stdout string, er
return doExecuteSSHCmd(cmd, localAddress, sshConfig) return doExecuteSSHCmd(cmd, localAddress, sshConfig)
} }
func forward(local_conn net.Conn, config *gossh.ClientConfig, server, remote_dest string, remote_port uint) error { func forward(local_conn net.Conn, config *gossh.ClientConfig, server string, server_ssh_port int, remote_dest string, remote_port uint) error {
defer local_conn.Close() defer local_conn.Close()
ssh_client_conn, err := gossh.Dial("tcp", server+":22", config) ssh_client_conn, err := gossh.Dial("tcp", fmt.Sprintf("%s:%d", server, server_ssh_port), config)
if err != nil { if err != nil {
log.Printf("local ssh.Dial error: %s", err) log.Printf("local ssh.Dial error: %s", err)
return err return err
@ -157,7 +157,7 @@ func forward(local_conn net.Conn, config *gossh.ClientConfig, server, remote_des
return nil return nil
} }
func ssh_port_forward(local_listener net.Listener, remote_port int, remote_dest, host, username, password string) error { func ssh_port_forward(local_listener net.Listener, remote_port int, remote_dest, host string, host_ssh_port int, username, password string) error {
config := &gossh.ClientConfig{ config := &gossh.ClientConfig{
User: username, User: username,
@ -176,7 +176,7 @@ func ssh_port_forward(local_listener net.Listener, remote_port int, remote_dest,
} }
// Forward to a remote port // Forward to a remote port
go forward(local_connection, config, host, remote_dest, uint(remote_port)) go forward(local_connection, config, host, host_ssh_port, remote_dest, uint(remote_port))
} }
return nil return nil

View File

@ -1,4 +1,4 @@
package iso package common
import ( import (
"context" "context"
@ -9,18 +9,21 @@ import (
"github.com/hashicorp/packer-plugin-sdk/packer" "github.com/hashicorp/packer-plugin-sdk/packer"
xenapi "github.com/terra-farm/go-xen-api-client" xenapi "github.com/terra-farm/go-xen-api-client"
xsclient "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 {
// 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 instance *xsclient.VMRef
vdi *xsclient.VDIRef 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) c := state.Get("client").(*Connection)
config := state.Get("config").(xscommon.Config) config := state.Get("config").(Config)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
ui.Say("Step: Create Instance") ui.Say("Step: Create Instance")
@ -101,37 +104,45 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa
} }
} }
// Create VDI for the instance if !self.AssumePreInstalledOS {
sr, err := config.GetSR(c) 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 err != nil { // Create VDI for the instance
ui.Error(fmt.Sprintf("Unable to get SR: %s", err.Error())) sr, err := config.GetSR(c)
return multistep.ActionHalt
}
ui.Say(fmt.Sprintf("Using the following SR for the VM: %s", sr)) if err != nil {
ui.Error(fmt.Sprintf("Unable to get SR: %s", err.Error()))
return multistep.ActionHalt
}
vdi, err := c.GetClient().VDI.Create(c.GetSessionRef(), xenapi.VDIRecord{ ui.Say(fmt.Sprintf("Using the following SR for the VM: %s", sr))
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 = xscommon.ConnectVdi(c, instance, vdi, xsclient.VbdTypeDisk) vdi, err := c.GetClient().VDI.Create(c.GetSessionRef(), xenapi.VDIRecord{
if err != nil { NameLabel: config.DiskName,
ui.Error(fmt.Sprintf("Unable to connect packer disk VDI: %s", err.Error())) VirtualSize: int(config.DiskSize * 1024 * 1024),
return multistep.ActionHalt 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
}
} }
// Connect Network // Connect Network
@ -168,7 +179,7 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa
} }
log.Printf("Creating VIF on network '%s' on VM '%s'\n", network, instance) 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 { if err != nil {
ui.Error(fmt.Sprintf("Failed to create VIF with error: %v", err)) ui.Error(fmt.Sprintf("Failed to create VIF with error: %v", err))
@ -197,7 +208,7 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa
//we need the VIF index string //we need the VIF index string
vifIndexString := fmt.Sprintf("%d", i) vifIndexString := fmt.Sprintf("%d", i)
_, err = xscommon.ConnectNetwork(c, networks[0], instance, vifIndexString) _, err = ConnectNetwork(c, networks[0], instance, vifIndexString)
if err != nil { if err != nil {
ui.Say(fmt.Sprintf("Failed to connect VIF with error: %v", err.Error())) ui.Say(fmt.Sprintf("Failed to connect VIF with error: %v", err.Error()))
@ -205,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) instanceId, err := c.GetClient().VM.GetUUID(c.GetSessionRef(), instance)
if err != nil { if err != nil {
ui.Error(fmt.Sprintf("Unable to get VM UUID: %s", err.Error())) ui.Error(fmt.Sprintf("Unable to get VM UUID: %s", err.Error()))
@ -217,14 +234,14 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa
return multistep.ActionContinue return multistep.ActionContinue
} }
func (self *stepCreateInstance) Cleanup(state multistep.StateBag) { func (self *StepCreateInstance) Cleanup(state multistep.StateBag) {
config := state.Get("config").(xscommon.Config) config := state.Get("config").(Config)
if config.ShouldKeepVM(state) { if config.ShouldKeepVM(state) {
return return
} }
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
c := state.Get("client").(*xscommon.Connection) c := state.Get("client").(*Connection)
if self.instance != nil { if self.instance != nil {
ui.Say("Destroying VM") ui.Say("Destroying VM")

View File

@ -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)
}

View File

@ -35,10 +35,11 @@ func (self *StepForwardPortOverSSH) Run(ctx context.Context, state multistep.Sta
ui.Say(fmt.Sprintf("Creating a local port forward over SSH on local port %d", sshHostPort)) ui.Say(fmt.Sprintf("Creating a local port forward over SSH on local port %d", sshHostPort))
hostAddress, _ := state.Get("ssh_address").(string) hostAddress, _ := state.Get("ssh_address").(string)
hostSshPort, _ := state.Get("ssh_port").(int)
remotePort, _ := self.RemotePort(state) remotePort, _ := self.RemotePort(state)
remoteDest, _ := self.RemoteDest(state) remoteDest, _ := self.RemoteDest(state)
go ssh_port_forward(l, remotePort, remoteDest, hostAddress, config.Username, config.Password) go ssh_port_forward(l, remotePort, remoteDest, hostAddress, hostSshPort, config.Username, config.Password)
ui.Say(fmt.Sprintf("Port forward setup. %d ---> %s:%d on %s", sshHostPort, remoteDest, remotePort, hostAddress)) ui.Say(fmt.Sprintf("Port forward setup. %d ---> %s:%d on %s", sshHostPort, remoteDest, remotePort, hostAddress))
// Provide the local port to future steps. // Provide the local port to future steps.

View File

@ -13,6 +13,7 @@ type StepSetVmHostSshAddress struct{}
func (self *StepSetVmHostSshAddress) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { func (self *StepSetVmHostSshAddress) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
c := state.Get("client").(*Connection) c := state.Get("client").(*Connection)
config := state.Get("config").(Config)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
ui.Say("Step: Set SSH address to VM host IP") ui.Say("Step: Set SSH address to VM host IP")
@ -37,6 +38,9 @@ func (self *StepSetVmHostSshAddress) Run(ctx context.Context, state multistep.St
state.Put("ssh_address", address) state.Put("ssh_address", address)
ui.Say(fmt.Sprintf("Set host SSH address to '%s'.", address)) ui.Say(fmt.Sprintf("Set host SSH address to '%s'.", address))
state.Put("ssh_port", config.HostSshPort)
ui.Say(fmt.Sprintf("Set host SSH port to %d.", config.HostSshPort))
return multistep.ActionContinue return multistep.ActionContinue
} }

View File

@ -16,6 +16,7 @@ func (self *StepStartVmPaused) Run(ctx context.Context, state multistep.StateBag
c := state.Get("client").(*Connection) c := state.Get("client").(*Connection)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
config := state.Get("config").(Config)
ui.Say("Step: Start VM Paused") ui.Say("Step: Start VM Paused")
@ -34,7 +35,7 @@ func (self *StepStartVmPaused) Run(ctx context.Context, state multistep.StateBag
return multistep.ActionHalt return multistep.ActionHalt
} }
err = c.client.VM.SetHVMBootParams(c.session, instance, map[string]string{"order": "cd"}) err = c.client.VM.SetHVMBootParams(c.session, instance, map[string]string{"order": "cd", "firmware": config.Firmware})
if err != nil { if err != nil {
ui.Error(fmt.Sprintf("Unable to set HVM boot params: %s", err.Error())) ui.Error(fmt.Sprintf("Unable to set HVM boot params: %s", err.Error()))
return multistep.ActionHalt return multistep.ActionHalt

View File

@ -32,8 +32,8 @@ type StepTypeBootCommand struct {
Ctx interpolate.Context Ctx interpolate.Context
} }
func (self *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { func (step *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("commonconfig").(CommonConfig) config := state.Get("config").(Config)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
c := state.Get("client").(*Connection) c := state.Get("client").(*Connection)
httpPort := state.Get("http_port").(int) httpPort := state.Get("http_port").(int)
@ -74,7 +74,8 @@ func (self *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateB
} }
locationPieces := strings.SplitAfter(location, "/") locationPieces := strings.SplitAfter(location, "/")
consoleHost := strings.TrimSuffix(locationPieces[2], "/") consoleHost := strings.TrimSuffix(locationPieces[2], "/")
ui.Say(fmt.Sprintf("Connecting to the VM console VNC over xapi via %s", consoleHost)) ui.Say("Connecting to VNC over XAPI...")
log.Printf("Connecting to host: %s", consoleHost)
conn, err := net.Dial("tcp", fmt.Sprintf("%s:443", consoleHost)) conn, err := net.Dial("tcp", fmt.Sprintf("%s:443", consoleHost))
if err != nil { if err != nil {
@ -95,7 +96,7 @@ func (self *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateB
httpReq := fmt.Sprintf("CONNECT %s HTTP/1.0\r\nHost: %s\r\nCookie: session_id=%s\r\n\r\n", consoleLocation, consoleHost, c.session) httpReq := fmt.Sprintf("CONNECT %s HTTP/1.0\r\nHost: %s\r\nCookie: session_id=%s\r\n\r\n", consoleLocation, consoleHost, c.session)
fmt.Printf("Sending the follow http req: %v", httpReq) fmt.Printf("Sending the follow http req: %v", httpReq)
ui.Say(fmt.Sprintf("Making HTTP request to initiate VNC connection: %s", httpReq)) ui.Message(fmt.Sprintf("Making HTTP request to initiate VNC connection: %s", httpReq))
_, err = io.WriteString(tlsConn, httpReq) _, err = io.WriteString(tlsConn, httpReq)
if err != nil { if err != nil {
@ -114,9 +115,9 @@ func (self *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateB
return multistep.ActionHalt return multistep.ActionHalt
} }
ui.Say(fmt.Sprintf("Received response: %s", string(buffer))) ui.Message(fmt.Sprintf("Received response: %s", string(buffer)))
vncClient, err := vnc.Client(tlsConn, &vnc.ClientConfig{Exclusive: true}) vncClient, err := vnc.Client(tlsConn, &vnc.ClientConfig{Exclusive: !config.PackerDebug})
if err != nil { if err != nil {
err := fmt.Errorf("Error establishing VNC session: %s", err) err := fmt.Errorf("Error establishing VNC session: %s", err)
@ -142,7 +143,7 @@ func (self *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateB
localIp := strings.Split(envVar, " ")[0] localIp := strings.Split(envVar, " ")[0]
ui.Message(fmt.Sprintf("Found local IP: %s", localIp)) ui.Message(fmt.Sprintf("Found local IP: %s", localIp))
self.Ctx.Data = &bootCommandTemplateData{ step.Ctx.Data = &bootCommandTemplateData{
config.VMName, config.VMName,
localIp, localIp,
uint(httpPort), uint(httpPort),
@ -151,7 +152,7 @@ func (self *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateB
ui.Say("Typing boot commands over VNC...") ui.Say("Typing boot commands over VNC...")
for _, command := range config.BootCommand { for _, command := range config.BootCommand {
command, err := interpolate.Render(command, &self.Ctx) command, err := interpolate.Render(command, &step.Ctx)
if err != nil { if err != nil {
err := fmt.Errorf("Error preparing boot command: %s", err) err := fmt.Errorf("Error preparing boot command: %s", err)
state.Put("error", err) state.Put("error", err)
@ -167,12 +168,10 @@ func (self *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateB
vncSendString(vncClient, command) vncSendString(vncClient, command)
} }
ui.Say("Finished typing.")
return multistep.ActionContinue return multistep.ActionContinue
} }
func (self *StepTypeBootCommand) Cleanup(multistep.StateBag) {} func (step *StepTypeBootCommand) Cleanup(multistep.StateBag) {}
// Taken from qemu's builder plugin - not an exported function. // Taken from qemu's builder plugin - not an exported function.
func vncSendString(c *vnc.ClientConn, original string) { func vncSendString(c *vnc.ClientConn, original string) {

View File

@ -18,7 +18,7 @@ type StepUploadVdi struct {
VdiUuidKey string 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) config := state.Get("commonconfig").(CommonConfig)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
c := state.Get("client").(*Connection) 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)) ui.Say(fmt.Sprintf("Step: Upload VDI '%s'", vdiName))
// Create VDI for the image // 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) sr, err := config.GetISOSR(c)
ui.Say(fmt.Sprintf("Step: Found SR for upload '%v'", sr))
if err != nil { if err != nil {
ui.Error(fmt.Sprintf("Unable to get SR: %v", err)) 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 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) { func (self *StepUploadVdi) Cleanup(state multistep.StateBag) {
config := state.Get("commonconfig").(CommonConfig) config := state.Get("commonconfig").(CommonConfig)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)

View File

@ -60,7 +60,8 @@ func (self *StepWaitForIP) Run(ctx context.Context, state multistep.StateBag) mu
return false, err return false, err
} }
networks := metrics.Networks networks := metrics.Networks
if ip, ok := networks["0/ip"]; ok { var ok bool
if ip, ok = networks["0/ip"]; ok {
if ip != "" { if ip != "" {
ui.Message(fmt.Sprintf("Got IP '%s' from XenServer tools", ip)) ui.Message(fmt.Sprintf("Got IP '%s' from XenServer tools", ip))
return true, nil return true, nil

View File

@ -40,7 +40,7 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
}, raws...) }, raws...)
if err != nil { if err != nil {
packer.MultiErrorAppend(errs, err) errs = packer.MultiErrorAppend(errs, err)
} }
errs = packer.MultiErrorAppend( errs = packer.MultiErrorAppend(
@ -53,6 +53,10 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
self.config.RawInstallTimeout = "200m" self.config.RawInstallTimeout = "200m"
} }
if self.config.DiskName == "" {
self.config.DiskName = "Packer-disk"
}
if self.config.DiskSize == 0 { if self.config.DiskSize == 0 {
self.config.DiskSize = 40000 self.config.DiskSize = 40000
} }
@ -77,6 +81,10 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
self.config.CloneTemplate = "Other install media" self.config.CloneTemplate = "Other install media"
} }
if self.config.Firmware == "" {
self.config.Firmware = "bios"
}
if len(self.config.PlatformArgs) == 0 { if len(self.config.PlatformArgs) == 0 {
pargs := make(map[string]string) pargs := make(map[string]string)
pargs["viridian"] = "false" pargs["viridian"] = "false"
@ -91,12 +99,11 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
// Template substitution // Template substitution
templates := map[string]*string{ templates := map[string]*string{
"clone_template": &self.config.CloneTemplate, "clone_template": &self.config.CloneTemplate,
"iso_checksum": &self.config.ISOChecksum, "iso_checksum": &self.config.ISOChecksum,
"iso_checksum_type": &self.config.ISOChecksumType, "iso_url": &self.config.ISOUrl,
"iso_url": &self.config.ISOUrl, "iso_name": &self.config.ISOName,
"iso_name": &self.config.ISOName, "install_timeout": &self.config.RawInstallTimeout,
"install_timeout": &self.config.RawInstallTimeout,
} }
for i := range self.config.ISOUrls { for i := range self.config.ISOUrls {
templates[fmt.Sprintf("iso_urls[%d]", i)] = &self.config.ISOUrls[i] templates[fmt.Sprintf("iso_urls[%d]", i)] = &self.config.ISOUrls[i]
@ -111,23 +118,8 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
} }
if self.config.ISOName == "" { if self.config.ISOName == "" {
// If ISO name is not specified, assume a URL and checksum has been provided. // If ISO name is not specified, assume a URL and checksum has been provided.
self.config.ISOChecksum = strings.ToLower(self.config.ISOChecksum)
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)
}
}
}
if len(self.config.ISOUrls) == 0 { if len(self.config.ISOUrls) == 0 {
if self.config.ISOUrl == "" { if self.config.ISOUrl == "" {
@ -136,10 +128,25 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
} else { } else {
self.config.ISOUrls = []string{self.config.ISOUrl} self.config.ISOUrls = []string{self.config.ISOUrl}
} }
} else if self.config.ISOUrl != "" { } else if self.config.ISOUrl != "" {
errs = packer.MultiErrorAppend( errs = packer.MultiErrorAppend(
errs, errors.New("Only one of iso_url or iso_urls may be specified.")) 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 { } else {
// An ISO name has been provided. It should be attached from an available SR. // An ISO name has been provided. It should be attached from an available SR.
@ -183,7 +190,6 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
Url: self.config.ISOUrls, Url: self.config.ISOUrls,
}, },
} }
steps := []multistep.Step{ steps := []multistep.Step{
&xscommon.StepPrepareOutputDir{ &xscommon.StepPrepareOutputDir{
Force: self.config.PackerForce, Force: self.config.PackerForce,
@ -191,6 +197,7 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
}, },
&commonsteps.StepCreateFloppy{ &commonsteps.StepCreateFloppy{
Files: self.config.FloppyFiles, Files: self.config.FloppyFiles,
Label: "cidata",
}, },
&xscommon.StepHTTPServer{ &xscommon.StepHTTPServer{
Chan: httpReqChan, Chan: httpReqChan,
@ -207,20 +214,22 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
}, },
VdiUuidKey: "floppy_vdi_uuid", VdiUuidKey: "floppy_vdi_uuid",
}, },
&xscommon.StepUploadVdi{ &xscommon.StepFindOrUploadVdi{
VdiNameFunc: func() string { xscommon.StepUploadVdi{
if len(self.config.ISOUrls) > 0 { VdiNameFunc: func() string {
return path.Base(self.config.ISOUrls[0]) if len(self.config.ISOUrls) > 0 {
} return path.Base(self.config.ISOUrls[0])
return "" }
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{ &xscommon.StepFindVdi{
VdiName: self.config.ToolsIsoName, VdiName: self.config.ToolsIsoName,
@ -230,7 +239,9 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
VdiName: self.config.ISOName, VdiName: self.config.ISOName,
VdiUuidKey: "isoname_vdi_uuid", VdiUuidKey: "isoname_vdi_uuid",
}, },
new(stepCreateInstance), &xscommon.StepCreateInstance{
AssumePreInstalledOS: false,
},
&xscommon.StepAttachVdi{ &xscommon.StepAttachVdi{
VdiUuidKey: "floppy_vdi_uuid", VdiUuidKey: "floppy_vdi_uuid",
VdiType: xsclient.VbdTypeFloppy, VdiType: xsclient.VbdTypeFloppy,
@ -279,7 +290,14 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
}, },
new(commonsteps.StepProvision), new(commonsteps.StepProvision),
new(xscommon.StepShutdown), new(xscommon.StepShutdown),
new(xscommon.StepSetVmToTemplate), }
if !self.config.SkipSetTemplate {
steps = append(steps,
new(xscommon.StepSetVmToTemplate))
}
steps = append(steps,
&xscommon.StepDetachVdi{ &xscommon.StepDetachVdi{
VdiUuidKey: "iso_vdi_uuid", VdiUuidKey: "iso_vdi_uuid",
}, },
@ -292,8 +310,7 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
&xscommon.StepDetachVdi{ &xscommon.StepDetachVdi{
VdiUuidKey: "floppy_vdi_uuid", VdiUuidKey: "floppy_vdi_uuid",
}, },
new(xscommon.StepExport), new(xscommon.StepExport))
}
if self.config.ISOName == "" { if self.config.ISOName == "" {
steps = append(download_steps, steps...) steps = append(download_steps, steps...)

View File

@ -4,22 +4,22 @@ import (
"reflect" "reflect"
"testing" "testing"
"github.com/hashicorp/packer-plugin-sdk/common"
"github.com/hashicorp/packer-plugin-sdk/packer" "github.com/hashicorp/packer-plugin-sdk/packer"
) )
func testConfig() map[string]interface{} { func testConfig() map[string]interface{} {
return map[string]interface{}{ return map[string]interface{}{
"remote_host": "localhost", "remote_host": "localhost",
"remote_username": "admin", "remote_username": "admin",
"remote_password": "admin", "remote_password": "admin",
"vm_name": "foo", "vm_name": "foo",
"iso_checksum": "foo", "iso_checksum": "md5:A221725EE181A44C67E25BD6A2516742",
"iso_checksum_type": "md5", "iso_url": "http://www.google.com/",
"iso_url": "http://www.google.com/", "shutdown_command": "yes",
"shutdown_command": "yes", "ssh_username": "foo",
"ssh_username": "foo",
packer.BuildNameConfigKey: "foo", common.BuildNameConfigKey: "foo",
} }
} }
@ -42,7 +42,7 @@ func TestBuilderPrepare_Defaults(t *testing.T) {
t.Fatalf("should not have error: %s", err) t.Fatalf("should not have error: %s", err)
} }
if b.config.ToolsIsoName != "xs-tools.iso" { if b.config.ToolsIsoName != "" {
t.Errorf("bad tools ISO name: %s", b.config.ToolsIsoName) t.Errorf("bad tools ISO name: %s", b.config.ToolsIsoName)
} }
@ -61,6 +61,10 @@ func TestBuilderPrepare_Defaults(t *testing.T) {
if b.config.KeepVM != "never" { if b.config.KeepVM != "never" {
t.Errorf("bad keep instance: %s", b.config.KeepVM) t.Errorf("bad keep instance: %s", b.config.KeepVM)
} }
if b.config.HostSshPort != 22 {
t.Errorf("bad ssh port: %d", b.config.HostSshPort)
}
} }
func TestBuilderPrepare_DiskSize(t *testing.T) { func TestBuilderPrepare_DiskSize(t *testing.T) {
@ -179,64 +183,19 @@ func TestBuilderPrepare_ISOChecksum(t *testing.T) {
var b Builder var b Builder
config := testConfig() 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 // Test bad
config["iso_checksum"] = "" config["iso_checksum"] = ""
_, 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"] = "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) _, warns, err = b.Prepare(config)
if len(warns) > 0 { if len(warns) > 0 {
t.Fatalf("bad: %#v", warns) t.Fatalf("bad: %#v", warns)
@ -245,23 +204,6 @@ func TestBuilderPrepare_ISOChecksumType(t *testing.T) {
t.Fatal("should have error") 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) { func TestBuilderPrepare_ISOUrl(t *testing.T) {

View File

@ -3,7 +3,6 @@ package xva
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"time" "time"
"github.com/hashicorp/hcl/v2/hcldec" "github.com/hashicorp/hcl/v2/hcldec"
@ -38,11 +37,12 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
}, raws...) }, raws...)
if err != nil { if err != nil {
packer.MultiErrorAppend(errs, err) errs = packer.MultiErrorAppend(errs, err)
} }
errs = packer.MultiErrorAppend( errs = packer.MultiErrorAppend(
errs, self.config.CommonConfig.Prepare(self.config.GetInterpContext(), &self.config.PackerConfig)...) 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 // Set default values
if self.config.VCPUsMax == 0 { if self.config.VCPUsMax == 0 {
@ -74,8 +74,12 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
// Validation // Validation
if self.config.SourcePath == "" { if self.config.SourcePath == "" && self.config.CloneTemplate == "" {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("A source_path must be specified")) 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 { if len(errs.Errors) > 0 {
@ -101,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 //Share state between the other steps using a statebag
state := new(multistep.BasicStateBag) state := new(multistep.BasicStateBag)
state.Put("client", c) state.Put("client", c)
// state.Put("config", self.config) state.Put("config", self.config)
state.Put("commonconfig", self.config.CommonConfig) state.Put("commonconfig", self.config.CommonConfig)
state.Put("hook", hook) state.Put("hook", hook)
state.Put("ui", ui) state.Put("ui", ui)
@ -116,8 +120,11 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
}, },
&commonsteps.StepCreateFloppy{ &commonsteps.StepCreateFloppy{
Files: self.config.FloppyFiles, Files: self.config.FloppyFiles,
Label: "cidata",
},
&xscommon.StepHTTPServer{
Chan: httpReqChan,
}, },
new(xscommon.StepHTTPServer),
&xscommon.StepUploadVdi{ &xscommon.StepUploadVdi{
VdiNameFunc: func() string { VdiNameFunc: func() string {
return "Packer-floppy-disk" return "Packer-floppy-disk"
@ -134,6 +141,9 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
VdiName: self.config.ToolsIsoName, VdiName: self.config.ToolsIsoName,
VdiUuidKey: "tools_vdi_uuid", VdiUuidKey: "tools_vdi_uuid",
}, },
&xscommon.StepCreateInstance{
AssumePreInstalledOS: true,
},
new(stepImportInstance), new(stepImportInstance),
&xscommon.StepAttachVdi{ &xscommon.StepAttachVdi{
VdiUuidKey: "floppy_vdi_uuid", VdiUuidKey: "floppy_vdi_uuid",
@ -153,20 +163,28 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
Chan: httpReqChan, Chan: httpReqChan,
Timeout: 300 * time.Minute, /*self.config.InstallTimeout*/ // @todo change this 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{ &communicator.StepConnect{
Config: &self.config.SSHConfig.Comm, Config: &self.config.SSHConfig.Comm,
Host: xscommon.CommHost, Host: xscommon.InstanceSSHIP,
SSHConfig: xscommon.SSHConfigFunc(self.config.CommonConfig.SSHConfig), SSHConfig: self.config.Comm.SSHConfigFunc(),
SSHPort: xscommon.SSHPort, SSHPort: xscommon.InstanceSSHPort,
}, },
new(commonsteps.StepProvision), new(commonsteps.StepProvision),
new(xscommon.StepShutdown), new(xscommon.StepShutdown),
&xscommon.StepDetachVdi{ new(xscommon.StepSetVmToTemplate),
VdiUuidKey: "floppy_vdi_uuid",
},
&xscommon.StepDetachVdi{ &xscommon.StepDetachVdi{
VdiUuidKey: "tools_vdi_uuid", VdiUuidKey: "tools_vdi_uuid",
}, },
&xscommon.StepDetachVdi{
VdiUuidKey: "floppy_vdi_uuid",
},
new(xscommon.StepExport), new(xscommon.StepExport),
} }

View File

@ -3,6 +3,7 @@ package xva
import ( import (
"testing" "testing"
"github.com/hashicorp/packer-plugin-sdk/common"
"github.com/hashicorp/packer-plugin-sdk/packer" "github.com/hashicorp/packer-plugin-sdk/packer"
) )
@ -16,7 +17,7 @@ func testConfig() map[string]interface{} {
"ssh_username": "foo", "ssh_username": "foo",
"source_path": ".", "source_path": ".",
packer.BuildNameConfigKey: "foo", common.BuildNameConfigKey: "foo",
} }
} }
@ -39,7 +40,7 @@ func TestBuilderPrepare_Defaults(t *testing.T) {
t.Fatalf("should not have error: %s", err) t.Fatalf("should not have error: %s", err)
} }
if b.config.ToolsIsoName != "xs-tools.iso" { if b.config.ToolsIsoName != "" {
t.Errorf("bad tools ISO name: %s", b.config.ToolsIsoName) t.Errorf("bad tools ISO name: %s", b.config.ToolsIsoName)
} }
@ -54,6 +55,10 @@ func TestBuilderPrepare_Defaults(t *testing.T) {
if b.config.KeepVM != "never" { if b.config.KeepVM != "never" {
t.Errorf("bad keep instance: %s", b.config.KeepVM) t.Errorf("bad keep instance: %s", b.config.KeepVM)
} }
if b.config.HostSshPort != 22 {
t.Errorf("bad ssh port: %d", b.config.HostSshPort)
}
} }
func TestBuilderPrepare_Format(t *testing.T) { func TestBuilderPrepare_Format(t *testing.T) {

View File

@ -3,6 +3,7 @@ package xva
import ( import (
"context" "context"
"fmt" "fmt"
"log"
"os" "os"
"github.com/hashicorp/packer-plugin-sdk/multistep" "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") ui.Say("Step: Import Instance")
if config.SourcePath == "" {
log.Println("Skipping importing instance - no `source_path` configured.")
return multistep.ActionContinue
}
// find the SR // find the SR
srs, err := c.GetClient().SR.GetAll(c.GetSessionRef()) srs, err := c.GetClient().SR.GetAll(c.GetSessionRef())
sr := srs[0] sr := srs[0]
@ -80,6 +86,12 @@ func (self *stepImportInstance) Run(ctx context.Context, state multistep.StateBa
return multistep.ActionHalt 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)) ui.Say(fmt.Sprintf("Imported instance '%s'", instanceId))
return multistep.ActionContinue return multistep.ActionContinue

View File

@ -18,7 +18,6 @@ the OS, then shutting it down. The result of the XenServer builder is a
directory containing all the files necessary to run the virtual machine directory containing all the files necessary to run the virtual machine
portably. portably.
## Configuration Reference ## Configuration Reference
There are many configuration options available for the XenServer builder. There are many configuration options available for the XenServer builder.
@ -29,21 +28,37 @@ each category, the available options are alphabetized and described.
* `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO * `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 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 to booting a virtual machine with the ISO attached. The type of
checksum is specified with `iso_checksum_type`, documented below. 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
an example 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. * `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). This URL can be either an HTTP URL or a file URL (or path to a file).
If this is an HTTP URL, Packer will download it and cache it between If this is an HTTP URL, Packer will download it and cache it between
runs. 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_ssh_port` (integer) - The port that SSH will be listening on in the Xenserver / XCP-ng pool primary. By default this is 22.
* `remote_username` (string) - The XenServer username used to access the remote machine. * `remote_username` (string) - The XenServer username used to access the remote machine.
@ -59,11 +74,12 @@ each category, the available options are alphabetized and described.
be to type just enough to initialize the operating system installer. Special 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 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 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 * `boot_wait` (string) - The time to wait after booting the initial virtual
machine before typing the `boot_command`. The value of this should be machine before typing the `boot_command`. The value of this should be
a duration. Examples are "5s" and "1m30s" which will cause Packer to wait a duration. Examples are `5s` and `1m30s` which will cause Packer to wait
five seconds and one minute 30 seconds, respectively. If this isn't specified, five seconds and one minute 30 seconds, respectively. If this isn't specified,
the default is 10 seconds. the default is 10 seconds.
@ -73,9 +89,15 @@ each category, the available options are alphabetized and described.
run `xe template-list`. Setting the correct value hints to XenServer how to run `xe template-list`. Setting the correct value hints to XenServer how to
optimize the virtual hardware to work best with that operating system. optimize the virtual hardware to work best with that operating system.
* `disk_name` (string) - The name of the hard disk to create for the VM.
By default, the name is "Packer-disk".
* `disk_size` (integer) - The size, in megabytes, of the hard disk to create * `disk_size` (integer) - The size, in megabytes, of the hard disk to create
for the VM. By default, this is 40000 (about 40 GB). for the VM. By default, this is 40000 (about 40 GB).
* `firmware` (string) - Whether to use `bios` or `uefi` as the boot firmware
for the resulting VM. Defaults to `bios`.
* `floppy_files` (array of strings) - A list of files to place onto a floppy * `floppy_files` (array of strings) - A list of files to place onto a floppy
disk that is attached when the VM is booted. This is most useful disk that is attached when the VM is booted. This is most useful
for unattended Windows installs, which look for an `Autounattend.xml` file for unattended Windows installs, which look for an `Autounattend.xml` file
@ -86,15 +108,15 @@ each category, the available options are alphabetized and described.
characters (\*, ?, and []) are allowed. Directory names are also allowed, characters (\*, ?, and []) are allowed. Directory names are also allowed,
which will add all the files found in the directory to the floppy. which will add all the files found in the directory to the floppy.
* `format` (string) - Either "xva", "vdi_raw" or "none", this specifies the * `format` (string) - Either "xva", "xva_compressed", "vdi_raw" or "none", this specifies the
output format of the exported virtual machine. This defaults to "xva". Set to output format of the exported virtual machine. This defaults to "xva". Set to
"vdi_raw" to export just the raw disk image. Set to "none" to export nothing; "vdi_raw" to export just the raw disk image. Set to "none" to export nothing;
this is only useful with "keep_vm" set to "always" or "on_success". this is only useful with "keep_vm" set to "always" or "on_success".
* `http_directory` (string) - Path to a directory to serve using an HTTP * `http_directory` (string) - Path to a directory to serve using an HTTP
server. The files in this directory will be available over HTTP that will server. The files in this directory will be available over HTTP which will
be requestable from the virtual machine. This is useful for hosting be requestable from the virtual machine. This is useful for hosting
kickstart files and so on. By default this is "", which means no HTTP kickstart files and so on. By default, this is `""`, which means no HTTP
server will be started. The address and port of the HTTP server will be server will be started. The address and port of the HTTP server will be
available as variables in `boot_command`. This is covered in more detail available as variables in `boot_command`. This is covered in more detail
below. below.
@ -104,7 +126,7 @@ each category, the available options are alphabetized and described.
Because Packer often runs in parallel, Packer will choose a randomly available Because Packer often runs in parallel, Packer will choose a randomly available
port in this range to run the HTTP server. If you want to force the HTTP port in this range to run the HTTP server. If you want to force the HTTP
server to be on one port, make this minimum and maximum port the same. server to be on one port, make this minimum and maximum port the same.
By default the values are 8000 and 9000, respectively. By default, the values are 8000 and 9000, respectively.
* `install_timeout` (string) - The amount of time to wait after booting the VM * `install_timeout` (string) - The amount of time to wait after booting the VM
for the installer to shut itself down. for the installer to shut itself down.
@ -114,38 +136,55 @@ each category, the available options are alphabetized and described.
* `iso_urls` (array of strings) - Multiple URLs for the ISO to download. * `iso_urls` (array of strings) - Multiple URLs for the ISO to download.
Packer will try these in order. If anything goes wrong attempting to download Packer will try these in order. If anything goes wrong attempting to download
or while downloading a single URL, it will move on to the next. All URLs or while downloading a single URL, it will move on to the next. All URLs
must point to the same file (same checksum). By default this is empty must point to the same file (same checksum). By default, this is empty
and `iso_url` is used. Only one of `iso_url` or `iso_urls` can be specified. and `iso_url` is used. Only one of `iso_url` or `iso_urls` can be specified.
* `tools_iso_name` (string) - Choose the tools iso you want to use.
Usually "guest-tools.iso", or "xs-tools.iso". Not setting this variable causes no tools-related
ISO to be attached.
* `keep_vm` (string) - Determine when to keep the VM and when to clean it up. This * `keep_vm` (string) - Determine when to keep the VM and when to clean it up. This
can be "always", "never" or "on_success". By default this is "never", and Packer can be `always`, `never` or `on_success`. The default is `never`, and Packer
always deletes the VM regardless of whether the process succeeded and an artifact always deletes the VM regardless of whether the process succeeded and an artifact
was produced. "always" asks Packer to leave the VM at the end of the process was produced. `always` asks Packer to leave the VM at the end of the process
regardless of success. "on_success" requests that the VM only be cleaned up if an regardless of success. `on_success` requests that the VM only be cleaned up if an
artifact was produced. The latter is useful for debugging templates that fail. artifact was produced. The latter is useful for debugging templates that fail.
* `network_names` (array of strings) - A list of networks identified by their name label which * `ip_getter` (string) - Defines the method by which the IP of the guest machine is
identified. Options are: `auto`, `tools`, `http`. The default is `auto`, which will
attempt both methods. `tools` requires that the guest tools be installed and functional
inside the quest machine.
* `skip_set_template` (bool) - If you want to get the full XVA, to be able to import the VM directly
instead of using the output template, you can set this to `true`.
* `network_names` (array of strings) - A list of networks identified by their name label which
will be used for the VM during creation. The first network will correspond to the VM's will be used for the VM during creation. The first network will correspond to the VM's
first network interface (VIF), the second will corespond to the second VIF and so on. first network interface (VIF), the second will correspond to the second VIF and so on.
* `export_network_names` (array of strings) - A list of networks identified by their name label which
will be attached to the export. The first network will correspond to the VM's
first network interface (VIF), the second will correspond to the second VIF and so on.
* `output_directory` (string) - This is the path to the directory where the * `output_directory` (string) - This is the path to the directory where the
resulting virtual machine will be created. This may be relative or absolute. resulting virtual machine will be created. This may be relative or absolute.
If relative, the path is relative to the working directory when `packer` If relative, the path is relative to the working directory when `packer`
is executed. This directory must not exist or be empty prior to running the builder. is executed. This directory must not exist or be empty prior to running the builder.
By default this is "output-BUILDNAME" where "BUILDNAME" is the name By default, this is "output-BUILDNAME" where "BUILDNAME" is the name
of the build. of the build.
* `platform_args` (object of key/value strings) - The platform args. * `platform_args` (object of key/value strings) - The platform args.
Defaults to Defaults to
```javascript
```json
{ {
"viridian": "false", "viridian": "false",
"nx": "true", "nx": "true",
"pae": "true", "pae": "true",
"apic": "true", "apic": "true",
"timeoffset": "0", "timeoffset": "0",
"acpi": "1", "acpi": "1",
"cores-per-socket": "1" "cores-per-socket": "1"
} }
``` ```
@ -154,6 +193,12 @@ each category, the available options are alphabetized and described.
will shut down the VM gracefully through the Xen api's vm shutdown command. Unless will shut down the VM gracefully through the Xen api's vm shutdown command. Unless
you have special requirements this should typically be left to its default. you have special requirements this should typically be left to its default.
* `sr_name` (string) - The SR to use for storing the disk for the VM that Packer
creates. By default, the default SR of the system will be used.
* `sr_iso_name` (string) - The SR to use for uploading the provided ISO.
By default, the default SR of the system will be used.
* `ssh_host_port_min` and `ssh_host_port_max` (integer) - The minimum and * `ssh_host_port_min` and `ssh_host_port_max` (integer) - The minimum and
maximum port to use for the SSH port on the host machine which is forwarded maximum port to use for the SSH port on the host machine which is forwarded
to the SSH port on the guest machine. Because Packer often runs in parallel, to the SSH port on the guest machine. Because Packer often runs in parallel,
@ -161,46 +206,50 @@ each category, the available options are alphabetized and described.
host port. host port.
* `ssh_key_path` (string) - Path to a private key to use for authenticating * `ssh_key_path` (string) - Path to a private key to use for authenticating
with SSH. By default this is not set (key-based auth won't be used). with SSH. By default, this is not set (key-based auth won't be used).
The associated public key is expected to already be configured on the The associated public key is expected to already be configured on the
VM being prepared by some other process (kickstart, etc.). VM being prepared by some other process (kickstart, etc.).
* `ssh_password` (string) - The password for `ssh_username` to use to * `ssh_password` (string) - The password for `ssh_username` to use to
authenticate with SSH. By default this is the empty string. authenticate with SSH. By default, this is the empty string.
* `ssh_port` (integer) - The port that SSH will be listening on in the guest * `ssh_port` (integer) - The port that SSH will be listening on in the guest
virtual machine. By default this is 22. virtual machine. By default, this is `22`.
* `ssh_wait_timeout` (string) - The duration to wait for SSH to become * `ssh_wait_timeout` (string) - The duration to wait for SSH to become
available. By default this is "20m", or 20 minutes. Note that this should available. By default, this is `20m`, or 20 minutes. **Note**: that this should
be quite long since the timer begins as soon as the virtual machine is booted. be quite long since the timer begins as soon as the virtual machine is booted.
* `tools_iso_name` (string) - The name of the XenServer Tools ISO. Defaults to * `tools_iso_name` (string) - The name of the XenServer Tools ISO. Defaults to
"xs-tools.iso". `xs-tools.iso`.
* `vm_description` (string) - The description of the new virtual * `vm_description` (string) - The description of the new virtual
machine. By default this is the empty string. machine. By default, this is an empty string.
* `vm_name` (string) - This is the name of the new virtual * `vm_name` (string) - This is the name of the new virtual
machine, without the file extension. By default this is machine, without the file extension. By default, this is
"packer-BUILDNAME-TIMESTAMP", where "BUILDNAME" is the name of the build. `packer-BUILDNAME-TIMESTAMP`, where "BUILDNAME" is the name of the build.
* `vcpus_max` (integer) - The maximum number of VCPUs for the VM. * `vcpus_max` (integer) - The maximum number of VCPUs for the VM.
By default this is 1. By default, this is `1`.
* `vcpus_atstartup` (integer) - The number of startup VCPUs for the VM. * `vcpus_atstartup` (integer) - The number of startup VCPUs for the VM.
By default this is 1. By default, this is `1`.
* `vm_memory` (integer) - The size, in megabytes, of the amount of memory to * `vm_memory` (integer) - The size, in megabytes, of the amount of memory to
allocate for the VM. By default, this is 1024 (1 GB). 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 ## Differences with other Packer builders
Currently the XenServer builder has some quirks when compared with other Packer builders. Currently, the XenServer builder has some quirks when compared with other Packer builders.
The builder currently only works remotely. The builder currently only works remotely.
The installer is expected to shut down the VM to indicate that it has completed. This is in contrast to other builders, which instead detect completion by a successful SSH connection. The reason for this difference is that currently the builder has no way of knowing what the IP address of the VM is without starting it on the HIMN. The installer is expected to shut down the VM to indicate that it has completed. This is in contrast to other builders,
which instead detect completion by a successful SSH connection. The reason for this difference is that currently the
builder has no way of knowing what the IP address of the VM is without starting it on the HIMN.
## Boot Command ## Boot Command
@ -213,8 +262,8 @@ As documented above, the `boot_command` is an array of strings. The
strings are all typed in sequence. It is an array only to improve readability strings are all typed in sequence. It is an array only to improve readability
within the template. within the template.
The boot command is "typed" character for character over a VNC connection The boot command is "typed" character by character over a VNC connection
to the machine, simulating a human actually typing the keyboard. There are to the machine, simulating a human actually typing on the keyboard. There are
a set of special keys available. If these are in your boot command, they a set of special keys available. If these are in your boot command, they
will be replaced by the proper key: will be replaced by the proper key:
@ -245,6 +294,7 @@ will be replaced by the proper key:
In addition to the special keys, each command to type is treated as a In addition to the special keys, each command to type is treated as a
configuration template. configuration template.
The available variables are: The available variables are:
* `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server * `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server
@ -252,4 +302,4 @@ The available variables are:
configuration parameter. If `http_directory` isn't specified, these will be configuration parameter. If `http_directory` isn't specified, these will be
blank! blank!
See the [examples](../../examples/) for working boot commands. See the [examples](../../../examples) for working boot commands.

View File

@ -1,7 +1,7 @@
packer { packer {
required_plugins { required_plugins {
xenserver= { xenserver= {
version = ">= v0.3.2" version = ">= v0.6.0"
source = "github.com/ddelnano/xenserver" source = "github.com/ddelnano/xenserver"
} }
} }
@ -47,8 +47,7 @@ locals {
} }
source "xenserver-iso" "centos8-local" { source "xenserver-iso" "centos8-local" {
iso_checksum = "aaf9d4b3071c16dbbda01dfe06085e5d0fdac76df323e3bbe87cce4318052247" iso_checksum = "sha1:aaf9d4b3071c16dbbda01dfe06085e5d0fdac76df323e3bbe87cce4318052247"
iso_checksum_type = "sha1"
iso_url = "http://mirrors.ocf.berkeley.edu/centos/8.3.2011/isos/x86_64/CentOS-8.3.2011-x86_64-dvd1.iso" 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 sr_iso_name = var.sr_iso_name

View File

@ -1,7 +1,7 @@
packer { packer {
required_plugins { required_plugins {
xenserver= { xenserver= {
version = ">= v0.3.2" version = ">= v0.6.0"
source = "github.com/ddelnano/xenserver" source = "github.com/ddelnano/xenserver"
} }
} }
@ -47,8 +47,7 @@ locals {
} }
source "xenserver-iso" "centos8-netinstall" { source "xenserver-iso" "centos8-netinstall" {
iso_checksum = "07a8e59c42cc086ec4c49bdce4fae5a17b077dea" iso_checksum = "sha1:07a8e59c42cc086ec4c49bdce4fae5a17b077dea"
iso_checksum_type = "sha1"
iso_url = "http://mirrors.ocf.berkeley.edu/centos/8.3.2011/isos/x86_64/CentOS-8.3.2011-x86_64-boot.iso" 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 sr_iso_name = var.sr_iso_name

View File

@ -1,4 +1,13 @@
#cloud-config #cloud-config
# hack for cloud-init per:
# https://github.com/leakespeake/packer/blob/3f3e361751b4be9326b66771d96f2519bc8f885e/builders/vmware/vsphere-iso/ubuntu-server-20-04/hcl2/http/ubuntu-server-subiquity/user-data
runcmd:
# to enable true auto-install for Ubuntu 20.04 with cloud-init nocloud (eliminates "Continue with autoinstall?" prompt)
- [eval, 'echo $(cat /proc/cmdline) "autoinstall" > /root/cmdline']
- [eval, 'mount -n --bind -o ro /root/cmdline /proc/cmdline']
- [eval, 'snap restart subiquity.subiquity-service']
autoinstall: autoinstall:
version: 1 version: 1
identity: identity:
@ -6,6 +15,8 @@ autoinstall:
# This is the crypted pass of 'ubuntu' # This is the crypted pass of 'ubuntu'
password: "$6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0" password: "$6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0"
username: testuser username: testuser
packages:
- xe-guest-utilities
ssh: ssh:
install-server: yes install-server: yes
allow-pw: yes allow-pw: yes

View File

@ -1,12 +1,43 @@
packer { packer {
required_plugins { required_plugins {
xenserver= { xenserver= {
version = ">= v0.3.2" version = ">= v0.5.2"
source = "github.com/ddelnano/xenserver" 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
# 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
# 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" { variable "remote_host" {
type = string type = string
description = "The ip or fqdn of your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_HOST'" description = "The ip or fqdn of your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_HOST'"
@ -42,15 +73,9 @@ variable "sr_name" {
description = "The name of the SR to packer will use" description = "The name of the SR to packer will use"
} }
locals {
timestamp = regex_replace(timestamp(), "[- TZ:]", "")
}
source "xenserver-iso" "ubuntu-2004" { source "xenserver-iso" "ubuntu-2004" {
iso_checksum = "d1f2bf834bbe9bb43faf16f9be992a6f3935e65be0edece1dee2aa6eb1767423" iso_checksum = "sha256:${local.ubuntu_sha256.0}"
iso_checksum_type = "sha256" iso_url = "https://releases.ubuntu.com/${local.ubuntu_version}/ubuntu-${local.ubuntu_version}.${local.ubuntu_url_path.0}-live-server-amd64.iso"
iso_url = "http://releases.ubuntu.com/20.04/ubuntu-20.04.2-live-server-amd64.iso"
sr_iso_name = var.sr_iso_name sr_iso_name = var.sr_iso_name
sr_name = var.sr_name sr_name = var.sr_name
@ -60,17 +85,17 @@ source "xenserver-iso" "ubuntu-2004" {
remote_password = var.remote_password remote_password = var.remote_password
remote_username = var.remote_username remote_username = var.remote_username
vm_name = "packer-ubuntu-2004-${local.timestamp}" # Change this to match the ISO of ubuntu you are using in the iso_url variable
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_description = "Build started: ${local.timestamp}"
vm_memory = 4096 vm_memory = 4096
disk_size = 20000 disk_size = 30720
http_directory = "examples/http/ubuntu-2004" floppy_files = [
boot_command = [ "examples/http/ubuntu-2004/meta-data",
"<esc><f6> autoinstall ds=nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/<enter><wait>", "examples/http/ubuntu-2004/user-data",
"<f6><wait><esc><wait> autoinstall ds=nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/<enter><wait>"
] ]
boot_wait = "10s"
ssh_username = "testuser" ssh_username = "testuser"
ssh_password = "ubuntu" ssh_password = "ubuntu"
@ -83,4 +108,4 @@ source "xenserver-iso" "ubuntu-2004" {
build { build {
sources = ["xenserver-iso.ubuntu-2004"] sources = ["xenserver-iso.ubuntu-2004"]
} }

105
go.mod
View File

@ -1,15 +1,104 @@
module github.com/xenserver/packer-builder-xenserver module github.com/xenserver/packer-builder-xenserver
go 1.16 go 1.20
require ( require (
github.com/amfranz/go-xmlrpc-client v0.0.0-20190612172737-76858463955d github.com/amfranz/go-xmlrpc-client v0.0.0-20190612172737-76858463955d
github.com/hashicorp/hcl/v2 v2.8.0 github.com/hashicorp/hcl/v2 v2.20.1
github.com/hashicorp/packer-plugin-sdk v0.1.0 github.com/hashicorp/packer-plugin-sdk v0.3.0
github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/terra-farm/go-xen-api-client v0.0.2
github.com/terra-farm/go-xen-api-client v0.0.1 github.com/zclconf/go-cty v1.14.4
github.com/zclconf/go-cty v1.7.0 golang.org/x/crypto v0.24.0
golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
) )
require (
cloud.google.com/go v0.110.0 // indirect
cloud.google.com/go/compute v1.19.1 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v0.13.0 // indirect
cloud.google.com/go/storage v1.28.1 // indirect
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect
github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/armon/go-metrics v0.3.9 // indirect
github.com/aws/aws-sdk-go v1.40.34 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/dylanmei/iso8601 v0.1.0 // indirect
github.com/fatih/color v1.12.0 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gofrs/uuid v4.0.0+incompatible // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
github.com/hashicorp/consul/api v1.10.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter/gcs/v2 v2.1.0 // indirect
github.com/hashicorp/go-getter/s3/v2 v2.1.0 // indirect
github.com/hashicorp/go-getter/v2 v2.1.0 // indirect
github.com/hashicorp/go-hclog v0.16.2 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/hashicorp/go-version v1.3.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/serf v0.9.5 // indirect
github.com/hashicorp/vault/api v1.1.1 // indirect
github.com/hashicorp/vault/sdk v0.2.1 // indirect
github.com/hashicorp/yamux v0.0.0-20210826001029-26ff87cf9493 // indirect
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 // indirect
github.com/masterzen/winrm v0.0.0-20210623064412-3b76017826b0 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-isatty v0.0.13 // indirect
github.com/mitchellh/go-fs v0.0.0-20180402235330-b7b9ca407fff // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/iochan v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/mitchellh/reflectwalk v1.0.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/packer-community/winrmcp v0.0.0-20180921211025-c76d91c1e7db // indirect
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
github.com/pkg/sftp v1.13.2 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/ugorji/go/codec v1.2.6 // indirect
github.com/ulikunitz/xz v0.5.10 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/oauth2 v0.7.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/term v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.114.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
google.golang.org/grpc v1.56.3 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
replace github.com/zclconf/go-cty => github.com/nywilken/go-cty v1.13.3 // added by packer-sdc fix as noted in github.com/hashicorp/packer-plugin-sdk/issues/187

735
go.sum

File diff suppressed because it is too large Load Diff

18
main.go
View File

@ -6,30 +6,16 @@ import (
"github.com/xenserver/packer-builder-xenserver/builder/xenserver/iso" "github.com/xenserver/packer-builder-xenserver/builder/xenserver/iso"
"github.com/xenserver/packer-builder-xenserver/builder/xenserver/xva" "github.com/xenserver/packer-builder-xenserver/builder/xenserver/xva"
"github.com/xenserver/packer-builder-xenserver/version"
"github.com/hashicorp/packer-plugin-sdk/plugin" "github.com/hashicorp/packer-plugin-sdk/plugin"
"github.com/hashicorp/packer-plugin-sdk/version"
)
var (
// Version is the main version number that is being run at the moment.
Version = "v0.3.0"
// VersionPrerelease is A pre-release marker for the Version. If this is ""
// (empty string) then it means that it is a final release. Otherwise, this
// is a pre-release such as "dev" (in development), "beta", "rc1", etc.
VersionPrerelease = ""
// PluginVersion is used by the plugin set to allow Packer to recognize
// what version this plugin is.
PluginVersion = version.InitializePluginVersion(Version, VersionPrerelease)
) )
func main() { func main() {
pps := plugin.NewSet() pps := plugin.NewSet()
pps.RegisterBuilder("iso", new(iso.Builder)) pps.RegisterBuilder("iso", new(iso.Builder))
pps.RegisterBuilder("xva", new(xva.Builder)) pps.RegisterBuilder("xva", new(xva.Builder))
pps.SetVersion(PluginVersion) pps.SetVersion(version.PluginVersion)
err := pps.Run() err := pps.Run()
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err.Error()) fmt.Fprintln(os.Stderr, err.Error())

View File

@ -1,6 +0,0 @@
{
"builders": [{
"type": "xenserver-iso",
"tools_iso_name": "guest-tools.iso"
}]
}

19
version/version.go Normal file
View File

@ -0,0 +1,19 @@
package version
import (
"github.com/hashicorp/packer-plugin-sdk/version"
)
var (
// Version is the main version number that is being run at the moment.
Version = "v0.6.0"
// VersionPrerelease is A pre-release marker for the Version. If this is ""
// (empty string) then it means that it is a final release. Otherwise, this
// is a pre-release such as "dev" (in development), "beta", "rc1", etc.
VersionPrerelease = "dev"
// PluginVersion is used by the plugin set to allow Packer to recognize
// what version this plugin is.
PluginVersion = version.InitializePluginVersion(Version, VersionPrerelease)
)