From f1f8f212b57bb64963bc24dd19ffb5f380f0d5f9 Mon Sep 17 00:00:00 2001 From: Ethan Paul Date: Thu, 13 Nov 2025 18:03:43 -0500 Subject: [PATCH] Add act-runner target for building local ACT env --- Makefile | 11 ++- act-runner/act-runner.bu | 131 ++++++++++++++++++++++++++++++++++ act-runner/rebuild.bash | 102 ++++++++++++++++++++++++++ shell/scripts.d/01-aliases.sh | 3 +- shell/scripts.d/50-act.sh | 32 +++++++++ 5 files changed, 276 insertions(+), 3 deletions(-) create mode 100644 act-runner/act-runner.bu create mode 100644 act-runner/rebuild.bash create mode 100644 shell/scripts.d/50-act.sh diff --git a/Makefile b/Makefile index 077f049..1b51636 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,13 @@ vscodium: podman stop vscodium-setup-temp podman rm vscodium-setup-temp -.PHONY: install -install: toolbox shell vscodium; +.PHONY: act-runner +act-runner: + systemctl enable libvirtd --now + mkdir --parents ~/.local/share/act-runner + cp act-runner/act-runner.bu ~/.local/share/act-runner/act-runner.bu + bash act-runner/rebuild.bash $(HOME)/.local/share/act-runner + +.PHONY: install +install: toolbox shell vscodium act-runner; diff --git a/act-runner/act-runner.bu b/act-runner/act-runner.bu new file mode 100644 index 0000000..f697d8c --- /dev/null +++ b/act-runner/act-runner.bu @@ -0,0 +1,131 @@ +--- +variant: fcos +version: 1.6.0 + +passwd: + users: + - name: root + ssh_authorized_keys: [] + + - name: core + groups: + - docker + ssh_authorized_keys_local: + - core_ssh_keys.pub + +systemd: + units: + - name: docker-image-prune.service + enabled: false + contents: | + [Unit] + Description=Remove unused images from Docker + Wants=docker.socket + After=docker.socket + After=docker.service + + [Service] + Type=oneshot + ExecStart=docker image prune --force --all --filter 'reference!="catthehacker/ubuntu"' + ExecStart=docker builder prune --force + RemainAfterExit=no + + [Install] + WantedBy=multi-user.target + + - name: docker-image-prune.timer + enabled: true + contents: | + [Unit] + Description=Start docker-image-prune every day + + [Timer] + OnBootSec=30min + OnUnitActiveSec=1d + + [Install] + WantedBy=timers.target + +storage: + files: + - path: /etc/hostname + mode: 0644 + overwrite: true + contents: + local: hostname + + - path: /etc/ssh/sshd_config.d/99-custom.conf + mode: 0644 + user: + name: root + group: + name: root + contents: + inline: | + UseDNS no + PermitRootLogin no + AllowUsers core@* + AuthenticationMethods publickey + HostKey /etc/ssh/ssh_host_rsa_key + HostKey /etc/ssh/ssh_host_ed25519_key + HostKey /etc/ssh/ssh_host_ecdsa_key + + - path: /etc/ssh/ssh_host_rsa_key + mode: 0600 + overwrite: true + user: + name: root + group: + name: root + contents: + local: host_keys/ssh_rsa + + - path: /etc/ssh/ssh_host_rsa_key.pub + mode: 0644 + overwrite: true + user: + name: root + group: + name: root + contents: + local: host_keys/ssh_rsa.pub + + - path: /etc/ssh/ssh_host_ed25519_key + mode: 0600 + overwrite: true + user: + name: root + group: + name: root + contents: + local: host_keys/ssh_ed25519 + + - path: /etc/ssh/ssh_host_ed25519_key.pub + mode: 0644 + overwrite: true + user: + name: root + group: + name: root + contents: + local: host_keys/ssh_ed25519.pub + + - path: /etc/ssh/ssh_host_ecdsa_key + mode: 0600 + overwrite: true + user: + name: root + group: + name: root + contents: + local: host_keys/ssh_ecdsa + + - path: /etc/ssh/ssh_host_ecdsa_key.pub + mode: 0644 + overwrite: true + user: + name: root + group: + name: root + contents: + local: host_keys/ssh_ecdsa.pub diff --git a/act-runner/rebuild.bash b/act-runner/rebuild.bash new file mode 100644 index 0000000..2157ebf --- /dev/null +++ b/act-runner/rebuild.bash @@ -0,0 +1,102 @@ +#!/usr/bin/env bash + +set -e + +if [ $# -lt 1 ]; then + echo "ERROR: Specify config path" + exit 1 +fi + +CONFIG_PATH="${1}" + +if [ ! -f "${CONFIG_PATH}/act-runner.bu" ]; then + echo "ERROR: Config path ${CONFIG_PATH} must include the act-runner.bu file" + exit 1 +fi + +NAME="${HOSTNAME}-act-runner" +STREAM="stable" +BUTANE_CONFIG="${CONFIG_PATH}/act-runner.bu" +VCPUS="8" +RAM_MB="16132" +DISK_GB="100" + +IGNITION_PATH="${CONFIG_PATH}/${NAME}.ign" +IMAGE_PATH="${CONFIG_PATH}/${NAME}.qcow2" +KVM="qemu:///session" + +if ! systemctl is-active libvirtd --quiet; then + systemctl start libvirtd +fi + +all_vms=$(virsh --connect="${KVM}" list --all) + +if [[ $all_vms == *"${NAME}"* ]]; then + running_vms=$(virsh --connect="$KVM" list) + if [[ $running_vms == *"${NAME}"* ]]; then + echo "Shutting down VM ${NAME}..." + virsh --connect="${KVM}" destroy "${NAME}" + fi + echo "Destroying VM ${NAME}..." + virsh --connect="${KVM}" undefine --domain="${NAME}" --remove-all-storage --managed-save + echo "Deleting image ${IMAGE_PATH}..." + rm -rf "${IMAGE_PATH}" + echo "Deleting ignition file ${IGNITION_PATH}..." + rm "${IGNITION_PATH}" +fi + +download_dir=$(mktemp -d) + +podman run \ + --rm \ + -v "${download_dir}:/data:z" \ + -w /data \ + quay.io/coreos/coreos-installer:release \ + download -s "${STREAM}" -p qemu -f qcow2.xz --decompress + +download_image=$(command ls "${download_dir}"/*.qcow2) + +mv "${download_image}" "${IMAGE_PATH}" + +echo "${HOSTNAME}-act-runner" >"${CONFIG_PATH}/hostname" +cat ~/.ssh/*.pub >"${CONFIG_PATH}/core_ssh_keys.pub" + +mkdir --parents "${CONFIG_PATH}/host_keys" + +key_formats=( + "rsa" + "ed25519" + "ecdsa" +) + +for key in "${key_formats[@]}"; do + if [ ! -f "${CONFIG_PATH}/host_keys/ssh_${key}" ]; then + ssh-keygen -q \ + -f "${CONFIG_PATH}/host_keys/ssh_${key}" \ + -t "${key}" \ + -C "${HOSTNAME}-act-runner" \ + -N '' + fi +done + +podman run \ + --interactive \ + --rm \ + -v "${CONFIG_PATH}:/data:z" \ + quay.io/coreos/butane:release \ + --pretty --strict --files-dir=/data < "${BUTANE_CONFIG}" > "${IGNITION_PATH}" + +chcon --verbose --type svirt_home_t "${IGNITION_PATH}" + +virt-install \ + --connect="${KVM}" \ + --name="${NAME}" \ + --vcpus="${VCPUS}" \ + --memory="${RAM_MB}" \ + --os-variant="fedora-coreos-${STREAM}" \ + --import \ + --noautoconsole \ + --graphics=none \ + --disk="size=${DISK_GB},backing_store=${IMAGE_PATH}" \ + --network bridge=virbr0 \ + --qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=${IGNITION_PATH}" diff --git a/shell/scripts.d/01-aliases.sh b/shell/scripts.d/01-aliases.sh index edbae35..2e960b6 100644 --- a/shell/scripts.d/01-aliases.sh +++ b/shell/scripts.d/01-aliases.sh @@ -15,4 +15,5 @@ alias psync="poetry install --sync" alias code='codium' alias ssh='ssh -F ~/.ssh/config' alias whereami='echo $LOCATION' -alias gg='dev' \ No newline at end of file +alias gg='dev' +alias bk='cd -' diff --git a/shell/scripts.d/50-act.sh b/shell/scripts.d/50-act.sh new file mode 100644 index 0000000..e90c1d0 --- /dev/null +++ b/shell/scripts.d/50-act.sh @@ -0,0 +1,32 @@ +function start-act-runner() { + if ! systemctl is-active libvirtd --quiet; then + systemctl start libvirtd + fi + + running_vms=$(virsh --connect=qemu:///session list) + if [[ "$running_vms" != *"${HOSTNAME}-act-runner"* ]]; then + echo "Sarting ACT runner '${HOSTNAME}-act-runner'..." + virsh --connect=qemu:///session start --domain="${HOSTNAME}-act-runner" && sleep 15 + fi + + _configure_act_alias +} + +function _configure_act_alias() { + if systemctl is-active libvirtd --quiet; then + running_vms=$(virsh --connect=qemu:///session list) + if [[ "$running_vms" = *"${HOSTNAME}-act-runner"* ]]; then + export ACT_RUNNER_MAC=$(virsh --connect="qemu:///session" domiflist "${HOSTNAME}-act-runner" | awk '{ print $5 }' | tail -2 | head -1) + export ACT_RUNNER_IP=$(arp -a | grep $ACT_RUNNER_MAC | awk '{ print $2 }' | sed 's/[()]//g') + export ACT_SOURCE_IP="$(echo $ACT_RUNNER_IP | cut -d '.' -f -3).1" + export ACT_DOCKER_HOST="ssh://core@$ACT_RUNNER_IP:22" + alias act='DOCKER_HOST=$ACT_DOCKER_HOST act --rm --secret=GITHUB_TOKEN=$(gh auth token) --platform="ubuntu-latest=docker.io/catthehacker/ubuntu:full-latest" --platform="ubuntu-24.04=docker.io/catthehacker/ubuntu:full-latest" --container-options="--privileged" --artifact-server-path=$(mktemp --directory) --artifact-server-addr=$ACT_SOURCE_IP --cache-server-path=$(mkdir --parents /tmp/act-cache && echo /tmp/act-cache) --cache-server-addr=$ACT_SOURCE_IP' + else + alias act='echo ERROR: local act runner is not active, use "start-act-runner" to start it' + fi + else + alias act='echo ERROR: local act runner is not running, use "start-act-runner" to start it' + fi +} + +_configure_act_alias