Compare commits
4 Commits
5efb3dab48
...
debian-13
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0817d6a815 | ||
|
|
ae72614636 | ||
|
|
e885584f71 | ||
|
|
e2bb3a956a |
83
README.md
83
README.md
@@ -10,52 +10,53 @@ Run the main setup script to install software, configure development tools, and
|
||||
./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
|
||||
|
||||
### Core Packages
|
||||
- Development tools: `git`, `gh`, `curl`, `wget`, `ripgrep`, `fd-find`
|
||||
- System utilities: `btop`, `fastfetch`, `zsh`, `flatpak`
|
||||
- Virtualization: `virt-manager`
|
||||
### Core Packages (distro packages)
|
||||
- Development tools: `git`, `curl`, `wget`, `ripgrep`, `fd-find`, `bat`, `eza`
|
||||
- System utilities: `btop`, `zsh`, `tmux`, `fzf`, `zoxide`, `flatpak`
|
||||
- Virtualization (KVM): `virt-manager` + libvirt/QEMU stack
|
||||
- Python: `python3`, `python3-pip`
|
||||
- Networking: `nmap`, `mtr`, `tcpdump`, `socat`, `whois`, `iperf3`, `traceroute`
|
||||
- Cloud / DevOps: `kubectl`, `k9s`, `minikube`, `terraform`, `helm`, `direnv`
|
||||
- HTTP: `curl`, `httpie`
|
||||
- Networking: `nmap`, `mtr`, `tcpdump`, `socat`, `whois`, `iperf3`, `traceroute`, `bind9-dnsutils`
|
||||
- HTTP: `httpie`
|
||||
- DevOps helpers: `ansible`, `direnv`, `jq`, `tldr`, `unzip`
|
||||
|
||||
### Development Environment
|
||||
- **Neovim** (latest version from GitHub)
|
||||
- **Hack Nerd Font** for terminal
|
||||
- **Oh My Zsh** shell framework
|
||||
- **Starship** prompt
|
||||
### Upstream Tooling (installed by 01)
|
||||
`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).
|
||||
|
||||
### Development Environment (02)
|
||||
- **Neovim** (latest from GitHub, installed to `/opt/nvim`)
|
||||
- **Hack Nerd Font** for terminals
|
||||
- **Go** toolchain (`/usr/local/go`)
|
||||
- **Rust** toolchain via rustup
|
||||
- **Oh-My-Posh** prompt (`~/.local/bin`)
|
||||
- **Helm**, **kubectx/kubens**, **stern**, **dive**, **trivy**, **AWS CLI v2**
|
||||
|
||||
### Fedora-Specific (.NET Development)
|
||||
On Fedora systems, additional packages are installed:
|
||||
- **Visual Studio Code**
|
||||
- **.NET SDK** (with Microsoft repository)
|
||||
### .NET / Backend Services (03, optional)
|
||||
Distro-agnostic .NET development environment:
|
||||
- **.NET SDK** via the official `dotnet-install.sh` (no vendor repository needed)
|
||||
- **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
|
||||
- Bitwarden
|
||||
- Flatseal
|
||||
- Steam
|
||||
- ProtonUp-Qt
|
||||
- Rider
|
||||
- Veloren Airshipper
|
||||
- Visual Studio Code
|
||||
- VLC Media Player
|
||||
- Bolt, Bitwarden, Discord, Teams for Linux, Flatseal
|
||||
- Steam, ProtonUp-Qt (pupgui2), VLC
|
||||
- Visual Studio Code, Podman Desktop
|
||||
- Signal, Thunderbird
|
||||
|
||||
## Modular Architecture
|
||||
|
||||
The setup is broken down into focused scripts:
|
||||
|
||||
- `00-system-prep.sh` - System updates and Flathub setup
|
||||
- `01-package-install.sh` - Core packages and Flatpak apps
|
||||
- `02-dev-tools-setup.sh` - Development tools (Neovim, Go, Rust, Helm, kubectx, stern, dive, trivy, AWS CLI)
|
||||
- `03-fedora-dotnet-setup.sh` - Fedora-specific .NET environment
|
||||
- `00-system-prep.sh` - System updates, `sudo` bootstrap, Debian `contrib`/`non-free-firmware` + `needrestart`, Flathub setup
|
||||
- `01-package-install.sh` - Core packages, upstream tooling, and Flatpak apps
|
||||
- `02-dev-tools-setup.sh` - Development tools (Neovim, Go, Rust, Oh-My-Posh, Helm, kubectx, stern, dive, trivy, AWS CLI)
|
||||
- `03-dotnet-setup.sh` - .NET SDK + PostgreSQL + Podman (distro-agnostic)
|
||||
- `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.
|
||||
|
||||
@@ -97,14 +98,22 @@ After running the setup, remember to:
|
||||
ssh-keygen -t ed25519 -C ${USER}@$(hostname --fqdn)
|
||||
```
|
||||
|
||||
3. **Install Powerlevel10k gitstatus (if using):**
|
||||
3. **Set zsh as your login shell:**
|
||||
```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
|
||||
- GitLens
|
||||
- Prettier
|
||||
@@ -112,9 +121,9 @@ After running the setup, remember to:
|
||||
|
||||
## Supported Distributions
|
||||
|
||||
- **Fedora** (with full .NET development environment)
|
||||
- **Ubuntu/Debian** (core packages and development tools)
|
||||
- **Pop!_OS** (core packages and development tools)
|
||||
- **Debian 13 "trixie"** (primary target — full setup incl. upstream tooling, .NET, and backend services)
|
||||
- **Ubuntu / Pop!_OS** (apt; core + development tools)
|
||||
- **Fedora** (dnf; core + development tools, best-effort upstream tooling)
|
||||
|
||||
## Customization
|
||||
|
||||
|
||||
119
docs/debian-13-migration-plan.md
Normal file
119
docs/debian-13-migration-plan.md
Normal 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
|
||||
```
|
||||
@@ -54,7 +54,8 @@ prompt_yes_no() {
|
||||
# Function to run a script if approved
|
||||
run_script() {
|
||||
local script_path="$1"
|
||||
local script_name="$(basename "$script_path")"
|
||||
local script_name
|
||||
script_name="$(basename "$script_path")"
|
||||
|
||||
if ! bash "$script_path"; then
|
||||
echo "ERROR: $script_name failed."
|
||||
@@ -87,6 +88,23 @@ echo "Script Root Directory: $SCRIPT_ROOT_DIR"
|
||||
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 ---
|
||||
|
||||
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 dev tools setup (02-dev-tools-setup.sh)?" && RUN_DEV_TOOLS=1 || RUN_DEV_TOOLS=0
|
||||
|
||||
if [ "$DISTRO" == "fedora" ]; then
|
||||
prompt_yes_no "Run Fedora .NET setup (03-fedora-dotnet-setup.sh)?" && RUN_DOTNET=1 || RUN_DOTNET=0
|
||||
else
|
||||
RUN_DOTNET=0
|
||||
fi
|
||||
# 03-dotnet-setup.sh is distro-agnostic (dotnet-install.sh) so offer it everywhere
|
||||
prompt_yes_no "Run .NET / backend services setup (03-dotnet-setup.sh)?" && RUN_DOTNET=1 || RUN_DOTNET=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
|
||||
|
||||
if [ $RUN_DOTNET -eq 1 ]; then
|
||||
echo "Executing 03-fedora-dotnet-setup.sh..."
|
||||
if ! run_script "${SCRIPTS_DIR}/03-fedora-dotnet-setup.sh"; then
|
||||
echo "ERROR: 03-fedora-dotnet-setup.sh failed."
|
||||
echo "Executing 03-dotnet-setup.sh..."
|
||||
if ! run_script "${SCRIPTS_DIR}/03-dotnet-setup.sh"; then
|
||||
echo "ERROR: 03-dotnet-setup.sh failed."
|
||||
fi
|
||||
echo "--------------------------------------------------"
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 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.
|
||||
|
||||
echo "--- Starting System Preparation ---"
|
||||
@@ -11,6 +12,27 @@ if [ -z "$DISTRO" ] || [ -z "$PACKAGE_MANAGER" ]; then
|
||||
exit 1
|
||||
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
|
||||
echo "Updating system packages..."
|
||||
if [ "$PACKAGE_MANAGER" == "dnf" ]; then
|
||||
@@ -21,6 +43,66 @@ else
|
||||
echo "WARNING: Unknown package manager '$PACKAGE_MANAGER'. Skipping system update."
|
||||
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
|
||||
echo "Setting up Flathub repository..."
|
||||
if command -v flatpak &> /dev/null; then
|
||||
|
||||
@@ -12,6 +12,9 @@ if [ -z "$DISTRO" ] || [ -z "$PACKAGE_MANAGER" ]; then
|
||||
fi
|
||||
|
||||
# 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=(
|
||||
ansible
|
||||
bat
|
||||
@@ -23,13 +26,9 @@ BASE_PACKAGE_LIST=(
|
||||
flatpak
|
||||
fzf
|
||||
git
|
||||
gh
|
||||
httpie
|
||||
iperf3
|
||||
jq
|
||||
k9s
|
||||
kubectl
|
||||
minikube
|
||||
mtr
|
||||
nmap
|
||||
python3
|
||||
@@ -37,7 +36,6 @@ BASE_PACKAGE_LIST=(
|
||||
ripgrep
|
||||
socat
|
||||
tcpdump
|
||||
terraform
|
||||
tldr
|
||||
tmux
|
||||
traceroute
|
||||
@@ -57,20 +55,63 @@ if [ "$PACKAGE_MANAGER" == "dnf" ]; then
|
||||
"fontconfig-devel" # for fc-cache
|
||||
"nmap-ncat" # netcat utility
|
||||
"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
|
||||
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"
|
||||
"libssl-dev"
|
||||
"libvirt-clients" # virsh
|
||||
"libvirt-daemon-system" # libvirtd daemon + default network
|
||||
"netcat-openbsd"
|
||||
"qemu-system-x86" # KVM/QEMU backend for virt-manager
|
||||
"virtinst" # virt-install
|
||||
)
|
||||
fi
|
||||
|
||||
# Combine package lists
|
||||
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=(
|
||||
@@ -131,6 +172,132 @@ if [ "$PACKAGE_MANAGER" == "apt" ] && command -v fdfind &>/dev/null && ! command
|
||||
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..."
|
||||
if command -v flatpak &> /dev/null; then
|
||||
|
||||
@@ -35,12 +35,19 @@ else
|
||||
fi
|
||||
|
||||
# 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..."
|
||||
if /usr/bin/python3 -m pip show pynvim &>/dev/null; then
|
||||
echo "pynvim already installed."
|
||||
else
|
||||
/usr/bin/python3 -m pip install --user pynvim
|
||||
echo "pynvim installed for the current user."
|
||||
if /usr/bin/python3 -m pip install --user pynvim; then
|
||||
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
|
||||
|
||||
# Install Nerd Font (Hack)
|
||||
|
||||
162
scripts/03-dotnet-setup.sh
Executable file
162
scripts/03-dotnet-setup.sh
Executable 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 ---"
|
||||
@@ -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
176
scripts/verify-debian.sh
Executable 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
|
||||
@@ -1 +1 @@
|
||||
/home/bridgway/dotfiles/terminal/nushell
|
||||
/home/blake/dotfiles/terminal/nushell
|
||||
7
zshrc
7
zshrc
@@ -1,10 +1,6 @@
|
||||
# Path to your oh-my-zsh installation.
|
||||
export ZSH=$HOME/.oh-my-zsh
|
||||
|
||||
# Plain zsh config (oh-my-zsh was removed in favor of Oh-My-Posh).
|
||||
DEFAULT_USER="$USER"
|
||||
|
||||
plugins=(git)
|
||||
|
||||
# Editor
|
||||
export EDITOR='nvim'
|
||||
|
||||
@@ -23,7 +19,6 @@ export NVM_DIR="$HOME/.nvm"
|
||||
# Rust/Cargo
|
||||
[ -f "$HOME/.cargo/env" ] && source "$HOME/.cargo/env"
|
||||
|
||||
source $ZSH/oh-my-zsh.sh
|
||||
source $HOME/dotfiles/aliases.zsh
|
||||
|
||||
# SSH agent
|
||||
|
||||
Reference in New Issue
Block a user