Browse Source

initial commit

Steven Jacobs 2 years ago
commit
76e6dbf3be

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+packer_cache/
+dist/

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Steven Jacobs
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 87 - 0
README.md

@@ -0,0 +1,87 @@
+# linode-packer-templates
+
+The packer templates included here aim to build Linode images that are compatible with Linode services where possible.
+
+Exceptions to this include:
+- Network Helper - These images instead use dhcp for obtaining IP addresses.
+
+## Notice
+
+These are not official Linode images.
+
+## Requirements
+
+To build the images in this repository, you will need:
+
+- Linux machine to build images
+- [Packer](https://www.packer.io)
+- KVM
+- QEMU
+
+## Building
+
+Using the [Void](https://www.voidlinux.eu/) image as an example, the build process is as follows.
+When extending the template, the notes in the "[Troubleshooting](#troubleshooting)" may be helpful.
+
+```sh
+cd base/void/
+packer build template.json
+```
+
+This will output images to the `dist` directory, within the corresponding directory to the template and builder type.
+
+```sh
+$ tree dist
+dist
+└── void-x86_64-20171007-qemu
+    ├── void-x86_64-20171007.gz     # a compressed raw disk image for sending over the network
+    ├── void-x86_64-20171007.qcow2  # a qcow disk image
+    └── void-x86_64-20171007.raw    # a raw disk image
+```
+
+## Deploying
+
+### Preparing the new disk
+
+To deploy a built image, start in the Linode Manager.
+
+1. Create an `ext4` disk on the destination Linode.
+2. Boot into [Rescue Mode](https://www.linode.com/docs/troubleshooting/rescue-and-rebuild#booting-into-rescue-mode) with the disk in the `/dev/sda` slot.
+3. From the [Lish console](https://www.linode.com/docs/networking/using-the-linode-shell-lish), set the root password and enable SSH.
+   If you aren't familiar with the process, there is a guide, [here](https://www.linode.com/docs/troubleshooting/rescue-and-rebuild#starting-ssh).
+
+### Copy the image
+
+Now that the Linode is booted into Rescue Mode and has SSH up and listening, the disk image can be copied to the remote device.
+This again uses the `void` image as an example.
+
+There is a helper `bin/sync.sh` to help with this.
+
+Here is an example.
+The target IP address needs to be replaced.
+It has been excluded to avoid copy-paste accidents with `dd`.
+
+```sh
+cd dist/void-x86_64-20171007-qemu
+../../bin/sync.sh void-x86_64-20171007 123.45.nn.nn /dev/sda
+```
+
+### Final setup
+
+1. Shut down the Linode.
+2. Reset the root password of the disk from the 'Rescue' tab.
+3. Add the disk to a configuration profile which includes a swap disk in `/dev/sdb` and all helpers disabled.
+4. Boot using the above configuration profile.
+5. Enjoy!
+
+## Troubleshooting
+
+To get more verbose output from packer, print the logs to the console.
+
+```sh
+PACKER_LOG=1 packer build template.json
+```
+
+Provisioning scripts are currently being run with the `-x` flag.
+Because of this, all commands that are run during the build step will be printed to the console, and therefore the packer logs.
+To stop this behavior, just remove the `-x` from the first line of the scripts, leaving only `#!/bin/sh`.

+ 2 - 0
_common/files/fstab

@@ -0,0 +1,2 @@
+/dev/sda        /       ext4    rw,relatime,data=ordered        0 1
+/dev/sdb        none    swap    defaults                        0 0

+ 8 - 0
_common/files/grub.cfg

@@ -0,0 +1,8 @@
+GRUB_CMDLINE_LINUX_DEFAULT=""
+GRUB_TIMEOUT=10
+GRUB_CMDLINE_LINUX="console=ttyS0,19200n8 net.ifnames=0"
+GRUB_PRELOAD_MODULES="part_msdos"
+GRUB_TERMINAL=serial
+GRUB_GFXPAYLOAD_LINUX=text
+GRUB_DISABLE_LINUX_UUID=true
+GRUB_SERIAL_COMMAND="serial --speed=19200 --unit=0 --word=8 --parity=no --stop=1"

+ 3 - 0
bin/fix.sh

@@ -0,0 +1,3 @@
+TMPFILE=$(mktemp) || exit 1
+
+packer fix $1 >> $TMPFILE && cat $TMPFILE > $1

+ 8 - 0
bin/sync.sh

@@ -0,0 +1,8 @@
+#!/usr/bin/env bash -eux
+
+src_image=$1
+target_ip=$2
+target_dev=$3
+
+
+dd if=${src_image}.gz | ssh root@${target_ip} "gzip -d | dd of=${target_dev}"

+ 38 - 0
void/files/dhcpcd.conf

@@ -0,0 +1,38 @@
+# A sample configuration for dhcpcd.
+# See dhcpcd.conf(5) for details.
+
+# Allow users of this group to interact with dhcpcd via the control socket.
+controlgroup wheel
+
+# Inform the DHCP server of our hostname for DDNS.
+hostname
+
+# Use the hardware address of the interface for the Client ID.
+#clientid
+# or
+# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
+# Some non-RFC compliant DHCP servers do not reply with this set.
+# In this case, comment out duid and enable clientid above.
+duid
+
+# Persist interface configuration when dhcpcd exits.
+persistent
+
+# Rapid commit support.
+# Safe to enable by default because it requires the equivalent option set
+# on the server to actually work.
+option rapid_commit
+
+# A list of options to request from the DHCP server.
+option domain_name_servers, domain_name, domain_search, host_name
+option classless_static_routes
+# Most distributions have NTP support.
+option ntp_servers
+# Respect the network MTU. This is applied to DHCP routes.
+option interface_mtu
+
+# A ServerID is required by RFC2131.
+require dhcp_server_identifier
+
+# Generate IPv6 Addresses based on hardware
+slaac hwaddr

+ 3 - 0
void/files/virtio.conf

@@ -0,0 +1,3 @@
+virtio-scsi
+virtio-net
+virtio-pci

+ 59 - 0
void/scripts/bootstrap.sh

@@ -0,0 +1,59 @@
+#!/bin/sh -eux
+
+XBPS_ARCH="$(xbps-uhelper arch)"
+
+# Format disk to 64bit ext4
+mkfs.ext4 -O ^64bit /dev/sda
+
+# Mount the disk to be build
+mount /dev/sda /mnt
+
+# Import keys from live image to prevent prompt for key confirmation
+# https://github.com/voidlinux/void-mklive/blob/a15a4a69ac4ecbc7dbb75abd3279e53d7a1c6e14/installer.sh.in#L1159
+mkdir -p /mnt/var/db/xbps/keys
+cp /var/db/xbps/keys/*.plist /mnt/var/db/xbps/keys
+
+# Install the base system and some helper packages
+# https://github.com/voidlinux/void-mklive/blob/414ebf318f87cca1d036e3ef6674ade15876db55/dracut/autoinstaller/install.sh#L201
+base_pkgs="bind-utils curl inetutils iotop lsof nano sysstat wget"
+suppl_pkgs="htop mtr ncdu rxvt-unicode-terminfo vim"
+
+case $XBPS_ARCH in
+    *-musl)
+        xbpsrepository="https://repo.voidlinux.eu/current/musl"
+        ;;
+    *)
+        xbpsrepository="https://repo.voidlinux.eu/current"
+        ;;
+esac
+
+XBPS_ARCH="${XBPS_ARCH}" xbps-install -Sy -R "${xbpsrepository}" -r /mnt base-voidstrap linux grub ${base_pkgs} ${suppl_pkgs}
+
+# Copy provided config files from packer in place
+cp /tmp/fstab /mnt/etc/fstab
+cp /tmp/grub.cfg /mnt/etc/default/grub
+cp /tmp/dhcpcd.conf /mnt/etc/dhcpcd.conf
+
+mkdir /mnt/etc/modules-load.d
+cp /tmp/virtio.conf /mnt/etc/modules-load.d/virtio.conf
+
+# Mount target
+mount -t proc proc /mnt/proc/
+mount -t sysfs sys /mnt/sys/
+mount -o bind /dev /mnt/dev/
+mount -t devpts pts /mnt/dev/pts/
+
+# Change root and configure
+cp /tmp/install.sh /mnt/tmp/install.sh
+chmod +x /mnt/tmp/install.sh
+chroot /mnt "/tmp/install.sh"
+
+# Remove install script
+rm /mnt/tmp/install.sh
+
+# Remove imported keys
+rm /mnt/var/db/xbps/keys/*.plist
+
+# Final cleanup
+sync
+umount -R /mnt

+ 49 - 0
void/scripts/install.sh

@@ -0,0 +1,49 @@
+#!/bin/sh -eux
+
+XBPS_ARCH="$(xbps-uhelper arch)"
+
+# Set localtime to UTC
+ln -sf /usr/share/zoneinfo/UTC /etc/localtime
+
+# Set hostname to localhost
+echo "localhost" > /etc/hostname
+
+# Configure locales
+case $XBPS_ARCH in
+  *-musl)
+    ;;
+  *)
+    echo "LANG=en_US.UTF-8" > /etc/locale.conf
+    echo "LC_COLLATE=C" >> /etc/locale.conf
+    sed -i 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/g' /etc/default/libc-locales
+    xbps-reconfigure -f glibc-locales
+    ;;
+esac
+
+# Permit root login with password
+sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/g' /etc/ssh/sshd_config
+
+# Configure serial terminal
+sed -i 's/BAUD_RATE=115200/BAUD_RATE=19200/g' /etc/sv/agetty-ttyS0/conf
+
+# Set boot services
+ln -s /etc/sv/agetty-ttyS0 /etc/runit/runsvdir/default/agetty-ttys0
+ln -s /etc/sv/dhcpcd-eth0 /etc/runit/runsvdir/default/dhcpcd-eth0
+ln -s /etc/sv/sshd /etc/runit/runsvdir/default/sshd
+ln -s /etc/sv/uuidd /etc/runit/runsvdir/default/uuidd
+
+# Ensure initramfs files are generated
+dracut --force --regenerate-all
+
+# Create new grub config
+mkdir -p /boot/grub
+grub-mkconfig -o /boot/grub/grub.cfg
+
+# Use bash for the root shell
+chsh -s /bin/bash
+
+# Clean package cache
+xbps-remove -o
+xbps-remove -O
+
+exit

+ 83 - 0
void/void-20171007-x86_64-musl.json

@@ -0,0 +1,83 @@
+{
+  "builders": [
+    {
+      "accelerator": "kvm",
+      "boot_command": [
+        "<enter><wait20s>",
+        "root<enter><wait>",
+        "voidlinux<enter><wait>",
+        "ln -s /etc/sv/sshd /var/service"
+      ],
+      "boot_wait": "5s",
+      "disk_interface": "virtio-scsi",
+      "disk_size": 5000,
+      "format": "qcow2",
+      "headless": true,
+      "iso_checksum": "{{user `iso_checksum`}}",
+      "iso_checksum_type": "sha256",
+      "iso_url": "https://{{user `mirror`}}/live/current/void-live-{{user `arch`}}-{{user `os_year`}}{{user `os_month`}}{{user `os_day`}}.iso",
+      "net_device": "virtio-net",
+      "output_directory": "../dist/{{user `template`}}-qemu",
+      "shutdown_command": "shutdown -P now",
+      "ssh_password": "voidlinux",
+      "ssh_port": 22,
+      "ssh_username": "root",
+      "ssh_wait_timeout": "10m",
+      "type": "qemu",
+      "vm_name": "{{user `template`}}"
+    }
+  ],
+  "post-processors": [
+    {
+      "inline": [
+        "mv ../dist/{{user `template`}}-qemu/{{user `template`}} ../dist/{{user `template`}}-qemu/{{user `template`}}.qcow2",
+        "qemu-img convert -O raw ../dist/{{user `template`}}-qemu/{{user `template`}}.qcow2 ../dist/{{user `template`}}-qemu/{{user `template`}}.raw",
+        "e2fsck -fy ../dist/{{user `template`}}-qemu/{{user `template`}}.raw",
+        "resize2fs -M ../dist/{{user `template`}}-qemu/{{user `template`}}.raw",
+        "gzip -c ../dist/{{user `template`}}-qemu/{{user `template`}}.raw > ../dist/{{user `template`}}-qemu/{{user `template`}}.gz"
+      ],
+      "type": "shell-local"
+    }
+  ],
+  "provisioners": [
+    {
+      "destination": "/tmp/fstab",
+      "source": "../_common/files/fstab",
+      "type": "file"
+    },
+    {
+      "destination": "/tmp/grub.cfg",
+      "source": "../_common/files/grub.cfg",
+      "type": "file"
+    },
+    {
+      "destination": "/tmp/dhcpcd.conf",
+      "source": "files/dhcpcd.conf",
+      "type": "file"
+    },
+    {
+      "destination": "/tmp/virtio.conf",
+      "source": "files/virtio.conf",
+      "type": "file"
+    },
+    {
+      "destination": "/tmp/install.sh",
+      "source": "scripts/install.sh",
+      "type": "file"
+    },
+    {
+      "script": "scripts/bootstrap.sh",
+      "type": "shell"
+    }
+  ],
+  "variables": {
+    "arch": "x86_64-musl",
+    "iso_checksum": "f48356303115a4faad4235a1760c0f256a1dfd285e772e675262b19825631217",
+    "mirror": "repo.voidlinux.eu",
+    "os_day": "07",
+    "os_month": "10",
+    "os_year": "2017",
+    "template": "void-x86_64-musl-20171007"
+  }
+}
+

+ 83 - 0
void/void-20171007-x86_64.json

@@ -0,0 +1,83 @@
+{
+  "builders": [
+    {
+      "accelerator": "kvm",
+      "boot_command": [
+        "<enter><wait20s>",
+        "root<enter><wait>",
+        "voidlinux<enter><wait>",
+        "ln -s /etc/sv/sshd /var/service"
+      ],
+      "boot_wait": "5s",
+      "disk_interface": "virtio-scsi",
+      "disk_size": 5000,
+      "format": "qcow2",
+      "headless": true,
+      "iso_checksum": "{{user `iso_checksum`}}",
+      "iso_checksum_type": "sha256",
+      "iso_url": "https://{{user `mirror`}}/live/current/void-live-{{user `arch`}}-{{user `os_year`}}{{user `os_month`}}{{user `os_day`}}.iso",
+      "net_device": "virtio-net",
+      "output_directory": "../dist/{{user `template`}}-qemu",
+      "shutdown_command": "shutdown -P now",
+      "ssh_password": "voidlinux",
+      "ssh_port": 22,
+      "ssh_username": "root",
+      "ssh_wait_timeout": "10m",
+      "type": "qemu",
+      "vm_name": "{{user `template`}}"
+    }
+  ],
+  "post-processors": [
+    {
+      "inline": [
+        "mv ../dist/{{user `template`}}-qemu/{{user `template`}} ../dist/{{user `template`}}-qemu/{{user `template`}}.qcow2",
+        "qemu-img convert -O raw ../dist/{{user `template`}}-qemu/{{user `template`}}.qcow2 ../dist/{{user `template`}}-qemu/{{user `template`}}.raw",
+        "e2fsck -fy ../dist/{{user `template`}}-qemu/{{user `template`}}.raw",
+        "resize2fs -M ../dist/{{user `template`}}-qemu/{{user `template`}}.raw",
+        "gzip -c ../dist/{{user `template`}}-qemu/{{user `template`}}.raw > ../dist/{{user `template`}}-qemu/{{user `template`}}.gz"
+      ],
+      "type": "shell-local"
+    }
+  ],
+  "provisioners": [
+    {
+      "destination": "/tmp/fstab",
+      "source": "../_common/files/fstab",
+      "type": "file"
+    },
+    {
+      "destination": "/tmp/grub.cfg",
+      "source": "../_common/files/grub.cfg",
+      "type": "file"
+    },
+    {
+      "destination": "/tmp/dhcpcd.conf",
+      "source": "files/dhcpcd.conf",
+      "type": "file"
+    },
+    {
+      "destination": "/tmp/virtio.conf",
+      "source": "files/virtio.conf",
+      "type": "file"
+    },
+    {
+      "destination": "/tmp/install.sh",
+      "source": "scripts/install.sh",
+      "type": "file"
+    },
+    {
+      "script": "scripts/bootstrap.sh",
+      "type": "shell"
+    }
+  ],
+  "variables": {
+    "arch": "x86_64",
+    "iso_checksum": "a425a42481f22fc22562733c5e32e0e054e80ba68c25236850ec00ea2a31264e",
+    "mirror": "repo.voidlinux.eu",
+    "os_day": "07",
+    "os_month": "10",
+    "os_year": "2017",
+    "template": "void-x86_64-20171007"
+  }
+}
+