Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Register plug-in as Packer integration #277

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/ensure-docs-compiled.yaml
Original file line number Diff line number Diff line change
@@ -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@v2
- 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

50 changes: 50 additions & 0 deletions .github/workflows/notify-integration-release-via-manual.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Manual release workflow is used for deploying documentation updates
# on the specified branch without making an official plugin release.
name: Notify Integration Release (Manual)
on:
workflow_dispatch:
inputs:
version:
description: "The release version (semver)"
default: 1.0.0
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@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
with:
ref: ${{ github.event.inputs.branch }}
# Ensure that Docs are Compiled
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
- 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@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
with:
repository: hashicorp/integration-release-action
path: ./integration-release-action
- name: Notify Release
uses: ./integration-release-action
with:
# The integration identifier will be used by the Packer team to register the integration
# the expected format is packer/<GitHub Org Name>/<plugin-name>
integration_identifier: "packer/vultr/vultr"
release_version: ${{ github.event.inputs.version }}
release_sha: ${{ github.event.inputs.branch }}
github_token: ${{ secrets.GITHUB_TOKEN }}
54 changes: 54 additions & 0 deletions .github/workflows/notify-integration-release-via-tag.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Notify Integration Release (Tag)
on:
push:
tags:
- '*.*.*' # Proper releases
jobs:
strip-version:
runs-on: ubuntu-latest
outputs:
packer-version: ${{ steps.strip.outputs.packer-version }}
steps:
- name: Strip leading v from version tag
id: strip
env:
REF: ${{ github.ref_name }}
run: |
echo "packer-version=$(echo "$REF" | sed -E 's/v?([0-9]+\.[0-9]+\.[0-9]+)/\1/')" >> "$GITHUB_OUTPUT"
notify-release:
needs:
- strip-version
runs-on: ubuntu-latest
steps:
- name: Checkout this repo
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
with:
ref: ${{ github.ref }}
# Ensure that Docs are Compiled
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
- 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@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
with:
repository: hashicorp/integration-release-action
path: ./integration-release-action
- name: Notify Release
uses: ./integration-release-action
with:
# The integration identifier will be used by the Packer team to register the integration
# the expected format is packer/<GitHub Org Name>/<plugin-name>
integration_identifier: "packer/vultr/vultr"
release_version: ${{ needs.strip-version.outputs.packer-version }}
release_sha: ${{ github.ref }}
github_token: ${{ secrets.GITHUB_TOKEN }}
30 changes: 30 additions & 0 deletions .web-docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
The [Vultr](https://www.Vultr.com/) Packer plugin provides a builder for building images in
Vultr.

### Installation

To install this plugin, copy and paste this code into your Packer configuration, then run [`packer init`](https://www.packer.io/docs/commands/init).

```hcl
packer {
required_plugins {
vultr = {
version = ">= 2.5.0"
source = "github.com/vultr/vultr"
}
}
}
```

Alternatively, you can use `packer plugins install` to manage installation of this plugin.

```sh
$ packer plugins install github.com/vultr/vultr
```


### Components

#### Builders

- [vultr](/packer/integrations/vultr/vultr/latest/components/builder/vultr) - The builder takes a source image, runs any provisioning necessary on the image after launching it, then snapshots it into a reusable image. This reusable image can then be used as the foundation of new servers that are launched within Vultr.
81 changes: 81 additions & 0 deletions .web-docs/components/builder/vultr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
Type: `vultr`

The `vultr` Packer builder is able to create new images for use with
[Vultr](https://www.vultr.com). The builder takes a source image,
runs any provisioning necessary on the image after launching it, then snapshots
it into a reusable image. This reusable image can be then used as the
foundation of new servers that are launched within Vultr.

The builder does *not* manage images. Once it creates an image, it is up to you
to use it or delete it.

**NOTE**: Packer-Builder-Vultr [v2+](https://github.com/vultr/packer-builder-vultr/blob/master/CHANGELOG.md#v200-2020-11-23) uses [API V2](https://www.vultr.com/api/)


## Required:

- `api_key` (string) - The Vultr API Key to access your account.

- `region_id` (string) - The id of the region to launch the instance in. See [List Regions](https://www.vultr.com/api/v2/#operation/list-regions).

- `plan_id` (string) - The id of the plan you wish to use. See [List Plans](https://www.vultr.com/api/v2/#tag/plans).

**NOTE**: that `os_id`, `app_id`, `snapshot_id`, or `iso_id` are not required and are optional. You **must** supply at least one for instance creation.
## Optional

- `os_id` (int) - The id of the os to use. This will be the OS that will be used to launch a new instance and provision it. See [List Operating Systems](https://www.vultr.com/api/v2/#operation/list-os).

- `snapshot_description` (string) - Description of the snapshot.

- `snapshot_id` (string) - If you've selected the 'snapshot' operating system, this should be the ID of the snapshot. See [Snapshot](https://www.vultr.com/api/v2/#operation/list-snapshots).

- `iso_id` (string) - If you've selected the 'custom' operating system, this is the ID of a specific ISO to mount during the deployment. See [ISO](https://www.vultr.com/api/v2/#operation/list-isos).

- `iso_url` (string) - Upload a new ISO from this url that is publicly accessible. See [Create ISO](https://www.vultr.com/api/#operation/create-iso). This ISO will be deleted upon successful provisioning, or if the build is cancelled.

- `app_id` (int) - If launching an application, this is the ID to launch. See [App](https://www.vultr.com/api/v2/#operation/list-applications).

- `image_id` (string) If launching a marketplace application. See [App](https://www.vultr.com/api/v2/#operation/list-applications). Note marketplace applications are denoted by `type: marketplace` and you must use the `image_id` not the `id`.

- `enable_ipv6` (bool) - IPv6 subnet will be assigned to the machine. Defaults to `false`

- `enable_private_network` (bool) - Enables private networking support to the new server. Defaults to `false`

- `script_id` (string) - If you've not selected a 'custom' (OS 159) operating system, this can be the `id` of a startup script to execute on boot. See [Startup Script](https://www.vultr.com/api/v2/#operation/list-startup-scripts).

- `ssh_key_ids` (array of string) - List of SSH keys to apply to this server on install. Separate keys with commas. See [SSH Key](https://www.vultr.com/api/v2/#operation/list-ssh-keys).

- `instance_label` (string) - This is a text label that will be shown in the control panel.

- `userdata` (string) - Base64 encoded user-data.

- `hostname` (string) - Hostname to assign to this server.

- `tag` (string) - The tag to assign to this server.

- `state_timeout` (string) - A duration to wait for the instance to boot, or a snapshot to be taken. Must be a string in [golang Duration-parsable format](https://golang.org/pkg/time/#ParseDuration), like "10m" or "30s". Defaults to `10m`

You may also adjust the [SSH communicator settings](https://www.packer.io/docs/communicators/ssh) to configure how Packer will log into Vultr Instances.
## Example Usage


```hcl
variable "vultr_api_key" {
type = string
default = "${env("VULTR_API_KEY")}"
}

source "vultr" "ubuntu-20" {
api_key = "${var.vultr_api_key}"
os_id = "413"
plan_id = "vhf-1c-1gb"
region_id = "atl"
snapshot_description = "testing"
state_timeout = "10m"
ssh_username = "root"
}

build {
sources = ["source.vultr.ubuntu-20"]
}
```
12 changes: 12 additions & 0 deletions .web-docs/metadata.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# For full specification on the configuration of this file visit:
# https://github.com/hashicorp/integration-template#metadata-configuration
integration {
name = "Vultr"
description = "A plugin for creating Vultr snapshots."
identifier = "packer/vultr/vultr"
component {
type = "builder"
name = "Vultr"
slug = "vultr"
}
}
129 changes: 129 additions & 0 deletions .web-docs/scripts/compile-to-webdocs.sh
Original file line number Diff line number Diff line change
@@ -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"