diff --git a/.github/workflows/ensure-docs-compiled.yaml b/.github/workflows/ensure-docs-compiled.yaml new file mode 100644 index 00000000..74a174d3 --- /dev/null +++ b/.github/workflows/ensure-docs-compiled.yaml @@ -0,0 +1,22 @@ +name: Ensure Docs are Compiled +on: + push: +jobs: + ensure-docs-compiled: + runs-on: ubuntu-latest + steps: + - name: Checkout 🛎 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - shell: bash + run: make build-docs + - shell: bash + run: | + if [[ -z "$(git status -s)" ]]; then + echo "OK" + else + echo "Docs have been updated, but the compiled docs have not been committed." + echo "Run 'make build-docs', and commit the result to resolve this error." + exit 1 + fi + diff --git a/.github/workflows/notify-integration-release-via-manual.yaml b/.github/workflows/notify-integration-release-via-manual.yaml new file mode 100644 index 00000000..14a7664a --- /dev/null +++ b/.github/workflows/notify-integration-release-via-manual.yaml @@ -0,0 +1,46 @@ +name: Notify Integration Release (Manual) +on: + workflow_dispatch: + inputs: + version: + description: "The release version (semver)" + default: 0.0.1 + required: false + branch: + description: "A branch or SHA" + default: 'main' + required: false +jobs: + notify-release: + runs-on: ubuntu-latest + steps: + - name: Checkout this repo + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + with: + ref: ${{ github.event.inputs.branch }} + # Ensure that Docs are Compiled + - uses: actions/setup-go@v4 + - shell: bash + run: make build-docs + - shell: bash + run: | + if [[ -z "$(git status -s)" ]]; then + echo "OK" + else + echo "Docs have been updated, but the compiled docs have not been committed." + echo "Run 'make build-docs', and commit the result to resolve this error." + exit 1 + fi + # Perform the Release + - name: Checkout integration-release-action + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + with: + repository: hashicorp/integration-release-action + path: ./integration-release-action + - name: Notify Release + uses: ./integration-release-action + with: + integration_identifier: 'packer/hashicorp/vagrant' + release_version: ${{ github.event.inputs.version }} + release_sha: ${{ github.event.inputs.branch }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/notify-integration-release-via-tag.yaml b/.github/workflows/notify-integration-release-via-tag.yaml new file mode 100644 index 00000000..6e8ecb45 --- /dev/null +++ b/.github/workflows/notify-integration-release-via-tag.yaml @@ -0,0 +1,40 @@ +name: Notify Integration Release (Tag) +on: + push: + tags: + - '*.*.*' # Proper releases + - '*.*.*-*' # Pre releases +jobs: + notify-release: + runs-on: ubuntu-latest + steps: + - name: Checkout this repo + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + with: + ref: ${{ github.ref }} + # Ensure that Docs are Compiled + - uses: actions/setup-go@v4 + - shell: bash + run: make build-docs + - shell: bash + run: | + if [[ -z "$(git status -s)" ]]; then + echo "OK" + else + echo "Docs have been updated, but the compiled docs have not been committed." + echo "Run 'make build-docs', and commit the result to resolve this error." + exit 1 + fi + # Perform the Release + - name: Checkout integration-release-action + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + with: + repository: hashicorp/integration-release-action + path: ./integration-release-action + - name: Notify Release + uses: ./integration-release-action + with: + integration_identifier: 'packer/hashicorp/vagrant' + release_version: ${{ github.ref_name }} + release_sha: ${{ github.ref }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.web-docs/README.md b/.web-docs/README.md new file mode 100644 index 00000000..38cb3a8c --- /dev/null +++ b/.web-docs/README.md @@ -0,0 +1,31 @@ + +The Vagrant plugin integrates Packer with HashiCorp [Vagrant](https://www.vagrantup.com/), allowing you to use Packer to create development boxes. + +### Installation +To install this plugin add this code into your Packer configuration and run [packer init](/packer/docs/commands/init) + +```hcl +packer { + required_plugins { + vagrant = { + version = "~> 1" + source = "github.com/hashicorp/vagrant" + } + } +} +``` + +Alternatively, you can use `packer plugins install` to manage installation of this plugin. + +```sh +packer plugins install github.com/hashicorp/vagrant +``` + +### Components + +#### Builders +- [vagrant](/packer/integrations/hashicorp/vagrant/latest/components/builder/vagrant) - The Vagrant builder is intended for building new boxes from already-existing boxes. + +#### Post-Processor +- [vagrant](/packer/integrations/hashicorp/vagrant/latest/components/post-processor/vagrant) - The Packer Vagrant post-processor takes a build and converts the artifact into a valid Vagrant box. +- [vagrant-cloud](/packer/integrations/hashicorp/vagrant/latest/components/post-processor/vagrant-cloud) - The Vagrant Cloud post-processor enables the upload of Vagrant boxes to Vagrant Cloud. diff --git a/.web-docs/components/builder/vagrant/README.md b/.web-docs/components/builder/vagrant/README.md new file mode 100644 index 00000000..3e859d33 --- /dev/null +++ b/.web-docs/components/builder/vagrant/README.md @@ -0,0 +1,216 @@ +Type: `vagrant` +Artifact BuilderId: `vagrant` + +The Vagrant builder is intended for building new boxes from already-existing +boxes. Your source should be a URL or path to a .box file or a Vagrant Cloud +box name such as `hashicorp/precise64`. + +Packer will not install vagrant, nor will it install the underlying +virtualization platforms or extra providers; We expect when you run this +builder that you have already installed what you need. + +By default, this builder will initialize a new Vagrant workspace, launch your +box from that workspace, provision it, call `vagrant package` to package it +into a new box, and then destroy the original box. Please note that vagrant +will _not_ remove the box file from your system (we don't call +`vagrant box remove`). + +You can change the behavior so that the builder doesn't destroy the box by +setting the `teardown_method` option. You can change the behavior so the builder +doesn't package it (not all provisioners support the `vagrant package` command) +by setting the `skip package` option. You can also change the behavior so that +rather than initializing a new Vagrant workspace, you use an already defined +one, by using `global_id` instead of `source_box`. + +Please note that if you are using the Vagrant builder, then the Vagrant +post-processor is unnecessary because the output of the Vagrant builder is +already a Vagrant box; using that post-processor with the Vagrant builder will +cause your build to fail. Similarly, since Vagrant boxes are already compressed, +the Compress post-processor will not work with this builder. + +## Configuration Reference + +### Required + +- `source_path` (string) - URL of the vagrant box to use, or the name of the + vagrant box. `hashicorp/precise64`, `./mylocalbox.box` and + `https://example.com/my-box.box` are all valid source boxes. If your + source is a .box file, whether locally or from a URL like the latter example + above, you will also need to provide a `box_name`. This option is required, + unless you set `global_id`. You may only set one or the other, not both. + + or + +- `global_id` (string) - the global id of a Vagrant box already added to Vagrant + on your system. You can find the global id of your Vagrant boxes using the + command `vagrant global-status`; your global_id will be a 7-digit number and + letter combination that you'll find in the leftmost column of the + global-status output. If you choose to use `global_id` instead of + `source_box`, Packer will skip the Vagrant initialize and add steps, and + simply launch the box directly using the global id. + +### Optional + + + +- `output_dir` (string) - The directory to create that will contain your output box. We always + create this directory and run from inside of it to prevent Vagrant init + collisions. If unset, it will be set to packer- plus your buildname. + +- `checksum` (string) - The checksum for the .box file. The type of the checksum is specified + within the checksum field as a prefix, ex: "md5:{$checksum}". The type + of the checksum can also be omitted and Packer will try to infer it + based on string length. Valid values are "none", "{$checksum}", + "md5:{$checksum}", "sha1:{$checksum}", "sha256:{$checksum}", + "sha512:{$checksum}" or "file:{$path}". Here is a list of valid checksum + values: + * md5:090992ba9fd140077b0661cb75f7ce13 + * 090992ba9fd140077b0661cb75f7ce13 + * sha1:ebfb681885ddf1234c18094a45bbeafd91467911 + * ebfb681885ddf1234c18094a45bbeafd91467911 + * sha256:ed363350696a726b7932db864dda019bd2017365c9e299627830f06954643f93 + * ed363350696a726b7932db864dda019bd2017365c9e299627830f06954643f93 + * file:http://releases.ubuntu.com/20.04/SHA256SUMS + * file:file://./local/path/file.sum + * file:./local/path/file.sum + * none + Although the checksum will not be verified when it is set to "none", + this is not recommended since these files can be very large and + corruption does happen from time to time. + +- `box_name` (string) - if your source_box is a boxfile that we need to add to Vagrant, this is + the name to give it. If left blank, will default to "packer_" plus your + buildname. + +- `insert_key` (bool) - If true, Vagrant will automatically insert a keypair to use for SSH, + replacing Vagrant's default insecure key inside the machine if detected. + By default, Packer sets this to false. + +- `provider` (string) - The vagrant provider. + This parameter is required when source_path have more than one provider, + or when using vagrant-cloud post-processor. Defaults to unset. + +- `vagrantfile_template` (string) - What vagrantfile to use + +- `teardown_method` (string) - Whether to halt, suspend, or destroy the box when the build has + completed. Defaults to "halt" + +- `box_version` (string) - What box version to use when initializing Vagrant. + +- `template` (string) - 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 + correspond to the Packer options box_name, synced_folder, and insert_key. + +- `synced_folder` (string) - Path to the folder to be synced to the guest. The path can be absolute + or relative to the directory Packer is being run from. + +- `skip_add` (bool) - Don't call "vagrant add" to add the box to your local environment; this + is necessary if you want to launch a box that is already added to your + vagrant environment. + +- `add_cacert` (string) - Equivalent to setting the + --cacert + option in vagrant add; defaults to unset. + +- `add_capath` (string) - Equivalent to setting the + --capath option + in vagrant add; defaults to unset. + +- `add_cert` (string) - Equivalent to setting the + --cert option in + vagrant add; defaults to unset. + +- `add_clean` (bool) - Equivalent to setting the + --clean flag in + vagrant add; defaults to unset. + +- `add_force` (bool) - Equivalent to setting the + --force flag in + vagrant add; defaults to unset. + +- `add_insecure` (bool) - Equivalent to setting the + --insecure flag in + vagrant add; defaults to unset. + +- `skip_package` (bool) - if true, Packer will not call vagrant package to + package your base box into its own standalone .box file. + +- `output_vagrantfile` (string) - Output Vagrantfile + +- `package_include` ([]string) - Equivalent to setting the + [`--include`](https://developer.hashicorp.com/vagrant/docs/cli/package#include-x-y-z) option + in `vagrant package`; defaults to unset + + + + +## Example + +Sample for `hashicorp/precise64` with virtualbox provider. + +**JSON** + +```json +{ + "builders": [ + { + "communicator": "ssh", + "source_path": "hashicorp/precise64", + "provider": "virtualbox", + "add_force": true, + "type": "vagrant" + } + ] +} +``` + +**HCL2** + +```hcl +source "vagrant" "example" { + communicator = "ssh" + source_path = "hashicorp/precise64" + provider = "virtualbox" + add_force = true +} + +build { + sources = ["source.vagrant.example"] +} +``` + + +## Regarding output directory and new box + +After Packer completes building and provisioning a new Vagrant Box file, it is worth +noting that the new box file will need to be added to Vagrant. For a beginner to Packer +and Vagrant, it may seem as if a simple 'vagrant up' in the output directory will run the +the newly created Box. This is not the case. + +Rather, create a new directory (to avoid Vagarant init collisions), add the new +package.box to Vagrant and init. Then run vagrant up to bring up the new box created +by Packer. You will now be able to connect to the new box with provisioned changes. + +``` +'mkdir output2' +'cp package.box ./output2' +'vagrant box add new-box name-of-the-packer-box.box' +'vagrant init new-box' +'vagrant up' +``` + +## A note on SSH connections + +Currently this builder only works for SSH connections, and automatically fills +in all information needed for the SSH communicator using vagrant's ssh-config. + +If you would like to connect via a different username or authentication method +than is produced when you call `vagrant ssh-config`, then you must provide the + +`ssh_username` and all other relevant authentication information (e.g. +`ssh_password` or `ssh_private_key_file`) + +By providing the `ssh_username`, you're telling Packer not to use the vagrant +ssh config, except for determining the host and port for the virtual machine to +connect to. diff --git a/.web-docs/components/post-processor/vagrant-cloud/README.md b/.web-docs/components/post-processor/vagrant-cloud/README.md new file mode 100644 index 00000000..47e44311 --- /dev/null +++ b/.web-docs/components/post-processor/vagrant-cloud/README.md @@ -0,0 +1,271 @@ +Type: `vagrant-cloud` +Artifact BuilderId: `pearkes.post-processor.vagrant-cloud` + +[Vagrant Cloud](https://app.vagrantup.com/boxes/search) hosts and serves boxes +to Vagrant, allowing you to version and distribute boxes to an organization in a +simple way. + +The Vagrant Cloud post-processor enables the upload of Vagrant boxes to Vagrant +Cloud. Currently, the Vagrant Cloud post-processor will accept and upload boxes +supplied to it from the [Vagrant](/docs/post-processor/vagrant.mdx) or +[Artifice](https://developer.hashicorp.com/packer/docs/post-processor/artifice) post-processors and the +[Vagrant](/docs/builder/vagrant.mdx) builder. + +You'll need to be familiar with Vagrant Cloud, have an upgraded account to +enable box hosting, and be distributing your box via the [shorthand name](https://developer.hashicorp.com/vagrant/docs/cli/box) configuration. + +## Workflow + +It's important to understand the workflow that using this post-processor +enforces in order to take full advantage of Vagrant and Vagrant Cloud. + +The use of this processor assume that you currently distribute, or plan to +distribute, boxes via Vagrant Cloud. It also assumes you create Vagrant Boxes +and deliver them to your team in some fashion. + +Here is an example workflow: + +1. You use Packer to build a Vagrant Box for the `virtualbox` provider +2. The `vagrant-cloud` post-processor is configured to point to the box + `hashicorp/foobar` on Vagrant Cloud via the `box_tag` configuration +3. The post-processor receives the box from the `vagrant` post-processor +4. It then creates the configured version, or verifies the existence of it, on + Vagrant Cloud +5. A provider matching the name of the Vagrant provider is then created +6. The box is uploaded to Vagrant Cloud +7. The upload is verified +8. The version is released and available to users of the box + +~> The Vagrant Cloud box (`hashicorp/foobar` in this example) must already +exist. Packer will not create the box automatically. If running Packer in +automation, consider using the +[Vagrant Cloud API](https://developer.hashicorp.com/vagrant/vagrant-cloud/api) +to create the Vagrant Cloud box if it doesn't already exist. + +## Configuration + +The configuration allows you to specify the target box that you have access to +on Vagrant Cloud, as well as authentication and version information. + +### Required + +- `box_tag` (string) - The shorthand tag for your box that maps to Vagrant + Cloud, for example `hashicorp/precise64`, which is short for + `vagrantcloud.com/hashicorp/precise64`. This box must already exist in + Vagrant Cloud. Packer will not create the box automatically. + +- `version` (string) - The version number, typically incrementing a previous + version. The version string is validated based on [Semantic + Versioning](http://semver.org/). The string must match a pattern that could + be semver, and doesn't validate that the version comes after your previous + versions. + +- `access_token` (string) - Your access token for the Vagrant Cloud API. This + can be generated on your [tokens + page](https://app.vagrantup.com/settings/security). If not specified, the + environment will be searched. First, `VAGRANT_CLOUD_TOKEN` is checked, and + if nothing is found, finally `ATLAS_TOKEN` will be used. This is required + unless you are using a private hosting solution (i.e. `vagrant_cloud_url` + has been populated). + + **or** + +- `vagrant_cloud_url` (string) - Override the base URL for Vagrant Cloud. + This is useful if you're using Vagrant Private Cloud in your own network. + Defaults to `https://vagrantcloud.com/api/v1`. If this value is set to something + other than the default then `access_token` can be left blank and no + `Authorization` header will be added to requests sent by this post-processor. + +### Optional + +- `no_release` (string) - If set to true, does not release the version on + Vagrant Cloud, making it active. You can manually release the version via + the API or Web UI. Defaults to `false`. + +- `insecure_skip_tls_verify` (boolean) - If set to true _and_ `vagrant_cloud_url` + is set to something different than its default, it will set TLS InsecureSkipVerify + to true. In other words, this will disable security checks of SSL. You may need + to set this option to true if your host at `vagrant_cloud_url` is using a + self-signed certificate. + +- `keep_input_artifact` (boolean) - When true, preserve the local box + after uploading to Vagrant cloud. Defaults to `true`. + +- `version_description` (string) - Optional Markdown text used as a + full-length and in-depth description of the version, typically for denoting + changes introduced + +- `box_download_url` (string) - Optional URL for a self-hosted box. + If this is set the box will not be uploaded to the Vagrant Cloud. + This is a [template engine](https://developer.hashicorp.com/packer/docs/templates/legacy_json_templates/engine). + Therefore, you may use user variables and template functions in this field. + The following extra variables are also available in this engine: + + - `Provider`: The Vagrant provider the box is for + - `ArtifactId`: The ID of the input artifact. + +- `box_checksum` (string) - Optional checksum for the provider .box file. + The type of the checksum is specified within the checksum field as a prefix, + ex: "md5:{$checksum}". Valid values are: + - null or "" + - "md5:{$checksum}" + - "sha1:{$checksum}" + - "sha256:{$checksum}" + - "sha512:{$checksum}" + See + +- `no_direct_upload` (boolean) - When `true`, upload the box artifact through + Vagrant Cloud instead of directly to the backend storage. + +## Use with the Vagrant Post-Processor + +An example configuration is shown below. Note the use of the [post-processors](https://developer.hashicorp.com/packer/docs/templates/hcl_templates/blocks/build/post-processors) +block that wraps both the Vagrant and Vagrant Cloud [post-processor](https://developer.hashicorp.com/packer/docs/templates/hcl_templates/blocks/build/post-processor) blocks within the post-processor section. Chaining +the post-processors together in this way tells Packer that the artifact +produced by the Vagrant post-processor should be passed directly to the Vagrant +Cloud Post-Processor. It also sets the order in which the post-processors +should run. + +Failure to chain the post-processors together in this way will result in the +wrong artifact being supplied to the Vagrant Cloud post-processor. This will +likely cause the Vagrant Cloud post-processor to error and fail. + +**JSON** + +```json +{ + "variables": { + "cloud_token": "{{ env `VAGRANT_CLOUD_TOKEN` }}", + "version": "1.0.{{timestamp}}" + }, + "post-processors": [ + { + "type": "shell-local", + "inline": ["echo Doing stuff..."] + }, + [ + { + "type": "vagrant", + "include": ["image.iso"], + "vagrantfile_template": "vagrantfile.tpl", + "output": "proxycore_{{.Provider}}.box" + }, + { + "type": "vagrant-cloud", + "box_tag": "hashicorp/precise64", + "access_token": "{{user `cloud_token`}}", + "version": "{{user `version`}}" + } + ] + ] +} +``` + +**HCL2** + +```hcl +build { + sources = ["source.null.autogenerated_1"] + + post-processor "shell-local" { + inline = ["echo Doing stuff..."] + } + post-processors { + post-processor "vagrant" { + include = ["image.iso"] + output = "proxycore_{{.Provider}}.box" + vagrantfile_template = "vagrantfile.tpl" + } + post-processor "vagrant-cloud" { + access_token = "${var.cloud_token}" + box_tag = "hashicorp/precise64" + version = "${local.version}" + } + } +} +``` + + +## Use with the Artifice Post-Processor + +An example configuration is shown below. Note the use of the nested array that +wraps both the Artifice and Vagrant Cloud post-processors within the +post-processor section. Chaining the post-processors together in this way tells +Packer that the artifact produced by the Artifice post-processor should be +passed directly to the Vagrant Cloud Post-Processor. It also sets the order in +which the post-processors should run. + +Failure to chain the post-processors together in this way will result in the +wrong artifact being supplied to the Vagrant Cloud post-processor. This will +likely cause the Vagrant Cloud post-processor to error and fail. + +Note that the Vagrant box specified in the Artifice post-processor `files` array +must end in the `.box` extension. It must also be the first file in the array. +Additional files bundled by the Artifice post-processor will be ignored. + +**JSON** + +```json +{ + "variables": { + "cloud_token": "{{ env `VAGRANT_CLOUD_TOKEN` }}" + }, + + "builders": [ + { + "type": "null", + "communicator": "none" + } + ], + + "post-processors": [ + { + "type": "shell-local", + "inline": ["echo Doing stuff..."] + }, + [ + { + "type": "artifice", + "files": ["./path/to/my.box"] + }, + { + "type": "vagrant-cloud", + "box_tag": "myorganisation/mybox", + "access_token": "{{user `cloud_token`}}", + "version": "0.1.0" + } + ] + ] +} +``` + +**HCL2** + +```hcl +variable "cloud_token" { + type = string + default = "${env("VAGRANT_CLOUD_TOKEN")}" +} + +source "null" "autogenerated_1" { + communicator = "none" +} + +build { + sources = ["source.null.autogenerated_1"] + + post-processor "shell-local" { + inline = ["echo Doing stuff..."] + } + post-processors { + post-processor "artifice" { + files = ["./path/to/my.box"] + } + post-processor "vagrant-cloud" { + access_token = "${var.cloud_token}" + box_tag = "myorganisation/mybox" + version = "0.1.0" + } + } +} +``` diff --git a/.web-docs/components/post-processor/vagrant/README.md b/.web-docs/components/post-processor/vagrant/README.md new file mode 100644 index 00000000..13f11322 --- /dev/null +++ b/.web-docs/components/post-processor/vagrant/README.md @@ -0,0 +1,251 @@ +Type: `vagrant` +Artifact BuilderId: `mitchellh.post-processor.vagrant` + +The Packer Vagrant post-processor takes a build and converts the artifact into +a valid [Vagrant](https://developer.hashicorp.com/vagrant) box, if it can. This lets you use +Packer to automatically create arbitrarily complex Vagrant boxes, and is in +fact how the official boxes distributed by Vagrant are created. + +If you've never used a post-processor before, please read the documentation on +[using post-processors](https://developer.hashicorp.com/packer/docs/post-processors). +This knowledge will be expected for the remainder of this document. + +Because Vagrant boxes are +[provider-specific](https://developer.hashicorp.com/vagrant/docs/boxes/format), the +Vagrant post-processor is hardcoded to understand how to convert the artifacts +of certain builders into proper boxes for their respective providers. + +Currently, the Vagrant post-processor can create boxes for the following +providers. + +- AWS +- Azure +- DigitalOcean +- Docker +- Hyper-V +- LXC +- Parallels +- QEMU +- VirtualBox +- VMware + +-> **Support for additional providers** is planned. If the Vagrant +post-processor doesn't support creating boxes for a provider you care about, +please help by contributing to Packer and adding support for it. + +Please note that if you are using the Vagrant builder, then the Vagrant +post-processor is unnecessary because the output of the Vagrant builder is +already a Vagrant box; using this post-processor with the Vagrant builder will +cause your build to fail. + +## Configuration + +The simplest way to use the post-processor is to just enable it. No +configuration is required by default. This will mostly do what you expect and +will build functioning boxes for many of the built-in builders of Packer. + +However, if you want to configure things a bit more, the post-processor does +expose some configuration options. The available options are listed below, with +more details about certain options in following sections. + +- `compression_level` (number) - An integer representing the compression + level to use when creating the Vagrant box. Valid values range from 0 to 9, + with 0 being no compression and 9 being the best compression. By default, + compression is enabled at level 6. + +- `include` (array of strings) - Paths to files to include in the Vagrant + box. These files will each be copied into the top level directory of the + Vagrant box (regardless of their paths). They can then be used from the + Vagrantfile. + +- `keep_input_artifact` (boolean) - When true, preserve the artifact we use to + create the vagrant box. Defaults to `false`, except when you set a cloud + provider (e.g. aws, azure, google, digitalocean). In these cases deleting + the input artifact would render the vagrant box useless, so we always keep + these artifacts -- even if you specifically set + `"keep_input_artifact":false` + +- `output` (string) - The full path to the box file that will be created by + this post-processor. This is a + [template engine](https://developer.hashicorp.com/packer/docs/templates/legacy_json_templates/engine). Therefore, you may use user + variables and template functions in this field. The following extra + variables are also available in this engine: + + - `Provider`: The Vagrant provider the box is for + - `ArtifactId`: The ID of the input artifact. + - `BuildName`: The name of the build. + + By default, the value of this config is + `packer_{{.BuildName}}_{{.Provider}}.box`. + +- `provider_override` (string) - this option will override the internal logic + that decides which Vagrant provider to set for a particular Packer builder's + or post-processor's artifact. It is required when the artifact comes from the + Artifice post-processor, but is otherwise optional. Valid options are: + `digitalocean`, `virtualbox`, `azure`, `vmware`, `libvirt`, `docker`, + `lxc`, `scaleway`, `hyperv`, `parallels`, `aws`, or `google`. + +- `vagrantfile_template` (string) - Path to a template to use for the + Vagrantfile that is packaged with the box. This option supports the usage of the [template engine](https://developer.hashicorp.com/packer/docs/templates/legacy_json_templates/engine) + for JSON and the [contextual variables](https://developer.hashicorp.com/packer/docs/templates/hcl_templates/contextual-variables) for HCL2. + +- `vagrantfile_template_generated` (boolean) - By default, Packer will + exit with an error if the file specified using the + `vagrantfile_template` variable is not found. However, under certain + circumstances, it may be desirable to dynamically generate the + Vagrantfile during the course of the build. Setting this variable to + `true` skips the start up check and allows the user to script the + creation of the Vagrantfile at some previous point in the build. + Defaults to `false`. + +## Using together with the Artifice post-processor + +Sometimes you may want to run several builds in a pipeline rather than running +this post-processor inside a long-running Packer build. Here is an example of +how to do this: + +**JSON** + +```json +{ + "builders": [ + { + "type": "null", + "communicator": "none" + } + ], + "post-processors": [ + [ + { + "type": "artifice", + "files": [ + "output-virtualbox-iso/vbox-example-disk001.vmdk", + "output-virtualbox-iso/vbox-example.ovf" + ] + }, + { + "type": "vagrant", + "keep_input_artifact": true, + "provider_override": "virtualbox" + } + ] + ] +} +``` + +**HCL2** + +```hcl +source "null" "example" { + communicator = "none" +} + +build { + sources = [ + "source.null.example" + ] + post-processors { + post-processor "artifice" { + files = [ + "output-virtualbox-iso/vbox-example-disk001.vmdk", + "output-virtualbox-iso/vbox-example.ovf" + ] + } + post-processor "vagrant" { + keep_input_artifact = true + provider_override = "virtualbox" + } + } +} +``` + + +## Provider-Specific Overrides + +If you have a Packer template with multiple builder types within it, you may +want to configure the box creation for each type a little differently. For +example, the contents of the Vagrantfile for a Vagrant box for AWS might be +different from the contents of the Vagrantfile you want for VMware. The +post-processor lets you do this. + +Specify overrides within the `override` configuration by provider name: + +**JSON** + +```json +{ + "type": "vagrant", + "compression_level": 1, + "override": { + "vmware": { + "compression_level": 0 + } + } +} +``` + +**HCL2** + +```hcl +## This feature is not implemented in HCL. +``` + + +In the example above, the compression level will be set to 1 except for VMware, +where it will be set to 0. + +The available provider names are: + +- `aws` +- `azure` +- `digitalocean` +- `google` +- `hyperv` +- `parallels` +- `libvirt` +- `lxc` +- `scaleway` +- `virtualbox` +- `vmware` +- `docker` + +## Input Artifacts + +By default, Packer will delete the original input artifact, assuming you only +want the final Vagrant box as the result. If you wish to keep the input +artifact (the raw virtual machine, for example), then you must configure Packer +to keep it. + +Please see the [documentation on input artifacts](https://developer.hashicorp.com/packer/docs/templates/legacy_json_templates/post-processors#input-artifacts) +for more information. + +### Docker + +Using a Docker input artifact will include a reference to the image in the +`Vagrantfile`. If the image tag is not specified in the post-processor, the +sha256 hash will be used. + +The following Docker input artifacts are supported: + +- `docker` builder with `commit: true`, always uses the sha256 hash +- `docker-import` +- `docker-tag` +- `docker-push` + +### QEMU/libvirt + +The `libvirt` provider supports QEMU artifacts built using any these +accelerators: none, kvm, tcg, or hvf. + +### VMWare + +If you are using the Vagrant post-processor with the `vmware-esxi` builder, you +must export the builder artifact locally; the Vagrant post-processor will +not work on remote artifacts. + +### Artifice + +If you are using this post-processor after defining an artifact using the +Artifice post-processor, then you must set the "provider_override" template +option so that the Vagrant post-processor knows what provider to use to create +the Vagrant box. diff --git a/.web-docs/metadata.hcl b/.web-docs/metadata.hcl new file mode 100644 index 00000000..0dee45d7 --- /dev/null +++ b/.web-docs/metadata.hcl @@ -0,0 +1,22 @@ +# For full specification on the configuration of this file visit: +# https://github.com/hashicorp/integration-template#metadata-configuration +integration { + name = "Vagrant" + description = "The Vagrant multi-component plugin can be used with HashiCorp Packer to create custom images." + identifier = "packer/hashicorp/vagrant" + component { + type = "builder" + name = "Vagrant" + slug = "vagrant" + } + component { + type = "post-processor" + name = "Vagrant Cloud" + slug = "vagrant-cloud" + } + component { + type = "post-processor" + name = "Vagrant" + slug = "vagrant" + } +} diff --git a/.web-docs/scripts/compile-to-webdocs.sh b/.web-docs/scripts/compile-to-webdocs.sh new file mode 100755 index 00000000..51a72383 --- /dev/null +++ b/.web-docs/scripts/compile-to-webdocs.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env bash + +# Converts the folder name that the component documentation file +# is stored in into the integration slug of the component. +componentTypeFromFolderName() { + if [[ "$1" = "builders" ]]; then + echo "builder" + elif [[ "$1" = "provisioners" ]]; then + echo "provisioner" + elif [[ "$1" = "post-processors" ]]; then + echo "post-processor" + elif [[ "$1" = "datasources" ]]; then + echo "data-source" + else + echo "" + fi +} + +# $1: The content to adjust links +# $2: The organization of the integration +rewriteLinks() { + local result="$1" + local organization="$2" + + urlSegment="([^/]+)" + urlAnchor="(#[^/]+)" + + # Rewrite Component Index Page links to the Integration root page. + # + # (\1) (\2) (\3) + # /packer/plugins/datasources/amazon#anchor-tag--> + # /packer/integrations/hashicorp/amazon#anchor-tag + local find="\(\/packer\/plugins\/$urlSegment\/$urlSegment$urlAnchor?\)" + local replace="\(\/packer\/integrations\/$organization\/\2\3\)" + result="$(echo "$result" | sed -E "s/$find/$replace/g")" + + + # Rewrite Component links to the Integration component page + # + # (\1) (\2) (\3) (\4) + # /packer/plugins/datasources/amazon/parameterstore#anchor-tag --> + # /packer/integrations/{organization}/amazon/latest/components/datasources/parameterstore + local find="\(\/packer\/plugins\/$urlSegment\/$urlSegment\/$urlSegment$urlAnchor?\)" + local replace="\(\/packer\/integrations\/$organization\/\2\/latest\/components\/\1\/\3\4\)" + result="$(echo "$result" | sed -E "s/$find/$replace/g")" + + # Rewrite the Component URL segment from the Packer Plugin format + # to the Integrations format + result="$(echo "$result" \ + | sed "s/\/datasources\//\/data-source\//g" \ + | sed "s/\/builders\//\/builder\//g" \ + | sed "s/\/post-processors\//\/post-processor\//g" \ + | sed "s/\/provisioners\//\/provisioner\//g" \ + )" + + echo "$result" +} + +# $1: Docs Dir +# $2: Web Docs Dir +# $3: Component File +# $4: The org of the integration +processComponentFile() { + local docsDir="$1" + local webDocsDir="$2" + local componentFile="$3" + + local escapedDocsDir="$(echo "$docsDir" | sed 's/\//\\\//g' | sed 's/\./\\\./g')" + local componentTypeAndSlug="$(echo "$componentFile" | sed "s/$escapedDocsDir\///g" | sed 's/\.mdx//g')" + + # Parse out the Component Slug & Component Type + local componentSlug="$(echo "$componentTypeAndSlug" | cut -d'/' -f 2)" + local componentType="$(componentTypeFromFolderName "$(echo "$componentTypeAndSlug" | cut -d'/' -f 1)")" + if [[ "$componentType" = "" ]]; then + echo "Failed to process '$componentFile', unexpected folder name." + echo "Documentation for components must be stored in one of:" + echo "builders, provisioners, post-processors, datasources" + exit 1 + fi + + + # Calculate the location of where this file will ultimately go + local webDocsFolder="$webDocsDir/components/$componentType/$componentSlug" + mkdir -p "$webDocsFolder" + local webDocsFile="$webDocsFolder/README.md" + local webDocsFileTmp="$webDocsFolder/README.md.tmp" + + # Copy over the file to its webDocsFile location + cp "$componentFile" "$webDocsFile" + + # Remove the Header + local lastMetadataLine="$(grep -n -m 2 '^\-\-\-' "$componentFile" | tail -n1 | cut -d':' -f1)" + cat "$webDocsFile" | tail -n +"$(($lastMetadataLine+2))" > "$webDocsFileTmp" + mv "$webDocsFileTmp" "$webDocsFile" + + # Remove the top H1, as this will be added automatically on the web + cat "$webDocsFile" | tail -n +3 > "$webDocsFileTmp" + mv "$webDocsFileTmp" "$webDocsFile" + + # Rewrite Links + rewriteLinks "$(cat "$webDocsFile")" "$4" > "$webDocsFileTmp" + mv "$webDocsFileTmp" "$webDocsFile" +} + +# Compiles the Packer SDC compiled docs folder down +# to a integrations-compliant folder (web docs) +# +# $1: The directory of the plugin +# $2: The directory of the SDC compiled docs files +# $3: The output directory to place the web-docs files +# $4: The org of the integration +compileWebDocs() { + local docsDir="$1/$2" + local webDocsDir="$1/$3" + + echo "Compiling MDX docs in '$2' to Markdown in '$3'..." + # Create the web-docs directory if it hasn't already been created + mkdir -p "$webDocsDir" + + # Copy the README over + cp "$docsDir/README.md" "$webDocsDir/README.md" + + # Process all MDX component files (exclude index files, which are unsupported) + for file in $(find "$docsDir" | grep "$docsDir/.*/.*\.mdx" | grep --invert-match "index.mdx"); do + processComponentFile "$docsDir" "$webDocsDir" "$file" "$4" + done +} + +compileWebDocs "$1" "$2" "$3" "$4" diff --git a/GNUmakefile b/GNUmakefile index fe638393..d9a8e031 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -34,3 +34,9 @@ generate: install-packer-sdc @go generate ./... packer-sdc renderdocs -src ./docs -dst ./.docs -partials ./docs-partials # checkout the .docs folder for a preview of the docs + +build-docs: install-packer-sdc + @if [ -d ".docs" ]; then rm -r ".docs"; fi + @packer-sdc renderdocs -src "docs" -partials docs-partials/ -dst ".docs/" + @./.web-docs/scripts/compile-to-webdocs.sh "." ".docs" ".web-docs" "hashicorp" + @rm -r ".docs" diff --git a/docs/README.md b/docs/README.md index d7205cc9..38cb3a8c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,9 +1,31 @@ -# Vagrant Plugin The Vagrant plugin integrates Packer with HashiCorp [Vagrant](https://www.vagrantup.com/), allowing you to use Packer to create development boxes. -- [vagrant builder](/docs/builders/vagrant.mdx) - The Vagrant builder is intended for building new boxes from already-existing boxes. +### Installation +To install this plugin add this code into your Packer configuration and run [packer init](/packer/docs/commands/init) -- [vagrant post-processor](/docs/post-processors/vagrant.mdx) - The Packer Vagrant post-processor takes a build and converts the artifact into a valid Vagrant box. +```hcl +packer { + required_plugins { + vagrant = { + version = "~> 1" + source = "github.com/hashicorp/vagrant" + } + } +} +``` -- [vagrant-cloud post-processor](/docs/post-processors/vagrant-cloud.mdx) - The Vagrant Cloud post-processor enables the upload of Vagrant boxes to Vagrant Cloud. +Alternatively, you can use `packer plugins install` to manage installation of this plugin. + +```sh +packer plugins install github.com/hashicorp/vagrant +``` + +### Components + +#### Builders +- [vagrant](/packer/integrations/hashicorp/vagrant/latest/components/builder/vagrant) - The Vagrant builder is intended for building new boxes from already-existing boxes. + +#### Post-Processor +- [vagrant](/packer/integrations/hashicorp/vagrant/latest/components/post-processor/vagrant) - The Packer Vagrant post-processor takes a build and converts the artifact into a valid Vagrant box. +- [vagrant-cloud](/packer/integrations/hashicorp/vagrant/latest/components/post-processor/vagrant-cloud) - The Vagrant Cloud post-processor enables the upload of Vagrant boxes to Vagrant Cloud. diff --git a/docs/builders/vagrant.mdx b/docs/builders/vagrant.mdx index fec91707..30b72083 100644 --- a/docs/builders/vagrant.mdx +++ b/docs/builders/vagrant.mdx @@ -67,8 +67,7 @@ the Compress post-processor will not work with this builder. Sample for `hashicorp/precise64` with virtualbox provider. - - +**JSON** ```json { @@ -84,8 +83,7 @@ Sample for `hashicorp/precise64` with virtualbox provider. } ``` - - +**HCL2** ```hcl source "vagrant" "example" { @@ -100,8 +98,6 @@ build { } ``` - - ## Regarding output directory and new box diff --git a/docs/post-processors/vagrant-cloud.mdx b/docs/post-processors/vagrant-cloud.mdx index 3050bf14..6c24d395 100644 --- a/docs/post-processors/vagrant-cloud.mdx +++ b/docs/post-processors/vagrant-cloud.mdx @@ -22,7 +22,7 @@ supplied to it from the [Vagrant](/docs/post-processors/vagrant.mdx) or [Vagrant](/docs/builders/vagrant.mdx) builder. You'll need to be familiar with Vagrant Cloud, have an upgraded account to -enable box hosting, and be distributing your box via the [shorthand name](https://docs.vagrantup.com/v2/cli/box.html) configuration. +enable box hosting, and be distributing your box via the [shorthand name](https://developer.hashicorp.com/vagrant/docs/cli/box) configuration. ## Workflow @@ -49,7 +49,7 @@ Here is an example workflow: ~> The Vagrant Cloud box (`hashicorp/foobar` in this example) must already exist. Packer will not create the box automatically. If running Packer in automation, consider using the -[Vagrant Cloud API](https://www.vagrantup.com/docs/vagrant-cloud/api) +[Vagrant Cloud API](https://developer.hashicorp.com/vagrant/vagrant-cloud/api) to create the Vagrant Cloud box if it doesn't already exist. ## Configuration @@ -130,7 +130,7 @@ on Vagrant Cloud, as well as authentication and version information. ## Use with the Vagrant Post-Processor An example configuration is shown below. Note the use of the [post-processors](https://developer.hashicorp.com/packer/docs/templates/hcl_templates/blocks/build/post-processors) -block that wraps both the Vagrant and Vagrant Cloud [post-processor](https://developer.hashicorp.com/packer/docs/templates/hcl_templates/blocks/build/post-processors) blocks within the post-processor section. Chaining +block that wraps both the Vagrant and Vagrant Cloud [post-processor](https://developer.hashicorp.com/packer/docs/templates/hcl_templates/blocks/build/post-processor) blocks within the post-processor section. Chaining the post-processors together in this way tells Packer that the artifact produced by the Vagrant post-processor should be passed directly to the Vagrant Cloud Post-Processor. It also sets the order in which the post-processors @@ -140,8 +140,7 @@ Failure to chain the post-processors together in this way will result in the wrong artifact being supplied to the Vagrant Cloud post-processor. This will likely cause the Vagrant Cloud post-processor to error and fail. - - +**JSON** ```json { @@ -172,8 +171,7 @@ likely cause the Vagrant Cloud post-processor to error and fail. } ``` - - +**HCL2** ```hcl build { @@ -197,8 +195,6 @@ build { } ``` - - ## Use with the Artifice Post-Processor @@ -217,8 +213,7 @@ Note that the Vagrant box specified in the Artifice post-processor `files` array must end in the `.box` extension. It must also be the first file in the array. Additional files bundled by the Artifice post-processor will be ignored. - - +**JSON** ```json { @@ -254,8 +249,7 @@ Additional files bundled by the Artifice post-processor will be ignored. } ``` - - +**HCL2** ```hcl variable "cloud_token" { @@ -285,6 +279,3 @@ build { } } ``` - - - diff --git a/docs/post-processors/vagrant.mdx b/docs/post-processors/vagrant.mdx index a772617b..78d364bd 100644 --- a/docs/post-processors/vagrant.mdx +++ b/docs/post-processors/vagrant.mdx @@ -18,7 +18,7 @@ Type: `vagrant` Artifact BuilderId: `mitchellh.post-processor.vagrant` The Packer Vagrant post-processor takes a build and converts the artifact into -a valid [Vagrant](https://www.vagrantup.com) box, if it can. This lets you use +a valid [Vagrant](https://developer.hashicorp.com/vagrant) box, if it can. This lets you use Packer to automatically create arbitrarily complex Vagrant boxes, and is in fact how the official boxes distributed by Vagrant are created. @@ -120,8 +120,7 @@ Sometimes you may want to run several builds in a pipeline rather than running this post-processor inside a long-running Packer build. Here is an example of how to do this: - - +**JSON** ```json { @@ -150,8 +149,7 @@ how to do this: } ``` - - +**HCL2** ```hcl source "null" "example" { @@ -162,7 +160,7 @@ build { sources = [ "source.null.example" ] - post-processors { + post-processors { post-processor "artifice" { files = [ "output-virtualbox-iso/vbox-example-disk001.vmdk", @@ -172,13 +170,11 @@ build { post-processor "vagrant" { keep_input_artifact = true provider_override = "virtualbox" - } - } + } + } } ``` - - ## Provider-Specific Overrides @@ -190,8 +186,7 @@ post-processor lets you do this. Specify overrides within the `override` configuration by provider name: - - +**JSON** ```json { @@ -205,15 +200,12 @@ Specify overrides within the `override` configuration by provider name: } ``` - - +**HCL2** ```hcl ## This feature is not implemented in HCL. ``` - - In the example above, the compression level will be set to 1 except for VMware, where it will be set to 0.