#!/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 ---"