From 9773dcfb6341e83f6b4edf20119bfbdd8098ea90 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 4 Jun 2026 01:00:57 +0000 Subject: [PATCH 1/3] bootstrap: support USB/local-copy and private repo PAT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three usage modes now documented and implemented: 1. Public repo: curl | sudo bash (unchanged) 2. Private repo, USB: copy whole repo to thumb drive, run bootstrap.sh from it — detects setup.sh alongside itself, copies to ~/ubuntu-post-install, execs setup.sh. No git auth, no internet needed for the scripts. 3. Private repo, PAT: bootstrap.sh --pat ghp_xxx — PAT stripped from stored remote URL after clone so it is not saved in plain text. USB mode is the recommended approach for private repos: clone once, put on a drive, run on every new machine. https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG --- README.md | 24 +++++++++++++----- bootstrap.sh | 72 +++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 74 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 7e068c7..b83203b 100644 --- a/README.md +++ b/README.md @@ -5,20 +5,30 @@ install exactly what you need — interactively or by name. ## Quick start on a fresh box +**Public repo — paste on any new box:** ```bash curl -fsSL https://raw.githubusercontent.com/outis1one/ubuntu-post-install/main/bootstrap.sh | sudo bash ``` -That installs git (if missing), clones the repo to `~/ubuntu-post-install`, -and drops you into the interactive wizard. - -If you already have git: - +**Private repo — USB thumb drive (recommended):** ```bash +# Once, on any connected machine: git clone https://github.com/outis1one/ubuntu-post-install.git -cd ubuntu-post-install -sudo ./setup.sh +cp -r ubuntu-post-install /media/user/DRIVE/ + +# On every new box — plug in USB, run: +sudo bash /media/$(whoami)/DRIVE/ubuntu-post-install/bootstrap.sh ``` +No auth, no internet needed for the scripts. The bootstrap detects it is +running from the repo and copies it to `~/ubuntu-post-install` before +launching the wizard, so the USB can be unplugged once setup starts. + +**Private repo — PAT (alternative):** +```bash +sudo bash bootstrap.sh --pat ghp_xxxxxxxxxxxxxxxxxxxx +``` +Use a fine-grained read-only PAT scoped to just this repo (Contents: Read). +The PAT is stripped from the stored remote URL after cloning. ## Usage diff --git a/bootstrap.sh b/bootstrap.sh index 0e79a28..a053159 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,23 +1,39 @@ #!/bin/bash # bootstrap.sh — get and run ubuntu-post-install on a fresh system. # -# One command to paste into a new Ubuntu box: -# curl -fsSL https://raw.githubusercontent.com/outis1one/ubuntu-post-install/main/bootstrap.sh | sudo bash +# THREE ways to use this: # -# What it does: -# 1. Installs git if missing (the only hard dependency) -# 2. Clones (or updates) the repo to ~/ubuntu-post-install -# 3. Launches the interactive setup wizard +# 1. Public repo — paste on any new box (internet required): +# curl -fsSL https://raw.githubusercontent.com/outis1one/ubuntu-post-install/main/bootstrap.sh | sudo bash +# +# 2. Private repo — copy just this file, supply a fine-grained read-only PAT: +# sudo bash bootstrap.sh --pat ghp_xxxxxxxxxxxxxxxxxxxx +# +# 3. USB / offline — copy the WHOLE REPO to a thumb drive, run from there +# (no auth, no internet needed for the scripts themselves): +# sudo bash /media/user/DRIVE/ubuntu-post-install/bootstrap.sh +# +# Option 3 is the recommended approach for private repos: clone once on a +# connected machine, put the directory on a USB drive, done. set -euo pipefail REPO_URL="https://github.com/outis1one/ubuntu-post-install.git" -DEST="${HOME:-/root}/ubuntu-post-install" # Resolve actual user home when running under sudo +ACTUAL_HOME="${HOME:-/root}" if [ -n "${SUDO_USER:-}" ]; then ACTUAL_HOME="$(getent passwd "$SUDO_USER" | cut -d: -f6)" - DEST="$ACTUAL_HOME/ubuntu-post-install" fi +DEST="$ACTUAL_HOME/ubuntu-post-install" + +# Parse --pat flag +PAT="" +for arg in "$@"; do + case "$arg" in + --pat) shift; PAT="${1:-}" ;; + --pat=*) PAT="${arg#--pat=}" ;; + esac +done echo "" echo "╔══════════════════════════════════════════════════════════════╗" @@ -25,23 +41,49 @@ echo "║ ubuntu-post-install · bootstrap ║" echo "╚══════════════════════════════════════════════════════════════╝" echo "" -# 1) Ensure git is available +# ── Option 3: already running from inside the repo ─────────────────────────── +# If setup.sh is sitting next to this script, we have everything we need. +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd || echo "")" +if [ -f "${SCRIPT_DIR}/setup.sh" ]; then + echo " Running from local copy at $SCRIPT_DIR" + echo " (No git or internet needed)" + echo "" + # Copy to home so the install persists after the USB is removed + if [ "$SCRIPT_DIR" != "$DEST" ]; then + echo " Copying to $DEST for future use..." + cp -r "$SCRIPT_DIR" "$DEST" 2>/dev/null \ + && chown -R "${SUDO_USER:-$(id -un)}:" "$DEST" 2>/dev/null || true + echo "" + fi + exec bash "${SCRIPT_DIR}/setup.sh" +fi + +# ── Options 1 & 2: clone from GitHub ───────────────────────────────────────── if ! command -v git >/dev/null 2>&1; then - echo "Installing git..." + echo " Installing git..." apt-get update -qq && apt-get install -y git fi -# 2) Clone or update +# Build clone URL (with PAT if supplied) +CLONE_URL="$REPO_URL" +if [ -n "$PAT" ]; then + CLONE_URL="https://${PAT}@github.com/${REPO_URL#https://github.com/}" +fi + if [ -d "$DEST/.git" ]; then - echo "Repo already exists at $DEST — pulling latest..." + echo " Repo already exists at $DEST — pulling latest..." git -C "$DEST" pull --ff-only || echo " (pull failed — continuing with existing version)" else - echo "Cloning to $DEST ..." - git clone "$REPO_URL" "$DEST" + echo " Cloning to $DEST ..." + git clone "$CLONE_URL" "$DEST" + # Remove PAT from stored remote URL so it isn't saved in plain text + if [ -n "$PAT" ]; then + git -C "$DEST" remote set-url origin "$REPO_URL" + fi fi echo "" -echo "Launching setup..." +echo " Launching setup..." echo "" exec bash "$DEST/setup.sh" From 39280d71cb50a7a1600485a5670eafa84bece60a Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 4 Jun 2026 01:08:42 +0000 Subject: [PATCH 2/3] README: document USB prep via GitHub ZIP download MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous USB instructions assumed git was available. Added step-by-step for the no-git path: GitHub ZIP download → unzip → copy to USB → run bootstrap.sh. Includes the Ubuntu auto-mount path tip for finding the drive name. Folder name note (ubuntu-post-install-main from ZIP) added. https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG --- README.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index b83203b..4c1ca6e 100644 --- a/README.md +++ b/README.md @@ -10,18 +10,24 @@ install exactly what you need — interactively or by name. curl -fsSL https://raw.githubusercontent.com/outis1one/ubuntu-post-install/main/bootstrap.sh | sudo bash ``` -**Private repo — USB thumb drive (recommended):** -```bash -# Once, on any connected machine: -git clone https://github.com/outis1one/ubuntu-post-install.git -cp -r ubuntu-post-install /media/user/DRIVE/ +**USB thumb drive — works for public or private repos:** -# On every new box — plug in USB, run: -sudo bash /media/$(whoami)/DRIVE/ubuntu-post-install/bootstrap.sh +Prepare the USB once on any machine (no git required): +1. Go to the repo on GitHub → green **Code** button → **Download ZIP** +2. Unzip it — you'll get a folder called `ubuntu-post-install-main` +3. Copy that folder to your USB drive + +On every new box — plug in USB, open a terminal, run: +```bash +sudo bash /media/$(whoami)/DRIVENAME/ubuntu-post-install-main/bootstrap.sh ``` -No auth, no internet needed for the scripts. The bootstrap detects it is -running from the repo and copies it to `~/ubuntu-post-install` before -launching the wizard, so the USB can be unplugged once setup starts. +`bootstrap.sh` detects it is running from inside the repo, copies everything +to `~/ubuntu-post-install`, then launches the wizard — so the USB can be +unplugged once setup starts. No auth, no internet needed for the scripts +themselves (services still pull packages and Docker images over the network). + +> **Finding your drive name:** Ubuntu mounts USB drives at `/media/USERNAME/DRIVENAME`. +> Run `ls /media/$(whoami)/` right after plugging in to see it. **Private repo — PAT (alternative):** ```bash From 8ffebe9a5a0d171138ee9f111c59277c2f874c2f Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 4 Jun 2026 01:14:54 +0000 Subject: [PATCH 3/3] bootstrap: self-elevate sudo; document double-click workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added exec sudo bash self-elevation so bootstrap.sh works correctly when double-clicked ("Run in Terminal") without the user needing to prefix sudo. If already root, the check is a no-op. Removed bootstrap.desktop — too fragile across desktop environments. README now covers both "Open in Terminal" and double-click paths. https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG --- README.md | 19 +++++++++---------- bootstrap.sh | 5 +++++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4c1ca6e..6574263 100644 --- a/README.md +++ b/README.md @@ -17,17 +17,16 @@ Prepare the USB once on any machine (no git required): 2. Unzip it — you'll get a folder called `ubuntu-post-install-main` 3. Copy that folder to your USB drive -On every new box — plug in USB, open a terminal, run: -```bash -sudo bash /media/$(whoami)/DRIVENAME/ubuntu-post-install-main/bootstrap.sh -``` -`bootstrap.sh` detects it is running from inside the repo, copies everything -to `~/ubuntu-post-install`, then launches the wizard — so the USB can be -unplugged once setup starts. No auth, no internet needed for the scripts -themselves (services still pull packages and Docker images over the network). +On every new box: +1. Plug in the USB — it opens in the file manager +2. Navigate into the `ubuntu-post-install-main` folder +3. **Either:** + - Right-click inside the folder → **Open in Terminal** → type `bash bootstrap.sh` + - **Or** double-click `bootstrap.sh` → if prompted, choose **Run in Terminal** -> **Finding your drive name:** Ubuntu mounts USB drives at `/media/USERNAME/DRIVENAME`. -> Run `ls /media/$(whoami)/` right after plugging in to see it. +The script asks for your password if needed. It detects it is running from +inside the repo, copies everything to `~/ubuntu-post-install`, then launches +the wizard — the USB can be unplugged once setup starts. **Private repo — PAT (alternative):** ```bash diff --git a/bootstrap.sh b/bootstrap.sh index a053159..af9e050 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -17,6 +17,11 @@ # connected machine, put the directory on a USB drive, done. set -euo pipefail +# Self-elevate: if double-clicked or run without sudo, ask for password. +if [ "$(id -u)" -ne 0 ]; then + exec sudo bash "$0" "$@" +fi + REPO_URL="https://github.com/outis1one/ubuntu-post-install.git" # Resolve actual user home when running under sudo