Compare commits
12
Commits
146c79a57e
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce5041bc50 | ||
|
|
9f164f61ef | ||
|
|
0cfe10e387 | ||
|
|
efdf056352 | ||
|
|
435d66aad2 | ||
|
|
94a0bac9f4 | ||
|
|
26185978ac | ||
|
|
cb0e517a7d | ||
|
|
b653191de2 | ||
|
|
ca8f01083c | ||
|
|
ff9fc4db4e | ||
|
|
f7e4bb96d7 |
No files matched your search
+5
-4
@@ -9,12 +9,13 @@ ok() { printf '\033[1;32mok\033[0m %s\n' "$*"; }
|
||||
# run a command as root when not already root
|
||||
sudo_() { if (( EUID == 0 )); then "$@"; else sudo "$@"; fi; }
|
||||
|
||||
# run a command AS the invoking (non-root) user — used for AUR builds, etc.
|
||||
# when root: drop to SUDO_USER (or USER) via runuser; when not root: run directly.
|
||||
# run a command AS the target non-root user — used for AUR builds, nvm, etc.
|
||||
# precedence (when running as root): TARGET_USER (set by create-user) > SUDO_USER > USER.
|
||||
# when not root: run directly as ourselves.
|
||||
as_user() {
|
||||
local u="$USER"
|
||||
local u="${SUDO_USER:-$USER}"
|
||||
if (( EUID == 0 )); then
|
||||
u="${SUDO_USER:-$USER}"
|
||||
u="${TARGET_USER:-${SUDO_USER:-$USER}}"
|
||||
command -v runuser >/dev/null 2>&1 && runuser -u "$u" -- "$@" || su "$u" -c "$*"
|
||||
else
|
||||
"$@"
|
||||
|
||||
+62
-19
@@ -20,32 +20,54 @@ run_packages() {
|
||||
}
|
||||
|
||||
# ── arch ─────────────────────────────────────────────────────────────────────
|
||||
# official-repo packages (verified in extra/core). Any name not in the official
|
||||
# repos would abort the whole `pacman --needed` batch, so keep this list clean
|
||||
# and route AUR-only tools through _install_aur_packages instead.
|
||||
ARCH_OFFICIAL=(git ufw mosh btop fzf ripgrep fd bat dust procs jq yq tree
|
||||
ncdu duf tldr httpie rsync lazygit neovim curl unzip less starship
|
||||
eza zoxide openssh)
|
||||
|
||||
# AUR-only packages (not in official repos) — installed through yay after build.
|
||||
ARCH_AUR=(byobu)
|
||||
|
||||
_pkg_arch() {
|
||||
sudo_ pacman -Sy --noconfirm --needed base-devel openssh
|
||||
# most tools live in extra/community (the merged repos); names map 1:1
|
||||
local p=(git byobu ufw mosh btop fzf ripgrep fd bat dust procs jq yq tree
|
||||
ncdu duf tldr httpie rsync lazygit neovim curl unzip less starship
|
||||
eza zoxide openssh)
|
||||
sudo_ pacman -Sy --noconfirm --needed "${p[@]}"
|
||||
sudo_ pacman -Sy --noconfirm --needed "${ARCH_OFFICIAL[@]}"
|
||||
_install_yay
|
||||
|
||||
_install_aur_packages
|
||||
# fd/bat ship with their real names on arch — no shims needed
|
||||
}
|
||||
|
||||
_install_yay() {
|
||||
if command -v yay >/dev/null 2>&1; then ok "yay already installed"; return; fi
|
||||
log "building yay from AUR (requires a non-root sudoer)"
|
||||
if (( EUID == 0 )) && [[ -z "${SUDO_USER:-}" ]]; then
|
||||
err "running as root with no SUDO_USER — yay cannot build. Re-run bootstrap as a normal user with sudo."
|
||||
if (( EUID == 0 )) && [[ -z "${TARGET_USER:-${SUDO_USER:-}}" ]]; then
|
||||
err "running as root with no target/sudo user — yay cannot build. Run the create-user step first, or re-run bootstrap as a normal user with sudo."
|
||||
return 1
|
||||
fi
|
||||
local tmp; tmp="$(mktemp -d)"
|
||||
# chown the build dir so the non-root build user can write into it
|
||||
if (( EUID == 0 )); then
|
||||
chown -R "${TARGET_USER:-${SUDO_USER}}" "$tmp"
|
||||
fi
|
||||
as_user git clone --depth 1 https://aur.archlinux.org/yay.git "$tmp/yay"
|
||||
( cd "$tmp/yay" && as_user makepkg -si --noconfirm )
|
||||
rm -rf "$tmp"
|
||||
command -v yay >/dev/null 2>&1 && ok "yay installed" || warn "yay install may need a manual pass"
|
||||
}
|
||||
|
||||
_install_aur_packages() {
|
||||
[[ "${#ARCH_AUR[@]}" -eq 0 ]] && return
|
||||
if ! command -v yay >/dev/null 2>&1; then
|
||||
warn "yay not available — skipping AUR packages: ${ARCH_AUR[*]}"
|
||||
return
|
||||
fi
|
||||
log "installing AUR-only packages: ${ARCH_AUR[*]}"
|
||||
# yay -S as the non-root target user (makepkg refuses root; TARGET_USER via as_user).
|
||||
as_user yay -S --noconfirm --needed "${ARCH_AUR[@]}" \
|
||||
|| warn "some AUR packages failed: ${ARCH_AUR[*]} (install manually with: yay -S ${ARCH_AUR[*]})"
|
||||
}
|
||||
|
||||
# ── debian/ubuntu ────────────────────────────────────────────────────────────
|
||||
_pkg_debian() {
|
||||
sudo_ apt-get update -y
|
||||
@@ -56,24 +78,45 @@ _pkg_debian() {
|
||||
# rename packages: fd -> fdfind, bat -> batcat (fix via aliases in zsh)
|
||||
sudo_ apt-get install -y fdfind batcat 2>/dev/null || true
|
||||
|
||||
# eza via the gierens PPA (debs not in base apt)
|
||||
# eza: the old apt.fury.io/gierens PPA is dead (401 Unauthorized). Install the
|
||||
# single binary from the upstream GitHub release tarball into /usr/local/bin
|
||||
# (system-wide — works for root and every sudo user; no HOME dependency).
|
||||
# Remove a stale eza.list left by the old (pre-fix) run that used the now-dead
|
||||
# apt.fury.io PPA — otherwise 'apt-get update' keeps hitting the 401 forever.
|
||||
sudo_ rm -f /etc/apt/sources.list.d/eza.list /etc/apt/keyrings/gierens.gpg
|
||||
if ! command -v eza >/dev/null 2>&1; then
|
||||
sudo_ install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://raw.githubusercontent.com/eza-community/eza/main/deb.asc \
|
||||
| sudo_ tee /etc/apt/keyrings/gierens.gpg >/dev/null
|
||||
echo "deb [signed-by=/etc/apt/keyrings/gierens.gpg] http://apt.fury.io/eza/ /" \
|
||||
| sudo_ tee /etc/apt/sources.list.d/eza.list >/dev/null
|
||||
sudo_ apt-get update -y && sudo_ apt-get install -y eza || warn "eza PPA failed"
|
||||
local eza_arch; case "$ARCH" in
|
||||
amd64) eza_arch=x86_64-unknown-linux-gnu ;;
|
||||
arm64) eza_arch=aarch64-unknown-linux-gnu ;;
|
||||
*) eza_arch="${ARCH}-unknown-linux-gnu" ;;
|
||||
esac
|
||||
local url="https://github.com/eza-community/eza/releases/latest/download/eza_${eza_arch}.tar.gz"
|
||||
local tmp; tmp="$(mktemp -d)"
|
||||
if wget -qO "$tmp/eza.tgz" "$url" && tar xzf "$tmp/eza.tgz" -C "$tmp"; then
|
||||
sudo_ install -m 0755 "$tmp/eza" /usr/local/bin/eza
|
||||
else
|
||||
warn "eza download failed ($url)"
|
||||
fi
|
||||
rm -rf "$tmp"
|
||||
fi
|
||||
|
||||
# starship: official installer
|
||||
# starship: official installer. NOTE — scrub $ARCH/$PLATFORM from the env first:
|
||||
# the installer reuses a pre-set ARCH (our lib/detect.sh exports ARCH=amd64) and
|
||||
# skips its own amd64->x86_64 mapping, yielding an unsupported 'amd64-unknown-linux-
|
||||
# musl' target ('builds for amd64-unknown-linux-musl are not yet available').
|
||||
# Default bin dir is /usr/local/bin (system-wide).
|
||||
if ! command -v starship >/dev/null 2>&1; then
|
||||
curl -sS https://starship.rs/install.sh | sh -s -- -y || warn "starship install failed"
|
||||
curl -sS https://starship.rs/install.sh \
|
||||
| env -u ARCH -u PLATFORM sh -s -- -y || warn "starship install failed"
|
||||
fi
|
||||
|
||||
# zoxide: official installer
|
||||
# zoxide: official installer. Install system-wide (/usr/local/bin) instead of the
|
||||
# default ~/.local/bin — when run as root the default lands in /root (wrong user
|
||||
# for the create-user path) and isn't on $PATH; /usr/local/bin is on PATH for all.
|
||||
if ! command -v zoxide >/dev/null 2>&1; then
|
||||
curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | bash || warn "zoxide install failed"
|
||||
curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh \
|
||||
| env -u ARCH sh -s -- --bin-dir /usr/local/bin --man-dir /usr/local/share/man \
|
||||
|| warn "zoxide install failed"
|
||||
fi
|
||||
|
||||
# yq: direct binary from mikefarah/yq releases (stable URL)
|
||||
|
||||
+23
-6
@@ -27,12 +27,25 @@ run_angie() {
|
||||
}
|
||||
|
||||
_angie_arch() {
|
||||
if command -v yay >/dev/null 2>&1; then
|
||||
as_user yay -S --noconfirm angie 2>/dev/null \
|
||||
|| as_user yay -S --noconfirm aur/angie 2>/dev/null \
|
||||
|| warn "angie AUR build failed — try: yay -S angie"
|
||||
if ! command -v yay >/dev/null 2>&1; then
|
||||
warn "yay not available — install angie manually from AUR: yay -S angie-bin"
|
||||
return
|
||||
fi
|
||||
# Prefer angie-bin: it repackages the upstream official Ubuntu .deb, so it's
|
||||
# instant (no source compile) and carries the same compiled-in modules our
|
||||
# config relies on — http_acme, http_ssl, http_v2/v3, http_realip, stream*
|
||||
# (verified via the .deb's 'angie -V'). Drop back to the source 'angie'
|
||||
# package only if the binary package is unavailable.
|
||||
log "AUR install: angie-bin first, fall back to angie (source build)"
|
||||
if as_user yay -S --noconfirm --needed angie-bin 2>/dev/null; then
|
||||
ok "angie-bin installed from AUR"
|
||||
return
|
||||
fi
|
||||
log "angie-bin unavailable/failed — building angie from source (may take a few minutes)"
|
||||
if as_user yay -S --noconfirm --needed aur/angie 2>/dev/null; then
|
||||
ok "angie (source) installed from AUR"
|
||||
else
|
||||
warn "yay not available — install angie manually from AUR: yay -S angie"
|
||||
warn "angie install failed — try manually: yay -S angie-bin (or: yay -S angie)"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -41,7 +54,11 @@ _angie_debian() {
|
||||
sudo_ install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://angie.software/keys/angie-signing.gpg \
|
||||
| sudo_ tee /etc/apt/keyrings/angie-signing.gpg >/dev/null
|
||||
echo "deb [signed-by=/etc/apt/keyrings/angie-signing.gpg] https://download.angie.software/angie/${ID}/ ${VERSION_CODENAME} main" \
|
||||
# Repo path is angie/<ID>/<VERSION_ID>/ with the codename as the apt suite, e.g.
|
||||
# debian/13/dists/trixie/ or ubuntu/22.04/dists/jammy/. Omitting VERSION_ID (just
|
||||
# angie/debian/) fetches debian/dists/trixie -> 404 'no Release file' — must pin the
|
||||
# numeric version in the URL path.
|
||||
echo "deb [signed-by=/etc/apt/keyrings/angie-signing.gpg] https://download.angie.software/angie/${ID}/${VERSION_ID}/ ${VERSION_CODENAME} main" \
|
||||
| sudo_ tee /etc/apt/sources.list.d/angie.list >/dev/null
|
||||
sudo_ apt-get update -y
|
||||
sudo_ apt-get install -y angie
|
||||
|
||||
@@ -6,9 +6,13 @@ step_desc="zsh + oh-my-zsh + plugins, set default shell, ship config"
|
||||
step_run="run_zsh"
|
||||
|
||||
# All paths resolve against the config TARGET (set by 05-create-user).
|
||||
ZSH="${ZSH:-$TARGET_HOME/.oh-my-zsh}"
|
||||
ZSH_CUSTOM="${ZSH_CUSTOM:-$ZSH/custom}"
|
||||
ZDOTDIR_TARGET="${ZDOTDIR_TARGET:-$TARGET_HOME/.config/zsh}"
|
||||
# NOTE: we deliberately do NOT honor an inherited $ZSH env var — oh-my-zsh exports
|
||||
# ZSH when it loads, so a setup.sh run from an omz-equipped shell would otherwise
|
||||
# pin these to the *old* home (e.g. /root) while the chown step retargets to the
|
||||
# *new* user, mis-owning the wrong tree (the 'insecure completion dirs' bug).
|
||||
ZSH="$TARGET_HOME/.oh-my-zsh"
|
||||
ZSH_CUSTOM="$ZSH/custom"
|
||||
ZDOTDIR_TARGET="$TARGET_HOME/.config/zsh"
|
||||
|
||||
run_zsh() {
|
||||
log "installing zsh + oh-my-zsh"
|
||||
@@ -53,8 +57,8 @@ _install_plugins() {
|
||||
_clone_plugin zsh-users/zsh-autosuggestions "$ZSH_CUSTOM/plugins/zsh-autosuggestions"
|
||||
_clone_plugin zsh-users/zsh-syntax-highlighting "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting"
|
||||
_clone_plugin zsh-users/zsh-completions "$ZSH_CUSTOM/plugins/zsh-completions"
|
||||
_clone_plugin Aloofenlore/history-substring-search "$ZSH_CUSTOM/plugins/history-substring-search"
|
||||
_clone_plugin Aloof98/fzf-tab "$ZSH_CUSTOM/plugins/fzf-tab"
|
||||
_clone_plugin zsh-users/zsh-history-substring-search "$ZSH_CUSTOM/plugins/history-substring-search"
|
||||
_clone_plugin Aloxaf/fzf-tab "$ZSH_CUSTOM/plugins/fzf-tab"
|
||||
}
|
||||
|
||||
_clone_plugin() { # repo dest
|
||||
|
||||
+77
-12
@@ -206,20 +206,38 @@ _h_angie_config() {
|
||||
sudo_ install -d -m 0755 "$d/_on" "$d/targets" "$d/modules" "$d/modules/http"
|
||||
|
||||
# ── extract packaging-specific values from the stock angie.conf ──
|
||||
# Angie packages set user/pid/error_log differently per distro; preserve them.
|
||||
local oldcfg="$d/angie.conf" angie_user angie_pid angie_err angie_modules=""
|
||||
if [[ -f "$oldcfg" ]]; then
|
||||
angie_user=$(grep -E '^\s*user\s+' "$oldcfg" | head -1 | awk '{print $2}' | tr -d ';')
|
||||
angie_pid=$(grep -E '^\s*pid\s+' "$oldcfg" | head -1 | awk '{print $2}' | tr -d ';')
|
||||
angie_err=$(grep -E '^\s*error_log\s+' "$oldcfg" | head -1 | awk '{print $2}' | tr -d ';')
|
||||
# Different Angie packages set user/pid/error_log differently (Arch source
|
||||
# package → /etc/nginx/nginx.conf with 'user http'; angie-bin / Debian .deb
|
||||
# → /etc/angie/angie.conf with 'user angie'). Preserve them when present,
|
||||
# fall back to sane defaults otherwise (defaults cover all distros here).
|
||||
local oldcfg="$d/angie.conf"
|
||||
local altcfg="/etc/nginx/nginx.conf" # the source AUR package's path
|
||||
local stock="$oldcfg"
|
||||
[[ -f "$oldcfg" ]] || stock="$altcfg"
|
||||
local angie_user="" angie_pid="" angie_err="" angie_modules=""
|
||||
if [[ -f "$stock" ]]; then
|
||||
angie_user=$(grep -E '^\s*user\s+' "$stock" | head -1 | awk '{print $2}' | tr -d ';')
|
||||
angie_pid=$(grep -E '^\s*pid\s+' "$stock" | head -1 | awk '{print $2}' | tr -d ';')
|
||||
angie_err=$(grep -E '^\s*error_log\s+' "$stock" | head -1 | awk '{print $2}' | tr -d ';')
|
||||
# collect any load_module lines (dynamic modules)
|
||||
angie_modules=$(grep -E '^\s*load_module\s+' "$oldcfg" || true)
|
||||
angie_modules=$(grep -E '^\s*load_module\s+' "$stock" || true)
|
||||
fi
|
||||
# sane defaults if not found
|
||||
[[ -z "$angie_user" ]] && angie_user=$({ [[ "$DISTRO" == "arch" ]] && echo http || echo angie; })
|
||||
[[ -z "$angie_user" ]] && angie_user=$({ [[ "${DISTRO:-}" == "arch" ]] && echo http || echo angie; })
|
||||
[[ -z "$angie_pid" ]] && angie_pid=/run/angie.pid
|
||||
[[ -z "$angie_err" ]] && angie_err=/var/log/angie/error.log
|
||||
|
||||
# locate mime.types: angie-bin/Debian ship /etc/angie/mime.types; the Arch source
|
||||
# 'angie' package instead pulls it from the 'mailcap' dep at /etc/nginx/mime.types
|
||||
# (and deletes its own). Pick whichever exists so 'angie -t' doesn't fail on include.
|
||||
local angie_mime=""
|
||||
for m in "$d/mime.types" /etc/nginx/mime.types /etc/mime.types; do
|
||||
[[ -f "$m" ]] && { angie_mime="$m"; break; }
|
||||
done
|
||||
[[ -z "$angie_mime" ]] && { warn "no mime.types found; installing a minimal one"; _angie_install_mime "$d/mime.types"; angie_mime="$d/mime.types"; }
|
||||
# the modules/ include dir must exist or the glob fails the config test
|
||||
sudo_ install -d -m 0755 "$d/modules" "$d/modules/http"
|
||||
|
||||
# backup the original once
|
||||
if [[ -f "$oldcfg" && ! -f "$oldcfg.orig.bootstrap" ]]; then
|
||||
sudo_ cp -a "$oldcfg" "$oldcfg.orig.bootstrap"
|
||||
@@ -248,7 +266,7 @@ events {
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/angie/mime.types;
|
||||
include $angie_mime;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
|
||||
@@ -304,14 +322,25 @@ EOF
|
||||
|
||||
# ── default catch-all server: unmatched Host -> drop ──
|
||||
if [[ ! -f "$d/_on/00-default.conf" ]]; then
|
||||
# The default_server also listens on 443 to catch unknown-SNI TLS clients.
|
||||
# It needs SOME cert to complete the handshake before `return 444` drops them;
|
||||
# angie won't start a 443 listener without ssl_certificate. Generate a self-signed
|
||||
# dummy once (CN='bootstrap-default', 10y) so unknown-SNI clients get dropped
|
||||
# after connecting while real vhosts are picked by SNI.
|
||||
if [[ ! -f "$d/ssl/bootstrap-default.crt" ]]; then
|
||||
sudo_ install -d -m 0755 "$d/ssl"
|
||||
sudo_ openssl req -x509 -newkey rsa:2048 -nodes -days 3650 -keyout "$d/ssl/bootstrap-default.key" -out "$d/ssl/bootstrap-default.crt" -subj "/CN=bootstrap-default/O=bootstrap" 2>/dev/null
|
||||
fi
|
||||
sudo_ tee "$d/_on/00-default.conf" >/dev/null <<'EOF'
|
||||
# default_server: drop requests that match no enabled host (drive-by scanners, bare-IP)
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
listen 443 default_server;
|
||||
listen [::]:443 default_server;
|
||||
listen 443 ssl default_server;
|
||||
listen [::]:443 ssl default_server;
|
||||
server_name _;
|
||||
ssl_certificate /etc/angie/ssl/bootstrap-default.crt;
|
||||
ssl_certificate_key /etc/angie/ssl/bootstrap-default.key;
|
||||
return 444;
|
||||
}
|
||||
EOF
|
||||
@@ -320,7 +349,25 @@ EOF
|
||||
# ── angie-enable / angie-disable helpers ──
|
||||
_angie_helpers
|
||||
|
||||
# validate + (best-effort) reload
|
||||
# ── source-angie bridge: point /etc/nginx/nginx.conf at our /etc/angie layout ─
|
||||
# The source AUR 'angie' package compiles --conf-path=/etc/nginx/nginx.conf and
|
||||
# its service runs '/usr/bin/nginx' with no -c flag, so it ignores /etc/angie.
|
||||
# When that path is where angie actually reads, back it up once and symlink it to
|
||||
# our managed angie.conf so the _on/targetsmodules layout takes effect. The
|
||||
# angie-bin / Debian packages already read /etc/angie/angie.conf directly.
|
||||
if [[ -f /etc/nginx/nginx.conf && -f "$d/angie.conf" ]]; then
|
||||
local nginxconf=/etc/nginx/nginx.conf
|
||||
if [[ "$(readlink -f "$nginxconf" 2>/dev/null)" == "$d/angie.conf" ]]; then
|
||||
ok "$nginxconf already symlinks to $d/angie.conf"
|
||||
else
|
||||
if [[ ! -f "${nginxconf}.orig.bootstrap" && ! -L "$nginxconf" ]]; then
|
||||
sudo_ cp -a "$nginxconf" "${nginxconf}.orig.bootstrap"
|
||||
fi
|
||||
sudo_ ln -sfn "$d/angie.conf" "$nginxconf"
|
||||
ok "symlinked $nginxconf -> $d/angie.conf (source-angie bridge); backup at ${nginxconf}.orig.bootstrap"
|
||||
fi
|
||||
fi
|
||||
|
||||
if sudo_ angie -t 2>&1; then
|
||||
ok "angie config valid"
|
||||
if command -v systemctl >/dev/null 2>&1 && systemctl is-active angie >/dev/null 2>&1; then
|
||||
@@ -339,6 +386,24 @@ EOF
|
||||
# ufw already opened 80/443 in _h_ufw
|
||||
}
|
||||
|
||||
_angie_install_mime() { # dest — write a minimal mime.types if none exists on the host
|
||||
sudo_ tee "$1" >/dev/null <<'EOF'
|
||||
types {
|
||||
text/html html htm shtml;
|
||||
text/css css;
|
||||
text/xml xml;
|
||||
image/gif gif;
|
||||
image/jpeg jpeg jpg;
|
||||
image/png png;
|
||||
image/svg+xml svg svgz;
|
||||
application/javascript js;
|
||||
application/json json;
|
||||
application/pdf pdf;
|
||||
application/zip zip;
|
||||
application/octet-stream bin exe dll so deb dmg iso img;
|
||||
}
|
||||
EOF
|
||||
}
|
||||
_angie_helpers() {
|
||||
sudo_ tee /usr/local/bin/angie-enable >/dev/null <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
|
||||
@@ -15,7 +15,7 @@ run_sanity() {
|
||||
echo " memory : $(free -h | awk '/^Mem/ {print $2}') total"
|
||||
echo " swap : $(swapon --show 2>/dev/null | awk 'NR>1{print $3; found=1} END{if(!found) print "none"}')"
|
||||
echo " timezone : $(timedatectl show -p Timezone --value 2>/dev/null || cat /etc/timezone 2>/dev/null || echo '?')"
|
||||
echo " hostname : $(hostname)"
|
||||
echo " hostname : $(uname -n 2>/dev/null || hostnamectl --static 2>/dev/null || cat /etc/hostname 2>/dev/null || echo '?')"
|
||||
echo " locale : $(locale 2>/dev/null | awk -F= '/^LANG/ {print $2}')"
|
||||
echo " ufw : $(sudo_ ufw status 2>/dev/null | head -1 || echo 'not installed')"
|
||||
echo " fail2ban : $(sudo_ fail2ban-client status 2>/dev/null | head -2 || echo 'not running')"
|
||||
@@ -32,7 +32,7 @@ run_sanity() {
|
||||
- Add starship config if you want a custom prompt: starship preset list
|
||||
(defaults ship with the bootstrap).
|
||||
- Consider 'newgrp docker' or re-login to activate the docker group.
|
||||
- Install domain + TLS for angie separately (certbot/acme.sh), not handled here.
|
||||
- Issue TLS certs for angie hosts with: angie-issue <domain> you@email.com
|
||||
EOF
|
||||
ok "bootstrap sanity report done."
|
||||
}
|
||||
Reference in new issue
Block a user