diff --git a/.github/workflows/build-templates.yml b/.github/workflows/build-templates.yml deleted file mode 100644 index 80f76f06..00000000 --- a/.github/workflows/build-templates.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Build and Upload Templates -on: - push: - paths: - - 'packer/**' - schedule: - - cron: "0 4 * * *" - workflow_dispatch: - -jobs: - build: - runs-on: ubuntu-latest - env: - PROXMOX_API_URL: ${{ secrets.PROXMOX_API_URL }} - PROXMOX_TOKEN_ID: ${{ secrets.PROXMOX_TOKEN_ID }} - PROXMOX_TOKEN_SECRET: ${{ secrets.PROXMOX_TOKEN_SECRET }} - - steps: - - uses: actions/checkout@v4 - - - name: Set TEMPLATE_VERSION - run: echo "TEMPLATE_VERSION=$(date +%Y%m%d)" >> $GITHUB_ENV - - - name: Install dependencies - run: sudo apt-get update && sudo apt-get install -y packer ansible zstd python3-requests - - - name: Build Debian 12 Template - run: | - packer build \ - -var "template_version=${TEMPLATE_VERSION}" \ - debian12.pkr.hcl - - - name: Upload Debian 12 Template - run: | - python3 api/proxmox_upload.py \ - --file /tmp/output/debian12-fungible_${TEMPLATE_VERSION}.tar.xz - - - name: Build Rocky 9 Template - run: | - packer build \ - -var "template_version=${TEMPLATE_VERSION}" \ - rocky9.pkr.hcl - - - name: Upload Rocky 9 Template - run: | - python3 api/proxmox_upload.py \ - --file /tmp/output/rocky9-fungible_${TEMPLATE_VERSION}.tar.xz \ No newline at end of file diff --git a/ci-cd-automation/README.md b/ci-cd-automation/README.md deleted file mode 100644 index b8b97510..00000000 --- a/ci-cd-automation/README.md +++ /dev/null @@ -1 +0,0 @@ -# CI/CD Automation \ No newline at end of file diff --git a/ci-cd-automation/check-container-exists.sh b/ci-cd-automation/check-container-exists.sh deleted file mode 100644 index ba0b2c9a..00000000 --- a/ci-cd-automation/check-container-exists.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -# Script to check if a container exists, and if so, whether it needs to be updated or cloned. -# Last Modified by Maxwell Klema on July 13th, 2025 -# ----------------------------------------------------- - -outputError() { - echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" - echo -e "${BOLD}${MAGENTA}❌ Script Failed. Exiting... ${RESET}" - echo -e "$2" - echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" - exit $1 -} - -RESET="\033[0m" -BOLD="\033[1m" -MAGENTA='\033[35m' - -echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" -echo -e "${BOLD}${MAGENTA}🔎 Check Container Exists ${RESET}" -echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" - -TYPE_RUNNER="true" -source /var/lib/vz/snippets/helper-scripts/PVE_user_authentication.sh -source /var/lib/vz/snippets/helper-scripts/verify_container_ownership.sh - -STATUS=$? -if [ "$STATUS" != 0 ]; then - exit 1; -fi - -REPO_BASE_NAME=$(basename -s .git "$PROJECT_REPOSITORY") - -# Check if repository folder is present. -if [ "$PVE1" == "true" ]; then - if [ ! -z "$CONTAINER_ID" ] && pct exec $CONTAINER_ID -- test -f /root/container-updates.log; then - exit 2; # Update Repository - else - exit 0; # Clone Repository - fi -else - if [ ! -z "$CONTAINER_ID" ] && ssh 10.15.0.5 "pct exec $CONTAINER_ID -- test -f /root/container-updates.log" ; then - exit 2; # Update Repository - else - exit 0; # Clone Repository - fi -fi \ No newline at end of file diff --git a/ci-cd-automation/delete-container.sh b/ci-cd-automation/delete-container.sh deleted file mode 100644 index d46ce23b..00000000 --- a/ci-cd-automation/delete-container.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# Script to delete a container permanently -# Last Modified by Maxwell Klema on July 13th, 2025 -# ----------------------------------------------------- - -RESET="\033[0m" -BOLD="\033[1m" -MAGENTA='\033[35m' - -echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" -echo -e "${BOLD}${MAGENTA}🗑️ Delete Container ${RESET}" -echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" - -CMD=( -bash /var/lib/vz/snippets/helper-scripts/delete-runner.sh -"$PROJECT_REPOSITORY" -"$GITHUB_PAT" -"$PROXMOX_USERNAME" -"$PROXMOX_PASSWORD" -"$CONTAINER_NAME" -) - -# Safely quote each argument for the shell -QUOTED_CMD=$(printf ' %q' "${CMD[@]}") - -tmux new-session -d -s delete-runner "$QUOTED_CMD" - -echo "✅ Container with name \"$CONTAINER_NAME\" will be permanently deleted." -exit 0 # Container Deleted Successfully \ No newline at end of file diff --git a/ci-cd-automation/helper-scripts/PVE_user_authentication.sh b/ci-cd-automation/helper-scripts/PVE_user_authentication.sh deleted file mode 100755 index f2f07204..00000000 --- a/ci-cd-automation/helper-scripts/PVE_user_authentication.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# Script that checks if a user is authenticated in Proxmox PVE Realm @ opensource.mieweb.org -# Last Modified by Maxwell Klema on July 13th, 2025 -# ----------------------------------------------------- - -# Authenticate User (Only Valid Users can Create Containers) - -if [ -z "$PROXMOX_USERNAME" ]; then - read -p "Enter Proxmox Username → " PROXMOX_USERNAME -fi - -if [ -z "$PROXMOX_PASSWORD" ]; then - read -sp "Enter Proxmox Password → " PROXMOX_PASSWORD - echo "" -fi - -USER_AUTHENTICATED=$(ssh root@create-container "node /root/bin/js/runner.js authenticateUser \"$PROXMOX_USERNAME\" \"$PROXMOX_PASSWORD\"") - -if [ $USER_AUTHENTICATED == 'false' ]; then - outputError 1 "Your Proxmox account, $PROXMOX_USERNAME@pve, was not authenticated. Retry with valid credentials." -fi - -echo "🎉 Your proxmox account, $PROXMOX_USERNAME@pve, has been authenticated" \ No newline at end of file diff --git a/ci-cd-automation/helper-scripts/create-template.sh b/ci-cd-automation/helper-scripts/create-template.sh deleted file mode 100755 index 54d5e1ea..00000000 --- a/ci-cd-automation/helper-scripts/create-template.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash -# Creates a template of a LXC container -# Last modified by Maxwell Klema on July 23rd, 2025. -# -------------------------------------------------- - -if [ "${DEPLOY_ON_START^^}" != "Y" ] || [ "${GH_ACTION^^}" != "Y" ]; then - return 0 -fi - -DEFAULT_BRANCH=$(curl -s https://api.github.com/repos/$REPO_BASE_NAME_WITH_OWNER/$REPO_BASE_NAME | jq -r '.default_branch') - -if [ "$DEFAULT_BRANCH" != "$PROJECT_BRANCH" ]; then - return 0 -fi - -echo "📝 Creating Container Template..." - -# Check if template already exists, and if it does, destroy it ===== - -TEMPLATE_NAME="template-$REPO_BASE_NAME-$REPO_BASE_NAME_WITH_OWNER" -TEMPLATE_CONTAINER_ID=$( { pct list; ssh root@10.15.0.5 'pct list'; } | awk -v name="$TEMPLATE_NAME" '$3 == name {print $1}') - -if [ ! -z "$TEMPLATE_CONTAINER_ID" ]; then - pct destroy $TEMPLATE_CONTAINER_ID | true -fi - -# Clone LXC container and convert it into a template ===== - -NEXT_ID=$(pvesh get /cluster/nextid) - -if (( $CONTAINER_ID % 2 == 101 )); then - ssh root@10.15.0.5 " - pct clone $CONTAINER_ID $NEXT_ID \ - --hostname "$TEMPLATE_NAME" \ - --full true - pct migrate $NEXT_ID intern-phxdc-pve1 --target-storage containers-pve1 - " > /dev/null 2>&1 -else - pct clone $CONTAINER_ID $NEXT_ID \ - --hostname "$TEMPLATE_NAME" \ - --full true -fi - -# AUTH_TOKEN_RESPONSE=$(curl --location --request POST https://api.github.com/repos/$REPO_BASE_NAME_WITH_OWNER/$REPO_BASE_NAME/actions/runners/registration-token --header "Authorization: token $GITHUB_PAT") -# TOKEN=$(echo "$AUTH_TOKEN_RESPONSE" | jq -r '.token') - -# Remove rsa keys ==== -pct start $NEXT_ID -pct enter $NEXT_ID < /dev/null 2>&1 - else - ssh root@10.15.0.5 "pct destroy $CONTAINER_ID" > /dev/null 2>&1 - fi -else - if pct status "$CONTAINER_ID" | grep -q "status: running"; then - pct stop "$CONTAINER_ID" && pct destroy "$CONTAINER_ID" > /dev/null 2>&1 - else - pct destroy "$CONTAINER_ID" > /dev/null 2>&1 - fi -fi - -source /usr/local/bin/prune_iptables.sh - -REPO_BASE_NAME=$(basename -s .git "$PROJECT_REPOSITORY") -REPO_BASE_NAME_WITH_OWNER=$(echo "$PROJECT_REPOSITORY" | cut -d'/' -f4) - -RUNNERS=$(curl --location https://api.github.com/repos/$REPO_BASE_NAME_WITH_OWNER/$REPO_BASE_NAME/actions/runners --header "Authorization: token $GITHUB_PAT") - -while read -r RUNNER; do - RUNNER_NAME=$(echo "$RUNNER" | jq -r '.name') - if [ "$RUNNER_NAME" == "$CONTAINER_NAME" ]; then - RUNNER_ID=$(echo "$RUNNER" | jq -r '.id') - curl --location --request DELETE "https://api.github.com/repos/$REPO_BASE_NAME_WITH_OWNER/$REPO_BASE_NAME/actions/runners/$RUNNER_ID" \ - --header "Authorization: token $GITHUB_PAT" - fi -done < <(echo "$RUNNERS" | jq -c '.runners[]') \ No newline at end of file diff --git a/ci-cd-automation/helper-scripts/repository_status.sh b/ci-cd-automation/helper-scripts/repository_status.sh deleted file mode 100755 index 5ec73b76..00000000 --- a/ci-cd-automation/helper-scripts/repository_status.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -# Helper script to determine if container needs to clone repository or simply update it -# Last Modified by Maxwell Klema on July 21st, 2025 -# ------------------------------------------------- - -set +e -TYPE_RUNNER="true" -source /var/lib/vz/snippets/helper-scripts/PVE_user_authentication.sh -source /var/lib/vz/snippets/helper-scripts/verify_container_ownership.sh - -STATUS=$? - -if [ "$STATUS" != 0 ]; then - exit 1; -fi - -REPO_BASE_NAME=$(basename -s .git "$PROJECT_REPOSITORY") - -# Check if repository folder is present. - -if [ "$PVE1" == "true" ]; then - if pct exec $CONTAINER_ID -- test -d /root/$REPO_BASE_NAME; then - echo "Update" - exit 2; # Update Repository - else - echo "Clone" - exit 0; # Clone Repository - fi -else - if ssh 10.15.0.5 "pct exec $CONTAINER_ID -- test -d /root/$REPO_BASE_NAME"; then - echo "Update" - exit 2; # Update Repository - else - echo "Clone" - exit 0; # Clone Repository - fi -fi \ No newline at end of file diff --git a/ci-cd-automation/helper-scripts/verify_container_ownership.sh b/ci-cd-automation/helper-scripts/verify_container_ownership.sh deleted file mode 100755 index f99849ae..00000000 --- a/ci-cd-automation/helper-scripts/verify_container_ownership.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -# Script to verify container ownership based on name and CTID -# Last Modified by Maxwell Klema on August 5th, 2025 -# ----------------------------------------------------- - -CONTAINER_NAME="${CONTAINER_NAME,,}" -CONTAINER_ID=$( { pct list; ssh root@10.15.0.5 'pct list'; } | awk -v name="$CONTAINER_NAME" '$3 == name {print $1}') - -if [ -z "$CONTAINER_ID" ]; then - echo "✅ Container with name \"$CONTAINER_NAME\" is available for use." - return 1 -fi - -CONTAINER_OWNERSHIP=$(ssh root@10.15.20.69 -- "jq '.\"$CONTAINER_NAME\".user' /etc/nginx/port_map.json") -if [ "$TYPE_RUNNER" == "true" ] && (( $CONTAINER_ID % 2 == 0 )); then - PVE1="false" -elif [ "$TYPE_RUNNER" == "true" ] && (( $CONTAINER_ID % 2 != 0 )); then - PVE1="true" -fi - -if [ "$CONTAINER_OWNERSHIP" == "null" ]; then - echo "❌ You do not own the container with name \"$CONTAINER_NAME\"." - outputError 1 "You do not own the container with name \"$CONTAINER_NAME\"." -fi \ No newline at end of file diff --git a/ci-cd-automation/setup-runner.sh b/ci-cd-automation/setup-runner.sh deleted file mode 100644 index aaf9fafe..00000000 --- a/ci-cd-automation/setup-runner.sh +++ /dev/null @@ -1,141 +0,0 @@ -#!/bin/bash -# A script for cloning a Distro template, installing, and starting a runner on it. -# Last Modified by Maxwell Klema on August 5th, 2025 -# ------------------------------------------------ - -outputError() { - echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" - echo -e "${BOLD}${MAGENTA}❌ Script Failed. Exiting... ${RESET}" - echo -e "$2" - echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" - exit $1 -} - -BOLD='\033[1m' -RESET='\033[0m' - -echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" -echo "🧬 Cloning a Template and installing a Runner" -echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" - -# Validating Container Name ===== - -source /var/lib/vz/snippets/helper-scripts/PVE_user_authentication.sh #Authenticate User -source /var/lib/vz/snippets/helper-scripts/verify_container_ownership.sh #Ensure container does not exist. - -if [ ! -z "$CONTAINER_OWNERSHIP" ]; then - outputError 1 "You already own a container with name \"$CONTAINER_NAME\". Please delete it before creating a new one." -fi - -# Cloning Container Template and Setting it up ===== - -REPO_BASE_NAME=$(basename -s .git "$PROJECT_REPOSITORY") -REPO_BASE_NAME_WITH_OWNER=$(echo "$PROJECT_REPOSITORY" | cut -d'/' -f4) - -TEMPLATE_NAME="template-$REPO_BASE_NAME-$REPO_BASE_NAME_WITH_OWNER" -CTID_TEMPLATE=$( { pct list; ssh root@10.15.0.5 'pct list'; } | awk -v name="$TEMPLATE_NAME" '$3 == name {print $1}') - -case "${LINUX_DISTRIBUTION^^}" in - "") PACKAGE_MANAGER="apt-get" ;; - ROCKY) PACKAGE_MANAGER="dnf" ;; -esac - -# If no template ID was provided, assign a default based on distro - -if [ -z "$CTID_TEMPLATE" ]; then - case "${LINUX_DISTRIBUTION^^}" in - "") CTID_TEMPLATE="160" ;; - ROCKY) CTID_TEMPLATE="138" ;; - esac -fi - -if [ "${LINUX_DISTRIBUTION^^}" != "ROCKY" ]; then - LINUX_DISTRIBUTION="DEBIAN" -fi - -REPO_BASE_NAME=$(basename -s .git "$PROJECT_REPOSITORY") -REPO_BASE_NAME_WITH_OWNER=$(echo "$PROJECT_REPOSITORY" | cut -d'/' -f4) - -NEXT_ID=$(pvesh get /cluster/nextid) #Get the next available LXC ID - -# Create the Container Clone -echo "⏳ Cloning Container..." -pct clone $CTID_TEMPLATE $NEXT_ID \ - --hostname $CONTAINER_NAME \ - --full true > /dev/null 2>&1 - -# Set Container Options -echo "⏳ Setting Container Properties..." -pct set $NEXT_ID \ - --tags "$PROXMOX_USERNAME" \ - --tags "$LINUX_DISTRIBUTION" \ - --onboot 1 \ - --cores 4 \ - --memory 4096 > /dev/null 2>&1 - -pct start $NEXT_ID > /dev/null 2>&1 -pveum aclmod /vms/$NEXT_ID --user "$PROXMOX_USERNAME@pve" --role PVEVMUser > /dev/null 2>&1 - -sleep 5 -echo "⏳ DHCP Allocating IP Address..." -CONTAINER_IP=$(pct exec $NEXT_ID -- hostname -I | awk '{print $1}') - -# Setting Up Github Runner ===== - -# Get Temporary Token -echo "🪙 Getting Authentication Token..." -AUTH_TOKEN_RESPONSE=$(curl --location --request POST https://api.github.com/repos/$REPO_BASE_NAME_WITH_OWNER/$REPO_BASE_NAME/actions/runners/registration-token --header "Authorization: token $GITHUB_PAT" --write-out "HTTPSTATUS:%{http_code}" --silent) - -HTTP_STATUS=$(echo "$AUTH_TOKEN_RESPONSE" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2) -AUTH_TOKEN_BODY=$(echo "$AUTH_TOKEN_RESPONSE" | sed 's/HTTPSTATUS:[0-9]*$//') - -if [ "$HTTP_STATUS" != "201" ]; then - outputError 1 "Failed to get GitHub authentication token. HTTP Status: $HTTP_STATUS\nResponse: $AUTH_TOKEN_BODY" -fi - -TOKEN=$(echo "$AUTH_TOKEN_BODY" | jq -r '.token') - -pct enter $NEXT_ID < /dev/null 2>&1 -rm -rf /root/container-updates.log || true && \ -cd /actions-runner && export RUNNER_ALLOW_RUNASROOT=1 && \ -runProcess=\$(ps aux | grep "[r]un.sh" | awk '{print \$2}' | head -n 1) && \ -if [ ! -z "\$runProcess" ]; then kill -9 \$runProcess || true; fi && \ -rm -rf .runner .credentials && rm -rf _work/* /var/log/runner/* 2>/dev/null || true && \ -export RUNNER_ALLOW_RUNASROOT=1 && \ -./config.sh --url $PROJECT_REPOSITORY --token $TOKEN --labels $CONTAINER_NAME --name $CONTAINER_NAME --unattended -EOF - -# Generate RSA Keys ===== - -echo "🔑 Generating RSA Key Pair..." -pct exec $NEXT_ID -- bash -c "ssh-keygen -t rsa -N '' -f /root/.ssh/id_rsa -q" -PUB_KEY=$(pct exec $NEXT_ID -- bash -c "cat /root/.ssh/id_rsa.pub") - -# Place public key in all necessary authorized_keys files -echo "$PUB_KEY" >> /home/create-container/.ssh/authorized_keys -echo "$PUB_KEY" >> /home/update-container/.ssh/authorized_keys -echo "$PUB_KEY" >> /home/delete-container/.ssh/authorized_keys -echo "$PUB_KEY" >> /home/container-exists/.ssh/authorized_keys - -echo "🔑 Creating Service File..." -pct exec $NEXT_ID -- bash -c "cat < /etc/systemd/system/github-runner.service -[Unit] -Description=GitHub Actions Runner -After=network.target - -[Service] -Type=simple -WorkingDirectory=/actions-runner -Environment=\"RUNNER_ALLOW_RUNASROOT=1\" -ExecStart=/actions-runner/run.sh -Restart=always - -[Install] -WantedBy=multi-user.target -EOF" - -pct exec $NEXT_ID -- systemctl daemon-reload -pct exec $NEXT_ID -- systemctl enable github-runner -pct exec $NEXT_ID -- systemctl start github-runner - -exit 3 diff --git a/ci-cd-automation/update-container.sh b/ci-cd-automation/update-container.sh deleted file mode 100644 index 0be5e739..00000000 --- a/ci-cd-automation/update-container.sh +++ /dev/null @@ -1,324 +0,0 @@ -#!/bin/bash -# Script to automatically fetch new contents from a branch, push them to container, and restart intern -# Last Modified on August 17th, 2025 by Maxwell Klema -# ---------------------------------------- - -RESET="\033[0m" -BOLD="\033[1m" -MAGENTA='\033[35m' - -outputError() { - echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" - echo -e "${BOLD}${MAGENTA}❌ Script Failed. Exiting... ${RESET}" - echo -e "$2" - echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" - exit $1 -} - - -echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" -echo -e "${BOLD}${MAGENTA}🔄 Update Container Contents ${RESET}" -echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" - -if [ -z "${RUNTIME_LANGUAGE^^}" ]; then - echo "Skipping container update because there is nothing to update." - exit 0 -fi - -source /var/lib/vz/snippets/helper-scripts/PVE_user_authentication.sh -source /var/lib/vz/snippets/helper-scripts/verify_container_ownership.sh - -# Get Project Details - -CONTAINER_NAME="${CONTAINER_NAME,,}" - -if [ -z "$PROJECT_REPOSITORY" ]; then - read -p "🚀 Paste the link to your project repository → " PROJECT_REPOSITORY -else - DEPLOY_ON_START="y" -fi - -CheckRepository() { - PROJECT_REPOSITORY_SHORTENED=${PROJECT_REPOSITORY#*github.com/} - PROJECT_REPOSITORY_SHORTENED=${PROJECT_REPOSITORY_SHORTENED%.git} - REPOSITORY_EXISTS=$(curl -s -o /dev/null -w "%{http_code}" https://github.com/$PROJECT_REPOSITORY_SHORTENED) -} - -CheckRepository - -if [ "$REPOSITORY_EXISTS" != "200" ]; then - outputError 1 "The repository link you provided, \"$PROJECT_REPOSITORY\" was not valid." -fi - -echo "✅ The repository link you provided, \"$PROJECT_REPOSITORY\", was valid." - -# Get Project Branch - -if [ -z "$PROJECT_BRANCH" ]; then - PROJECT_BRANCH="main" -fi - -REPOSITORY_BRANCH_EXISTS=$(curl -s -o /dev/null -w "%{http_code}" https://api.github.com/repos/$PROJECT_REPOSITORY_SHORTENED/branches/$PROJECT_BRANCH) - -if [ "$REPOSITORY_BRANCH_EXISTS" != "200" ]; then - outputError 1 "The branch you provided, \"$PROJECT_BRANCH\", does not exist on repository at \"$PROJECT_REPOSITORY\"." -fi - - -# Get Project Root Directroy - -if [ "$PROJECT_ROOT" == "." ] || [ -z "$PROJECT_ROOT" ]; then - PROJECT_ROOT="/" -fi - -VALID_PROJECT_ROOT=$(ssh root@10.15.234.122 "node /root/bin/js/runner.js authenticateRepo \"$PROJECT_REPOSITORY\" \"$PROJECT_BRANCH\" \"$PROJECT_ROOT\"") - -if [ "$VALID_PROJECT_ROOT" == "false" ]; then - outputError 1 "The root directory you provided, \"$PROJECT_ROOT\", does not exist on branch, \"$PROJECT_BRANCH\", on repository at \"$PROJECT_REPOSITORY\"." -fi - -REPO_BASE_NAME=$(basename -s .git "$PROJECT_REPOSITORY") -REPO_BASE_NAME_WITH_OWNER=$(echo "$PROJECT_REPOSITORY" | cut -d'/' -f4) - -if [ "$PROJECT_ROOT" == "" ] || [ "$PROJECT_ROOT" == "/" ]; then - PROJECT_ROOT="." -fi - -# Install Services ==== - -echo "🛎️ Installing Services..." - -if [ -z "$LINUX_DISTRIBUTION" ]; then - LINUX_DISTRIBUTION="debian" -fi - -if [ ! -z "$SERVICES" ] || [ ! -z "$CUSTOM_SERVICES" ]; then - REQUIRE_SERVICES="y" -fi - -SERVICE_COMMANDS=$(ssh -o SendEnv="LINUX_DISTRIBUTION SERVICES CUSTOM_SERVICES REQUIRE_SERVICES" \ - root@10.15.234.122 \ - "/root/bin/deployment-scripts/gatherServices.sh true") - -echo "$SERVICE_COMMANDS" | while read -r line; do - pct exec $CONTAINER_ID -- bash -c "$line | true" > /dev/null 2>&1 -done - -# Change HTTP port if necessary ==== - -if [ ! -z "$HTTP_PORT" ]; then - if [ "$HTTP_PORT" -lt 80 ] || [ "$HTTP_PORT" -gt 60000 ]; then - outputError 1 "Invalid HTTP port: $HTTP_PORT. Must be between 80 and 60000." - fi - ssh root@10.15.20.69 -- \ -"jq \ '.[\"$CONTAINER_NAME\"].ports.http = $HTTP_PORT' \ - /etc/nginx/port_map.json > /tmp/port_map.json.new \ - && mv -f /tmp/port_map.json.new /etc/nginx/port_map.json " -fi - -# Clone repository if needed ==== - -if (( "$CONTAINER_ID" % 2 == 0 )); then - ssh root@10.15.0.5 " - pct enter $CONTAINER_ID < /dev/null -fi -EOF - " -else - pct enter $CONTAINER_ID < /dev/null -fi -EOF -fi - -# Update Environment Variables - -if [ ! -z "$RUNTIME_LANGUAGE" ] && echo "$RUNTIME_LANGUAGE" | jq . >/dev/null 2>&1; then # If RUNTIME_LANGUAGE is set and is valid JSON - MULTI_COMPONENT="Y" -fi - -# Helper Function to write environment variables to a file inside container -writeEnvToFile() { - env_file_path="$1" - component_path="$2" - env_vars=$(cat "$env_file_path") - if (( $CONTAINER_ID % 2 == 0 )); then - ssh 10.15.0.5 "pct exec $CONTAINER_ID -- bash -c 'if [ ! -f \"$component_path/.env\" ]; then touch \"$component_path/.env\"; fi; echo \"$env_vars\" >> \"$component_path/.env\"'" - else - pct exec $CONTAINER_ID -- bash -c "if [ ! -f \"$component_path/.env\" ]; then touch \"$component_path/.env\"; fi; echo \"$env_vars\" >> \"$component_path/.env\"" - fi -} - -# Check If there are environment variables -if [ ! -z "$CONTAINER_ENV_VARS" ]; then - # generate random temp .env folder to store all env files for different components - RANDOM_NUM=$(shuf -i 100000-999999 -n 1) - ENV_FOLDER="env_$RANDOM_NUM" - ENV_FOLDER_PATH="/var/lib/vz/snippets/container-env-vars/$ENV_FOLDER" - mkdir -p "$ENV_FOLDER_PATH" - - if [ "${MULTI_COMPONENT^^}" == "Y" ]; then # Multi-Component - if echo "$CONTAINER_ENV_VARS" | jq -e > /dev/null 2>&1; then #if exit status of jq is 0 (valid JSON) // success - for key in $(echo "$CONTAINER_ENV_VARS" | jq -r 'keys[]'); do - COMPONENT_PATH="/root/$REPO_BASE_NAME/$PROJECT_ROOT/$key" - ENV_FILE_NAME=$(echo "$COMPONENT_PATH" | tr '/' '_') - ENV_FILE_NAME="$ENV_FILE_NAME.txt" - ENV_FILE_PATH="$ENV_FOLDER_PATH/$ENV_FILE_NAME" - touch "$ENV_FILE_PATH" - echo "$CONTAINER_ENV_VARS" | jq -r --arg key "$key" '.[$key] | to_entries[] | "\(.key)=\(.value)"' > "$ENV_FILE_PATH" - writeEnvToFile "$ENV_FILE_PATH" "$COMPONENT_PATH" - done - else - outputError "Your \"CONTAINER_ENV_VARS\" is not valid JSON. Please re-format and try again." - writeLog "Invalid JSON in CONTAINER_ENV_VARS (GH_ACTION mode)" - exit 16 - fi - else # Single Component - ENV_FILE="env_$RANDOM_NUM.txt" - ENV_FILE_PATH="$ENV_FOLDER_PATH/$ENV_FILE" - touch "$ENV_FILE_PATH" - if echo "$CONTAINER_ENV_VARS" | jq -e > /dev/null 2>&1; then #if exit status of jq is 0 (valid JSON) // success - COMPONENT_PATH="/root/$REPO_BASE_NAME/$PROJECT_ROOT" - echo "$CONTAINER_ENV_VARS " | jq -r 'to_entries[] | "\(.key)=\(.value)"' > "$ENV_FILE_PATH" #k=v pairs - writeEnvToFile "$ENV_FILE_PATH" "$COMPONENT_PATH" - else - outputError "Your \"CONTAINER_ENV_VARS\" is not valid JSON. Please re-format and try again." - writeLog "Invalid JSON in CONTAINER_ENV_VARS for single component (GH_ACTION mode)" - exit 16 - fi - fi -fi - -# Update Container with New Contents from repository ===== - -startComponentPVE1() { - - RUNTIME="$1" - BUILD_CMD="$2" - START_CMD="$3" - COMP_DIR="$4" - INSTALL_CMD="$5" - - if [ "${RUNTIME^^}" == "NODEJS" ]; then - pct set $CONTAINER_ID --memory 4096 --swap 0 --cores 4 - pct exec $CONTAINER_ID -- bash -c "cd /root/$REPO_BASE_NAME/$PROJECT_ROOT/ && git fetch origin && git reset --hard origin/$PROJECT_BRANCH && git pull" > /dev/null 2>&1 - pct exec $CONTAINER_ID -- bash -c "cd /root/$REPO_BASE_NAME/$PROJECT_ROOT/$COMP_DIR && $INSTALL_CMD && $BUILD_CMD" > /dev/null 2>&1 - pct set $CONTAINER_ID --memory 2048 --swap 0 --cores 2 - elif [ "${RUNTIME^^}" == "PYTHON" ]; then - pct set $CONTAINER_ID --memory 4096 --swap 0 --cores 4 - pct exec $CONTAINER_ID -- bash -c "cd /root/$REPO_BASE_NAME/$PROJECT_ROOT/ && git fetch origin && git reset --hard origin/$PROJECT_BRANCH && git pull" > /dev/null 2>&1 - pct exec $CONTAINER_ID -- bash -c "cd /root/$REPO_BASE_NAME/$PROJECT_ROOT/$COMP_DIR && source venv/bin/activate && $INSTALL_CMD && $BUILD_CMD" > /dev/null 2>&1 - pct set $CONTAINER_ID --memory 2048 --swap 0 --cores 2 - fi -} - -startComponentPVE2() { - - RUNTIME="$1" - BUILD_CMD="$2" - START_CMD="$3" - COMP_DIR="$4" - INSTALL_CMD="$5" - - if [ "${RUNTIME^^}" == "NODEJS" ]; then - ssh root@10.15.0.5 " - pct set $CONTAINER_ID --memory 4096 --swap 0 --cores 4 && - pct exec $CONTAINER_ID -- bash -c 'cd /root/$REPO_BASE_NAME/$PROJECT_ROOT/ && git fetch origin && git reset --hard origin/$PROJECT_BRANCH && git pull' > /dev/null 2>&1 - pct exec $CONTAINER_ID -- bash -c 'cd /root/$REPO_BASE_NAME/$PROJECT_ROOT/$COMP_DIR && $INSTALL_CMD' && '$BUILD_CMD' > /dev/null 2>&1 - pct set $CONTAINER_ID --memory 2048 --swap 0 --cores 2 - " - elif [ "${RUNTIME^^}" == "PYTHON" ]; then - ssh root@10.15.0.5 " - pct set $CONTAINER_ID --memory 4096 --swap 0 --cores 4 && - pct exec $CONTAINER_ID -- bash -c 'cd /root/$REPO_BASE_NAME/$PROJECT_ROOT && git fetch origin && git reset --hard origin/$PROJECT_BRANCH && git pull' > /dev/null 2>&1 - pct exec $CONTAINER_ID -- bash -c 'cd /root/$REPO_BASE_NAME/$PROJECT_ROOT/$COMP_DIR && source venv/bin/activate && $INSTALL_CMD' && '$BUILD_CMD' > /dev/null 2>&1 - pct set $CONTAINER_ID --memory 2048 --swap 0 --cores 2 - " - fi -} - -if [ "${MULTI_COMPONENT^^}" == "Y" ]; then - for COMPONENT in $(echo "$START_COMMAND" | jq -r 'keys[]'); do - START=$(echo "$START_COMMAND" | jq -r --arg k "$COMPONENT" '.[$k]') - RUNTIME=$(echo "$RUNTIME_LANGUAGE" | jq -r --arg k "$COMPONENT" '.[$k]') - BUILD=$(echo "$BUILD_COMMAND" | jq -r --arg k "$COMPONENT" '.[$k]') - INSTALL=$(echo "$INSTALL_COMMAND" | jq -r --arg k "$COMPONENT" '.[$k]') - if [ "$BUILD" == "null" ]; then - BUILD="" - fi - - if (( "$CONTAINER_ID" % 2 == 0 )); then - startComponentPVE2 "$RUNTIME" "$BUILD" "$START" "$COMPONENT" "$INSTALL" - else - startComponentPVE1 "$RUNTIME" "$BUILD" "$START" "$COMPONENT" "$INSTALL" - fi - done - if [ ! -z "$ROOT_START_COMMAND" ]; then - if (( $CONTAINER_ID % 2 == 0 )); then - ssh root@10.15.0.5 "pct exec $CONTAINER_ID -- bash -c 'cd /root/$REPO_BASE_NAME/$PROJECT_ROOT && $ROOT_START_COMMAND'" - else - pct exec $CONTAINER_ID -- bash -c "cd /root/$REPO_BASE_NAME/$PROJECT_ROOT && $ROOT_START_COMMAND" - fi - fi - # startComponent "$RUNTIME_LANGUAGE" "$BUILD_COMMAND" "$START_COMMAND" "." -else - if (( $CONTAINER_ID % 2 == 0 )); then - startComponentPVE2 "$RUNTIME_LANGUAGE" "$BUILD_COMMAND" "$START_COMMAND" "." "$INSTALL_COMMAND" - if [ ! -z "$ROOT_START_COMMAND" ]; then - ssh root@10.15.0.5 "pct exec $CONTAINER_ID -- bash -c 'cd /root/$REPO_BASE_NAME/$PROJECT_ROOT && $ROOT_START_COMMAND'" > /dev/null 2>&1 - fi - else - startComponentPVE1 "$RUNTIME_LANGUAGE" "$BUILD_COMMAND" "$START_COMMAND" "." "$INSTALL_COMMAND" - if [ ! -z "$ROOT_START_COMMAND" ]; then - ssh root@10.15.0.5 "pct exec $CONTAINER_ID -- bash -c 'cd /root/$REPO_BASE_NAME/$PROJECT_ROOT && $ROOT_START_COMMAND'" > /dev/null 2>&1 - fi - fi -fi - -# Update Log File - -if (( "$CONTAINER_ID" % 2 == 0 )); then - ssh root@10.15.0.5 "pct exec $CONTAINER_ID -- bash -c 'echo \"[$(date)]\" >> /root/container-updates.log'" -else - pct exec $CONTAINER_ID -- bash -c "echo \"[$(date)]\" >> /root/container-updates.log" -fi - -# Create new template if on default branch ===== - -UPDATE_CONTAINER="true" -BUILD_COMMAND_B64=$(echo -n "$BUILD_COMMAND" | base64) -RUNTIME_LANGUAGE_B64=$(echo -n "$RUNTIME_LANGUAGE" | base64) -START_COMMAND_B64=$(echo -n "$START_COMMAND" | base64) - -CMD=( -bash /var/lib/vz/snippets/start_services.sh -"$CONTAINER_ID" -"$CONTAINER_NAME" -"$REPO_BASE_NAME" -"$REPO_BASE_NAME_WITH_OWNER" -"$SSH_PORT" -"$CONTAINER_IP" -"$PROJECT_ROOT" -"$ROOT_START_COMMAND" -"$DEPLOY_ON_START" -"$MULTI_COMPONENT" -"$START_COMMAND_B64" -"$BUILD_COMMAND_B64" -"$RUNTIME_LANGUAGE_B64" -"$GH_ACTION" -"$PROJECT_BRANCH" -"$UPDATE_CONTAINER" -) - -# Safely quote each argument for the shell -QUOTED_CMD=$(printf ' %q' "${CMD[@]}") - -tmux new-session -d -s "$CONTAINER_NAME" "$QUOTED_CMD" -echo "✅ Container $CONTAINER_ID has been updated with new contents from branch \"$PROJECT_BRANCH\" on repository \"$PROJECT_REPOSITORY\"." -echo "Wait a few minutes for all background processes to complete before accessing the container." -exit 0 diff --git a/images/base/Dockerfile b/images/base/Dockerfile new file mode 100644 index 00000000..5392d06e --- /dev/null +++ b/images/base/Dockerfile @@ -0,0 +1,27 @@ +# This first layer is only to build the root filesystem. We use Proxmox's +# minimal Debian template as it is well maintained and optimized for LXC usage. +FROM debian:13 AS builder +RUN apt-get update && apt-get install -y \ + curl tar zstd +ARG URL=http://download.proxmox.com/images/system/debian-13-standard_13.1-2_amd64.tar.zst +RUN mkdir /rootfs && curl "$URL" | tar --zstd -x -C /rootfs + +# Stage 2 of the build uses the root filesystem built in stage 1. The rest of +# the Dockerfile builds from there. +FROM scratch +COPY --from=builder /rootfs / + +# Install and setup sssd autoconfiguration +RUN apt-get update && \ + apt-get install -y sssd && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* +COPY sssd-autoconfigure.sh /usr/local/bin/sssd-autoconfigure +COPY sssd-autoconfigure.service /etc/systemd/system/ +RUN chmod +x /usr/local/bin/sssd-autoconfigure && \ + systemctl enable sssd-autoconfigure.service + +# Configure systemd to run properly in a container. This isn't nessary for LXC +# in Proxmox, but is useful for testing with Docker directly. +STOPSIGNAL SIGRTMIN+3 +ENTRYPOINT [ "/sbin/init" ] diff --git a/images/base/sssd-autoconfigure.service b/images/base/sssd-autoconfigure.service new file mode 100644 index 00000000..3921a456 --- /dev/null +++ b/images/base/sssd-autoconfigure.service @@ -0,0 +1,12 @@ +[Unit] +Description=Auto-configure SSSD from DHCP search domain +After=network-online.target +Before=sssd.service +Wants=network-online.target + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/sssd-autoconfigure + +[Install] +WantedBy=multi-user.target diff --git a/images/base/sssd-autoconfigure.sh b/images/base/sssd-autoconfigure.sh new file mode 100644 index 00000000..d2a5b8bc --- /dev/null +++ b/images/base/sssd-autoconfigure.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# sssd-autoconfigure — Generate /etc/sssd/sssd.conf from DHCP search domain +set -euo pipefail + +RESOLV_CONF="/etc/resolv.conf" +SSSD_CONF="/etc/sssd/sssd.conf" + +# Extract the first search domain from resolv.conf +search_domain=$(awk '/^(search|domain)/ { print $2; exit }' "$RESOLV_CONF") + +if [ -z "$search_domain" ]; then + echo "sssd-autoconfigure: No search domain found in $RESOLV_CONF" >&2 + exit 1 +fi + +# Transform "example.mieweb.com" → "dc=example,dc=mieweb,dc=com" +ldap_search_base=$(echo "$search_domain" | sed 's/\./,dc=/g; s/^/dc=/') + +echo "sssd-autoconfigure: domain=$search_domain base=$ldap_search_base" + +cat > "$SSSD_CONF" < **Permissions** -\> **API Tokens**. -2. Create a token (e.g., for `root@pam` or a dedicated automation user). -3. **Permissions:** The token needs at minimum: - * `Nodes.View` (to find nodes) - * `Storage.View` (to find storage) - * `Storage.Upload` (to upload the template) - * `Datastore.AllocateTemplate` (implicitly used by upload) -4. Copy the **Token ID** and **Token Secret** immediately. - ------ - -## Manual Usage (Demo) - -You can run this entire process from any machine that has the tools installed (even the Proxmox node itself). - -1. **Clone the Repository:** - - ```bash - git clone - cd - ``` - -2. **Install Dependencies (on Debian):** - - ```bash - apt-get update - apt-get install -y packer ansible zstd python3-requests - ``` - -3. **Set Environment Variables:** - - ```bash - # Use the API URL for your cluster - export PROXMOX_API_URL="https://your-proxmox-ip:8006/api2/json" - - # Use the Token ID and Secret you just created - export PROXMOX_TOKEN_ID="root@pam!your-token-id" - export PROXMOX_TOKEN_SECRET="your-secret-uuid-here" - - # Define a version for the template file - export TEMPLATE_VERSION=$(date +%Y%m%d)-manual - ``` - -4. **Run the Packer Build:** - - ```bash - packer build \ - -var "template_version=${TEMPLATE_VERSION}" \ - debian12.pkr.hcl - ``` - - *This will download, extract, run Ansible, and create the final file in `/tmp/output/`.* - -5. **Run the Python Upload:** - - ```bash - python3 api/proxmox_upload.py \ - --file /tmp/output/debian12-fungible_${TEMPLATE_VERSION}.tar.xz - ``` - - *This will upload the file to all nodes in your cluster.* - -6. **Verify:** - Log in to your Proxmox GUI. Go to any node's `local` storage and click the **CT Templates** tab. You will see your new template, ready for cloning. \ No newline at end of file diff --git a/packer/api/proxmox_upload.js b/packer/api/proxmox_upload.js deleted file mode 100644 index 5125709f..00000000 --- a/packer/api/proxmox_upload.js +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env node -// api/proxmox_upload.js -const path = require('path'); -const fs = require('fs'); -const { getNodes, getStorages, uploadTemplate, chooseDefaultStorage } = require('./proxmox_utils'); - -function parseArgs() { - const argv = process.argv.slice(2); - const out = {}; - for (let i = 0; i < argv.length; i++) { - const a = argv[i]; - if (a === '--file' && argv[i + 1]) { - out.file = argv[i + 1]; - i++; - } - } - return out; -} - -async function main() { - const args = parseArgs(); - if (!args.file) { - console.error('Error: --file is required'); - process.exit(1); - } - - const filepath = args.file; - if (!fs.existsSync(filepath)) { - console.error(`Error: file not found: ${filepath}`); - process.exit(1); - } - - console.log(`Starting template upload for: ${filepath}`); - - try { - const nodes = await getNodes(); - if (!nodes || !nodes.length) { - console.error('Error: No Proxmox nodes found.'); - process.exit(1); - } - - console.log(`Found nodes: ${nodes.join(', ')}`); - - for (const node of nodes) { - console.log(`--- Processing Node: ${node} ---`); - const storagesList = await getStorages(node); - const storage = chooseDefaultStorage(storagesList); - if (!storage) { - console.warn(`Warning: No suitable storage found on node ${node}. Skipping.`); - continue; - } - - console.log(`Uploading to ${node}:${storage}...`); - try { - const result = await uploadTemplate(node, storage, filepath); - console.log(`Successfully uploaded to ${node}:${storage}. Task: ${JSON.stringify(result.data || result)}`); - } catch (e) { - console.error(`Error uploading to ${node}:${storage}: ${e.message || e}`); - } - } - } catch (e) { - console.error(`An unexpected error occurred: ${e.message || e}`); - process.exit(1); - } - - console.log('Template upload process finished.'); -} - -if (require.main === module) { - main(); -} diff --git a/packer/api/proxmox_utils.js b/packer/api/proxmox_utils.js deleted file mode 100644 index 04580418..00000000 --- a/packer/api/proxmox_utils.js +++ /dev/null @@ -1,71 +0,0 @@ -// api/proxmox_utils.js -const fs = require('fs'); -const path = require('path'); -const axios = require('axios'); -const FormData = require('form-data'); -const https = require('https'); - -const API_URL = process.env.PROXMOX_API_URL; -const TOKEN_ID = process.env.PROXMOX_TOKEN_ID; -const TOKEN_SECRET = process.env.PROXMOX_TOKEN_SECRET; - -if (!API_URL || !TOKEN_ID || !TOKEN_SECRET) { - // Do not throw; allow functions to be imported but fail loudly when used. - // Console a warning to help debugging. - console.warn('Warning: PROXMOX_API_URL, PROXMOX_TOKEN_ID or PROXMOX_TOKEN_SECRET is not set. Requests will fail.'); -} - -const HEADERS = { - Authorization: `PVEAPIToken=${TOKEN_ID}=${TOKEN_SECRET}`, -}; - -// Accept self-signed / insecure if needed (mirrors requests verify=true) -const httpsAgent = new https.Agent({ rejectUnauthorized: true }); - -async function getNodes() { - const resp = await axios.get(`${API_URL}/nodes`, { headers: HEADERS, httpsAgent }); - const data = resp.data && resp.data.data ? resp.data.data : []; - return data.map(n => n.node); -} - -async function getStorages(node) { - const resp = await axios.get(`${API_URL}/nodes/${encodeURIComponent(node)}/storage`, { headers: HEADERS, httpsAgent }); - const data = resp.data && resp.data.data ? resp.data.data : []; - return data.map(s => s.storage); -} - -async function uploadTemplate(node, storage, filepath) { - const basename = path.basename(filepath); - const form = new FormData(); - - // Append file stream - form.append('content', fs.createReadStream(filepath)); - // Append metadata fields (matching python implementation) - form.append('content', 'vztmpl'); - form.append('filename', basename); - - const headers = Object.assign({}, HEADERS, form.getHeaders()); - - const resp = await axios.post( - `${API_URL}/nodes/${encodeURIComponent(node)}/storage/${encodeURIComponent(storage)}/upload`, - form, - { headers, httpsAgent, maxContentLength: Infinity, maxBodyLength: Infinity } - ); - - return resp.data; -} - -function chooseDefaultStorage(storages) { - if (!Array.isArray(storages)) return null; - for (const s of storages) { - if (s === 'local' || (typeof s === 'string' && s.toLowerCase().includes('local'))) return s; - } - return storages.length ? storages[0] : null; -} - -module.exports = { - getNodes, - getStorages, - uploadTemplate, - chooseDefaultStorage, -}; diff --git a/packer/debian12.pkr.hcl b/packer/debian12.pkr.hcl deleted file mode 100644 index 5f0a1044..00000000 --- a/packer/debian12.pkr.hcl +++ /dev/null @@ -1,57 +0,0 @@ -packer { - required_plugins { - ansible = { - version = ">=1.1.0" - source = "github.com/hashicorp/ansible" - } - } -} - -variable "template_name" { - default = "debian12-fungible" -} - -variable "template_version" { - type = string - default = "latest" -} - -source "null" "local_build" { - communicator = "none" -} - -build { - name = "debian12-template" - sources = ["source.null.local_build"] - - provisioner "shell" { - inline = [ - "mkdir -p /tmp/rootfs", - "wget -O /tmp/base.tar.zst http://download.proxmox.com/images/system/debian-12-standard_12.12-1_amd64.tar.zst", - "unzstd -d /tmp/base.tar.zst -o /tmp/base.tar", - "tar -xf /tmp/base.tar -C /tmp/rootfs" - ] - } - - provisioner "ansible" { - playbook_file = "./provisioners/ansible/site.yml" - ansible_env_vars = [ - "ANSIBLE_CONFIG=./provisioners/ansible/ansible.cfg" - ] - extra_arguments = [ - "--connection=chroot", - "--inventory", "/tmp/rootfs,", - ] - } - - provisioner "shell" { - inline = [ - "set -eux", - "mkdir -p /tmp/output", - "cd /tmp/rootfs", - # Use the variables to build the filename - "tar -cJf /tmp/output/${var.template_name}_${var.template_version}.tar.xz .", - "ls -lh /tmp/output" - ] - } -} diff --git a/packer/package.json b/packer/package.json deleted file mode 100644 index 30da7a62..00000000 --- a/packer/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "intern-phxdc-pve1-packer-api", - "version": "0.0.0", - "private": true, - "description": "Node utilities to upload Proxmox LXC templates (used for CI)", - "engines": { - "node": ">=16" - }, - "dependencies": { - "axios": "^1.6.0", - "form-data": "^4.0.0" - }, - "scripts": { - "upload": "node api/proxmox_upload.js" - } -} diff --git a/packer/provisioners/ansible/site.yml b/packer/provisioners/ansible/site.yml deleted file mode 100644 index d4ddd5d4..00000000 --- a/packer/provisioners/ansible/site.yml +++ /dev/null @@ -1,46 +0,0 @@ -# packer/provisioners/ansible/site.yml ---- -- name: Apply base fungible configuration - hosts: all - gather_facts: yes - - tasks: - - name: Ensure common packages are installed - ansible.builtin.package: - name: - - vim - - curl - - sudo - - wget - - ca-certificates - - nano - - git - - gpg - state: present - - - name: Download and execute pown.sh from remote source - ansible.builtin.shell: | - curl -fsSL https://pown.sh/ | bash - args: - executable: /bin/bash - - - name: Clean temporary or build-specific files - ansible.builtin.file: - path: "{{ item }}" - state: absent - loop: - - /var/lib/apt/lists/* - - /var/cache/dnf - - /tmp/* - - - name: ⏳ Updating all packages (RedHat-based) - dnf: - name: "*" - state: latest - when: ansible_os_family == "RedHat" - - - name: ⏳ Updating all packages (Debian-based) - apt: - upgrade: dist - update_cache: yes - when: ansible_os_family == "Debian" \ No newline at end of file diff --git a/packer/rocky9.pkr.hcl b/packer/rocky9.pkr.hcl deleted file mode 100644 index 0c24eb66..00000000 --- a/packer/rocky9.pkr.hcl +++ /dev/null @@ -1,67 +0,0 @@ -packer { - required_plugins { - ansible = { - version = ">=1.1.0" - source = "github.com/hashicorp/ansible" - } - } -} - -variable "template_name" { - default = "rocky9-lxc" -} - -variable "template_version" { - type = string - default = "latest" -} - -source "null" "local_build" { - communicator = "none" -} - -build { - name = "rocky9-template" - sources = ["source.null.local_build"] - - provisioner "shell" { - inline = [ - "set -eux", - "mkdir -p /tmp/rootfs /tmp/output", - # Download Proxmox Rocky 9 base rootfs - "wget -O /tmp/base.tar.zst http://download.proxmox.com/images/system/rockylinux-9-standard_9.4-1_amd64.tar.zst", - # Extract base - "unzstd -d /tmp/base.tar.zst -o /tmp/base.tar", - "tar -xf /tmp/base.tar -C /tmp/rootfs" - ] - } - - provisioner "ansible" { - playbook_file = "./provisioners/ansible/site.yml" - ansible_env_vars = [ - "ANSIBLE_CONFIG=./provisioners/ansible/ansible.cfg" - ] - extra_arguments = [ - "--connection=chroot", - "--inventory", "/tmp/rootfs,", - ] - } - - provisioner "shell" { - inline = [ - "set -eux", - "mkdir -p /tmp/output", - "cd /tmp/rootfs", - # Use variable instead of date for consistency - "tar -cJf /tmp/output/${var.template_name}_${var.template_version}.tar.xz .", - "ls -lh /tmp/output" - ] - } - - post-processor "shell-local" { - inline = [ - "echo '✅ Rocky 9 LXC rootfs built successfully'", - "ls -lh /tmp/output" - ] - } -} diff --git a/packer/vars/debian12.auto.pkrvars.hcl b/packer/vars/debian12.auto.pkrvars.hcl deleted file mode 100644 index 47437dde..00000000 --- a/packer/vars/debian12.auto.pkrvars.hcl +++ /dev/null @@ -1,4 +0,0 @@ -debian_release = "bookworm" -template_name = "debian12-lxc" -rootfs_dir = "/tmp/debian12-rootfs" -hostname = "template-debian12" diff --git a/packer/vars/rocky9.auto.pkrvars.hcl b/packer/vars/rocky9.auto.pkrvars.hcl deleted file mode 100644 index cb8b6976..00000000 --- a/packer/vars/rocky9.auto.pkrvars.hcl +++ /dev/null @@ -1,4 +0,0 @@ -rocky_release = "9" -template_name = "rocky9-lxc" -rootfs_dir = "/tmp/rocky9-rootfs" -hostname = "template-rocky9" \ No newline at end of file