From 7e073587cee57db4d77ca7677cf80d07f5bc0583 Mon Sep 17 00:00:00 2001 From: m2 <69128853+m2Giles@users.noreply.github.com> Date: Wed, 15 May 2024 23:07:32 -0400 Subject: [PATCH] feat(dev): add justfile for local testing and integration with vscode (#578) --- .gitignore | 2 + .vscode/tasks.json | 109 +++++++++++++++++++++++ Containerfile | 7 +- Justfile | 49 ++++++++++ just_scripts/build-image.sh | 29 ++++++ just_scripts/build-iso-installer-main.sh | 86 ++++++++++++++++++ just_scripts/build-iso-makefile-patch | 11 +++ just_scripts/build-iso.sh | 86 ++++++++++++++++++ just_scripts/cleanup-dir.sh | 11 +++ just_scripts/cleanup-images.sh | 20 +++++ just_scripts/container_mgr.sh | 21 +++++ just_scripts/get-defaults.sh | 30 +++++++ just_scripts/list-images.sh | 19 ++++ just_scripts/run-image.sh | 29 ++++++ just_scripts/run-iso.sh | 40 +++++++++ just_scripts/sudoif.sh | 14 +++ 16 files changed, 561 insertions(+), 2 deletions(-) create mode 100644 .vscode/tasks.json create mode 100644 Justfile create mode 100755 just_scripts/build-image.sh create mode 100755 just_scripts/build-iso-installer-main.sh create mode 100644 just_scripts/build-iso-makefile-patch create mode 100755 just_scripts/build-iso.sh create mode 100755 just_scripts/cleanup-dir.sh create mode 100755 just_scripts/cleanup-images.sh create mode 100755 just_scripts/container_mgr.sh create mode 100755 just_scripts/get-defaults.sh create mode 100755 just_scripts/list-images.sh create mode 100755 just_scripts/run-image.sh create mode 100755 just_scripts/run-iso.sh create mode 100755 just_scripts/sudoif.sh diff --git a/.gitignore b/.gitignore index 485dee64..7d6592a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .idea +*.iso +*.iso-CHECKSUM* diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..03d8e38f --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,109 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Connect to VM", + "dependsOn": [ + "Run-ISO", + "Open Browser" + ], + "problemMatcher": [] + }, + { + "label": "Open Browser", + "command": "${input:openSimpleBrowser}", + "problemMatcher": [] + }, + { + "label": "Build Container", + "command": "just", + "args": [ + "build", + "${input:outputChoice}" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Build ISO", + "command": "just", + "args": [ + "${input:installerChoice}", + "${input:outputChoice}" + ], + "problemMatcher": [] + }, + { + "label": "Run-ISO", + "command": "just", + "args": [ + "run-iso", + "${input:outputChoice}" + ], + "problemMatcher": [], + "isBackground": true + }, + { + "label": "List Images", + "command": "just", + "args": [ + "list-images" + ], + "problemMatcher": [] + }, + { + "label": "Run Container", + "command": "just", + "args": [ + "run-container", + "${input:outputChoice}" + ], + "problemMatcher": [] + } + ], + "inputs": [ + { + "id": "openSimpleBrowser", + "type": "command", + "command": "simpleBrowser.show", + "args": [ + "http://localhost:8006" + ] + }, + { + "id": "installerChoice", + "type": "pickString", + "description": "Choose which Installer Builder to use", + "default": "build-iso", + "options": [ + "build-iso", + "build-iso-git" + ] + }, + { + "id": "outputChoice", + "type": "pickString", + "description": "Choose which container to build", + "default": "silverblue", + "options": [ + "silverblue latest", + "kinoite latest", + "sericea latest", + "onyx latest", + "base latest", + "lazurite latest", + "vauxite latest", + "silverblue gts", + "kinoite gts", + "sericea gts", + "onyx gts", + "base gts", + "lazurite gts", + "vauxite gts" + ] + } + ] +} diff --git a/Containerfile b/Containerfile index fe3c8502..7415437f 100644 --- a/Containerfile +++ b/Containerfile @@ -4,6 +4,9 @@ ARG SOURCE_ORG="${SOURCE_ORG:-fedora-ostree-desktops}" ARG BASE_IMAGE="quay.io/${SOURCE_ORG}/${SOURCE_IMAGE}" ARG FEDORA_MAJOR_VERSION="${FEDORA_MAJOR_VERSION:-40}" +FROM ghcr.io/ublue-os/config:latest as config +FROM ghcr.io/ublue-os/akmods:main-${FEDORA_MAJOR_VERSION} as akmods + FROM ${BASE_IMAGE}:${FEDORA_MAJOR_VERSION} ARG IMAGE_NAME="${IMAGE_NAME:-silverblue}" @@ -17,8 +20,8 @@ COPY github-release-install.sh \ packages.json \ /tmp/ -COPY --from=ghcr.io/ublue-os/config:latest /rpms /tmp/rpms -COPY --from=ghcr.io/ublue-os/akmods:main-${FEDORA_MAJOR_VERSION} /rpms/ublue-os /tmp/rpms +COPY --from=config /rpms /tmp/rpms +COPY --from=akmods /rpms/ublue-os /tmp/rpms COPY sys_files/usr /usr RUN mkdir -p /var/lib/alternatives && \ diff --git a/Justfile b/Justfile new file mode 100644 index 00000000..1e77de53 --- /dev/null +++ b/Justfile @@ -0,0 +1,49 @@ +export project_root := `git rev-parse --show-toplevel` +export git_branch := ` git branch --show-current` +export gts := "39" +export latest := "40" +export default_image := "silverblue" + +alias run := run-container +alias build-iso := build-iso-release + +_default: + @just --list + +_container_mgr: + @{{ project_root }}/just_scripts/container_mgr.sh + +_tag image: + @echo {{image}}-build + +# Build image +build image="" version="": + @{{ project_root }}/just_scripts/build-image.sh {{image}} {{version}} + +# Build ISO +build-iso-release image="" version="": + @{{ project_root }}/just_scripts/build-iso.sh {{image}} {{version}} + +# Build ISO using ISO Builder Git Head +build-iso-git image="" version="": + @{{ project_root }}/just_scripts/build-iso-installer-main.sh {{image}} {{version}} + +# Run ISO +run-iso image="" version="": + @{{ project_root }}/just_scripts/run-iso.sh {{image}} {{version}} + +# Run Container +run-container image="" version="": + @{{ project_root }}/just_scripts/run-image.sh {{image}} {{version}} + +# List Images +list-images: + @{{ project_root }}/just_scripts/list-images.sh + +# Clean Images +clean-images: + @{{ project_root }}/just_scripts/cleanup-images.sh + +# Clean ISOs +clean-isos: + @{{ project_root }}/just_scripts/cleanup-dir.sh diff --git a/just_scripts/build-image.sh b/just_scripts/build-image.sh new file mode 100755 index 00000000..4c0dd9e9 --- /dev/null +++ b/just_scripts/build-image.sh @@ -0,0 +1,29 @@ +#!/usr/bin/bash +set -eo pipefail +if [[ -z ${project_root} ]]; then + project_root=$(git rev-parse --show-toplevel) +fi +if [[ -z ${git_branch} ]]; then + git_branch=$(git branch --show-current) +fi + +# Get Inputs +image=$1 +version=$2 + +# Set image/target/version based on inputs +# shellcheck disable=SC2154,SC1091 +. "${project_root}/just_scripts/get-defaults.sh" + +# Get info +container_mgr=$(just _container_mgr) +tag=$(just _tag "${image}") + +# Build Image +$container_mgr build -f Containerfile \ + --build-arg="IMAGE_NAME=${tag}" \ + --build-arg="SOURCE_ORG=fedora-ostree-desktops" \ + --build-arg="SOURCE_IMAGE=${image}" \ + --build-arg="FEDORA_MAJOR_VERSION=${version}" \ + --tag localhost/"${tag}:${version}-${git_branch}" \ + "${project_root}" diff --git a/just_scripts/build-iso-installer-main.sh b/just_scripts/build-iso-installer-main.sh new file mode 100755 index 00000000..22e97c3b --- /dev/null +++ b/just_scripts/build-iso-installer-main.sh @@ -0,0 +1,86 @@ +#!/usr/bin/bash +#shellcheck disable=SC2154,SC2034 + +if [[ -z ${project_root} ]]; then + project_root=$(git rev-parse --show-toplevel) +fi +if [[ -z ${git_branch} ]]; then + git_branch=$(git branch --show-current) +fi + +# shellcheck disable=SC1091 +. "${project_root}/just_scripts/sudoif.sh" + +# Check if inside rootless container +if [[ -f /run/.containerenv ]]; then + #shellcheck disable=SC1091 + source /run/.containerenv + #shellcheck disable=SC2154 + if [[ "${rootless}" -eq "1" ]]; then + echo "Cannot build ISO inside rootless podman container... Exiting..." + exit 1 + fi +fi +container_mgr=$(just _container_mgr) +# If using rootless container manager, exit. Might not be best check +if "${container_mgr}" info | grep Root | grep -q /home; then + echo "Cannot build ISO with rootless container..." + exit 1 +fi + +# Get Inputs +image=$1 +version=$2 + +# Set image/target/version based on inputs +# shellcheck disable=SC2154,SC1091 +. "${project_root}/just_scripts/get-defaults.sh" + +# Set Container tag name +tag=$(just _tag "${image}") + +# Remove old ISO if present +sudoif rm -f "${project_root}/just_scripts/output/${tag}-${version}-${git_branch}.iso" +sudoif rm -f "${project_root}/just_scripts/output/${tag}-${version}-${git_branch}.iso-CHECKSUM" + +# Set variant +if [[ "${image}" =~ "silverblue" ]]; then + variant=Silverblue +else + variant=Kinoite +fi + +if [[ ${container_mgr} =~ "podman" ]]; then + api_socket=/run/podman/podman.sock +elif [[ ${container_mgr} =~ "docker" ]]; then + api_socket=/var/run/docker.sock +fi + +# Make sure image actually exists, build if it doesn't +ID=$(${container_mgr} images --filter reference=localhost/"${tag}:${version}-${git_branch}" --format "{{.ID}}") +if [[ -z ${ID} ]]; then + just build "${image}" "${version}" +fi + +workspace=${project_root} +if [[ -f /.dockerenv || -f /run/.containerenv ]]; then + workspace=${LOCAL_WORKSPACE_FOLDER} +fi + +# Make ISO +${container_mgr} run --rm --privileged \ + --volume "${api_socket}":/var/run/docker.sock \ + --volume "${workspace}"/just_scripts/build-iso-makefile-patch:/build-container-installer/container/Makefile \ + --volume "${workspace}"/just_scripts/output:/build-container-installer/build \ + ghcr.io/jasonn3/build-container-installer:main \ + ARCH="x86_64" \ + ENABLE_CACHE_DNF="false" \ + ENABLE_CACHE_SKOPEO="false" \ + ENROLLMENT_PASSWORD="ublue-os" \ + IMAGE_NAME="${tag}" \ + IMAGE_REPO="localhost" \ + IMAGE_TAG="${version}-${git_branch}" \ + ISO_NAME="build/${tag}-${version}-${git_branch}.iso" \ + SECURE_BOOT_KEY_URL='https://github.com/ublue-os/akmods/raw/main/certs/public_key.der' \ + VARIANT="${variant}" \ + VERSION="${version}" diff --git a/just_scripts/build-iso-makefile-patch b/just_scripts/build-iso-makefile-patch new file mode 100644 index 00000000..bb8d7d9d --- /dev/null +++ b/just_scripts/build-iso-makefile-patch @@ -0,0 +1,11 @@ +$(IMAGE_NAME)-$(IMAGE_TAG): + skopeo copy docker-daemon:$(IMAGE_REPO)/$(IMAGE_NAME):$(IMAGE_TAG) oci:$(IMAGE_NAME)-$(IMAGE_TAG) + +install-deps: + $(install_pkg) skopeo + +FILES=$(filter-out Makefile,$(wildcard *)) +clean: +ifneq ($(FILES),) + rm -Rf $(FILES) +endif diff --git a/just_scripts/build-iso.sh b/just_scripts/build-iso.sh new file mode 100755 index 00000000..c34f3416 --- /dev/null +++ b/just_scripts/build-iso.sh @@ -0,0 +1,86 @@ +#!/usr/bin/bash +#shellcheck disable=SC2154,SC2034 + +if [[ -z ${project_root} ]]; then + project_root=$(git rev-parse --show-toplevel) +fi +if [[ -z ${git_branch} ]]; then + git_branch=$(git branch --show-current) +fi + +# shellcheck disable=SC1091 +. "${project_root}/just_scripts/sudoif.sh" + +# Check if inside rootless container +if [[ -f /run/.containerenv ]]; then + #shellcheck disable=SC1091 + source /run/.containerenv + #shellcheck disable=SC2154 + if [[ "${rootless}" -eq "1" ]]; then + echo "Cannot build ISO inside rootless podman container... Exiting..." + exit 1 + fi +fi +container_mgr=$(just _container_mgr) +# If using rootless container manager, exit. Might not be best check +if "${container_mgr}" info | grep Root | grep -q /home; then + echo "Cannot build ISO with rootless container..." + exit 1 +fi + +# Get Inputs +image=$1 +version=$2 + +# Set image/target/version based on inputs +# shellcheck disable=SC2154,SC1091 +. "${project_root}/just_scripts/get-defaults.sh" + +# Set Container tag name +tag=$(just _tag "${image}") + +# Remove old ISO if present +sudoif rm -f "${project_root}/just_scripts/output/${tag}-${version}-${git_branch}.iso" +sudoif rm -f "${project_root}/just_scripts/output/${tag}-${version}-${git_branch}.iso-CHECKSUM" + +# Set variant +if [[ "${image}" =~ "silverblue" ]]; then + variant=Silverblue +else + variant=Kinoite +fi + +if [[ ${container_mgr} =~ "podman" ]]; then + api_socket=/run/podman/podman.sock +elif [[ ${container_mgr} =~ "docker" ]]; then + api_socket=/var/run/docker.sock +fi + +# Make sure image actually exists, build if it doesn't +ID=$(${container_mgr} images --filter reference=localhost/"${tag}:${version}-${git_branch}" --format "{{.ID}}") +if [[ -z ${ID} ]]; then + just build "${image}" "${version}" +fi + +workspace=${project_root} +if [[ -f /.dockerenv || -f /run/.containerenv ]]; then + workspace=${LOCAL_WORKSPACE_FOLDER} +fi + +# Make ISO +${container_mgr} run --rm --privileged \ + --volume "${api_socket}":/var/run/docker.sock \ + --volume "${workspace}"/just_scripts/build-iso-makefile-patch:/build-container-installer/container/Makefile \ + --volume "${workspace}"/just_scripts/output:/build-container-installer/build \ + ghcr.io/jasonn3/build-container-installer:latest \ + ARCH="x86_64" \ + ENABLE_CACHE_DNF="false" \ + ENABLE_CACHE_SKOPEO="false" \ + ENROLLMENT_PASSWORD="ublue-os" \ + IMAGE_NAME="${tag}" \ + IMAGE_REPO="localhost" \ + IMAGE_TAG="${version}-${git_branch}" \ + ISO_NAME="build/${tag}-${version}-${git_branch}.iso" \ + SECURE_BOOT_KEY_URL='https://github.com/ublue-os/akmods/raw/main/certs/public_key.der' \ + VARIANT="${variant}" \ + VERSION="${version}" diff --git a/just_scripts/cleanup-dir.sh b/just_scripts/cleanup-dir.sh new file mode 100755 index 00000000..03140923 --- /dev/null +++ b/just_scripts/cleanup-dir.sh @@ -0,0 +1,11 @@ +#!/usr/bin/bash +if [[ -z ${project_root} ]]; then + project_root=$(git rev-parse --show-toplevel) +fi +# shellcheck disable=SC1091 +. "${project_root}/just_scripts/sudoif.sh" + +set -euox pipefail + +#shellcheck disable=SC2154 +sudoif rm -f "${project_root}"/just_scripts/output/* #ISOs diff --git a/just_scripts/cleanup-images.sh b/just_scripts/cleanup-images.sh new file mode 100755 index 00000000..6b25bd7b --- /dev/null +++ b/just_scripts/cleanup-images.sh @@ -0,0 +1,20 @@ +#!/usr/bin/bash +set -euox pipefail +container_mgr=( + docker + podman + podman-remote +) +git_branches=($(git branch --format="%(refname:short)")) +for i in "${container_mgr[@]}"; do + if [[ $(command -v "$i") ]]; then + echo "Container Manager: ${i}" + for j in "${git_branches[@]}"; do + ID=$(${i} images --filter "reference=localhost/*-build:${gts}-${j}" --filter "reference=localhost/*-build:${latest}-${j}" --format "{{.ID}}") + if [[ -n "$ID" ]]; then + xargs -I {} "${i}" image rm {} <<< "$ID" + fi + done + echo "" + fi +done diff --git a/just_scripts/container_mgr.sh b/just_scripts/container_mgr.sh new file mode 100755 index 00000000..491f017b --- /dev/null +++ b/just_scripts/container_mgr.sh @@ -0,0 +1,21 @@ +#!/usr/bin/bash +valid_manager=( + docker + podman + podman-remote +) +if [[ -n ${CONTAINER_MGR} ]]; then + if [[ "${valid_manager[*]}" =~ ${CONTAINER_MGR} ]]; then + echo "${CONTAINER_MGR}" + else + exit 1 + fi +elif [[ $(command -v docker) ]]; then + echo docker +elif [[ $(command -v podman) ]]; then + echo podman +elif [[ $(command -v podman-remote) ]];then + echo podman-remote +else + exit 1 +fi \ No newline at end of file diff --git a/just_scripts/get-defaults.sh b/just_scripts/get-defaults.sh new file mode 100755 index 00000000..ea45b4c9 --- /dev/null +++ b/just_scripts/get-defaults.sh @@ -0,0 +1,30 @@ +#!/usr/bin/bash +if [[ -z "${image}" ]]; then + image=${default_image} +fi + +if [[ -z "${version}" ]]; then + version=${latest} +elif [[ ${version} == "latest" ]]; then + version=${latest} +elif [[ ${version} == "gts" ]]; then + version=${gts} +fi + +valid_images=( + silverblue + kinoite + sericea + onyx + base + lazurite + vauxite +) +image=${image,,} +if [[ ${image} == "mate" ]]; then + echo "Mate not supported..." + exit 1 +elif [[ ! ${valid_images[*]} =~ ${image} ]]; then + echo "Invalid image..." + exit 1 +fi \ No newline at end of file diff --git a/just_scripts/list-images.sh b/just_scripts/list-images.sh new file mode 100755 index 00000000..0fabbc59 --- /dev/null +++ b/just_scripts/list-images.sh @@ -0,0 +1,19 @@ +#!/usr/bin/bash +set -euo pipefail +container_mgr=( + docker + podman + podman-remote +) +git_branches=($(git branch --format="%(refname:short)")) +for i in "${container_mgr[@]}"; do + if [[ $(command -v "$i") ]]; then + echo "Container Manager: ${i}" + for j in "${git_branches[@]}"; do + ID=$(${i} images --filter "reference=localhost/*-build:${gts}-${j}" --filter "reference=localhost/*-build:${latest}-${j}" --format "{{.ID}}") + if [[ -n "$ID" ]]; then + ${i} images --filter "reference=localhost/*-build:${gts}-${j}" --filter "reference=localhost/*-build:${latest}-${j}" + fi + done + fi +done diff --git a/just_scripts/run-image.sh b/just_scripts/run-image.sh new file mode 100755 index 00000000..a768ba6f --- /dev/null +++ b/just_scripts/run-image.sh @@ -0,0 +1,29 @@ +#!/usr/bin/bash +if [[ -z ${project_root} ]]; then + project_root=$(git rev-parse --show-toplevel) +fi +if [[ -z ${git_branch} ]]; then + git_branch=$(git branch --show-current) +fi +set -eo pipefail + +# Get Inputs +image=$1 +version=$2 + +# Get image/target/version based on inputs +# shellcheck disable=SC2154,SC1091 +. "${project_root}/just_scripts/get-defaults.sh" + +# Get variables +container_mgr=$(just _container_mgr) +tag=$(just _tag "${image}") + +# Check if requested image exist, if it doesn't build it +ID=$(${container_mgr} images --filter reference=localhost/"${tag}":"${version}-${git_branch}" --format "{{.ID}}") +if [[ -z ${ID} ]]; then + just build "${image}" "${version}" +fi + +# Run image +"${container_mgr}" run -it --rm localhost/"${tag}:${version}-${git_branch}" /usr/bin/bash diff --git a/just_scripts/run-iso.sh b/just_scripts/run-iso.sh new file mode 100755 index 00000000..ea17b6f9 --- /dev/null +++ b/just_scripts/run-iso.sh @@ -0,0 +1,40 @@ +#!/usr/bin/bash +if [[ -z ${project_root} ]]; then + project_root=$(git rev-parse --show-toplevel) +fi +if [[ -z ${git_branch} ]]; then + git_branch=$(git branch --show-current) +fi +set -eo pipefail + +# Get Inputs +image=$1 +version=$2 + +# Get image/target/version based on inputs +# shellcheck disable=SC2154,SC1091 +. "${project_root}/just_scripts/get-defaults.sh" + +# Get variables +container_mgr=$(just _container_mgr) +tag=$(just _tag "${image}") + +#check if ISO exists. Create if it doesn't +if [[ ! -f "${project_root}/just_scripts/output/${tag}-${version}-${git_branch}.iso" ]]; then + just build-iso "$image" "$version" +fi + +workspace=${project_root} +if [[ -f /.dockerenv ]]; then + workspace=${LOCAL_WORKSPACE_FOLDER} +fi + +${container_mgr} run --rm --cap-add NET_ADMIN \ + --publish 127.0.0.1:8006:8006 \ + --env "CPU_CORES=2" \ + --env "RAM_SIZE=4G" \ + --env "DISK_SIZE=64G" \ + --env "BOOT_MODE=uefi" \ + --device=/dev/kvm \ + --volume "${workspace}/just_scripts/output/${tag}-${version}-${git_branch}.iso":/boot.iso \ + docker.io/qemux/qemu-docker \ No newline at end of file diff --git a/just_scripts/sudoif.sh b/just_scripts/sudoif.sh new file mode 100755 index 00000000..aeb7c722 --- /dev/null +++ b/just_scripts/sudoif.sh @@ -0,0 +1,14 @@ +#!/usr/bin/bash +function sudoif(){ + if [[ "${TERM_PROGRAM}" == "vscode" && \ + ! -f /run/.containerenv && \ + ! -f /.dockerenv ]]; then + [[ $(command -v systemd-run) ]] && \ + /usr/bin/systemd-run --uid=0 --gid=0 -d -E TERM="$TERM" -t -q -P -G "$@" \ + || exit 1 + else + [[ $(command -v sudo) ]] && \ + /usr/bin/sudo "$@" \ + || exit 1 + fi +}