From 8abb604654b5c479185d5b6499da42c1c694906a Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Fri, 10 Jan 2025 09:34:54 +0100 Subject: [PATCH] Armbian internals: deploy KVM instances --- .../modules/system/module_armbian_kvmtest.sh | 120 ++++++++++++ .../modules/system/module_armbian_runners.sh | 172 ------------------ 2 files changed, 120 insertions(+), 172 deletions(-) create mode 100644 tools/modules/system/module_armbian_kvmtest.sh delete mode 100644 tools/modules/system/module_armbian_runners.sh diff --git a/tools/modules/system/module_armbian_kvmtest.sh b/tools/modules/system/module_armbian_kvmtest.sh new file mode 100644 index 00000000..3c5e82ca --- /dev/null +++ b/tools/modules/system/module_armbian_kvmtest.sh @@ -0,0 +1,120 @@ +#declare -A module_options +module_options+=( + ["module_armbian_kvmtest,author"]="@igorpecovnik" + ["module_armbian_kvmtest,feature"]="module_armbian_kvmtest" + ["module_armbian_kvmtest,desc"]="Deploy Armbian KVM instances" + ["module_armbian_kvmtest,example"]="install remove help" + ["module_armbian_kvmtest,port"]="" + ["module_armbian_kvmtest,status"]="Active" + ["module_armbian_kvmtest,arch"]="" +) +# +# Module Armbian self hosted Github runners +# +function module_armbian_kvmtest () { + + local title="kvmtest" + local condition=$(which "$title" 2>/dev/null) + + # read parameters from command install + local parameter + IFS=' ' read -r -a parameter <<< "${1}" + for feature in instances stop; do + for selected in ${parameter[@]}; do + IFS='=' read -r -a split <<< "${selected}" + [[ ${split[0]} == $feature ]] && eval "$feature=${split[1]}" + done + done + + # default values if not defined + local instances="${instances:-01}" + local destination="${destination:-/var/lib/libvirt/images}" + local kvmprefix="${kvmprefix:-kvmtest}" + + # we can generate per org or per repo + local registration_url="${organisation}" + local prefix="orgs" + if [[ -n "${owner}" && -n "${repository}" ]]; then + registration_url="${owner}/${repository}" + prefix=repos + fi + + # we will mount qcow image + modprobe nbd max_part=8 + + local commands + IFS=' ' read -r -a commands <<< "${module_options["module_armbian_kvmtest,example"]}" + + case "${parameter[0]}" in + + "${commands[0]}") + # Install portainer with KVM support + # TBD + + # download images + tempfolder=$(mktemp -d) + qcowimages=( + "https://imola.armbian.com/dl/uefi-x86/archive/Armbian_24.11.1_Uefi-x86_noble_current_6.6.60_minimal.img.qcow2.xz" + "https://imola.armbian.com/dl/uefi-x86/archive/Armbian_24.11.1_Uefi-x86_bookworm_current_6.6.60_minimal.img.qcow2.xz" + ) + for qcowimage in ${qcowimages[@]}; do + curl --progress-bar -L $qcowimage | xz -d > ${tempfolder}/$(basename $qcowimage | sed "s/.xz//g") + done + + mounttempfolder=$(mktemp -d) + # Deploy several instances + for i in $(seq -w 01 $instances); do + for qcowimage in ${qcowimages[@]}; do + local image=$i-$(basename $qcowimage | sed "s/.xz//g" | cut -d"_" -f4,5) # get image name + cp ${tempfolder}/$(basename $qcowimage | sed "s/.xz//g") ${destination}/$i-$(basename $qcowimage | sed "s/.xz//g") # make a copy + qemu-img resize ${destination}/$i-$(basename $qcowimage | sed "s/.xz//g") +10G # expand + qemu-nbd --connect=/dev/nbd0 ${destination}/$i-$(basename $qcowimage | sed "s/.xz//g") # connect to qemu image + printf "fix\n" | sudo parted ---pretend-input-tty /dev/nbd0 print >/dev/null # fix resize + mount /dev/nbd0p3 ${mounttempfolder} # 3rd partition on uefi images is rootfs + cat ${mounttempfolder}/etc/os-release | grep ARMBIAN_PRETTY_NAME | cut -d"=" -f2 | sed 's/"//g' + # commands for changing follows here + umount /dev/nbd0p3 # unmount + qemu-nbd --disconnect /dev/nbd0 >/dev/null # disconnect from qemu image + # install and start VM + virt-install --name ${kvmprefix}-$image \ + --memory 2048 \ + --vcpus 4 \ + --disk ${destination}/$i-$(basename $qcowimage | sed "s/.xz//g"),bus=sata \ + --import --os-variant ubuntu24.04 \ + --network bridge=br1 \ + --noautoconsole + done + done + rm -rf ${tempfolder} ${mounttempfolder} + ;; + "${commands[1]}") + for i in {1..10}; do + for j in $(virsh list --all --name | grep ${kvmprefix}); do + virsh shutdown $j; + for snapshot in $(virsh snapshot-list $j | tail -n +3 | head -n -1 | cut -d' ' -f2); do virsh snapshot-delete $j $snapshot; done + done + if [[ -z "$(virsh list --name | grep ${kvmprefix})" ]]; then break; fi + sleep 2 + echo $i + done + if [[ $i -lt 10 ]]; then + for j in $(virsh list --all --name | grep ${kvmprefix}); do virsh undefine $j; done + fi + ;; + "${commands[6]}") + echo -e "\nUsage: ${module_options["module_armbian_kvmtest,feature"]} " + echo -e "Commands: ${module_options["module_armbian_kvmtest,example"]}" + echo "Available commands:" + echo -e "\tinstall\t- Install $title. Parameters:" + echo -e "\t\t gh_token runner_name start stop label_primary label_secondary organisation owner repository" + echo -e "\t\t organisation and owner + repository are mutually exclusive" + echo -e "\tremove\t- Remove $title." + echo -e "\tstatus\t- Installation status $title." + echo + ;; + *) + ${module_options["module_armbian_kvmtest,feature"]} ${commands[6]} + ;; + esac +} +#module_armbian_kvmtest $1 "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "$10" \ No newline at end of file diff --git a/tools/modules/system/module_armbian_runners.sh b/tools/modules/system/module_armbian_runners.sh deleted file mode 100644 index ccd952bc..00000000 --- a/tools/modules/system/module_armbian_runners.sh +++ /dev/null @@ -1,172 +0,0 @@ -#declare -A module_options -module_options+=( - ["module_armbian_runners,author"]="@igorpecovnik" - ["module_armbian_runners,feature"]="module_armbian_runners" - ["module_armbian_runners,desc"]="Manage self hosted runners" - ["module_armbian_runners,example"]="install remove remove_online help" - ["module_armbian_runners,port"]="" - ["module_armbian_runners,status"]="Active" - ["module_armbian_runners,arch"]="" -) -# -# Module Armbian self hosted Github runners -# -function module_armbian_runners () { - - local title="runners" - local condition=$(which "$title" 2>/dev/null) - - # read parameters from command install - local parameter - IFS=' ' read -r -a parameter <<< "${1}" - for feature in gh_token runner_name start stop label_primary label_secondary organisation owner repository; do - for selected in ${parameter[@]}; do - IFS='=' read -r -a split <<< "${selected}" - [[ ${split[0]} == $feature ]] && eval "$feature=${split[1]}" - done - done - - # default values if not defined - local gh_token="${gh_token}" - local runner_name="${runner_name:-armbian}" - local start="${start:-01}" - local stop="${stop:-01}" - local label_primary="${label_primary:-alfa}" - local label_secondary="${label_secondary:-fast,images}" - local organisation="${organisation:-armbian}" - local owner="${owner}" - local repository="${repository}" - - # we can generate per org or per repo - local registration_url="${organisation}" - local prefix="orgs" - if [[ -n "${owner}" && -n "${repository}" ]]; then - registration_url="${owner}/${repository}" - prefix=repos - fi - - local commands - IFS=' ' read -r -a commands <<< "${module_options["module_armbian_runners,example"]}" - - case "${parameter[0]}" in - - "${commands[0]}") - - if [[ -z $gh_token ]]; then - echo "Error: Github token is mandatory" - ${module_options["module_armbian_runners,feature"]} ${commands[6]} - exit 1 - fi - - # Docker preinstall is needed for our build framework - pkg_installed docker-ce || module_docker install - pkg_update - pkg_install jq curl - - # download latest runner package - local temp_dir=$(mktemp -d) - [[ "$ARCH" == "x86_64" ]] && local arch=x64 || local arch=arm64 - local LATEST=$(curl -sL https://api.github.com/repos/actions/runner/tags | jq -r '.[0].zipball_url' | rev | cut -d"/" -f1 | rev | sed "s/v//g") - curl --progress-bar --create-dir --output-dir ${temp_dir} -o \ - actions-runner-linux-${ARCH}-${LATEST}.tar.gz -L \ - https://github.com/actions/runner/releases/download/v${LATEST}/actions-runner-linux-${arch}-${LATEST}.tar.gz - - # make runners each under its own user - for i in $(seq -w $start $stop) - do - local token=$(curl -s \ - -X POST \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${gh_token}"\ - -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/${prefix}/${registration_url}/actions/runners/registration-token | jq -r .token) - - ${module_options["module_armbian_runners,feature"]} ${commands[1]} ${runner_name} - - adduser --quiet --disabled-password --shell /bin/bash \ - --home /home/actions-runner-${i} --gecos "actions-runner-${i}" actions-runner-${i} - - # add to sudoers - if ! sudo grep -q "actions-runner-${i}" /etc/sudoers; then - echo "actions-runner-${i} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers - fi - usermod -aG docker actions-runner-${i} - tar xzf ${temp_dir}/actions-runner-linux-${ARCH}-${LATEST}.tar.gz -C /home/actions-runner-${i} - chown -R actions-runner-${i}:actions-runner-${i} /home/actions-runner-${i} - - # 1st runner has different labels - local label=$label_secondary - if [[ "$i" == "${START}" ]]; then - local label=$label_primary - fi - - runuser -l actions-runner-${i} -c \ - "./config.sh --url https://github.com/${registration_url} \ - --token ${token} --labels ${label} --name ${runner_name}-${i} --unattended" - sh -c "cd /home/actions-runner-${i} ; \ - sudo ./svc.sh install actions-runner-${i} 2>/dev/null; \ - sudo ./svc.sh start actions-runner-${i} >/dev/null" - done - rm -rf ${temp_dir} - ;; - "${commands[1]}") - # delete if previous already exists - if id "actions-runner-${i}" >/dev/null 2>&1; then - echo "Removing runner ${i} on GitHub" - ${module_options["module_armbian_runners,feature"]} ${commands[2]} "$2-${i}" - echo "Removing runner ${i} locally" - runner_home=$(getent passwd "actions-runner-${i}" | cut -d: -f6) - sh -c "cd ${runner_home} ; sudo ./svc.sh stop actions-runner-${i} >/dev/null; sudo ./svc.sh uninstall actions-runner-${i} >/dev/null" - userdel -r -f actions-runner-${i} 2>/dev/null - groupdel actions-runner-${i} 2>/dev/null - sed -i "/^actions-runner-${i}.*/d" /etc/sudoers - rm -rf "${runner_home}" - fi - ;; - "${commands[2]}") - DELETE=$2 - x=1 - while [ $x -le 9 ] # need to do it different as it can be more then 9 pages - do - RUNNER=$( - curl -s -L \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${gh_token}" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/${prefix}/${registration_url}/actions/runners\?page\=${x} \ - | jq -r '.runners[] | .id, .name' | xargs -n2 -d'\n' | sed -e 's/ /,/g') - - while IFS= read -r DATA; do - RUNNER_ID=$(echo $DATA | cut -d"," -f1) - RUNNER_NAME=$(echo $DATA | cut -d"," -f2) - # deleting a runner - if [[ $RUNNER_NAME == ${DELETE} ]]; then - echo "Delete existing: $RUNNER_NAME" - curl -s -L \ - -X DELETE \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${gh_token}"\ - -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/${prefix}/${registration_url}/actions/runners/${RUNNER_ID} - fi - done <<< $RUNNER - x=$(( $x + 1 )) - done - ;; - "${commands[6]}") - echo -e "\nUsage: ${module_options["module_armbian_runners,feature"]} " - echo -e "Commands: ${module_options["module_armbian_runners,example"]}" - echo "Available commands:" - echo -e "\tinstall\t- Install $title. Parameters:" - echo -e "\t\t gh_token runner_name start stop label_primary label_secondary organisation owner repository" - echo -e "\t\t organisation and owner + repository are mutually exclusive" - echo -e "\tremove\t- Remove $title." - echo -e "\tstatus\t- Installation status $title." - echo - ;; - *) - ${module_options["module_armbian_runners,feature"]} ${commands[6]} - ;; - esac -} -#module_armbian_runners "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "$10" \ No newline at end of file