configs

configs
git clone https://git.prime8.dev/configs.git
Log | Files | Refs | README

setup.sh (9002B)


      1 #!/usr/bin/env bash
      2 set -euo pipefail
      3 
      4 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
      5 
      6 # Detect OS and run appropriate script
      7 if [[ "$(uname -s)" == "Darwin" ]]; then
      8 	echo "macOS detected, running macos/setup.sh..."
      9 	exec "$SCRIPT_DIR/macos/setup.sh"
     10 	exit
     11 fi
     12 
     13 FEDORA_DIR="$SCRIPT_DIR/fedora"
     14 
     15 # COPR repos
     16 echo "Enabling COPR repositories..."
     17 while IFS= read -r repo || [ -n "$repo" ]; do
     18 	[ -z "$repo" ] && continue
     19 	owner="${repo%%/*}"
     20 	name="${repo##*/}"
     21 	repo_id="copr:copr.fedorainfracloud.org:${owner}:${name}"
     22 	repo_file="/etc/yum.repos.d/_copr_${owner}-${name}.repo"
     23 
     24 	if [ -f "$repo_file" ]; then
     25 		echo "COPR already enabled: $repo"
     26 		continue
     27 	fi
     28 
     29 	echo "Adding COPR: $repo"
     30 	sudo tee "$repo_file" >/dev/null <<EOF
     31 [$repo_id]
     32 name=Copr repo for $name owned by $owner
     33 baseurl=https://download.copr.fedorainfracloud.org/results/$repo/fedora-\$releasever-\$basearch/
     34 type=rpm-md
     35 skip_if_unavailable=True
     36 gpgcheck=1
     37 gpgkey=https://download.copr.fedorainfracloud.org/results/$repo/pubkey.gpg
     38 repo_gpgcheck=0
     39 enabled=1
     40 enabled_metadata=1
     41 EOF
     42 done <"$FEDORA_DIR/copr.txt"
     43 
     44 # OBS repos
     45 echo "Enabling OBS repositories..."
     46 while IFS= read -r repo || [ -n "$repo" ]; do
     47 	[ -z "$repo" ] && continue
     48 	name="${repo##*:}"
     49 	repo_file="/etc/yum.repos.d/${name}.repo"
     50 
     51 	if [ -f "$repo_file" ]; then
     52 		echo "OBS already enabled: $repo"
     53 		continue
     54 	fi
     55 
     56 	echo "Adding OBS: $repo"
     57 	obs_path="${repo//:/:}"
     58 	sudo tee "$repo_file" >/dev/null <<EOF
     59 [home_${name}]
     60 name=${repo} (Fedora_\$releasever)
     61 type=rpm-md
     62 baseurl=https://download.opensuse.org/repositories/${obs_path}/Fedora_\$releasever/
     63 gpgcheck=1
     64 gpgkey=https://download.opensuse.org/repositories/${obs_path}/Fedora_\$releasever/repodata/repomd.xml.key
     65 enabled=1
     66 EOF
     67 done <"$FEDORA_DIR/obs.txt"
     68 
     69 # Vendor repos
     70 echo "Checking vendor repositories..."
     71 while IFS= read -r repo || [ -n "$repo" ]; do
     72 	[ -z "$repo" ] && continue
     73 	case "$repo" in
     74 	1password)
     75 		repo_file="/etc/yum.repos.d/1password.repo"
     76 		if [ ! -f "$repo_file" ]; then
     77 			echo "Adding 1Password repo..."
     78 			sudo rpm --import https://downloads.1password.com/linux/keys/1password.asc
     79 			sudo tee "$repo_file" >/dev/null <<EOF
     80 [1password]
     81 name=1Password Stable Channel
     82 baseurl=https://downloads.1password.com/linux/rpm/stable/\$basearch
     83 enabled=1
     84 gpgcheck=1
     85 repo_gpgcheck=1
     86 gpgkey=file:///etc/pki/rpm-gpg/1password.asc
     87 EOF
     88 		else
     89 			echo "Already enabled: 1password"
     90 		fi
     91 		;;
     92 	google-chrome)
     93 		repo_file="/etc/yum.repos.d/google-chrome.repo"
     94 		if [ ! -f "$repo_file" ]; then
     95 			echo "Adding Google Chrome repo..."
     96 			sudo tee "$repo_file" >/dev/null <<EOF
     97 [google-chrome]
     98 name=google-chrome
     99 baseurl=https://dl.google.com/linux/chrome/rpm/stable/x86_64
    100 skip_if_unavailable=True
    101 gpgcheck=1
    102 gpgkey=https://dl.google.com/linux/linux_signing_key.pub
    103 enabled=0
    104 EOF
    105 		else
    106 			echo "Already enabled: google-chrome"
    107 		fi
    108 		;;
    109 	*)
    110 		echo "Unknown vendor repo: $repo"
    111 		;;
    112 	esac
    113 done <"$FEDORA_DIR/repos.txt"
    114 
    115 # RPM Fusion
    116 echo "Checking RPM Fusion repositories..."
    117 while IFS= read -r repo || [ -n "$repo" ]; do
    118 	[ -z "$repo" ] && continue
    119 	if [ -f "/etc/yum.repos.d/${repo}.repo" ]; then
    120 		echo "Already enabled: $repo"
    121 		continue
    122 	fi
    123 
    124 	echo "Adding $repo..."
    125 	type="${repo#rpmfusion-}"
    126 	sudo rpm-ostree install --idempotent \
    127 		"https://mirrors.rpmfusion.org/${type}/fedora/rpmfusion-${type}-release-$(rpm -E %fedora).noarch.rpm"
    128 done <"$FEDORA_DIR/rpmfusion.txt"
    129 
    130 # Layer RPM packages
    131 echo "Layering packages with rpm-ostree..."
    132 mapfile -t packages < <(sed 's/#.*//;s/[[:space:]]*$//;/^$/d' "$FEDORA_DIR/packages.txt")
    133 
    134 # Filter out already installed packages
    135 packages_to_install=()
    136 for pkg in "${packages[@]}"; do
    137 	if ! rpm -q "$pkg" &>/dev/null; then
    138 		packages_to_install+=("$pkg")
    139 	else
    140 		echo "Already installed: $pkg"
    141 	fi
    142 done
    143 
    144 if [ ${#packages_to_install[@]} -gt 0 ]; then
    145 	sudo rpm-ostree install --idempotent "${packages_to_install[@]}"
    146 else
    147 	echo "All packages already installed"
    148 fi
    149 
    150 # Remove base packages with rpm-ostree overrides
    151 echo "Applying base package removal overrides..."
    152 mapfile -t overrides < <(sed 's/#.*//;s/[[:space:]]*$//;/^$/d' "$FEDORA_DIR/overrides.txt")
    153 
    154 if [ ${#overrides[@]} -gt 0 ]; then
    155 	mapfile -t current_overrides < <(
    156 		rpm-ostree status --json | python3 -c '
    157 import json, sys
    158 data = json.load(sys.stdin)
    159 seen = set()
    160 for deployment in data.get("deployments", []):
    161     for pkg in deployment.get("requested-base-removals", []):
    162         if pkg not in seen:
    163             seen.add(pkg)
    164             print(pkg)
    165 '
    166 	)
    167 
    168 	overrides_to_apply=()
    169 	for pkg in "${overrides[@]}"; do
    170 		already_removed=false
    171 		for removed in "${current_overrides[@]}"; do
    172 			if [ "$pkg" = "$removed" ]; then
    173 				already_removed=true
    174 				break
    175 			fi
    176 		done
    177 
    178 		if [ "$already_removed" = true ]; then
    179 			echo "Override already applied: $pkg"
    180 		else
    181 			overrides_to_apply+=("$pkg")
    182 		fi
    183 	done
    184 
    185 	if [ ${#overrides_to_apply[@]} -gt 0 ]; then
    186 		sudo rpm-ostree override remove "${overrides_to_apply[@]}"
    187 	else
    188 		echo "All base package removal overrides already applied"
    189 	fi
    190 else
    191 	echo "No base package removal overrides configured"
    192 fi
    193 
    194 # Manual installs
    195 
    196 ## bun
    197 if ! command -v bun &>/dev/null; then
    198 	echo "Installing bun..."
    199 	curl -fsSL https://bun.sh/install | bash
    200 fi
    201 
    202 ## opencode
    203 if ! command -v opencode &>/dev/null; then
    204 	echo "Installing opencode..."
    205 	curl -fsSL https://opencode.ai/install | bash
    206 fi
    207 
    208 ## codex
    209 if command -v codex &>/dev/null; then
    210 	echo "Updating codex..."
    211 	codex update || true
    212 else
    213 	echo "Installing codex..."
    214 	sudo npm install -g @openai/codex
    215 fi
    216 
    217 ## neovim-remote
    218 if ! command -v nvr &>/dev/null; then
    219 	echo "Installing neovim-remote..."
    220 	pip install --user neovim-remote
    221 fi
    222 
    223 # Install local RPMs
    224 RPMS_DIR="$SCRIPT_DIR/rpms"
    225 if [ -d "$RPMS_DIR" ]; then
    226 	echo "Checking local RPMs from $RPMS_DIR..."
    227 
    228 	# Build list of RPMs to install
    229 	rpms_to_install=()
    230 	for rpm in "$RPMS_DIR"/*.rpm; do
    231 		[ -f "$rpm" ] || continue
    232 
    233 		pkg_name=$(rpm -qp --queryformat '%{NAME}' "$rpm" 2>/dev/null)
    234 		if [ -z "$pkg_name" ]; then
    235 			echo "Warning: Could not read package name from $rpm"
    236 			continue
    237 		fi
    238 
    239 		# Check if this exact version is installed
    240 		pkg_version=$(rpm -qp --queryformat '%{VERSION}-%{RELEASE}' "$rpm" 2>/dev/null)
    241 		installed_version=$(rpm -q --queryformat '%{VERSION}-%{RELEASE}' "$pkg_name" 2>/dev/null || echo "not-installed")
    242 
    243 		if [ "$installed_version" = "$pkg_version" ]; then
    244 			echo "Already installed: $pkg_name-$pkg_version"
    245 		else
    246 			if [ "$installed_version" = "not-installed" ]; then
    247 				echo "Will install: $pkg_name-$pkg_version"
    248 			else
    249 				echo "Will update: $pkg_name from $installed_version to $pkg_version"
    250 			fi
    251 			rpms_to_install+=("$rpm")
    252 		fi
    253 	done
    254 
    255 	# Build uninstall flags for updates and collect all rpms to install
    256 	uninstall_flags=()
    257 	all_rpms=()
    258 	for rpm in "${rpms_to_install[@]}"; do
    259 		pkg_name=$(rpm -qp --queryformat '%{NAME}' "$rpm" 2>/dev/null)
    260 		if rpm -q "$pkg_name" &>/dev/null; then
    261 			uninstall_flags+=("--uninstall=$pkg_name")
    262 		fi
    263 		all_rpms+=("$rpm")
    264 	done
    265 
    266 	# Single transaction for all operations
    267 	if [ ${#rpms_to_install[@]} -gt 0 ]; then
    268 		if [ ${#uninstall_flags[@]} -gt 0 ]; then
    269 			echo "Updating ${#uninstall_flags[@]} and installing ${#all_rpms[@]} package(s)..."
    270 			sudo rpm-ostree install --idempotent --force-replacefiles "${uninstall_flags[@]}" "${all_rpms[@]}"
    271 		else
    272 			echo "Installing ${#all_rpms[@]} package(s)..."
    273 			sudo rpm-ostree install --idempotent "${all_rpms[@]}"
    274 		fi
    275 	else
    276 		echo "All local RPMs already installed"
    277 	fi
    278 fi
    279 
    280 # Update Flatpaks
    281 flatpak update -y --noninteractive
    282 
    283 # Enable hibernation support
    284 SWAP_DEV="/dev/nvme0n1p3"
    285 if [ -b "$SWAP_DEV" ]; then
    286 	SWAP_UUID=$(lsblk -no UUID "$SWAP_DEV" 2>/dev/null || echo "")
    287 	if [ -n "$SWAP_UUID" ]; then
    288 		if ! rpm-ostree kargs | grep -q "resume=UUID=$SWAP_UUID"; then
    289 			echo "Adding resume kernel argument for hibernation..."
    290 			sudo rpm-ostree kargs --append="resume=UUID=$SWAP_UUID"
    291 			echo "Hibernation enabled. Reboot required to apply changes."
    292 		else
    293 			echo "Resume kernel argument already set"
    294 		fi
    295 	else
    296 		echo "Warning: Could not determine UUID for $SWAP_DEV"
    297 	fi
    298 else
    299 	echo "Warning: Swap partition $SWAP_DEV not found"
    300 fi
    301 
    302 # Codex
    303 mkdir -p "$HOME/.codex"
    304 
    305 # Symlink configs
    306 "$SCRIPT_DIR/link.sh"
    307 
    308 # Map tuned-ppd balanced mode to battery-optimized profile
    309 if [ -d "/etc/tuned/profiles/battery-optimized" ]; then
    310 	echo "Configuring tuned-ppd profile mapping..."
    311 	sudo tee /etc/tuned/ppd.conf >/dev/null <<'EOF'
    312 [main]
    313 # The default PPD profile
    314 default=balanced
    315 battery_detection=true
    316 sysfs_acpi_monitor=true
    317 
    318 [profiles]
    319 # PPD = TuneD
    320 power-saver=powersave
    321 balanced=battery-optimized
    322 performance=throughput-performance
    323 
    324 [battery]
    325 # PPD = TuneD
    326 balanced=battery-optimized
    327 EOF
    328 
    329 	if systemctl list-unit-files --type=service | grep -q '^tuned-ppd\.service'; then
    330 		sudo systemctl restart tuned-ppd.service || true
    331 	fi
    332 fi
    333 
    334 # Change default shell to fish
    335 if command -v fish &>/dev/null; then
    336 	if [ "$SHELL" != "$(which fish)" ]; then
    337 		echo "Changing default shell to fish..."
    338 		chsh -s "$(which fish)"
    339 	fi
    340 fi
    341 
    342 echo "Setup complete!"