Skip to content

Commit 1bcfc50

Browse files
authored
Refactor/docs and examples (#22)
Use packer-sdc to build document fragments based on config and move documentation focus under docs directory. Remove old examples directory and replace it with example directory and add GH workflow to test it.
1 parent 129c9a6 commit 1bcfc50

File tree

20 files changed

+725
-311
lines changed

20 files changed

+725
-311
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# This is a manually triggered action workflow.
2+
# It uses Packer at latest version to init, validate and build
3+
# an example configuration in a folder.
4+
# This action is compatible with Packer v1.7.0 or later.
5+
name: test plugin example
6+
7+
on:
8+
workflow_dispatch:
9+
inputs:
10+
logs:
11+
description: "Set 1 to activate full logs"
12+
required: false
13+
default: "0"
14+
folder:
15+
description: "Example folder"
16+
required: false
17+
default: "./example"
18+
19+
jobs:
20+
build:
21+
runs-on: ubuntu-latest
22+
name: init and build example
23+
env:
24+
UPCLOUD_API_USER: ${{ secrets.UPCLOUD_API_USER }}
25+
UPCLOUD_API_PASSWORD: ${{ secrets.UPCLOUD_API_PASSWORD }}
26+
steps:
27+
- name: Checkout Repository
28+
uses: actions/checkout@v2
29+
30+
- name: Init
31+
uses: hashicorp/packer-github-actions@master
32+
with:
33+
working_directory: ${{ github.event.inputs.folder }}
34+
command: init
35+
36+
- name: Validate
37+
uses: hashicorp/packer-github-actions@master
38+
with:
39+
working_directory: ${{ github.event.inputs.folder }}
40+
command: validate
41+
arguments: -var="ssh_public_key=/dev/null"
42+
env:
43+
PACKER_LOG: ${{ github.event.inputs.logs }}
44+
45+
- name: Build
46+
uses: hashicorp/packer-github-actions@master
47+
with:
48+
working_directory: ${{ github.event.inputs.folder }}
49+
command: build
50+
arguments: -var="ssh_public_key=/dev/null"
51+
env:
52+
PACKER_LOG: ${{ github.event.inputs.logs }}

Makefile

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ GOBIN=$(shell go env GOBIN)
1010
endif
1111

1212
PACKER_SDC=$(GOBIN)/packer-sdc
13+
PACKER_SDC_RENDER_DOCS=$(PACKER_SDC) renderdocs -src docs-src/ -partials docs-partials/ -dst docs/
14+
1315

1416
default: build
1517

@@ -35,14 +37,19 @@ install-packer-sdc: ## Install packer sofware development command
3537
go install github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc@$(HASHICORP_PACKER_PLUGIN_SDK_VERSION)
3638

3739
ci-release-docs: install-packer-sdc
38-
@$(PACKER_SDC) renderdocs -src docs -partials docs-partials/ -dst docs/
40+
@$(PACKER_SDC_RENDER_DOCS)
3941
@/bin/sh -c "[ -d docs ] && zip -r docs.zip docs/"
4042

4143
plugin-check: install-packer-sdc build
4244
$(PACKER_SDC) plugin-check $(BINARY)
4345

44-
generate: install-packer-sdc
46+
generate: fmt install-packer-sdc
4547
@PATH=$(PATH):$(GOBIN) go generate ./...
46-
packer-sdc renderdocs -src ./docs -dst ./.docs -partials ./docs-partials
48+
@rm -fr $(CURDIR)/docs # renderdocs doesn't seem to properly overwrite files
49+
$(PACKER_SDC_RENDER_DOCS)
50+
51+
fmt:
52+
packer fmt example/
53+
packer fmt -recursive docs-partials/
4754

4855
.PHONY: default test test_integration lint build install

README.md

Lines changed: 4 additions & 202 deletions
Original file line numberDiff line numberDiff line change
@@ -1,213 +1,15 @@
1-
# UpCloud Packer builder
1+
# UpCloud Packer Plugin
22

33
![Build Status](https://github.com/UpCloudLtd/packer-plugin-upcloud/workflows/test/badge.svg)
44
![Release Status](https://github.com/UpCloudLtd/packer-plugin-upcloud/workflows/release/badge.svg)
55

66
This is a builder plugin for Packer which can be used to generate storage templates on UpCloud. It utilises the [UpCloud Go API](https://github.com/UpCloudLtd/upcloud-go-api) to interface with the UpCloud API.
77

8-
## Installation
8+
## Documentation
99

10-
### Installing using Packer Packet Manager
11-
12-
In order to use `packer init`:
13-
14-
1. You need to have Packer version ">=1.7.0" installed.
15-
2. The config template should be in `hcl` format.
16-
3. The config template file, when in `hcl` format, must have the extension `.pkr.hcl`.
17-
4. The config template must contain `required_plugins` block. For example:
18-
19-
```hcl
20-
...
21-
packer {
22-
required_plugins {
23-
upcloud = {
24-
version = ">=v1.0.0"
25-
source = "github.com/UpCloudLtd/upcloud"
26-
}
27-
}
28-
}
29-
...
30-
```
31-
32-
Run following command and check the output (NOTE: The file extension must be `*.pkr.hcl`):
33-
```sh
34-
$ packer init examples/basic_example.pkr.hcl
35-
36-
Installed plugin github.com/upcloudltd/upcloud v1.0.0 in "/Users/johndoe/.packer.d/plugins/github.com/upcloudltd/upcloud/packer-plugin-upcloud_v1.0.0_x5.0_darwin_amd64"
37-
```
38-
39-
After successful plugin installation, you can run the build command:
40-
```sh
41-
$ packer build examples/basic_example.pkr.hcl
42-
43-
...
44-
```
45-
46-
From Packer version 1.7.0, template HCL2 becomes officially the preferred way to write Packer configuration. While the `json` format is still supported, but certain new features, such as `packer init` works only in newer HCL2 format.
47-
If you are using `json` config templates, please consider upgrading them using the packer built-in command:
48-
49-
```sh
50-
$ packer hcl2_upgrade example.json
51-
Successfully created example.json.pkr.hcl
52-
```
53-
54-
55-
56-
57-
### Pre-built binaries
58-
59-
You can download the pre-built binaries of the plugin from the [GitHub releases page](https://github.com/UpCloudLtd/packer-plugin-upcloud/releases). Just download the archive for your operating system and architecture, unpack it, and place the binary in the appropriate location, e.g. on Linux `~/.packer.d/plugins`. Make sure the file is executable, then install [Packer](https://www.packer.io/).
60-
61-
Please note that use of symlinks with plugin binary can break Packer functionality ([see for details and workaround](https://github.com/hashicorp/packer/issues/10749#issuecomment-800120263)).
62-
63-
64-
### Installing from source
65-
66-
#### Prerequisites
67-
68-
You will need to have the [Go](https://golang.org/) programming language and the [Packer](https://www.packer.io/) itself installed. You can find instructions to install each of the prerequisites at their documentation.
69-
70-
#### Building and installing
71-
72-
Run the following commands to download and install the plugin from the source.
73-
74-
```sh
75-
git clone https://github.com/UpCloudLtd/packer-plugin-upcloud
76-
cd packer-plugin-upcloud
77-
go build
78-
cp packer-plugin-upcloud ~/.packer.d/plugins/
79-
```
80-
81-
## Usage
82-
83-
The builder will automatically generate a temporary SSH key pair for the `root` user which is used for provisioning. This means that if you do not provision a user during the process you will not be able to gain access to your server.
84-
85-
If you want to login to a server deployed with the template, you might want to include an SSH key to your `root` user by replacing the `<ssh-rsa_key>` in the below example with your public key.
86-
87-
Here is a sample template, which you can also find in the `examples/` directory. It reads your UpCloud API credentials from the environment variables and creates an Ubuntu 20.04 LTS server in the `nl-ams1` region.
88-
89-
```json
90-
{
91-
"variables": {
92-
"username": "{{ env `UPCLOUD_API_USER` }}",
93-
"password": "{{ env `UPCLOUD_API_PASSWORD` }}"
94-
},
95-
"builders": [
96-
{
97-
"type": "upcloud",
98-
"username": "{{ user `username` }}",
99-
"password": "{{ user `password` }}",
100-
"zone": "nl-ams1",
101-
"storage_uuid": "01000000-0000-4000-8000-000030200200"
102-
}
103-
],
104-
"provisioners": [
105-
{
106-
"type": "shell",
107-
"inline": [
108-
"apt-get update",
109-
"apt-get upgrade -y",
110-
"echo '<ssh-rsa_key>' | tee /root/.ssh/authorized_keys"
111-
]
112-
}
113-
]
114-
}
115-
```
116-
117-
You will need to provide a username and a password with the access rights to the API functions to authenticate. We recommend setting up a subaccount with only the API privileges for security purposes. You can do this at your [UpCloud Control Panel](https://my.upcloud.com/account) in the My Account menu under the User Accounts tab.
118-
119-
Enter the API user credentials in your terminal with the following commands. Replace the `<API_username>` and `<API_password>` with your user details.
120-
121-
```sh
122-
export UPCLOUD_API_USER=<API_username>
123-
export UPCLOUD_API_PASSWORD=<API_password>
124-
```
125-
Then run Packer using the example template with the command underneath.
126-
```
127-
packer build examples/basic_example.json
128-
```
129-
If everything goes according to plan, you should see something like the example output below.
130-
131-
```sh
132-
upcloud: output will be in this color.
133-
134-
==> upcloud: Creating temporary ssh key...
135-
==> upcloud: Getting storage...
136-
==> upcloud: Creating server based on storage "Ubuntu Server 20.04 LTS (Focal Fossa)"...
137-
==> upcloud: Server "packer-custom-image-20210206-213858" created and in 'started' state
138-
==> upcloud: Using ssh communicator to connect: 94.237.109.25
139-
==> upcloud: Waiting for SSH to become available...
140-
==> upcloud: Connected to SSH!
141-
==> upcloud: Provisioning with shell script: /var/folders/pt/x34s6zq90qxb78q8fcwx6jx80000gn/T/packer-shell198358867
142-
upcloud: Hit:1 http://archive.ubuntu.com/ubuntu focal InRelease
143-
upcloud: Get:2 http://archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]
144-
...
145-
==> upcloud: Stopping server "packer-custom-image-20210206-213858"...
146-
==> upcloud: Server "packer-custom-image-20210206-213858" is now in 'stopped' state
147-
==> upcloud: Creating storage template for server "packer-custom-image-20210206-213858"...
148-
==> upcloud: Storage template for server "packer-custom-image-20210206-213858" created
149-
==> upcloud: Stopping server "packer-custom-image-20210206-213858"...
150-
==> upcloud: Deleting server "packer-custom-image-20210206-213858"...
151-
Build 'upcloud' finished after 3 minutes 19 seconds.
152-
```
153-
154-
## Configuration reference
155-
156-
This section describes the available configuration options for the builder. Please note that the purpose of the builder is to create a storage template that can be used as a source for deploying new servers, therefore the temporary server used for building the template is not configurable.
157-
158-
### Required values
159-
160-
* `username` (string) The username to use when interfacing with the UpCloud API.
161-
* `password` (string) The password to use when interfacing with the UpCloud API.
162-
* `zone` (string) The zone in which the server and template should be created (e.g. `nl-ams1`).
163-
* `storage_uuid` (string) The UUID of the storage you want to use as a template when creating the server.
164-
165-
166-
### Optional values
167-
168-
* `storage_name` (string) The name of the storage that will be used to find the first matching storage in the list of existing templates. Note that `storage_uuid` parameter has higher priority. You should use either `storage_uuid` or `storage_name` for not strict matching (e.g "ubuntu server 20.04").
169-
* `storage_size` (int) The storage size in gigabytes. Defaults to `25`. Changing this value is useful if you aim to build a template for larger server configurations where the preconfigured server disk is larger than 25 GB. The operating system disk can also be later extended if needed. Note that Windows templates require large storage size, than default 25 Gb.
170-
* `state_timeout_duration` (string) The amount of time to wait for resource state changes. Defaults to `5m`.
171-
* `template_prefix` (string) The prefix to use for the generated template title. Defaults to an empty string, meaning the prefix will be the storage title. You can use this option to easily differentiate between different templates.
172-
* `template_name` (string) Similarly to `template_prefix`, but this will allow you to set the full template name and not just the prefix. Defaults to an empty string, meaning the name will be the storage title. You can use this option to easily differentiate between different templates. It cannot be used in conjunction with the prefix setting.
173-
* `clone_zones` ([]string) The array of extra zones (locations) where created templates should be cloned. Note that default `state_timeout_duration` is not enough for cloning, better to increase a value depending on storage size.
174-
* `ssh_private_key_path` (string) Path to SSH Private Key that will be used for provisioning and stored in the template.
175-
* `ssh_public_key_path` (string) Path to SSH Public Key that will be used for provisioning.
176-
* `network_interfaces` (array) The array of network interfaces to request during the creation of the server for building the packer image. Example:
177-
178-
```json
179-
...
180-
"network_interfaces": [
181-
{
182-
"type": "public",
183-
"ip_addresses": [
184-
{
185-
"family": "IPv4"
186-
}
187-
]
188-
},
189-
{
190-
"type": "private",
191-
"network": "{{ private_network_uuid }}",
192-
"ip_addresses": [
193-
{
194-
"family": "IPv4",
195-
"address": "192.168.3.123"
196-
}
197-
]
198-
},
199-
{
200-
"type": "utility",
201-
"ip_addresses": [
202-
{
203-
"family": "IPv4"
204-
}
205-
]
206-
}
207-
]
208-
...
209-
```
10+
Documentation is available in [docs](docs/) directory.
21011

12+
Check the [example](example/) directory for working example.
21113

21214
## License
21315

builder/upcloud/config.go

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//go:generate packer-sdc mapstructure-to-hcl2 -type Config,NetworkInterface,IPAddress
2+
//go:generate packer-sdc struct-markdown
23
package upcloud
34

45
import (
@@ -51,24 +52,55 @@ type Config struct {
5152
common.PackerConfig `mapstructure:",squash"`
5253
Comm communicator.Config `mapstructure:",squash"`
5354

54-
// Required configuration values
55-
Username string `mapstructure:"username"`
56-
Password string `mapstructure:"password"`
57-
Zone string `mapstructure:"zone"`
58-
StorageUUID string `mapstructure:"storage_uuid"`
55+
// The username to use when interfacing with the UpCloud API.
56+
Username string `mapstructure:"username" required:"true"`
57+
58+
// The password to use when interfacing with the UpCloud API.
59+
Password string `mapstructure:"password" required:"true"`
60+
61+
// The zone in which the server and template should be created (e.g. nl-ams1).
62+
Zone string `mapstructure:"zone" required:"true"`
63+
64+
// The UUID of the storage you want to use as a template when creating the server.
65+
//
66+
// Optionally use `storage_name` parameter to find matching storage
67+
StorageUUID string `mapstructure:"storage_uuid" required:"true"`
68+
69+
// The name of the storage that will be used to find the first matching storage in the list of existing templates.
70+
//
71+
// Note that `storage_uuid` parameter has higher priority. You should use either `storage_uuid` or `storage_name` for not strict matching (e.g "ubuntu server 20.04").
5972
StorageName string `mapstructure:"storage_name"`
6073

61-
// Optional configuration values
62-
TemplatePrefix string `mapstructure:"template_prefix"`
63-
TemplateName string `mapstructure:"template_name"`
64-
StorageSize int `mapstructure:"storage_size"`
65-
Timeout time.Duration `mapstructure:"state_timeout_duration"`
66-
CloneZones []string `mapstructure:"clone_zones"`
74+
// The prefix to use for the generated template title. Defaults to `custom-image`.
75+
// You can use this option to easily differentiate between different templates.
76+
TemplatePrefix string `mapstructure:"template_prefix"`
77+
78+
// Similarly to `template_prefix`, but this will allow you to set the full template name and not just the prefix.
79+
// Defaults to an empty string, meaning the name will be the storage title.
80+
// You can use this option to easily differentiate between different templates.
81+
// It cannot be used in conjunction with the prefix setting.
82+
TemplateName string `mapstructure:"template_name"`
6783

84+
// The storage size in gigabytes. Defaults to `25`.
85+
// Changing this value is useful if you aim to build a template for larger server configurations where the preconfigured server disk is larger than 25 GB.
86+
// The operating system disk can also be later extended if needed. Note that Windows templates require large storage size, than default 25 Gb.
87+
StorageSize int `mapstructure:"storage_size"`
88+
89+
// The amount of time to wait for resource state changes. Defaults to `5m`.
90+
Timeout time.Duration `mapstructure:"state_timeout_duration"`
91+
92+
// The array of extra zones (locations) where created templates should be cloned.
93+
// Note that default `state_timeout_duration` is not enough for cloning, better to increase a value depending on storage size.
94+
CloneZones []string `mapstructure:"clone_zones"`
95+
96+
// The array of network interfaces to request during the creation of the server for building the packer image.
6897
NetworkInterfaces []NetworkInterface `mapstructure:"network_interfaces"`
6998

99+
// Path to SSH Private Key that will be used for provisioning and stored in the template.
70100
SSHPrivateKeyPath string `mapstructure:"ssh_private_key_path"`
71-
SSHPublicKeyPath string `mapstructure:"ssh_public_key_path"`
101+
102+
// Path to SSH Public Key that will be used for provisioning.
103+
SSHPublicKeyPath string `mapstructure:"ssh_public_key_path"`
72104

73105
ctx interpolate.Context
74106
}

builder/upcloud/config.hcl2spec.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)