From e1ee30812f73acb1eb2aca25293e054bb32233af Mon Sep 17 00:00:00 2001 From: "John A. Hoeven" Date: Thu, 11 Jun 2026 21:55:21 +0200 Subject: [PATCH] Fix first real-hardware install issues from tinkerpad run MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - bootstrap: install bash before fetch (ash-only base installs) - bootstrap/deploy: correct URL (drop /repo prefix, webroot is /srv/repo) - 01_core: remove bash (bootstrap now handles it) - ce-base/minimal/basic: BusyBox-compatible df check (drop --output=avail) - ce-common: add ensure_testing_repo + install_pkg_testing - 12_access: espeakup + espeakup-openrc from edge/testing - 05_fonts: nerd-fonts → nerd-fonts-all (meta-package blocks by design) - 06_utils: tealdeer + bash-completion from edge/testing - 07_journal: jrnl test checks ~/.local/bin/jrnl (pipx not in PATH during install) - 11_wiki: arch-aware CE_REPO (${ARCH} replaces hardcoded amd64); Forgejo TODO updated Co-Authored-By: Claude Sonnet 4.6 --- bootstrap.sh | 16 ++++++++++------ ce-base.sh | 2 +- ce-basic.sh | 2 +- ce-minimal.sh | 2 +- deploy.sh | 4 ++-- lib/base/01_core.sh | 4 ++-- lib/basic/05_fonts.sh | 12 ++++++------ lib/basic/06_utils.sh | 8 +++++--- lib/ce-common.sh | 21 +++++++++++++++++++++ lib/minimal/07_journal.sh | 2 +- lib/minimal/11_wiki.sh | 4 +++- lib/minimal/12_access.sh | 11 ++++------- 12 files changed, 57 insertions(+), 31 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 2b9c201..f9cd128 100644 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -2,22 +2,21 @@ # Created by John A. Hoeven with the ethical assistance of Claude AI # --------------------------------------------------------------------------- # bootstrap.sh -# Served at: http://192.168.0.138/repo/scripts/alpine-ceos-installer/bootstrap.sh +# Served at: http://192.168.0.138/scripts/alpine-ceos-installer/bootstrap.sh # Version: v0.0.1 | Status: DEVELOPMENT # Target: Alpine Linux x86-64 (tinkerpad / ThinkPad T480) # --------------------------------------------------------------------------- # Run this on tinkerpad to download the full CE OS installer from workbench. -# Usage: wget http://192.168.0.138/repo/scripts/alpine-ceos-installer/bootstrap.sh +# Usage: wget http://192.168.0.138/scripts/alpine-ceos-installer/bootstrap.sh # bash bootstrap.sh # -# TODO — Forgejo: when git.jahnet.lan is deployed, replace the wget block -# below with these three lines and delete the rest of this file: +# TODO — Forgejo: replace the wget block below with these three lines and delete the rest of this file: # doas apk add git -# git clone -b dev http://git.jahnet.lan/john/ceos-alpine-installer.git +# git clone -b dev https://git.jhoeven.net/giovannino/ceos-alpine-installer.git # cd ceos-alpine-installer && bash ce-install.sh # --------------------------------------------------------------------------- -BASE="http://192.168.0.138/repo/scripts/alpine-ceos-installer" +BASE="http://192.168.0.138/scripts/alpine-ceos-installer" DEST="/tmp/ceos-installer-$(date +%Y%m%d%H%M%S)" echo "CE OS Alpine Installer — Bootstrap" @@ -26,6 +25,11 @@ echo "Source: ${BASE}" echo "Dest: ${DEST}" echo "" +if ! command -v bash > /dev/null 2>&1; then + echo "Installing bash..." + doas apk add bash || { echo "ERROR: could not install bash"; exit 1; } +fi + mkdir -p \ "${DEST}/lib/base" \ "${DEST}/lib/minimal" \ diff --git a/ce-base.sh b/ce-base.sh index ca517d1..dc25fc4 100644 --- a/ce-base.sh +++ b/ce-base.sh @@ -35,7 +35,7 @@ phase_preflight() { run_test "bash >= 4" '[[ "${BASH_VERSINFO[0]}" -ge 4 ]]' fail run_test "arch detected" '[[ -n "${ARCH}" ]]' fail run_test "apk available" 'command -v apk >/dev/null 2>&1' fail - run_test "disk >= 500MB" '[[ $(df / --output=avail | tail -1) -ge 512000 ]]' warn + run_test "disk >= 500MB" '[[ $(df -k / | awk "NR==2{print \$4}") -ge 512000 ]]' warn run_test "internet reachable" \ 'curl --silent --max-time 10 --output /dev/null https://dl-cdn.alpinelinux.org' warn log_info "Arch: ${ARCH}" diff --git a/ce-basic.sh b/ce-basic.sh index 9000cb0..bf23b48 100644 --- a/ce-basic.sh +++ b/ce-basic.sh @@ -40,7 +40,7 @@ phase_preflight() { run_test "community repo enabled" 'grep -q "^[^#].*community" /etc/apk/repositories' fail run_test "internet reachable" \ 'curl --silent --max-time 10 --output /dev/null https://dl-cdn.alpinelinux.org' warn - run_test "disk >= 2GB" '[[ $(df / --output=avail | tail -1) -ge 2097152 ]]' warn + run_test "disk >= 2GB" '[[ $(df -k / | awk "NR==2{print \$4}") -ge 2097152 ]]' warn log_info "Arch: ${ARCH}" log_info "Pre-flight complete" } diff --git a/ce-minimal.sh b/ce-minimal.sh index 4ab0a6e..0f8c5c6 100644 --- a/ce-minimal.sh +++ b/ce-minimal.sh @@ -40,7 +40,7 @@ phase_preflight() { run_test "community repo enabled" 'grep -q "^[^#].*community" /etc/apk/repositories' fail run_test "internet reachable" \ 'curl --silent --max-time 10 --output /dev/null https://dl-cdn.alpinelinux.org' warn - run_test "disk >= 1GB" '[[ $(df / --output=avail | tail -1) -ge 1048576 ]]' warn + run_test "disk >= 1GB" '[[ $(df -k / | awk "NR==2{print \$4}") -ge 1048576 ]]' warn log_info "Arch: ${ARCH}" log_info "Pre-flight complete" } diff --git a/deploy.sh b/deploy.sh index 76400dc..f19c936 100644 --- a/deploy.sh +++ b/deploy.sh @@ -41,5 +41,5 @@ doas chmod +x \ echo "" echo "Deploy complete." -echo "Pull URL: http://192.168.0.138/repo/scripts/alpine-ceos-installer/" -echo "Bootstrap: wget http://192.168.0.138/repo/scripts/alpine-ceos-installer/bootstrap.sh" +echo "Pull URL: http://192.168.0.138/scripts/alpine-ceos-installer/" +echo "Bootstrap: wget http://192.168.0.138/scripts/alpine-ceos-installer/bootstrap.sh" diff --git a/lib/base/01_core.sh b/lib/base/01_core.sh index f662817..27022c8 100644 --- a/lib/base/01_core.sh +++ b/lib/base/01_core.sh @@ -24,7 +24,7 @@ install_base_core() { log_info "--- base/01_core: verifying core packages available ---" local missing=() - for pkg in bash bash-completion ca-certificates curl openssh tzdata utmps; do + for pkg in bash-completion ca-certificates curl openssh tzdata utmps; do apk search "${pkg}" 2>/dev/null | grep -q "^${pkg}" \ || missing+=("${pkg}") done @@ -33,7 +33,7 @@ install_base_core() { fi log_info "--- base/01_core: installing core packages ---" - local -a PKGS=(bash bash-completion ca-certificates curl openssh tzdata utmps) + local -a PKGS=(bash-completion ca-certificates curl openssh tzdata utmps) for pkg in "${PKGS[@]}"; do install_pkg "${pkg}" done diff --git a/lib/basic/05_fonts.sh b/lib/basic/05_fonts.sh index bcd7103..c5173dc 100644 --- a/lib/basic/05_fonts.sh +++ b/lib/basic/05_fonts.sh @@ -18,15 +18,15 @@ install_basic_fonts() { install_pkg "figlet" run_test "figlet present" 'command -v figlet >/dev/null 2>&1' warn - # nerd-fonts — edge/community; package name verified as 'nerd-fonts' + # nerd-fonts-all — edge/community; 'nerd-fonts' meta-package blocks install by design ensure_edge_repo - log_info "Installing nerd-fonts from @edge/community..." - if install_pkg_edge "nerd-fonts"; then - log_info "nerd-fonts installed" + log_info "Installing nerd-fonts-all from @edge/community..." + if install_pkg_edge "nerd-fonts-all"; then + log_info "nerd-fonts-all installed" else - log_warn "nerd-fonts@edge not available — skipping gracefully" - MANUAL_PKGS+=("nerd-fonts: edge install failed — check pkgs.alpinelinux.org/packages?name=nerd-fonts&branch=edge") + log_warn "nerd-fonts-all@edge not available — skipping gracefully" + MANUAL_PKGS+=("nerd-fonts: edge install failed — check pkgs.alpinelinux.org/packages?name=nerd-fonts-all&branch=edge") fi } diff --git a/lib/basic/06_utils.sh b/lib/basic/06_utils.sh index 02af323..74c4259 100644 --- a/lib/basic/06_utils.sh +++ b/lib/basic/06_utils.sh @@ -7,14 +7,16 @@ # Target: Alpine Linux x86-64 (tinkerpad / ThinkPad T480) # --------------------------------------------------------------------------- # Basic Tier subscript: additional utilities — -# tealdeer, restic, jq, bc, zip, unzip, xz. -# Note: package name is 'tealdeer' (not 'tldr'). +# tealdeer (@edge/testing), restic, jq, bc, zip, unzip, xz. # Defines install_basic_utils(). # --------------------------------------------------------------------------- install_basic_utils() { log_info "--- basic/06_utils: additional utilities ---" - local -a PKGS=(tealdeer restic jq bc zip unzip xz) + ensure_testing_repo + install_pkg_testing "tealdeer" + install_pkg_testing "tealdeer-bash-completion" + local -a PKGS=(restic jq bc zip unzip xz) for pkg in "${PKGS[@]}"; do install_pkg "${pkg}" done diff --git a/lib/ce-common.sh b/lib/ce-common.sh index 9373178..c3f662d 100644 --- a/lib/ce-common.sh +++ b/lib/ce-common.sh @@ -106,6 +106,27 @@ ensure_edge_repo() { fi } +# ensure_testing_repo — add @testing tag if not present +ensure_testing_repo() { + if ! grep -q "^@testing" /etc/apk/repositories 2>/dev/null; then + log_info "Adding @testing edge/testing tag to /etc/apk/repositories" + printf '@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing\n' \ + | doas tee -a /etc/apk/repositories > /dev/null 2>&1 \ + || log_warn "Could not add @testing tag — testing installs may fail" + fi +} + +# install_pkg_testing — install with @testing tag, warn on fail +install_pkg_testing() { + local pkg="${1}" + if doas apk add "${pkg}@testing" >> "${LOG_FILE}" 2>&1; then + log_info "Installed: ${pkg} (@testing)" + else + log_warn "FAILED: ${pkg}@testing — manual verification required" + FAILED_PKGS+=("${pkg} (testing, manual verification required)") + fi +} + # --------------------------------------------------------------------------- # Guards and prompts # --------------------------------------------------------------------------- diff --git a/lib/minimal/07_journal.sh b/lib/minimal/07_journal.sh index 8c25582..3837f08 100644 --- a/lib/minimal/07_journal.sh +++ b/lib/minimal/07_journal.sh @@ -33,7 +33,7 @@ install_minimal_journal() { FAILED_PKGS+=("jrnl (pipx install failed)") fi - run_test "jrnl present" 'command -v jrnl >/dev/null 2>&1' warn + run_test "jrnl present" 'command -v jrnl >/dev/null 2>&1 || [[ -x "${HOME}/.local/bin/jrnl" ]]' warn } if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then diff --git a/lib/minimal/11_wiki.sh b/lib/minimal/11_wiki.sh index 38a5a02..76ff8e2 100644 --- a/lib/minimal/11_wiki.sh +++ b/lib/minimal/11_wiki.sh @@ -9,13 +9,15 @@ # Minimal Tier subscript: wiki viewer — glow from CE repo. # Downloads binary, verifies sha256 and GPG signature, installs to ~/.local/bin/. # Gracefully skips if CE repo is unreachable or verification fails. +# TODO — Forgejo: update CE_REPO_HOST to https://git.jhoeven.net/giovannino/ceos-alpine-installer/raw/branch/main/bin # Defines install_minimal_wiki(). # --------------------------------------------------------------------------- install_minimal_wiki() { log_info "--- minimal/11_wiki: glow (CE repo) ---" - local CE_REPO="https://cervelloelettrico.it/bin/amd64/alpine" + local CE_REPO_HOST="https://cervelloelettrico.it/bin" + local CE_REPO="${CE_REPO_HOST}/${ARCH}/alpine" local INSTALL_DIR="${HOME}/.local/bin" local TEMP_DIR TEMP_DIR="$(mktemp -d /tmp/ce-glow-XXXXXX)" diff --git a/lib/minimal/12_access.sh b/lib/minimal/12_access.sh index b010edd..bf7f3a7 100644 --- a/lib/minimal/12_access.sh +++ b/lib/minimal/12_access.sh @@ -27,13 +27,10 @@ install_minimal_access() { install_pkg "espeak-ng" run_test "espeak-ng present" 'command -v espeak-ng >/dev/null 2>&1' warn - # espeakup — verify package exists in current repo before attempting install - if apk search espeakup 2>/dev/null | grep -q "^espeakup"; then - install_pkg "espeakup" - else - log_warn "espeakup not found in current Alpine repos — skipping" - MANUAL_PKGS+=("espeakup: not found in Alpine v3.23 — check https://github.com/dermotbradley/alpine-espeakup") - fi + # espeakup — in edge/testing; also install espeakup-openrc for service management + ensure_testing_repo + install_pkg_testing "espeakup" + install_pkg_testing "espeakup-openrc" # speech-dispatcher — edge package ensure_edge_repo