Compare commits

..

166 Commits

Author SHA1 Message Date
Chris Bednarski 28c80a648c Updated changelog for 0.8.2 2015-07-17 14:02:22 -07:00
Chris Bednarski 9c72861438 Prep release for 0.8.2 2015-07-17 12:45:15 -07:00
Chris Bednarski ac75d5329e Merge pull request #2463 from mitchellh/b-2373
Make manifest_file work as either file.pp or a directory
2015-07-17 12:07:08 -07:00
Chris Bednarski 37c20e2bf0 Added links to puppet docs to clarify behavior of manifest with multiple files 2015-07-17 12:06:20 -07:00
Chris Bednarski dec1b65a20 Merge pull request #2468 from tylert/gh-2467-missing-some-qemu-builder-defaults
Fixes #2467 Add missing default values for 'disk_cache' and 'disk_discard' in qemu builder docs
2015-07-17 11:51:59 -07:00
Tyler Tidman bb6db46962 Cull duplicate word 'values' for disk_cache description 2015-07-17 12:20:57 -04:00
Tyler Tidman d8cde46e76 Add missing default values for 'disk_cache' and 'disk_discard' in qemu builder docs, sort qemu_binary before qemuargs so it matches ordering from 'packer fix' 2015-07-17 12:10:22 -04:00
Chris Bednarski f3f3d1fe73 Formatting 2015-07-16 19:34:36 -07:00
Chris Bednarski 2f5f6c159b Merge pull request #2462 from georgevicbell/master
Add PTY to Docker exec
2015-07-16 19:27:41 -07:00
Chris Bednarski 56745e14f5 manifest_file can now be a folder or file.pp and we will upload it correctly in either case 2015-07-16 19:15:16 -07:00
georgevicbell bf0c326cd5 Update step_connect_docker.go 2015-07-16 22:07:39 -04:00
georgevicbell b2811a8252 Update communicator.go 2015-07-16 21:51:13 -04:00
georgevicbell d00271aab3 Fix Capitilzation 2015-07-16 21:50:24 -04:00
georgevicbell 4da4150abe Update communicator.go 2015-07-16 21:37:08 -04:00
georgevicbell 3a681d0c0c Add Pty Bool 2015-07-16 21:22:11 -04:00
Chris Bednarski 518ad704b7 Added notes to warn against manifest_dir and note that manifest_file can be overloaded with a directory 2015-07-16 18:18:59 -07:00
georgevicbell fb39fa2cc6 Update step_connect_docker.go 2015-07-16 21:13:04 -04:00
georgevicbell e3ab74e09f Add Config struct for docker PTY 2015-07-16 21:06:03 -04:00
Chris Bednarski 39a8ba1365 Merge pull request #2459 from mitchellh/b-2360
Don't add ephemeral block devices to the EBS mapping
2015-07-16 13:24:10 -07:00
Tommy Ulfsparre 241903d0b0 no point in setting iops on a standard volumes 2015-07-15 17:18:03 -07:00
Chris Bednarski c615539929 Reformat long lines 2015-07-15 17:17:59 -07:00
Chris Bednarski 9365a43179 Reformat 2015-07-15 17:07:36 -07:00
Tommy Ulfsparre ae064207d5 Add test for ephemeral block device mapping 2015-07-15 17:05:32 -07:00
Anthony Spring 224bb78175 Make EBS block device mapping optional for ephemeral virtual names. 2015-07-15 17:04:45 -07:00
Chris Bednarski f27505626f Formatting tweak for ansible docs 2015-07-15 13:09:56 -07:00
Chris Bednarski 9b97726621 Merge branch 'documentation/ansible_inventory_groups' of https://github.com/Cbeck527/packer into b-ansible-inventory-docs 2015-07-15 13:09:04 -07:00
Chris Bednarski a49f263e90 Merge pull request #2418 from zakuro9715/fix-inconsistent-spelling
Fix inconsistent spelling
2015-07-15 13:03:39 -07:00
Chris Bednarski 618d2f3158 Merge pull request #2438 from lvillani/portcount-vbox-5.0
Use --portcount on VirtualBox 5.x
2015-07-15 13:01:22 -07:00
Chris Bednarski 4dccc54191 Merge pull request #2442 from mitchellh/b-2385
Don't override packer build version with min_packer_version from template
2015-07-15 12:55:09 -07:00
Chris Bednarski e7092ff5c5 Merge pull request #2456 from mitchellh/b-2416
Guard against uninitialized pointers in io.Copy in WinRM calls
2015-07-15 12:54:44 -07:00
Chris Bednarski 29e6194e49 Added a warning log so we can diagnose failure cases 2015-07-15 12:29:42 -07:00
Chris Bednarski 8e3559c3b1 Guard against uninitialized pointers in io.Copy to fix #2416 2015-07-15 12:26:19 -07:00
Chris Bednarski c614bb703d Bump version to 0.8.2.dev 2015-07-15 11:28:43 -07:00
Chris Bednarski 733376fa54 Merge pull request #2454 from monsterzz/docs-gobump
Fix go version in docs
2015-07-15 09:01:02 -07:00
Gleb M Borisov 985cd94952 Fix go version in docs 2015-07-15 13:54:41 +03:00
Chris Becker 6343d8f16a Update inventory_groups documentation for clarity 2015-07-14 21:53:38 -04:00
Clint Shryock a3bf467378 Update "getting started" link to Atlas
The current link 404's, but this fixes it.

Thanks to copyedt on Twitter: https://twitter.com/copyedt/status/620807196259958785
2015-07-14 08:34:56 -05:00
Chris Bednarski b3eacc5c2b Updated test to verify expected behavior 2015-07-13 19:32:28 -07:00
Chris Bednarski 78174dae4e Don't override packer's build version from a config file; fixes #2385 2015-07-13 19:03:36 -07:00
Chris Bednarski da20c36454 Removed unused variable breaking gorename 2015-07-13 18:04:50 -07:00
Chris Bednarski 28a13111b8 Add stub for validate test 2015-07-13 14:57:35 -07:00
Chris Bednarski d2339b7ccc Merge pull request #2408 from mitchellh/b-google-image-name
Fix interpolation in google compute image name
2015-07-13 14:18:55 -07:00
Seth Vargo 4128a49f7a Merge pull request #2437 from mitchellh/sethvargo/rack_protection
Use Rack::Protection
2015-07-13 16:08:26 -04:00
Lorenzo Villani 7e64e90670 Use --portcount on VirtualBox 5.x 2015-07-13 20:32:45 +02:00
Seth Vargo 034040d2a7 Weird bundler 2015-07-13 13:25:06 -04:00
Seth Vargo ff2e07771e Use Rack::Protection 2015-07-13 12:59:57 -04:00
Seth Vargo 1de5171857 Update middleman-hashicorp 2015-07-13 12:59:57 -04:00
Seth Vargo 683d6a73ec Merge pull request #2431 from walterdolce/fix/documentation-amendments
Fix other characters in docs displayed incorrectly
2015-07-12 10:27:11 -04:00
Walter Dolce 0c0ff5a25b Remove third 's' from word 2015-07-12 14:50:04 +01:00
Walter Dolce d99a1fab86 Fix other characters in docs displayed incorrectly 2015-07-12 00:11:59 +01:00
Seth Vargo 183beedb12 Merge pull request #2430 from walterdolce/patch-1
Fix character being displayed incorrectly in hashicorp ecosystem page
2015-07-11 17:27:03 -04:00
Walter Dolce 132b289b0e Fix character being displayed incorrectly 2015-07-11 19:45:34 +01:00
YuZakuro a6269671ec Fix inconsistent spelling
`(boolean)` is used in most cases, but `(bool)` is used in places.

I ran `find website/source/**/*.(markdown|md) | xargs sed -i 's/(bool)/(boolean)/g'`
2015-07-09 18:20:13 +09:00
Chris Bednarski 1c71eaaa91 Change panic to multierror 2015-07-07 17:12:21 -06:00
Chris Bednarski 775450f46a Merge branch 'fix_gce_image_name' of https://github.com/samitpal/packer into b-google-image-name 2015-07-07 16:19:55 -06:00
Chris Bednarski bd6c31c2d9 Added TestImageName and moved private methods to the bottom of the file 2015-07-07 16:18:31 -06:00
Mitchell Hashimoto da749e2470 Merge pull request #2407 from dayer4b/master
builder/null: When using a Null builder, this error message is incorrect.
2015-07-07 16:06:38 -06:00
Sunil K Chopra fcb7967bf5 Merge branch 'fix-error-message-for-null' 2015-07-07 17:04:39 -05:00
Sunil K Chopra 750e09d51d should be ssh_host, not host 2015-07-07 17:04:27 -05:00
Chris Bednarski eaf8550e50 Merge pull request #2383 from tylert/gh-2382-ssh-wait-timeout-example-cleanup
Remove ssh_wait_timeout from doc basic examples for virtualbox/vmware…
2015-07-07 11:45:28 -06:00
Samit Pal 6d6b3e1ac2 The default image name in the code has a bug. It is being set to packer-{{timestamp}}, the {{timestamp}} part needs to be interpolated. Without the interpolation the GCE builder fails with
the following error

==> googlecompute: Creating image...
==> googlecompute: Error waiting for image: googleapi: Error 400: Invalid value for field 'resource.name': 'packer-{{timestamp}}'. Must be a match of regex '(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)', invalid
2015-07-07 05:27:58 +00:00
Chris Bednarski db10f7c0ce Merge pull request #2396 from mitchellh/f-edit-docs
Add 'edit these docs' link in the website footer
2015-07-06 14:56:29 -06:00
Chris Bednarski cc9549eac8 Update README to recommend the makefile 2015-07-06 14:54:30 -06:00
Chris Bednarski 0cee01261c Added a makefile for the docs repo 2015-07-06 14:53:17 -06:00
Chris Bednarski 98e7f2a341 Added a footer link to edit the docs 2015-07-06 14:53:03 -06:00
Chris Bednarski ed463bccda Added post-processor crash fix to the changelog 2015-07-06 14:17:33 -06:00
Tyler Tidman c416f6e14b Remove ssh_wait_timeout from doc basic examples for virtualbox/vmware builders. Fixes GH-2382. 2015-07-02 17:37:03 -04:00
Chris Bednarski 872e78d5b0 v0.8.1 2015-07-02 14:14:56 -07:00
Chris Bednarski 7ca5984128 Merge pull request #2379 from mitchellh/b-ssh-handhake-timeout
Wrap SSH handshake in a timeout
2015-07-02 12:13:25 -07:00
Chris Bednarski 0ca03f09c1 Fix some style issues and add a doc to ErrHandshakeTimeout 2015-07-02 11:58:51 -07:00
Clint 67a1703768 Update CHANGELOG.md 2015-07-02 09:36:28 -05:00
Clint 61c083c0fd Merge pull request #2381 from smerrill/feature/GH-2380
Fix #2830.
2015-07-02 09:35:27 -05:00
Steven Merrill 0869c9fe64 Fix #2830. 2015-07-02 10:23:44 -04:00
Chris Bednarski 5dd8ae45c7 Cleanup some resources we may have created 2015-07-02 03:55:18 -07:00
Chris Bednarski 03850cafc6 Implemented timeout around the SSH handshake, including a unit test 2015-07-02 03:40:47 -07:00
Mitchell Hashimoto 6ca48fa3c8 Merge pull request #2374 from mifix/fix-null-builder-doc
wesbtei: Fix NULL builder config documentation.
2015-07-01 09:59:41 -07:00
Christian Mayer ebd4cb761d Fix NULL builder config documentation.
Change from "host" to "ssh_host" was introduced in d545431f9b
2015-07-01 10:46:47 +02:00
Chris Bednarski 3239d157c1 Merge pull request #2368 from jszwedko/fix-stdin
Fix `packer build` reading from STDIN
2015-06-30 11:12:37 -07:00
Zach Zolton 548f2ced1c Fix packer build reading from STDIN
Signed-off-by: Jesse Szwedko <jesse.szwedko@getbraintree.com>
2015-06-30 17:56:14 +00:00
Mitchell Hashimoto 3abec94936 update CHANGELOG 2015-06-30 10:46:14 -07:00
Mitchell Hashimoto 5ff86ae15f Merge pull request #2367 from mitchellh/b-build-type
helper/config: copy buildname/buildtype properly
2015-06-30 10:45:12 -07:00
Mitchell Hashimoto ac444accb1 helper/config: tests 2015-06-30 10:44:56 -07:00
Mitchell Hashimoto fd2d44c212 helper/config: copy buildname/buildtype properly 2015-06-30 10:42:55 -07:00
Mitchell Hashimoto 8fd673ff9f Merge pull request #2364 from tdg5/explicit_docker_pp_sequencing
website: Be more explicit about sequence definition usage in docker builder docs
2015-06-30 10:07:17 -07:00
Danny Guinther d1961e782b Be more explicit about sequence definition usage in docker builder docs 2015-06-30 08:33:01 -04:00
Chris Bednarski 31357df126 Merge pull request #2359 from mitchellh/d-execute-command
Document shell provisioner example for FreeBSD
2015-06-29 17:09:37 -07:00
Chris Bednarski 6c2e6c41d9 Added an example using tcsh with shell provisioner; reworded some of the execute_command docs 2015-06-29 17:06:49 -07:00
Chris Bednarski caa518b294 Merge pull request #2358 from mitchellh/b-do-private-network
Detect the first public IPv4 address for Digital Ocean
2015-06-29 15:13:31 -07:00
Chris Bednarski 51804e9132 Find a public IP address to provision a digital ocean box 2015-06-29 14:47:28 -07:00
Mitchell Hashimoto 61753d37cb Update CHANGELOG.md 2015-06-29 14:04:10 -07:00
Mitchell Hashimoto 2ee2850c1a Merge pull request #2353 from mitchellh/b-gce-comm-default
builder/googlecompute: default SSH settings properly [GH-2340]
2015-06-29 14:03:46 -07:00
Mitchell Hashimoto 95f9391fd6 Update CHANGELOG.md 2015-06-29 14:00:26 -07:00
Mitchell Hashimoto 6dd36075b2 Merge pull request #2352 from mitchellh/b-amazon-bundle
builder/amazon/instance: set valid bundle prefix [GH-2328]
2015-06-29 13:59:45 -07:00
Mitchell Hashimoto 782d693075 Update CHANGELOG.md 2015-06-29 13:47:53 -07:00
Mitchell Hashimoto d3ed169175 Merge pull request #2351 from mitchellh/f-winrm-debug
builder/amazon: output WinRM password for debug mode [GH-2336]
2015-06-29 13:46:51 -07:00
Mitchell Hashimoto 5c82ac2835 Merge pull request #2356 from mitchellh/b-min-version
packer: validate minimum version [GH-2310]
2015-06-29 13:46:35 -07:00
Chris Bednarski aa3a336e72 Merge pull request #2338 from mitchellh/b-only-flag
Fix flags so we can do e.g. -only=build1,build2
2015-06-29 13:06:20 -07:00
Mitchell Hashimoto 2498ad02c8 packer: validate minimum version [GH-2310] 2015-06-29 11:49:45 -07:00
Mitchell Hashimoto 8657b1e9d8 communicator/ssh: more logging 2015-06-29 11:40:08 -07:00
Mitchell Hashimoto 0904f4ed56 Merge pull request #2355 from ceh/appveyor-build-master-only
AppVeyor: only build master branch
2015-06-29 11:38:26 -07:00
Emil Hessman bfcd004497 AppVeyor: only build master branch
AppVeyor builds all branches per default.
Add a configuration setting to only build the master branch.

See http://www.appveyor.com/docs/branches#white-and-blacklisting for details.

For the record, AppVeyor builds can skipped by annotating the commit message
according to http://www.appveyor.com/docs/how-to/skip-build
Useful for e.g. website commits.

[skip appveyor]
2015-06-29 20:07:41 +02:00
Mitchell Hashimoto 9e6207f5bc Merge pull request #2354 from ceh/appveyor-status-badge
Add AppVeyor status badge to README
2015-06-29 10:26:05 -07:00
Emil Hessman eef260a11b Add AppVeyor status badge to README 2015-06-29 19:23:44 +02:00
Mitchell Hashimoto c1ad38155c Merge pull request #2350 from ceh/windows-ci-appveyor
Add AppVeyor configuration file
2015-06-29 10:09:48 -07:00
Mitchell Hashimoto 6c7a7b6068 builder/googlecompute: default SSH settings properly [GH-2340] 2015-06-29 09:56:33 -07:00
Mitchell Hashimoto 98db68e36c builder/amazon/instance: set valid bundle prefix [GH-2328] 2015-06-29 09:49:11 -07:00
Mitchell Hashimoto b315e470c8 builder/amazon: set debug flag for get password 2015-06-29 09:40:58 -07:00
Mitchell Hashimoto 0a2e54feaf builder/amazon: output WinRM password for debug mode [GH-2336] 2015-06-29 09:40:15 -07:00
Mitchell Hashimoto 1aef60ff76 update CHANGELOG 2015-06-29 09:35:42 -07:00
Mitchell Hashimoto 062b2270dd Merge pull request #2306 from wtschreiter/knife_config_by_template
Add knife config by template
2015-06-29 09:35:16 -07:00
Mitchell Hashimoto 1b9d0dcddd Merge pull request #2321 from acranox/chef-client-docs
website: Update docs for default configuration template
2015-06-29 09:33:48 -07:00
Mitchell Hashimoto 4a60e469e9 update CHANGELOG 2015-06-29 09:33:20 -07:00
Mitchell Hashimoto 677498a55c Merge pull request #2323 from israelshirk/feature/vmware-nonesum
builder/vmware: Run stat on vmware when checksum type = none
2015-06-29 09:32:08 -07:00
Mitchell Hashimoto 95dd79740f Merge pull request #2324 from tcahill/group-launch-permissions
Fix setting ami_groups
2015-06-29 09:30:51 -07:00
Mitchell Hashimoto 79de517e04 update CHANGELOG 2015-06-29 09:24:22 -07:00
Mitchell Hashimoto 7b64723a11 Merge pull request #2327 from emate/fix-for-spot-requests-cleanup
Fixes spot instance cleanup.
2015-06-29 09:24:01 -07:00
Mitchell Hashimoto 21d50916b6 Merge pull request #2335 from mitchellh/b-vagrantcloud-docs
website: Update some docs to point to Atlas instead of Vagrant Cloud
2015-06-29 09:23:50 -07:00
Mitchell Hashimoto 69777d8ad2 Merge pull request #2337 from benzenwen/bw-doc-debugging
website: Tips for debugging a build.
2015-06-29 09:23:32 -07:00
Mitchell Hashimoto 41e160ccda Merge pull request #2347 from grange74/master
#2346 updated to AMI that doesn't require accepting marketplace terms
2015-06-29 09:22:51 -07:00
Mitchell Hashimoto aab5ca7059 update CHANGELOG 2015-06-29 09:22:33 -07:00
Mitchell Hashimoto 60fabe64e1 Merge pull request #2348 from emate/fix-for-ami-permission-setting
builder/aws: fix adding launch permissions for created ami.
2015-06-29 09:21:36 -07:00
Emil Hessman a3fa7cdce3 Add AppVeyor configuration file
Packer lacks an official Windows CI server.
This commit adds a configuration file for AppVeyor, which is a Windows CI
service (free for open-source projects).
2015-06-29 18:14:45 +02:00
Marcin Matlaszek 3eaf7f38b0 Fix adding launch permissions for created ami. 2015-06-29 15:39:27 +02:00
nick.grange 5c64f7f7cf #2346 updated to ami that doesn't require accepting marketplace terms
Updated to same ami as in main readme.md which is from community AMIs
and therefore doesn't require accepting the AWS marketplace terms
before using in Packer build.
2015-06-29 23:10:56 +10:00
Chris Bednarski 94e1f83070 Added a black-box acceptance test for -only and -except build flags 2015-06-27 00:47:50 -07:00
Chris Bednarski eee066371a Support -flag=var1,var2,var3 to fix #2332 2015-06-26 17:54:59 -07:00
Ben Wen aa84f9eeb5 Tips for debugging a build. 2015-06-26 15:18:45 -07:00
Chris Bednarski 355364ce4c Change some outdate references to Vagrant Cloud to point to Atlas instead 2015-06-26 14:59:01 -07:00
Chris Bednarski 18e29e0f2b Merge pull request #2331 from mitchellh/b-awsami
Change docs usage of aws.ami to amazon.ami to be consistent with terraform
2015-06-26 14:44:27 -07:00
Tom Cahill 6644d76982 Use aws.String to obtain string pointers 2015-06-26 12:08:44 -07:00
Tom Cahill 016d916d83 Fix adding groups to AMI launch permissions.
Previously, groups were granted launch permissions by submitting a
ModifyImageAttribute request with the UserGroups parameter set
appropriately. This is no longer valid, as the LaunchPermission
parameter must be set.
2015-06-26 10:52:27 -07:00
Mark Peek d8b6c94012 Fix typo: diabled -> disabled 2015-06-26 10:52:21 -07:00
Chris Bednarski daf563e210 Change aws.ami to amazon.ami to be consistent with usage in terraform 2015-06-26 10:22:15 -07:00
Clint e112d9b288 Update CHANGELOG.md 2015-06-26 11:11:46 -05:00
Clint d740bad640 Merge pull request #2330 from mitchellh/b-amazon-instance-virt
builder/amazon-instance: Don't specify empty Virtualization Type
2015-06-26 11:10:54 -05:00
Clint Shryock 4d003aa5a3 builder/amazon-instance: Don't specify empty Virtualization Type 2015-06-26 10:43:13 -05:00
Marcin Matlaszek 586cab11ee Fixes spot instance cleanup. 2015-06-26 15:29:46 +02:00
Israel Shirk 88fac0b49c Have nonesum run stat rather than nonesum because nonesum sums none. k. 2015-06-25 19:03:00 -06:00
Peter Doherty 5896d96bdb Update docs for default configuration template
Update docs for default configuration template for the chef-client provisioner, to reflect the ability to set a custom validation_client_name
2015-06-25 16:03:24 -04:00
Clint fe0fde195d Update CHANGELOG.md 2015-06-25 14:51:01 -05:00
Clint 9805c10c87 Merge pull request #2320 from tommyulfsparre/block-device-mapping
InvalidBlockDeviceMapping
2015-06-25 14:50:09 -05:00
Tommy Ulfsparre 8ae0cfc759 copy and convert to pointer 2015-06-25 20:07:45 +02:00
Clint dd1fdc722a Update CHANGELOG.md 2015-06-25 10:18:56 -05:00
Clint 7b9d48799e Merge pull request #2316 from jjappi/fix-aws-tagging
Fix failing AMI snapshot tagging when copying to other regions.
2015-06-25 10:17:34 -05:00
Clint d5c17734b8 Merge pull request #2317 from emate/fix-for-amazon-builder-instance-tags
Fix for tag creation when creating new ec2 instance.
2015-06-25 10:11:41 -05:00
Marcin Matlaszek dd97a60c9b Fix for tag creation when creating new ec2 instance. 2015-06-25 17:02:38 +02:00
Jani Jappinen c537623bc6 Fix failing AMI snapshot tagging when copying to other regions. 2015-06-25 17:25:28 +03:00
Chris Bednarski 6bb480e2f7 Merge pull request #2313 from mitchellh/b-compress-crash 2015-06-24 21:49:30 -07:00
Chris Bednarski eba28519db Move vars to the top and cleanup extra whitespace 2015-06-24 18:29:32 -07:00
Chris Bednarski 1831a09055 Fix compress crash
- Changed config from pointer to value to fix crash
- Removed acceptance flag from compress tests since they would have
caught this
2015-06-24 17:47:00 -07:00
Clint f765d57009 Update CHANGELOG.md 2015-06-24 13:25:08 -05:00
Clint a2c9b2da8f Merge pull request #2308 from mitchellh/b-amazon-ami-sharing-fix
builder/amazon: Fix issue with sharing AMIs with ami_users
2015-06-24 13:23:10 -05:00
Clint Shryock 7af5d5419a builder/amazon: Fix issue with sharing AMIs with ami_users 2015-06-24 11:41:58 -05:00
Mitchell Hashimoto fbf7db0418 Merge pull request #2307 from mitchellh/b-docs-dashes
clean up character encodings
2015-06-24 08:29:24 -07:00
Clint Shryock def6f8aefc clean up character encodings 2015-06-24 10:28:01 -05:00
Schreiter, Wulf-Thilo 18438cf291 Add knife config by template
Since the chef-client provisioner is cleaning the node and client at the chef-server from the provisioned node
it needs to have a flexible configuration

This is replacing the used knife flags: -s '<chef-server-url>' -k '/tmp/packer-chef-client/client.pem' -u '<client-name>'
and puts their values into a generated knife.rb

Additionally the knife.rb may include the optional ssl_verify_mode attribute to enable the verify mode verify_none

Background:

When deleting node and client to a self-hosted chef-server using self signed cerfiticates the usage of

    knife node delete <node-name> -y -s '<chef-server-url>' -k '/tmp/packer-chef-client/client.pem' -u '<client-name>'

will lead into a ssl verification failure.

The error output of the knife call is somthing like:

    2015/06/24 12:29:17 ui:     docker: WARNING: No knife configuration file found
    docker: WARNING: No knife configuration file found
    2015/06/24 12:29:17 ui:     docker: ERROR: SSL Validation failure connecting to host: 172.16.117.63 - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B:
    certificate verify failed
    docker: ERROR: SSL Validation failure connecting to host: 172.16.117.63 - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
    2015/06/24 12:29:17 ui:     docker: ERROR: Could not establish a secure connection to the server.
    docker: ERROR: Could not establish a secure connection to the server.
    2015/06/24 12:29:17 ui:     docker: Use 'knife ssl check' to troubleshoot your SSL configuration.
    docker: Use 'knife ssl check' to troubleshoot your SSL configuration.
    2015/06/24 12:29:17 ui:     docker: If your Chef Server uses a self-signed certificate, you can use
    docker: If your Chef Server uses a self-signed certificate, you can use
    2015/06/24 12:29:17 ui:     docker: 'knife ssl fetch' to make knife trust the server's certificates.
    docker: 'knife ssl fetch' to make knife trust the server's certificates.
    2015/06/24 12:29:17 ui:     docker:
    docker:
    2015/06/24 12:29:17 ui:     docker: Original Exception: OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
    docker: Original Exception: OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
    2015/06/24 12:29:17 packer-builder-docker: 2015/06/24 12:29:17 Executed command exit status: 100
2015-06-24 15:22:59 +02:00
Mitchell Hashimoto 8f0e28fae1 Merge pull request #2302 from jfbrown/update-do-getting-started-docs
website: Fix DigitalOcean section of getting started docs.
2015-06-23 22:20:25 -07:00
John (Jack) Brown 49664ca9c6 Fix DigitalOcean section of getting started docs.
This updates the example for adding DigitalOcean
as a provider in the beginning tutorial. It looks
like it hadn't been updated in some time, and
was using old settings. I've updated it and
confirmed it works.
2015-06-23 22:10:04 -07:00
Mitchell Hashimoto 67fed8e802 Merge pull request #2299 from mitchellh/f-agent-disable
helper/communicator: support disabling SSH agent
2015-06-23 15:16:10 -07:00
Mitchell Hashimoto a019575026 helper/communicator: support disabling SSH agent 2015-06-23 14:52:37 -07:00
Mitchell Hashimoto 32f469dc9a up version fo dev 2015-06-23 14:49:56 -07:00
Mitchell Hashimoto c0bc74990b website: note SSH forwarding 2015-06-23 14:49:36 -07:00
Mitchell Hashimoto 3cc90768a2 website: update docs to link to communicator 2015-06-23 14:44:57 -07:00
Mitchell Hashimoto 4244a6ce8d website: communicator section 2015-06-23 14:39:29 -07:00
Mitchell Hashimoto 0ed15e039a website: fix the abnormally large image sizes 2015-06-23 14:02:29 -07:00
Mitchell Hashimoto b06158aeea website: update homepage copy 2015-06-23 14:01:02 -07:00
92 changed files with 1449 additions and 481 deletions
+48
View File
@@ -1,3 +1,51 @@
## 0.8.2 (July 17, 2015)
IMPROVEMENTS:
* builder/docker: Add option to use a Pty [GH-2425]
BUG FIXES:
* core: Fix crash when `min_packer_version` is specified in a template. [GH-2385]
* builder/amazon: Fix EC2 devices being included in EBS mappings [GH-2459]
* builder/googlecompute: Fix default name for GCE images [GH-2400]
* builder/null: Fix error message with missing ssh_host [GH-2407]
* builder/virtualbox: Use --portcount on VirtualBox 5.x [GH-2438]
* provisioner/puppet: Packer now correctly handles a directory for manifest_file [GH-2463]
* provisioner/winrm: Fix potential crash with WinRM [GH-2416]
## 0.8.1 (July 2, 2015)
IMPROVEMENTS:
* builder/amazon: When debug mode is enabled, the Windows administrator
password for Windows instances will be shown [GH-2351]
BUG FIXES:
* core: `min_packer_version` field in configs work [GH-2356]
* core: The `build_name` and `build_type` functions work in provisioners [GH-2367]
* core: Handle timeout in SSH handshake [GH-2333]
* command/build: Fix reading configuration from stdin [GH-2366]
* builder/amazon: Fix issue with sharing AMIs when using `ami_users` [GH-2308]
* builder/amazon: Fix issue when using multiple Security Groups [GH-2381]
* builder/amazon: Fix for tag creation when creating new ec2 instance [GH-2317]
* builder/amazon: Fix issue with creating AMIs with multiple device mappings [GH-2320]
* builder/amazon: Fix failing AMI snapshot tagging when copying to other
regions [GH-2316]
* builder/amazon: Fix setting AMI launch permissions [GH-2348]
* builder/amazon: Fix spot instance cleanup to remove the correct request [GH-2327]
* builder/amazon: Fix `bundle_prefix` not interpolating `timestamp` [GH-2352]
* builder/amazon-instance: Fix issue with creating AMIs without specifying a
virtualization type [GH-2330]
* builder/digitalocean: Fix builder using private IP instead of public IP [GH-2339]
* builder/google: Set default communicator settings properly [GH-2353]
* builder/vmware-iso: Setting `checksum_type` to `none` for ESX builds
now works [GH-2323]
* provisioner/chef: Use knife config file vs command-line params to
clean up nodes so full set of features can be used [GH-2306]
* post-processor/compress: Fixed crash in compress post-processor plugin [GH-2311]
## 0.8.0 (June 23, 2015)
BACKWARDS INCOMPATIBILITIES:
+2 -2
View File
@@ -53,8 +53,8 @@ it raises the chances we can quickly merge or address your contributions.
If you have never worked with Go before, you will have to complete the
following steps in order to be able to compile and test Packer.
1. Install Go. Make sure the Go version is at least Go 1.2. Packer will not work with anything less than
Go 1.2. On a Mac, you can `brew install go` to install Go 1.2.
1. Install Go. Make sure the Go version is at least Go 1.4. Packer will not work with anything less than
Go 1.4. On a Mac, you can `brew install go` to install Go 1.4.
2. Set and export the `GOPATH` environment variable and update your `PATH`.
For example, you can add to your `.bash_profile`.
+1
View File
@@ -1,6 +1,7 @@
# Packer
[![Build Status](https://travis-ci.org/mitchellh/packer.svg?branch=master)](https://travis-ci.org/mitchellh/packer)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/mitchellh/packer?branch=master&svg=true)](https://ci.appveyor.com/project/hashicorp/packer)
* Website: http://www.packer.io
* IRC: `#packer-tool` on Freenode
+37
View File
@@ -0,0 +1,37 @@
# appveyor.yml reference : http://www.appveyor.com/docs/appveyor-yml
version: "{build}"
skip_tags: true
branches:
only:
- master
os: Windows Server 2012 R2
environment:
GOPATH: c:\gopath
matrix:
- GOARCH: 386
GOVERSION: 1.4.2
- GOARCH: amd64
GOVERSION: 1.4.2
clone_folder: c:\gopath\src\github.com\mitchellh\packer
install:
- set Path=c:\go\bin;%Path%
- echo %Path%
- appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-%GOARCH%.msi
- msiexec /i go%GOVERSION%.windows-%GOARCH%.msi /q
- go version
- go env
- go get -d -v -t ./...
build_script:
- go test -v ./...
test: off
deploy: off
+14 -9
View File
@@ -1,6 +1,8 @@
package common
import (
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/mitchellh/packer/template/interpolate"
@@ -29,27 +31,30 @@ func buildBlockDevices(b []BlockDevice) []*ec2.BlockDeviceMapping {
for _, blockDevice := range b {
ebsBlockDevice := &ec2.EBSBlockDevice{
VolumeType: &blockDevice.VolumeType,
VolumeSize: &blockDevice.VolumeSize,
DeleteOnTermination: &blockDevice.DeleteOnTermination,
VolumeType: aws.String(blockDevice.VolumeType),
VolumeSize: aws.Long(blockDevice.VolumeSize),
DeleteOnTermination: aws.Boolean(blockDevice.DeleteOnTermination),
}
// IOPS is only valid for SSD Volumes
if blockDevice.VolumeType != "" && blockDevice.VolumeType != "standard" && blockDevice.VolumeType != "gp2" {
ebsBlockDevice.IOPS = &blockDevice.IOPS
ebsBlockDevice.IOPS = aws.Long(blockDevice.IOPS)
}
// You cannot specify Encrypted if you specify a Snapshot ID
if blockDevice.SnapshotId != "" {
ebsBlockDevice.SnapshotID = &blockDevice.SnapshotId
ebsBlockDevice.SnapshotID = aws.String(blockDevice.SnapshotId)
} else if blockDevice.Encrypted {
ebsBlockDevice.Encrypted = &blockDevice.Encrypted
ebsBlockDevice.Encrypted = aws.Boolean(blockDevice.Encrypted)
}
mapping := &ec2.BlockDeviceMapping{
EBS: ebsBlockDevice,
DeviceName: &blockDevice.DeviceName,
VirtualName: &blockDevice.VirtualName,
DeviceName: aws.String(blockDevice.DeviceName),
VirtualName: aws.String(blockDevice.VirtualName),
}
if !strings.HasPrefix(blockDevice.VirtualName, "ephemeral") {
mapping.EBS = ebsBlockDevice
}
if blockDevice.NoDevice {
+18 -7
View File
@@ -17,17 +17,15 @@ func TestBlockDevice(t *testing.T) {
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VirtualName: "ephemeral0",
SnapshotId: "snap-1234",
VolumeType: "standard",
VolumeSize: 8,
DeleteOnTermination: true,
IOPS: 1000,
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
VirtualName: aws.String("ephemeral0"),
VirtualName: aws.String(""),
EBS: &ec2.EBSBlockDevice{
SnapshotID: aws.String("snap-1234"),
VolumeType: aws.String("standard"),
@@ -55,7 +53,6 @@ func TestBlockDevice(t *testing.T) {
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VirtualName: "ephemeral0",
VolumeType: "io1",
VolumeSize: 8,
DeleteOnTermination: true,
@@ -64,7 +61,7 @@ func TestBlockDevice(t *testing.T) {
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
VirtualName: aws.String("ephemeral0"),
VirtualName: aws.String(""),
EBS: &ec2.EBSBlockDevice{
VolumeType: aws.String("io1"),
VolumeSize: aws.Long(8),
@@ -73,6 +70,17 @@ func TestBlockDevice(t *testing.T) {
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VirtualName: "ephemeral0",
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
VirtualName: aws.String("ephemeral0"),
},
},
}
for _, tc := range cases {
@@ -84,11 +92,14 @@ func TestBlockDevice(t *testing.T) {
expected := []*ec2.BlockDeviceMapping{tc.Result}
got := blockDevices.BuildAMIDevices()
if !reflect.DeepEqual(expected, got) {
t.Fatalf("Bad block device, \nexpected: %s\n\ngot: %s", awsutil.StringValue(expected), awsutil.StringValue(got))
t.Fatalf("Bad block device, \nexpected: %s\n\ngot: %s",
awsutil.StringValue(expected), awsutil.StringValue(got))
}
if !reflect.DeepEqual(expected, blockDevices.BuildLaunchDevices()) {
t.Fatalf("Bad block device, \nexpected: %s\n\ngot: %s", awsutil.StringValue(expected), awsutil.StringValue(blockDevices.BuildLaunchDevices()))
t.Fatalf("Bad block device, \nexpected: %s\n\ngot: %s",
awsutil.StringValue(expected),
awsutil.StringValue(blockDevices.BuildLaunchDevices()))
}
}
}
+6 -6
View File
@@ -34,8 +34,13 @@ func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction {
// Declare list of resources to tag
resourceIds := []*string{&ami}
regionconn := ec2.New(&aws.Config{
Credentials: ec2conn.Config.Credentials,
Region: region,
})
// Retrieve image list for given AMI
imageResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{
imageResp, err := regionconn.DescribeImages(&ec2.DescribeImagesInput{
ImageIDs: resourceIds,
})
@@ -63,11 +68,6 @@ func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction {
}
}
regionconn := ec2.New(&aws.Config{
Credentials: ec2conn.Config.Credentials,
Region: region,
})
_, err = regionconn.CreateTags(&ec2.CreateTagsInput{
Resources: resourceIds,
Tags: ec2Tags,
@@ -19,6 +19,7 @@ import (
// StepGetPassword reads the password from a Windows server and sets it
// on the WinRM config.
type StepGetPassword struct {
Debug bool
Comm *communicator.Config
Timeout time.Duration
}
@@ -85,6 +86,13 @@ WaitLoop:
}
}
}
// In debug-mode, we output the password
if s.Debug {
ui.Message(fmt.Sprintf(
"Password (since debug is enabled): %s", s.Comm.WinRMPassword))
}
return multistep.ActionContinue
}
@@ -44,21 +44,35 @@ func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAc
if len(s.Groups) > 0 {
groups := make([]*string, len(s.Groups))
adds := make([]*ec2.LaunchPermission, len(s.Groups))
addGroups := &ec2.ModifyImageAttributeInput{
LaunchPermission: &ec2.LaunchPermissionModifications{},
}
for i, g := range s.Groups {
groups[i] = &g
}
options["groups"] = &ec2.ModifyImageAttributeInput{
UserGroups: groups,
groups[i] = aws.String(g)
adds[i] = &ec2.LaunchPermission{
Group: aws.String(g),
}
}
addGroups.UserGroups = groups
addGroups.LaunchPermission.Add = adds
options["groups"] = addGroups
}
if len(s.Users) > 0 {
users := make([]*string, len(s.Users))
adds := make([]*ec2.LaunchPermission, len(s.Users))
for i, u := range s.Users {
users[i] = &u
users[i] = aws.String(u)
adds[i] = &ec2.LaunchPermission{UserID: aws.String(u)}
}
options["users"] = &ec2.ModifyImageAttributeInput{
UserIDs: users,
LaunchPermission: &ec2.LaunchPermissionModifications{
Add: adds,
},
}
}
@@ -43,7 +43,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
securityGroupIds := make([]*string, len(tempSecurityGroupIds))
for i, sg := range tempSecurityGroupIds {
securityGroupIds[i] = &sg
securityGroupIds[i] = aws.String(sg)
}
userData := s.UserData
@@ -256,7 +256,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
ec2Tags := make([]*ec2.Tag, 1, len(s.Tags)+1)
ec2Tags[0] = &ec2.Tag{Key: aws.String("Name"), Value: aws.String("Packer Builder")}
for k, v := range s.Tags {
ec2Tags = append(ec2Tags, &ec2.Tag{Key: &k, Value: &v})
ec2Tags = append(ec2Tags, &ec2.Tag{Key: aws.String(k), Value: aws.String(v)})
}
_, err = ec2conn.CreateTags(&ec2.CreateTagsInput{
@@ -296,7 +296,7 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) {
if s.spotRequest != nil {
ui.Say("Cancelling the spot request...")
input := &ec2.CancelSpotInstanceRequestsInput{
SpotInstanceRequestIDs: []*string{s.spotRequest.InstanceID},
SpotInstanceRequestIDs: []*string{s.spotRequest.SpotInstanceRequestID},
}
if _, err := ec2conn.CancelSpotInstanceRequests(input); err != nil {
ui.Error(fmt.Sprintf("Error cancelling the spot request, may still be around: %s", err))
+1
View File
@@ -119,6 +119,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Tags: b.config.RunTags,
},
&awscommon.StepGetPassword{
Debug: b.config.PackerDebug,
Comm: &b.config.RunConfig.Comm,
Timeout: b.config.WindowsPasswordTimeout,
},
+82
View File
@@ -5,6 +5,7 @@ import (
"os"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/mitchellh/packer/builder/amazon/common"
builderT "github.com/mitchellh/packer/helper/builder/testing"
@@ -44,6 +45,71 @@ func TestBuilderAcc_forceDeregister(t *testing.T) {
})
}
func TestBuilderAcc_amiSharing(t *testing.T) {
builderT.Test(t, builderT.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Builder: &Builder{},
Template: testBuilderAccSharing,
Check: checkAMISharing(2, "932021504756", "all"),
})
}
func checkAMISharing(count int, uid, group 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.(*common.Artifact)
if !ok {
return fmt.Errorf("unknown artifact: %#v", artifactRaw)
}
// describe the image, get block devices with a snapshot
ec2conn, _ := testEC2Conn()
imageResp, err := ec2conn.DescribeImageAttribute(&ec2.DescribeImageAttributeInput{
Attribute: aws.String("launchPermission"),
ImageID: aws.String(artifact.Amis["us-east-1"]),
})
if err != nil {
return fmt.Errorf("Error retrieving Image Attributes for AMI Artifact (%#v) in AMI Sharing Test: %s", artifact, err)
}
// Launch Permissions are in addition to the userid that created it, so if
// you add 3 additional ami_users, you expect 2 Launch Permissions here
if len(imageResp.LaunchPermissions) != count {
return fmt.Errorf("Error in Image Attributes, expected (%d) Launch Permissions, got (%d)", count, len(imageResp.LaunchPermissions))
}
userFound := false
for _, lp := range imageResp.LaunchPermissions {
if lp.UserID != nil && uid == *lp.UserID {
userFound = true
}
}
if !userFound {
return fmt.Errorf("Error in Image Attributes, expected User ID (%s) to have Launch Permissions, but was not found", uid)
}
groupFound := false
for _, lp := range imageResp.LaunchPermissions {
if lp.Group != nil && group == *lp.Group {
groupFound = true
}
}
if !groupFound {
return fmt.Errorf("Error in Image Attributes, expected Group ID (%s) to have Launch Permissions, but was not found", group)
}
return nil
}
}
func checkRegionCopy(regions []string) builderT.TestCheckFunc {
return func(artifacts []packer.Artifact) error {
if len(artifacts) > 1 {
@@ -138,6 +204,22 @@ const testBuilderAccForceDeregister = `
}
`
// share with catsby
const testBuilderAccSharing = `
{
"builders": [{
"type": "test",
"region": "us-east-1",
"instance_type": "m3.medium",
"source_ami": "ami-76b2a71e",
"ssh_username": "ubuntu",
"ami_name": "packer-test {{timestamp}}",
"ami_users":["932021504756"],
"ami_groups":["all"]
}]
}
`
func buildForceDeregisterConfig(name, flag string) string {
return fmt.Sprintf(testBuilderAccForceDeregister, name, flag)
}
+8 -5
View File
@@ -50,6 +50,12 @@ type Builder struct {
}
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
configs := make([]interface{}, len(raws)+1)
configs[0] = map[string]interface{}{
"bundle_prefix": "image-{{timestamp}}",
}
copy(configs[1:], raws)
b.config.ctx.Funcs = awscommon.TemplateFuncs
err := config.Decode(&b.config, &config.DecodeOpts{
Interpolate: true,
@@ -60,7 +66,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
"bundle_vol_command",
},
},
}, raws...)
}, configs...)
if err != nil {
return nil, err
}
@@ -69,10 +75,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
b.config.BundleDestination = "/tmp"
}
if b.config.BundlePrefix == "" {
b.config.BundlePrefix = "image-{{timestamp}}"
}
if b.config.BundleUploadCommand == "" {
if b.config.IamInstanceProfile != "" {
b.config.BundleUploadCommand = "sudo -i -n ec2-upload-bundle " +
@@ -204,6 +206,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Tags: b.config.RunTags,
},
&awscommon.StepGetPassword{
Debug: b.config.PackerDebug,
Comm: &b.config.RunConfig.Comm,
Timeout: b.config.WindowsPasswordTimeout,
},
-1
View File
@@ -130,7 +130,6 @@ func TestBuilderPrepare_BundlePrefix(t *testing.T) {
b := &Builder{}
config := testConfig()
config["bundle_prefix"] = ""
warnings, err := b.Prepare(config)
if len(warnings) > 0 {
t.Fatalf("bad: %#v", warnings)
+7 -4
View File
@@ -3,6 +3,7 @@ package instance
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep"
awscommon "github.com/mitchellh/packer/builder/amazon/common"
@@ -20,15 +21,17 @@ func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction {
ui.Say("Registering the AMI...")
registerOpts := &ec2.RegisterImageInput{
ImageLocation: &manifestPath,
Name: &config.AMIName,
Name: aws.String(config.AMIName),
BlockDeviceMappings: config.BlockDevices.BuildAMIDevices(),
VirtualizationType: &config.AMIVirtType,
}
if config.AMIVirtType != "" {
registerOpts.VirtualizationType = aws.String(config.AMIVirtType)
}
// Set SriovNetSupport to "simple". See http://goo.gl/icuXh5
if config.AMIEnhancedNetworking {
simple := "simple"
registerOpts.SRIOVNetSupport = &simple
registerOpts.SRIOVNetSupport = aws.String("simple")
}
registerResp, err := ec2conn.RegisterImage(registerOpts)
+20 -5
View File
@@ -14,11 +14,11 @@ func (s *stepDropletInfo) Run(state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*godo.Client)
ui := state.Get("ui").(packer.Ui)
c := state.Get("config").(Config)
dropletId := state.Get("droplet_id").(int)
dropletID := state.Get("droplet_id").(int)
ui.Say("Waiting for droplet to become active...")
err := waitForDropletState("active", dropletId, client, c.StateTimeout)
err := waitForDropletState("active", dropletID, client, c.StateTimeout)
if err != nil {
err := fmt.Errorf("Error waiting for droplet to become active: %s", err)
state.Put("error", err)
@@ -27,7 +27,7 @@ func (s *stepDropletInfo) Run(state multistep.StateBag) multistep.StepAction {
}
// Set the IP on the state for later
droplet, _, err := client.Droplets.Get(dropletId)
droplet, _, err := client.Droplets.Get(dropletID)
if err != nil {
err := fmt.Errorf("Error retrieving droplet: %s", err)
state.Put("error", err)
@@ -39,13 +39,28 @@ func (s *stepDropletInfo) Run(state multistep.StateBag) multistep.StepAction {
invalid := droplet.Networks == nil ||
len(droplet.Networks.V4) == 0
if invalid {
err := fmt.Errorf("IPv4 address not found for droplet!")
err := fmt.Errorf("IPv4 address not found for droplet")
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Find a public IPv4 network
foundNetwork := false
for _, network := range droplet.Networks.V4 {
if network.Type == "public" {
state.Put("droplet_ip", network.IPAddress)
foundNetwork = true
break
}
}
if !foundNetwork {
err := fmt.Errorf("Count not find a public IPv4 address for this droplet")
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
state.Put("droplet_ip", droplet.Networks.V4[0].IPAddress)
return multistep.ActionContinue
}
+6 -2
View File
@@ -24,7 +24,7 @@ type Communicator struct {
HostDir string
ContainerDir string
Version *version.Version
Config *Config
lock sync.Mutex
}
@@ -45,7 +45,11 @@ func (c *Communicator) Start(remote *packer.RemoteCmd) error {
var cmd *exec.Cmd
if c.canExec() {
cmd = exec.Command("docker", "exec", "-i", c.ContainerId, "/bin/sh")
if c.Config.Pty {
cmd = exec.Command("docker", "exec", "-i", "-t", c.ContainerId, "/bin/sh")
} else {
cmd = exec.Command("docker", "exec", "-i", c.ContainerId, "/bin/sh")
}
} else {
cmd = exec.Command("docker", "attach", c.ContainerId)
}
+1
View File
@@ -28,6 +28,7 @@ type Config struct {
LoginUsername string `mapstructure:"login_username"`
LoginPassword string `mapstructure:"login_password"`
LoginServer string `mapstructure:"login_server"`
Pty bool
ctx interpolate.Context
}
+2
View File
@@ -7,6 +7,7 @@ import (
type StepConnectDocker struct{}
func (s *StepConnectDocker) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
containerId := state.Get("container_id").(string)
driver := state.Get("driver").(Driver)
tempDir := state.Get("temp_dir").(string)
@@ -25,6 +26,7 @@ func (s *StepConnectDocker) Run(state multistep.StateBag) multistep.StepAction {
HostDir: tempDir,
ContainerDir: "/packer-files",
Version: version,
Config: config,
}
state.Put("communicator", comm)
+11 -2
View File
@@ -59,6 +59,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
return nil, nil, err
}
var errs *packer.MultiError
// Set defaults.
if c.Network == "" {
c.Network = "default"
@@ -73,7 +75,12 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
}
if c.ImageName == "" {
c.ImageName = "packer-{{timestamp}}"
img, err := interpolate.Render("packer-{{timestamp}}", nil)
if err != nil {
errs = packer.MultiErrorAppend(errs,
fmt.Errorf("Unable to parse image name: %s ", err))
c.ImageName = img
}
}
if c.InstanceName == "" {
@@ -96,7 +103,9 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
c.Comm.SSHUsername = "root"
}
var errs *packer.MultiError
if es := c.Comm.Prepare(&c.ctx); len(es) > 0 {
errs = packer.MultiErrorAppend(errs, es...)
}
// Process required parameters.
if c.ProjectId == "" {
+78 -39
View File
@@ -2,48 +2,10 @@ package googlecompute
import (
"io/ioutil"
"strings"
"testing"
)
func testConfig(t *testing.T) map[string]interface{} {
return map[string]interface{}{
"account_file": testAccountFile(t),
"project_id": "hashicorp",
"source_image": "foo",
"zone": "us-east-1a",
}
}
func testConfigStruct(t *testing.T) *Config {
c, warns, errs := NewConfig(testConfig(t))
if len(warns) > 0 {
t.Fatalf("bad: %#v", len(warns))
}
if errs != nil {
t.Fatalf("bad: %#v", errs)
}
return c
}
func testConfigErr(t *testing.T, warns []string, err error, extra string) {
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err == nil {
t.Fatalf("should error: %s", extra)
}
}
func testConfigOk(t *testing.T, warns []string, err error) {
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err != nil {
t.Fatalf("bad: %s", err)
}
}
func TestConfigPrepare(t *testing.T) {
cases := []struct {
Key string
@@ -152,6 +114,83 @@ func TestConfigPrepare(t *testing.T) {
}
}
func TestConfigDefaults(t *testing.T) {
cases := []struct {
Read func(c *Config) interface{}
Value interface{}
}{
{
func(c *Config) interface{} { return c.Comm.Type },
"ssh",
},
{
func(c *Config) interface{} { return c.Comm.SSHPort },
22,
},
}
for _, tc := range cases {
raw := testConfig(t)
c, warns, errs := NewConfig(raw)
testConfigOk(t, warns, errs)
actual := tc.Read(c)
if actual != tc.Value {
t.Fatalf("bad: %#v", actual)
}
}
}
func TestImageName(t *testing.T) {
c, _, _ := NewConfig(testConfig(t))
if strings.Contains(c.ImageName, "{{timestamp}}") {
t.Errorf("ImageName should be interpolated; found %s", c.ImageName)
}
}
// Helper stuff below
func testConfig(t *testing.T) map[string]interface{} {
return map[string]interface{}{
"account_file": testAccountFile(t),
"project_id": "hashicorp",
"source_image": "foo",
"zone": "us-east-1a",
}
}
func testConfigStruct(t *testing.T) *Config {
c, warns, errs := NewConfig(testConfig(t))
if len(warns) > 0 {
t.Fatalf("bad: %#v", len(warns))
}
if errs != nil {
t.Fatalf("bad: %#v", errs)
}
return c
}
func testConfigErr(t *testing.T, warns []string, err error, extra string) {
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err == nil {
t.Fatalf("should error: %s", extra)
}
}
func testConfigOk(t *testing.T, warns []string, err error) {
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err != nil {
t.Fatalf("bad: %s", err)
}
}
func testAccountFile(t *testing.T) string {
tf, err := ioutil.TempFile("", "packer")
if err != nil {
+1 -1
View File
@@ -33,7 +33,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
}
if c.CommConfig.SSHHost == "" {
errs = packer.MultiErrorAppend(errs,
fmt.Errorf("host must be specified"))
fmt.Errorf("ssh_host must be specified"))
}
if c.CommConfig.SSHUsername == "" {
+1 -1
View File
@@ -22,7 +22,7 @@ func (d *VBox42Driver) CreateSATAController(vmName string, name string) error {
}
portCountArg := "--sataportcount"
if strings.HasPrefix(version, "4.3") {
if strings.HasPrefix(version, "4.3") || strings.HasPrefix(version, "5.") {
portCountArg = "--portcount"
}
+11 -4
View File
@@ -396,11 +396,18 @@ func (d *ESX5Driver) upload(dst, src string) error {
}
func (d *ESX5Driver) verifyChecksum(ctype string, hash string, file string) bool {
stdin := bytes.NewBufferString(fmt.Sprintf("%s %s", hash, file))
_, err := d.run(stdin, fmt.Sprintf("%ssum", ctype), "-c")
if err != nil {
return false
if ctype == "none" {
if err := d.sh("stat", file); err != nil {
return false
}
} else {
stdin := bytes.NewBufferString(fmt.Sprintf("%s %s", hash, file))
_, err := d.run(stdin, fmt.Sprintf("%ssum", ctype), "-c")
if err != nil {
return false
}
}
return true
}
+7 -1
View File
@@ -37,7 +37,13 @@ func (c BuildCommand) Run(args []string) int {
}
// Parse the template
tpl, err := template.ParseFile(args[0])
var tpl *template.Template
var err error
if args[0] == "-" {
tpl, err = template.Parse(os.Stdin)
} else {
tpl, err = template.ParseFile(args[0])
}
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to parse template: %s", err))
return 1
+162
View File
@@ -0,0 +1,162 @@
package command
import (
"bytes"
"os"
"path/filepath"
"testing"
"github.com/mitchellh/packer/builder/file"
"github.com/mitchellh/packer/packer"
)
func TestBuildOnlyFileCommaFlags(t *testing.T) {
c := &BuildCommand{
Meta: testMetaFile(t),
}
args := []string{
"-only=chocolate,vanilla",
filepath.Join(testFixture("build-only"), "template.json"),
}
defer cleanup()
if code := c.Run(args); code != 0 {
fatalCommand(t, c.Meta)
}
if !fileExists("chocolate.txt") {
t.Error("Expected to find chocolate.txt")
}
if !fileExists("vanilla.txt") {
t.Error("Expected to find vanilla.txt")
}
if fileExists("cherry.txt") {
t.Error("Expected NOT to find cherry.txt")
}
}
func TestBuildStdin(t *testing.T) {
c := &BuildCommand{
Meta: testMetaFile(t),
}
f, err := os.Open(filepath.Join(testFixture("build-only"), "template.json"))
if err != nil {
t.Fatal(err)
}
defer f.Close()
stdin := os.Stdin
os.Stdin = f
defer func() { os.Stdin = stdin }()
defer cleanup()
if code := c.Run([]string{"-"}); code != 0 {
fatalCommand(t, c.Meta)
}
if !fileExists("chocolate.txt") {
t.Error("Expected to find chocolate.txt")
}
if !fileExists("vanilla.txt") {
t.Error("Expected to find vanilla.txt")
}
if !fileExists("cherry.txt") {
t.Error("Expected to find cherry.txt")
}
}
func TestBuildOnlyFileMultipleFlags(t *testing.T) {
c := &BuildCommand{
Meta: testMetaFile(t),
}
args := []string{
"-only=chocolate",
"-only=cherry",
filepath.Join(testFixture("build-only"), "template.json"),
}
defer cleanup()
if code := c.Run(args); code != 0 {
fatalCommand(t, c.Meta)
}
if !fileExists("chocolate.txt") {
t.Error("Expected to find chocolate.txt")
}
if fileExists("vanilla.txt") {
t.Error("Expected NOT to find vanilla.txt")
}
if !fileExists("cherry.txt") {
t.Error("Expected to find cherry.txt")
}
}
func TestBuildExceptFileCommaFlags(t *testing.T) {
c := &BuildCommand{
Meta: testMetaFile(t),
}
args := []string{
"-except=chocolate",
filepath.Join(testFixture("build-only"), "template.json"),
}
defer cleanup()
if code := c.Run(args); code != 0 {
fatalCommand(t, c.Meta)
}
if fileExists("chocolate.txt") {
t.Error("Expected NOT to find chocolate.txt")
}
if !fileExists("vanilla.txt") {
t.Error("Expected to find vanilla.txt")
}
if !fileExists("cherry.txt") {
t.Error("Expected to find cherry.txt")
}
}
// fileExists returns true if the filename is found
func fileExists(filename string) bool {
if _, err := os.Stat(filename); err == nil {
return true
}
return false
}
// testCoreConfigBuilder creates a packer CoreConfig that has a file builder
// available. This allows us to test a builder that writes files to disk.
func testCoreConfigBuilder(t *testing.T) *packer.CoreConfig {
components := packer.ComponentFinder{
Builder: func(n string) (packer.Builder, error) {
return &file.Builder{}, nil
},
}
return &packer.CoreConfig{
Components: components,
}
}
// testMetaFile creates a Meta object that includes a file builder
func testMetaFile(t *testing.T) Meta {
var out, err bytes.Buffer
return Meta{
CoreConfig: testCoreConfigBuilder(t),
Ui: &packer.BasicUi{
Writer: &out,
ErrorWriter: &err,
},
}
}
func cleanup() {
os.RemoveAll("chocolate.txt")
os.RemoveAll("vanilla.txt")
os.RemoveAll("cherry.txt")
}
+7
View File
@@ -20,6 +20,13 @@ func fatalCommand(t *testing.T, m Meta) {
err.String())
}
func outputCommand(t *testing.T, m Meta) (string, string) {
ui := m.Ui.(*packer.BasicUi)
out := ui.Writer.(*bytes.Buffer)
err := ui.ErrorWriter.(*bytes.Buffer)
return out.String(), err.String()
}
func testFixture(n string) string {
return filepath.Join(fixturesDir, n)
}
+1
View File
@@ -28,6 +28,7 @@ type Meta struct {
CoreConfig *packer.CoreConfig
Cache packer.Cache
Ui packer.Ui
Version string
// These are set by command-line flags
flagBuildExcept []string
-2
View File
@@ -122,10 +122,8 @@ func TestPush_noName(t *testing.T) {
func TestPush_cliName(t *testing.T) {
var actual []string
var actualOpts *uploadOpts
uploadFn := func(r io.Reader, opts *uploadOpts) (<-chan struct{}, <-chan error, error) {
actual = testArchive(t, r)
actualOpts = opts
doneCh := make(chan struct{})
close(doneCh)
@@ -0,0 +1,22 @@
{
"builders": [
{
"name":"chocolate",
"type":"file",
"content":"chocolate",
"target":"chocolate.txt"
},
{
"name":"vanilla",
"type":"file",
"content":"vanilla",
"target":"vanilla.txt"
},
{
"name":"cherry",
"type":"file",
"content":"cherry",
"target":"cherry.txt"
}
]
}
@@ -0,0 +1,10 @@
{
"builders":[
{
"type":"file",
"target":"chocolate.txt",
"content":"chocolate"
}
],
"min_packer_version":"101.0.0"
}
+44
View File
@@ -0,0 +1,44 @@
package command
import (
"path/filepath"
"testing"
)
func TestValidateCommandOKVersion(t *testing.T) {
c := &ValidateCommand{
Meta: testMetaFile(t),
}
args := []string{
filepath.Join(testFixture("validate"), "template.json"),
}
// This should pass with a valid configuration version
c.CoreConfig.Version = "102.0.0"
if code := c.Run(args); code != 0 {
fatalCommand(t, c.Meta)
}
}
func TestValidateCommandBadVersion(t *testing.T) {
c := &ValidateCommand{
Meta: testMetaFile(t),
}
args := []string{
filepath.Join(testFixture("validate"), "template.json"),
}
// This should fail with an invalid configuration version
c.CoreConfig.Version = "100.0.0"
if code := c.Run(args); code != 1 {
t.Errorf("Expected exit code 1")
}
stdout, stderr := outputCommand(t, c.Meta)
expected := `Error initializing core: This template requires Packer version 101.0.0 or higher; using 100.0.0
`
if stderr != expected {
t.Fatalf("Expected:\n%s\nFound:\n%s\n", expected, stderr)
}
t.Log(stdout)
}
+59 -4
View File
@@ -5,9 +5,6 @@ import (
"bytes"
"errors"
"fmt"
"github.com/mitchellh/packer/packer"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"io"
"io/ioutil"
"log"
@@ -16,8 +13,18 @@ import (
"path/filepath"
"strconv"
"sync"
"time"
"github.com/mitchellh/packer/packer"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
)
// ErrHandshakeTimeout is returned from New() whenever we're unable to establish
// an ssh connection within a certain timeframe. By default the handshake time-
// out period is 1 minute. You can change it with Config.HandshakeTimeout.
var ErrHandshakeTimeout = fmt.Errorf("Timeout during SSH handshake")
type comm struct {
client *ssh.Client
config *Config
@@ -37,6 +44,13 @@ type Config struct {
// Pty, if true, will request a pty from the remote end.
Pty bool
// DisableAgent, if true, will not forward the SSH agent.
DisableAgent bool
// HandshakeTimeout limits the amount of time we'll wait to handshake before
// saying the connection failed.
HandshakeTimeout time.Duration
}
// Creates a new packer.Communicator implementation over SSH. This takes
@@ -270,10 +284,46 @@ func (c *comm) reconnect() (err error) {
}
log.Printf("handshaking with SSH")
sshConn, sshChan, req, err := ssh.NewClientConn(c.conn, c.address, c.config.SSHConfig)
// Default timeout to 1 minute if it wasn't specified (zero value). For
// when you need to handshake from low orbit.
var duration time.Duration
if c.config.HandshakeTimeout == 0 {
duration = 1 * time.Minute
} else {
duration = c.config.HandshakeTimeout
}
connectionEstablished := make(chan struct{}, 1)
var sshConn ssh.Conn
var sshChan <-chan ssh.NewChannel
var req <-chan *ssh.Request
go func() {
sshConn, sshChan, req, err = ssh.NewClientConn(c.conn, c.address, c.config.SSHConfig)
close(connectionEstablished)
}()
select {
case <-connectionEstablished:
// We don't need to do anything here. We just want select to block until
// we connect or timeout.
case <-time.After(duration):
if c.conn != nil {
c.conn.Close()
}
if sshConn != nil {
sshConn.Close()
}
return ErrHandshakeTimeout
}
if err != nil {
log.Printf("handshake error: %s", err)
return
}
log.Printf("handshake complete!")
if sshConn != nil {
c.client = ssh.NewClient(sshConn, sshChan, req)
}
@@ -287,6 +337,11 @@ func (c *comm) connectToAgent() {
return
}
if c.config.DisableAgent {
log.Printf("[INFO] SSH agent forwarding is disabled.")
return
}
// open connection to the local agent
socketLocation := os.Getenv("SSH_AUTH_SOCK")
if socketLocation == "" {
+65 -7
View File
@@ -5,10 +5,12 @@ package ssh
import (
"bytes"
"fmt"
"github.com/mitchellh/packer/packer"
"golang.org/x/crypto/ssh"
"net"
"testing"
"time"
"github.com/mitchellh/packer/packer"
"golang.org/x/crypto/ssh"
)
// private key for mock server
@@ -94,6 +96,28 @@ func newMockLineServer(t *testing.T) string {
return l.Addr().String()
}
func newMockBrokenServer(t *testing.T) string {
l, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("Unable tp listen for connection: %s", err)
}
go func() {
defer l.Close()
c, err := l.Accept()
if err != nil {
t.Errorf("Unable to accept incoming connection: %s", err)
}
defer c.Close()
// This should block for a period of time longer than our timeout in
// the test case. That way we invoke a failure scenario.
t.Log("Block on handshaking for SSH connection")
time.Sleep(5 * time.Second)
}()
return l.Addr().String()
}
func TestCommIsCommunicator(t *testing.T) {
var raw interface{}
raw = &comm{}
@@ -157,10 +181,44 @@ func TestStart(t *testing.T) {
t.Fatalf("error connecting to SSH: %s", err)
}
var cmd packer.RemoteCmd
stdout := new(bytes.Buffer)
cmd.Command = "echo foo"
cmd.Stdout = stdout
cmd := &packer.RemoteCmd{
Command: "echo foo",
Stdout: new(bytes.Buffer),
}
client.Start(&cmd)
client.Start(cmd)
}
func TestHandshakeTimeout(t *testing.T) {
clientConfig := &ssh.ClientConfig{
User: "user",
Auth: []ssh.AuthMethod{
ssh.Password("pass"),
},
}
address := newMockBrokenServer(t)
conn := func() (net.Conn, error) {
conn, err := net.Dial("tcp", address)
if err != nil {
t.Fatalf("unable to dial to remote side: %s", err)
}
return conn, err
}
config := &Config{
Connection: conn,
SSHConfig: clientConfig,
HandshakeTimeout: 50 * time.Millisecond,
}
_, err := New(address, config)
if err != ErrHandshakeTimeout {
// Note: there's another error that can come back from this call:
// ssh: handshake failed: EOF
// This should appear in cases where the handshake fails because of
// malformed (or no) data sent back by the server, but should not happen
// in a timeout scenario.
t.Fatalf("Expected handshake timeout, got: %s", err)
}
}
+11 -2
View File
@@ -85,8 +85,17 @@ func (c *Communicator) Start(rc *packer.RemoteCmd) error {
func runCommand(shell *winrm.Shell, cmd *winrm.Command, rc *packer.RemoteCmd) {
defer shell.Close()
go io.Copy(rc.Stdout, cmd.Stdout)
go io.Copy(rc.Stderr, cmd.Stderr)
if rc.Stdout != nil && cmd.Stdout != nil {
go io.Copy(rc.Stdout, cmd.Stdout)
} else {
log.Printf("[WARN] Failed to read stdout for command '%s'", rc.Command)
}
if rc.Stderr != nil && cmd.Stderr != nil {
go io.Copy(rc.Stderr, cmd.Stderr)
} else {
log.Printf("[WARN] Failed to read stderr for command '%s'", rc.Command)
}
cmd.Wait()
+1
View File
@@ -22,6 +22,7 @@ type Config struct {
SSHPrivateKey string `mapstructure:"ssh_private_key_file"`
SSHPty bool `mapstructure:"ssh_pty"`
SSHTimeout time.Duration `mapstructure:"ssh_timeout"`
SSHDisableAgent bool `mapstructure:"ssh_disable_agent"`
SSHHandshakeAttempts int `mapstructure:"ssh_handshake_attempts"`
SSHBastionHost string `mapstructure:"ssh_bastion_host"`
SSHBastionPort int `mapstructure:"ssh_bastion_port"`
+4 -3
View File
@@ -158,9 +158,10 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru
// Then we attempt to connect via SSH
config := &ssh.Config{
Connection: connFunc,
SSHConfig: sshConfig,
Pty: s.Config.SSHPty,
Connection: connFunc,
SSHConfig: sshConfig,
Pty: s.Config.SSHPty,
DisableAgent: s.Config.SSHDisableAgent,
}
log.Println("[INFO] Attempting SSH connection...")
+2
View File
@@ -42,6 +42,8 @@ func Decode(target interface{}, config *DecodeOpts, raws ...interface{}) error {
if config.InterpolateContext == nil {
config.InterpolateContext = ctx
} else {
config.InterpolateContext.BuildName = ctx.BuildName
config.InterpolateContext.BuildType = ctx.BuildType
config.InterpolateContext.TemplatePath = ctx.TemplatePath
config.InterpolateContext.UserVariables = ctx.UserVariables
}
+30
View File
@@ -74,6 +74,36 @@ func TestDecode(t *testing.T) {
},
},
},
"build name": {
[]interface{}{
map[string]interface{}{
"name": "{{build_name}}",
},
map[string]interface{}{
"packer_build_name": "foo",
},
},
&Target{
Name: "foo",
},
nil,
},
"build type": {
[]interface{}{
map[string]interface{}{
"name": "{{build_type}}",
},
map[string]interface{}{
"packer_builder_type": "foo",
},
},
&Target{
Name: "foo",
},
nil,
},
}
for k, tc := range cases {
+1 -1
View File
@@ -11,6 +11,6 @@ func (s *StringFlag) String() string {
}
func (s *StringFlag) Set(value string) error {
*s = append(*s, value)
*s = append(*s, strings.Split(value, ",")...)
return nil
}
+17
View File
@@ -14,6 +14,8 @@ func TestStringFlag_implements(t *testing.T) {
}
}
// TestStringFlagSet tests for setting the same flag more than once on the CLI
// like: blah -flag foo -flag bar
func TestStringFlagSet(t *testing.T) {
sv := new(StringFlag)
err := sv.Set("foo")
@@ -31,3 +33,18 @@ func TestStringFlagSet(t *testing.T) {
t.Fatalf("Bad: %#v", sv)
}
}
// TestMultiStringFlag tests for setting the same flag using a comma-separated
// list of items like: blah -flag=foo,bar
func TestMultiStringFlag(t *testing.T) {
sv := new(StringFlag)
err := sv.Set("chocolate,vanilla")
if err != nil {
t.Fatalf("err :%s", err)
}
expected := []string{"chocolate", "vanilla"}
if !reflect.DeepEqual([]string(*sv), expected) {
t.Fatalf("Expected: %#v, found: %#v", expected, sv)
}
}
+1
View File
@@ -168,6 +168,7 @@ func wrappedMain() int {
PostProcessor: config.LoadPostProcessor,
Provisioner: config.LoadProvisioner,
},
Version: Version,
},
Cache: cache,
Ui: ui,
+26
View File
@@ -5,6 +5,7 @@ import (
"sort"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/go-version"
"github.com/mitchellh/packer/template"
"github.com/mitchellh/packer/template/interpolate"
)
@@ -17,6 +18,7 @@ type Core struct {
components ComponentFinder
variables map[string]string
builds map[string]*template.Builder
version string
}
// CoreConfig is the structure for initializing a new Core. Once a CoreConfig
@@ -25,6 +27,7 @@ type CoreConfig struct {
Components ComponentFinder
Template *template.Template
Variables map[string]string
Version string
}
// The function type used to lookup Builder implementations.
@@ -55,6 +58,7 @@ func NewCore(c *CoreConfig) (*Core, error) {
Template: c.Template,
components: c.Components,
variables: c.Variables,
version: c.Version,
}
if err := result.validate(); err != nil {
return nil, err
@@ -226,6 +230,28 @@ func (c *Core) validate() error {
return err
}
// Validate the minimum version is satisfied
if c.Template.MinVersion != "" {
versionActual, err := version.NewVersion(c.version)
if err != nil {
// This shouldn't happen since we set it via the compiler
panic(err)
}
versionMin, err := version.NewVersion(c.Template.MinVersion)
if err != nil {
return fmt.Errorf(
"min_version is invalid: %s", err)
}
if versionActual.LessThan(versionMin) {
return fmt.Errorf(
"This template requires Packer version %s or higher; using %s",
versionMin,
versionActual)
}
}
// Validate variables are set
var err error
for n, v := range c.Template.Variables {
+14
View File
@@ -484,6 +484,19 @@ func TestCoreValidate(t *testing.T) {
map[string]string{"foo": "bar"},
false,
},
// Min version good
{
"validate-min-version.json",
map[string]string{"foo": "bar"},
false,
},
{
"validate-min-version-high.json",
map[string]string{"foo": "bar"},
true,
},
}
for _, tc := range cases {
@@ -501,6 +514,7 @@ func TestCoreValidate(t *testing.T) {
_, err = NewCore(&CoreConfig{
Template: tpl,
Variables: tc.Vars,
Version: "1.0.0",
})
if (err != nil) != tc.Err {
t.Fatalf("err: %s\n\n%s", tc.File, err)
@@ -0,0 +1,7 @@
{
"min_packer_version": "2.1.0",
"builders": [
{"type": "foo"}
]
}
@@ -0,0 +1,7 @@
{
"min_packer_version": "0.1.0",
"builders": [
{"type": "foo"}
]
}
+13 -14
View File
@@ -19,6 +19,18 @@ import (
"github.com/pierrec/lz4"
)
var (
// ErrInvalidCompressionLevel is returned when the compression level passed
// to gzip is not in the expected range. See compress/flate for details.
ErrInvalidCompressionLevel = fmt.Errorf(
"Invalid compression level. Expected an integer from -1 to 9.")
ErrWrongInputCount = fmt.Errorf(
"Can only have 1 input file when not using tar/zip")
filenamePattern = regexp.MustCompile(`(?:\.([a-z0-9]+))`)
)
type Config struct {
common.PackerConfig `mapstructure:",squash"`
@@ -35,21 +47,9 @@ type Config struct {
}
type PostProcessor struct {
config *Config
config Config
}
var (
// ErrInvalidCompressionLevel is returned when the compression level passed
// to gzip is not in the expected range. See compress/flate for details.
ErrInvalidCompressionLevel = fmt.Errorf(
"Invalid compression level. Expected an integer from -1 to 9.")
ErrWrongInputCount = fmt.Errorf(
"Can only have 1 input file when not using tar/zip")
filenamePattern = regexp.MustCompile(`(?:\.([a-z0-9]+))`)
)
func (p *PostProcessor) Configure(raws ...interface{}) error {
err := config.Decode(&p.config, &config.DecodeOpts{
Interpolate: true,
@@ -109,7 +109,6 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
}
return nil
}
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
@@ -9,7 +9,6 @@ import (
"testing"
"github.com/mitchellh/packer/builder/file"
env "github.com/mitchellh/packer/helper/builder/testing"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/template"
)
@@ -187,11 +186,6 @@ func setup(t *testing.T) (packer.Ui, packer.Artifact, error) {
}
func testArchive(t *testing.T, config string) packer.Artifact {
if os.Getenv(env.TestEnvVar) == "" {
t.Skip(fmt.Sprintf(
"Acceptance tests skipped unless env '%s' set", env.TestEnvVar))
}
ui, artifact, err := setup(t)
if err != nil {
t.Fatalf("Error bootstrapping test: %s", err)
+51 -10
View File
@@ -187,14 +187,20 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
}
err = p.executeChef(ui, comm, configPath, jsonPath)
knifeConfigPath, err2 := p.createKnifeConfig(
ui, comm, nodeName, serverUrl, p.config.ClientKey, p.config.SslVerifyMode)
if err2 != nil {
return fmt.Errorf("Error creating knife config on node: %s", err2)
}
if !p.config.SkipCleanNode {
if err2 := p.cleanNode(ui, comm, nodeName); err2 != nil {
if err2 := p.cleanNode(ui, comm, nodeName, knifeConfigPath); err2 != nil {
return fmt.Errorf("Error cleaning up chef node: %s", err2)
}
}
if !p.config.SkipCleanClient {
if err2 := p.cleanClient(ui, comm, nodeName); err2 != nil {
if err2 := p.cleanClient(ui, comm, nodeName, knifeConfigPath); err2 != nil {
return fmt.Errorf("Error cleaning up chef client: %s", err2)
}
}
@@ -273,6 +279,32 @@ func (p *Provisioner) createConfig(ui packer.Ui, comm packer.Communicator, nodeN
return remotePath, nil
}
func (p *Provisioner) createKnifeConfig(ui packer.Ui, comm packer.Communicator, nodeName string, serverUrl string, clientKey string, sslVerifyMode string) (string, error) {
ui.Message("Creating configuration file 'knife.rb'")
// Read the template
tpl := DefaultKnifeTemplate
ctx := p.config.ctx
ctx.Data = &ConfigTemplate{
NodeName: nodeName,
ServerUrl: serverUrl,
ClientKey: clientKey,
SslVerifyMode: sslVerifyMode,
}
configString, err := interpolate.Render(tpl, &ctx)
if err != nil {
return "", err
}
remotePath := filepath.ToSlash(filepath.Join(p.config.StagingDir, "knife.rb"))
if err := comm.Upload(remotePath, bytes.NewReader([]byte(configString)), nil); err != nil {
return "", err
}
return remotePath, nil
}
func (p *Provisioner) createJson(ui packer.Ui, comm packer.Communicator) (string, error) {
ui.Message("Creating JSON attribute file")
@@ -334,32 +366,30 @@ func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir stri
return nil
}
func (p *Provisioner) cleanNode(ui packer.Ui, comm packer.Communicator, node string) error {
func (p *Provisioner) cleanNode(ui packer.Ui, comm packer.Communicator, node string, knifeConfigPath string) error {
ui.Say("Cleaning up chef node...")
args := []string{"node", "delete", node}
if err := p.knifeExec(ui, comm, node, args); err != nil {
if err := p.knifeExec(ui, comm, node, knifeConfigPath, args); err != nil {
return fmt.Errorf("Failed to cleanup node: %s", err)
}
return nil
}
func (p *Provisioner) cleanClient(ui packer.Ui, comm packer.Communicator, node string) error {
func (p *Provisioner) cleanClient(ui packer.Ui, comm packer.Communicator, node string, knifeConfigPath string) error {
ui.Say("Cleaning up chef client...")
args := []string{"client", "delete", node}
if err := p.knifeExec(ui, comm, node, args); err != nil {
if err := p.knifeExec(ui, comm, node, knifeConfigPath, args); err != nil {
return fmt.Errorf("Failed to cleanup client: %s", err)
}
return nil
}
func (p *Provisioner) knifeExec(ui packer.Ui, comm packer.Communicator, node string, args []string) error {
func (p *Provisioner) knifeExec(ui packer.Ui, comm packer.Communicator, node string, knifeConfigPath string, args []string) error {
flags := []string{
"-y",
"-s", fmt.Sprintf("'%s'", p.config.ServerUrl),
"-k", fmt.Sprintf("'%s'", p.config.ClientKey),
"-u", fmt.Sprintf("'%s'", node),
"-c", knifeConfigPath,
}
cmdText := fmt.Sprintf(
@@ -573,3 +603,14 @@ environment "{{.ChefEnvironment}}"
ssl_verify_mode :{{.SslVerifyMode}}
{{end}}
`
var DefaultKnifeTemplate = `
log_level :info
log_location STDOUT
chef_server_url "{{.ServerUrl}}"
client_key "{{.ClientKey}}"
node_name "{{.NodeName}}"
{{if ne .SslVerifyMode ""}}
ssl_verify_mode :{{.SslVerifyMode}}
{{end}}
`
+32 -17
View File
@@ -270,28 +270,43 @@ func (p *Provisioner) uploadManifests(ui packer.Ui, comm packer.Communicator) (s
return "", fmt.Errorf("Error creating manifests directory: %s", err)
}
// Upload the main manifest
f, err := os.Open(p.config.ManifestFile)
// NOTE! manifest_file may either be a directory or a file, as puppet apply
// now accepts either one.
fi, err := os.Stat(p.config.ManifestFile)
if err != nil {
return "", err
}
defer f.Close()
manifestFilename := p.config.ManifestFile
if fi, err := os.Stat(p.config.ManifestFile); err != nil {
return "", fmt.Errorf("Error inspecting manifest file: %s", err)
} else if !fi.IsDir() {
manifestFilename = filepath.Base(manifestFilename)
}
if fi.IsDir() {
// If manifest_file is a directory we'll upload the whole thing
ui.Message(fmt.Sprintf(
"Uploading manifest directory from: %s", p.config.ManifestFile))
remoteManifestDir := fmt.Sprintf("%s/manifests", p.config.StagingDir)
err := p.uploadDirectory(ui, comm, remoteManifestDir, p.config.ManifestFile)
if err != nil {
return "", fmt.Errorf("Error uploading manifest dir: %s", err)
}
return remoteManifestDir, nil
} else {
ui.Say("WARNING: manifest_file should be a file. Use manifest_dir for directories")
}
// Otherwise manifest_file is a file and we'll upload it
ui.Message(fmt.Sprintf(
"Uploading manifest file from: %s", p.config.ManifestFile))
remoteManifestFile := fmt.Sprintf("%s/%s", remoteManifestsPath, manifestFilename)
if err := comm.Upload(remoteManifestFile, f, nil); err != nil {
return "", err
}
f, err := os.Open(p.config.ManifestFile)
if err != nil {
return "", err
}
defer f.Close()
return remoteManifestFile, nil
manifestFilename := filepath.Base(p.config.ManifestFile)
remoteManifestFile := fmt.Sprintf("%s/%s", remoteManifestsPath, manifestFilename)
if err := comm.Upload(remoteManifestFile, f, nil); err != nil {
return "", err
}
return remoteManifestFile, nil
}
}
func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir string) error {
+1 -1
View File
@@ -71,7 +71,7 @@ func funcGenBuildName(ctx *Context) interface{} {
func funcGenBuildType(ctx *Context) interface{} {
return func() (string, error) {
if ctx == nil || ctx.BuildType == "" {
return "", errors.New("build_name not available")
return "", errors.New("build_type not available")
}
return ctx.BuildType, nil
+1 -1
View File
@@ -4,7 +4,7 @@ package main
var GitCommit string
// The main version number that is being run at the moment.
const Version = "0.8.0"
const Version = "0.8.2"
// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
+31 -29
View File
@@ -1,6 +1,6 @@
GIT
remote: git://github.com/hashicorp/middleman-hashicorp.git
revision: 7796ba44d303ac8e1b566e855e2766e6d0f695fc
revision: 76f0f284ad44cea0457484ea83467192f02daf87
specs:
middleman-hashicorp (0.1.0)
bootstrap-sass (~> 3.3)
@@ -11,6 +11,7 @@ GIT
middleman-minify-html (~> 3.4)
middleman-syntax (~> 2.0)
rack-contrib (~> 1.2)
rack-protection (~> 1.5)
rack-rewrite (~> 1.5)
rack-ssl-enforcer (~> 0.2)
redcarpet (~> 3.2)
@@ -20,18 +21,18 @@ GIT
GEM
remote: https://rubygems.org/
specs:
activesupport (4.1.10)
activesupport (4.1.12)
i18n (~> 0.6, >= 0.6.9)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.1)
tzinfo (~> 1.1)
autoprefixer-rails (5.1.11)
autoprefixer-rails (5.2.1)
execjs
json
bootstrap-sass (3.3.4.1)
bootstrap-sass (3.3.5.1)
autoprefixer-rails (>= 5.0.0.1)
sass (>= 3.2.19)
sass (>= 3.3.0)
builder (3.2.2)
celluloid (0.16.0)
timers (~> 4.0.0)
@@ -53,29 +54,30 @@ GEM
sass (>= 3.3.0, < 3.5)
compass-import-once (1.0.5)
sass (>= 3.2, < 3.5)
daemons (1.2.2)
daemons (1.2.3)
em-websocket (0.5.1)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
erubis (2.7.0)
eventmachine (1.0.7)
execjs (2.5.2)
ffi (1.9.8)
ffi (1.9.10)
git-version-bump (0.15.1)
haml (4.0.6)
tilt
hike (1.2.3)
hitimes (1.2.2)
hooks (0.4.0)
uber (~> 0.0.4)
htmlcompressor (0.1.2)
htmlcompressor (0.2.0)
http_parser.rb (0.6.0)
i18n (0.7.0)
json (1.8.2)
kramdown (1.7.0)
json (1.8.3)
kramdown (1.8.0)
less (2.6.0)
commonjs (~> 0.2.7)
libv8 (3.16.14.7)
listen (2.10.0)
libv8 (3.16.14.11)
listen (2.10.1)
celluloid (~> 0.16.0)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
@@ -106,8 +108,8 @@ GEM
em-websocket (~> 0.5.1)
middleman-core (>= 3.3)
rack-livereload (~> 0.3.15)
middleman-minify-html (3.4.0)
htmlcompressor (~> 0.1.0)
middleman-minify-html (3.4.1)
htmlcompressor (~> 0.2.0)
middleman-core (>= 3.2)
middleman-sprockets (3.4.2)
middleman-core (>= 3.3)
@@ -117,31 +119,34 @@ GEM
middleman-syntax (2.0.0)
middleman-core (~> 3.2)
rouge (~> 1.0)
minitest (5.6.1)
multi_json (1.11.0)
minitest (5.7.0)
multi_json (1.11.2)
padrino-helpers (0.12.5)
i18n (~> 0.6, >= 0.6.7)
padrino-support (= 0.12.5)
tilt (~> 1.4.1)
padrino-support (0.12.5)
activesupport (>= 3.1)
rack (1.6.1)
rack-contrib (1.2.0)
rack (>= 0.9.1)
rack-livereload (0.3.15)
rack (1.6.4)
rack-contrib (1.3.0)
git-version-bump (~> 0.15)
rack (~> 1.4)
rack-livereload (0.3.16)
rack
rack-protection (1.5.3)
rack
rack-rewrite (1.5.1)
rack-ssl-enforcer (0.2.8)
rack-test (0.6.3)
rack (>= 1.0)
rb-fsevent (0.9.4)
rb-fsevent (0.9.5)
rb-inotify (0.9.5)
ffi (>= 0.5.0)
redcarpet (3.2.3)
ref (1.0.5)
rouge (1.8.0)
sass (3.4.13)
sprockets (2.12.3)
redcarpet (3.3.2)
ref (2.0.0)
rouge (1.9.1)
sass (3.4.16)
sprockets (2.12.4)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
@@ -175,6 +180,3 @@ PLATFORMS
DEPENDENCIES
middleman-hashicorp!
BUNDLED WITH
1.10.2
+10
View File
@@ -0,0 +1,10 @@
all: build
init:
bundle
dev: init
PACKER_DISABLE_DOWNLOAD_FETCH=true PACKER_VERSION=1.0 bundle exec middleman server
build: init
PACKER_DISABLE_DOWNLOAD_FETCH=true PACKER_VERSION=1.0 bundle exec middleman build
+1 -2
View File
@@ -16,8 +16,7 @@ Running the site locally is simple. Clone this repo and run the following
commands:
```
$ bundle
$ PACKER_DISABLE_DOWNLOAD_FETCH=true PACKER_VERSION=1.0 bundle exec middleman server
make dev
```
Then open up `localhost:4567`. Note that some URLs you may need to append
+11
View File
@@ -3,6 +3,17 @@ require "rack/contrib/not_found"
require "rack/contrib/response_headers"
require "rack/contrib/static_cache"
require "rack/contrib/try_static"
require "rack/protection"
# Protect against various bad things
use Rack::Protection::JsonCsrf
use Rack::Protection::RemoteReferrer
use Rack::Protection::HttpOrigin
use Rack::Protection::EscapedParams
use Rack::Protection::XSSHeader
use Rack::Protection::FrameOptions
use Rack::Protection::PathTraversal
use Rack::Protection::IPSpoofing
# Properly compress the output if the client can handle it.
use Rack::Deflater
@@ -321,6 +321,10 @@ header .header {
.person {
margin-bottom: 30px;
img {
width: 125px;
}
h3 {
text-transform: none;
}
@@ -51,6 +51,10 @@ There are many configuration options available for the builder. They are
segmented below into two categories: required and optional parameters. Within
each category, the available configuration keys are alphabetized.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `access_key` (string) - The access key used to communicate with AWS.
@@ -124,7 +128,7 @@ each category, the available configuration keys are alphabetized.
* `enhanced_networking` (boolean) - Enable enhanced networking (SriovNetSupport) on
HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your AWS IAM policy.
* `force_deregister` (boolean)  Force Packer to first deregister an existing
* `force_deregister` (boolean) - Force Packer to first deregister an existing
AMI if one with the same name already exists. Default `false`.
* `mount_path` (string) - The path where the volume will be mounted. This is
@@ -133,13 +137,13 @@ AMI if one with the same name already exists. Default `false`.
template where the `.Device` variable is replaced with the name of the
device where the volume is attached.
* `mount_options` (array of strings)  Options to supply the `mount` command
* `mount_options` (array of strings) - 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
discrestion is advised. See [this manual page for the mount command][1] for valid
file system specific options
* `root_volume_size` (integer)  The size of the root volume for the chroot
* `root_volume_size` (integer) - The size of the root volume for the chroot
environment, and the resulting AMI
* `tags` (object of key/value strings) - Tags applied to the AMI.
@@ -31,6 +31,10 @@ There are many configuration options available for the builder. They are
segmented below into two categories: required and optional parameters. Within
each category, the available configuration keys are alphabetized.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `access_key` (string) - The access key used to communicate with AWS.
@@ -63,22 +67,22 @@ each category, the available configuration keys are alphabetized.
* `ami_block_device_mappings` (array of block device mappings) - Add the block
device mappings to the AMI. The block device mappings allow for keys:
- `device_name` (string)  The device name exposed to the instance (for
- `device_name` (string) - The device name exposed to the instance (for
example, "/dev/sdh" or "xvdh")
- `virtual_name` (string) The virtual device name. See the documentation on
- `virtual_name` (string) - The virtual device name. See the documentation on
[Block Device Mapping][1] for more information
- `snapshot_id` (string)  The ID of the snapshot
- `volume_type` (string)  The volume type. gp2 for General Purpose (SSD)
- `snapshot_id` (string) - The ID of the snapshot
- `volume_type` (string) - The volume type. gp2 for General Purpose (SSD)
volumes, io1 for Provisioned IOPS (SSD) volumes, and standard for Magnetic
volumes
- `volume_size` (integer)  The size of the volume, in GiB. Required if not
- `volume_size` (integer) - The size of the volume, in GiB. Required if not
specifying a `snapshot_id`
- `delete_on_termination` (boolean)  Indicates whether the EBS volume is
- `delete_on_termination` (boolean) - Indicates whether the EBS volume is
deleted on instance termination
- `encrypted` (boolean) Indicates whether to encrypt the volume or not
- `no_device` (boolean) Suppresses the specified device included in the
- `encrypted` (boolean) - Indicates whether to encrypt the volume or not
- `no_device` (boolean) - Suppresses the specified device included in the
block device mapping of the AMI
- `iops` (integer) The number of I/O operations per second (IOPS) that the
- `iops` (integer) - The number of I/O operations per second (IOPS) that the
volume supports. See the documentation on [IOPs][2] for more information
@@ -112,7 +116,7 @@ each category, the available configuration keys are alphabetized.
* `enhanced_networking` (boolean) - Enable enhanced networking (SriovNetSupport) on
HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your AWS IAM policy.
* `force_deregister` (boolean)  Force Packer to first deregister an existing
* `force_deregister` (boolean) - Force Packer to first deregister an existing
AMI if one with the same name already exists. Default `false`.
* `iam_instance_profile` (string) - The name of an
@@ -154,20 +158,9 @@ AMI if one with the same name already exists. Default `false`.
generate a temporary keypair. `ssh_private_key_file` must be specified
with this.
* `ssh_port` (integer) - The port that SSH will be available on. This defaults
to port 22.
* `ssh_private_key_file` (string) - Use this ssh private key file instead of
a generated ssh key pair for connecting to the instance. This key file must
already exist on the `source_ami`
* `ssh_private_ip` (bool) - If true, then SSH will always use the private
* `ssh_private_ip` (boolean) - If true, then SSH will always use the private
IP if available.
* `ssh_timeout` (string) - The time to wait for SSH to become available
before timing out. The format of this value is a duration such as "5s"
or "5m". The default SSH timeout is "5m", or five minutes.
* `subnet_id` (string) - If using VPC, the ID of the subnet, such as
"subnet-12345def", where Packer will launch the EC2 instance. This field is
required if you are using an non-default VPC.
@@ -279,11 +272,11 @@ Here is an example using the optional AMI tags. This will add the tags
```
-> **Note:** Packer uses pre-built AMIs as the source for building images.
These source AMIs may include volumes that are not flagged to be destroyed on
These source AMIs may include volumes that are not flagged to be destroyed on
termiation of the instance building the new image. Packer will attempt to clean
up all residual volumes that are not designated by the user to remain after
termination. If you need to preserve those source volumes, you can overwrite the
termination setting by specifying `delete_on_termination=false` in the
termination setting by specifying `delete_on_termination=false` in the
`launch_device_mappings` block for the device.
[1]: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_BlockDeviceMapping.html
@@ -36,6 +36,10 @@ There are many configuration options available for the builder. They are
segmented below into two categories: required and optional parameters. Within
each category, the available configuration keys are alphabetized.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `access_key` (string) - The access key used to communicate with AWS.
@@ -83,22 +87,22 @@ each category, the available configuration keys are alphabetized.
* `ami_block_device_mappings` (array of block device mappings) - Add the block
device mappings to the AMI. The block device mappings allow for keys:
- `device_name` (string)  The device name exposed to the instance (for
- `device_name` (string) - The device name exposed to the instance (for
example, "/dev/sdh" or "xvdh")
- `virtual_name` (string) The virtual device name. See the documentation on
- `virtual_name` (string) - The virtual device name. See the documentation on
[Block Device Mapping][1] for more information
- `snapshot_id` (string)  The ID of the snapshot
- `volume_type` (string)  The volume type. gp2 for General Purpose (SSD)
- `snapshot_id` (string) - The ID of the snapshot
- `volume_type` (string) - The volume type. gp2 for General Purpose (SSD)
volumes, io1 for Provisioned IOPS (SSD) volumes, and standard for Magnetic
volumes
- `volume_size` (integer)  The size of the volume, in GiB. Required if not
- `volume_size` (integer) - The size of the volume, in GiB. Required if not
specifying a `snapshot_id`
- `delete_on_termination` (boolean)  Indicates whether the EBS volume is
- `delete_on_termination` (boolean) - Indicates whether the EBS volume is
deleted on instance termination
- `encrypted` (boolean) Indicates whether to encrypt the volume or not
- `no_device` (boolean) Suppresses the specified device included in the
- `encrypted` (boolean) - Indicates whether to encrypt the volume or not
- `no_device` (boolean) - Suppresses the specified device included in the
block device mapping of the AMI
- `iops` (integer) The number of I/O operations per second (IOPS) that the
- `iops` (integer) - The number of I/O operations per second (IOPS) that the
volume supports. See the documentation on [IOPs][2] for more information
* `ami_description` (string) - The description to set for the resulting
@@ -151,7 +155,7 @@ each category, the available configuration keys are alphabetized.
* `enhanced_networking` (boolean) - Enable enhanced networking (SriovNetSupport) on
HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your AWS IAM policy.
* `force_deregister` (boolean)  Force Packer to first deregister an existing
* `force_deregister` (boolean) - Force Packer to first deregister an existing
AMI if one with the same name already exists. Default `false`.
* `iam_instance_profile` (string) - The name of an
@@ -193,20 +197,9 @@ AMI if one with the same name already exists. Default `false`.
generate a temporary keypair. `ssh_private_key_file` must be specified
with this.
* `ssh_port` (integer) - The port that SSH will be available on. This defaults
to port 22.
* `ssh_private_key_file` (string) - Use this ssh private key file instead of
a generated ssh key pair for connecting to the instance. This key file must
already exist on the `source_ami`
* `ssh_private_ip` (bool) - If true, then SSH will always use the private
* `ssh_private_ip` (boolean) - If true, then SSH will always use the private
IP if available.
* `ssh_timeout` (string) - The time to wait for SSH to become available
before timing out. The format of this value is a duration such as "5s"
or "5m". The default SSH timeout is "5m", or five minutes.
* `subnet_id` (string) - If using VPC, the ID of the subnet, such as
"subnet-12345def", where Packer will launch the EC2 instance. This field is
required if you are using an non-default VPC.
@@ -24,6 +24,10 @@ There are many configuration options available for the builder. They are
segmented below into two categories: required and optional parameters. Within
each category, the available configuration keys are alphabetized.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `api_token` (string) - The client TOKEN to use to access your account.
@@ -53,16 +57,6 @@ each category, the available configuration keys are alphabetized.
To help make this unique, use a function like `timestamp` (see
[configuration templates](/docs/templates/configuration-templates.html) for more info)
* `ssh_port` (integer) - The port that SSH will be available on. Defaults to port
22.
* `ssh_timeout` (string) - The time to wait for SSH to become available
before timing out. The format of this value is a duration such as "5s"
or "5m". The default SSH timeout is "1m".
* `ssh_username` (string) - The username to use in order to communicate
over SSH to the running droplet. Default is "root".
* `state_timeout` (string) - The time to wait, as a duration string,
for a droplet to enter a desired state (such as "active") before
timing out. The default state timeout is "6m".
@@ -62,6 +62,10 @@ Configuration options are organized below into two categories: required and
optional. Within each category, the available options are alphabetized and
described.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `commit` (boolean) - If true, the container will be committed to an
@@ -113,7 +117,10 @@ _exported_. More specifically, if you set `export_path` in your configuration.
If you set `commit`, see the next section.
The example below shows a full configuration that would import and push
the created image:
the created image. This is accomplished using a sequence definition (a
collection of post-processors that are treated as as single pipeline, see
[Post-Processors](/docs/templates/post-processors.html)
for more information):
```javascript
{
@@ -130,6 +137,12 @@ the created image:
}
```
In the above example, the result of each builder is passed through the defined
sequence of post-processors starting first with the `docker-import`
post-processor which will import the artifact as a docker image. The resulting
docker image is then passed on to the `docker-push` post-processor which handles
pushing the image to a container repository.
If you want to do this manually, however, perhaps from a script, you can
import the image using the process below:
@@ -142,9 +155,12 @@ and `docker push`, respectively.
## Using the Artifact: Committed
If you committed your container to an image, you probably want to tag,
save, push, etc. Packer can do this automatically for you. An example is
shown below which tags and pushes the image:
If you committed your container to an image, you probably want to tag, save,
push, etc. Packer can do this automatically for you. An example is shown below
which tags and pushes an image. This is accomplished using a sequence
definition (a collection of post-processors that are treated as as single
pipeline, see [Post-Processors](/docs/templates/post-processors.html) for more
information):
```javascript
{
@@ -161,6 +177,39 @@ shown below which tags and pushes the image:
}
```
In the above example, the result of each builder is passed through the defined
sequence of post-processors starting first with the `docker-tag` post-processor
which tags the committed image with the supplied repository and tag information.
Once tagged, the resulting artifact is then passed on to the `docker-push`
post-processor which handles pushing the image to a container repository.
Going a step further, if you wanted to tag and push an image to multiple
container repositories, this could be accomplished by defining two,
nearly-identical sequence definitions, as demonstrated by the example below:
```javascript
{
"post-processors": [
[
{
"type": "docker-tag",
"repository": "mitchellh/packer",
"tag": "0.7"
},
"docker-push"
],
[
{
"type": "docker-tag",
"repository": "hashicorp/packer",
"tag": "0.7"
},
"docker-push"
]
]
}
```
## Dockerfiles
This builder allows you to build Docker images _without_ Dockerfiles.
@@ -15,7 +15,7 @@ Compute Engine doesn't allow the creation of images from scratch.
## Authentication
Authenticating with Google Cloud services requires at most one JSON file,
Authenticating with Google Cloud services requires at most one JSON file,
called the _account file_. The _account file_ is **not** required if you are running
the `googlecompute` Packer builder from a GCE instance with a properly-configured
[Compute Engine Service Account](https://cloud.google.com/compute/docs/authentication).
@@ -23,7 +23,7 @@ the `googlecompute` Packer builder from a GCE instance with a properly-configure
### Running With a Compute Engine Service Account
If you run the `googlecompute` Packer builder from a GCE instance, you can configure that
instance to use a [Compute Engine Service Account](https://cloud.google.com/compute/docs/authentication). This will allow Packer to authenticate
to Google Cloud without having to bake in a separate credential/authentication file.
to Google Cloud without having to bake in a separate credential/authentication file.
To create a GCE instance that uses a service account, provide the required scopes when
launching the instance.
@@ -85,6 +85,10 @@ existing GCE image. The account file is obtained in the previous section.
Configuration options are organized below into two categories: required and optional. Within
each category, the available options are alphabetized and described.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `project_id` (string) - The project ID that will be used to launch instances
@@ -120,13 +124,6 @@ each category, the available options are alphabetized and described.
* `network` (string) - The Google Compute network to use for the launched
instance. Defaults to `"default"`.
* `ssh_port` (integer) - The SSH port. Defaults to `22`.
* `ssh_timeout` (string) - The time to wait for SSH to become available.
Defaults to `"1m"`.
* `ssh_username` (string) - The SSH username. Defaults to `"root"`.
* `state_timeout` (string) - The time to wait for instance state changes.
Defaults to `"5m"`.
@@ -20,8 +20,8 @@ no provisioners are defined, but it will connect to the specified host via ssh.
```javascript
{
"type": "null",
"host": "127.0.0.1",
"type": "null",
"ssh_host": "127.0.0.1",
"ssh_username": "foo",
"ssh_password": "bar"
}
@@ -29,23 +29,6 @@ no provisioners are defined, but it will connect to the specified host via ssh.
## Configuration Reference
Configuration options are organized into two categories: required and
optional. Within each category, the available options are alphabetized and
described.
### Required:
* `host` (string) - The hostname or IP address to connect to.
* `ssh_password` (string) - The password to be used for the ssh connection.
Cannot be combined with ssh_private_key_file.
* `ssh_private_key_file` (string) - The filename of the ssh private key to be
used for the ssh connection. E.g. /home/user/.ssh/identity_rsa.
* `ssh_username` (string) - The username to be used for the ssh connection.
### Optional:
* `port` (integer) - ssh port to connect to, defaults to 22.
The null builder has no configuration parameters other than the
[communicator](/docs/templates/communicator.html) settings.
@@ -27,6 +27,10 @@ There are many configuration options available for the builder. They are
segmented below into two categories: required and optional parameters. Within
each category, the available configuration keys are alphabetized.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `flavor` (string) - The ID, name, or full URL for the desired flavor for the
@@ -82,16 +86,6 @@ each category, the available configuration keys are alphabetized.
If not specified, Packer will use the environment variable
`OS_REGION_NAME`, if set.
* `ssh_port` (integer) - The port that SSH will be available on. Defaults to port
22.
* `ssh_timeout` (string) - The time to wait for SSH to become available
before timing out. The format of this value is a duration such as "5s"
or "1m". The default SSH timeout is "5m".
* `ssh_username` (string) - The username to use in order to communicate
over SSH to the running server. The default is "root".
* `ssh_interface` (string) - The type of interface to connect via SSH. Values
useful for Rackspace are "public" or "private", and the default behavior is
to connect via whichever is returned first from the OpenStack API.
@@ -50,6 +50,10 @@ There are many configuration options available for the Parallels builder.
They are organized below into two categories: required and optional. Within
each category, the available options are alphabetized and described.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO
@@ -190,21 +194,6 @@ each category, the available options are alphabetized and described.
If it doesn't shut down in this time, it is an error. By default, the timeout
is "5m", or five minutes.
* `ssh_key_path` (string) - Path to a private key to use for authenticating
with SSH. By default this is not set (key-based auth won't be used).
The associated public key is expected to already be configured on the
VM being prepared by some other process (kickstart, etc.).
* `ssh_password` (string) - The password for `ssh_username` to use to
authenticate with SSH. By default this is the empty string.
* `ssh_port` (integer) - The port that SSH will be listening on in the guest
virtual machine. By default this is 22.
* `ssh_wait_timeout` (string) - The duration to wait for SSH to become
available. By default this is "20m", or 20 minutes. Note that this should
be quite long since the timer begins as soon as the virtual machine is booted.
* `vm_name` (string) - This is the name of the PVM directory for the new
virtual machine, without the file extension. By default this is
"packer-BUILDNAME", where "BUILDNAME" is the name of the build.
@@ -46,6 +46,10 @@ There are many configuration options available for the Parallels builder.
They are organized below into two categories: required and optional. Within
each category, the available options are alphabetized and described.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `source_path` (string) - The path to a PVM directory that acts as
@@ -133,21 +137,6 @@ each category, the available options are alphabetized and described.
If it doesn't shut down in this time, it is an error. By default, the timeout
is "5m", or five minutes.
* `ssh_key_path` (string) - Path to a private key to use for authenticating
with SSH. By default this is not set (key-based auth won't be used).
The associated public key is expected to already be configured on the
VM being prepared by some other process (kickstart, etc.).
* `ssh_password` (string) - The password for `ssh_username` to use to
authenticate with SSH. By default this is the empty string.
* `ssh_port` (integer) - The port that SSH will be listening on in the guest
virtual machine. By default this is 22.
* `ssh_wait_timeout` (string) - The duration to wait for SSH to become
available. By default this is "20m", or 20 minutes. Note that this should
be quite long since the timer begins as soon as the virtual machine is booted.
* `vm_name` (string) - This is the name of the virtual machine when it is
imported as well as the name of the PVM directory when the virtual machine is
exported. By default this is "packer-BUILDNAME", where "BUILDNAME" is
+13 -26
View File
@@ -73,6 +73,10 @@ There are many configuration options available for the Qemu builder.
They are organized below into two categories: required and optional. Within
each category, the available options are alphabetized and described.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO
@@ -112,11 +116,11 @@ each category, the available options are alphabetized and described.
the default is 10 seconds.
* `disk_cache` (string) - The cache mode to use for disk. Allowed values
values include any of "writethrough", "writeback", "none", "unsafe" or
"directsync".
include any of "writethrough", "writeback", "none", "unsafe" or
"directsync". By default, this is set to "writeback".
* `disk_discard` (string) - The discard mode to use for disk. Allowed values
include any of "unmap" or "ignore".
include any of "unmap" or "ignore". By default, this is set to "ignore".
* `disk_image` (boolean) - Packer defaults to building from an ISO file,
this parameter controls whether the ISO URL supplied is actually a bootable
@@ -144,7 +148,7 @@ each category, the available options are alphabetized and described.
* `format` (string) - Either "qcow2" or "raw", this specifies the output
format of the virtual machine image. This defaults to "qcow2".
* `headless` (boolean) - Packer defaults to building virtual machines by
* `headless` (boolean) - Packer defaults to building QEMU virtual machines by
launching a GUI that shows the console of the machine being built.
When this value is set to true, the machine will start without a console.
@@ -184,6 +188,11 @@ each category, the available options are alphabetized and described.
By default this is "output-BUILDNAME" where "BUILDNAME" is the name
of the build.
* `qemu_binary` (string) - The name of the Qemu binary to look for. This
defaults to "qemu-system-x86_64", but may need to be changed for some
platforms. For example "qemu-kvm", or "qemu-system-i386" may be a better
choice for some systems.
* `qemuargs` (array of array of strings) - Allows complete control over
the qemu command line (though not, at this time, qemu-img). Each array
of strings makes up a command line switch that overrides matching default
@@ -221,11 +230,6 @@ qemu-system-x86 command. The arguments are all printed for review.
qemu-system-x86 -m 1024m --no-acpi -netdev user,id=mynet0,hostfwd=hostip:hostport-guestip:guestport -device virtio-net,netdev=mynet0"
</pre>
* `qemu_binary` (string) - The name of the Qemu binary to look for. This
defaults to "qemu-system-x86_64", but may need to be changed for some
platforms. For example "qemu-kvm", or "qemu-system-i386" may be a better
choice for some systems.
* `shutdown_command` (string) - The command to use to gracefully shut down
the machine once all the provisioning is done. By default this is an empty
string, which tells Packer to just forcefully shut down the machine.
@@ -241,23 +245,6 @@ qemu-system-x86 command. The arguments are all printed for review.
Packer will choose a randomly available port in this range to use as the
host port.
* `ssh_key_path` (string) - Path to a private key to use for authenticating
with SSH. By default this is not set (key-based auth won't be used).
The associated public key is expected to already be configured on the
VM being prepared by some other process (kickstart, etc.).
* `ssh_password` (string) - The password for `ssh_username` to use to
authenticate with SSH. By default this is the empty string.
* `ssh_port` (integer) - The port that SSH will be listening on in the guest
virtual machine. By default this is 22. The Qemu builder will map, via
port forward, a port on the host machine to the port listed here so
machines outside the installing VM can access the VM.
* `ssh_wait_timeout` (string) - The duration to wait for SSH to become
available. By default this is "20m", or 20 minutes. Note that this should
be quite long since the timer begins as soon as the virtual machine is booted.
* `vm_name` (string) - This is the name of the image (QCOW2 or IMG) file for
the new virtual machine, without the file extension. By default this is
"packer-BUILDNAME", where "BUILDNAME" is the name of the build.
@@ -33,7 +33,6 @@ Ubuntu to self-install. Still, the example serves to show the basic configuratio
"iso_checksum_type": "md5",
"ssh_username": "packer",
"ssh_password": "packer",
"ssh_wait_timeout": "30s",
"shutdown_command": "echo 'packer' | sudo -S shutdown -P now"
}
```
@@ -48,6 +47,10 @@ There are many configuration options available for the VirtualBox builder.
They are organized below into two categories: required and optional. Within
each category, the available options are alphabetized and described.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO
@@ -196,22 +199,7 @@ each category, the available options are alphabetized and described.
Packer will choose a randomly available port in this range to use as the
host port.
* `ssh_key_path` (string) - Path to a private key to use for authenticating
with SSH. By default this is not set (key-based auth won't be used).
The associated public key is expected to already be configured on the
VM being prepared by some other process (kickstart, etc.).
* `ssh_password` (string) - The password for `ssh_username` to use to
authenticate with SSH. By default this is the empty string.
* `ssh_port` (integer) - The port that SSH will be listening on in the guest
virtual machine. By default this is 22.
* `ssh_wait_timeout` (string) - The duration to wait for SSH to become
available. By default this is "20m", or 20 minutes. Note that this should
be quite long since the timer begins as soon as the virtual machine is booted.
* `ssh_skip_nat_mapping` (bool) - Defaults to false. When enabled, Packer does
* `ssh_skip_nat_mapping` (boolean) - Defaults to false. When enabled, Packer does
not setup forwarded port mapping for SSH requests and uses `ssh_port` on the
host to communicate to the virtual machine
@@ -39,7 +39,6 @@ the settings here.
"source_path": "source.ovf",
"ssh_username": "packer",
"ssh_password": "packer",
"ssh_wait_timeout": "30s",
"shutdown_command": "echo 'packer' | sudo -S shutdown -P now"
}
```
@@ -54,6 +53,10 @@ There are many configuration options available for the VirtualBox builder.
They are organized below into two categories: required and optional. Within
each category, the available options are alphabetized and described.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `source_path` (string) - The path to an OVF or OVA file that acts as
@@ -171,22 +174,7 @@ each category, the available options are alphabetized and described.
Packer will choose a randomly available port in this range to use as the
host port.
* `ssh_key_path` (string) - Path to a private key to use for authenticating
with SSH. By default this is not set (key-based auth won't be used).
The associated public key is expected to already be configured on the
VM being prepared by some other process (kickstart, etc.).
* `ssh_password` (string) - The password for `ssh_username` to use to
authenticate with SSH. By default this is the empty string.
* `ssh_port` (integer) - The port that SSH will be listening on in the guest
virtual machine. By default this is 22.
* `ssh_wait_timeout` (string) - The duration to wait for SSH to become
available. By default this is "20m", or 20 minutes. Note that this should
be quite long since the timer begins as soon as the virtual machine is booted.
* `ssh_skip_nat_mapping` (bool) - Defaults to false. When enabled, Packer does
* `ssh_skip_nat_mapping` (boolean) - Defaults to false. When enabled, Packer does
not setup forwarded port mapping for SSH requests and uses `ssh_port` on the
host to communicate to the virtual machine
@@ -38,7 +38,6 @@ Ubuntu to self-install. Still, the example serves to show the basic configuratio
"iso_checksum": "af5f788aee1b32c4b2634734309cc9e9",
"iso_checksum_type": "md5",
"ssh_username": "packer",
"ssh_wait_timeout": "30s",
"shutdown_command": "shutdown -P now"
}
```
@@ -49,6 +48,10 @@ There are many configuration options available for the VMware builder.
They are organized below into two categories: required and optional. Within
each category, the available options are alphabetized and described.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO
@@ -201,28 +204,6 @@ each category, the available options are alphabetized and described.
slightly larger. If you find this to be the case, you can disable compaction
using this configuration value.
* `ssh_host` (string) - Hostname or IP address of the host. By default, DHCP
is used to connect to the host and this field is not used.
* `ssh_key_path` (string) - Path to a private key to use for authenticating
with SSH. By default this is not set (key-based auth won't be used).
The associated public key is expected to already be configured on the
VM being prepared by some other process (kickstart, etc.).
* `ssh_password` (string) - The password for `ssh_username` to use to
authenticate with SSH. By default this is the empty string.
* `ssh_port` (integer) - The port that SSH will listen on within the virtual
machine. By default this is 22.
* `ssh_skip_request_pty` (boolean) - If true, a pty will not be requested as
part of the SSH connection. By default, this is "false", so a pty
_will_ be requested.
* `ssh_wait_timeout` (string) - The duration to wait for SSH to become
available. By default this is "20m", or 20 minutes. Note that this should
be quite long since the timer begins as soon as the virtual machine is booted.
* `tools_upload_flavor` (string) - The flavor of the VMware Tools ISO to
upload into the VM. Valid values are "darwin", "linux", and "windows".
By default, this is empty, which means VMware tools won't be uploaded.
@@ -44,6 +44,10 @@ There are many configuration options available for the VMware builder.
They are organized below into two categories: required and optional. Within
each category, the available options are alphabetized and described.
In addition to the options listed here, a
[communicator](/docs/templates/communicator.html)
can be configured for this builder.
### Required:
* `source_path` (string) - Path to the source VMX file to clone.
@@ -126,25 +130,6 @@ each category, the available options are alphabetized and described.
slightly larger. If you find this to be the case, you can disable compaction
using this configuration value.
* `ssh_key_path` (string) - Path to a private key to use for authenticating
with SSH. By default this is not set (key-based auth won't be used).
The associated public key is expected to already be configured on the
VM being prepared by some other process (kickstart, etc.).
* `ssh_password` (string) - The password for `ssh_username` to use to
authenticate with SSH. By default this is the empty string.
* `ssh_port` (integer) - The port that SSH will listen on within the virtual
machine. By default this is 22.
* `ssh_skip_request_pty` (boolean) - If true, a pty will not be requested as
part of the SSH connection. By default, this is "false", so a pty
_will_ be requested.
* `ssh_wait_timeout` (string) - The duration to wait for SSH to become
available. By default this is "20m", or 20 minutes. Note that this should
be quite long since the timer begins as soon as the virtual machine is booted.
* `vm_name` (string) - This is the name of the VMX file for the new virtual
machine, without the file extension. By default this is "packer-BUILDNAME",
where "BUILDNAME" is the name of the build.
@@ -5,18 +5,41 @@ description: |-
Packer strives to be stable and bug-free, but issues inevitably arise where certain things may not work entirely correctly, or may not appear to work correctly. In these cases, it is sometimes helpful to see more details about what Packer is actually doing.
---
# Debugging Packer
# Debugging Packer Builds
Packer strives to be stable and bug-free, but issues inevitably arise where
certain things may not work entirely correctly, or may not appear to work
correctly. In these cases, it is sometimes helpful to see more details about
what Packer is actually doing.
For remote builds with cloud providers like Amazon Web Services AMIs, debugging
a Packer build can be eased greatly with `packer build -debug`. This disables
parallelization and enables debug mode.
Debug mode informs the builders that they should output debugging information.
The exact behavior of debug mode is left to the builder. In general, builders
usually will stop between each step, waiting for keyboard input before
continuing. This will allow you to inspect state and so on.
In debug mode once the remote instance is instantiated, Packer will emit to the
current directory an emphemeral private ssh key as a .pem file. Using that you
can `ssh -i <key.pem>` into the remote build instance and see what is going on
for debugging. The emphemeral key will be deleted at the end of the packer run
during cleanup.
### Windows
As of Packer 0.8.1 the default WinRM communicator will emit the password for a
Remote Desktop Connection into your instance. This happens following the several
minute pause as the instance is booted. Note a .pem key is still created for
securely transmitting the password. Packer automatically decrypts the password
for you in debug mode.
## Debugging Packer
Issues occasionally arise where certain things may not work entirely correctly,
or may not appear to work correctly. In these cases, it is sometimes helpful to
see more details about what Packer is actually doing.
Packer has detailed logs which can be enabled by setting the `PACKER_LOG`
environmental variable to any value. This will cause detailed logs to appear
on stderr. The logs contain log messages from Packer as well as any plugins
that are being used. Log messages from plugins are prefixed by their application
name.
environmental variable to any value like this `PACKER_LOG=1 packer build
<config.json>`. This will cause detailed logs to appear on stderr. The logs
contain log messages from Packer as well as any plugins that are being used. Log
messages from plugins are prefixed by their application name.
Note that because Packer is highly parallelized, log messages sometimes
appear out of order, especially with respect to plugins. In this case,
@@ -37,10 +37,10 @@ The configuration allows you to specify and access the artifact in Atlas.
have access to the organization, hashicorp in this example, in order to add an artifact to
the organization in Atlas.
* `artifact_type` (string) - For uploading AMIs to Atlas, `artifact_type` will always be `aws.ami`.
* `artifact_type` (string) - For uploading AMIs to Atlas, `artifact_type` will always be `amazon.ami`.
This field must be defined because Atlas can host other artifact types, such as Vagrant boxes.
-> **Note:** If you want to upload Vagrant boxes to Atlas, for now use the [Vagrant Cloud post-processor](/docs/post-processors/vagrant-cloud.html).
-> **Note:** If you want to upload Vagrant boxes to Atlas, use the [Atlas post-processor](/docs/post-processors/atlas.html).
### Optional:
@@ -85,7 +85,7 @@ to `https://atlas.hashicorp.com/api/v1`.
"type": "atlas",
"token": "{{user `atlas_token`}}",
"artifact": "hashicorp/foobar",
"artifact_type": "aws.ami",
"artifact_type": "amazon.ami",
"metadata": {
"created_at": "{{timestamp}}"
}
@@ -34,7 +34,7 @@ If you want more control over how the archive is created you can specify the fol
that support it, from 1 through 9 inclusive. Typically higher compression
levels take longer but produce smaller files. Defaults to `6`
* `keep_input_artifact` (bool) - Keep source files; defaults to `false`
* `keep_input_artifact` (boolean) - Keep source files; defaults to `false`
### Supported Formats
@@ -7,6 +7,8 @@ description: |-
# Vagrant Cloud Post-Processor
~> Vagrant Cloud has been superseded by Atlas. Please use the [Atlas post-processor](/docs/post-processors/atlas.html) instead. Learn more about [Atlas](https://atlas.hashicorp.com/).
Type: `vagrant-cloud`
The Packer Vagrant Cloud post-processor receives a Vagrant box from the `vagrant`
@@ -41,15 +41,16 @@ Optional:
* `extra_arguments` (array of strings) - An array of extra arguments to pass to the
ansible command. By default, this is empty.
* `inventory_groups` (string) - You can let Packer generate a temporary inventory
for you. It will contains only `127.0.0.1`. Thanks to `inventory_groups`,
packer will set the current machine into different groups and will
generate an inventory like:
* `inventory_groups` (string) - A comma-separated list of groups to which
packer will assign the host `127.0.0.1`. A value of `my_group_1,my_group_2`
will generate an Ansible inventory like:
```text
[my_group_1]
127.0.0.1
[my_group_2]
127.0.0.1
```
* `inventory_file` (string) - The inventory file to be used by ansible.
This file must exist on your local system and will be uploaded to the
@@ -113,11 +113,17 @@ The default value for the configuration template is:
log_level :info
log_location STDOUT
chef_server_url "{{.ServerUrl}}"
{{if ne .ValidationClientName ""}}
validation_client_name "{{.ValidationClientName}}"
{{else}}
validation_client_name "chef-validator"
{{end}}
{{if ne .ValidationKeyPath ""}}
validation_key "{{.ValidationKeyPath}}"
{{end}}
{{if ne .NodeName ""}}
node_name "{{.NodeName}}"
{{end}}
```
This template is a [configuration template](/docs/templates/configuration-templates.html)
@@ -40,9 +40,12 @@ The reference of available configuration options is listed below.
Required parameters:
* `manifest_file` (string) - The manifest file for Puppet to use in order
to compile and run a catalog. This file must exist on your local system
and will be uploaded to the remote machine.
* `manifest_file` (string) - This is either a path to a puppet manifest (`.pp`
file) _or_ a directory containing multiple manifests that puppet will apply
(the ["main manifest"][1]). These file(s) must exist on your local system and
will be uploaded to the remote machine.
[1]: https://docs.puppetlabs.com/puppet/latest/reference/dirs_manifest.html
Optional parameters:
@@ -64,6 +67,10 @@ Optional parameters:
the `manifest_file`. It is a separate directory that will be set as
the "manifestdir" setting on Puppet.
~> `manifest_dir` is passed to `puppet apply` as the `--manifestdir` option.
This option was deprecated in puppet 3.6, and removed in puppet 4.0. If you
have multiple manifests you should use `manifest_file` instead.
* `module_paths` (array of strings) - This is an array of paths to module
directories on your local filesystem. These will be uploaded to the remote
machine. By default, this is empty.
@@ -51,7 +51,7 @@ required. They are listed below:
* `facter` (object of key/value strings) - Additional Facter facts to make available to the
Puppet run.
* `ignore_exit_codes` (bool) - If true, Packer will never consider the
* `ignore_exit_codes` (boolean) - If true, Packer will never consider the
provisioner a failure.
* `options` (string) - Additional command line options to pass
@@ -89,10 +89,14 @@ Optional parameters:
To many new users, the `execute_command` is puzzling. However, it provides
an important function: customization of how the command is executed. The
most common use case for this is dealing with **sudo password prompts**.
most common use case for this is dealing with **sudo password prompts**. You may
also need to customize this if you use a non-POSIX shell, such as `tcsh` on
FreeBSD.
For example, if the default user of an installed operating system is "packer"
and has the password "packer" for sudo usage, then you'll likely want to
### Sudo Example
Some operating systems default to a non-root user. For example if you login
as `ubuntu` and can sudo using the password `packer`, then you'll want to
change `execute_command` to be:
```text
@@ -100,13 +104,23 @@ change `execute_command` to be:
```
The `-S` flag tells `sudo` to read the password from stdin, which in this
case is being piped in with the value of "packer". The `-E` flag tells `sudo`
case is being piped in with the value of `packer`. The `-E` flag tells `sudo`
to preserve the environment, allowing our environmental variables to work
within the script.
By setting the `execute_command` to this, your script(s) can run with
root privileges without worrying about password prompts.
### FreeBSD Example
FreeBSD's default shell is `tcsh`, which deviates from POSIX sematics. In order
for packer to pass environment variables you will need to change the
`execute_command` to:
chmod +x {{ .Path }}; env {{ .Vars }} {{ .Path }}
Note the addition of `env` before `{{ .Vars }}`.
## Default Environmental Variables
In addition to being able to specify custom environmental variables using
+12
View File
@@ -61,3 +61,15 @@ you can specify a custom name using the `name` key within the builder definition
This is particularly useful if you have multiple builds defined that use
the same underlying builder. In this case, you must specify a name for at least
one of them since the names must be unique.
## Communicators
Every build is associated with a single
[communicator](/docs/templates/communicator.html). Communicators are
used to establish a connection for provisioning a remote machine (such
as an AWS instance or local virtual machine).
All the examples for the various builders show some communicator (usually
SSH), but the communicators are highly customizable so we recommend
reading the
[communicator documentation](/docs/templates/communicator.html).
+109
View File
@@ -0,0 +1,109 @@
---
layout: "docs"
page_title: "Templates: Communicators"
description: |-
Communicators are the mechanism Packer uses to upload files, execute scripts, etc. with the machine being created.
---
# Templates: Communicators
Communicators are the mechanism Packer uses to upload files, execute
scripts, etc. with the machine being created.
Communicators are configured within the [builder](/docs/templates/builders.html)
section. Packer currently supports three kinds of communicators:
* `none` - No communicator will be used. If this is set, most provisioners
also can't be used.
* `ssh` - An SSH connection will be established to the machine. This is
usually the default.
* `winrm` - A WinRM connection will be established.
In addition to the above, some builders have custom communicators they can
use. For example, the Docker builder has a "docker" communicator that uses
`docker exec` and `docker cp` to execute scripts and copy files.
## Using a Communicator
By default, the SSH communicator is usually used. Additional configuration
may not even be necessary, since some builders such as Amazon automatically
configure everything.
However, to specify a communicator, you set the `communicator` key within
a build. Multiple builds can have different communicators. Example:
```javascript
{
"builders": [{
"type": "amazon-ebs",
"communicator": "ssh"
}]
}
```
After specifying the `communicator`, you can specify a number of other
configuration parameters for that communicator. These are documented below.
## SSH Communicator
The SSH communicator connects to the host via SSH. If you have an SSH
agent enabled on the machine running Packer, it will automatically forward
the SSH agent to the remote host.
The SSH communicator has the following options:
* `ssh_host` (string) - The address to SSH to. This usually is automatically
configured by the builder.
* `ssh_port` (int) - The port to connect to SSH. This defaults to 22.
* `ssh_username` (string) - The username to connect to SSH with.
* `ssh_password` (string) - A plaintext password to use to authenticate
with SSH.
* `ssh_private_key_file` (string) - Path to a PEM encoded private key
file to use to authentiate with SSH.
* `ssh_pty` (boolean) - If true, a PTY will be requested for the SSH connection.
This defaults to false.
* `ssh_timeout` (string) - The time to wait for SSH to become available.
Packer uses this to determine when the machine has booted so this is usually
quite long. Example value: "10m"
* `ssh_handshake_attempts` (int) - The number of handshakes to attempt with
SSH once it can connect. This defaults to 10.
* `ssh_disable_agent` (boolean) - If true, SSH agent forwarding will be disabled.
* `ssh_bastion_host` (string) - A bastion host to use for the actual
SSH connection.
* `ssh_bastion_port` (int) - The port of the bastion host. Defaults to 22.
* `ssh_bastion_username` (string) - The username to connect to the bastion host.
* `ssh_bastion_password` (string) - The password to use to authenticate
with the bastion host.
* `ssh_bastion_private_key_file` (string) - A private key file to use
to authenticate with the bastion host.
## WinRM Communicator
The WinRM communicator has the following options.
* `winrm_host` (string) - The address for WinRM to connect to.
* `winrm_port` (int) - The WinRM port to connect to. This defaults to 5985.
* `winrm_username` (string) - The username to use to connect to WinRM.
* `winrm_password` (string) - The password to use to connect to WinRM.
* `winrm_timeout` (string) - The amount of time to wait for WinRM to
become available. This defaults to "30m" since setting up a Windows
machine generally takes a long time.
+1 -1
View File
@@ -59,7 +59,7 @@ each category, the available configuration keys are alphabetized.
* `token` (string) - An access token to use to authenticate to the build
service.
* `vcs` (bool) - If true, Packer will detect your VCS (if there is one)
* `vcs` (boolean) - If true, Packer will detect your VCS (if there is one)
and only upload the files that are tracked by the VCS. This is useful
for automatically excluding ignored files. This defaults to false.
+2 -2
View File
@@ -10,7 +10,7 @@ description: |-
<div class="row">
<div class="col-md-4 col-md-offset-1">
<h2>
<span class="text-green">Packer</span> is a tool for creating identical machine images for multiple platforms from a single source configuration.
<span class="text-green">Packer</span> is a tool for creating machine and container images for multiple platforms from a single source configuration.
</h2>
</div>
</div>
@@ -58,7 +58,7 @@ description: |-
<h2 class="text-green text-center">Works Great With</h2>
<p>
Out of the box Packer comes with support to build images for
Amazon EC2, DigitalOcean, Google Compute Engine, QEMU,
Amazon EC2, DigitalOcean, Docker, Google Compute Engine, QEMU,
VirtualBox, VMware, and more. Support for
more platforms is on the way, and anyone can add new platforms
via plugins.
@@ -54,7 +54,7 @@ briefly. Create a file `example.json` and fill it with the following contents:
"access_key": "{{user `aws_access_key`}}",
"secret_key": "{{user `aws_secret_key`}}",
"region": "us-east-1",
"source_ami": "ami-c65be9ae",
"source_ami": "ami-de0d9eb7",
"instance_type": "t1.micro",
"ssh_username": "ubuntu",
"ami_name": "packer-example {{timestamp}}"
@@ -17,7 +17,7 @@ the [documentation](/docs). The documentation is less of a guide and
more of a reference of all the overall features and options of Packer.
If you're interested in learning more about how Packer fits into the
HashiCorp ecosystem of tools, read our [Atlas getting started overview](https://atlas.hashicorp.com/help/getting-started/getting-started-overview).
HashiCorp ecosystem of tools, read our [Atlas getting started overview](https://atlas.hashicorp.com/help/intro/getting-started).
As you use Packer more, please voice your comments and concerns on
the [mailing list or IRC](/community). Additionally, Packer is
@@ -49,9 +49,9 @@ you're not okay with this, just follow along.
!> **Warning!** You _will_ be charged $0.01 by DigitalOcean per image
created with Packer because of the time the "droplet" is running.
Once you sign up for an account, grab your client ID and API key from
the [DigitalOcean API access page](https://www.digitalocean.com/api_access).
Save these values somewhere, you'll need them in a second.
Once you sign up for an account, grab your API token from
the [DigitalOcean API access page](https://cloud.digitalocean.com/settings/applications).
Save these values somewhere; you'll need them in a second.
## Modifying the Template
@@ -62,8 +62,10 @@ array.
```javascript
{
"type": "digitalocean",
"api_key": "{{user `do_api_key`}}",
"client_id": "{{user `do_client_id`}}"
"api_token": "{{user `do_api_token`}}",
"image": "ubuntu-14-04-x64",
"region": "nyc3",
"size": "512mb",
}
```
@@ -72,13 +74,46 @@ to include the access keys for DigitalOcean.
```javascript
"variables": {
"do_api_key": "",
"do_client_id": ""
"do_api_token": "",
// ...
}
```
The entire template should now [look like this](https://gist.github.com/pearkes/cc5f8505eee5403a43a6).
The entire template should now look like this:
```javascript
{
"variables": {
"aws_access_key": "",
"aws_secret_key": "",
"do_api_token": ""
},
"builders": [{
"type": "amazon-ebs",
"access_key": "{{user `aws_access_key`}}",
"secret_key": "{{user `aws_secret_key`}}",
"region": "us-east-1",
"source_ami": "ami-de0d9eb7",
"instance_type": "t1.micro",
"ssh_username": "ubuntu",
"ami_name": "packer-example {{timestamp}}"
},{
"type": "digitalocean",
"api_token": "{{user `do_api_token`}}",
"image": "ubuntu-14-04-x64",
"region": "nyc3",
"size": "512mb"
}],
"provisioners": [{
"type": "shell",
"inline": [
"sleep 30",
"sudo apt-get update",
"sudo apt-get install -y redis-server"
]
}]
}
```
Additional builders are simply added to the `builders` array in the template.
This tells Packer to build multiple images. The builder `type` values don't
@@ -104,8 +139,7 @@ same.
$ packer build \
-var 'aws_access_key=YOUR ACCESS KEY' \
-var 'aws_secret_key=YOUR SECRET KEY' \
-var 'do_api_key=YOUR API KEY' \
-var 'do_client_id=YOUR CLIENT ID' \
-var 'do_api_token=YOUR API TOKEN' \
example.json
==> amazon-ebs: amazon-ebs output will be in this color.
==> digitalocean: digitalocean output will be in this color.
@@ -66,7 +66,7 @@ Now we have Atlas building an AMI with Redis pre-configured. This is great, but
{
"type": "atlas",
"artifact": "ATLAS_USERNAME/packer-tutorial",
"artifact_type": "aws.ami"
"artifact_type": "amazon.ami"
}
]
}
@@ -12,9 +12,9 @@ description: |-
HashiCorp is the creator of the open source projects Vagrant, Packer, Terraform, Serf, and Consul, and the commercial product Atlas. Packer is just one piece of the ecosystem HashiCorp has built to make application delivery a versioned, auditable, repeatable, and collaborative process. To learn more about our beliefs on the qualities of the modern datacenter and responsible application delivery, read [The Atlas Mindset: Version Control for Infrastructure](https://hashicorp.com/blog/atlas-mindset.html/?utm_source=packer&utm_campaign=HashicorpEcosystem).
If you are using Packer to build machine images and deployable artifacts, its likely that you need a solution for deploying those artifacts. Terraform is our tool for creating, combining, and modifying infrastructure.
If you are using Packer to build machine images and deployable artifacts, it's likely that you need a solution for deploying those artifacts. Terraform is our tool for creating, combining, and modifying infrastructure.
Below are summaries of HashiCorps open source projects and a graphic showing how Atlas connects them to create a full application delivery workflow.
Below are summaries of HashiCorp's open source projects and a graphic showing how Atlas connects them to create a full application delivery workflow.
# HashiCorp Ecosystem
![Atlas Workflow](docs/atlas-workflow.png)
@@ -27,6 +27,6 @@ Below are summaries of HashiCorps open source projects and a graphic showing
[Consul](https://consul.io/?utm_source=packer&utm_campaign=HashicorpEcosystem) is a HashiCorp tool for service discovery, service registry, and health checks. In the Atlas workflow Consul is configured at the Packer build stage and identifies the service(s) contained in each artifact. Since Consul is configured at the build phase with Packer, when the artifact is deployed with Terraform, it is fully configured with dependencies and service discovery pre-baked. This greatly reduces the risk of an unhealthy node in production due to configuration failure at runtime.
[Serf](https://serfdom.io/?utm_source=packer&utm_campaign=HashicorpEcosystem) is a HashiCorp tool for cluster membership and failure detection. Consul uses Serfs gossip protocol as the foundation for service discovery.
[Serf](https://serfdom.io/?utm_source=packer&utm_campaign=HashicorpEcosystem) is a HashiCorp tool for cluster membership and failure detection. Consul uses Serf's gossip protocol as the foundation for service discovery.
[Vagrant](https://www.vagrantup.com/?utm_source=packer&utm_campaign=HashicorpEcosystem) is a HashiCorp tool for managing development environments that mirror production. Vagrant environments reduce the friction of developing a project and reduce the risk of unexpected behavior appearing after deployment. Vagrant boxes can be built in parallel with production artifacts with Packer to maintain parity between development and production.
+1
View File
@@ -25,6 +25,7 @@
<li><a href="/docs/templates/provisioners.html">Provisioners</a></li>
<li><a href="/docs/templates/post-processors.html">Post-Processors</a></li>
<li><a href="/docs/templates/push.html">Push</a></li>
<li><a href="/docs/templates/communicator.html">Communicators</a></li>
<li><a href="/docs/templates/configuration-templates.html">Configuration Templates</a></li>
<li><a href="/docs/templates/user-variables.html">User Variables</a></li>
<li><a href="/docs/templates/veewee-to-packer.html">Veewee-to-Packer</a></li>
+9 -6
View File
@@ -51,12 +51,15 @@
<div class="col-md-12">
<ul>
<li class="packer"><a href="/">Packer</a></li>
<li>
A <a href="http://www.hashicorp.com/">HashiCorp</a> project.
</li>
<a href="http://www.hashicorp.com">
<li class="pull-right hashi-logo">&nbps;</li>
</a>
<li>
A <a href="http://www.hashicorp.com/">HashiCorp</a> project.
</li>
<li>
<a href="https://github.com/mitchellh/packer/blob/master/website/source/<%= current_page.path %>.markdown">Edit this page</a>
</li>
<a href="http://www.hashicorp.com">
<li class="pull-right hashi-logo">&nbps;</li>
</a>
</ul>
</div>
</div>