mirror of
https://github.com/community-scripts/ProxmoxVE
synced 2025-02-15 12:19:17 +00:00
Add Workflow to test Scripts (#2269)
This commit is contained in:
parent
1c89ef3f12
commit
bf5fc97e1a
139
.github/workflows/script-test.yml
vendored
Normal file
139
.github/workflows/script-test.yml
vendored
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
name: Run Scripts on PVE Node
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- 'install/*.sh'
|
||||||
|
- 'ct/*.sh'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run-install-script:
|
||||||
|
runs-on: pvenode
|
||||||
|
steps:
|
||||||
|
- name: Checkout PR branch
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.ref }}
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Add Git safe directory
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory /__w/ProxmoxVE/ProxmoxVE
|
||||||
|
|
||||||
|
- name: Set up GH_TOKEN
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Get changed files in PR
|
||||||
|
id: changed-files
|
||||||
|
run: |
|
||||||
|
CHANGED_FILES=$(gh pr diff --name-only ${{ github.event.pull_request.number }})
|
||||||
|
CHANGED_FILES=$(echo "$CHANGED_FILES" | tr '\n' ' ')
|
||||||
|
echo "Changed files: $CHANGED_FILES"
|
||||||
|
echo "SCRIPT=$CHANGED_FILES" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Get scripts
|
||||||
|
id: check-install-script
|
||||||
|
run: |
|
||||||
|
ALL_FILES=()
|
||||||
|
ADDED_FILES=()
|
||||||
|
for FILE in ${{ env.SCRIPT }}; do
|
||||||
|
if [[ $FILE =~ ^install/.*-install\.sh$ ]] || [[ $FILE =~ ^ct/.*\.sh$ ]]; then
|
||||||
|
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
|
||||||
|
if [[ ! " ${ADDED_FILES[@]} " =~ " $STRIPPED_NAME " ]]; then
|
||||||
|
ALL_FILES+=("$FILE")
|
||||||
|
ADDED_FILES+=("$STRIPPED_NAME") # Mark this base file as added (without the path)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
ALL_FILES=$(echo "${ALL_FILES[@]}" | xargs)
|
||||||
|
echo "$ALL_FILES"
|
||||||
|
echo "ALL_FILES=$ALL_FILES" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Run scripts
|
||||||
|
id: run-install
|
||||||
|
continue-on-error: true
|
||||||
|
run: |
|
||||||
|
set +e
|
||||||
|
#run for each files in /ct
|
||||||
|
for FILE in ${{ env.ALL_FILES }}; do
|
||||||
|
echo "Running: $FILE"
|
||||||
|
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
|
||||||
|
if [[ $FILE =~ ^install/.*-install\.sh$ ]]; then
|
||||||
|
CT_SCRIPT="ct/$STRIPPED_NAME.sh"
|
||||||
|
if [[ ! -f $CT_SCRIPT ]]; then
|
||||||
|
echo "No CT script found for $STRIPPED_NAME"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Found CT script for $STRIPPED_NAME"
|
||||||
|
chmod +x "$CT_SCRIPT"
|
||||||
|
RUNNING_FILE=$CT_SCRIPT
|
||||||
|
elif [[ $FILE =~ ^ct/.*\.sh$ ]]; then
|
||||||
|
INSTALL_SCRIPT="install/$STRIPPED_NAME-install.sh"
|
||||||
|
if [[ ! -f $INSTALL_SCRIPT ]]; then
|
||||||
|
echo "No install script found for $STRIPPED_NAME"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Found install script for $STRIPPED_NAME"
|
||||||
|
chmod +x "$INSTALL_SCRIPT"
|
||||||
|
RUNNING_FILE=$FILE
|
||||||
|
fi
|
||||||
|
git checkout origin/main .github/workflows/scripts/app-test/pr-build.func
|
||||||
|
git checkout origin/main .github/workflows/scripts/app-test/pr-install.func
|
||||||
|
git checkout origin/main .github/workflows/scripts/app-test/pr-alpine-install.func
|
||||||
|
git checkout origin/main .github/workflows/scripts/app-test/pr-create-lxc.sh
|
||||||
|
sed -i 's|source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)|source .github/workflows/scripts/app-test/pr-build.func|g' "$RUNNING_FILE"
|
||||||
|
chmod +x $RUNNING_FILE
|
||||||
|
chmod +x .github/workflows/scripts/app-test/pr-create-lxc.sh
|
||||||
|
chmod +x .github/workflows/scripts/app-test/pr-install.func
|
||||||
|
chmod +x .github/workflows/scripts/app-test/pr-alpine-install.func
|
||||||
|
chmod +x .github/workflows/scripts/app-test/pr-build.func
|
||||||
|
|
||||||
|
ERROR_MSG=$(./$RUNNING_FILE 2>&1 > /dev/null)
|
||||||
|
echo "Finished running $FILE"
|
||||||
|
if [ -n "$ERROR_MSG" ]; then
|
||||||
|
echo "ERROR in $STRIPPED_NAME: $ERROR_MSG"
|
||||||
|
echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
set -e # Restore exit-on-error
|
||||||
|
|
||||||
|
- name: Cleanup PVE Node
|
||||||
|
run: |
|
||||||
|
containers=$(pct list | tail -n +2 | awk '{print $0 " " $4}' | awk '{print $1}')
|
||||||
|
|
||||||
|
for container_id in $containers; do
|
||||||
|
status=$(pct status $container_id | awk '{print $2}')
|
||||||
|
if [[ $status == "running" ]]; then
|
||||||
|
pct stop $container_id
|
||||||
|
pct destroy $container_id
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Post error comments
|
||||||
|
run: |
|
||||||
|
ERROR="false"
|
||||||
|
SEARCH_LINE=".github/workflows/scripts/app-test/pr-build.func: line 113:"
|
||||||
|
for FILE in ${{ env.ALL_FILES }}; do
|
||||||
|
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
|
||||||
|
if [[ ! -f result_$STRIPPED_NAME.log ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
ERROR_MSG=$(cat result_$STRIPPED_NAME.log)
|
||||||
|
|
||||||
|
if [ -n "$ERROR_MSG" ]; then
|
||||||
|
CLEANED_ERROR_MSG=$(echo "$ERROR_MSG" | sed "s|$SEARCH_LINE.*||")
|
||||||
|
echo "Posting error message for $FILE"
|
||||||
|
echo ${CLEANED_ERROR_MSG}
|
||||||
|
gh pr comment ${{ github.event.pull_request.number }} \
|
||||||
|
--body ":warning: The script _**$FILE**_ failed with the following message: <br> <div><strong>${CLEANED_ERROR_MSG}</strong></div>"
|
||||||
|
|
||||||
|
ERROR="true"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "ERROR=$ERROR" >> $GITHUB_ENV
|
||||||
|
- name: Fail if error
|
||||||
|
if: ${{ env.ERROR }} == 'true'
|
||||||
|
run: exit 1
|
88
.github/workflows/scripts/app-test/pr-alpine-install.func
vendored
Normal file
88
.github/workflows/scripts/app-test/pr-alpine-install.func
vendored
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Copyright (c) 2021-2025 community-scripts ORG
|
||||||
|
# Author: michelroegl-brunner
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
|
||||||
|
color() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
catch_errors() {
|
||||||
|
set -Eeuo pipefail
|
||||||
|
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
error_handler() {
|
||||||
|
local line_number="$1"
|
||||||
|
local command="$2"
|
||||||
|
SCRIPT_NAME=$(basename "$0")
|
||||||
|
local error_message="$SCRIPT_NAME: Failure in line $line_number while executing command $command"
|
||||||
|
echo -e "\n$error_message"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
verb_ip6() {
|
||||||
|
STD=""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_info() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -ne "${msg}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_ok() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -e "${msg}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_error() {
|
||||||
|
|
||||||
|
local msg="$1"
|
||||||
|
echo -e "${msg}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
RETRY_NUM=10
|
||||||
|
RETRY_EVERY=3
|
||||||
|
i=$RETRY_NUM
|
||||||
|
|
||||||
|
setting_up_container() {
|
||||||
|
while [ $i -gt 0 ]; do
|
||||||
|
if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
echo 1>&2 -en "No Network! "
|
||||||
|
sleep $RETRY_EVERY
|
||||||
|
i=$((i - 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then
|
||||||
|
echo 1>&2 -e "\n No Network After $RETRY_NUM Tries"
|
||||||
|
echo -e "Check Network Settings"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
msg_ok "Set up Container OS"
|
||||||
|
msg_ok "Network Connected: $(hostname -i)"
|
||||||
|
}
|
||||||
|
|
||||||
|
network_check() {
|
||||||
|
RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')
|
||||||
|
if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi
|
||||||
|
set -e
|
||||||
|
}
|
||||||
|
|
||||||
|
update_os() {
|
||||||
|
msg_info "Updating Container OS"
|
||||||
|
apk update
|
||||||
|
apk upgrade
|
||||||
|
msg_ok "Updated Container OS"
|
||||||
|
}
|
||||||
|
|
||||||
|
motd_ssh() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
customize() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
259
.github/workflows/scripts/app-test/pr-build.func
vendored
Normal file
259
.github/workflows/scripts/app-test/pr-build.func
vendored
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Copyright (c) 2021-2025 community-scripts ORG
|
||||||
|
# Author: michelroegl-brunner
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
|
||||||
|
variables() {
|
||||||
|
NSAPP=$(echo ${APP,,} | tr -d ' ')
|
||||||
|
var_install="${NSAPP}-install"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NEXTID=$(pvesh get /cluster/nextid)
|
||||||
|
timezone=$(cat /etc/timezone)
|
||||||
|
header_info(){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
base_settings() {
|
||||||
|
|
||||||
|
CT_TYPE="1"
|
||||||
|
DISK_SIZE="4"
|
||||||
|
CORE_COUNT="1"
|
||||||
|
RAM_SIZE="1024"
|
||||||
|
VERBOSE="${1:-no}"
|
||||||
|
PW=""
|
||||||
|
CT_ID=$NEXTID
|
||||||
|
HN="Testing"
|
||||||
|
BRG="vmbr0"
|
||||||
|
NET="dhcp"
|
||||||
|
GATE=""
|
||||||
|
APT_CACHER=""
|
||||||
|
APT_CACHER_IP=""
|
||||||
|
DISABLEIP6="no"
|
||||||
|
MTU=""
|
||||||
|
SD=""
|
||||||
|
NS=""
|
||||||
|
MAC=""
|
||||||
|
VLAN=""
|
||||||
|
SSH="no"
|
||||||
|
SSH_AUTHORIZED_KEY=""
|
||||||
|
TAGS="community-script;"
|
||||||
|
|
||||||
|
|
||||||
|
CT_TYPE=${var_unprivileged:-$CT_TYPE}
|
||||||
|
DISK_SIZE=${var_disk:-$DISK_SIZE}
|
||||||
|
CORE_COUNT=${var_cpu:-$CORE_COUNT}
|
||||||
|
RAM_SIZE=${var_ram:-$RAM_SIZE}
|
||||||
|
VERB=${var_verbose:-$VERBOSE}
|
||||||
|
TAGS="${TAGS}${var_tags:-}"
|
||||||
|
|
||||||
|
if [ -z "$var_os" ]; then
|
||||||
|
var_os="debian"
|
||||||
|
fi
|
||||||
|
if [ -z "$var_version" ]; then
|
||||||
|
var_version="12"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
color() {
|
||||||
|
# Colors
|
||||||
|
YW=$(echo "\033[33m")
|
||||||
|
YWB=$(echo "\033[93m")
|
||||||
|
BL=$(echo "\033[36m")
|
||||||
|
RD=$(echo "\033[01;31m")
|
||||||
|
BGN=$(echo "\033[4;92m")
|
||||||
|
GN=$(echo "\033[1;92m")
|
||||||
|
DGN=$(echo "\033[32m")
|
||||||
|
|
||||||
|
# Formatting
|
||||||
|
CL=$(echo "\033[m")
|
||||||
|
UL=$(echo "\033[4m")
|
||||||
|
BOLD=$(echo "\033[1m")
|
||||||
|
BFR="\\r\\033[K"
|
||||||
|
HOLD=" "
|
||||||
|
TAB=" "
|
||||||
|
|
||||||
|
# Icons
|
||||||
|
CM="${TAB}✔️${TAB}${CL}"
|
||||||
|
CROSS="${TAB}✖️${TAB}${CL}"
|
||||||
|
INFO="${TAB}💡${TAB}${CL}"
|
||||||
|
OS="${TAB}🖥️${TAB}${CL}"
|
||||||
|
OSVERSION="${TAB}🌟${TAB}${CL}"
|
||||||
|
CONTAINERTYPE="${TAB}📦${TAB}${CL}"
|
||||||
|
DISKSIZE="${TAB}💾${TAB}${CL}"
|
||||||
|
CPUCORE="${TAB}🧠${TAB}${CL}"
|
||||||
|
RAMSIZE="${TAB}🛠️${TAB}${CL}"
|
||||||
|
SEARCH="${TAB}🔍${TAB}${CL}"
|
||||||
|
VERIFYPW="${TAB}🔐${TAB}${CL}"
|
||||||
|
CONTAINERID="${TAB}🆔${TAB}${CL}"
|
||||||
|
HOSTNAME="${TAB}🏠${TAB}${CL}"
|
||||||
|
BRIDGE="${TAB}🌉${TAB}${CL}"
|
||||||
|
NETWORK="${TAB}📡${TAB}${CL}"
|
||||||
|
GATEWAY="${TAB}🌐${TAB}${CL}"
|
||||||
|
DISABLEIPV6="${TAB}🚫${TAB}${CL}"
|
||||||
|
DEFAULT="${TAB}⚙️${TAB}${CL}"
|
||||||
|
MACADDRESS="${TAB}🔗${TAB}${CL}"
|
||||||
|
VLANTAG="${TAB}🏷️${TAB}${CL}"
|
||||||
|
ROOTSSH="${TAB}🔑${TAB}${CL}"
|
||||||
|
CREATING="${TAB}🚀${TAB}${CL}"
|
||||||
|
ADVANCED="${TAB}🧩${TAB}${CL}"
|
||||||
|
}
|
||||||
|
|
||||||
|
catch_errors() {
|
||||||
|
set -Eeuo pipefail
|
||||||
|
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function handles errors
|
||||||
|
error_handler() {
|
||||||
|
local line_number="$1"
|
||||||
|
local command="$2"
|
||||||
|
SCRIPT_NAME=$(basename "$0")
|
||||||
|
local error_message="$SCRIPT_NAME: Failure in line $line_number while executing command $command"
|
||||||
|
echo -e "\n$error_message"
|
||||||
|
exit "$error_message"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
msg_info() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -ne "${msg}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_ok() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -e "${msg}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_error() {
|
||||||
|
|
||||||
|
local msg="$1"
|
||||||
|
echo -e "${msg}\n"
|
||||||
|
}
|
||||||
|
start(){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
build_container() {
|
||||||
|
|
||||||
|
if [ "$CT_TYPE" == "1" ]; then
|
||||||
|
FEATURES="keyctl=1,nesting=1"
|
||||||
|
else
|
||||||
|
FEATURES="nesting=1"
|
||||||
|
fi
|
||||||
|
TEMP_DIR=$(mktemp -d)
|
||||||
|
pushd $TEMP_DIR >/dev/null
|
||||||
|
if [ "$var_os" == "alpine" ]; then
|
||||||
|
export FUNCTIONS_FILE_PATH="$(cat /root/actions-runner/_work/ProxmoxVE/ProxmoxVE/.github/workflows/scripts/app-test/pr-alpine-install.func)"
|
||||||
|
else
|
||||||
|
export FUNCTIONS_FILE_PATH="$(cat /root/actions-runner/_work/ProxmoxVE/ProxmoxVE/.github/workflows/scripts/app-test/pr-install.func)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export CACHER="$APT_CACHER"
|
||||||
|
export CACHER_IP="$APT_CACHER_IP"
|
||||||
|
export tz=""
|
||||||
|
export DISABLEIPV6="$DISABLEIP6"
|
||||||
|
export APPLICATION="$APP"
|
||||||
|
export app="$NSAPP"
|
||||||
|
export PASSWORD="$PW"
|
||||||
|
export VERBOSE="$VERB"
|
||||||
|
export SSH_ROOT="${SSH}"
|
||||||
|
export SSH_AUTHORIZED_KEY
|
||||||
|
export CTID="$CT_ID"
|
||||||
|
export CTTYPE="$CT_TYPE"
|
||||||
|
export PCT_OSTYPE="$var_os"
|
||||||
|
export PCT_OSVERSION="$var_version"
|
||||||
|
export PCT_DISK_SIZE="$DISK_SIZE"
|
||||||
|
export tz="$timezone"
|
||||||
|
export PCT_OPTIONS="
|
||||||
|
-features $FEATURES
|
||||||
|
-hostname $HN
|
||||||
|
-tags $TAGS
|
||||||
|
$SD
|
||||||
|
$NS
|
||||||
|
-net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU
|
||||||
|
-onboot 1
|
||||||
|
-cores $CORE_COUNT
|
||||||
|
-memory $RAM_SIZE
|
||||||
|
-unprivileged $CT_TYPE
|
||||||
|
$PW
|
||||||
|
"
|
||||||
|
echo "Container ID: $CTID"
|
||||||
|
|
||||||
|
|
||||||
|
# This executes create_lxc.sh and creates the container and .conf file
|
||||||
|
bash /root/actions-runner/_work/ProxmoxVE/ProxmoxVE/.github/workflows/scripts/app-test/pr-create-lxc.sh
|
||||||
|
|
||||||
|
LXC_CONFIG=/etc/pve/lxc/${CTID}.conf
|
||||||
|
if [ "$CT_TYPE" == "0" ]; then
|
||||||
|
cat <<EOF >>$LXC_CONFIG
|
||||||
|
# USB passthrough
|
||||||
|
lxc.cgroup2.devices.allow: a
|
||||||
|
lxc.cap.drop:
|
||||||
|
lxc.cgroup2.devices.allow: c 188:* rwm
|
||||||
|
lxc.cgroup2.devices.allow: c 189:* rwm
|
||||||
|
lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir
|
||||||
|
lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file
|
||||||
|
lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file
|
||||||
|
lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file
|
||||||
|
lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$CT_TYPE" == "0" ]; then
|
||||||
|
if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" ]]; then
|
||||||
|
cat <<EOF >>$LXC_CONFIG
|
||||||
|
# VAAPI hardware transcoding
|
||||||
|
lxc.cgroup2.devices.allow: c 226:0 rwm
|
||||||
|
lxc.cgroup2.devices.allow: c 226:128 rwm
|
||||||
|
lxc.cgroup2.devices.allow: c 29:0 rwm
|
||||||
|
lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file
|
||||||
|
lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir
|
||||||
|
lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" ]]; then
|
||||||
|
if [[ -e "/dev/dri/renderD128" ]]; then
|
||||||
|
if [[ -e "/dev/dri/card0" ]]; then
|
||||||
|
cat <<EOF >>$LXC_CONFIG
|
||||||
|
# VAAPI hardware transcoding
|
||||||
|
dev0: /dev/dri/card0,gid=44
|
||||||
|
dev1: /dev/dri/renderD128,gid=104
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
cat <<EOF >>$LXC_CONFIG
|
||||||
|
# VAAPI hardware transcoding
|
||||||
|
dev0: /dev/dri/card1,gid=44
|
||||||
|
dev1: /dev/dri/renderD128,gid=104
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This starts the container and executes <app>-install.sh
|
||||||
|
msg_info "Starting LXC Container"
|
||||||
|
pct start "$CTID"
|
||||||
|
msg_ok "Started LXC Container"
|
||||||
|
|
||||||
|
if [[ ! -f "/root/actions-runner/_work/ProxmoxVE/ProxmoxVE/install/$var_install.sh" ]]; then
|
||||||
|
msg_error "No install script found for $APP"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$var_os" == "alpine" ]; then
|
||||||
|
sleep 3
|
||||||
|
pct exec "$CTID" -- /bin/sh -c 'cat <<EOF >/etc/apk/repositories
|
||||||
|
http://dl-cdn.alpinelinux.org/alpine/latest-stable/main
|
||||||
|
http://dl-cdn.alpinelinux.org/alpine/latest-stable/community
|
||||||
|
EOF'
|
||||||
|
pct exec "$CTID" -- ash -c "apk add bash >/dev/null"
|
||||||
|
fi
|
||||||
|
lxc-attach -n "$CTID" -- bash -c "$(< /root/actions-runner/_work/ProxmoxVE/ProxmoxVE/install/$var_install.sh)"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
description(){
|
||||||
|
return
|
||||||
|
}
|
158
.github/workflows/scripts/app-test/pr-create-lxc.sh
vendored
Normal file
158
.github/workflows/scripts/app-test/pr-create-lxc.sh
vendored
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Copyright (c) 2021-2025 community-scripts ORG
|
||||||
|
# Author: michelroegl-brunner
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
|
||||||
|
color() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
catch_errors() {
|
||||||
|
set -Eeuo pipefail
|
||||||
|
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
error_handler() {
|
||||||
|
local exit_code="$?"
|
||||||
|
local line_number="$1"
|
||||||
|
local command="$2"
|
||||||
|
local error_message="Failure in line $line_number: exit code $exit_code: while executing command $command"
|
||||||
|
echo -e "\n$error_message"
|
||||||
|
exit 100
|
||||||
|
}
|
||||||
|
verb_ip6() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_info() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -ne "${msg}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_ok() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -e "${msg}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_error() {
|
||||||
|
|
||||||
|
local msg="$1"
|
||||||
|
echo -e "${msg}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VALIDCT=$(pvesm status -content rootdir | awk 'NR>1')
|
||||||
|
if [ -z "$VALIDCT" ]; then
|
||||||
|
msg_error "Unable to detect a valid Container Storage location."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
VALIDTMP=$(pvesm status -content vztmpl | awk 'NR>1')
|
||||||
|
if [ -z "$VALIDTMP" ]; then
|
||||||
|
msg_error "Unable to detect a valid Template Storage location."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
function select_storage() {
|
||||||
|
local CLASS=$1
|
||||||
|
local CONTENT
|
||||||
|
local CONTENT_LABEL
|
||||||
|
case $CLASS in
|
||||||
|
container)
|
||||||
|
CONTENT='rootdir'
|
||||||
|
CONTENT_LABEL='Container'
|
||||||
|
;;
|
||||||
|
template)
|
||||||
|
CONTENT='vztmpl'
|
||||||
|
CONTENT_LABEL='Container template'
|
||||||
|
;;
|
||||||
|
*) false || { msg_error "Invalid storage class."; exit 201; };;
|
||||||
|
esac
|
||||||
|
|
||||||
|
local -a MENU
|
||||||
|
while read -r line; do
|
||||||
|
local TAG=$(echo $line | awk '{print $1}')
|
||||||
|
local TYPE=$(echo $line | awk '{printf "%-10s", $2}')
|
||||||
|
local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
|
||||||
|
local ITEM="Type: $TYPE Free: $FREE "
|
||||||
|
local OFFSET=2
|
||||||
|
if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then
|
||||||
|
local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))
|
||||||
|
fi
|
||||||
|
MENU+=("$TAG" "$ITEM" "OFF")
|
||||||
|
done < <(pvesm status -content $CONTENT | awk 'NR>1')
|
||||||
|
|
||||||
|
if [ $((${#MENU[@]}/3)) -eq 1 ]; then
|
||||||
|
printf ${MENU[0]}
|
||||||
|
else
|
||||||
|
msg_error "STORAGE ISSUES!"
|
||||||
|
exit 202
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[ "${CTID:-}" ]] || { msg_error "You need to set 'CTID' variable."; exit 203; }
|
||||||
|
[[ "${PCT_OSTYPE:-}" ]] || { msg_error "You need to set 'PCT_OSTYPE' variable."; exit 204; }
|
||||||
|
|
||||||
|
[ "$CTID" -ge "100" ] || { msg_error "ID cannot be less than 100."; exit 205; }
|
||||||
|
|
||||||
|
if pct status $CTID &>/dev/null; then
|
||||||
|
echo -e "ID '$CTID' is already in use."
|
||||||
|
unset CTID
|
||||||
|
msg_error "Cannot use ID that is already in use."
|
||||||
|
exit 206
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
TEMPLATE_STORAGE=$(select_storage template) || exit
|
||||||
|
msg_ok "Using $TEMPLATE_STORAGE for Template Storage."
|
||||||
|
|
||||||
|
|
||||||
|
CONTAINER_STORAGE=$(select_storage container) || exit
|
||||||
|
msg_ok "Using $CONTAINER_STORAGE for Container Storage."
|
||||||
|
|
||||||
|
msg_info "Updating LXC Template List"
|
||||||
|
pveam update >/dev/null
|
||||||
|
msg_ok "Updated LXC Template List"
|
||||||
|
|
||||||
|
TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-}
|
||||||
|
mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V)
|
||||||
|
[ ${#TEMPLATES[@]} -gt 0 ] || { msg_error "Unable to find a template when searching for '$TEMPLATE_SEARCH'."; exit 207; }
|
||||||
|
TEMPLATE="${TEMPLATES[-1]}"
|
||||||
|
|
||||||
|
TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
|
||||||
|
|
||||||
|
if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then
|
||||||
|
[[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
|
||||||
|
msg_info "Downloading LXC Template"
|
||||||
|
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null ||
|
||||||
|
{ msg_error "A problem occurred while downloading the LXC template."; exit 208; }
|
||||||
|
msg_ok "Downloaded LXC Template"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >> /etc/subuid
|
||||||
|
grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >> /etc/subgid
|
||||||
|
|
||||||
|
|
||||||
|
PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
|
||||||
|
[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
|
||||||
|
|
||||||
|
echo "${PCT_OPTIONS[@]}"
|
||||||
|
|
||||||
|
|
||||||
|
msg_info "Creating LXC Container"
|
||||||
|
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
|
||||||
|
[[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
|
||||||
|
|
||||||
|
msg_ok "Template integrity check completed"
|
||||||
|
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null ||
|
||||||
|
{ msg_error "A problem occurred while re-downloading the LXC template."; exit 208; }
|
||||||
|
|
||||||
|
msg_ok "Re-downloaded LXC Template"
|
||||||
|
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
|
||||||
|
msg_error "A problem occurred while trying to create container after re-downloading template."
|
||||||
|
exit 200
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
msg_ok "LXC Container $CTID was successfully created."
|
93
.github/workflows/scripts/app-test/pr-install.func
vendored
Normal file
93
.github/workflows/scripts/app-test/pr-install.func
vendored
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Copyright (c) 2021-2025 community-scripts ORG
|
||||||
|
# Author: michelroegl-brunner
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
|
||||||
|
color() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
catch_errors() {
|
||||||
|
set -Eeuo pipefail
|
||||||
|
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||||
|
}
|
||||||
|
|
||||||
|
error_handler() {
|
||||||
|
local line_number="$1"
|
||||||
|
local command="$2"
|
||||||
|
SCRIPT_NAME=$(basename "$0")
|
||||||
|
local error_message="$SCRIPT_NAME: Failure in line $line_number while executing command $command"
|
||||||
|
echo -e "\n$error_message"
|
||||||
|
exit "$error_message"
|
||||||
|
}
|
||||||
|
verb_ip6() {
|
||||||
|
STD=""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_info() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -ne "${msg}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_ok() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -e "${msg}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_error() {
|
||||||
|
|
||||||
|
local msg="$1"
|
||||||
|
echo -e "${msg}\n"
|
||||||
|
}
|
||||||
|
RETRY_NUM=10
|
||||||
|
RETRY_EVERY=3
|
||||||
|
setting_up_container() {
|
||||||
|
sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen
|
||||||
|
locale_line=$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print $1}' | head -n 1)
|
||||||
|
echo "LANG=${locale_line}" >/etc/default/locale
|
||||||
|
locale-gen >/dev/null
|
||||||
|
export LANG=${locale_line}
|
||||||
|
echo $tz >/etc/timezone
|
||||||
|
ln -sf /usr/share/zoneinfo/$tz /etc/localtime
|
||||||
|
|
||||||
|
for ((i = RETRY_NUM; i > 0; i--)); do
|
||||||
|
if [ "$(hostname -I)" != "" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
echo 1>&2 -en "No Network! "
|
||||||
|
sleep $RETRY_EVERY
|
||||||
|
done
|
||||||
|
if [ "$(hostname -I)" = "" ]; then
|
||||||
|
echo 1>&2 -e "\nNo Network After $RETRY_NUM Tries"
|
||||||
|
echo -e "Check Network Settings"
|
||||||
|
exit 101
|
||||||
|
fi
|
||||||
|
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
|
||||||
|
systemctl disable -q --now systemd-networkd-wait-online.service
|
||||||
|
msg_ok "Set up Container OS"
|
||||||
|
msg_ok "Network Connected: $(hostname -I)"
|
||||||
|
}
|
||||||
|
|
||||||
|
network_check() {
|
||||||
|
RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')
|
||||||
|
if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi
|
||||||
|
set -e
|
||||||
|
}
|
||||||
|
|
||||||
|
update_os() {
|
||||||
|
msg_info "Updating Container OS"
|
||||||
|
apt-get update
|
||||||
|
apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade
|
||||||
|
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
|
||||||
|
msg_ok "Updated Container OS"
|
||||||
|
}
|
||||||
|
|
||||||
|
motd_ssh() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
customize() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user