Compare commits

...

1348 Commits

Author SHA1 Message Date
David Dymko
e1f70147d9
vultr remote docs (#11070) 2021-06-08 15:00:03 +02:00
Brandon Romano
6e037aa84b
Merge pull request #11063 from hashicorp/ks.updates-alert-banner-hashiconf
chore: updates alert banner data
2021-06-08 04:22:14 -07:00
Wilken Rivera
4ab255caba
Update absolute links to relative (#11068)
* Update absolute links to relative

* Update packer-integration-program.mdx

Fix case for component names
2021-06-04 11:58:51 +02:00
Jeff Escalante
2b26376180
rotate algolia api key (#11055) 2021-06-03 15:05:22 -04:00
Yoan Blanc
36a7b28b5f
fix: print unchanged formatted file when using stdin (#11047)
Signed-off-by: Yoan Blanc <yoan@dosimple.ch>
2021-06-03 14:02:42 +02:00
Adrien Delorme
4be9dfd183
Say so when an only or an except option did not match anything (#11050)
* Say so when an only or an except option did not match anything
2021-06-03 13:50:34 +02:00
Adrien Delorme
98990fc34e
hcl2_upgrade: allow to hcl2_upgrade with unknown builders, just log errors (#11049) 2021-06-03 13:41:16 +02:00
Jimmy Merritello
21833e7324
Merge pull request #11065 from jmfury/jm.packer-homepage-update
[Website] Update the homepage
2021-06-02 15:48:12 -05:00
Jimmy Merritello
3e3e013be5
Update the homepage 2021-06-02 14:00:34 -05:00
Andy Bettisworth
940180fb5b
spelling (#11064) 2021-06-02 15:18:37 +02:00
Wilken Rivera
1aa7a1b3f8 workflows/issue-comment-created.yml: Add GH token input
Addresses reported error at
https://github.com/hashicorp/packer/runs/2722241524?check_suite_focus=true
2021-06-01 20:45:34 -04:00
Kendall Strautman
86007b04aa chore: updates alert banner data 2021-06-01 14:01:15 -07:00
Wilken Rivera
488e6d80aa .github/workflows/lock.yml: Fix ISO 8601 date format 2021-05-27 13:50:05 -04:00
Wilken Rivera
0a05b834d7
remove hashibot (#11053)
* Replace `closed_issue_locker` HashiBot action with GitHub action

Related to: #11043

* Replace  with GitHub action

* Replace  with GitHub action
2021-05-27 12:58:58 -04:00
Megan Marsh
f80da79b85
Merge pull request #11046 from hashicorp/extract_oneandone
Extract 1&1 builder
2021-05-25 08:44:25 -07:00
Wilken Rivera
f3f58b1c39
Add Packer Integration Program page (#11042)
* Initial draft of Packer Integration Program docs page

- [ ] Add text from program document.
- [ ] Fix image alignment
- [ ] Fix Checklist alignment (remove bullets if possible)
- [ ] Validate with program team

* Fix broken markdown

* fix styling on centered image and checklist

* revert package-lock update

* Update packer-integration-program.mdx

Fix a few formatting issues

Co-authored-by: Jeff Escalante <jescalan@users.noreply.github.com>
2021-05-25 09:22:12 -04:00
sylviamoss
8eb85ac0e5 put back empty datasource folder 2021-05-25 14:49:45 +02:00
sylviamoss
444605c127 vendor oneandone 2021-05-25 14:46:44 +02:00
sylviamoss
e3010fa817 extract oneandone and add remote docs 2021-05-25 14:26:22 +02:00
Megan Marsh
638be57e43
document gotcha around third party plugins (#11032)
* document gotcha around third party plugins
* Update website/content/docs/commands/hcl2_upgrade.mdx

Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2021-05-25 13:55:25 +02:00
Sylvia Moss
69572b442a
Add tip about using local instead of locals for complex cases (#11036)
* add tip about using local instead of locals

* Apply suggestions from code review

Co-authored-by: Megan Marsh <megan@hashicorp.com>

Co-authored-by: Wilken Rivera <wilken@hashicorp.com>
Co-authored-by: Megan Marsh <megan@hashicorp.com>
2021-05-24 21:50:35 -04:00
Jeff Escalante
f07813e14d
fix a typo on the downloads page (#11044) 2021-05-24 16:45:52 -04:00
Megan Marsh
5a14b11f2e update changelog 2021-05-19 15:24:38 -07:00
Megan Marsh
fe6077fc85
Merge pull request #11024 from hashicorp/remove_veewee_guide
Remove veewee guide
2021-05-18 13:57:05 -07:00
Megan Marsh
df89b4b52c
Merge pull request #11025 from hashicorp/remove_isotime_guide
Remove isotime guide
2021-05-18 13:31:36 -07:00
Megan Marsh
70739cf1a1
Merge pull request #11030 from hashicorp/remove_comment_guide
delete comment guide, moving contents to the comment section of the t…
2021-05-18 13:19:13 -07:00
Megan Marsh
ca513aa028 upgrade to azure v0.0.3 2021-05-18 09:56:39 -07:00
Megan Marsh
57639e8330 remove workflow-tips-and-tricks pages 2021-05-18 09:49:35 -07:00
Megan Marsh
41c0668d6e delete comment guide, moving contents to the comment section of the template engine docs for json templates 2021-05-18 09:43:42 -07:00
Megan Marsh
b6a9da11a2 clarify template variable warning 2021-05-18 09:21:26 -07:00
Megan Marsh
a3daf4c686 escape backticks 2021-05-18 09:18:40 -07:00
Megan Marsh
d9b874f118 tweak engine docs to contain guide docs for isotime
remove docs page
2021-05-18 09:08:25 -07:00
Megan Marsh
1d4a8e7ba2 delete veewee references. Veewee hasn't been updated for three years, and the veewee-to-packer library for even longer. This page gets almost no views. 2021-05-18 08:44:45 -07:00
Ilya Voronin
6867456a72
Implemented DEFAULT_NAME handling for datasource plugins (#11026) 2021-05-18 10:47:43 +02:00
Brandon Romano
b6db1ac319
Merge pull request #11023 from hashicorp/br.hashiconf-banner
Adds AlertBanner to promote HashiConf EU
2021-05-17 15:32:16 -07:00
Brandon Romano
5a290aabef Adds AlertBanner to promote HashiConf EU 2021-05-17 15:07:18 -07:00
Megan Marsh
cb09e62fac
Merge pull request #11017 from hashicorp/d-hcl2upgrade-tutorial
Add link to the new HCL2 upgrade command tutorial
2021-05-14 11:34:16 -07:00
Wilken Rivera
d24fa1d8ad Add link to the new HCL2 upgrade command tutorial
This change replaces the from JSON v1 guide with a redirect to the
released hcl2_upgrade command tutorial on learn.hashicorp.com
2021-05-14 14:17:25 -04:00
Wilken Rivera
c262467413
Extract Azure plugin components from Packer (#10979)
* Remove Azure plugin components and docs

* Add Azure plugin to vendored_plugins

* Updates Azure to use remote plugin docs

* Revendor packer-plugin-azure at v0.0.2

* Update to new version of the Packer plugin SDK v0.2.1
* Update to the official version of go-getter@v2.0.0
* Update salt provisioner to use new go-getter API

* Update vendored plugins to working versions

This changes fixes an issue with the go.sum for the Azure plugin.
It also revendors the plugins for puppet, chef, and ansible as v0.0.1
of those plugins where not usable.
2021-05-13 16:13:21 -04:00
Wilken Rivera
a8db14ab6b
Fix broken links (#11016) 2021-05-13 12:16:04 -04:00
Geoffrey Grosenbach
f900049fc2
Fix links to Learn (#11014)
Some links to introductory tutorials were incorrect after some URLs changed. This fixes the links and the redirects.
2021-05-13 12:15:02 -04:00
Megan Marsh
f24599ecca
Merge pull request #11005 from ryapric/packer-docs-build-kvm-in-container
Rough guide-doc update for QEMU KVM builds from within containers
2021-05-11 10:04:11 -07:00
Ryan J. Price
32dc0aa731 Remove extra parenthesis 2021-05-11 11:00:08 -05:00
Sergio Conde Gómez
f6f2469d4d
fix: HCL "index" function now actually returns the index of the element (#11008) 2021-05-11 10:24:46 +02:00
Ryan J. Price
f26a764b8a Clarify paragraph wording 2021-05-10 20:32:23 -05:00
Ryan J. Price
09676ac699 Missed VMWare in CICD Guide change 2021-05-10 20:27:37 -05:00
Ryan J. Price
90b6747e3d Edit CICD website guide to be more clear 2021-05-10 20:24:37 -05:00
Megan Marsh
8c93297eb0
update docs to use double quotes, which works on more shells (#11009) 2021-05-10 16:00:53 -04:00
Ryan J. Price
627cbcdcba Rought guide-doc update for QEMU KVM builds from within containers 2021-05-08 17:03:23 -05:00
Steph Gosling
1e51ed9df9
fix: specify a string for name rather than a variable which is not supported (#10987) 2021-05-07 11:02:03 +02:00
Zachary Shilton
17899731ea
website: support hidden pages in nav-data (#10993)
* website: bump to docs-page prerelease with hidden page support

* website: remove temporary check for hidden pages, now covered by docs-page

* website: bump to stable docs-page, w next-mdx-remote bump

* website: bump to latest markdown-page
2021-05-06 13:19:26 -04:00
Kendall Strautman
a9c2283ee5
chore(website): adds ts config, upgrades deps (#10905)
* chore(website): adds ts config, upgrades deps

* chore: adjust ts config option

* chore: upgrade deps

* fix: subnav active path routing

* style(home): update integrations bg color

* chore: upgrade deps

* style: fix body copy color

* style: fix product downloads page height

* feat: updates favicon

* chore(downloads): upgrade to prerelease

* chore: upgrades product download page to stable

* chore: update favicon.ico
2021-05-03 10:58:09 -07:00
Megan Marsh
5555987e4d clean up changelog entries 2021-04-27 11:55:45 -07:00
Megan Marsh
b66a8b783a update changelog 2021-04-26 14:46:55 -07:00
Megan Marsh
28567dedb8
Merge pull request #10977 from ShiChangkuo/huaweicloud_plugin
website: add huaweicloud remote plugin
2021-04-26 11:35:06 -07:00
Megan Marsh
69705f3e40
Merge pull request #10978 from hashicorp/azr_invalid_prov_pause_before
Fix Invalid provprovisioner pause_before panic
2021-04-26 11:31:42 -07:00
Adrien Delorme
bf939b7474 Update types.build.provisioners.go
if pause_before is invalid, that's an error
2021-04-26 17:37:24 +02:00
Adrien Delorme
e60a7e60b9 add test to repro #10975 2021-04-26 17:31:22 +02:00
ShiChangkuo
05ef5590a5 website: add huaweicloud remote plugin 2021-04-26 20:24:50 +08:00
Megan Marsh
4ebc09f08f
Merge pull request #10863 from notchairmk/az-sig-account
azure arm: support for shared image gallery storage account type
2021-04-23 16:57:58 -07:00
Taylor Chaparro
9441a69ad1 azure builder: add support for shared image gallery storage account type 2021-04-23 16:57:24 -07:00
Taylor Chaparro
c0902d7519 azure builder: use struct for publishing shared image gallery image version 2021-04-23 16:56:38 -07:00
Megan Marsh
61db31e8ae
Merge pull request #10045 from ContigoRed/azure_keep_os_disk
Azure: arm builder: adding keep_os_disk parameter to control OS disk deletion
2021-04-23 16:55:17 -07:00
Megan Marsh
1788d29567 fix 2021-04-23 16:50:41 -07:00
Contigo Red
82a1f017aa azure: arm builder: adding keep_os_disk parameter to control OS disk deletion.
keep_os_disk: auto generated help
azure: arm builder: add disk os to artifact
azure: arm builder: fmt'ed artifact_test.go
2021-04-23 12:36:09 -07:00
Zachary Shilton
95ed4443bb
website: check for unlinked content, rm split-out vagrant content (#10958) 2021-04-23 17:04:20 +02:00
Sylvia Moss
0bd7b20bb8
website: add the possibility to fetch a local docs.zip for remote plugins (#10973) 2021-04-23 16:33:32 +02:00
Megan Marsh
8a3912c54b
Merge pull request #10938 from AHuusom/master
Added custom nicname and osdiskname
2021-04-22 11:05:19 -07:00
Adrien Delorme
38837848f9
Breakout yandex (#10970) 2021-04-22 17:03:14 +02:00
Sylvia Moss
e681669c70
Remove codecov config file (#10969) 2021-04-22 16:58:43 +02:00
Sylvia Moss
58bf783a2f
Update plugins badge (#10968) 2021-04-22 16:58:17 +02:00
Sylvia Moss
bcb25f1916
Extract Tencent Cloud (#10967)
* extract and vendor tencentcloud plugin

* fix fmt
2021-04-22 15:21:34 +02:00
Adrien Delorme
ef612c0eb1
Breakout hcloud (#10966)
* Delete hetzner-cloud.mdx

* delete hcloud builder

* use hcloud plugin

* up mods

* use github.com/hashicorp/packer-plugin-hcloud v0.0.1
2021-04-22 14:52:07 +02:00
Sylvia Moss
972497589e
extract and vendor lxc and lxd (#10965) 2021-04-22 14:21:23 +02:00
Adrien Delorme
2cd296874e
Triton plugin breakout (#10963) 2021-04-22 14:06:30 +02:00
Megan Marsh
f161f2bed2
extract oracle plugin (#10962) 2021-04-22 11:50:00 +02:00
Megan Marsh
6b59525408
remove digitalocean directories, revendor, add to vendored_plugins, regenerate code, and update website paths (#10961) 2021-04-22 11:45:27 +02:00
Megan Marsh
d0a15f9a15
Merge pull request #10956 from hashicorp/extract-converge
Extract converge provisioner
2021-04-21 13:40:15 -07:00
Megan Marsh
af37f53439
Extract vagrant (#10960)
* remove vagrant, rework website

* regenerate command/plugin, and go mod tidy
2021-04-21 16:31:28 -04:00
Wilken Rivera
d0588580fa Empty commit to trigger Vercel 2021-04-21 16:14:50 -04:00
Megan Marsh
ccbd0a29cc
remove outdatedlinode codeowners (#10957) 2021-04-21 15:38:35 -04:00
Zachary Shilton
d08aa6f6b0
website: update readme (#10931)
* website: bump to nextjs-scripts prerelease

* website: update stale sections in readme

* website: bump nextjs-scripts to latest prerelease

* website: update docs-sidebar section to prep for shared section

* website: update readme with latest blocks

* website: revert bump to nextjs-scripts, deferred

* website: bump to latest nextjs-scripts
2021-04-21 15:35:52 -04:00
Wilken Rivera
bb511e9592 Extract converge provisioner 2021-04-21 14:19:34 -04:00
Megan Marsh
b3ba270f2d fix typo and regenerate 2021-04-21 11:19:16 -07:00
Sylvia Moss
4be2c350bf
extract and vendor ucloud (#10953) 2021-04-21 13:25:04 -04:00
Megan Marsh
bc35a737c0
remove codecov from repo (#10955) 2021-04-21 13:22:34 -04:00
Megan Marsh
b5666b84cd
Extract jdcloud (#10946)
* delete jdcloud builder dir, revendor, regenerate, add to vendored_plugins

* change website pathing

* Extract linode (#10947)

* started extracting linode

* revendor linode

* clean up vendoring
2021-04-21 10:55:41 -04:00
Sylvia Moss
469f033c36
remove and vendor hyperv (#10952) 2021-04-21 16:32:34 +02:00
Sylvia Moss
2db338e322
Extract Hyperone (#10949) 2021-04-21 15:08:38 +02:00
Adrien Delorme
0f6a081724
Remove the vendor dir (#10916)
* update ci scripts
2021-04-21 10:52:55 +02:00
Megan Marsh
4b093aab78
Merge pull request #10934 from hashicorp/extract_cloudstack
Extract cloudstack
2021-04-20 13:52:36 -07:00
Megan Marsh
5145893ae5 update website 2021-04-20 13:47:37 -07:00
Megan Marsh
9044deeb05 Delete cloudstack dir, revendor 2021-04-20 13:46:11 -07:00
Megan Marsh
dc63b9a7a4
Merge pull request #10943 from hashicorp/extract-puppet
Extract Puppet plugins
2021-04-20 13:44:20 -07:00
Megan Marsh
d8c3584b46
Merge pull request #10921 from hashicorp/extract-chef
Extract Chef Plugins
2021-04-20 13:42:55 -07:00
Wilken Rivera
386f7c3f56 Remove duplicate routs from rebase 2021-04-20 15:27:21 -04:00
Wilken Rivera
8bf03cbca7 Vendor packer-plugin-puppet 2021-04-20 15:27:21 -04:00
Wilken Rivera
eb6527c8b6 Remove Puppet components and docs 2021-04-20 15:27:21 -04:00
Wilken Rivera
fd028b71b3 Add remote docs 2021-04-20 15:27:21 -04:00
Wilken Rivera
0ec3ad3db1 Add remote docs 2021-04-20 15:27:21 -04:00
Wilken Rivera
a29f3340c2 Vendor packer-plugin-chef 2021-04-20 15:26:56 -04:00
Wilken Rivera
45dfb97ff4 Add remote docs 2021-04-20 15:26:56 -04:00
Wilken Rivera
30bcf44c2c Remove Chef components and docs 2021-04-20 15:25:08 -04:00
Megan Marsh
2da9c21733
Merge pull request #10944 from hashicorp/openstack-extraction-followup
Remove reference to openstackbuilder
2021-04-20 11:01:30 -07:00
Wilken Rivera
987080a409 Remove reference to openstackbuilder 2021-04-20 13:54:57 -04:00
Anders Huusom
ed4ca8e6dc formatted code 2021-04-20 19:53:49 +02:00
Megan Marsh
9bdb809edd
Merge pull request #10933 from hashicorp/extract_openstack
extract openstack into its own plugin
2021-04-20 10:28:00 -07:00
Megan Marsh
88192f1fdd delete openstack files 2021-04-20 10:17:14 -07:00
Megan Marsh
6fa213235f extract and revendor
update website nav
2021-04-20 10:17:10 -07:00
Megan Marsh
af34218909
Merge pull request #10932 from hashicorp/remove-alicloud
extract alicloud plugin to its own repo
2021-04-20 10:16:41 -07:00
Megan Marsh
2dbfef5750
Update website/data/docs-remote-plugins.json
Co-authored-by: Wilken Rivera <wilken@hashicorp.com>
2021-04-20 10:11:32 -07:00
Megan Marsh
2f927177d9 fix website 2021-04-20 09:54:49 -07:00
Megan Marsh
50fadc4118 remove from website, add remote docs 2021-04-20 09:54:49 -07:00
Megan Marsh
b54121a72d delete and revendor alicloud plugin 2021-04-20 09:54:45 -07:00
Adrien Delorme
4de2954d01
Scaleway plugin breakout (#10939)
* use vendored scaleway plugin

* wipe out scaleway

* vendor vendors

* use remote docs

* go get github.com/hashicorp/packer-plugin-scaleway@v0.0.1

* empty commit
2021-04-20 11:59:59 -04:00
Sylvia Moss
25a999978b
Remove Parallels plugin (#10936) 2021-04-20 17:46:42 +02:00
Sylvia Moss
d6904502ac
Extract outscale (#10941)
* remove outscale, vendor it and add remote docs

* fix lint

* add community plugin tier

* Update go.mod

* up mods

Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2021-04-20 17:18:45 +02:00
Wilken Rivera
2061aa9e69
Add pluginTier to community plugins (#10942) 2021-04-20 10:49:35 -04:00
Zachary Shilton
cbe06050b4
website: enable plugin tier override (#10919)
* website: enable plugin tier override

* website: validate remote plugins config pluginTier
2021-04-20 10:28:41 -04:00
Anders Huusom
de86b45848 removed obsolete line 2021-04-20 15:54:29 +02:00
Anders Huusom
770124207c added TempOSDiskName definition 2021-04-20 15:51:16 +02:00
Adrien Delorme
d22ba61ae0
ncloud breakout (#10937) 2021-04-20 15:09:11 +02:00
Adrien Delorme
9eaad88ac0
Move proxmox builder out + vendor it (#10930)
* use vendored proxmox builders

* Update docs-nav-data.json

remove proxmox ref

* Update docs-remote-plugins.json

* remove builder/proxmox dir

* remove website/content/docs/builders/proxmox/

* up vendors

* Update modules.txt

* Update HTTPConfig-not-required.mdx

* Update HTTPConfig-not-required.mdx

* tidy mod

* fmt

* Update modules.txt
2021-04-20 14:59:34 +02:00
Anders Huusom
dbe6010510 Added custom nicname and osdiskname 2021-04-20 14:16:27 +02:00
Megan Marsh
20faaef05c
Merge pull request #10929 from hashicorp/extract_qemu
Extract QEMU plugin
2021-04-19 15:39:44 -07:00
Megan Marsh
d0a4a71da8
Merge pull request #10927 from hashicorp/fix_typo
Fix TEMPATE to TEMPLATE in fmt cmd help text
2021-04-19 09:24:50 -07:00
sylviamoss
3af472be9a update qemu to latest version 2021-04-19 17:47:09 +02:00
sylviamoss
5a00020830 add qemu to docs-remote-plugins.json 2021-04-19 17:45:51 +02:00
Adrien Delorme
6094c97998 Update docs-remote-plugins.json
order alphabetically
2021-04-19 17:20:46 +02:00
Adrien Delorme
1a41eac70b Update vendored_plugins.go
order alphabetically
2021-04-19 17:05:21 +02:00
sylviamoss
7a85b7328e vendor qemu plugin 2021-04-19 16:32:04 +02:00
Sylvia Moss
3dac34766c
add legacy_isotime docs (#10928) 2021-04-19 16:29:43 +02:00
sylviamoss
642ed07476 remote qemu plugin 2021-04-19 16:28:12 +02:00
Sylvia Moss
88f8feecfe
Extract vmware plugin (#10920) 2021-04-19 14:28:48 +02:00
sylviamoss
b448c3182c fix TEMPATE to TEMPLATE in fmt cmd 2021-04-19 14:07:22 +02:00
Adrien Delorme
9230a06920
move googlecompute plugin to github.com/hashicorp/packer-plugin-googlecompute (#10890) 2021-04-19 11:10:15 +02:00
Sylvia Moss
16658a9f47
Extract virtualbox plugin (#10910) 2021-04-16 17:38:02 +02:00
Wilken Rivera
ceb96d061a
Extract ansible plugins (#10912)
* Remove ansible components and docs

* Vendored packer-plugin-ansible

* Add remote ansible docs
2021-04-16 10:31:09 -04:00
Romain Lecat
bb1a025f60
Add outscale-mgo to osc codeowners (#10917) 2021-04-16 15:25:44 +02:00
Adrien Delorme
87ba7258b3
Use packer-sdc in packer + remove mapstructure-to-hcl2 & struct-markdown (#10913)
* start using `go:generate packer-sdc struct-markdown`

* Update Makefile

remove @go install ./cmd/struct-markdown

* run go generate for struct-markdown

* use //go:generate packer-sdc mapstructure-to-hcl2

* run go generate for mapstructure-to-hcl2

* remove struct-markdown and mapstructure-to-hcl2

* vendor vendors
2021-04-16 11:52:03 +02:00
Megan Marsh
da312e2785
Merge pull request #10896 from hashicorp/extract_vsphere
Extract vSphere plugin
2021-04-15 16:30:27 -07:00
Megan Marsh
84af0ba6da go mod tidy 2021-04-15 16:25:58 -07:00
sylviamoss
3c6b7841bc fix vsphere link 2021-04-15 16:25:36 -07:00
sylviamoss
c7ee5f1efd update packer-plugin-vsphere and sdk 2021-04-15 16:25:36 -07:00
sylviamoss
a00846102b add vsphere to docs-remote-plugins.json 2021-04-15 16:25:36 -07:00
sylviamoss
41c66d6935 vendor vsphere plugin 2021-04-15 16:25:31 -07:00
sylviamoss
f6854f5528 update go vendor 2021-04-15 16:24:57 -07:00
sylviamoss
38fe79948b remove vsphere components and docs 2021-04-15 16:24:57 -07:00
Daniel Finneran
a6c5958c67
Adds bzip2 support to post-processor (#10867)
* compress post processor: add bzip2 + tests

* post-processor/compress/post-processor_test.go: refactor tests and add tests for bzip2

* post-processor_test.go: test write/read for all compression algos

* check artifact.Destroy() errors

* close archive before deleting it

Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2021-04-15 18:05:09 +02:00
Jeff Escalante
c17f236e85
Upgrade Downloads Page (#10907)
* upgrade downloads page

* fix syntax errors on builders/ncloud page
2021-04-14 14:51:29 -04:00
Megan Marsh
bb5d7b6c40
Merge pull request #10870 from NaverCloudPlatform/master
Support ncloud vpc version
2021-04-13 10:32:16 -07:00
sangkyu-kim
1ea5a547e2
Merge branch 'master' into master 2021-04-13 13:46:48 +09:00
Megan Marsh
86b8ce8df0
Postprocessor only docs (#10899)
* add a note for only/except from cli to the post-processor template section

* typo; missing space

* Update website/content/docs/templates/hcl_templates/blocks/build/post-processor.mdx

Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>

* tweak wording

Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-04-12 15:39:27 -04:00
Megan Marsh
b51bf9250e
Merge pull request #10900 from hashicorp/digitalocean-import-docs-fix
Update URL to custom-images overview page
2021-04-12 12:18:00 -07:00
Wilken Rivera
2d5a32629a Update URL to custom-images overview page 2021-04-12 10:30:25 -04:00
Kerim Satirli
3e2db82cab
fixes typo (#10894) 2021-04-09 11:59:08 +02:00
Megan Marsh
bc9dd69669
Merge pull request #10880 from hashicorp/amazon_acc_test
Add plugin acceptance test using the Amazon plugin
2021-04-08 13:31:32 -07:00
Megan Marsh
734e91b97c
Merge pull request #10878 from hashicorp/rewrite_acctests
Move acctest pkg from the SDK to core and update acceptance tests
2021-04-08 13:21:18 -07:00
Zachary Shilton
ab0d1ee363
website: fix edit links for remote plugins (#10884)
* website: fix issue with edits links, use branch name, not version

* website: patch layout shift issue related to global style

* website: update plugin config docs with sourceBranch

* website: tweak spacing above plugin tier label

* website: add note on default value for sourceBranch
2021-04-08 10:09:58 -04:00
Kerim Satirli
cf94fd1778
switches JSON and HCL2 tabs (#10888)
* switches JSON and HCL2 tabs for all provisioners

* corrects `packer` to `Packer`

* corrects `http` to `HTTP`

* corrects typos and highlighting consistency issues

* corrects typos and highlighting consistency issues

* corrects typos and highlighting consistency issues

* `ansible` -> `Ansible`

* `packer fmt` for HCL2 blocks in provisioners

* linting and spelling

* fixes formatting

* fixes formatting

* Update website/content/docs/provisioners/ansible.mdx

Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>

* fixes formatting

* improves example

* generate stuff

Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2021-04-08 15:02:57 +02:00
George Wilson
15a2e59bba
Autogenerated docs for ansible local provisioner (#10829) 2021-04-08 12:18:49 +02:00
Kerim Satirli
8c4eb5f4aa
corrects default value and adds highlighting (#10886)
* value is expected to be `ssh` not `SSH`

* highlighting default values
2021-04-08 12:02:05 +02:00
Kendall Strautman
86788220a9
Merge pull request #10875 from hashicorp/ks.style/branding-refresh
style(website): upgrade react-components, colors, logos
2021-04-07 08:02:13 -07:00
Kerim Satirli
e3bcb4f2ac
adds highlighting to locals stanza (#10881) 2021-04-07 16:38:23 +02:00
Kendall Strautman
ccd0430fda
Update website/pages/downloads/style.css
Co-authored-by: Zachary Shilton <4624598+zchsh@users.noreply.github.com>
2021-04-07 07:35:05 -07:00
sylviamoss
49474f8f37 add plugin acceptance test using amazon plugin 2021-04-07 16:21:15 +02:00
sylviamoss
e0614cabf4 move acctest pkg from sdk to core and update acceptance tests 2021-04-07 11:52:19 +02:00
Shaun McEvoy
eaec3e5564
Add Image Storage Locations field to Google Compute Import post-processor (#10864)
* add image storage locations to Google Compute Import
2021-04-07 10:36:08 +02:00
James
eaaf22dcde
builder/digitalocean: support ecdsa, ed25519, dsa temporary key types via packer-plugin-sdk/communicator step… (#10856)
* support ecdsa, ed25519 temporary key algos via temporary_key_pair_algorith config

* builder/digitalocean: improve public key marshalling error handling

* builder/digitalocean: use packer-plugin-sdk to manage temporary ssh keys

* builder/digitalocean: clean up unused properties

Co-authored-by: tserkov <tserkov@penguin>
2021-04-07 10:33:05 +02:00
Qingchuan Hao
f2f33fa344
Correct SIG timout (#10816) 2021-04-07 10:00:17 +02:00
Kendall Strautman
9189f1228e chore: adds comment 2021-04-06 15:37:05 -07:00
Kendall Strautman
5e7b5729e6 style: override product-downloader colors 2021-04-06 15:35:23 -07:00
Megan Marsh
9365c90c0b revendor 2021-04-06 13:52:07 -07:00
Megan Marsh
f27bdf85f4 upgrade exoscale dependency 2021-04-06 13:51:14 -07:00
Kendall Strautman
9f7bb4da25 chore: fix deps 2021-04-06 13:48:00 -07:00
Kendall Strautman
b1967e99c7 chore: upgrade react-components, colors, logos 2021-04-06 13:47:58 -07:00
Brandon Romano
7efb41868f
Upgrade StackMenu to latest (#10874) 2021-04-06 16:40:48 -04:00
Wilken Rivera
260906c3e4
Add redirect for Docker post-processor pages (#10872)
Remote plugin docs such as Docker now fall under a top level path named
after the provider (e.g https://packer.io/docs/docker/...). This change
adds a redirect for the old URLs to the new location.
2021-04-06 10:37:05 -04:00
Roshan Padaki
f65e1d5d55
Fix tiny typo in hcl2_upgrade.mdx (#10868) 2021-04-06 11:51:10 +02:00
sangkyu.kim
23e8684aae fix lint, fmt, generate 2021-04-06 11:40:41 +09:00
sangkyu.kim
e22d9861aa update modules 2021-04-06 10:56:16 +09:00
sangkyu-kim
1c8fc65223
Merge branch 'master' into master 2021-04-06 10:35:58 +09:00
sangkyu-kim
42ca66752f
Merge pull request #1 from NaverCloudPlatform/ncloud_vpc
Implement VPC
2021-04-06 10:27:50 +09:00
packer-ci
33461126e2 Putting source back into Dev Mode 2021-04-05 23:32:25 +00:00
packer-ci
1f834e229a
Cut version 1.7.2 2021-04-05 22:55:12 +00:00
packer-ci
4417f8b3bf cut version 1.7.2 2021-04-05 22:55:11 +00:00
packer-ci
8db540a935 update changelog 2021-04-05 22:55:11 +00:00
Megan Marsh
e8780bf7b8 add massive warning about error logging to WrappedMain 2021-04-05 15:03:39 -07:00
Megan Marsh
3b0226d496 update changelog 2021-04-05 11:16:39 -07:00
Megan Marsh
4c08789642
Merge pull request #10850 from hashicorp/ui_fix
Switch to using ui once it is initialized
2021-04-05 11:14:20 -07:00
Wilken Rivera
634bf87d99 Update CHANGELOG 2021-04-05 12:51:05 -04:00
Wilken Rivera
d566419c45 Update unmaintained-plugins partial 2021-04-05 08:14:43 -04:00
Recai Oktaş
cce1f5c1e3
Update index.mdx (#10865)
Fix a minor typo.
2021-04-05 06:40:32 -04:00
elsnepal
7f26429a2a
feature[alicloud]: add ramrole to ecs instance (#10845)
* add RamRole support for ecs instance

* ordering of attributes

* run make generate
2021-04-02 15:02:13 -04:00
Sylvia Moss
d81c02b456
Fix primary disk resize on clone and add tests (#10848)
* Fix primary disk resize on clone and add tests

* remove commented tests
2021-04-02 14:41:11 -04:00
mmassez
794e83b171
Proxmox builder return first ipv4 address (#10858)
* Check if IP address is IPv4 before returning it

Returns the first IPv4 address instead of the first IP address which is an IPv6 for Windows VMs

* Updated the go module

* Reversed the order of checks

First check if it's a loopback and check for ipv4 afterwards
2021-04-02 14:37:20 -04:00
Zachary Shilton
58fb58c2ea
website: fix issue with bloated static props (#10860)
* website: fix issue with bloated static props

* website: remove script to check static props size
2021-04-02 11:29:31 -04:00
sangkyu.kim
15a9e1b20a skip validate product_code if empty 2021-04-02 18:18:59 +09:00
sangkyu.kim
3f23a5ec74 Remove getClassicServerImageProductList within block storage size 100GB 2021-04-02 16:38:58 +09:00
sangkyu.kim
f4cbb5d7dc fix length validation message 2021-04-02 14:55:05 +09:00
Wilken Rivera
c3e78d2c32 Update error messaging to bypass panicwrap only on non-recoverable
errors

While working on this change it was found that prefixing an error
message with the ErrorPrefix string would trigger a copyOutput function
that would copy any outputted string to Stderr, until a new ErrorPrefix
or Outprefix string is encountered in the output. During background runs of
Packer an error message with the ErrorPrefix was being outputted which
was causing all output, including Stdout, to be written to Stderr.

This change updates the logic to only override the Stdout logging
for non-recoverable errors. The idea being that any non-recoverable
error should bypass panicwrap so that user know an error occurred.
All other errors should follow the same behavior that we had prior to
Packer v1.7.1.

Closes #10855
2021-04-01 13:48:41 -04:00
Brian Choy
fb04fa7a25
Fix vault function docs example (#10851)
The given example is missing a `,`.
2021-04-01 15:18:06 +02:00
Zachary Shilton
830140157d
website: remove obselete nav data (#10811)
* website: remove obselete sidebar_title frontmatter from docs

* website: bump to latest docs-page

* website: update plugin creation and registration docs

* website: fix broken links
2021-03-31 15:07:00 -04:00
Megan Marsh
1b8e71ca1f switch to using ui once it is initialized 2021-03-31 11:44:40 -07:00
packer-ci
3e497e3712 Putting source back into Dev Mode 2021-03-31 17:32:59 +00:00
packer-ci
030da4b6b9
Cut version 1.7.1 2021-03-31 16:43:47 +00:00
packer-ci
3a437d4891 cut version 1.7.1 2021-03-31 16:43:45 +00:00
packer-ci
8c2f26718e update changelog 2021-03-31 16:43:45 +00:00
Wilken Rivera
076596cd3b Makefile: Update install steps for gox 2021-03-31 11:53:41 -04:00
Wilken Rivera
f541cd59ed Update packer-plugin-sdk to latest release
```
go get github.com/hashicorp/packer-plugin-sdk@v0.1.1
go mod tidy
go mod vendor
```
2021-03-31 10:36:41 -04:00
sangkyu.kim
cdcdf6a618 fix checking subnet type 2021-03-31 18:22:22 +09:00
sangkyu.kim
74434b3c3e create temporary ACG for VPC 2021-03-31 15:15:57 +09:00
Wilken Rivera
4b6891d6d5 Update CHANGELOG 2021-03-30 17:37:13 -04:00
Wilken Rivera
4746fc682d
Update version of packer-plugin-docker (#10847)
```
go get github.com/hashicorp/packer-plugin-docker@v0.0.7
go mod tidy
go mod vendor
```
2021-03-30 17:12:43 -04:00
Wilken Rivera
f6dbc3e78a
Update steps for generating the remote plugin docs.zip file (#10846)
* Update steps for generating the remote plugin docs.zip file

* Update a few typos

* Fix tabbing issue
2021-03-30 17:12:28 -04:00
Adrien Delorme
03d79a2c39
HCL2 variables: split validation from getting value (#10843)
* HCL2 variables: split validation from getting value, to only

This way we do this only once and log this only once. The errors were being ignored anyways.

* Update types.variables_test.go
2021-03-30 14:58:26 -04:00
Sylvia Moss
349a300213
Add new disk to existingDevices list (#10844)
* add new disk to existingDevices list

* add tests
2021-03-30 14:48:06 -04:00
Megan Marsh
dfc5d76108
Merge pull request #10833 from harveylowndes/add-oci-flex-shape-support
Support OCI flexible shapes
2021-03-30 10:11:47 -07:00
Adrien Delorme
77a29fc2f8
Allow to have dynamic blocks in a build block + tests (#10825)
This :
* allows to have a `build.dynamic` block
* add tests
* makes sure to show a correct message when a source was not found
  * display only name of source (instead of a weird map printout) 
  * use a "Did you mean %q" feature where possible 


Because dynamic blocks need all variables to be evaluated and available, I moved parsing of everything that is not a variable to "after" variables are extrapolated. Meaning that dynamic block get expanded in the `init` phase and then only we start interpreting HCL2 content.

After #10819 fix #10657
2021-03-30 15:53:04 +02:00
sangkyu.kim
3a11352dfa Fix ncloud builder unhandled buildvar type 2021-03-30 13:59:59 +09:00
sangkyu.kim
56728a937b update ncloud guide 2021-03-30 11:53:42 +09:00
sangkyu.kim
f044a64014 fix test code 2021-03-29 22:51:04 +09:00
sangkyu.kim
cd370aaaad implement vpc environment 2021-03-29 22:51:04 +09:00
sangkyu.kim
af865b1591 update ncloud-sdk-go-v2 vendor 2021-03-29 22:51:03 +09:00
Sylvia Moss
a588808270
update v1.7.1 changelog (#10837) 2021-03-29 14:04:32 +02:00
Harvey Lowndes
b9b1cdf75f Address review comments 2021-03-29 12:57:10 +01:00
Kerim Satirli
2ac5fe894c
adds missing word (#10836) 2021-03-29 11:01:03 +02:00
Kaivalya Shah
fbb9429910
HCL2 example syntax changes (#10832)
An HCL2 example contained commas to separate the lines, and the metadata block did not have the equals sign, which is not valid.
2021-03-29 11:00:42 +02:00
Harvey Lowndes
cb359e8064 Update OCI docs for flex shapes
Update the docs to reflect flex shape additions. Also makes a fix to the mapstructure.
2021-03-26 12:26:52 +00:00
Adrien Delorme
a9bec7945e
remove .mdx extensions in links (#10823)
Some of them were added in #10800 some where already there
2021-03-25 14:02:21 +01:00
Sylvia Moss
505cbd2591
Vendor amazon plugin (#10800)
* remove amazon from core
* vendor amazon plugin
* remove website content
* Add amazon to docs-remote-plugins
* update amazon reference links in the documentation
* update amazon docs version to latest

Co-authored-by: Adrien Delorme <adrien.delorme@icloud.com>
2021-03-25 13:37:48 +01:00
GennadySpb
25fddf3199
Add release build for darwin/arm64 (#10804)
* Add release build for darwin/arm64

Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2021-03-25 13:34:21 +01:00
Ricardo Katz
166df2ce1d
correct provisioner typo (#10822)
Correct provision typo
2021-03-25 13:27:05 +01:00
Megan Marsh
755395faf8
Merge pull request #10820 from chrisroberts/force-no-direct-upload-to-vagrantcloud
Override direct upload based on box size
2021-03-24 14:50:49 -07:00
Megan Marsh
b958fe7a54
Merge pull request #10821 from zchsh/zs.fix-nested-plugin-urls
website: fix issue with .mdx in plugin docs URL paths
2021-03-24 14:10:14 -07:00
Zach Shilton
cc133ea250
website: fix issue with .mdx in URL paths 2021-03-24 16:39:29 -04:00
Chris Roberts
4ea4c0570f Add test coverage for direct upload file size limits 2021-03-24 10:54:11 -07:00
Chris Roberts
a665e6b822 Always include all upload steps regardless of configuration 2021-03-24 10:53:38 -07:00
Chris Roberts
2de91e4862 Check configuration before running callback for upload confirmation 2021-03-24 10:52:56 -07:00
Chris Roberts
3a11820a41 Adjust upload limit value and fix error value stored in state bag 2021-03-24 10:51:10 -07:00
Adrien Delorme
0e3fcb589b
Implicit required_plugin blocks (#10732)
* used components that don't have a required_plugin block will make Packer 'implicitly' require those. These components are manually selected and commented for now.
* add tests
 * docs
2021-03-24 11:31:39 +01:00
Wilken Rivera
70ceed1110 Update vendor modules 2021-03-23 17:41:43 -04:00
Wilken Rivera
82eedc8f02
Update packer docs to latest (#10814) 2021-03-23 17:02:44 -04:00
Wilken Rivera
1d53080625
Update script to exit on immediate failure (#10815) 2021-03-23 16:44:21 -04:00
Zachary Shilton
89931d0f2a
website: fixes and tweaks for plugin docs (#10812)
* website: sort nested plugin docs files

* website: allow ignored .md files in plugin docs folders

* website: allow plugin docs/README.md only as extra file

* website: fix issue with latest link for plugin docs.zip
2021-03-23 16:06:50 -04:00
Wilken Rivera
5e17dbeff2 Fix up regex in test 2021-03-23 14:39:45 -04:00
Wilken Rivera
d0512c6edd docs/amazon: Updated generated docs 2021-03-23 14:14:59 -04:00
Adrien Delorme
7732f7998c
Add http_content func to serve variables from HTTP @ preseed (#10801)
This imports hashicorp/packer-plugin-sdk#43

* code generate things
* update docs
* update guides
* update examples

We want to add a new guide.
2021-03-23 12:31:13 +01:00
Adrien Delorme
ff01e6715a
HCL2: add templatefile function (#10776)
* tests
* docs
2021-03-23 12:02:05 +01:00
Megan Marsh
edc19eb859
Merge pull request #10806 from onlydole/bugfix/hashicorp-typo
Update 'Hashicorp' to 'HashiCorp' in the Amazon Documentation
2021-03-22 11:20:53 -07:00
Taylor Dolezal
1bb5c455aa
Update 'Hashicorp' to 'HashiCorp' 2021-03-22 11:05:42 -07:00
Bryce Kalow
8c61ca174f
feat: adds should-build website script (#10779) 2021-03-22 10:21:59 -04:00
Kyle MacDonald
ef6093c4c3
Merge pull request #10764 from zchsh/zs.remote-plugin-zip-approach
website: Implement RFC MKTG-033
2021-03-22 09:59:38 -04:00
Marcus Weiner
4d9fb629c6
Allow using API tokens for Proxmox authentication (#10797) 2021-03-22 11:48:31 +01:00
Megan Marsh
0993c976fa
hcl2_upgrade escaped quotes fix (#10794)
* clean up extra quoting that can cause text template failures. when everyone else abandons you, regex will always be there.

* LINTING
2021-03-22 10:56:30 +01:00
outscale-mgo
1e312ebc21
Fix description that was ignored in Osc builder (#10792)
Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com>
2021-03-22 09:05:10 +01:00
Zach Shilton
b780da5750
website: run plugin docs check also on schedule 2021-03-20 21:59:34 -04:00
Zach Shilton
565ca6627c
website: revert test of plugin docs config validation 2021-03-20 21:51:42 -04:00
Zach Shilton
c100b56d44
website: clarify error message in plugin config check 2021-03-20 21:50:20 -04:00
Avi Miller
e6596a0a1d
[oracle-oci] Add support for E3/E4.Flex shapes
This addes an optional shape_config stanza which allows
you to specify how many ocpus and memory the Flex
instance should be allocated.

This required an upgrade of the OCI Go SDK version.

Signed-off-by: Avi Miller <avi.miller@oracle.com>
2021-03-21 12:46:21 +11:00
Zach Shilton
55012937a9
website: add comments to duo of plugin docs zip fns 2021-03-20 21:45:40 -04:00
Zach Shilton
15d467eaf1
website: fix outdated comment 2021-03-20 21:45:12 -04:00
Zach Shilton
ce896351b9
website: temporary change to double-check validation 2021-03-20 21:37:21 -04:00
Zach Shilton
fb0886b724
website: Implement basic validation for plugin docs config 2021-03-20 21:35:46 -04:00
Andrew Pryde
a915ec8e05 Upgrade oci-go-sdk to latest 2021-03-20 02:16:17 +00:00
Megan Marsh
667f930d3d
Merge pull request #10793 from hashicorp/update-changelog-plugin-extraction-notes
update CHANGELOG
2021-03-19 13:42:54 -07:00
Wilken Rivera
f2f65607eb update CHANGELOG 2021-03-19 14:32:05 -04:00
Megan Marsh
ecaff88af9
Merge pull request #10780 from hashicorp/fix_10728
add legacy_isotime hcl function
2021-03-19 09:51:24 -07:00
Megan Marsh
a40a782408 remove escaped dir 2021-03-19 09:28:30 -07:00
Brian Farrell
80f807de4d
Fix issue with test breaking default value when client_cert_token_timeout is missing (#10783) 2021-03-19 15:17:41 +01:00
Wilken Rivera
ac7c0f2f04
Update link in issue migrator config (#10791) 2021-03-19 09:48:58 -04:00
Adrien Delorme
e2e6bce4c4 Update hcl2_upgrade_test.go
show diffs with strings
2021-03-19 13:56:41 +01:00
jhawk28
9f647ba2bb
try to retype key if an error is received (#10541) 2021-03-19 13:27:05 +01:00
Wilken Rivera
7c6c399a38
Add hashibot configuration for transferring issues (#10785)
The added configuration will allow us to transfer open remote-plugin/* issues from
hashicorp/packer to their new respective repos. HashiBot issue transfer
only works with orgs it has write access to. Which is similar to how
GitHub's issue transfer feature works.
2021-03-19 12:47:32 +01:00
Adrien Delorme
d5ccf73e91
oci builder: Show key_file errors (#10774) 2021-03-19 11:59:10 +01:00
Megan Marsh
502708b86a
Refactor hcl2_upgrade (#10787) 2021-03-19 10:24:49 +01:00
sophia
9b641c9bfd Force NoDirectUpload for vagrantcloud if asset size > 5 GB 2021-03-18 17:22:27 -05:00
Zach Shilton
1d485988ea
website: bump timeout for vercel build polling 2021-03-18 15:31:04 -04:00
Zach Shilton
de12cd318d
website: remove outdated comment on plugin config entries 2021-03-18 15:10:02 -04:00
Zachary Shilton
597dcce2ab
website: fix tag vs version reference in README
Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-03-18 15:06:42 -04:00
Zachary Shilton
0f8a658a23
website: clarify tag vs version in error msg
Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-03-18 15:05:52 -04:00
Megan Marsh
4242cf3151 fix tests 2021-03-18 10:02:27 -07:00
Zach Shilton
618a3d42c6
website: clarify purpose of sourceUrl 2021-03-18 12:31:24 -04:00
Zach Shilton
203900e403
website: delete unused plugin-docs utilities 2021-03-18 12:26:27 -04:00
Zach Shilton
bece5c3c69
website: fix minor style issue in PluginTier component 2021-03-18 12:26:16 -04:00
Zach Shilton
9e03647ad7
website: update readme to reflect revised nav-data and plugin docs 2021-03-18 12:26:03 -04:00
Zach Shilton
e68e736b6c
website: add indexing for plugin docs content 2021-03-18 12:25:49 -04:00
Zach Shilton
26a572270d
website: add github action to flag plugin-docs issues 2021-03-18 12:25:36 -04:00
Zach Shilton
8b3e7e6f2f
website: use revised remote-plugin-docs server implementation
- also bumps to stable docs-page, and makes related api changes for intro and guides routes
2021-03-18 12:24:36 -04:00
Zach Shilton
341308c582
website: add refactored remote-plugin-docs utilities 2021-03-18 12:21:53 -04:00
Ace Eldeib
3227d3da43
clean up azure temporary managed os disk (#10713)
* clean up temporary managed os disk

* improve message for skipping disk deletion

Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>

* re-arrange osdisk/additional disk cleanup

Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>

* remove additional disk cleanup

* add some validation on scenarios

* alway clean up resources inside template cleanup

* tidy to master

* clarify naming and comments

Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>

* test: add acceptance testing for azure cleanup

* revert template changes

* fix err check

* delete resources in parallel with retry to avoid serial deletion

* nit: improve log message for transient deletion errors

* fix: typo

* remove unused func to make lint happy

Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-03-18 12:09:57 -04:00
Sylvia Moss
0f541aaf5e
Update CONTRIBUTING.md (#10782) 2021-03-18 16:24:34 +01:00
Megan Marsh
0ecc4b5e52 add annotation warning to isotime func usage 2021-03-17 16:06:19 -07:00
Megan Marsh
6986fb0e81 make upgrade set isotime func properly 2021-03-17 15:52:22 -07:00
Megan Marsh
a6f907c688 tests 2021-03-17 10:48:55 -07:00
Adrien Delorme
3e8641e30e
Delete formatted.pkr.hcl (#10775) 2021-03-17 14:41:46 +01:00
Sylvia Moss
d0737dcd17
skip DownloadPathKey and ShouldUploadISO on mapstructure-to-hcl2 (#10772) 2021-03-17 14:26:38 +01:00
Megan Marsh
f12c89bd84 add legacy_isotime function to hcl funcs 2021-03-16 13:33:43 -07:00
Megan Marsh
0b5f8901cc changelog 2021-03-16 09:59:49 -07:00
Megan Marsh
64a3219f69
fix error messaging in wrappedmain. Stderr gets eaten by panicwrap, so we need to write to stdout, which then gets unpacked into error and output messages using the ErrorPrefix and OutputPrefix (#10766) 2021-03-16 11:21:00 +01:00
Megan Marsh
60c961c021
Merge pull request #10457 from teddylear/feature/recursivefmt-2
Adding recursive flag to formatter to format subdirectories
2021-03-15 11:01:01 -07:00
Adrien Delorme
f32b67c3bb
Simplify error message when config file can't be "stat'd" (#10763)
* remove confusing message when a stat error happens while trying to list HCL2 files

* leave early if our first GetHCL2Files has errors
2021-03-15 14:07:07 +01:00
Adrien Delorme
160d932cce remove weir "Cannot tell wether " + path + " is a directory" error 2021-03-15 12:04:16 +01:00
Adrien Delorme
e0fe579837 un-remove tests 2021-03-15 12:00:19 +01:00
Adrien Delorme
fe21ff905d test that folders containing a - file won't hang forever 2021-03-15 11:51:21 +01:00
Adrien Delorme
8ee8420408 simplify return 2021-03-15 11:49:03 +01:00
Adrien Delorme
25ee6a19a6 flatten if a little 2021-03-15 11:48:13 +01:00
Adrien Delorme
a6321ac137 remove debug line 2021-03-15 11:46:07 +01:00
Adrien Delorme
832c0f2b2a actually run fmt tests and then remove debug statements 2021-03-15 11:41:14 +01:00
Kyle
33cf6bf454
Fix logic for checking for KMS keys (#10754) 2021-03-15 11:37:13 +01:00
teddylear
22d373c279 Adding more debug logic 2021-03-15 11:36:10 +01:00
Dom Del Nano
77ce2b39d8
Fix the version parsing in ChecksumFileEntry.init() so that plugins whose name contain v's can packer init (#10760)
* fix
* test
2021-03-15 11:31:21 +01:00
Shane Lee
4bbeec4733
Update urls for the bootstrap scripts used by salt-masterless provider (#10755)
* Fix salt masterless url. Use saltproject.io

* Specify Tls12
2021-03-12 14:59:34 -05:00
Sylvia Moss
7ae42bbb21
Update PULL_REQUEST_TEMPLATE.md (#10758) 2021-03-12 17:10:11 +01:00
finchr
d1254a5e48
Fix for issue #7413 - Allow non-zero exit codes for inspec provisioner (#10723) 2021-03-12 16:47:21 +01:00
Wilken Rivera
cf65b7b494
Remove remote plugin docs for exoscale (#10757)
* Remove remote plugin docs for exoscale

* Add link to github repo for Exoscale components
2021-03-12 10:13:52 -05:00
Adrien Delorme
be7d7313c5 add tests for piping fmt 2021-03-12 11:25:10 +01:00
Adrien Delorme
7d30a5d79d remove duplicate tests 2021-03-12 11:18:38 +01:00
Adrien Delorme
a115b428ac simplify fmt test case a little 2021-03-12 11:07:26 +01:00
Adrien Delorme
4e22147909 Merge remote-tracking branch 'origin/master' into pr/teddylear/10457 2021-03-12 10:38:04 +01:00
Megan Marsh
f1017a19d3 update changelog 2021-03-11 16:58:02 -08:00
Megan Marsh
3ced522659
Merge pull request #10750 from hashicorp/azr-plugin-real-world-examples
Give a list of working projects to checkout
2021-03-11 16:43:00 -08:00
Megan Marsh
6c8e997d19
Update website/content/docs/plugins/creation/index.mdx 2021-03-11 16:42:55 -08:00
Megan Marsh
44f0be2314
Merge pull request #10748 from hashicorp/fix_virtualbox_winrmhost
make Packer respect winrm_host flag in virtualbox connect func
2021-03-11 16:41:37 -08:00
Wilken Rivera
bf9bb7b5c7
Merge pull request #10738 from twiggy/patch-1
Wrap more than one extra var in quotes.
2021-03-11 18:43:49 -05:00
Thomas Dreibholz
1a5678dd86
Added VirtualBox ISO builder option to create additional disks (#10674) 2021-03-11 16:09:30 +01:00
Adrien Delorme
b2d692c33d Give a list of working projects to checkout 2021-03-11 11:48:23 +01:00
Megan Marsh
e8b3a0e3bf make virtualbox, hyperv, openstack, and parallels builders respect winrm_host by correctly passing communicator config Host() func to commhost instead of just SSHHost 2021-03-10 15:36:19 -08:00
Megan Marsh
9944031580
Merge pull request #10743 from hashicorp/fix_10547
modify logging to make overrides clearer in face of vagrant always st…
2021-03-10 09:49:26 -08:00
Megan Marsh
35604a98a7
actually use the partials created in code generation inside the digitalocean docs page (#10742) 2021-03-10 13:24:00 +01:00
Megan Marsh
8bb3df7121 modify logging to make overrides clearer in face of vagrant always streaming to stdout. Add tests for config override. Make sure that user overrides of ssh_host and ssh_port are respected. 2021-03-09 16:40:49 -08:00
Megan Marsh
d2ec658e78
Merge pull request #10724 from jkl73/image-project-update
Update public GCP image project as gce-uefi-images is be deprecated
2021-03-09 14:42:03 -08:00
Megan Marsh
bb54b8bf10
Merge pull request #10709 from hashicorp/stubout-post-processor-exoscale-import
Shim "exoscale-import" post-processor
2021-03-09 13:14:39 -08:00
Wilken Rivera
1e27138857
plugins: Update Packer plugin documentation with details for remote plugin docs (#10718)
* Add instructions for registering remote plugin documentation

* Add documentation to plugins page about tiers and namespaces

* Update tiers

* Update website/content/docs/plugins/creation/index.mdx

Co-authored-by: Megan Marsh <megan@hashicorp.com>

* Add missing section for single-component install

Co-authored-by: Megan Marsh <megan@hashicorp.com>
2021-03-09 13:06:11 -05:00
Wilken Rivera
3c282de6c3 Add maps for statically vendored components
This change adds a new set of maps for builders, provisioners, and
post-processors that store reference to components that were once part
of Packer and are now vendored. This file acts as a single place for
defining this vendored components, which are then merged into the main
components maps to be used in Packer.

Quick test to ensure the exoscale-import post-processor is still loaded
```
// Validate that exoscale-import is in the know post-procoessors list
~>  packer.test build docker_centos_shell_provisioner.pkr.hcl
Error: Unknown post-processor type "badlynamed-import"

  on docker_centos_shell_provisioner.pkr.hcl line 18:
  (source code not available)

known post-processors: [ucloud-import digitalocean-import docker-push
googlecompute-export manifest vsphere-template docker-tag vsphere checksum
docker-import exoscale-import yandex-export compress googlecompute-import
yandex-import vagrant-cloud alicloud-import amazon-import artifice shell-local
docker-save vagrant]

// Validate that exoscale-import get loaded
~>  packer.test build docker_centos_shell_provisioner.pkr.hcl
Error: Failed preparing post-processor-block "exoscale-import" ""

  on docker_centos_shell_provisioner.pkr.hcl line 18:
  (source code not available)

4 error(s) occurred:

* api_key must be set
* api_secret must be set
* image_bucket must be set
* template_zone must be set

==> Wait completed after 2 microseconds

==> Builds finished but no artifacts were created.
```
2021-03-09 10:09:13 -05:00
Wilken Rivera
beceace7b7 Move to remote plugin docs for exoscale 2021-03-09 10:04:04 -05:00
Wilken Rivera
6f23bc0d97 Vendor exoscale-import plugin
This change will vendor the new version of the exoscale-import
post-processor component, but remove all of its code from Packer. After
the v1.8.0 release this change should be removed entirely.

This vendor process is being used as a workaround for decoupling the
exoscale-import component without causing a breaking change in Packer.

Users of Exoscale are encouraged to leverage `packer init` for
installing the latest version of packer-plugin-exoscale.
2021-03-09 10:02:30 -05:00
Wilken Rivera
edd4567096 Remove plugin registration generation step
This change removes the generation of command/plugin.go so that plugin
registration can be managed manually. As we begin to break out plugins
we will need to begin modifying this file, possibly with stubs to allow
for the removal of plugins without breaking Packer's backwards
  compatibility with 1.7.0. After 1.8.0 is released we should be able to
  revet these changes so that we can continue to generate the plugin
  file for those plugins core to Packer.
2021-03-09 10:02:02 -05:00
Marc Falzon
9a1f2d0c97 fixup! Remove "exoscale-import" post-processor 2021-03-09 10:01:38 -05:00
Marc Falzon
125a2f1f76 Remove "exoscale-import" post-processor
This change removes the `exoscale-import` post-processor from the
upstream Packer repository, following extraction as a standalone plugin
in a dedicated repository (https://github.com/exoscale/packer-post-processor-exoscale-import)
2021-03-09 10:01:05 -05:00
Wilken Rivera
3ac5046260
Merge pull request #10727 from tasha-marreiros/feature/gcp-windows-password-timeout-#10717
#10717 make googlecompute windows password timeout configurable
2021-03-09 09:40:51 -05:00
Tasha Marreiros
8c18f8fa6d amend email 2021-03-09 09:01:07 +00:00
Megan Marsh
0ea92f6369
Merge pull request #10736 from dreibh/dreibh/virtualbox-options-2
More options for VirtualBox builder: nested virtualisation and RTC time base
2021-03-08 14:48:17 -08:00
twiggy
bf1046e970
Wrap more than one extra var in quotes.
When multiple extra vars are passed the list of vars must be wrapped in "s. At least with ansible-local it will not parse correctly leading to an error stating the second extra var is a playbook file that cannot be found.
2021-03-08 11:29:33 -06:00
Kris Fremen
de50cadb5c
docs: fix post-processor(checksum) hcl example. (#10734) 2021-03-08 13:03:39 +01:00
Thomas Dreibholz
4f2f9f8a1e
Formatting fix. 2021-03-08 12:37:00 +01:00
Thomas Dreibholz
68f810891f Ran "make generate". 2021-03-08 12:29:00 +01:00
Thomas Dreibholz
be8b2968bd Added options for VRAM size, 3D acceleration and EFI screen size. 2021-03-08 12:29:00 +01:00
Thomas Dreibholz
4c9f3eb9ca Added options for nested virtualisation and RTC time base. 2021-03-08 12:29:00 +01:00
Kennith Leung
f4caf5978f
doc: fix sources typo (#10733) 2021-03-08 10:34:05 +01:00
Megan Marsh
cd93957225
Merge pull request #10695 from hashicorp/docker_vendoring
Initial docker extraction
2021-03-05 16:26:55 -08:00
Megan Marsh
71b815a5fd reword commits 2021-03-05 16:07:32 -08:00
Wilken Rivera
79481ed7ec Add vendored components map as opposed to removing code generation for command/plugin.go 2021-03-05 15:44:04 -05:00
Wilken Rivera
a101d46589 update modules.txt 2021-03-05 15:33:35 -05:00
Wilken Rivera
3058c437a3 Register remote plugins docs with https://packer.io 2021-03-05 15:33:34 -05:00
Wilken Rivera
10e1573930 Remove docker documentation from website 2021-03-05 15:33:34 -05:00
Megan Marsh
c3e48ebb71 add vendored files 2021-03-05 15:33:34 -05:00
Megan Marsh
04cbcd7ae9 add docker vendoring to modules.txt 2021-03-05 15:33:34 -05:00
Megan Marsh
1c3c1f17d9 stop generating plugins file to make it possible to vendor plugins 2021-03-05 15:33:34 -05:00
Megan Marsh
9331afcf80 revendor 2021-03-05 15:33:34 -05:00
Megan Marsh
a5b0e37d7e docker extraction POC 2021-03-05 15:33:34 -05:00
Hosh
6b5a3dacd4
Fix multiple files downloading overwrites same file (#10711) 2021-03-05 18:06:47 +01:00
Sylvia Moss
610dde7f02
check for nil config map (#10730) 2021-03-05 11:10:00 +01:00
Forrest C. Shields II
9df637d1f3
Fix syntax in BlockDevice JSON example (#10719)
* Fix syntax in BlockDevice JSON example

Keys must be quoted in JSON.

* Update comment to match generated docs

Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-03-04 10:33:42 -05:00
Jiankun Lu
22cb31cb7b Update public GCP image project as gce-uefi-images is be deprecated 2021-03-03 16:12:25 -08:00
Wilken Rivera
10a5b0e7d8
Update HCL source example block (#10720) 2021-03-03 16:15:54 -05:00
Zachary Shilton
a906a1b426
docs: Enable docs from remote plugin (#10656)
* Add local components to build on new DocsPage functionality.

* Add new nav-data format, and placeholder remote-plugins config

* Bump to pre-release components and implement remote loading

- Migrates /docs to new DocsPage API, and adds remote plugin loading functionality
- Migrates /guides and /intro to new DocsPage API

* Remove now unused JS nav config

* Cut empty comment line
2021-03-03 10:13:50 -05:00
Zachary Shilton
16ccb8f685
Update readme logo for matched system + github appearances (#10715) 2021-03-03 10:07:34 -05:00
Kyle MacDonald
447a5b0286
readme: add white bg to packer logo in reamde.md (#10712)
- for better legibility when displaying in github’s dark-mode
2021-03-03 09:55:35 +01:00
Sylvia Moss
6ff6916429
Update README.md (#10710) 2021-03-02 12:21:45 +01:00
Blake Garner
0b1829ef88
Update to gopsutil v3.21.1 to allow builds to work for darwin arm64 (#10697)
* Update to v3.21.1 to allow builds to work for darwin arm64

Co-authored-by: Megan Marsh <megan@hashicorp.com>
Co-authored-by: Adrien Delorme <adrien.delorme@icloud.com>
2021-03-02 12:13:59 +01:00
Thomas Dreibholz
c5df930437
Added firmware option for QEMU builder (#10683) 2021-03-02 11:56:28 +01:00
Brian Farrell
273a720440
Add client_cert_token_timeout to address GH-9465 (#10528) 2021-03-02 11:51:18 +01:00
Megan Marsh
96b753f3b0
pin packer to golang 1.16 (#10702)
* pin packer to golang 1.16
* vet command/build_cancellation_test.go
2021-03-02 11:43:58 +01:00
Megan Marsh
751038cd6d
clarify onlyexcept docs further (#10679) 2021-03-01 11:45:58 +01:00
Alvaro Miranda Aguilera
eea215adf9
Update VBoxManageConfig-not-required.mdx (#10707)
replace indentation with spaces
2021-03-01 11:06:18 +01:00
Megan Marsh
5c2e47b3da
Merge pull request #10685 from hashicorp/hcl2_upgrade_variables_to_locals
hcl2_upgrade: Improve error message and transform every variable using template engine to a local
2021-02-26 13:09:47 -08:00
Megan Marsh
0ac4bbcb02
Merge pull request #10703 from kiddom-kq/small-docs-fix
Update index.mdx
2021-02-26 12:52:47 -08:00
kiddom-kq
824fe13bd5
Update index.mdx
While trying to get packer to:

1. Assume a role
2. use `auto` price for spot instances
2. Assign an instance profile to the provisioned instance, I hit this error:

```
The provided credentials do not have permission to create the service-linked role for EC2 Spot Instances.
```

Adding the `iam:CreateServiceLinkedRole` entitlement to the role that packer assumes was all I needed to do.
2021-02-26 12:15:15 -08:00
Wilken Rivera
1c6daa23ac
Add UpCloud builder to community builders page (#10689)
* Add UpCloud builder to community builders page

* Update plugin description
2021-02-26 11:31:22 -05:00
Megan Marsh
fbe6ebebf1
Merge pull request #10693 from hashicorp/docs-update-multi-component-bin-name
Update plugin location docs
2021-02-24 12:01:52 -08:00
Wilken Rivera
e441733cbd Update plugin location docs
This change updates the multi-component name to reflect the name
generated by the goreleaser configuration in packer-plugin-scaffolding.

It also adds a small call out about the SHA256SUM file that needs to be
present for binaries installed via `packer init` in case maintainers
want to test packer init locally without having to call out to GitHub.
2021-02-24 13:33:08 -05:00
Megan Marsh
b4b0df44b4
Merge pull request #9591 from Timdawson264/ebs-volume-snapshot
ebsvolume snapshot
2021-02-23 15:47:27 -08:00
Megan Marsh
25920b2bd3 remove unused mock fields 2021-02-23 10:38:15 -08:00
Megan Marsh
74a6c1987c change name of singular block device in loop to be less confusing; fix snapshot tests 2021-02-23 10:30:55 -08:00
Megan Marsh
160be7e773 refactor aws test tooling so we can apply common test function helpers to ebsvolume tests 2021-02-23 09:24:03 -08:00
Sylvia Moss
fc23eb9241
add missing provisioner override hcl docs (#10684) 2021-02-23 12:00:02 -05:00
sylviamoss
5ccbd27b72 Improve upgrade error and transform all variables with template eng to locals 2021-02-23 16:51:13 +01:00
sylviamoss
20e8f666d9 make locals out of variables with template engines 2021-02-23 14:18:43 +01:00
Sylvia Moss
ff5b55b560
chef-solo: json_string to HCL2 templates compatibility (#10655) 2021-02-23 11:17:32 +01:00
Megan Marsh
95fb13209a
Merge pull request #10680 from bbigras/patch-1
fix typo in website/content/docs/plugins/index.mdx
2021-02-22 15:57:55 -08:00
Bruno Bigras
5515d7293f
fix typo in website/content/docs/plugins/index.mdx 2021-02-22 23:30:11 +00:00
Megan Marsh
6107aa51ef
Merge pull request #10676 from hashicorp/hcl2_upgrade_variables_only
Allows hcl2_upgrade variables json file
2021-02-22 15:05:02 -08:00
Megan Marsh
d398487afd
Merge pull request #10671 from dreibh/dreibh/virtualbox-options
More options for the VirtualBox ISO builder
2021-02-22 14:45:19 -08:00
Tim Black
0f86c66f8b
Fix wrong link in post-processor docs (#10678) 2021-02-22 17:35:27 -05:00
Megan Marsh
822dcf93af
Merge pull request #10543 from arizvisa/GH-10009
Added a fallback to both the player and workstation drivers from the vmware builder when trying to determine the network-mapping configuration
2021-02-22 09:34:39 -08:00
Megan Marsh
11a7b4f74e
Merge pull request #10670 from mr-evilbit/patch-1
Update vagrant.mdx
2021-02-22 09:30:50 -08:00
Megan Marsh
ae1069d3df
Merge pull request #10503 from remyleone/timeout
scaleway: add support for timeout in shutdown step
2021-02-22 09:26:05 -08:00
sylviamoss
a1a5cf0113 upgrade variables with other variables 2021-02-22 17:16:19 +01:00
sylviamoss
60017822e0 add docs 2021-02-22 16:19:55 +01:00
sylviamoss
2016d6baec Fix panic on upgrading variables json file 2021-02-22 16:07:37 +01:00
Rémy Léone
2967fccfd7 Fix 2021-02-22 14:10:31 +01:00
Rémy Léone
95e8263280 Fix 2021-02-22 12:18:43 +01:00
Rémy Léone
1f4971f5ac Fix 2021-02-22 12:18:43 +01:00
Rémy Léone
44d19f160a fix 2021-02-22 12:18:43 +01:00
Rémy Léone
557bffc94a scaleway: add support for timeout in shutdown step 2021-02-22 12:18:42 +01:00
Megan Marsh
08fd0a7e33
add a brief explanation of the difference between vars and locals in the docs for vars and locals (#10664) 2021-02-22 11:33:20 +01:00
Megan Marsh
079786f8d0
remove this logline -- it is spammy and seems like a leftover dev debug line (#10665) 2021-02-22 11:20:44 +01:00
Megan Marsh
9a11fd4136
Update amazon sdk (#10668) 2021-02-22 11:18:48 +01:00
Ali Rizvi-Santiago
c7545c37dd Fixed an issue identified by @SwampDragons when checking if the networkmapper configuration file exists. 2021-02-21 05:32:30 -06:00
Thomas Dreibholz
2b35873dd9
Formatting fix. 2021-02-20 20:31:09 +01:00
Thomas Dreibholz
8226bc9d9f
Ran "make generate". 2021-02-20 20:23:47 +01:00
Thomas Dreibholz
ffa8b7de8a
Added option for the graphics controller. 2021-02-20 20:21:57 +01:00
Thomas Dreibholz
e9936cf0da
Added option for audio controller. 2021-02-20 20:09:16 +01:00
Thomas Dreibholz
eb4a6f30a0
Added option for NIC type. 2021-02-20 19:59:39 +01:00
Thomas Dreibholz
fa844543ec
Added options for chipset and firmware. 2021-02-20 19:59:06 +01:00
mr-evilbit
e8ccd5304b
Update vagrant.mdx
Add newbie friendly reminder that just running a 'vagrant up' in the Packer Vagrant builder output directory does not run the newly built and provisioned .box file.
2021-02-20 12:07:19 -05:00
Megan Marsh
fca92b1953
Merge pull request #10632 from dreibh/dreibh/virtualbox-virtio
VirtualBox builder: support for "virtio" storage and ISO drive
2021-02-20 07:41:05 -08:00
Thomas Dreibholz
a29075d6c1 Ran "make generate". 2021-02-20 15:29:37 +01:00
Thomas Dreibholz
7ad99c2c85 Added documentation comments. 2021-02-20 15:09:38 +01:00
Thomas Dreibholz
5385275836 Fixed formatting. 2021-02-20 15:09:38 +01:00
Thomas Dreibholz
591b1c2637 VirtualBox: added support for "virtio" ISO interface. 2021-02-20 15:09:38 +01:00
Thomas Dreibholz
f48d7e3990 VirtualBox: added support for "virtio" storage. 2021-02-20 15:09:38 +01:00
Megan Marsh
c9c65383e9
Merge pull request #10651 from sparshev/vmware_attach_snapshot
Added "attach_snapshot" parameter to vmware vmx builder
2021-02-19 15:14:35 -08:00
Megan Marsh
1ddbe4d9ce update changelog 2021-02-19 10:43:31 -08:00
Megan Marsh
dd167925d7
add machine readable to the cli help func and docs (#10658) 2021-02-19 11:17:47 +01:00
Taylor Chaparro
317e2da000
azure client sig fix: don't overwrite subscription id if unset (#10659) 2021-02-19 11:16:31 +01:00
Megan Marsh
c4a22e9a56
fix packer interpolation of packer log path (#10660) 2021-02-19 11:08:17 +01:00
Tim Dawson
aef74cd059 Fixed up after rebaseing 2021-02-19 14:09:23 +13:00
Sergei Parshev
b3b4559434
Added "attach_snapshot" parameter to vmware vmx builder 2021-02-18 15:16:28 -08:00
Tim Dawson
ac2ce0097c Fixed formatting 2021-02-19 11:09:55 +13:00
Tim Dawson
ca0b11028e Started instramenting some functions and building out unit tests for snapshot step.
Added some basic config tests.
2021-02-19 11:09:55 +13:00
Tim Dawson
b199ce9a22 Added snapshots to artifacts
Increased Snapshot wait timeout
2021-02-19 10:58:03 +13:00
Tim Dawson
0f83ba6ee6 Removed Rouge refrence to AMI creation in volume builder 2021-02-19 10:58:03 +13:00
Tim Dawson
3e754c9f3f Using new Polling config for snapshot step 2021-02-19 10:58:03 +13:00
Tim Dawson
7f0b41bb0e Refactored SnapshotConfig
Added Group and user permission to each snapshot
2021-02-19 10:58:03 +13:00
Tim Dawson
482a2c8232 Adding ebs-volume snapshot creation 2021-02-19 10:06:04 +13:00
Megan Marsh
3d55fa51d8
Merge pull request #10560 from trown/bump-oci-go-sdk
Update Oracle Go SDK
2021-02-18 11:46:02 -08:00
Sylvia Moss
37d05c85ff
upgrade pause_before (#10654) 2021-02-18 15:05:12 +01:00
dreic
ab89df9a88
Update Config-not-required.mdx (#10527) 2021-02-18 11:47:40 +01:00
Megan Marsh
00e503388e
change template parsing error to include warning about file extensions (#10652) 2021-02-18 09:59:30 +01:00
Adrien Delorme
bf5b4d63da tweak docs to trigger a re-release 2021-02-17 17:29:16 +01:00
packer-ci
21c6811334 Putting source back into Dev Mode 2021-02-17 16:12:20 +00:00
packer-ci
7ea4a779af
Cut version 1.7.0 2021-02-17 11:13:51 +00:00
packer-ci
a939671abb cut version 1.7.0 2021-02-17 11:13:50 +00:00
packer-ci
c6c047905d update changelog 2021-02-17 11:13:50 +00:00
Adrien Delorme
c6c8c88b74
Update CHANGELOG.md 2021-02-17 11:24:52 +01:00
Adrien Delorme
3b40127cb0
Update CHANGELOG.md 2021-02-17 11:24:31 +01:00
Adrien Delorme
993ae765e5
Prepare release (#10646)
* get github.com/hashicorp/packer-plugin-sdk@v0.0.14

* Update CHANGELOG.md

* Update CHANGELOG.md

* Update CHANGELOG.md
2021-02-17 11:22:08 +01:00
Sylvia Moss
201869d627
Update HCL2 and JSON example for amazon builders (#10645)
* move hcl2 example up over json to amazon-ebs
* switch hcl and json templates for all amazon builders
* fix json format
2021-02-17 10:32:13 +01:00
Megan Marsh
6ea7edf4e9 update changelog 2021-02-16 16:17:47 -08:00
Megan Marsh
99087d71bc
Merge pull request #10641 from zchsh/zs.bump-components
Bump components to remove md processing, fix theme
2021-02-16 14:33:17 -08:00
Megan Marsh
1710590418
Merge pull request #10633 from hashicorp/azr_init_no_magic_host
Packer init: remove host and namespace guessing
2021-02-16 14:32:20 -08:00
Megan Marsh
10d32bda6d
Merge pull request #10591 from neumayer/retry
Add retry strategies to oci calls
2021-02-16 13:59:26 -08:00
Megan Marsh
0d14df3020
Merge pull request #10635 from hashicorp/docs_small_changes
Docs small updates
2021-02-16 13:58:32 -08:00
Megan Marsh
2065de0b4f
Merge pull request #10642 from hashicorp/wilken_init_no_magic_host
github/getter: Adds a hostname check to Get function
2021-02-16 11:27:11 -08:00
Wilken Rivera
728c5a217d Add test case for non-github hostname
Tests results on current branch; install succeeded which was not expected
```
2021/02/16 14:02:24 ui: Installed plugin example.com/sylviamoss/comment v0.2.19 in "/tmp/pkr-test-cfg-dir-6_pkr_config458005728/example.com/sylviamoss/comment/packer-plugin-comment_v0.2.19_x5.0_linux_amd64"
    init_test.go:361: InitCommand.Run() = 0, want 1
    init_test.go:381: unexpected dir hash after init:   string(
        -       "h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
        +       "h1:iVtzkl/nVm2KiLvlz8rH56ME8QEqRxq8+XT2Lo6bzGU=",
          )
--- FAIL: TestInitCommand_Run (6.39s)
    --- PASS: TestInitCommand_Run/already-installed-no-op (0.01s)
        --- PASS: TestInitCommand_Run/already-installed-no-op/-subtest-0 (0.00s)
    --- PASS: TestInitCommand_Run/already-installed-upgrade (2.30s)
        --- PASS: TestInitCommand_Run/already-installed-upgrade/-subtest-0 (0.06s)
    --- PASS: TestInitCommand_Run/release-with-no-binary (0.17s)
    --- PASS: TestInitCommand_Run/manually-installed-single-component-plugin-works (1.32s)
        --- PASS: TestInitCommand_Run/manually-installed-single-component-plugin-works/-subtest-0 (0.01s)
    --- PASS: TestInitCommand_Run/manually-installed-single-component-plugin-old-api-fails (1.42s)
        --- PASS: TestInitCommand_Run/manually-installed-single-component-plugin-old-api-fails/-subtest-0 (0.01s)
    --- FAIL: TestInitCommand_Run/unsupported-non-github-source-address (1.18s)
```

Tests results after change with change in this branch
```
2021/02/16 14:03:14 [TRACE] getting available versions for the example.com/sylviamoss/comment plugin
2021/02/16 14:03:14 [TRACE] &{%!q(*github.Client=<nil>) "packer-getter-github-1.7.0-dev"} getter could not get release: example.com/sylviamoss/comment doesn't appear to be a valid github.com source address; check source and try again.
2021/02/16 14:03:14 [DEBUG] will try to install: []
2021/02/16 14:03:14 ui error: no release version found for the example.com/sylviamoss/comment plugin matching the constraint(s): "v0.2.19"
--- PASS: TestInitCommand_Run (5.38s)
    --- PASS: TestInitCommand_Run/already-installed-no-op (0.01s)
        --- PASS: TestInitCommand_Run/already-installed-no-op/-subtest-0 (0.00s)
    --- PASS: TestInitCommand_Run/already-installed-upgrade (2.08s)
        --- PASS: TestInitCommand_Run/already-installed-upgrade/-subtest-0 (0.07s)
    --- PASS: TestInitCommand_Run/release-with-no-binary (0.21s)
    --- PASS: TestInitCommand_Run/manually-installed-single-component-plugin-works (1.20s)
        --- PASS: TestInitCommand_Run/manually-installed-single-component-plugin-works/-subtest-0 (0.01s)
    --- PASS: TestInitCommand_Run/manually-installed-single-component-plugin-old-api-fails (1.88s)
        --- PASS: TestInitCommand_Run/manually-installed-single-component-plugin-old-api-fails/-subtest-0 (0.01s)
    --- PASS: TestInitCommand_Run/unsupported-non-github-source-address (0.00s)
```
2021-02-16 14:03:29 -05:00
Wilken Rivera
f48583c57e github/getter: Adds a hostname check to Get function
This change adds a simple hostname validation check to validate that a
plugins source address is github.com before continuing with the Get
call. An issue was encountered when using a hostname different from
github.com, where the getter would continue to pull a plugin from GitHub
even if the hostname was something like "example.com". See log details
below.

Before change
```
2021/02/16 12:49:41 [TRACE] fetching checksums file for the "0.0.2" version of the example.com/hashicorp/docker plugin in
"/home/wilken/.packer.d/plugins/example.com/hashicorp/docker"...

2021/02/16 12:49:41 [DEBUG] github-getter: getting "https://github.com/hashicorp/packer-plugin-docker/releases/download/v0.0.2/packer-plugin-docker_v0.0.2_SHA256SUMS"
2021/02/16 12:49:42 [TRACE] Ignoring remote binary packer-plugin-docker_v0.0.2_x5.0_linux_arm64.zip, wrong system, expected
2021/02/16 12:49:42 [TRACE] About to get: packer-plugin-docker_v0.0.2_x5.0_linux_amd64.zip
2021/02/16 12:49:42 [DEBUG] github-getter: getting "https://github.com/hashicorp/packer-plugin-docker/releases/download/v0.0.2/packer-plugin-docker_v0.0.2_x5.0_linux_amd64.zip"
```

After change
```
2021/02/16 13:36:32 [TRACE] for plugin example.com/hashicorp/docker found 0 matching installation(s)
2021/02/16 13:36:32 [TRACE] getting available versions for the the example.com/hashicorp/docker plugin
2021/02/16 13:36:32 [TRACE] &{%!q(*github.Client=<nil>) "packer-getter-github-1.7.0-dev"} getter could not get release: example.com/hashicorp/docker doesn't appear to be a valid github.com source address; check source and try again.
2021/02/16 13:36:32 [DEBUG] will try to install: []
2021/02/16 13:36:32 [INFO] (telemetry) Finalizing.  no release version found for the example.com/hashicorp/docker plugin matching the constraint(s): ">=v0.0.2"
2021/02/16 13:36:32 waiting for all plugin processes to complete...
```
2021-02-16 13:38:57 -05:00
Zach Shilton
6cc3933c77
Bump components to remove md processing, fix theme 2021-02-16 12:55:09 -05:00
Adrien Delorme
4409991887 add emojis to version table 2021-02-16 14:37:24 +01:00
sylviamoss
6e195f92e8 update components docs 2021-02-16 14:31:05 +01:00
Sylvia Moss
715fe51517
Update website/content/docs/commands/fix.mdx
Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2021-02-16 14:09:32 +01:00
Adrien Delorme
d2a8408577 update "how to comment in json" guide 2021-02-16 13:57:33 +01:00
Adrien Delorme
192e85951f packer build template.pkr.hcl in .github/CONTRIBUTING.md 2021-02-16 13:54:49 +01:00
Adrien Delorme
e2a337e0ea packer build template.pkr.hcl 2021-02-16 13:49:13 +01:00
sylviamoss
c29b9f957d reorder terminology 2021-02-16 12:51:49 +01:00
Sylvia Moss
514be931be
Update website/content/partials/guides/hcl2-beta-note.mdx
Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2021-02-16 12:48:39 +01:00
Sylvia Moss
1049db4f98
Update website/content/docs/commands/fix.mdx
Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2021-02-16 12:48:33 +01:00
sylviamoss
9ce9f49f4d fix types and add text to templates index 2021-02-16 12:48:07 +01:00
sylviamoss
47adccabf2 swtichs the sidebar order of HCL and JSON templates 2021-02-16 10:13:05 +01:00
sylviamoss
1a20146993 update command section 2021-02-16 10:08:47 +01:00
Glenn McDonald
496e3ed07b
Fix invalid link for env function docs (#10637) 2021-02-16 09:15:15 +01:00
sylviamoss
9718af4982 update hcl guides 2021-02-15 18:17:39 +01:00
Sylvia Moss
e0557f84e9
Add access config to generated amazon ami data source (#10634) 2021-02-15 17:35:03 +01:00
Adrien Delorme
f7ee3f8ead
Update website/content/guides/1.7-template-upgrade.mdx
Co-authored-by: Sylvia Moss <moss@hashicorp.com>
2021-02-15 17:24:56 +01:00
Adrien Delorme
8208f425c8 addrs: remove Plugin.ForDisplay func, the String one does the job
to make things less confusing
2021-02-15 15:32:42 +01:00
Adrien Delorme
516e919c5e Update init.mdx 2021-02-15 15:15:00 +01:00
Adrien Delorme
13b34e2c73 Update 1.7-template-upgrade.mdx 2021-02-15 15:13:36 +01:00
Adrien Delorme
ba87656273 Update CHANGELOG.md 2021-02-15 14:20:50 +01:00
Adrien Delorme
429262030f fix paths for windows ! 2021-02-15 14:11:00 +01:00
Adrien Delorme
4487152d1e cosmetic commit 2021-02-15 14:07:22 +01:00
Adrien Delorme
72e4dc4cb5 update docs to remove 'magic' required_plugin block usages 2021-02-15 13:58:58 +01:00
Adrien Delorme
7809242f41 quote template example 2021-02-15 13:47:40 +01:00
Adrien Delorme
632e918c52 Update plugins_test.go 2021-02-15 13:47:40 +01:00
Adrien Delorme
4cb94a67b0 Update types.variables.go 2021-02-15 13:47:40 +01:00
Adrien Delorme
029729225d tests and fixes 2021-02-15 13:47:39 +01:00
Adrien Delorme
aeecfcd422 show version constrain error in case it's handy 2021-02-15 13:47:39 +01:00
Adrien Delorme
9f545c28fe required_plugins: prevent using plugin = "version", and show an example 2021-02-15 13:47:39 +01:00
Adrien Delorme
fe12d53e77 addr: remove support for defaulting plugin namespace and host 2021-02-15 13:47:39 +01:00
Sylvia Moss
00fce3c46f
Add v1.7.0 template upgrade guide (#10615) 2021-02-15 11:38:11 +01:00
Megan Marsh
bd7b31853e
Multi plugin naming (#10608) 2021-02-15 11:10:43 +01:00
Megan Marsh
cac6b04546
update help text for hcl2_upgrade (#10624) 2021-02-15 11:03:44 +01:00
Megan Marsh
80ed988ffe
Hcl2 upgrade fix (#10625)
* fix random nil pointer dereference I found while debugging hcl2_upgrade issues

* fix hcl2_upgrade command by creating passthroughs for all text template fields
2021-02-15 10:40:21 +01:00
Megan Marsh
b20dea6aec
Merge pull request #10614 from hashicorp/azr_acc_test_old_single_component_plugins
Acc test "old style" single component plugins
2021-02-12 14:22:29 -08:00
Megan Marsh
4f5af3b919
Merge pull request #10619 from hashicorp/hcl2_upgrade_annotations
Add -with-annotation flag to hcl2_upgrade command
2021-02-12 14:17:10 -08:00
sylviamoss
e69410b633 fix lint 2021-02-12 15:38:44 +01:00
sylviamoss
855ba9775a add docs 2021-02-12 15:31:13 +01:00
sylviamoss
76e3d57cae add with-annotation flag to hcl2_upgrade 2021-02-12 15:18:53 +01:00
teddylear
0637601eda Fixing recursive formatting tests to work on all platforms 2021-02-11 22:08:36 -05:00
Adrien Delorme
7089e0854a rename setup func to avoid name conflict 2021-02-11 18:00:18 +01:00
Adrien Delorme
40c2b2a153 add manually-installed-single-component-plugin-old-api-fails 2021-02-11 16:55:30 +01:00
Adrien Delorme
3677069010 test: manually-installed-single-component-plugin-works 2021-02-11 16:35:08 +01:00
Adrien Delorme
b321c64c1e Update init_test.go 2021-02-11 15:26:33 +01:00
Adrien Delorme
ad0ce49cec fix tmpdir creation 2021-02-11 15:17:05 +01:00
Adrien Delorme
021044e963 put name first 2021-02-11 14:56:42 +01:00
Adrien Delorme
ba8484ee6b tests: pre make dir in case nothing happens 2021-02-11 14:49:52 +01:00
Adrien Delorme
3052e3c5d5 tests 2021-02-11 14:46:53 +01:00
Sylvia Moss
c5fca1f876
Make template documentation visible from components docs (#10611) 2021-02-11 14:21:06 +01:00
Adrien Delorme
915372c73d
get packer plugin sdk version 0.0.12 (#10612) 2021-02-11 14:14:04 +01:00
Adrien Delorme
37769c2b95
Change PKR_GITHUB_API_TOKEN to PACKER_GITHUB_API_TOKEN to stay consistent with other env var settings (#10588) 2021-02-11 13:54:25 +01:00
Trond Isak
2c08479825
add AWS API call retries on AMIGetFilteredImage (#10610) 2021-02-11 11:58:56 +01:00
Sylvia Moss
774c5903f6
Add error-cleanup-provisioner to HCL2 (#10604) 2021-02-11 10:23:15 +01:00
Megan Marsh
fd8e76636a
Merge pull request #10599 from hashicorp/extending-packer-updates
Extending packer updates
2021-02-10 16:05:56 -08:00
teddylear
d85286e228 Merging in master 2021-02-10 17:44:11 -05:00
Robert Neumayer
50a6732859 Use http constants and use switch instead of if 2021-02-10 16:46:00 +01:00
Wilken Rivera
4e2d2961b6 Update with suggestion from review 2021-02-10 10:37:24 -05:00
Wilken Rivera
926e287025
Apply suggestions from code review
Co-authored-by: Megan Marsh <megan@hashicorp.com>
Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2021-02-10 10:33:01 -05:00
Sylvia Moss
d28e6fe009
write timestamp local only when necessary (#10602) 2021-02-10 14:54:19 +01:00
Sylvia Moss
1e889078fd
add regex and regexall functions (#10601) 2021-02-10 11:58:20 +01:00
Calle Pettersson
6c77d28537
proxmox: Fix additional_iso_files (#10586) 2021-02-10 10:59:44 +01:00
Megan Marsh
92f384b52f update changelog 2021-02-09 14:08:27 -08:00
Wilken Rivera
29beb051c5 Fix borken URL 2021-02-09 15:37:03 -05:00
Wilken Rivera
bb03a321f2 Add distributing migrated plugins section 2021-02-09 15:28:03 -05:00
Wilken Rivera
25b2ab9082 guides/1-7-plugin-upgrade: Update migration guide
* Add text to call out the packer-sdk-migrator tool.
* Add text around the naming conventions for registering multi-plugins
2021-02-09 14:23:44 -05:00
Wilken Rivera
9986834a62 website/commands/init: Add blurb on plugin selection
This change adds text around how plugin selection for plugins defined in
a require_plugins block work. It also adds a small call out to users
that third party plugins are not verified by HashiCorp.
2021-02-09 12:19:15 -05:00
Sylvia Moss
368ccfe7c9
add profitbricks code owners (#10596) 2021-02-09 11:29:24 -05:00
Adrien Delorme
ffbb110167
Test running plugins with fake and fresh plugins (#10595)
* show error as to why plugin discovery failed
* allow to run more manual tests after a plugin installation
* test that a freshly installed external plugin can run
2021-02-09 17:07:59 +01:00
mflorin
9afaa5a21f
Profitbricks builder fixes (#10549) 2021-02-09 16:56:06 +01:00
Robert Neumayer
bcd60c3895 Improve retry policy 2021-02-09 16:16:10 +01:00
Sylvia Moss
f5006d0842
fix empty locals and source name with blank space (#10593) 2021-02-09 14:57:42 +01:00
Jessi
88c516b2d5
Add IMDSv2 support for AWS EBS builder (#10546) 2021-02-09 11:47:54 +01:00
Robert Neumayer
6b947edd04 Add retry strategies to oci calls
The oci api returns 429, among others in case a per-user rate limit is
hit. Currently our only mechanism to deal with this is to wait 5s
between the requests that poll for image availability (and export).

With a custom retry strategy we can handle more error situations while
putting less load on the api.
2021-02-09 09:33:43 +01:00
Bryce Kalow
d7bb60ea86
website: update next and nextjs-scripts (#10570)
website: update next and nextjs-scripts
2021-02-08 14:48:35 -06:00
Megan Marsh
08e67f8990
Merge pull request #10587 from hashicorp/azr_doc_init_less_highlights
Document init with less highlights
2021-02-08 11:09:04 -08:00
Wilken Rivera
8c3b3ca00f
Update website/content/docs/commands/init.mdx 2021-02-08 13:34:14 -05:00
Bryce Kalow
4a686ef66d chore: upgrade nextjs-scripts & next 2021-02-08 17:47:18 +00:00
Sylvia Moss
f616955ebc
Fix issue when loading datasource single plugin type (#10589) 2021-02-08 13:58:35 +01:00
Adrien Delorme
a1b2e71005
Update website/content/docs/commands/init.mdx
Co-authored-by: Sylvia Moss <moss@hashicorp.com>
2021-02-08 13:53:29 +01:00
Sylvia Moss
d53488db68
Add aws_secretsmanager transformation to hcl2_upgrade (#10553) 2021-02-08 11:28:26 +01:00
Adrien Delorme
b6cfe16444 Document the PKR_GITHUB_API_TOKEN setting in /configure#env vars 2021-02-08 10:59:04 +01:00
Adrien Delorme
4c02123142 init documentation: have less highlights and more text 2021-02-08 10:58:14 +01:00
teddylear
d3754e3021 Updating recursive formatter tests to be cleaner and table driven 2021-02-06 18:02:26 -05:00
Adrien Delorme
ab7e89781a empty commit to check if I can push 2021-02-06 18:02:26 -05:00
teddylear
40a97e29db Clean up recursive format tests to be more accurate 2021-02-06 18:02:26 -05:00
teddylear
93df53a275 Refactor recursive formatting test cases to be table driven 2021-02-06 18:02:26 -05:00
teddylear
6adf1f6659 Fixing recursive fmt tests syntax and adding test case when recursive
option is off
2021-02-06 18:02:26 -05:00
teddylear
261abe0cae Setting recursive fmt to false, updatting recursive fmt test to validate
formatted files
2021-02-06 18:02:26 -05:00
teddylear
ab4b3a8465 Adding recursive flag to formatter to format subdirectories 2021-02-06 18:02:23 -05:00
Megan Marsh
13320650f0
document builder id of artifact for each builder's output on website (#10580)
* document builder id of artifact for each builder's output on website

* document postprocessor artifact ids on website

* Fix links to new communicator page

Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-02-05 19:49:28 -05:00
Megan Marsh
2324f433f7
Merge pull request #10579 from hashicorp/fix-single-plugin-loading
Fix issue when loading single plugin type `packer-provisioner-comment` built with latest SDK
2021-02-05 14:06:27 -08:00
Megan Marsh
ece5e94c3d
remove dev line (#10578) 2021-02-05 16:47:41 -05:00
Wilken Rivera
ad239bd2b9
Fix markdown link checker issues (#10575)
* Remove exclusions for docs on master

* Update extending redirects with new page locations

* Update documentation links for SaltStack
2021-02-05 16:46:53 -05:00
Wilken Rivera
39d550054d Fix lint errors 2021-02-05 16:46:24 -05:00
Wilken Rivera
ef4d35097b Fix issue when loading single plugin type
This changes wraps the plugin client start call with an anonymous function so that Packer starts a
new plugin for each occurrence of a particular plugin block.

Before only one subprocess was being created causing subsquent calls to fail as it was trying start
an already started plugin subprocess.

Before Change
```
???????: failed loading comment: error dial unix /tmp/packer-plugin358226172: connect: no such file or directory
2021/02/05 16:09:13 On error:
2021/02/05 16:09:13 Waiting on builds to complete...

2021/02/05 16:09:13 Starting build run: null.basic-example
2021/02/05 16:09:13 Running builder:
2021/02/05 16:09:13 [INFO] (telemetry) Starting builder
  on examples/basic-example.pkr.hcl line 29:
  (source code not available)

dial unix /tmp/packer-plugin358226172: connect: no such file or directory

???????: failed loading comment: error dial unix /tmp/packer-plugin358226172: connect: no such file or directory

2021/02/05 16:09:13 packer.test plugin: [INFO] communicator disabled, will not connect
2021/02/05 16:09:13 packer.test plugin: Unable to load communicator config from state to populate provisionHookData
  on examples/basic-example.pkr.hcl line 38:
2021/02/05 16:09:13 packer.test plugin: Running the provision hook
  (source code not available)

dial unix /tmp/packer-plugin358226172: connect: no such file or directory

???????: failed loading comment: error dial unix /tmp/packer-plugin358226172: connect: no such file or directory

  on examples/basic-example.pkr.hcl line 42:
  (source code not available)

2021/02/05 16:09:13 [INFO] (telemetry) Starting provisioner comment
dial unix /tmp/packer-plugin358226172: connect: no such file or directory
```

After change
```

null.basic-example: output will be in this color.

==> null.basic-example:   ____                   _
==> null.basic-example:  | __ )    ___    __ _  (_)  _ __
==> null.basic-example:  |  _ \   / _ \  / _` | | | | '_ \
==> null.basic-example:  | |_) | |  __/ | (_| | | | | | | |
==> null.basic-example:  |____/   \___|  \__, | |_| |_| |_|
==> null.basic-example:                  |___/
==> null.basic-example:
==> null.basic-example: Running local shell script: /tmp/packer-shell646549657
    null.basic-example: This is a shell script
==> null.basic-example: Pausing at breakpoint provisioner.
==> null.basic-example: Press enter to continue.
==> null.basic-example: In the middle of Provisioning run
==> null.basic-example: Running local shell script: /tmp/packer-shell177279484
    null.basic-example: This is another shell script
==> null.basic-example:   _____               _
==> null.basic-example:  | ____|  _ __     __| |
==> null.basic-example:  |  _|   | '_ \   / _` |
==> null.basic-example:  | |___  | | | | | (_| |
==> null.basic-example:  |_____| |_| |_|  \__,_|
==> null.basic-example:
Build 'null.basic-example' finished after 1 second 32 milliseconds.

==> Wait completed after 1 second 32 milliseconds

==> Builds finished. The artifacts of successful builds are:
--> null.basic-example: Did not export anything. This is the null builder
 Please enter the commit message for your changes. Lines starting
```
2021-02-05 16:35:01 -05:00
Megan Marsh
a63ad19b0c
Merge pull request #10577 from hashicorp/fix_build_run_diags
plugin loading failure should be considered an error so build will no…
2021-02-05 13:31:40 -08:00
Megan Marsh
ca123721a6 plugin loading failure should be considered an error so build will not try to run 2021-02-05 11:06:52 -08:00
Alex Chan
540effbbc0
Correct the spelling of heirarchical/hierarchical (#10576) 2021-02-05 16:32:28 +01:00
Adrien Delorme
692433721d
Add some acceptance testing for Packer init commands (#10566) 2021-02-05 14:06:28 +01:00
Adrien Delorme
0f34592daa
packer init doc clarification (#10558)
* Packer has no state like Terraform has

* init command docs: tell where a plugin will be installed

* docs: add a note that packer init does not work with legacy JSON templates

* docs: add a not that packer init does not install single-plugin binaries

* the plugin getter => packer init

* Update init.mdx

* grammar

* link to how to install plugins manually

* Update website/content/docs/commands/init.mdx

Co-authored-by: Sylvia Moss <moss@hashicorp.com>

* Update website/content/docs/commands/init.mdx

Co-authored-by: Sylvia Moss <moss@hashicorp.com>

Co-authored-by: Sylvia Moss <moss@hashicorp.com>
2021-02-05 13:26:58 +01:00
Megan Marsh
ba1ad9ea15
Vsphere example update (#10574)
* fix ubuntu json template example

* add hcl template example

* add hcl alpine example

* add hcl versions of alpine and macos; update macos json

* add hcl version of windows template, call fix on windows json
2021-02-05 13:21:29 +01:00
Sylvia Moss
ef4afafde9
Fix force flag for hcl2 provisioners and post-processors (#10571) 2021-02-05 10:57:14 +01:00
Adrien Delorme
f588c46fb6
add some docs for the cache dir (#10568) 2021-02-05 10:56:03 +01:00
Adrien Delorme
1075120109
use the SDK version 0.0.11 (#10572) 2021-02-04 17:52:40 +01:00
Sylvia Moss
3ddb17ad86
Don't allow data sources to be used inside data sources (#10559) 2021-02-04 11:25:44 +01:00
Adrien Delorme
92ccd5fa1d
init: show successful installs in cyan (#10557) 2021-02-04 11:11:42 +01:00
Wilken Rivera
8ccd164f25
Update diagnostic detail to display list of PostProcessors (#10564) 2021-02-04 10:56:59 +01:00
John Trowbridge
30b0229fb4 Fix vendor 2021-02-03 12:26:24 -05:00
John Trowbridge
34b86c0228 Update Oracle Go SDK
Currently, the oracle-oci builder is broken, because it is unable
to read the key file provide by Oracle cloud. Updating to the
latest oci-go-sdk fixes the issue.
2021-02-03 10:44:12 -05:00
Adrien Delorme
ed091163be
HCL2 Parse packer.required_plugins block + packer init (#10304)
This adds the new `required_plugins` block to be nested under the packer block.

Example:
```hcl
packer {
  required_plugins {
    aws = {
      version = ">= 2.7.0"
      source = "azr/aws"
    }
    azure = ">= 2.7.0"
  }
}
```

For example on darwin_amd64 Packer will install those under :
* "${PACKER_HOME_DIR}/plugin/github.com/azr/amazon/packer-plugin-amazon_2.7.0_x5.0_darwin_amd64"
* "${PACKER_HOME_DIR}/plugin/github.com/hashicorp/azure/packer-plugin-azure_2.7.0_x5.0_darwin_amd64_x5"

+ docs
+ tests
2021-02-02 18:05:04 +01:00
Megan Marsh
ac014fc1c3
Merge pull request #10542 from MarckK/tags
edit examples of docker tags for post processor hcl syntax to be array of strings
2021-01-29 11:29:46 -08:00
Kara de la Marck
61f03cc137 docs: fix instructions to show docker tags for post processor hcl syntax as array of strings 2021-01-29 18:58:13 +00:00
Megan Marsh
18970bfbe4
Merge pull request #10534 from timblaktu/patch-1
Improve Documentation for Build-level Source Block
2021-01-27 14:01:47 -08:00
Tim Black
300604675b
Improve Documentation for Build-level Source Block
The docs for top-level and build-level source blocks did not make it clear enough, early enough in the page, how packer merges their contents and fails when ambiguities  arise from redefinition. I know the info it there, but it's at the end and I feel that my modification shortens the page overall while putting the most useful info front and center. 

Also, there is simply an error in the note at the end of this page, which further confuses the situation for new readers trying to use HCL and reuse source blocks. It's referring to a non-existent amazon source which is probably a past copy/paste error. 

It took me a day to get re-usable source blocks working, bc I skimmed the page at first (I know slap my wrist), but didn't really grasp what it was saying in the Note at the end, and found it confusing. It wasn't until I found the Issues and PRs related to this feature getting added last April/May that I realized how it was implemented that I started to grasp what this was saying.
2021-01-27 11:12:42 -08:00
Wilken Rivera
f36554fa0e
Update redirects and URLs to legacy JSON template docs (#10530) 2021-01-27 09:08:59 -05:00
Miguel Hernández
782cf058b5
Add 'skip_create_ami' option to the amazon-ebs builder (#10531) 2021-01-27 09:00:42 -05:00
Megan Marsh
a5a1344948
Merge pull request #10516 from hashicorp/fix_uint8_hcl
fix uint8
2021-01-26 10:22:13 -08:00
Megan Marsh
90fb09e52a linting 2021-01-26 10:09:29 -08:00
Megan Marsh
21df997061 Handle case where list is empty
Co-authored-by: Sylvia Moss <moss@hashicorp.com>
2021-01-26 10:02:16 -08:00
Megan Marsh
fbbda0f9d9
Sensitive locals (#10509)
* Allow locals to be delcared as individual blocks, and give them the Sensitive flag

* add docs for new local block

* linting

* add tests

* modified parsing to use schema, check for dupes properly

* update comment

fix wording a liiitle

* add tests for duplicate variables definition in two different files

* remove unnecessary slice initialisation

* fix crash by returning when decode error is hit

* parseLocalVariables: only treat a local vars if its not nil

also return in case of error
return locals in case of error too

* fix duplicate_locals test for windows

Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2021-01-26 10:21:44 +01:00
Megan Marsh
e3b14d888b create util function in hcl2 template that will load config values into hcl values without panicing if it finds something it cannot handle 2021-01-25 12:25:41 -08:00
Megan Marsh
c8d5d56f61 fix 2021-01-25 11:41:42 -08:00
Megan Marsh
a8c8d247bb fix uint8 2021-01-25 11:41:42 -08:00
Wilken Rivera
ea7fef699f
Test against deployment url (#10501)
* Test against deployment url

* Remove infinite redirect configuration

* Add DEPLOYMENT_URL for builds against master

* website: Update README

* tip on seconds

* Test with GHA timeout_minutes clause

* Add continue on error for poll job

* Add empty url check

* Move to pull-request path filter

* Remove www for packer.io

* Apply suggestions from code review

* Update path filter

Vercel deploys on any change under the website directory.

* Use custom action as test

Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2021-01-25 10:28:34 -05:00
Roman Mingazeev
e588029d6a
yandex: some fix (#10522) 2021-01-25 12:26:21 +01:00
Megan Marsh
c3266cc3b0
remove indexing from cdrom command and let qemu handle it (#10519) 2021-01-25 10:54:41 +01:00
Megan Marsh
37dcf6183c
skip credential validation if we are not exporting an image (#10520) 2021-01-25 10:53:51 +01:00
Megan Marsh
3242b7ee10
read iops and throughput as pointers so we can test for the nil case;… (#10518) 2021-01-25 10:49:37 +01:00
Wilken Rivera
48a31d1b6a
Slight markdown fixes (#10517) 2021-01-25 10:43:41 +01:00
Wilken Rivera
85bb4e7a1e
Merge pull request #10514 from hashicorp/fix_source_ami_docs
remove confusing from_scratch reference which is not relevant in this…
2021-01-22 12:54:28 -05:00
Megan Marsh
3aab42b770 remove confusing from_scratch reference which is not relevant in this config 2021-01-22 09:36:17 -08:00
Sylvia Moss
7d0578c5b7
add DatasourceOutput type to struct-markdown cmd (#10512) 2021-01-22 17:55:32 +01:00
Sylvia Moss
d1ada744e1
Aws Secrets Manager data sources (#10505) 2021-01-22 14:49:45 +01:00
Megan Marsh
e48a86ffba
Merge pull request #10504 from hashicorp/fix-ansible-docs-links
Update Ansible local links
2021-01-20 16:36:22 -08:00
Wilken Rivera
23b50e5a7a Update ansible local links 2021-01-20 16:21:07 -05:00
Megan Marsh
93008045cd
Merge pull request #10500 from hashicorp/format_stdin
enable Packer fmt to read from stdin
2021-01-20 11:47:55 -08:00
Megan Marsh
2b0996daa6 dont print filename if its reading from stdin 2021-01-20 11:30:50 -08:00
Sylvia Moss
3c7944624a
(3) Add amazon-ami data source (#10467) 2021-01-20 11:05:03 +01:00
Sylvia Moss
291121dd55
(2) Implement datasources (#10440) 2021-01-20 10:37:16 +01:00
Megan Marsh
40df74e95a linting 2021-01-19 15:34:18 -08:00
Megan Marsh
4323b49130 enable Packer fmt to read from stdin 2021-01-19 15:30:34 -08:00
Megan Marsh
ab98409069
Merge pull request #10488 from Direnol/yandex/update-dump-method
yandex/update-dump-method
2021-01-19 11:10:33 -08:00
Megan Marsh
71412fe465
Merge pull request #10489 from hashicorp/datasource_documentation
(1) Add Data Sources docs
2021-01-19 09:47:46 -08:00
Megan Marsh
a4a70e0bb8 Merge branch 'master' into datasource_documentation 2021-01-19 09:38:48 -08:00
Megan Marsh
24051f038b exclude patterns 2021-01-19 09:36:57 -08:00
fr123k
056ac4a3ea
Add skip_create_image option to the openstack builder (#10496) 2021-01-19 10:43:18 +01:00
Felix Hillingshaeuser
490616a301
Improve cloud init logging for proxmox builder (#10499) 2021-01-19 10:28:01 +01:00
Sylvia Moss
e44cb9d7e5
Add Amazon AMI data source to hcl_upgrade command (#10491) 2021-01-19 10:21:39 +01:00
Megan Marsh
4cb6e07900
Hcl beta tag (#10493)
* change beta tag

* remove beta tag from hcl2_upgrade comment

* add a partial to describe the legacy json limitations

* exclude legacy category from templates until it is deployed to the website
2021-01-18 15:08:04 +01:00
sylviamoss
95721df95c add amazon-ami output example 2021-01-18 13:53:57 +01:00
Sylvia Moss
78a48ea429
Update website/content/docs/templates/hcl_templates/datasources.mdx
Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2021-01-18 13:43:08 +01:00
Megan Marsh
94e22e6664
Merge pull request #10490 from marinsalinas/master
fix: [bsusurrogate] override bsu when omi root device is set
2021-01-15 15:55:23 -08:00
Megan Marsh
a9c4c056c9
Merge pull request #10458 from seventieskid/gcp-on-gitlab-using-docker
GCP add timeout to GCP metadata server read
2021-01-15 14:51:28 -08:00
Megan Marsh
378786dcd6 fix links 2021-01-15 14:25:44 -08:00
Megan Marsh
fde3a753c2 re-add datasource example to index that got lost in rebase 2021-01-15 14:23:16 -08:00
sylviamoss
f914335621 add data sources docs 2021-01-15 14:18:51 -08:00
Megan Marsh
1f963687be
Merge pull request #10486 from hashicorp/hcl_docs_refactor
HCL docs refactor
2021-01-15 13:59:37 -08:00
Megan Marsh
af796f0d38 soften language around legacy for now 2021-01-15 13:50:50 -08:00
Megan Marsh
86f326b391 dont use legacy in sidebar, for now 2021-01-15 13:49:10 -08:00
Wilken Rivera
a91a8ec63b Ignore new links from markdown link checker because site isnt live
use relative pathing in links
fix vagrant docs link
2021-01-15 13:42:10 -08:00
Wilken Rivera
8cb4acfb73
Merge pull request #10492 from hashicorp/website-redirects
redirects-next.js: Fix regex for builder redirects
2021-01-15 16:20:10 -05:00
Wilken Rivera
06f2b7822b redirects-next.js: Fix regex for builder redirects 2021-01-15 15:56:03 -05:00
Megan Marsh
e3b1af4711 change wording to soften 2021-01-15 11:59:36 -08:00
Megan Marsh
927b539ee1 fix redirects according to Moss's suggestion, and fix double-slash docs prepending 2021-01-15 11:59:36 -08:00
Megan Marsh
54a75421ea regenerate 2021-01-15 11:59:36 -08:00
Megan Marsh
1cb9aea752 change markdown references to new pathing 2021-01-15 11:59:36 -08:00
Megan Marsh
cca3109755 refactor site to move HCL docs next to JSON docs 2021-01-15 11:59:35 -08:00
Marin Salinas
170286a427 fix: [bsusurrogate] override bsu when omi root device is set 2021-01-15 09:36:56 -06:00
Roman Mingazeev
0554c33951 update description 2021-01-15 14:11:12 +03:00
Roman Mingazeev
c0f7b2ef39 fix wg.Add(1) lint 2021-01-15 12:59:27 +03:00
Pero P
5a61823082
Fix broken links to all Amazon builders (#10487) 2021-01-15 10:58:59 +01:00
Roman Mingazeev
379a33de42 yandex/update-dump-method 2021-01-15 12:51:54 +03:00
Megan Marsh
f5cbb56c14
Merge pull request #10478 from hashicorp/builder_revamp
refresh builder docs
2021-01-14 11:21:22 -08:00
Megan Marsh
c64aa83c56
Update website/content/docs/extending/custom-builders.mdx
Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-01-14 11:06:32 -08:00
Megan Marsh
2f42d4a7ce
Update website/content/docs/extending/custom-builders.mdx
Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-01-14 11:06:24 -08:00
Wilken Rivera
b6fb3e8bc9
Merge pull request #10484 from hashicorp/website-readme-update
website/README: Update link checker text
2021-01-14 13:04:02 -05:00
Brandon Romano
e370e43a66
Merge pull request #10475 from hashicorp/br.stack-menu
[Website] StackMenu updates for 1/14
2021-01-14 09:55:26 -08:00
Wilken Rivera
e4059cf6d2 website/README: update link checker text 2021-01-14 12:22:26 -05:00
Megan Marsh
dd7638a369
Merge pull request #10476 from hashicorp/17_upgrade_guide
17 upgrade guide
2021-01-13 16:31:37 -08:00
Megan Marsh
a34a33296a refresh builder docs 2021-01-13 16:27:14 -08:00
Megan Marsh
51d45ab77f
Merge pull request #10472 from hashicorp/17_upgrade_guide
add docs
2021-01-13 14:05:33 -08:00
Megan Marsh
368eb4aa00 add more context to intro 2021-01-13 13:19:10 -08:00
Megan Marsh
f43bb2f0c6 make table from import changes 2021-01-13 13:15:32 -08:00
Megan Marsh
21b37d4f8a Co-authored-by: Sylvia Moss <moss@hashicorp.com>
Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>

Review comments
2021-01-13 13:13:01 -08:00
Megan Marsh
f504d37b98 fix table 2021-01-13 13:12:34 -08:00
Megan Marsh
ff0e9f00b2 make table 2021-01-13 13:05:22 -08:00
Megan Marsh
561862a353
Update website/content/guides/1.7-plugin-upgrade/index.mdx
Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-01-13 13:01:24 -08:00
Megan Marsh
4955045240
Update website/content/guides/1.7-plugin-upgrade/index.mdx
Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-01-13 13:01:03 -08:00
Megan Marsh
8e7f513805
Update website/content/guides/1.7-plugin-upgrade/index.mdx
Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-01-13 13:00:51 -08:00
Megan Marsh
22c2d1a5bd
Update website/content/guides/1.7-plugin-upgrade/index.mdx
Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-01-13 12:15:19 -08:00
Megan Marsh
ebb609e4f2
Update website/content/guides/1.7-plugin-upgrade/index.mdx
Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2021-01-13 12:14:56 -08:00
Megan Marsh
26d5c271ab
Update website/content/guides/1.7-plugin-upgrade/index.mdx
Co-authored-by: Sylvia Moss <moss@hashicorp.com>
2021-01-13 12:13:53 -08:00
Megan Marsh
a112882999
Update website/content/guides/1.7-plugin-upgrade/index.mdx
Co-authored-by: Sylvia Moss <moss@hashicorp.com>
2021-01-13 12:13:41 -08:00
Megan Marsh
bc01ffe2dd
Merge pull request #10456 from triarius/spot-instance-lt-resource-tags
Add tags as resource tags in the launch template used to request spot instances
2021-01-13 12:12:17 -08:00
Brandon Romano
5ad0913dbe Website StackMenu updates for 1/14 2021-01-13 10:25:02 -08:00
Adrien Delorme
52d2d7fe5f
Copy MapOf... plugin types back into Packer core (#10466)
* move maps of plugins back in core

* go mod vendor

* more fixes

* fix imports

* Update core_test.go

* fix build

* more fixes

* more fixes

* up vendors after fixing sdk

* Update post_processor_mock.hcl2spec.go

* Leave implementatino of MapOf in the sdk for plugi tests

Other wise use the interface

* go mod tidy

* add MapOfDatasource type too
2021-01-13 12:14:06 +01:00
Daniel Frederick Crisman
1e8b0723f5
minor doc update with missing "use" vsphere config (#10474) 2021-01-13 11:38:45 +01:00
Megan Marsh
5d49a522c0 add to navigation js page 2021-01-12 13:49:49 -08:00
Megan Marsh
f591396b7e Add guide for upgrading plugins to use the packer-plugin-sdk 2021-01-12 13:42:12 -08:00
Gareth Rees
2dd2ef3c49 - Isolate OSLogin service account derivation from google metadata server to OSLogin step only 2021-01-12 21:38:41 +00:00
Jeff Escalante
e77d270fc4
remove netlify artifacts (#10471) 2021-01-12 15:04:36 -05:00
Narthana Epa
cf30b49e6c
Use run_tags (resp run_volume_tags) to tags intances (resp volumes) created from the spot instance launch template 2021-01-12 23:37:01 +11:00
seventieskid
707d2d8236 Refined logging and return scope 2021-01-11 23:04:36 +00:00
Megan Marsh
c3da09b441
Merge pull request #10468 from hashicorp/fix_vsphere_pp
fix regression in return code checking in vsphere postprocessor. this…
2021-01-11 13:34:00 -08:00
Megan Marsh
6917866259 fix regression in return code checking in vsphere postprocessor. this was introduced in v1.6.1 2021-01-11 13:12:24 -08:00
Megan Marsh
e7a2615383
Merge pull request #10451 from somerandomqaguy/fix-qemu-vnc_min_port
Fix for vnc_min_port set to value greater then 5900 potentially causing packer to be unable to connect to QEMU
2021-01-11 11:29:17 -08:00
Jeff Escalante
80a449cc5e
Website: prepare for vercel hosting move (#10402)
* prepare to move to vercel hosting

* add html extension handling

* add back netlify files for transition
2021-01-11 14:10:47 -05:00
Tristan Watson
17c806fbf5
Removing obsolete packer HCL warnings from CLI for validate and command (#10461) 2021-01-11 11:50:23 +01:00
Gareth Rees
f525e884ed Timeout on metadata server 2021-01-10 18:29:37 +00:00
Narthana Epa
bb94df2d02
Add mocking of launch template id
It is being printed after it is created so we need to mock it to prevent
a nil pointer dereference when the tests are run with the launch
template create request is mocked.
2021-01-10 00:00:16 +11:00
Narthana Epa
f7588a3737
Add printing of launch template id 2021-01-09 23:59:31 +11:00
Narthana Epa
f7e68f1d71
Add spot tags as resource tags of instances and volumes in launch template
According to the APIReference:
<https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_LaunchTemplateTagSpecificationRequest.html>,
the resource types `instance` and `volume` support tagging on creation.
It is useful to add the spot tags here as it should be more reliable
than tagging them after the spot request is fulfilled as we currently
do.
2021-01-09 23:58:23 +11:00
Darwin Liu
8ef4cfa070 Add in a sanity check for valid vnc ports
Check to make sure that the max and min VNC ports be below 65535 in
config.
2021-01-08 13:43:02 -07:00
Darwin Liu
2b698478a6 Adjusted QEMU step_run_tests.go to reflect previous changes 2021-01-07 22:23:51 -07:00
Darwin Liu
4f2e9117c3 QEMU: Minor fix to VNC mapping parameters and output
* Set the QEMU builder vnc_port_min to have a minimum value of 5900,
  with updated documentation to explain why.

* Changed output messages so that the correct port is listed in packer's
  messaging to the user.

LONGER DESCRIPTION

If vnc_min_port is set to anything above 5900, then packer will fail to
connect via VNC to the QEMU instance. This is due to how QEMU parses
the port for listening to VNC:

   host:d
               TCP connections will only be allowed from host on
               display d.  By convention the TCP port is 5900+d.

Previously the calculation for the port was vncPort - VNCPortMin,
however this will result in an incorrect port being displayed in
packer's messages and potentially packer being unable to connect via VNC
to the host.

For example if vnc_port_min=5990 nad vnc_port_max=5999:

```
Looking for available port between 5990 and 5999 on 0.0.0.0
Found available port: 5996 on IP: 0.0.0.0
Found available VNC port: 5996 on IP: 0.0.0.0
[....]
==> Starting VM, booting disk image
     view the screen of the VM, connect via VNC without a password to
     vnc://0.0.0.0:6
```

This will cause QEMU to set the listening port to 5906 while packer's
VNC client is attempting to connect to 5996.

I am a touch concerned as this commit undoes pull request #9905
(specfically commit 7335695c), but I am also confused as to how he was
able to get QEMU to get a VNC listening port below 5900, as examining
QEMU's git history has shown that this behavior has been in since at
least 2017, probably older.

Hopefully the more explicit error messaging and documentation can make
it clear why this is being undone.
2021-01-07 22:23:43 -07:00
Megan Marsh
6564ee76e8 fix vendoring 2021-01-07 15:45:16 -08:00
Megan Marsh
77c3c12244 fix vendoring 2021-01-07 15:44:58 -08:00
Megan Marsh
da0ee96cdd fix imports 2021-01-07 15:38:46 -08:00
Megan Marsh
beba3a90a9 fix discover.go 2021-01-07 15:38:38 -08:00
Megan Marsh
c94d66db13 clean up dependencies 2021-01-07 13:03:20 -08:00
Megan Marsh
4ac55446a1 fix go.mod 2021-01-07 12:00:57 -08:00
Megan Marsh
0666b787fc allow plugins with registered items with name from plugin.DEFAULT_NAME string constant to be passthroughs to the plugin binary suffix 2021-01-07 11:55:51 -08:00
Wilken Rivera
9adeb989c6
Merge pull request #10442 from hashicorp/d-broken-link-check
Add GitHub action to check for broken markdown links
2021-01-06 16:30:38 -05:00
Wilken Rivera
8d4c7d31b4 Add regenerated docs from packer-plugin-sdk
```
cd $HOME/Development/packer-plugin-sdk
PROJECT_ROOT=packer-plugin-sdk go generate ./...
rsync -av multistep/commonsteps/packer-plugin-sdk/website/content/partials/ ../packer/website/content/partials/
rsync -av bootcommand/packer-plugin-sdk/website/content/partials/ ../packer/website/content/partials/
rsync -av shutdowncommand/packer-plugin-sdk/website/content/partials/ ../packer/website/content/partials/
rsync -av communicator/packer-plugin-sdk/website/content/partials/ ../packer/website/content/partials/
```
2021-01-06 16:27:12 -05:00
Wilken Rivera
04dbbe2d8e Fix broken links detected by link checker
- Fix broken example links
- Fix broken provisioner links
- Ignore linode.com because of DDOS protection settings
2021-01-06 16:27:12 -05:00
Wilken Rivera
7b793cefb1 Add GHA to check for broken links on pull-request
- Add scheduled cron job for checking against master
- Change configuration file path
2021-01-06 16:26:57 -05:00
Jeff Escalante
a4e5df9149
set main branch to master for 'edit this page' links (#10447) 2021-01-06 16:19:06 -05:00
Felix Hillingshaeuser
233c7f0a83
docs: Add default value for cloud_init in builders/proxmox (#10445) 2021-01-06 10:37:23 -05:00
Ali Rizvi-Santiago
9b1d31cee7 Added a fallback to the vmware builder when trying to determine the networkmapping configuration.
Some instances of VMWare will not generate the networkmapping configuration (netmap.conf)
at the time of installation. To deal with this issue, we check for the networkmapping file
first, and then fallback to the networking file which also might exist and contain the
interface information that we require.

This fixes issue #10009.
2021-01-05 11:24:50 -06:00
Megan Marsh
4b0de7263e
Merge pull request #10412 from adeniyistephen/hlc-doc
Add hcl Example to openstack
2021-01-04 09:44:52 -08:00
Megan Marsh
d260bb63d3
Merge pull request #10413 from adeniyistephen/hcl-doc
Add hcl Example to docker-save
2021-01-04 09:41:15 -08:00
Megan Marsh
560d5ff270
Merge pull request #10415 from adeniyistephen/hcl-docs
Add hcl example to docker-tag
2021-01-04 09:40:24 -08:00
Megan Marsh
e83603faa5
Merge pull request #10425 from adeniyistephen/scaleway
Add hcl example for scaleway
2021-01-04 09:39:18 -08:00
Shigetaka Shirouchi
7ef5246e94
docs: Fix trivial json format (#10437) 2021-01-04 11:02:11 +01:00
adeniyistephen
4d25a59600 add hcl example to docker-save 2020-12-28 15:05:08 +01:00
adeniyistephen
ed4ed9885b add hcl example to docker-tag 2020-12-28 15:03:13 +01:00
adeniyistephen
779a5d9bbb add hcl example to scaleway 2020-12-28 14:58:53 +01:00
adeniyistephen
73d9e8430a Add hcl example for scaleway 2020-12-27 19:43:10 +01:00
adeniyistephen
08e0f1ea72 Add hcl example to docker-tag 2020-12-21 17:22:44 +01:00
adeniyistephen
7abe0a4759 Add hcl Example to docker-save 2020-12-21 17:01:39 +01:00
adeniyistephen
dc87825d5c Add hcl Example to docker-save 2020-12-21 16:56:12 +01:00
adeniyistephen
11d7b9d7ee Add hcl Example to openstack 2020-12-21 16:27:10 +01:00
Megan Marsh
28245ec143
Merge pull request #10134 from borancar/feat/azure_pfx_support
Add Azure PFX certificate support
2020-12-18 12:09:17 -08:00
Megan Marsh
d1d5706048
Merge pull request #10362 from nielspardon/master
OpenStack builder: Make external source image props configurable
2020-12-18 10:55:40 -08:00
Megan Marsh
d27e627e2a
Merge pull request #10391 from hashicorp/plugin_release_docs
Plugin release step by step docs
2020-12-18 10:45:35 -08:00
Megan Marsh
bee182e480
Merge pull request #10405 from hashicorp/remove_sdk
Remove sdk
2020-12-18 09:21:57 -08:00
Megan Marsh
37652b05eb update vendoring 2020-12-17 15:12:16 -08:00
Megan Marsh
82eb22c8bb go.mod updates 2020-12-17 14:55:14 -08:00
Megan Marsh
ce99640fe2 fix test fixture path 2020-12-17 14:41:36 -08:00
Megan Marsh
88b7b0e14a remove sdk 2020-12-17 13:29:25 -08:00
Megan Marsh
dd9a8b2669
Merge pull request #10388 from hashicorp/sdk_docs
Sdk docs
2020-12-16 15:30:47 -08:00
Megan Marsh
761200485e remove partials since they moved 2020-12-16 15:21:35 -08:00
Megan Marsh
e4642c0b13 turn markdown example into godoc format 2020-12-16 15:14:49 -08:00
Megan Marsh
7ef8b290e8 Apply suggestions from code review
Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2020-12-16 15:14:49 -08:00
Megan Marsh
3fd8066a95 Apply suggestions from code review
Co-authored-by: Sylvia Moss <moss@hashicorp.com>
2020-12-16 15:14:48 -08:00
Megan Marsh
8650f7990c add more docs 2020-12-16 15:14:48 -08:00
Megan Marsh
185614f886 more package docs 2020-12-16 15:14:47 -08:00
Megan Marsh
3a66391e30 more package docs 2020-12-16 15:14:46 -08:00
Megan Marsh
c5e6e84806 remove iochan package from sdk, switch to using its descendent, mitchellh/iochan 2020-12-16 15:14:46 -08:00
Megan Marsh
608b62f699 more godoc tweaks 2020-12-16 15:14:45 -08:00
Megan Marsh
e5a95c7017 regenerate code to add extra line to prevent bad godoc synopsis string loading 2020-12-16 15:14:44 -08:00
Megan Marsh
6a672f3948 docs 2020-12-16 15:14:44 -08:00
Megan Marsh
5f34bbd56e add extra line before package declaration so this line does not become the synopsis of a package for godoc 2020-12-16 15:14:43 -08:00
packer-ci
166a3663c3 Putting source back into Dev Mode 2020-12-16 21:34:25 +00:00
packer-ci
9b997f28d5
Cut version 1.6.6 2020-12-16 21:03:56 +00:00
packer-ci
8b59e703da cut version 1.6.6 2020-12-16 21:03:54 +00:00
packer-ci
7af115b319 update changelog 2020-12-16 21:03:54 +00:00
Megan Marsh
11d39e4247 add link to changelog 2020-12-16 11:14:01 -08:00
Megan Marsh
17bd88b81c add note about sdk split 2020-12-16 11:12:47 -08:00
Megan Marsh
7dd8d3e67f update changelog 2020-12-16 10:50:48 -08:00
Niels Pardon
0e56b83196 OpenStack builder: Make external source image props configurable
Signed-off-by: Niels Pardon <par@zurich.ibm.com>
2020-12-16 17:19:52 +00:00
Wilken Rivera
8eeeb91c90 Update CHANGELOG 2020-12-16 09:33:17 -05:00
Megan Marsh
75803397cb
Document exception to encryption (#10395)
* Update docs on ebs encrypt_boot to clarify that packer will not override global account settings

* Update struct-markdown generator and regenerate partials with new website location. This overwrites some linting that got automatically applied when the files got moved
2020-12-16 10:35:34 +01:00
Megan Marsh
eecac40d77
Merge pull request #10394 from anssijun/aws-ebs-retry-spot-instance-tagging
Fix retry logic in AWS spot instance tagging
2020-12-15 11:07:48 -08:00
Megan Marsh
b0795f86fd
Merge pull request #10243 from dany1532/feature/amazon-chroot-encrypted-volumes
adding support for root volume encryption for amazon-chroot
2020-12-15 11:03:14 -08:00
Megan Marsh
1113301c1b fix conflicts 2020-12-15 10:53:51 -08:00
Dany Garcia
905d8401ea removing unused import 2020-12-15 10:41:25 -08:00
Dany Garcia
0b13d44a23 exporting reusable validatekmskey function 2020-12-15 10:41:25 -08:00
Dany Garcia
3389fded48 merging latest master 2020-12-15 10:40:46 -08:00
Dany Garcia
39bb3a6c55 incorrect error message regarding parameter names 2020-12-15 10:40:12 -08:00
Dany Garcia
504c3807f7 adding support for root volume encryption for amazon-chroot 2020-12-15 10:40:08 -08:00
Anssi Junnola
82a25ec419 Fix retry logic in AWS spot instance tagging 2020-12-15 17:21:03 +00:00
sylviamoss
85eb704770 improve text 2020-12-15 14:59:25 +01:00
sylviamoss
180feebaea make releases link prettier 2020-12-15 12:52:40 +01:00
sylviamoss
af316bbc97 add more information to release doc 2020-12-15 12:44:43 +01:00
Adrien Delorme
72c1912b60
allow to discover & start packer-plugin-* muliplugin binaries (#10277)
This add :
* discovery of `packer-plugin-*` binaries from the known folders and ask them to describe themselves
* tests

For testing: in go we create a bash script that in turn calls back to Go. I could not make the tests to work on windows and then would like to postpone testing this for when we know more about the finite layout of this feature. That is mainly: how things are going to work with init, versioning and such.
2020-12-15 10:58:09 +01:00
sylviamoss
081d18f9ca write plugin release step by step docs 2020-12-15 10:28:17 +01:00
Megan Marsh
0db037b4ff
Merge pull request #10316 from unixsurfer/unixsurfer/adjust_googlecompute-export
googlecompute-export: Add logging.write to service account scopes
2020-12-14 16:35:21 -08:00
Megan Marsh
4f419506fd
Merge pull request #10384 from Pyrrvs/vmware-dhcp-leases-bigsur
make packer compatible with MacOS BigSur by using Apple DHCP leases instead of VMWare leases
2020-12-14 16:30:50 -08:00
Megan Marsh
4213754905
Merge pull request #10389 from hashicorp/dependabot/npm_and_yarn/website/lodash-4.17.20
Bump lodash from 4.17.15 to 4.17.20 in /website
2020-12-14 16:12:35 -08:00
dependabot[bot]
e7e02c591d
Bump lodash from 4.17.15 to 4.17.20 in /website
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.20.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.20)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 23:55:46 +00:00
Megan Marsh
bf0a19f2cf
Merge pull request #10345 from hashicorp/je.mdx-remote
Implement MDX Remote
2020-12-14 15:54:39 -08:00
Jeff Escalante
a7be0df3de
resolve hanging conflicts 2020-12-14 18:20:31 -05:00
Jeff Escalante
29b01e5111
update deps, restore search 2020-12-14 18:20:31 -05:00
Jeff Escalante
9d4ffb6cbd
use global markdownpage component 2020-12-14 18:20:19 -05:00
Jeff Escalante
5f68414ce0
Update website/components/_temporary-markdown-page/README.md
Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2020-12-14 18:20:04 -05:00
Jeff Escalante
6809b16b14
fix tab indentation on inspec provisioner page 2020-12-14 18:20:03 -05:00
Jeff Escalante
ad81e9df2f
remove unneeded initialprops in app.js 2020-12-14 18:20:03 -05:00
Jeff Escalante
25380116f2
remove layout frontmatter prop 2020-12-14 18:20:03 -05:00
Jeff Escalante
2de270341c
refactor to mdx remote 2020-12-14 18:20:01 -05:00
Pyrrvs
12a6fddbd8 handle apple dhcp lease with missing 'name' and 'lease' informations 2020-12-14 19:16:00 +01:00
Megan Marsh
568916067e
Merge pull request #10385 from Direnol/yandex/do-not-use-cloud-config
yandex: do not use cloud-config fileds due to possible collision
2020-12-14 09:24:21 -08:00
dependabot[bot]
77047c6425
Bump ini from 1.3.5 to 1.3.8 in /website (#10381)
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-14 12:21:52 -05:00
Sylvia Moss
b7ebcd78db
add method to set multi-plugin version (#10386) 2020-12-14 17:08:38 +01:00
Wilken Rivera
4e58987026
command/fmt: Ensure all variable files ending in .pkrvars.hcl get formatted (#10377)
Before change
```
⇶  packer fmt -check /tmp/unformatted.pkrvars.hcl
Error: Cannot tell whether /tmp/unformatted.pkrvars.hcl contains HCL2 configuration data

⇶  echo $?
1
```

After fix
```
⇶  packer fmt -check /tmp/unformatted.pkrvars.hcl
/tmp/unformatted.pkrvars.hcl

⇶  echo $?
3

⇶  packer fmt -check command/test-fixtures/fmt
command/test-fixtures/fmt/unformatted.pkr.hcl
command/test-fixtures/fmt/unformatted.auto.pkrvars.hcl
command/test-fixtures/fmt/unformatted.pkrvars.hcl

```
2020-12-14 10:29:58 -05:00
Roman Mingazeev
354166350d yandex: do not use cloud-config fileds due to possible collision 2020-12-14 13:04:27 +03:00
Donald Guy
889e42443a
Fix 2nd binding of string reverse for list reverse (#10380) 2020-12-14 10:57:08 +01:00
Pyrrvs
f0612e4688 improve parser by skipping all lines containing a '{' or a '}'. fix unecessary []byte cast (linter issue). 2020-12-14 01:00:24 +01:00
gla
7201ce9248 make packer compatible MacOS BigSur by making vmware fusion drivers able to lookup the VM IP address in apple dhcpd leases instead of vmware leases. 2020-12-13 23:26:53 +01:00
Megan Marsh
d8277aa455
Merge pull request #10373 from hashicorp/makefile_changes
Modify struct-markdown generator code to work from different projct roots
2020-12-11 16:06:13 -08:00
Megan Marsh
2c62c9bff1 fix var naming and docs in acctest package 2020-12-11 15:23:12 -08:00
Megan Marsh
7f1456fc50 add godoc for acctest package 2020-12-11 15:15:25 -08:00
Megan Marsh
2805a59dbd remove unused tools, add some docs 2020-12-11 15:15:08 -08:00
Megan Marsh
575f8ab8e8 add readme to plugin-sdk subdir 2020-12-11 14:02:41 -08:00
Megan Marsh
a6b6819b1d add makefile and go.mod file to sdk subdir. this'll make it easier to extract when we're ready. TODO: readme 2020-12-11 13:51:10 -08:00
Megan Marsh
edb9d73027
Merge pull request #10368 from GennadySpb/yandex-export-show-progress
Yandex export show progress
2020-12-11 13:47:38 -08:00
Megan Marsh
c90e3d8466 fix makefile 2020-12-11 13:37:03 -08:00
Megan Marsh
395920f917 didnt mean to delete this 2020-12-10 14:38:16 -08:00
Megan Marsh
f179f01314 Modify struct-markdown generator code to work from different projct roots
Modify makefile to call generate code properly, setting project root.
'make generate' now avoids deleting website code generated in the packer plugin sdk.
For now it will be maintainers' responsibility to regenerate this docs code from the
packer plugin sdk every release, and commit it to these folders manually.
remove boot command generator code
2020-12-10 14:35:14 -08:00
Gennady Lipenkov
d0367d90bd Periodically send signal to trigger qemu-img to show current progress 2020-12-10 18:50:28 +03:00
Roman Mingazeev
992cbe6dee
Update post-processor/yandex-export/step-attach-disk.go
Co-authored-by: GennadySpb <lipenkov@gmail.com>
2020-12-10 15:17:27 +03:00
Roman Mingazeev
69adcdb2a3
Update post-processor/yandex-export/step-attach-disk.go
Co-authored-by: GennadySpb <lipenkov@gmail.com>
2020-12-10 15:17:21 +03:00
Roman Mingazeev
ceb02833a4
Update post-processor/yandex-export/step-attach-disk.go
Co-authored-by: GennadySpb <lipenkov@gmail.com>
2020-12-10 15:17:09 +03:00
Roman Mingazeev
bbd9ee8589 fix export when using empty ubuntu image 2020-12-10 14:52:22 +03:00
Adrien Delorme
e89db37717
add aws multiplugin binary canary code (#10272)
This creates a new plumbing to allow to have binaries that can define any plugin on any type.
2020-12-10 09:22:09 +01:00
Roman Mingazeev
aa0efcf73e
Yandex/ssh communicator in export (#10352)
* use ssh for communicate to export
* Update post-processor/yandex-export/step-create-s3-keys.go

Co-authored-by: GennadySpb <lipenkov@gmail.com>
2020-12-09 16:51:34 +01:00
Gareth Rees
355b93730b
Gcp oslogin issue 10170 (#10360) 2020-12-09 15:01:51 +01:00
Roman Mingazeev
f8e85f94fd
fix set user-agent (#10361) 2020-12-09 14:48:35 +01:00
Mike Tougeron
e0e82e2192
Support AWS gp3 volumes (#10338)
* Support AWS gp3 volumes
* docs
* tests
2020-12-09 13:06:57 +01:00
Megan Marsh
39ab646236
move plugin and rpc code into sdk; other minor tweaks (#10359) 2020-12-09 12:39:54 +01:00
Sylvia Moss
1e86c49e32
Add packer-plugin-check command (#10351) 2020-12-09 10:16:22 +01:00
Megan Marsh
26946f1300
Merge pull request #10320 from seventieskid/gcp-wait-to-add-ssh-keys-10312
Gcp wait to add ssh keys 10312
2020-12-08 15:52:52 -08:00
Megan Marsh
1d2ee0bf81
Merge pull request #10337 from serverwentdown/serverwentdown/duplicate-output-file
Fix duplication of main disk in QEMU
2020-12-08 15:18:38 -08:00
Megan Marsh
7a05d0ce15
Merge pull request #10355 from hashicorp/clean_provisioners
Clean provisioners
2020-12-08 11:14:31 -08:00
Megan Marsh
48a0172670 better error handling and messaging in provisioner acc test framework 2020-12-08 09:59:04 -08:00
Megan Marsh
2797c686e0
Update packer-plugin-sdk/acctest/provisioneracc/provisioners.go
Co-authored-by: Sylvia Moss <moss@hashicorp.com>
2020-12-08 08:24:26 -08:00
Megan Marsh
3c346867f4 fix nil pointer dereference 2020-12-07 15:45:16 -08:00
Megan Marsh
00c61f9987 fix documentation for acceptance tests 2020-12-07 15:45:16 -08:00
Megan Marsh
6ecdd3ca16 small tweaks 2020-12-07 15:45:16 -08:00
Megan Marsh
76177b50ce Refactor provisioner acceptance tests to shell directly out to Packer rather than import the core. Modify test case formatting to more closely reflect the builder test cases. 2020-12-07 15:45:16 -08:00
Megan Marsh
bc7dae2dff fix ansible acceptance tests not to import packer core; add override to Builder acctest TestCase so you can supply your own provisionerstore. 2020-12-07 15:45:16 -08:00
Megan Marsh
823ff34434 remove noop ui, replace in adapter and ansible tests with sdk's TestUi 2020-12-07 15:45:16 -08:00
Megan Marsh
e117117ea5
Merge pull request #10317 from Direnol/yandex/common-configs
reuse common configs
2020-12-07 09:48:13 -08:00
Roman Mingazeev
9fabad6f1d rebase && some fixes 2020-12-07 18:27:22 +03:00
Roman Mingazeev
1c08463204 rebase 2020-12-07 18:13:12 +03:00
Roman Mingazeev
efe6d2f08f add comment and remove overrides 2020-12-07 18:13:12 +03:00
Roman Mingazeev
23118c451c fix delete 2020-12-07 18:13:12 +03:00
Roman Mingazeev
4eb3daec8e lint 2020-12-07 18:13:12 +03:00
Roman Mingazeev
d30c09e642 remove incorrect doc 2020-12-07 18:13:12 +03:00
Roman Mingazeev
478fda12ba reuse common configs 2020-12-07 18:13:06 +03:00
Roman Mingazeev
adb4a14471
do better mount image (#10335)
* do better mount image

* check error
2020-12-07 12:20:06 +01:00
Megan Marsh
4c0adb7d67
Merge pull request #10340 from hashicorp/acceptance_test_fix
Modify vmware_vmx and docker acceptance tests to use builderT framework
2020-12-04 09:28:38 -08:00
Megan Marsh
cda3aa205a linting 2020-12-03 16:11:36 -08:00
Megan Marsh
352f064b55 fix docker acceptance tests. Turns out they were broken on the main branch too; needed to move noop progress bar into the sdk to be used in the builder testui. 2020-12-03 16:04:49 -08:00
Megan Marsh
8f51a8bfae move provisioner acceptance tests into sdk alongside builder acceptance tests. Reorganize slightly to make sure no import cycles of doom get formed 2020-12-03 14:22:18 -08:00
Megan Marsh
becf7723e6 move builder/testing to acctest inside sdk 2020-12-03 11:57:06 -08:00
Megan Marsh
f3f4fef44a fix import 2020-12-03 11:43:06 -08:00
Megan Marsh
98f5fa453c move aws specific acceptance test helper into amazon builder dir 2020-12-03 11:34:45 -08:00
Megan Marsh
2d04ef9b99 remove commented code 2020-12-03 11:32:05 -08:00
Megan Marsh
afc798c30a Modify vmware_vmx acceptance tests to use builderT framework
Modify builderT framework to enable use of shell and file provisioners
2020-12-03 11:25:02 -08:00
Megan Marsh
469fb763d4
Merge pull request #10330 from hashicorp/expanduser
Expanduser
2020-12-03 11:24:25 -08:00
Megan Marsh
3681e2a7ee fix pathing 2020-12-03 10:39:21 -08:00
Megan Marsh
5e49ddb285
Merge pull request #10329 from hashicorp/sdk_testing_2
Sdk testing 2
2020-12-03 10:35:43 -08:00
Megan Marsh
d767c69ed3 rebase and fix conflicts
fix tests
2020-12-03 10:26:48 -08:00
Megan Marsh
5576bb5caa move packer config constants next to the packer config 2020-12-03 10:17:35 -08:00
Megan Marsh
8558d1241f move TestUi func to sdk 2020-12-03 10:15:30 -08:00
Megan Marsh
16bab1daf1 delete unused code with confusing name collision 2020-12-03 10:15:30 -08:00
Megan Marsh
a0e81806d3
Merge pull request #10328 from hashicorp/sdk_testing
move builder/testing framework into sdk; it imports the core but I th…
2020-12-03 10:11:28 -08:00
Megan Marsh
2667bf3d3b
Merge pull request #10336 from hashicorp/move_plugin_discover
Move plugin discover to plugin package
2020-12-03 10:09:37 -08:00
sylviamoss
efa7ec7883 don't override builder/prov/pproc 2020-12-03 18:24:00 +01:00
Ambrose Chua
436ac8ef26 Fix duplication of main disk in QEMU 2020-12-04 01:16:26 +08:00
sylviamoss
4f8a27be10 fix linter 2020-12-03 17:11:35 +01:00
sylviamoss
2c10c21445 move plugin discover tests to plugin pkg 2020-12-03 17:07:24 +01:00
Ambrose Chua
f5d5e28012
Update step_copy_disk.go (#10333) 2020-12-03 15:30:11 +01:00
Major Hayden
4254fa3581
docs: trivial spelling fix (#10334)
🤗
2020-12-03 15:00:11 +01:00
Gareth Rees
937e39d9f4 Amend commit author to align with Hashicorp license 2020-12-03 11:33:49 +00:00
Gareth Rees
d6831a4de3 Amend commit author for license pass 2020-12-03 11:33:19 +00:00
Gareth Rees
833855eec5 Amend commit author for license pass 2020-12-03 11:33:02 +00:00
Gareth Rees
3ab9bae79c Amend commit author for license pass
$ make test
find: -executable: unknown primary or operator
find: -executable: unknown primary or operator
==> Checking that only certain files are executable...
Check passed.
ok  	github.com/hashicorp/packer	0.098s
ok  	github.com/hashicorp/packer/builder/alicloud/ecs	70.102s
?   	github.com/hashicorp/packer/builder/alicloud/version	[no test files]
ok  	github.com/hashicorp/packer/builder/amazon/chroot	0.076s
ok  	github.com/hashicorp/packer/builder/amazon/common	0.052s
?   	github.com/hashicorp/packer/builder/amazon/common/awserrors	[no test files]
?   	github.com/hashicorp/packer/builder/amazon/common/ssm	[no test files]
ok  	github.com/hashicorp/packer/builder/amazon/ebs	0.053s
?   	github.com/hashicorp/packer/builder/amazon/ebs/acceptance	[no test files]
ok  	github.com/hashicorp/packer/builder/amazon/ebssurrogate	0.057s
ok  	github.com/hashicorp/packer/builder/amazon/ebsvolume	0.052s
ok  	github.com/hashicorp/packer/builder/amazon/instance	0.092s
?   	github.com/hashicorp/packer/builder/amazon/version	[no test files]
ok  	github.com/hashicorp/packer/builder/azure/arm	8.929s
ok  	github.com/hashicorp/packer/builder/azure/chroot	0.071s
ok  	github.com/hashicorp/packer/builder/azure/common	0.032s
ok  	github.com/hashicorp/packer/builder/azure/common/client	2.768s
?   	github.com/hashicorp/packer/builder/azure/common/constants	[no test files]
?   	github.com/hashicorp/packer/builder/azure/common/lin	[no test files]
?   	github.com/hashicorp/packer/builder/azure/common/logutil	[no test files]
ok  	github.com/hashicorp/packer/builder/azure/common/template	0.038s
ok  	github.com/hashicorp/packer/builder/azure/dtl	1.508s
ok  	github.com/hashicorp/packer/builder/azure/pkcs12	0.250s
ok  	github.com/hashicorp/packer/builder/azure/pkcs12/rc2	0.018s
?   	github.com/hashicorp/packer/builder/azure/version	[no test files]
ok  	github.com/hashicorp/packer/builder/cloudstack	0.074s
?   	github.com/hashicorp/packer/builder/cloudstack/version	[no test files]
ok  	github.com/hashicorp/packer/builder/digitalocean	0.078s
?   	github.com/hashicorp/packer/builder/digitalocean/version	[no test files]
ok  	github.com/hashicorp/packer/builder/docker	0.054s
?   	github.com/hashicorp/packer/builder/docker/version	[no test files]
ok  	github.com/hashicorp/packer/builder/file	0.037s
?   	github.com/hashicorp/packer/builder/file/version	[no test files]
ok  	github.com/hashicorp/packer/builder/googlecompute	7.982s
?   	github.com/hashicorp/packer/builder/googlecompute/version	[no test files]
ok  	github.com/hashicorp/packer/builder/hcloud	0.037s
?   	github.com/hashicorp/packer/builder/hcloud/version	[no test files]
ok  	github.com/hashicorp/packer/builder/hyperone	0.031s
?   	github.com/hashicorp/packer/builder/hyperone/version	[no test files]
ok  	github.com/hashicorp/packer/builder/hyperv/common	0.042s
ok  	github.com/hashicorp/packer/builder/hyperv/common/powershell	0.017s
ok  	github.com/hashicorp/packer/builder/hyperv/common/powershell/hyperv	0.027s
ok  	github.com/hashicorp/packer/builder/hyperv/iso	0.193s
?   	github.com/hashicorp/packer/builder/hyperv/version	[no test files]
ok  	github.com/hashicorp/packer/builder/hyperv/vmcx	0.160s
ok  	github.com/hashicorp/packer/builder/jdcloud	0.038s
?   	github.com/hashicorp/packer/builder/jdcloud/version	[no test files]
ok  	github.com/hashicorp/packer/builder/linode	0.074s
?   	github.com/hashicorp/packer/builder/linode/version	[no test files]
ok  	github.com/hashicorp/packer/builder/lxc	0.038s
?   	github.com/hashicorp/packer/builder/lxc/version	[no test files]
ok  	github.com/hashicorp/packer/builder/lxd	0.033s
?   	github.com/hashicorp/packer/builder/lxd/version	[no test files]
ok  	github.com/hashicorp/packer/builder/ncloud	0.038s
?   	github.com/hashicorp/packer/builder/ncloud/version	[no test files]
ok  	github.com/hashicorp/packer/builder/null	0.036s
?   	github.com/hashicorp/packer/builder/null/version	[no test files]
ok  	github.com/hashicorp/packer/builder/oneandone	0.038s
?   	github.com/hashicorp/packer/builder/oneandone/version	[no test files]
ok  	github.com/hashicorp/packer/builder/openstack	0.048s
?   	github.com/hashicorp/packer/builder/openstack/version	[no test files]
ok  	github.com/hashicorp/packer/builder/oracle/classic	0.055s
?   	github.com/hashicorp/packer/builder/oracle/common	[no test files]
ok  	github.com/hashicorp/packer/builder/oracle/oci	6.349s
?   	github.com/hashicorp/packer/builder/oracle/version	[no test files]
ok  	github.com/hashicorp/packer/builder/osc/bsu	0.045s
ok  	github.com/hashicorp/packer/builder/osc/bsusurrogate	0.043s
ok  	github.com/hashicorp/packer/builder/osc/bsuvolume	0.048s
ok  	github.com/hashicorp/packer/builder/osc/chroot	0.035s
ok  	github.com/hashicorp/packer/builder/osc/common	0.030s
ok  	github.com/hashicorp/packer/builder/osc/common/retry	0.018s
?   	github.com/hashicorp/packer/builder/osc/version	[no test files]
ok  	github.com/hashicorp/packer/builder/parallels/common	1.546s
ok  	github.com/hashicorp/packer/builder/parallels/iso	0.047s
ok  	github.com/hashicorp/packer/builder/parallels/pvm	0.044s
?   	github.com/hashicorp/packer/builder/parallels/version	[no test files]
ok  	github.com/hashicorp/packer/builder/profitbricks	0.046s
?   	github.com/hashicorp/packer/builder/profitbricks/version	[no test files]
?   	github.com/hashicorp/packer/builder/proxmox	[no test files]
?   	github.com/hashicorp/packer/builder/proxmox/clone	[no test files]
ok  	github.com/hashicorp/packer/builder/proxmox/common	0.070s
ok  	github.com/hashicorp/packer/builder/proxmox/iso	0.072s
?   	github.com/hashicorp/packer/builder/proxmox/version	[no test files]
ok  	github.com/hashicorp/packer/builder/qemu	0.088s
?   	github.com/hashicorp/packer/builder/qemu/version	[no test files]
ok  	github.com/hashicorp/packer/builder/scaleway	0.062s
?   	github.com/hashicorp/packer/builder/scaleway/version	[no test files]
ok  	github.com/hashicorp/packer/builder/tencentcloud/cvm	0.037s
?   	github.com/hashicorp/packer/builder/tencentcloud/version	[no test files]
ok  	github.com/hashicorp/packer/builder/triton	0.057s
?   	github.com/hashicorp/packer/builder/triton/version	[no test files]
ok  	github.com/hashicorp/packer/builder/ucloud/common	0.039s
ok  	github.com/hashicorp/packer/builder/ucloud/uhost	0.045s
?   	github.com/hashicorp/packer/builder/ucloud/version	[no test files]
ok  	github.com/hashicorp/packer/builder/vagrant	0.046s
?   	github.com/hashicorp/packer/builder/vagrant/version	[no test files]
ok  	github.com/hashicorp/packer/builder/virtualbox/common	2.546s
ok  	github.com/hashicorp/packer/builder/virtualbox/iso	0.053s
?   	github.com/hashicorp/packer/builder/virtualbox/iso/acceptance	[no test files]
ok  	github.com/hashicorp/packer/builder/virtualbox/ovf	0.043s
?   	github.com/hashicorp/packer/builder/virtualbox/version	[no test files]
?   	github.com/hashicorp/packer/builder/virtualbox/vm	[no test files]
ok  	github.com/hashicorp/packer/builder/vmware/common	5.228s
ok  	github.com/hashicorp/packer/builder/vmware/iso	0.104s
?   	github.com/hashicorp/packer/builder/vmware/version	[no test files]
ok  	github.com/hashicorp/packer/builder/vmware/vmx	0.055s
ok  	github.com/hashicorp/packer/builder/vsphere/clone	0.072s
ok  	github.com/hashicorp/packer/builder/vsphere/common	0.037s
?   	github.com/hashicorp/packer/builder/vsphere/common/testing	[no test files]
ok  	github.com/hashicorp/packer/builder/vsphere/driver	0.443s
?   	github.com/hashicorp/packer/builder/vsphere/examples/driver	[no test files]
ok  	github.com/hashicorp/packer/builder/vsphere/iso	0.063s
?   	github.com/hashicorp/packer/builder/vsphere/version	[no test files]
ok  	github.com/hashicorp/packer/builder/yandex	0.098s
?   	github.com/hashicorp/packer/builder/yandex/version	[no test files]
?   	github.com/hashicorp/packer/cmd/generate-fixer-deprecations	[no test files]
?   	github.com/hashicorp/packer/cmd/mapstructure-to-hcl2	[no test files]
?   	github.com/hashicorp/packer/cmd/snippet-extractor	[no test files]
?   	github.com/hashicorp/packer/cmd/ssh-keygen	[no test files]
?   	github.com/hashicorp/packer/cmd/struct-markdown	[no test files]
ok  	github.com/hashicorp/packer/command	3.717s
?   	github.com/hashicorp/packer/command/enumflag	[no test files]
ok  	github.com/hashicorp/packer/command/flag-kv	0.019s
ok  	github.com/hashicorp/packer/command/flag-slice	0.018s
ok  	github.com/hashicorp/packer/fix	0.026s
ok  	github.com/hashicorp/packer/hcl2template	0.281s
?   	github.com/hashicorp/packer/hcl2template/addrs	[no test files]
ok  	github.com/hashicorp/packer/hcl2template/function	0.028s
?   	github.com/hashicorp/packer/hcl2template/internal	[no test files]
?   	github.com/hashicorp/packer/hcl2template/repl	[no test files]
ok  	github.com/hashicorp/packer/hcl2template/shim	0.019s
ok  	github.com/hashicorp/packer/helper/builder/testing	0.027s
ok  	github.com/hashicorp/packer/helper/communicator	0.034s
ok  	github.com/hashicorp/packer/helper/communicator/ssh	4.204s
ok  	github.com/hashicorp/packer/helper/communicator/sshkey	2.744s
?   	github.com/hashicorp/packer/helper/tests	[no test files]
?   	github.com/hashicorp/packer/helper/tests/acc	[no test files]
?   	github.com/hashicorp/packer/helper/wrappedreadline	[no test files]
?   	github.com/hashicorp/packer/helper/wrappedstreams	[no test files]
ok  	github.com/hashicorp/packer/packer	0.221s
ok  	github.com/hashicorp/packer/packer/plugin	0.417s
ok  	github.com/hashicorp/packer/packer/rpc	0.059s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/adapter	0.063s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/bootcommand	2.778s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/chroot	0.038s
?   	github.com/hashicorp/packer/packer-plugin-sdk/common	[no test files]
?   	github.com/hashicorp/packer/packer-plugin-sdk/filelock	[no test files]
ok  	github.com/hashicorp/packer/packer-plugin-sdk/guestexec	0.029s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/iochan	0.019s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/json	0.017s [no tests to run]
ok  	github.com/hashicorp/packer/packer-plugin-sdk/multistep	0.126s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/multistep/commonsteps	0.136s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/net	1.041s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/packerbuilderdata	0.018s
?   	github.com/hashicorp/packer/packer-plugin-sdk/random	[no test files]
ok  	github.com/hashicorp/packer/packer-plugin-sdk/retry	0.021s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/sdk-internals/communicator/none	0.026s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/sdk-internals/communicator/ssh	0.095s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/sdk-internals/communicator/winrm	0.062s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/shell	0.023s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/shell-local	0.045s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/shell-local/localexec	0.031s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/shutdowncommand	0.032s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/template	0.041s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/template/config	0.033s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate	0.032s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate/aws/secretsmanager	0.030s
?   	github.com/hashicorp/packer/packer-plugin-sdk/tmp	[no test files]
ok  	github.com/hashicorp/packer/packer-plugin-sdk/useragent	0.018s
ok  	github.com/hashicorp/packer/packer-plugin-sdk/uuid	0.019s
?   	github.com/hashicorp/packer/packer-plugin-sdk/version	[no test files]
ok  	github.com/hashicorp/packer/plugin/example	0.040s [no tests to run]
?   	github.com/hashicorp/packer/post-processor/alicloud-import	[no test files]
?   	github.com/hashicorp/packer/post-processor/alicloud-import/version	[no test files]
?   	github.com/hashicorp/packer/post-processor/amazon-import	[no test files]
?   	github.com/hashicorp/packer/post-processor/amazon-import/version	[no test files]
?   	github.com/hashicorp/packer/post-processor/artifice	[no test files]
?   	github.com/hashicorp/packer/post-processor/artifice/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/checksum	0.032s
?   	github.com/hashicorp/packer/post-processor/checksum/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/compress	0.046s
?   	github.com/hashicorp/packer/post-processor/compress/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/digitalocean-import	0.038s
?   	github.com/hashicorp/packer/post-processor/digitalocean-import/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/docker-import	0.036s
?   	github.com/hashicorp/packer/post-processor/docker-import/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/docker-push	0.037s
?   	github.com/hashicorp/packer/post-processor/docker-push/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/docker-save	0.038s
?   	github.com/hashicorp/packer/post-processor/docker-save/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/docker-tag	0.042s
?   	github.com/hashicorp/packer/post-processor/docker-tag/version	[no test files]
?   	github.com/hashicorp/packer/post-processor/exoscale-import	[no test files]
?   	github.com/hashicorp/packer/post-processor/exoscale-import/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/googlecompute-export	0.044s [no tests to run]
?   	github.com/hashicorp/packer/post-processor/googlecompute-export/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/googlecompute-import	0.035s
?   	github.com/hashicorp/packer/post-processor/googlecompute-import/version	[no test files]
?   	github.com/hashicorp/packer/post-processor/manifest	[no test files]
?   	github.com/hashicorp/packer/post-processor/manifest/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/shell-local	0.047s
?   	github.com/hashicorp/packer/post-processor/shell-local/version	[no test files]
?   	github.com/hashicorp/packer/post-processor/ucloud-import	[no test files]
?   	github.com/hashicorp/packer/post-processor/ucloud-import/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/vagrant	0.045s
?   	github.com/hashicorp/packer/post-processor/vagrant/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/vagrant-cloud	0.089s
?   	github.com/hashicorp/packer/post-processor/vagrant-cloud/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/vsphere	0.038s
?   	github.com/hashicorp/packer/post-processor/vsphere/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/vsphere-template	0.047s
?   	github.com/hashicorp/packer/post-processor/vsphere-template/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/yandex-export	0.055s
?   	github.com/hashicorp/packer/post-processor/yandex-export/version	[no test files]
ok  	github.com/hashicorp/packer/post-processor/yandex-import	0.052s
?   	github.com/hashicorp/packer/post-processor/yandex-import/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/ansible	0.469s
?   	github.com/hashicorp/packer/provisioner/ansible/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/ansible-local	0.055s
?   	github.com/hashicorp/packer/provisioner/ansible-local/version	[no test files]
?   	github.com/hashicorp/packer/provisioner/azure-dtlartifact	[no test files]
?   	github.com/hashicorp/packer/provisioner/azure-dtlartifact/version	[no test files]
?   	github.com/hashicorp/packer/provisioner/breakpoint	[no test files]
?   	github.com/hashicorp/packer/provisioner/breakpoint/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/chef-client	0.056s
?   	github.com/hashicorp/packer/provisioner/chef-client/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/chef-solo	0.045s
?   	github.com/hashicorp/packer/provisioner/chef-solo/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/converge	0.033s
?   	github.com/hashicorp/packer/provisioner/converge/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/file	0.051s
?   	github.com/hashicorp/packer/provisioner/file/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/inspec	0.050s
?   	github.com/hashicorp/packer/provisioner/inspec/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/powershell	2.095s
?   	github.com/hashicorp/packer/provisioner/powershell/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/puppet-masterless	0.049s
?   	github.com/hashicorp/packer/provisioner/puppet-masterless/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/puppet-server	0.043s
?   	github.com/hashicorp/packer/provisioner/puppet-server/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/salt-masterless	0.054s
?   	github.com/hashicorp/packer/provisioner/salt-masterless/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/shell	0.085s
?   	github.com/hashicorp/packer/provisioner/shell/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/shell-local	0.071s
?   	github.com/hashicorp/packer/provisioner/shell-local/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/sleep	0.027s
?   	github.com/hashicorp/packer/provisioner/sleep/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/windows-restart	0.051s
?   	github.com/hashicorp/packer/provisioner/windows-restart/version	[no test files]
ok  	github.com/hashicorp/packer/provisioner/windows-shell	0.039s
?   	github.com/hashicorp/packer/provisioner/windows-shell/version	[no test files]
?   	github.com/hashicorp/packer/scripts	[no test files]
?   	github.com/hashicorp/packer/version	[no test files]
2020-12-03 11:32:34 +00:00
Gareth Rees
a05c554d14 Amend commit author for license pass 2020-12-03 10:05:07 +00:00
Megan Marsh
863e20ad65 move builder/testing framework into sdk; it imports the core but I think we just need to accept that. It doesn't expose the core directly to the SDK. 2020-12-02 09:46:42 -08:00
Megan Marsh
196ac12d07
Merge pull request #10325 from hashicorp/move_comm_helper
Move comm helper
2020-12-02 08:52:28 -08:00
Megan Marsh
39354f64e5 move helper/communicator dir into packer-plugin-sdk
fix imports; fix website and generated partials
2020-12-02 08:41:32 -08:00
Megan Marsh
ff549e0b23 fix tests 2020-12-02 08:41:31 -08:00
Megan Marsh
307f56f560 move postprocessor to sdk, fix generation code 2020-12-02 08:41:31 -08:00
Megan Marsh
b4bc3f1c7b move provisioner interface into sdk 2020-12-02 08:41:31 -08:00
Megan Marsh
faa3832537 extract builder interface to sdk 2020-12-02 08:41:31 -08:00
Megan Marsh
179e436670
Merge pull request #10323 from hashicorp/more_sdk
extract builder interface to sdk
2020-12-02 08:40:01 -08:00
jhawk28
89199a4c57
WaitForIP should not return an error if an IP is not found (#10321) 2020-12-02 10:30:42 +01:00
Megan Marsh
bf6ab0c290 fix tests 2020-12-01 15:02:15 -08:00
Megan Marsh
b69d69095e move postprocessor to sdk, fix generation code 2020-12-01 14:48:55 -08:00
Megan Marsh
be5763ec41 move provisioner interface into sdk 2020-12-01 14:25:14 -08:00
Megan Marsh
ada91b24e9 extract builder interface to sdk 2020-12-01 13:42:42 -08:00
Megan Marsh
fab442eb52
Merge pull request #10289 from hashicorp/extract_ui
Untangle packer/packer
2020-12-01 11:27:21 -08:00
Megan Marsh
f8bc406306 update changelog 2020-12-01 11:27:03 -08:00
Megan Marsh
edbd483917 fix go-getter imports 2020-12-01 10:59:08 -08:00
Megan Marsh
19bdc8b49e fix conflicts 2020-11-30 14:34:20 -08:00
Megan Marsh
0eff73293a fix imports, vendoring, and linting 2020-11-30 14:30:30 -08:00
Megan Marsh
d5971ca25e fix tests by moving mock hooks and communicators, and BasicUi definition, into SDK 2020-11-30 14:30:30 -08:00
Megan Marsh
f81ed344a2 regenerate code 2020-11-30 14:30:30 -08:00
Megan Marsh
56a45b04ab Move hook and communicator definitions to packer-plugin-sdk 2020-11-30 14:30:30 -08:00
Megan Marsh
a6fdeca099 move logsecretfilter into packer sdk 2020-11-30 14:30:30 -08:00
Megan Marsh
14bdb9516c move Artifact and artifact mock to the sdk 2020-11-30 14:29:52 -08:00
Megan Marsh
c70870cb83 move multierror and multierrorappend into sdk 2020-11-30 14:29:06 -08:00
Megan Marsh
001886670d move Ui definition into the packer plugin sdk. 2020-11-30 14:26:54 -08:00
Megan Marsh
47f623a3a5
Merge pull request #10297 from Direnol/yandex/prepare-user-data
support merge cloud user-data
2020-11-30 14:09:23 -08:00
Megan Marsh
a56477c2e4
Merge branch 'master' into yandex/prepare-user-data 2020-11-30 13:57:35 -08:00
Megan Marsh
ab8d034818
Merge pull request #10292 from adeniyistephen/newfeature
Fix SSH-Private-Key-File to the vsphere-iso mdx file
2020-11-30 13:41:10 -08:00
adeniyistephen1
5ff59be242 Fix SSH-Private-Key-File to the vsphere-iso mdx file 2020-11-30 13:28:10 -08:00
Megan Marsh
862700b1a5
Merge pull request #10306 from bugfood/fix-attach
allow attaching guest additions without a communicator
2020-11-30 10:58:23 -08:00
Megan Marsh
c30a80e63d
Merge pull request #10308 from hashicorp/vsphere_clone_docs_10288
Improve vsphere-clone customization example
2020-11-30 10:36:37 -08:00
Megan Marsh
3bda89467d
Merge pull request #10303 from GennadySpb/yndx-export-wait-and-retries
yandex-export: Add retries and wait after disk attach operation
2020-11-30 10:14:25 -08:00
Megan Marsh
f40eab4733
Merge pull request #10305 from Direnol/yandex/fix-verify-service-account-id-in-export
added check of service account id in export
2020-11-30 09:39:33 -08:00
Wilken Rivera
d82b9d2072
builder/qemu: Add ok check for state values (#10249)
This changes fixes two crashes in `step_run` that expects certain
information to be in state from prior steps. This change requires
testing to ensure the bugs have been fixed.

I believe there may be more state values that need to be checked as they
may not be put into state if a build configuration has attributes that
would skip or otherwise not put data into the statebag.
2020-11-30 10:40:03 -05:00
Pavlos Parissis
fac8ba2040
googlecompute-export: Add logging.write to service account scopes 2020-11-30 10:49:34 +01:00
Gennady Lipenkov
4c3e310f57 manually trigger udev 2020-11-26 17:29:33 +03:00
Gennady Lipenkov
ef67fb1cc8 Some wait before check 2020-11-25 15:45:49 +03:00
sylviamoss
6c410e4d13 improve customization example 2020-11-25 10:50:09 +01:00
Corey Hickey
fdb36e329d allow attaching guest additions without a communicator
This avoids the error:
* guest_additions_mode has to be 'disable' when communicator = 'none'.

...when the following are set:
"communicator": "none",
"guest_additions_mode": "attach",

This particular combination of parameters is valid; for example, in my
case, a kickstart post-install script mounts the CD image from /dev/sr1
and runs the installer, without needing any intervention from packer
itself.

From my reading of the documentation, it appears that the "upload" mode
would indeed require a communicator, so I change the logic to check for
that specifically.
2020-11-24 15:46:14 -08:00
Roman Mingazeev
677c48d294 add record to changelog 2020-11-24 20:07:52 +03:00
Roman Mingazeev
a509781a03 added check of service account id in export 2020-11-24 20:04:37 +03:00
Gennady Lipenkov
138e3a081b Add retries and wait after disk attach operation 2020-11-24 19:15:46 +03:00
Adrien Delorme
73b7499811
HCL2: version block: test validation & document version/availability (#10298)
* HCL2: Test that the packer block passes in packer validate

* HCL2: Test invalid packer blocks are invalid

* docs: state from which version the packer block is available
2020-11-23 10:27:26 -05:00
Roman Mingazeev
937e3425e5 add changelog record 2020-11-23 17:46:18 +03:00
Roman Mingazeev
2b8fcead23 support shellscript 2020-11-23 17:15:12 +03:00
Roman Mingazeev
0101eb1bb1 support merge cloud user-data 2020-11-23 13:19:50 +03:00
Adrien Delorme
c5da8c5c37
Fix salt-masterless provisioner after merge conflict compilation error (#10296)
This is most likely due to the merge between #10291 and #10257 ( that moves WindowsOSType into guestexec.

This fixes #10291
2020-11-23 10:29:12 +01:00
Megan Marsh
b50fe930e5
fix retries (#10290) 2020-11-23 09:39:17 +01:00
Megan Marsh
5a804de9a3
Merge pull request #10212 from OblateSpheroid/GH8211
Feat (builder/oracle-oci): support image launch mode
2020-11-20 15:53:18 -08:00
Megan Marsh
7141dcfecb
Merge pull request #10201 from davewoodward/feature/windows-package-manager
Add calls to winrepo.update_git_repos and pkg.refresh_db
2020-11-20 15:48:42 -08:00
Megan Marsh
f4041ee4d0
Merge pull request #10200 from aleksandrserbin/feature/describe-instance-on-fail
amazon-ebs: log state details on change
2020-11-20 15:31:40 -08:00
Megan Marsh
10c1b638b6 fix spaces vs tabs in formatting from github commit resolution 2020-11-20 15:24:43 -08:00
Megan Marsh
392cdc5fe4
Merge pull request #10199 from aleksandrserbin/feature/aws-ebs-io-validation
amazon-ebs: validate IOPS ratio
2020-11-20 15:23:59 -08:00
Megan Marsh
ba1e60ff35
Update builder/amazon/common/block_device_test.go 2020-11-20 15:15:39 -08:00
Megan Marsh
b3401b4f4d
Merge branch 'master' into feature/aws-ebs-io-validation 2020-11-20 15:09:22 -08:00
Megan Marsh
6bf4e89615
Merge pull request #10181 from remyleone/profile
scaleway: use the SDK functions to load profile from file and env
2020-11-20 15:06:50 -08:00
Megan Marsh
01f6763db0 fix generation 2020-11-20 14:53:08 -08:00
Megan Marsh
e34248a45d
Merge pull request #10172 from anish/gcpshieldedvms
Add support for creating shielded VMs to GCP
2020-11-20 14:46:51 -08:00
Megan Marsh
8ec7ee0ab7
Merge pull request #10093 from ufukty/digitalocean-connect-with-private-ip
Adds the capability of provisioning with private ip for digitalocean
2020-11-20 14:33:03 -08:00
Megan Marsh
60e62bbb51
Merge pull request #10287 from hashicorp/implement_9990
Add configuration options to add additional storage to a cloned vm
2020-11-20 13:34:56 -08:00
Megan Marsh
030f40a7b6
Merge pull request #10286 from hashicorp/hcl2template_extraction
move hcl2template kv types into the config/custom_types
2020-11-20 12:48:26 -08:00
Megan Marsh
779661bee6
Merge pull request #10285 from hashicorp/fix_generate_errors
Fix generate errors
2020-11-20 10:36:22 -08:00
sylviamoss
99e7ac5f42 fix test and generated code 2020-11-20 17:15:47 +01:00
sylviamoss
3b523e147e add config opt to additional storage to cloned vm 2020-11-20 16:20:46 +01:00
Wilken Rivera
f42094688f
Add note to unmaintained provisioners (#10283) 2020-11-19 10:36:31 -05:00
Megan Marsh
ea1ac530b0 move hcl2template kv types into the config/custom_types with trilean definitions 2020-11-18 15:46:59 -08:00
Megan Marsh
cbaecf9077 remove unused SkipValidation field which was a duplicate of the SkipRegionValidation field.
remove duplicate temporary key pair name
change communicator code
2020-11-18 14:21:40 -08:00
Megan Marsh
aff33f057a
Merge pull request #10282 from hashicorp/version_and_useragent_to_sdk
Version and useragent to sdk
2020-11-18 14:11:25 -08:00
Megan Marsh
5323e3f83c
Merge pull request #10281 from hashicorp/communicator_helper_move
move communicator helpers into communicator dir
2020-11-18 14:10:53 -08:00
Megan Marsh
f8f1ebf0c7 move version and useragent definitions into sdk 2020-11-18 11:42:02 -08:00
Megan Marsh
9e47696dff move helper/config to bundle with the other template definitions 2020-11-18 10:34:59 -08:00
Megan Marsh
007337989e move communicator helpers into communicator dir 2020-11-18 10:24:25 -08:00
Megan Marsh
bf47d12cf2
Merge pull request #10275 from hashicorp/multistep
move multistep into the plugin sdk
2020-11-18 09:56:33 -08:00
Anish Bhatt
ecb72663f3 Add support for creating shielded VMs to GCP 2020-11-17 18:37:46 -08:00
Megan Marsh
da0e478044 fix imports 2020-11-17 17:18:45 -08:00
Megan Marsh
3a11954d96 fix generated files and website 2020-11-17 17:07:02 -08:00
Megan Marsh
3f6deb8828 move multistep into the plugin sdk 2020-11-17 16:31:03 -08:00
Megan Marsh
8350ade7ef
Merge pull request #10266 from hashicorp/command_flags
Move flag packages from helper to command
2020-11-17 10:59:07 -08:00
Megan Marsh
e637407797
Merge pull request #10257 from hashicorp/plugin-sdk-5
Plugin sdk 5
2020-11-17 10:54:53 -08:00
Megan Marsh
7d658149ea update tests and website and generated partials to reflect new package format 2020-11-17 10:36:01 -08:00
Megan Marsh
3da99f7bdc add more documentation to the packages in common directory 2020-11-17 10:35:00 -08:00
Megan Marsh
2baffa3ebc
Merge pull request #10267 from hashicorp/move_tmp
move tmp helper func into packer-plugin-sdk
2020-11-17 10:17:32 -08:00
Chris Lundquist
f8cee26dac
Merge pull request #10265 from lz1irq/update-lxd-builder-docs
Add couple of missing LXD builder parameters to documentation
2020-11-16 17:47:42 -08:00
Megan Marsh
1ffc358ada move tmp helper func into packer-plugin-sdk 2020-11-16 15:13:08 -08:00
Megan Marsh
6a1a22151c move the various flag packages from helper to command, since command is the only package that uses them. 2020-11-16 14:23:35 -08:00
Ivaylo Markov
37eec09cea Add couple of missing LXD builder parameters to documentation 2020-11-16 23:17:35 +02:00
Megan Marsh
4ead224c3b
Merge pull request #10256 from hashicorp/plugin-sdk-4
Plugin sdk 4
2020-11-16 12:00:06 -08:00
Megan Marsh
94a660147e rename retry so it doesn't stutter 2020-11-16 11:49:33 -08:00
Megan Marsh
bf7daa1d93
Merge pull request #10255 from hashicorp/plugin-sdk-3
Plugin sdk 3
2020-11-16 11:36:17 -08:00
Megan Marsh
efe11da4a3
Merge pull request #10254 from hashicorp/plugin-sdk-2
Plugin sdk 2
2020-11-16 11:29:20 -08:00
Megan Marsh
220bca460e
Merge pull request #10253 from hashicorp/plugin-sdk-1
Plugin sdk 1
2020-11-16 11:13:59 -08:00
Megan Marsh
3e54e9ea80
Merge pull request #10235 from hashicorp/refactor_version_code
Refactor version code
2020-11-16 11:12:59 -08:00
Sora Morimoto
4e33f99c79
Fix a broken link in the README (#10259)
Signed-off-by: Sora Morimoto <sora@morimoto.io>
2020-11-16 10:51:55 -05:00
Calle Pettersson
ae4c9461ec
Merge pull request #10260 from loloolllool/10252-proxmox-iso-bad-boot-order-prevent
Proxmox builder pass through boot-order
2020-11-16 08:18:14 +01:00
loloolllool
5a3ea4b094 Adding optional boot documentation 2020-11-16 05:02:28 +01:00
loloolllool
54afe0b880 Generating new hcl2specs for proxmox builder. 2020-11-14 23:41:16 +01:00
lollen
2bdfd53756 Proxmox-builder pass through boot-order
Adding the boot field supported by Proxmox api and proxmox-api-go library.
This is due to a change in Proxmox to allow for multiple boot harddrives which would break the packer proxmox builder (the hardcoded cdn boot value).

Can be specified like the following example:     
      "disks": [
        {
          "type": "scsi",
          "disk_size": "20G",
          "storage_pool": "vmstorage",
          "storage_pool_type": "lvm"
        }
      ],
      "boot": "order=scsi0;ide2",
      "iso_file": "media:iso/{{ user `ubuntu_iso_file` }}"

Not sure this is ideal, but it's a workaround for the #10252 issue.
2020-11-14 07:27:55 +01:00
Megan Marsh
f52a2ad0fa move retry function that is only used by osc builder into that builder's common dir instead of the global common dir. Fix bug in quemu where the wrong retry value is checked against. 2020-11-13 15:24:58 -08:00
Megan Marsh
fa233a6a56 remove unused code leftover from original progress bar implementation 2020-11-13 15:24:58 -08:00
Megan Marsh
c4d0c5505a fix tests
regenerate code
regenerate code, revendor
fix website
2020-11-13 15:00:12 -08:00
Megan Marsh
e04eaa89e6 move steps and step configs from packer/common to packer/common/commonsteps 2020-11-13 11:15:04 -08:00
Megan Marsh
6402362018 create packer-plugin-sdk directory and begin moving the relevant folders into it. 2020-11-13 10:47:36 -08:00
Megan Marsh
df9febef1b move communicators into sdk-internals directory 2020-11-13 10:44:07 -08:00
Megan Marsh
6871a3a85d
Merge pull request #10250 from Direnol/yandex/change-disk-creation-method
fix(yandex): change disk creation method to manual
2020-11-13 09:28:10 -08:00
Roman Mingazeev
6be26e50e0
Update builder/yandex/config.go
Co-authored-by: GennadySpb <lipenkov@gmail.com>
2020-11-13 17:27:50 +03:00
Roman Mingazeev
14abb8ce2b
Update website/pages/partials/builder/yandex/Config-not-required.mdx
Co-authored-by: GennadySpb <lipenkov@gmail.com>
2020-11-13 17:21:32 +03:00
Roman Mingazeev
5bf03df694 fix fmt 2020-11-13 16:44:15 +03:00
Roman Mingazeev
6a327b1330 add labels for temp disk 2020-11-13 16:35:48 +03:00
Roman Mingazeev
fe9dca4c75 change disk creation method to manual 2020-11-13 16:16:35 +03:00
Adrien Delorme
38c50cf00e
HCL2: Add more documentation to path-variables (#10245)
* HCL2: Add more documentation to path-variables

Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2020-11-13 11:05:57 +01:00
Wilken Rivera
67e2c0b83c
Add nullStep as return for multistep.If (#10247)
This change introduces a new nullStep type that can be used in place of
a nil step. This fixes an issue where multistep.If would return a nil
step if the condition was not met causing a builder to crash when
executed using `-on-error=ask` or `-on-error=abort`.

Closes #10241
2020-11-12 11:26:54 -05:00
Adrien Delorme
f44e912072
Update hcl2upgrade command to update env calls + tests (#10244) 2020-11-11 14:54:22 -05:00
Wilken Rivera
1a08bf8ce9 update CHANGELOG
* fix spacing, typos
2020-11-11 13:57:36 -05:00
Wilken Rivera
2e9e7d13b6 update CHANGELOG 2020-11-11 13:46:18 -05:00
Wilken Rivera
acabc1c1aa
Add packer fmt command (#10225)
* Add packer fmt command

This change adds a new command that allows users to format one or more
HCL2 Packer configuration template files.

Related to: #9174

* command/fmt: Add check flag

Packer's fmt command now supports a check flag that will output the name
of any file that would be changed by the HCL2 formatting engine. The
check flag is mutually exclusive with the write flag and will only check
if formatting is needed.

The update write flag will now overwrite the source files with the newly
formatted HCL2 source unless the `-write=false` or `-check` is passed at
the command line.

* Returns a diagnostic error if Format is unable to show a diff - equivalent to `terraform fmt`
* Updates testing to run against #Format and not the private methods of the HCL2Formatter; fixes ShowDiff test failure on Windows
* Updates comments for exported functions

* Add docs for fmt command
2020-11-11 11:49:39 -05:00
Adrien Delorme
deba1484ff
HCL2: allow calling env as input var default value (#10240)
* HCL2: allow to use env in default value of input variables
2020-11-11 11:27:32 +01:00
Megan Marsh
46cf8a1602 add all provisioner version files 2020-11-10 15:01:07 -08:00
Megan Marsh
2167118126 add version files for all postprocessors 2020-11-10 14:55:45 -08:00
Megan Marsh
3db40194af version files 2020-11-10 14:48:06 -08:00
Megan Marsh
8ecd16db81 regenerate code 2020-11-10 08:16:59 -08:00
Adrien Delorme
17ec88246f
hcl2_upgrade update (#10221)
* handle template_dir, pwd funcs, handle min_packer_version
* gotpl packer_version becomes hcl2 packer.version
* uuid becomes hcl2 uuidv4
* test code with emojis
* handle all cases were we cannot guess what the argument was
* handle clean_resource_name cases
* up docs
2020-11-10 10:46:20 +01:00
Megan Marsh
1ecd715221 refactor code so that packer/version is not a dependency of sdk code or plugin code 2020-11-09 17:20:42 -08:00
Megan Marsh
cd59d938b2 refactor core version pkg imports out of json interpolation/decode pathway. 2020-11-09 13:20:36 -08:00
Megan Marsh
bc85854a53 refactor packer version out of hcltemplate code. 2020-11-09 12:29:53 -08:00
Megan Marsh
2bf912bddf
Merge pull request #10203 from aleksandrserbin/feature/launch-template-tags
amazon-ebs: add tags to launch template
2020-11-09 09:14:02 -08:00
Daniel Underwood
23a7f67778
Fix proxmox page links (#10230) 2020-11-09 09:33:07 -05:00
Megan Marsh
88e03280b6
Extract plugin-specific examples to plugin directories (#10228)
* move alicloud examples from common example directory to alicloud builder

* move amazon examples to amazon builder dir

* move examples into ansible provisioner directory

* move azure examples to builder dir

* move hyperone examples into builder directory

* move jdcloud builder examples into builder directory

* move tencent cloud examples into the builder directory

* move ucloud examples into ucloud builder directory
2020-11-09 12:17:41 +01:00
Megan Marsh
cd74456026
Common provisioner helpers (#10229)
* update docstrings to make it clear that plugins are servers and core is client

* move provisioner guest helper functions into common dir.
2020-11-09 12:16:44 +01:00
Paul Meyer
b7568f5a4d
Update CHANGELOG.md 2020-11-06 14:08:58 -08:00
Paul Meyer
5ea90fea5b
Merge pull request #10210 from sumit-kalra/master
[builder/azure-arm] Create keyvaults with SoftDelete enabled
2020-11-06 14:07:41 -08:00
Megan Marsh
efc117fb55
Merge pull request #10218 from hashicorp/clean_plugin_sdk
Clean plugin sdk
2020-11-06 12:35:23 -08:00
Simon Gottschlag
65b7d3b604
Add Azure CLI authentication (#10157)
Adds the ability to use an active `az login` session for authenticating the Azure builder
2020-11-06 14:24:16 -05:00
Jimmy Merritello
bb076d8ad7
Bump HSM version for design tweaks (#10216) 2020-11-06 14:07:04 -05:00
Megan Marsh
396b0237fa
Merge pull request #10224 from hashicorp/fix_tag_interpolation
fix single tag interpolation to allow golang template engine usage
2020-11-06 11:05:24 -08:00
Megan Marsh
2d90ffe7a4 move GeneratedData struct and PlaceholderMsg to same package under common 2020-11-06 10:45:38 -08:00
Chris Roberts
d8222b1656
Add support for uploading directly to storage on Vagrant Cloud (#10193)
Vagrant Cloud provides support for uploading directly to the backend
storage instead of streaming through Vagrant Cloud. This adds support
for direct to storage uploads and sets it as the default upload method.
A new option has been added to disable this behavior and revert back
to streaming upload via Vagrant Cloud (`no_direct_upload`).

This default for uploading directly to the backend storage also matches
up with changes being added to Vagrant proper for box upload behavior:
hashicorp/vagrant#11916
2020-11-05 20:01:55 -05:00
Megan Marsh
f13f3d4d5f fix single tag interpolation to allow golang template engine usage 2020-11-05 16:27:53 -08:00
Megan Marsh
7a1680df97
modify a ton of error messages to make them specifically placable. (#10191)
* modify a ton of error messages to make them specifically placable.
* remove specific loglines but keep the specialized error messages

Co-authored-by: Adrien Delorme <azr@users.noreply.github.com>
2020-11-05 11:27:07 +01:00
Megan Marsh
45b5f0c2ee move custom http client creation with env proxy args into same package as other network related helpers 2020-11-04 14:51:14 -08:00
Megan Marsh
7b57e28600 move localexec to common/shell-local dir since it is related to shelling out locally 2020-11-04 11:56:46 -08:00
Aleksandr Serbin
a763c8ab02 amazon: validate IOPS only for io volumes 2020-11-04 20:49:04 +01:00
Aleksandr Serbin
09c2620c48 amazon: validate IOPS max and min values 2020-11-04 20:29:09 +01:00
Megan Marsh
61b9015415
Merge pull request #10206 from hashicorp/azr_variable_validation
HCL2: add variable validation
2020-11-04 10:46:17 -08:00
Megan Marsh
23552bfbd7
Merge pull request #10213 from chrisroberts/vagrant-driv-stderr
Return error if ssh-config command fails
2020-11-04 10:39:23 -08:00
Adrien Delorme
addd2da101 add can examples 2020-11-04 15:44:21 +01:00
Megan Marsh
d8fec2e9e5
move the hyperv-only powershell dependency into the hyperv subdirectory (#10198) 2020-11-04 15:15:43 +01:00
Marin Salinas
8b5e2903b9
feat: add hk endpoint support for osc builder (#10207) 2020-11-04 15:13:37 +01:00
Aleksandr Serbin
0cf9b55c5c amazon-ebs: validate IOPS ratio 2020-11-04 14:37:41 +01:00
Adrien Delorme
73caad492c Update custom-validation.mdx
add complex example
2020-11-04 13:31:45 +01:00
Adrien Delorme
fd873b8811 Referenceable: explain a bit more of the whys 2020-11-04 13:21:41 +01:00
Adrien Delorme
10eb32d29e require less English 2020-11-04 13:13:45 +01:00
Chris Roberts
8248f52ff7 Return error if ssh-config command fails
Update error detection to return an error if the process fails instead
of testing for content in stderr.
2020-11-03 16:20:34 -08:00
Aleksandr Serbin
7cb8af1441 amazon: remove region from state for chroot builder 2020-11-03 22:28:19 +01:00
Aleksandr Serbin
8dab31b548 amazon: use spot tags for launch template tags
- use `spot_tags` instead of `run_tags` for launch template
- move region to `StepRunSpotInstance` from state
2020-11-03 22:16:00 +01:00
Dave Woodward
257439786c Remove brackets intended to scope usage of cmd variable and leverage unique variable names instead. 2020-11-03 10:39:51 -06:00
js-g
749a1372d2 test (builder/oracle-oci): add config test for LaunchMode 2020-11-03 11:36:11 -05:00
js-g
ab23014489 docs (builder/oracle-oci): add reference to image_launch_mode 2020-11-03 11:36:03 -05:00
js-g
ba6173b84c fix (builder/oracle-oci): remove subnet from LaunchInstanceDetails
Deprecated use. Use subnet in CreateVnicDetails instead.
2020-11-03 11:35:34 -05:00
js-g
c3ffb3dc22 feat (builder/oracle-oci): add launch mode property to image 2020-11-03 10:33:23 -05:00
Sumit Kalra
2b69a5f496 azure-arm builder: Create keyvaults with SoftDelete enabled 2020-11-02 20:42:55 -08:00
Dave Woodward
4152d527df Include download and installation of Git to satisfy the winrepo.update_git_repos prerequisite. Also removed unneeded p.sudo since we know we are working with Windows. 2020-11-02 21:27:11 -06:00
Megan Marsh
9ec55d3cd7 update changelog 2020-11-02 15:19:31 -08:00
Megan Marsh
b7c6712874
Merge pull request #10197 from hashicorp/dependabot/npm_and_yarn/website/bl-1.2.3
Bump bl from 1.2.2 to 1.2.3 in /website
2020-11-02 09:23:18 -08:00
Megan Marsh
4aa143a429
Merge pull request #10188 from Direnol/yandex/check-access-to-specific-bucket
verifying the access to a specific bucket
2020-11-02 09:21:27 -08:00
Megan Marsh
0bb110ddb3
Merge pull request #10161 from marinsalinas/x509cert
feat: OSC: add x509 certificate support
2020-11-02 09:20:15 -08:00
Adrien Delorme
2987d25335 simplify tests 2020-11-02 17:52:19 +01:00
Adrien Delorme
20b7fd9687 add hcl2template/addrs/doc.go 2020-11-02 17:48:29 +01:00
Adrien Delorme
971254928a various fixes 2020-11-02 17:43:21 +01:00
Adrien Delorme
d919fc28ab add doc 2020-11-02 17:20:46 +01:00
Marin Salinas
378dae4a8d chore: add x509 configuration description to website 2020-11-02 10:04:00 -06:00
Marin Salinas
f2b386a9d0 feat: add x509 certificate support 2020-11-02 10:04:00 -06:00
Adrien Delorme
88175873e5 fix tests to actually check cty values & types 2020-11-02 17:03:38 +01:00
Adrien Delorme
6dd06fad14 add command/ tests 2020-11-02 15:50:38 +01:00
Adrien Delorme
6911495fc4 add VariableAssignment struct that help describe an input var assignment 2020-11-02 15:22:29 +01:00
Aleksandr Serbin
d561b404d6 amazon-ebs: add tags to launch template 2020-11-01 16:25:43 +01:00
Dave Woodward
8a0aa68a4e Add calls to winrepo.update_git_repos and pkg.refresh_db if the operating system is Windows. 2020-10-31 20:26:33 -05:00
Aleksandr Serbin
4669c0f852 amazon-ebs: log state details on change 2020-10-31 16:00:19 +01:00
packer-ci
a64d3baf8e Putting source back into Dev Mode 2020-10-30 20:35:50 +00:00
dependabot[bot]
e11a305707
Bump bl from 1.2.2 to 1.2.3 in /website
Bumps [bl](https://github.com/rvagg/bl) from 1.2.2 to 1.2.3.
- [Release notes](https://github.com/rvagg/bl/releases)
- [Commits](https://github.com/rvagg/bl/compare/v1.2.2...v1.2.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-30 20:23:21 +00:00
packer-ci
945908fd74
Cut version 1.6.5 2020-10-30 19:31:47 +00:00
packer-ci
40d60af00a cut version 1.6.5 2020-10-30 19:31:46 +00:00
packer-ci
c3b3675d65 update changelog 2020-10-30 19:31:46 +00:00
Megan Marsh
d39dffc573
Merge pull request #10196 from hashicorp/b-aws_secretsmanager-stage-override-issue
Fix issue with AWS secrets manager override default stage
2020-10-30 11:35:37 -07:00
Wilken Rivera
50211622b2 Update documenation for HCL enables aws_secretsmanager function 2020-10-30 14:18:17 -04:00
Wilken Rivera
bbb6754367 Fix issue with AWS secrets manager override default stage
Before change
```
⇶  packer build amazon-ebs_secretsmanager_shell-local.json
Error:
template: root:1:3: executing "root" at <aws_secretsmanager `packer/test/keys`

`shell`>: error calling aws_secretsmanager: ResourceNotFoundException: Secrets
Manager can't find the specified secret value for staging label: shell

2020/10/30 12:53:40 [INFO] (telemetry) Finalizing.
template: root:1:3: executing "root" at <aws_secretsmanager `packer/test/keys`
`shell`>: error calling aws_secretsmanager: ResourceNotFoundException: Secrets
Manager can't find the specified secret value for staging label: shell

⇶  packer build amazon-ebs_secretsmanager_shell-local.json.pkr.hcl
Error: Error in function call

  on amazon-ebs_secretsmanager_shell-local.json.pkr.hcl line 28:
  (source code not available)

Call to function "aws_secretsmanager" failed: ResourceNotFoundException: Secrets
Manager can't find the specified secret value for staging label: home.

```

After change
```
⇶  packer.test build amazon-ebs_secretsmanager_shell-local.json
null: output will be in this color.

==> null: Running local shell script: /tmp/packer-shell463393820
    null: boo
    null: keys:powershell
Build 'null' finished after 8 milliseconds 225 microseconds.

==> Wait completed after 8 milliseconds 319 microseconds

==> Builds finished. The artifacts of successful builds are:
--> null: Did not export anything. This is the null builder

⇶  packer.test build amazon-ebs_secretsmanager_shell-local.json.pkr.hcl
null.autogenerated_1: output will be in this color.

==> null.autogenerated_1: Running local shell script: /tmp/packer-shell834410761
    null.autogenerated_1: boo
    null.autogenerated_1: keys:powershell
Build 'null.autogenerated_1' finished after 18 milliseconds 834 microseconds.

==> Wait completed after 18 milliseconds 954 microseconds

==> Builds finished. The artifacts of successful builds are:
--> null.autogenerated_1: Did not export anything. This is the null builder

```
2020-10-30 13:17:38 -04:00
Adrien Delorme
8de2f40a07 add tests for length 2020-10-30 15:42:59 +01:00
Adrien Delorme
b892414e84 add failing test case 2020-10-30 15:40:31 +01:00
Adrien Delorme
9932fd1217 add Variable.validateValue func 2020-10-30 15:38:29 +01:00
Adrien Delorme
4d386dd806 add length function that can work with more types 2020-10-30 15:36:23 +01:00
Adrien Delorme
4e08ea6a92 add a test 2020-10-30 12:41:29 +01:00
Adrien Delorme
91d7332471 add basic code for variable validation parsing
* hcl2template/addrs.ParseRef will parse a reference and tell for example if we
  are referring to a variable and its name, for now it can only do that and in
  the future it improved when we need to most of it is from the TF code. This
  is used to tell wether a variable vas referenced in a variable validation
  condition; for now.
* Added Validations blocks to the hcl2 Variable struct and code to
  parse/validate that.
2020-10-30 12:26:22 +01:00
Roman Mingazeev
3fc185924d fix delete access key 2020-10-30 12:20:10 +03:00
Megan Marsh
7105b5bbcc update changelog 2020-10-29 16:05:23 -07:00
Megan Marsh
845a10867e
Merge pull request #10003 from hashicorp/ssm_session_retry
Add retry mechanism to retry SSM session creation
2020-10-29 16:02:54 -07:00
Megan Marsh
858f49e91e update changelog 2020-10-29 15:45:56 -07:00
Megan Marsh
887a791f35
Merge pull request #10192 from hashicorp/fix_azure_crash
fix crash
2020-10-29 14:58:01 -07:00
Megan Marsh
72fd763207 fix crash 2020-10-29 14:29:16 -07:00
Megan Marsh
54fbc26968
Merge pull request #10190 from hashicorp/use-docker-mirror
Use docker mirror
2020-10-29 13:01:45 -07:00
Michele
54786d8c2e Use docker mirror 2020-10-29 11:05:41 -07:00
Roman Mingazeev
7ab2866d5c verifying the access to a specific bucket 2020-10-29 20:53:04 +03:00
Rémy Léone
0cfaf4a620 Fix 2020-10-29 17:45:03 +01:00
Wilken Rivera
01d5e5ca76 test/amazon/ebs: Add acceptance test for Session Manager Interface connectivity
Test Results
```
...

2020/10/29 09:35:39 ui:     test: Starting session with SessionId: wilken-00bcfae4d314f54e7
2020/10/29 09:35:40 [DEBUG] TCP connection to SSH ip/port failed: dial tcp [::1]:8047: connect: connection refused
2020/10/29 09:35:40 ui:     test: Port 8047 opened for sessionId wilken-00bcfae4d314f54e7.
2020/10/29 09:35:45 [INFO] Attempting SSH connection to localhost:8047...
2020/10/29 09:35:45 [DEBUG] reconnecting to TCP connection for SSH
2020/10/29 09:35:45 ui:     test: Connection accepted for session wilken-00bcfae4d314f54e7.
2020/10/29 09:35:45 [DEBUG] handshaking with SSH
2020/10/29 09:35:45 [DEBUG] SSH handshake err: ssh: handshake failed: ssh: invalid packet length, packet too large
2020/10/29 09:35:52 [INFO] Attempting SSH connection to localhost:8047...
2020/10/29 09:35:52 [DEBUG] reconnecting to TCP connection for SSH
2020/10/29 09:35:52 [DEBUG] handshaking with SSH
2020/10/29 09:35:52 [DEBUG] handshake complete!
2020/10/29 09:35:52 [DEBUG] Opening new ssh session
2020/10/29 09:35:53 [INFO] agent forwarding enabled
2020/10/29 09:35:53 ui: ==> test: Connected to SSH!
2020/10/29 09:35:53 Running the provision hook
2020/10/29 09:35:53 ui: ==> test: Stopping the source instance...
2020/10/29 09:35:53 ui:     test: Stopping instance
2020/10/29 09:35:54 ui: ==> test: Waiting for the instance to stop...
2020/10/29 09:36:25 ui: ==> test: Creating AMI packer-ssm-test-1603978447 from instance i-0853cb6186a3406d5
2020/10/29 09:36:25 ui:     test: AMI: ami-0868a41bbb2df77b3
2020/10/29 09:36:25 ui: ==> test: Waiting for AMI to become ready...
2020/10/29 09:37:59 ui: ==> test: Terminating the source AWS instance...
2020/10/29 09:37:59 ui error: ==> test: Bad exit status: -1
2020/10/29 09:38:15 ui: ==> test: Cleaning up any extra volumes...
2020/10/29 09:38:15 ui: ==> test: No volumes to clean up, skipping
2020/10/29 09:38:15 ui: ==> test: Deleting temporary security group...
2020/10/29 09:38:16 ui: ==> test: Deleting temporary keypair...
2020/10/29 09:38:16 Deregistering image ID (ami-0868a41bbb2df77b3) from region (us-east-1)
2020/10/29 09:38:17 Deregistered AMI id: ami-0868a41bbb2df77b3
2020/10/29 09:38:17 Deleted snapshot: snap-09602f15994bc9f51
--- PASS: TestBuilderAcc_SessionManagerInterface (249.87s)
PASS

```
2020-10-29 09:39:19 -04:00
Adrien Delorme
aae1992649 remove default PauseBeforeSSM, this will have to be set manually 2020-10-29 13:38:03 +01:00
Adrien Delorme
6c45f04467 Delete ssm_mock_funcs.go 2020-10-29 13:37:44 +01:00
Adrien Delorme
5d06a6e6df rename file correctly 2020-10-29 13:26:09 +01:00
Adrien Delorme
c6e2dd5538 remove unit test file for now, I think that an acceptance test will be easier here 2020-10-29 13:22:17 +01:00
Adrien Delorme
a4bd744955 simplify things a bit more 2020-10-29 13:11:07 +01:00
Adrien Delorme
aef3d24213 Update step_create_ssm_tunnel.go 2020-10-29 12:31:01 +01:00
Adrien Delorme
f329cb5b93 simplify code 2020-10-29 12:18:41 +01:00
Adrien Delorme
b058de072a move packer/builder/amazon/common.IsAWSErr to builder/amazon/common/awserrors.Matches
to avoid cyclic dependency issues
2020-10-29 12:02:41 +01:00
Adrien Delorme
8e355d0fe7 Move ssm code to its own ssm package and make it singlethreaded 2020-10-29 11:57:29 +01:00
Rémy Léone
db96c5c9ae Fix 2020-10-29 11:21:31 +01:00
Rémy Léone
3413fc5c46 Fix 2020-10-29 11:19:18 +01:00
Rémy Léone
adb74ba15d Fix 2020-10-29 11:09:04 +01:00
Megan Marsh
69312458c4
Merge pull request #10111 from hashicorp/azr_selectable_temp_keygen_type_gcp
GCP: Allow to select algo when generating temporary SSH keypair
2020-10-28 11:25:50 -07:00
Rémy Léone
288e29b1e0 scaleway: use the SDK functions to load profile from file and env 2020-10-28 17:52:34 +01:00
Wilken Rivera
646b973bd3 Remove logic to retry a connection that reuses an existing SSM Session
After testing it was found that once an session is terminated via an
instance restart, console termination, or SSM agent restart. Any active
session will essentially be terminated and unusable. So knowing that it
is always best to start a new session and let the old one timeout get
terminated.
2020-10-28 06:36:23 -04:00
Wilken Rivera
dff9cde775 Remove waitgroups 2020-10-28 06:36:23 -04:00
Wilken Rivera
eb11009e2a Check for closed channels as opposed to using a separate closeRetry channel 2020-10-28 06:36:23 -04:00
Megan Marsh
fb3d357e84
fix step_shutdown when a null communicator is used (#10178) 2020-10-28 11:14:03 +01:00
sylviamoss
aa73cc7d7e add close chan to avoid unwanted retries 2020-10-27 16:32:20 -04:00
sylviamoss
1f62249097 add retry terminated session chan 2020-10-27 16:32:20 -04:00
sylviamoss
8e3f3e514c improve logs 2020-10-27 16:32:20 -04:00
sylviamoss
b2c7897f58 add WaitGroup to avoid data race 2020-10-27 16:32:20 -04:00
sylviamoss
1c2b469acd add retry channel to ssm driver 2020-10-27 16:32:19 -04:00
Megan Marsh
8f3a115c5a
Merge pull request #10173 from hashicorp/azr-fix-hcl2-gcp-image_encryption_key
Fix GCP HCL image_encryption_key fields and use the same casing in JSON and HCL2
2020-10-27 10:56:26 -07:00
Megan Marsh
dc38fadeeb
Merge pull request #10155 from hashicorp/logging_for_10042
builder/vsphere: Don't try to delete a cd file from the remote datastore if the upload of the cd failed
2020-10-27 10:54:07 -07:00
Megan Marsh
8adbba6904 switch to guard clause format 2020-10-27 10:37:03 -07:00
Adrien Delorme
ef32147a4a Fix GCP HCL image_encryption_key fields and use the same casing in JSON and HCL2
this closes #9997
2020-10-27 15:46:45 +01:00
Megan Marsh
c4866504e1
respect the destroy flag in content library config (#10165)
* respect the destroy flag in content library config

* Make vsphere-clone respect delete_vm state tag; use a common delete func to prevent future drift
2020-10-27 09:07:08 -04:00
Adrien Delorme
4bc16455b4
HCL2: add a packer block with a required_version input setting (#10149)
* add the possibility to set the packer.required_version field; to make sure the template file works with that version of Packer
* add tests
* add documentation on packer.required_version

Example:

packer {
  required_version = ">= 1.2.0, < 2.0.0"
}
2020-10-27 10:03:36 +01:00
Wilken Rivera
73e842fab6 update CHANGELOG 2020-10-26 14:00:17 -04:00
Adrien Delorme
bab29060fe regen hcl after master merge 2020-10-26 15:48:10 +01:00
Adrien Delorme
f5e037e8b4 Merge remote-tracking branch 'origin/master' into azr_selectable_temp_keygen_type_gcp 2020-10-26 15:47:29 +01:00
Adrien Delorme
b4f68767a3 make default key type RSA instead of DSA 2020-10-26 15:45:06 +01:00
blz-ea
73370570f4
Fix Proxmox builder unhandled buildvar type (#10154)
* Fix Proxmox builder unhandled buildvar type #10139

Co-authored-by: Calle Pettersson <carlpett@users.noreply.github.com>
Co-authored-by: Adrien Delorme <adrien.delorme@icloud.com>
2020-10-26 15:11:09 +01:00
Megan Marsh
25f4e24772
Merge pull request #10150 from nshalman/nshalman/tag-snapshots
amazon/ebssurrogate: apply snapshot tags right when taking snapshot
2020-10-23 15:57:18 -07:00
Megan Marsh
7646ecf8c6 fix tests 2020-10-23 15:35:37 -07:00
Megan Marsh
8821114e97
Merge pull request #10162 from hashicorp/td-makefile-test-targets
makefile: Disable test caching explicitly for go test
2020-10-23 15:22:20 -07:00
Megan Marsh
4862b2c0f0
Merge pull request #10163 from hashicorp/fix-azure_arm-manageddisk-deletion-regression
builder/azure_arm: Fix build failures due to the deletion of attached managed disks
2020-10-23 15:19:30 -07:00
Wilken Rivera
791a69e78f
Merge pull request #10166 from hashicorp/fix_master
fix fixer deprecated options conflict
2020-10-23 17:09:16 -04:00
Megan Marsh
645eff58d1 fix fixer deprecated options conflict 2020-10-23 14:00:12 -07:00
Megan Marsh
fc619dc977
Merge pull request #9626 from featheredtoast/add-proxmox-vm-clone
builder/proxmox FEATURE: split Proxmox into proxmox-iso and proxmox-clone
2020-10-23 13:36:45 -07:00
Megan Marsh
b6424354c3
Merge pull request #9964 from netapp-jgriffit/hashicorp/packer#9924
Hashicorp/packer#9924
2020-10-23 12:44:55 -07:00
Megan Marsh
56c7a9cda5 rebase 2020-10-23 11:47:20 -07:00
netapp-jgriffit
15467aa868 Update builder/vsphere/common/step_shutdown.go
Co-authored-by: Sylvia Moss <sylviamoss.m@gmail.com>
2020-10-23 11:41:03 -07:00
James Griffith
185f3d9d48 vsphere clone config not yet using warnings, leaving code commented out 2020-10-23 11:41:03 -07:00
James Griffith
c8ad66f419 update to docs as suggested 2020-10-23 11:41:03 -07:00
James Griffith
c86a48fbc9 syntax change 2020-10-23 11:41:03 -07:00
James Griffith
f86f7c4464 Another instance using Prepare() needed an update 2020-10-23 11:41:03 -07:00
James Griffith
09edada93d moved the warning into Prepare() and updated the invocation 2020-10-23 11:41:03 -07:00
James Griffith
572de129d7 update documentation 2020-10-23 11:41:03 -07:00
James Griffith
1048cdbcc4 check for no communicator and provide messaging to user 2020-10-23 11:41:03 -07:00
James Griffith
2ecf5cc9aa Communicator is not needed unless shutdown_command is populated 2020-10-23 11:41:03 -07:00
James Griffith
6b39b1eed6 StepShutdown should still occur if Comm.Type is none 2020-10-23 11:41:03 -07:00
James Griffith
65ff092fd4 hashicorp/packer#9924 2020-10-23 11:41:03 -07:00
Megan Marsh
19bd997f11 add directory existence check 2020-10-23 11:06:25 -07:00
Wilken Rivera
a1d69bfe91 Fix liniting issues 2020-10-23 13:52:05 -04:00
Wilken Rivera
afd33679f5 builder/azure_arm: Fix build failures due to the deletion of attached managed disks
Previously (prior to v1.6.2) the Azure ARM builder had two delete functions
one that would run before any of the StepDelete* types, and one on deployment template
cleanup. The refactored coded re-introduces the logic from the previously removed
step in v1.6.1 as the main delete logic for the whole deployment
template. Ensuring that all deployed items are deleted before trying to
remove any managed disks.

This change moves all the deletion logic into the
step_deployment_template#Cleanup function to ensure that dependent steps
are only called once the created deployment items (i.e
StepDelateAdditionalDisks) have been deleted.

Test results before change
```

    compute.DisksClient#Delete: Failure sending request: StatusCode=0 -- Original Error: autorest/azure: Service returned an error. Status=<nil> Code="OperationNotAllowed" Message="Disk pkrdd02e9rzzu5k-1 is attached to VM /subscriptions/1f90521a-24f6-4758-ac3d-88d869fb0bf5/resourceGroups/packer-acceptance-test/providers/Microsoft.Compute/virtualMachines/pkrvm02e9rzzu5k."
--- FAIL: TestBuilderAcc_ManagedDisk_Windows_Build_Resource_Group_Additional_Disk (454.00s)
FAIL
FAIL    github.com/hashicorp/packer/builder/azure/arm   454.008s

```

Test results after change
```
--- PASS: TestBuilderAcc_ManagedDisk_Windows_Build_Resource_Group_Additional_Disk (563.56s)

```

Closes #10070
2020-10-23 13:44:27 -04:00
Wilken Rivera
26161b7599 makefile: Disable test caching explicitly for go test
* Bump the default time for acceptance tests to 120m
2020-10-23 13:41:14 -04:00
Megan Marsh
8f67f939f9
Merge pull request #10158 from Direnol/yandex-add-support-iam-auth
Added support for IAM credential in the token field and YC_TOKEN env
2020-10-23 09:39:46 -07:00
Roman Mingazeev
75befba67e add more doc 2020-10-23 18:01:52 +03:00
Roman Mingazeev
09add100f2 fix doc generate 2020-10-23 14:36:00 +03:00
Roman Mingazeev
60595ad522 remove extra log 2020-10-23 14:09:05 +03:00
Roman Mingazeev
cc54c564e2
Update website/pages/docs/builders/yandex.mdx
Co-authored-by: GennadySpb <lipenkov@gmail.com>
2020-10-23 14:08:08 +03:00
Roman Mingazeev
c5a8e6f823
Update website/pages/docs/builders/yandex.mdx
Co-authored-by: GennadySpb <lipenkov@gmail.com>
2020-10-23 14:07:37 +03:00
Roman Mingazeev
72fe3bbc26
Update builder/yandex/access_config.go
Co-authored-by: GennadySpb <lipenkov@gmail.com>
2020-10-23 14:05:39 +03:00
Roman Mingazeev
33dce4fc83 fix yandex vendor 2020-10-23 12:26:16 +03:00
Roman Mingazeev
0788c49ec0 update vendor/yandex-cloud/go-sdk 2020-10-23 12:22:35 +03:00
Roman Mingazeev
ae7fc84557 Added support for IAM credential in the token field and YC_TOKEN env 2020-10-23 11:47:28 +03:00
Megan Marsh
7fac596b37 don't try to delete a cd file if the upload of the cd itself failed 2020-10-22 16:53:40 -07:00
Megan Marsh
3be53e10af
Merge pull request #10128 from nayyara-samuel/add-state-timeout-linode
Add documented `state_timeout` parameters to Linode builder
2020-10-22 15:13:59 -07:00
Megan Marsh
c4001734d0
Merge pull request #10143 from hashicorp/do_9951
builder/vsphere: skip iso download if hashed file is already present on remote datastore
2020-10-22 15:06:04 -07:00
Megan Marsh
00037d8e69
Merge pull request #10145 from hashicorp/fix_10135
commhostport isn't present if communicator is null; protect casting i…
2020-10-22 14:24:23 -07:00
Megan Marsh
77298a23a9
Merge pull request #10091 from hashicorp/fix_fixer
command/fix: re-work fixer deprecation code so we know what plugins they relate to
2020-10-22 10:32:58 -07:00
Megan Marsh
9a869f50bd
Merge pull request #10140 from hashicorp/azr-add-vmware-vmx-example
HCL2: add vmware vmx example
2020-10-22 10:22:07 -07:00
Megan Marsh
edca188175
Update docs to clarify how to use build vars in build template engines (#10141) 2020-10-22 09:42:45 +02:00
Megan Marsh
70cb4097e1 review comments, add plugin type for a few missing builders 2020-10-21 16:17:32 -07:00
Megan Marsh
1192e457ff fix linting 2020-10-21 15:29:05 -07:00
Megan Marsh
c0ce8a9414 rework fixer deprecation code so we know what plugins they relate to 2020-10-21 15:28:59 -07:00
Megan Marsh
f1f834b8fe commhostport isn't present if communicator is null; protect casting in a check 2020-10-21 14:30:23 -07:00
Megan Marsh
ee4b3e796e update changelog 2020-10-21 13:17:38 -07:00
Nahum Shalman
83a672f2c9 amazon/ebssurrogate: apply snapshot tags right when taking snapshot 2020-10-21 16:17:37 -04:00
Megan Marsh
796c40f89b builder/vsphere: skip iso download if hashed file is already present in remote packer_cache 2020-10-21 11:33:43 -07:00
Wilken Rivera
a2ba700ac0 Remove deprecated object ids from configs 2020-10-21 13:56:22 -04:00
Adrien Delorme
5a3526a669 Add vmware vmx example 2020-10-21 15:55:54 +02:00
Adrien Delorme
522d122858 regen all code 2020-10-21 12:04:10 +02:00
Adrien Delorme
4aea2efd0f HCL2: fully name SSHTemporaryKeyPair fields so that they don't conflict and can be generated 2020-10-21 11:53:07 +02:00
Wilken Rivera
1621ab59d8
tests/azure/arm: Update test image name (#10133)
I've run into a few cases where running the full test suite for the ARM
builder would fail because of conflicting image names. This is a
workaround for now the bigger fix is to have the acceptance clean up any
created images.

Results before change
```
the managed image named testBuilderAccManagedDiskWindows-1603151855 already exists in the resource group packer-acceptance-test, use the -force option to automatically delete it.
--- FAIL: TestBuilderAcc_ManagedDisk_Windows_Build_Resource_Group (0.66s)
```

Results after change
```
PASS
ok      github.com/hashicorp/packer/builder/azure/arm   2431.115s

```
2020-10-21 11:12:50 +02:00
Megan Marsh
799c548c40
Merge pull request #10116 from OblateSpheroid/GH8915
Feat (builder/oracle-oci): Allow filtering on base image
2020-10-20 14:41:09 -07:00
Boran Car
9b89439ec2 Rearrange cert add after err check for idiomatic 2020-10-20 22:20:57 +02:00
Boran Car
1082bffddd Add Azure PFX certificate support
Azure typically uses pfx files for service principal authentication.
These are PKCS#12 files so just try and read a cert file as such if we
can't already read it as PEM.
2020-10-20 22:15:38 +02:00
Adrien Delorme
d1e0214bec avoid panic debugging ssh key 2020-10-20 16:59:46 +02:00
Adrien Delorme
f51b231c17 Merge remote-tracking branch 'origin/master' into azr_selectable_temp_keygen_type_gcp 2020-10-20 16:39:01 +02:00
Adrien Delorme
6d4fae0f2d
Add HCL2 aws_secretsmanager function (#10124)
* refactor aws get secrets function out to reuse it else where
* add aws_secretsmanager func and docs for HCL2
* fix GetSecret: allow to pick secret version
2020-10-20 16:21:40 +02:00
Adrien Delorme
536421efaf debug mode: don't dump the ssh key if its from a file 2020-10-20 12:00:49 +02:00
js-g
2f26e6d823 tests (builder/oracle-oci): test base image filter in config 2020-10-19 23:30:46 -04:00
Nayyara Samuel
32ebabfcf5 Add documented state_timeout parameters to Linode builder 2020-10-19 22:07:22 -04:00
Megan Marsh
584fea678b update changelog 2020-10-19 15:34:55 -07:00
Ufuk
2124d3d6b8 builder/digitalocean: tests added for new features vpc_uuid and connect_with_private_ip 2020-10-19 23:19:11 +03:00
Megan Marsh
b8e6e2c081
Merge pull request #10085 from 10000coins/f-aws-tenancy
builder/amazon: Support for source instance tenancy
2020-10-19 12:49:07 -07:00
Megan Marsh
cc7dbf6092
Add consul_key function to integrate concul with hcl2 tempaltes. (#10119)
* Add consul_key function to integrate concul with hcl2 tempaltes.
* sidebar nav
2020-10-19 14:07:13 +02:00
Jeroen Ketelaar
4f5e878a17
Fixed documentation to have valid JSON for image_filter (#10122) 2020-10-19 11:05:58 +02:00
Adrien Delorme
b24911661f
add sshkey package and ssh-keygen comand (#10101)
* add sshkey.Generate function that returns an sshkey.Pair to be used with openssh.
* add cmd/ssh-keygen/main.go for testing purposes
* add a test calling ssh.ParsePrivateKey & ssh.ParseAuthorizedKey (which is very
   similar to what openssh would do to read a keypair)

The wrapping of the keys should be handled by crypto/x509.MarshalPKCS8PrivateKey 
& x/crypto/ssh.NewPublicKey which does not work for ed25519 and dsa. 
x509.MarshalPKCS8PrivateKey marshals ed25519 keys but the keys did not work with openssh. 
x509.MarshalPKCS8PrivateKey does not handle dsa keys.
So I had to 'wrap' those manually by reading the code of the openssh package.
Note that ssh.NewPublicKey works with any keytype. I should probably do a PR to ssh to have a NewPrivateKey & Marshalling funcs
2020-10-19 10:24:34 +02:00
Evan Pipho
dd068acfd1 Re-generate docs 2020-10-16 23:44:58 +00:00
Megan Marsh
ef1b401a22
Merge pull request #10102 from mattr-/update-amazon-builder-for-io2
builder/amazon: Add io2 as a supported volume type
2020-10-16 16:32:57 -07:00
Megan Marsh
cee3a14392
Merge pull request #10115 from bhundven/googlecompute_add-create-image-option
Add 'create_image' option to googlecompute
2020-10-16 16:01:44 -07:00
Bryan Hundven
ecc8c6a44a Replace create_image with skip_create_image, as requested
Closes #9965
2020-10-16 15:42:30 -07:00
Bryan Hundven
476eefa26b Add 'create_image' option to googlecompute
When building a CI/CD deployment, during the PR process it's nice to be
able to run the builder, but not create the image the build produces.

Closes #9965
2020-10-16 15:42:17 -07:00
Megan Marsh
456214eb51
Merge pull request #10056 from marinsalinas/new_client
New official Outscale SDK migration.
2020-10-16 15:28:54 -07:00
Evan Pipho
608307cd1e Re-allow spot + tenancy. Validate tenancy is set to a usable value 2020-10-16 21:43:22 +00:00
Evan Pipho
d5d1a8708e Add tests for Tenancy vs Spot Price 2020-10-16 21:43:22 +00:00
Evan Pipho
6967e02103 Add support for source instance tenancy to amazon builders 2020-10-16 21:43:22 +00:00
Megan Marsh
a8ee23a9f9
Merge pull request #10117 from hashicorp/packer_version_func_hcl
implement packer_version func in hcl
2020-10-16 14:38:39 -07:00
Megan Marsh
f696e8286e contextual functions menu section for vault func 2020-10-16 14:27:16 -07:00
Megan Marsh
09c6d2880f implement packer_version variable in hcl 2020-10-16 14:07:05 -07:00
Megan Marsh
66b81d9bee
add build.name to hcl code (#10114) 2020-10-16 10:57:42 +02:00
Wilken Rivera
a17b1a5a89
Fix references to source blocks (#10113) 2020-10-16 10:26:29 +02:00
js-g
b0cc71d35e docs (builder/oracle-oci): add documentaion for base_image_filter 2020-10-15 17:26:01 -04:00
js-g
0c34d6ca12 feat (builder/oracle-oci): add regex search on base image name 2020-10-15 15:28:38 -04:00
Wilken Rivera
7ba2ffe171
Merge pull request #10106 from hashicorp/more_hcl_docs
More hcl docs
2020-10-15 13:50:46 -04:00
Wilken Rivera
5d2f2b20e7
Merge pull request #10112 from jmfury/jm.bump-hsm-version-1.0.7
[Website] Update HSM version w/ waypoint
2020-10-15 13:45:48 -04:00
Jimmy Merritello
f79b9dc735
Update HSM version 2020-10-15 11:35:19 -05:00
js-g
27128dc62f feat (builder/oracle-oci): allow filtering on base image 2020-10-15 11:02:16 -04:00
Adrien Delorme
df913f596b Update googlecompute.mdx 2020-10-15 16:51:35 +02:00
Adrien Delorme
54032d6c11 gen code and docs 2020-10-15 16:51:23 +02:00
Adrien Delorme
f4f731b83c Refactor google compute's temporary ssh keygen genertion to use the sshkey package 2020-10-15 16:51:11 +02:00
Wilken Rivera
343ac2d48d
syntax-json: Fix nested provisioner block example (#10109) 2020-10-15 16:04:01 +02:00
Megan Marsh
06efa61c13 a tiny bit more cleanup 2020-10-14 15:56:58 -07:00
Megan Marsh
da15b85451 more updates 2020-10-14 13:35:21 -07:00
Megan Marsh
2cdc052d7c
Merge pull request #10097 from hashicorp/more_hcl_docs
Update HCL docs with a local resource-free example to empower users t…
2020-10-14 13:34:54 -07:00
Megan Marsh
31df482b61 remove old docs for previous behavior 2020-10-14 13:11:52 -07:00
Megan Marsh
00cc425b84 docs tweaks 2020-10-14 12:58:04 -07:00
Megan Marsh
5522980e4d
Merge pull request #10103 from jmfury/jm.website-bump-hsm-menu-v1.0.5
[Website] Bump HSM version
2020-10-14 12:46:16 -07:00
Megan Marsh
84d5de369f
Merge pull request #10104 from pwillis-els/pwillis-els-patch-1
Fix typos in hcl2_upgrade
2020-10-14 12:38:07 -07:00
Peter Willis
f1b57b1e66
Fix typos 2020-10-14 15:04:18 -04:00
Peter Willis
a81811663a
Fix typos 2020-10-14 14:52:17 -04:00
Megan Marsh
c16354d594 Update HCL docs with a local resource-free example to empower users to tinker. 2020-10-14 11:24:15 -07:00
Jimmy Merritello
e98b2d39db
Updated pkg 2020-10-14 12:55:53 -05:00
Jimmy Merritello
8121d6d8dc
Bump HSM version 2020-10-14 09:39:50 -05:00
Adrien Delorme
5b7037c069 add more comments 2020-10-14 16:01:41 +02:00
Matt Rogers
15f97421e2
builder/amazon: Add io2 as a supported volume type
io2 volumes are new as of 2020-08-24. This adds support for specifying
them in a packer template and having the iops value specified take
effect.
2020-10-14 09:01:17 -05:00
Adrien Delorme
10d38fc588 Merge remote-tracking branch 'origin/master' into azr_pick_keygen_type 2020-10-14 15:55:13 +02:00
Adrien Delorme
fe8d287036 some linting 2020-10-14 15:54:51 +02:00
Adrien Delorme
c5d6e72720 comment PairFromED25519 2020-10-14 13:21:46 +02:00
Adrien Delorme
766e7872a0 add a comment for DSA default bits setting 2020-10-14 13:17:53 +02:00
Adrien Delorme
77adeb1191 create PairFromED25519 func to create valid ed25519 keypairs 2020-10-14 13:12:17 +02:00
Wilken Rivera
c7ba5c9a14
Fix line ending issues for test files (#10096) 2020-10-14 11:03:43 +02:00
Megan Marsh
22622b234b
Merge pull request #10095 from hashicorp/hcl_docs
add docs for hcl2_upgrade command
2020-10-13 15:36:49 -07:00
Marin Salinas
22a49a2f2e chore: fix test 2020-10-13 16:19:15 -05:00
Megan Marsh
33019a0e01 add docs for hcl2_upgrade command 2020-10-13 13:56:54 -07:00
Marin Salinas
472b008a94 chore: fix test 2020-10-13 15:16:01 -05:00
Megan Marsh
4810a3d86f
Merge pull request #10077 from hashicorp/document_3348
builder/qemu: docs: users must re-apply packer defaults for drive and device arguments
2020-10-13 11:41:28 -07:00
Marin Salinas
2578bbbb50 chore: fix test 2020-10-13 12:54:25 -05:00
Marin Salinas
09f57537bf chore: fix lint issues on osc builder 2020-10-13 11:02:13 -05:00
Ufuk
a100fe496b go fmt 2020-10-13 18:57:57 +03:00
Adrien Delorme
3712cd8e2c bump default RSA bits to 4096 2020-10-13 17:50:43 +02:00
Marin Salinas
56807553fc chore: fix lint issues on osc builder 2020-10-13 10:45:32 -05:00
Ufuk
49cd4baa0c VPCUUID and ConnectWithPrivateIP have been added to builder/digitalocean 2020-10-13 18:26:00 +03:00
Marin Salinas
c5dffc1bff chore: add go mod vendor for new Outscale SDK 2020-10-13 10:17:37 -05:00
Wilken Rivera
3abae29752 Update generated docs 2020-10-13 10:33:59 -04:00
Adrien Delorme
9b68099ad5 remove specific EC code 2020-10-13 16:27:59 +02:00
Adrien Delorme
48199c5aa8 add basic test to see if generated files are parseable 2020-10-13 16:25:24 +02:00
Adrien Delorme
ca23dab943 set correct type for PEM block 2020-10-13 12:43:21 +02:00
Adrien Delorme
b6efe28a96 better cmd 2020-10-13 12:06:49 +02:00
Adrien Delorme
750102901c add cmd/ssh-keygen/main.go to try this on real servers 2020-10-13 11:25:52 +02:00
Megan Marsh
ad129e7df9 update changelog 2020-10-12 16:29:41 -07:00
Megan Marsh
75cfc97da4
Merge pull request #10081 from hashicorp/f-ansible-remote-ssm-connectivity
provisioner/Ansible: Add Amazon SSM setup documentation
2020-10-12 10:49:41 -07:00
Jeff Wong
0f12414126
Merge branch 'master' into add-proxmox-vm-clone 2020-10-12 10:48:15 -07:00
Adrien Delorme
0cf7af4247 add sshkey.Generate function 2020-10-12 18:04:02 +02:00
Megan Marsh
01ed398756
fix up alicloud docs to make it clearer that disk_size and other disk device options are not top level fields. (#10080) 2020-10-12 10:28:25 +02:00
Jeff Wong
2861ad9074
clean up imports 2020-10-11 11:47:02 -07:00
Jeff Wong
a35eda70d8
Add proxmox fixer 2020-10-11 11:39:24 -07:00
Wilken Rivera
d378a4477a
Merge pull request #10079 from hashicorp/vsphere_cluster_host_investigation
fix docs linking issue
2020-10-09 22:11:31 -04:00
Wilken Rivera
8154e5772f provisioner/Ansible: Add Amazon SSM setup documentation 2020-10-09 17:05:14 -04:00
Megan Marsh
709a173060 fix docs linking issue 2020-10-09 14:01:21 -07:00
Marin Salinas
dcaf56596d
Merge pull request #10 from marinsalinas/bsuvolume
BSU Volume sdk migration
2020-10-09 14:37:53 -05:00
Megan Marsh
b05fd9303e document that users must re-apply packer defualts for drive and device arguments 2020-10-09 10:39:27 -07:00
Megan Marsh
b460d687ea
Merge pull request #10068 from jmfury/jm.website-bump-hsm-menu
Bump HSM version and rm meganav styles
2020-10-09 10:15:23 -07:00
Megan Marsh
774a168957
Merge pull request #10064 from hashicorp/refactor_step_run
builder/qemu: (tech-debt) Major refactor of step_run.
2020-10-08 11:54:34 -07:00
Jimmy Merritello
7ed2c2920f
Bump HSM version and rm meganav styles 2020-10-08 13:53:36 -05:00
Megan Marsh
3e35630d8d remove slashes to prevent windows test fails 2020-10-08 11:36:36 -07:00
James Cradock
153d4111fa
Fix typo in build argument description (#10066) 2020-10-08 14:58:22 +02:00
Megan Marsh
62a401ef28
Fix 10060 (#10065)
* fix overeager validation
* fix validation of openstack source images
2020-10-08 10:54:41 +02:00
Jeff Wong
93531b3ec5
[proxmox] Adds proxmox fixer and fixer test
Add fixer for proxmox to proxmox-iso. Updated gofmt.
2020-10-08 00:04:43 -07:00
Jeff Wong
a140c13943
[proxmox] add proxmox builder alias
Adds an alias for `proxmox` that points to proxmox-iso builder for
backwards compatibility
2020-10-07 23:43:12 -07:00
Megan Marsh
d6aa172edc remove typo'd option from docs 2020-10-07 16:14:13 -07:00
Megan Marsh
d7ba10c23e update changelog 2020-10-07 15:52:06 -07:00
Megan Marsh
f076c97e5c
Merge pull request #10062 from jmfury/jm.add-hashi-stack-menu
[Website] Add new HashiStackMenu
2020-10-07 15:36:31 -07:00
Megan Marsh
8e632866b1 typo 2020-10-07 15:22:08 -07:00
Megan Marsh
b54b778572 major refactor of the step_run. Splits step into two major parts:
- generating defaults
- overriding defaults with user args

The default generation has been shuffled around some, in order to
make sure that any changes to a specific arg happen in one place
to make it easier to reason about those args. Related args have
been moved close to one another.

The deviceArgs and driveArgs were overly complex after several
layers of copy/paste modifications. Careful pruning reduced the
layers of logic and repeated code, to help make it easier to reason
about.
2020-10-07 15:09:45 -07:00
Jimmy Merritello
ea3b804af1
Bump version 2020-10-07 15:30:18 -05:00
Adrien Delorme
14e253f316
upgrade panicwrap to v1 (#10059)
* and go mod tidy this allows us to get rid of a dep
2020-10-07 11:22:32 -04:00
Jimmy Merritello
7f0a043a63
Add new HashiStackMenu 2020-10-07 09:57:47 -05:00
Patrik
d4d78feed2
feat(scaleway): get image by label if not an UUID (#10061)
Signed-off-by: Patrik Cyvoct <patrik@ptrk.io>
2020-10-07 16:04:00 +02:00
abarbare
a478bf6f37
fix: update scaleway website documentation (#10058) 2020-10-07 12:02:08 +02:00
Adrien Delorme
3e0633fc20 scripts/generate-plugins.go: ignore "common" packages 2020-10-07 11:43:15 +02:00
Ricardo Rosales
809f38be3a
[azure-chroot] Updating parameter exlude_from_latest to exclude_from_latest (#10034) 2020-10-07 11:08:33 +02:00
Jeff Wong
cd3bdc9e38
REFACTOR: do not pass comm ref through statebag 2020-10-06 22:45:19 -07:00
Jeff Wong
fdda18e392
Use Trilean for boolean value, and allow for missing values for defaults 2020-10-06 17:24:45 -07:00
Jeff Wong
977022fb35
Go format 2020-10-06 16:53:29 -07:00
Jeff Wong
a26e3e6887
[Proxmox] FIX: tests, add required iso_file to basic iso config tests 2020-10-06 16:04:18 -07:00
Megan Marsh
61c6085651
final fix to make service account impersonation work with iap tunnels (#10054) 2020-10-06 15:34:06 -04:00
Megan Marsh
d05eb3401b
Merge pull request #10030 from angdraug/no-panicwrap-in-plugins
no panicwrap in plugins
2020-10-06 12:21:15 -07:00
Megan Marsh
7ee9a4b638
Merge pull request #9968 from upodroid/google-impersonation
GCP: add service account impersonation
2020-10-06 11:32:03 -07:00
Romain Lecat
10e356abe6
Fix typo in Outscale name (#10051) 2020-10-06 16:43:49 +02:00
Adrien Delorme
f6d362d392 skip Ctx 2020-10-06 11:54:04 +02:00
Adrien Delorme
25d7e7ce17 fix tests 2020-10-06 11:48:24 +02:00
Adrien Delorme
5b3ff89cb0 proxmox: move iso.storageConfig to common.storageConfig 2020-10-06 11:42:49 +02:00
Adrien Delorme
1260e123aa proxmox.Config: remove mapstructure:",squash" tag 2020-10-06 11:14:09 +02:00
Adrien Delorme
b2be255057 Merge remote-tracking branch 'origin/master' into pr/featheredtoast/9626-1 2020-10-06 11:11:04 +02:00
zhsj
ef9713b348
Replace kardianos/osext.Executable with os.Executable (#10048)
os.Executable is available since go1.8
https://github.com/kardianos/osext/blob/master/osext_go18.go
2020-10-06 10:59:32 +02:00
Megan Marsh
b34e61c961 update changelog 2020-10-05 15:11:18 -07:00
Megan Marsh
deb08409f1
Merge pull request #10040 from OblateSpheroid/GH6844
Feat (oracle/oci): allow specifying image compartment
2020-10-05 15:02:23 -07:00
Megan Marsh
aeb63f9bef
Merge pull request #10031 from hashicorp/hcl_sensitive
HCL: hide sensitive variables from output
2020-10-05 14:58:55 -07:00
Megan Marsh
721cbac645
Merge pull request #9996 from hashicorp/fix_9995
Make shell-local post-processor return copy of previous artifact
2020-10-05 13:00:51 -07:00
Adrien Delorme
4cb218749b remove unecessary check 2020-10-05 15:34:35 +02:00
Adrien Delorme
fcaf766569 add docs for sensitive variables 2020-10-05 15:34:35 +02:00
Adrien Delorme
9f97173371 PostProcessorServer.PostProcess: don't close the artifact we are serving
Sometimes, the artifact returned by PostProcess is the artifact from client.Artifact() and in that case we don't want to close client; otherwise the outcome is sort of undetermined. See #9995 for a good test file.

fix #9995
2020-10-05 14:27:55 +02:00
js-g
2222d112bd docs: update OCI page to include image_compartment_id 2020-10-04 23:05:31 -04:00
js-g
c892f0582b GH#6844: allow image compartment to be specified 2020-10-02 22:30:52 -04:00
Megan Marsh
157b5cdc28
Merge pull request #10017 from kostasns/oci_boot_volume
Allow to specify boot volume size in OCI builder
2020-10-02 11:04:05 -07:00
Megan Marsh
37b4533cba
Merge pull request #10022 from hashicorp/fix_10020
fix pathing in cd_files copy to make sure directories make it into th…
2020-10-02 09:43:57 -07:00
Megan Marsh
b105e5e416
Update common/step_create_cdrom.go
Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
2020-10-02 09:17:29 -07:00
Adrien Delorme
8f9001b531 uncopy 2020-10-02 11:35:20 +02:00
Adrien Delorme
10b648b282 Update .gitattributes 2020-10-02 11:06:02 +02:00
Adrien Delorme
ebb1cb406c ignore walk error 2020-10-02 10:53:17 +02:00
Adrien Delorme
fcf16315a3 add tests 2020-10-02 10:49:21 +02:00
Adrien Delorme
bb22cfcf34 HCL2: pass sensitive variables to packer.LogSecretFilter
Co-Authored-By: Megan Marsh <1008838+SwampDragons@users.noreply.github.com>
2020-10-02 10:17:07 +02:00
upodroid
1c4b8c3d31 fmt fix 2020-10-01 23:24:46 +01:00
upodroid
b1c74f9df0 Merge branch 'master' of github.com:hashicorp/packer into google-impersonation 2020-10-01 23:19:15 +01:00
Megan Marsh
c0be097afc
Merge pull request #10010 from OblateSpheroid/GH10008
Bug fix(10008): fix ansible-galaxy for v1 files
2020-10-01 14:25:22 -07:00
upodroid
2228b18fcb revendor the libraries 2020-10-01 22:06:15 +01:00
Dmitry Borodaenko
d18b7839b9 no panicwrap in plugins
As of mitchellh/panicwrap#25, a call to panicwrap.Wrapped() unsets the
cookie in the env, that makes packer plugin child process inherit an env
without the panicwrap cookie and panicwrap itself.

This trips up CleanupClients() in Packer's plugin client: instead of the
real plugin server it now kills its panicwrap parent -- which doesn't
forward SIGKILL to its child because it's not a signal that can be
caught -- and ends up indefinitely waiting in client.Kill() for an EOF
that will never come.

This workaround is to not even try to panicwrap in a plugin server.
2020-10-01 13:32:00 -07:00
upodroid
f13099edfb rebase the branch 2020-10-01 20:39:06 +01:00
Kostas
8c07e21be8 update hcl2spec 2020-10-01 09:06:22 +03:00
Kostas
18c4f271ac rename variable; add docs 2020-10-01 09:01:51 +03:00
Megan Marsh
984f21d409
Merge pull request #10016 from hashicorp/azr-fix-coalesce-empty-string-
use "github.com/hashicorp/go-cty-funcs/collection".CoalesceFunc
2020-09-30 15:49:02 -07:00
Megan Marsh
465ce3596f
Merge pull request #10019 from hashicorp/circleci-build-tools-update
Update build tools to latest supported versions
2020-09-30 15:31:38 -07:00
Megan Marsh
69fd5a1527 fix pathing in cd_files copy to make sure directories make it into the cd root. 2020-09-30 15:15:55 -07:00
packer-ci
e08e7734f5 Putting source back into Dev Mode 2020-09-30 18:45:29 +00:00
Marin Salinas
49e4d83cd7 refactor: remove oapi references in bsusurrogate builder 2020-09-30 10:39:24 -05:00
Marin Salinas
aa3ec3fd0f refactor: change chroot builder to new SDK 2020-09-30 10:38:31 -05:00
Marin Salinas
c0c0f003f9 refactor: fix bsu builder to accept proxy 2020-09-30 10:37:41 -05:00
Marin Salinas
d813c3647d refactor: change bsuvolume builder to new SDK 2020-09-30 10:37:09 -05:00
Marin Salinas
79e25bf4ac
Merge pull request #9 from marinsalinas/bsusurrogate
Bsusurrogate sdk migration
2020-09-30 10:35:26 -05:00
Wilken Rivera
2a879aff14 Update build tools to latest supported versions 2020-09-30 11:22:13 -04:00
Kostas
72166febee allow to specify boot volume size 2020-09-30 13:31:37 +03:00
Adrien Delorme
180dc4a54e add test 2020-09-30 12:02:52 +02:00
Adrien Delorme
f3e65b5eb1 use "github.com/hashicorp/go-cty-funcs/collection".CoalesceFunc
fix #9419
after https://github.com/hashicorp/go-cty-funcs/pull/5 was merged
2020-09-30 11:59:36 +02:00
js-g
d7507ae67c fix (provisioner/ansible): add checks for both roles and collections 2020-09-29 13:46:59 -04:00
sylviamoss
c8874c9382 improve docker_tag cast to avoid failures 2020-09-29 14:41:43 +02:00
js-g
08d485b1f9 GH 10008: fix ansible-galaxy for v1 files 2020-09-28 18:32:27 -04:00
sylviamoss
49bc7665c1 fix docker push tags cast 2020-09-28 11:18:24 +02:00
sylviamoss
aa9c162c60 improve docker_tags artifact state read 2020-09-28 10:52:28 +02:00
sylviamoss
e758891878 make shell-local post-processor return copy of previous artifact 2020-09-25 16:53:59 +02:00
upodroid
be56632f7e fix vendoring 2020-09-20 16:50:03 +01:00
upodroid
9b121e85f9 fix dodgy pointers 2020-09-20 15:31:45 +01:00
Upo
3f6230470b
Merge branch 'master' into google-impersonation 2020-09-20 15:23:04 +01:00
upodroid
2faacfd5d7 add service account impersonation 2020-09-20 15:18:37 +01:00
Jeff Wong
5d15f5e2f4 No longer need a 15 second sleep 2020-09-14 13:36:26 -07:00
Jeff Wong
bac66b48a6 Move proxmox website docs to iso 2020-09-14 13:03:30 -07:00
Jeff Wong
3c9969d841 cleanup goimports for linter 2020-09-14 12:49:38 -07:00
Jeff Wong
f0c76bad52 DOCS: update docs navigation 2020-09-14 12:22:18 -07:00
Jeff Wong
018a1a5da0 Correct full clone logic 2020-09-14 12:15:07 -07:00
Jeff Wong
681d0f8467 Correct builder ID 2020-09-14 11:59:47 -07:00
Jeff Wong
99c3872a48 run go fmt 2020-09-14 11:58:50 -07:00
Jeff Wong
aa5eb770d0 DEV: use proper interfaces for vmCreator 2020-09-11 16:45:16 -07:00
Marin Salinas
abdb4bcfbf refactor: change ssh host to osc ssh host 2020-09-11 12:11:52 -05:00
Marin Salinas
645e5afa36 refactor: change bsuvolume builder to new SDK 2020-09-11 12:11:24 -05:00
Marin Salinas
b844b7f1c7 refactor: change bsusurrogate builder to new SDK 2020-09-11 10:38:13 -05:00
Marin Salinas
007f6cce4c feat: add wait funtions for snapshot and omi in osc builders 2020-09-11 09:47:08 -05:00
Marin Salinas
eed047b83b feat: add proxy support to osc builder 2020-09-11 09:46:04 -05:00
Marin Salinas
ddc09ded89
Merge pull request #8 from marinsalinas/step_create_omi
refactor: update step_create_omi to new OSC SDK
2020-09-11 09:39:58 -05:00
Jeff Wong
8aeafa986f DOCS: split proxmox docs for clone 2020-09-10 17:33:30 -07:00
Jeff Wong
cfece501d0 Implement proxmox-clone 2020-09-09 23:55:35 -07:00
Calle Pettersson
905869308d Split proxmox builder into a common part and iso/clone builders
Clone builder is still just a stub. Proof-of-concept for #9626

Signed-off-by: Calle Pettersson <calle@cape.nu>
2020-09-04 23:53:09 +02:00
Marin Salinas
e0badb3fb7 refactor: update step_update_omi_attributes and create_tags to new OSC SDK 2020-08-26 12:25:46 -05:00
Marin Salinas
8885a5ef31 refactor: update step_create_omi to new OSC SDK 2020-08-25 18:02:11 -05:00
Marin Salinas
f0dc26613a
Merge pull request #7 from marinsalinas/step_deregister_omi
Step Deregister OMI
2020-08-25 17:22:58 -05:00
Marin Salinas
8166dad533
Merge pull request #5 from marinsalinas/step_cleanup_volumes
refactor: change step_cleanup_volumes to new OSC SDK
2020-08-21 15:03:47 -05:00
Marin Salinas
aba6e104ae
Merge pull request #6 from marinsalinas/step_security_group
Step Security Group
2020-08-21 13:33:30 -05:00
PacoDw
8274d4848c chore: added forece_deregister in the test case to verify the step_deregister_omi 2020-08-21 13:30:21 -05:00
PacoDw
071854ea4a chore: implemented OSC API in step_deregister_omi 2020-08-21 13:29:41 -05:00
PacoDw
a13dfe1f42 chore: added GetRegion() and NewOSCClientByRegion functions 2020-08-21 13:29:27 -05:00
PacoDw
60bd61dc18 chore: removed security group filter function, it was moved to step_security_group file 2020-08-21 11:31:00 -05:00
PacoDw
c3a4b60ea5 chore: implemented OSC API in step_security_group 2020-08-21 11:30:10 -05:00
Marin Salinas
7a45e4c8b0 refactor: change step tag bsu volumes to new OSC SDK 2020-08-21 10:40:14 -05:00
Marin Salinas
c58d6f9b33 refactor: migrate run vm step to new SDK 2020-08-21 10:10:25 -05:00
Marin Salinas
6f0bb33c9a refactor: change tags ssh file to new OSC SDK 2020-08-20 20:35:51 -05:00
Marin Salinas
e5c14044fb refactor: change tags file to new OSC SDK 2020-08-20 19:12:38 -05:00
Marin Salinas
addc3dd6e7 refactor: change step_cleanup_volumes to new OSC SDK 2020-08-20 18:33:02 -05:00
Marin Salinas
d9a7626249
Merge pull request #4 from marinsalinas/step_public_ip
Step public ip
2020-08-20 18:04:03 -05:00
PacoDw
7745369dce chore: set true associate_public_ip_address attribute to test the step_public_ip 2020-08-20 14:00:13 -05:00
PacoDw
86966ecfee :chore: implemented OSC API in pre_public_ip step 2020-08-20 13:59:25 -05:00
Marin Salinas
6f6a656486
Merge pull request #3 from marinsalinas/step_key_pair
Step Key Pair
2020-08-18 16:20:35 -05:00
PacoDw
232d5a3ce6 chore: changed oapi to osc 2020-08-18 15:06:00 -05:00
PacoDw
43e9d43ebd chore: removed API attribute 2020-08-18 13:52:49 -05:00
Marin Salinas
7d8f28e1a3
Merge pull request #2 from marinsalinas/step_source_info
Step source info
2020-08-18 13:34:16 -05:00
Marin Salinas
8b2cdc5821 refactor: change step_network_info to new OSC SDK 2020-08-18 13:33:45 -05:00
Marin Salinas
8649496c6c refactor: change new sdk on step_source_omi_info 2020-08-18 13:33:45 -05:00
Marin Salinas
daefa4d086 chore: update vendor dependencies 2020-08-18 13:33:45 -05:00
PacoDw
4431bb87b2 :chore: added api key to specify the API connection 2020-08-18 13:33:45 -05:00
PacoDw
823b957a1f :chore: implemented OSC connection in pre_validate file 2020-08-18 13:33:45 -05:00
PacoDw
22481d1ac2 :chore: added OSC Connection in builder file 2020-08-18 13:32:38 -05:00
PacoDw
1fbe715c13 :chore: added OSC Connection in builder file 2020-08-18 12:23:39 -05:00
PacoDw
1bfb2d9170 :chore: implemented transport file to make the OSC API Connection 2020-08-17 10:04:28 -05:00
PacoDw
1055007cba :chore: added OSC API Client Connection 2020-08-17 10:02:00 -05:00
PacoDw
74f868da37 :chore: changed the AMI with an existing AMI to work fine with the test case 2020-08-13 17:03:32 -05:00
10351 changed files with 63572 additions and 2810857 deletions

View File

@ -1,17 +1,16 @@
orbs:
win: circleci/windows@1.0.0
codecov: codecov/codecov@1.0.5
version: 2.1
executors:
golang:
docker:
- image: circleci/golang:1.13
- image: docker.mirror.hashicorp.services/circleci/golang:1.16
resource_class: medium+
darwin:
macos:
xcode: "9.0"
xcode: "12.0.0"
commands:
install-go-run-tests-unix:
@ -20,10 +19,13 @@ commands:
type: string
GOVERSION:
type: string
HOME:
type: string
default: "~"
steps:
- checkout
- run: curl https://dl.google.com/go/go<< parameters.GOVERSION >>.<< parameters.GOOS >>-amd64.tar.gz | tar -C ~/ -xz
- run: ~/go/bin/go test ./... -coverprofile=coverage.txt -covermode=atomic
- run: curl https://dl.google.com/go/go<< parameters.GOVERSION >>.<< parameters.GOOS >>-amd64.tar.gz | tar -C << parameters.HOME >>/ -xz
- run: << parameters.HOME >>/go/bin/go test ./... -coverprofile=coverage.txt -covermode=atomic
install-go-run-tests-windows:
parameters:
GOVERSION:
@ -37,15 +39,19 @@ commands:
parameters:
GOOS:
type: string
GOARCH:
default: "amd64"
type: string
steps:
- checkout
- run: GOOS=<< parameters.GOOS >> go build -ldflags="-s -w -X github.com/hashicorp/packer/version.GitCommit=${CIRCLE_SHA1}" -o ./pkg/packer_<< parameters.GOOS >>_$(go env GOARCH) .
- run: zip ./pkg/packer_<< parameters.GOOS >>_$(go env GOARCH).zip ./pkg/packer_<< parameters.GOOS >>_$(go env GOARCH)
- run: rm ./pkg/packer_<< parameters.GOOS >>_$(go env GOARCH)
- run: GOOS=<< parameters.GOOS >> GOARCH=<<parameters.GOARCH>> go build -ldflags="-s -w -X github.com/hashicorp/packer/version.GitCommit=${CIRCLE_SHA1}" -o ./pkg/packer_<< parameters.GOOS >>_<< parameters.GOARCH >> .
- run: zip ./pkg/packer_<< parameters.GOOS >>_<< parameters.GOARCH >>.zip ./pkg/packer_<< parameters.GOOS >>_<< parameters.GOARCH >>
- run: rm ./pkg/packer_<< parameters.GOOS >>_<< parameters.GOARCH >>
- persist_to_workspace:
root: .
paths:
- ./pkg/
# Golang CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-go/ for more details
@ -57,28 +63,20 @@ jobs:
steps:
- checkout
- run: TESTARGS="-coverprofile=coverage.txt -covermode=atomic" make ci
- codecov/upload:
file: coverage.txt
test-darwin:
executor: darwin
working_directory: ~/go/src/github.com/hashicorp/packer
environment:
GO111MODULE: "off"
working_directory: ~/go/github.com/hashicorp/packer
steps:
- install-go-run-tests-unix:
GOOS: darwin
GOVERSION: "1.13"
- codecov/upload:
file: coverage.txt
GOVERSION: "1.16"
test-windows:
executor:
name: win/vs2019
shell: bash.exe
steps:
- install-go-run-tests-windows:
GOVERSION: "1.13"
- codecov/upload:
file: coverage.txt
GOVERSION: "1.16"
check-lint:
executor: golang
resource_class: xlarge
@ -88,15 +86,6 @@ jobs:
- run:
command: make ci-lint
no_output_timeout: 30m
check-vendor-vs-mod:
executor: golang
working_directory: /go/src/github.com/hashicorp/packer
environment:
GO111MODULE: "off"
steps:
- checkout
- run: GO111MODULE=on go run . --help
- run: make check-vendor-vs-mod
check-fmt:
executor: golang
steps:
@ -125,6 +114,13 @@ jobs:
steps:
- build-and-persist-packer-binary:
GOOS: darwin
build_darwin_arm64:
executor: golang
working_directory: /go/src/github.com/hashicorp/packer
steps:
- build-and-persist-packer-binary:
GOOS: darwin
GOARCH: arm64
build_freebsd:
executor: golang
working_directory: /go/src/github.com/hashicorp/packer
@ -153,7 +149,7 @@ jobs:
destination: /
build-website-docker-image:
docker:
- image: circleci/buildpack-deps
- image: docker.mirror.hashicorp.services/circleci/buildpack-deps
shell: /usr/bin/env bash -euo pipefail -c
steps:
- checkout
@ -167,14 +163,14 @@ jobs:
echo "Dependencies have not changed, not building a new website docker image."
else
cd website/
docker login -u $WEBSITE_DOCKER_USER -p $WEBSITE_DOCKER_PASS
docker build -t hashicorp/packer-website:$IMAGE_TAG .
docker tag hashicorp/packer-website:$IMAGE_TAG hashicorp/packer-website:latest
docker login -u $WEBSITE_DOCKER_USER -p $WEBSITE_DOCKER_PASS
docker push hashicorp/packer-website
fi
algolia-index:
docker:
- image: node:12
- image: docker.mirror.hashicorp.services/node:12
steps:
- checkout
- run:
@ -198,13 +194,13 @@ workflows:
check-code:
jobs:
- check-lint
- check-vendor-vs-mod
- check-fmt
- check-generate
build_packer_binaries:
jobs:
- build_linux
- build_darwin
- build_darwin_arm64
- build_windows
- build_freebsd
- build_openbsd
@ -213,6 +209,7 @@ workflows:
requires:
- build_linux
- build_darwin
- build_darwin_arm64
- build_windows
- build_freebsd
- build_openbsd

View File

@ -1,18 +0,0 @@
comment:
layout: "flags, files"
behavior: default
require_changes: true # only comment on changes in coverage
require_base: yes # [yes :: must have a base report to post]
require_head: yes # [yes :: must have a head report to post]
after_n_builds: 3 # wait for all OS test coverage builds to post comment
branches: # branch names that can post comment
- "master"
coverage:
status:
project: off
patch: off
ignore: # ignore hcl2spec generated code for coverage and mocks
- "**/*.hcl2spec.go"
- "**/*_mock.go"

2
.gitattributes vendored
View File

@ -6,6 +6,8 @@
*.mdx text eol=lf
*.ps1 text eol=lf
*.hcl text eol=lf
*.tmpl text eol=lf
*.txt text eol=lf
go.mod text eol=lf
go.sum text eol=lf
common/test-fixtures/root/* eol=lf

View File

@ -11,6 +11,12 @@ contribute to the project, read on. This document will cover what we're looking
for. By addressing all the points we're looking for, it raises the chances we
can quickly merge or address your contributions.
When contributing in any way to the Packer project (new issue, PR, etc), please
be aware that our team identifies with many gender pronouns. Please remember to
use nonbinary pronouns (they/them) and gender neutral language ("Hello folks")
when addressing our team. For more reading on our code of conduct, please see the
[HashiCorp community guidelines](https://www.hashicorp.com/community-guidelines).
## Issues
### Reporting an Issue
@ -19,7 +25,7 @@ can quickly merge or address your contributions.
already fixed the bug you're experiencing.
- Run the command with debug output with the environment variable `PACKER_LOG`.
For example: `PACKER_LOG=1 packer build template.json`. Take the _entire_
For example: `PACKER_LOG=1 packer build template.pkr.hcl`. Take the _entire_
output and create a [gist](https://gist.github.com) for linking to in your
issue. Packer should strip sensitive keys from the output, but take a look
through just in case.
@ -64,7 +70,9 @@ can quickly merge or address your contributions.
If you have never worked with Go before, you will have to install its
runtime in order to build packer.
1. This project always releases from the latest version of golang. [Install go](https://golang.org/doc/install#install)
1. This project always releases from the latest version of golang.
[Install go](https://golang.org/doc/install#install) To properly build from
source, you need to have golang >= v1.16
## Setting up Packer for dev
@ -72,7 +80,6 @@ If/when you have go installed you can already `go get` packer and `make` in
order to compile and test Packer. These instructions target
POSIX-like environments (macOS, Linux, Cygwin, etc.) so you may need to
adjust them for Windows or other shells.
The instructions below are for go 1.7. or later.
1. Download the Packer source (and its dependencies) by running
`go get github.com/hashicorp/packer`. This will download the Packer source to
@ -91,7 +98,7 @@ The instructions below are for go 1.7. or later.
4. After running building Packer successfully, use
`$GOPATH/src/github.com/hashicorp/packer/bin/packer` to build a machine and
verify your changes work. For instance:
`$GOPATH/src/github.com/hashicorp/packer/bin/packer build template.json`.
`$GOPATH/src/github.com/hashicorp/packer/bin/packer build template.pkr.hcl`.
5. If everything works well and the tests pass, run `go fmt` on your code before
submitting a pull-request.
@ -259,7 +266,7 @@ does not attempt to track the latest version for each dependency.
#### Code generation
Packer relies on `go generate` to generate a [peg parser for boot
commands](https://github.com/hashicorp/packer/blob/master/common/bootcommand/boot_command.go),
commands](https://github.com/hashicorp/packer/blob/master/packer-plugin-sdk/bootcommand/boot_command.go),
[docs](https://github.com/hashicorp/packer/blob/master/website/pages/partials/builder/amazon/chroot/_Config-not-required.mdx)
and HCL2's bridging code. Packer's testing suite will run `make check-generate`
to check that all the generated files Packer needs are what they should be.
@ -301,15 +308,15 @@ You can run tests for individual packages using commands like this:
make test TEST=./builder/amazon/...
```
#### Running Acceptance Tests
#### Running Builder Acceptance Tests
Packer has [acceptance tests](https://en.wikipedia.org/wiki/Acceptance_testing)
for various builders. These typically require an API key (AWS, GCE), or
additional software to be installed on your computer (VirtualBox, VMware).
If you're working on a new builder or builder feature and want to verify it is
functioning (and also hasn't broken anything else), we recommend running the
acceptance tests.
functioning (and also hasn't broken anything else), we recommend creating or
running the acceptance tests.
**Warning:** The acceptance tests create/destroy/modify _real resources_, which
may incur costs for real money. In the presence of a bug, it is possible that
@ -340,7 +347,7 @@ Acceptance tests typically require other environment variables to be set for
things such as API tokens and keys. Each test should error and tell you which
credentials are missing, so those are not documented here.
#### Running Provisioners Acceptance Tests
#### Running Provisioner Acceptance Tests
**Warning:** The acceptance tests create/destroy/modify _real resources_, which
may incur costs for real money. In the presence of a bug, it is possible that
@ -351,124 +358,164 @@ resources are not accidentally destroyed or overwritten during testing.
Also, these typically require an API key (AWS, GCE), or additional software
to be installed on your computer (VirtualBox, VMware).
To run the Provisioners Acceptance Tests you should use both **ACC_TEST_BUILDERS** and **ACC_TEST_PROVISIONERS** variables to
tell which provisioner and builder the test should be run against.
To run the Provisioners Acceptance Tests you should use the
**ACC_TEST_BUILDERS** environment variable to tell the tests which builder the
test should be run against.
Examples of usage:
- Run the Shell provisioner acceptance tests against the Amazon EBS builder.
```
ACC_TEST_BUILDERS=amazon-ebs ACC_TEST_PROVISIONERS=shell go test ./provisioner/shell/... -v -timeout=1h
ACC_TEST_BUILDERS=amazon-ebs go test ./provisioner/shell/... -v -timeout=1h
```
- Do the same but using the Makefile
```
ACC_TEST_BUILDERS=amazon-ebs ACC_TEST_PROVISIONERS=shell make provisioners-acctest
ACC_TEST_BUILDERS=amazon-ebs make provisioners-acctest TEST=./provisioner/shell
```
- Run the all Shell and Powershell provisioners acceptance tests against the Amazon EBS builder.
- Run all provisioner acceptance tests against the Amazon EBS builder.
```
ACC_TEST_BUILDERS=amazon-ebs ACC_TEST_PROVISIONERS=shell,powershell make provisioners-acctest
ACC_TEST_BUILDERS=amazon-ebs make provisioners-acctest TEST=./...
```
- Run the all provisioners acceptance tests against the Amazon EBS builder.
- Run all provisioner acceptance tests against all builders whenever they are compatible.
```
ACC_TEST_BUILDERS=amazon-ebs ACC_TEST_PROVISIONERS=all make provisioners-acctest
```
- Run the all provisioners acceptance tests against all builders whenever they are compatible.
```
ACC_TEST_BUILDERS=all ACC_TEST_PROVISIONERS=all make provisioners-acctest
ACC_TEST_BUILDERS=all make provisioners-acctest TEST=./...
```
Both **ACC_TEST_BUILDERS** and **ACC_TEST_PROVISIONERS** allows defining a list of builders and provisioners separated by comma
(e.g. `ACC_TEST_BUILDERS=amazon-ebs,virtualbox-iso`)
The **ACC_TEST_BUILDERS** env variable accepts a list of builders separated by
commas. (e.g. `ACC_TEST_BUILDERS=amazon-ebs,virtualbox-iso`)
#### Writing Provisioner Acceptance Tests
Packer has an already implemented structure that will run the provisioner against builders and you can find it in `helper/tests/acc/provisioners.go`.
All provisioners should use this structure in their acceptance tests.
To start writing a new provisioner acceptance test, you should add a test file named as `provisioner_acc_test.go` in the provisioner folder
and the package should be `<provisioner>_test`. This file should have a struct that will implement the ProvisionerAcceptance interface.
Packer has implemented a `ProvisionerTestCase` structure to help write
provisioner acceptance tests.
```go
type ProvisionerAcceptance interface {
GetName() string
GetConfig() (string, error)
GetProvisionerStore() packer.MapOfProvisioner
IsCompatible(builder string, vmOS string) bool
RunTest(c *command.BuildCommand, args []string) error
type ProvisionerTestCase struct {
// Check is called after this step is executed in order to test that
// the step executed successfully. If this is not set, then the next
// step will be called
Check func(*exec.Cmd, string) error
// IsCompatible checks whether a provisioner is able to run against a
// given builder type and guest operating system, and returns a boolean.
// if it returns true, the test combination is okay to run. If false, the
// test combination is not okay to run.
IsCompatible func(builderType string, BuilderGuestOS string) bool
// Name is the name of the test case. Be simple but unique and descriptive.
Name string
// Setup, if non-nil, will be called once before the test case
// runs. This can be used for some setup like setting environment
// variables, or for validation prior to the
// test running. For example, you can use this to make sure certain
// binaries are installed, or text fixtures are in place.
Setup func() error
// Teardown will be called before the test case is over regardless
// of if the test succeeded or failed. This should return an error
// in the case that the test can't guarantee all resources were
// properly cleaned up.
Teardown builderT.TestTeardownFunc
// Template is the provisioner template to use.
// The provisioner template fragment must be a json-formatted string
// containing the provisioner definition but no other portions of a packer
// template. For
// example:
//
// ```json
// {
// "type": "shell-local",
// "inline", ["echo hello world"]
// }
//```
//
// is a valid entry for "template" here, but the complete Packer template:
//
// ```json
// {
// "provisioners": [
// {
// "type": "shell-local",
// "inline", ["echo hello world"]
// }
// ]
// }
// ```
//
// is invalid as input.
//
// You may provide multiple provisioners in the same template. For example:
// ```json
// {
// "type": "shell-local",
// "inline", ["echo hello world"]
// },
// {
// "type": "shell-local",
// "inline", ["echo hello world 2"]
// }
// ```
Template string
// Type is the type of provisioner.
Type string
}
```
- **GetName()** should return the provisioner type. For example for the Shell provisioner the method returns "shell".
To start writing a new provisioner acceptance test, you should add a test file
named `provisioner_acc_test.go` in the same folder as your provisioner is
defined. Create a test case by implementing the above struct, and run it
by calling `provisioneracc.TestProvisionersAgainstBuilders(testCase, t)`
- **GetConfig()** should read a text file with the json configuration block for the provisioner and any other necessary provisioner.
For the Shell one the file contains:
The following example has been adapted from a shell-local provisioner test:
```
{
"type": "shell",
"inline": [
"echo {{ build `ID`}} > provisioner.{{ build `PackerRunUUID`}}.txt"
]
```
import (
"github.com/hashicorp/packer-plugin-sdk/acctest/provisioneracc"
"github.com/hashicorp/packer-plugin-sdk/acctest/testutils"
)
// ...
func TestAccShellProvisioner_basic(t *testing.T) {
// Create a json template fragment containing just the provisioners you want
// to run.
templateString := `{
"type": "shell-local",
"script": "test-fixtures/script.sh",
"max_retries" : 5
}`
// instantiate a test case.
testCase := &provisioneracc.ProvisionerTestCase{
IsCompatible: func() bool {return true},
Name: "shell-local-provisioner-basic",
Teardown: func() error {
testutils.CleanupFiles("test-fixtures/file.txt")
return nil
},
{
"type": "file",
"source": "provisioner.{{ build `PackerRunUUID`}}.txt",
"destination": "provisioner.shell.{{ build `PackerRunUUID`}}.txt",
"direction": "download"
}
```
The file should be placed under the `test-fixtures` folder.
In this case, it's necessary to use the File provisioner to validate if the Shell provisioner test is successful or not.
This config should be returned as string that will be later merged with the builder config into a full template.
- **GetProvisionerStore()** this returns the provisioner store where we declare the available provisioners for running the build.
For the Shell provisioners this is:
```go
func (s *ShellProvisionerAccTest) GetProvisionerStore() packer.MapOfProvisioner {
return packer.MapOfProvisioner{
"shell": func() (packer.Provisioner, error) { return &shell.Provisioner{}, nil },
"file": func() (packer.Provisioner, error) { return &file.Provisioner{}, nil },
}
Template: templateString,
Type: "shell-local",
Check: func(buildcommand *exec.Cmd, logfile string) error {
if buildcommand.ProcessState != nil {
if buildcommand.ProcessState.ExitCode() != 0 {
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
}
}
```
- **IsCompatible(builder string, vmOS string)** returns true or false whether the provisioner should run against a
specific builder or/and specific OS.
- **RunTest(c \*command.BuildCommand, args []string)** it will actually run the build and return any error if it fails the validations.
For the Shell provisioner this is:
```go
func (s *ShellProvisionerAccTest) RunTest(c *command.BuildCommand, args []string) error {
// Provisioner specific setup
UUID := os.Getenv("PACKER_RUN_UUID")
if UUID == "" {
UUID, _ = uuid.GenerateUUID()
os.Setenv("PACKER_RUN_UUID", UUID)
}
file := "provisioner.shell." + UUID + ".txt"
defer testshelper.CleanupFiles(file)
// Run build
// All provisioner acc tests should contain this code and validation
if code := c.Run(args); code != 0 {
ui := c.Meta.Ui.(*packer.BasicUi)
out := ui.Writer.(*bytes.Buffer)
err := ui.ErrorWriter.(*bytes.Buffer)
return fmt.Errorf(
"Bad exit code.\n\nStdout:\n\n%s\n\nStderr:\n\n%s",
out.String(),
err.String())
}
// Any other extra specific validation
if !testshelper.FileExists(file) {
return fmt.Errorf("Expected to find %s", file)
}
return nil
filecontents, err := loadFile("file.txt")
if err != nil {
return err
}
if !strings.Contains(filecontents, "hello") {
return fmt.Errorf("file contents were wrong: %s", filecontents)
}
return nil
},
}
provisioneracc.TestProvisionersAgainstBuilders(testCase, t)
}
```
```
After writing the struct and implementing the interface, now is time to write the test that will run all
of this code you wrote. Your test should be like:
@ -480,64 +527,101 @@ func TestShellProvisioner(t *testing.T) {
}
```
If the environment variable **ACC_TEST_PROVISIONERS** is set as `all` or contains the provisioner type, then the test should run, otherwise the test should skip.
In case of running it, you'll need to call the helper function `acc.TestProvisionersAgainstBuilders` passing a pointer to the test struct created above and the test testing pointer.
The method `TestProvisionersAgainstBuilders` will run the provisioner against
all available and compatible builders. If there are not builders compatible with
the test you want to run, you can add a builder using the following steps:
The method `TestProvisionersAgainstBuilders` will run the provisioner against all available and compatible builders. An available builder
is the one that has the necessary code for running this type of test. In case the builder you want to run against is not available for testing, you can write it following the next steps.
Create a subdirectory in provisioneracc/test-fixtures for the type of builder
you are adding. In this subdirectory, add one json file containing a single
builder fragment. For example, one of our amazon-ebs builders is defined in
provisioneracc/test-fixtures/amazon-ebs/amazon-ebs.txt and contains:
To add a new builder to the available builders for provisioners acc testing, you'll need to create a new folder under the builder folder
called `acceptance` and inside you create the `builder_acceptance.go` file and the package should be `<builder>_acc`. Like the provisioners, you'll need to create a struct that will
implement the BuilderAcceptance interface.
```go
type BuilderAcceptance interface {
GetConfigs() (map[string]string, error)
GetBuilderStore() packer.MapOfBuilder
CleanUp() error
}
```
- **GetConfigs()** should read a text file with the json configuration block for the builder and return a map of configs by OS type.
For the Amazon EBS builder the file contains:
```
{
"type": "amazon-ebs",
"ami_name": "packer-acc-test",
"instance_type": "m1.small",
"region": "us-east-1",
"ssh_username": "ubuntu",
"source_ami": "ami-0568456c",
"force_deregister" : true,
"tags": {
"packer-test": "true"
}
}
```
The file should be placed under the `test-fixtures` folder.
In case you need to make references to another file, you'll need to add the relative path to provisioners folder like:
`../../builder/amazon/ebs/acceptance/test-fixtures/file.txt`.
- **GetBuilderStore()** this returns the builder store where we declare the available builders for running the build.
For the Amazon EBS builder this is:
```go
func (s *AmazonEBSAccTest) GetBuilderStore() packer.MapOfBuilder {
return packer.MapOfBuilder{
"amazon-ebs": func() (packer.Builder, error) { return &amazonebsbuilder.Builder{}, nil },
}
}
```
- **CleanUp()** cleans any resource created by the builder whether local or remote.
Once you created the builder necessary code, the last step is adding it to the `BuildersAccTest` map in `helper/tests/acc/provisioners.go`.
```go
var BuildersAccTest = map[string]BuilderAcceptance{
...
"amazon-ebs": new(amazonEBS.AmazonEBSAccTest),
...
```json
{
"type": "amazon-ebs",
"ami_name": "packer-acc-test",
"instance_type": "t2.micro",
"region": "us-east-1",
"ssh_username": "ubuntu",
"source_ami_filter": {
"filters": {
"virtualization-type": "hvm",
"name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*",
"root-device-type": "ebs"
},
"owners": ["099720109477"],
"most_recent": true
},
"force_deregister" : true,
"tags": {
"packer-test": "true"
}
}
```
Once you finish the steps, you should be ready to run your new provisioner acceptance test.
note that this fragment does not contain anything other than a single builder
definition. The testing framework will combine this with the provisioner
fragment to create a working json template.
In order to tell the testing framework how to use this builder fragment, you
need to implement a `BuilderFixture` struct:
```go
type BuilderFixture struct {
// Name is the name of the builder fixture.
// Be simple and descriptive.
Name string
// Setup creates necessary extra test fixtures, and renders their values
// into the BuilderFixture.Template.
Setup func()
// Template is the path to a builder template fragment.
// The builder template fragment must be a json-formatted file containing
// the builder definition but no other portions of a packer template. For
// example:
//
// ```json
// {
// "type": "null",
// "communicator", "none"
// }
//```
//
// is a valid entry for "template" here, but the complete Packer template:
//
// ```json
// {
// "builders": [
// "type": "null",
// "communicator": "none"
// ]
// }
// ```
//
// is invalid as input.
//
// Only provide one builder template fragment per file.
TemplatePath string
// GuestOS says what guest os type the builder template fragment creates.
// Valid values are "windows", "linux" or "darwin" guests.
GuestOS string
// HostOS says what host os type the builder is capable of running on.
// Valid values are "any", windows", or "posix". If you set "posix", then
// this builder can run on a "linux" or "darwin" platform. If you set
// "any", then this builder can be used on any platform.
HostOS string
Teardown builderT.TestTeardownFunc
}
```
Implement this struct to the file "provisioneracc/builders.go", then add
the new implementation to the `BuildersAccTest` map in
`provisioneracc/provisioners.go`
Once you finish these steps, you should be ready to run your new provisioner
acceptance test by setting the name used in the BuildersAccTest map as your
`ACC_TEST_BUILDERS` environment variable.
#### Debugging Plugins

View File

@ -10,7 +10,7 @@ Describe the change you are making here!
Please include tests. Check out these examples:
- https://github.com/hashicorp/packer/blob/master/builder/virtualbox/common/ssh_config_test.go#L19-L37
- https://github.com/hashicorp/packer/blob/master/builder/parallels/common/ssh_config_test.go#L34
- https://github.com/hashicorp/packer/blob/master/post-processor/compress/post-processor_test.go#L153-L182
If your PR resolves any open issue(s), please indicate them like this so they will be closed when your PR is merged:

5
.github/labeler-issue-triage.yml vendored Normal file
View File

@ -0,0 +1,5 @@
bug:
- 'panic:'
crash:
- 'panic:'

102
.github/workflows/check-plugin-docs.js vendored Normal file
View File

@ -0,0 +1,102 @@
const fs = require("fs");
const path = require("path");
const fetchPluginDocs = require("../../website/components/remote-plugin-docs/utils/fetch-plugin-docs");
const COLOR_RESET = "\x1b[0m";
const COLOR_GREEN = "\x1b[32m";
const COLOR_BLUE = "\x1b[34m";
const COLOR_RED = "\x1b[31m";
async function checkPluginDocs() {
const failureMessages = [];
const pluginsPath = "website/data/docs-remote-plugins.json";
const pluginsFile = fs.readFileSync(path.join(process.cwd(), pluginsPath));
const pluginEntries = JSON.parse(pluginsFile);
const entriesCount = pluginEntries.length;
console.log(`\nResolving plugin docs from ${entriesCount} repositories …`);
for (var i = 0; i < entriesCount; i++) {
const pluginEntry = pluginEntries[i];
const { title, repo, version } = pluginEntry;
console.log(`\n${COLOR_BLUE}${repo}${COLOR_RESET} | ${title}`);
console.log(`Fetching docs from release "${version}" …`);
try {
// Validate that all required properties are present
const undefinedProps = ["title", "repo", "version", "path"].filter(
(key) => typeof pluginEntry[key] == "undefined"
);
if (undefinedProps.length > 0) {
throw new Error(
`Failed to validate plugin docs config. Undefined configuration properties ${JSON.stringify(
undefinedProps
)} found for "${
title || pluginEntry.path || repo
}". In "website/data/docs-remote-plugins.json", please ensure the missing properties ${JSON.stringify(
undefinedProps
)} are defined. Additional information on this configuration can be found in "website/README.md".`
);
}
// Validate pluginTier property
const { pluginTier } = pluginEntry;
if (typeof pluginTier !== "undefined") {
const validPluginTiers = ["official", "community"];
const isValid = validPluginTiers.indexOf(pluginTier) !== -1;
if (!isValid) {
throw new Error(
`Failed to validate plugin docs config. Invalid pluginTier "${pluginTier}" found for "${
title || pluginEntry.path || repo
}". In "website/data/docs-remote-plugins.json", the optional pluginTier property must be one of ${JSON.stringify(
validPluginTiers
)}. The pluginTier property can also be omitted, in which case it will be determined from the plugin repository owner.`
);
}
}
// Validate that local zip files are not used in production
if (typeof pluginEntry.zipFile !== "undefined") {
throw new Error(
`Local ZIP file being used for "${
title || pluginEntry.path || repo
}". The zipFile option should only be used for local development. Please omit the zipFile attribute and ensure the plugin entry points to a remote repository.`
);
}
// Attempt to fetch plugin docs files
const docsMdxFiles = await fetchPluginDocs({ repo, tag: version });
const mdxFilesByComponent = docsMdxFiles.reduce((acc, mdxFile) => {
const componentType = mdxFile.filePath.split("/")[1];
if (!acc[componentType]) acc[componentType] = [];
acc[componentType].push(mdxFile);
return acc;
}, {});
console.log(`${COLOR_GREEN}Found valid docs:${COLOR_RESET}`);
Object.keys(mdxFilesByComponent).forEach((component) => {
const componentFiles = mdxFilesByComponent[component];
console.log(` ${component}`);
componentFiles.forEach(({ filePath }) => {
const pathFromComponent = filePath.split("/").slice(2).join("/");
console.log(` ├── ${pathFromComponent}`);
});
});
} catch (err) {
console.log(`${COLOR_RED}${err}${COLOR_RESET}`);
failureMessages.push(`\n${COLOR_RED}× ${repo}: ${COLOR_RESET}${err}`);
}
}
if (failureMessages.length === 0) {
console.log(
`\n---\n\n${COLOR_GREEN}Summary: Successfully resolved all plugin docs.`
);
pluginEntries.forEach((e) =>
console.log(`${COLOR_GREEN}${e.repo}${COLOR_RESET}`)
);
console.log("");
} else {
console.log(
`\n---\n\n${COLOR_RED}Summary: Failed to fetch docs for ${failureMessages.length} plugin(s):`
);
failureMessages.forEach((err) => console.log(err));
console.log("");
process.exit(1);
}
}
checkPluginDocs();

29
.github/workflows/check-plugin-docs.yml vendored Normal file
View File

@ -0,0 +1,29 @@
#
# This GitHub action checks plugin repositories for valid docs.
#
# This provides a quick assessment on PRs of whether
# there might be issues with docs in plugin repositories.
#
# This is intended to help debug Vercel build issues, which
# may or may not be related to docs in plugin repositories.
name: "website: Check plugin docs"
on:
pull_request:
paths:
- "website/**"
schedule:
- cron: "45 0 * * *"
jobs:
check-plugin-docs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v1
- name: Install Dependencies
run: npm i isomorphic-unfetch adm-zip gray-matter
- name: Fetch and validate plugin docs
run: node .github/workflows/check-plugin-docs.js

View File

@ -0,0 +1,17 @@
name: Issue Comment Created Triage
on:
issue_comment:
types: [created]
jobs:
issue_comment_triage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-ecosystem/action-remove-labels@v1
with:
github_token: "${{ secrets.GITHUB_TOKEN }}"
labels: |
stale
waiting-reply

16
.github/workflows/issues-opened.yml vendored Normal file
View File

@ -0,0 +1,16 @@
name: Issue Opened Triage
on:
issues:
types: [opened]
jobs:
issue_triage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: github/issue-labeler@v2
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
configuration-path: .github/labeler-issue-triage.yml

37
.github/workflows/linkchecker.yml vendored Normal file
View File

@ -0,0 +1,37 @@
on:
pull_request:
paths:
- 'website/**'
name: Check markdown links on modified website files
jobs:
vercel-deployment-poll:
runs-on: ubuntu-latest
timeout-minutes: 5 #cancel job if no deployment is found within x minutes
outputs:
url: ${{ steps.waitForVercelPreviewDeployment.outputs.url }}
steps:
- name: Wait for Vercel preview deployment to be ready
uses: nywilken/wait-for-vercel-preview@master
id: waitForVercelPreviewDeployment
with:
token: ${{ secrets.GITHUB_TOKEN }}
max_timeout: 600 # in seconds, set really high to leverage job timeout-minutes values
allow_inactive: true # needed to ensure we get a URL for a previously released deployment
markdown-link-check:
needs: vercel-deployment-poll
if: ${{ needs.vercel-deployment-poll.outputs.url != '' }}
runs-on: ubuntu-latest
steps:
- name: Get Deployment URL
run:
echo "DEPLOYMENT_URL=${{ needs.vercel-deployment-poll.outputs.url }}" >> $GITHUB_ENV
- name: Checkout source branch
uses: actions/checkout@master
- name: Check links
uses: gaurav-nelson/github-action-markdown-link-check@v1
with:
use-quiet-mode: 'yes'
file-extension: 'mdx'
check-modified-files-only: 'yes'
folder-path: 'website/content'

29
.github/workflows/lock.yml vendored Normal file
View File

@ -0,0 +1,29 @@
name: 'Lock Threads'
on:
schedule:
- cron: '50 1 * * *'
# Only 50 issues will be handled during a given run.
jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2
with:
github-token: ${{ github.token }}
issue-lock-comment: >
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
issue-lock-inactive-days: '30'
# Issues older than 180 days ago should be ignored
issue-exclude-created-before: '2020-11-01'
pr-lock-comment: >
I'm going to lock this pull request because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
pr-lock-inactive-days: '30'
# Issues older than 180 days ago should be ignored
pr-exclude-created-before: '2020-11-01'

View File

@ -0,0 +1,17 @@
on:
schedule:
- cron: "45 0 * * *"
name: Check Markdown links on main branch
jobs:
markdown-link-check:
runs-on: ubuntu-latest
steps:
- name: Set deployment URL env
run:
echo "DEPLOYMENT_URL=https://packer-git-master.hashicorp.vercel.app" >> $GITHUB_ENV
- uses: actions/checkout@master
- uses: gaurav-nelson/github-action-markdown-link-check@v1
with:
use-quiet-mode: 'yes'
file-extension: 'mdx'
folder-path: 'website/content'

3
.gitignore vendored
View File

@ -13,6 +13,8 @@ test/.env
*.received.*
*.swp
vendor/
website/.bundle
website/vendor
@ -27,3 +29,4 @@ Thumbs.db
/packer.exe
.project
cache
/.vscode/

View File

@ -85,8 +85,7 @@ run:
# If invoked with -mod=vendor, the go command assumes that the vendor
# directory holds the correct copies of dependencies and ignores
# the dependency descriptions in go.mod.
modules-download-mode: vendor
modules-download-mode: readonly
# output configuration options
output:

View File

@ -1,24 +1,17 @@
poll "label_issue_migrater" "remote_plugin_migrater" {
schedule = "0 20 * * * *"
new_owner = "hashicorp"
repo_prefix = "packer-plugin-"
label_prefix = "remote-plugin/"
excluded_label_prefixes = ["communicator/"]
excluded_labels = ["build", "core", "new-plugin-contribution", "website"]
behavior "regexp_issue_labeler" "panic_label" {
regexp = "panic:"
labels = ["crash", "bug"]
issue_header = <<-EOF
_This issue was originally opened by @${var.user} as ${var.repository}#${var.issue_number}. It was migrated here as a result of the [Packer plugin split](https://github.com/hashicorp/packer/issues/8610#issuecomment-770034737). The original body of the issue is below._
<hr>
EOF
migrated_comment = "This issue has been automatically migrated to ${var.repository}#${var.issue_number} because it looks like an issue with that plugin. If you believe this is _not_ an issue with the plugin, please reply to ${var.repository}#${var.issue_number}."
}
behavior "remove_labels_on_reply" "remove_stale" {
labels = ["waiting-reply", "stale"]
only_non_maintainers = true
}
poll "closed_issue_locker" "locker" {
schedule = "0 50 1 * * *"
closed_for = "720h" # 30 days
max_issues = 500
sleep_between_issues = "5s"
no_comment_if_no_activity_for = "4320h" # 180 days
message = <<-EOF
I'm going to lock this issue because it has been closed for _30 days_ . This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
EOF
}

View File

@ -1,3 +1,490 @@
## 1.7.3 (Upcoming)
### IMPROVEMENTS:
Major refactor: Extracted a majority of HashiCorp-maintained and community plugins from the Packer Core repository. They now live in their own multi-component plugin repositiores. The following repositories have been created, and their components have been deleted from the "github.com/hashicorp/packer" repository.
* "github.com/hashicorp/packer-plugin-alicloud" [GH-10932]
* "github.com/hashicorp/packer-plugin-amazon" [GH-10800]
* "github.com/hashicorp/packer-plugin-ansible" [GH-10912]
* "github.com/hashicorp/packer-plugin-azure" [GH-10979]
* "github.com/hashicorp/packer-plugin-chef" [GH-10921]
* "github.com/hashicorp/packer-plugin-cloudstack" [GH-10934]
* "github.com/hashicorp/packer-plugin-converge" [GH-10956]
* "github.com/hashicorp/packer-plugin-digitalocean" [GH-10961]
* "github.com/hashicorp/packer-plugin-docker" [GH-10695]
* "github.com/hashicorp/packer-plugin-googlecompute" [GH-10890]
* "github.com/hashicorp/packer-plugin-hcloud" [GH-10966]
* "github.com/hashicorp/packer-plugin-hyperone" [GH-10949]
* "github.com/hashicorp/packer-plugin-hyperv" [GH-10949]
* "github.com/hashicorp/packer-plugin-inspec"
* "github.com/hashicorp/packer-plugin-ionos-cloud"
* "github.com/hashicorp/packer-plugin-jdcloud" [GH-10946]
* "github.com/hashicorp/packer-plugin-linode" [GH-10947]
* "github.com/hashicorp/packer-plugin-lxc" [GH-10965]
* "github.com/hashicorp/packer-plugin-lxd" [GH-10965]
* "github.com/hashicorp/packer-plugin-ncloud" [GH-10937]
* "github.com/hashicorp/packer-plugin-openstack" [GH-10933]
* "github.com/hashicorp/packer-plugin-oracle" [GH-10962]
* "github.com/hashicorp/packer-plugin-outscale" [GH-10941]
* "github.com/hashicorp/packer-plugin-parallels" [GH-10936]
* "github.com/hashicorp/packer-plugin-proxmox" [GH-10930]
* "github.com/hashicorp/packer-plugin-puppet" [GH-10943]
* "github.com/hashicorp/packer-plugin-qemu" [GH-10929]
* "github.com/hashicorp/packer-plugin-salt"
* "github.com/hashicorp/packer-plugin-scaleway" [GH-10939]
* "github.com/hashicorp/packer-plugin-tencentcloud" [GH-10967]
* "github.com/hashicorp/packer-plugin-triton" [GH-10963]
* "github.com/hashicorp/packer-plugin-ucloud" [GH-10953]
* "github.com/hashicorp/packer-plugin-vagrant" [GH-10960]
* "github.com/hashicorp/packer-plugin-virtualbox" [GH-10910]
* "github.com/hashicorp/packer-plugin-vmware" [GH-10920]
* "github.com/hashicorp/packer-plugin-vsphere" [GH-10896]
* "github.com/hashicorp/packer-plugin-yandex" [GH-10970]
_this will not be a backwards-breaking change in v1.7.3_ because the extracted
components are being vendored back into Packer. However, we encourage users to
begin using `packer init` to download and install plugins to get the latest
updates to each plugin, and to prepare for Packer v2.0 when we will stop
vendoring the above plugins into the main Packer binary. The following
components will not be removed from the main packer binary:
* `null` builder
* `file` builder
* `breakpoint` provisioner
* `file` provisioner
* `powershell` provisioner
* `shell` provisioner
* `shell-local` provisioner
* `sleep` provisioner
* `windows-restart` provisioner
* `windows-shell` provisioner
* `artifice` post-processor
* `checksum` post-processor
* `compress` post-processor
* `manifest` post-processor
* `shell-local` post-processor
### Bug Fixes:
* builder/azure: Add `keep_os_disk` parameter to control OS disk deletion
[GH-10045]
* builder/azure: Stop SIG timout from being overridden by PollingDuration
[GH-10816]
* builder/azure: Support shared image gallery storage account type [GH-10863]
* builder/proxmox: Proxmox builder use ipv4 address instead of always ipv6.
[GH-10858]
* core/hcl: Fix Invalid provisioner pause_before panic [GH-10978]
* core: HCL "index" function now actually returns the index of the element
[GH-11008]
* core: Implemented DEFAULT_NAME handling for datasource plugins [GH-11026]
### Enhancements:
* builder/azure: Added custom nicname and osdiskname [GH-10938]
* builder/azure: Add support for shared image gallery storage account type
[GH-10863]
* builder/digitalocean: support ecdsa, ed25519, dsa temporary key types.
[GH-10856]
* builder/ncloud: Support ncloud vpc version [GH-10870]
* post-processor/compress: Add bzip2 support to post-processor [GH-10867]
* post-processor/googlecompute-import: Add Image Storage Locations field
[GH-10864]
* Removed the golang "vendor" directory in favor of go modules. This should not
affect end users. [GH-10916]
## 1.7.2 (April 05, 2021)
### IMPROVEMENTS:
* builder/alicloud: Add `ramrole` configuration to ECS instance. [GH-10845]
### BUG FIXES:
* builder/proxmox: Update Proxmox Go API to ensure only the first non-loopback
IPv4 address gets returned. [GH-10858]
* builder/vsphere: Fix primary disk resize on clone. [GH-10848]
* core: Fix bug where call to "packer version" sent output to stderr instead of
stdout. [GH-10850]
## 1.7.1 (March 31, 2021)
### NOTES:
* builder/amazon: Has been vendored in this release and will no longer be
updated with Packer core. In Packer v1.8.0 the plugin will be removed
entirely. The `amazon` components will continue to work as expected until
then, but for the latest offerings of the Amazon plugin, users are
encourage to use the `packer init` command to install the latest release
version. For more details see [Installing Packer
Plugins](https://www.packer.io/docs/plugins#installing-plugins)
* builder/docker: Has been vendored in this release and will no longer be
updated with Packer core. In Packer v1.8.0 the plugin will be removed
entirely. The `docker` builder will continue to work as expected until
then, but for the latest offerings of the Docker plugin, users are
encourage to use the `packer init` command to install the latest release
version. For more details see [Installing Packer
Plugins](https://www.packer.io/docs/plugins#installing-plugins)
* darwin/arm64: Packer now includes the darwin/arm64 binary to its releases to
supports the new OSX M1. [GH-10804]
* post-processor/docker-\*: Have been vendored in this release and will no
longer be updated with Packer core. In Packer v1.8.0 the plugin will be
removed entirely. The `docker` builder will continue to work as expected
until then, but for the latest offerings of the Docker plugin, users are
encourage to use the `packer init` command to install the latest release
version. For more details see [Installing Packer
Plugins](https://www.packer.io/docs/plugins#installing-plugins)
* post-processor/exoscale-import: Has been vendored in this release and will no
longer be updated with Packer core. In Packer v1.8.0 the plugin will be
removed entirely. The `exoscale-import` post-processor will continue to
work as expected until then, but for the latest offerings of the Exoscale
plugin, users are encourage to use the `packer init` command to install the
latest release version. For more details see [Exoscale Plugin
Repostiroy](https://github.com/exoscale/packer-plugin-exoscale). [GH-10709]
### IMPROVEMENTS
* builder/amazon: allow creation of ebs snapshots without volumes. [GH-9591]
* builder/amazon: Fix issue for multi-region AMI build that fail when
encrypting with KMS and sharing across accounts. [GH-10754]
* builder/azure: Add client_cert_token_timeout option. [GH-10528]
* builder/google: Make Windows password timeout configurable. [GH-10727]
* builder/google: Update public GCP image project as gce-uefi-images are
deprecated. [GH-10724]
* builder/oracle-oci: Update Oracle Go SDK to add support for OCI flexible
shapes. [GH-10833]
* builder/proxmox: Allow using API tokens for Proxmox authentication.
[GH-10797]
* builder/qemu: Added firmware option. [GH-10683]
* builder/scaleway: add support for timeout in shutdown step. [GH-10503]
* builder/vagrant: Fix logging to be clearer when Vagrant builder overrides
values retrieved from vagrant's ssh_config call. [GH-10743]
* builder/virtualbox: Added ISO builder option to create additional disks.
[GH-10674]
* builder/virtualbox: Add options for nested virtualisation and RTC time base.
[GH-10736]
* builder/virtualbox: Add template options for chipset, firmware, nic, graphics
controller, and audio controller. [GH-10671]
* builder/virtualbox: Support for "virtio" storage and ISO drive. [GH-10632]
* builder/vmware: Added "attach_snapshot" parameter to vmware vmx builder.
[GH-10651]
* command/fmt: Adding recursive flag to formatter to format subdirectories.
[GH-10457]
* core/hcl2: Add legacy_isotime function. [GH-10780]
* core/hcl2: Add support for generating `dynamic` blocks within a `build`
block. [GH-10825]
* core/hcl2: Add templatefile function. [GH-10776]
* core/hcl2_upgrade: hcl2_upgrade command can now upgrade json var-files.
[GH-10676]
* core/init: Add implicit required_plugin blocks feature. [GH-10732]
* core: Add http_content option to serve variables from HTTP at preseed.
[GH-10801]
* core: Change template parsing error to include warning about file extensions.
[GH-10652]
* core: Update to gopsutil v3.21.1 to allow builds to work for darwin arm64.
[GH-10697]
* provisioner/inspec: Allow non-zero exit codes for inspec provisioner.
[GH-10723]
### BUG FIXES
* buider/azure: Update builder to ensure a proper clean up Azure temporary
managed Os disks. [GH-10713]
* builder/amazon: Update amazon SDK to fix an SSO login issue. [GH-10668]
* builder/azure: Don't overwrite subscription id if unset. [GH-10659]
* builder/azure: Set default for the parameter client_cert_token_timeout
[GH-10783]
* builder/google: Add new configuration field `windows_password_timeout` to
allow user to set configurable timeouts. [GH-10727]
* builder/hyperv: Make Packer respect winrm_host flag in winrm connect func.
[GH-10748]
* builder/openstack: Make Packer respect winrm_host flag in winrm connect func.
[GH-10748]
* builder/oracle-oci: Update Oracle Go SDK to fix issue with reading key file.
[GH-10560] [GH-10774]
* builder/outscale: Fix omi_description that was ignored in Osc builder
[GH-10792]
* builder/parallels: Make Packer respect winrm_host flag in winrm connect func.
[GH-10748]
* builder/proxmox: Fixes issue when using `additional_iso_files` in HCL enabled
templates. [GH-10772]
* builder/qemu: Make Packer respect winrm_host flag in winrm connect func.
[GH-10748]
* builder/virtualbox: Make Packer respect winrm_host flag in winrm connect
func. [GH-10748]
* builder/vmware: Added a fallback file check when trying to determine the
network-mapping configuration. [GH-10543]
* builder/vsphere: Fix invalid device configuration issue when creating a
vm with multiple disk on the same controller. [GH-10844]
* builder/vsphere: Fix issue where boot command would fail the build do to a
key typing error. This change will now retry to type the key on error
before giving up. [GH-10541]
* core/hcl2_upgrade: Check for nil config map when provisioner/post-processor
doesn't have config. [GH-10730]
* core/hcl2_upgrade: Fix escaped quotes in template functions [GH-10794]
* core/hcl2_upgrade: Make hcl2_upgrade command correctly translate
pause_before. [GH-10654]
* core/hcl2_upgrade: Make json variables using template engines get stored as
locals so they can be properly interpolated. [GH-10685]
* core/init: Fixes issue where `packer init` was failing to install valid
plugins containing a 'v' within its name. [GH-10760]
* core: Packer will now show a proper error message when failing to load the
contents of PACKER_CONFIG. [GH-10766]
* core: Pin Packer to Golang 1.16 to fix code generation issues. [GH-10702]
* core: Templates previously could not interpolate the environment variable
PACKER_LOG_PATH. [GH-10660]
* post-processor/vagrant-cloud: Override direct upload based on box size
[GH-10820]
* provisioner/chef-solo: HCL2 templates can support the json_string option.
[GH-10655]
* provisioner/inspec: Add new configuration field `valid_exit_codes` to allow
for non-zero exit codes. [GH-10723]
* provisioner/salt-masterless: Update urls for the bootstrap scripts used by
salt-masterless provide. [GH-10755]
## 1.7.0 (February 17, 2021)
### FEATURES
* **New Command** (HCL only) `packer init` command will download plugins defined
in a new `required_plugins` block [GH-10304] [GH-10633].
* **New Plugin Type** Data sources can be implemented (blog post forthcoming).
[GH-10440]
* **New Plugin** Aws Secrets Manager data source [GH-10505] [GH-10467]
### BACKWARDS INCOMPATIBILITIES
* core: The API that the Packer core uses to communicate with community plugins
has changed; maintainers of community plugins will need to upgrade their
plugins in order to make them compatible with v1.7.0. An upgrade guide will
be available on our guides page https://www.packer.io/guides.
### IMPROVEMENTS
* builder/amazon: Add `skip_create_ami` option for testing and situations where
artifact is not the ami. [GH-10531]
* builder/amazon: Add IMDSv2 support for AWS EBS builder. [GH-10546]
* builder/amazon: Add resource tags in the launch template used to request spot
instances. [GH-10456]
* builder/openstack: Add `skip_create_image` option for testing and situations
where artifact is not the image. [GH-10496]
* builder/oracle-oci: Add retry strategies to oci calls [GH-10591]
* core/fmt: The `packer fmt` can now read from stdin. [GH-10500]
* core/hcl: Add regex and regexall hcl2 template functions. [GH-10601]
* core/hcl: Templates now support "sensitive" locals. [GH-10509]
* core/hcl: Templates now support error-cleanup-provisioner. [GH-10604]
* hcl2_upgrade: Command now comes with a flag so you can control whether output
templates are annotated with helpful comments. [GH-10619]
* hcl2_upgrade: Command now gracefully handles options with template engine
interpolations. [GH-10625]
* hcl2_upgrade: Command will convert amazon filters to use the ami data source.
[GH-10491]
### BUG FIXES
* amazon/ebssurrogate: Apply snapshot tags at same time as when taking
snapshot. [GH-10150]
* builder/amazon: Fix bug where validation fails if optional iops value is
unset. [GH-10518]
* builder/amazon: Wrap API call to get filtered image in a retry. [GH-10610]
* builder/bsusurrogate: override bsu when omi root device is set. [GH-10490]
* builder/google: Fix bug where Packer would fail when run by users who do not
have permission to access the metadata, even though the metadata is not
necessary to the run. [GH-10458]
* builder/profitbricks: Profitbricks builder could not connect using SSH
communicator. [GH-10549]
* builder/proxmox: Ensure ISOs in additional_iso_files are mounted during VM
creation. [GH-10586]
* builder/proxmox: Improve cloud init error logging for proxmox builder.
[GH-10499]
* builder/qemu: Fix bug where vnc_min_port set to value greater then 5900 could
prevent Packer from connecting to QEMU. [GH-10450] [GH-10451]
* builder/qemu: Fix regression with cd indexing when disk_interface is `ide`.
[GH-10519]
* builder/vmware-esx: Skip credential validation, which requires ovftool to be
installed, if we are not exporting an image. [GH-10520]
* builder/yandex: Fix cloud-init config for ubuntu 20.04. [GH-10522]
* builder/yandex: Fix incorrect access to `instance_id`. [GH-10522]
* core/hcl: Fix bug where []uint8 types could not be passed to plugins.
* core/hcl: fix bug where HCL core could not handle passing []uint8 to plugins.
[GH-10516]
* core/hcl: Fix force flag for hcl2 provisioners and post-processors.
[GH-10571]
* post-processor/vsphere: Fix regression where Packer would not check the exit
status after streaming UI from the ovftool command. [GH-10468]
* post-processor/yandex-export: Changed dhclient command and supported
configuring disk for exportupdate-dump-method. Also added support for
`file` builder. [GH-10488]
## 1.6.6 (December 16, 2020)
### FEATURES
* **New command** `fmt` allows users to format existing HCL2 configuration
files into a canonical style. Please see [fmt command
docs](https://packer.io/docs/commands/fmt) for more details. [GH-10225]
[GH-10377]
* **New function** `env` allows users to set the default value of a variable to
the value of an environment variable. Please see [env function
docs](https://www.packer.io/docs/templates/hcl_templates/functions/contextual/env) for
more details. [GH-10240]
* **Future Scaffolding** This release contains a large number of no-op
refactoring changes. The Packer team at HashiCorp is preparing to split the
plugins and core to make it easier for our third party maintainers and
community members to release and maintain plugins, just like HashiCorp did
with the Terraform Core-Provider split. The Packer team is committed to
making sure that this split is seamless for our users and for our community
maintainers -- if you are a community maintainer, you may want to follow
along with some of the work by looking at the
[core-plugin-split github tag.](https://github.com/hashicorp/packer/pulls?q=is%3Apr+label%3Acore-plugin-split)
No one needs to do anything, yet, but we felt it was worth calling out all
the work that isn't making it into the changelog. We will be following up
with lots of documentation and communication in early 2021 with more
information.
### IMPROVEMENTS
* builder/amazon-ebs: Add tags to launch templates. [GH-10203]
* builder/amazon: Add support for Amazon EBS gp3 volumes. [Gh-10338]
* builder/amazon: Increase default max_retries to lessen throttling issues.
[GH-10290]
* builder/amazon: Support AWS gp3 volumes [GH-10338]
* builder/amazon: Support root volume encryption for amazon-chroot. [GH-10243]
* builder/amazon: Validate IOPS ratio. [GH-10199]
* builder/azure-arm: Add Azure CLI authentication support to builder.
[GH-10157]
* builder/azure-arm: Create keyvaults with SoftDelete enabled. [GH-10210]
* builder/digitalocean: New option to provision with private ip. [GH-10093]
* builder/google: Add `wait_to_add_ssh_keys` option to delay the addition of
SSH configuration that may be disrupted during an instance boot sequence.
[GH-10320]
* builder/google: Add support for creating shielded VMs. [GH-10172]
* builder/googlecompute-export: Add logging.write to service account scopes.
[GH-10316]
* builder/oracle-oci: Support image launch mode. [GH-10212]
* builder/outscale: Add outscale.hk endpoint support [GH-10207]
* builder/outscale: Add x509 certificate support. [GH-10161]
* builder/proxmox: New config option for boot-order. [GH-10260]
* builder/scaleway: Use the SDK functions to load profile from file and env.
[GH-10181]
* builder/virtualbox: Allow attaching guest additions with "none" communicator.
[GH-10306]
* builder/vmware: Make compatible with MacOS BigSur by using Apple DHCP leases
instead of VMWare leases [GH-10384]
* builder/vsphere: New option to add additional storage to a cloned vm.
[GH-10287]
* builder/yandex: More resilient image mounting and initialization. [GH-10335]
* builder/yandex: Update user-data to not use cloud-config fields to prevent
possible user data collisions. [GH-10385]
* core/hcl: Update to `hcl2_upgrade` command to support complex variable values
and packer version blocks. [GH-10221]
* hcl2upgrade: Update command to fix `env` call upgrade. [GH-10244]
* post-processor/vagrant-cloud: Add support for uploading directly to storage
on Vagrant Cloud. [GH-10193]
* post-processor/yandex-export: Add retries and wait after disk attach
operation. [GH-10303]
* post-processor/yandex-export: Show progress on export. [GH-10368]
* post-processor/yandex-export: Use ssh communicator in export. [GH-10352]
* post-processor/yandex-export: Verify the access to a specific bucket.
[GH-10188]
* provisioner/salt-masterless: Call winrepo.update_git_repos and
pkg.refresh_db. [GH-10201]
### BUG FIXES
* builder/amazon: Fix retry logic in AWS spot instance tagging. [GH-10394]
* builder/amazon: Fix single `tag` interpolation to allow for templating engine
usage. [GH-10224]
* builder/google: Fix crash when using the `-on-error` build flag. [GH-10247]
* builder/google: Fix issue with service account detection when running Packer
on a compute instance with `use_os_login` enabled. [GH-10360]
* builder/qemu: Fix duplication of main disk when setting "disk_image: true".
[GH-10337]
* builder/qemu: Fix nil pointer dereference when loading values from state.
[GH-10249]
* builder/qemu: Fix panic when disk_image=true and source image has no file
extension. [GH-10226]
* builder/vagrant: Return error if ssh-config command fails. [GH-10213]
* builder/vsphere: WaitForIP should not return an error if an IP is not found
[GH-10321]
* builder/yandex: Change disk creation method to manual. [GH-10250]
* builder/yandex: Fix issue with UserAgent string. [GH-10361]
* builder/yandex: Fixed using cloud config when using IPv6. [GH-10297]
* core/hcl: Ensure the `reverse` function does not break when given a value of
type list. [GH-10380]
* post-processor/yandex-export: Check service account id. [GH-10305]
## 1.6.5 (October 30, 2020)
### FEATURES:
* New Builder(s): Proxmox builder has been split into two new builders
`proxmox-iso` and `promox-clone`. See [Proxmox
Builder](https://packer.io/docs/builders/proxmox) for more information on
the builder. For users of the previous `proxmox` builder please use `packer
fix` to migrate your templates to the new `promox-iso` builder. [GH-9262]
### BUG FIXES:
* builder/amazon: SSM connection now recovers from reboots. [GH-10003]
* builder/azure-arm: Fix build failures due to the deletion of additional
managed disks defined in "disk_additional_size". [GH-10163]
* builder/azure-chroot: Fix typo in option `exlude_from_latest` to
`exclude_from_latest`. Old name will still be respected. [GH-10034]
* builder/googlecompute: Fix HCL image_encryption_key fields and use the same
casing in JSON and HCL2 [GH-10173]
* builder/openstack: Fix source image validation regression when using filters.
[GH-10065]
* builder/proxmox: Fix unhandled buildvar type for HCL2 enabled build
templates. [GH-10154]
* builder/qemu: Fix a regression where Packer would not wait properly in
step_shutdown when a null communicator was used. [GH-10178]
* builder/qemu: Fix crash in step_run of qemu when loading commhostport form
the statebag in a situation where the communicator is none. [GH-10145]
* builder/vsphere-clone: Packer was not respecting the "destroy" flag set in
the content library config, and always keeping the source vm. This has been
fixed. [GH-10165]
* builder/vsphere: Ensure builds are able to continue when no communicator has
been specified `"communicator": "none"`. [GH-9964]
* builder/vsphere: Fix CD uploads so that Packer does not try to delete a CD
that was not successfully uploaded. [GH-10155]
* core/hcl: Hide sensitive variables from output. [GH-10031]
* core/hcl: Packer HCL's "Coalesce" function now behaves same way as
Terraform's. [GH-10016]
* core: Fix artifact handling so that input artifacts are properly preserved in
postprocessors that don't modify artifacts. [GH-9996]
* core: Fix pathing in cd_files to copy proper directory tree when user
provided absolute paths. [GH-10022]
* provisioner/ansible: Ansible galaxy no longer forces use of collections in v1
files. [GH-10010]
### IMPROVEMENTS:
* builder/amazon-ebssurrogate: Apply snapshot tags at snapshot creation time.
[GH-10150]
* builder/amazon: Add `io2` as a supported volume type. [GH-10102]
* builder/amazon: Add support for source instance tenancy [GH-10085]
* builder/google: Add service account impersonation. [GH-9968] [GH-10054]
* builder/googlecompute: Add `skip_create_image` option. [GH-10115]
* builder/googlecompute: Allow users to select the algorithm to use when
generating temporary SSH keypair [GH-10111]
* builder/linode: Add `state_timeout` attribute to Linode builder. [GH-10128]
* builder/oracle-oci: New option to specify image compartment separate from
build compartment. [GH-10040]
* builder/oracle-oci: New option to specify boot volume size. [GH-10017]
* builder/oracle: Add `base_image_filter` option as alternative to
`base_image_ocid` [GH-10116]
* builder/outscale: Migrate to new Outscale SDK. [GH-10056]
* builder/proxmox: split Proxmox into proxmox-iso and proxmox-clone. [GH-9626]
[GH-10166]
* builder/scaleway: Allow the user to use an image label (eg ubuntu_focal)
instead of a hardcoded UUID on the Scaleway builder. [GH-10061]
* builder/vsphere: Skip iso download if hashed file is already present on
remote datastore. [GH-10143]
* builder/yandex: Add support for IAM credentials in the token field and
YC_TOKEN environment variable. [GH-10158]
* core/hcl: Add ability to set version restrictions [GH-10149]
* core/hcl: Add build.name variable so users can access build name in addition
to source name. [GH-10114]
* core/hcl: Add consul_key function to HCL templates. [GH-10119]
* core/hcl: Add HCL2 aws_secretsmanager function [GH-10124]
* core/hcl: Add packer.version variable to hcl configs so users can access the
Packer release version. [GH-10117]
* core: Let user provide type of generated ssh key instead of always doing ssh-
rsa [GH-10101]
## 1.6.4 (September 30, 2020)
### BUG FIXES:

View File

@ -13,15 +13,12 @@
/builder/digitalocean/ @andrewsomething
/website/pages/docs/builders/digitalocean* @andrewsomething
/builder/hyperv/ @taliesins
/website/pages/docs/builders/hyperv* @taliesins
/examples/jdcloud/ @XiaohanLiang @remrain
/builder/jdcloud/ @XiaohanLiang @remrain
/website/pages/docs/builders/jdcloud* @XiaohanLiang @remrain
/builder/linode/ @displague @ctreatma @stvnjacobs @charliekenney23 @phillc
/website/pages/docs/builders/linode* @displague @ctreatma @stvnjacobs @charliekenney23 @phillc
/builder/linode/ @stvnjacobs @charliekenney23 @phillc
/website/pages/docs/builders/linode* @stvnjacobs @charliekenney23 @phillc
/builder/lxc/ @ChrisLundquist
/website/pages/docs/builders/lxc* @ChrisLundquist
@ -37,15 +34,12 @@
/builder/oracle/ @prydie @owainlewis
/website/pages/docs/builders/oracle* @prydie @owainlewis
/builder/profitbricks/ @jasmingacic
/website/pages/docs/builders/profitbricks* @jasmingacic
/builder/profitbricks/ @LiviusP @mflorin
/website/pages/docs/builders/profitbricks* @LiviusP @mflorin
/builder/triton/ @sean-
/website/pages/docs/builders/triton* @sean-
/builder/ncloud/ @YuSungDuk
/website/pages/docs/builders/ncloud* @YuSungDuk
/builder/proxmox/ @carlpett
/website/pages/docs/builders/proxmox* @carlpett
@ -55,28 +49,13 @@
/builder/hcloud/ @LKaemmerling
/website/pages/docs/builders/hcloud* @LKaemmerling
/examples/hyperone/ @m110 @gregorybrzeski @ad-m
/builder/hyperone/ @m110 @gregorybrzeski @ad-m
/website/pages/docs/builders/hyperone* @m110 @gregorybrzeski @ad-m
/test/builder_hyperone* @m110 @gregorybrzeski @ad-m
/test/fixtures/builder-hyperone/ @m110 @gregorybrzeski @ad-m
/examples/ucloud/ @shawnmssu
/builder/ucloud/ @shawnmssu
/website/pages/docs/builders/ucloud* @shawnmssu
/builder/yandex/ @GennadySpb @alexanderKhaustov @seukyaso
/website/pages/docs/builders/yandex* @GennadySpb @alexanderKhaustov @seukyaso
/builder/osc/ @marinsalinas @Hakujou
/website/pages/docs/builders/osc* @marinsalinas @Hakujou
/examples/tencentcloud/ @likexian
/builder/tencentcloud/ @likexian
/website/pages/docs/builders/tencentcloud* @likexian
# provisioners
/examples/ansible/ @bhcleek
@ -87,9 +66,7 @@
/post-processor/alicloud-import/ dongxiao.zzh@alibaba-inc.com
/post-processor/checksum/ v.tolstov@selfip.ru
/post-processor/exoscale-import/ @falzm @mcorbin
/post-processor/googlecompute-export/ crunkleton@google.com
/post-processor/yandex-export/ @GennadySpb
/post-processor/yandex-import/ @GennadySpb
/post-processor/vsphere-template/ nelson@bennu.cl
/post-processor/ucloud-import/ @shawnmssu

View File

@ -1,4 +1,4 @@
FROM ubuntu:16.04
FROM docker.mirror.hashicorp.services/ubuntu:16.04
ENV DEBIAN_FRONTEND noninteractive

View File

@ -1,5 +1,7 @@
TEST?=$(shell go list ./...)
COUNT?=1
VET?=$(shell go list ./...)
ACC_TEST_BUILDERS?=all
ACC_TEST_PROVISIONERS?=all
# Get the current full sha from git
@ -47,7 +49,7 @@ package:
@sh -c "$(CURDIR)/scripts/dist.sh $(VERSION)"
install-build-deps: ## Install dependencies for bin build
@go get github.com/mitchellh/gox
@go install github.com/mitchellh/gox@v1.0.1
install-gen-deps: ## Install dependencies for code generation
# to avoid having to tidy our go deps, we `go get` our binaries from a temp
@ -55,10 +57,8 @@ install-gen-deps: ## Install dependencies for code generation
# out code dependencies; so a go mod tidy will remove them again. `go
# install` seems to install the last tagged version and we want to install
# master.
@(cd $(TEMPDIR) && GO111MODULE=on go get github.com/mna/pigeon@master)
@(cd $(TEMPDIR) && GO111MODULE=on go get github.com/alvaroloes/enumer@master)
@go install ./cmd/struct-markdown
@go install ./cmd/mapstructure-to-hcl2
@go install github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc@latest
install-lint-deps: ## Install linter dependencies
# Pinning golangci-lint at v1.23.8 as --new-from-rev seems to work properly; the latest 1.24.0 has caused issues with memory consumption
@ -119,13 +119,11 @@ fmt-examples:
# generate runs `go generate` to build the dynamically generated
# source files.
generate: install-gen-deps ## Generate dynamically generated code
@echo "==> removing autogenerated markdown..."
@find website/pages/ -type f | xargs grep -l '^<!-- Code generated' | xargs rm -f
@echo "==> removing autogenerated markdown..." # but don't remove partials generated in the SDK and copied over.
@find website/pages -path website/pages/partials/packer-plugin-sdk -prune -o -type f | xargs grep -l '^<!-- Code generated' | xargs rm -f
@echo "==> removing autogenerated code..."
@find post-processor common helper template builder provisioner -type f | xargs grep -l '^// Code generated' | xargs rm -f
go generate ./...
go fmt common/bootcommand/boot_command.go
go run ./cmd/generate-fixer-deprecations
@find post-processor helper builder provisioner -type f | xargs grep -l '^// Code generated' | xargs rm -f
PROJECT_ROOT="$(shell pwd)" go generate $(shell go list ./... | grep -v packer-plugin-sdk)
generate-check: generate ## Check go code generation is on par
@echo "==> Checking that auto-generated code is not changed..."
@ -136,33 +134,26 @@ generate-check: generate ## Check go code generation is on par
fi
test: mode-check vet ## Run unit tests
@go test $(TEST) $(TESTARGS) -timeout=3m
@go test -count $(COUNT) $(TEST) $(TESTARGS) -timeout=3m
# acctest runs provisioners acceptance tests
provisioners-acctest: install-build-deps generate
ACC_TEST_BUILDERS=$(ACC_TEST_BUILDERS) ACC_TEST_PROVISIONERS=$(ACC_TEST_PROVISIONERS) go test ./provisioner/... -timeout=1h
provisioners-acctest: #install-build-deps generate
ACC_TEST_BUILDERS=$(ACC_TEST_BUILDERS) go test $(TEST) $(TESTARGS) -timeout=1h
# testacc runs acceptance tests
testacc: install-build-deps generate ## Run acceptance tests
testacc: # install-build-deps generate ## Run acceptance tests
@echo "WARN: Acceptance tests will take a long time to run and may cost money. Ctrl-C if you want to cancel."
PACKER_ACC=1 go test -v $(TEST) $(TESTARGS) -timeout=45m
PACKER_ACC=1 go test -count $(COUNT) -v $(TEST) $(TESTARGS) -timeout=120m
testrace: mode-check vet ## Test with race detection enabled
@GO111MODULE=off go test -race $(TEST) $(TESTARGS) -timeout=3m -p=8
@go test -count $(COUNT) -race $(TEST) $(TESTARGS) -timeout=3m -p=8
# Runs code coverage and open a html page with report
cover:
go test $(TEST) $(TESTARGS) -timeout=3m -coverprofile=coverage.out
go test -count $(COUNT) $(TEST) $(TESTARGS) -timeout=3m -coverprofile=coverage.out
go tool cover -html=coverage.out
rm coverage.out
check-vendor-vs-mod: ## Check that go modules and vendored code are on par
@GO111MODULE=on go mod vendor
@git diff --exit-code --ignore-space-change --ignore-space-at-eol -- vendor ; if [ $$? -eq 1 ]; then \
echo "ERROR: vendor dir is not on par with go modules definition." && \
exit 1; \
fi
vet: ## Vet Go code
@go vet $(VET) ; if [ $$? -eq 1 ]; then \
echo "ERROR: Vet found problems in the code."; \

View File

@ -1,23 +1,23 @@
# Packer
[![Build Status][circleci-badge]][circleci]
[![Windows Build Status][appveyor-badge]][appveyor]
[![Discuss](https://img.shields.io/badge/discuss-packer-3d89ff?style=flat)](https://discuss.hashicorp.com/c/packer)
[![PkgGoDev](https://pkg.go.dev/badge/github.com/hashicorp/packer)](https://pkg.go.dev/github.com/hashicorp/packer)
[![GoReportCard][report-badge]][report]
[![codecov](https://codecov.io/gh/hashicorp/packer/branch/master/graph/badge.svg)](https://codecov.io/gh/hashicorp/packer)
[circleci-badge]: https://circleci.com/gh/hashicorp/packer.svg?style=svg
[circleci]: https://app.circleci.com/pipelines/github/hashicorp/packer
[appveyor-badge]: https://ci.appveyor.com/api/projects/status/miavlgnp989e5obc/branch/master?svg=true
[appveyor]: https://ci.appveyor.com/project/hashicorp/packer
[godoc-badge]: https://godoc.org/github.com/hashicorp/packer?status.svg
[godoc]: https://godoc.org/github.com/hashicorp/packer
[report-badge]: https://goreportcard.com/badge/github.com/hashicorp/packer
[report]: https://goreportcard.com/report/github.com/hashicorp/packer
* Website: https://www.packer.io
* IRC: `#packer-tool` on Freenode
* Mailing list: [Google Groups](https://groups.google.com/forum/#!forum/packer-tool)
<p align="center" style="text-align:center;">
<a href="https://www.packer.io">
<img alt="HashiCorp Packer logo" src="website/public/img/logo-packer-padded.svg" width="500" />
</a>
</p>
Packer is a tool for building identical machine images for multiple platforms
from a single source configuration.
@ -25,7 +25,7 @@ from a single source configuration.
Packer is lightweight, runs on every major operating system, and is highly
performant, creating machine images for multiple platforms in parallel. Packer
comes out of the box with support for many platforms, the full list of which can
be found at https://www.packer.io/docs/builders/index.html.
be found at https://www.packer.io/docs/builders.
Support for other platforms can be added via plugins.
@ -47,33 +47,43 @@ yourself](https://github.com/hashicorp/packer/blob/master/.github/CONTRIBUTING.m
After Packer is installed, create your first template, which tells Packer
what platforms to build images for and how you want to build them. In our
case, we'll create a simple AMI that has Redis pre-installed. Save this
file as `quick-start.json`. Export your AWS credentials as the
case, we'll create a simple AMI that has Redis pre-installed.
Save this file as `quick-start.pkr.hcl`. Export your AWS credentials as the
`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables.
```json
{
"variables": {
"access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
"secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}"
},
"builders": [{
"type": "amazon-ebs",
"access_key": "{{user `access_key`}}",
"secret_key": "{{user `secret_key`}}",
"region": "us-east-1",
"source_ami": "ami-af22d9b9",
"instance_type": "t2.micro",
"ssh_username": "ubuntu",
"ami_name": "packer-example {{timestamp}}"
}]
```hcl
variable "access_key" {
type = string
default = "${env("AWS_ACCESS_KEY_ID")}"
}
variable "secret_key" {
type = string
default = "${env("AWS_SECRET_ACCESS_KEY")}"
}
locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }
source "amazon-ebs" "quick-start" {
access_key = "${var.access_key}"
ami_name = "packer-example ${local.timestamp}"
instance_type = "t2.micro"
region = "us-east-1"
secret_key = "${var.secret_key}"
source_ami = "ami-af22d9b9"
ssh_username = "ubuntu"
}
build {
sources = ["source.amazon-ebs.quick-start"]
}
```
Next, tell Packer to build the image:
```
$ packer build quick-start.json
$ packer build quick-start.pkr.hcl
...
```
@ -85,11 +95,9 @@ they're run, etc., is up to you.
## Documentation
Comprehensive documentation is viewable on the Packer website:
Comprehensive documentation is viewable on the Packer website at https://www.packer.io/docs.
https://www.packer.io/docs
## Developing Packer
## Contributing to Packer
See
[CONTRIBUTING.md](https://github.com/hashicorp/packer/blob/master/.github/CONTRIBUTING.md)

View File

@ -0,0 +1,71 @@
// component_acc_test.go should contain acceptance tests for plugin components
// to make sure all component types can be discovered and started.
package plugin
import (
_ "embed"
"fmt"
"io/ioutil"
"os"
"os/exec"
"testing"
amazonacc "github.com/hashicorp/packer-plugin-amazon/builder/ebs/acceptance"
"github.com/hashicorp/packer-plugin-sdk/acctest"
"github.com/hashicorp/packer/hcl2template/addrs"
)
//go:embed test-fixtures/basic-amazon-ami-datasource.pkr.hcl
var basicAmazonAmiDatasourceHCL2Template string
func TestAccInitAndBuildBasicAmazonAmiDatasource(t *testing.T) {
plugin := addrs.Plugin{
Hostname: "github.com",
Namespace: "hashicorp",
Type: "amazon",
}
testCase := &acctest.PluginTestCase{
Name: "amazon-ami_basic_datasource_test",
Setup: func() error {
return cleanupPluginInstallation(plugin)
},
Teardown: func() error {
helper := amazonacc.AWSHelper{
Region: "us-west-2",
AMIName: "packer-amazon-ami-test",
}
return helper.CleanUpAmi()
},
Template: basicAmazonAmiDatasourceHCL2Template,
Type: "amazon-ami",
Init: true,
CheckInit: func(initCommand *exec.Cmd, logfile string) error {
if initCommand.ProcessState != nil {
if initCommand.ProcessState.ExitCode() != 0 {
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
}
}
logs, err := os.Open(logfile)
if err != nil {
return fmt.Errorf("Unable find %s", logfile)
}
defer logs.Close()
logsBytes, err := ioutil.ReadAll(logs)
if err != nil {
return fmt.Errorf("Unable to read %s", logfile)
}
initOutput := string(logsBytes)
return checkPluginInstallation(initOutput, plugin)
},
Check: func(buildCommand *exec.Cmd, logfile string) error {
if buildCommand.ProcessState != nil {
if buildCommand.ProcessState.ExitCode() != 0 {
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
}
}
return nil
},
}
acctest.TestPlugin(t, testCase)
}

View File

@ -0,0 +1,112 @@
// plugin_acc_test.go should contain acceptance tests for features related to
// installing, discovering and running plugins.
package plugin
import (
_ "embed"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"regexp"
"testing"
amazonacc "github.com/hashicorp/packer-plugin-amazon/builder/ebs/acceptance"
"github.com/hashicorp/packer-plugin-sdk/acctest"
"github.com/hashicorp/packer-plugin-sdk/acctest/testutils"
"github.com/hashicorp/packer/hcl2template/addrs"
"github.com/mitchellh/go-homedir"
)
//go:embed test-fixtures/basic-amazon-ebs.pkr.hcl
var basicAmazonEbsHCL2Template string
func TestAccInitAndBuildBasicAmazonEbs(t *testing.T) {
plugin := addrs.Plugin{
Hostname: "github.com",
Namespace: "hashicorp",
Type: "amazon",
}
testCase := &acctest.PluginTestCase{
Name: "amazon-ebs_basic_plugin_init_and_build_test",
Setup: func() error {
return cleanupPluginInstallation(plugin)
},
Teardown: func() error {
helper := amazonacc.AWSHelper{
Region: "us-east-1",
AMIName: "packer-plugin-amazon-ebs-test",
}
return helper.CleanUpAmi()
},
Template: basicAmazonEbsHCL2Template,
Type: "amazon-ebs",
Init: true,
CheckInit: func(initCommand *exec.Cmd, logfile string) error {
if initCommand.ProcessState != nil {
if initCommand.ProcessState.ExitCode() != 0 {
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
}
}
logs, err := os.Open(logfile)
if err != nil {
return fmt.Errorf("Unable find %s", logfile)
}
defer logs.Close()
logsBytes, err := ioutil.ReadAll(logs)
if err != nil {
return fmt.Errorf("Unable to read %s", logfile)
}
initOutput := string(logsBytes)
return checkPluginInstallation(initOutput, plugin)
},
Check: func(buildCommand *exec.Cmd, logfile string) error {
if buildCommand.ProcessState != nil {
if buildCommand.ProcessState.ExitCode() != 0 {
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
}
}
return nil
},
}
acctest.TestPlugin(t, testCase)
}
func cleanupPluginInstallation(plugin addrs.Plugin) error {
home, err := homedir.Dir()
if err != nil {
return err
}
pluginPath := filepath.Join(home,
".packer.d",
"plugins",
plugin.Hostname,
plugin.Namespace,
plugin.Type)
testutils.CleanupFiles(pluginPath)
return nil
}
func checkPluginInstallation(initOutput string, plugin addrs.Plugin) error {
expectedInitLog := "Installed plugin " + plugin.String()
if matched, _ := regexp.MatchString(expectedInitLog+".*", initOutput); !matched {
return fmt.Errorf("logs doesn't contain expected foo value %q", initOutput)
}
home, err := homedir.Dir()
if err != nil {
return err
}
pluginPath := filepath.Join(home,
".packer.d",
"plugins",
plugin.Hostname,
plugin.Namespace,
plugin.Type)
if !testutils.FileExists(pluginPath) {
return fmt.Errorf("%s plugin installation not found", plugin.String())
}
return nil
}

View File

@ -0,0 +1,33 @@
packer {
required_plugins {
amazon = {
version = ">= 0.0.1"
source = "github.com/hashicorp/amazon"
}
}
}
data "amazon-ami" "test" {
filters = {
name = "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true
owners = ["099720109477"]
}
source "amazon-ebs" "basic-example" {
region = "us-west-2"
source_ami = data.amazon-ami.test.id
ami_name = "packer-amazon-ami-test"
communicator = "ssh"
instance_type = "t2.micro"
ssh_username = "ubuntu"
}
build {
sources = [
"source.amazon-ebs.basic-example"
]
}

View File

@ -0,0 +1,20 @@
packer {
required_plugins {
amazon = {
version = ">= 0.0.1"
source = "github.com/hashicorp/amazon"
}
}
}
source "amazon-ebs" "basic-test" {
region = "us-east-1"
instance_type = "m3.medium"
source_ami = "ami-76b2a71e"
ssh_username = "ubuntu"
ami_name = "packer-plugin-amazon-ebs-test"
}
build {
sources = ["source.amazon-ebs.basic-test"]
}

224
acctest/testing.go Normal file
View File

@ -0,0 +1,224 @@
package acctest
import (
"context"
"fmt"
"io/ioutil"
"log"
"os"
"strings"
"testing"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
"github.com/hashicorp/packer-plugin-sdk/template"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/provisioner/file"
shellprovisioner "github.com/hashicorp/packer/provisioner/shell"
)
// TestEnvVar must be set to a non-empty value for acceptance tests to run.
const TestEnvVar = "PACKER_ACC"
// TestCase is a single set of tests to run for a backend. A TestCase
// should generally map 1:1 to each test method for your acceptance
// tests.
type TestCase struct {
// Precheck, if non-nil, will be called once before the test case
// runs at all. This can be used for some validation prior to the
// test running.
PreCheck func()
// Builder is the Builder that will be tested. It will be available
// as the "test" builder in the template.
Builder packersdk.Builder
// Template is the template contents to use.
Template string
// Check is called after this step is executed in order to test that
// the step executed successfully. If this is not set, then the next
// step will be called
Check TestCheckFunc
// Teardown will be called before the test case is over regardless
// of if the test succeeded or failed. This should return an error
// in the case that the test can't guarantee all resources were
// properly cleaned up.
Teardown TestTeardownFunc
// If SkipArtifactTeardown is true, we will not attempt to destroy the
// artifact created in this test run.
SkipArtifactTeardown bool
// If set, overrides the default provisioner store with custom provisioners.
// This can be useful for running acceptance tests for a particular
// provisioner using a specific builder.
// Default provisioner store:
// ProvisionerStore: packersdk.MapOfProvisioner{
// "shell": func() (packersdk.Provisioner, error) { return &shellprovisioner.Provisioner{}, nil },
// "file": func() (packersdk.Provisioner, error) { return &file.Provisioner{}, nil },
// },
ProvisionerStore packersdk.MapOfProvisioner
}
// TestCheckFunc is the callback used for Check in TestStep.
type TestCheckFunc func([]packersdk.Artifact) error
// TestTeardownFunc is the callback used for Teardown in TestCase.
type TestTeardownFunc func() error
// TestT is the interface used to handle the test lifecycle of a test.
//
// Users should just use a *testing.T object, which implements this.
type TestT interface {
Error(args ...interface{})
Fatal(args ...interface{})
Skip(args ...interface{})
}
type TestBuilderSet struct {
packer.BuilderSet
StartFn func(name string) (packersdk.Builder, error)
}
func (tbs TestBuilderSet) Start(name string) (packersdk.Builder, error) { return tbs.StartFn(name) }
// Test performs an acceptance test on a backend with the given test case.
//
// Tests are not run unless an environmental variable "PACKER_ACC" is
// set to some non-empty value. This is to avoid test cases surprising
// a user by creating real resources.
//
// Tests will fail unless the verbose flag (`go test -v`, or explicitly
// the "-test.v" flag) is set. Because some acceptance tests take quite
// long, we require the verbose flag so users are able to see progress
// output.
func Test(t TestT, c TestCase) {
// We only run acceptance tests if an env var is set because they're
// slow and generally require some outside configuration.
if os.Getenv(TestEnvVar) == "" {
t.Skip(fmt.Sprintf(
"Acceptance tests skipped unless env '%s' set",
TestEnvVar))
return
}
// We require verbose mode so that the user knows what is going on.
if !testTesting && !testing.Verbose() {
t.Fatal("Acceptance tests must be run with the -v flag on tests")
return
}
// Run the PreCheck if we have it
if c.PreCheck != nil {
c.PreCheck()
}
// Parse the template
log.Printf("[DEBUG] Parsing template...")
tpl, err := template.Parse(strings.NewReader(c.Template))
if err != nil {
t.Fatal(fmt.Sprintf("Failed to parse template: %s", err))
return
}
if c.ProvisionerStore == nil {
c.ProvisionerStore = packersdk.MapOfProvisioner{
"shell": func() (packersdk.Provisioner, error) { return &shellprovisioner.Provisioner{}, nil },
"file": func() (packersdk.Provisioner, error) { return &file.Provisioner{}, nil },
}
}
// Build the core
log.Printf("[DEBUG] Initializing core...")
core := packer.NewCore(&packer.CoreConfig{
Components: packer.ComponentFinder{
PluginConfig: &packer.PluginConfig{
Builders: TestBuilderSet{
StartFn: func(n string) (packersdk.Builder, error) {
if n == "test" {
return c.Builder, nil
}
return nil, nil
},
},
Provisioners: c.ProvisionerStore,
},
},
Template: tpl,
})
err = core.Initialize()
if err != nil {
t.Fatal(fmt.Sprintf("Failed to init core: %s", err))
return
}
// Get the build
log.Printf("[DEBUG] Retrieving 'test' build")
build, err := core.Build("test")
if err != nil {
t.Fatal(fmt.Sprintf("Failed to get 'test' build: %s", err))
return
}
// Prepare it
log.Printf("[DEBUG] Preparing 'test' build")
warnings, err := build.Prepare()
if err != nil {
t.Fatal(fmt.Sprintf("Prepare error: %s", err))
return
}
if len(warnings) > 0 {
t.Fatal(fmt.Sprintf(
"Prepare warnings:\n\n%s",
strings.Join(warnings, "\n")))
return
}
// Run it! We use a temporary directory for caching and discard
// any UI output. We discard since it shows up in logs anyways.
log.Printf("[DEBUG] Running 'test' build")
ui := &packersdk.BasicUi{
Reader: os.Stdin,
Writer: ioutil.Discard,
ErrorWriter: ioutil.Discard,
PB: &packersdk.NoopProgressTracker{},
}
artifacts, err := build.Run(context.Background(), ui)
if err != nil {
t.Fatal(fmt.Sprintf("Run error:\n\n%s", err))
goto TEARDOWN
}
// Check function
if c.Check != nil {
log.Printf("[DEBUG] Running check function")
if err := c.Check(artifacts); err != nil {
t.Fatal(fmt.Sprintf("Check error:\n\n%s", err))
goto TEARDOWN
}
}
TEARDOWN:
if !c.SkipArtifactTeardown {
// Delete all artifacts
for _, a := range artifacts {
if err := a.Destroy(); err != nil {
t.Error(fmt.Sprintf(
"!!! ERROR REMOVING ARTIFACT '%s': %s !!!",
a.String(), err))
}
}
}
// Teardown
if c.Teardown != nil {
log.Printf("[DEBUG] Running teardown function")
if err := c.Teardown(); err != nil {
t.Fatal(fmt.Sprintf("Teardown failure:\n\n%s", err))
return
}
}
}
// This is for unit tests of this package.
var testTesting = false

View File

@ -1,4 +1,4 @@
package testing
package acctest
import (
"os"

View File

@ -1,226 +0,0 @@
//go:generate struct-markdown
package ecs
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"runtime"
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/template/interpolate"
"github.com/hashicorp/packer/version"
"github.com/mitchellh/go-homedir"
)
// Config of alicloud
type AlicloudAccessConfig struct {
// Alicloud access key must be provided unless `profile` is set, but it can
// also be sourced from the `ALICLOUD_ACCESS_KEY` environment variable.
AlicloudAccessKey string `mapstructure:"access_key" required:"true"`
// Alicloud secret key must be provided unless `profile` is set, but it can
// also be sourced from the `ALICLOUD_SECRET_KEY` environment variable.
AlicloudSecretKey string `mapstructure:"secret_key" required:"true"`
// Alicloud region must be provided unless `profile` is set, but it can
// also be sourced from the `ALICLOUD_REGION` environment variable.
AlicloudRegion string `mapstructure:"region" required:"true"`
// The region validation can be skipped if this value is true, the default
// value is false.
AlicloudSkipValidation bool `mapstructure:"skip_region_validation" required:"false"`
// The image validation can be skipped if this value is true, the default
// value is false.
AlicloudSkipImageValidation bool `mapstructure:"skip_image_validation" required:"false"`
// Alicloud profile must be set unless `access_key` is set; it can also be
// sourced from the `ALICLOUD_PROFILE` environment variable.
AlicloudProfile string `mapstructure:"profile" required:"false"`
// Alicloud shared credentials file path. If this file exists, access and
// secret keys will be read from this file.
AlicloudSharedCredentialsFile string `mapstructure:"shared_credentials_file" required:"false"`
// STS access token, can be set through template or by exporting as
// environment variable such as `export SECURITY_TOKEN=value`.
SecurityToken string `mapstructure:"security_token" required:"false"`
client *ClientWrapper
}
const Packer = "HashiCorp-Packer"
const DefaultRequestReadTimeout = 10 * time.Second
// Client for AlicloudClient
func (c *AlicloudAccessConfig) Client() (*ClientWrapper, error) {
if c.client != nil {
return c.client, nil
}
if c.SecurityToken == "" {
c.SecurityToken = os.Getenv("SECURITY_TOKEN")
}
var getProviderConfig = func(str string, key string) string {
value, err := getConfigFromProfile(c, key)
if err == nil && value != nil {
str = value.(string)
}
return str
}
if c.AlicloudAccessKey == "" || c.AlicloudSecretKey == "" {
c.AlicloudAccessKey = getProviderConfig(c.AlicloudAccessKey, "access_key_id")
c.AlicloudSecretKey = getProviderConfig(c.AlicloudSecretKey, "access_key_secret")
c.AlicloudRegion = getProviderConfig(c.AlicloudRegion, "region_id")
c.SecurityToken = getProviderConfig(c.SecurityToken, "sts_token")
}
client, err := ecs.NewClientWithStsToken(c.AlicloudRegion, c.AlicloudAccessKey, c.AlicloudSecretKey, c.SecurityToken)
if err != nil {
return nil, err
}
client.AppendUserAgent(Packer, version.FormattedVersion())
client.SetReadTimeout(DefaultRequestReadTimeout)
c.client = &ClientWrapper{client}
return c.client, nil
}
func (c *AlicloudAccessConfig) Prepare(ctx *interpolate.Context) []error {
var errs []error
if err := c.Config(); err != nil {
errs = append(errs, err)
}
if c.AlicloudRegion == "" {
c.AlicloudRegion = os.Getenv("ALICLOUD_REGION")
}
if c.AlicloudRegion == "" {
errs = append(errs, fmt.Errorf("region option or ALICLOUD_REGION must be provided in template file or environment variables."))
}
if len(errs) > 0 {
return errs
}
return nil
}
func (c *AlicloudAccessConfig) Config() error {
if c.AlicloudAccessKey == "" {
c.AlicloudAccessKey = os.Getenv("ALICLOUD_ACCESS_KEY")
}
if c.AlicloudSecretKey == "" {
c.AlicloudSecretKey = os.Getenv("ALICLOUD_SECRET_KEY")
}
if c.AlicloudProfile == "" {
c.AlicloudProfile = os.Getenv("ALICLOUD_PROFILE")
}
if c.AlicloudSharedCredentialsFile == "" {
c.AlicloudSharedCredentialsFile = os.Getenv("ALICLOUD_SHARED_CREDENTIALS_FILE")
}
if (c.AlicloudAccessKey == "" || c.AlicloudSecretKey == "") && c.AlicloudProfile == "" {
return fmt.Errorf("ALICLOUD_ACCESS_KEY and ALICLOUD_SECRET_KEY must be set in template file or environment variables.")
}
return nil
}
func (c *AlicloudAccessConfig) ValidateRegion(region string) error {
supportedRegions, err := c.getSupportedRegions()
if err != nil {
return err
}
for _, supportedRegion := range supportedRegions {
if region == supportedRegion {
return nil
}
}
return fmt.Errorf("Not a valid alicloud region: %s", region)
}
func (c *AlicloudAccessConfig) getSupportedRegions() ([]string, error) {
client, err := c.Client()
if err != nil {
return nil, err
}
regionsRequest := ecs.CreateDescribeRegionsRequest()
regionsResponse, err := client.DescribeRegions(regionsRequest)
if err != nil {
return nil, err
}
validRegions := make([]string, len(regionsResponse.Regions.Region))
for _, valid := range regionsResponse.Regions.Region {
validRegions = append(validRegions, valid.RegionId)
}
return validRegions, nil
}
func getConfigFromProfile(c *AlicloudAccessConfig, ProfileKey string) (interface{}, error) {
providerConfig := make(map[string]interface{})
current := c.AlicloudProfile
if current != "" {
profilePath, err := homedir.Expand(c.AlicloudSharedCredentialsFile)
if err != nil {
return nil, err
}
if profilePath == "" {
profilePath = fmt.Sprintf("%s/.aliyun/config.json", os.Getenv("HOME"))
if runtime.GOOS == "windows" {
profilePath = fmt.Sprintf("%s/.aliyun/config.json", os.Getenv("USERPROFILE"))
}
}
_, err = os.Stat(profilePath)
if !os.IsNotExist(err) {
data, err := ioutil.ReadFile(profilePath)
if err != nil {
return nil, err
}
config := map[string]interface{}{}
err = json.Unmarshal(data, &config)
if err != nil {
return nil, err
}
for _, v := range config["profiles"].([]interface{}) {
if current == v.(map[string]interface{})["name"] {
providerConfig = v.(map[string]interface{})
}
}
}
}
mode := ""
if v, ok := providerConfig["mode"]; ok {
mode = v.(string)
} else {
return v, nil
}
switch ProfileKey {
case "access_key_id", "access_key_secret":
if mode == "EcsRamRole" {
return "", nil
}
case "ram_role_name":
if mode != "EcsRamRole" {
return "", nil
}
case "sts_token":
if mode != "StsToken" {
return "", nil
}
case "ram_role_arn", "ram_session_name":
if mode != "RamRoleArn" {
return "", nil
}
case "expired_seconds":
if mode != "RamRoleArn" {
return float64(0), nil
}
}
return providerConfig[ProfileKey], nil
}

View File

@ -1,52 +0,0 @@
package ecs
import (
"os"
"testing"
)
func testAlicloudAccessConfig() *AlicloudAccessConfig {
return &AlicloudAccessConfig{
AlicloudAccessKey: "ak",
AlicloudSecretKey: "acs",
}
}
func TestAlicloudAccessConfigPrepareRegion(t *testing.T) {
c := testAlicloudAccessConfig()
c.AlicloudRegion = ""
if err := c.Prepare(nil); err == nil {
t.Fatalf("should have err")
}
c.AlicloudRegion = "cn-beijing"
if err := c.Prepare(nil); err != nil {
t.Fatalf("shouldn't have err: %s", err)
}
os.Setenv("ALICLOUD_REGION", "cn-hangzhou")
c.AlicloudRegion = ""
if err := c.Prepare(nil); err != nil {
t.Fatalf("shouldn't have err: %s", err)
}
c.AlicloudAccessKey = ""
if err := c.Prepare(nil); err == nil {
t.Fatalf("should have err")
}
c.AlicloudProfile = "default"
if err := c.Prepare(nil); err != nil {
t.Fatalf("shouldn't have err: %s", err)
}
c.AlicloudProfile = ""
os.Setenv("ALICLOUD_PROFILE", "default")
if err := c.Prepare(nil); err != nil {
t.Fatalf("shouldn't have err: %s", err)
}
c.AlicloudSkipValidation = false
}

View File

@ -1,186 +0,0 @@
package ecs
import (
"fmt"
"log"
"sort"
"strings"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/packer"
)
type Artifact struct {
// A map of regions to alicloud image IDs.
AlicloudImages map[string]string
// BuilderId is the unique ID for the builder that created this alicloud image
BuilderIdValue string
// Alcloud connection for performing API stuff.
Client *ClientWrapper
}
func (a *Artifact) BuilderId() string {
return a.BuilderIdValue
}
func (*Artifact) Files() []string {
// We have no files
return nil
}
func (a *Artifact) Id() string {
parts := make([]string, 0, len(a.AlicloudImages))
for region, ecsImageId := range a.AlicloudImages {
parts = append(parts, fmt.Sprintf("%s:%s", region, ecsImageId))
}
sort.Strings(parts)
return strings.Join(parts, ",")
}
func (a *Artifact) String() string {
alicloudImageStrings := make([]string, 0, len(a.AlicloudImages))
for region, id := range a.AlicloudImages {
single := fmt.Sprintf("%s: %s", region, id)
alicloudImageStrings = append(alicloudImageStrings, single)
}
sort.Strings(alicloudImageStrings)
return fmt.Sprintf("Alicloud images were created:\n\n%s", strings.Join(alicloudImageStrings, "\n"))
}
func (a *Artifact) State(name string) interface{} {
switch name {
case "atlas.artifact.metadata":
return a.stateAtlasMetadata()
default:
return nil
}
}
func (a *Artifact) Destroy() error {
errors := make([]error, 0)
copyingImages := make(map[string]string, len(a.AlicloudImages))
sourceImage := make(map[string]*ecs.Image, 1)
for regionId, imageId := range a.AlicloudImages {
describeImagesRequest := ecs.CreateDescribeImagesRequest()
describeImagesRequest.RegionId = regionId
describeImagesRequest.ImageId = imageId
describeImagesRequest.Status = ImageStatusQueried
imagesResponse, err := a.Client.DescribeImages(describeImagesRequest)
if err != nil {
errors = append(errors, err)
}
images := imagesResponse.Images.Image
if len(images) == 0 {
err := fmt.Errorf("Error retrieving details for alicloud image(%s), no alicloud images found", imageId)
errors = append(errors, err)
continue
}
if images[0].IsCopied && images[0].Status != ImageStatusAvailable {
copyingImages[regionId] = imageId
} else {
sourceImage[regionId] = &images[0]
}
}
for regionId, imageId := range copyingImages {
log.Printf("Cancel copying alicloud image (%s) from region (%s)", imageId, regionId)
errs := a.unsharedAccountsOnImages(regionId, imageId)
if errs != nil {
errors = append(errors, errs...)
}
cancelImageCopyRequest := ecs.CreateCancelCopyImageRequest()
cancelImageCopyRequest.RegionId = regionId
cancelImageCopyRequest.ImageId = imageId
if _, err := a.Client.CancelCopyImage(cancelImageCopyRequest); err != nil {
errors = append(errors, err)
}
}
for regionId, image := range sourceImage {
imageId := image.ImageId
log.Printf("Delete alicloud image (%s) from region (%s)", imageId, regionId)
errs := a.unsharedAccountsOnImages(regionId, imageId)
if errs != nil {
errors = append(errors, errs...)
}
deleteImageRequest := ecs.CreateDeleteImageRequest()
deleteImageRequest.RegionId = regionId
deleteImageRequest.ImageId = imageId
if _, err := a.Client.DeleteImage(deleteImageRequest); err != nil {
errors = append(errors, err)
}
//Delete the snapshot of this images
for _, diskDevices := range image.DiskDeviceMappings.DiskDeviceMapping {
deleteSnapshotRequest := ecs.CreateDeleteSnapshotRequest()
deleteSnapshotRequest.SnapshotId = diskDevices.SnapshotId
_, err := a.Client.DeleteSnapshot(deleteSnapshotRequest)
if err != nil {
errors = append(errors, err)
}
}
}
if len(errors) > 0 {
if len(errors) == 1 {
return errors[0]
} else {
return &packer.MultiError{Errors: errors}
}
}
return nil
}
func (a *Artifact) unsharedAccountsOnImages(regionId string, imageId string) []error {
var errors []error
describeImageShareRequest := ecs.CreateDescribeImageSharePermissionRequest()
describeImageShareRequest.RegionId = regionId
describeImageShareRequest.ImageId = imageId
imageShareResponse, err := a.Client.DescribeImageSharePermission(describeImageShareRequest)
if err != nil {
errors = append(errors, err)
return errors
}
accountsNumber := len(imageShareResponse.Accounts.Account)
if accountsNumber > 0 {
accounts := make([]string, accountsNumber)
for index, account := range imageShareResponse.Accounts.Account {
accounts[index] = account.AliyunId
}
modifyImageShareRequest := ecs.CreateModifyImageSharePermissionRequest()
modifyImageShareRequest.RegionId = regionId
modifyImageShareRequest.ImageId = imageId
modifyImageShareRequest.RemoveAccount = &accounts
_, err := a.Client.ModifyImageSharePermission(modifyImageShareRequest)
if err != nil {
errors = append(errors, err)
}
}
return errors
}
func (a *Artifact) stateAtlasMetadata() interface{} {
metadata := make(map[string]string)
for region, imageId := range a.AlicloudImages {
k := fmt.Sprintf("region.%s", region)
metadata[k] = imageId
}
return metadata
}

View File

@ -1,47 +0,0 @@
package ecs
import (
"reflect"
"testing"
"github.com/hashicorp/packer/packer"
)
func TestArtifact_Impl(t *testing.T) {
var _ packer.Artifact = new(Artifact)
}
func TestArtifactId(t *testing.T) {
expected := `east:foo,west:bar`
ecsImages := make(map[string]string)
ecsImages["east"] = "foo"
ecsImages["west"] = "bar"
a := &Artifact{
AlicloudImages: ecsImages,
}
result := a.Id()
if result != expected {
t.Fatalf("bad: %s", result)
}
}
func TestArtifactState_atlasMetadata(t *testing.T) {
a := &Artifact{
AlicloudImages: map[string]string{
"east": "foo",
"west": "bar",
},
}
actual := a.State("atlas.artifact.metadata")
expected := map[string]string{
"region.east": "foo",
"region.west": "bar",
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}

View File

@ -1,267 +0,0 @@
//go:generate mapstructure-to-hcl2 -type Config,AlicloudDiskDevice
// The alicloud contains a packer.Builder implementation that
// builds ecs images for alicloud.
package ecs
import (
"context"
"fmt"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
)
// The unique ID for this builder
const BuilderId = "alibaba.alicloud"
type Config struct {
common.PackerConfig `mapstructure:",squash"`
AlicloudAccessConfig `mapstructure:",squash"`
AlicloudImageConfig `mapstructure:",squash"`
RunConfig `mapstructure:",squash"`
ctx interpolate.Context
}
type Builder struct {
config Config
runner multistep.Runner
}
type InstanceNetWork string
const (
ALICLOUD_DEFAULT_SHORT_TIMEOUT = 180
ALICLOUD_DEFAULT_TIMEOUT = 1800
ALICLOUD_DEFAULT_LONG_TIMEOUT = 3600
)
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
err := config.Decode(&b.config, &config.DecodeOpts{
Interpolate: true,
InterpolateContext: &b.config.ctx,
InterpolateFilter: &interpolate.RenderFilter{
Exclude: []string{
"run_command",
},
},
}, raws...)
b.config.ctx.EnableEnv = true
if err != nil {
return nil, nil, err
}
if b.config.PackerConfig.PackerForce {
b.config.AlicloudImageForceDelete = true
b.config.AlicloudImageForceDeleteSnapshots = true
}
// Accumulate any errors
var errs *packer.MultiError
errs = packer.MultiErrorAppend(errs, b.config.AlicloudAccessConfig.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.AlicloudImageConfig.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...)
if errs != nil && len(errs.Errors) > 0 {
return nil, nil, errs
}
packer.LogSecretFilter.Set(b.config.AlicloudAccessKey, b.config.AlicloudSecretKey)
return nil, nil, nil
}
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
client, err := b.config.Client()
if err != nil {
return nil, err
}
state := new(multistep.BasicStateBag)
state.Put("config", &b.config)
state.Put("client", client)
state.Put("hook", hook)
state.Put("ui", ui)
state.Put("networktype", b.chooseNetworkType())
var steps []multistep.Step
// Build the steps
steps = []multistep.Step{
&stepPreValidate{
AlicloudDestImageName: b.config.AlicloudImageName,
ForceDelete: b.config.AlicloudImageForceDelete,
},
&stepCheckAlicloudSourceImage{
SourceECSImageId: b.config.AlicloudSourceImage,
},
&stepConfigAlicloudKeyPair{
Debug: b.config.PackerDebug,
Comm: &b.config.Comm,
DebugKeyPath: fmt.Sprintf("ecs_%s.pem", b.config.PackerBuildName),
RegionId: b.config.AlicloudRegion,
},
}
if b.chooseNetworkType() == InstanceNetworkVpc {
steps = append(steps,
&stepConfigAlicloudVPC{
VpcId: b.config.VpcId,
CidrBlock: b.config.CidrBlock,
VpcName: b.config.VpcName,
},
&stepConfigAlicloudVSwitch{
VSwitchId: b.config.VSwitchId,
ZoneId: b.config.ZoneId,
CidrBlock: b.config.CidrBlock,
VSwitchName: b.config.VSwitchName,
})
}
steps = append(steps,
&stepConfigAlicloudSecurityGroup{
SecurityGroupId: b.config.SecurityGroupId,
SecurityGroupName: b.config.SecurityGroupId,
RegionId: b.config.AlicloudRegion,
},
&stepCreateAlicloudInstance{
IOOptimized: b.config.IOOptimized,
InstanceType: b.config.InstanceType,
UserData: b.config.UserData,
UserDataFile: b.config.UserDataFile,
RegionId: b.config.AlicloudRegion,
InternetChargeType: b.config.InternetChargeType,
InternetMaxBandwidthOut: b.config.InternetMaxBandwidthOut,
InstanceName: b.config.InstanceName,
ZoneId: b.config.ZoneId,
})
if b.chooseNetworkType() == InstanceNetworkVpc {
steps = append(steps, &stepConfigAlicloudEIP{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
RegionId: b.config.AlicloudRegion,
InternetChargeType: b.config.InternetChargeType,
InternetMaxBandwidthOut: b.config.InternetMaxBandwidthOut,
SSHPrivateIp: b.config.SSHPrivateIp,
})
} else {
steps = append(steps, &stepConfigAlicloudPublicIP{
RegionId: b.config.AlicloudRegion,
SSHPrivateIp: b.config.SSHPrivateIp,
})
}
steps = append(steps,
&stepAttachKeyPair{},
&stepRunAlicloudInstance{},
&communicator.StepConnect{
Config: &b.config.RunConfig.Comm,
Host: SSHHost(
client,
b.config.SSHPrivateIp),
SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(),
},
&common.StepProvision{},
&common.StepCleanupTempKeys{
Comm: &b.config.RunConfig.Comm,
},
&stepStopAlicloudInstance{
ForceStop: b.config.ForceStopInstance,
DisableStop: b.config.DisableStopInstance,
},
&stepDeleteAlicloudImageSnapshots{
AlicloudImageForceDeleteSnapshots: b.config.AlicloudImageForceDeleteSnapshots,
AlicloudImageForceDelete: b.config.AlicloudImageForceDelete,
AlicloudImageName: b.config.AlicloudImageName,
AlicloudImageDestinationRegions: b.config.AlicloudImageConfig.AlicloudImageDestinationRegions,
AlicloudImageDestinationNames: b.config.AlicloudImageConfig.AlicloudImageDestinationNames,
})
if b.config.AlicloudImageIgnoreDataDisks {
steps = append(steps, &stepCreateAlicloudSnapshot{
WaitSnapshotReadyTimeout: b.getSnapshotReadyTimeout(),
})
}
steps = append(steps,
&stepCreateAlicloudImage{
AlicloudImageIgnoreDataDisks: b.config.AlicloudImageIgnoreDataDisks,
WaitSnapshotReadyTimeout: b.getSnapshotReadyTimeout(),
},
&stepCreateTags{
Tags: b.config.AlicloudImageTags,
},
&stepRegionCopyAlicloudImage{
AlicloudImageDestinationRegions: b.config.AlicloudImageDestinationRegions,
AlicloudImageDestinationNames: b.config.AlicloudImageDestinationNames,
RegionId: b.config.AlicloudRegion,
},
&stepShareAlicloudImage{
AlicloudImageShareAccounts: b.config.AlicloudImageShareAccounts,
AlicloudImageUNShareAccounts: b.config.AlicloudImageUNShareAccounts,
RegionId: b.config.AlicloudRegion,
})
// Run!
b.runner = common.NewRunner(steps, b.config.PackerConfig, ui)
b.runner.Run(ctx, state)
// If there was an error, return that
if rawErr, ok := state.GetOk("error"); ok {
return nil, rawErr.(error)
}
// If there are no ECS images, then just return
if _, ok := state.GetOk("alicloudimages"); !ok {
return nil, nil
}
// Build the artifact and return it
artifact := &Artifact{
AlicloudImages: state.Get("alicloudimages").(map[string]string),
BuilderIdValue: BuilderId,
Client: client,
}
return artifact, nil
}
func (b *Builder) chooseNetworkType() InstanceNetWork {
if b.isVpcNetRequired() {
return InstanceNetworkVpc
} else {
return InstanceNetworkClassic
}
}
func (b *Builder) isVpcNetRequired() bool {
// UserData and KeyPair only works in VPC
return b.isVpcSpecified() || b.isUserDataNeeded() || b.isKeyPairNeeded()
}
func (b *Builder) isVpcSpecified() bool {
return b.config.VpcId != "" || b.config.VSwitchId != ""
}
func (b *Builder) isUserDataNeeded() bool {
// Public key setup requires userdata
if b.config.RunConfig.Comm.SSHPrivateKeyFile != "" {
return true
}
return b.config.UserData != "" || b.config.UserDataFile != ""
}
func (b *Builder) isKeyPairNeeded() bool {
return b.config.Comm.SSHKeyPairName != "" || b.config.Comm.SSHTemporaryKeyPairName != ""
}
func (b *Builder) getSnapshotReadyTimeout() int {
if b.config.WaitSnapshotReadyTimeout > 0 {
return b.config.WaitSnapshotReadyTimeout
}
return ALICLOUD_DEFAULT_LONG_TIMEOUT
}

View File

@ -1,266 +0,0 @@
// Code generated by "mapstructure-to-hcl2 -type Config,AlicloudDiskDevice"; DO NOT EDIT.
package ecs
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer/hcl2template"
"github.com/zclconf/go-cty/cty"
)
// FlatAlicloudDiskDevice is an auto-generated flat version of AlicloudDiskDevice.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatAlicloudDiskDevice struct {
DiskName *string `mapstructure:"disk_name" required:"false" cty:"disk_name" hcl:"disk_name"`
DiskCategory *string `mapstructure:"disk_category" required:"false" cty:"disk_category" hcl:"disk_category"`
DiskSize *int `mapstructure:"disk_size" required:"false" cty:"disk_size" hcl:"disk_size"`
SnapshotId *string `mapstructure:"disk_snapshot_id" required:"false" cty:"disk_snapshot_id" hcl:"disk_snapshot_id"`
Description *string `mapstructure:"disk_description" required:"false" cty:"disk_description" hcl:"disk_description"`
DeleteWithInstance *bool `mapstructure:"disk_delete_with_instance" required:"false" cty:"disk_delete_with_instance" hcl:"disk_delete_with_instance"`
Device *string `mapstructure:"disk_device" required:"false" cty:"disk_device" hcl:"disk_device"`
Encrypted *bool `mapstructure:"disk_encrypted" required:"false" cty:"disk_encrypted" hcl:"disk_encrypted"`
}
// FlatMapstructure returns a new FlatAlicloudDiskDevice.
// FlatAlicloudDiskDevice is an auto-generated flat version of AlicloudDiskDevice.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*AlicloudDiskDevice) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatAlicloudDiskDevice)
}
// HCL2Spec returns the hcl spec of a AlicloudDiskDevice.
// This spec is used by HCL to read the fields of AlicloudDiskDevice.
// The decoded values from this spec will then be applied to a FlatAlicloudDiskDevice.
func (*FlatAlicloudDiskDevice) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"disk_name": &hcldec.AttrSpec{Name: "disk_name", Type: cty.String, Required: false},
"disk_category": &hcldec.AttrSpec{Name: "disk_category", Type: cty.String, Required: false},
"disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, Required: false},
"disk_snapshot_id": &hcldec.AttrSpec{Name: "disk_snapshot_id", Type: cty.String, Required: false},
"disk_description": &hcldec.AttrSpec{Name: "disk_description", Type: cty.String, Required: false},
"disk_delete_with_instance": &hcldec.AttrSpec{Name: "disk_delete_with_instance", Type: cty.Bool, Required: false},
"disk_device": &hcldec.AttrSpec{Name: "disk_device", Type: cty.String, Required: false},
"disk_encrypted": &hcldec.AttrSpec{Name: "disk_encrypted", Type: cty.Bool, Required: false},
}
return s
}
// FlatConfig is an auto-generated flat version of Config.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatConfig struct {
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"`
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"`
AlicloudAccessKey *string `mapstructure:"access_key" required:"true" cty:"access_key" hcl:"access_key"`
AlicloudSecretKey *string `mapstructure:"secret_key" required:"true" cty:"secret_key" hcl:"secret_key"`
AlicloudRegion *string `mapstructure:"region" required:"true" cty:"region" hcl:"region"`
AlicloudSkipValidation *bool `mapstructure:"skip_region_validation" required:"false" cty:"skip_region_validation" hcl:"skip_region_validation"`
AlicloudSkipImageValidation *bool `mapstructure:"skip_image_validation" required:"false" cty:"skip_image_validation" hcl:"skip_image_validation"`
AlicloudProfile *string `mapstructure:"profile" required:"false" cty:"profile" hcl:"profile"`
AlicloudSharedCredentialsFile *string `mapstructure:"shared_credentials_file" required:"false" cty:"shared_credentials_file" hcl:"shared_credentials_file"`
SecurityToken *string `mapstructure:"security_token" required:"false" cty:"security_token" hcl:"security_token"`
AlicloudImageName *string `mapstructure:"image_name" required:"true" cty:"image_name" hcl:"image_name"`
AlicloudImageVersion *string `mapstructure:"image_version" required:"false" cty:"image_version" hcl:"image_version"`
AlicloudImageDescription *string `mapstructure:"image_description" required:"false" cty:"image_description" hcl:"image_description"`
AlicloudImageShareAccounts []string `mapstructure:"image_share_account" required:"false" cty:"image_share_account" hcl:"image_share_account"`
AlicloudImageUNShareAccounts []string `mapstructure:"image_unshare_account" cty:"image_unshare_account" hcl:"image_unshare_account"`
AlicloudImageDestinationRegions []string `mapstructure:"image_copy_regions" required:"false" cty:"image_copy_regions" hcl:"image_copy_regions"`
AlicloudImageDestinationNames []string `mapstructure:"image_copy_names" required:"false" cty:"image_copy_names" hcl:"image_copy_names"`
ImageEncrypted *bool `mapstructure:"image_encrypted" required:"false" cty:"image_encrypted" hcl:"image_encrypted"`
AlicloudImageForceDelete *bool `mapstructure:"image_force_delete" required:"false" cty:"image_force_delete" hcl:"image_force_delete"`
AlicloudImageForceDeleteSnapshots *bool `mapstructure:"image_force_delete_snapshots" required:"false" cty:"image_force_delete_snapshots" hcl:"image_force_delete_snapshots"`
AlicloudImageForceDeleteInstances *bool `mapstructure:"image_force_delete_instances" cty:"image_force_delete_instances" hcl:"image_force_delete_instances"`
AlicloudImageIgnoreDataDisks *bool `mapstructure:"image_ignore_data_disks" required:"false" cty:"image_ignore_data_disks" hcl:"image_ignore_data_disks"`
AlicloudImageTags map[string]string `mapstructure:"tags" required:"false" cty:"tags" hcl:"tags"`
AlicloudImageTag []hcl2template.FlatKeyValue `mapstructure:"tag" required:"false" cty:"tag" hcl:"tag"`
ECSSystemDiskMapping *FlatAlicloudDiskDevice `mapstructure:"system_disk_mapping" required:"false" cty:"system_disk_mapping" hcl:"system_disk_mapping"`
ECSImagesDiskMappings []FlatAlicloudDiskDevice `mapstructure:"image_disk_mappings" required:"false" cty:"image_disk_mappings" hcl:"image_disk_mappings"`
AssociatePublicIpAddress *bool `mapstructure:"associate_public_ip_address" cty:"associate_public_ip_address" hcl:"associate_public_ip_address"`
ZoneId *string `mapstructure:"zone_id" required:"false" cty:"zone_id" hcl:"zone_id"`
IOOptimized *bool `mapstructure:"io_optimized" required:"false" cty:"io_optimized" hcl:"io_optimized"`
InstanceType *string `mapstructure:"instance_type" required:"true" cty:"instance_type" hcl:"instance_type"`
Description *string `mapstructure:"description" cty:"description" hcl:"description"`
AlicloudSourceImage *string `mapstructure:"source_image" required:"true" cty:"source_image" hcl:"source_image"`
ForceStopInstance *bool `mapstructure:"force_stop_instance" required:"false" cty:"force_stop_instance" hcl:"force_stop_instance"`
DisableStopInstance *bool `mapstructure:"disable_stop_instance" required:"false" cty:"disable_stop_instance" hcl:"disable_stop_instance"`
SecurityGroupId *string `mapstructure:"security_group_id" required:"false" cty:"security_group_id" hcl:"security_group_id"`
SecurityGroupName *string `mapstructure:"security_group_name" required:"false" cty:"security_group_name" hcl:"security_group_name"`
UserData *string `mapstructure:"user_data" required:"false" cty:"user_data" hcl:"user_data"`
UserDataFile *string `mapstructure:"user_data_file" required:"false" cty:"user_data_file" hcl:"user_data_file"`
VpcId *string `mapstructure:"vpc_id" required:"false" cty:"vpc_id" hcl:"vpc_id"`
VpcName *string `mapstructure:"vpc_name" required:"false" cty:"vpc_name" hcl:"vpc_name"`
CidrBlock *string `mapstructure:"vpc_cidr_block" required:"false" cty:"vpc_cidr_block" hcl:"vpc_cidr_block"`
VSwitchId *string `mapstructure:"vswitch_id" required:"false" cty:"vswitch_id" hcl:"vswitch_id"`
VSwitchName *string `mapstructure:"vswitch_name" required:"false" cty:"vswitch_name" hcl:"vswitch_name"`
InstanceName *string `mapstructure:"instance_name" required:"false" cty:"instance_name" hcl:"instance_name"`
InternetChargeType *string `mapstructure:"internet_charge_type" required:"false" cty:"internet_charge_type" hcl:"internet_charge_type"`
InternetMaxBandwidthOut *int `mapstructure:"internet_max_bandwidth_out" required:"false" cty:"internet_max_bandwidth_out" hcl:"internet_max_bandwidth_out"`
WaitSnapshotReadyTimeout *int `mapstructure:"wait_snapshot_ready_timeout" required:"false" cty:"wait_snapshot_ready_timeout" hcl:"wait_snapshot_ready_timeout"`
Type *string `mapstructure:"communicator" cty:"communicator" hcl:"communicator"`
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting" hcl:"pause_before_connecting"`
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host" hcl:"ssh_host"`
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port" hcl:"ssh_port"`
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username" hcl:"ssh_username"`
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password" hcl:"ssh_password"`
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" undocumented:"true" cty:"ssh_keypair_name" hcl:"ssh_keypair_name"`
SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" undocumented:"true" cty:"temporary_key_pair_name" hcl:"temporary_key_pair_name"`
SSHCiphers []string `mapstructure:"ssh_ciphers" cty:"ssh_ciphers" hcl:"ssh_ciphers"`
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys" hcl:"ssh_clear_authorized_keys"`
SSHKEXAlgos []string `mapstructure:"ssh_key_exchange_algorithms" cty:"ssh_key_exchange_algorithms" hcl:"ssh_key_exchange_algorithms"`
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" undocumented:"true" cty:"ssh_private_key_file" hcl:"ssh_private_key_file"`
SSHCertificateFile *string `mapstructure:"ssh_certificate_file" cty:"ssh_certificate_file" hcl:"ssh_certificate_file"`
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty" hcl:"ssh_pty"`
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout" hcl:"ssh_timeout"`
SSHWaitTimeout *string `mapstructure:"ssh_wait_timeout" undocumented:"true" cty:"ssh_wait_timeout" hcl:"ssh_wait_timeout"`
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" undocumented:"true" cty:"ssh_agent_auth" hcl:"ssh_agent_auth"`
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding" hcl:"ssh_disable_agent_forwarding"`
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts" hcl:"ssh_handshake_attempts"`
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host" hcl:"ssh_bastion_host"`
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port" hcl:"ssh_bastion_port"`
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth" hcl:"ssh_bastion_agent_auth"`
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username" hcl:"ssh_bastion_username"`
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password" hcl:"ssh_bastion_password"`
SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive" hcl:"ssh_bastion_interactive"`
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file" hcl:"ssh_bastion_private_key_file"`
SSHBastionCertificateFile *string `mapstructure:"ssh_bastion_certificate_file" cty:"ssh_bastion_certificate_file" hcl:"ssh_bastion_certificate_file"`
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method" hcl:"ssh_file_transfer_method"`
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host" hcl:"ssh_proxy_host"`
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port" hcl:"ssh_proxy_port"`
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username" hcl:"ssh_proxy_username"`
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password" hcl:"ssh_proxy_password"`
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval" hcl:"ssh_keep_alive_interval"`
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout" hcl:"ssh_read_write_timeout"`
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels" hcl:"ssh_remote_tunnels"`
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels" hcl:"ssh_local_tunnels"`
SSHPublicKey []byte `mapstructure:"ssh_public_key" undocumented:"true" cty:"ssh_public_key" hcl:"ssh_public_key"`
SSHPrivateKey []byte `mapstructure:"ssh_private_key" undocumented:"true" cty:"ssh_private_key" hcl:"ssh_private_key"`
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username" hcl:"winrm_username"`
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password" hcl:"winrm_password"`
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host" hcl:"winrm_host"`
WinRMNoProxy *bool `mapstructure:"winrm_no_proxy" cty:"winrm_no_proxy" hcl:"winrm_no_proxy"`
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port" hcl:"winrm_port"`
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout" hcl:"winrm_timeout"`
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl" hcl:"winrm_use_ssl"`
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure" hcl:"winrm_insecure"`
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm" hcl:"winrm_use_ntlm"`
SSHPrivateIp *bool `mapstructure:"ssh_private_ip" required:"false" cty:"ssh_private_ip" hcl:"ssh_private_ip"`
}
// FlatMapstructure returns a new FlatConfig.
// FlatConfig is an auto-generated flat version of Config.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatConfig)
}
// HCL2Spec returns the hcl spec of a Config.
// This spec is used by HCL to read the fields of Config.
// The decoded values from this spec will then be applied to a FlatConfig.
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
"packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false},
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
"access_key": &hcldec.AttrSpec{Name: "access_key", Type: cty.String, Required: false},
"secret_key": &hcldec.AttrSpec{Name: "secret_key", Type: cty.String, Required: false},
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
"skip_region_validation": &hcldec.AttrSpec{Name: "skip_region_validation", Type: cty.Bool, Required: false},
"skip_image_validation": &hcldec.AttrSpec{Name: "skip_image_validation", Type: cty.Bool, Required: false},
"profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false},
"shared_credentials_file": &hcldec.AttrSpec{Name: "shared_credentials_file", Type: cty.String, Required: false},
"security_token": &hcldec.AttrSpec{Name: "security_token", Type: cty.String, Required: false},
"image_name": &hcldec.AttrSpec{Name: "image_name", Type: cty.String, Required: false},
"image_version": &hcldec.AttrSpec{Name: "image_version", Type: cty.String, Required: false},
"image_description": &hcldec.AttrSpec{Name: "image_description", Type: cty.String, Required: false},
"image_share_account": &hcldec.AttrSpec{Name: "image_share_account", Type: cty.List(cty.String), Required: false},
"image_unshare_account": &hcldec.AttrSpec{Name: "image_unshare_account", Type: cty.List(cty.String), Required: false},
"image_copy_regions": &hcldec.AttrSpec{Name: "image_copy_regions", Type: cty.List(cty.String), Required: false},
"image_copy_names": &hcldec.AttrSpec{Name: "image_copy_names", Type: cty.List(cty.String), Required: false},
"image_encrypted": &hcldec.AttrSpec{Name: "image_encrypted", Type: cty.Bool, Required: false},
"image_force_delete": &hcldec.AttrSpec{Name: "image_force_delete", Type: cty.Bool, Required: false},
"image_force_delete_snapshots": &hcldec.AttrSpec{Name: "image_force_delete_snapshots", Type: cty.Bool, Required: false},
"image_force_delete_instances": &hcldec.AttrSpec{Name: "image_force_delete_instances", Type: cty.Bool, Required: false},
"image_ignore_data_disks": &hcldec.AttrSpec{Name: "image_ignore_data_disks", Type: cty.Bool, Required: false},
"tags": &hcldec.AttrSpec{Name: "tags", Type: cty.Map(cty.String), Required: false},
"tag": &hcldec.BlockListSpec{TypeName: "tag", Nested: hcldec.ObjectSpec((*hcl2template.FlatKeyValue)(nil).HCL2Spec())},
"system_disk_mapping": &hcldec.BlockSpec{TypeName: "system_disk_mapping", Nested: hcldec.ObjectSpec((*FlatAlicloudDiskDevice)(nil).HCL2Spec())},
"image_disk_mappings": &hcldec.BlockListSpec{TypeName: "image_disk_mappings", Nested: hcldec.ObjectSpec((*FlatAlicloudDiskDevice)(nil).HCL2Spec())},
"associate_public_ip_address": &hcldec.AttrSpec{Name: "associate_public_ip_address", Type: cty.Bool, Required: false},
"zone_id": &hcldec.AttrSpec{Name: "zone_id", Type: cty.String, Required: false},
"io_optimized": &hcldec.AttrSpec{Name: "io_optimized", Type: cty.Bool, Required: false},
"instance_type": &hcldec.AttrSpec{Name: "instance_type", Type: cty.String, Required: false},
"description": &hcldec.AttrSpec{Name: "description", Type: cty.String, Required: false},
"source_image": &hcldec.AttrSpec{Name: "source_image", Type: cty.String, Required: false},
"force_stop_instance": &hcldec.AttrSpec{Name: "force_stop_instance", Type: cty.Bool, Required: false},
"disable_stop_instance": &hcldec.AttrSpec{Name: "disable_stop_instance", Type: cty.Bool, Required: false},
"security_group_id": &hcldec.AttrSpec{Name: "security_group_id", Type: cty.String, Required: false},
"security_group_name": &hcldec.AttrSpec{Name: "security_group_name", Type: cty.String, Required: false},
"user_data": &hcldec.AttrSpec{Name: "user_data", Type: cty.String, Required: false},
"user_data_file": &hcldec.AttrSpec{Name: "user_data_file", Type: cty.String, Required: false},
"vpc_id": &hcldec.AttrSpec{Name: "vpc_id", Type: cty.String, Required: false},
"vpc_name": &hcldec.AttrSpec{Name: "vpc_name", Type: cty.String, Required: false},
"vpc_cidr_block": &hcldec.AttrSpec{Name: "vpc_cidr_block", Type: cty.String, Required: false},
"vswitch_id": &hcldec.AttrSpec{Name: "vswitch_id", Type: cty.String, Required: false},
"vswitch_name": &hcldec.AttrSpec{Name: "vswitch_name", Type: cty.String, Required: false},
"instance_name": &hcldec.AttrSpec{Name: "instance_name", Type: cty.String, Required: false},
"internet_charge_type": &hcldec.AttrSpec{Name: "internet_charge_type", Type: cty.String, Required: false},
"internet_max_bandwidth_out": &hcldec.AttrSpec{Name: "internet_max_bandwidth_out", Type: cty.Number, Required: false},
"wait_snapshot_ready_timeout": &hcldec.AttrSpec{Name: "wait_snapshot_ready_timeout", Type: cty.Number, Required: false},
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
"ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false},
"ssh_port": &hcldec.AttrSpec{Name: "ssh_port", Type: cty.Number, Required: false},
"ssh_username": &hcldec.AttrSpec{Name: "ssh_username", Type: cty.String, Required: false},
"ssh_password": &hcldec.AttrSpec{Name: "ssh_password", Type: cty.String, Required: false},
"ssh_keypair_name": &hcldec.AttrSpec{Name: "ssh_keypair_name", Type: cty.String, Required: false},
"temporary_key_pair_name": &hcldec.AttrSpec{Name: "temporary_key_pair_name", Type: cty.String, Required: false},
"ssh_ciphers": &hcldec.AttrSpec{Name: "ssh_ciphers", Type: cty.List(cty.String), Required: false},
"ssh_clear_authorized_keys": &hcldec.AttrSpec{Name: "ssh_clear_authorized_keys", Type: cty.Bool, Required: false},
"ssh_key_exchange_algorithms": &hcldec.AttrSpec{Name: "ssh_key_exchange_algorithms", Type: cty.List(cty.String), Required: false},
"ssh_private_key_file": &hcldec.AttrSpec{Name: "ssh_private_key_file", Type: cty.String, Required: false},
"ssh_certificate_file": &hcldec.AttrSpec{Name: "ssh_certificate_file", Type: cty.String, Required: false},
"ssh_pty": &hcldec.AttrSpec{Name: "ssh_pty", Type: cty.Bool, Required: false},
"ssh_timeout": &hcldec.AttrSpec{Name: "ssh_timeout", Type: cty.String, Required: false},
"ssh_wait_timeout": &hcldec.AttrSpec{Name: "ssh_wait_timeout", Type: cty.String, Required: false},
"ssh_agent_auth": &hcldec.AttrSpec{Name: "ssh_agent_auth", Type: cty.Bool, Required: false},
"ssh_disable_agent_forwarding": &hcldec.AttrSpec{Name: "ssh_disable_agent_forwarding", Type: cty.Bool, Required: false},
"ssh_handshake_attempts": &hcldec.AttrSpec{Name: "ssh_handshake_attempts", Type: cty.Number, Required: false},
"ssh_bastion_host": &hcldec.AttrSpec{Name: "ssh_bastion_host", Type: cty.String, Required: false},
"ssh_bastion_port": &hcldec.AttrSpec{Name: "ssh_bastion_port", Type: cty.Number, Required: false},
"ssh_bastion_agent_auth": &hcldec.AttrSpec{Name: "ssh_bastion_agent_auth", Type: cty.Bool, Required: false},
"ssh_bastion_username": &hcldec.AttrSpec{Name: "ssh_bastion_username", Type: cty.String, Required: false},
"ssh_bastion_password": &hcldec.AttrSpec{Name: "ssh_bastion_password", Type: cty.String, Required: false},
"ssh_bastion_interactive": &hcldec.AttrSpec{Name: "ssh_bastion_interactive", Type: cty.Bool, Required: false},
"ssh_bastion_private_key_file": &hcldec.AttrSpec{Name: "ssh_bastion_private_key_file", Type: cty.String, Required: false},
"ssh_bastion_certificate_file": &hcldec.AttrSpec{Name: "ssh_bastion_certificate_file", Type: cty.String, Required: false},
"ssh_file_transfer_method": &hcldec.AttrSpec{Name: "ssh_file_transfer_method", Type: cty.String, Required: false},
"ssh_proxy_host": &hcldec.AttrSpec{Name: "ssh_proxy_host", Type: cty.String, Required: false},
"ssh_proxy_port": &hcldec.AttrSpec{Name: "ssh_proxy_port", Type: cty.Number, Required: false},
"ssh_proxy_username": &hcldec.AttrSpec{Name: "ssh_proxy_username", Type: cty.String, Required: false},
"ssh_proxy_password": &hcldec.AttrSpec{Name: "ssh_proxy_password", Type: cty.String, Required: false},
"ssh_keep_alive_interval": &hcldec.AttrSpec{Name: "ssh_keep_alive_interval", Type: cty.String, Required: false},
"ssh_read_write_timeout": &hcldec.AttrSpec{Name: "ssh_read_write_timeout", Type: cty.String, Required: false},
"ssh_remote_tunnels": &hcldec.AttrSpec{Name: "ssh_remote_tunnels", Type: cty.List(cty.String), Required: false},
"ssh_local_tunnels": &hcldec.AttrSpec{Name: "ssh_local_tunnels", Type: cty.List(cty.String), Required: false},
"ssh_public_key": &hcldec.AttrSpec{Name: "ssh_public_key", Type: cty.List(cty.Number), Required: false},
"ssh_private_key": &hcldec.AttrSpec{Name: "ssh_private_key", Type: cty.List(cty.Number), Required: false},
"winrm_username": &hcldec.AttrSpec{Name: "winrm_username", Type: cty.String, Required: false},
"winrm_password": &hcldec.AttrSpec{Name: "winrm_password", Type: cty.String, Required: false},
"winrm_host": &hcldec.AttrSpec{Name: "winrm_host", Type: cty.String, Required: false},
"winrm_no_proxy": &hcldec.AttrSpec{Name: "winrm_no_proxy", Type: cty.Bool, Required: false},
"winrm_port": &hcldec.AttrSpec{Name: "winrm_port", Type: cty.Number, Required: false},
"winrm_timeout": &hcldec.AttrSpec{Name: "winrm_timeout", Type: cty.String, Required: false},
"winrm_use_ssl": &hcldec.AttrSpec{Name: "winrm_use_ssl", Type: cty.Bool, Required: false},
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
"ssh_private_ip": &hcldec.AttrSpec{Name: "ssh_private_ip", Type: cty.Bool, Required: false},
}
return s
}

View File

@ -1,891 +0,0 @@
package ecs
import (
"encoding/json"
"fmt"
"os"
"strings"
"testing"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
builderT "github.com/hashicorp/packer/helper/builder/testing"
"github.com/hashicorp/packer/packer"
)
const defaultTestRegion = "cn-beijing"
func TestBuilderAcc_validateRegion(t *testing.T) {
t.Parallel()
if os.Getenv(builderT.TestEnvVar) == "" {
t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", builderT.TestEnvVar))
return
}
testAccPreCheck(t)
access := &AlicloudAccessConfig{AlicloudRegion: "cn-beijing"}
err := access.Config()
if err != nil {
t.Fatalf("init AlicloudAccessConfig failed: %s", err)
}
err = access.ValidateRegion("cn-hangzhou")
if err != nil {
t.Fatalf("Expect pass with valid region id but failed: %s", err)
}
err = access.ValidateRegion("invalidRegionId")
if err == nil {
t.Fatal("Expect failure due to invalid region id but passed")
}
}
func TestBuilderAcc_basic(t *testing.T) {
t.Parallel()
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: testBuilderAccBasic,
})
}
const testBuilderAccBasic = `
{ "builders": [{
"type": "test",
"region": "cn-beijing",
"instance_type": "ecs.n1.tiny",
"source_image":"ubuntu_18_04_64_20G_alibase_20190509.vhd",
"io_optimized":"true",
"ssh_username":"root",
"image_name": "packer-test-basic_{{timestamp}}"
}]
}`
func TestBuilderAcc_withDiskSettings(t *testing.T) {
t.Parallel()
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: testBuilderAccWithDiskSettings,
Check: checkImageDisksSettings(),
})
}
const testBuilderAccWithDiskSettings = `
{ "builders": [{
"type": "test",
"region": "cn-beijing",
"instance_type": "ecs.n1.tiny",
"source_image":"ubuntu_18_04_64_20G_alibase_20190509.vhd",
"io_optimized":"true",
"ssh_username":"root",
"image_name": "packer-test-withDiskSettings_{{timestamp}}",
"system_disk_mapping": {
"disk_size": 60
},
"image_disk_mappings": [
{
"disk_name": "datadisk1",
"disk_size": 25,
"disk_delete_with_instance": true
},
{
"disk_name": "datadisk2",
"disk_size": 25,
"disk_delete_with_instance": true
}
]
}]
}`
func checkImageDisksSettings() builderT.TestCheckFunc {
return func(artifacts []packer.Artifact) error {
if len(artifacts) > 1 {
return fmt.Errorf("more than 1 artifact")
}
// Get the actual *Artifact pointer so we can access the AMIs directly
artifactRaw := artifacts[0]
artifact, ok := artifactRaw.(*Artifact)
if !ok {
return fmt.Errorf("unknown artifact: %#v", artifactRaw)
}
imageId := artifact.AlicloudImages[defaultTestRegion]
// describe the image, get block devices with a snapshot
client, _ := testAliyunClient()
describeImagesRequest := ecs.CreateDescribeImagesRequest()
describeImagesRequest.RegionId = defaultTestRegion
describeImagesRequest.ImageId = imageId
imagesResponse, err := client.DescribeImages(describeImagesRequest)
if err != nil {
return fmt.Errorf("describe images failed due to %s", err)
}
if len(imagesResponse.Images.Image) == 0 {
return fmt.Errorf("image %s generated can not be found", imageId)
}
image := imagesResponse.Images.Image[0]
if image.Size != 60 {
return fmt.Errorf("the size of image %s should be equal to 60G but got %dG", imageId, image.Size)
}
if len(image.DiskDeviceMappings.DiskDeviceMapping) != 3 {
return fmt.Errorf("image %s should contains 3 disks", imageId)
}
var snapshotIds []string
for _, mapping := range image.DiskDeviceMappings.DiskDeviceMapping {
if mapping.Type == DiskTypeSystem {
if mapping.Size != "60" {
return fmt.Errorf("the system snapshot size of image %s should be equal to 60G but got %sG", imageId, mapping.Size)
}
} else {
if mapping.Size != "25" {
return fmt.Errorf("the data disk size of image %s should be equal to 25G but got %sG", imageId, mapping.Size)
}
snapshotIds = append(snapshotIds, mapping.SnapshotId)
}
}
data, _ := json.Marshal(snapshotIds)
describeSnapshotRequest := ecs.CreateDescribeSnapshotsRequest()
describeSnapshotRequest.RegionId = defaultTestRegion
describeSnapshotRequest.SnapshotIds = string(data)
describeSnapshotsResponse, err := client.DescribeSnapshots(describeSnapshotRequest)
if err != nil {
return fmt.Errorf("describe data snapshots failed due to %s", err)
}
if len(describeSnapshotsResponse.Snapshots.Snapshot) != 2 {
return fmt.Errorf("expect %d data snapshots but got %d", len(snapshotIds), len(describeSnapshotsResponse.Snapshots.Snapshot))
}
var dataDiskIds []string
for _, snapshot := range describeSnapshotsResponse.Snapshots.Snapshot {
dataDiskIds = append(dataDiskIds, snapshot.SourceDiskId)
}
data, _ = json.Marshal(dataDiskIds)
describeDisksRequest := ecs.CreateDescribeDisksRequest()
describeDisksRequest.RegionId = defaultTestRegion
describeDisksRequest.DiskIds = string(data)
describeDisksResponse, err := client.DescribeDisks(describeDisksRequest)
if err != nil {
return fmt.Errorf("describe snapshots failed due to %s", err)
}
if len(describeDisksResponse.Disks.Disk) != 0 {
return fmt.Errorf("data disks should be deleted but %d left", len(describeDisksResponse.Disks.Disk))
}
return nil
}
}
func TestBuilderAcc_withIgnoreDataDisks(t *testing.T) {
t.Parallel()
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: testBuilderAccIgnoreDataDisks,
Check: checkIgnoreDataDisks(),
})
}
const testBuilderAccIgnoreDataDisks = `
{ "builders": [{
"type": "test",
"region": "cn-beijing",
"instance_type": "ecs.gn5-c8g1.2xlarge",
"source_image":"ubuntu_18_04_64_20G_alibase_20190509.vhd",
"io_optimized":"true",
"ssh_username":"root",
"image_name": "packer-test-ignoreDataDisks_{{timestamp}}",
"image_ignore_data_disks": true
}]
}`
func checkIgnoreDataDisks() builderT.TestCheckFunc {
return func(artifacts []packer.Artifact) error {
if len(artifacts) > 1 {
return fmt.Errorf("more than 1 artifact")
}
// Get the actual *Artifact pointer so we can access the AMIs directly
artifactRaw := artifacts[0]
artifact, ok := artifactRaw.(*Artifact)
if !ok {
return fmt.Errorf("unknown artifact: %#v", artifactRaw)
}
imageId := artifact.AlicloudImages[defaultTestRegion]
// describe the image, get block devices with a snapshot
client, _ := testAliyunClient()
describeImagesRequest := ecs.CreateDescribeImagesRequest()
describeImagesRequest.RegionId = defaultTestRegion
describeImagesRequest.ImageId = imageId
imagesResponse, err := client.DescribeImages(describeImagesRequest)
if err != nil {
return fmt.Errorf("describe images failed due to %s", err)
}
if len(imagesResponse.Images.Image) == 0 {
return fmt.Errorf("image %s generated can not be found", imageId)
}
image := imagesResponse.Images.Image[0]
if len(image.DiskDeviceMappings.DiskDeviceMapping) != 1 {
return fmt.Errorf("image %s should only contain one disks", imageId)
}
return nil
}
}
func TestBuilderAcc_windows(t *testing.T) {
t.Parallel()
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: testBuilderAccWindows,
})
}
const testBuilderAccWindows = `
{ "builders": [{
"type": "test",
"region": "cn-beijing",
"instance_type": "ecs.n1.tiny",
"source_image":"winsvr_64_dtcC_1809_en-us_40G_alibase_20190318.vhd",
"io_optimized":"true",
"communicator": "winrm",
"winrm_port": 5985,
"winrm_username": "Administrator",
"winrm_password": "Test1234",
"image_name": "packer-test-windows_{{timestamp}}",
"user_data_file": "../../../examples/alicloud/basic/winrm_enable_userdata.ps1"
}]
}`
func TestBuilderAcc_regionCopy(t *testing.T) {
t.Parallel()
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: testBuilderAccRegionCopy,
Check: checkRegionCopy([]string{"cn-hangzhou", "cn-shenzhen"}),
})
}
const testBuilderAccRegionCopy = `
{
"builders": [{
"type": "test",
"region": "cn-beijing",
"instance_type": "ecs.n1.tiny",
"source_image":"ubuntu_18_04_64_20G_alibase_20190509.vhd",
"io_optimized":"true",
"ssh_username":"root",
"image_name": "packer-test-regionCopy_{{timestamp}}",
"image_copy_regions": ["cn-hangzhou", "cn-shenzhen"],
"image_copy_names": ["packer-copy-test-hz_{{timestamp}}", "packer-copy-test-sz_{{timestamp}}"]
}]
}
`
func checkRegionCopy(regions []string) builderT.TestCheckFunc {
return func(artifacts []packer.Artifact) error {
if len(artifacts) > 1 {
return fmt.Errorf("more than 1 artifact")
}
// Get the actual *Artifact pointer so we can access the AMIs directly
artifactRaw := artifacts[0]
artifact, ok := artifactRaw.(*Artifact)
if !ok {
return fmt.Errorf("unknown artifact: %#v", artifactRaw)
}
// Verify that we copied to only the regions given
regionSet := make(map[string]struct{})
for _, r := range regions {
regionSet[r] = struct{}{}
}
for r := range artifact.AlicloudImages {
if r == "cn-beijing" {
delete(regionSet, r)
continue
}
if _, ok := regionSet[r]; !ok {
return fmt.Errorf("region %s is not the target region but found in artifacts", r)
}
delete(regionSet, r)
}
if len(regionSet) > 0 {
return fmt.Errorf("following region(s) should be the copying targets but corresponding artifact(s) not found: %#v", regionSet)
}
client, _ := testAliyunClient()
for regionId, imageId := range artifact.AlicloudImages {
describeImagesRequest := ecs.CreateDescribeImagesRequest()
describeImagesRequest.RegionId = regionId
describeImagesRequest.ImageId = imageId
describeImagesRequest.Status = ImageStatusQueried
describeImagesResponse, err := client.DescribeImages(describeImagesRequest)
if err != nil {
return fmt.Errorf("describe generated image %s failed due to %s", imageId, err)
}
if len(describeImagesResponse.Images.Image) == 0 {
return fmt.Errorf("image %s in artifacts can not be found", imageId)
}
image := describeImagesResponse.Images.Image[0]
if image.IsCopied && regionId == "cn-hangzhou" && !strings.HasPrefix(image.ImageName, "packer-copy-test-hz") {
return fmt.Errorf("the name of image %s in artifacts should begin with %s but got %s", imageId, "packer-copy-test-hz", image.ImageName)
}
if image.IsCopied && regionId == "cn-shenzhen" && !strings.HasPrefix(image.ImageName, "packer-copy-test-sz") {
return fmt.Errorf("the name of image %s in artifacts should begin with %s but got %s", imageId, "packer-copy-test-sz", image.ImageName)
}
}
return nil
}
}
func TestBuilderAcc_forceDelete(t *testing.T) {
t.Parallel()
// Build the same alicloud image twice, with ecs_image_force_delete on the second run
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: buildForceDeregisterConfig("false", "delete"),
SkipArtifactTeardown: true,
})
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: buildForceDeregisterConfig("true", "delete"),
})
}
func buildForceDeregisterConfig(val, name string) string {
return fmt.Sprintf(testBuilderAccForceDelete, val, name)
}
const testBuilderAccForceDelete = `
{
"builders": [{
"type": "test",
"region": "cn-beijing",
"instance_type": "ecs.n1.tiny",
"source_image":"ubuntu_18_04_64_20G_alibase_20190509.vhd",
"io_optimized":"true",
"ssh_username":"root",
"image_force_delete": "%s",
"image_name": "packer-test-forceDelete_%s"
}]
}
`
func TestBuilderAcc_ECSImageSharing(t *testing.T) {
t.Parallel()
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: testBuilderAccSharing,
Check: checkECSImageSharing("1309208528360047"),
})
}
const testBuilderAccSharing = `
{
"builders": [{
"type": "test",
"region": "cn-beijing",
"instance_type": "ecs.n1.tiny",
"source_image":"ubuntu_18_04_64_20G_alibase_20190509.vhd",
"io_optimized":"true",
"ssh_username":"root",
"image_name": "packer-test-ECSImageSharing_{{timestamp}}",
"image_share_account":["1309208528360047"]
}]
}
`
func checkECSImageSharing(uid string) builderT.TestCheckFunc {
return func(artifacts []packer.Artifact) error {
if len(artifacts) > 1 {
return fmt.Errorf("more than 1 artifact")
}
// Get the actual *Artifact pointer so we can access the AMIs directly
artifactRaw := artifacts[0]
artifact, ok := artifactRaw.(*Artifact)
if !ok {
return fmt.Errorf("unknown artifact: %#v", artifactRaw)
}
// describe the image, get block devices with a snapshot
client, _ := testAliyunClient()
describeImageShareRequest := ecs.CreateDescribeImageSharePermissionRequest()
describeImageShareRequest.RegionId = "cn-beijing"
describeImageShareRequest.ImageId = artifact.AlicloudImages["cn-beijing"]
imageShareResponse, err := client.DescribeImageSharePermission(describeImageShareRequest)
if err != nil {
return fmt.Errorf("Error retrieving Image Attributes for ECS Image Artifact (%#v) "+
"in ECS Image Sharing Test: %s", artifact, err)
}
if len(imageShareResponse.Accounts.Account) != 1 && imageShareResponse.Accounts.Account[0].AliyunId != uid {
return fmt.Errorf("share account is incorrect %d", len(imageShareResponse.Accounts.Account))
}
return nil
}
}
func TestBuilderAcc_forceDeleteSnapshot(t *testing.T) {
t.Parallel()
destImageName := "delete"
// Build the same alicloud image name twice, with force_delete_snapshot on the second run
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: buildForceDeleteSnapshotConfig("false", destImageName),
SkipArtifactTeardown: true,
})
// Get image data by image image name
client, _ := testAliyunClient()
describeImagesRequest := ecs.CreateDescribeImagesRequest()
describeImagesRequest.RegionId = "cn-beijing"
describeImagesRequest.ImageName = "packer-test-" + destImageName
images, _ := client.DescribeImages(describeImagesRequest)
image := images.Images.Image[0]
// Get snapshot ids for image
snapshotIds := []string{}
for _, device := range image.DiskDeviceMappings.DiskDeviceMapping {
if device.Device != "" && device.SnapshotId != "" {
snapshotIds = append(snapshotIds, device.SnapshotId)
}
}
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: buildForceDeleteSnapshotConfig("true", destImageName),
Check: checkSnapshotsDeleted(snapshotIds),
})
}
func buildForceDeleteSnapshotConfig(val, name string) string {
return fmt.Sprintf(testBuilderAccForceDeleteSnapshot, val, val, name)
}
const testBuilderAccForceDeleteSnapshot = `
{
"builders": [{
"type": "test",
"region": "cn-beijing",
"instance_type": "ecs.n1.tiny",
"source_image":"ubuntu_18_04_64_20G_alibase_20190509.vhd",
"io_optimized":"true",
"ssh_username":"root",
"image_force_delete_snapshots": "%s",
"image_force_delete": "%s",
"image_name": "packer-test-%s"
}]
}
`
func checkSnapshotsDeleted(snapshotIds []string) builderT.TestCheckFunc {
return func(artifacts []packer.Artifact) error {
// Verify the snapshots are gone
client, _ := testAliyunClient()
data, err := json.Marshal(snapshotIds)
if err != nil {
return fmt.Errorf("Marshal snapshotIds array failed %v", err)
}
describeSnapshotsRequest := ecs.CreateDescribeSnapshotsRequest()
describeSnapshotsRequest.RegionId = "cn-beijing"
describeSnapshotsRequest.SnapshotIds = string(data)
snapshotResp, err := client.DescribeSnapshots(describeSnapshotsRequest)
if err != nil {
return fmt.Errorf("Query snapshot failed %v", err)
}
snapshots := snapshotResp.Snapshots.Snapshot
if len(snapshots) > 0 {
return fmt.Errorf("Snapshots weren't successfully deleted by " +
"`ecs_image_force_delete_snapshots`")
}
return nil
}
}
func TestBuilderAcc_imageTags(t *testing.T) {
t.Parallel()
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: testBuilderAccImageTags,
Check: checkImageTags(),
})
}
const testBuilderAccImageTags = `
{ "builders": [{
"type": "test",
"region": "cn-beijing",
"instance_type": "ecs.n1.tiny",
"source_image":"ubuntu_18_04_64_20G_alibase_20190509.vhd",
"ssh_username": "root",
"io_optimized":"true",
"image_name": "packer-test-imageTags_{{timestamp}}",
"tags": {
"TagKey1": "TagValue1",
"TagKey2": "TagValue2"
}
}]
}`
func checkImageTags() builderT.TestCheckFunc {
return func(artifacts []packer.Artifact) error {
if len(artifacts) > 1 {
return fmt.Errorf("more than 1 artifact")
}
// Get the actual *Artifact pointer so we can access the AMIs directly
artifactRaw := artifacts[0]
artifact, ok := artifactRaw.(*Artifact)
if !ok {
return fmt.Errorf("unknown artifact: %#v", artifactRaw)
}
imageId := artifact.AlicloudImages[defaultTestRegion]
// describe the image, get block devices with a snapshot
client, _ := testAliyunClient()
describeImageTagsRequest := ecs.CreateDescribeTagsRequest()
describeImageTagsRequest.RegionId = defaultTestRegion
describeImageTagsRequest.ResourceType = TagResourceImage
describeImageTagsRequest.ResourceId = imageId
imageTagsResponse, err := client.DescribeTags(describeImageTagsRequest)
if err != nil {
return fmt.Errorf("Error retrieving Image Attributes for ECS Image Artifact (%#v) "+
"in ECS Image Tags Test: %s", artifact, err)
}
if len(imageTagsResponse.Tags.Tag) != 2 {
return fmt.Errorf("expect 2 tags set on image %s but got %d", imageId, len(imageTagsResponse.Tags.Tag))
}
for _, tag := range imageTagsResponse.Tags.Tag {
if tag.TagKey != "TagKey1" && tag.TagKey != "TagKey2" {
return fmt.Errorf("tags on image %s should be within the list of TagKey1 and TagKey2 but got %s", imageId, tag.TagKey)
}
if tag.TagKey == "TagKey1" && tag.TagValue != "TagValue1" {
return fmt.Errorf("the value for tag %s on image %s should be TagValue1 but got %s", tag.TagKey, imageId, tag.TagValue)
} else if tag.TagKey == "TagKey2" && tag.TagValue != "TagValue2" {
return fmt.Errorf("the value for tag %s on image %s should be TagValue2 but got %s", tag.TagKey, imageId, tag.TagValue)
}
}
describeImagesRequest := ecs.CreateDescribeImagesRequest()
describeImagesRequest.RegionId = defaultTestRegion
describeImagesRequest.ImageId = imageId
imagesResponse, err := client.DescribeImages(describeImagesRequest)
if err != nil {
return fmt.Errorf("describe images failed due to %s", err)
}
if len(imagesResponse.Images.Image) == 0 {
return fmt.Errorf("image %s generated can not be found", imageId)
}
image := imagesResponse.Images.Image[0]
for _, mapping := range image.DiskDeviceMappings.DiskDeviceMapping {
describeSnapshotTagsRequest := ecs.CreateDescribeTagsRequest()
describeSnapshotTagsRequest.RegionId = defaultTestRegion
describeSnapshotTagsRequest.ResourceType = TagResourceSnapshot
describeSnapshotTagsRequest.ResourceId = mapping.SnapshotId
snapshotTagsResponse, err := client.DescribeTags(describeSnapshotTagsRequest)
if err != nil {
return fmt.Errorf("failed to get snapshot tags due to %s", err)
}
if len(snapshotTagsResponse.Tags.Tag) != 2 {
return fmt.Errorf("expect 2 tags set on snapshot %s but got %d", mapping.SnapshotId, len(snapshotTagsResponse.Tags.Tag))
}
for _, tag := range snapshotTagsResponse.Tags.Tag {
if tag.TagKey != "TagKey1" && tag.TagKey != "TagKey2" {
return fmt.Errorf("tags on snapshot %s should be within the list of TagKey1 and TagKey2 but got %s", mapping.SnapshotId, tag.TagKey)
}
if tag.TagKey == "TagKey1" && tag.TagValue != "TagValue1" {
return fmt.Errorf("the value for tag %s on snapshot %s should be TagValue1 but got %s", tag.TagKey, mapping.SnapshotId, tag.TagValue)
} else if tag.TagKey == "TagKey2" && tag.TagValue != "TagValue2" {
return fmt.Errorf("the value for tag %s on snapshot %s should be TagValue2 but got %s", tag.TagKey, mapping.SnapshotId, tag.TagValue)
}
}
}
return nil
}
}
func TestBuilderAcc_dataDiskEncrypted(t *testing.T) {
t.Parallel()
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: testBuilderAccDataDiskEncrypted,
Check: checkDataDiskEncrypted(),
})
}
const testBuilderAccDataDiskEncrypted = `
{ "builders": [{
"type": "test",
"region": "cn-beijing",
"instance_type": "ecs.n1.tiny",
"source_image":"ubuntu_18_04_64_20G_alibase_20190509.vhd",
"io_optimized":"true",
"ssh_username":"root",
"image_name": "packer-test-dataDiskEncrypted_{{timestamp}}",
"image_disk_mappings": [
{
"disk_name": "data_disk1",
"disk_size": 25,
"disk_encrypted": true,
"disk_delete_with_instance": true
},
{
"disk_name": "data_disk2",
"disk_size": 35,
"disk_encrypted": false,
"disk_delete_with_instance": true
},
{
"disk_name": "data_disk3",
"disk_size": 45,
"disk_delete_with_instance": true
}
]
}]
}`
func checkDataDiskEncrypted() builderT.TestCheckFunc {
return func(artifacts []packer.Artifact) error {
if len(artifacts) > 1 {
return fmt.Errorf("more than 1 artifact")
}
// Get the actual *Artifact pointer so we can access the AMIs directly
artifactRaw := artifacts[0]
artifact, ok := artifactRaw.(*Artifact)
if !ok {
return fmt.Errorf("unknown artifact: %#v", artifactRaw)
}
imageId := artifact.AlicloudImages[defaultTestRegion]
// describe the image, get block devices with a snapshot
client, _ := testAliyunClient()
describeImagesRequest := ecs.CreateDescribeImagesRequest()
describeImagesRequest.RegionId = defaultTestRegion
describeImagesRequest.ImageId = imageId
imagesResponse, err := client.DescribeImages(describeImagesRequest)
if err != nil {
return fmt.Errorf("describe images failed due to %s", err)
}
if len(imagesResponse.Images.Image) == 0 {
return fmt.Errorf("image %s generated can not be found", imageId)
}
image := imagesResponse.Images.Image[0]
var snapshotIds []string
for _, mapping := range image.DiskDeviceMappings.DiskDeviceMapping {
snapshotIds = append(snapshotIds, mapping.SnapshotId)
}
data, _ := json.Marshal(snapshotIds)
describeSnapshotRequest := ecs.CreateDescribeSnapshotsRequest()
describeSnapshotRequest.RegionId = defaultTestRegion
describeSnapshotRequest.SnapshotIds = string(data)
describeSnapshotsResponse, err := client.DescribeSnapshots(describeSnapshotRequest)
if err != nil {
return fmt.Errorf("describe data snapshots failed due to %s", err)
}
if len(describeSnapshotsResponse.Snapshots.Snapshot) != 4 {
return fmt.Errorf("expect %d data snapshots but got %d", len(snapshotIds), len(describeSnapshotsResponse.Snapshots.Snapshot))
}
snapshots := describeSnapshotsResponse.Snapshots.Snapshot
for _, snapshot := range snapshots {
if snapshot.SourceDiskType == DiskTypeSystem {
if snapshot.Encrypted != false {
return fmt.Errorf("the system snapshot expected to be non-encrypted but got true")
}
continue
}
if snapshot.SourceDiskSize == "25" && snapshot.Encrypted != true {
return fmt.Errorf("the first snapshot expected to be encrypted but got false")
}
if snapshot.SourceDiskSize == "35" && snapshot.Encrypted != false {
return fmt.Errorf("the second snapshot expected to be non-encrypted but got true")
}
if snapshot.SourceDiskSize == "45" && snapshot.Encrypted != false {
return fmt.Errorf("the third snapshot expected to be non-encrypted but got true")
}
}
return nil
}
}
func TestBuilderAcc_systemDiskEncrypted(t *testing.T) {
t.Parallel()
builderT.Test(t, builderT.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Builder: &Builder{},
Template: testBuilderAccSystemDiskEncrypted,
Check: checkSystemDiskEncrypted(),
})
}
const testBuilderAccSystemDiskEncrypted = `
{
"builders": [{
"type": "test",
"region": "cn-beijing",
"instance_type": "ecs.n1.tiny",
"source_image":"ubuntu_18_04_64_20G_alibase_20190509.vhd",
"io_optimized":"true",
"ssh_username":"root",
"image_name": "packer-test_{{timestamp}}",
"image_encrypted": "true"
}]
}`
func checkSystemDiskEncrypted() builderT.TestCheckFunc {
return func(artifacts []packer.Artifact) error {
if len(artifacts) > 1 {
return fmt.Errorf("more than 1 artifact")
}
// Get the actual *Artifact pointer so we can access the AMIs directly
artifactRaw := artifacts[0]
artifact, ok := artifactRaw.(*Artifact)
if !ok {
return fmt.Errorf("unknown artifact: %#v", artifactRaw)
}
// describe the image, get block devices with a snapshot
client, _ := testAliyunClient()
imageId := artifact.AlicloudImages[defaultTestRegion]
describeImagesRequest := ecs.CreateDescribeImagesRequest()
describeImagesRequest.RegionId = defaultTestRegion
describeImagesRequest.ImageId = imageId
describeImagesRequest.Status = ImageStatusQueried
imagesResponse, err := client.DescribeImages(describeImagesRequest)
if err != nil {
return fmt.Errorf("describe images failed due to %s", err)
}
if len(imagesResponse.Images.Image) == 0 {
return fmt.Errorf("image %s generated can not be found", imageId)
}
image := imagesResponse.Images.Image[0]
if image.IsCopied == false {
return fmt.Errorf("image %s generated expexted to be copied but false", image.ImageId)
}
describeSnapshotRequest := ecs.CreateDescribeSnapshotsRequest()
describeSnapshotRequest.RegionId = defaultTestRegion
describeSnapshotRequest.SnapshotIds = fmt.Sprintf("[\"%s\"]", image.DiskDeviceMappings.DiskDeviceMapping[0].SnapshotId)
describeSnapshotsResponse, err := client.DescribeSnapshots(describeSnapshotRequest)
if err != nil {
return fmt.Errorf("describe system snapshots failed due to %s", err)
}
snapshots := describeSnapshotsResponse.Snapshots.Snapshot[0]
if snapshots.Encrypted != true {
return fmt.Errorf("system snapshot of image %s expected to be encrypted but got false", imageId)
}
return nil
}
}
func testAccPreCheck(t *testing.T) {
if v := os.Getenv("ALICLOUD_ACCESS_KEY"); v == "" {
t.Fatal("ALICLOUD_ACCESS_KEY must be set for acceptance tests")
}
if v := os.Getenv("ALICLOUD_SECRET_KEY"); v == "" {
t.Fatal("ALICLOUD_SECRET_KEY must be set for acceptance tests")
}
}
func testAliyunClient() (*ClientWrapper, error) {
access := &AlicloudAccessConfig{AlicloudRegion: "cn-beijing"}
err := access.Config()
if err != nil {
return nil, err
}
client, err := access.Client()
if err != nil {
return nil, err
}
return client, nil
}

View File

@ -1,237 +0,0 @@
package ecs
import (
"reflect"
"testing"
helperconfig "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer"
)
func testBuilderConfig() map[string]interface{} {
return map[string]interface{}{
"access_key": "foo",
"secret_key": "bar",
"source_image": "foo",
"instance_type": "ecs.n1.tiny",
"region": "cn-beijing",
"ssh_username": "root",
"image_name": "foo",
"io_optimized": true,
}
}
func TestBuilder_ImplementsBuilder(t *testing.T) {
var raw interface{}
raw = &Builder{}
if _, ok := raw.(packer.Builder); !ok {
t.Fatalf("Builder should be a builder")
}
}
func TestBuilder_Prepare_BadType(t *testing.T) {
b := &Builder{}
c := map[string]interface{}{
"access_key": []string{},
}
_, warnings, err := b.Prepare(c)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err == nil {
t.Fatalf("prepare should fail")
}
}
func TestBuilderPrepare_ECSImageName(t *testing.T) {
var b Builder
config := testBuilderConfig()
// Test good
config["image_name"] = "ecs.n1.tiny"
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Fatalf("should not have error: %s", err)
}
// Test bad
config["ecs_image_name"] = "foo {{"
b = Builder{}
_, warnings, err = b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err == nil {
t.Fatal("should have error")
}
// Test bad
delete(config, "image_name")
b = Builder{}
_, warnings, err = b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err == nil {
t.Fatal("should have error")
}
}
func TestBuilderPrepare_InvalidKey(t *testing.T) {
var b Builder
config := testBuilderConfig()
// Add a random key
config["i_should_not_be_valid"] = true
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err == nil {
t.Fatal("should have error")
}
}
func TestBuilderPrepare_Devices(t *testing.T) {
var b Builder
config := testBuilderConfig()
config["system_disk_mapping"] = map[string]interface{}{
"disk_category": "cloud",
"disk_description": "system disk",
"disk_name": "system_disk",
"disk_size": 60,
}
config["image_disk_mappings"] = []map[string]interface{}{
{
"disk_category": "cloud_efficiency",
"disk_name": "data_disk1",
"disk_size": 100,
"disk_snapshot_id": "s-1",
"disk_description": "data disk1",
"disk_device": "/dev/xvdb",
"disk_delete_with_instance": false,
},
{
"disk_name": "data_disk2",
"disk_device": "/dev/xvdc",
},
}
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Fatalf("should not have error: %s", err)
}
expected := AlicloudDiskDevice{
DiskCategory: "cloud",
Description: "system disk",
DiskName: "system_disk",
DiskSize: 60,
Encrypted: helperconfig.TriUnset,
}
if !reflect.DeepEqual(b.config.ECSSystemDiskMapping, expected) {
t.Fatalf("system disk is not set properly, actual: %v; expected: %v", b.config.ECSSystemDiskMapping, expected)
}
if !reflect.DeepEqual(b.config.ECSImagesDiskMappings, []AlicloudDiskDevice{
{
DiskCategory: "cloud_efficiency",
DiskName: "data_disk1",
DiskSize: 100,
SnapshotId: "s-1",
Description: "data disk1",
Device: "/dev/xvdb",
DeleteWithInstance: false,
},
{
DiskName: "data_disk2",
Device: "/dev/xvdc",
},
}) {
t.Fatalf("data disks are not set properly, actual: %#v", b.config.ECSImagesDiskMappings)
}
}
func TestBuilderPrepare_IgnoreDataDisks(t *testing.T) {
var b Builder
config := testBuilderConfig()
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Fatalf("should not have error: %s", err)
}
if b.config.AlicloudImageIgnoreDataDisks != false {
t.Fatalf("image_ignore_data_disks is not set properly, expect: %t, actual: %t", false, b.config.AlicloudImageIgnoreDataDisks)
}
config["image_ignore_data_disks"] = "false"
_, warnings, err = b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Fatalf("should not have error: %s", err)
}
if b.config.AlicloudImageIgnoreDataDisks != false {
t.Fatalf("image_ignore_data_disks is not set properly, expect: %t, actual: %t", false, b.config.AlicloudImageIgnoreDataDisks)
}
config["image_ignore_data_disks"] = "true"
_, warnings, err = b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Fatalf("should not have error: %s", err)
}
if b.config.AlicloudImageIgnoreDataDisks != true {
t.Fatalf("image_ignore_data_disks is not set properly, expect: %t, actual: %t", true, b.config.AlicloudImageIgnoreDataDisks)
}
}
func TestBuilderPrepare_WaitSnapshotReadyTimeout(t *testing.T) {
var b Builder
config := testBuilderConfig()
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Fatalf("should not have error: %s", err)
}
if b.config.WaitSnapshotReadyTimeout != 0 {
t.Fatalf("wait_snapshot_ready_timeout is not set properly, expect: %d, actual: %d", 0, b.config.WaitSnapshotReadyTimeout)
}
if b.getSnapshotReadyTimeout() != ALICLOUD_DEFAULT_LONG_TIMEOUT {
t.Fatalf("default timeout is not set properly, expect: %d, actual: %d", ALICLOUD_DEFAULT_LONG_TIMEOUT, b.getSnapshotReadyTimeout())
}
config["wait_snapshot_ready_timeout"] = ALICLOUD_DEFAULT_TIMEOUT
_, warnings, err = b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Fatalf("should not have error: %s", err)
}
if b.config.WaitSnapshotReadyTimeout != ALICLOUD_DEFAULT_TIMEOUT {
t.Fatalf("wait_snapshot_ready_timeout is not set properly, expect: %d, actual: %d", ALICLOUD_DEFAULT_TIMEOUT, b.config.WaitSnapshotReadyTimeout)
}
if b.getSnapshotReadyTimeout() != ALICLOUD_DEFAULT_TIMEOUT {
t.Fatalf("default timeout is not set properly, expect: %d, actual: %d", ALICLOUD_DEFAULT_TIMEOUT, b.getSnapshotReadyTimeout())
}
}

View File

@ -1,310 +0,0 @@
package ecs
import (
"fmt"
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
)
type ClientWrapper struct {
*ecs.Client
}
const (
InstanceStatusRunning = "Running"
InstanceStatusStarting = "Starting"
InstanceStatusStopped = "Stopped"
InstanceStatusStopping = "Stopping"
)
const (
ImageStatusWaiting = "Waiting"
ImageStatusCreating = "Creating"
ImageStatusCreateFailed = "CreateFailed"
ImageStatusAvailable = "Available"
)
var ImageStatusQueried = fmt.Sprintf("%s,%s,%s,%s", ImageStatusWaiting, ImageStatusCreating, ImageStatusCreateFailed, ImageStatusAvailable)
const (
SnapshotStatusAll = "all"
SnapshotStatusProgressing = "progressing"
SnapshotStatusAccomplished = "accomplished"
SnapshotStatusFailed = "failed"
)
const (
DiskStatusInUse = "In_use"
DiskStatusAvailable = "Available"
DiskStatusAttaching = "Attaching"
DiskStatusDetaching = "Detaching"
DiskStatusCreating = "Creating"
DiskStatusReIniting = "ReIniting"
)
const (
VpcStatusPending = "Pending"
VpcStatusAvailable = "Available"
)
const (
VSwitchStatusPending = "Pending"
VSwitchStatusAvailable = "Available"
)
const (
EipStatusAssociating = "Associating"
EipStatusUnassociating = "Unassociating"
EipStatusInUse = "InUse"
EipStatusAvailable = "Available"
)
const (
ImageOwnerSystem = "system"
ImageOwnerSelf = "self"
ImageOwnerOthers = "others"
ImageOwnerMarketplace = "marketplace"
)
const (
IOOptimizedNone = "none"
IOOptimizedOptimized = "optimized"
)
const (
InstanceNetworkClassic = "classic"
InstanceNetworkVpc = "vpc"
)
const (
DiskTypeSystem = "system"
DiskTypeData = "data"
)
const (
TagResourceImage = "image"
TagResourceInstance = "instance"
TagResourceSnapshot = "snapshot"
TagResourceDisk = "disk"
)
const (
IpProtocolAll = "all"
IpProtocolTCP = "tcp"
IpProtocolUDP = "udp"
IpProtocolICMP = "icmp"
IpProtocolGRE = "gre"
)
const (
NicTypeInternet = "internet"
NicTypeIntranet = "intranet"
)
const (
DefaultPortRange = "-1/-1"
DefaultCidrIp = "0.0.0.0/0"
DefaultCidrBlock = "172.16.0.0/24"
)
const (
defaultRetryInterval = 5 * time.Second
defaultRetryTimes = 12
shortRetryTimes = 36
mediumRetryTimes = 360
longRetryTimes = 720
)
type WaitForExpectEvalResult struct {
evalPass bool
stopRetry bool
}
var (
WaitForExpectSuccess = WaitForExpectEvalResult{
evalPass: true,
stopRetry: true,
}
WaitForExpectToRetry = WaitForExpectEvalResult{
evalPass: false,
stopRetry: false,
}
WaitForExpectFailToStop = WaitForExpectEvalResult{
evalPass: false,
stopRetry: true,
}
)
type WaitForExpectArgs struct {
RequestFunc func() (responses.AcsResponse, error)
EvalFunc func(response responses.AcsResponse, err error) WaitForExpectEvalResult
RetryInterval time.Duration
RetryTimes int
RetryTimeout time.Duration
}
func (c *ClientWrapper) WaitForExpected(args *WaitForExpectArgs) (responses.AcsResponse, error) {
if args.RetryInterval <= 0 {
args.RetryInterval = defaultRetryInterval
}
if args.RetryTimes <= 0 {
args.RetryTimes = defaultRetryTimes
}
var timeoutPoint time.Time
if args.RetryTimeout > 0 {
timeoutPoint = time.Now().Add(args.RetryTimeout)
}
var lastResponse responses.AcsResponse
var lastError error
for i := 0; ; i++ {
if args.RetryTimeout > 0 && time.Now().After(timeoutPoint) {
break
}
if args.RetryTimeout <= 0 && i >= args.RetryTimes {
break
}
response, err := args.RequestFunc()
lastResponse = response
lastError = err
evalResult := args.EvalFunc(response, err)
if evalResult.evalPass {
return response, nil
}
if evalResult.stopRetry {
return response, err
}
time.Sleep(args.RetryInterval)
}
if lastError == nil {
lastError = fmt.Errorf("<no error>")
}
if args.RetryTimeout > 0 {
return lastResponse, fmt.Errorf("evaluate failed after %d seconds timeout with %d seconds retry interval: %s", int(args.RetryTimeout.Seconds()), int(args.RetryInterval.Seconds()), lastError)
}
return lastResponse, fmt.Errorf("evaluate failed after %d times retry with %d seconds retry interval: %s", args.RetryTimes, int(args.RetryInterval.Seconds()), lastError)
}
func (c *ClientWrapper) WaitForInstanceStatus(regionId string, instanceId string, expectedStatus string) (responses.AcsResponse, error) {
return c.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
request := ecs.CreateDescribeInstancesRequest()
request.RegionId = regionId
request.InstanceIds = fmt.Sprintf("[\"%s\"]", instanceId)
return c.DescribeInstances(request)
},
EvalFunc: func(response responses.AcsResponse, err error) WaitForExpectEvalResult {
if err != nil {
return WaitForExpectToRetry
}
instancesResponse := response.(*ecs.DescribeInstancesResponse)
instances := instancesResponse.Instances.Instance
for _, instance := range instances {
if instance.Status == expectedStatus {
return WaitForExpectSuccess
}
}
return WaitForExpectToRetry
},
RetryTimes: mediumRetryTimes,
})
}
func (c *ClientWrapper) WaitForImageStatus(regionId string, imageId string, expectedStatus string, timeout time.Duration) (responses.AcsResponse, error) {
return c.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
request := ecs.CreateDescribeImagesRequest()
request.RegionId = regionId
request.ImageId = imageId
request.Status = ImageStatusQueried
return c.DescribeImages(request)
},
EvalFunc: func(response responses.AcsResponse, err error) WaitForExpectEvalResult {
if err != nil {
return WaitForExpectToRetry
}
imagesResponse := response.(*ecs.DescribeImagesResponse)
images := imagesResponse.Images.Image
for _, image := range images {
if image.Status == expectedStatus {
return WaitForExpectSuccess
}
}
return WaitForExpectToRetry
},
RetryTimeout: timeout,
})
}
func (c *ClientWrapper) WaitForSnapshotStatus(regionId string, snapshotId string, expectedStatus string, timeout time.Duration) (responses.AcsResponse, error) {
return c.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
request := ecs.CreateDescribeSnapshotsRequest()
request.RegionId = regionId
request.SnapshotIds = fmt.Sprintf("[\"%s\"]", snapshotId)
return c.DescribeSnapshots(request)
},
EvalFunc: func(response responses.AcsResponse, err error) WaitForExpectEvalResult {
if err != nil {
return WaitForExpectToRetry
}
snapshotsResponse := response.(*ecs.DescribeSnapshotsResponse)
snapshots := snapshotsResponse.Snapshots.Snapshot
for _, snapshot := range snapshots {
if snapshot.Status == expectedStatus {
return WaitForExpectSuccess
}
}
return WaitForExpectToRetry
},
RetryTimeout: timeout,
})
}
type EvalErrorType bool
const (
EvalRetryErrorType = EvalErrorType(true)
EvalNotRetryErrorType = EvalErrorType(false)
)
func (c *ClientWrapper) EvalCouldRetryResponse(evalErrors []string, evalErrorType EvalErrorType) func(response responses.AcsResponse, err error) WaitForExpectEvalResult {
return func(response responses.AcsResponse, err error) WaitForExpectEvalResult {
if err == nil {
return WaitForExpectSuccess
}
e, ok := err.(errors.Error)
if !ok {
return WaitForExpectToRetry
}
if evalErrorType == EvalRetryErrorType && !ContainsInArray(evalErrors, e.ErrorCode()) {
return WaitForExpectFailToStop
}
if evalErrorType == EvalNotRetryErrorType && ContainsInArray(evalErrors, e.ErrorCode()) {
return WaitForExpectFailToStop
}
return WaitForExpectToRetry
}
}

View File

@ -1,80 +0,0 @@
package ecs
import (
"fmt"
"testing"
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
)
func TestWaitForExpectedExceedRetryTimes(t *testing.T) {
c := ClientWrapper{}
iter := 0
waitDone := make(chan bool, 1)
go func() {
_, _ = c.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
iter++
return nil, fmt.Errorf("test: let iteration %d failed", iter)
},
EvalFunc: func(response responses.AcsResponse, err error) WaitForExpectEvalResult {
if err != nil {
fmt.Printf("need retry: %s\n", err)
return WaitForExpectToRetry
}
return WaitForExpectSuccess
},
})
waitDone <- true
}()
select {
case <-waitDone:
if iter != defaultRetryTimes {
t.Fatalf("WaitForExpected should terminate at the %d iterations", defaultRetryTimes)
}
}
}
func TestWaitForExpectedExceedRetryTimeout(t *testing.T) {
c := ClientWrapper{}
expectTimeout := 10 * time.Second
iter := 0
waitDone := make(chan bool, 1)
go func() {
_, _ = c.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
iter++
return nil, fmt.Errorf("test: let iteration %d failed", iter)
},
EvalFunc: func(response responses.AcsResponse, err error) WaitForExpectEvalResult {
if err != nil {
fmt.Printf("need retry: %s\n", err)
return WaitForExpectToRetry
}
return WaitForExpectSuccess
},
RetryTimeout: expectTimeout,
})
waitDone <- true
}()
timeTolerance := 1 * time.Second
select {
case <-waitDone:
if iter > int(expectTimeout/defaultRetryInterval) {
t.Fatalf("WaitForExpected should terminate before the %d iterations", int(expectTimeout/defaultRetryInterval))
}
case <-time.After(expectTimeout + timeTolerance):
t.Fatalf("WaitForExpected should terminate within %f seconds", (expectTimeout + timeTolerance).Seconds())
}
}

View File

@ -1,238 +0,0 @@
//go:generate struct-markdown
package ecs
import (
"fmt"
"regexp"
"strings"
"github.com/hashicorp/packer/hcl2template"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
type AlicloudDiskDevice struct {
// The value of disk name is blank by default. [2,
// 128] English or Chinese characters, must begin with an
// uppercase/lowercase letter or Chinese character. Can contain numbers,
// ., _ and -. The disk name will appear on the console. It cannot
// begin with `http://` or `https://`.
DiskName string `mapstructure:"disk_name" required:"false"`
// Category of the system disk. Optional values
// are:
// - cloud - general cloud disk
// - cloud_efficiency - efficiency cloud disk
// - cloud_ssd - cloud SSD
DiskCategory string `mapstructure:"disk_category" required:"false"`
// Size of the system disk, measured in GiB. Value
// range: [20, 500]. The specified value must be equal to or greater
// than max{20, ImageSize}. Default value: max{40, ImageSize}.
DiskSize int `mapstructure:"disk_size" required:"false"`
// Snapshots are used to create the data
// disk After this parameter is specified, Size is ignored. The actual
// size of the created disk is the size of the specified snapshot.
SnapshotId string `mapstructure:"disk_snapshot_id" required:"false"`
// The value of disk description is blank by
// default. [2, 256] characters. The disk description will appear on the
// console. It cannot begin with `http://` or `https://`.
Description string `mapstructure:"disk_description" required:"false"`
// Whether or not the disk is
// released along with the instance:
DeleteWithInstance bool `mapstructure:"disk_delete_with_instance" required:"false"`
// Device information of the related instance:
// such as /dev/xvdb It is null unless the Status is In_use.
Device string `mapstructure:"disk_device" required:"false"`
// Whether or not to encrypt the data disk.
// If this option is set to true, the data disk will be encryped and corresponding snapshot in the target image will also be encrypted. By
// default, if this is an extra data disk, Packer will not encrypt the
// data disk. Otherwise, Packer will keep the encryption setting to what
// it was in the source image. Please refer to Introduction of ECS disk encryption
// for more details.
Encrypted config.Trilean `mapstructure:"disk_encrypted" required:"false"`
}
type AlicloudDiskDevices struct {
// Image disk mapping for system
// disk.
// - `disk_category` (string) - Category of the system disk. Optional values
// are:
// - `cloud` - general cloud disk
// - `cloud_efficiency` - efficiency cloud disk
// - `cloud_ssd` - cloud SSD
//
// For phased-out instance types and non-I/O optimized instances, the
// default value is cloud. Otherwise, the default value is
// cloud\_efficiency.
//
// - `disk_description` (string) - The value of disk description is blank by
// default. \[2, 256\] characters. The disk description will appear on the
// console. It cannot begin with `http://` or `https://`.
//
// - `disk_name` (string) - The value of disk name is blank by default. \[2,
// 128\] English or Chinese characters, must begin with an
// uppercase/lowercase letter or Chinese character. Can contain numbers,
// `.`, `_` and `-`. The disk name will appear on the console. It cannot
// begin with `http://` or `https://`.
//
// - `disk_size` (number) - Size of the system disk, measured in GiB. Value
// range: \[20, 500\]. The specified value must be equal to or greater
// than max{20, ImageSize}. Default value: max{40, ImageSize}.
//
ECSSystemDiskMapping AlicloudDiskDevice `mapstructure:"system_disk_mapping" required:"false"`
// Add one or more data
// disks to the image.
//
// - `disk_category` (string) - Category of the data disk. Optional values
// are:
// - `cloud` - general cloud disk
// - `cloud_efficiency` - efficiency cloud disk
// - `cloud_ssd` - cloud SSD
//
// Default value: cloud.
//
// - `disk_delete_with_instance` (boolean) - Whether or not the disk is
// released along with the instance:
// - True indicates that when the instance is released, this disk will
// be released with it
// - False indicates that when the instance is released, this disk will
// be retained.
// - `disk_description` (string) - The value of disk description is blank by
// default. \[2, 256\] characters. The disk description will appear on the
// console. It cannot begin with `http://` or `https://`.
//
// - `disk_device` (string) - Device information of the related instance:
// such as `/dev/xvdb` It is null unless the Status is In\_use.
//
// - `disk_name` (string) - The value of disk name is blank by default. \[2,
// 128\] English or Chinese characters, must begin with an
// uppercase/lowercase letter or Chinese character. Can contain numbers,
// `.`, `_` and `-`. The disk name will appear on the console. It cannot
// begin with `http://` or `https://`.
//
// - `disk_size` (number) - Size of the data disk, in GB, values range:
// - `cloud` - 5 \~ 2000
// - `cloud_efficiency` - 20 \~ 2048
// - `cloud_ssd` - 20 \~ 2048
//
// The value should be equal to or greater than the size of the specific
// SnapshotId.
//
// - `disk_snapshot_id` (string) - Snapshots are used to create the data
// disk After this parameter is specified, Size is ignored. The actual
// size of the created disk is the size of the specified snapshot.
//
// Snapshots from on or before July 15, 2013 cannot be used to create a
// disk.
//
// - `disk_encrypted` (boolean) - Whether or not to encrypt the data disk.
// If this option is set to true, the data disk will be encryped and corresponding snapshot in the target image will also be encrypted. By
// default, if this is an extra data disk, Packer will not encrypt the
// data disk. Otherwise, Packer will keep the encryption setting to what
// it was in the source image. Please refer to Introduction of [ECS disk encryption](https://www.alibabacloud.com/help/doc-detail/59643.htm)
// for more details.
//
ECSImagesDiskMappings []AlicloudDiskDevice `mapstructure:"image_disk_mappings" required:"false"`
}
type AlicloudImageConfig struct {
// The name of the user-defined image, [2, 128] English or Chinese
// characters. It must begin with an uppercase/lowercase letter or a
// Chinese character, and may contain numbers, `_` or `-`. It cannot begin
// with `http://` or `https://`.
AlicloudImageName string `mapstructure:"image_name" required:"true"`
// The version number of the image, with a length limit of 1 to 40 English
// characters.
AlicloudImageVersion string `mapstructure:"image_version" required:"false"`
// The description of the image, with a length limit of 0 to 256
// characters. Leaving it blank means null, which is the default value. It
// cannot begin with `http://` or `https://`.
AlicloudImageDescription string `mapstructure:"image_description" required:"false"`
// The IDs of to-be-added Aliyun accounts to which the image is shared. The
// number of accounts is 1 to 10. If number of accounts is greater than 10,
// this parameter is ignored.
AlicloudImageShareAccounts []string `mapstructure:"image_share_account" required:"false"`
AlicloudImageUNShareAccounts []string `mapstructure:"image_unshare_account"`
// Copy to the destination regionIds.
AlicloudImageDestinationRegions []string `mapstructure:"image_copy_regions" required:"false"`
// The name of the destination image, [2, 128] English or Chinese
// characters. It must begin with an uppercase/lowercase letter or a
// Chinese character, and may contain numbers, _ or -. It cannot begin with
// `http://` or `https://`.
AlicloudImageDestinationNames []string `mapstructure:"image_copy_names" required:"false"`
// Whether or not to encrypt the target images, including those
// copied if image_copy_regions is specified. If this option is set to
// true, a temporary image will be created from the provisioned instance in
// the main region and an encrypted copy will be generated in the same
// region. By default, Packer will keep the encryption setting to what it
// was in the source image.
ImageEncrypted config.Trilean `mapstructure:"image_encrypted" required:"false"`
// If this value is true, when the target image names including those
// copied are duplicated with existing images, it will delete the existing
// images and then create the target images, otherwise, the creation will
// fail. The default value is false. Check `image_name` and
// `image_copy_names` options for names of target images. If
// [-force](/docs/commands/build#force) option is provided in `build`
// command, this option can be omitted and taken as true.
AlicloudImageForceDelete bool `mapstructure:"image_force_delete" required:"false"`
// If this value is true, when delete the duplicated existing images, the
// source snapshots of those images will be delete either. If
// [-force](/docs/commands/build#force) option is provided in `build`
// command, this option can be omitted and taken as true.
AlicloudImageForceDeleteSnapshots bool `mapstructure:"image_force_delete_snapshots" required:"false"`
AlicloudImageForceDeleteInstances bool `mapstructure:"image_force_delete_instances"`
// If this value is true, the image created will not include any snapshot
// of data disks. This option would be useful for any circumstance that
// default data disks with instance types are not concerned. The default
// value is false.
AlicloudImageIgnoreDataDisks bool `mapstructure:"image_ignore_data_disks" required:"false"`
// The region validation can be skipped if this value is true, the default
// value is false.
AlicloudImageSkipRegionValidation bool `mapstructure:"skip_region_validation" required:"false"`
// Key/value pair tags applied to the destination image and relevant
// snapshots.
AlicloudImageTags map[string]string `mapstructure:"tags" required:"false"`
// Same as [`tags`](#tags) but defined as a singular repeatable block
// containing a `key` and a `value` field. In HCL2 mode the
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
AlicloudImageTag hcl2template.KeyValues `mapstructure:"tag" required:"false"`
AlicloudDiskDevices `mapstructure:",squash"`
}
func (c *AlicloudImageConfig) Prepare(ctx *interpolate.Context) []error {
var errs []error
errs = append(errs, c.AlicloudImageTag.CopyOn(&c.AlicloudImageTags)...)
if c.AlicloudImageName == "" {
errs = append(errs, fmt.Errorf("image_name must be specified"))
} else if len(c.AlicloudImageName) < 2 || len(c.AlicloudImageName) > 128 {
errs = append(errs, fmt.Errorf("image_name must less than 128 letters and more than 1 letters"))
} else if strings.HasPrefix(c.AlicloudImageName, "http://") ||
strings.HasPrefix(c.AlicloudImageName, "https://") {
errs = append(errs, fmt.Errorf("image_name can't start with 'http://' or 'https://'"))
}
reg := regexp.MustCompile(`\s+`)
if reg.FindString(c.AlicloudImageName) != "" {
errs = append(errs, fmt.Errorf("image_name can't include spaces"))
}
if len(c.AlicloudImageDestinationRegions) > 0 {
regionSet := make(map[string]struct{})
regions := make([]string, 0, len(c.AlicloudImageDestinationRegions))
for _, region := range c.AlicloudImageDestinationRegions {
// If we already saw the region, then don't look again
if _, ok := regionSet[region]; ok {
continue
}
// Mark that we saw the region
regionSet[region] = struct{}{}
regions = append(regions, region)
}
c.AlicloudImageDestinationRegions = regions
}
return errs
}

View File

@ -1,61 +0,0 @@
package ecs
import (
"testing"
)
func testAlicloudImageConfig() *AlicloudImageConfig {
return &AlicloudImageConfig{
AlicloudImageName: "foo",
}
}
func TestECSImageConfigPrepare_name(t *testing.T) {
c := testAlicloudImageConfig()
if err := c.Prepare(nil); err != nil {
t.Fatalf("shouldn't have err: %s", err)
}
c.AlicloudImageName = ""
if err := c.Prepare(nil); err == nil {
t.Fatal("should have error")
}
}
func TestAMIConfigPrepare_regions(t *testing.T) {
c := testAlicloudImageConfig()
c.AlicloudImageDestinationRegions = nil
if err := c.Prepare(nil); err != nil {
t.Fatalf("shouldn't have err: %s", err)
}
c.AlicloudImageDestinationRegions = []string{"cn-beijing", "cn-hangzhou", "eu-central-1"}
if err := c.Prepare(nil); err != nil {
t.Fatalf("bad: %s", err)
}
c.AlicloudImageDestinationRegions = nil
c.AlicloudImageSkipRegionValidation = true
if err := c.Prepare(nil); err != nil {
t.Fatal("shouldn't have error")
}
c.AlicloudImageSkipRegionValidation = false
}
func TestECSImageConfigPrepare_imageTags(t *testing.T) {
c := testAlicloudImageConfig()
c.AlicloudImageTags = map[string]string{
"TagKey1": "TagValue1",
"TagKey2": "TagValue2",
}
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if len(c.AlicloudImageTags) != 2 || c.AlicloudImageTags["TagKey1"] != "TagValue1" ||
c.AlicloudImageTags["TagKey2"] != "TagValue2" {
t.Fatalf("invalid value, expected: %s, actual: %s", map[string]string{
"TagKey1": "TagValue1",
"TagKey2": "TagValue2",
}, c.AlicloudImageTags)
}
}

View File

@ -1,52 +0,0 @@
package ecs
import (
"fmt"
"strconv"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
func cleanUpMessage(state multistep.StateBag, module string) {
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
ui := state.Get("ui").(packer.Ui)
if cancelled || halted {
ui.Say(fmt.Sprintf("Deleting %s because of cancellation or error...", module))
} else {
ui.Say(fmt.Sprintf("Cleaning up '%s'", module))
}
}
func halt(state multistep.StateBag, err error, prefix string) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
if prefix != "" {
err = fmt.Errorf("%s: %s", prefix, err)
}
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
func convertNumber(value int) string {
if value <= 0 {
return ""
}
return strconv.Itoa(value)
}
func ContainsInArray(arr []string, value string) bool {
for _, item := range arr {
if item == value {
return true
}
}
return false
}

View File

@ -1,154 +0,0 @@
//go:generate struct-markdown
package ecs
import (
"errors"
"fmt"
"os"
"strings"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
type RunConfig struct {
AssociatePublicIpAddress bool `mapstructure:"associate_public_ip_address"`
// ID of the zone to which the disk belongs.
ZoneId string `mapstructure:"zone_id" required:"false"`
// Whether an ECS instance is I/O optimized or not. If this option is not
// provided, the value will be determined by product API according to what
// `instance_type` is used.
IOOptimized config.Trilean `mapstructure:"io_optimized" required:"false"`
// Type of the instance. For values, see [Instance Type
// Table](https://www.alibabacloud.com/help/doc-detail/25378.htm?spm=a3c0i.o25499en.a3.9.14a36ac8iYqKRA).
// You can also obtain the latest instance type table by invoking the
// [Querying Instance Type
// Table](https://intl.aliyun.com/help/doc-detail/25620.htm?spm=a3c0i.o25499en.a3.6.Dr1bik)
// interface.
InstanceType string `mapstructure:"instance_type" required:"true"`
Description string `mapstructure:"description"`
// This is the base image id which you want to
// create your customized images.
AlicloudSourceImage string `mapstructure:"source_image" required:"true"`
// Whether to force shutdown upon device
// restart. The default value is `false`.
//
// If it is set to `false`, the system is shut down normally; if it is set to
// `true`, the system is forced to shut down.
ForceStopInstance bool `mapstructure:"force_stop_instance" required:"false"`
// If this option is set to true, Packer
// will not stop the instance for you, and you need to make sure the instance
// will be stopped in the final provisioner command. Otherwise, Packer will
// timeout while waiting the instance to be stopped. This option is provided
// for some specific scenarios that you want to stop the instance by yourself.
// E.g., Sysprep a windows which may shutdown the instance within its command.
// The default value is false.
DisableStopInstance bool `mapstructure:"disable_stop_instance" required:"false"`
// ID of the security group to which a newly
// created instance belongs. Mutual access is allowed between instances in one
// security group. If not specified, the newly created instance will be added
// to the default security group. If the default group doesnt exist, or the
// number of instances in it has reached the maximum limit, a new security
// group will be created automatically.
SecurityGroupId string `mapstructure:"security_group_id" required:"false"`
// The security group name. The default value
// is blank. [2, 128] English or Chinese characters, must begin with an
// uppercase/lowercase letter or Chinese character. Can contain numbers, .,
// _ or -. It cannot begin with `http://` or `https://`.
SecurityGroupName string `mapstructure:"security_group_name" required:"false"`
// User data to apply when launching the instance. Note
// that you need to be careful about escaping characters due to the templates
// being JSON. It is often more convenient to use user_data_file, instead.
// Packer will not automatically wait for a user script to finish before
// shutting down the instance this must be handled in a provisioner.
UserData string `mapstructure:"user_data" required:"false"`
// Path to a file that will be used for the user
// data when launching the instance.
UserDataFile string `mapstructure:"user_data_file" required:"false"`
// VPC ID allocated by the system.
VpcId string `mapstructure:"vpc_id" required:"false"`
// The VPC name. The default value is blank. [2, 128]
// English or Chinese characters, must begin with an uppercase/lowercase
// letter or Chinese character. Can contain numbers, _ and -. The disk
// description will appear on the console. Cannot begin with `http://` or
// `https://`.
VpcName string `mapstructure:"vpc_name" required:"false"`
// Value options: 192.168.0.0/16 and
// 172.16.0.0/16. When not specified, the default value is 172.16.0.0/16.
CidrBlock string `mapstructure:"vpc_cidr_block" required:"false"`
// The ID of the VSwitch to be used.
VSwitchId string `mapstructure:"vswitch_id" required:"false"`
// The ID of the VSwitch to be used.
VSwitchName string `mapstructure:"vswitch_name" required:"false"`
// Display name of the instance, which is a string of 2 to 128 Chinese or
// English characters. It must begin with an uppercase/lowercase letter or
// a Chinese character and can contain numerals, `.`, `_`, or `-`. The
// instance name is displayed on the Alibaba Cloud console. If this
// parameter is not specified, the default value is InstanceId of the
// instance. It cannot begin with `http://` or `https://`.
InstanceName string `mapstructure:"instance_name" required:"false"`
// Internet charge type, which can be
// `PayByTraffic` or `PayByBandwidth`. Optional values:
// - `PayByBandwidth`
// - `PayByTraffic`
//
// If this parameter is not specified, the default value is `PayByBandwidth`.
// For the regions out of China, currently only support `PayByTraffic`, you
// must set it manfully.
InternetChargeType string `mapstructure:"internet_charge_type" required:"false"`
// Maximum outgoing bandwidth to the
// public network, measured in Mbps (Mega bits per second).
//
// Value range:
// - `PayByBandwidth`: \[0, 100\]. If this parameter is not specified, API
// automatically sets it to 0 Mbps.
// - `PayByTraffic`: \[1, 100\]. If this parameter is not specified, an
// error is returned.
InternetMaxBandwidthOut int `mapstructure:"internet_max_bandwidth_out" required:"false"`
// Timeout of creating snapshot(s).
// The default timeout is 3600 seconds if this option is not set or is set
// to 0. For those disks containing lots of data, it may require a higher
// timeout value.
WaitSnapshotReadyTimeout int `mapstructure:"wait_snapshot_ready_timeout" required:"false"`
// Communicator settings
Comm communicator.Config `mapstructure:",squash"`
// If this value is true, packer will connect to
// the ECS created through private ip instead of allocating a public ip or an
// EIP. The default value is false.
SSHPrivateIp bool `mapstructure:"ssh_private_ip" required:"false"`
}
func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
if c.Comm.SSHKeyPairName == "" && c.Comm.SSHTemporaryKeyPairName == "" &&
c.Comm.SSHPrivateKeyFile == "" && c.Comm.SSHPassword == "" && c.Comm.WinRMPassword == "" {
c.Comm.SSHTemporaryKeyPairName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID())
}
// Validation
errs := c.Comm.Prepare(ctx)
if c.AlicloudSourceImage == "" {
errs = append(errs, errors.New("A source_image must be specified"))
}
if strings.TrimSpace(c.AlicloudSourceImage) != c.AlicloudSourceImage {
errs = append(errs, errors.New("The source_image can't include spaces"))
}
if c.InstanceType == "" {
errs = append(errs, errors.New("An alicloud_instance_type must be specified"))
}
if c.UserData != "" && c.UserDataFile != "" {
errs = append(errs, fmt.Errorf("Only one of user_data or user_data_file can be specified."))
} else if c.UserDataFile != "" {
if _, err := os.Stat(c.UserDataFile); err != nil {
errs = append(errs, fmt.Errorf("user_data_file not found: %s", c.UserDataFile))
}
}
return errs
}

View File

@ -1,178 +0,0 @@
package ecs
import (
"io/ioutil"
"os"
"testing"
"github.com/hashicorp/packer/helper/communicator"
)
func testConfig() *RunConfig {
return &RunConfig{
AlicloudSourceImage: "alicloud_images",
InstanceType: "ecs.n1.tiny",
Comm: communicator.Config{
SSH: communicator.SSH{
SSHUsername: "alicloud",
},
},
}
}
func TestRunConfigPrepare(t *testing.T) {
c := testConfig()
err := c.Prepare(nil)
if len(err) > 0 {
t.Fatalf("err: %s", err)
}
}
func TestRunConfigPrepare_InstanceType(t *testing.T) {
c := testConfig()
c.InstanceType = ""
if err := c.Prepare(nil); len(err) != 1 {
t.Fatalf("err: %s", err)
}
}
func TestRunConfigPrepare_SourceECSImage(t *testing.T) {
c := testConfig()
c.AlicloudSourceImage = ""
if err := c.Prepare(nil); len(err) != 1 {
t.Fatalf("err: %s", err)
}
}
func TestRunConfigPrepare_SSHPort(t *testing.T) {
c := testConfig()
c.Comm.SSHPort = 0
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if c.Comm.SSHPort != 22 {
t.Fatalf("invalid value: %d", c.Comm.SSHPort)
}
c.Comm.SSHPort = 44
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if c.Comm.SSHPort != 44 {
t.Fatalf("invalid value: %d", c.Comm.SSHPort)
}
}
func TestRunConfigPrepare_UserData(t *testing.T) {
c := testConfig()
tf, err := ioutil.TempFile("", "packer")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.Remove(tf.Name())
defer tf.Close()
c.UserData = "foo"
c.UserDataFile = tf.Name()
if err := c.Prepare(nil); len(err) != 1 {
t.Fatalf("err: %s", err)
}
}
func TestRunConfigPrepare_UserDataFile(t *testing.T) {
c := testConfig()
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
c.UserDataFile = "idontexistidontthink"
if err := c.Prepare(nil); len(err) != 1 {
t.Fatalf("err: %s", err)
}
tf, err := ioutil.TempFile("", "packer")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.Remove(tf.Name())
defer tf.Close()
c.UserDataFile = tf.Name()
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
}
func TestRunConfigPrepare_TemporaryKeyPairName(t *testing.T) {
c := testConfig()
c.Comm.SSHTemporaryKeyPairName = ""
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if c.Comm.SSHTemporaryKeyPairName == "" {
t.Fatal("keypair name is empty")
}
c.Comm.SSHTemporaryKeyPairName = "ssh-key-123"
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if c.Comm.SSHTemporaryKeyPairName != "ssh-key-123" {
t.Fatal("keypair name does not match")
}
}
func TestRunConfigPrepare_SSHPrivateIp(t *testing.T) {
c := testConfig()
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if c.SSHPrivateIp != false {
t.Fatalf("invalid value, expected: %t, actul: %t", false, c.SSHPrivateIp)
}
c.SSHPrivateIp = true
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if c.SSHPrivateIp != true {
t.Fatalf("invalid value, expected: %t, actul: %t", true, c.SSHPrivateIp)
}
c.SSHPrivateIp = false
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if c.SSHPrivateIp != false {
t.Fatalf("invalid value, expected: %t, actul: %t", false, c.SSHPrivateIp)
}
}
func TestRunConfigPrepare_DisableStopInstance(t *testing.T) {
c := testConfig()
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if c.DisableStopInstance != false {
t.Fatalf("invalid value, expected: %t, actul: %t", false, c.DisableStopInstance)
}
c.DisableStopInstance = true
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if c.DisableStopInstance != true {
t.Fatalf("invalid value, expected: %t, actul: %t", true, c.DisableStopInstance)
}
c.DisableStopInstance = false
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("err: %s", err)
}
if c.DisableStopInstance != false {
t.Fatalf("invalid value, expected: %t, actul: %t", false, c.DisableStopInstance)
}
}

View File

@ -1,23 +0,0 @@
package ecs
import (
"time"
"github.com/hashicorp/packer/helper/multistep"
)
var (
// modified in tests
sshHostSleepDuration = time.Second
)
type alicloudSSHHelper interface {
}
// SSHHost returns a function that can be given to the SSH communicator
func SSHHost(e alicloudSSHHelper, private bool) func(multistep.StateBag) (string, error) {
return func(state multistep.StateBag) (string, error) {
ipAddress := state.Get("ipaddress").(string)
return ipAddress, nil
}
}

View File

@ -1,77 +0,0 @@
package ecs
import (
"context"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepAttachKeyPair struct {
}
var attachKeyPairNotRetryErrors = []string{
"MissingParameter",
"DependencyViolation.WindowsInstance",
"InvalidKeyPairName.NotFound",
"InvalidRegionId.NotFound",
}
func (s *stepAttachKeyPair) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
client := state.Get("client").(*ClientWrapper)
config := state.Get("config").(*Config)
instance := state.Get("instance").(*ecs.Instance)
keyPairName := config.Comm.SSHKeyPairName
if keyPairName == "" {
return multistep.ActionContinue
}
_, err := client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
request := ecs.CreateAttachKeyPairRequest()
request.RegionId = config.AlicloudRegion
request.KeyPairName = keyPairName
request.InstanceIds = "[\"" + instance.InstanceId + "\"]"
return client.AttachKeyPair(request)
},
EvalFunc: client.EvalCouldRetryResponse(attachKeyPairNotRetryErrors, EvalNotRetryErrorType),
})
if err != nil {
return halt(state, err, fmt.Sprintf("Error attaching keypair %s to instance %s", keyPairName, instance.InstanceId))
}
ui.Message(fmt.Sprintf("Attach keypair %s to instance: %s", keyPairName, instance.InstanceId))
return multistep.ActionContinue
}
func (s *stepAttachKeyPair) Cleanup(state multistep.StateBag) {
client := state.Get("client").(*ClientWrapper)
config := state.Get("config").(*Config)
ui := state.Get("ui").(packer.Ui)
instance := state.Get("instance").(*ecs.Instance)
keyPairName := config.Comm.SSHKeyPairName
if keyPairName == "" {
return
}
detachKeyPairRequest := ecs.CreateDetachKeyPairRequest()
detachKeyPairRequest.RegionId = config.AlicloudRegion
detachKeyPairRequest.KeyPairName = keyPairName
detachKeyPairRequest.InstanceIds = fmt.Sprintf("[\"%s\"]", instance.InstanceId)
_, err := client.DetachKeyPair(detachKeyPairRequest)
if err != nil {
err := fmt.Errorf("Error Detaching keypair %s to instance %s : %s", keyPairName,
instance.InstanceId, err)
state.Put("error", err)
ui.Error(err.Error())
return
}
ui.Message(fmt.Sprintf("Detach keypair %s from instance: %s", keyPairName, instance.InstanceId))
}

View File

@ -1,57 +0,0 @@
package ecs
import (
"context"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepCheckAlicloudSourceImage struct {
SourceECSImageId string
}
func (s *stepCheckAlicloudSourceImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*ClientWrapper)
config := state.Get("config").(*Config)
ui := state.Get("ui").(packer.Ui)
describeImagesRequest := ecs.CreateDescribeImagesRequest()
describeImagesRequest.RegionId = config.AlicloudRegion
describeImagesRequest.ImageId = config.AlicloudSourceImage
if config.AlicloudSkipImageValidation {
describeImagesRequest.ShowExpired = "true"
}
imagesResponse, err := client.DescribeImages(describeImagesRequest)
if err != nil {
return halt(state, err, "Error querying alicloud image")
}
images := imagesResponse.Images.Image
// Describe marketplace image
describeImagesRequest.ImageOwnerAlias = "marketplace"
marketImagesResponse, err := client.DescribeImages(describeImagesRequest)
if err != nil {
return halt(state, err, "Error querying alicloud marketplace image")
}
marketImages := marketImagesResponse.Images.Image
if len(marketImages) > 0 {
images = append(images, marketImages...)
}
if len(images) == 0 {
err := fmt.Errorf("No alicloud image was found matching filters: %v", config.AlicloudSourceImage)
return halt(state, err, "")
}
ui.Message(fmt.Sprintf("Found image ID: %s", images[0].ImageId))
state.Put("source_image", &images[0])
return multistep.ActionContinue
}
func (s *stepCheckAlicloudSourceImage) Cleanup(multistep.StateBag) {}

View File

@ -1,165 +0,0 @@
package ecs
import (
"context"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
"github.com/hashicorp/packer/common/uuid"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepConfigAlicloudEIP struct {
AssociatePublicIpAddress bool
RegionId string
InternetChargeType string
InternetMaxBandwidthOut int
allocatedId string
SSHPrivateIp bool
}
var allocateEipAddressRetryErrors = []string{
"LastTokenProcessing",
}
func (s *stepConfigAlicloudEIP) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
instance := state.Get("instance").(*ecs.Instance)
if s.SSHPrivateIp {
ipaddress := instance.VpcAttributes.PrivateIpAddress.IpAddress
if len(ipaddress) == 0 {
ui.Say("Failed to get private ip of instance")
return multistep.ActionHalt
}
state.Put("ipaddress", ipaddress[0])
return multistep.ActionContinue
}
ui.Say("Allocating eip...")
allocateEipAddressRequest := s.buildAllocateEipAddressRequest(state)
allocateEipAddressResponse, err := client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
return client.AllocateEipAddress(allocateEipAddressRequest)
},
EvalFunc: client.EvalCouldRetryResponse(allocateEipAddressRetryErrors, EvalRetryErrorType),
})
if err != nil {
return halt(state, err, "Error allocating eip")
}
ipaddress := allocateEipAddressResponse.(*ecs.AllocateEipAddressResponse).EipAddress
ui.Message(fmt.Sprintf("Allocated eip: %s", ipaddress))
allocateId := allocateEipAddressResponse.(*ecs.AllocateEipAddressResponse).AllocationId
s.allocatedId = allocateId
err = s.waitForEipStatus(client, instance.RegionId, s.allocatedId, EipStatusAvailable)
if err != nil {
return halt(state, err, "Error wait eip available timeout")
}
associateEipAddressRequest := ecs.CreateAssociateEipAddressRequest()
associateEipAddressRequest.AllocationId = allocateId
associateEipAddressRequest.InstanceId = instance.InstanceId
if _, err := client.AssociateEipAddress(associateEipAddressRequest); err != nil {
e, ok := err.(errors.Error)
if !ok || e.ErrorCode() != "TaskConflict" {
return halt(state, err, "Error associating eip")
}
ui.Error(fmt.Sprintf("Error associate eip: %s", err))
}
err = s.waitForEipStatus(client, instance.RegionId, s.allocatedId, EipStatusInUse)
if err != nil {
return halt(state, err, "Error wait eip associated timeout")
}
state.Put("ipaddress", ipaddress)
return multistep.ActionContinue
}
func (s *stepConfigAlicloudEIP) Cleanup(state multistep.StateBag) {
if len(s.allocatedId) == 0 {
return
}
cleanUpMessage(state, "EIP")
client := state.Get("client").(*ClientWrapper)
instance := state.Get("instance").(*ecs.Instance)
ui := state.Get("ui").(packer.Ui)
unassociateEipAddressRequest := ecs.CreateUnassociateEipAddressRequest()
unassociateEipAddressRequest.AllocationId = s.allocatedId
unassociateEipAddressRequest.InstanceId = instance.InstanceId
if _, err := client.UnassociateEipAddress(unassociateEipAddressRequest); err != nil {
ui.Say(fmt.Sprintf("Failed to unassociate eip: %s", err))
}
if err := s.waitForEipStatus(client, instance.RegionId, s.allocatedId, EipStatusAvailable); err != nil {
ui.Say(fmt.Sprintf("Timeout while unassociating eip: %s", err))
}
releaseEipAddressRequest := ecs.CreateReleaseEipAddressRequest()
releaseEipAddressRequest.AllocationId = s.allocatedId
if _, err := client.ReleaseEipAddress(releaseEipAddressRequest); err != nil {
ui.Say(fmt.Sprintf("Failed to release eip: %s", err))
}
}
func (s *stepConfigAlicloudEIP) waitForEipStatus(client *ClientWrapper, regionId string, allocationId string, expectedStatus string) error {
describeEipAddressesRequest := ecs.CreateDescribeEipAddressesRequest()
describeEipAddressesRequest.RegionId = regionId
describeEipAddressesRequest.AllocationId = s.allocatedId
_, err := client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
response, err := client.DescribeEipAddresses(describeEipAddressesRequest)
if err == nil && len(response.EipAddresses.EipAddress) == 0 {
err = fmt.Errorf("eip allocated is not find")
}
return response, err
},
EvalFunc: func(response responses.AcsResponse, err error) WaitForExpectEvalResult {
if err != nil {
return WaitForExpectToRetry
}
eipAddressesResponse := response.(*ecs.DescribeEipAddressesResponse)
eipAddresses := eipAddressesResponse.EipAddresses.EipAddress
for _, eipAddress := range eipAddresses {
if eipAddress.Status == expectedStatus {
return WaitForExpectSuccess
}
}
return WaitForExpectToRetry
},
RetryTimes: shortRetryTimes,
})
return err
}
func (s *stepConfigAlicloudEIP) buildAllocateEipAddressRequest(state multistep.StateBag) *ecs.AllocateEipAddressRequest {
instance := state.Get("instance").(*ecs.Instance)
request := ecs.CreateAllocateEipAddressRequest()
request.ClientToken = uuid.TimeOrderedUUID()
request.RegionId = instance.RegionId
request.InternetChargeType = s.InternetChargeType
request.Bandwidth = string(convertNumber(s.InternetMaxBandwidthOut))
return request
}

View File

@ -1,132 +0,0 @@
package ecs
import (
"context"
"fmt"
"os"
"runtime"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepConfigAlicloudKeyPair struct {
Debug bool
Comm *communicator.Config
DebugKeyPath string
RegionId string
keyName string
}
func (s *stepConfigAlicloudKeyPair) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
if s.Comm.SSHPrivateKeyFile != "" {
ui.Say("Using existing SSH private key")
privateKeyBytes, err := s.Comm.ReadSSHPrivateKeyFile()
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
s.Comm.SSHPrivateKey = privateKeyBytes
return multistep.ActionContinue
}
if s.Comm.SSHAgentAuth && s.Comm.SSHKeyPairName == "" {
ui.Say("Using SSH Agent with key pair in source image")
return multistep.ActionContinue
}
if s.Comm.SSHAgentAuth && s.Comm.SSHKeyPairName != "" {
ui.Say(fmt.Sprintf("Using SSH Agent for existing key pair %s", s.Comm.SSHKeyPairName))
return multistep.ActionContinue
}
if s.Comm.SSHTemporaryKeyPairName == "" {
ui.Say("Not using temporary keypair")
s.Comm.SSHKeyPairName = ""
return multistep.ActionContinue
}
client := state.Get("client").(*ClientWrapper)
ui.Say(fmt.Sprintf("Creating temporary keypair: %s", s.Comm.SSHTemporaryKeyPairName))
createKeyPairRequest := ecs.CreateCreateKeyPairRequest()
createKeyPairRequest.RegionId = s.RegionId
createKeyPairRequest.KeyPairName = s.Comm.SSHTemporaryKeyPairName
keyResp, err := client.CreateKeyPair(createKeyPairRequest)
if err != nil {
return halt(state, err, "Error creating temporary keypair")
}
// Set the keyname so we know to delete it later
s.keyName = s.Comm.SSHTemporaryKeyPairName
// Set some state data for use in future steps
s.Comm.SSHKeyPairName = s.keyName
s.Comm.SSHPrivateKey = []byte(keyResp.PrivateKeyBody)
// If we're in debug mode, output the private key to the working
// directory.
if s.Debug {
ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath))
f, err := os.Create(s.DebugKeyPath)
if err != nil {
state.Put("error", fmt.Errorf("Error saving debug key: %s", err))
return multistep.ActionHalt
}
defer f.Close()
// Write the key out
if _, err := f.Write([]byte(keyResp.PrivateKeyBody)); err != nil {
state.Put("error", fmt.Errorf("Error saving debug key: %s", err))
return multistep.ActionHalt
}
// Chmod it so that it is SSH ready
if runtime.GOOS != "windows" {
if err := f.Chmod(0600); err != nil {
state.Put("error", fmt.Errorf("Error setting permissions of debug key: %s", err))
return multistep.ActionHalt
}
}
}
return multistep.ActionContinue
}
func (s *stepConfigAlicloudKeyPair) Cleanup(state multistep.StateBag) {
// If no key name is set, then we never created it, so just return
// If we used an SSH private key file, do not go about deleting
// keypairs
if s.Comm.SSHPrivateKeyFile != "" || (s.Comm.SSHKeyPairName == "" && s.keyName == "") {
return
}
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
// Remove the keypair
ui.Say("Deleting temporary keypair...")
deleteKeyPairsRequest := ecs.CreateDeleteKeyPairsRequest()
deleteKeyPairsRequest.RegionId = s.RegionId
deleteKeyPairsRequest.KeyPairNames = fmt.Sprintf("[\"%s\"]", s.keyName)
_, err := client.DeleteKeyPairs(deleteKeyPairsRequest)
if err != nil {
ui.Error(fmt.Sprintf(
"Error cleaning up keypair. Please delete the key manually: %s", s.keyName))
}
// Also remove the physical key if we're debugging.
if s.Debug {
if err := os.Remove(s.DebugKeyPath); err != nil {
ui.Error(fmt.Sprintf(
"Error removing debug key '%s': %s", s.DebugKeyPath, err))
}
}
}

View File

@ -1,48 +0,0 @@
package ecs
import (
"context"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepConfigAlicloudPublicIP struct {
publicIPAddress string
RegionId string
SSHPrivateIp bool
}
func (s *stepConfigAlicloudPublicIP) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
instance := state.Get("instance").(*ecs.Instance)
if s.SSHPrivateIp {
ipaddress := instance.InnerIpAddress.IpAddress
if len(ipaddress) == 0 {
ui.Say("Failed to get private ip of instance")
return multistep.ActionHalt
}
state.Put("ipaddress", ipaddress[0])
return multistep.ActionContinue
}
allocatePublicIpAddressRequest := ecs.CreateAllocatePublicIpAddressRequest()
allocatePublicIpAddressRequest.InstanceId = instance.InstanceId
ipaddress, err := client.AllocatePublicIpAddress(allocatePublicIpAddressRequest)
if err != nil {
return halt(state, err, "Error allocating public ip")
}
s.publicIPAddress = ipaddress.IpAddress
ui.Say(fmt.Sprintf("Allocated public ip address %s.", ipaddress.IpAddress))
state.Put("ipaddress", ipaddress.IpAddress)
return multistep.ActionContinue
}
func (s *stepConfigAlicloudPublicIP) Cleanup(state multistep.StateBag) {
}

View File

@ -1,152 +0,0 @@
package ecs
import (
"context"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepConfigAlicloudSecurityGroup struct {
SecurityGroupId string
SecurityGroupName string
Description string
VpcId string
RegionId string
isCreate bool
}
var createSecurityGroupRetryErrors = []string{
"IdempotentProcessing",
}
var deleteSecurityGroupRetryErrors = []string{
"DependencyViolation",
}
func (s *stepConfigAlicloudSecurityGroup) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
networkType := state.Get("networktype").(InstanceNetWork)
if len(s.SecurityGroupId) != 0 {
describeSecurityGroupsRequest := ecs.CreateDescribeSecurityGroupsRequest()
describeSecurityGroupsRequest.RegionId = s.RegionId
describeSecurityGroupsRequest.SecurityGroupId = s.SecurityGroupId
if networkType == InstanceNetworkVpc {
vpcId := state.Get("vpcid").(string)
describeSecurityGroupsRequest.VpcId = vpcId
}
securityGroupsResponse, err := client.DescribeSecurityGroups(describeSecurityGroupsRequest)
if err != nil {
return halt(state, err, "Failed querying security group")
}
securityGroupItems := securityGroupsResponse.SecurityGroups.SecurityGroup
for _, securityGroupItem := range securityGroupItems {
if securityGroupItem.SecurityGroupId == s.SecurityGroupId {
state.Put("securitygroupid", s.SecurityGroupId)
s.isCreate = false
return multistep.ActionContinue
}
}
s.isCreate = false
err = fmt.Errorf("The specified security group {%s} doesn't exist.", s.SecurityGroupId)
return halt(state, err, "")
}
ui.Say("Creating security group...")
createSecurityGroupRequest := s.buildCreateSecurityGroupRequest(state)
securityGroupResponse, err := client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
return client.CreateSecurityGroup(createSecurityGroupRequest)
},
EvalFunc: client.EvalCouldRetryResponse(createSecurityGroupRetryErrors, EvalRetryErrorType),
})
if err != nil {
return halt(state, err, "Failed creating security group")
}
securityGroupId := securityGroupResponse.(*ecs.CreateSecurityGroupResponse).SecurityGroupId
ui.Message(fmt.Sprintf("Created security group: %s", securityGroupId))
state.Put("securitygroupid", securityGroupId)
s.isCreate = true
s.SecurityGroupId = securityGroupId
authorizeSecurityGroupEgressRequest := ecs.CreateAuthorizeSecurityGroupEgressRequest()
authorizeSecurityGroupEgressRequest.SecurityGroupId = securityGroupId
authorizeSecurityGroupEgressRequest.RegionId = s.RegionId
authorizeSecurityGroupEgressRequest.IpProtocol = IpProtocolAll
authorizeSecurityGroupEgressRequest.PortRange = DefaultPortRange
authorizeSecurityGroupEgressRequest.NicType = NicTypeInternet
authorizeSecurityGroupEgressRequest.DestCidrIp = DefaultCidrIp
if _, err := client.AuthorizeSecurityGroupEgress(authorizeSecurityGroupEgressRequest); err != nil {
return halt(state, err, "Failed authorizing security group")
}
authorizeSecurityGroupRequest := ecs.CreateAuthorizeSecurityGroupRequest()
authorizeSecurityGroupRequest.SecurityGroupId = securityGroupId
authorizeSecurityGroupRequest.RegionId = s.RegionId
authorizeSecurityGroupRequest.IpProtocol = IpProtocolAll
authorizeSecurityGroupRequest.PortRange = DefaultPortRange
authorizeSecurityGroupRequest.NicType = NicTypeInternet
authorizeSecurityGroupRequest.SourceCidrIp = DefaultCidrIp
if _, err := client.AuthorizeSecurityGroup(authorizeSecurityGroupRequest); err != nil {
return halt(state, err, "Failed authorizing security group")
}
return multistep.ActionContinue
}
func (s *stepConfigAlicloudSecurityGroup) Cleanup(state multistep.StateBag) {
if !s.isCreate {
return
}
cleanUpMessage(state, "security group")
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
_, err := client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
request := ecs.CreateDeleteSecurityGroupRequest()
request.RegionId = s.RegionId
request.SecurityGroupId = s.SecurityGroupId
return client.DeleteSecurityGroup(request)
},
EvalFunc: client.EvalCouldRetryResponse(deleteSecurityGroupRetryErrors, EvalRetryErrorType),
RetryTimes: shortRetryTimes,
})
if err != nil {
ui.Error(fmt.Sprintf("Failed to delete security group, it may still be around: %s", err))
}
}
func (s *stepConfigAlicloudSecurityGroup) buildCreateSecurityGroupRequest(state multistep.StateBag) *ecs.CreateSecurityGroupRequest {
networkType := state.Get("networktype").(InstanceNetWork)
request := ecs.CreateCreateSecurityGroupRequest()
request.ClientToken = uuid.TimeOrderedUUID()
request.RegionId = s.RegionId
request.SecurityGroupName = s.SecurityGroupName
if networkType == InstanceNetworkVpc {
vpcId := state.Get("vpcid").(string)
request.VpcId = vpcId
}
return request
}

View File

@ -1,148 +0,0 @@
package ecs
import (
"context"
errorsNew "errors"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepConfigAlicloudVPC struct {
VpcId string
CidrBlock string //192.168.0.0/16 or 172.16.0.0/16 (default)
VpcName string
isCreate bool
}
var createVpcRetryErrors = []string{
"TOKEN_PROCESSING",
}
var deleteVpcRetryErrors = []string{
"DependencyViolation.Instance",
"DependencyViolation.RouteEntry",
"DependencyViolation.VSwitch",
"DependencyViolation.SecurityGroup",
"Forbbiden",
"TaskConflict",
}
func (s *stepConfigAlicloudVPC) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
if len(s.VpcId) != 0 {
describeVpcsRequest := ecs.CreateDescribeVpcsRequest()
describeVpcsRequest.VpcId = s.VpcId
describeVpcsRequest.RegionId = config.AlicloudRegion
vpcsResponse, err := client.DescribeVpcs(describeVpcsRequest)
if err != nil {
return halt(state, err, "Failed querying vpcs")
}
vpcs := vpcsResponse.Vpcs.Vpc
if len(vpcs) > 0 {
state.Put("vpcid", vpcs[0].VpcId)
s.isCreate = false
return multistep.ActionContinue
}
message := fmt.Sprintf("The specified vpc {%s} doesn't exist.", s.VpcId)
return halt(state, errorsNew.New(message), "")
}
ui.Say("Creating vpc...")
createVpcRequest := s.buildCreateVpcRequest(state)
createVpcResponse, err := client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
return client.CreateVpc(createVpcRequest)
},
EvalFunc: client.EvalCouldRetryResponse(createVpcRetryErrors, EvalRetryErrorType),
})
if err != nil {
return halt(state, err, "Failed creating vpc")
}
vpcId := createVpcResponse.(*ecs.CreateVpcResponse).VpcId
_, err = client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
request := ecs.CreateDescribeVpcsRequest()
request.RegionId = config.AlicloudRegion
request.VpcId = vpcId
return client.DescribeVpcs(request)
},
EvalFunc: func(response responses.AcsResponse, err error) WaitForExpectEvalResult {
if err != nil {
return WaitForExpectToRetry
}
vpcsResponse := response.(*ecs.DescribeVpcsResponse)
vpcs := vpcsResponse.Vpcs.Vpc
if len(vpcs) > 0 {
for _, vpc := range vpcs {
if vpc.Status == VpcStatusAvailable {
return WaitForExpectSuccess
}
}
}
return WaitForExpectToRetry
},
RetryTimes: shortRetryTimes,
})
if err != nil {
return halt(state, err, "Failed waiting for vpc to become available")
}
ui.Message(fmt.Sprintf("Created vpc: %s", vpcId))
state.Put("vpcid", vpcId)
s.isCreate = true
s.VpcId = vpcId
return multistep.ActionContinue
}
func (s *stepConfigAlicloudVPC) Cleanup(state multistep.StateBag) {
if !s.isCreate {
return
}
cleanUpMessage(state, "VPC")
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
_, err := client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
request := ecs.CreateDeleteVpcRequest()
request.VpcId = s.VpcId
return client.DeleteVpc(request)
},
EvalFunc: client.EvalCouldRetryResponse(deleteVpcRetryErrors, EvalRetryErrorType),
RetryTimes: shortRetryTimes,
})
if err != nil {
ui.Error(fmt.Sprintf("Error deleting vpc, it may still be around: %s", err))
}
}
func (s *stepConfigAlicloudVPC) buildCreateVpcRequest(state multistep.StateBag) *ecs.CreateVpcRequest {
config := state.Get("config").(*Config)
request := ecs.CreateCreateVpcRequest()
request.ClientToken = uuid.TimeOrderedUUID()
request.RegionId = config.AlicloudRegion
request.CidrBlock = s.CidrBlock
request.VpcName = s.VpcName
return request
}

View File

@ -1,207 +0,0 @@
package ecs
import (
"context"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepConfigAlicloudVSwitch struct {
VSwitchId string
ZoneId string
isCreate bool
CidrBlock string
VSwitchName string
}
var createVSwitchRetryErrors = []string{
"TOKEN_PROCESSING",
}
var deleteVSwitchRetryErrors = []string{
"IncorrectVSwitchStatus",
"DependencyViolation",
"DependencyViolation.HaVip",
"IncorrectRouteEntryStatus",
"TaskConflict",
}
func (s *stepConfigAlicloudVSwitch) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
vpcId := state.Get("vpcid").(string)
config := state.Get("config").(*Config)
if len(s.VSwitchId) != 0 {
describeVSwitchesRequest := ecs.CreateDescribeVSwitchesRequest()
describeVSwitchesRequest.VpcId = vpcId
describeVSwitchesRequest.VSwitchId = s.VSwitchId
describeVSwitchesRequest.ZoneId = s.ZoneId
vswitchesResponse, err := client.DescribeVSwitches(describeVSwitchesRequest)
if err != nil {
return halt(state, err, "Failed querying vswitch")
}
vswitch := vswitchesResponse.VSwitches.VSwitch
if len(vswitch) > 0 {
state.Put("vswitchid", vswitch[0].VSwitchId)
s.isCreate = false
return multistep.ActionContinue
}
s.isCreate = false
return halt(state, fmt.Errorf("The specified vswitch {%s} doesn't exist.", s.VSwitchId), "")
}
if s.ZoneId == "" {
describeZonesRequest := ecs.CreateDescribeZonesRequest()
describeZonesRequest.RegionId = config.AlicloudRegion
zonesResponse, err := client.DescribeZones(describeZonesRequest)
if err != nil {
return halt(state, err, "Query for available zones failed")
}
var instanceTypes []string
zones := zonesResponse.Zones.Zone
for _, zone := range zones {
isVSwitchSupported := false
for _, resourceType := range zone.AvailableResourceCreation.ResourceTypes {
if resourceType == "VSwitch" {
isVSwitchSupported = true
}
}
if isVSwitchSupported {
for _, instanceType := range zone.AvailableInstanceTypes.InstanceTypes {
if instanceType == config.InstanceType {
s.ZoneId = zone.ZoneId
break
}
instanceTypes = append(instanceTypes, instanceType)
}
}
}
if s.ZoneId == "" {
if len(instanceTypes) > 0 {
ui.Say(fmt.Sprintf("The instance type %s isn't available in this region."+
"\n You can either change the instance to one of following: %v \n"+
"or choose another region.", config.InstanceType, instanceTypes))
state.Put("error", fmt.Errorf("The instance type %s isn't available in this region."+
"\n You can either change the instance to one of following: %v \n"+
"or choose another region.", config.InstanceType, instanceTypes))
return multistep.ActionHalt
} else {
ui.Say(fmt.Sprintf("The instance type %s isn't available in this region."+
"\n You can change to other regions.", config.InstanceType))
state.Put("error", fmt.Errorf("The instance type %s isn't available in this region."+
"\n You can change to other regions.", config.InstanceType))
return multistep.ActionHalt
}
}
}
if config.CidrBlock == "" {
s.CidrBlock = DefaultCidrBlock //use the default CirdBlock
}
ui.Say("Creating vswitch...")
createVSwitchRequest := s.buildCreateVSwitchRequest(state)
createVSwitchResponse, err := client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
return client.CreateVSwitch(createVSwitchRequest)
},
EvalFunc: client.EvalCouldRetryResponse(createVSwitchRetryErrors, EvalRetryErrorType),
})
if err != nil {
return halt(state, err, "Error Creating vswitch")
}
vSwitchId := createVSwitchResponse.(*ecs.CreateVSwitchResponse).VSwitchId
describeVSwitchesRequest := ecs.CreateDescribeVSwitchesRequest()
describeVSwitchesRequest.VpcId = vpcId
describeVSwitchesRequest.VSwitchId = vSwitchId
_, err = client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
return client.DescribeVSwitches(describeVSwitchesRequest)
},
EvalFunc: func(response responses.AcsResponse, err error) WaitForExpectEvalResult {
if err != nil {
return WaitForExpectToRetry
}
vSwitchesResponse := response.(*ecs.DescribeVSwitchesResponse)
vSwitches := vSwitchesResponse.VSwitches.VSwitch
if len(vSwitches) > 0 {
for _, vSwitch := range vSwitches {
if vSwitch.Status == VSwitchStatusAvailable {
return WaitForExpectSuccess
}
}
}
return WaitForExpectToRetry
},
RetryTimes: shortRetryTimes,
})
if err != nil {
return halt(state, err, "Timeout waiting for vswitch to become available")
}
ui.Message(fmt.Sprintf("Created vswitch: %s", vSwitchId))
state.Put("vswitchid", vSwitchId)
s.isCreate = true
s.VSwitchId = vSwitchId
return multistep.ActionContinue
}
func (s *stepConfigAlicloudVSwitch) Cleanup(state multistep.StateBag) {
if !s.isCreate {
return
}
cleanUpMessage(state, "vSwitch")
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
_, err := client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
request := ecs.CreateDeleteVSwitchRequest()
request.VSwitchId = s.VSwitchId
return client.DeleteVSwitch(request)
},
EvalFunc: client.EvalCouldRetryResponse(deleteVSwitchRetryErrors, EvalRetryErrorType),
RetryTimes: shortRetryTimes,
})
if err != nil {
ui.Error(fmt.Sprintf("Error deleting vswitch, it may still be around: %s", err))
}
}
func (s *stepConfigAlicloudVSwitch) buildCreateVSwitchRequest(state multistep.StateBag) *ecs.CreateVSwitchRequest {
vpcId := state.Get("vpcid").(string)
request := ecs.CreateCreateVSwitchRequest()
request.ClientToken = uuid.TimeOrderedUUID()
request.CidrBlock = s.CidrBlock
request.ZoneId = s.ZoneId
request.VpcId = vpcId
request.VSwitchName = s.VSwitchName
return request
}

View File

@ -1,144 +0,0 @@
package ecs
import (
"context"
"fmt"
"time"
"github.com/hashicorp/packer/common/random"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepCreateAlicloudImage struct {
AlicloudImageIgnoreDataDisks bool
WaitSnapshotReadyTimeout int
image *ecs.Image
}
var createImageRetryErrors = []string{
"IdempotentProcessing",
}
func (s *stepCreateAlicloudImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
tempImageName := config.AlicloudImageName
if config.ImageEncrypted.True() {
tempImageName = fmt.Sprintf("packer_%s", random.AlphaNum(7))
ui.Say(fmt.Sprintf("Creating temporary image for encryption: %s", tempImageName))
} else {
ui.Say(fmt.Sprintf("Creating image: %s", tempImageName))
}
createImageRequest := s.buildCreateImageRequest(state, tempImageName)
createImageResponse, err := client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
return client.CreateImage(createImageRequest)
},
EvalFunc: client.EvalCouldRetryResponse(createImageRetryErrors, EvalRetryErrorType),
})
if err != nil {
return halt(state, err, "Error creating image")
}
imageId := createImageResponse.(*ecs.CreateImageResponse).ImageId
imagesResponse, err := client.WaitForImageStatus(config.AlicloudRegion, imageId, ImageStatusAvailable, time.Duration(s.WaitSnapshotReadyTimeout)*time.Second)
// save image first for cleaning up if timeout
images := imagesResponse.(*ecs.DescribeImagesResponse).Images.Image
if len(images) == 0 {
return halt(state, err, "Unable to find created image")
}
s.image = &images[0]
if err != nil {
return halt(state, err, "Timeout waiting for image to be created")
}
var snapshotIds []string
for _, device := range images[0].DiskDeviceMappings.DiskDeviceMapping {
snapshotIds = append(snapshotIds, device.SnapshotId)
}
state.Put("alicloudimage", imageId)
state.Put("alicloudsnapshots", snapshotIds)
alicloudImages := make(map[string]string)
alicloudImages[config.AlicloudRegion] = images[0].ImageId
state.Put("alicloudimages", alicloudImages)
return multistep.ActionContinue
}
func (s *stepCreateAlicloudImage) Cleanup(state multistep.StateBag) {
if s.image == nil {
return
}
config := state.Get("config").(*Config)
encryptedSet := config.ImageEncrypted.True()
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
if !cancelled && !halted && !encryptedSet {
return
}
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
if !cancelled && !halted && encryptedSet {
ui.Say(fmt.Sprintf("Deleting temporary image %s(%s) and related snapshots after finishing encryption...", s.image.ImageId, s.image.ImageName))
} else {
ui.Say("Deleting the image and related snapshots because of cancellation or error...")
}
deleteImageRequest := ecs.CreateDeleteImageRequest()
deleteImageRequest.RegionId = config.AlicloudRegion
deleteImageRequest.ImageId = s.image.ImageId
if _, err := client.DeleteImage(deleteImageRequest); err != nil {
ui.Error(fmt.Sprintf("Error deleting image, it may still be around: %s", err))
return
}
//Delete the snapshot of this image
for _, diskDevices := range s.image.DiskDeviceMappings.DiskDeviceMapping {
deleteSnapshotRequest := ecs.CreateDeleteSnapshotRequest()
deleteSnapshotRequest.SnapshotId = diskDevices.SnapshotId
if _, err := client.DeleteSnapshot(deleteSnapshotRequest); err != nil {
ui.Error(fmt.Sprintf("Error deleting snapshot, it may still be around: %s", err))
return
}
}
}
func (s *stepCreateAlicloudImage) buildCreateImageRequest(state multistep.StateBag, imageName string) *ecs.CreateImageRequest {
config := state.Get("config").(*Config)
request := ecs.CreateCreateImageRequest()
request.ClientToken = uuid.TimeOrderedUUID()
request.RegionId = config.AlicloudRegion
request.ImageName = imageName
request.ImageVersion = config.AlicloudImageVersion
request.Description = config.AlicloudImageDescription
if s.AlicloudImageIgnoreDataDisks {
snapshotId := state.Get("alicloudsnapshot").(string)
request.SnapshotId = snapshotId
} else {
instance := state.Get("instance").(*ecs.Instance)
request.InstanceId = instance.InstanceId
}
return request
}

View File

@ -1,208 +0,0 @@
package ecs
import (
"context"
"encoding/base64"
"fmt"
"io/ioutil"
"strconv"
"github.com/hashicorp/packer/common/uuid"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
confighelper "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepCreateAlicloudInstance struct {
IOOptimized confighelper.Trilean
InstanceType string
UserData string
UserDataFile string
instanceId string
RegionId string
InternetChargeType string
InternetMaxBandwidthOut int
InstanceName string
ZoneId string
instance *ecs.Instance
}
var createInstanceRetryErrors = []string{
"IdempotentProcessing",
}
var deleteInstanceRetryErrors = []string{
"IncorrectInstanceStatus.Initializing",
}
func (s *stepCreateAlicloudInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
ui.Say("Creating instance...")
createInstanceRequest, err := s.buildCreateInstanceRequest(state)
if err != nil {
return halt(state, err, "")
}
createInstanceResponse, err := client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
return client.CreateInstance(createInstanceRequest)
},
EvalFunc: client.EvalCouldRetryResponse(createInstanceRetryErrors, EvalRetryErrorType),
})
if err != nil {
return halt(state, err, "Error creating instance")
}
instanceId := createInstanceResponse.(*ecs.CreateInstanceResponse).InstanceId
_, err = client.WaitForInstanceStatus(s.RegionId, instanceId, InstanceStatusStopped)
if err != nil {
return halt(state, err, "Error waiting create instance")
}
describeInstancesRequest := ecs.CreateDescribeInstancesRequest()
describeInstancesRequest.InstanceIds = fmt.Sprintf("[\"%s\"]", instanceId)
instances, err := client.DescribeInstances(describeInstancesRequest)
if err != nil {
return halt(state, err, "")
}
ui.Message(fmt.Sprintf("Created instance: %s", instanceId))
s.instance = &instances.Instances.Instance[0]
state.Put("instance", s.instance)
// instance_id is the generic term used so that users can have access to the
// instance id inside of the provisioners, used in step_provision.
state.Put("instance_id", instanceId)
return multistep.ActionContinue
}
func (s *stepCreateAlicloudInstance) Cleanup(state multistep.StateBag) {
if s.instance == nil {
return
}
cleanUpMessage(state, "instance")
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
_, err := client.WaitForExpected(&WaitForExpectArgs{
RequestFunc: func() (responses.AcsResponse, error) {
request := ecs.CreateDeleteInstanceRequest()
request.InstanceId = s.instance.InstanceId
request.Force = requests.NewBoolean(true)
return client.DeleteInstance(request)
},
EvalFunc: client.EvalCouldRetryResponse(deleteInstanceRetryErrors, EvalRetryErrorType),
RetryTimes: shortRetryTimes,
})
if err != nil {
ui.Say(fmt.Sprintf("Failed to clean up instance %s: %s", s.instance.InstanceId, err))
}
}
func (s *stepCreateAlicloudInstance) buildCreateInstanceRequest(state multistep.StateBag) (*ecs.CreateInstanceRequest, error) {
request := ecs.CreateCreateInstanceRequest()
request.ClientToken = uuid.TimeOrderedUUID()
request.RegionId = s.RegionId
request.InstanceType = s.InstanceType
request.InstanceName = s.InstanceName
request.ZoneId = s.ZoneId
sourceImage := state.Get("source_image").(*ecs.Image)
request.ImageId = sourceImage.ImageId
securityGroupId := state.Get("securitygroupid").(string)
request.SecurityGroupId = securityGroupId
networkType := state.Get("networktype").(InstanceNetWork)
if networkType == InstanceNetworkVpc {
vswitchId := state.Get("vswitchid").(string)
request.VSwitchId = vswitchId
userData, err := s.getUserData(state)
if err != nil {
return nil, err
}
request.UserData = userData
} else {
if s.InternetChargeType == "" {
s.InternetChargeType = "PayByTraffic"
}
if s.InternetMaxBandwidthOut == 0 {
s.InternetMaxBandwidthOut = 5
}
}
request.InternetChargeType = s.InternetChargeType
request.InternetMaxBandwidthOut = requests.Integer(convertNumber(s.InternetMaxBandwidthOut))
if s.IOOptimized.True() {
request.IoOptimized = IOOptimizedOptimized
} else if s.IOOptimized.False() {
request.IoOptimized = IOOptimizedNone
}
config := state.Get("config").(*Config)
password := config.Comm.SSHPassword
if password == "" && config.Comm.WinRMPassword != "" {
password = config.Comm.WinRMPassword
}
request.Password = password
systemDisk := config.AlicloudImageConfig.ECSSystemDiskMapping
request.SystemDiskDiskName = systemDisk.DiskName
request.SystemDiskCategory = systemDisk.DiskCategory
request.SystemDiskSize = requests.Integer(convertNumber(systemDisk.DiskSize))
request.SystemDiskDescription = systemDisk.Description
imageDisks := config.AlicloudImageConfig.ECSImagesDiskMappings
var dataDisks []ecs.CreateInstanceDataDisk
for _, imageDisk := range imageDisks {
var dataDisk ecs.CreateInstanceDataDisk
dataDisk.DiskName = imageDisk.DiskName
dataDisk.Category = imageDisk.DiskCategory
dataDisk.Size = string(convertNumber(imageDisk.DiskSize))
dataDisk.SnapshotId = imageDisk.SnapshotId
dataDisk.Description = imageDisk.Description
dataDisk.DeleteWithInstance = strconv.FormatBool(imageDisk.DeleteWithInstance)
dataDisk.Device = imageDisk.Device
if imageDisk.Encrypted != confighelper.TriUnset {
dataDisk.Encrypted = strconv.FormatBool(imageDisk.Encrypted.True())
}
dataDisks = append(dataDisks, dataDisk)
}
request.DataDisk = &dataDisks
return request, nil
}
func (s *stepCreateAlicloudInstance) getUserData(state multistep.StateBag) (string, error) {
userData := s.UserData
if s.UserDataFile != "" {
data, err := ioutil.ReadFile(s.UserDataFile)
if err != nil {
return "", err
}
userData = string(data)
}
if userData != "" {
userData = base64.StdEncoding.EncodeToString([]byte(userData))
}
return userData, nil
}

View File

@ -1,90 +0,0 @@
package ecs
import (
"context"
"fmt"
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepCreateAlicloudSnapshot struct {
snapshot *ecs.Snapshot
WaitSnapshotReadyTimeout int
}
func (s *stepCreateAlicloudSnapshot) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
instance := state.Get("instance").(*ecs.Instance)
describeDisksRequest := ecs.CreateDescribeDisksRequest()
describeDisksRequest.RegionId = config.AlicloudRegion
describeDisksRequest.InstanceId = instance.InstanceId
describeDisksRequest.DiskType = DiskTypeSystem
disksResponse, err := client.DescribeDisks(describeDisksRequest)
if err != nil {
return halt(state, err, "Error describe disks")
}
disks := disksResponse.Disks.Disk
if len(disks) == 0 {
return halt(state, err, "Unable to find system disk of instance")
}
createSnapshotRequest := ecs.CreateCreateSnapshotRequest()
createSnapshotRequest.DiskId = disks[0].DiskId
snapshot, err := client.CreateSnapshot(createSnapshotRequest)
if err != nil {
return halt(state, err, "Error creating snapshot")
}
// Create the alicloud snapshot
ui.Say(fmt.Sprintf("Creating snapshot from system disk %s: %s", disks[0].DiskId, snapshot.SnapshotId))
snapshotsResponse, err := client.WaitForSnapshotStatus(config.AlicloudRegion, snapshot.SnapshotId, SnapshotStatusAccomplished, time.Duration(s.WaitSnapshotReadyTimeout)*time.Second)
if err != nil {
_, ok := err.(errors.Error)
if ok {
return halt(state, err, "Error querying created snapshot")
}
return halt(state, err, "Timeout waiting for snapshot to be created")
}
snapshots := snapshotsResponse.(*ecs.DescribeSnapshotsResponse).Snapshots.Snapshot
if len(snapshots) == 0 {
return halt(state, err, "Unable to find created snapshot")
}
s.snapshot = &snapshots[0]
state.Put("alicloudsnapshot", snapshot.SnapshotId)
return multistep.ActionContinue
}
func (s *stepCreateAlicloudSnapshot) Cleanup(state multistep.StateBag) {
if s.snapshot == nil {
return
}
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
if !cancelled && !halted {
return
}
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
ui.Say("Deleting the snapshot because of cancellation or error...")
deleteSnapshotRequest := ecs.CreateDeleteSnapshotRequest()
deleteSnapshotRequest.SnapshotId = s.snapshot.SnapshotId
if _, err := client.DeleteSnapshot(deleteSnapshotRequest); err != nil {
ui.Error(fmt.Sprintf("Error deleting snapshot, it may still be around: %s", err))
return
}
}

View File

@ -1,65 +0,0 @@
package ecs
import (
"context"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepCreateTags struct {
Tags map[string]string
}
func (s *stepCreateTags) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
imageId := state.Get("alicloudimage").(string)
snapshotIds := state.Get("alicloudsnapshots").([]string)
if len(s.Tags) == 0 {
return multistep.ActionContinue
}
ui.Say(fmt.Sprintf("Adding tags(%s) to image: %s", s.Tags, imageId))
var tags []ecs.AddTagsTag
for key, value := range s.Tags {
var tag ecs.AddTagsTag
tag.Key = key
tag.Value = value
tags = append(tags, tag)
}
addTagsRequest := ecs.CreateAddTagsRequest()
addTagsRequest.RegionId = config.AlicloudRegion
addTagsRequest.ResourceId = imageId
addTagsRequest.ResourceType = TagResourceImage
addTagsRequest.Tag = &tags
if _, err := client.AddTags(addTagsRequest); err != nil {
return halt(state, err, "Error Adding tags to image")
}
for _, snapshotId := range snapshotIds {
ui.Say(fmt.Sprintf("Adding tags(%s) to snapshot: %s", s.Tags, snapshotId))
addTagsRequest := ecs.CreateAddTagsRequest()
addTagsRequest.RegionId = config.AlicloudRegion
addTagsRequest.ResourceId = snapshotId
addTagsRequest.ResourceType = TagResourceSnapshot
addTagsRequest.Tag = &tags
if _, err := client.AddTags(addTagsRequest); err != nil {
return halt(state, err, "Error Adding tags to snapshot")
}
}
return multistep.ActionContinue
}
func (s *stepCreateTags) Cleanup(state multistep.StateBag) {
// Nothing need to do, tags will be cleaned when the resource is cleaned
}

View File

@ -1,101 +0,0 @@
package ecs
import (
"context"
"fmt"
"log"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepDeleteAlicloudImageSnapshots struct {
AlicloudImageForceDelete bool
AlicloudImageForceDeleteSnapshots bool
AlicloudImageName string
AlicloudImageDestinationRegions []string
AlicloudImageDestinationNames []string
}
func (s *stepDeleteAlicloudImageSnapshots) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
// Check for force delete
if s.AlicloudImageForceDelete {
err := s.deleteImageAndSnapshots(state, s.AlicloudImageName, config.AlicloudRegion)
if err != nil {
return halt(state, err, "")
}
numberOfName := len(s.AlicloudImageDestinationNames)
if numberOfName == 0 {
return multistep.ActionContinue
}
for index, destinationRegion := range s.AlicloudImageDestinationRegions {
if destinationRegion == config.AlicloudRegion {
continue
}
if index < numberOfName {
err = s.deleteImageAndSnapshots(state, s.AlicloudImageDestinationNames[index], destinationRegion)
if err != nil {
return halt(state, err, "")
}
} else {
break
}
}
}
return multistep.ActionContinue
}
func (s *stepDeleteAlicloudImageSnapshots) deleteImageAndSnapshots(state multistep.StateBag, imageName string, region string) error {
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
describeImagesRequest := ecs.CreateDescribeImagesRequest()
describeImagesRequest.RegionId = region
describeImagesRequest.ImageName = imageName
describeImagesRequest.Status = ImageStatusQueried
imageResponse, _ := client.DescribeImages(describeImagesRequest)
images := imageResponse.Images.Image
if len(images) < 1 {
return nil
}
ui.Say(fmt.Sprintf("Deleting duplicated image and snapshot in %s: %s", region, imageName))
for _, image := range images {
if image.ImageOwnerAlias != ImageOwnerSelf {
log.Printf("You can not delete non-customized images: %s ", image.ImageId)
continue
}
deleteImageRequest := ecs.CreateDeleteImageRequest()
deleteImageRequest.RegionId = region
deleteImageRequest.ImageId = image.ImageId
if _, err := client.DeleteImage(deleteImageRequest); err != nil {
err := fmt.Errorf("Failed to delete image: %s", err)
return err
}
if s.AlicloudImageForceDeleteSnapshots {
for _, diskDevice := range image.DiskDeviceMappings.DiskDeviceMapping {
deleteSnapshotRequest := ecs.CreateDeleteSnapshotRequest()
deleteSnapshotRequest.SnapshotId = diskDevice.SnapshotId
if _, err := client.DeleteSnapshot(deleteSnapshotRequest); err != nil {
err := fmt.Errorf("Deleting ECS snapshot failed: %s", err)
return err
}
}
}
}
return nil
}
func (s *stepDeleteAlicloudImageSnapshots) Cleanup(state multistep.StateBag) {
}

View File

@ -1,87 +0,0 @@
package ecs
import (
"context"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepPreValidate struct {
AlicloudDestImageName string
ForceDelete bool
}
func (s *stepPreValidate) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
if err := s.validateRegions(state); err != nil {
return halt(state, err, "")
}
if err := s.validateDestImageName(state); err != nil {
return halt(state, err, "")
}
return multistep.ActionContinue
}
func (s *stepPreValidate) validateRegions(state multistep.StateBag) error {
ui := state.Get("ui").(packer.Ui)
config := state.Get("config").(*Config)
if config.AlicloudSkipValidation {
ui.Say("Skip region validation flag found, skipping prevalidating source region and copied regions.")
return nil
}
ui.Say("Prevalidating source region and copied regions...")
var errs *packer.MultiError
if err := config.ValidateRegion(config.AlicloudRegion); err != nil {
errs = packer.MultiErrorAppend(errs, err)
}
for _, region := range config.AlicloudImageDestinationRegions {
if err := config.ValidateRegion(region); err != nil {
errs = packer.MultiErrorAppend(errs, err)
}
}
if errs != nil && len(errs.Errors) > 0 {
return errs
}
return nil
}
func (s *stepPreValidate) validateDestImageName(state multistep.StateBag) error {
ui := state.Get("ui").(packer.Ui)
client := state.Get("client").(*ClientWrapper)
config := state.Get("config").(*Config)
if s.ForceDelete {
ui.Say("Force delete flag found, skipping prevalidating image name.")
return nil
}
ui.Say("Prevalidating image name...")
describeImagesRequest := ecs.CreateDescribeImagesRequest()
describeImagesRequest.RegionId = config.AlicloudRegion
describeImagesRequest.ImageName = s.AlicloudDestImageName
describeImagesRequest.Status = ImageStatusQueried
imagesResponse, err := client.DescribeImages(describeImagesRequest)
if err != nil {
return fmt.Errorf("Error querying alicloud image: %s", err)
}
images := imagesResponse.Images.Image
if len(images) > 0 {
return fmt.Errorf("Error: Image Name: '%s' is used by an existing alicloud image: %s", images[0].ImageName, images[0].ImageId)
}
return nil
}
func (s *stepPreValidate) Cleanup(multistep.StateBag) {}

View File

@ -1,106 +0,0 @@
package ecs
import (
"context"
"fmt"
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
confighelper "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepRegionCopyAlicloudImage struct {
AlicloudImageDestinationRegions []string
AlicloudImageDestinationNames []string
RegionId string
}
func (s *stepRegionCopyAlicloudImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
if config.ImageEncrypted != confighelper.TriUnset {
s.AlicloudImageDestinationRegions = append(s.AlicloudImageDestinationRegions, s.RegionId)
s.AlicloudImageDestinationNames = append(s.AlicloudImageDestinationNames, config.AlicloudImageName)
}
if len(s.AlicloudImageDestinationRegions) == 0 {
return multistep.ActionContinue
}
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
srcImageId := state.Get("alicloudimage").(string)
alicloudImages := state.Get("alicloudimages").(map[string]string)
numberOfName := len(s.AlicloudImageDestinationNames)
ui.Say(fmt.Sprintf("Coping image %s from %s...", srcImageId, s.RegionId))
for index, destinationRegion := range s.AlicloudImageDestinationRegions {
if destinationRegion == s.RegionId && config.ImageEncrypted == confighelper.TriUnset {
continue
}
ecsImageName := ""
if numberOfName > 0 && index < numberOfName {
ecsImageName = s.AlicloudImageDestinationNames[index]
}
copyImageRequest := ecs.CreateCopyImageRequest()
copyImageRequest.RegionId = s.RegionId
copyImageRequest.ImageId = srcImageId
copyImageRequest.DestinationRegionId = destinationRegion
copyImageRequest.DestinationImageName = ecsImageName
if config.ImageEncrypted != confighelper.TriUnset {
copyImageRequest.Encrypted = requests.NewBoolean(config.ImageEncrypted.True())
}
imageResponse, err := client.CopyImage(copyImageRequest)
if err != nil {
return halt(state, err, "Error copying images")
}
alicloudImages[destinationRegion] = imageResponse.ImageId
ui.Message(fmt.Sprintf("Copy image from %s(%s) to %s(%s)", s.RegionId, srcImageId, destinationRegion, imageResponse.ImageId))
}
if config.ImageEncrypted != confighelper.TriUnset {
if _, err := client.WaitForImageStatus(s.RegionId, alicloudImages[s.RegionId], ImageStatusAvailable, time.Duration(ALICLOUD_DEFAULT_LONG_TIMEOUT)*time.Second); err != nil {
return halt(state, err, fmt.Sprintf("Timeout waiting image %s finish copying", alicloudImages[s.RegionId]))
}
}
return multistep.ActionContinue
}
func (s *stepRegionCopyAlicloudImage) Cleanup(state multistep.StateBag) {
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
if !cancelled && !halted {
return
}
ui := state.Get("ui").(packer.Ui)
ui.Say(fmt.Sprintf("Stopping copy image because cancellation or error..."))
client := state.Get("client").(*ClientWrapper)
alicloudImages := state.Get("alicloudimages").(map[string]string)
srcImageId := state.Get("alicloudimage").(string)
for copiedRegionId, copiedImageId := range alicloudImages {
if copiedImageId == srcImageId {
continue
}
cancelCopyImageRequest := ecs.CreateCancelCopyImageRequest()
cancelCopyImageRequest.RegionId = copiedRegionId
cancelCopyImageRequest.ImageId = copiedImageId
if _, err := client.CancelCopyImage(cancelCopyImageRequest); err != nil {
ui.Error(fmt.Sprintf("Error cancelling copy image: %v", err))
}
}
}

View File

@ -1,72 +0,0 @@
package ecs
import (
"context"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepRunAlicloudInstance struct {
}
func (s *stepRunAlicloudInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*ClientWrapper)
ui := state.Get("ui").(packer.Ui)
instance := state.Get("instance").(*ecs.Instance)
startInstanceRequest := ecs.CreateStartInstanceRequest()
startInstanceRequest.InstanceId = instance.InstanceId
if _, err := client.StartInstance(startInstanceRequest); err != nil {
return halt(state, err, "Error starting instance")
}
ui.Say(fmt.Sprintf("Starting instance: %s", instance.InstanceId))
_, err := client.WaitForInstanceStatus(instance.RegionId, instance.InstanceId, InstanceStatusRunning)
if err != nil {
return halt(state, err, "Timeout waiting for instance to start")
}
return multistep.ActionContinue
}
func (s *stepRunAlicloudInstance) Cleanup(state multistep.StateBag) {
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
if !cancelled && !halted {
return
}
ui := state.Get("ui").(packer.Ui)
client := state.Get("client").(*ClientWrapper)
instance := state.Get("instance").(*ecs.Instance)
describeInstancesRequest := ecs.CreateDescribeInstancesRequest()
describeInstancesRequest.InstanceIds = fmt.Sprintf("[\"%s\"]", instance.InstanceId)
instancesResponse, _ := client.DescribeInstances(describeInstancesRequest)
if len(instancesResponse.Instances.Instance) == 0 {
return
}
instanceAttribute := instancesResponse.Instances.Instance[0]
if instanceAttribute.Status == InstanceStatusStarting || instanceAttribute.Status == InstanceStatusRunning {
stopInstanceRequest := ecs.CreateStopInstanceRequest()
stopInstanceRequest.InstanceId = instance.InstanceId
stopInstanceRequest.ForceStop = requests.NewBoolean(true)
if _, err := client.StopInstance(stopInstanceRequest); err != nil {
ui.Say(fmt.Sprintf("Error stopping instance %s, it may still be around %s", instance.InstanceId, err))
return
}
_, err := client.WaitForInstanceStatus(instance.RegionId, instance.InstanceId, InstanceStatusStopped)
if err != nil {
ui.Say(fmt.Sprintf("Error stopping instance %s, it may still be around %s", instance.InstanceId, err))
}
}
}

View File

@ -1,60 +0,0 @@
package ecs
import (
"context"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepShareAlicloudImage struct {
AlicloudImageShareAccounts []string
AlicloudImageUNShareAccounts []string
RegionId string
}
func (s *stepShareAlicloudImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*ClientWrapper)
alicloudImages := state.Get("alicloudimages").(map[string]string)
for regionId, imageId := range alicloudImages {
modifyImageShareRequest := ecs.CreateModifyImageSharePermissionRequest()
modifyImageShareRequest.RegionId = regionId
modifyImageShareRequest.ImageId = imageId
modifyImageShareRequest.AddAccount = &s.AlicloudImageShareAccounts
modifyImageShareRequest.RemoveAccount = &s.AlicloudImageUNShareAccounts
if _, err := client.ModifyImageSharePermission(modifyImageShareRequest); err != nil {
return halt(state, err, "Failed modifying image share permissions")
}
}
return multistep.ActionContinue
}
func (s *stepShareAlicloudImage) Cleanup(state multistep.StateBag) {
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
if !cancelled && !halted {
return
}
ui := state.Get("ui").(packer.Ui)
client := state.Get("client").(*ClientWrapper)
alicloudImages := state.Get("alicloudimages").(map[string]string)
ui.Say("Restoring image share permission because cancellations or error...")
for regionId, imageId := range alicloudImages {
modifyImageShareRequest := ecs.CreateModifyImageSharePermissionRequest()
modifyImageShareRequest.RegionId = regionId
modifyImageShareRequest.ImageId = imageId
modifyImageShareRequest.AddAccount = &s.AlicloudImageUNShareAccounts
modifyImageShareRequest.RemoveAccount = &s.AlicloudImageShareAccounts
if _, err := client.ModifyImageSharePermission(modifyImageShareRequest); err != nil {
ui.Say(fmt.Sprintf("Restoring image share permission failed: %s", err))
}
}
}

View File

@ -1,48 +0,0 @@
package ecs
import (
"context"
"fmt"
"strconv"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepStopAlicloudInstance struct {
ForceStop bool
DisableStop bool
}
func (s *stepStopAlicloudInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*ClientWrapper)
instance := state.Get("instance").(*ecs.Instance)
ui := state.Get("ui").(packer.Ui)
if !s.DisableStop {
ui.Say(fmt.Sprintf("Stopping instance: %s", instance.InstanceId))
stopInstanceRequest := ecs.CreateStopInstanceRequest()
stopInstanceRequest.InstanceId = instance.InstanceId
stopInstanceRequest.ForceStop = requests.Boolean(strconv.FormatBool(s.ForceStop))
if _, err := client.StopInstance(stopInstanceRequest); err != nil {
return halt(state, err, "Error stopping alicloud instance")
}
}
ui.Say(fmt.Sprintf("Waiting instance stopped: %s", instance.InstanceId))
_, err := client.WaitForInstanceStatus(instance.RegionId, instance.InstanceId, InstanceStatusStopped)
if err != nil {
return halt(state, err, "Error waiting for alicloud instance to stop")
}
return multistep.ActionContinue
}
func (s *stepStopAlicloudInstance) Cleanup(multistep.StateBag) {
// No cleanup...
}

View File

@ -1,499 +0,0 @@
//go:generate struct-markdown
//go:generate mapstructure-to-hcl2 -type Config,BlockDevices,BlockDevice
// The chroot package is able to create an Amazon AMI without requiring the
// launch of a new instance for every build. It does this by attaching and
// mounting the root volume of another AMI and chrooting into that directory.
// It then creates an AMI from that attached drive.
package chroot
import (
"context"
"errors"
"runtime"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer/builder"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/chroot"
"github.com/hashicorp/packer/hcl2template"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
)
// The unique ID for this builder
const BuilderId = "mitchellh.amazon.chroot"
// Config is the configuration that is chained through the steps and settable
// from the template.
type Config struct {
common.PackerConfig `mapstructure:",squash"`
awscommon.AMIConfig `mapstructure:",squash"`
awscommon.AccessConfig `mapstructure:",squash"`
// Add one or more [block device
// mappings](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html)
// to the AMI. If this field is populated, and you are building from an
// existing source image, the block device mappings in the source image
// will be overwritten. This means you must have a block device mapping
// entry for your root volume, `root_volume_size` and `root_device_name`.
// See the [BlockDevices](#block-devices-configuration) documentation for
// fields.
AMIMappings awscommon.BlockDevices `mapstructure:"ami_block_device_mappings" hcl2-schema-generator:"ami_block_device_mappings,direct" required:"false"`
// This is a list of devices to mount into the chroot environment. This
// configuration parameter requires some additional documentation which is
// in the Chroot Mounts section. Please read that section for more
// information on how to use this.
ChrootMounts [][]string `mapstructure:"chroot_mounts" required:"false"`
// How to run shell commands. This defaults to `{{.Command}}`. This may be
// useful to set if you want to set environmental variables or perhaps run
// it with sudo or so on. This is a configuration template where the
// .Command variable is replaced with the command to be run. Defaults to
// `{{.Command}}`.
CommandWrapper string `mapstructure:"command_wrapper" required:"false"`
// Paths to files on the running EC2 instance that will be copied into the
// chroot environment prior to provisioning. Defaults to /etc/resolv.conf
// so that DNS lookups work. Pass an empty list to skip copying
// /etc/resolv.conf. You may need to do this if you're building an image
// that uses systemd.
CopyFiles []string `mapstructure:"copy_files" required:"false"`
// The path to the device where the root volume of the source AMI will be
// attached. This defaults to "" (empty string), which forces Packer to
// find an open device automatically.
DevicePath string `mapstructure:"device_path" required:"false"`
// When we call the mount command (by default mount -o device dir), the
// string provided in nvme_mount_path will replace device in that command.
// When this option is not set, device in that command will be something
// like /dev/sdf1, mirroring the attached device name. This assumption
// works for most instances but will fail with c5 and m5 instances. In
// order to use the chroot builder with c5 and m5 instances, you must
// manually set nvme_device_path and device_path.
NVMEDevicePath string `mapstructure:"nvme_device_path" required:"false"`
// Build a new volume instead of starting from an existing AMI root volume
// snapshot. Default false. If true, source_ami/source_ami_filter are no
// longer used and the following options become required:
// ami_virtualization_type, pre_mount_commands and root_volume_size.
FromScratch bool `mapstructure:"from_scratch" required:"false"`
// Options to supply the mount command when mounting devices. Each option
// will be prefixed with -o and supplied to the mount command ran by
// Packer. Because this command is ran in a shell, user discretion is
// advised. See this manual page for the mount command for valid file
// system specific options.
MountOptions []string `mapstructure:"mount_options" required:"false"`
// The partition number containing the / partition. By default this is the
// first partition of the volume, (for example, xvda1) but you can
// designate the entire block device by setting "mount_partition": "0" in
// your config, which will mount xvda instead.
MountPartition string `mapstructure:"mount_partition" required:"false"`
// The path where the volume will be mounted. This is where the chroot
// environment will be. This defaults to
// `/mnt/packer-amazon-chroot-volumes/{{.Device}}`. This is a configuration
// template where the .Device variable is replaced with the name of the
// device where the volume is attached.
MountPath string `mapstructure:"mount_path" required:"false"`
// As pre_mount_commands, but the commands are executed after mounting the
// root device and before the extra mount and copy steps. The device and
// mount path are provided by `{{.Device}}` and `{{.MountPath}}`.
PostMountCommands []string `mapstructure:"post_mount_commands" required:"false"`
// A series of commands to execute after attaching the root volume and
// before mounting the chroot. This is not required unless using
// from_scratch. If so, this should include any partitioning and filesystem
// creation commands. The path to the device is provided by `{{.Device}}`.
PreMountCommands []string `mapstructure:"pre_mount_commands" required:"false"`
// The root device name. For example, xvda.
RootDeviceName string `mapstructure:"root_device_name" required:"false"`
// The size of the root volume in GB for the chroot environment and the
// resulting AMI. Default size is the snapshot size of the source_ami
// unless from_scratch is true, in which case this field must be defined.
RootVolumeSize int64 `mapstructure:"root_volume_size" required:"false"`
// The type of EBS volume for the chroot environment and resulting AMI. The
// default value is the type of the source_ami, unless from_scratch is
// true, in which case the default value is gp2. You can only specify io1
// if building based on top of a source_ami which is also io1.
RootVolumeType string `mapstructure:"root_volume_type" required:"false"`
// The source AMI whose root volume will be copied and provisioned on the
// currently running instance. This must be an EBS-backed AMI with a root
// volume snapshot that you have access to. Note: this is not used when
// from_scratch is set to true.
SourceAmi string `mapstructure:"source_ami" required:"true"`
// Filters used to populate the source_ami field. Example:
//
//```json
//{
// "source_ami_filter": {
// "filters": {
// "virtualization-type": "hvm",
// "name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*",
// "root-device-type": "ebs"
// },
// "owners": ["099720109477"],
// "most_recent": true
// }
//}
//```
//
//This selects the most recent Ubuntu 16.04 HVM EBS AMI from Canonical. NOTE:
//This will fail unless *exactly* one AMI is returned. In the above example,
//`most_recent` will cause this to succeed by selecting the newest image.
//
//- `filters` (map of strings) - filters used to select a `source_ami`.
// NOTE: This will fail unless *exactly* one AMI is returned. Any filter
// described in the docs for
// [DescribeImages](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeImages.html)
// is valid.
//
//- `owners` (array of strings) - Filters the images by their owner. You
// may specify one or more AWS account IDs, "self" (which will use the
// account whose credentials you are using to run Packer), or an AWS owner
// alias: for example, "amazon", "aws-marketplace", or "microsoft". This
// option is required for security reasons.
//
//- `most_recent` (boolean) - Selects the newest created image when true.
// This is most useful for selecting a daily distro build.
//
//You may set this in place of `source_ami` or in conjunction with it. If you
//set this in conjunction with `source_ami`, the `source_ami` will be added
//to the filter. The provided `source_ami` must meet all of the filtering
//criteria provided in `source_ami_filter`; this pins the AMI returned by the
//filter, but will cause Packer to fail if the `source_ami` does not exist.
SourceAmiFilter awscommon.AmiFilterOptions `mapstructure:"source_ami_filter" required:"false"`
// Key/value pair tags to apply to the volumes that are *launched*. This is
// a [template engine](/docs/templates/engine), see [Build template
// data](#build-template-data) for more information.
RootVolumeTags map[string]string `mapstructure:"root_volume_tags" required:"false"`
// Same as [`root_volume_tags`](#root_volume_tags) but defined as a
// singular block containing a `key` and a `value` field. In HCL2 mode the
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
RootVolumeTag hcl2template.KeyValues `mapstructure:"root_volume_tag" required:"false"`
// what architecture to use when registering the final AMI; valid options
// are "x86_64" or "arm64". Defaults to "x86_64".
Architecture string `mapstructure:"ami_architecture" required:"false"`
ctx interpolate.Context
}
func (c *Config) GetContext() interpolate.Context {
return c.ctx
}
type wrappedCommandTemplate struct {
Command string
}
type Builder struct {
config Config
runner multistep.Runner
}
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
b.config.ctx.Funcs = awscommon.TemplateFuncs
err := config.Decode(&b.config, &config.DecodeOpts{
Interpolate: true,
InterpolateContext: &b.config.ctx,
InterpolateFilter: &interpolate.RenderFilter{
Exclude: []string{
"ami_description",
"snapshot_tags",
"tags",
"root_volume_tags",
"command_wrapper",
"post_mount_commands",
"pre_mount_commands",
"mount_path",
},
},
}, raws...)
if err != nil {
return nil, nil, err
}
if b.config.Architecture == "" {
b.config.Architecture = "x86_64"
}
if b.config.PackerConfig.PackerForce {
b.config.AMIForceDeregister = true
}
// Defaults
if b.config.ChrootMounts == nil {
b.config.ChrootMounts = make([][]string, 0)
}
if len(b.config.ChrootMounts) == 0 {
b.config.ChrootMounts = [][]string{
{"proc", "proc", "/proc"},
{"sysfs", "sysfs", "/sys"},
{"bind", "/dev", "/dev"},
{"devpts", "devpts", "/dev/pts"},
{"binfmt_misc", "binfmt_misc", "/proc/sys/fs/binfmt_misc"},
}
}
// set default copy file if we're not giving our own
if b.config.CopyFiles == nil {
if !b.config.FromScratch {
b.config.CopyFiles = []string{"/etc/resolv.conf"}
}
}
if b.config.CommandWrapper == "" {
b.config.CommandWrapper = "{{.Command}}"
}
if b.config.MountPath == "" {
b.config.MountPath = "/mnt/packer-amazon-chroot-volumes/{{.Device}}"
}
if b.config.MountPartition == "" {
b.config.MountPartition = "1"
}
// Accumulate any errors or warnings
var errs *packer.MultiError
var warns []string
errs = packer.MultiErrorAppend(errs, b.config.RootVolumeTag.CopyOn(&b.config.RootVolumeTags)...)
errs = packer.MultiErrorAppend(errs, b.config.SourceAmiFilter.Prepare()...)
errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs,
b.config.AMIConfig.Prepare(&b.config.AccessConfig, &b.config.ctx)...)
for _, mounts := range b.config.ChrootMounts {
if len(mounts) != 3 {
errs = packer.MultiErrorAppend(
errs, errors.New("Each chroot_mounts entry should be three elements."))
break
}
}
if b.config.FromScratch {
if b.config.SourceAmi != "" || !b.config.SourceAmiFilter.Empty() {
warns = append(warns, "source_ami and source_ami_filter are unused when from_scratch is true")
}
if b.config.RootVolumeSize == 0 {
errs = packer.MultiErrorAppend(
errs, errors.New("root_volume_size is required with from_scratch."))
}
if len(b.config.PreMountCommands) == 0 {
errs = packer.MultiErrorAppend(
errs, errors.New("pre_mount_commands is required with from_scratch."))
}
if b.config.AMIVirtType == "" {
errs = packer.MultiErrorAppend(
errs, errors.New("ami_virtualization_type is required with from_scratch."))
}
if b.config.RootDeviceName == "" {
errs = packer.MultiErrorAppend(
errs, errors.New("root_device_name is required with from_scratch."))
}
if len(b.config.AMIMappings) == 0 {
errs = packer.MultiErrorAppend(
errs, errors.New("ami_block_device_mappings is required with from_scratch."))
}
} else {
if b.config.SourceAmi == "" && b.config.SourceAmiFilter.Empty() {
errs = packer.MultiErrorAppend(
errs, errors.New("source_ami or source_ami_filter is required."))
}
if len(b.config.AMIMappings) > 0 && b.config.RootDeviceName != "" {
if b.config.RootVolumeSize == 0 {
// Although, they can specify the device size in the block
// device mapping, it's easier to be specific here.
errs = packer.MultiErrorAppend(
errs, errors.New("root_volume_size is required if ami_block_device_mappings is specified"))
}
warns = append(warns, "ami_block_device_mappings from source image will be completely overwritten")
} else if len(b.config.AMIMappings) > 0 {
errs = packer.MultiErrorAppend(
errs, errors.New("If ami_block_device_mappings is specified, root_device_name must be specified"))
} else if b.config.RootDeviceName != "" {
errs = packer.MultiErrorAppend(
errs, errors.New("If root_device_name is specified, ami_block_device_mappings must be specified"))
}
}
valid := false
for _, validArch := range []string{"x86_64", "arm64"} {
if validArch == b.config.Architecture {
valid = true
break
}
}
if !valid {
errs = packer.MultiErrorAppend(errs, errors.New(`The only valid ami_architecture values are "x86_64" and "arm64"`))
}
if errs != nil && len(errs.Errors) > 0 {
return nil, warns, errs
}
packer.LogSecretFilter.Set(b.config.AccessKey, b.config.SecretKey, b.config.Token)
generatedData := awscommon.GetGeneratedDataList()
generatedData = append(generatedData, "Device", "MountPath")
return generatedData, warns, nil
}
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
if runtime.GOOS != "linux" {
return nil, errors.New("The amazon-chroot builder only works on Linux environments.")
}
session, err := b.config.Session()
if err != nil {
return nil, err
}
ec2conn := ec2.New(session)
wrappedCommand := func(command string) (string, error) {
ictx := b.config.ctx
ictx.Data = &wrappedCommandTemplate{Command: command}
return interpolate.Render(b.config.CommandWrapper, &ictx)
}
// Setup the state bag and initial state for the steps
state := new(multistep.BasicStateBag)
state.Put("config", &b.config)
state.Put("access_config", &b.config.AccessConfig)
state.Put("ami_config", &b.config.AMIConfig)
state.Put("ec2", ec2conn)
state.Put("awsSession", session)
state.Put("hook", hook)
state.Put("ui", ui)
state.Put("wrappedCommand", common.CommandWrapper(wrappedCommand))
generatedData := &builder.GeneratedData{State: state}
// Build the steps
steps := []multistep.Step{
&awscommon.StepPreValidate{
DestAmiName: b.config.AMIName,
ForceDeregister: b.config.AMIForceDeregister,
},
&StepInstanceInfo{},
}
if !b.config.FromScratch {
steps = append(steps,
&awscommon.StepSourceAMIInfo{
SourceAmi: b.config.SourceAmi,
EnableAMISriovNetSupport: b.config.AMISriovNetSupport,
EnableAMIENASupport: b.config.AMIENASupport,
AmiFilters: b.config.SourceAmiFilter,
AMIVirtType: b.config.AMIVirtType,
},
&StepCheckRootDevice{},
)
}
steps = append(steps,
&StepFlock{},
&StepPrepareDevice{
GeneratedData: generatedData,
},
&StepCreateVolume{
PollingConfig: b.config.PollingConfig,
RootVolumeType: b.config.RootVolumeType,
RootVolumeSize: b.config.RootVolumeSize,
RootVolumeTags: b.config.RootVolumeTags,
Ctx: b.config.ctx,
},
&StepAttachVolume{
PollingConfig: b.config.PollingConfig,
},
&StepEarlyUnflock{},
&chroot.StepPreMountCommands{
Commands: b.config.PreMountCommands,
},
&StepMountDevice{
MountOptions: b.config.MountOptions,
MountPartition: b.config.MountPartition,
GeneratedData: generatedData,
},
&chroot.StepPostMountCommands{
Commands: b.config.PostMountCommands,
},
&chroot.StepMountExtra{
ChrootMounts: b.config.ChrootMounts,
},
&chroot.StepCopyFiles{
Files: b.config.CopyFiles,
},
&awscommon.StepSetGeneratedData{
GeneratedData: generatedData,
},
&chroot.StepChrootProvision{},
&chroot.StepEarlyCleanup{},
&StepSnapshot{
PollingConfig: b.config.PollingConfig,
},
&awscommon.StepDeregisterAMI{
AccessConfig: &b.config.AccessConfig,
ForceDeregister: b.config.AMIForceDeregister,
ForceDeleteSnapshot: b.config.AMIForceDeleteSnapshot,
AMIName: b.config.AMIName,
Regions: b.config.AMIRegions,
},
&StepRegisterAMI{
RootVolumeSize: b.config.RootVolumeSize,
EnableAMISriovNetSupport: b.config.AMISriovNetSupport,
EnableAMIENASupport: b.config.AMIENASupport,
AMISkipBuildRegion: b.config.AMISkipBuildRegion,
PollingConfig: b.config.PollingConfig,
},
&awscommon.StepAMIRegionCopy{
AccessConfig: &b.config.AccessConfig,
Regions: b.config.AMIRegions,
AMIKmsKeyId: b.config.AMIKmsKeyId,
RegionKeyIds: b.config.AMIRegionKMSKeyIDs,
EncryptBootVolume: b.config.AMIEncryptBootVolume,
Name: b.config.AMIName,
OriginalRegion: *ec2conn.Config.Region,
},
&awscommon.StepModifyAMIAttributes{
Description: b.config.AMIDescription,
Users: b.config.AMIUsers,
Groups: b.config.AMIGroups,
ProductCodes: b.config.AMIProductCodes,
SnapshotUsers: b.config.SnapshotUsers,
SnapshotGroups: b.config.SnapshotGroups,
Ctx: b.config.ctx,
GeneratedData: generatedData,
},
&awscommon.StepCreateTags{
Tags: b.config.AMITags,
SnapshotTags: b.config.SnapshotTags,
Ctx: b.config.ctx,
},
)
// Run!
b.runner = common.NewRunner(steps, b.config.PackerConfig, ui)
b.runner.Run(ctx, state)
// If there was an error, return that
if rawErr, ok := state.GetOk("error"); ok {
return nil, rawErr.(error)
}
// If there are no AMIs, then just return
if _, ok := state.GetOk("amis"); !ok {
return nil, nil
}
// Build the artifact and return it
artifact := &awscommon.Artifact{
Amis: state.Get("amis").(map[string]string),
BuilderIdValue: BuilderId,
Session: session,
StateData: map[string]interface{}{"generated_data": state.Get("generated_data")},
}
return artifact, nil
}

View File

@ -1,160 +0,0 @@
// Code generated by "mapstructure-to-hcl2 -type Config,BlockDevices,BlockDevice"; DO NOT EDIT.
package chroot
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/hcl2template"
"github.com/zclconf/go-cty/cty"
)
// FlatConfig is an auto-generated flat version of Config.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatConfig struct {
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"`
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"`
AMIName *string `mapstructure:"ami_name" required:"true" cty:"ami_name" hcl:"ami_name"`
AMIDescription *string `mapstructure:"ami_description" required:"false" cty:"ami_description" hcl:"ami_description"`
AMIVirtType *string `mapstructure:"ami_virtualization_type" required:"false" cty:"ami_virtualization_type" hcl:"ami_virtualization_type"`
AMIUsers []string `mapstructure:"ami_users" required:"false" cty:"ami_users" hcl:"ami_users"`
AMIGroups []string `mapstructure:"ami_groups" required:"false" cty:"ami_groups" hcl:"ami_groups"`
AMIProductCodes []string `mapstructure:"ami_product_codes" required:"false" cty:"ami_product_codes" hcl:"ami_product_codes"`
AMIRegions []string `mapstructure:"ami_regions" required:"false" cty:"ami_regions" hcl:"ami_regions"`
AMISkipRegionValidation *bool `mapstructure:"skip_region_validation" required:"false" cty:"skip_region_validation" hcl:"skip_region_validation"`
AMITags map[string]string `mapstructure:"tags" required:"false" cty:"tags" hcl:"tags"`
AMITag []hcl2template.FlatKeyValue `mapstructure:"tag" required:"false" cty:"tag" hcl:"tag"`
AMIENASupport *bool `mapstructure:"ena_support" required:"false" cty:"ena_support" hcl:"ena_support"`
AMISriovNetSupport *bool `mapstructure:"sriov_support" required:"false" cty:"sriov_support" hcl:"sriov_support"`
AMIForceDeregister *bool `mapstructure:"force_deregister" required:"false" cty:"force_deregister" hcl:"force_deregister"`
AMIForceDeleteSnapshot *bool `mapstructure:"force_delete_snapshot" required:"false" cty:"force_delete_snapshot" hcl:"force_delete_snapshot"`
AMIEncryptBootVolume *bool `mapstructure:"encrypt_boot" required:"false" cty:"encrypt_boot" hcl:"encrypt_boot"`
AMIKmsKeyId *string `mapstructure:"kms_key_id" required:"false" cty:"kms_key_id" hcl:"kms_key_id"`
AMIRegionKMSKeyIDs map[string]string `mapstructure:"region_kms_key_ids" required:"false" cty:"region_kms_key_ids" hcl:"region_kms_key_ids"`
AMISkipBuildRegion *bool `mapstructure:"skip_save_build_region" cty:"skip_save_build_region" hcl:"skip_save_build_region"`
SnapshotTags map[string]string `mapstructure:"snapshot_tags" required:"false" cty:"snapshot_tags" hcl:"snapshot_tags"`
SnapshotTag []hcl2template.FlatKeyValue `mapstructure:"snapshot_tag" required:"false" cty:"snapshot_tag" hcl:"snapshot_tag"`
SnapshotUsers []string `mapstructure:"snapshot_users" required:"false" cty:"snapshot_users" hcl:"snapshot_users"`
SnapshotGroups []string `mapstructure:"snapshot_groups" required:"false" cty:"snapshot_groups" hcl:"snapshot_groups"`
AccessKey *string `mapstructure:"access_key" required:"true" cty:"access_key" hcl:"access_key"`
AssumeRole *common.FlatAssumeRoleConfig `mapstructure:"assume_role" required:"false" cty:"assume_role" hcl:"assume_role"`
CustomEndpointEc2 *string `mapstructure:"custom_endpoint_ec2" required:"false" cty:"custom_endpoint_ec2" hcl:"custom_endpoint_ec2"`
CredsFilename *string `mapstructure:"shared_credentials_file" required:"false" cty:"shared_credentials_file" hcl:"shared_credentials_file"`
DecodeAuthZMessages *bool `mapstructure:"decode_authorization_messages" required:"false" cty:"decode_authorization_messages" hcl:"decode_authorization_messages"`
InsecureSkipTLSVerify *bool `mapstructure:"insecure_skip_tls_verify" required:"false" cty:"insecure_skip_tls_verify" hcl:"insecure_skip_tls_verify"`
MaxRetries *int `mapstructure:"max_retries" required:"false" cty:"max_retries" hcl:"max_retries"`
MFACode *string `mapstructure:"mfa_code" required:"false" cty:"mfa_code" hcl:"mfa_code"`
ProfileName *string `mapstructure:"profile" required:"false" cty:"profile" hcl:"profile"`
RawRegion *string `mapstructure:"region" required:"true" cty:"region" hcl:"region"`
SecretKey *string `mapstructure:"secret_key" required:"true" cty:"secret_key" hcl:"secret_key"`
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check" hcl:"skip_metadata_api_check"`
SkipCredsValidation *bool `mapstructure:"skip_credential_validation" cty:"skip_credential_validation" hcl:"skip_credential_validation"`
Token *string `mapstructure:"token" required:"false" cty:"token" hcl:"token"`
VaultAWSEngine *common.FlatVaultAWSEngineOptions `mapstructure:"vault_aws_engine" required:"false" cty:"vault_aws_engine" hcl:"vault_aws_engine"`
PollingConfig *common.FlatAWSPollingConfig `mapstructure:"aws_polling" required:"false" cty:"aws_polling" hcl:"aws_polling"`
AMIMappings []common.FlatBlockDevice `mapstructure:"ami_block_device_mappings" hcl2-schema-generator:"ami_block_device_mappings,direct" required:"false" cty:"ami_block_device_mappings" hcl:"ami_block_device_mappings"`
ChrootMounts [][]string `mapstructure:"chroot_mounts" required:"false" cty:"chroot_mounts" hcl:"chroot_mounts"`
CommandWrapper *string `mapstructure:"command_wrapper" required:"false" cty:"command_wrapper" hcl:"command_wrapper"`
CopyFiles []string `mapstructure:"copy_files" required:"false" cty:"copy_files" hcl:"copy_files"`
DevicePath *string `mapstructure:"device_path" required:"false" cty:"device_path" hcl:"device_path"`
NVMEDevicePath *string `mapstructure:"nvme_device_path" required:"false" cty:"nvme_device_path" hcl:"nvme_device_path"`
FromScratch *bool `mapstructure:"from_scratch" required:"false" cty:"from_scratch" hcl:"from_scratch"`
MountOptions []string `mapstructure:"mount_options" required:"false" cty:"mount_options" hcl:"mount_options"`
MountPartition *string `mapstructure:"mount_partition" required:"false" cty:"mount_partition" hcl:"mount_partition"`
MountPath *string `mapstructure:"mount_path" required:"false" cty:"mount_path" hcl:"mount_path"`
PostMountCommands []string `mapstructure:"post_mount_commands" required:"false" cty:"post_mount_commands" hcl:"post_mount_commands"`
PreMountCommands []string `mapstructure:"pre_mount_commands" required:"false" cty:"pre_mount_commands" hcl:"pre_mount_commands"`
RootDeviceName *string `mapstructure:"root_device_name" required:"false" cty:"root_device_name" hcl:"root_device_name"`
RootVolumeSize *int64 `mapstructure:"root_volume_size" required:"false" cty:"root_volume_size" hcl:"root_volume_size"`
RootVolumeType *string `mapstructure:"root_volume_type" required:"false" cty:"root_volume_type" hcl:"root_volume_type"`
SourceAmi *string `mapstructure:"source_ami" required:"true" cty:"source_ami" hcl:"source_ami"`
SourceAmiFilter *common.FlatAmiFilterOptions `mapstructure:"source_ami_filter" required:"false" cty:"source_ami_filter" hcl:"source_ami_filter"`
RootVolumeTags map[string]string `mapstructure:"root_volume_tags" required:"false" cty:"root_volume_tags" hcl:"root_volume_tags"`
RootVolumeTag []hcl2template.FlatKeyValue `mapstructure:"root_volume_tag" required:"false" cty:"root_volume_tag" hcl:"root_volume_tag"`
Architecture *string `mapstructure:"ami_architecture" required:"false" cty:"ami_architecture" hcl:"ami_architecture"`
}
// FlatMapstructure returns a new FlatConfig.
// FlatConfig is an auto-generated flat version of Config.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatConfig)
}
// HCL2Spec returns the hcl spec of a Config.
// This spec is used by HCL to read the fields of Config.
// The decoded values from this spec will then be applied to a FlatConfig.
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
"packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false},
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
"ami_name": &hcldec.AttrSpec{Name: "ami_name", Type: cty.String, Required: false},
"ami_description": &hcldec.AttrSpec{Name: "ami_description", Type: cty.String, Required: false},
"ami_virtualization_type": &hcldec.AttrSpec{Name: "ami_virtualization_type", Type: cty.String, Required: false},
"ami_users": &hcldec.AttrSpec{Name: "ami_users", Type: cty.List(cty.String), Required: false},
"ami_groups": &hcldec.AttrSpec{Name: "ami_groups", Type: cty.List(cty.String), Required: false},
"ami_product_codes": &hcldec.AttrSpec{Name: "ami_product_codes", Type: cty.List(cty.String), Required: false},
"ami_regions": &hcldec.AttrSpec{Name: "ami_regions", Type: cty.List(cty.String), Required: false},
"skip_region_validation": &hcldec.AttrSpec{Name: "skip_region_validation", Type: cty.Bool, Required: false},
"tags": &hcldec.AttrSpec{Name: "tags", Type: cty.Map(cty.String), Required: false},
"tag": &hcldec.BlockListSpec{TypeName: "tag", Nested: hcldec.ObjectSpec((*hcl2template.FlatKeyValue)(nil).HCL2Spec())},
"ena_support": &hcldec.AttrSpec{Name: "ena_support", Type: cty.Bool, Required: false},
"sriov_support": &hcldec.AttrSpec{Name: "sriov_support", Type: cty.Bool, Required: false},
"force_deregister": &hcldec.AttrSpec{Name: "force_deregister", Type: cty.Bool, Required: false},
"force_delete_snapshot": &hcldec.AttrSpec{Name: "force_delete_snapshot", Type: cty.Bool, Required: false},
"encrypt_boot": &hcldec.AttrSpec{Name: "encrypt_boot", Type: cty.Bool, Required: false},
"kms_key_id": &hcldec.AttrSpec{Name: "kms_key_id", Type: cty.String, Required: false},
"region_kms_key_ids": &hcldec.AttrSpec{Name: "region_kms_key_ids", Type: cty.Map(cty.String), Required: false},
"skip_save_build_region": &hcldec.AttrSpec{Name: "skip_save_build_region", Type: cty.Bool, Required: false},
"snapshot_tags": &hcldec.AttrSpec{Name: "snapshot_tags", Type: cty.Map(cty.String), Required: false},
"snapshot_tag": &hcldec.BlockListSpec{TypeName: "snapshot_tag", Nested: hcldec.ObjectSpec((*hcl2template.FlatKeyValue)(nil).HCL2Spec())},
"snapshot_users": &hcldec.AttrSpec{Name: "snapshot_users", Type: cty.List(cty.String), Required: false},
"snapshot_groups": &hcldec.AttrSpec{Name: "snapshot_groups", Type: cty.List(cty.String), Required: false},
"access_key": &hcldec.AttrSpec{Name: "access_key", Type: cty.String, Required: false},
"assume_role": &hcldec.BlockSpec{TypeName: "assume_role", Nested: hcldec.ObjectSpec((*common.FlatAssumeRoleConfig)(nil).HCL2Spec())},
"custom_endpoint_ec2": &hcldec.AttrSpec{Name: "custom_endpoint_ec2", Type: cty.String, Required: false},
"shared_credentials_file": &hcldec.AttrSpec{Name: "shared_credentials_file", Type: cty.String, Required: false},
"decode_authorization_messages": &hcldec.AttrSpec{Name: "decode_authorization_messages", Type: cty.Bool, Required: false},
"insecure_skip_tls_verify": &hcldec.AttrSpec{Name: "insecure_skip_tls_verify", Type: cty.Bool, Required: false},
"max_retries": &hcldec.AttrSpec{Name: "max_retries", Type: cty.Number, Required: false},
"mfa_code": &hcldec.AttrSpec{Name: "mfa_code", Type: cty.String, Required: false},
"profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false},
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
"secret_key": &hcldec.AttrSpec{Name: "secret_key", Type: cty.String, Required: false},
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
"skip_credential_validation": &hcldec.AttrSpec{Name: "skip_credential_validation", Type: cty.Bool, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
"aws_polling": &hcldec.BlockSpec{TypeName: "aws_polling", Nested: hcldec.ObjectSpec((*common.FlatAWSPollingConfig)(nil).HCL2Spec())},
"ami_block_device_mappings": &hcldec.BlockListSpec{TypeName: "ami_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
"chroot_mounts": &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.List(cty.String)), Required: false},
"command_wrapper": &hcldec.AttrSpec{Name: "command_wrapper", Type: cty.String, Required: false},
"copy_files": &hcldec.AttrSpec{Name: "copy_files", Type: cty.List(cty.String), Required: false},
"device_path": &hcldec.AttrSpec{Name: "device_path", Type: cty.String, Required: false},
"nvme_device_path": &hcldec.AttrSpec{Name: "nvme_device_path", Type: cty.String, Required: false},
"from_scratch": &hcldec.AttrSpec{Name: "from_scratch", Type: cty.Bool, Required: false},
"mount_options": &hcldec.AttrSpec{Name: "mount_options", Type: cty.List(cty.String), Required: false},
"mount_partition": &hcldec.AttrSpec{Name: "mount_partition", Type: cty.String, Required: false},
"mount_path": &hcldec.AttrSpec{Name: "mount_path", Type: cty.String, Required: false},
"post_mount_commands": &hcldec.AttrSpec{Name: "post_mount_commands", Type: cty.List(cty.String), Required: false},
"pre_mount_commands": &hcldec.AttrSpec{Name: "pre_mount_commands", Type: cty.List(cty.String), Required: false},
"root_device_name": &hcldec.AttrSpec{Name: "root_device_name", Type: cty.String, Required: false},
"root_volume_size": &hcldec.AttrSpec{Name: "root_volume_size", Type: cty.Number, Required: false},
"root_volume_type": &hcldec.AttrSpec{Name: "root_volume_type", Type: cty.String, Required: false},
"source_ami": &hcldec.AttrSpec{Name: "source_ami", Type: cty.String, Required: false},
"source_ami_filter": &hcldec.BlockSpec{TypeName: "source_ami_filter", Nested: hcldec.ObjectSpec((*common.FlatAmiFilterOptions)(nil).HCL2Spec())},
"root_volume_tags": &hcldec.AttrSpec{Name: "root_volume_tags", Type: cty.Map(cty.String), Required: false},
"root_volume_tag": &hcldec.BlockListSpec{TypeName: "root_volume_tag", Nested: hcldec.ObjectSpec((*hcl2template.FlatKeyValue)(nil).HCL2Spec())},
"ami_architecture": &hcldec.AttrSpec{Name: "ami_architecture", Type: cty.String, Required: false},
}
return s
}

View File

@ -1,251 +0,0 @@
package chroot
import (
"testing"
"github.com/hashicorp/packer/packer"
)
func testConfig() map[string]interface{} {
return map[string]interface{}{
"ami_name": "foo",
"source_ami": "foo",
"region": "us-east-1",
// region validation logic is checked in ami_config_test
"skip_region_validation": true,
}
}
func TestBuilder_ImplementsBuilder(t *testing.T) {
var raw interface{}
raw = &Builder{}
if _, ok := raw.(packer.Builder); !ok {
t.Fatalf("Builder should be a builder")
}
}
func TestBuilderPrepare_AMIName(t *testing.T) {
var b Builder
config := testConfig()
// Test good
config["ami_name"] = "foo"
config["skip_region_validation"] = true
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Fatalf("should not have error: %s", err)
}
// Test bad
config["ami_name"] = "foo {{"
b = Builder{}
_, warnings, err = b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err == nil {
t.Fatal("should have error")
}
// Test bad
delete(config, "ami_name")
b = Builder{}
_, warnings, err = b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err == nil {
t.Fatal("should have error")
}
}
func TestBuilderPrepare_ChrootMounts(t *testing.T) {
b := &Builder{}
config := testConfig()
config["chroot_mounts"] = nil
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Errorf("err: %s", err)
}
}
func TestBuilderPrepare_ChrootMountsBadDefaults(t *testing.T) {
b := &Builder{}
config := testConfig()
config["chroot_mounts"] = [][]string{
{"bad"},
}
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err == nil {
t.Fatal("should have error")
}
}
func TestBuilderPrepare_SourceAmi(t *testing.T) {
b := &Builder{}
config := testConfig()
config["source_ami"] = ""
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err == nil {
t.Fatal("should have error")
}
config["source_ami"] = "foo"
_, warnings, err = b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Errorf("err: %s", err)
}
}
func TestBuilderPrepare_CommandWrapper(t *testing.T) {
b := &Builder{}
config := testConfig()
config["command_wrapper"] = "echo hi; {{.Command}}"
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Errorf("err: %s", err)
}
}
func TestBuilderPrepare_CopyFiles(t *testing.T) {
b := &Builder{}
config := testConfig()
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Errorf("err: %s", err)
}
if len(b.config.CopyFiles) != 1 && b.config.CopyFiles[0] != "/etc/resolv.conf" {
t.Errorf("Was expecting default value for copy_files.")
}
}
func TestBuilderPrepare_CopyFilesNoDefault(t *testing.T) {
b := &Builder{}
config := testConfig()
config["copy_files"] = []string{}
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Errorf("err: %s", err)
}
if len(b.config.CopyFiles) > 0 {
t.Errorf("Was expecting no default value for copy_files. Found %v",
b.config.CopyFiles)
}
}
func TestBuilderPrepare_RootDeviceNameAndAMIMappings(t *testing.T) {
var b Builder
config := testConfig()
config["root_device_name"] = "/dev/sda"
config["ami_block_device_mappings"] = []interface{}{map[string]string{}}
config["root_volume_size"] = 15
_, warnings, err := b.Prepare(config)
if len(warnings) == 0 {
t.Fatal("Missing warning, stating block device mappings will be overwritten")
} else if len(warnings) > 1 {
t.Fatalf("excessive warnings: %#v", warnings)
}
if err != nil {
t.Fatalf("should not have error: %s", err)
}
}
func TestBuilderPrepare_AMIMappingsNoRootDeviceName(t *testing.T) {
var b Builder
config := testConfig()
config["ami_block_device_mappings"] = []interface{}{map[string]string{}}
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err == nil {
t.Fatalf("should have error")
}
}
func TestBuilderPrepare_RootDeviceNameNoAMIMappings(t *testing.T) {
var b Builder
config := testConfig()
config["root_device_name"] = "/dev/sda"
_, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err == nil {
t.Fatalf("should have error")
}
}
func TestBuilderPrepare_ReturnGeneratedData(t *testing.T) {
var b Builder
config := testConfig()
generatedData, warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
}
if err != nil {
t.Fatalf("should not have error: %s", err)
}
if len(generatedData) == 0 {
t.Fatalf("Generated data should not be empty")
}
if generatedData[0] != "SourceAMIName" {
t.Fatalf("Generated data should contain SourceAMIName")
}
if generatedData[1] != "BuildRegion" {
t.Fatalf("Generated data should contain BuildRegion")
}
if generatedData[2] != "SourceAMI" {
t.Fatalf("Generated data should contain SourceAMI")
}
if generatedData[3] != "SourceAMICreationDate" {
t.Fatalf("Generated data should contain SourceAMICreationDate")
}
if generatedData[4] != "SourceAMIOwner" {
t.Fatalf("Generated data should contain SourceAMIOwner")
}
if generatedData[5] != "SourceAMIOwnerName" {
t.Fatalf("Generated data should contain SourceAMIOwnerName")
}
if generatedData[6] != "Device" {
t.Fatalf("Generated data should contain Device")
}
if generatedData[7] != "MountPath" {
t.Fatalf("Generated data should contain MountPath")
}
}

View File

@ -1 +0,0 @@
package chroot

View File

@ -1,51 +0,0 @@
package chroot
import (
"fmt"
"io/ioutil"
"os"
"runtime"
"testing"
"github.com/hashicorp/packer/common"
)
func TestCopyFile(t *testing.T) {
if runtime.GOOS == "windows" {
return
}
first, err := ioutil.TempFile("", "copy_files_test")
if err != nil {
t.Fatalf("couldn't create temp file.")
}
defer os.Remove(first.Name())
newName := first.Name() + "-new"
payload := "copy_files_test.go payload"
if _, err = first.WriteString(payload); err != nil {
t.Fatalf("Couldn't write payload to first file.")
}
first.Sync()
cmd := common.ShellCommand(fmt.Sprintf("cp %s %s", first.Name(), newName))
if err := cmd.Run(); err != nil {
t.Fatalf("Couldn't copy file")
}
defer os.Remove(newName)
second, err := os.Open(newName)
if err != nil {
t.Fatalf("Couldn't open copied file.")
}
defer second.Close()
var copiedPayload = make([]byte, len(payload))
if _, err := second.Read(copiedPayload); err != nil {
t.Fatalf("Couldn't open copied file for reading.")
}
if string(copiedPayload) != payload {
t.Fatalf("payload not copied.")
}
}

View File

@ -1,70 +0,0 @@
package chroot
import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
)
// AvailableDevice finds an available device and returns it. Note that
// you should externally hold a flock or something in order to guarantee
// that this device is available across processes.
func AvailableDevice() (string, error) {
prefix, err := devicePrefix()
if err != nil {
return "", err
}
letters := "fghijklmnop"
for _, letter := range letters {
device := fmt.Sprintf("/dev/%s%c", prefix, letter)
// If the block device itself, i.e. /dev/sf, exists, then we
// can't use any of the numbers either.
if _, err := os.Stat(device); err == nil {
continue
}
// To be able to build both Paravirtual and HVM images, the unnumbered
// device and the first numbered one must be available.
// E.g. /dev/xvdf and /dev/xvdf1
numbered_device := fmt.Sprintf("%s%d", device, 1)
if _, err := os.Stat(numbered_device); err != nil {
return device, nil
}
}
return "", errors.New("available device could not be found")
}
// devicePrefix returns the prefix ("sd" or "xvd" or so on) of the devices
// on the system.
func devicePrefix() (string, error) {
available := []string{"sd", "xvd"}
f, err := os.Open("/sys/block")
if err != nil {
return "", err
}
defer f.Close()
dirs, err := f.Readdirnames(-1)
if dirs != nil && len(dirs) > 0 {
for _, dir := range dirs {
dirBase := filepath.Base(dir)
for _, prefix := range available {
if strings.HasPrefix(dirBase, prefix) {
return prefix, nil
}
}
}
}
if err != nil {
return "", err
}
return "", errors.New("device prefix could not be detected")
}

View File

@ -1,10 +0,0 @@
package chroot
import "testing"
func TestDevicePrefixMatch(t *testing.T) {
/*
if devicePrefixMatch("nvme0n1") != "" {
}
*/
}

View File

@ -1,16 +0,0 @@
// +build windows
package chroot
import (
"errors"
"os"
)
func lockFile(*os.File) error {
return errors.New("not supported on Windows")
}
func unlockFile(f *os.File) error {
return nil
}

View File

@ -1,27 +0,0 @@
// +build !windows
package chroot
import (
"os"
"golang.org/x/sys/unix"
)
// See: http://linux.die.net/include/sys/file.h
const LOCK_EX = 2
const LOCK_NB = 4
const LOCK_UN = 8
func lockFile(f *os.File) error {
err := unix.Flock(int(f.Fd()), LOCK_EX)
if err != nil {
return err
}
return nil
}
func unlockFile(f *os.File) error {
return unix.Flock(int(f.Fd()), LOCK_UN)
}

View File

@ -1,97 +0,0 @@
package chroot
import (
"context"
"fmt"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
// StepAttachVolume attaches the previously created volume to an
// available device location.
//
// Produces:
// device string - The location where the volume was attached.
// attach_cleanup CleanupFunc
type StepAttachVolume struct {
PollingConfig *awscommon.AWSPollingConfig
attached bool
volumeId string
}
func (s *StepAttachVolume) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(*ec2.EC2)
device := state.Get("device").(string)
instance := state.Get("instance").(*ec2.Instance)
ui := state.Get("ui").(packer.Ui)
volumeId := state.Get("volume_id").(string)
// For the API call, it expects "sd" prefixed devices.
attachVolume := strings.Replace(device, "/xvd", "/sd", 1)
ui.Say(fmt.Sprintf("Attaching the root volume to %s", attachVolume))
_, err := ec2conn.AttachVolume(&ec2.AttachVolumeInput{
InstanceId: instance.InstanceId,
VolumeId: &volumeId,
Device: &attachVolume,
})
if err != nil {
err := fmt.Errorf("Error attaching volume: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Mark that we attached it so we can detach it later
s.attached = true
s.volumeId = volumeId
// Wait for the volume to become attached
err = s.PollingConfig.WaitUntilVolumeAttached(ctx, ec2conn, s.volumeId)
if err != nil {
err := fmt.Errorf("Error waiting for volume: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
state.Put("attach_cleanup", s)
return multistep.ActionContinue
}
func (s *StepAttachVolume) Cleanup(state multistep.StateBag) {
ui := state.Get("ui").(packer.Ui)
if err := s.CleanupFunc(state); err != nil {
ui.Error(err.Error())
}
}
func (s *StepAttachVolume) CleanupFunc(state multistep.StateBag) error {
if !s.attached {
return nil
}
ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui)
ui.Say("Detaching EBS volume...")
_, err := ec2conn.DetachVolume(&ec2.DetachVolumeInput{VolumeId: &s.volumeId})
if err != nil {
return fmt.Errorf("Error detaching EBS volume: %s", err)
}
s.attached = false
// Wait for the volume to detach
err = s.PollingConfig.WaitUntilVolumeDetached(aws.BackgroundContext(), ec2conn, s.volumeId)
if err != nil {
return fmt.Errorf("Error waiting for volume: %s", err)
}
return nil
}

View File

@ -1,15 +0,0 @@
package chroot
import (
"testing"
"github.com/hashicorp/packer/common/chroot"
)
func TestAttachVolumeCleanupFunc_ImplementsCleanupFunc(t *testing.T) {
var raw interface{}
raw = new(StepAttachVolume)
if _, ok := raw.(chroot.Cleanup); !ok {
t.Fatalf("cleanup func should be a CleanupFunc")
}
}

View File

@ -1,32 +0,0 @@
package chroot
import (
"context"
"fmt"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
// StepCheckRootDevice makes sure the root device on the AMI is EBS-backed.
type StepCheckRootDevice struct{}
func (s *StepCheckRootDevice) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
image := state.Get("source_image").(*ec2.Image)
ui := state.Get("ui").(packer.Ui)
ui.Say("Checking the root device on source AMI...")
// It must be EBS-backed otherwise the build won't work
if *image.RootDeviceType != "ebs" {
err := fmt.Errorf("The root device of the source AMI must be EBS-backed.")
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
return multistep.ActionContinue
}
func (s *StepCheckRootDevice) Cleanup(multistep.StateBag) {}

View File

@ -1,169 +0,0 @@
package chroot
import (
"context"
"errors"
"fmt"
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
)
// StepCreateVolume creates a new volume from the snapshot of the root
// device of the AMI.
//
// Produces:
// volume_id string - The ID of the created volume
type StepCreateVolume struct {
PollingConfig *awscommon.AWSPollingConfig
volumeId string
RootVolumeSize int64
RootVolumeType string
RootVolumeTags map[string]string
Ctx interpolate.Context
}
func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
ec2conn := state.Get("ec2").(*ec2.EC2)
instance := state.Get("instance").(*ec2.Instance)
ui := state.Get("ui").(packer.Ui)
volTags, err := awscommon.TagMap(s.RootVolumeTags).EC2Tags(s.Ctx, *ec2conn.Config.Region, state)
if err != nil {
err := fmt.Errorf("Error tagging volumes: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Collect tags for tagging on resource creation
var tagSpecs []*ec2.TagSpecification
if len(volTags) > 0 {
runVolTags := &ec2.TagSpecification{
ResourceType: aws.String("volume"),
Tags: volTags,
}
tagSpecs = append(tagSpecs, runVolTags)
}
var createVolume *ec2.CreateVolumeInput
if config.FromScratch {
rootVolumeType := ec2.VolumeTypeGp2
if s.RootVolumeType == "io1" {
err := errors.New("Cannot use io1 volume when building from scratch")
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
} else if s.RootVolumeType != "" {
rootVolumeType = s.RootVolumeType
}
createVolume = &ec2.CreateVolumeInput{
AvailabilityZone: instance.Placement.AvailabilityZone,
Size: aws.Int64(s.RootVolumeSize),
VolumeType: aws.String(rootVolumeType),
}
} else {
// Determine the root device snapshot
image := state.Get("source_image").(*ec2.Image)
log.Printf("Searching for root device of the image (%s)", *image.RootDeviceName)
var rootDevice *ec2.BlockDeviceMapping
for _, device := range image.BlockDeviceMappings {
if *device.DeviceName == *image.RootDeviceName {
rootDevice = device
break
}
}
ui.Say("Creating the root volume...")
createVolume, err = s.buildCreateVolumeInput(*instance.Placement.AvailabilityZone, rootDevice)
if err != nil {
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
}
if len(tagSpecs) > 0 {
createVolume.SetTagSpecifications(tagSpecs)
volTags.Report(ui)
}
log.Printf("Create args: %+v", createVolume)
createVolumeResp, err := ec2conn.CreateVolume(createVolume)
if err != nil {
err := fmt.Errorf("Error creating root volume: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Set the volume ID so we remember to delete it later
s.volumeId = *createVolumeResp.VolumeId
log.Printf("Volume ID: %s", s.volumeId)
// Wait for the volume to become ready
err = s.PollingConfig.WaitUntilVolumeAvailable(ctx, ec2conn, s.volumeId)
if err != nil {
err := fmt.Errorf("Error waiting for volume: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
state.Put("volume_id", s.volumeId)
return multistep.ActionContinue
}
func (s *StepCreateVolume) Cleanup(state multistep.StateBag) {
if s.volumeId == "" {
return
}
ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui)
ui.Say("Deleting the created EBS volume...")
_, err := ec2conn.DeleteVolume(&ec2.DeleteVolumeInput{VolumeId: &s.volumeId})
if err != nil {
ui.Error(fmt.Sprintf("Error deleting EBS volume: %s", err))
}
}
func (s *StepCreateVolume) buildCreateVolumeInput(az string, rootDevice *ec2.BlockDeviceMapping) (*ec2.CreateVolumeInput, error) {
if rootDevice == nil {
return nil, fmt.Errorf("Couldn't find root device!")
}
createVolumeInput := &ec2.CreateVolumeInput{
AvailabilityZone: aws.String(az),
Size: rootDevice.Ebs.VolumeSize,
SnapshotId: rootDevice.Ebs.SnapshotId,
VolumeType: rootDevice.Ebs.VolumeType,
Iops: rootDevice.Ebs.Iops,
}
if s.RootVolumeSize > *rootDevice.Ebs.VolumeSize {
createVolumeInput.Size = aws.Int64(s.RootVolumeSize)
}
if s.RootVolumeType == "" || s.RootVolumeType == *rootDevice.Ebs.VolumeType {
return createVolumeInput, nil
}
if s.RootVolumeType == "io1" {
return nil, fmt.Errorf("Root volume type cannot be io1, because existing root volume type was %s", *rootDevice.Ebs.VolumeType)
}
createVolumeInput.VolumeType = aws.String(s.RootVolumeType)
// non io1 cannot set iops
createVolumeInput.Iops = nil
return createVolumeInput, nil
}

View File

@ -1,74 +0,0 @@
package chroot
import (
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/stretchr/testify/assert"
)
func buildTestRootDevice() *ec2.BlockDeviceMapping {
return &ec2.BlockDeviceMapping{
Ebs: &ec2.EbsBlockDevice{
VolumeSize: aws.Int64(10),
SnapshotId: aws.String("snap-1234"),
VolumeType: aws.String("gp2"),
},
}
}
func TestCreateVolume_Default(t *testing.T) {
stepCreateVolume := new(StepCreateVolume)
_, err := stepCreateVolume.buildCreateVolumeInput("test-az", buildTestRootDevice())
assert.NoError(t, err)
}
func TestCreateVolume_Shrink(t *testing.T) {
stepCreateVolume := StepCreateVolume{RootVolumeSize: 1}
testRootDevice := buildTestRootDevice()
ret, err := stepCreateVolume.buildCreateVolumeInput("test-az", testRootDevice)
assert.NoError(t, err)
// Ensure that the new value is equal to the size of the old root device
assert.Equal(t, *ret.Size, *testRootDevice.Ebs.VolumeSize)
}
func TestCreateVolume_Expand(t *testing.T) {
stepCreateVolume := StepCreateVolume{RootVolumeSize: 25}
testRootDevice := buildTestRootDevice()
ret, err := stepCreateVolume.buildCreateVolumeInput("test-az", testRootDevice)
assert.NoError(t, err)
// Ensure that the new value is equal to the size of the value passed in
assert.Equal(t, *ret.Size, stepCreateVolume.RootVolumeSize)
}
func TestCreateVolume_io1_to_io1(t *testing.T) {
stepCreateVolume := StepCreateVolume{RootVolumeType: "io1"}
testRootDevice := buildTestRootDevice()
testRootDevice.Ebs.VolumeType = aws.String("io1")
testRootDevice.Ebs.Iops = aws.Int64(1000)
ret, err := stepCreateVolume.buildCreateVolumeInput("test-az", testRootDevice)
assert.NoError(t, err)
assert.Equal(t, *ret.VolumeType, stepCreateVolume.RootVolumeType)
assert.Equal(t, *ret.Iops, *testRootDevice.Ebs.Iops)
}
func TestCreateVolume_io1_to_gp2(t *testing.T) {
stepCreateVolume := StepCreateVolume{RootVolumeType: "gp2"}
testRootDevice := buildTestRootDevice()
testRootDevice.Ebs.VolumeType = aws.String("io1")
testRootDevice.Ebs.Iops = aws.Int64(1000)
ret, err := stepCreateVolume.buildCreateVolumeInput("test-az", testRootDevice)
assert.NoError(t, err)
assert.Equal(t, *ret.VolumeType, stepCreateVolume.RootVolumeType)
assert.Nil(t, ret.Iops)
}
func TestCreateVolume_gp2_to_io1(t *testing.T) {
stepCreateVolume := StepCreateVolume{RootVolumeType: "io1"}
testRootDevice := buildTestRootDevice()
_, err := stepCreateVolume.buildCreateVolumeInput("test-az", testRootDevice)
assert.Error(t, err)
}

View File

@ -1,31 +0,0 @@
package chroot
import (
"context"
"fmt"
"log"
"github.com/hashicorp/packer/common/chroot"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
// StepEarlyUnflock unlocks the flock.
type StepEarlyUnflock struct{}
func (s *StepEarlyUnflock) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
cleanup := state.Get("flock_cleanup").(chroot.Cleanup)
ui := state.Get("ui").(packer.Ui)
log.Println("Unlocking file lock...")
if err := cleanup.CleanupFunc(state); err != nil {
err := fmt.Errorf("Error unlocking file lock: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
return multistep.ActionContinue
}
func (s *StepEarlyUnflock) Cleanup(state multistep.StateBag) {}

View File

@ -1,74 +0,0 @@
package chroot
import (
"context"
"fmt"
"log"
"os"
"path/filepath"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
// StepFlock provisions the instance within a chroot.
//
// Produces:
// flock_cleanup Cleanup - To perform early cleanup
type StepFlock struct {
fh *os.File
}
func (s *StepFlock) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
lockfile := "/var/lock/packer-chroot/lock"
if err := os.MkdirAll(filepath.Dir(lockfile), 0755); err != nil {
err := fmt.Errorf("Error creating lock: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
log.Printf("Obtaining lock: %s", lockfile)
f, err := os.Create(lockfile)
if err != nil {
err := fmt.Errorf("Error creating lock: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// LOCK!
if err := lockFile(f); err != nil {
err := fmt.Errorf("Error obtaining lock: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Set the file handle, we can't close it because we need to hold
// the lock.
s.fh = f
state.Put("flock_cleanup", s)
return multistep.ActionContinue
}
func (s *StepFlock) Cleanup(state multistep.StateBag) {
s.CleanupFunc(state)
}
func (s *StepFlock) CleanupFunc(state multistep.StateBag) error {
if s.fh == nil {
return nil
}
log.Printf("Unlocking: %s", s.fh.Name())
if err := unlockFile(s.fh); err != nil {
return err
}
s.fh = nil
return nil
}

View File

@ -1,15 +0,0 @@
package chroot
import (
"testing"
"github.com/hashicorp/packer/common/chroot"
)
func TestFlockCleanupFunc_ImplementsCleanupFunc(t *testing.T) {
var raw interface{}
raw = new(StepFlock)
if _, ok := raw.(chroot.Cleanup); !ok {
t.Fatalf("cleanup func should be a CleanupFunc")
}
}

View File

@ -1,60 +0,0 @@
package chroot
import (
"context"
"fmt"
"log"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
// StepInstanceInfo verifies that this builder is running on an EC2 instance.
type StepInstanceInfo struct{}
func (s *StepInstanceInfo) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(*ec2.EC2)
session := state.Get("awsSession").(*session.Session)
ui := state.Get("ui").(packer.Ui)
// Get our own instance ID
ui.Say("Gathering information about this EC2 instance...")
ec2meta := ec2metadata.New(session)
identity, err := ec2meta.GetInstanceIdentityDocument()
if err != nil {
err := fmt.Errorf(
"Error retrieving the ID of the instance Packer is running on.\n" +
"Please verify Packer is running on a proper AWS EC2 instance.")
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
log.Printf("Instance ID: %s", identity.InstanceID)
// Query the entire instance metadata
instancesResp, err := ec2conn.DescribeInstances(&ec2.DescribeInstancesInput{InstanceIds: []*string{&identity.InstanceID}})
if err != nil {
err := fmt.Errorf("Error getting instance data: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
if len(instancesResp.Reservations) == 0 {
err := fmt.Errorf("Error getting instance data: no instance found.")
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
instance := instancesResp.Reservations[0].Instances[0]
state.Put("instance", instance)
return multistep.ActionContinue
}
func (s *StepInstanceInfo) Cleanup(multistep.StateBag) {}

View File

@ -1,157 +0,0 @@
package chroot
import (
"bytes"
"context"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/builder"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
)
type mountPathData struct {
Device string
}
// StepMountDevice mounts the attached device.
//
// Produces:
// mount_path string - The location where the volume was mounted.
// mount_device_cleanup CleanupFunc - To perform early cleanup
type StepMountDevice struct {
MountOptions []string
MountPartition string
mountPath string
GeneratedData *builder.GeneratedData
}
func (s *StepMountDevice) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
ui := state.Get("ui").(packer.Ui)
device := state.Get("device").(string)
if config.NVMEDevicePath != "" {
// customizable device path for mounting NVME block devices on c5 and m5 HVM
device = config.NVMEDevicePath
}
wrappedCommand := state.Get("wrappedCommand").(common.CommandWrapper)
var virtualizationType string
if config.FromScratch || config.AMIVirtType != "" {
virtualizationType = config.AMIVirtType
} else {
image := state.Get("source_image").(*ec2.Image)
virtualizationType = *image.VirtualizationType
log.Printf("Source image virtualization type is: %s", virtualizationType)
}
ictx := config.ctx
ictx.Data = &mountPathData{Device: filepath.Base(device)}
mountPath, err := interpolate.Render(config.MountPath, &ictx)
if err != nil {
err := fmt.Errorf("Error preparing mount directory: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
mountPath, err = filepath.Abs(mountPath)
if err != nil {
err := fmt.Errorf("Error preparing mount directory: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
log.Printf("Mount path: %s", mountPath)
if err := os.MkdirAll(mountPath, 0755); err != nil {
err := fmt.Errorf("Error creating mount directory: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
deviceMount := device
if virtualizationType == "hvm" && s.MountPartition != "0" {
deviceMount = fmt.Sprintf("%s%s", device, s.MountPartition)
}
state.Put("deviceMount", deviceMount)
ui.Say("Mounting the root device...")
stderr := new(bytes.Buffer)
// build mount options from mount_options config, useful for nouuid options
// or other specific device type settings for mount
opts := ""
if len(s.MountOptions) > 0 {
opts = "-o " + strings.Join(s.MountOptions, " -o ")
}
mountCommand, err := wrappedCommand(
fmt.Sprintf("mount %s %s %s", opts, deviceMount, mountPath))
if err != nil {
err := fmt.Errorf("Error creating mount command: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
log.Printf("[DEBUG] (step mount) mount command is %s", mountCommand)
cmd := common.ShellCommand(mountCommand)
cmd.Stderr = stderr
if err := cmd.Run(); err != nil {
err := fmt.Errorf(
"Error mounting root volume: %s\nStderr: %s", err, stderr.String())
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Set the mount path so we remember to unmount it later
s.mountPath = mountPath
state.Put("mount_path", s.mountPath)
s.GeneratedData.Put("MountPath", s.mountPath)
state.Put("mount_device_cleanup", s)
return multistep.ActionContinue
}
func (s *StepMountDevice) Cleanup(state multistep.StateBag) {
ui := state.Get("ui").(packer.Ui)
if err := s.CleanupFunc(state); err != nil {
ui.Error(err.Error())
}
}
func (s *StepMountDevice) CleanupFunc(state multistep.StateBag) error {
if s.mountPath == "" {
return nil
}
ui := state.Get("ui").(packer.Ui)
wrappedCommand := state.Get("wrappedCommand").(common.CommandWrapper)
ui.Say("Unmounting the root device...")
unmountCommand, err := wrappedCommand(fmt.Sprintf("umount %s", s.mountPath))
if err != nil {
return fmt.Errorf("Error creating unmount command: %s", err)
}
cmd := common.ShellCommand(unmountCommand)
if err := cmd.Run(); err != nil {
return fmt.Errorf("Error unmounting root device: %s", err)
}
s.mountPath = ""
return nil
}

View File

@ -1,15 +0,0 @@
package chroot
import (
"testing"
"github.com/hashicorp/packer/common/chroot"
)
func TestMountDeviceCleanupFunc_ImplementsCleanupFunc(t *testing.T) {
var raw interface{}
raw = new(StepMountDevice)
if _, ok := raw.(chroot.Cleanup); !ok {
t.Fatalf("cleanup func should be a CleanupFunc")
}
}

View File

@ -1,49 +0,0 @@
package chroot
import (
"context"
"fmt"
"log"
"os"
"github.com/hashicorp/packer/builder"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
// StepPrepareDevice finds an available device and sets it.
type StepPrepareDevice struct {
GeneratedData *builder.GeneratedData
}
func (s *StepPrepareDevice) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
ui := state.Get("ui").(packer.Ui)
device := config.DevicePath
if device == "" {
var err error
log.Println("Device path not specified, searching for available device...")
device, err = AvailableDevice()
if err != nil {
err := fmt.Errorf("Error finding available device: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
}
if _, err := os.Stat(device); err == nil {
err := fmt.Errorf("Device is in use: %s", device)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
log.Printf("Device: %s", device)
state.Put("device", device)
s.GeneratedData.Put("Device", device)
return multistep.ActionContinue
}
func (s *StepPrepareDevice) Cleanup(state multistep.StateBag) {}

View File

@ -1,169 +0,0 @@
package chroot
import (
"context"
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/common/random"
confighelper "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
// StepRegisterAMI creates the AMI.
type StepRegisterAMI struct {
PollingConfig *awscommon.AWSPollingConfig
RootVolumeSize int64
EnableAMIENASupport confighelper.Trilean
EnableAMISriovNetSupport bool
AMISkipBuildRegion bool
}
func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
ec2conn := state.Get("ec2").(*ec2.EC2)
snapshotID := state.Get("snapshot_id").(string)
ui := state.Get("ui").(packer.Ui)
ui.Say("Registering the AMI...")
var registerOpts *ec2.RegisterImageInput
// Create the image
amiName := config.AMIName
state.Put("intermediary_image", false)
if config.AMIEncryptBootVolume.True() || s.AMISkipBuildRegion {
state.Put("intermediary_image", true)
// From AWS SDK docs: You can encrypt a copy of an unencrypted snapshot,
// but you cannot use it to create an unencrypted copy of an encrypted
// snapshot. Your default CMK for EBS is used unless you specify a
// non-default key using KmsKeyId.
// If encrypt_boot is nil or true, we need to create a temporary image
// so that in step_region_copy, we can copy it with the correct
// encryption
amiName = random.AlphaNum(7)
}
// Source Image is only required to be passed if the image is not from scratch
if config.FromScratch {
registerOpts = buildBaseRegisterOpts(config, nil, s.RootVolumeSize, snapshotID, amiName)
} else {
image := state.Get("source_image").(*ec2.Image)
registerOpts = buildBaseRegisterOpts(config, image, s.RootVolumeSize, snapshotID, amiName)
}
if s.EnableAMISriovNetSupport {
// Set SriovNetSupport to "simple". See http://goo.gl/icuXh5
// As of February 2017, this applies to C3, C4, D2, I2, R3, and M4 (excluding m4.16xlarge)
registerOpts.SriovNetSupport = aws.String("simple")
}
if s.EnableAMIENASupport.True() {
// Set EnaSupport to true
// As of February 2017, this applies to C5, I3, P2, R4, X1, and m4.16xlarge
registerOpts.EnaSupport = aws.Bool(true)
}
registerResp, err := ec2conn.RegisterImage(registerOpts)
if err != nil {
state.Put("error", fmt.Errorf("Error registering AMI: %s", err))
ui.Error(state.Get("error").(error).Error())
return multistep.ActionHalt
}
// Set the AMI ID in the state
ui.Say(fmt.Sprintf("AMI: %s", *registerResp.ImageId))
amis := make(map[string]string)
amis[*ec2conn.Config.Region] = *registerResp.ImageId
state.Put("amis", amis)
ui.Say("Waiting for AMI to become ready...")
if err := s.PollingConfig.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil {
err := fmt.Errorf("Error waiting for AMI: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
return multistep.ActionContinue
}
func (s *StepRegisterAMI) Cleanup(state multistep.StateBag) {}
// Builds the base register opts with architecture, name, root block device, mappings, virtualizationtype
func buildBaseRegisterOpts(config *Config, sourceImage *ec2.Image, rootVolumeSize int64, snapshotID string, amiName string) *ec2.RegisterImageInput {
var (
mappings []*ec2.BlockDeviceMapping
rootDeviceName string
)
generatingNewBlockDeviceMappings := config.FromScratch || len(config.AMIMappings) > 0
if generatingNewBlockDeviceMappings {
mappings = config.AMIMappings.BuildEC2BlockDeviceMappings()
rootDeviceName = config.RootDeviceName
} else {
// If config.FromScratch is false, source image must be set
mappings = sourceImage.BlockDeviceMappings
rootDeviceName = *sourceImage.RootDeviceName
}
newMappings := make([]*ec2.BlockDeviceMapping, len(mappings))
for i, device := range mappings {
newDevice := device
if *newDevice.DeviceName == rootDeviceName {
if newDevice.Ebs != nil {
newDevice.Ebs.SnapshotId = aws.String(snapshotID)
} else {
newDevice.Ebs = &ec2.EbsBlockDevice{SnapshotId: aws.String(snapshotID)}
}
if generatingNewBlockDeviceMappings || rootVolumeSize > *newDevice.Ebs.VolumeSize {
newDevice.Ebs.VolumeSize = aws.Int64(rootVolumeSize)
}
}
// assume working from a snapshot, so we unset the Encrypted field if set,
// otherwise AWS API will return InvalidParameter
if newDevice.Ebs != nil && newDevice.Ebs.Encrypted != nil {
newDevice.Ebs.Encrypted = nil
}
newMappings[i] = newDevice
}
if config.FromScratch {
return &ec2.RegisterImageInput{
Name: &amiName,
Architecture: aws.String(config.Architecture),
RootDeviceName: aws.String(rootDeviceName),
VirtualizationType: aws.String(config.AMIVirtType),
BlockDeviceMappings: newMappings,
}
}
return buildRegisterOptsFromExistingImage(config, sourceImage, newMappings, rootDeviceName, amiName)
}
func buildRegisterOptsFromExistingImage(config *Config, image *ec2.Image, mappings []*ec2.BlockDeviceMapping, rootDeviceName string, amiName string) *ec2.RegisterImageInput {
registerOpts := &ec2.RegisterImageInput{
Name: &amiName,
Architecture: image.Architecture,
RootDeviceName: &rootDeviceName,
BlockDeviceMappings: mappings,
VirtualizationType: image.VirtualizationType,
}
if config.AMIVirtType != "" {
registerOpts.VirtualizationType = aws.String(config.AMIVirtType)
}
if config.AMIVirtType != "hvm" {
registerOpts.KernelId = image.KernelId
registerOpts.RamdiskId = image.RamdiskId
}
return registerOpts
}

View File

@ -1,216 +0,0 @@
package chroot
import (
"testing"
amazon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/common"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
)
func testImage() ec2.Image {
return ec2.Image{
ImageId: aws.String("ami-abcd1234"),
Name: aws.String("ami_test_name"),
Architecture: aws.String("x86_64"),
KernelId: aws.String("aki-abcd1234"),
}
}
func TestStepRegisterAmi_buildRegisterOpts_pv(t *testing.T) {
config := Config{}
config.AMIName = "test_ami_name"
config.AMIDescription = "test_ami_description"
config.AMIVirtType = "paravirtual"
rootDeviceName := "foo"
image := testImage()
blockDevices := []*ec2.BlockDeviceMapping{}
opts := buildRegisterOptsFromExistingImage(&config, &image, blockDevices, rootDeviceName, config.AMIName)
expected := config.AMIVirtType
if *opts.VirtualizationType != expected {
t.Fatalf("Unexpected VirtType value: expected %s got %s\n", expected, *opts.VirtualizationType)
}
expected = config.AMIName
if *opts.Name != expected {
t.Fatalf("Unexpected Name value: expected %s got %s\n", expected, *opts.Name)
}
expected = *image.KernelId
if *opts.KernelId != expected {
t.Fatalf("Unexpected KernelId value: expected %s got %s\n", expected, *opts.KernelId)
}
expected = rootDeviceName
if *opts.RootDeviceName != expected {
t.Fatalf("Unexpected RootDeviceName value: expected %s got %s\n", expected, *opts.RootDeviceName)
}
}
func TestStepRegisterAmi_buildRegisterOpts_hvm(t *testing.T) {
config := Config{}
config.AMIName = "test_ami_name"
config.AMIDescription = "test_ami_description"
config.AMIVirtType = "hvm"
rootDeviceName := "foo"
image := testImage()
blockDevices := []*ec2.BlockDeviceMapping{}
opts := buildRegisterOptsFromExistingImage(&config, &image, blockDevices, rootDeviceName, config.AMIName)
expected := config.AMIVirtType
if *opts.VirtualizationType != expected {
t.Fatalf("Unexpected VirtType value: expected %s got %s\n", expected, *opts.VirtualizationType)
}
expected = config.AMIName
if *opts.Name != expected {
t.Fatalf("Unexpected Name value: expected %s got %s\n", expected, *opts.Name)
}
if opts.KernelId != nil {
t.Fatalf("Unexpected KernelId value: expected nil got %s\n", *opts.KernelId)
}
expected = rootDeviceName
if *opts.RootDeviceName != expected {
t.Fatalf("Unexpected RootDeviceName value: expected %s got %s\n", expected, *opts.RootDeviceName)
}
}
func TestStepRegisterAmi_buildRegisterOptsFromScratch(t *testing.T) {
rootDeviceName := "/dev/sda"
snapshotID := "foo"
config := Config{
FromScratch: true,
PackerConfig: common.PackerConfig{},
AMIMappings: []amazon.BlockDevice{
{
DeviceName: rootDeviceName,
},
},
RootDeviceName: rootDeviceName,
}
registerOpts := buildBaseRegisterOpts(&config, nil, 10, snapshotID, config.AMIName)
if len(registerOpts.BlockDeviceMappings) != 1 {
t.Fatal("Expected block device mapping of length 1")
}
if *registerOpts.BlockDeviceMappings[0].Ebs.SnapshotId != snapshotID {
t.Fatalf("Snapshot ID of root disk not set to snapshot id %s", rootDeviceName)
}
}
func TestStepRegisterAmi_buildRegisterOptFromExistingImage(t *testing.T) {
rootDeviceName := "/dev/sda"
snapshotID := "foo"
config := Config{
FromScratch: false,
PackerConfig: common.PackerConfig{},
}
sourceImage := ec2.Image{
RootDeviceName: &rootDeviceName,
BlockDeviceMappings: []*ec2.BlockDeviceMapping{
{
DeviceName: &rootDeviceName,
Ebs: &ec2.EbsBlockDevice{
VolumeSize: aws.Int64(10),
},
},
// Throw in an ephemeral device, it seems like all devices in the return struct in a source AMI have
// a size, even if it's for ephemeral
{
DeviceName: aws.String("/dev/sdb"),
VirtualName: aws.String("ephemeral0"),
Ebs: &ec2.EbsBlockDevice{
VolumeSize: aws.Int64(0),
},
},
},
}
registerOpts := buildBaseRegisterOpts(&config, &sourceImage, 15, snapshotID, config.AMIName)
if len(registerOpts.BlockDeviceMappings) != 2 {
t.Fatal("Expected block device mapping of length 2")
}
for _, dev := range registerOpts.BlockDeviceMappings {
if dev.Ebs.SnapshotId != nil && *dev.Ebs.SnapshotId == snapshotID {
// Even though root volume size is in config, it isn't used, instead we use the root volume size
// that's derived when we build the step
if *dev.Ebs.VolumeSize != 15 {
t.Fatalf("Root volume size not 15 GB instead %d", *dev.Ebs.VolumeSize)
}
return
}
}
t.Fatalf("Could not find device with snapshot ID %s", snapshotID)
}
func TestStepRegisterAmi_buildRegisterOptFromExistingImageWithBlockDeviceMappings(t *testing.T) {
const (
rootDeviceName = "/dev/xvda"
oldRootDevice = "/dev/sda1"
)
snapshotId := "foo"
config := Config{
FromScratch: false,
PackerConfig: common.PackerConfig{},
AMIMappings: []amazon.BlockDevice{
{
DeviceName: rootDeviceName,
},
},
RootDeviceName: rootDeviceName,
}
// Intentionally try to use a different root devicename
sourceImage := ec2.Image{
RootDeviceName: aws.String(oldRootDevice),
BlockDeviceMappings: []*ec2.BlockDeviceMapping{
{
DeviceName: aws.String(oldRootDevice),
Ebs: &ec2.EbsBlockDevice{
VolumeSize: aws.Int64(10),
},
},
// Throw in an ephemeral device, it seems like all devices in the return struct in a source AMI have
// a size, even if it's for ephemeral
{
DeviceName: aws.String("/dev/sdb"),
VirtualName: aws.String("ephemeral0"),
Ebs: &ec2.EbsBlockDevice{
VolumeSize: aws.Int64(0),
},
},
},
}
registerOpts := buildBaseRegisterOpts(&config, &sourceImage, 15, snapshotId, config.AMIName)
if len(registerOpts.BlockDeviceMappings) != 1 {
t.Fatal("Expected block device mapping of length 1")
}
if *registerOpts.BlockDeviceMappings[0].Ebs.SnapshotId != snapshotId {
t.Fatalf("Snapshot ID of root disk set to '%s' expected '%s'", *registerOpts.BlockDeviceMappings[0].Ebs.SnapshotId, rootDeviceName)
}
if *registerOpts.RootDeviceName != rootDeviceName {
t.Fatalf("Root device set to '%s' expected %s", *registerOpts.RootDeviceName, rootDeviceName)
}
if *registerOpts.BlockDeviceMappings[0].Ebs.VolumeSize != 15 {
t.Fatalf("Size of root disk not set to 15 GB, instead %d", *registerOpts.BlockDeviceMappings[0].Ebs.VolumeSize)
}
}

View File

@ -1,82 +0,0 @@
package chroot
import (
"context"
"fmt"
"time"
"github.com/aws/aws-sdk-go/service/ec2"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
// StepSnapshot creates a snapshot of the created volume.
//
// Produces:
// snapshot_id string - ID of the created snapshot
type StepSnapshot struct {
PollingConfig *awscommon.AWSPollingConfig
snapshotId string
}
func (s *StepSnapshot) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui)
volumeId := state.Get("volume_id").(string)
ui.Say("Creating snapshot...")
description := fmt.Sprintf("Packer: %s", time.Now().String())
createSnapResp, err := ec2conn.CreateSnapshot(&ec2.CreateSnapshotInput{
VolumeId: &volumeId,
Description: &description,
})
if err != nil {
err := fmt.Errorf("Error creating snapshot: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Set the snapshot ID so we can delete it later
s.snapshotId = *createSnapResp.SnapshotId
ui.Message(fmt.Sprintf("Snapshot ID: %s", s.snapshotId))
// Wait for the snapshot to be ready
err = s.PollingConfig.WaitUntilSnapshotDone(ctx, ec2conn, s.snapshotId)
if err != nil {
err := fmt.Errorf("Error waiting for snapshot: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
state.Put("snapshot_id", s.snapshotId)
snapshots := map[string][]string{
*ec2conn.Config.Region: {s.snapshotId},
}
state.Put("snapshots", snapshots)
return multistep.ActionContinue
}
func (s *StepSnapshot) Cleanup(state multistep.StateBag) {
if s.snapshotId == "" {
return
}
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)
if cancelled || halted {
ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui)
ui.Say("Removing snapshot since we cancelled or halted...")
_, err := ec2conn.DeleteSnapshot(&ec2.DeleteSnapshotInput{SnapshotId: &s.snapshotId})
if err != nil {
ui.Error(fmt.Sprintf("Error: %s", err))
}
}
}

View File

@ -1,430 +0,0 @@
//go:generate struct-markdown
//go:generate mapstructure-to-hcl2 -type VaultAWSEngineOptions,AssumeRoleConfig
package common
import (
"crypto/tls"
"fmt"
"log"
"net/http"
"strings"
"github.com/aws/aws-sdk-go/aws"
awsCredentials "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
awsbase "github.com/hashicorp/aws-sdk-go-base"
cleanhttp "github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/packer/template/interpolate"
vaultapi "github.com/hashicorp/vault/api"
)
// AssumeRoleConfig lets users set configuration options for assuming a special
// role when executing Packer.
//
// Usage example:
//
// HCL config example:
//
// ```HCL
// source "example" "amazon-ebs"{
// assume_role {
// role_arn = "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME"
// session_name = "SESSION_NAME"
// external_id = "EXTERNAL_ID"
// }
// }
// ```
//
// JSON config example:
//
// ```json
// builder{
// "type": "amazon-ebs",
// "assume_role": {
// "role_arn" : "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME",
// "session_name": "SESSION_NAME",
// "external_id" : "EXTERNAL_ID"
// }
// }
// ```
type AssumeRoleConfig struct {
// Amazon Resource Name (ARN) of the IAM Role to assume.
AssumeRoleARN string `mapstructure:"role_arn" required:"false"`
// Number of seconds to restrict the assume role session duration.
AssumeRoleDurationSeconds int `mapstructure:"duration_seconds" required:"false"`
// The external ID to use when assuming the role. If omitted, no external
// ID is passed to the AssumeRole call.
AssumeRoleExternalID string `mapstructure:"external_id" required:"false"`
// IAM Policy JSON describing further restricting permissions for the IAM
// Role being assumed.
AssumeRolePolicy string `mapstructure:"policy" required:"false"`
// Set of Amazon Resource Names (ARNs) of IAM Policies describing further
// restricting permissions for the IAM Role being
AssumeRolePolicyARNs []string `mapstructure:"policy_arns" required:"false"`
// Session name to use when assuming the role.
AssumeRoleSessionName string `mapstructure:"session_name" required:"false"`
// Map of assume role session tags.
AssumeRoleTags map[string]string `mapstructure:"tags" required:"false"`
// Set of assume role session tag keys to pass to any subsequent sessions.
AssumeRoleTransitiveTagKeys []string `mapstructure:"transitive_tag_keys" required:"false"`
}
type VaultAWSEngineOptions struct {
Name string `mapstructure:"name"`
RoleARN string `mapstructure:"role_arn"`
// Specifies the TTL for the use of the STS token. This
// is specified as a string with a duration suffix. Valid only when
// credential_type is assumed_role or federation_token. When not
// specified, the default_sts_ttl set for the role will be used. If that
// is also not set, then the default value of 3600s will be used. AWS
// places limits on the maximum TTL allowed. See the AWS documentation on
// the DurationSeconds parameter for AssumeRole (for assumed_role
// credential types) and GetFederationToken (for federation_token
// credential types) for more details.
TTL string `mapstructure:"ttl" required:"false"`
EngineName string `mapstructure:"engine_name"`
}
func (v *VaultAWSEngineOptions) Empty() bool {
return len(v.Name) == 0 && len(v.RoleARN) == 0 &&
len(v.EngineName) == 0 && len(v.TTL) == 0
}
// AccessConfig is for common configuration related to AWS access
type AccessConfig struct {
// The access key used to communicate with AWS. [Learn how to set this]
// (/docs/builders/amazon#specifying-amazon-credentials). On EBS, this
// is not required if you are using `use_vault_aws_engine` for
// authentication instead.
AccessKey string `mapstructure:"access_key" required:"true"`
// If provided with a role ARN, Packer will attempt to assume this role
// using the supplied credentials. See
// [AssumeRoleConfig](#assume-role-configuration) below for more
// details on all of the options available, and for a usage example.
AssumeRole AssumeRoleConfig `mapstructure:"assume_role" required:"false"`
// This option is useful if you use a cloud
// provider whose API is compatible with aws EC2. Specify another endpoint
// like this https://ec2.custom.endpoint.com.
CustomEndpointEc2 string `mapstructure:"custom_endpoint_ec2" required:"false"`
// Path to a credentials file to load credentials from
CredsFilename string `mapstructure:"shared_credentials_file" required:"false"`
// Enable automatic decoding of any encoded authorization (error) messages
// using the `sts:DecodeAuthorizationMessage` API. Note: requires that the
// effective user/role have permissions to `sts:DecodeAuthorizationMessage`
// on resource `*`. Default `false`.
DecodeAuthZMessages bool `mapstructure:"decode_authorization_messages" required:"false"`
// This allows skipping TLS
// verification of the AWS EC2 endpoint. The default is false.
InsecureSkipTLSVerify bool `mapstructure:"insecure_skip_tls_verify" required:"false"`
// This is the maximum number of times an API call is retried, in the case
// where requests are being throttled or experiencing transient failures.
// The delay between the subsequent API calls increases exponentially.
MaxRetries int `mapstructure:"max_retries" required:"false"`
// The MFA
// [TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm)
// code. This should probably be a user variable since it changes all the
// time.
MFACode string `mapstructure:"mfa_code" required:"false"`
// The profile to use in the shared credentials file for
// AWS. See Amazon's documentation on [specifying
// profiles](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-profiles)
// for more details.
ProfileName string `mapstructure:"profile" required:"false"`
// The name of the region, such as `us-east-1`, in which
// to launch the EC2 instance to create the AMI.
// When chroot building, this value is guessed from environment.
RawRegion string `mapstructure:"region" required:"true"`
// The secret key used to communicate with AWS. [Learn how to set
// this](/docs/builders/amazon#specifying-amazon-credentials). This is not required
// if you are using `use_vault_aws_engine` for authentication instead.
SecretKey string `mapstructure:"secret_key" required:"true"`
// Set to true if you want to skip
// validation of the ami_regions configuration option. Default false.
SkipValidation bool `mapstructure:"skip_region_validation" required:"false"`
SkipMetadataApiCheck bool `mapstructure:"skip_metadata_api_check"`
// Set to true if you want to skip validating AWS credentials before runtime.
SkipCredsValidation bool `mapstructure:"skip_credential_validation"`
// The access token to use. This is different from the
// access key and secret key. If you're not sure what this is, then you
// probably don't need it. This will also be read from the AWS_SESSION_TOKEN
// environmental variable.
Token string `mapstructure:"token" required:"false"`
session *session.Session
// Get credentials from Hashicorp Vault's aws secrets engine. You must
// already have created a role to use. For more information about
// generating credentials via the Vault engine, see the [Vault
// docs.](https://www.vaultproject.io/api/secret/aws#generate-credentials)
// If you set this flag, you must also set the below options:
// - `name` (string) - Required. Specifies the name of the role to generate
// credentials against. This is part of the request URL.
// - `engine_name` (string) - The name of the aws secrets engine. In the
// Vault docs, this is normally referred to as "aws", and Packer will
// default to "aws" if `engine_name` is not set.
// - `role_arn` (string)- The ARN of the role to assume if credential\_type
// on the Vault role is assumed\_role. Must match one of the allowed role
// ARNs in the Vault role. Optional if the Vault role only allows a single
// AWS role ARN; required otherwise.
// - `ttl` (string) - Specifies the TTL for the use of the STS token. This
// is specified as a string with a duration suffix. Valid only when
// credential\_type is assumed\_role or federation\_token. When not
// specified, the default\_sts\_ttl set for the role will be used. If that
// is also not set, then the default value of 3600s will be used. AWS
// places limits on the maximum TTL allowed. See the AWS documentation on
// the DurationSeconds parameter for AssumeRole (for assumed\_role
// credential types) and GetFederationToken (for federation\_token
// credential types) for more details.
//
// JSON example:
//
// ```json
// {
// "vault_aws_engine": {
// "name": "myrole",
// "role_arn": "myarn",
// "ttl": "3600s"
// }
// }
// ```
//
// HCL2 example:
//
// ```hcl
// vault_aws_engine {
// name = "myrole"
// role_arn = "myarn"
// ttl = "3600s"
// }
// ```
VaultAWSEngine VaultAWSEngineOptions `mapstructure:"vault_aws_engine" required:"false"`
// [Polling configuration](#polling-configuration) for the AWS waiter. Configures the waiter that checks
// resource state.
PollingConfig *AWSPollingConfig `mapstructure:"aws_polling" required:"false"`
getEC2Connection func() ec2iface.EC2API
}
// Config returns a valid aws.Config object for access to AWS services, or
// an error if the authentication and region couldn't be resolved
func (c *AccessConfig) Session() (*session.Session, error) {
if c.session != nil {
return c.session, nil
}
// Create new AWS config
config := aws.NewConfig().WithCredentialsChainVerboseErrors(true)
if c.MaxRetries > 0 {
config = config.WithMaxRetries(c.MaxRetries)
}
// Set AWS config defaults.
if c.RawRegion != "" {
config = config.WithRegion(c.RawRegion)
}
if c.CustomEndpointEc2 != "" {
config = config.WithEndpoint(c.CustomEndpointEc2)
}
config = config.WithHTTPClient(cleanhttp.DefaultClient())
transport := config.HTTPClient.Transport.(*http.Transport)
if c.InsecureSkipTLSVerify {
transport.TLSClientConfig = &tls.Config{
InsecureSkipVerify: true,
}
}
transport.Proxy = http.ProxyFromEnvironment
// Figure out which possible credential providers are valid; test that we
// can get credentials via the selected providers, and set the providers in
// the config.
creds, err := c.GetCredentials(config)
if err != nil {
return nil, err
}
config.WithCredentials(creds)
// Create session options based on our AWS config
opts := session.Options{
SharedConfigState: session.SharedConfigEnable,
Config: *config,
}
if c.ProfileName != "" {
opts.Profile = c.ProfileName
}
if c.MFACode != "" {
opts.AssumeRoleTokenProvider = func() (string, error) {
return c.MFACode, nil
}
}
sess, err := session.NewSessionWithOptions(opts)
if err != nil {
return nil, err
}
log.Printf("Found region %s", *sess.Config.Region)
c.session = sess
cp, err := c.session.Config.Credentials.Get()
if IsAWSErr(err, "NoCredentialProviders", "") {
return nil, c.NewNoValidCredentialSourcesError(err)
}
if err != nil {
return nil, fmt.Errorf("Error loading credentials for AWS Provider: %s", err)
}
log.Printf("[INFO] AWS Auth provider used: %q", cp.ProviderName)
if c.DecodeAuthZMessages {
DecodeAuthZMessages(c.session)
}
return c.session, nil
}
func (c *AccessConfig) SessionRegion() string {
if c.session == nil {
panic("access config session should be set.")
}
return aws.StringValue(c.session.Config.Region)
}
func (c *AccessConfig) IsGovCloud() bool {
return strings.HasPrefix(c.SessionRegion(), "us-gov-")
}
func (c *AccessConfig) IsChinaCloud() bool {
return strings.HasPrefix(c.SessionRegion(), "cn-")
}
// GetCredentials gets credentials from the environment, shared credentials,
// the session (which may include a credential process), or ECS/EC2 metadata
// endpoints. GetCredentials also validates the credentials and the ability to
// assume a role or will return an error if unsuccessful.
func (c *AccessConfig) GetCredentials(config *aws.Config) (*awsCredentials.Credentials, error) {
// Reload values into the config used by the Packer-Terraform shared SDK
awsbaseConfig := &awsbase.Config{
AccessKey: c.AccessKey,
AssumeRoleARN: c.AssumeRole.AssumeRoleARN,
AssumeRoleDurationSeconds: c.AssumeRole.AssumeRoleDurationSeconds,
AssumeRoleExternalID: c.AssumeRole.AssumeRoleExternalID,
AssumeRolePolicy: c.AssumeRole.AssumeRolePolicy,
AssumeRolePolicyARNs: c.AssumeRole.AssumeRolePolicyARNs,
AssumeRoleSessionName: c.AssumeRole.AssumeRoleSessionName,
AssumeRoleTags: c.AssumeRole.AssumeRoleTags,
AssumeRoleTransitiveTagKeys: c.AssumeRole.AssumeRoleTransitiveTagKeys,
CredsFilename: c.CredsFilename,
DebugLogging: false,
// TODO: implement for Packer
// IamEndpoint: c.Endpoints["iam"],
Insecure: c.InsecureSkipTLSVerify,
MaxRetries: c.MaxRetries,
Profile: c.ProfileName,
Region: c.RawRegion,
SecretKey: c.SecretKey,
SkipCredsValidation: c.SkipCredsValidation,
SkipMetadataApiCheck: c.SkipMetadataApiCheck,
// TODO: implement for Packer
// SkipRequestingAccountId: c.SkipRequestingAccountId,
// StsEndpoint: c.Endpoints["sts"],
Token: c.Token,
}
return awsbase.GetCredentials(awsbaseConfig)
}
func (c *AccessConfig) GetCredsFromVault() error {
// const EnvVaultAddress = "VAULT_ADDR"
// const EnvVaultToken = "VAULT_TOKEN"
vaultConfig := vaultapi.DefaultConfig()
cli, err := vaultapi.NewClient(vaultConfig)
if err != nil {
return fmt.Errorf("Error getting Vault client: %s", err)
}
if c.VaultAWSEngine.EngineName == "" {
c.VaultAWSEngine.EngineName = "aws"
}
path := fmt.Sprintf("/%s/creds/%s", c.VaultAWSEngine.EngineName,
c.VaultAWSEngine.Name)
secret, err := cli.Logical().Read(path)
if err != nil {
return fmt.Errorf("Error reading vault secret: %s", err)
}
if secret == nil {
return fmt.Errorf("Vault Secret does not exist at the given path.")
}
c.AccessKey = secret.Data["access_key"].(string)
c.SecretKey = secret.Data["secret_key"].(string)
token := secret.Data["security_token"]
if token != nil {
c.Token = token.(string)
} else {
c.Token = ""
}
return nil
}
func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
var errs []error
if c.SkipMetadataApiCheck {
log.Println("(WARN) skip_metadata_api_check ignored.")
}
// Make sure it's obvious from the config how we're getting credentials:
// Vault, Packer config, or environment.
if !c.VaultAWSEngine.Empty() {
if len(c.AccessKey) > 0 {
errs = append(errs,
fmt.Errorf("If you have set vault_aws_engine, you must not set"+
" the access_key or secret_key."))
}
// Go ahead and grab those credentials from Vault now, so we can set
// the keys and token now.
err := c.GetCredsFromVault()
if err != nil {
errs = append(errs, err)
}
}
if (len(c.AccessKey) > 0) != (len(c.SecretKey) > 0) {
errs = append(errs,
fmt.Errorf("`access_key` and `secret_key` must both be either set or not set."))
}
if c.PollingConfig == nil {
c.PollingConfig = new(AWSPollingConfig)
}
c.PollingConfig.LogEnvOverrideWarnings()
return errs
}
func (c *AccessConfig) NewNoValidCredentialSourcesError(err error) error {
return fmt.Errorf("No valid credential sources found for AWS Builder. "+
"Please see https://www.packer.io/docs/builders/amazon#authentication "+
"for more information on providing credentials for the AWS Builder. "+
"Error: %w", err)
}
func (c *AccessConfig) NewEC2Connection() (ec2iface.EC2API, error) {
if c.getEC2Connection != nil {
return c.getEC2Connection(), nil
}
sess, err := c.Session()
if err != nil {
return nil, err
}
ec2conn := ec2.New(sess)
return ec2conn, nil
}

View File

@ -1,73 +0,0 @@
// Code generated by "mapstructure-to-hcl2 -type VaultAWSEngineOptions,AssumeRoleConfig"; DO NOT EDIT.
package common
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/zclconf/go-cty/cty"
)
// FlatAssumeRoleConfig is an auto-generated flat version of AssumeRoleConfig.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatAssumeRoleConfig struct {
AssumeRoleARN *string `mapstructure:"role_arn" required:"false" cty:"role_arn" hcl:"role_arn"`
AssumeRoleDurationSeconds *int `mapstructure:"duration_seconds" required:"false" cty:"duration_seconds" hcl:"duration_seconds"`
AssumeRoleExternalID *string `mapstructure:"external_id" required:"false" cty:"external_id" hcl:"external_id"`
AssumeRolePolicy *string `mapstructure:"policy" required:"false" cty:"policy" hcl:"policy"`
AssumeRolePolicyARNs []string `mapstructure:"policy_arns" required:"false" cty:"policy_arns" hcl:"policy_arns"`
AssumeRoleSessionName *string `mapstructure:"session_name" required:"false" cty:"session_name" hcl:"session_name"`
AssumeRoleTags map[string]string `mapstructure:"tags" required:"false" cty:"tags" hcl:"tags"`
AssumeRoleTransitiveTagKeys []string `mapstructure:"transitive_tag_keys" required:"false" cty:"transitive_tag_keys" hcl:"transitive_tag_keys"`
}
// FlatMapstructure returns a new FlatAssumeRoleConfig.
// FlatAssumeRoleConfig is an auto-generated flat version of AssumeRoleConfig.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*AssumeRoleConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatAssumeRoleConfig)
}
// HCL2Spec returns the hcl spec of a AssumeRoleConfig.
// This spec is used by HCL to read the fields of AssumeRoleConfig.
// The decoded values from this spec will then be applied to a FlatAssumeRoleConfig.
func (*FlatAssumeRoleConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"role_arn": &hcldec.AttrSpec{Name: "role_arn", Type: cty.String, Required: false},
"duration_seconds": &hcldec.AttrSpec{Name: "duration_seconds", Type: cty.Number, Required: false},
"external_id": &hcldec.AttrSpec{Name: "external_id", Type: cty.String, Required: false},
"policy": &hcldec.AttrSpec{Name: "policy", Type: cty.String, Required: false},
"policy_arns": &hcldec.AttrSpec{Name: "policy_arns", Type: cty.List(cty.String), Required: false},
"session_name": &hcldec.AttrSpec{Name: "session_name", Type: cty.String, Required: false},
"tags": &hcldec.AttrSpec{Name: "tags", Type: cty.Map(cty.String), Required: false},
"transitive_tag_keys": &hcldec.AttrSpec{Name: "transitive_tag_keys", Type: cty.List(cty.String), Required: false},
}
return s
}
// FlatVaultAWSEngineOptions is an auto-generated flat version of VaultAWSEngineOptions.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatVaultAWSEngineOptions struct {
Name *string `mapstructure:"name" cty:"name" hcl:"name"`
RoleARN *string `mapstructure:"role_arn" cty:"role_arn" hcl:"role_arn"`
TTL *string `mapstructure:"ttl" required:"false" cty:"ttl" hcl:"ttl"`
EngineName *string `mapstructure:"engine_name" cty:"engine_name" hcl:"engine_name"`
}
// FlatMapstructure returns a new FlatVaultAWSEngineOptions.
// FlatVaultAWSEngineOptions is an auto-generated flat version of VaultAWSEngineOptions.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*VaultAWSEngineOptions) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatVaultAWSEngineOptions)
}
// HCL2Spec returns the hcl spec of a VaultAWSEngineOptions.
// This spec is used by HCL to read the fields of VaultAWSEngineOptions.
// The decoded values from this spec will then be applied to a FlatVaultAWSEngineOptions.
func (*FlatVaultAWSEngineOptions) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"name": &hcldec.AttrSpec{Name: "name", Type: cty.String, Required: false},
"role_arn": &hcldec.AttrSpec{Name: "role_arn", Type: cty.String, Required: false},
"ttl": &hcldec.AttrSpec{Name: "ttl", Type: cty.String, Required: false},
"engine_name": &hcldec.AttrSpec{Name: "engine_name", Type: cty.String, Required: false},
}
return s
}

View File

@ -1,71 +0,0 @@
package common
import (
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
)
func testAccessConfig() *AccessConfig {
return &AccessConfig{
getEC2Connection: func() ec2iface.EC2API {
return &mockEC2Client{}
},
PollingConfig: new(AWSPollingConfig),
}
}
func TestAccessConfigPrepare_Region(t *testing.T) {
c := testAccessConfig()
c.RawRegion = "us-east-12"
err := c.ValidateRegion(c.RawRegion)
if err == nil {
t.Fatalf("should have region validation err: %s", c.RawRegion)
}
c.RawRegion = "us-east-1"
err = c.ValidateRegion(c.RawRegion)
if err != nil {
t.Fatalf("shouldn't have region validation err: %s", c.RawRegion)
}
c.RawRegion = "custom"
err = c.ValidateRegion(c.RawRegion)
if err == nil {
t.Fatalf("should have region validation err: %s", c.RawRegion)
}
c.RawRegion = "custom"
c.SkipValidation = true
// testing whole prepare func here; this is checking that validation is
// skipped, so we don't need a mock connection
if err := c.Prepare(nil); err != nil {
t.Fatalf("shouldn't have err: %s", err)
}
c.SkipValidation = false
c.RawRegion = ""
if err := c.Prepare(nil); err != nil {
t.Fatalf("shouldn't have err: %s", err)
}
}
func TestAccessConfigPrepare_RegionRestricted(t *testing.T) {
c := testAccessConfig()
// Create a Session with a custom region
c.session = session.Must(session.NewSession(&aws.Config{
Region: aws.String("us-gov-west-1"),
}))
if err := c.Prepare(nil); err != nil {
t.Fatalf("shouldn't have err: %s", err)
}
if !c.IsGovCloud() {
t.Fatal("We should be in gov region.")
}
}

View File

@ -1,310 +0,0 @@
//go:generate struct-markdown
package common
import (
"fmt"
"log"
"regexp"
"github.com/hashicorp/packer/hcl2template"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
// AMIConfig is for common configuration related to creating AMIs.
type AMIConfig struct {
// The name of the resulting AMI that will appear when managing AMIs in the
// AWS console or via APIs. This must be unique. To help make this unique,
// use a function like timestamp (see [template
// engine](/docs/templates/engine) for more info).
AMIName string `mapstructure:"ami_name" required:"true"`
// The description to set for the resulting
// AMI(s). By default this description is empty. This is a
// [template engine](/docs/templates/engine), see [Build template
// data](#build-template-data) for more information.
AMIDescription string `mapstructure:"ami_description" required:"false"`
// The type of virtualization for the AMI
// you are building. This option is required to register HVM images. Can be
// paravirtual (default) or hvm.
AMIVirtType string `mapstructure:"ami_virtualization_type" required:"false"`
// A list of account IDs that have access to
// launch the resulting AMI(s). By default no additional users other than the
// user creating the AMI has permissions to launch it.
AMIUsers []string `mapstructure:"ami_users" required:"false"`
// A list of groups that have access to
// launch the resulting AMI(s). By default no groups have permission to launch
// the AMI. all will make the AMI publicly accessible.
AMIGroups []string `mapstructure:"ami_groups" required:"false"`
// A list of product codes to
// associate with the AMI. By default no product codes are associated with the
// AMI.
AMIProductCodes []string `mapstructure:"ami_product_codes" required:"false"`
// A list of regions to copy the AMI to.
// Tags and attributes are copied along with the AMI. AMI copying takes time
// depending on the size of the AMI, but will generally take many minutes.
AMIRegions []string `mapstructure:"ami_regions" required:"false"`
// Set to true if you want to skip
// validation of the ami_regions configuration option. Default false.
AMISkipRegionValidation bool `mapstructure:"skip_region_validation" required:"false"`
// Key/value pair tags applied to the AMI. This is a [template
// engine](/docs/templates/engine), see [Build template
// data](#build-template-data) for more information.
AMITags map[string]string `mapstructure:"tags" required:"false"`
// Same as [`tags`](#tags) but defined as a singular repeatable block
// containing a `key` and a `value` field. In HCL2 mode the
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
AMITag hcl2template.KeyValues `mapstructure:"tag" required:"false"`
// Enable enhanced networking (ENA but not SriovNetSupport) on
// HVM-compatible AMIs. If set, add `ec2:ModifyInstanceAttribute` to your
// AWS IAM policy.
//
// Note: you must make sure enhanced networking is enabled on your
// instance. See [Amazon's documentation on enabling enhanced
// networking](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking.html#enabling_enhanced_networking).
AMIENASupport config.Trilean `mapstructure:"ena_support" required:"false"`
// Enable enhanced networking (SriovNetSupport but not ENA) on
// HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your
// AWS IAM policy. Note: you must make sure enhanced networking is enabled
// on your instance. See [Amazon's documentation on enabling enhanced
// networking](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking.html#enabling_enhanced_networking).
// Default `false`.
AMISriovNetSupport bool `mapstructure:"sriov_support" required:"false"`
// Force Packer to first deregister an existing
// AMI if one with the same name already exists. Default false.
AMIForceDeregister bool `mapstructure:"force_deregister" required:"false"`
// Force Packer to delete snapshots
// associated with AMIs, which have been deregistered by force_deregister.
// Default false.
AMIForceDeleteSnapshot bool `mapstructure:"force_delete_snapshot" required:"false"`
// Whether or not to encrypt the resulting AMI when
// copying a provisioned instance to an AMI. By default, Packer will keep
// the encryption setting to what it was in the source image. Setting false
// will result in an unencrypted image, and true will result in an encrypted
// one.
//
// If you have used the `launch_block_device_mappings` to set an encryption
// key and that key is the same as the one you want the image encrypted with
// at the end, then you don't need to set this field; leaving it empty will
// prevent an unnecessary extra copy step and save you some time.
AMIEncryptBootVolume config.Trilean `mapstructure:"encrypt_boot" required:"false"`
// ID, alias or ARN of the KMS key to use for AMI encryption. This
// only applies to the main `region` -- any regions the AMI gets copied to
// copied will be encrypted by the default EBS KMS key for that region,
// unless you set region-specific keys in AMIRegionKMSKeyIDs.
//
// Set this value if you select `encrypt_boot`, but don't want to use the
// region's default KMS key.
//
// If you have a custom kms key you'd like to apply to the launch volume,
// and are only building in one region, it is more efficient to leave this
// and `encrypt_boot` empty and to instead set the key id in the
// launch_block_device_mappings (you can find an example below). This saves
// potentially many minutes at the end of the build by preventing Packer
// from having to copy and re-encrypt the image at the end of the build.
//
// For valid formats see *KmsKeyId* in the [AWS API docs -
// CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CopyImage.html).
// This field is validated by Packer, when using an alias, you will have to
// prefix `kms_key_id` with `alias/`.
AMIKmsKeyId string `mapstructure:"kms_key_id" required:"false"`
// regions to copy the ami to, along with the custom kms key id (alias or
// arn) to use for encryption for that region. Keys must match the regions
// provided in `ami_regions`. If you just want to encrypt using a default
// ID, you can stick with `kms_key_id` and `ami_regions`. If you want a
// region to be encrypted with that region's default key ID, you can use an
// empty string `""` instead of a key id in this map. (e.g. `"us-east-1":
// ""`) However, you cannot use default key IDs if you are using this in
// conjunction with `snapshot_users` -- in that situation you must use
// custom keys. For valid formats see *KmsKeyId* in the [AWS API docs -
// CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CopyImage.html).
//
// This option supercedes the `kms_key_id` option -- if you set both, and
// they are different, Packer will respect the value in
// `region_kms_key_ids` for your build region and silently disregard the
// value provided in `kms_key_id`.
AMIRegionKMSKeyIDs map[string]string `mapstructure:"region_kms_key_ids" required:"false"`
// If true, Packer will not check whether an AMI with the `ami_name` exists
// in the region it is building in. It will use an intermediary AMI name,
// which it will not convert to an AMI in the build region. It will copy
// the intermediary AMI into any regions provided in `ami_regions`, then
// delete the intermediary AMI. Default `false`.
AMISkipBuildRegion bool `mapstructure:"skip_save_build_region"`
// Key/value pair tags to apply to snapshot. They will override AMI tags if
// already applied to snapshot. This is a [template
// engine](/docs/templates/engine), see [Build template
// data](#build-template-data) for more information.
SnapshotTags map[string]string `mapstructure:"snapshot_tags" required:"false"`
// Same as [`snapshot_tags`](#snapshot_tags) but defined as a singular
// repeatable block containing a `key` and a `value` field. In HCL2 mode the
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
SnapshotTag hcl2template.KeyValues `mapstructure:"snapshot_tag" required:"false"`
// A list of account IDs that have
// access to create volumes from the snapshot(s). By default no additional
// users other than the user creating the AMI has permissions to create
// volumes from the backing snapshot(s).
SnapshotUsers []string `mapstructure:"snapshot_users" required:"false"`
// A list of groups that have access to
// create volumes from the snapshot(s). By default no groups have permission
// to create volumes from the snapshot(s). all will make the snapshot
// publicly accessible.
SnapshotGroups []string `mapstructure:"snapshot_groups" required:"false"`
}
func stringInSlice(s []string, searchstr string) bool {
for _, item := range s {
if item == searchstr {
return true
}
}
return false
}
func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context) []error {
var errs []error
errs = append(errs, c.SnapshotTag.CopyOn(&c.SnapshotTags)...)
errs = append(errs, c.AMITag.CopyOn(&c.AMITags)...)
if c.AMIName == "" {
errs = append(errs, fmt.Errorf("ami_name must be specified"))
}
// Make sure that if we have region_kms_key_ids defined,
// the regions in region_kms_key_ids are also in ami_regions
if len(c.AMIRegionKMSKeyIDs) > 0 {
for kmsKeyRegion := range c.AMIRegionKMSKeyIDs {
if !stringInSlice(c.AMIRegions, kmsKeyRegion) {
errs = append(errs, fmt.Errorf("Region %s is in region_kms_key_ids but not in ami_regions", kmsKeyRegion))
}
}
}
errs = append(errs, c.prepareRegions(accessConfig)...)
// Prevent sharing of default KMS key encrypted volumes with other aws users
if len(c.AMIUsers) > 0 {
if len(c.AMIKmsKeyId) == 0 && c.AMIEncryptBootVolume.True() {
errs = append(errs, fmt.Errorf("Cannot share AMI encrypted with default KMS key"))
}
if len(c.AMIRegionKMSKeyIDs) > 0 {
for _, kmsKey := range c.AMIRegionKMSKeyIDs {
if len(kmsKey) == 0 {
errs = append(errs, fmt.Errorf("Cannot share AMI encrypted with default KMS key for other regions"))
}
}
}
}
kmsKeys := make([]string, 0)
if len(c.AMIKmsKeyId) > 0 {
kmsKeys = append(kmsKeys, c.AMIKmsKeyId)
}
if len(c.AMIRegionKMSKeyIDs) > 0 {
for _, kmsKey := range c.AMIRegionKMSKeyIDs {
if len(kmsKey) > 0 {
kmsKeys = append(kmsKeys, kmsKey)
}
}
}
if len(kmsKeys) > 0 && !c.AMIEncryptBootVolume.True() {
errs = append(errs, fmt.Errorf("If you have set either "+
"region_kms_key_ids or kms_key_id, encrypt_boot must also be true."))
}
for _, kmsKey := range kmsKeys {
if !validateKmsKey(kmsKey) {
errs = append(errs, fmt.Errorf("%q is not a valid KMS Key Id.", kmsKey))
}
}
if len(c.SnapshotUsers) > 0 {
if len(c.AMIKmsKeyId) == 0 && len(c.AMIRegionKMSKeyIDs) == 0 && c.AMIEncryptBootVolume.True() {
errs = append(errs, fmt.Errorf("Cannot share snapshot encrypted "+
"with default KMS key, see https://www.packer.io/docs/builders/amazon-ebs#region_kms_key_ids for more information"))
}
if len(c.AMIRegionKMSKeyIDs) > 0 {
for _, kmsKey := range c.AMIRegionKMSKeyIDs {
if len(kmsKey) == 0 {
errs = append(errs, fmt.Errorf("Cannot share snapshot encrypted with default KMS key"))
}
}
}
}
if len(c.AMIName) < 3 || len(c.AMIName) > 128 {
errs = append(errs, fmt.Errorf("ami_name must be between 3 and 128 characters long"))
}
if c.AMIName != templateCleanAMIName(c.AMIName) {
errs = append(errs, fmt.Errorf("AMIName should only contain "+
"alphanumeric characters, parentheses (()), square brackets ([]), spaces "+
"( ), periods (.), slashes (/), dashes (-), single quotes ('), at-signs "+
"(@), or underscores(_). You can use the `clean_resource_name` template "+
"filter to automatically clean your ami name."))
}
if len(errs) > 0 {
return errs
}
return nil
}
func (c *AMIConfig) prepareRegions(accessConfig *AccessConfig) (errs []error) {
if len(c.AMIRegions) > 0 {
regionSet := make(map[string]struct{})
regions := make([]string, 0, len(c.AMIRegions))
for _, region := range c.AMIRegions {
// If we already saw the region, then don't look again
if _, ok := regionSet[region]; ok {
continue
}
// Mark that we saw the region
regionSet[region] = struct{}{}
// Make sure that if we have region_kms_key_ids defined,
// the regions in ami_regions are also in region_kms_key_ids
if len(c.AMIRegionKMSKeyIDs) > 0 {
if _, ok := c.AMIRegionKMSKeyIDs[region]; !ok {
errs = append(errs, fmt.Errorf("Region %s is in ami_regions but not in region_kms_key_ids", region))
}
}
if (accessConfig != nil) && (region == accessConfig.RawRegion) {
// make sure we don't try to copy to the region we originally
// create the AMI in.
log.Printf("Cannot copy AMI to AWS session region '%s', deleting it from `ami_regions`.", region)
continue
}
regions = append(regions, region)
}
c.AMIRegions = regions
}
return errs
}
// See https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CopyImage.html
func validateKmsKey(kmsKey string) (valid bool) {
kmsKeyIdPattern := `[a-f0-9-]+$`
aliasPattern := `alias/[a-zA-Z0-9:/_-]+$`
kmsArnStartPattern := `^arn:aws(-us-gov)?:kms:([a-z]{2}-(gov-)?[a-z]+-\d{1})?:(\d{12}):`
if regexp.MustCompile(fmt.Sprintf("^%s", kmsKeyIdPattern)).MatchString(kmsKey) {
return true
}
if regexp.MustCompile(fmt.Sprintf("^%s", aliasPattern)).MatchString(kmsKey) {
return true
}
if regexp.MustCompile(fmt.Sprintf("%skey/%s", kmsArnStartPattern, kmsKeyIdPattern)).MatchString(kmsKey) {
return true
}
if regexp.MustCompile(fmt.Sprintf("%s%s", kmsArnStartPattern, aliasPattern)).MatchString(kmsKey) {
return true
}
return false
}

View File

@ -1,249 +0,0 @@
package common
import (
"fmt"
"reflect"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/hashicorp/packer/helper/config"
)
func testAMIConfig() *AMIConfig {
return &AMIConfig{
AMIName: "foo",
}
}
func getFakeAccessConfig(region string) *AccessConfig {
c := testAccessConfig()
c.RawRegion = region
return c
}
func TestAMIConfigPrepare_name(t *testing.T) {
c := testAMIConfig()
accessConf := testAccessConfig()
if err := c.Prepare(accessConf, nil); err != nil {
t.Fatalf("shouldn't have err: %s", err)
}
c.AMIName = ""
if err := c.Prepare(accessConf, nil); err == nil {
t.Fatal("should have error")
}
}
type mockEC2Client struct {
ec2iface.EC2API
}
func (m *mockEC2Client) DescribeRegions(*ec2.DescribeRegionsInput) (*ec2.DescribeRegionsOutput, error) {
return &ec2.DescribeRegionsOutput{
Regions: []*ec2.Region{
{RegionName: aws.String("us-east-1")},
{RegionName: aws.String("us-east-2")},
{RegionName: aws.String("us-west-1")},
},
}, nil
}
func TestAMIConfigPrepare_regions(t *testing.T) {
c := testAMIConfig()
c.AMIRegions = nil
var errs []error
var err error
accessConf := testAccessConfig()
mockConn := &mockEC2Client{}
if errs = c.prepareRegions(accessConf); len(errs) > 0 {
t.Fatalf("shouldn't have err: %#v", errs)
}
c.AMIRegions, err = listEC2Regions(mockConn)
if err != nil {
t.Fatalf("shouldn't have err: %s", err.Error())
}
if errs = c.prepareRegions(accessConf); len(errs) > 0 {
t.Fatalf("shouldn't have err: %#v", errs)
}
c.AMIRegions = []string{"us-east-1", "us-west-1", "us-east-1"}
if errs = c.prepareRegions(accessConf); len(errs) > 0 {
t.Fatalf("bad: %s", errs[0])
}
expected := []string{"us-east-1", "us-west-1"}
if !reflect.DeepEqual(c.AMIRegions, expected) {
t.Fatalf("bad: %#v", c.AMIRegions)
}
c.AMIRegions = []string{"custom"}
if errs = c.prepareRegions(accessConf); len(errs) > 0 {
t.Fatal("shouldn't have error")
}
c.AMIRegions = []string{"us-east-1", "us-east-2", "us-west-1"}
c.AMIRegionKMSKeyIDs = map[string]string{
"us-east-1": "123-456-7890",
"us-west-1": "789-012-3456",
"us-east-2": "456-789-0123",
}
if errs = c.prepareRegions(accessConf); len(errs) > 0 {
t.Fatal(fmt.Sprintf("shouldn't have error: %s", errs[0]))
}
c.AMIRegions = []string{"us-east-1", "us-east-2", "us-west-1"}
c.AMIRegionKMSKeyIDs = map[string]string{
"us-east-1": "123-456-7890",
"us-west-1": "789-012-3456",
"us-east-2": "",
}
if errs = c.prepareRegions(accessConf); len(errs) > 0 {
t.Fatal("should have passed; we are able to use default KMS key if not sharing")
}
c.SnapshotUsers = []string{"user-foo", "user-bar"}
c.AMIRegions = []string{"us-east-1", "us-east-2", "us-west-1"}
c.AMIRegionKMSKeyIDs = map[string]string{
"us-east-1": "123-456-7890",
"us-west-1": "789-012-3456",
"us-east-2": "",
}
if errs = c.prepareRegions(accessConf); len(errs) > 0 {
t.Fatal("should have an error b/c can't use default KMS key if sharing")
}
c.AMIRegions = []string{"us-east-1", "us-west-1"}
c.AMIRegionKMSKeyIDs = map[string]string{
"us-east-1": "123-456-7890",
"us-west-1": "789-012-3456",
"us-east-2": "456-789-0123",
}
if errs = c.prepareRegions(accessConf); len(errs) > 0 {
t.Fatal("should have error b/c theres a region in the key map that isn't in ami_regions")
}
c.AMIRegions = []string{"us-east-1", "us-west-1", "us-east-2"}
c.AMIRegionKMSKeyIDs = map[string]string{
"us-east-1": "123-456-7890",
"us-west-1": "789-012-3456",
}
if err := c.Prepare(accessConf, nil); err == nil {
t.Fatal("should have error b/c theres a region in in ami_regions that isn't in the key map")
}
c.SnapshotUsers = []string{"foo", "bar"}
c.AMIKmsKeyId = "123-abc-456"
c.AMIEncryptBootVolume = config.TriTrue
c.AMIRegions = []string{"us-east-1", "us-west-1"}
c.AMIRegionKMSKeyIDs = map[string]string{
"us-east-1": "123-456-7890",
"us-west-1": "",
}
if errs = c.prepareRegions(accessConf); len(errs) > 0 {
t.Fatal("should have error b/c theres a region in in ami_regions that isn't in the key map")
}
// allow rawregion to exist in ami_regions list.
accessConf = getFakeAccessConfig("us-east-1")
c.AMIRegions = []string{"us-east-1", "us-west-1", "us-east-2"}
c.AMIRegionKMSKeyIDs = nil
if errs = c.prepareRegions(accessConf); len(errs) > 0 {
t.Fatal("should allow user to have the raw region in ami_regions")
}
}
func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) {
c := testAMIConfig()
c.AMIUsers = []string{"testAccountID"}
c.AMIEncryptBootVolume = config.TriTrue
accessConf := testAccessConfig()
c.AMIKmsKeyId = ""
if err := c.Prepare(accessConf, nil); err == nil {
t.Fatal("shouldn't be able to share ami with encrypted boot volume")
}
c.AMIKmsKeyId = "89c3fb9a-de87-4f2a-aedc-fddc5138193c"
if err := c.Prepare(accessConf, nil); err != nil {
t.Fatal("should be able to share ami with encrypted boot volume")
}
}
func TestAMIConfigPrepare_ValidateKmsKey(t *testing.T) {
c := testAMIConfig()
c.AMIEncryptBootVolume = config.TriTrue
accessConf := testAccessConfig()
validCases := []string{
"abcd1234-e567-890f-a12b-a123b4cd56ef",
"alias/foo/bar",
"arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef",
"arn:aws:kms:us-east-1:012345678910:alias/foo/bar",
"arn:aws-us-gov:kms:us-gov-east-1:123456789012:key/12345678-1234-abcd-0000-123456789012",
}
for _, validCase := range validCases {
c.AMIKmsKeyId = validCase
if err := c.Prepare(accessConf, nil); err != nil {
t.Fatalf("%s should not have failed KMS key validation", validCase)
}
}
invalidCases := []string{
"ABCD1234-e567-890f-a12b-a123b4cd56ef",
"ghij1234-e567-890f-a12b-a123b4cd56ef",
"ghij1234+e567_890f-a12b-a123b4cd56ef",
"foo/bar",
"arn:aws:kms:us-east-1:012345678910:foo/bar",
"arn:foo:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef",
}
for _, invalidCase := range invalidCases {
c.AMIKmsKeyId = invalidCase
if err := c.Prepare(accessConf, nil); err == nil {
t.Fatalf("%s should have failed KMS key validation", invalidCase)
}
}
}
func TestAMINameValidation(t *testing.T) {
c := testAMIConfig()
accessConf := testAccessConfig()
c.AMIName = "aa"
if err := c.Prepare(accessConf, nil); err == nil {
t.Fatal("shouldn't be able to have an ami name with less than 3 characters")
}
var longAmiName string
for i := 0; i < 129; i++ {
longAmiName += "a"
}
c.AMIName = longAmiName
if err := c.Prepare(accessConf, nil); err == nil {
t.Fatal("shouldn't be able to have an ami name with great than 128 characters")
}
c.AMIName = "+aaa"
if err := c.Prepare(accessConf, nil); err == nil {
t.Fatal("shouldn't be able to have an ami name with invalid characters")
}
c.AMIName = "fooBAR1()[] ./-'@_"
if err := c.Prepare(accessConf, nil); err != nil {
t.Fatal("should be able to use all of the allowed AMI characters")
}
c.AMIName = `xyz-base-2017-04-05-1934`
if err := c.Prepare(accessConf, nil); err != nil {
t.Fatalf("expected `xyz-base-2017-04-05-1934` to pass validation.")
}
}

View File

@ -1,121 +0,0 @@
package common
import (
"fmt"
"log"
"sort"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/packer"
)
// Artifact is an artifact implementation that contains built AMIs.
type Artifact struct {
// A map of regions to AMI IDs.
Amis map[string]string
// BuilderId is the unique ID for the builder that created this AMI
BuilderIdValue string
// StateData should store data such as GeneratedData
// to be shared with post-processors
StateData map[string]interface{}
// EC2 connection for performing API stuff.
Session *session.Session
}
func (a *Artifact) BuilderId() string {
return a.BuilderIdValue
}
func (*Artifact) Files() []string {
// We have no files
return nil
}
func (a *Artifact) Id() string {
parts := make([]string, 0, len(a.Amis))
for region, amiId := range a.Amis {
parts = append(parts, fmt.Sprintf("%s:%s", region, amiId))
}
sort.Strings(parts)
return strings.Join(parts, ",")
}
func (a *Artifact) String() string {
amiStrings := make([]string, 0, len(a.Amis))
for region, id := range a.Amis {
single := fmt.Sprintf("%s: %s", region, id)
amiStrings = append(amiStrings, single)
}
sort.Strings(amiStrings)
return fmt.Sprintf("AMIs were created:\n%s\n", strings.Join(amiStrings, "\n"))
}
func (a *Artifact) State(name string) interface{} {
if _, ok := a.StateData[name]; ok {
return a.StateData[name]
}
switch name {
case "atlas.artifact.metadata":
return a.stateAtlasMetadata()
default:
return nil
}
}
func (a *Artifact) Destroy() error {
errors := make([]error, 0)
for region, imageId := range a.Amis {
log.Printf("Deregistering image ID (%s) from region (%s)", imageId, region)
regionConn := ec2.New(a.Session, &aws.Config{
Region: aws.String(region),
})
// Get image metadata
imageResp, err := regionConn.DescribeImages(&ec2.DescribeImagesInput{
ImageIds: []*string{&imageId},
})
if err != nil {
errors = append(errors, err)
}
if len(imageResp.Images) == 0 {
err := fmt.Errorf("Error retrieving details for AMI (%s), no images found", imageId)
errors = append(errors, err)
}
err = DestroyAMIs([]*string{&imageId}, regionConn)
if err != nil {
errors = append(errors, err)
}
}
if len(errors) > 0 {
if len(errors) == 1 {
return errors[0]
} else {
return &packer.MultiError{Errors: errors}
}
}
return nil
}
func (a *Artifact) stateAtlasMetadata() interface{} {
metadata := make(map[string]string)
for region, imageId := range a.Amis {
k := fmt.Sprintf("region.%s", region)
metadata[k] = imageId
}
return metadata
}

View File

@ -1,90 +0,0 @@
package common
import (
"reflect"
"testing"
"github.com/hashicorp/packer/packer"
)
func TestArtifact_Impl(t *testing.T) {
var _ packer.Artifact = new(Artifact)
}
func TestArtifactId(t *testing.T) {
expected := `east:foo,west:bar`
amis := make(map[string]string)
amis["east"] = "foo"
amis["west"] = "bar"
a := &Artifact{
Amis: amis,
}
result := a.Id()
if result != expected {
t.Fatalf("bad: %s", result)
}
}
func TestArtifactState_atlasMetadata(t *testing.T) {
a := &Artifact{
Amis: map[string]string{
"east": "foo",
"west": "bar",
},
}
actual := a.State("atlas.artifact.metadata")
expected := map[string]string{
"region.east": "foo",
"region.west": "bar",
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}
func TestArtifactString(t *testing.T) {
expected := `AMIs were created:
east: foo
west: bar
`
amis := make(map[string]string)
amis["east"] = "foo"
amis["west"] = "bar"
a := &Artifact{Amis: amis}
result := a.String()
if result != expected {
t.Fatalf("bad: %s", result)
}
}
func TestArtifactState(t *testing.T) {
expectedData := "this is the data"
artifact := &Artifact{
StateData: map[string]interface{}{"state_data": expectedData},
}
// Valid state
result := artifact.State("state_data")
if result != expectedData {
t.Fatalf("Bad: State data was %s instead of %s", result, expectedData)
}
// Invalid state
result = artifact.State("invalid_key")
if result != nil {
t.Fatalf("Bad: State should be nil for invalid state data name")
}
// Nil StateData should not fail and should return nil
artifact = &Artifact{}
result = artifact.State("key")
if result != nil {
t.Fatalf("Bad: State should be nil for nil StateData")
}
}

View File

@ -1,180 +0,0 @@
//go:generate struct-markdown
//go:generate mapstructure-to-hcl2 -type BlockDevice
package common
import (
"fmt"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
// These will be attached when launching your instance. Your
// options here may vary depending on the type of VM you use.
//
// Example use case:
//
// The following mapping will tell Packer to encrypt the root volume of the
// build instance at launch using a specific non-default kms key:
//
// JSON example:
//
// ```json
// launch_block_device_mappings: [
// {
// "device_name": "/dev/sda1",
// "encrypted": true,
// "kms_key_id": "1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d"
// }
// ]
// ```
//
// HCL2 example:
//
// ```hcl
// launch_block_device_mappings {
// device_name = "/dev/sda1"
// encrypted = true
// kms_key_id = "1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d"
// }
// ```
//
// Please note that the kms_key_id option in this example exists for
// launch_block_device_mappings but not ami_block_device_mappings.
//
// Documentation for Block Devices Mappings can be found here:
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html
//
type BlockDevice struct {
// Indicates whether the EBS volume is deleted on instance termination.
// Default false. NOTE: If this value is not explicitly set to true and
// volumes are not cleaned up by an alternative method, additional volumes
// will accumulate after every build.
DeleteOnTermination bool `mapstructure:"delete_on_termination" required:"false"`
// The device name exposed to the instance (for example, /dev/sdh or xvdh).
// Required for every device in the block device mapping.
DeviceName string `mapstructure:"device_name" required:"false"`
// Indicates whether or not to encrypt the volume. By default, Packer will
// keep the encryption setting to what it was in the source image. Setting
// false will result in an unencrypted device, and true will result in an
// encrypted one.
Encrypted config.Trilean `mapstructure:"encrypted" required:"false"`
// The number of I/O operations per second (IOPS) that the volume supports.
// See the documentation on
// [IOPs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html)
// for more information
IOPS int64 `mapstructure:"iops" required:"false"`
// Suppresses the specified device included in the block device mapping of
// the AMI.
NoDevice bool `mapstructure:"no_device" required:"false"`
// The ID of the snapshot.
SnapshotId string `mapstructure:"snapshot_id" required:"false"`
// The virtual device name. See the documentation on Block Device Mapping
// for more information.
VirtualName string `mapstructure:"virtual_name" required:"false"`
// The volume type. gp2 for General Purpose (SSD) volumes, io1 for
// Provisioned IOPS (SSD) volumes, st1 for Throughput Optimized HDD, sc1
// for Cold HDD, and standard for Magnetic volumes.
VolumeType string `mapstructure:"volume_type" required:"false"`
// The size of the volume, in GiB. Required if not specifying a
// snapshot_id.
VolumeSize int64 `mapstructure:"volume_size" required:"false"`
// ID, alias or ARN of the KMS key to use for boot volume encryption.
// This option exists for launch_block_device_mappings but not
// ami_block_device_mappings. The kms key id defined here only applies to
// the original build region; if the AMI gets copied to other regions, the
// volume in those regions will be encrypted by the default EBS KMS key.
// For valid formats see KmsKeyId in the [AWS API docs -
// CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CopyImage.html)
// This field is validated by Packer. When using an alias, you will have to
// prefix kms_key_id with alias/.
KmsKeyId string `mapstructure:"kms_key_id" required:"false"`
}
type BlockDevices []BlockDevice
func (bds BlockDevices) BuildEC2BlockDeviceMappings() []*ec2.BlockDeviceMapping {
var blockDevices []*ec2.BlockDeviceMapping
for _, blockDevice := range bds {
blockDevices = append(blockDevices, blockDevice.BuildEC2BlockDeviceMapping())
}
return blockDevices
}
func (blockDevice BlockDevice) BuildEC2BlockDeviceMapping() *ec2.BlockDeviceMapping {
mapping := &ec2.BlockDeviceMapping{
DeviceName: aws.String(blockDevice.DeviceName),
}
if blockDevice.NoDevice {
mapping.NoDevice = aws.String("")
return mapping
} else if blockDevice.VirtualName != "" {
if strings.HasPrefix(blockDevice.VirtualName, "ephemeral") {
mapping.VirtualName = aws.String(blockDevice.VirtualName)
}
return mapping
}
ebsBlockDevice := &ec2.EbsBlockDevice{
DeleteOnTermination: aws.Bool(blockDevice.DeleteOnTermination),
}
if blockDevice.VolumeType != "" {
ebsBlockDevice.VolumeType = aws.String(blockDevice.VolumeType)
}
if blockDevice.VolumeSize > 0 {
ebsBlockDevice.VolumeSize = aws.Int64(blockDevice.VolumeSize)
}
// IOPS is only valid for io1 type
if blockDevice.VolumeType == "io1" {
ebsBlockDevice.Iops = aws.Int64(blockDevice.IOPS)
}
// You cannot specify Encrypted if you specify a Snapshot ID
if blockDevice.SnapshotId != "" {
ebsBlockDevice.SnapshotId = aws.String(blockDevice.SnapshotId)
}
ebsBlockDevice.Encrypted = blockDevice.Encrypted.ToBoolPointer()
if blockDevice.KmsKeyId != "" {
ebsBlockDevice.KmsKeyId = aws.String(blockDevice.KmsKeyId)
}
mapping.Ebs = ebsBlockDevice
return mapping
}
func (b *BlockDevice) Prepare(ctx *interpolate.Context) error {
if b.DeviceName == "" {
return fmt.Errorf("The `device_name` must be specified " +
"for every device in the block device mapping.")
}
// Warn that encrypted must be true or nil when setting kms_key_id
if b.KmsKeyId != "" && b.Encrypted.False() {
return fmt.Errorf("The device %v, must also have `encrypted: "+
"true` when setting a kms_key_id.", b.DeviceName)
}
_, err := interpolate.RenderInterface(&b, ctx)
return err
}
func (bds BlockDevices) Prepare(ctx *interpolate.Context) (errs []error) {
for _, block := range bds {
if err := block.Prepare(ctx); err != nil {
errs = append(errs, err)
}
}
return errs
}

View File

@ -1,48 +0,0 @@
// Code generated by "mapstructure-to-hcl2 -type BlockDevice"; DO NOT EDIT.
package common
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/zclconf/go-cty/cty"
)
// FlatBlockDevice is an auto-generated flat version of BlockDevice.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatBlockDevice struct {
DeleteOnTermination *bool `mapstructure:"delete_on_termination" required:"false" cty:"delete_on_termination" hcl:"delete_on_termination"`
DeviceName *string `mapstructure:"device_name" required:"false" cty:"device_name" hcl:"device_name"`
Encrypted *bool `mapstructure:"encrypted" required:"false" cty:"encrypted" hcl:"encrypted"`
IOPS *int64 `mapstructure:"iops" required:"false" cty:"iops" hcl:"iops"`
NoDevice *bool `mapstructure:"no_device" required:"false" cty:"no_device" hcl:"no_device"`
SnapshotId *string `mapstructure:"snapshot_id" required:"false" cty:"snapshot_id" hcl:"snapshot_id"`
VirtualName *string `mapstructure:"virtual_name" required:"false" cty:"virtual_name" hcl:"virtual_name"`
VolumeType *string `mapstructure:"volume_type" required:"false" cty:"volume_type" hcl:"volume_type"`
VolumeSize *int64 `mapstructure:"volume_size" required:"false" cty:"volume_size" hcl:"volume_size"`
KmsKeyId *string `mapstructure:"kms_key_id" required:"false" cty:"kms_key_id" hcl:"kms_key_id"`
}
// FlatMapstructure returns a new FlatBlockDevice.
// FlatBlockDevice is an auto-generated flat version of BlockDevice.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*BlockDevice) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatBlockDevice)
}
// HCL2Spec returns the hcl spec of a BlockDevice.
// This spec is used by HCL to read the fields of BlockDevice.
// The decoded values from this spec will then be applied to a FlatBlockDevice.
func (*FlatBlockDevice) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"delete_on_termination": &hcldec.AttrSpec{Name: "delete_on_termination", Type: cty.Bool, Required: false},
"device_name": &hcldec.AttrSpec{Name: "device_name", Type: cty.String, Required: false},
"encrypted": &hcldec.AttrSpec{Name: "encrypted", Type: cty.Bool, Required: false},
"iops": &hcldec.AttrSpec{Name: "iops", Type: cty.Number, Required: false},
"no_device": &hcldec.AttrSpec{Name: "no_device", Type: cty.Bool, Required: false},
"snapshot_id": &hcldec.AttrSpec{Name: "snapshot_id", Type: cty.String, Required: false},
"virtual_name": &hcldec.AttrSpec{Name: "virtual_name", Type: cty.String, Required: false},
"volume_type": &hcldec.AttrSpec{Name: "volume_type", Type: cty.String, Required: false},
"volume_size": &hcldec.AttrSpec{Name: "volume_size", Type: cty.Number, Required: false},
"kms_key_id": &hcldec.AttrSpec{Name: "kms_key_id", Type: cty.String, Required: false},
}
return s
}

View File

@ -1,165 +0,0 @@
package common
import (
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/packer/helper/config"
)
func TestBlockDevice(t *testing.T) {
cases := []struct {
Config *BlockDevice
Result *ec2.BlockDeviceMapping
}{
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
SnapshotId: "snap-1234",
VolumeType: "standard",
VolumeSize: 8,
DeleteOnTermination: true,
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
SnapshotId: aws.String("snap-1234"),
VolumeType: aws.String("standard"),
VolumeSize: aws.Int64(8),
DeleteOnTermination: aws.Bool(true),
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VolumeSize: 8,
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
VolumeSize: aws.Int64(8),
DeleteOnTermination: aws.Bool(false),
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "io1",
VolumeSize: 8,
DeleteOnTermination: true,
IOPS: 1000,
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
VolumeType: aws.String("io1"),
VolumeSize: aws.Int64(8),
DeleteOnTermination: aws.Bool(true),
Iops: aws.Int64(1000),
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "gp2",
VolumeSize: 8,
DeleteOnTermination: true,
Encrypted: config.TriTrue,
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
VolumeType: aws.String("gp2"),
VolumeSize: aws.Int64(8),
DeleteOnTermination: aws.Bool(true),
Encrypted: aws.Bool(true),
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "gp2",
VolumeSize: 8,
DeleteOnTermination: true,
Encrypted: config.TriTrue,
KmsKeyId: "2Fa48a521f-3aff-4b34-a159-376ac5d37812",
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
VolumeType: aws.String("gp2"),
VolumeSize: aws.Int64(8),
DeleteOnTermination: aws.Bool(true),
Encrypted: aws.Bool(true),
KmsKeyId: aws.String("2Fa48a521f-3aff-4b34-a159-376ac5d37812"),
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "standard",
DeleteOnTermination: true,
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
VolumeType: aws.String("standard"),
DeleteOnTermination: aws.Bool(true),
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VirtualName: "ephemeral0",
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
VirtualName: aws.String("ephemeral0"),
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
NoDevice: true,
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
NoDevice: aws.String(""),
},
},
}
for _, tc := range cases {
var amiBlockDevices BlockDevices = []BlockDevice{*tc.Config}
var launchBlockDevices BlockDevices = []BlockDevice{*tc.Config}
expected := []*ec2.BlockDeviceMapping{tc.Result}
amiResults := amiBlockDevices.BuildEC2BlockDeviceMappings()
if diff := cmp.Diff(expected, amiResults); diff != "" {
t.Fatalf("Bad block device: %s", diff)
}
launchResults := launchBlockDevices.BuildEC2BlockDeviceMappings()
if diff := cmp.Diff(expected, launchResults); diff != "" {
t.Fatalf("Bad block device: %s", diff)
}
}
}

View File

@ -1,19 +0,0 @@
package common
import (
"github.com/aws/aws-sdk-go/service/ec2"
)
// Build a slice of EC2 (AMI/Subnet/VPC) filter options from the filters provided.
func buildEc2Filters(input map[string]string) []*ec2.Filter {
var filters []*ec2.Filter
for k, v := range input {
a := k
b := v
filters = append(filters, &ec2.Filter{
Name: &a,
Values: []*string{&b},
})
}
return filters
}

View File

@ -1,31 +0,0 @@
package common
import (
"testing"
)
func TestStepSourceAmiInfo_BuildFilter(t *testing.T) {
filter_key := "name"
filter_value := "foo"
filter_key2 := "name2"
filter_value2 := "foo2"
inputFilter := map[string]string{filter_key: filter_value, filter_key2: filter_value2}
outputFilter := buildEc2Filters(inputFilter)
// deconstruct filter back into things we can test
foundMap := map[string]bool{filter_key: false, filter_key2: false}
for _, filter := range outputFilter {
for key, value := range inputFilter {
if *filter.Name == key && *filter.Values[0] == value {
foundMap[key] = true
}
}
}
for k, v := range foundMap {
if !v {
t.Fatalf("Fail: should have found value for key: %s", k)
}
}
}

View File

@ -1,58 +0,0 @@
package common
import (
"fmt"
"log"
"regexp"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/sts"
)
var encodedFailureMessagePattern = regexp.MustCompile(`(?i)(.*) Encoded authorization failure message: ([\w-]+) ?( .*)?`)
type stsDecoder interface {
DecodeAuthorizationMessage(input *sts.DecodeAuthorizationMessageInput) (*sts.DecodeAuthorizationMessageOutput, error)
}
// decodeError replaces encoded authorization messages with the
// decoded results
func decodeAWSError(decoder stsDecoder, err error) error {
groups := encodedFailureMessagePattern.FindStringSubmatch(err.Error())
if len(groups) > 1 {
result, decodeErr := decoder.DecodeAuthorizationMessage(&sts.DecodeAuthorizationMessageInput{
EncodedMessage: aws.String(groups[2]),
})
if decodeErr == nil {
msg := aws.StringValue(result.DecodedMessage)
return fmt.Errorf("%s Authorization failure message: '%s'%s", groups[1], msg, groups[3])
}
log.Printf("[WARN] Attempted to decode authorization message, but received: %v", decodeErr)
}
return err
}
// DecodeAuthZMessages enables automatic decoding of any
// encoded authorization messages
func DecodeAuthZMessages(sess *session.Session) {
azd := &authZMessageDecoder{
Decoder: sts.New(sess),
}
sess.Handlers.UnmarshalError.AfterEachFn = azd.afterEachFn
}
type authZMessageDecoder struct {
Decoder stsDecoder
}
func (a *authZMessageDecoder) afterEachFn(item request.HandlerListRunItem) bool {
if err, ok := item.Request.Error.(awserr.Error); ok && err.Code() == "UnauthorizedOperation" {
item.Request.Error = decodeAWSError(a.Decoder, err)
}
return true
}

View File

@ -1,70 +0,0 @@
package common
import (
"fmt"
"strings"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/aws/aws-sdk-go/aws/awserr"
)
type mockSTS struct {
}
func (m *mockSTS) DecodeAuthorizationMessage(input *sts.DecodeAuthorizationMessageInput) (*sts.DecodeAuthorizationMessageOutput, error) {
return &sts.DecodeAuthorizationMessageOutput{
DecodedMessage: aws.String(`{
"allowed": false,
"explicitDeny": true,
"matchedStatements": {}
}`),
}, nil
}
func TestErrorsParsing_RequestFailure(t *testing.T) {
ae := awserr.New("UnauthorizedOperation",
`You are not authorized to perform this operation. Encoded authorization failure message: D9Q7oicjOMr9l2CC-NPP1FiZXK9Ijia1k-3l0siBFCcrK3oSuMFMkBIO5TNj0HdXE-WfwnAcdycFOohfKroNO6toPJEns8RFVfy_M_IjNGmrEFJ6E62pnmBW0OLrMsXxR9FQE4gB4gJzSM0AD6cV6S3FOfqYzWBRX-sQdOT4HryGkFNRoFBr9Xbp-tRwiadwkbdHdfnV9fbRkXmnwCdULml16NBSofC4ZPepLMKmIB5rKjwk-m179UUh2XA-J5no0si6XcRo5GbHQB5QfCIwSHL4vsro2wLZUd16-8OWKyr3tVlTbQe0ERZskqRqRQ5E28QuiBCVV6XstUyo-T4lBSr75Fgnyr3wCO-dS3b_5Ns3WzA2JD4E2AJOAStXIU8IH5YuKkAg7C-dJMuBMPpmKCBEXhNoHDwCyOo5PsV3xMlc0jSb0qYGpfst_TDDtejcZfn7NssUjxVq9qkdH-OXz2gPoQB-hX8ycmZCL5UZwKc3TCLUr7TGnudHjmnMrE9cUo-yTCWfyHPLprhiYhTCKW18EikJ0O1EKI3FJ_b4F19_jFBPARjSwQc7Ut6MNCVzrPdZGYSF6acj5gPaxdy9uSkVQwWXK7Pd5MFP7EBDE1_DgYbzodgwDO2PXeVFUbSLBHKWo_ebZS9ZX2nYPcGss_sYaly0ZVSIJXp7G58B5BoFVhvVH6jYnF9XiAOjMltuP_ycu1pQP1lki500RY3baLvfeYeAsB38XZHKEgWZzq7Fei-uh89q0cjJTmlVyrfRU3q6`,
fmt.Errorf("You can't do it!!"))
rf := awserr.NewRequestFailure(ae, 400, "abc-def-123-456")
result := decodeAWSError(&mockSTS{}, rf)
if result == nil {
t.Error("Expected resulting error")
}
if !strings.Contains(result.Error(), "Authorization failure message:") {
t.Error("Expected authorization failure message")
}
}
func TestErrorsParsing_NonAuthorizationFailure(t *testing.T) {
ae := awserr.New("BadRequest",
`You did something wrong. Try again`,
fmt.Errorf("Request was no good."))
rf := awserr.NewRequestFailure(ae, 400, "abc-def-123-456")
result := decodeAWSError(&mockSTS{}, rf)
if result == nil {
t.Error("Expected resulting error")
}
if result != rf {
t.Error("Expected original error to be returned unchanged")
}
}
func TestErrorsParsing_NonAWSError(t *testing.T) {
err := fmt.Errorf("Random error occurred")
result := decodeAWSError(&mockSTS{}, err)
if result == nil {
t.Error("Expected resulting error")
}
if result != err {
t.Error("Expected original error to be returned unchanged")
}
}

View File

@ -1,87 +0,0 @@
package common
import (
"context"
"fmt"
"log"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/common/retry"
)
// DestroyAMIs deregisters the AWS machine images in imageids from an active AWS account
func DestroyAMIs(imageids []*string, ec2conn *ec2.EC2) error {
resp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{
ImageIds: imageids,
})
if err != nil {
err := fmt.Errorf("Error describing AMI: %s", err)
return err
}
// Deregister image by name.
for _, i := range resp.Images {
ctx := context.TODO()
err = retry.Config{
Tries: 11,
ShouldRetry: func(err error) bool {
return IsAWSErr(err, "UnauthorizedOperation", "")
},
RetryDelay: (&retry.Backoff{InitialBackoff: 200 * time.Millisecond, MaxBackoff: 30 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
_, err := ec2conn.DeregisterImage(&ec2.DeregisterImageInput{
ImageId: i.ImageId,
})
return err
})
if err != nil {
err := fmt.Errorf("Error deregistering existing AMI: %s", err)
return err
}
log.Printf("Deregistered AMI id: %s", *i.ImageId)
// Delete snapshot(s) by image
for _, b := range i.BlockDeviceMappings {
if b.Ebs != nil && aws.StringValue(b.Ebs.SnapshotId) != "" {
err = retry.Config{
Tries: 11,
ShouldRetry: func(err error) bool {
return IsAWSErr(err, "UnauthorizedOperation", "")
},
RetryDelay: (&retry.Backoff{InitialBackoff: 200 * time.Millisecond, MaxBackoff: 30 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
_, err := ec2conn.DeleteSnapshot(&ec2.DeleteSnapshotInput{
SnapshotId: b.Ebs.SnapshotId,
})
return err
})
if err != nil {
err := fmt.Errorf("Error deleting existing snapshot: %s", err)
return err
}
log.Printf("Deleted snapshot: %s", *b.Ebs.SnapshotId)
}
}
}
return nil
}
// Returns true if the error matches all these conditions:
// * err is of type awserr.Error
// * Error.Code() matches code
// * Error.Message() contains message
func IsAWSErr(err error, code string, message string) bool {
if err, ok := err.(awserr.Error); ok {
return err.Code() == code && strings.Contains(err.Message(), message)
}
return false
}

Some files were not shown because too many files have changed in this diff Show More