From e885584f715c3b47cf47a417f01a1a3870cc8d18 Mon Sep 17 00:00:00 2001 From: Blake Ridgway Date: Wed, 2 Sep 2026 16:27:02 -0500 Subject: [PATCH] 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 --- README.md | 80 +++++----- docs/debian-13-migration-plan.md | 9 ++ main-setup.sh | 30 +++- scripts/01-package-install.sh | 170 +++++++++++++++++++- scripts/02-dev-tools-setup.sh | 11 +- scripts/03-dotnet-setup.sh | 162 +++++++++++++++++++ scripts/03-fedora-dotnet-setup.sh | 248 ------------------------------ zshrc | 9 +- 8 files changed, 412 insertions(+), 307 deletions(-) create mode 100755 scripts/03-dotnet-setup.sh delete mode 100755 scripts/03-fedora-dotnet-setup.sh diff --git a/README.md b/README.md index e44976a..44f5e45 100644 --- a/README.md +++ b/README.md @@ -10,51 +10,51 @@ 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 +- `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 You can run individual scripts if you only need specific components. @@ -97,14 +97,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 +120,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 diff --git a/docs/debian-13-migration-plan.md b/docs/debian-13-migration-plan.md index a2ac7fb..2ddab5d 100644 --- a/docs/debian-13-migration-plan.md +++ b/docs/debian-13-migration-plan.md @@ -4,6 +4,15 @@ Goal: make this dotfiles repo fully suited for **Debian 13 (trixie)** so a fresh 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 diff --git a/main-setup.sh b/main-setup.sh index b98f206..f9d4ef2 100755 --- a/main-setup.sh +++ b/main-setup.sh @@ -87,6 +87,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 +113,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 +152,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 diff --git a/scripts/01-package-install.sh b/scripts/01-package-install.sh index c52fec2..368ab7d 100755 --- a/scripts/01-package-install.sh +++ b/scripts/01-package-install.sh @@ -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,14 +55,22 @@ 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 @@ -72,6 +78,41 @@ fi PACKAGE_LIST=("${BASE_PACKAGE_LIST[@]}" "${DISTRO_SPECIFIC_PACKAGES[@]}") 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=( com.adamcake.Bolt @@ -131,6 +172,121 @@ 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. Bump K8S_MINOR to track the current stable minor. +K8S_MINOR="v1.32" +_apt_add_kubernetes_repo() { + [ -f /etc/apt/sources.list.d/kubernetes.list ] && { echo "Kubernetes repo already configured."; return 0; } + 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 diff --git a/scripts/02-dev-tools-setup.sh b/scripts/02-dev-tools-setup.sh index 8cf072a..5a00dd7 100755 --- a/scripts/02-dev-tools-setup.sh +++ b/scripts/02-dev-tools-setup.sh @@ -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) diff --git a/scripts/03-dotnet-setup.sh b/scripts/03-dotnet-setup.sh new file mode 100755 index 0000000..d9a79f5 --- /dev/null +++ b/scripts/03-dotnet-setup.sh @@ -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 ---" diff --git a/scripts/03-fedora-dotnet-setup.sh b/scripts/03-fedora-dotnet-setup.sh deleted file mode 100755 index 7373235..0000000 --- a/scripts/03-fedora-dotnet-setup.sh +++ /dev/null @@ -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 ---" - diff --git a/zshrc b/zshrc index 262e527..34189f1 100755 --- a/zshrc +++ b/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 @@ -43,3 +38,5 @@ export CPLUS_INCLUDE_PATH=/usr/local/include # Oh My Posh prompt eval "$(oh-my-posh init zsh --config ~/.config/oh-my-posh/theme.omp.json)" +# added by 02-dev-tools-setup.sh +export PATH=$PATH:/usr/local/go/bin