139 lines
4.2 KiB
Bash
Executable File
139 lines
4.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Function to check if a package is installed
|
|
is_installed() {
|
|
pacman -Qi "$1" &> /dev/null
|
|
}
|
|
|
|
# Function to check if a package is installed
|
|
is_group_installed() {
|
|
pacman -Qg "$1" &> /dev/null
|
|
}
|
|
|
|
# Function to install packages if not already installed
|
|
install_packages() {
|
|
local packages=("$@")
|
|
local to_install=()
|
|
|
|
for pkg in "${packages[@]}"; do
|
|
if ! is_installed "$pkg" && ! is_group_installed "$pkg"; then
|
|
to_install+=("$pkg")
|
|
fi
|
|
done
|
|
|
|
if [ ${#to_install[@]} -ne 0 ]; then
|
|
echo "Installing: ${to_install[*]}"
|
|
yay -S --noconfirm --answerdiff=None --answeredit=None --answerclean=None "${to_install[@]}"
|
|
fi
|
|
}
|
|
|
|
# Function to remove pacman/AUR packages if installed
|
|
remove_packages() {
|
|
local packages=("$@")
|
|
local to_remove=()
|
|
|
|
for pkg in "${packages[@]}"; do
|
|
if is_installed "$pkg"; then
|
|
to_remove+=("$pkg")
|
|
fi
|
|
done
|
|
|
|
if [ ${#to_remove[@]} -ne 0 ]; then
|
|
echo "Removing: ${to_remove[*]}"
|
|
sudo pacman -Rns --noconfirm "${to_remove[@]}"
|
|
fi
|
|
}
|
|
|
|
# Function to enable systemd services if not already enabled
|
|
enable_services() {
|
|
for service in "$@"; do
|
|
if ! systemctl is-enabled "$service" &> /dev/null; then
|
|
echo "Enabling $service..."
|
|
sudo systemctl enable "$service"
|
|
else
|
|
echo "$service is already enabled."
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Output of the last update's pacman -Su, written by updates.d/10-pacman.sh
|
|
PACMAN_UPDATE_LOG="$HOME/.local/state/miniserver/pacman-update.log"
|
|
|
|
# True if the last update rebuilt the initramfs and mkinitcpio reported a
|
|
# failure. Rebooting then can leave the machine unbootable.
|
|
initramfs_build_failed() {
|
|
[ -f "$PACMAN_UPDATE_LOG" ] || return 1
|
|
grep -q "Updating linux initcpios" "$PACMAN_UPDATE_LOG" || return 1
|
|
grep -q "==> ERROR" "$PACMAN_UPDATE_LOG" || ! grep -q "Image generation successful" "$PACMAN_UPDATE_LOG"
|
|
}
|
|
|
|
# Install a script atomically (copy to a temp file, then rename over the target)
|
|
# so a copy of it that is running right now keeps reading the old file
|
|
install_script() {
|
|
local tmp
|
|
tmp="$(mktemp "$2.XXXXXX")" && cp "$1" "$tmp" && chmod 755 "$tmp" && mv -f "$tmp" "$2"
|
|
}
|
|
|
|
# Start Cockpit. Safe to re-run: does nothing once set up. The cockpit package
|
|
# itself comes from packages.conf; its firewall port is in firewall.conf.
|
|
setup_cockpit() {
|
|
if ! systemctl is-enabled --quiet cockpit.socket || ! systemctl is-active --quiet cockpit.socket; then
|
|
echo "Enabling Cockpit..."
|
|
sudo systemctl enable --now cockpit.socket
|
|
fi
|
|
}
|
|
|
|
# Allow the services and ports in firewall.conf through firewalld's default
|
|
# zone, then make sure firewalld is running. Only adds rules, never removes
|
|
# them, so rules added by hand or by sibling projects stay. Safe to re-run.
|
|
setup_firewall() {
|
|
command -v firewall-offline-cmd &> /dev/null || return 0
|
|
source "$HOME/.local/share/MiniServer/firewall.conf"
|
|
|
|
# firewall-cmd only works while firewalld is running; before that, write the
|
|
# permanent config directly so SSH is allowed before the firewall comes up
|
|
local fw running=0 changed=0 svc port
|
|
if systemctl is-active --quiet firewalld; then
|
|
running=1
|
|
fw=(sudo firewall-cmd --permanent)
|
|
else
|
|
fw=(sudo firewall-offline-cmd)
|
|
fi
|
|
|
|
# Keep SSH reachable if sshd listens on a port other than 22
|
|
local ports=("${FIREWALL_PORTS[@]}")
|
|
if command -v sshd &> /dev/null; then
|
|
for port in $(sudo sshd -T 2> /dev/null | awk '$1 == "port" && $2 != 22 { print $2 }'); do
|
|
ports+=("$port/tcp")
|
|
done
|
|
fi
|
|
|
|
for svc in "${FIREWALL_SERVICES[@]}"; do
|
|
if ! "${fw[@]}" --query-service="$svc" &> /dev/null; then
|
|
echo "Firewall: allowing $svc"
|
|
"${fw[@]}" --add-service="$svc"
|
|
changed=1
|
|
fi
|
|
done
|
|
for port in "${ports[@]}"; do
|
|
if ! "${fw[@]}" --query-port="$port" &> /dev/null; then
|
|
echo "Firewall: allowing $port"
|
|
"${fw[@]}" --add-port="$port"
|
|
changed=1
|
|
fi
|
|
done
|
|
|
|
if (( running )); then
|
|
if (( changed )); then
|
|
sudo firewall-cmd --reload
|
|
fi
|
|
else
|
|
echo "Starting firewalld..."
|
|
sudo systemctl enable --now firewalld
|
|
# Docker sets up its firewalld zone only when it starts
|
|
if systemctl is-active --quiet docker; then
|
|
echo "Docker started before firewalld. Restart it (sudo systemctl restart docker) or reboot so its containers' ports work through the firewall."
|
|
fi
|
|
fi
|
|
}
|