From 564121a9e8a0e6df4f5e60bbbb07605f14c2e141 Mon Sep 17 00:00:00 2001 From: Jonas L Date: Tue, 11 Jun 2024 15:28:52 +0200 Subject: [PATCH] docs: refresh the documentation (#197) - Update some broken links, - Split examples into multiple directories, - Link examples folder in the builder documentation, - Add tips for keeping images size small. --- .github/workflows/test.yml | 8 +- .web-docs/components/builder/hcloud/README.md | 80 +++++++++++++++++-- docs/builders/hcloud.mdx | 80 +++++++++++++++++-- example/README.md | 21 +---- example/{ => basic}/build.pkr.hcl | 11 +-- example/docker/build.pkr.hcl | 57 +++++++++++++ example/docker/cleanup.sh | 56 +++++++++++++ example/docker/install.sh | 46 +++++++++++ example/docker/upgrade.sh | 9 +++ .../{build_hcp.pkr.hcl => hcp/build.pkr.hcl} | 12 +-- 10 files changed, 337 insertions(+), 43 deletions(-) rename example/{ => basic}/build.pkr.hcl (74%) create mode 100644 example/docker/build.pkr.hcl create mode 100755 example/docker/cleanup.sh create mode 100755 example/docker/install.sh create mode 100755 example/docker/upgrade.sh rename example/{build_hcp.pkr.hcl => hcp/build.pkr.hcl} (78%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5157f4bc..c16fa21b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -68,7 +68,7 @@ jobs: defaults: run: - working-directory: example + working-directory: example/basic env: PACKER_LOG: "1" @@ -82,6 +82,6 @@ jobs: with: version: 1.11.0 # renovate: datasource=github-releases depName=hashicorp/packer extractVersion=v(?.+) - - run: packer init build.pkr.hcl - - run: packer validate build.pkr.hcl - - run: packer build build.pkr.hcl + - run: packer init . + - run: packer validate . + - run: packer build . diff --git a/.web-docs/components/builder/hcloud/README.md b/.web-docs/components/builder/hcloud/README.md index bd2492f5..ef46cfa0 100644 --- a/.web-docs/components/builder/hcloud/README.md +++ b/.web-docs/components/builder/hcloud/README.md @@ -2,7 +2,7 @@ Type: `hcloud` Artifact BuilderId: `hcloud.builder` The `hcloud` Packer builder is able to create new images for use with [Hetzner -Cloud](https://www.hetzner.cloud). The builder takes a source image, runs any +Cloud](https://www.hetzner.com/cloud/). 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 the Hetzner Cloud. @@ -10,11 +10,14 @@ servers that are launched within the Hetzner Cloud. The builder does _not_ manage images. Once it creates an image, it is up to you to use it or delete it. +## Connection to the server + The builder will connect to the server using the first available IP, in the following order: -- `public_ipv4` -- `public_ipv6` -- `private_ipv4` +- `public_ipv4`: If enabled, the public IPv4 will be used, +- `public_ipv6`: If enabled, the public IPv6 will be used, +- `private_ipv4`: If the server is attached to private networks, the private IPv4 of the + first private network will be used. ## Configuration Reference @@ -62,7 +65,7 @@ builder. - `with_selector` (list of strings) - label selectors used to select an `image`. NOTE: This will fail unless _exactly_ one image is returned. Check the official hcloud docs on - [Label Selectors](https://docs.hetzner.cloud/#overview-label-selector) + [Label Selectors](https://docs.hetzner.cloud/#label-selector) for more info. - `most_recent` (boolean) - Selects the newest created image when true. @@ -165,3 +168,70 @@ build { sources = ["source.hcloud.basic_example"] } ``` + +See the [examples](https://github.com/hetznercloud/packer-plugin-hcloud/tree/main/example) folder in the Packer project for more examples. + +## Tips + +### Keeping the images size small + +To reduce the size of your images, we recommend cleaning up any temporary files that +were added during the build process and discard the unused blocks from the disk. + +Below are a few commands that might useful: + +- Clean and reset could-init files: + + ```bash + cloud-init clean --logs --machine-id --seed --configs all + + rm -rf /run/cloud-init/* + rm -rf /var/lib/cloud/* + ``` + +- Clean apt files: + + ```bash + export DEBIAN_FRONTEND=noninteractive + + apt-get -y autopurge + apt-get -y clean + + rm -rf /var/lib/apt/lists/* + ``` + +- Clean logs: + + ```bash + journalctl --flush + journalctl --rotate --vacuum-time=0 + + find /var/log -type f -exec truncate --size 0 {} \; # truncate system logs + find /var/log -type f -name '*.[1-9]' -delete # remove archived logs + find /var/log -type f -name '*.gz' -delete # remove compressed archived logs + ``` + +- Reset host ssh keys: + + ```bash + rm -f /etc/ssh/ssh_host_*_key /etc/ssh/ssh_host_*_key.pub + ``` + +Once the cleanup is complete, you must discard the now unused blocks from the disk. This can be done with the following: + +```bash +dd if=/dev/zero of=/zero bs=4M || true +sync +rm -f /zero +``` + +To speed up the process above, you may configure cloud-init to not grow the system partition to the server disk size during the boot process, leaving you with a 4GB system partition: + +```yaml +#cloud-config +growpart: + mode: "off" +resize_rootfs: false +``` + +See the [docker example](https://github.com/hetznercloud/packer-plugin-hcloud/tree/main/example/docker) in the Packer project for more details. diff --git a/docs/builders/hcloud.mdx b/docs/builders/hcloud.mdx index 1428d68a..1245b82a 100644 --- a/docs/builders/hcloud.mdx +++ b/docs/builders/hcloud.mdx @@ -15,7 +15,7 @@ Type: `hcloud` Artifact BuilderId: `hcloud.builder` The `hcloud` Packer builder is able to create new images for use with [Hetzner -Cloud](https://www.hetzner.cloud). The builder takes a source image, runs any +Cloud](https://www.hetzner.com/cloud/). 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 the Hetzner Cloud. @@ -23,11 +23,14 @@ servers that are launched within the Hetzner Cloud. The builder does _not_ manage images. Once it creates an image, it is up to you to use it or delete it. +## Connection to the server + The builder will connect to the server using the first available IP, in the following order: -- `public_ipv4` -- `public_ipv6` -- `private_ipv4` +- `public_ipv4`: If enabled, the public IPv4 will be used, +- `public_ipv6`: If enabled, the public IPv6 will be used, +- `private_ipv4`: If the server is attached to private networks, the private IPv4 of the + first private network will be used. ## Configuration Reference @@ -75,7 +78,7 @@ builder. - `with_selector` (list of strings) - label selectors used to select an `image`. NOTE: This will fail unless _exactly_ one image is returned. Check the official hcloud docs on - [Label Selectors](https://docs.hetzner.cloud/#overview-label-selector) + [Label Selectors](https://docs.hetzner.cloud/#label-selector) for more info. - `most_recent` (boolean) - Selects the newest created image when true. @@ -155,3 +158,70 @@ build { sources = ["source.hcloud.basic_example"] } ``` + +See the [examples](https://github.com/hetznercloud/packer-plugin-hcloud/tree/main/example) folder in the Packer project for more examples. + +## Tips + +### Keeping the images size small + +To reduce the size of your images, we recommend cleaning up any temporary files that +were added during the build process and discard the unused blocks from the disk. + +Below are a few commands that might useful: + +- Clean and reset could-init files: + + ```bash + cloud-init clean --logs --machine-id --seed --configs all + + rm -rf /run/cloud-init/* + rm -rf /var/lib/cloud/* + ``` + +- Clean apt files: + + ```bash + export DEBIAN_FRONTEND=noninteractive + + apt-get -y autopurge + apt-get -y clean + + rm -rf /var/lib/apt/lists/* + ``` + +- Clean logs: + + ```bash + journalctl --flush + journalctl --rotate --vacuum-time=0 + + find /var/log -type f -exec truncate --size 0 {} \; # truncate system logs + find /var/log -type f -name '*.[1-9]' -delete # remove archived logs + find /var/log -type f -name '*.gz' -delete # remove compressed archived logs + ``` + +- Reset host ssh keys: + + ```bash + rm -f /etc/ssh/ssh_host_*_key /etc/ssh/ssh_host_*_key.pub + ``` + +Once the cleanup is complete, you must discard the now unused blocks from the disk. This can be done with the following: + +```bash +dd if=/dev/zero of=/zero bs=4M || true +sync +rm -f /zero +``` + +To speed up the process above, you may configure cloud-init to not grow the system partition to the server disk size during the boot process, leaving you with a 4GB system partition: + +```yaml +#cloud-config +growpart: + mode: "off" +resize_rootfs: false +``` + +See the [docker example](https://github.com/hetznercloud/packer-plugin-hcloud/tree/main/example/docker) in the Packer project for more details. diff --git a/example/README.md b/example/README.md index ced3cc89..51bfb4ae 100644 --- a/example/README.md +++ b/example/README.md @@ -1,20 +1,3 @@ -## The Example Folder +## Examples -This folder must contain a fully working example of the plugin usage. The example must define the `required_plugins` -block. A pre-defined GitHub Action will run `packer init`, `packer validate`, and `packer build` to test your plugin -with the latest version available of Packer. - -The folder can contain multiple HCL2 compatible files. The action will execute Packer at this folder level -running `packer init -upgrade .` and `packer build .`. - -If the plugin requires authentication, the configuration should be provided via GitHub Secrets and set as environment -variables in the [test-plugin-example.yml](/.github/workflows/test-plugin-example.yml) file. Example: - -```yml - - name: Build - working-directory: ${{ github.event.inputs.folder }} - run: PACKER_LOG=${{ github.event.inputs.logs }} packer build . - env: - AUTH_KEY: ${{ secrets.AUTH_KEY }} - AUTH_PASSWORD: ${{ secrets.AUTH_PASSWORD }} -``` \ No newline at end of file +This folder contain fully working examples of the plugin usage. diff --git a/example/build.pkr.hcl b/example/basic/build.pkr.hcl similarity index 74% rename from example/build.pkr.hcl rename to example/basic/build.pkr.hcl index 6c52084f..fac557f2 100644 --- a/example/build.pkr.hcl +++ b/example/basic/build.pkr.hcl @@ -5,7 +5,7 @@ packer { required_plugins { hcloud = { source = "github.com/hetznercloud/hcloud" - version = ">=1.1.0" + version = ">=1.5.1" } } } @@ -22,13 +22,13 @@ source "hcloud" "example" { location = "hel1" image = "ubuntu-24.04" server_type = "cpx11" - server_name = "hcloud-example" + server_name = "example-{{ timestamp }}" ssh_username = "root" - snapshot_name = "hcloud-example" + snapshot_name = "example-{{ timestamp }}" snapshot_labels = { - app = "hcloud-example" + app = "example" } } @@ -36,7 +36,8 @@ build { sources = ["source.hcloud.example"] provisioner "shell" { - inline = ["cloud-init status --wait || test $? -eq 2"] + inline = ["cloud-init status --wait --long"] + valid_exit_codes = [0, 2] } provisioner "shell" { diff --git a/example/docker/build.pkr.hcl b/example/docker/build.pkr.hcl new file mode 100644 index 00000000..7bdbd4f4 --- /dev/null +++ b/example/docker/build.pkr.hcl @@ -0,0 +1,57 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +packer { + required_plugins { + hcloud = { + source = "github.com/hetznercloud/hcloud" + version = ">=1.5.1" + } + } +} + +variable "hcloud_token" { + type = string + sensitive = true + default = "${env("HCLOUD_TOKEN")}" +} + +source "hcloud" "docker" { + token = var.hcloud_token + + location = "hel1" + image = "ubuntu-24.04" + server_type = "cpx11" + server_name = "docker-{{ timestamp }}" + + user_data = <<-EOF + #cloud-config + growpart: + mode: "off" + resize_rootfs: false + EOF + + ssh_username = "root" + + snapshot_name = "docker-{{ timestamp }}" + snapshot_labels = { + app = "docker" + } +} + +build { + sources = ["source.hcloud.docker"] + + provisioner "shell" { + inline = ["cloud-init status --wait --long"] + valid_exit_codes = [0, 2] + } + + provisioner "shell" { + scripts = [ + "install.sh", + "upgrade.sh", + "cleanup.sh", + ] + } +} diff --git a/example/docker/cleanup.sh b/example/docker/cleanup.sh new file mode 100755 index 00000000..3d1f1f02 --- /dev/null +++ b/example/docker/cleanup.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +set -eux + +clean_cloud_init() { + cloud-init clean --logs --machine-id --seed --configs all + + rm -rf /run/cloud-init/* + rm -rf /var/lib/cloud/* +} + +clean_apt() { + export DEBIAN_FRONTEND=noninteractive + + apt-get -y autopurge + apt-get -y clean + + rm -rf /var/lib/apt/lists/* +} + +clean_ssh_keys() { + rm -f /etc/ssh/ssh_host_*_key /etc/ssh/ssh_host_*_key.pub +} + +clean_logs() { + journalctl --flush + journalctl --rotate --vacuum-time=0 + + find /var/log -type f -exec truncate --size 0 {} \; # truncate system logs + find /var/log -type f -name '*.[1-9]' -delete # remove archived logs + find /var/log -type f -name '*.gz' -delete # remove compressed archived logs +} + +clean_root() { + unset HISTFILE + + rm -rf /root/.cache + rm -rf /root/.ssh + rm -f /root/.bash_history + rm -f /root/.lesshst + rm -f /root/.viminfo +} + +flush_disk() { + dd if=/dev/zero of=/zero bs=4M || true + sync + rm -f /zero +} + +clean_cloud_init +clean_apt +clean_ssh_keys +clean_logs +clean_root + +flush_disk diff --git a/example/docker/install.sh b/example/docker/install.sh new file mode 100755 index 00000000..30d55344 --- /dev/null +++ b/example/docker/install.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +set -eux + +export DEBIAN_FRONTEND=noninteractive + +apt-get update +apt-get install -y ca-certificates curl + +install -m 0755 -d /etc/apt/keyrings + +distribution="$(lsb_release --short --id | awk '{ print tolower($0) }')" +distribution_release="$(lsb_release --short --codename)" + +packages_installed=() +packages_removed=() +services_enabled=() + +install_docker() { + curl -fsSL "https://download.docker.com/linux/${distribution}/gpg" -o /etc/apt/keyrings/docker.asc + chmod a+r /etc/apt/keyrings/docker.asc + + cat > /etc/apt/sources.list.d/docker.sources << EOL +Enabled: yes +Types: deb +URIs: https://download.docker.com/linux/${distribution} +Suites: ${distribution_release} +Components: stable +Signed-By: /etc/apt/keyrings/docker.asc +EOL + + packages_installed+=(docker-ce docker-compose-plugin) + services_enabled+=(docker) +} + +remove_snapd() { + packages_removed+=(snapd) +} + +install_docker +remove_snapd + +apt-get update +apt-get install -y "${packages_installed[@]}" + +systemctl enable "${services_enabled[@]}" diff --git a/example/docker/upgrade.sh b/example/docker/upgrade.sh new file mode 100755 index 00000000..15688d1e --- /dev/null +++ b/example/docker/upgrade.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -eux + +export DEBIAN_FRONTEND=noninteractive + +apt-get update +apt-get upgrade -y +apt-get autopurge -y diff --git a/example/build_hcp.pkr.hcl b/example/hcp/build.pkr.hcl similarity index 78% rename from example/build_hcp.pkr.hcl rename to example/hcp/build.pkr.hcl index 5ecb92f9..44321124 100644 --- a/example/build_hcp.pkr.hcl +++ b/example/hcp/build.pkr.hcl @@ -5,7 +5,7 @@ packer { required_plugins { hcloud = { source = "github.com/hetznercloud/hcloud" - version = ">=1.1.0" + version = ">=1.5.1" } } } @@ -22,19 +22,20 @@ source "hcloud" "example" { location = "hel1" image = "ubuntu-24.04" server_type = "cpx11" - server_name = "hcloud-example" + server_name = "example-{{ timestamp }}" ssh_username = "root" - snapshot_name = "hcloud-example" + snapshot_name = "example-{{ timestamp }}" snapshot_labels = { - app = "hcloud-example" + app = "example" } } build { hcp_packer_registry { description = "A nice test description" + bucket_name = "hcloud-hcp-test" bucket_labels = { "packer version" = packer.version @@ -44,7 +45,8 @@ build { sources = ["source.hcloud.example"] provisioner "shell" { - inline = ["cloud-init status --wait || test $? -eq 2"] + inline = ["cloud-init status --wait --long"] + valid_exit_codes = [0, 2] } provisioner "shell" {