Compare commits

4 Commits

Author SHA1 Message Date
Blake Ridgway
0817d6a815 feat: Debian prep hardening, verify script, and quality pass
- 00-system-prep.sh: bootstrap sudo when run as root; on Debian enable
  contrib/non-free-firmware (SKIP_NONFREE to opt out) + install needrestart
- scripts/verify-debian.sh: non-destructive post-install sanity checker
  (exit 0/1) covering OS, tools, Debian renames, upstream tooling,
  .NET/Podman/Postgres, groups, flatpak, dotfile symlinks
- 01-package-install.sh: auto-detect current Kubernetes minor from upstream
  (fallback v1.36, override K8S_MINOR) instead of stale v1.32 pin
- fix shellcheck findings (SC2155, SC2207, SC2088); all scripts clean at
  warning severity
- docs: fold decisions/status into plan; README lists new tools
2026-09-02 16:32:40 -05:00
Blake Ridgway
ae72614636 chore: remove duplicate Go PATH lines in rc files; update self-symlink targets to /home/blake 2026-09-02 16:29:54 -05:00
Blake Ridgway
e885584f71 feat: retool setup scripts as Debian 13-first (keep Fedora support)
- main-setup.sh: sudo/root preflight for fresh Debian installs; offer
  distro-agnostic 03-dotnet-setup.sh on all supported distros
- 01-package-install.sh: Debian package renames (bind9-dnsutils), batcat
  symlink, libvirt/QEMU stack; vendor repos for gh/terraform/kubectl +
  k9s/minikube binaries (not in Debian main); keep dnf path for Fedora
- 02-dev-tools-setup.sh: PEP 668 fallback for pynvim pip install
- 03-fedora-dotnet-setup.sh -> 03-dotnet-setup.sh: .NET SDK via official
  dotnet-install.sh (no MS repo), PostgreSQL + Podman/podman-docker
- zshrc: purge dead oh-my-zsh references (prompt is Oh-My-Posh)
- README: Debian 13 first-class; docs: record decisions + status
2026-09-02 16:27:02 -05:00
Blake Ridgway
e2bb3a956a docs: add Debian 13 (trixie) migration plan 2026-09-02 16:20:23 -05:00
12 changed files with 797 additions and 313 deletions

View File

@@ -10,52 +10,53 @@ Run the main setup script to install software, configure development tools, and
./main-setup.sh ./main-setup.sh
``` ```
The script will automatically detect your Linux distribution (Fedora, Ubuntu, Debian, etc.) and use the appropriate package manager. The script will automatically detect your Linux distribution (Debian 13 "trixie" is the primary target; Ubuntu and Fedora also work) and use the appropriate package manager (`apt` or `dnf`).
## What Gets Installed ## What Gets Installed
### Core Packages ### Core Packages (distro packages)
- Development tools: `git`, `gh`, `curl`, `wget`, `ripgrep`, `fd-find` - Development tools: `git`, `curl`, `wget`, `ripgrep`, `fd-find`, `bat`, `eza`
- System utilities: `btop`, `fastfetch`, `zsh`, `flatpak` - System utilities: `btop`, `zsh`, `tmux`, `fzf`, `zoxide`, `flatpak`
- Virtualization: `virt-manager` - Virtualization (KVM): `virt-manager` + libvirt/QEMU stack
- Python: `python3`, `python3-pip` - Python: `python3`, `python3-pip`
- Networking: `nmap`, `mtr`, `tcpdump`, `socat`, `whois`, `iperf3`, `traceroute` - Networking: `nmap`, `mtr`, `tcpdump`, `socat`, `whois`, `iperf3`, `traceroute`, `bind9-dnsutils`
- Cloud / DevOps: `kubectl`, `k9s`, `minikube`, `terraform`, `helm`, `direnv` - HTTP: `httpie`
- HTTP: `curl`, `httpie` - DevOps helpers: `ansible`, `direnv`, `jq`, `tldr`, `unzip`
### Development Environment ### Upstream Tooling (installed by 01)
- **Neovim** (latest version from GitHub) `gh` (GitHub CLI), `terraform`, `kubectl`, `k9s` and `minikube` are **not packaged in Debian**, so `01-package-install.sh` adds the official vendor apt repositories (GitHub CLI, HashiCorp, `pkgs.k8s.io`) and installs `k9s`/`minikube` from upstream binaries. On Fedora these are a best-effort `dnf` install (usually COPR/manual).
- **Hack Nerd Font** for terminal
- **Oh My Zsh** shell framework ### Development Environment (02)
- **Starship** prompt - **Neovim** (latest from GitHub, installed to `/opt/nvim`)
- **Hack Nerd Font** for terminals
- **Go** toolchain (`/usr/local/go`)
- **Rust** toolchain via rustup - **Rust** toolchain via rustup
- **Oh-My-Posh** prompt (`~/.local/bin`)
- **Helm**, **kubectx/kubens**, **stern**, **dive**, **trivy**, **AWS CLI v2**
### Fedora-Specific (.NET Development) ### .NET / Backend Services (03, optional)
On Fedora systems, additional packages are installed: Distro-agnostic .NET development environment:
- **Visual Studio Code** - **.NET SDK** via the official `dotnet-install.sh` (no vendor repository needed)
- **.NET SDK** (with Microsoft repository)
- **PostgreSQL** server and tools - **PostgreSQL** server and tools
- **Docker** (moby-engine) with Docker Compose - **Podman** + `podman-compose` + `podman-docker` (Docker-CLI-compatible containers)
- VS Code is installed as a **Flatpak** (`com.visualstudio.code`)
### Flatpak Applications ### Flatpak Applications
- Bitwarden - Bolt, Bitwarden, Discord, Teams for Linux, Flatseal
- Flatseal - Steam, ProtonUp-Qt (pupgui2), VLC
- Steam - Visual Studio Code, Podman Desktop
- ProtonUp-Qt - Signal, Thunderbird
- Rider
- Veloren Airshipper
- Visual Studio Code
- VLC Media Player
## Modular Architecture ## Modular Architecture
The setup is broken down into focused scripts: The setup is broken down into focused scripts:
- `00-system-prep.sh` - System updates and Flathub setup - `00-system-prep.sh` - System updates, `sudo` bootstrap, Debian `contrib`/`non-free-firmware` + `needrestart`, Flathub setup
- `01-package-install.sh` - Core packages and Flatpak apps - `01-package-install.sh` - Core packages, upstream tooling, and Flatpak apps
- `02-dev-tools-setup.sh` - Development tools (Neovim, Go, Rust, Helm, kubectx, stern, dive, trivy, AWS CLI) - `02-dev-tools-setup.sh` - Development tools (Neovim, Go, Rust, Oh-My-Posh, Helm, kubectx, stern, dive, trivy, AWS CLI)
- `03-fedora-dotnet-setup.sh` - Fedora-specific .NET environment - `03-dotnet-setup.sh` - .NET SDK + PostgreSQL + Podman (distro-agnostic)
- `04-config-symlinks.sh` - Dotfile symlinking - `04-config-symlinks.sh` - Dotfile symlinking
- `verify-debian.sh` - Post-install sanity checker (run manually, no root needed)
You can run individual scripts if you only need specific components. You can run individual scripts if you only need specific components.
@@ -97,14 +98,22 @@ After running the setup, remember to:
ssh-keygen -t ed25519 -C ${USER}@$(hostname --fqdn) ssh-keygen -t ed25519 -C ${USER}@$(hostname --fqdn)
``` ```
3. **Install Powerlevel10k gitstatus (if using):** 3. **Set zsh as your login shell:**
```bash ```bash
~/.oh-my-zsh/custom/themes/powerlevel10k/gitstatus/install -f chsh -s /usr/bin/zsh
``` ```
4. **Log out and back in** for Docker group changes to take effect (Fedora) 4. **Add yourself to virtualization groups** (log out/in afterward):
```bash
sudo usermod -aG libvirt,kvm $USER
```
5. **Install VS Code extensions** (Fedora): 5. **(Optional) enable the rootless Podman API socket:**
```bash
systemctl --user enable --now podman.socket
```
6. **Install VS Code extensions:**
- C# Dev Kit - C# Dev Kit
- GitLens - GitLens
- Prettier - Prettier
@@ -112,9 +121,9 @@ After running the setup, remember to:
## Supported Distributions ## Supported Distributions
- **Fedora** (with full .NET development environment) - **Debian 13 "trixie"** (primary target — full setup incl. upstream tooling, .NET, and backend services)
- **Ubuntu/Debian** (core packages and development tools) - **Ubuntu / Pop!_OS** (apt; core + development tools)
- **Pop!_OS** (core packages and development tools) - **Fedora** (dnf; core + development tools, best-effort upstream tooling)
## Customization ## Customization

View File

@@ -0,0 +1,119 @@
# Debian 13 ("trixie") Migration Plan
Goal: make this dotfiles repo fully suited for **Debian 13 (trixie)** so a fresh Debian install can be brought up to the same state as the current Fedora setup.
Working branch: `debian-13` (base: `master`).
> **Status: implemented on this branch** (see `git log` on `debian-13`). Recorded decisions below.
### Decisions (user-confirmed)
1. **Container runtime:** Podman (`podman`, `podman-compose`, `podman-docker` shim) — no Docker CE / moby-engine.
2. **VS Code:** keep the **Flatpak** install (`com.visualstudio.code`); no MS apt/rpm repo for the editor.
3. **.NET install:** official **`dotnet-install.sh`** (channel `STS`, overridable via `DOTNET_CHANNEL`) — no Microsoft vendor repo.
4. **oh-my-zsh:** **purge** its remnants from `zshrc` (now plain zsh + Oh-My-Posh).
5. **Scope:** **full rework** applied to `main-setup.sh` and all `scripts/*.sh`, `zshrc`, `README.md`.
---
## 1. Summary of what changes
The repo is mostly distro-agnostic already (shell rc files, aliases, nvim via NvChad + Mason, Flatpak list, GitHub-downloaded dev tools). The Fedora coupling is concentrated in:
1. **Package manager + detection** (`main-setup.sh`, scripts 00/01) — mostly *works* for Debian already since detection returns `debian``apt`, but package *names* and repos differ.
2. **Fedora-only .NET script** (`03-fedora-dotnet-setup.sh`) — needs a distro-agnostic (or Debian-specific) counterpart.
3. **README + comments** referencing Fedora-only steps/groups.
4. Several **Debian 13 gotchas** (PEP 668 pip, `dnsutils``bind9-dnsutils`, `bat``batcat`, missing upstream-only tools like `kubectl`/`gh`/`terraform`/`minikube`/`k9s`, `sudo` not always present, Microsoft repo for trixie).
---
## 2. Debian 13 facts that drive the changes
| Topic | Fedora behavior | Debian 13 (trixie) behavior |
|---|---|---|
| Package manager | `dnf` / `rpm -q` | `apt` / `dpkg-query` (already handled) |
| `sudo` | preinstalled | **not always installed** on fresh installs |
| pip | system pip installs OK | **PEP 668** blocks `pip install --user` (`externally-managed-environment`) |
| `dnsutils` | `bind-utils` | package renamed to `bind9-dnsutils` (trixie) |
| `bat` | binary `bat` | package ships **`batcat`**, needs `bat` symlink/alias |
| `fd-find` | binary `fd` | binary **`fdfind`**, script already symlinks |
| `.NET` | MS repo for Fedora + `moby-engine` | MS repo for `debian/13` (`packages-microsoft-prod.deb`) or `dotnet-install.sh` |
| Docker | `moby-engine` | `docker.io` (Debian) or `docker-ce` (Docker repo) |
| PostgreSQL | needs `postgresql-setup --initdb` | cluster auto-created by package scripts |
| `kubectl`/`gh`/`terraform`/`minikube`/`k9s` | in COPR/DNF repos | **not in Debian main** → add upstream apt repos or download `.deb` |
| `chsh` | `util-linux-user` package | in base util-linux; needs password/sudo to change shell |
| libvirt group | `libvirt` | same `libvirt` group (add user) |
| default shell | zsh setup via OhMyZsh scripts | zsh not default; needs `chsh` after install |
---
## 3. File-by-file status (as of 2026-09-02)
### `main-setup.sh` — DONE
- [x] `detect_linux_distro()` returns `debian` for trixie; `PACKAGE_MANAGER=apt`.
- [x] Preflight: if non-root and `sudo` missing → clear guidance (run as root or install `sudo`); `sudo -n` note.
- [x] `.NET` prompt is now distro-agnostic → runs `03-dotnet-setup.sh` on every supported distro.
### `scripts/00-system-prep.sh` — DONE
- [x] `sudo` bootstrap when running as root on a fresh install (apt/dnf).
- [x] Debian: idempotently add `contrib` + `non-free-firmware` to `debian.sources` (deb822) or legacy `sources.list` (skip with `SKIP_NONFREE=1`); `needrestart` installed on apt.
### `scripts/01-package-install.sh` — DONE
- [x] Split base vs distro lists; `dnsutils``bind9-dnsutils`; `bat``batcat` symlink; libvirt/QEMU stack (`libvirt-daemon-system`, `libvirt-clients`, `qemu-system-x86`, `virtinst`, `bridge-utils`); prereqs (`sudo`, `ca-certificates`, `gnupg`, `curl`).
- [x] `setup_upstream_tooling()`: vendor repos for `gh` (GitHub CLI), `terraform` (HashiCorp), `kubectl` (pkgs.k8s.io); `k9s` (GitHub tarball) + `minikube` (official `.deb`) on apt; best-effort `dnf` on Fedora.
- [x] Kubernetes minor auto-detected from the latest k8s release (fallback `v1.36`; override with `K8S_MINOR`).
- [x] Flatpak list unchanged (VS Code stays Flatpak per decision).
### `scripts/02-dev-tools-setup.sh` — DONE
- [x] `pynvim` PEP 668 fix: try `pip install --user`, fall back to `--break-system-packages`.
### `scripts/03-fedora-dotnet-setup.sh` → `03-dotnet-setup.sh` — DONE
- [x] Renamed to `03-dotnet-setup.sh`, distro-agnostic (apt/dnf).
- [x] `.NET SDK` via official `dotnet-install.sh` (channel `STS`, override `DOTNET_CHANNEL`) → `~/.dotnet`, PATH added to `bashrc`/`zshrc`.
- [x] PostgreSQL: auto-cluster on Debian; `--initdb` only on Fedora.
- [x] Containers = **Podman** + `podman-compose` + `podman-docker` (Docker-CLI shim). No MS repo, no moby/docker-ce.
### `scripts/04-config-symlinks.sh` — no changes required
- [x] Pure symlinking; distro-agnostic as-is.
### Shell rc files (`bashrc`, `zshrc`, aliases) — DONE
- [x] `zshrc` oh-my-zsh remnants purged (plain zsh + Oh-My-Posh).
- [x] Duplicate Go `PATH` lines (appended by an old 02 run) removed from `bashrc`/`zshrc`.
- [x] `nvim/nvim` + `nushell/nushell` self-symlink targets updated to `/home/blake`.
### `README.md` — DONE
- [x] Debian 13 first-class; feature lists, modular architecture, post-install steps, and supported-distro matrix updated (Podman, Flatpak VS Code, libvirt/kvm groups, rootless podman socket).
### Tooling / quality — DONE (this pass)
- [x] **`scripts/verify-debian.sh`** added — non-destructive end-to-end sanity checker (OS, binaries, Debian renames, upstream tools, dev tools, .NET/Podman/Postgres, groups, flatpak, dotfile symlinks); exit code 0/1.
- [x] **ShellCheck** (v0.11.0) run on all scripts — clean at warning severity (remaining notes are pre-existing info/style only).
---
## 4. Decisions (confirmed)
1. **Container runtime:** Podman (`podman-docker` provides the `docker` shim so existing aliases keep working).
2. **VS Code:** Flatpak `com.visualstudio.code` (no MS editor repo).
3. **.NET:** official `dotnet-install.sh` (no MS vendor repo).
4. **oh-my-zsh:** purged from `zshrc`.
5. **Scope:** full rework (applied).
## 5. Remaining work / next steps
- [ ] **Test end-to-end on a real Debian 13 box**: run `./main-setup.sh`, then `bash scripts/verify-debian.sh`, and fix anything the checker flags.
- [ ] Decide whether to keep Fedora/dnf support long-term or trim it later (kept for now).
- [ ] Merge `debian-13``master` after validation.
---
## 6. Verification checklist (on Debian 13)
```bash
# sanity
cat /etc/os-release # expect ID=debian, VERSION_CODENAME=trixie
./main-setup.sh # expect "Using Package Manager: apt"
bat --version # symlink check
fd --version # symlink check
dig example.com # bind9-dnsutils
python3 -m pip install --user pynvim # must not hit PEP 668 error
dotnet --list-sdks
docker ps # group membership
virsh list # libvirt group
```

View File

@@ -54,7 +54,8 @@ prompt_yes_no() {
# Function to run a script if approved # Function to run a script if approved
run_script() { run_script() {
local script_path="$1" local script_path="$1"
local script_name="$(basename "$script_path")" local script_name
script_name="$(basename "$script_path")"
if ! bash "$script_path"; then if ! bash "$script_path"; then
echo "ERROR: $script_name failed." echo "ERROR: $script_name failed."
@@ -87,6 +88,23 @@ echo "Script Root Directory: $SCRIPT_ROOT_DIR"
echo "--------------------------------------------------" echo "--------------------------------------------------"
echo "" echo ""
# --- Preflight: ensure we can elevate privileges ---
# A fresh Debian install often has no sudo configured for the user yet.
if [ "$(id -u)" -ne 0 ]; then
if ! command -v sudo &>/dev/null; then
echo "ERROR: 'sudo' is not installed and you are not root."
echo "On a fresh Debian system, either:"
echo " 1. Run this script as root: su -c './main-setup.sh'"
echo " 2. Install sudo first (as root): apt install -y sudo && usermod -aG sudo \$USER"
echo " then log out/in and re-run this script."
exit 1
fi
if ! sudo -n true 2>/dev/null; then
echo "NOTE: sudo is present but may prompt for your password."
echo " Run 'sudo -v' first if you want to avoid interactive prompts."
fi
fi
# --- Prompt for Setup Options --- # --- Prompt for Setup Options ---
echo "Select which setup tasks to run:" echo "Select which setup tasks to run:"
@@ -96,11 +114,8 @@ prompt_yes_no "Run system preparation (00-system-prep.sh)?" && RUN_SYSTEM_PREP=1
prompt_yes_no "Run package installation (01-package-install.sh)?" && RUN_PKG_INSTALL=1 || RUN_PKG_INSTALL=0 prompt_yes_no "Run package installation (01-package-install.sh)?" && RUN_PKG_INSTALL=1 || RUN_PKG_INSTALL=0
prompt_yes_no "Run dev tools setup (02-dev-tools-setup.sh)?" && RUN_DEV_TOOLS=1 || RUN_DEV_TOOLS=0 prompt_yes_no "Run dev tools setup (02-dev-tools-setup.sh)?" && RUN_DEV_TOOLS=1 || RUN_DEV_TOOLS=0
if [ "$DISTRO" == "fedora" ]; then # 03-dotnet-setup.sh is distro-agnostic (dotnet-install.sh) so offer it everywhere
prompt_yes_no "Run Fedora .NET setup (03-fedora-dotnet-setup.sh)?" && RUN_DOTNET=1 || RUN_DOTNET=0 prompt_yes_no "Run .NET / backend services setup (03-dotnet-setup.sh)?" && RUN_DOTNET=1 || RUN_DOTNET=0
else
RUN_DOTNET=0
fi
prompt_yes_no "Run config symlinks setup (04-config-symlinks.sh)?" && RUN_CONFIG_SYMLINKS=1 || RUN_CONFIG_SYMLINKS=0 prompt_yes_no "Run config symlinks setup (04-config-symlinks.sh)?" && RUN_CONFIG_SYMLINKS=1 || RUN_CONFIG_SYMLINKS=0
@@ -138,9 +153,9 @@ if [ $RUN_DEV_TOOLS -eq 1 ]; then
fi fi
if [ $RUN_DOTNET -eq 1 ]; then if [ $RUN_DOTNET -eq 1 ]; then
echo "Executing 03-fedora-dotnet-setup.sh..." echo "Executing 03-dotnet-setup.sh..."
if ! run_script "${SCRIPTS_DIR}/03-fedora-dotnet-setup.sh"; then if ! run_script "${SCRIPTS_DIR}/03-dotnet-setup.sh"; then
echo "ERROR: 03-fedora-dotnet-setup.sh failed." echo "ERROR: 03-dotnet-setup.sh failed."
fi fi
echo "--------------------------------------------------" echo "--------------------------------------------------"
fi fi

View File

@@ -1 +1 @@
/home/bridgway/dotfiles/nvim /home/blake/dotfiles/nvim

View File

@@ -1,7 +1,8 @@
#!/bin/bash #!/bin/bash
# 00-system-prep.sh # 00-system-prep.sh
# Updates system and sets up Flathub. # Updates system, bootstraps sudo, enables Debian extra components,
# and sets up Flathub.
# Relies on DISTRO and PACKAGE_MANAGER being set by the caller. # Relies on DISTRO and PACKAGE_MANAGER being set by the caller.
echo "--- Starting System Preparation ---" echo "--- Starting System Preparation ---"
@@ -11,6 +12,27 @@ if [ -z "$DISTRO" ] || [ -z "$PACKAGE_MANAGER" ]; then
exit 1 exit 1
fi fi
# Ensure 'sudo' exists so all later scripts can use it.
# - Running as root on a fresh Debian: installing sudo lets root invoke
# `sudo ...` directly (root is not subject to sudoers).
# - Non-root users without sudo are handled by main-setup.sh's preflight.
if ! command -v sudo &>/dev/null; then
echo "sudo not found. Bootstrapping it..."
if [ "$(id -u)" -eq 0 ]; then
if [ "$PACKAGE_MANAGER" == "apt" ]; then
apt-get update && apt-get install -y sudo
elif [ "$PACKAGE_MANAGER" == "dnf" ]; then
dnf install -y sudo
fi
echo "sudo installed. Add your normal user to the sudo group if desired:"
echo " usermod -aG sudo <your-user> (then log out/in)"
else
echo "ERROR: 'sudo' is required but missing, and you are not root."
echo "As root, run: apt install -y sudo && usermod -aG sudo \$USER"
exit 1
fi
fi
# Update system before installing packages # Update system before installing packages
echo "Updating system packages..." echo "Updating system packages..."
if [ "$PACKAGE_MANAGER" == "dnf" ]; then if [ "$PACKAGE_MANAGER" == "dnf" ]; then
@@ -21,6 +43,66 @@ else
echo "WARNING: Unknown package manager '$PACKAGE_MANAGER'. Skipping system update." echo "WARNING: Unknown package manager '$PACKAGE_MANAGER'. Skipping system update."
fi fi
# ---------------------------------------------------------------------------
# Debian extras (only on Debian; idempotent)
# ---------------------------------------------------------------------------
if [ "$DISTRO" == "debian" ]; then
# Enable contrib + non-free-firmware components on the main archive.
# Needed for some WiFi/GPU firmware and non-free tooling. Skip with SKIP_NONFREE=1.
if [ -z "$SKIP_NONFREE" ]; then
echo "Enabling 'contrib' and 'non-free-firmware' apt components..."
_enable_debian_components() {
local f="/etc/apt/sources.list.d/debian.sources"
local tmp
# deb822 format used by Debian 12+ (trixie ships debian.sources)
if [ -f "$f" ]; then
tmp="$(mktemp)"
if awk '
/^URIs:[[:space:]]/ { in_archive = ($0 ~ /deb\.debian\.org\/debian/) }
in_archive && /^Components:/ && $0 !~ /contrib/ {
print $0 " contrib non-free-firmware"
in_archive = 0
next
}
{ print }
' "$f" > "$tmp"; then
if ! diff -q "$f" "$tmp" >/dev/null; then
sudo cp "$f" "${f}.bak"
sudo mv "$tmp" "$f"
echo " -> updated ${f}"
else
rm -f "$tmp"
echo " -> components already present in ${f}"
fi
else
rm -f "$tmp"
echo "WARNING: could not parse ${f}; skipping component changes."
fi
fi
# Legacy single-line /etc/apt/sources.list fallback
if [ -f /etc/apt/sources.list ] \
&& grep -qE '^deb[[:space:]]+https?://deb\.debian\.org/debian' /etc/apt/sources.list \
&& ! grep -qE '^deb[[:space:]]+https?://deb\.debian\.org/debian[^#]*non-free-firmware' /etc/apt/sources.list; then
sudo sed -i -E 's/^(deb[[:space:]]+https?:\/\/deb\.debian\.org\/debian[^#]*main)([[:space:]]|$)/\1 contrib non-free-firmware/' /etc/apt/sources.list
echo " -> updated /etc/apt/sources.list"
fi
sudo apt update
}
_enable_debian_components
else
echo "SKIP_NONFREE is set - leaving apt components unchanged."
fi
# needrestart prompts (or auto-restarts) services after library upgrades.
if ! dpkg-query -W -f='${Status}' needrestart 2>/dev/null | grep -q "ok installed"; then
echo "Installing needrestart..."
sudo apt install -y needrestart
else
echo "needrestart already installed."
fi
fi
# Setup Flatpak # Setup Flatpak
echo "Setting up Flathub repository..." echo "Setting up Flathub repository..."
if command -v flatpak &> /dev/null; then if command -v flatpak &> /dev/null; then

View File

@@ -12,6 +12,9 @@ if [ -z "$DISTRO" ] || [ -z "$PACKAGE_MANAGER" ]; then
fi fi
# Define base package list # Define base package list
# Base packages available in BOTH Debian and Fedora repositories.
# NOTE: gh, kubectl, minikube, k9s, terraform are NOT in Debian main —
# they are handled later in setup_upstream_tooling() via vendor repos/.deb.
BASE_PACKAGE_LIST=( BASE_PACKAGE_LIST=(
ansible ansible
bat bat
@@ -23,13 +26,9 @@ BASE_PACKAGE_LIST=(
flatpak flatpak
fzf fzf
git git
gh
httpie httpie
iperf3 iperf3
jq jq
k9s
kubectl
minikube
mtr mtr
nmap nmap
python3 python3
@@ -37,7 +36,6 @@ BASE_PACKAGE_LIST=(
ripgrep ripgrep
socat socat
tcpdump tcpdump
terraform
tldr tldr
tmux tmux
traceroute traceroute
@@ -57,20 +55,63 @@ if [ "$PACKAGE_MANAGER" == "dnf" ]; then
"fontconfig-devel" # for fc-cache "fontconfig-devel" # for fc-cache
"nmap-ncat" # netcat utility "nmap-ncat" # netcat utility
"openssl-devel" # for various compilations "openssl-devel" # for various compilations
"util-linux-user" # for chsh, if needed by OhMyZsh script "util-linux-user" # for chsh (if needed)
) )
elif [ "$PACKAGE_MANAGER" == "apt" ]; then elif [ "$PACKAGE_MANAGER" == "apt" ]; then
DISTRO_SPECIFIC_PACKAGES+=( DISTRO_SPECIFIC_PACKAGES+=(
"dnsutils" "bind9-dnsutils" # dig/nslookup (replaces dnsutils on Debian 13+)
"bridge-utils" # virt-manager bridge networking
"ca-certificates" # HTTPS repo keys
"curl" # ensure present for repo bootstrapping
"gnupg" # apt keyring handling
"libfontconfig-dev" "libfontconfig-dev"
"libssl-dev" "libssl-dev"
"libvirt-clients" # virsh
"libvirt-daemon-system" # libvirtd daemon + default network
"netcat-openbsd" "netcat-openbsd"
"qemu-system-x86" # KVM/QEMU backend for virt-manager
"virtinst" # virt-install
) )
fi fi
# Combine package lists # Combine package lists
PACKAGE_LIST=("${BASE_PACKAGE_LIST[@]}" "${DISTRO_SPECIFIC_PACKAGES[@]}") PACKAGE_LIST=("${BASE_PACKAGE_LIST[@]}" "${DISTRO_SPECIFIC_PACKAGES[@]}")
PACKAGE_LIST=($(printf "%s\n" "${PACKAGE_LIST[@]}" | LC_ALL=C sort -u)) mapfile -t PACKAGE_LIST < <(printf "%s\n" "${PACKAGE_LIST[@]}" | LC_ALL=C sort -u)
# --- apt helpers ---------------------------------------------------------
_apt_is_installed() {
dpkg-query -W -f='${Status}' "$1" 2>/dev/null | grep -q "ok installed"
}
_apt_install() {
if _apt_is_installed "$1"; then
echo "$1 already installed."
return 0
fi
echo "Installing $1 (apt)..."
if sudo apt install -y "$1"; then
echo "$1 has been installed."
return 0
fi
echo "WARNING: Failed to install $1."
return 1
}
# debian/ubuntu codename, e.g. "trixie" (no lsb_release dependency)
_get_codename() {
. /etc/os-release
echo "$VERSION_CODENAME"
}
# uname -m -> Go/GitHub style arch token (amd64/arm64)
_get_upstream_arch() {
case "$(uname -m)" in
x86_64) echo "amd64" ;;
aarch64|arm64) echo "arm64" ;;
*) echo "unsupported" ;;
esac
}
FLATPAK_LIST=( FLATPAK_LIST=(
@@ -131,6 +172,132 @@ if [ "$PACKAGE_MANAGER" == "apt" ] && command -v fdfind &>/dev/null && ! command
fi fi
fi fi
# Post-install for bat on Debian/Ubuntu (package ships the binary as 'batcat')
if [ "$PACKAGE_MANAGER" == "apt" ] && command -v batcat &>/dev/null && ! command -v bat &>/dev/null; then
echo "Creating symlink for bat from batcat..."
sudo ln -sf /usr/bin/batcat /usr/local/bin/bat
fi
# ---------------------------------------------------------------------------
# Upstream-only tooling (NOT packaged in Debian main / Fedora base repos)
# ---------------------------------------------------------------------------
# gh -> GitHub CLI apt repository
# terraform -> HashiCorp apt repository
# kubectl -> Kubernetes (pkgs.k8s.io) apt repository
# k9s -> GitHub release tarball
# minikube -> official .deb from Google's release bucket
# On Fedora these are a best-effort dnf attempt (usually need COPR/manual).
# ---------------------------------------------------------------------------
_apt_add_gh_repo() {
[ -f /etc/apt/sources.list.d/github-cli.list ] && { echo "GitHub CLI repo already configured."; return 0; }
echo "Adding GitHub CLI apt repository..."
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
| sudo tee /usr/share/keyrings/githubcli-archive-keyring.gpg >/dev/null
sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
| sudo tee /etc/apt/sources.list.d/github-cli.list >/dev/null
}
_apt_add_hashicorp_repo() {
[ -f /etc/apt/sources.list.d/hashicorp.list ] && { echo "HashiCorp repo already configured."; return 0; }
echo "Adding HashiCorp apt repository..."
curl -fsSL https://apt.releases.hashicorp.com/gpg \
| sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
sudo chmod go+r /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(_get_codename) main" \
| sudo tee /etc/apt/sources.list.d/hashicorp.list >/dev/null
}
# Kubernetes apt repo. Auto-detects the latest stable minor from the
# kubernetes/kubernetes GitHub release feed, falling back to a pinned minor
# if the API is unreachable. Override explicitly with K8S_MINOR=...
K8S_MINOR_FALLBACK="v1.36"
_k8s_latest_minor() {
local tag minor
tag="$(curl -fsSL --max-time 10 https://api.github.com/repos/kubernetes/kubernetes/releases/latest \
| grep '"tag_name"' | cut -d'"' -f4)" || return 1
minor="${tag#v}" # e.g. 1.36.0
minor="${minor%.*}" # strip patch -> 1.36
echo "v${minor}"
}
_apt_add_kubernetes_repo() {
[ -f /etc/apt/sources.list.d/kubernetes.list ] && { echo "Kubernetes repo already configured."; return 0; }
K8S_MINOR="${K8S_MINOR:-$(_k8s_latest_minor || echo "$K8S_MINOR_FALLBACK")}"
echo "Adding Kubernetes apt repository (${K8S_MINOR})..."
curl -fsSL "https://pkgs.k8s.io/core:/stable:/${K8S_MINOR}/deb/Release.key" \
| sudo gpg --dearmor -o /usr/share/keyrings/kubernetes-archive-keyring.gpg
sudo chmod go+r /usr/share/keyrings/kubernetes-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://pkgs.k8s.io/core:/stable:/${K8S_MINOR}/deb/ /" \
| sudo tee /etc/apt/sources.list.d/kubernetes.list >/dev/null
}
_install_k9s_bin() {
command -v k9s &>/dev/null && { echo "k9s already installed."; return 0; }
local K9S_VERSION K9S_URL TMPDIR UPSTREAM_ARCH
UPSTREAM_ARCH="$(_get_upstream_arch)"
[ "$UPSTREAM_ARCH" = "unsupported" ] && { echo "WARNING: unsupported arch for k9s."; return 1; }
K9S_VERSION="$(curl -fsSL https://api.github.com/repos/derailed/k9s/releases/latest | grep '"tag_name"' | cut -d'"' -f4)"
K9S_URL="https://github.com/derailed/k9s/releases/download/${K9S_VERSION}/k9s_Linux_${UPSTREAM_ARCH}.tar.gz"
echo "Downloading k9s ${K9S_VERSION}..."
TMPDIR="$(mktemp -d)"
if curl -fsSL -L "${K9S_URL}" -o "${TMPDIR}/k9s.tar.gz"; then
tar -C "${TMPDIR}" -xzf "${TMPDIR}/k9s.tar.gz" k9s
sudo install -m755 "${TMPDIR}/k9s" /usr/local/bin/k9s
echo "k9s ${K9S_VERSION} installed to /usr/local/bin/k9s"
else
echo "WARNING: Failed to download k9s."
fi
rm -rf "${TMPDIR}"
}
_install_minikube_deb() {
command -v minikube &>/dev/null && { echo "minikube already installed."; return 0; }
local UPSTREAM_ARCH TMPDIR
UPSTREAM_ARCH="$(_get_upstream_arch)"
[ "$UPSTREAM_ARCH" = "unsupported" ] && { echo "WARNING: unsupported arch for minikube."; return 1; }
echo "Downloading minikube (.deb)..."
TMPDIR="$(mktemp -d)"
if curl -fsSL -L "https://storage.googleapis.com/minikube/releases/latest/minikube_latest_${UPSTREAM_ARCH}.deb" -o "${TMPDIR}/minikube.deb"; then
sudo dpkg -i "${TMPDIR}/minikube.deb" 2>/dev/null || sudo apt-get install -f -y
echo "minikube installed from .deb."
else
echo "WARNING: Failed to download minikube."
fi
rm -rf "${TMPDIR}"
}
setup_upstream_tooling() {
echo ""
echo "Installing upstream-only tooling (gh, terraform, kubectl, k9s, minikube)..."
if [ "$PACKAGE_MANAGER" == "apt" ]; then
_apt_add_gh_repo
_apt_add_hashicorp_repo
_apt_add_kubernetes_repo
echo "Refreshing apt after adding vendor repos..."
sudo apt update
_apt_install gh
_apt_install terraform
_apt_install kubectl
_install_k9s_bin
_install_minikube_deb
else
# dnf best-effort: these usually need COPR/manual installs on Fedora.
for upstream_pkg in gh terraform kubectl k9s minikube; do
if ! rpm -q "$upstream_pkg" &>/dev/null; then
echo "Attempting $upstream_pkg (dnf)..."
if ! sudo dnf install -y "$upstream_pkg"; then
echo "WARNING: $upstream_pkg unavailable in dnf repos — install it via COPR/manually."
fi
else
echo "$upstream_pkg already installed."
fi
done
fi
}
setup_upstream_tooling
echo "Installing Flatpak Applications..." echo "Installing Flatpak Applications..."
if command -v flatpak &> /dev/null; then if command -v flatpak &> /dev/null; then

View File

@@ -35,12 +35,19 @@ else
fi fi
# pynvim # pynvim
# On Debian 13+/Ubuntu 23.04+ the system python is PEP 668 'externally-managed',
# so a plain `pip install --user` is rejected. Fall back to --break-system-packages.
echo "Installing pynvim for Neovim Python support..." echo "Installing pynvim for Neovim Python support..."
if /usr/bin/python3 -m pip show pynvim &>/dev/null; then if /usr/bin/python3 -m pip show pynvim &>/dev/null; then
echo "pynvim already installed." echo "pynvim already installed."
else else
/usr/bin/python3 -m pip install --user pynvim if /usr/bin/python3 -m pip install --user pynvim; then
echo "pynvim installed for the current user." echo "pynvim installed for the current user."
elif /usr/bin/python3 -m pip install --user --break-system-packages pynvim; then
echo "pynvim installed for the current user (PEP 668 --break-system-packages fallback)."
else
echo "WARNING: Could not install pynvim. Install it inside your Neovim Python provider venv manually."
fi
fi fi
# Install Nerd Font (Hack) # Install Nerd Font (Hack)

162
scripts/03-dotnet-setup.sh Executable file
View File

@@ -0,0 +1,162 @@
#!/bin/bash
# 03-dotnet-setup.sh
# Sets up a .NET Development Environment (distro-agnostic).
# - .NET SDK via the official dotnet-install.sh (no vendor repo needed)
# - PostgreSQL (backend database)
# - Podman + podman-compose + podman-docker (Docker-CLI-compatible containers)
# Works on Debian/Ubuntu (apt) and Fedora/RHEL (dnf).
# Relies on DISTRO and PACKAGE_MANAGER being set by the caller (main-setup.sh),
# but falls back to auto-detection when run standalone.
echo "--- Starting .NET / Backend Services Setup ---"
if [ -z "$PACKAGE_MANAGER" ] || [ -z "$DISTRO" ]; then
if [ -f /etc/os-release ]; then
# shellcheck disable=SC1091
. /etc/os-release
DISTRO="$ID"
fi
case "$DISTRO" in
debian|ubuntu|pop) PACKAGE_MANAGER="apt" ;;
fedora|rhel|centos) PACKAGE_MANAGER="dnf" ;;
*) echo "WARNING: Unsupported distro '$DISTRO'. Some steps may fail." ;;
esac
echo "Auto-detected distribution: $DISTRO (package manager: $PACKAGE_MANAGER)"
fi
_apt_install() {
if ! dpkg-query -W -f='${Status}' "$1" 2>/dev/null | grep -q "ok installed"; then
echo "Installing $1 (apt)..."
sudo apt install -y "$1" || echo "WARNING: Failed to install $1."
else
echo "$1 already installed."
fi
}
_dnf_install() {
if ! rpm -q "$1" &>/dev/null; then
echo "Installing $1 (dnf)..."
sudo dnf install -y "$1" || echo "WARNING: Failed to install $1."
else
echo "$1 already installed."
fi
}
# Append a line to an rc file if not already present
_add_to_rc() {
local rcfile="$1" snippet="$2"
[ -f "$rcfile" ] || return 0
grep -qxF "$snippet" "$rcfile" 2>/dev/null || {
{ echo ""; echo "# added by 03-dotnet-setup.sh"; echo "$snippet"; } >> "$rcfile"
echo " -> updated ${rcfile}"
}
}
echo ""
echo "--------------------------------------------------"
echo "I. .NET SDK (via official dotnet-install.sh)"
echo "--------------------------------------------------"
# Channel: STS currently maps to .NET 10; LTS maps to .NET 8.
# Override at runtime: DOTNET_CHANNEL=LTS ./03-dotnet-setup.sh
DOTNET_CHANNEL="${DOTNET_CHANNEL:-STS}"
if command -v dotnet &>/dev/null || [ -x "$HOME/.dotnet/dotnet" ]; then
echo ".NET SDK already installed: $(dotnet --version 2>/dev/null || "$HOME/.dotnet/dotnet" --version)"
else
echo "Installing .NET SDK ($DOTNET_CHANNEL channel) via dotnet-install.sh..."
TMPDIR=$(mktemp -d)
curl -fsSL https://dot.net/v1/dotnet-install.sh -o "${TMPDIR}/dotnet-install.sh"
chmod +x "${TMPDIR}/dotnet-install.sh"
if bash "${TMPDIR}/dotnet-install.sh" --channel "$DOTNET_CHANNEL"; then
echo ".NET SDK installed to ~/.dotnet."
_add_to_rc "$HOME/.bashrc" 'export PATH="$PATH:$HOME/.dotnet"'
_add_to_rc "$HOME/.zshrc" 'export PATH="$PATH:$HOME/.dotnet"'
else
echo "ERROR: dotnet-install.sh failed. Retry manually:"
echo " curl -fsSL https://dot.net/v1/dotnet-install.sh | bash"
fi
rm -rf "$TMPDIR"
fi
echo ""
echo "To verify .NET Installation, run:"
echo " dotnet --version"
echo " dotnet --list-sdks"
echo ""
echo "--------------------------------------------------"
echo "II. Code Editor / IDE Notes"
echo "--------------------------------------------------"
echo "Visual Studio Code (Flatpak: com.visualstudio.code) is installed by 01-package-install.sh."
echo "Install these extensions from the Extensions view (Ctrl+Shift+X):"
echo " - C# Dev Kit (Microsoft)"
echo " - NuGet Package Manager GUI"
echo " - GitLens"
echo " - Prettier - Code formatter"
echo "Restart VS Code if prompted after installing extensions."
echo ""
echo "--------------------------------------------------"
echo "III. Version Control (Git)"
echo "--------------------------------------------------"
echo "Git is installed by 01-package-install.sh. Ensure your identity is set:"
echo " git config --global user.name \"Your Name\""
echo " git config --global user.email \"you@example.com\""
echo ""
echo "--------------------------------------------------"
echo "IV. Database (PostgreSQL)"
echo "--------------------------------------------------"
if [ "$PACKAGE_MANAGER" == "apt" ]; then
# Debian/Ubuntu: the postgresql package auto-creates the cluster on install
_apt_install postgresql
_apt_install postgresql-contrib
echo "Enabling and starting PostgreSQL..."
sudo systemctl enable --now postgresql
elif [ "$PACKAGE_MANAGER" == "dnf" ]; then
_dnf_install postgresql-server
_dnf_install postgresql-contrib
if ! sudo systemctl is-active --quiet postgresql; then
echo "Initializing PostgreSQL database cluster..."
if [ -x /usr/bin/postgresql-setup ]; then
sudo postgresql-setup --initdb || echo "Initialization failed or already done."
fi
echo "Enabling and starting PostgreSQL..."
sudo systemctl enable --now postgresql
else
echo "PostgreSQL already running."
fi
fi
echo "Create a database/user with:"
echo " sudo -u postgres psql"
echo " CREATE USER myappuser WITH PASSWORD 'yoursecurepassword';"
echo " CREATE DATABASE myappdb OWNER myappuser;"
echo ""
echo "--------------------------------------------------"
echo "V. Containers (Podman)"
echo "--------------------------------------------------"
# Podman chosen as the container runtime. podman-docker provides a
# /usr/bin/docker shim so existing `docker`/`docker compose` aliases keep working.
if [ "$PACKAGE_MANAGER" == "apt" ]; then
_apt_install podman
_apt_install podman-compose
_apt_install podman-docker
elif [ "$PACKAGE_MANAGER" == "dnf" ]; then
_dnf_install podman
_dnf_install podman-compose
_dnf_install podman-docker
fi
echo "Verify with:"
echo " podman --version"
echo " docker --version # provided by podman-docker (compat shim)"
echo " podman compose version"
echo "Rootless Podman needs no group membership. To enable the rootless API socket:"
echo " systemctl --user enable --now podman.socket"
echo ""
echo "--- .NET / Backend Services Setup Finished ---"

View File

@@ -1,248 +0,0 @@
#!/bin/bash
# 03-fedora-dotnet-setup.sh
# Sets up .NET Development Environment specifically for Fedora.
# Assumes it's being run on Fedora and dnf is available.
echo "--- Starting Fedora .NET Development Environment Setup ---"
# Detect current Fedora version
CURRENT_FEDORA_VERSION=$(rpm -E %fedora)
echo "Detected Fedora version: $CURRENT_FEDORA_VERSION"
echo ""
echo "############################################################"
echo "# Fedora Specific: .NET Development Environment Setup #"
echo "# #"
echo "# Using Fedora version: $CURRENT_FEDORA_VERSION #"
echo "# If this is a future/unsupported version, some packages #"
echo "# or repositories might not be available yet. #"
echo "############################################################"
echo ""
FEDORA_DOTNET_PACKAGES=(
"postgresql-server"
"postgresql-contrib"
"moby-engine" # Docker Engine on Fedora
"docker-compose" # Note: might be 'podman-compose' on newer Fedora
)
echo "Installing Fedora-specific packages for .NET development..."
for pkg_name in "${FEDORA_DOTNET_PACKAGES[@]}"; do
if ! rpm -q "$pkg_name" &>/dev/null; then
echo "Installing $pkg_name..."
if sudo dnf install -y "$pkg_name"; then
echo "$pkg_name has been installed."
else
echo "WARNING: Failed to install $pkg_name. It may not be available in the repositories."
# Special handling for docker-compose
if [ "$pkg_name" == "docker-compose" ]; then
echo "Trying alternative: podman-compose..."
if sudo dnf install -y podman-compose; then
echo "podman-compose installed as alternative to docker-compose."
else
echo "Neither docker-compose nor podman-compose could be installed."
fi
fi
fi
else
echo "$pkg_name is already installed."
fi
done
echo ""
echo "--------------------------------------------------"
echo "I. Core .NET Development Environment"
echo "--------------------------------------------------"
echo "Registering Microsoft Package Repository..."
MS_REPO_URL_BASE="https://packages.microsoft.com/config/fedora"
FEDORA_VERSION_FOR_MS_REPO="$CURRENT_FEDORA_VERSION"
MS_REPO_RPM_URL="${MS_REPO_URL_BASE}/${FEDORA_VERSION_FOR_MS_REPO}/packages-microsoft-prod.rpm"
MS_GPG_KEY_URL="https://packages.microsoft.com/keys/microsoft.asc"
TEMP_MS_RPM_DIR=$(mktemp -d)
TEMP_MS_RPM_PATH="${TEMP_MS_RPM_DIR}/packages-microsoft-prod-temp.rpm"
if ! sudo dnf repolist enabled | grep -q "packages-microsoft-com-prod"; then
echo "Importing Microsoft GPG key: $MS_GPG_KEY_URL"
if sudo rpm --import "$MS_GPG_KEY_URL"; then
echo "Microsoft GPG key imported successfully."
else
echo "WARNING: Failed to import Microsoft GPG key."
fi
echo "Downloading Microsoft package repository for Fedora $FEDORA_VERSION_FOR_MS_REPO: $MS_REPO_RPM_URL"
if wget --quiet "$MS_REPO_RPM_URL" -O "$TEMP_MS_RPM_PATH"; then
echo "Installing downloaded repository configuration..."
if sudo dnf install -y "$TEMP_MS_RPM_PATH"; then
echo "Microsoft repository RPM installed."
else
echo "ERROR: Failed to install Microsoft repository RPM."
fi
else
echo "ERROR: Failed to download Microsoft repository RPM from $MS_REPO_RPM_URL."
echo "This might be because Microsoft doesn't yet support Fedora $FEDORA_VERSION_FOR_MS_REPO."
echo "You can try using a previous Fedora version number or install .NET manually."
# Fallback: try with previous Fedora version
FALLBACK_VERSION=$((CURRENT_FEDORA_VERSION - 1))
echo "Trying fallback with Fedora $FALLBACK_VERSION..."
FALLBACK_URL="${MS_REPO_URL_BASE}/${FALLBACK_VERSION}/packages-microsoft-prod.rpm"
if wget --quiet "$FALLBACK_URL" -O "$TEMP_MS_RPM_PATH"; then
echo "Fallback download successful. Installing..."
sudo dnf install -y "$TEMP_MS_RPM_PATH"
else
echo "Fallback also failed. Skipping Microsoft repository setup."
fi
fi
sudo rm -rf "$TEMP_MS_RPM_DIR" # Clean up
else
echo "Microsoft package repository already configured."
fi
echo "Installing .NET SDK..."
# Try different .NET SDK package names
DOTNET_SDK_PACKAGES=("dotnet-sdk-8.0" "dotnet-sdk-9.0" "dotnet")
DOTNET_INSTALLED=false
for sdk_package in "${DOTNET_SDK_PACKAGES[@]}"; do
if rpm -q "$sdk_package" &>/dev/null; then
echo ".NET SDK ($sdk_package) already installed."
DOTNET_INSTALLED=true
break
fi
done
if [ "$DOTNET_INSTALLED" = false ]; then
for sdk_package in "${DOTNET_SDK_PACKAGES[@]}"; do
echo "Attempting to install $sdk_package..."
if sudo dnf install -y "$sdk_package"; then
echo ".NET SDK ($sdk_package) installed successfully."
DOTNET_INSTALLED=true
break
else
echo "Failed to install $sdk_package, trying next option..."
fi
done
if [ "$DOTNET_INSTALLED" = false ]; then
echo "ERROR: Failed to install any .NET SDK package."
echo "You may need to install .NET manually from https://dotnet.microsoft.com/"
fi
fi
echo "To verify .NET Installation, run these commands manually:"
echo " dotnet --version"
echo " dotnet --list-sdks"
echo " dotnet --list-runtimes"
echo ""
echo "--------------------------------------------------"
echo "II. Code Editor/IDE (Visual Studio Code)"
echo "--------------------------------------------------"
echo "Visual Studio Code (package 'code') should have been installed."
echo "Open VS Code and install these essential extensions from the Extensions view (Ctrl+Shift+X):"
echo " - C# Dev Kit (Publisher: Microsoft)"
echo " - (Optional but Recommended) NuGet Package Manager GUI"
echo " - (Optional but Recommended) GitLens"
echo " - (Optional but Recommended) Prettier - Code formatter"
echo " - (Optional) Any Blazor-specific snippet or tooling extensions"
echo "Restart VS Code if prompted after extension installations."
echo ""
echo "--------------------------------------------------"
echo "III. Version Control (Git)"
echo "--------------------------------------------------"
echo "Git (package 'git') should have been installed by 01-package-install.sh."
echo "Configure Git with your details by running these commands:"
echo " git config --global user.name \"Your Name\""
echo " git config --global user.email \"youremail@example.com\""
echo ""
echo "--------------------------------------------------"
echo "IV. Web Browser for Frontend Testing"
echo "--------------------------------------------------"
echo "Ensure you have a modern web browser (e.g., Firefox, usually pre-installed on Fedora)."
echo "If needed, you can install Chromium with: sudo dnf install -y chromium"
echo "Familiarize yourself with its Developer Tools (Inspector, Console, Network)."
echo ""
echo "--------------------------------------------------"
echo "V. Database (Optional - PostgreSQL Example)"
echo "--------------------------------------------------"
echo "PostgreSQL server and contrib packages should have been installed."
if command -v postgresql-setup &>/dev/null; then
echo "Initializing PostgreSQL Database Cluster (if not already done)..."
# Fixed the postgresql-setup command
if sudo postgresql-setup --initdb; then
echo "PostgreSQL database cluster initialized."
else
echo "PostgreSQL initialization failed or was already done."
fi
else
echo "WARNING: postgresql-setup command not found. Manual initialization might be needed."
fi
echo "Enabling and Starting PostgreSQL Service..."
if sudo systemctl enable --now postgresql; then
echo "PostgreSQL service enabled and started."
else
echo "WARNING: Failed to enable/start PostgreSQL service."
fi
echo "To create a PostgreSQL User and Database, run the following commands:"
echo " 1. Access psql: sudo -u postgres psql"
echo " 2. Inside psql, execute (replace placeholders):"
echo " CREATE USER myappuser WITH PASSWORD 'yoursecurepassword';"
echo " CREATE DATABASE myappdb OWNER myappuser;"
echo " 3. Exit psql: \\q"
echo "(Optional) Install a PostgreSQL GUI Tool like pgAdmin 4:"
echo " sudo dnf install -y pgadmin4"
echo "Or DBeaver (download from their website or check Fedora repos/Flathub)."
echo ""
echo "--------------------------------------------------"
echo "VI. Containerization (Optional but Recommended - Docker)"
echo "--------------------------------------------------"
echo "Docker Engine (moby-engine) and Docker Compose should have been installed."
echo "Enabling and Starting Docker Service..."
if sudo systemctl enable --now docker; then
echo "Docker service enabled and started."
else
echo "WARNING: Failed to enable/start Docker service."
fi
echo "Adding current user ($USER) to the Docker group..."
if sudo usermod -aG docker "$USER"; then
echo "User added to docker group successfully."
else
echo "WARNING: Failed to add user to docker group."
fi
echo "IMPORTANT: You MUST log out and log back in for this group change to take effect."
echo "After logging back in, verify Docker Installation by running:"
echo " docker --version"
echo " docker-compose --version (or podman-compose --version)"
echo " docker run hello-world"
echo ""
echo "--------------------------------------------------"
echo "VII. Final Checks for .NET Setup"
echo "--------------------------------------------------"
echo "Consider rebooting your system to ensure all services and paths are correctly initialized: sudo reboot"
echo "After setup (and potential relogin for Docker), create a Test .NET Project:"
echo " mkdir -p ~/dotnet_test_projects && cd ~/dotnet_test_projects"
echo " dotnet new webapi -o TestApi"
echo " cd TestApi"
echo " dotnet run # (and check in browser at http://localhost:5000 or https://localhost:5001)"
echo " cd .."
echo " dotnet new blazorserver -o TestBlazorApp # or blazorwasm"
echo " cd TestBlazorApp"
echo " dotnet run # (and check in browser)"
echo ""
echo "############################################################"
echo "# End of Fedora Specific .NET Setup #"
echo "############################################################"
echo "--- Fedora .NET Development Environment Setup Finished ---"

176
scripts/verify-debian.sh Executable file
View File

@@ -0,0 +1,176 @@
#!/bin/bash
# verify-debian.sh
# Non-destructive sanity checks for a freshly set-up Debian 13 machine.
# Verifies the pieces that 00-03 + 04-config-symlinks.sh are expected to leave behind.
# Exit code: 0 = all critical checks passed; 1 = at least one critical check failed.
#
# Usage: bash scripts/verify-debian.sh (no root needed)
# --- output helpers -------------------------------------------------------
if [ -t 1 ]; then
C_GREEN=$'\e[32m'; C_RED=$'\e[31m'; C_YELLOW=$'\e[33m'; C_BOLD=$'\e[1m'; C_OFF=$'\e[0m'
else
C_GREEN=""; C_RED=""; C_YELLOW=""; C_BOLD=""; C_OFF=""
fi
PASS=0
WARN=0
FAIL=0
ok() { PASS=$((PASS+1)); echo "${C_GREEN}${C_OFF} $1"; }
warn() { WARN=$((WARN+1)); echo "${C_YELLOW}${C_OFF} $1"; }
bad() { FAIL=$((FAIL+1)); echo "${C_RED}${C_OFF} $1"; }
# --- helpers --------------------------------------------------------------
check_cmd() { # check_cmd "label" "command-name"
if command -v "$2" &>/dev/null; then ok "$1: found ($(command -v "$2"))"; else bad "$1: NOT FOUND"; fi
}
check_symlink_target() { # check_symlink_target "label" "link-path" "expected-target"
if [ -L "$2" ]; then
local target; target="$(readlink -f "$2")"
if [ "$target" = "$3" ] || [ "$(basename "$target")" = "$(basename "$3")" ]; then
ok "$1: $2 -> $target"
else
warn "$1: $2 points to $target (expected $3)"
fi
else
warn "$1: $2 is not a symlink"
fi
}
check_service() { # check_service "label" "unit"
if systemctl is-active --quiet "$2" 2>/dev/null; then ok "$1: active"; else warn "$1: not active"; fi
}
# --- 1. OS ------------------------------------------------------------------
echo "${C_BOLD}== OS ==${C_OFF}"
. /etc/os-release
echo " distro: $PRETTY_NAME (id=$ID, codename=${VERSION_CODENAME:-unknown})"
if [ "$ID" = "debian" ]; then
ok "Debian detected"
else
warn "Not Debian (id=$ID) - this script targets Debian 13"
fi
# --- 2. Package manager ------------------------------------------------------
echo ""
echo "${C_BOLD}== Package manager ==${C_OFF}"
if command -v apt-get &>/dev/null; then ok "apt present"; else bad "apt missing"; fi
if command -v dpkg-query &>/dev/null; then :; else bad "dpkg missing"; fi
# --- 3. Core packages ---------------------------------------------------------
echo ""
echo "${C_BOLD}== Core tools ==${C_OFF}"
for c in git curl wget jq ripgrep tmux zsh fzf zoxide eza unzip btop direnv tldr socat mtr nmap whois traceroute tcpdump iperf3 httpie ansible virt-manager flatpak python3; do
check_cmd "$c" "$c"
done
# --- 4. Debian binary renames -------------------------------------------------
echo ""
echo "${C_BOLD}== Debian binary renames ==${C_OFF}"
if command -v batcat &>/dev/null; then
check_symlink_target "bat -> batcat" "/usr/local/bin/bat" "/usr/bin/batcat"
elif command -v bat &>/dev/null; then
ok "bat present directly"
else
bad "bat/batcat not found"
fi
if command -v fdfind &>/dev/null; then
check_symlink_target "fd -> fdfind" "/usr/local/bin/fd" "/usr/bin/fdfind"
elif command -v fd &>/dev/null; then
ok "fd present directly"
else
bad "fd/fdfind not found"
fi
if command -v dig &>/dev/null; then ok "dig present"; else bad "dig missing (install bind9-dnsutils)"; fi
# --- 5. Upstream-only tools ----------------------------------------------------
echo ""
echo "${C_BOLD}== Upstream tooling ==${C_OFF}"
for c in gh terraform kubectl k9s minikube; do check_cmd "$c" "$c"; done
# --- 6. Development tools -------------------------------------------------------
echo ""
echo "${C_BOLD}== Development tools ==${C_OFF}"
for c in nvim go rustc cargo oh-my-posh helm kubectx kubens stern dive trivy aws; do check_cmd "$c" "$c"; done
# Go binary path sanity
if command -v go &>/dev/null; then ok "GOPATH=$(go env GOPATH 2>/dev/null)"; fi
# pynvim (PEP 668 note: system pip is externally managed on Debian 13)
if /usr/bin/python3 -m pip show pynvim &>/dev/null; then
ok "pynvim installed for python3"
else
warn "pynvim not found for /usr/bin/python3 (install with --break-system-packages if wanted)"
fi
# --- 7. .NET / backend -----------------------------------------------------------
echo ""
echo "${C_BOLD}== .NET / backend services ==${C_OFF}"
if command -v dotnet &>/dev/null; then
ok "dotnet: $(dotnet --version 2>/dev/null)"
else
bad "dotnet not on PATH (install via 03-dotnet-setup.sh or add ~/.dotnet to PATH)"
fi
check_cmd "podman" "podman"
if command -v docker &>/dev/null; then
ok "docker shim present ($(readlink -f "$(command -v docker)" 2>/dev/null || echo docker))"
else
warn "docker shim missing (install podman-docker)"
fi
if command -v podman-compose &>/dev/null; then ok "podman-compose present"; else warn "podman-compose missing"; fi
check_service "postgresql" "postgresql"
check_service "libvirtd" "libvirtd"
# --- 8. Groups -------------------------------------------------------------------
echo ""
echo "${C_BOLD}== Group membership ==${C_OFF}"
for g in libvirt kvm; do
if id -nG 2>/dev/null | tr ' ' '\n' | grep -qx "$g"; then
ok "in group '$g'"
else
warn "not in group '$g' (needed for virt-manager/KVM; log out/in after usermod)"
fi
done
# --- 9. Flatpak --------------------------------------------------------------------
echo ""
echo "${C_BOLD}== Flatpak ==${C_OFF}"
if command -v flatpak &>/dev/null && flatpak remotes 2>/dev/null | grep -q flathub; then
ok "flathub remote present"
else
warn "flathub remote not configured"
fi
# --- 10. Shell rc symlinks ----------------------------------------------------------
echo ""
echo "${C_BOLD}== Dotfile symlinks ==${C_OFF}"
for d in bashrc zshrc gitconfig aliases.bash aliases.zsh; do
if [ -e "$HOME/.$d" ] || [ -L "$HOME/.$d" ]; then
# shellcheck disable=SC2088
ok "~/.$d linked"
else
# shellcheck disable=SC2088
warn "~/.$d missing"
fi
done
check_symlink_target "oh-my-posh theme" "$HOME/.config/oh-my-posh/theme.omp.json" "theme.omp.json"
check_symlink_target "nvim config" "$HOME/.config/nvim" "nvim"
check_symlink_target "nushell config" "$HOME/.config/nushell" "nushell"
# --- Summary ------------------------------------------------------------------------
echo ""
echo "${C_BOLD}========================================${C_OFF}"
echo "${C_GREEN}${C_OFF} ${PASS} passed ${C_YELLOW}${C_OFF} ${WARN} warnings ${C_RED}${C_OFF} ${FAIL} failed"
echo "${C_BOLD}========================================${C_OFF}"
echo ""
if [ "$FAIL" -gt 0 ]; then
echo "Some critical checks failed. See ✘ items above."
exit 1
else
echo "All critical checks passed. Warnings above are optional/suggested."
exit 0
fi

View File

@@ -1 +1 @@
/home/bridgway/dotfiles/terminal/nushell /home/blake/dotfiles/terminal/nushell

7
zshrc
View File

@@ -1,10 +1,6 @@
# Path to your oh-my-zsh installation. # Plain zsh config (oh-my-zsh was removed in favor of Oh-My-Posh).
export ZSH=$HOME/.oh-my-zsh
DEFAULT_USER="$USER" DEFAULT_USER="$USER"
plugins=(git)
# Editor # Editor
export EDITOR='nvim' export EDITOR='nvim'
@@ -23,7 +19,6 @@ export NVM_DIR="$HOME/.nvm"
# Rust/Cargo # Rust/Cargo
[ -f "$HOME/.cargo/env" ] && source "$HOME/.cargo/env" [ -f "$HOME/.cargo/env" ] && source "$HOME/.cargo/env"
source $ZSH/oh-my-zsh.sh
source $HOME/dotfiles/aliases.zsh source $HOME/dotfiles/aliases.zsh
# SSH agent # SSH agent