Merge branch 'set_azure_custom_res_names' of github.com:vijayrajah/packer into set_azure_custom_res_names

This commit is contained in:
Vijay Rajah 2020-04-08 23:54:21 +05:30
commit 56bf8bd686
782 changed files with 36106 additions and 17607 deletions

View File

@ -158,6 +158,28 @@ jobs:
at: .
- run: |
ghr -prerelease -t ${GITHUB_TOKEN_AZR} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${CIRCLE_TAG} ./pkg/
build-website-docker-image:
docker:
- image: circleci/buildpack-deps
shell: /usr/bin/env bash -euo pipefail -c
steps:
- checkout
- setup_remote_docker
- run:
name: Build Docker Image if Necessary
command: |
IMAGE_TAG=$(cat website/Dockerfile website/package-lock.json | sha256sum | awk '{print $1;}')
echo "Using $IMAGE_TAG"
if curl https://hub.docker.com/v2/repositories/hashicorp/packer-website/tags/$IMAGE_TAG -fsL > /dev/null; then
echo "Dependencies have not changed, not building a new website docker image."
else
cd website/
docker build -t hashicorp/packer-website:$IMAGE_TAG .
docker tag hashicorp/packer-website:$IMAGE_TAG hashicorp/packer-website:latest
docker login -u $WEBSITE_DOCKER_USER -p $WEBSITE_DOCKER_PASS
docker push hashicorp/packer-website
fi
workflows:
version: 2
test:
@ -218,3 +240,10 @@ workflows:
ignore: /.*/
tags:
only: nightly
build_website_docker_image:
jobs:
- build-website-docker-image:
filters:
branches:
only:
- master

View File

@ -15,20 +15,20 @@ can quickly merge or address your contributions.
### Reporting an Issue
* Make sure you test against the latest released version. It is possible we
- Make sure you test against the latest released version. It is possible we
already fixed the bug you're experiencing.
* Run the command with debug output with the environment variable `PACKER_LOG`.
- Run the command with debug output with the environment variable `PACKER_LOG`.
For example: `PACKER_LOG=1 packer build template.json`. Take the _entire_
output and create a [gist](https://gist.github.com) for linking to in your
issue. Packer should strip sensitive keys from the output, but take a look
through just in case.
* Provide a reproducible test case. If a contributor can't reproduce an issue,
- Provide a reproducible test case. If a contributor can't reproduce an issue,
then it dramatically lowers the chances it'll get fixed. And in some cases,
the issue will eventually be closed.
* Respond promptly to any questions made by the Packer team to your issue. Stale
- Respond promptly to any questions made by the Packer team to your issue. Stale
issues will be closed.
### Issue Lifecycle
@ -86,23 +86,23 @@ The instructions below are for go 1.7. or later.
submitting a pull-request.
### Windows Systems
On windows systems you need at least the [MinGW Tools](http://www.mingw.org/), e.g. install via [choco](https://chocolatey.org/):
```
choco install mingw -y
```
This installs the GCC compiler, as well as a ```mingw32-make``` which can be used wherever
this documentation mentions ```make```
This installs the GCC compiler, as well as a `mingw32-make` which can be used wherever
this documentation mentions `make`
when building using ```go``` you also need to mention the windows
when building using `go` you also need to mention the windows
executable extension
```
go build -o bin/packer.exe
```
### Opening an Pull Request
Thank you for contributing! When you are ready to open a pull-request, you will
@ -131,37 +131,36 @@ to use `git push ...`.
### Pull Request Lifecycle
1. You are welcome to submit your pull request for commentary or review before
it is fully completed. Please prefix the title of your pull request with
"[WIP]" to indicate this. It's also a good idea to include specific questions
or items you'd like feedback on.
it is fully completed. Please prefix the title of your pull request with
"[WIP]" to indicate this. It's also a good idea to include specific questions
or items you'd like feedback on.
2. Once you believe your pull request is ready to be merged, you can remove any
"[WIP]" prefix from the title and a core team member will review.
"[WIP]" prefix from the title and a core team member will review.
3. One of Packer's core team members will look over your contribution and
either merge, or provide comments letting you know if there is anything left
to do. We do our best to provide feedback in a timely manner, but it may take
some time for us to respond. We may also have questions that we need answered
about the code, either because something doesn't make sense to us or because
we want to understand your thought process.
either merge, or provide comments letting you know if there is anything left
to do. We do our best to provide feedback in a timely manner, but it may take
some time for us to respond. We may also have questions that we need answered
about the code, either because something doesn't make sense to us or because
we want to understand your thought process.
4. If we have requested changes, you can either make those changes or, if you
disagree with the suggested changes, we can have a conversation about our
reasoning and agree on a path forward. This may be a multi-step process. Our
view is that pull requests are a chance to collaborate, and we welcome
conversations about how to do things better. It is the contributor's
responsibility to address any changes requested. While reviewers are happy to
give guidance, it is unsustainable for us to perform the coding work necessary
to get a PR into a mergeable state.
disagree with the suggested changes, we can have a conversation about our
reasoning and agree on a path forward. This may be a multi-step process. Our
view is that pull requests are a chance to collaborate, and we welcome
conversations about how to do things better. It is the contributor's
responsibility to address any changes requested. While reviewers are happy to
give guidance, it is unsustainable for us to perform the coding work necessary
to get a PR into a mergeable state.
5. Once all outstanding comments and checklist items have been addressed, your
contribution will be merged! Merged PRs will be included in the next
Packer release. The core team takes care of updating the
[CHANGELOG.md](../CHANGELOG.md) as they merge.
contribution will be merged! Merged PRs will be included in the next
Packer release. The core team takes care of updating the
[CHANGELOG.md](../CHANGELOG.md) as they merge.
6. In rare cases, we might decide that a PR should be closed without merging.
We'll make sure to provide clear reasoning when this happens.
We'll make sure to provide clear reasoning when this happens.
### Tips for Working on Packer
@ -250,7 +249,7 @@ does not attempt to track the latest version for each dependency.
Packer relies on `go generate` to generate a [peg parser for boot
commands](https://github.com/hashicorp/packer/blob/master/common/bootcommand/boot_command.go),
[docs](https://github.com/hashicorp/packer/blob/master/website/source/partials/builder/amazon/chroot/_Config-not-required.html.md)
[docs](https://github.com/hashicorp/packer/blob/master/website/pages/partials/builder/amazon/chroot/_Config-not-required.mdx)
and HCL2's bridging code. Packer's testing suite will run `make check-generate`
to check that all the generated files Packer needs are what they should be.
`make generate` re-generates all these file and can take a while depending on
@ -266,11 +265,13 @@ Packer relies on [golangci-lint](https://github.com/golangci/golangci-lint) for
The main configuration for golangci-lint is the `.golangci.yml` in the project root. See `golangci-lint --help` for a list of flags that can be used to override the default configuration.
Run golangci-lint on the entire Packer code base.
```
make lint
```
Run golangci-lint on a single pkg or directory; PKG_NAME expands to /builder/amazon/...
```
make lint PKG_NAME=builder/amazon
```
@ -328,6 +329,205 @@ Acceptance tests typically require other environment variables to be set for
things such as API tokens and keys. Each test should error and tell you which
credentials are missing, so those are not documented here.
#### Running Provisioners Acceptance Tests
**Warning:** The acceptance tests create/destroy/modify _real resources_, which
may incur costs for real money. In the presence of a bug, it is possible that
resources may be left behind, which can cost money even though you were not
using them. We recommend running tests in an account used only for that purpose
so it is easy to see if there are any dangling resources, and so production
resources are not accidentally destroyed or overwritten during testing.
Also, these typically require an API key (AWS, GCE), or additional software
to be installed on your computer (VirtualBox, VMware).
To run the Provisioners Acceptance Tests you should use both **ACC_TEST_BUILDERS** and **ACC_TEST_PROVISIONERS** variables to
tell which provisioner and builder the test should be run against.
Examples of usage:
- Run the Shell provisioner acceptance tests against the Amazon EBS builder.
```
ACC_TEST_BUILDERS=amazon-ebs ACC_TEST_PROVISIONERS=shell go test ./provisioner/shell/... -v -timeout=1h
```
- Do the same but using the Makefile
```
ACC_TEST_BUILDERS=amazon-ebs ACC_TEST_PROVISIONERS=shell make provisioners-acctest
```
- Run the all Shell and Powershell provisioners acceptance tests against the Amazon EBS builder.
```
ACC_TEST_BUILDERS=amazon-ebs ACC_TEST_PROVISIONERS=shell,powershell make provisioners-acctest
```
- Run the all provisioners acceptance tests against the Amazon EBS builder.
```
ACC_TEST_BUILDERS=amazon-ebs ACC_TEST_PROVISIONERS=all make provisioners-acctest
```
- Run the all provisioners acceptance tests against all builders whenever they are compatible.
```
ACC_TEST_BUILDERS=all ACC_TEST_PROVISIONERS=all make provisioners-acctest
```
Both **ACC_TEST_BUILDERS** and **ACC_TEST_PROVISIONERS** allows defining a list of builders and provisioners separated by comma
(e.g. `ACC_TEST_BUILDERS=amazon-ebs,virtualbox-iso`)
#### Writing Provisioner Acceptance Tests
Packer has an already implemented structure that will run the provisioner against builders and you can find it in `helper/tests/acc/provisioners.go`.
All provisioners should use this structure in their acceptance tests.
To start writing a new provisioner acceptance test, you should add a test file named as `provisioner_acc_test.go` in the provisioner folder
and the package should be `<provisioner>_test`. This file should have a struct that will implement the ProvisionerAcceptance interface.
```go
type ProvisionerAcceptance interface {
GetName() string
GetConfig() (string, error)
GetProvisionerStore() packer.MapOfProvisioner
IsCompatible(builder string, vmOS string) bool
RunTest(c *command.BuildCommand, args []string) error
}
```
- **GetName()** should return the provisioner type. For example for the Shell provisioner the method returns "shell".
- **GetConfig()** should read a text file with the json configuration block for the provisioner and any other necessary provisioner.
For the Shell one the file contains:
```
{
"type": "shell",
"inline": [
"echo {{ build `ID`}} > provisioner.{{ build `PackerRunUUID`}}.txt"
]
},
{
"type": "file",
"source": "provisioner.{{ build `PackerRunUUID`}}.txt",
"destination": "provisioner.shell.{{ build `PackerRunUUID`}}.txt",
"direction": "download"
}
```
The file should be placed under the `test-fixtures` folder.
In this case, it's necessary to use the File provisioner to validate if the Shell provisioner test is successful or not.
This config should be returned as string that will be later merged with the builder config into a full template.
- **GetProvisionerStore()** this returns the provisioner store where we declare the available provisioners for running the build.
For the Shell provisioners this is:
```go
func (s *ShellProvisionerAccTest) GetProvisionerStore() packer.MapOfProvisioner {
return packer.MapOfProvisioner{
"shell": func() (packer.Provisioner, error) { return &shell.Provisioner{}, nil },
"file": func() (packer.Provisioner, error) { return &file.Provisioner{}, nil },
}
}
```
- **IsCompatible(builder string, vmOS string)** returns true or false whether the provisioner should run against a
specific builder or/and specific OS.
- **RunTest(c \*command.BuildCommand, args []string)** it will actually run the build and return any error if it fails the validations.
For the Shell provisioner this is:
```go
func (s *ShellProvisionerAccTest) RunTest(c *command.BuildCommand, args []string) error {
// Provisioner specific setup
UUID := os.Getenv("PACKER_RUN_UUID")
if UUID == "" {
UUID, _ = uuid.GenerateUUID()
os.Setenv("PACKER_RUN_UUID", UUID)
}
file := "provisioner.shell." + UUID + ".txt"
defer testshelper.CleanupFiles(file)
// Run build
// All provisioner acc tests should contain this code and validation
if code := c.Run(args); code != 0 {
ui := c.Meta.Ui.(*packer.BasicUi)
out := ui.Writer.(*bytes.Buffer)
err := ui.ErrorWriter.(*bytes.Buffer)
return fmt.Errorf(
"Bad exit code.\n\nStdout:\n\n%s\n\nStderr:\n\n%s",
out.String(),
err.String())
}
// Any other extra specific validation
if !testshelper.FileExists(file) {
return fmt.Errorf("Expected to find %s", file)
}
return nil
}
```
After writing the struct and implementing the interface, now is time to write the test that will run all
of this code you wrote. Your test should be like:
```go
func TestShellProvisioner(t *testing.T) {
acc.TestProvisionersPreCheck("shell", t)
acc.TestProvisionersAgainstBuilders(new(ShellProvisionerAccTest), t)
}
```
If the environment variable **ACC_TEST_PROVISIONERS** is set as `all` or contains the provisioner type, then the test should run, otherwise the test should skip.
In case of running it, you'll need to call the helper function `acc.TestProvisionersAgainstBuilders` passing a pointer to the test struct created above and the test testing pointer.
The method `TestProvisionersAgainstBuilders` will run the provisioner against all available and compatible builders. An available builder
is the one that has the necessary code for running this type of test. In case the builder you want to run against is not available for testing, you can write it following the next steps.
To add a new builder to the available builders for provisioners acc testing, you'll need to create a new folder under the builder folder
called `acceptance` and inside you create the `builder_acceptance.go` file and the package should be `<builder>_acc`. Like the provisioners, you'll need to create a struct that will
implement the BuilderAcceptance interface.
```go
type BuilderAcceptance interface {
GetConfigs() (map[string]string, error)
GetBuilderStore() packer.MapOfBuilder
CleanUp() error
}
```
- **GetConfigs()** should read a text file with the json configuration block for the builder and return a map of configs by OS type.
For the Amazon EBS builder the file contains:
```
{
"type": "amazon-ebs",
"ami_name": "packer-acc-test",
"instance_type": "m1.small",
"region": "us-east-1",
"ssh_username": "ubuntu",
"source_ami": "ami-0568456c",
"force_deregister" : true,
"tags": {
"packer-test": "true"
}
}
```
The file should be placed under the `test-fixtures` folder.
In case you need to make references to another file, you'll need to add the relative path to provisioners folder like:
`../../builder/amazon/ebs/acceptance/test-fixtures/file.txt`.
- **GetBuilderStore()** this returns the builder store where we declare the available builders for running the build.
For the Amazon EBS builder this is:
```go
func (s *AmazonEBSAccTest) GetBuilderStore() packer.MapOfBuilder {
return packer.MapOfBuilder{
"amazon-ebs": func() (packer.Builder, error) { return &amazonebsbuilder.Builder{}, nil },
}
}
```
- **CleanUp()** cleans any resource created by the builder whether local or remote.
Once you created the builder necessary code, the last step is adding it to the `BuildersAccTest` map in `helper/tests/acc/provisioners.go`.
```go
var BuildersAccTest = map[string]BuilderAcceptance{
...
"amazon-ebs": new(amazonEBS.AmazonEBSAccTest),
...
}
```
Once you finish the steps, you should be ready to run your new provisioner acceptance test.
#### Debugging Plugins
Each packer plugin runs in a separate process and communicates via RPC over a

View File

@ -8,8 +8,8 @@ Issues on GitHub are intended to be related to bugs or feature requests, so we
recommend using our other community resources instead of asking here if you
have a question.
- Packer Guides: https://www.packer.io/guides/index.html
- Packer Guides: https://www.packer.io/guides
- Discussion List: https://groups.google.com/group/packer-tool
- Any other questions can be sent to the packer section of the HashiCorp
forum: https://discuss.hashicorp.com/c/packer
- Packer community links: https://www.packer.io/community.html
- Packer community links: https://www.packer.io/community

View File

@ -6,19 +6,18 @@ labels: communicator-question
Got one of the following errors ? See if the related guides can help.
* `Waiting for WinRM to become available` ?
- `Waiting for WinRM to become available` ?
- See our basic WinRm Packer guide: https://www.packer.io/guides/automatic-operating-system-installs/autounattend_windows.html
- See our basic WinRm Packer guide: https://www.packer.io/guides/automatic-operating-system-installs/autounattend_windows
* `Waiting for SSH to become available` ?
- See our basic SSH Packer guide: https://www.packer.io/guides/automatic-operating-system-installs/preseed_ubuntu.html
- `Waiting for SSH to become available` ?
- See our basic SSH Packer guide: https://www.packer.io/guides/automatic-operating-system-installs/preseed_ubuntu
Issues on GitHub are intended to be related to bugs or feature requests, so we recommend using our other community resources instead of asking here if you have a question.
- Packer Guides: https://www.packer.io/guides/index.html
- Packer Guides: https://www.packer.io/guides
- Discussion List: https://groups.google.com/group/packer-tool
- Any other questions can be sent to the packer section of the HashiCorp
forum: https://discuss.hashicorp.com/c/packer
- Packer community links: https://www.packer.io/community.html
- Packer community links: https://www.packer.io/community

View File

@ -12,12 +12,15 @@
### Bug Fixes:
* builder/amazon: Fix bug with launch_block_device_mappings in spot instances.
[GH-8945] builder/vsphere-iso: disk_size is no longer required if storage
is defined [GH-8975]
[GH-8945]
* builder/azure: Allow Managed Data Disks to be used with Azure Shared Image
Gallery [GH-8912]
* builder/qemu: Remove `net_device` pre-validation [GH-8979]
* builder/vsphere-iso: disk_size is no longer required if storage is defined
[GH-8975]
* core: Make sure CLI variables supersede variables from var files [GH-8964]
* provisioner/powershell: Fix integer decoding issue in the execution policy
parser [GH-8997]
## 1.5.5 (March 25,2020)

View File

@ -3,61 +3,61 @@
# builders
/builder/alicloud/ @chhaj5236 @alexyueer
/website/source/docs/builders/alicloud* @chhaj5236 @alexyueer
/website/pages/docs/builders/alicloud* @chhaj5236 @alexyueer
/builder/azure/ @paulmey
/website/source/docs/builders/azure* @paulmey
/website/pages/docs/builders/azure* @paulmey
/builder/hyperv/ @taliesins
/website/source/docs/builders/hyperv* @taliesins
/website/pages/docs/builders/hyperv* @taliesins
/builder/jdcloud/ @XiaohanLiang @remrain
/website/source/docs/builders/jdcloud* @XiaohanLiang @remrain
/website/pages/docs/builders/jdcloud* @XiaohanLiang @remrain
/builder/linode/ @displague @ctreatma @stvnjacobs
/website/source/docs/builders/linode* @displague @ctreatma @stvnjacobs
/website/pages/docs/builders/linode* @displague @ctreatma @stvnjacobs
/builder/lxc/ @ChrisLundquist
/website/source/docs/builders/lxc* @ChrisLundquist
/website/pages/docs/builders/lxc* @ChrisLundquist
/builder/lxd/ @ChrisLundquist
/website/source/docs/builders/lxd* @ChrisLundquist
/website/pages/docs/builders/lxd* @ChrisLundquist
/builder/oneandone/ @jasmingacic
/website/source/docs/builders/oneandone* @jasmingacic
/website/pages/docs/builders/oneandone* @jasmingacic
/builder/oracle/ @prydie @owainlewis
/website/source/docs/builders/oracle* @prydie @owainlewis
/website/pages/docs/builders/oracle* @prydie @owainlewis
/builder/profitbricks/ @jasmingacic
/website/source/docs/builders/profitbricks* @jasmingacic
/website/pages/docs/builders/profitbricks* @jasmingacic
/builder/triton/ @sean-
/website/source/docs/builders/triton* @sean-
/website/pages/docs/builders/triton* @sean-
/builder/ncloud/ @YuSungDuk
/website/source/docs/builders/ncloud* @YuSungDuk
/website/pages/docs/builders/ncloud* @YuSungDuk
/builder/proxmox/ @carlpett
/website/source/docs/builders/proxmox* @carlpett
/website/pages/docs/builders/proxmox* @carlpett
/builder/scaleway/ @sieben @mvaude @jqueuniet @fflorens @brmzkw
/website/source/docs/builders/scaleway* @sieben @mvaude @jqueuniet @fflorens @brmzkw
/website/pages/docs/builders/scaleway* @sieben @mvaude @jqueuniet @fflorens @brmzkw
/builder/hcloud/ @LKaemmerling
/website/source/docs/builders/hcloud* @LKaemmerling
/website/pages/docs/builders/hcloud* @LKaemmerling
/builder/hyperone/ @m110 @gregorybrzeski @ad-m
/website/source/docs/builders/hyperone* @m110 @gregorybrzeski @ad-m
/website/pages/docs/builders/hyperone* @m110 @gregorybrzeski @ad-m
/builder/ucloud/ @shawnmssu
/website/source/docs/builders/ucloud* @shawnmssu
/website/pages/docs/builders/ucloud* @shawnmssu
/builder/yandex/ @GennadySpb @alexanderKhaustov @seukyaso
/website/source/docs/builders/yandex* @GennadySpb @alexanderKhaustov @seukyaso
/website/pages/docs/builders/yandex* @GennadySpb @alexanderKhaustov @seukyaso
/builder/osc/ @marinsalinas
/website/source/docs/builders/osc* @marinsalinas
/website/pages/docs/builders/osc* @marinsalinas
# provisioners

View File

@ -108,7 +108,7 @@ mode-check: ## Check that only certain files are executable
echo "Check passed."; \
fi
fmt-docs:
@find ./website/source/docs -name "*.md" -exec pandoc --wrap auto --columns 79 --atx-headers -s -f "markdown_github+yaml_metadata_block" -t "markdown_github+yaml_metadata_block" {} -o {} \;
@find ./website/pages/docs -name "*.md" -exec pandoc --wrap auto --columns 79 --atx-headers -s -f "markdown_github+yaml_metadata_block" -t "markdown_github+yaml_metadata_block" {} -o {} \;
# Install js-beautify with npm install -g js-beautify
fmt-examples:
@ -118,7 +118,7 @@ fmt-examples:
# source files.
generate: install-gen-deps ## Generate dynamically generated code
@echo "==> removing autogenerated markdown..."
@find website/source/ -type f | xargs grep -l '^<!-- Code generated' | xargs rm
@find website/pages/ -type f | xargs grep -l '^<!-- Code generated' | xargs rm
@echo "==> removing autogenerated code..."
@find post-processor common helper template builder provisioner -type f | xargs grep -l '^// Code generated' | xargs rm
go generate ./...

View File

@ -17,7 +17,7 @@ type AlicloudDiskDevice struct {
// 128] English or Chinese characters, must begin with an
// uppercase/lowercase letter or Chinese character. Can contain numbers,
// ., _ and -. The disk name will appear on the console. It cannot
// begin with http:// or https://.
// begin with `http://` or `https://`.
DiskName string `mapstructure:"disk_name" required:"false"`
// Category of the system disk. Optional values
// are:
@ -35,7 +35,7 @@ type AlicloudDiskDevice struct {
SnapshotId string `mapstructure:"disk_snapshot_id" required:"false"`
// The value of disk description is blank by
// default. [2, 256] characters. The disk description will appear on the
// console. It cannot begin with http:// or https://.
// console. It cannot begin with `http://` or `https://`.
Description string `mapstructure:"disk_description" required:"false"`
// Whether or not the disk is
// released along with the instance:
@ -61,9 +61,9 @@ type AlicloudDiskDevices struct {
// - `cloud_efficiency` - efficiency cloud disk
// - `cloud_ssd` - cloud SSD
//
// For phased-out instance types and non-I/O optimized instances, the
// default value is cloud. Otherwise, the default value is
// cloud\_efficiency.
// For phased-out instance types and non-I/O optimized instances, the
// default value is cloud. Otherwise, the default value is
// cloud\_efficiency.
//
// - `disk_description` (string) - The value of disk description is blank by
// default. \[2, 256\] characters. The disk description will appear on the
@ -139,14 +139,14 @@ type AlicloudImageConfig struct {
// The name of the user-defined image, [2, 128]
// English or Chinese characters. It must begin with an uppercase/lowercase
// letter or a Chinese character, and may contain numbers, _ or -. It
// cannot begin with http:// or https://.
// cannot begin with `http://` or `https://`.
AlicloudImageName string `mapstructure:"image_name" required:"true"`
// The version number of the image, with a length
// limit of 1 to 40 English characters.
AlicloudImageVersion string `mapstructure:"image_version" required:"false"`
// The description of the image, with a length
// limit of 0 to 256 characters. Leaving it blank means null, which is the
// default value. It cannot begin with http:// or https://.
// default value. It cannot begin with `http://` or `https://`.
AlicloudImageDescription string `mapstructure:"image_description" required:"false"`
// The IDs of to-be-added Aliyun
// accounts to which the image is shared. The number of accounts is 1 to 10.
@ -158,7 +158,7 @@ type AlicloudImageConfig struct {
// The name of the destination image,
// [2, 128] English or Chinese characters. It must begin with an
// uppercase/lowercase letter or a Chinese character, and may contain numbers,
// _ or -. It cannot begin with http:// or https://.
// _ or -. It cannot begin with `http://` or `https://`.
AlicloudImageDestinationNames []string `mapstructure:"image_copy_names" required:"false"`
// Whether or not to encrypt the target images, including those copied if image_copy_regions is specified. If this option
// is set to true, a temporary image will be created from the provisioned
@ -171,13 +171,13 @@ type AlicloudImageConfig struct {
// images and then create the target images, otherwise, the creation will
// fail. The default value is false. Check `image_name` and
// `image_copy_names` options for names of target images. If
// [-force](https://packer.io/docs/commands/build.html#force) option is
// [-force](/docs/commands/build#force) option is
// provided in `build` command, this option can be omitted and taken as
// true.
AlicloudImageForceDelete bool `mapstructure:"image_force_delete" required:"false"`
// If this value is true, when delete the duplicated existing images, the
// source snapshots of those images will be delete either. If
// [-force](https://packer.io/docs/commands/build.html#force) option is
// [-force](/docs/commands/build#force) option is
// provided in `build` command, this option can be omitted and taken as
// true.
AlicloudImageForceDeleteSnapshots bool `mapstructure:"image_force_delete_snapshots" required:"false"`
@ -194,7 +194,7 @@ type AlicloudImageConfig struct {
AlicloudImageTags map[string]string `mapstructure:"tags" required:"false"`
// Same as [`tags`](#tags) but defined as a singular repeatable block
// containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
AlicloudImageTag hcl2template.NameValues `mapstructure:"tag" required:"false"`
AlicloudDiskDevices `mapstructure:",squash"`

View File

@ -57,7 +57,7 @@ type RunConfig struct {
// The security group name. The default value
// is blank. [2, 128] English or Chinese characters, must begin with an
// uppercase/lowercase letter or Chinese character. Can contain numbers, .,
// _ or -. It cannot begin with http:// or https://.
// _ or -. It cannot begin with `http://` or `https://`.
SecurityGroupName string `mapstructure:"security_group_name" required:"false"`
// User data to apply when launching the instance. Note
// that you need to be careful about escaping characters due to the templates
@ -73,8 +73,8 @@ type RunConfig struct {
// The VPC name. The default value is blank. [2, 128]
// English or Chinese characters, must begin with an uppercase/lowercase
// letter or Chinese character. Can contain numbers, _ and -. The disk
// description will appear on the console. Cannot begin with http:// or
// https://.
// description will appear on the console. Cannot begin with `http://` or
// `https://`.
VpcName string `mapstructure:"vpc_name" required:"false"`
// Value options: 192.168.0.0/16 and
// 172.16.0.0/16. When not specified, the default value is 172.16.0.0/16.

View File

@ -48,11 +48,11 @@ type Config struct {
// in the Chroot Mounts section. Please read that section for more
// information on how to use this.
ChrootMounts [][]string `mapstructure:"chroot_mounts" required:"false"`
// How to run shell commands. This defaults to {{.Command}}. This may be
// How to run shell commands. This defaults to `{{.Command}}`. This may be
// useful to set if you want to set environmental variables or perhaps run
// it with sudo or so on. This is a configuration template where the
// .Command variable is replaced with the command to be run. Defaults to
// {{.Command}}.
// `{{.Command}}`.
CommandWrapper string `mapstructure:"command_wrapper" required:"false"`
// Paths to files on the running EC2 instance that will be copied into the
// chroot environment prior to provisioning. Defaults to /etc/resolv.conf
@ -90,18 +90,18 @@ type Config struct {
MountPartition string `mapstructure:"mount_partition" required:"false"`
// The path where the volume will be mounted. This is where the chroot
// environment will be. This defaults to
// /mnt/packer-amazon-chroot-volumes/{{.Device}}. This is a configuration
// `/mnt/packer-amazon-chroot-volumes/{{.Device}}`. This is a configuration
// template where the .Device variable is replaced with the name of the
// device where the volume is attached.
MountPath string `mapstructure:"mount_path" required:"false"`
// As pre_mount_commands, but the commands are executed after mounting the
// root device and before the extra mount and copy steps. The device and
// mount path are provided by {{.Device}} and {{.MountPath}}.
// mount path are provided by `{{.Device}}` and `{{.MountPath}}`.
PostMountCommands []string `mapstructure:"post_mount_commands" required:"false"`
// A series of commands to execute after attaching the root volume and
// before mounting the chroot. This is not required unless using
// from_scratch. If so, this should include any partitioning and filesystem
// creation commands. The path to the device is provided by {{.Device}}.
// creation commands. The path to the device is provided by `{{.Device}}`.
PreMountCommands []string `mapstructure:"pre_mount_commands" required:"false"`
// The root device name. For example, xvda.
RootDeviceName string `mapstructure:"root_device_name" required:"false"`
@ -161,12 +161,12 @@ type Config struct {
//filter, but will cause Packer to fail if the `source_ami` does not exist.
SourceAmiFilter awscommon.AmiFilterOptions `mapstructure:"source_ami_filter" required:"false"`
// Tags to apply to the volumes that are *launched*. This is a [template
// engine](/docs/templates/engine.html), see [Build template
// engine](/docs/templates/engine), see [Build template
// data](#build-template-data) for more information.
RootVolumeTags map[string]string `mapstructure:"root_volume_tags" required:"false"`
// Same as [`root_volume_tags`](#root_volume_tags) but defined as a
// singular block containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
RootVolumeTag hcl2template.NameValues `mapstructure:"root_volume_tag" required:"false"`
// what architecture to use when registering the final AMI; valid options

View File

@ -44,7 +44,7 @@ func (v *VaultAWSEngineOptions) Empty() bool {
// AccessConfig is for common configuration related to AWS access
type AccessConfig struct {
// The access key used to communicate with AWS. [Learn how to set this]
// (/docs/builders/amazon.html#specifying-amazon-credentials). On EBS, this
// (/docs/builders/amazon#specifying-amazon-credentials). On EBS, this
// is not required if you are using `use_vault_aws_engine` for
// authentication instead.
AccessKey string `mapstructure:"access_key" required:"true"`
@ -79,7 +79,7 @@ type AccessConfig struct {
// When chroot building, this value is guessed from environment.
RawRegion string `mapstructure:"region" required:"true"`
// The secret key used to communicate with AWS. [Learn how to set
// this](amazon.html#specifying-amazon-credentials). This is not required
// this](/docs/builders/amazon#specifying-amazon-credentials). This is not required
// if you are using `use_vault_aws_engine` for authentication instead.
SecretKey string `mapstructure:"secret_key" required:"true"`
// Set to true if you want to skip
@ -95,7 +95,7 @@ type AccessConfig struct {
// Get credentials from Hashicorp Vault's aws secrets engine. You must
// already have created a role to use. For more information about
// generating credentials via the Vault engine, see the [Vault
// docs.](https://www.vaultproject.io/api/secret/aws/index.html#generate-credentials)
// docs.](https://www.vaultproject.io/api/secret/aws#generate-credentials)
// If you set this flag, you must also set the below options:
// - `name` (string) - Required. Specifies the name of the role to generate
// credentials against. This is part of the request URL.
@ -190,7 +190,7 @@ func (c *AccessConfig) Session() (*session.Session, error) {
if isAWSErr(err, "NoCredentialProviders", "") {
return nil, fmt.Errorf("No valid credential sources found for AWS Builder. " +
"Please see https://www.packer.io/docs/builders/amazon.html#specifying-amazon-credentials " +
"Please see https://www.packer.io/docs/builders/amazon#specifying-amazon-credentials " +
"for more information on providing credentials for the AWS Builder.")
}

View File

@ -17,11 +17,11 @@ type AMIConfig struct {
// The name of the resulting AMI that will appear when managing AMIs in the
// AWS console or via APIs. This must be unique. To help make this unique,
// use a function like timestamp (see [template
// engine](../templates/engine.html) for more info).
// engine](/docs/templates/engine) for more info).
AMIName string `mapstructure:"ami_name" required:"true"`
// The description to set for the resulting
// AMI(s). By default this description is empty. This is a
// [template engine](/docs/templates/engine.html), see [Build template
// [template engine](/docs/templates/engine), see [Build template
// data](#build-template-data) for more information.
AMIDescription string `mapstructure:"ami_description" required:"false"`
// The type of virtualization for the AMI
@ -48,12 +48,12 @@ type AMIConfig struct {
// validation of the ami_regions configuration option. Default false.
AMISkipRegionValidation bool `mapstructure:"skip_region_validation" required:"false"`
// Tags applied to the AMI. This is a
// [template engine](/docs/templates/engine.html), see [Build template
// [template engine](/docs/templates/engine), see [Build template
// data](#build-template-data) for more information.
AMITags map[string]string `mapstructure:"tags" required:"false"`
// Same as [`tags`](#tags) but defined as a singular repeatable block
// containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
AMITag hcl2template.NameValues `mapstructure:"tag" required:"false"`
// Enable enhanced networking (ENA but not SriovNetSupport) on
@ -119,12 +119,12 @@ type AMIConfig struct {
AMISkipBuildRegion bool `mapstructure:"skip_save_build_region"`
// Tags to apply to snapshot.
// They will override AMI tags if already applied to snapshot. This is a
// [template engine](../templates/engine.html), see [Build template
// [template engine](/docs/templates/engine), see [Build template
// data](#build-template-data) for more information.
SnapshotTags map[string]string `mapstructure:"snapshot_tags" required:"false"`
// Same as [`snapshot_tags`](#snapshot_tags) but defined as a singular
// repeatable block containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
SnapshotTag hcl2template.NameValues `mapstructure:"snapshot_tag" required:"false"`
// A list of account IDs that have
@ -210,7 +210,7 @@ func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context
if len(c.SnapshotUsers) > 0 {
if len(c.AMIKmsKeyId) == 0 && len(c.AMIRegionKMSKeyIDs) == 0 && c.AMIEncryptBootVolume.True() {
errs = append(errs, fmt.Errorf("Cannot share snapshot encrypted "+
"with default KMS key, see https://www.packer.io/docs/builders/amazon-ebs.html#region_kms_key_ids for more information"))
"with default KMS key, see https://www.packer.io/docs/builders/amazon-ebs#region_kms_key_ids for more information"))
}
if len(c.AMIRegionKMSKeyIDs) > 0 {
for _, kmsKey := range c.AMIRegionKMSKeyIDs {

View File

@ -90,7 +90,7 @@ type RunConfig struct {
// *will not* stop the instance but will assume that you will send the stop
// signal yourself through your final provisioner. You can do this with a
// [windows-shell
// provisioner](https://www.packer.io/docs/provisioners/windows-shell.html).
// provisioner](/docs/provisioners/windows-shell).
// Note that Packer will still wait for the instance to be stopped, and
// failing to send the stop signal yourself, when you have set this flag to
// `true`, will cause a timeout.
@ -184,12 +184,12 @@ type RunConfig struct {
// `security_group_ids` take precedence over this.
SecurityGroupFilter SecurityGroupFilterOptions `mapstructure:"security_group_filter" required:"false"`
// Tags to apply to the instance that is that is *launched* to create the
// EBS volumes. This is a [template engine](/docs/templates/engine.html),
// EBS volumes. This is a [template engine](/docs/templates/engine),
// see [Build template data](#build-template-data) for more information.
RunTags map[string]string `mapstructure:"run_tags" required:"false"`
// Same as [`run_tags`](#run_tags) but defined as a singular repeatable
// block containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
RunTag hcl2template.NameValues `mapstructure:"run_tag" required:"false"`
// The ID (not the name) of the security
@ -286,7 +286,7 @@ type RunConfig struct {
SpotTags map[string]string `mapstructure:"spot_tags" required:"false"`
// Same as [`spot_tags`](#spot_tags) but defined as a singular repeatable block
// containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
SpotTag hcl2template.NameValues `mapstructure:"spot_tag" required:"false"`
// Filters used to populate the `subnet_id` field.

View File

@ -9,7 +9,8 @@ import (
"os"
"path/filepath"
"github.com/hashicorp/packer/command"
amazonebsbuilder "github.com/hashicorp/packer/builder/amazon/ebs"
"github.com/hashicorp/packer/packer"
testshelper "github.com/hashicorp/packer/helper/tests"
@ -18,18 +19,31 @@ import (
type AmazonEBSAccTest struct{}
func (s *AmazonEBSAccTest) GetConfigs() (map[string]string, error) {
filePath := filepath.Join("../../builder/amazon/ebs/acceptance/test-fixtures/", "amazon-ebs.txt")
config, err := os.Open(filePath)
if err != nil {
return nil, fmt.Errorf("Expected to find %s", filePath)
fixtures := map[string]string{
"linux": "amazon-ebs.txt",
"windows": "amazon-ebs_windows.txt",
}
defer config.Close()
file, err := ioutil.ReadAll(config)
if err != nil {
return nil, fmt.Errorf("Uneble to read %s", filePath)
configs := make(map[string]string)
for distro, fixture := range fixtures {
fileName := fixture
filePath := filepath.Join("../../builder/amazon/ebs/acceptance/test-fixtures/", fileName)
config, err := os.Open(filePath)
if err != nil {
return nil, fmt.Errorf("Expected to find %s", filePath)
}
defer config.Close()
file, err := ioutil.ReadAll(config)
if err != nil {
return nil, fmt.Errorf("Unable to read %s", filePath)
}
configs[distro] = string(file)
}
return map[string]string{"linux": string(file)}, nil
return configs, nil
}
func (s *AmazonEBSAccTest) CleanUp() error {
@ -42,6 +56,6 @@ func (s *AmazonEBSAccTest) CleanUp() error {
func (s *AmazonEBSAccTest) GetBuilderStore() packer.MapOfBuilder {
return packer.MapOfBuilder{
"amazon-ebs": func() (packer.Builder, error) { return command.Builders["amazon-ebs"], nil },
"amazon-ebs": func() (packer.Builder, error) { return &amazonebsbuilder.Builder{}, nil },
}
}

View File

@ -0,0 +1,23 @@
{
"type": "amazon-ebs",
"region": "us-east-1",
"instance_type": "t2.micro",
"source_ami_filter": {
"filters": {
"virtualization-type": "hvm",
"name": "*Windows_Server-2012-R2*English-64Bit-Base*",
"root-device-type": "ebs"
},
"most_recent": true,
"owners": "amazon"
},
"ami_name": "packer-acc-test",
"user_data_file": "../../builder/amazon/ebs/acceptance/test-fixtures/scripts/bootstrap_win.txt",
"communicator": "winrm",
"winrm_username": "Administrator",
"winrm_password": "SuperS3cr3t!!!!",
"force_deregister" : true,
"tags": {
"packer-test": "true"
}
}

View File

@ -0,0 +1,40 @@
<powershell>
# Set administrator password
net user Administrator SuperS3cr3t!!!!
wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE
# First, make sure WinRM can't be connected to
netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block
# Delete any existing WinRM listeners
winrm delete winrm/config/listener?Address=*+Transport=HTTP 2>$Null
winrm delete winrm/config/listener?Address=*+Transport=HTTPS 2>$Null
# Disable group policies which block basic authentication and unencrypted login
Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WinRM\Client -Name AllowBasic -Value 1
Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WinRM\Client -Name AllowUnencryptedTraffic -Value 1
Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WinRM\Service -Name AllowBasic -Value 1
Set-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WinRM\Service -Name AllowUnencryptedTraffic -Value 1
# Create a new WinRM listener and configure
winrm create winrm/config/listener?Address=*+Transport=HTTP
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="0"}'
winrm set winrm/config '@{MaxTimeoutms="7200000"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
winrm set winrm/config/service '@{MaxConcurrentOperationsPerUser="12000"}'
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/client/auth '@{Basic="true"}'
# Configure UAC to allow privilege elevation in remote shells
$Key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
$Setting = 'LocalAccountTokenFilterPolicy'
Set-ItemProperty -Path $Key -Name $Setting -Value 1 -Force
# Configure and restart the WinRM Service; Enable the required firewall exception
Stop-Service -Name WinRM
Set-Service -Name WinRM -StartupType Automatic
netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new action=allow localip=any remoteip=any
Start-Service -Name WinRM
</powershell>

View File

@ -52,7 +52,7 @@ type Config struct {
// Tags to apply to the volumes that are *launched* to create the AMI.
// These tags are *not* applied to the resulting AMI unless they're
// duplicated in `tags`. This is a [template
// engine](/docs/templates/engine.html), see [Build template
// engine](/docs/templates/engine), see [Build template
// data](#build-template-data) for more information.
VolumeRunTags awscommon.TagMap `mapstructure:"run_volume_tags"`
// Relevant only to Windows guests: If you set this flag, we'll add clauses

View File

@ -58,7 +58,7 @@ type Config struct {
// Tags to apply to the volumes that are *launched* to create the AMI.
// These tags are *not* applied to the resulting AMI unless they're
// duplicated in `tags`. This is a [template
// engine](/docs/templates/engine.html), see [Build template
// engine](/docs/templates/engine), see [Build template
// data](#build-template-data) for more information.
VolumeRunTags awscommon.TagMap `mapstructure:"run_volume_tags"`
// what architecture to use when registering the

View File

@ -12,12 +12,12 @@ import (
type BlockDevice struct {
awscommon.BlockDevice `mapstructure:",squash"`
// Tags to apply to the volume. These are retained after the builder
// completes. This is a [template engine](/docs/templates/engine.html), see
// completes. This is a [template engine](/docs/templates/engine), see
// [Build template data](#build-template-data) for more information.
Tags map[string]string `mapstructure:"tags" required:"false"`
// Same as [`tags`](#tags) but defined as a singular repeatable block
// containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
Tag hcl2template.NameValues `mapstructure:"tag" required:"false"`
}

View File

@ -57,7 +57,7 @@ type Config struct {
// create EBS Volumes. These tags will *not* appear in the tags of the
// resulting EBS volumes unless they're duplicated under `tags` in the
// `ebs_volumes` setting. This is a [template
// engine](/docs/templates/engine.html), see [Build template
// engine](/docs/templates/engine), see [Build template
// data](#build-template-data) for more information.
//
// Note: The tags specified here will be *temporarily* applied to volumes
@ -69,7 +69,7 @@ type Config struct {
// Same as [`run_volume_tags`](#run_volume_tags) but defined as a singular
// repeatable block containing a `name` and a `value` field. In HCL2 mode
// the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
VolumeRunTag hcl2template.NameValues `mapstructure:"run_volume_tag"`

View File

@ -61,7 +61,7 @@ type Config struct {
// exist and be writable.
BundleDestination string `mapstructure:"bundle_destination" required:"false"`
// The prefix for files created from bundling the root volume. By default
// this is image-{{timestamp}}. The timestamp variable should be used to
// this is `image-{{timestamp}}`. The timestamp variable should be used to
// make sure this is unique, otherwise it can collide with other created
// AMIs by Packer in your account.
BundlePrefix string `mapstructure:"bundle_prefix" required:"false"`

View File

@ -247,7 +247,7 @@ type Config struct {
AzureTags map[string]*string `mapstructure:"azure_tags" required:"false"`
// Same as [`azure_tags`](#azure_tags) but defined as a singular repeatable block
// containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
AzureTag hcl2template.NameValues `mapstructure:"azure_tag" required:"false"`
// Resource group under which the final artifact will be stored.
@ -399,6 +399,7 @@ type Config struct {
tmpDeploymentName string
tmpKeyVaultName string
tmpOSDiskName string
tmpDataDiskName string
tmpSubnetName string
tmpVirtualNetworkName string
tmpNsgName string
@ -655,6 +656,7 @@ func setRuntimeValues(c *Config) {
c.tmpNicName = tempName.NicName
c.tmpPublicIPAddressName = tempName.PublicIPAddressName
c.tmpOSDiskName = tempName.OSDiskName
c.tmpDataDiskName = tempName.DataDiskname
c.tmpSubnetName = tempName.SubnetName
c.tmpVirtualNetworkName = tempName.VirtualNetworkName
c.tmpNsgName = tempName.NsgName

View File

@ -37,6 +37,7 @@ func GetVirtualMachineDeployment(config *Config) (*resources.Deployment, error)
DnsNameForPublicIP: &template.TemplateParameter{Value: config.tmpComputeName},
NicName: &template.TemplateParameter{Value: config.tmpNicName},
OSDiskName: &template.TemplateParameter{Value: config.tmpOSDiskName},
DataDiskName: &template.TemplateParameter{Value: config.tmpDataDiskName},
PublicIPAddressName: &template.TemplateParameter{Value: config.tmpPublicIPAddressName},
SubnetName: &template.TemplateParameter{Value: config.tmpSubnetName},
StorageAccountBlobEndpoint: &template.TemplateParameter{Value: config.storageAccountBlobEndpoint},
@ -96,7 +97,7 @@ func GetVirtualMachineDeployment(config *Config) (*resources.Deployment, error)
if len(config.AdditionalDiskSize) > 0 {
isManaged := config.CustomManagedImageName != "" || (config.ManagedImageName != "" && config.ImagePublisher != "") || config.SharedGallery.Subscription != ""
builder.SetAdditionalDisks(config.AdditionalDiskSize, isManaged, config.diskCachingType)
builder.SetAdditionalDisks(config.AdditionalDiskSize, config.tmpDataDiskName, isManaged, config.diskCachingType)
}
if config.customData != "" {

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},
@ -144,9 +147,9 @@
"createOption": "Empty",
"diskSizeGB": 32,
"lun": 0,
"name": "datadisk-1",
"name": "[concat(parameters('dataDiskName'),'-1')]",
"vhd": {
"uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/datadisk-', '1','.vhd')]"
"uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),parameters('dataDiskName'), '-1','.vhd')]"
}
}
],

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},
@ -147,7 +150,7 @@
"managedDisk": {
"storageAccountType": "Standard_LRS"
},
"name": "datadisk-1"
"name": "[concat(parameters('dataDiskName'),'-1')]"
}
],
"imageReference": {

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -15,6 +15,7 @@ type TempName struct {
KeyVaultName string
ResourceGroupName string
OSDiskName string
DataDiskname string
NicName string
SubnetName string
PublicIPAddressName string
@ -25,6 +26,7 @@ type TempName struct {
func NewTempName(p string) *TempName {
tempName := &TempName{}
if p == "" {
suffix := random.AlphaNumLower(10)
tempName.ComputeName = fmt.Sprintf("pkrvm%s", suffix)

View File

@ -231,7 +231,7 @@ func (s *TemplateBuilder) SetOSDiskSizeGB(diskSizeGB int32) error {
return nil
}
func (s *TemplateBuilder) SetAdditionalDisks(diskSizeGB []int32, isManaged bool, cachingType compute.CachingTypes) error {
func (s *TemplateBuilder) SetAdditionalDisks(diskSizeGB []int32, dataDiskname string, isManaged bool, cachingType compute.CachingTypes) error {
resource, err := s.getResourceByType(resourceVirtualMachine)
if err != nil {
return err
@ -243,7 +243,8 @@ func (s *TemplateBuilder) SetAdditionalDisks(diskSizeGB []int32, isManaged bool,
for i, additionalSize := range diskSizeGB {
dataDisks[i].DiskSizeGB = to.Int32Ptr(additionalSize)
dataDisks[i].Lun = to.IntPtr(i)
dataDisks[i].Name = to.StringPtr(fmt.Sprintf("datadisk-%d", i+1))
// dataDisks[i].Name = to.StringPtr(fmt.Sprintf("%s-%d", dataDiskname, i+1))
dataDisks[i].Name = to.StringPtr(fmt.Sprintf("[concat(parameters('dataDiskName'),'-%d')]", i+1))
dataDisks[i].CreateOption = "Empty"
dataDisks[i].Caching = cachingType
if isManaged {
@ -251,7 +252,7 @@ func (s *TemplateBuilder) SetAdditionalDisks(diskSizeGB []int32, isManaged bool,
dataDisks[i].ManagedDisk = profile.OsDisk.ManagedDisk
} else {
dataDisks[i].Vhd = &compute.VirtualHardDisk{
URI: to.StringPtr(fmt.Sprintf("[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/datadisk-', '%d','.vhd')]", i+1)),
URI: to.StringPtr(fmt.Sprintf("[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),parameters('dataDiskName'), '-%d','.vhd')]", i+1)),
}
dataDisks[i].ManagedDisk = nil
}
@ -581,7 +582,10 @@ const BasicTemplate = `{
},
"vmName": {
"type": "string"
}
},
"dataDiskName": {
"type": "string"
}
},
"variables": {
"addressPrefix": "10.0.0.0/16",

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},
@ -161,7 +164,7 @@
"managedDisk": {
"storageAccountType": "Premium_LRS"
},
"name": "datadisk-1"
"name": "[concat(parameters('dataDiskName'),'-1')]"
},
{
"caching": "ReadWrite",
@ -171,7 +174,7 @@
"managedDisk": {
"storageAccountType": "Premium_LRS"
},
"name": "datadisk-2"
"name": "[concat(parameters('dataDiskName'),'-2')]"
}
],
"imageReference": {

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},
@ -158,9 +161,9 @@
"createOption": "Empty",
"diskSizeGB": 32,
"lun": 0,
"name": "datadisk-1",
"name": "[concat(parameters('dataDiskName'),'-1')]",
"vhd": {
"uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/datadisk-', '1','.vhd')]"
"uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),parameters('dataDiskName'), '-1','.vhd')]"
}
},
{
@ -168,9 +171,9 @@
"createOption": "Empty",
"diskSizeGB": 64,
"lun": 1,
"name": "datadisk-2",
"name": "[concat(parameters('dataDiskName'),'-2')]",
"vhd": {
"uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/datadisk-', '2','.vhd')]"
"uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),parameters('dataDiskName'), '-2','.vhd')]"
}
}
],

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -8,6 +8,9 @@
"adminUsername": {
"type": "string"
},
"dataDiskName": {
"type": "string"
},
"dnsNameForPublicIP": {
"type": "string"
},

View File

@ -138,7 +138,7 @@ func TestBuildWindows01(t *testing.T) {
t.Fatal(err)
}
err = testSubject.SetAdditionalDisks([]int32{32, 64}, true, compute.CachingTypesReadWrite)
err = testSubject.SetAdditionalDisks([]int32{32, 64}, "datadisk", true, compute.CachingTypesReadWrite)
if err != nil {
t.Fatal(err)
}
@ -166,7 +166,7 @@ func TestBuildWindows02(t *testing.T) {
t.Fatal(err)
}
err = testSubject.SetAdditionalDisks([]int32{32, 64}, false, compute.CachingTypesReadWrite)
err = testSubject.SetAdditionalDisks([]int32{32, 64}, "datadisk", false, compute.CachingTypesReadWrite)
if err != nil {
t.Fatal(err)
}

View File

@ -27,6 +27,7 @@ type TemplateParameters struct {
ObjectId *TemplateParameter `json:"objectId,omitempty"`
NicName *TemplateParameter `json:"nicName,omitempty"`
OSDiskName *TemplateParameter `json:"osDiskName,omitempty"`
DataDiskName *TemplateParameter `json:"dataDiskName,omitempty"`
PublicIPAddressName *TemplateParameter `json:"publicIPAddressName,omitempty"`
StorageAccountBlobEndpoint *TemplateParameter `json:"storageAccountBlobEndpoint,omitempty"`
SubnetName *TemplateParameter `json:"subnetName,omitempty"`

View File

@ -103,32 +103,34 @@ type Config struct {
// as the source for this build. *VHD targets are incompatible with this
// build type* - the target must be a *Managed Image*.
//
// "shared_image_gallery": {
// "subscription": "00000000-0000-0000-0000-00000000000",
// "resource_group": "ResourceGroup",
// "gallery_name": "GalleryName",
// "image_name": "ImageName",
// "image_version": "1.0.0"
// }
// "managed_image_name": "TargetImageName",
// "managed_image_resource_group_name": "TargetResourceGroup"
// ```json
// "shared_image_gallery": {
// "subscription": "00000000-0000-0000-0000-00000000000",
// "resource_group": "ResourceGroup",
// "gallery_name": "GalleryName",
// "image_name": "ImageName",
// "image_version": "1.0.0"
// }
// "managed_image_name": "TargetImageName",
// "managed_image_resource_group_name": "TargetResourceGroup"
// ```
SharedGallery SharedImageGallery `mapstructure:"shared_image_gallery"`
// The name of the Shared Image Gallery under which the managed image will be published as Shared Gallery Image version.
//
// Following is an example.
//
// <!-- -->
//
// "shared_image_gallery_destination": {
// "resource_group": "ResourceGroup",
// "gallery_name": "GalleryName",
// "image_name": "ImageName",
// "image_version": "1.0.0",
// "replication_regions": ["regionA", "regionB", "regionC"]
// }
// "managed_image_name": "TargetImageName",
// "managed_image_resource_group_name": "TargetResourceGroup"
// ```json
// "shared_image_gallery_destination": {
// "resource_group": "ResourceGroup",
// "gallery_name": "GalleryName",
// "image_name": "ImageName",
// "image_version": "1.0.0",
// "replication_regions": ["regionA", "regionB", "regionC"]
// }
// "managed_image_name": "TargetImageName",
// "managed_image_resource_group_name": "TargetResourceGroup"
// ```
SharedGalleryDestination SharedImageGalleryDestination `mapstructure:"shared_image_gallery_destination"`
// How long to wait for an image to be published to the shared image

View File

@ -114,7 +114,7 @@ type Config struct {
SourceTemplate string `mapstructure:"source_template" required:"true"`
// The name of the temporary SSH key pair
// to generate. By default, Packer generates a name that looks like
// packer_<UUID>, where <UUID> is a 36 character unique identifier.
// `packer_<UUID>`, where `<UUID>` is a 36 character unique identifier.
TemporaryKeypairName string `mapstructure:"temporary_keypair_name" required:"false"`
// Set to true to indicate that the
// provisioners should connect to the local IP address of the instance.
@ -134,7 +134,7 @@ type Config struct {
// created.
Zone string `mapstructure:"zone" required:"true"`
// The name of the new template. Defaults to
// "packer-{{timestamp}}" where timestamp will be the current time.
// `packer-{{timestamp}}` where timestamp will be the current time.
TemplateName string `mapstructure:"template_name" required:"false"`
// The display text of the new template.
// Defaults to the template_name.

View File

@ -55,7 +55,7 @@ type Config struct {
// created. This defaults to false, or not enabled.
IPv6 bool `mapstructure:"ipv6" required:"false"`
// The name of the resulting snapshot that will
// appear in your account. Defaults to "packer-{{timestamp}}" (see
// appear in your account. Defaults to `packer-{{timestamp}}` (see
// configuration templates for more info).
SnapshotName string `mapstructure:"snapshot_name" required:"false"`
// The regions of the resulting

View File

@ -36,12 +36,12 @@ type Config struct {
Commit bool `mapstructure:"commit" required:"true"`
// The directory inside container to mount temp directory from host server
// for work [file provisioner](/docs/provisioners/file.html). This defaults
// for work [file provisioner](/docs/provisioners/file). This defaults
// to c:/packer-files on windows and /packer-files on other systems.
ContainerDir string `mapstructure:"container_dir" required:"false"`
// Throw away the container when the build is complete. This is useful for
// the [artifice
// post-processor](https://www.packer.io/docs/post-processors/artifice.html).
// post-processor](/docs/post-processors/artifice).
Discard bool `mapstructure:"discard" required:"true"`
// Username (UID) to run remote commands with. You can also set the group
// name/ID if you want: (UID or UID:GID). You may need this if you get
@ -63,10 +63,10 @@ type Config struct {
// used. This defaults to true if not set.
Pull bool `mapstructure:"pull" required:"false"`
// An array of arguments to pass to docker run in order to run the
// container. By default this is set to ["-d", "-i", "-t",
// "--entrypoint=/bin/sh", "--", "{{.Image}}"] if you are using a linux
// container, and ["-d", "-i", "-t", "--entrypoint=powershell", "--",
// "{{.Image}}"] if you are running a windows container. {{.Image}} is a
// container. By default this is set to `["-d", "-i", "-t",
// "--entrypoint=/bin/sh", "--", "{{.Image}}"]` if you are using a linux
// container, and `["-d", "-i", "-t", "--entrypoint=powershell", "--",
// "{{.Image}}"]` if you are running a windows container. `{{.Image}}` is a
// template variable that corresponds to the image template option. Passing
// the entrypoint option this way will make it the default entrypoint of
// the resulting image, so running docker run -it --rm will start the

View File

@ -58,7 +58,7 @@ type Config struct {
// Defaults to pd-standard.
DiskType string `mapstructure:"disk_type" required:"false"`
// The unique name of the resulting image. Defaults to
// "packer-{{timestamp}}".
// `packer-{{timestamp}}`.
ImageName string `mapstructure:"image_name" required:"false"`
// The description of the resulting image.
ImageDescription string `mapstructure:"image_description" required:"false"`
@ -84,7 +84,7 @@ type Config struct {
// Licenses to apply to the created image.
ImageLicenses []string `mapstructure:"image_licenses" required:"false"`
// A name to give the launched instance. Beware that this must be unique.
// Defaults to "packer-{{uuid}}".
// Defaults to `packer-{{uuid}}`.
InstanceName string `mapstructure:"instance_name" required:"false"`
// Key/value pair labels to apply to the launched instance.
Labels map[string]string `mapstructure:"labels" required:"false"`
@ -172,7 +172,7 @@ type Config struct {
// Google's cloud. The value should be the path of the token generator
// within vault.
// For information on how to configure your Vault + GCP engine to produce
// Oauth tokens, see https://www.vaultproject.io/docs/auth/gcp.html
// Oauth tokens, see https://www.vaultproject.io/docs/auth/gcp
// You must have the environment variables VAULT_ADDR and VAULT_TOKEN set,
// along with any other relevant variables for accessing your vault
// instance. For more information, see the Vault docs:

View File

@ -56,7 +56,7 @@ type Config struct {
// ID or name of the image to launch server from.
SourceImage string `mapstructure:"source_image" required:"true"`
// The name of the resulting image. Defaults to
// "packer-{{timestamp}}"
// `packer-{{timestamp}}`
// (see configuration templates for more info).
ImageName string `mapstructure:"image_name" required:"false"`
// The description of the resulting image.
@ -65,7 +65,7 @@ type Config struct {
ImageTags map[string]string `mapstructure:"image_tags" required:"false"`
// Same as [`image_tags`](#image_tags) but defined as a singular repeatable
// block containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
ImageTag hcl2template.NameValues `mapstructure:"image_tag" required:"false"`
// The service of the resulting image.
@ -79,7 +79,7 @@ type Config struct {
VmTags map[string]string `mapstructure:"vm_tags" required:"false"`
// Same as [`vm_tags`](#vm_tags) but defined as a singular repeatable block
// containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
VmTag hcl2template.NameValues `mapstructure:"vm_tag" required:"false"`
// The name of the created disk.
@ -107,11 +107,11 @@ type Config struct {
ChrootMountPath string `mapstructure:"chroot_mount_path"`
ChrootMounts [][]string `mapstructure:"chroot_mounts"`
ChrootCopyFiles []string `mapstructure:"chroot_copy_files"`
// How to run shell commands. This defaults to {{.Command}}. This may be
// How to run shell commands. This defaults to `{{.Command}}`. This may be
// useful to set if you want to set environmental variables or perhaps run
// it with sudo or so on. This is a configuration template where the
// .Command variable is replaced with the command to be run. Defaults to
// {{.Command}}.
// `{{.Command}}`.
ChrootCommandWrapper string `mapstructure:"chroot_command_wrapper"`
MountOptions []string `mapstructure:"mount_options"`
@ -119,11 +119,11 @@ type Config struct {
// A series of commands to execute after attaching the root volume and
// before mounting the chroot. This is not required unless using
// from_scratch. If so, this should include any partitioning and filesystem
// creation commands. The path to the device is provided by {{.Device}}.
// creation commands. The path to the device is provided by `{{.Device}}`.
PreMountCommands []string `mapstructure:"pre_mount_commands"`
// As pre_mount_commands, but the commands are executed after mounting the
// root device and before the extra mount and copy steps. The device and
// mount path are provided by {{.Device}} and {{.MountPath}}.
// mount path are provided by `{{.Device}}` and `{{.MountPath}}`.
PostMountCommands []string `mapstructure:"post_mount_commands"`
// List of SSH keys by name or id to be added
// to the server on launch.

View File

@ -20,11 +20,11 @@ type Config struct {
// The path to the lxc configuration file.
ConfigFile string `mapstructure:"config_file" required:"true"`
// The directory in which to save the exported
// tar.gz. Defaults to output-<BuildName> in the current directory.
// tar.gz. Defaults to `output-<BuildName>` in the current directory.
OutputDir string `mapstructure:"output_directory" required:"false"`
// The name of the LXC container. Usually stored
// in /var/lib/lxc/containers/<container_name>. Defaults to
// packer-<BuildName>.
// in `/var/lib/lxc/containers/<container_name>`. Defaults to
// `packer-<BuildName>`.
ContainerName string `mapstructure:"container_name" required:"false"`
// Allows you to specify a wrapper command, such
// as ssh so you can execute packer builds on a remote host. Defaults to
@ -53,7 +53,7 @@ type Config struct {
Name string `mapstructure:"template_name" required:"true"`
// Options to pass to the given
// lxc-template command, usually located in
// /usr/share/lxc/templates/lxc-<template_name>. Note: This gets passed as
// `/usr/share/lxc/templates/lxc-<template_name>`. Note: This gets passed as
// ARGV to the template command. Ensure you have an array of strings, as a
// single string with spaces probably won't work. Defaults to [].
Parameters []string `mapstructure:"template_parameters" required:"false"`

View File

@ -20,7 +20,7 @@ type Config struct {
OutputImage string `mapstructure:"output_image" required:"false"`
ContainerName string `mapstructure:"container_name"`
// Lets you prefix all builder commands, such as
// with ssh for a remote build host. Defaults to "{{.Command}}"; i.e. no
// with ssh for a remote build host. Defaults to `{{.Command}}`; i.e. no
// wrapper.
CommandWrapper string `mapstructure:"command_wrapper" required:"false"`
// The source image to use when creating the build

View File

@ -66,13 +66,9 @@ type RunConfig struct {
// following are valid:
//
// - name (string)
//
// - owner (string)
//
// - tags (array of strings)
//
// - visibility (string)
//
// - properties (map of strings to strings) (fields that can be set
// with `openstack image set --property key=value`)
//

View File

@ -29,7 +29,7 @@ type ToolsConfig struct {
// is "upload". This is a configuration
// template that has a single
// valid variable: Flavor, which will be the value of
// parallels_tools_flavor. By default this is "prl-tools-{{.Flavor}}.iso"
// parallels_tools_flavor. By default this is `prl-tools-{{.Flavor}}.iso`
// which should upload into the login directory of the user.
ParallelsToolsGuestPath string `mapstructure:"parallels_tools_guest_path" required:"false"`
// The method by which Parallels Tools are

View File

@ -65,7 +65,7 @@ type Config struct {
HardDriveInterface string `mapstructure:"hard_drive_interface" required:"false"`
// A list of which interfaces on the
// host should be searched for a IP address. The first IP address found on one
// of these will be used as {{ .HTTPIP }} in the boot_command. Defaults to
// of these will be used as `{{ .HTTPIP }}` in the boot_command. Defaults to
// ["en0", "en1", "en2", "en3", "en4", "en5", "en6", "en7", "en8", "en9",
// "ppp0", "ppp1", "ppp2"].
HostInterfaces []string `mapstructure:"host_interfaces" required:"false"`

View File

@ -86,7 +86,7 @@ type TencentCloudRunConfig struct {
RunTags map[string]string `mapstructure:"run_tags" required:"false"`
// Same as [`run_tags`](#run_tags) but defined as a singular repeatable
// block containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
RunTag hcl2template.NameValues `mapstructure:"run_tag" required:"false"`

View File

@ -57,7 +57,7 @@ type SourceMachineConfig struct {
MachineTags map[string]string `mapstructure:"source_machine_tags" required:"false"`
// Same as [`source_machine_tags`](#source_machine_tags) but defined as a
// singular block containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
MachineTag hcl2template.NameValues `mapstructure:"source_machine_tag" required:"false"`
// Whether or not the firewall

View File

@ -39,7 +39,7 @@ type TargetImageConfig struct {
ImageTags map[string]string `mapstructure:"image_tags" required:"false"`
// Same as [`image_tags`](#image_tags) but defined as a singular repeatable
// block containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks)
// [`dynamic_block`](/docs/configuration/from-1.5/expressions#dynamic-blocks)
// will allow you to create those programatically.
ImageTag hcl2template.NameValues `mapstructure:"image_tag" required:"false"`
}

View File

@ -90,7 +90,7 @@ type Config struct {
BoxVersion string `mapstructure:"box_version" required:"false"`
// a path to a golang template for a vagrantfile. Our default template can
// be found here. The template variables available to you are
// {{ .BoxName }}, {{ .SyncedFolder }}, and {{.InsertKey}}, which
// `{{ .BoxName }}`, `{{ .SyncedFolder }}`, and `{{.InsertKey}}`, which
// correspond to the Packer options box_name, synced_folder, and insert_key.
Template string `mapstructure:"template" required:"false"`

View File

@ -39,8 +39,7 @@ type ExportConfig struct {
// packer call like this (shell `>` continuation character snipped for easier
// copy & paste):
//
// ``` {.shell}
//
// ``` shell
// vm_description='some
// multiline
// description'

View File

@ -14,7 +14,7 @@ type VBoxManageConfig struct {
// array of strings, where each string represents a single argument on the
// command-line to `VBoxManage` (but excluding `VBoxManage` itself). Each
// arg is treated as a [configuration
// template](/docs/templates/engine.html), where the `Name` variable is
// template](/docs/templates/engine), where the `Name` variable is
// replaced with the VM name. More details on how to use `VBoxManage` are
// below.
VBoxManage [][]string `mapstructure:"vboxmanage" required:"false"`

View File

@ -9,7 +9,8 @@ import (
"os"
"path/filepath"
"github.com/hashicorp/packer/command"
"github.com/hashicorp/packer/builder/virtualbox/iso"
"github.com/hashicorp/packer/packer"
testshelper "github.com/hashicorp/packer/helper/tests"
@ -40,6 +41,6 @@ func (v *VirtualBoxISOAccTest) CleanUp() error {
func (v *VirtualBoxISOAccTest) GetBuilderStore() packer.MapOfBuilder {
return packer.MapOfBuilder{
"virtualbox-iso": func() (packer.Builder, error) { return command.Builders["virtualbox-iso"], nil },
"virtualbox-iso": func() (packer.Builder, error) { return &iso.Builder{}, nil },
}
}

View File

@ -22,7 +22,7 @@ type ExportConfig struct {
// argument. Currently, exporting the build VM (with ovftool) is only
// supported when building on ESXi e.g. when `remote_type` is set to
// `esx5`. See the [Building on a Remote vSphere
// Hypervisor](/docs/builders/vmware-iso.html#building-on-a-remote-vsphere-hypervisor)
// Hypervisor](/docs/builders/vmware-iso#building-on-a-remote-vsphere-hypervisor)
// section below for more info.
OVFToolOptions []string `mapstructure:"ovftool_options" required:"false"`
// Defaults to `false`. When enabled, Packer will not export the VM. Useful
@ -30,7 +30,7 @@ type ExportConfig struct {
// VM. Currently, exporting the build VM is only supported when building on
// ESXi e.g. when `remote_type` is set to `esx5`. See the [Building on a
// Remote vSphere
// Hypervisor](/docs/builders/vmware-iso.html#building-on-a-remote-vsphere-hypervisor)
// Hypervisor](/docs/builders/vmware-iso#building-on-a-remote-vsphere-hypervisor)
// section below for more info.
SkipExport bool `mapstructure:"skip_export" required:"false"`
// Set this to true if you would like to keep

View File

@ -46,39 +46,39 @@ type HWConfig struct {
// * `FILE:path(,yield)` - Specifies the path to the local file to be used
// as the serial port.
//
// * `yield` (bool) - This is an optional boolean that specifies
// whether the vm should yield the cpu when polling the port. By
// default, the builder will assume this as `FALSE`.
// * `yield` (bool) - This is an optional boolean that specifies
// whether the vm should yield the cpu when polling the port. By
// default, the builder will assume this as `FALSE`.
//
// * `DEVICE:path(,yield)` - Specifies the path to the local device to be
//  used as the serial port. If `path` is empty, then default to the first
// serial port.
//
// * `yield` (bool) - This is an optional boolean that specifies
// whether the vm should yield the cpu when polling the port. By
// default, the builder will assume this as `FALSE`.
// * `yield` (bool) - This is an optional boolean that specifies
// whether the vm should yield the cpu when polling the port. By
// default, the builder will assume this as `FALSE`.
//
// * `PIPE:path,endpoint,host(,yield)` - Specifies to use the named-pipe
// "path" as a serial port. This has a few options that determine how the
// VM should use the named-pipe.
//
// * `endpoint` (string) - Chooses the type of the VM-end, which can be
// either a `client` or `server`.
// * `endpoint` (string) - Chooses the type of the VM-end, which can be
// either a `client` or `server`.
//
// * `host` (string) - Chooses the type of the host-end, which can
// be either `app` (application) or `vm` (another virtual-machine).
// * `host` (string) - Chooses the type of the host-end, which can
// be either `app` (application) or `vm` (another virtual-machine).
//
// * `yield` (bool) - This is an optional boolean that specifies
// whether the vm should yield the cpu when polling the port. By
// default, the builder will assume this as `FALSE`.
// * `yield` (bool) - This is an optional boolean that specifies
// whether the vm should yield the cpu when polling the port. By
// default, the builder will assume this as `FALSE`.
//
// * `AUTO:(yield)` - Specifies to use auto-detection to determine the
// serial port to use. This has one option to determine how the VM should
// support the serial port.
//
// * `yield` (bool) - This is an optional boolean that specifies
// whether the vm should yield the cpu when polling the port. By
// default, the builder will assume this as `FALSE`.
// * `yield` (bool) - This is an optional boolean that specifies
// whether the vm should yield the cpu when polling the port. By
// default, the builder will assume this as `FALSE`.
//
// * `NONE` - Specifies to not use a serial port. (default)
//

View File

@ -13,7 +13,7 @@ type ToolsConfig struct {
ToolsUploadFlavor string `mapstructure:"tools_upload_flavor" required:"false"`
// The path in the VM to upload the VMware tools. This only takes effect if
// `tools_upload_flavor` is non-empty. This is a [configuration
// template](/docs/templates/engine.html) that has a single valid variable:
// template](/docs/templates/engine) that has a single valid variable:
// `Flavor`, which will be the value of `tools_upload_flavor`. By default
// the upload path is set to `{{.Flavor}}.iso`. This setting is not used
// when `remote_type` is `esx5`.

View File

@ -107,7 +107,7 @@ type Config struct {
VMName string `mapstructure:"vm_name" required:"false"`
VMXDiskTemplatePath string `mapstructure:"vmx_disk_template_path"`
// Path to a [configuration template](/docs/templates/engine.html) that
// Path to a [configuration template](/docs/templates/engine) that
// defines the contents of the virtual machine VMX file for VMware. The
// engine has access to the template variables `{{ .DiskNumber }}` and
// `{{ .DiskName }}`.

View File

@ -42,7 +42,7 @@ import (
// ```
// The above configuration would create the following files:
//
// ```
// ```text
// ./output_vsphere/example-ubuntu-disk-0.vmdk
// ./output_vsphere/example-ubuntu.mf
// ./output_vsphere/example-ubuntu.ovf

View File

@ -64,18 +64,18 @@ func main() {
header := Struct{
SourcePath: sourcePath,
Name: typeSpec.Name.Name,
Filename: "_" + typeSpec.Name.Name + ".html.md",
Filename: typeSpec.Name.Name + ".mdx",
Header: typeDecl.Doc.Text(),
}
required := Struct{
SourcePath: sourcePath,
Name: typeSpec.Name.Name,
Filename: "_" + typeSpec.Name.Name + "-required.html.md",
Filename: typeSpec.Name.Name + "-required.mdx",
}
notRequired := Struct{
SourcePath: sourcePath,
Name: typeSpec.Name.Name,
Filename: "_" + typeSpec.Name.Name + "-not-required.html.md",
Filename: typeSpec.Name.Name + "-not-required.mdx",
}
for _, field := range fields {
@ -133,7 +133,7 @@ func main() {
}
}
dir := filepath.Join(packerDir, "website", "source", "partials", builderName)
dir := filepath.Join(packerDir, "website", "pages", "partials", builderName)
os.MkdirAll(dir, 0755)
for _, str := range []Struct{header, required, notRequired} {

View File

@ -50,7 +50,7 @@ func (c *VersionCommand) Run(args []string) int {
if info.Outdated {
c.Ui.Say(fmt.Sprintf(
"\nYour version of Packer is out of date! The latest version\n"+
"is %s. You can update by downloading from www.packer.io/downloads.html",
"is %s. You can update by downloading from www.packer.io/downloads",
info.Latest))
}
}

View File

@ -105,7 +105,7 @@ import (
// ]
// ```
// For more examples of various boot commands, see the sample projects from our
// [community templates page](/community-tools.html#templates).
// [community templates page](/community-tools#templates).
type BootConfig struct {
// Time to wait after sending a group of key pressses. The value of this
// should be a duration. Examples are `5s` and `1m30s` which will cause
@ -117,7 +117,8 @@ type BootConfig struct {
// the `boot_command`. The value of this should be a duration. Examples are
// `5s` and `1m30s` which will cause Packer to wait five seconds and one
// minute 30 seconds, respectively. If this isn't specified, the default is
// `10s` or 10 seconds.
// `10s` or 10 seconds. To set boot_wait to 0s, use a negative number, such
// as "-1s"
BootWait time.Duration `mapstructure:"boot_wait"`
// This is an array of commands to type when the virtual machine is first
// booted. The goal of these commands should be to type just enough to

View File

@ -18,7 +18,7 @@ import (
// is attached as the first floppy device. The summary size of the listed files
// must not exceed 1.44 MB. The supported ways to move large files into the OS
// are using `http_directory` or [the file
// provisioner](https://www.packer.io/docs/provisioners/file.html).
// provisioner](/docs/provisioners/file).
type FloppyConfig struct {
// A list of files to place onto a floppy disk that is attached when the VM
// is booted. Currently, no support exists for creating sub-directories on

View File

@ -894,7 +894,7 @@ func scpUploadFile(dst string, src io.Reader, w io.Writer, r *bufio.Reader, fi *
if _, err := io.Copy(tf, src); err != nil {
return fmt.Errorf("Error copying input data into local temporary "+
"file. Check that TEMPDIR has enough space. Please see "+
"https://www.packer.io/docs/other/environment-variables.html#tmpdir"+
"https://www.packer.io/docs/other/environment-variables#tmpdir"+
"for more info. Error: %s", err)
}

View File

@ -73,7 +73,7 @@ func (v *Variable) Value() (cty.Value, *hcl.Diagnostic) {
Severity: hcl.DiagError,
Summary: fmt.Sprintf("Unset variable %q", v.Name),
Detail: "A used variable must be set or have a default value; see " +
"https://packer.io/docs/configuration/from-1.5/syntax.html for " +
"https://packer.io/docs/configuration/from-1.5/syntax for " +
"details.",
Context: v.Range.Ptr(),
}

View File

@ -175,7 +175,7 @@ type WinRM struct {
//
// NOTE: If using an Amazon EBS builder, you can specify the interface
// WinRM connects to via
// [`ssh_interface`](https://www.packer.io/docs/builders/amazon-ebs.html#ssh_interface)
// [`ssh_interface`](/docs/builders/amazon-ebs#ssh_interface)
WinRMHost string `mapstructure:"winrm_host"`
// The WinRM port to connect to. This defaults to `5985` for plain
// unencrypted connection and `5986` for SSL when `winrm_use_ssl` is set to

View File

@ -3,13 +3,14 @@ package acc
import (
"bytes"
"fmt"
"github.com/hashicorp/packer/helper/tests"
"log"
"os"
"path/filepath"
"strings"
"testing"
testshelper "github.com/hashicorp/packer/helper/tests"
amazonEBS "github.com/hashicorp/packer/builder/amazon/ebs/acceptance"
virtualboxISO "github.com/hashicorp/packer/builder/virtualbox/iso/acceptance"
"github.com/hashicorp/packer/command"
@ -68,6 +69,26 @@ func TestProvisionersAgainstBuilders(provisionerAcc ProvisionerAcceptance, t *te
}
}
// TestProvisionersPreCheck checks if the Provisioner with name is set in ACC_TEST_PROVISIONERS environment variable
func TestProvisionersPreCheck(name string, t *testing.T) {
p := os.Getenv("ACC_TEST_PROVISIONERS")
if p == "all" {
return
}
provisioners := strings.Split(p, ",")
for _, provisioner := range provisioners {
if provisioner == name {
return
}
}
msg := fmt.Sprintf("Provisioner %q not defined in ACC_TEST_PROVISIONERS", name)
t.Skip(msg)
}
func checkBuilders(t *testing.T) []string {
b := os.Getenv("ACC_TEST_BUILDERS")
// validate if we want to run provisioners acc tests

View File

@ -4,6 +4,7 @@ package powershell
import (
"reflect"
"strconv"
)
// ExecutionPolicy setting to run the command(s).
@ -27,5 +28,14 @@ func StringToExecutionPolicyHook(f reflect.Kind, t reflect.Kind, data interface{
}
raw := data.(string)
// It's possible that the thing being read is not supposed to be an
// execution policy; if the string provided is actally an int, just return
// the int.
i, err := strconv.Atoi(raw)
if err == nil {
return i, nil
}
// If it can't just be cast to an int, try to parse string into an
// execution policy.
return ExecutionPolicyString(raw)
}

View File

@ -188,6 +188,13 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
}
}
if p.config.ExecutionPolicy > 7 {
errs = packer.MultiErrorAppend(errs, fmt.Errorf(`Invalid execution `+
`policy provided. Please supply one of: "bypass", "allsigned",`+
` "default", "remotesigned", "restricted", "undefined", `+
`"unrestricted", "none".`))
}
if errs != nil {
return errs
}

View File

@ -0,0 +1,86 @@
package powershell_test
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/hashicorp/packer/provisioner/powershell"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/packer/command"
"github.com/hashicorp/packer/helper/tests/acc"
"github.com/hashicorp/packer/packer"
)
const TestProvisionerName = "powershell"
func TestPowershellProvisioner_Inline(t *testing.T) {
acc.TestProvisionersPreCheck(TestProvisionerName, t)
testProvisioner := PowershellProvisionerAccTest{"powershell-inline-provisioner.txt"}
acc.TestProvisionersAgainstBuilders(&testProvisioner, t)
}
func TestPowershellProvisioner_Script(t *testing.T) {
acc.TestProvisionersPreCheck(TestProvisionerName, t)
testProvisioner := PowershellProvisionerAccTest{"powershell-script-provisioner.txt"}
acc.TestProvisionersAgainstBuilders(&testProvisioner, t)
}
type PowershellProvisionerAccTest struct {
ConfigName string
}
func (s *PowershellProvisionerAccTest) GetName() string {
return TestProvisionerName
}
func (s *PowershellProvisionerAccTest) GetConfig() (string, error) {
filePath := filepath.Join("./test-fixtures", s.ConfigName)
config, err := os.Open(filePath)
if err != nil {
return "", fmt.Errorf("os.Open:%v", err)
}
defer config.Close()
file, err := ioutil.ReadAll(config)
if err != nil {
return "", fmt.Errorf("ioutil.ReadAll:%v", err)
}
return string(file), nil
}
func (s *PowershellProvisionerAccTest) GetProvisionerStore() packer.MapOfProvisioner {
return packer.MapOfProvisioner{
TestProvisionerName: func() (packer.Provisioner, error) { return &powershell.Provisioner{}, nil },
}
}
func (s *PowershellProvisionerAccTest) IsCompatible(builder string, vmOS string) bool {
return vmOS == "windows"
}
func (s *PowershellProvisionerAccTest) RunTest(c *command.BuildCommand, args []string) error {
UUID := os.Getenv("PACKER_RUN_UUID")
if UUID == "" {
UUID, _ = uuid.GenerateUUID()
os.Setenv("PACKER_RUN_UUID", UUID)
}
if code := c.Run(args); code != 0 {
ui := c.Meta.Ui.(*packer.BasicUi)
out := ui.Writer.(*bytes.Buffer)
err := ui.ErrorWriter.(*bytes.Buffer)
return fmt.Errorf(
"Bad exit code.\n\nStdout:\n\n%s\n\nStderr:\n\n%s",
out.String(),
err.String())
}
return nil
}

View File

@ -3,6 +3,7 @@ package powershell
import (
"bytes"
"context"
"fmt"
"io/ioutil"
"os"
"regexp"
@ -11,6 +12,7 @@ import (
"time"
"github.com/hashicorp/packer/packer"
"github.com/stretchr/testify/assert"
)
func testConfig() map[string]interface{} {
@ -564,6 +566,113 @@ func TestProvisioner_createFlattenedElevatedEnvVars_windows(t *testing.T) {
}
}
func TestProvisionerCorrectlyInterpolatesValidExitCodes(t *testing.T) {
type testCases struct {
Input interface{}
Expected []int
}
validExitCodeTests := []testCases{
{"0", []int{0}},
{[]string{"0"}, []int{0}},
{[]int{0, 12345}, []int{0, 12345}},
{[]string{"0", "12345"}, []int{0, 12345}},
{"0,12345", []int{0, 12345}},
}
for _, tc := range validExitCodeTests {
p := new(Provisioner)
config := testConfig()
config["valid_exit_codes"] = tc.Input
err := p.Prepare(config)
if err != nil {
t.Fatalf("Shouldn't have had error interpolating exit codes")
}
assert.ElementsMatchf(t, p.config.ValidExitCodes, tc.Expected,
fmt.Sprintf("expected exit codes to be: %#v, got %#v.", p.config.ValidExitCodes, tc.Expected))
}
}
func TestProvisionerCorrectlyInterpolatesExecutionPolicy(t *testing.T) {
type testCases struct {
Input interface{}
Expected ExecutionPolicy
ErrExpected bool
}
tests := []testCases{
{
Input: "bypass",
Expected: ExecutionPolicy(0),
ErrExpected: false,
},
{
Input: "allsigned",
Expected: ExecutionPolicy(1),
ErrExpected: false,
},
{
Input: "default",
Expected: ExecutionPolicy(2),
ErrExpected: false,
},
{
Input: "remotesigned",
Expected: ExecutionPolicy(3),
ErrExpected: false,
},
{
Input: "restricted",
Expected: ExecutionPolicy(4),
ErrExpected: false,
},
{
Input: "undefined",
Expected: ExecutionPolicy(5),
ErrExpected: false,
},
{
Input: "unrestricted",
Expected: ExecutionPolicy(6),
ErrExpected: false,
},
{
Input: "none",
Expected: ExecutionPolicy(7),
ErrExpected: false,
},
{
Input: "0", // User can supply a valid number for policy, too
Expected: 0,
ErrExpected: false,
},
{
Input: "invalid",
Expected: 0,
ErrExpected: true,
},
{
Input: "100", // If number is invalid policy, reject.
Expected: 100,
ErrExpected: true,
},
}
for _, tc := range tests {
p := new(Provisioner)
config := testConfig()
config["execution_policy"] = tc.Input
err := p.Prepare(config)
if (err != nil) != tc.ErrExpected {
t.Fatalf("Either err was expected, or shouldn't have happened: %#v", tc)
}
if err == nil {
assert.Equal(t, p.config.ExecutionPolicy, tc.Expected,
fmt.Sprintf("expected %#v, got %#v.", p.config.ExecutionPolicy, tc.Expected))
}
}
}
func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) {
var flattenedEnvVars string
config := testConfig()

View File

@ -0,0 +1,8 @@
{
"type": "powershell",
"environment_vars": "PackerRunUUID={{build `PackerRunUUID`}},ID={{build `ID`}}",
"inline": [
"Write-Host \"$env:ID for provisioner.$env:PackerRunUUID\""
]
}

View File

@ -0,0 +1,11 @@
{
"type": "powershell",
"script": "../../provisioner/powershell/test-fixtures/scripts/sample_script.ps1",
"environment_vars": [
"VAR1=A$Dollar",
"VAR2=A`Backtick",
"VAR3=A'SingleQuote",
"VAR4=A\"DoubleQuote"
]
}

View File

@ -0,0 +1,5 @@
write-output("packer_build_name is automatically set for you, or you can set it in your builder variables; the default for this builder is: " + $env:packer_build_name )
write-output("remember that escaping variables in powershell requires backticks; for example var1 from our config is " + $env:var1 )
write-output("likewise, var2 is " + $env:var2 )
write-output("and var3 is " + $env:var3 )

View File

@ -3,13 +3,15 @@ package shell_test
import (
"bytes"
"fmt"
"github.com/hashicorp/packer/helper/tests/acc"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/hashicorp/packer/helper/tests/acc"
"github.com/hashicorp/packer/provisioner/file"
"github.com/hashicorp/packer/provisioner/shell"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/go-uuid"
@ -18,10 +20,7 @@ import (
)
func TestShellProvisioner(t *testing.T) {
p := os.Getenv("ACC_TEST_PROVISIONERS")
if p != "all" && !strings.Contains(p, "shell") {
t.Skip()
}
acc.TestProvisionersPreCheck("shell", t)
acc.TestProvisionersAgainstBuilders(new(ShellProvisionerAccTest), t)
}
@ -40,13 +39,13 @@ func (s *ShellProvisionerAccTest) GetConfig() (string, error) {
defer config.Close()
file, err := ioutil.ReadAll(config)
return string(file), nil
return string(file), err
}
func (s *ShellProvisionerAccTest) GetProvisionerStore() packer.MapOfProvisioner {
return packer.MapOfProvisioner{
"shell": func() (packer.Provisioner, error) { return command.Provisioners["shell"], nil },
"file": func() (packer.Provisioner, error) { return command.Provisioners["file"], nil },
"shell": func() (packer.Provisioner, error) { return &shell.Provisioner{}, nil },
"file": func() (packer.Provisioner, error) { return &file.Provisioner{}, nil },
}
}

View File

@ -328,7 +328,7 @@ func funcGenSed(ctx *Context) interface{} {
return func(expression string, inputString string) (string, error) {
return "", errors.New("template function `sed` is deprecated " +
"use `replace` or `replace_all` instead." +
"Documentation: https://www.packer.io/docs/templates/engine.html")
"Documentation: https://www.packer.io/docs/templates/engine")
}
}

18
website/.editorconfig Normal file
View File

@ -0,0 +1,18 @@
# This file is for unifying the coding style for different editors and IDEs
# editorconfig.org
root = true
[*]
end_of_line = lf
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 2
[Makefile]
indent_style = tab
[{*.md,*.json}]
max_line_length = null

4
website/.eslintrc.js Normal file
View File

@ -0,0 +1,4 @@
module.exports = {
...require('@hashicorp/nextjs-scripts/.eslintrc.js'),
ignorePatterns: ['public/']
}

5
website/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
node_modules
.DS_Store
.next
out
.mdx-data

View File

@ -0,0 +1,8 @@
{
"ignore": {
"marked": {
"versions": "0.8.2",
"reason": "IE breaks"
}
}
}

7
website/Dockerfile Normal file
View File

@ -0,0 +1,7 @@
FROM node:10.16.3-alpine
RUN apk add --update --no-cache git make g++ automake autoconf libtool nasm libpng-dev
COPY ./package.json /website/package.json
COPY ./package-lock.json /website/package-lock.json
WORKDIR /website
RUN npm install

View File

@ -1,3 +0,0 @@
source "https://rubygems.org"
gem "middleman-hashicorp", "0.3.44"

View File

@ -1,161 +0,0 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (4.2.11.1)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
autoprefixer-rails (9.7.4)
execjs
bootstrap-sass (3.4.1)
autoprefixer-rails (>= 5.2.1)
sassc (>= 2.0.0)
builder (3.2.4)
capybara (2.4.4)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
chunky_png (1.3.11)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.12.2)
compass (1.0.3)
chunky_png (~> 1.2)
compass-core (~> 1.0.2)
compass-import-once (~> 1.0.5)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
sass (>= 3.3.13, < 3.5)
compass-core (1.0.3)
multi_json (~> 1.0)
sass (>= 3.3.0, < 3.5)
compass-import-once (1.0.5)
sass (>= 3.2, < 3.5)
em-websocket (0.5.1)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
erubis (2.7.0)
eventmachine (1.2.7)
execjs (2.7.0)
ffi (1.12.2)
haml (5.1.2)
temple (>= 0.8.0)
tilt
hike (1.2.3)
hooks (0.4.1)
uber (~> 0.0.14)
http_parser.rb (0.6.0)
i18n (0.7.0)
json (2.3.0)
kramdown (1.17.0)
listen (3.0.8)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
middleman (3.4.1)
coffee-script (~> 2.2)
compass (>= 1.0.0, < 2.0.0)
compass-import-once (= 1.0.5)
execjs (~> 2.0)
haml (>= 4.0.5)
kramdown (~> 1.2)
middleman-core (= 3.4.1)
middleman-sprockets (>= 3.1.2)
sass (>= 3.4.0, < 4.0)
uglifier (~> 2.5)
middleman-core (3.4.1)
activesupport (~> 4.1)
bundler (~> 1.1)
capybara (~> 2.4.4)
erubis
hooks (~> 0.3)
i18n (~> 0.7.0)
listen (~> 3.0.3)
padrino-helpers (~> 0.12.3)
rack (>= 1.4.5, < 2.0)
thor (>= 0.15.2, < 2.0)
tilt (~> 1.4.1, < 2.0)
middleman-hashicorp (0.3.44)
bootstrap-sass (~> 3.3)
builder (~> 3.2)
middleman (~> 3.4)
middleman-livereload (~> 3.4)
middleman-syntax (~> 3.0)
redcarpet (~> 3.3)
turbolinks (~> 5.0)
middleman-livereload (3.4.6)
em-websocket (~> 0.5.1)
middleman-core (>= 3.3)
rack-livereload (~> 0.3.15)
middleman-sprockets (3.5.0)
middleman-core (>= 3.3)
sprockets (~> 2.12.1)
sprockets-helpers (~> 1.1.0)
sprockets-sass (~> 1.3.0)
middleman-syntax (3.2.0)
middleman-core (>= 3.2)
rouge (~> 3.2)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2019.1009)
mini_portile2 (2.4.0)
minitest (5.14.0)
multi_json (1.14.1)
nokogiri (1.10.9)
mini_portile2 (~> 2.4.0)
padrino-helpers (0.12.9)
i18n (~> 0.6, >= 0.6.7)
padrino-support (= 0.12.9)
tilt (>= 1.4.1, < 3)
padrino-support (0.12.9)
activesupport (>= 3.1)
rack (1.6.13)
rack-livereload (0.3.17)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rb-fsevent (0.10.3)
rb-inotify (0.10.1)
ffi (~> 1.0)
redcarpet (3.5.0)
rouge (3.16.0)
sass (3.4.25)
sassc (2.2.1)
ffi (~> 1.9)
sprockets (2.12.5)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sprockets-helpers (1.1.0)
sprockets (~> 2.0)
sprockets-sass (1.3.1)
sprockets (~> 2.0)
tilt (~> 1.1)
temple (0.8.2)
thor (1.0.1)
thread_safe (0.3.6)
tilt (1.4.1)
turbolinks (5.2.1)
turbolinks-source (~> 5.2)
turbolinks-source (5.2.0)
tzinfo (1.2.6)
thread_safe (~> 0.1)
uber (0.0.15)
uglifier (2.7.2)
execjs (>= 0.3.0)
json (>= 1.8.0)
xpath (2.1.0)
nokogiri (~> 1.3)
PLATFORMS
ruby
DEPENDENCIES
middleman-hashicorp (= 0.3.44)
BUNDLED WITH
1.17.3

View File

@ -1,30 +1,54 @@
configure_cache:
mkdir -p tmp/cache
build: configure_cache
@echo "==> Starting build in Docker..."
@docker run \
--interactive \
--rm \
--tty \
--volume "$(shell pwd):/opt/buildhome/repo" \
--volume "$(shell pwd)/tmp/cache:/opt/buildhome/cache" \
--env "ENV=production" \
netlify/build \
build middleman build --verbose
website: configure_cache
# Default: run this if working on the website locally to run in watch mode.
website:
@echo "==> Downloading latest Docker image..."
@docker pull hashicorp/packer-website
@echo "==> Starting website in Docker..."
@docker run \
--interactive \
--rm \
--tty \
--volume "$(shell pwd):/opt/buildhome/repo" \
--volume "$(shell pwd)/tmp/cache:/opt/buildhome/cache" \
--publish "4567:4567" \
--publish "35729:35729" \
--env "ENV=production" \
netlify/build \
build middleman
--workdir "/website" \
--volume "$(shell pwd):/website" \
--volume "/website/node_modules" \
--publish "3000:3000" \
hashicorp/packer-website \
npm start
.PHONY: build website
# This command will generate a static version of the website to the "out" folder.
build:
@echo "==> Downloading latest Docker image..."
@docker pull hashicorp/packer-website
@echo "==> Starting build in Docker..."
@docker run \
--interactive \
--rm \
--tty \
--workdir "/website" \
--volume "$(shell pwd):/website" \
--volume "/website/node_modules" \
hashicorp/packer-website \
npm run static
# If you are changing node dependencies locally, run this to generate a new
# local Docker image with the dependency changes included.
build-image:
@echo "==> Building Docker image..."
@docker build -t hashicorp-packer-website-local .
# Use this if you have run `build-image` to use the locally built image
# rather than our CI-generated image to test dependency changes.
website-local:
@echo "==> Starting website in Docker..."
@docker run \
--interactive \
--rm \
--tty \
--workdir "/website" \
--volume "$(shell pwd):/website" \
--volume "/website/node_modules" \
--publish "3000:3000" \
hashicorp-packer-website-local \
npm start
.DEFAULT_GOAL := website
.PHONY: build build-image website website-local

View File

@ -1,22 +1,193 @@
# Packer Website
This subdirectory contains the entire source for the [Packer Website][packer].
This is a [Middleman][middleman] project, which builds a static site from these
source files.
[![Netlify Status](https://img.shields.io/netlify/f7fa8963-0022-4a0e-9ccf-f5385355906b?style=flat-square)](https://app.netlify.com/sites/packer-docs-platform/deploys)
This subdirectory contains the entire source for the [Packer Website](https://packer.io/). This is a [NextJS](https://nextjs.org/) project, which builds a static site from these source files.
## Contributions Welcome!
If you find a typo or you feel like you can improve the HTML, CSS, or
JavaScript, we welcome contributions. Feel free to open issues or pull requests
like any normal GitHub project, and we'll merge it in.
If you find a typo or you feel like you can improve the HTML, CSS, or JavaScript, we welcome contributions. Feel free to open issues or pull requests like any normal GitHub project, and we'll merge it in 🚀
## Running the Site Locally
1. Install [Docker](https://docs.docker.com/engine/installation/) if you have not already done so
2. Clone this repo and run `make website`
The website can be run locally through node.js or Docker. If you choose to run through Docker, everything will be a little bit slower due to the additional overhead, so for frequent contributors it may be worth it to use node. Also if you are a vim user, it's also worth noting that vim's swapfile usage can cause issues for the live reload functionality. In order to avoid these issues, make sure you have run `:set backupcopy=yes` within vim.
Then open up `http://localhost:4567`. Note that some URLs you may need to append
".html" to make them work (in the navigation).
### With Docker
[middleman]: https://www.middlemanapp.com
[packer]: https://www.packer.io
Running the site locally is simple. Provided you have Docker installed, clone this repo, run `make`, and then visit `http://localhost:3000`.
The docker image is pre-built with all the website dependencies installed, which is what makes it so quick and simple, but also means if you need to change dependencies and test the changes within Docker, you'll need a new image. If this is something you need to do, you can run `make build-image` to generate a local Docker image with updated dependencies, then `make website-local` to use that image and preview.
### With Node
If your local development environment has a supported version (v10.0.0+) of [node installed](https://nodejs.org/en/) you can run:
- `npm install`
- `npm start`
and then visit `http://localhost:3000`.
If you pull down new code from github, you should run `npm install` again. Otherwise, there's no need to re-run `npm install` each time the site is run, you can just run `npm start` to get it going.
## Editing Content
Documentation content is written in [Markdown](https://www.markdownguide.org/cheat-sheet/) and you'll find all files listed under the `/pages` directory.
To create a new page with Markdown, create a file ending in `.mdx` in the `pages/` directory. The path in the pages directory will be the URL route. For example, `pages/hello/world.mdx` will be served from the `/hello/world` URL.
This file can be standard Markdown and also supports [YAML frontmatter](https://middlemanapp.com/basics/frontmatter/). YAML frontmatter is optional, there are defaults for all keys.
```yaml
---
title: 'My Title'
description: "A thorough, yet succinct description of the page's contents"
---
```
The significant keys in the YAML frontmatter are:
- `title` `(string)` - This is the title of the page that will be set in the HTML title.
- `description` `(string)` - This is a description of the page that will be set in the HTML description.
> ⚠Since `api` is a reserved directory within NextJS, all `/api/**` pages are listed under the `/pages/api-docs` path.
### Editing Sidebars
The structure of the sidebars are controlled by files in the [`/data` directory](data).
- Edit [this file](data/docs-navigation.js) to change the **docs** sidebar
- Edit [this file](data/guides-navigation.js) to change the **guides** sidebar
- Edit [this file](data/intro-navigation.js) to change the **intro** sidebar
To nest sidebar items, you'll want to add a new `category` key/value accompanied by the appropriate embedded `content` values.
- `category` values will be **directory names** within the `pages` directory
- `content` values will be **file names** within their appropriately nested directory.
### Creating New Pages
There is currently a small bug with new page creation - if you create a new page and link it up via subnav data while the server is running, it will report an error saying the page was not found. This can be resolved by restarting the server.
### Changing the Release Version
To change the version of Packer displayed for download on the website, head over to `data/version.js` and change the number there. It's important to note that the version number must match a version that has been released and is live on `releases.hashicorp.com` -- if it does not, the website will be unable to fetch links to the binaries and will not compile. So this version number should be changed _only after a release_.
#### Displaying a Prerelease
If there is a prerelease of any type that should be displayed on the downloads page, this can be done by editing `pages/downloads/index.jsx`. By default, the download component might look something like this:
```jsx
<ProductDownloader
product="Packer"
version={VERSION}
downloads={downloadData}
community="/resources"
/>
```
To add a prerelease, an extra `prerelease` property can be added to the component as such:
```jsx
<ProductDownloader
product="Packer"
version={VERSION}
downloads={downloadData}
community="/resources"
prerelease={{
type: 'release candidate', // the type of prerelease: beta, release candidate, etc.
name: 'v1.0.0', // the name displayed in text on the website
version: '1.0.0-rc1', // the actual version tag that was pushed to releases.hashicorp.com
}}
/>
```
This configuration would display something like the following text on the website, emphasis added to the configurable parameters:
```
A {{ release candidate }} for Packer {{ v1.0.0 }} is available! The release can be <a href='https://releases.hashicorp.com/packer/{{ 1.0.0-rc1 }}'>downloaded here</a>.
```
You may customize the parameters in any way you'd like. To remove a prerelease from the website, simply delete the `prerelease` paremeter from the above component.
### Markdown Enhancements
There are several custom markdown plugins that are available by default that enhance standard markdown to fit our use cases. This set of plugins introduces a couple instances of custom syntax, and a couple specific pitfalls that are not present by default with markdown, detailed below:
- If you see the symbols `~>`, `->`, `=>`, or `!>`, these represent [custom alerts](https://github.com/hashicorp/remark-plugins/tree/master/plugins/paragraph-custom-alerts#paragraph-custom-alerts). These render as colored boxes to draw the user's attention to some type of aside.
- If you see `@include '/some/path.mdx'`, this is a [markdown include](https://github.com/hashicorp/remark-plugins/tree/master/plugins/include-markdown#include-markdown-plugin). It's worth noting as well that all includes resolve from `website/pages/partials` by default.
- If you see `# Headline ((#slug))`, this is an example of an [anchor link alias](https://github.com/hashicorp/remark-plugins/tree/je.anchor-link-adjustments/plugins/anchor-links#anchor-link-aliases). It adds an extra permalink to a headline for compatibility and is removed from the output.
- Due to [automatically generated permalinks](https://github.com/hashicorp/remark-plugins/tree/je.anchor-link-adjustments/plugins/anchor-links#anchor-links), any text changes to _headlines_ or _list items that begin with inline code_ can and will break existing permalinks. Be very cautious when changing either of these two text items.
Headlines are fairly self-explanitory, but here's an example of how list items that begin with inline code look.
```markdown
- this is a normal list item
- `this` is a list item that begins with inline code
```
Its worth noting that _only the inline code at the beginning of the list item_ will cause problems if changed. So if you changed the above markup to...
```markdown
- lsdhfhksdjf
- `this` jsdhfkdsjhkdsfjh
```
...while it perhaps would not be an improved user experience, no links would break because of it. The best approach is to **avoid changing headlines and inline code at the start of a list item**. If you must change one of these items, make sure to tag someone from the digital marketing development team on your pull request, they will help to ensure as much compatibility as possible.
### Redirects
This website structures URLs based on the filesystem layout. This means that if a file is moved, removed, or a folder is re-organized, links will break. If a path change is necessary, it can be mitigated using redirects.
To add a redirect, head over to the `_redirects` file - the format is fairly simple. On the left is the current path, and on the right is the path that should be redirected to. It's important to note that if there are links to a `.html` version of a page, that must also be explicitly redirected. For example:
```
/foo /bar
/foo.html /bar
```
This redirect rule will send all incoming links to `/foo` and `/foo.html` to `/bar`. For more details on the redirects file format, [check out the docs on netlify](https://docs.netlify.com/routing/redirects/rewrites-proxies).
There are a couple important caveats with redirects. First, redirects are applied at the hosting layer, and therefore will not work by default in local dev mode. To test in local dev mode, you can use [`netlify dev`](https://www.netlify.com/products/dev/), or just push a commit and check using the deploy preview.
Second, redirects do not apply to client-side navigation. By default, all links in the navigation and docs sidebar will navigate purely on the client side, which makes navigation through the docs significantly faster, especially for those with low-end devices and/or weak internet connections. In the future, we plan to convert all internal links within docs pages to behave this way as well. This means that if there is a link on this website to a given piece of content that has changed locations in some way, we need to also _directly change existing links to the content_. This way, if a user clicks a link that navigates on the client side, or if they hit the url directly and the page renders from the server side, either one will work perfectly.
Let's look at an example. Say you have a page called `/docs/foo` which needs to be moved to `/docs/nested/foo`. Additionally, this is a page that has been around for a while and we know there are links into `/docs/foo.html` left over from our previous website structure. First, we move the page, then adjust the docs sidenav, in `data/docs-navigation.js`. Find the category the page is in, and move it into the appropriate subcategory. Next, we add to `_redirects` as such:
```
/foo /nested/foo
/foo.html /nested/foo
```
Finally, we run a global search for internal links to `/foo`, and make sure to adjust them to be `/nested/foo` - this is to ensure that client-side navigation still works correctly. _Adding a redirect alone is not enough_.
One more example - let's say that content is being moved to an external website. A common example is guides moving to `learn.hashicorp.com`. In this case, we take all the same steps, except that we need to make a different type of change to the `docs-navigation` file. If previously the structure looked like:
```js
{
category: 'docs',
content: [
'foo'
]
}
```
If we no longer want the link to be in the side nav, we can simply remove it. If we do still want the link in the side nav, but pointing to an external destnation, we need to slightly change the structure as such:
```js
{
category: 'docs',
content: [
{ title: 'Foo Title', href: 'https://learn.hashicorp.com/vault/foo' }
]
}
```
As the majority of items in the side nav are internal links, the structure makes it as easy as possible to represent these links. This alternate syntax is the most concise manner than an external link can be represented. External links can be used anywhere within the docs sidenav.
It's also worth noting that it is possible to do glob-based redirects, for example matching `/docs/*`, and you may see this pattern in the `_redirects` file. This type of redirect is much higher risk and the behavior is a bit more nuanced, so if you need to add a glob redirect, please reach out to the website maintainers and ask about it first.
### Deployment
This website is hosted on Netlify and configured to automatically deploy anytime you push code to the `stable-website` branch. Any time a pull request is submitted that changes files within the `website` folder, a deployment preview will appear in the github checks which can be used to validate the way docs changes will look live. Deployments from `stable-website` will look and behave the same way as deployment previews.

71
website/_redirects Normal file
View File

@ -0,0 +1,71 @@
# REDIRECTS FILE
#
# See https://www.netlify.com/docs/redirects/ for documentation. Please do not
# modify or delete existing redirects without first verifying internally.
/docs/installation.html /docs/install 301!
/docs/command-line/machine-readable.html /docs/commands 301!
/docs/command-line/introduction.html /docs/commands 301!
/docs/templates/introduction.html /docs/templates 301!
/docs/builders/azure-setup.html /docs/builders/azure 301!
/docs/templates/veewee-to-packer.html /guides/veewee-to-packer 301!
/docs/extend/developing-plugins.html /docs/extending/plugins 301!
/docs/extending/developing-plugins.html /docs/extending/plugins 301!
/docs/extend/builder.html /docs/extending/custom-builders 301!
/docs/getting-started/setup.html /docs/getting-started/install 301!
/docs/other/community.html /community-tools 301!
/downloads-community.html /community-tools 301!
/community/index.html /community 301!
/docs/other/environmental-variables.html /docs/other/environment-variables 301!
/docs/platforms.html /docs/builders 301!
/intro/platforms.html /docs/builders 301!
/docs/templates/configuration-templates.html /docs/templates/engine 301!
/docs/machine-readable/* /docs/commands 301!
/docs/command-line/* /docs/commands/:splat 200
/docs/extend/* /docs/extending/:splat 200
/intro/getting-started/install /intro/getting-started 301!
/intro/getting-started/install.html /intro/getting-started 301!
/docs/basics/terminology /docs/terminology 301!
/docs/basics/terminology.html /docs/terminology 301!
/docs/other/* /docs/:splat 200
/docs/configuration/from-1.5/* /docs/from-1.5/:splat 200
/docs/configuration/from-1.5/*/overview /docs/from-1.5/:splat 200
/docs/configuration/from-1.5/*/overview.html /docs/from-1.5/:splat 200
/docs/builders/amazon.html /docs/builders/amazon 301!
/docs/builders/amazon-*.html /docs/builders/amazon/:splat 200
/docs/builders/amazon-* /docs/builders/amazon/:splat 200
/docs/builders/azure.html /docs/builders/azure 301!
/docs/builders/azure-*.html /docs/builders/azure/:splat 200
/docs/builders/azure-* /docs/builders/azure/:splat 200
/docs/builders/hyperv.html /docs/builders/hyperv 301!
/docs/builders/hyperv-*.html /docs/builders/hyperv/:splat 200
/docs/builders/hyperv-* /docs/builders/hyperv/:splat 200
/docs/builders/oracle.html /docs/builders/oracle 301!
/docs/builders/oracle-*.html /docs/builders/oracle/:splat 200
/docs/builders/oracle-* /docs/builders/oracle/:splat 200
/docs/builders/outscale.html /docs/builders/outscale 301!
/docs/builders/osc-*.html /docs/builders/outscale/:splat 200
/docs/builders/osc-* /docs/builders/outscale/:splat 200
/docs/builders/parallels.html /docs/builders/parallels 301!
/docs/builders/parallels-*.html /docs/builders/parallels/:splat 200
/docs/builders/parallels-* /docs/builders/parallels/:splat 200
/docs/builders/virtualbox.html /docs/builders/virtualbox 301!
/docs/builders/virtualbox-*.html /docs/builders/virtualbox/:splat 200
/docs/builders/virtualbox-* /docs/builders/virtualbox/:splat 200
/docs/builders/vmware.html /docs/builders/vmware 301!
/docs/builders/vmware-*.html /docs/builders/vmware/:splat 200
/docs/builders/vmware-* /docs/builders/vmware/:splat 200
/docs/builders/vsphere-*.html /docs/builders/vmware/vsphere-:splat 200
/docs/builders/vsphere-* /docs/builders/vmware/vsphere-:splat 200

4
website/babel.config.js Normal file
View File

@ -0,0 +1,4 @@
module.exports = {
presets: ['next/babel'],
plugins: ['import-glob-array']
}

View File

@ -0,0 +1,32 @@
import Link from 'next/link'
export default function Footer({ openConsentManager }) {
return (
<footer className="g-footer">
<div className="g-container">
<div className="left">
<Link href="/intro">
<a>Intro</a>
</Link>
<Link href="/guides">
<a>Guides</a>
</Link>
<Link href="/docs">
<a>Docs</a>
</Link>
<Link href="/community">
<a>Community</a>
</Link>
<a href="https://hashicorp.com/privacy">Privacy</a>
<Link href="/security">
<a>Security</a>
</Link>
<Link href="/files/press-kit.zip">
<a>Press Kit</a>
</Link>
<a onClick={openConsentManager}>Consent Manager</a>
</div>
</div>
</footer>
)
}

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