Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/verify-split-files.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ on:
- "tests/vm-dialog-esc.sh"
- "tests/cs-clear.sh"
- "tests/forge-appversion-scope.sh"
- "tests/motd-os-version.sh"
- ".github/workflows/verify-split-files.yml"
push:
branches: [main]
Expand Down Expand Up @@ -105,6 +106,7 @@ on:
- "tests/vm-dialog-esc.sh"
- "tests/cs-clear.sh"
- "tests/forge-appversion-scope.sh"
- "tests/motd-os-version.sh"
- ".github/workflows/verify-split-files.yml"
workflow_dispatch:

Expand Down Expand Up @@ -211,6 +213,8 @@ jobs:
run: bash tests/silent-verbose.sh
- name: VM dialog Esc tests
run: bash tests/vm-dialog-esc.sh
- name: MOTD OS version tests
run: bash tests/motd-os-version.sh
- name: GitHub release without the API tests
run: bash tests/github-release-noapi.sh
- name: Screen clear without a terminal tests
Expand Down
1 change: 1 addition & 0 deletions core/error_handler.func
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,7 @@ on_exit() {
if [[ $exit_code -eq 0 && "${_CS_UPDATE_CLEANUP:-}" == "1" ]] && declare -f cleanup_lxc >/dev/null 2>&1; then
_CS_UPDATE_CLEANUP=0
cleanup_lxc || true
declare -f update_motd_ip >/dev/null 2>&1 && { update_motd_ip || true; }
fi

# fetch_and_deploy_release leaves a pending marker next to the stamp; only a
Expand Down
17 changes: 3 additions & 14 deletions lxc/install.func
Original file line number Diff line number Diff line change
Expand Up @@ -1503,16 +1503,8 @@ fi
EOF
fi

# Get OS information
local os_name="$OS_TYPE"
local os_version="$OS_VERSION"

if [[ -f /etc/os-release ]]; then
os_name=$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"' || true)
os_version=$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"' || true)
[[ -z "$os_name" ]] && os_name="$OS_TYPE"
[[ -z "$os_version" ]] && os_version="${OS_VERSION:-rolling}"
fi
# No & or \: update_motd_ip puts this into a sed replacement.
local os_line='$(if [ -r /etc/os-release ]; then . /etc/os-release; fi; echo "${NAME:-Linux} - Version: ${VERSION_ID:-rolling}")'

# Create MOTD profile script. The testing block is conditional -- printed
# unconditionally it told every Incus container it was a DevScripts build.
Expand Down Expand Up @@ -1544,7 +1536,7 @@ EOF
cat >>"$PROFILE_FILE" <<EOF
echo -e "${GATEWAY:-}${YW:-}Provided by: ${GN:-}community-scripts ORG ${YW:-}| GitHub: ${GN:-}https://github.com/community-scripts/ProxmoxVE${CL:-}"
echo ""
echo -e "${OS:-}${YW:-}OS: ${GN:-}${os_name} - Version: ${os_version}${CL:-}"
echo -e "${OS:-}${YW:-}OS: ${GN:-}${os_line}${CL:-}"
echo -e "${HOSTNAME:-}${YW:-}Hostname: ${GN:-}\$(uname -n)${CL:-}"
echo -e "${INFO:-}${YW:-}IP Address: ${GN:-}\$(ip -4 route get 1 2>/dev/null | sed -n 's/.* src \\([0-9.]\\+\\).*/\\1/p' | head -1)${CL:-}"
EOF
Expand Down Expand Up @@ -1576,7 +1568,6 @@ EOF

${APPLICATION:-Container} LXC Container - TESTING BUILD
This script is still being tested. Without feedback it cannot be finished.
OS: ${os_name} - Version: ${os_version}

Report back: ${CS_TESTING_URL}
Works, broken, or anything odd - one line is enough.
Expand All @@ -1587,15 +1578,13 @@ EOF

${APPLICATION:-Container} LXC Container - DEV Repository
WARNING: This is a DEVELOPMENT version (DevScripts). Do NOT use in production!
OS: ${os_name} - Version: ${os_version}
Repository: https://github.com/community-scripts/DevScripts

EOF
else
cat >/etc/motd <<EOF

${APPLICATION:-Container} LXC Container
OS: ${os_name} - Version: ${os_version}

EOF
fi
Expand Down
78 changes: 78 additions & 0 deletions tests/motd-os-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env bash
set -uo pipefail

CORE_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
T="$(mktemp -d)"
trap 'rm -rf -- "$T"' EXIT
mkdir -p "$T/etc/profile.d" "$T/root"
relocate() { sed "s|/etc/|$T/etc/|g; s|/root/|$T/root/|g"; }
eval "$(awk '/^motd_ssh\(\) \{/,/^}/' "$CORE_DIR/lxc/install.func" | relocate)"
eval "$(awk '/^update_motd_ip\(\) \{/,/^}/' "$CORE_DIR/ui/validate.func" | relocate)"
eval "$(awk '/^on_exit\(\) \{/,/^}/' "$CORE_DIR/core/error_handler.func")"

PROFILE="$T/etc/profile.d/00_lxc-details.sh"
passed=0 failed=0

check() {
if [[ "$3" == *"$2"* ]]; then
echo "PASS $1"
passed=$((passed + 1))
else
echo "FAIL $1: expected <$2> in <$3>" >&2
failed=$((failed + 1))
fi
}

os_release() { printf 'NAME="%s"\n%s' "$1" "${2:+VERSION_ID=\"$2\"$'\n'}" >"$T/etc/os-release"; }
get_current_ip() { echo 192.0.2.10; }
post_progress_to_api() { :; }
_is_container_context() { return 0; }
# shellcheck disable=SC2034
TAB="" NETWORK="" YW="" GN="" CL="" OS="" HOSTNAME="" INFO="" GATEWAY="" BOLD="" RD="" OS_TYPE=debian OS_VERSION=12

shells=()
for sh in bash dash "busybox sh"; do
command -v "${sh%% *}" >/dev/null 2>&1 && $sh -c : 2>/dev/null && shells+=("$sh")
done

os_release "Debian GNU/Linux" 12
APPLICATION=Test motd_ssh
os_release "Debian GNU/Linux" 13
for sh in "${shells[@]}"; do
check "$sh: login shows the upgraded release" "OS: Debian GNU/Linux - Version: 13" "$($sh -c ". '$PROFILE'" 2>&1)"
check "$sh: NAME stays out of the login shell" "unset" "$($sh -c ". '$PROFILE' >/dev/null 2>&1; echo \${NAME-unset}")"
done

os_release "Arch Linux"
check "no VERSION_ID reads as rolling" "Arch Linux - Version: rolling" "$(bash -c ". '$PROFILE'")"
rm -f "$T/etc/os-release"
check "no os-release still prints a line" "OS: Linux - Version: rolling" "$(bash -c ". '$PROFILE'")"
check "/etc/motd carries no version" "none" "$(grep -q 'Version' "$T/etc/motd" && echo found || echo none)"

esc=$'\033'
cat >"$PROFILE" <<EOF
echo -e "${esc}[1mTest LXC Container${esc}[m"
echo -e " community-scripts"
echo -e " ${esc}[33m OS: ${esc}[1;92mDebian GNU/Linux - Version: 12${esc}[m"
echo -e " ${esc}[33m IP Address: ${esc}[1;92m\$(echo 192.0.2.10)${esc}[m"
EOF
printf '\nTest LXC Container\n OS: Debian GNU/Linux - Version: 12\n\n' >"$T/etc/motd"
os_release "Debian GNU/Linux" 13
update_motd_ip >/dev/null 2>&1
check "update turns a fixed OS line into one read at login" "Debian GNU/Linux - Version: 13" "$(bash -c ". '$PROFILE'")"
check "update drops the fixed OS line from /etc/motd" "none" "$(grep -q 'Version' "$T/etc/motd" && echo found || echo none)"
cp "$PROFILE" "$T/before"
update_motd_ip >/dev/null 2>&1
check "a second update leaves the OS line alone" "same" "$(cmp -s "$PROFILE" "$T/before" && echo same || echo changed)"

result=$(
cleanup_lxc() { :; }
update_motd_ip() { echo motd; }
_CS_UPDATE_CLEANUP=1
trap on_exit EXIT
exit 0
)
check "an update that exits inside update_script still refreshes the MOTD" "motd" "$result"

printf '%s passed, %s failed (shells: %s)\n' "$passed" "$failed" "${shells[*]}"
((failed == 0))
5 changes: 2 additions & 3 deletions ui/menu.func
Original file line number Diff line number Diff line change
Expand Up @@ -1126,8 +1126,8 @@ check_breaking_change_guard() {

# The update path, shared by the three branches of start() that reach it.
# exit, not return: returning continues into the ct script's host-only tail.
# Most ct scripts exit inside update_script, so the two calls after it are
# unreachable for them; the cleanup therefore runs from on_exit.
# Most ct scripts exit inside update_script, so the call after it is
# unreachable for them; cleanup and MOTD therefore run from on_exit.
_cs_run_update() {
ensure_profile_loaded
ensure_recorded_toolchains
Expand All @@ -1140,7 +1140,6 @@ _cs_run_update() {
_CS_UPDATE_CLEANUP=1
update_script
run_addon_updates
update_motd_ip
exit 0
}

Expand Down
11 changes: 5 additions & 6 deletions ui/validate.func
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ update_motd_ip() {
# always checked whose file it is; this one never did.
if [ -f "$MOTD_FILE" ] && grep -q "LXC Container" "$MOTD_FILE" 2>/dev/null; then
# Remove existing IP Address lines to prevent duplication
sed -i '/IP Address:/d' "$MOTD_FILE"
sed -i '/IP Address:/d; / OS: .* - Version: /d' "$MOTD_FILE"

IP=$(get_current_ip)
# Add the new IP address
Expand Down Expand Up @@ -104,7 +104,7 @@ update_motd_ip() {
fi

# Get current values
local current_os="$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"') - Version: $(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"')"
local os_line='$(if [ -r /etc/os-release ]; then . /etc/os-release; fi; echo "${NAME:-Linux} - Version: ${VERSION_ID:-rolling}")'
local current_hostname="$(hostname 2>/dev/null || uname -n)"
# get_current_ip, not `hostname -I`: BusyBox's hostname has no -I, so on
# Alpine this aborted the update with "unrecognized option: I". The helper
Expand All @@ -114,15 +114,14 @@ update_motd_ip() {
# $GN/$CL are unset in a login shell, so a line using them never colors.
# The staleness checks below only compare the value text, so a line with a
# current value but a dead placeholder is never revisited; force it here.
local esc dead_color_os dead_color_hostname dead_color_ip
local esc dead_color_hostname dead_color_ip
esc=$'\033'
grep -qE 'OS:.*\$\{GN\}' "$profile_file" 2>/dev/null && dead_color_os=1
grep -qE 'Hostname:.*\$\{GN\}' "$profile_file" 2>/dev/null && dead_color_hostname=1
grep -qE 'IP Address:.*\$\{GN\}' "$profile_file" 2>/dev/null && dead_color_ip=1

# Update only if values actually changed (or the color placeholder is dead)
if [[ -n "${dead_color_os:-}" ]] || ! grep -q "OS:.*$current_os" "$profile_file" 2>/dev/null; then
sed -i "s|OS:.*|OS: ${esc}[1;92m$current_os${esc}[m\\\"|" "$profile_file"
if ! grep -q 'OS:.*os-release' "$profile_file" 2>/dev/null; then
sed -i "s|OS:.*|OS: ${esc}[1;92m${os_line}${esc}[m\\\"|" "$profile_file"
fi
if [[ -n "${dead_color_hostname:-}" ]] || ! grep -q "Hostname:.*$current_hostname" "$profile_file" 2>/dev/null; then
sed -i "s|Hostname:.*|Hostname: ${esc}[1;92m$current_hostname${esc}[m\\\"|" "$profile_file"
Expand Down
Loading