mirror of
https://gitlab.com/hacklab01/pivilion.git
synced 2026-08-06 16:08:22 +00:00
Fix early-boot hostname application
This commit is contained in:
parent
b5e19f08f6
commit
0f20889948
5 changed files with 130 additions and 4 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
INSTALL_VERSION=4
|
INSTALL_VERSION=5
|
||||||
ACTION=install
|
ACTION=install
|
||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
'') ;;
|
'') ;;
|
||||||
|
|
@ -174,7 +174,7 @@ deploy_files() {
|
||||||
local php_version
|
local php_version
|
||||||
log "Deploying Pivilion files"
|
log "Deploying Pivilion files"
|
||||||
install -d -m 0755 /usr/local/lib/pivilion /usr/local/bin /etc/systemd/system /etc/tor/torrc.d /etc/profile.d /var/lib/pivilion
|
install -d -m 0755 /usr/local/lib/pivilion /usr/local/bin /etc/systemd/system /etc/tor/torrc.d /etc/profile.d /var/lib/pivilion
|
||||||
install -m 0644 "$SOURCE_DIR/usr/local/lib/pivilion/common.sh" /usr/local/lib/pivilion/common.sh
|
install -m 0644 "$SOURCE_DIR/usr/local/lib/pivilion/common.sh" "$SOURCE_DIR/usr/local/lib/pivilion/hostname.sh" /usr/local/lib/pivilion/
|
||||||
install -m 0755 "$SOURCE_DIR/usr/local/lib/pivilion/mode.sh" "$SOURCE_DIR/usr/local/lib/pivilion/config-sync.sh" "$SOURCE_DIR/usr/local/lib/pivilion/diagnose.sh" \
|
install -m 0755 "$SOURCE_DIR/usr/local/lib/pivilion/mode.sh" "$SOURCE_DIR/usr/local/lib/pivilion/config-sync.sh" "$SOURCE_DIR/usr/local/lib/pivilion/diagnose.sh" \
|
||||||
"$SOURCE_DIR/usr/local/lib/pivilion/issue-banner.sh" /usr/local/lib/pivilion/
|
"$SOURCE_DIR/usr/local/lib/pivilion/issue-banner.sh" /usr/local/lib/pivilion/
|
||||||
install -m 0755 "$SOURCE_DIR"/usr/local/bin/* /usr/local/bin/
|
install -m 0755 "$SOURCE_DIR"/usr/local/bin/* /usr/local/bin/
|
||||||
|
|
@ -319,7 +319,7 @@ check_install() {
|
||||||
local failed=0 file
|
local failed=0 file
|
||||||
for file in /etc/pivilion.defaults /var/lib/pivilion/install-state /etc/issue.d/90-pivilion.issue \
|
for file in /etc/pivilion.defaults /var/lib/pivilion/install-state /etc/issue.d/90-pivilion.issue \
|
||||||
/usr/local/lib/pivilion/common.sh /usr/local/lib/pivilion/mode.sh /usr/local/lib/pivilion/diagnose.sh \
|
/usr/local/lib/pivilion/common.sh /usr/local/lib/pivilion/mode.sh /usr/local/lib/pivilion/diagnose.sh \
|
||||||
/usr/local/lib/pivilion/config-sync.sh \
|
/usr/local/lib/pivilion/config-sync.sh /usr/local/lib/pivilion/hostname.sh \
|
||||||
/usr/local/lib/pivilion/issue-banner.sh /etc/systemd/system/pivilion-mode.service \
|
/usr/local/lib/pivilion/issue-banner.sh /etc/systemd/system/pivilion-mode.service \
|
||||||
/etc/systemd/system/pivilion-config.service /etc/systemd/system/pivilion-login-banner.service; do
|
/etc/systemd/system/pivilion-config.service /etc/systemd/system/pivilion-login-banner.service; do
|
||||||
if [ ! -e "$file" ]; then echo "Missing: $file" >&2; failed=1; fi
|
if [ ! -e "$file" ]; then echo "Missing: $file" >&2; failed=1; fi
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,8 @@ boot_config_contract() {
|
||||||
grep -q 'pivilion_boot_config_path' "$ROOT/usr/local/lib/pivilion/config-sync.sh" &&
|
grep -q 'pivilion_boot_config_path' "$ROOT/usr/local/lib/pivilion/config-sync.sh" &&
|
||||||
grep -q 'pivilion.conf.last-good' "$ROOT/usr/local/lib/pivilion/config-sync.sh" &&
|
grep -q 'pivilion.conf.last-good' "$ROOT/usr/local/lib/pivilion/config-sync.sh" &&
|
||||||
grep -q 'derive_psk' "$ROOT/usr/local/lib/pivilion/config-sync.sh" &&
|
grep -q 'derive_psk' "$ROOT/usr/local/lib/pivilion/config-sync.sh" &&
|
||||||
|
grep -q 'pivilion_apply_hostname' "$ROOT/usr/local/lib/pivilion/config-sync.sh" &&
|
||||||
|
! grep -R -q --include='*.sh' --include='*.service' 'hostnamectl' "$ROOT/install.sh" "$ROOT/usr" "$ROOT/etc" &&
|
||||||
grep -q 'Before=.*NetworkManager' "$ROOT/etc/systemd/system/pivilion-config.service" &&
|
grep -q 'Before=.*NetworkManager' "$ROOT/etc/systemd/system/pivilion-config.service" &&
|
||||||
grep -q 'config-sync.sh set PIVILION_MODE' "$ROOT/usr/local/bin/hotspot" &&
|
grep -q 'config-sync.sh set PIVILION_MODE' "$ROOT/usr/local/bin/hotspot" &&
|
||||||
grep -q 'config-sync.sh set-wifi' "$ROOT/usr/local/bin/pikey"
|
grep -q 'config-sync.sh set-wifi' "$ROOT/usr/local/bin/pikey"
|
||||||
|
|
@ -83,6 +85,7 @@ shellcheck_scripts() {
|
||||||
}
|
}
|
||||||
|
|
||||||
run "configuration and state fixtures" "$ROOT/tests/test-common.sh"
|
run "configuration and state fixtures" "$ROOT/tests/test-common.sh"
|
||||||
|
run "early-boot hostname application" "$ROOT/tests/test-hostname.sh"
|
||||||
run "shell syntax" shell_syntax
|
run "shell syntax" shell_syntax
|
||||||
run "PHP syntax" php_syntax
|
run "PHP syntax" php_syntax
|
||||||
run "systemd unit syntax" systemd_syntax
|
run "systemd unit syntax" systemd_syntax
|
||||||
|
|
|
||||||
55
tests/test-hostname.sh
Executable file
55
tests/test-hostname.sh
Executable file
|
|
@ -0,0 +1,55 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
||||||
|
TMP=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$TMP"' EXIT
|
||||||
|
|
||||||
|
export PIVILION_HOSTNAME_FILE="$TMP/hostname"
|
||||||
|
export PIVILION_HOSTS_FILE="$TMP/hosts"
|
||||||
|
export PIVILION_HOSTNAME_COMMAND="$TMP/hostname-command"
|
||||||
|
export MOCK_HOSTNAME_STATE="$TMP/kernel-hostname"
|
||||||
|
export MOCK_HOSTNAME_CALLS="$TMP/hostname-calls"
|
||||||
|
|
||||||
|
cat > "$PIVILION_HOSTS_FILE" <<'EOF'
|
||||||
|
127.0.0.1 localhost
|
||||||
|
127.0.1.1 old-name old-alias
|
||||||
|
192.0.2.1 example.test
|
||||||
|
127.0.1.1 stale-duplicate
|
||||||
|
EOF
|
||||||
|
printf 'old-name\n' > "$PIVILION_HOSTNAME_FILE"
|
||||||
|
printf 'old-name\n' > "$MOCK_HOSTNAME_STATE"
|
||||||
|
|
||||||
|
cat > "$PIVILION_HOSTNAME_COMMAND" <<'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
if [ "${1:-}" = -s ]; then cat "$MOCK_HOSTNAME_STATE"; exit 0; fi
|
||||||
|
printf '%s\n' "$1" > "$MOCK_HOSTNAME_STATE"
|
||||||
|
printf '%s\n' "$1" >> "$MOCK_HOSTNAME_CALLS"
|
||||||
|
EOF
|
||||||
|
chmod +x "$PIVILION_HOSTNAME_COMMAND"
|
||||||
|
|
||||||
|
source "$ROOT/usr/local/lib/pivilion/hostname.sh"
|
||||||
|
|
||||||
|
for mode in hotspot onion; do
|
||||||
|
name="pivilion-$mode"
|
||||||
|
pivilion_apply_hostname "$name"
|
||||||
|
[ "$(cat "$PIVILION_HOSTNAME_FILE")" = "$name" ]
|
||||||
|
[ "$(awk '$1 == "127.0.1.1" { print $2 }' "$PIVILION_HOSTS_FILE")" = "$name" ]
|
||||||
|
[ "$(awk '$1 == "127.0.1.1" { count++ } END { print count+0 }' "$PIVILION_HOSTS_FILE")" -eq 1 ]
|
||||||
|
[ "$("$PIVILION_HOSTNAME_COMMAND" -s)" = "$name" ]
|
||||||
|
|
||||||
|
before=$(sha256sum "$PIVILION_HOSTNAME_FILE" "$PIVILION_HOSTS_FILE")
|
||||||
|
inodes=$(stat -c '%i' "$PIVILION_HOSTNAME_FILE" "$PIVILION_HOSTS_FILE")
|
||||||
|
calls=$(wc -l < "$MOCK_HOSTNAME_CALLS")
|
||||||
|
pivilion_apply_hostname "$name"
|
||||||
|
[ "$before" = "$(sha256sum "$PIVILION_HOSTNAME_FILE" "$PIVILION_HOSTS_FILE")" ]
|
||||||
|
[ "$inodes" = "$(stat -c '%i' "$PIVILION_HOSTNAME_FILE" "$PIVILION_HOSTS_FILE")" ]
|
||||||
|
[ "$calls" -eq "$(wc -l < "$MOCK_HOSTNAME_CALLS")" ]
|
||||||
|
done
|
||||||
|
|
||||||
|
grep -Fqx '192.0.2.1 example.test' "$PIVILION_HOSTS_FILE"
|
||||||
|
|
||||||
|
PIVILION_HOSTNAME_FILE="$TMP/missing/hostname"
|
||||||
|
export PIVILION_HOSTNAME_FILE
|
||||||
|
if pivilion_apply_hostname broken >"$TMP/failure.out" 2>&1; then exit 1; fi
|
||||||
|
grep -q 'Could not create a temporary file' "$TMP/failure.out"
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
source "${PIVILION_COMMON_PATH:-/usr/local/lib/pivilion/common.sh}"
|
source "${PIVILION_COMMON_PATH:-/usr/local/lib/pivilion/common.sh}"
|
||||||
|
source "${PIVILION_HOSTNAME_LIB_PATH:-$(dirname -- "${BASH_SOURCE[0]}")/hostname.sh}"
|
||||||
pivilion_require_root
|
pivilion_require_root
|
||||||
|
|
||||||
BOOT_ROOT=$(pivilion_boot_root)
|
BOOT_ROOT=$(pivilion_boot_root)
|
||||||
|
|
@ -189,7 +190,10 @@ migrate_paths() {
|
||||||
apply_runtime() {
|
apply_runtime() {
|
||||||
local php_version post_mb escaped_ssid
|
local php_version post_mb escaped_ssid
|
||||||
migrate_paths
|
migrate_paths
|
||||||
if [ "$(hostname -s)" != "$PIVILION_HOSTNAME" ] && command -v hostnamectl >/dev/null 2>&1; then hostnamectl set-hostname "$PIVILION_HOSTNAME"; fi
|
if ! pivilion_apply_hostname "$PIVILION_HOSTNAME"; then
|
||||||
|
fail_boot "Failed to apply hostname '$PIVILION_HOSTNAME' without D-Bus"
|
||||||
|
return "$PIVILION_E_CONFIG"
|
||||||
|
fi
|
||||||
command -v iw >/dev/null 2>&1 && iw reg set "$PIVILION_WIFI_COUNTRY" 2>/dev/null || true
|
command -v iw >/dev/null 2>&1 && iw reg set "$PIVILION_WIFI_COUNTRY" 2>/dev/null || true
|
||||||
if [ -n "$PIVILION_WIFI_SSID" ] && [ -n "$PIVILION_WIFI_PSK" ]; then
|
if [ -n "$PIVILION_WIFI_SSID" ] && [ -n "$PIVILION_WIFI_PSK" ]; then
|
||||||
if command -v nmcli >/dev/null 2>&1 && { systemctl is-enabled --quiet NetworkManager 2>/dev/null || systemctl is-active --quiet NetworkManager 2>/dev/null; }; then
|
if command -v nmcli >/dev/null 2>&1 && { systemctl is-enabled --quiet NetworkManager 2>/dev/null || systemctl is-active --quiet NetworkManager 2>/dev/null; }; then
|
||||||
|
|
|
||||||
64
usr/local/lib/pivilion/hostname.sh
Normal file
64
usr/local/lib/pivilion/hostname.sh
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Apply a hostname without systemd-hostnamed. This file is also sourced by the
|
||||||
|
# test suite, so paths and the hostname command may be redirected there.
|
||||||
|
pivilion_apply_hostname() {
|
||||||
|
local hostname=$1
|
||||||
|
local hostname_file=${PIVILION_HOSTNAME_FILE:-/etc/hostname}
|
||||||
|
local hosts_file=${PIVILION_HOSTS_FILE:-/etc/hosts}
|
||||||
|
local hostname_command=${PIVILION_HOSTNAME_COMMAND:-/bin/hostname}
|
||||||
|
local tmp current
|
||||||
|
|
||||||
|
tmp=$(mktemp "$(dirname "$hostname_file")/.pivilion-hostname.XXXXXX") || {
|
||||||
|
echo "Could not create a temporary file for $hostname_file" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
printf '%s\n' "$hostname" > "$tmp" && chmod 0644 "$tmp" || {
|
||||||
|
rm -f "$tmp"
|
||||||
|
echo "Could not prepare $hostname_file for hostname '$hostname'" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if [ -r "$hostname_file" ] && cmp -s "$tmp" "$hostname_file"; then
|
||||||
|
rm -f "$tmp"
|
||||||
|
elif ! mv -f "$tmp" "$hostname_file"; then
|
||||||
|
rm -f "$tmp"
|
||||||
|
echo "Could not atomically write hostname '$hostname' to $hostname_file" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmp=$(mktemp "$(dirname "$hosts_file")/.pivilion-hosts.XXXXXX") || {
|
||||||
|
echo "Could not create a temporary file for $hosts_file" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
awk -v hostname="$hostname" '
|
||||||
|
$1 == "127.0.1.1" { if (!written++) print "127.0.1.1\t" hostname; next }
|
||||||
|
{ print }
|
||||||
|
END { if (!written) print "127.0.1.1\t" hostname }
|
||||||
|
' "$hosts_file" > "$tmp" 2>/dev/null || {
|
||||||
|
rm -f "$tmp"
|
||||||
|
echo "Could not update the 127.0.1.1 entry in $hosts_file" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
chmod 0644 "$tmp" || {
|
||||||
|
rm -f "$tmp"
|
||||||
|
echo "Could not prepare the updated $hosts_file" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if [ -r "$hosts_file" ] && cmp -s "$tmp" "$hosts_file"; then
|
||||||
|
rm -f "$tmp"
|
||||||
|
elif ! mv -f "$tmp" "$hosts_file"; then
|
||||||
|
rm -f "$tmp"
|
||||||
|
echo "Could not atomically update the 127.0.1.1 entry in $hosts_file" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -x "$hostname_command" ] || {
|
||||||
|
echo "Cannot set the running hostname: $hostname_command is not executable" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
current=$($hostname_command -s 2>/dev/null || true)
|
||||||
|
if [ "$current" != "$hostname" ] && ! "$hostname_command" "$hostname"; then
|
||||||
|
echo "Could not set the running kernel hostname to '$hostname' with $hostname_command" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue