update
This commit is contained in:
parent
47d33a59a9
commit
845567d1f5
3
.gitignore
vendored
3
.gitignore
vendored
@ -9,3 +9,6 @@ Thumbs.db
|
|||||||
|
|
||||||
node_modules/
|
node_modules/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
|
||||||
|
# Local machine secrets and filled-in templates
|
||||||
|
smb/fstab.fragment
|
||||||
|
|||||||
24
README.md
24
README.md
@ -1,14 +1,21 @@
|
|||||||
# Milan's Omarchy Config
|
# Milan's Omarchy Config
|
||||||
|
|
||||||
## Install
|
This repository is the source of truth for Milan's Omarchy workstation.
|
||||||
|
Configs are restored with symlinks so future edits should happen here.
|
||||||
|
|
||||||
|
## Fresh install
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://git.ta52.dk/milan/omarchy-config.git
|
git clone https://git.ta52.dk/milan/omarchy-config.git
|
||||||
|
|
||||||
cd omarchy-config
|
cd omarchy-config
|
||||||
|
|
||||||
chmod +x install.sh
|
./bootstrap.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Restore on an existing install
|
||||||
|
|
||||||
|
```bash
|
||||||
./install.sh
|
./install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -25,3 +32,16 @@ git commit -m "Update"
|
|||||||
|
|
||||||
git push
|
git push
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
- `tracked-configs.txt` lists every managed config symlink.
|
||||||
|
- `configs/` stores files that restore into `~/.config`.
|
||||||
|
- `bash/` can store `.bashrc` and `.bash_aliases` when enabled in `tracked-configs.txt`.
|
||||||
|
- `scripts/` restores executable helpers into `~/.local/bin`.
|
||||||
|
- `applications/` restores custom launchers into `~/.local/share/applications`.
|
||||||
|
- `fonts/` restores into `~/.local/share/fonts/omarchy-config`.
|
||||||
|
- `system/` stores exported service and system package metadata.
|
||||||
|
- `smb/` stores SMB automount templates without credentials.
|
||||||
|
|
||||||
|
Set `ENABLE_SYSTEM_SERVICES=1` to restore system services and `INSTALL_SMB=1` to run the SMB installer.
|
||||||
|
|||||||
1
applications/.gitkeep
Normal file
1
applications/.gitkeep
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
103
backup.sh
Normal file → Executable file
103
backup.sh
Normal file → Executable file
@ -2,36 +2,109 @@
|
|||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
TRACKED_CONFIGS="$REPO_DIR/tracked-configs.txt"
|
||||||
|
|
||||||
|
copy_path() {
|
||||||
|
local source="$1"
|
||||||
|
local destination="$2"
|
||||||
|
|
||||||
|
if [[ ! -e "$source" && ! -L "$source" ]]; then
|
||||||
|
echo "Skipping missing source: $source"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -e "$destination" || -L "$destination" ]]; then
|
||||||
|
if [[ "$(readlink -f "$source")" == "$(readlink -f "$destination")" ]]; then
|
||||||
|
echo "Already tracked: ${destination#$REPO_DIR/}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
rm -rf "$destination"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$destination")"
|
||||||
|
cp -a "$source" "$destination"
|
||||||
|
echo "Copied $source -> ${destination#$REPO_DIR/}"
|
||||||
|
}
|
||||||
|
|
||||||
|
read_list() {
|
||||||
|
local file="$1"
|
||||||
|
|
||||||
|
[[ -f "$file" ]] || return 0
|
||||||
|
|
||||||
|
sed 's/#.*//' "$file" | awk 'NF {print $1}'
|
||||||
|
}
|
||||||
|
|
||||||
|
write_version_file() {
|
||||||
|
{
|
||||||
|
echo "Generated: $(date -Is)"
|
||||||
|
echo "Kernel: $(uname -r)"
|
||||||
|
if command -v hyprctl >/dev/null 2>&1; then
|
||||||
|
hyprctl version | sed -n '1p' | sed 's/^/Hyprland: /'
|
||||||
|
fi
|
||||||
|
if command -v omarchy >/dev/null 2>&1; then
|
||||||
|
omarchy version 2>/dev/null | sed 's/^/Omarchy: /' || true
|
||||||
|
fi
|
||||||
|
} > "$REPO_DIR/version.txt"
|
||||||
|
}
|
||||||
|
|
||||||
|
cd "$REPO_DIR"
|
||||||
|
|
||||||
echo "Updating package lists..."
|
echo "Updating package lists..."
|
||||||
|
|
||||||
pacman -Qqe > packages.txt
|
pacman -Qqe > packages.txt
|
||||||
pacman -Qqem > aur-packages.txt
|
pacman -Qqem > aur-packages.txt
|
||||||
pacman -Qe > installed-packages-full.txt
|
pacman -Qe > installed-packages-full.txt
|
||||||
|
|
||||||
echo "Updating configs..."
|
if command -v flatpak >/dev/null 2>&1; then
|
||||||
|
flatpak list --app --columns=application > flatpaks.txt
|
||||||
|
fi
|
||||||
|
|
||||||
rm -rf configs
|
echo "Updating version info..."
|
||||||
|
write_version_file
|
||||||
|
|
||||||
mkdir configs
|
echo "Updating tracked configs..."
|
||||||
|
|
||||||
cp -r ~/.config/omarchy configs/
|
if [[ ! -f "$TRACKED_CONFIGS" ]]; then
|
||||||
cp -r ~/.config/hypr configs/
|
echo "Missing tracked-configs.txt"
|
||||||
cp -r ~/.config/waybar configs/
|
exit 1
|
||||||
cp -r ~/.config/walker configs/
|
fi
|
||||||
cp -r ~/.config/ghostty configs/
|
|
||||||
cp -r ~/.config/kitty configs/
|
|
||||||
cp -r ~/.config/mako configs/
|
|
||||||
cp -r ~/.config/nvim configs/
|
|
||||||
cp -r ~/.config/fastfetch configs/
|
|
||||||
|
|
||||||
cp ~/.config/starship.toml configs/
|
while read -r destination source; do
|
||||||
cp ~/.config/mimeapps.list configs/
|
[[ -n "${destination:-}" ]] || continue
|
||||||
|
[[ "$destination" != \#* ]] || continue
|
||||||
|
[[ -n "${source:-}" ]] || source="$destination"
|
||||||
|
|
||||||
|
destination="${destination/#\~/$HOME}"
|
||||||
|
source="${source/#\~/$HOME}"
|
||||||
|
|
||||||
|
[[ "$destination" = /* ]] || destination="$REPO_DIR/$destination"
|
||||||
|
[[ "$source" = /* ]] || source="$HOME/$source"
|
||||||
|
|
||||||
|
copy_path "$source" "$destination"
|
||||||
|
done < "$TRACKED_CONFIGS"
|
||||||
|
|
||||||
|
echo "Updating scripts, launchers, and fonts..."
|
||||||
|
|
||||||
|
if [[ -d "$HOME/.local/bin" ]]; then
|
||||||
|
mkdir -p scripts
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -d "$HOME/.local/share/applications" ]]; then
|
||||||
|
mkdir -p applications
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -d "$HOME/.local/share/fonts/omarchy-config" ]]; then
|
||||||
|
copy_path "$HOME/.local/share/fonts/omarchy-config" "$REPO_DIR/fonts"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Updating services..."
|
echo "Updating services..."
|
||||||
|
|
||||||
systemctl --user list-unit-files --state=enabled > system/user-services.txt
|
systemctl --user list-unit-files --state=enabled > system/user-services.txt
|
||||||
|
|
||||||
sudo systemctl list-unit-files --state=enabled > system/system-services.txt
|
if command -v sudo >/dev/null 2>&1; then
|
||||||
|
sudo -n systemctl list-unit-files --state=enabled > system/system-services.txt 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Done!"
|
echo "Done!"
|
||||||
|
|||||||
1
bash/.gitkeep
Normal file
1
bash/.gitkeep
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
31
bootstrap.sh
Executable file
31
bootstrap.sh
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
require_command() {
|
||||||
|
local command_name="$1"
|
||||||
|
|
||||||
|
if ! command -v "$command_name" >/dev/null 2>&1; then
|
||||||
|
echo "Missing required command: $command_name"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "========================================"
|
||||||
|
echo " Milan's Omarchy Bootstrap"
|
||||||
|
echo "========================================"
|
||||||
|
echo
|
||||||
|
|
||||||
|
require_command yay
|
||||||
|
require_command systemctl
|
||||||
|
require_command fc-cache
|
||||||
|
|
||||||
|
if [[ ! -f "$REPO_DIR/tracked-configs.txt" ]]; then
|
||||||
|
echo "Missing tracked-configs.txt"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
chmod +x "$REPO_DIR/install.sh"
|
||||||
|
"$REPO_DIR/install.sh"
|
||||||
1
flatpaks.txt
Normal file
1
flatpaks.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Add one Flatpak application ID per line.
|
||||||
1
fonts/.gitkeep
Normal file
1
fonts/.gitkeep
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
195
install.sh
Normal file → Executable file
195
install.sh
Normal file → Executable file
@ -3,98 +3,179 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
CONFIGS_DIR="$REPO_DIR/configs"
|
TRACKED_CONFIGS="$REPO_DIR/tracked-configs.txt"
|
||||||
|
BACKUP_DIR="$HOME/.local/state/omarchy-config/backups/$(date +%Y%m%d-%H%M%S)"
|
||||||
|
|
||||||
echo "========================================"
|
echo "========================================"
|
||||||
echo " Milan's Omarchy Setup Installer"
|
echo " Milan's Omarchy Setup Installer"
|
||||||
echo "========================================"
|
echo "========================================"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
#
|
ensure_dir() {
|
||||||
# Update system
|
mkdir -p "$1"
|
||||||
#
|
}
|
||||||
echo "[1/5] Updating system..."
|
|
||||||
|
read_list() {
|
||||||
|
local file="$1"
|
||||||
|
|
||||||
|
[[ -f "$file" ]] || return 0
|
||||||
|
|
||||||
|
sed 's/#.*//' "$file" | awk 'NF {print $1}'
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_target() {
|
||||||
|
local target="$1"
|
||||||
|
local backup
|
||||||
|
|
||||||
|
[[ -e "$target" || -L "$target" ]] || return 0
|
||||||
|
|
||||||
|
ensure_dir "$BACKUP_DIR"
|
||||||
|
backup="$BACKUP_DIR/${target#$HOME/}"
|
||||||
|
ensure_dir "$(dirname "$backup")"
|
||||||
|
|
||||||
|
echo "Backing up $target"
|
||||||
|
mv "$target" "$backup"
|
||||||
|
}
|
||||||
|
|
||||||
|
link_path() {
|
||||||
|
local source="$1"
|
||||||
|
local target="$2"
|
||||||
|
|
||||||
|
if [[ ! -e "$source" ]]; then
|
||||||
|
echo "Skipping missing source: ${source#$REPO_DIR/}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ensure_dir "$(dirname "$target")"
|
||||||
|
|
||||||
|
if [[ -L "$target" && "$(readlink -f "$target")" == "$(readlink -f "$source")" ]]; then
|
||||||
|
echo "Already linked: $target"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
backup_target "$target"
|
||||||
|
ln -s "$source" "$target"
|
||||||
|
echo "Linked $target -> ${source#$REPO_DIR/}"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_packages() {
|
||||||
|
local file="$1"
|
||||||
|
|
||||||
|
[[ -s "$file" ]] || return 0
|
||||||
|
mapfile -t packages < <(read_list "$file")
|
||||||
|
((${#packages[@]} > 0)) || return 0
|
||||||
|
|
||||||
|
yay -S --needed --noconfirm "${packages[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "[1/8] Updating system..."
|
||||||
yay -Syu --noconfirm
|
yay -Syu --noconfirm
|
||||||
|
|
||||||
#
|
|
||||||
# Install packages
|
|
||||||
#
|
|
||||||
echo
|
echo
|
||||||
echo "[2/5] Installing packages..."
|
echo "[2/8] Installing packages..."
|
||||||
|
install_packages "$REPO_DIR/packages.txt"
|
||||||
|
install_packages "$REPO_DIR/aur-packages.txt"
|
||||||
|
|
||||||
if [[ -f "$REPO_DIR/packages.txt" ]]; then
|
if [[ -s "$REPO_DIR/flatpaks.txt" ]] && command -v flatpak >/dev/null 2>&1; then
|
||||||
yay -S --needed --noconfirm $(<"$REPO_DIR/packages.txt")
|
while read -r app; do
|
||||||
|
[[ -n "$app" ]] || continue
|
||||||
|
flatpak install --user --noninteractive flathub "$app" || true
|
||||||
|
done < <(read_list "$REPO_DIR/flatpaks.txt")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -s "$REPO_DIR/aur-packages.txt" ]]; then
|
|
||||||
yay -S --needed --noconfirm $(<"$REPO_DIR/aur-packages.txt")
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# Symlink configs
|
|
||||||
#
|
|
||||||
echo
|
echo
|
||||||
echo "[3/5] Linking configs..."
|
echo "[3/8] Linking tracked configs..."
|
||||||
|
|
||||||
mkdir -p "$HOME/.config"
|
if [[ ! -f "$TRACKED_CONFIGS" ]]; then
|
||||||
|
echo "Missing tracked-configs.txt"
|
||||||
for item in "$CONFIGS_DIR"/*; do
|
exit 1
|
||||||
|
|
||||||
name="$(basename "$item")"
|
|
||||||
|
|
||||||
target="$HOME/.config/$name"
|
|
||||||
|
|
||||||
# Skip if already linked correctly
|
|
||||||
if [[ -L "$target" ]]; then
|
|
||||||
if [[ "$(readlink -f "$target")" == "$(readlink -f "$item")" ]]; then
|
|
||||||
echo "✓ $name already linked"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Backup existing config
|
while read -r source target; do
|
||||||
if [[ -e "$target" && ! -L "$target" ]]; then
|
[[ -n "${source:-}" ]] || continue
|
||||||
backup="${target}.backup.$(date +%Y%m%d-%H%M%S)"
|
[[ "$source" != \#* ]] || continue
|
||||||
echo "Backing up $name -> $(basename "$backup")"
|
[[ -n "${target:-}" ]] || target="$source"
|
||||||
mv "$target" "$backup"
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -rf "$target"
|
source="${source/#\~/$HOME}"
|
||||||
|
target="${target/#\~/$HOME}"
|
||||||
|
|
||||||
ln -s "$item" "$target"
|
[[ "$source" = /* ]] || source="$REPO_DIR/$source"
|
||||||
|
[[ "$target" = /* ]] || target="$HOME/$target"
|
||||||
|
|
||||||
echo "Linked $name"
|
link_path "$source" "$target"
|
||||||
|
done < "$TRACKED_CONFIGS"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "[4/8] Linking scripts..."
|
||||||
|
|
||||||
|
if [[ -d "$REPO_DIR/scripts" ]]; then
|
||||||
|
ensure_dir "$HOME/.local/bin"
|
||||||
|
find "$REPO_DIR/scripts" -maxdepth 1 -type f -executable | sort |
|
||||||
|
while read -r script; do
|
||||||
|
link_path "$script" "$HOME/.local/bin/$(basename "$script")"
|
||||||
done
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
#
|
|
||||||
# Enable user services
|
|
||||||
#
|
|
||||||
echo
|
echo
|
||||||
echo "[4/5] Enabling user services..."
|
echo "[5/8] Linking desktop launchers..."
|
||||||
|
|
||||||
|
if [[ -d "$REPO_DIR/applications" ]]; then
|
||||||
|
ensure_dir "$HOME/.local/share/applications"
|
||||||
|
find "$REPO_DIR/applications" -maxdepth 1 -type f -name '*.desktop' | sort |
|
||||||
|
while read -r launcher; do
|
||||||
|
link_path "$launcher" "$HOME/.local/share/applications/$(basename "$launcher")"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "[6/8] Linking fonts..."
|
||||||
|
|
||||||
|
if [[ -d "$REPO_DIR/fonts" ]]; then
|
||||||
|
ensure_dir "$HOME/.local/share/fonts"
|
||||||
|
link_path "$REPO_DIR/fonts" "$HOME/.local/share/fonts/omarchy-config"
|
||||||
|
fc-cache -fv >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "[7/8] Enabling user services..."
|
||||||
|
|
||||||
if [[ -f "$REPO_DIR/system/user-services.txt" ]]; then
|
if [[ -f "$REPO_DIR/system/user-services.txt" ]]; then
|
||||||
awk '{print $1}' "$REPO_DIR/system/user-services.txt" |
|
read_list "$REPO_DIR/system/user-services.txt" |
|
||||||
while read -r service; do
|
while read -r service; do
|
||||||
[[ -z "$service" ]] && continue
|
|
||||||
systemctl --user enable "$service" >/dev/null 2>&1 || true
|
systemctl --user enable "$service" >/dev/null 2>&1 || true
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#
|
if [[ -f "$REPO_DIR/system/system-services.txt" ]]; then
|
||||||
# Font cache
|
if [[ "${ENABLE_SYSTEM_SERVICES:-0}" == "1" ]]; then
|
||||||
#
|
read_list "$REPO_DIR/system/system-services.txt" |
|
||||||
|
while read -r service; do
|
||||||
|
if systemctl list-unit-files "$service" >/dev/null 2>&1; then
|
||||||
|
sudo systemctl enable "$service" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "Skipping system services. Run with ENABLE_SYSTEM_SERVICES=1 to enable them."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "[5/5] Refreshing font cache..."
|
echo "[8/8] Running optional installers..."
|
||||||
fc-cache -fv >/dev/null 2>&1 || true
|
|
||||||
|
if [[ -x "$REPO_DIR/smb/install.sh" ]]; then
|
||||||
|
if [[ "${INSTALL_SMB:-0}" == "1" ]]; then
|
||||||
|
"$REPO_DIR/smb/install.sh"
|
||||||
|
else
|
||||||
|
echo "Skipping SMB installer. Run with INSTALL_SMB=1 to enable it."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "========================================"
|
echo "========================================"
|
||||||
echo " Finished!"
|
echo " Finished!"
|
||||||
echo "========================================"
|
echo "========================================"
|
||||||
echo
|
echo
|
||||||
echo "You may want to:"
|
echo "Backups were written to: $BACKUP_DIR"
|
||||||
echo " • Log out and back in"
|
echo
|
||||||
echo " • Run: omarchy-theme (if needed)"
|
echo "You may want to log out and back in, or restart Waybar/Hyprland if configs changed."
|
||||||
echo " • Restart Waybar/Hyprland if configs changed"
|
|
||||||
echo
|
echo
|
||||||
|
|||||||
283
smb-setup.md
Normal file
283
smb-setup.md
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
# SVR52 Samba Client Setup (Omarchy / Arch Linux)
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
This document describes the complete client-side configuration for automatically connecting to the Samba share hosted on **svr52** (a Raspberry Pi server) from another Linux machine running Omarchy/Arch.
|
||||||
|
|
||||||
|
The server is accessed primarily over **Tailscale**, meaning the machine may not be on the same LAN.
|
||||||
|
|
||||||
|
The goal is:
|
||||||
|
|
||||||
|
* Automatically access the Samba share after boot.
|
||||||
|
* Do **not** fail boot if the server is unavailable.
|
||||||
|
* Wait until the share is actually accessed before attempting to connect.
|
||||||
|
* Work reliably with Tailscale's startup delay.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Server Information
|
||||||
|
|
||||||
|
Hostname:
|
||||||
|
|
||||||
|
```text
|
||||||
|
svr52
|
||||||
|
```
|
||||||
|
|
||||||
|
Samba user:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ta52
|
||||||
|
```
|
||||||
|
|
||||||
|
Primary share:
|
||||||
|
|
||||||
|
```text
|
||||||
|
smb
|
||||||
|
```
|
||||||
|
|
||||||
|
Mount point on client:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/home/milan/svr52
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Required packages
|
||||||
|
|
||||||
|
Arch:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo pacman -S cifs-utils smbclient
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Verify connectivity
|
||||||
|
|
||||||
|
List available shares:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
smbclient -L //svr52 -U ta52
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected shares:
|
||||||
|
|
||||||
|
```
|
||||||
|
smb
|
||||||
|
ta52
|
||||||
|
print$
|
||||||
|
IPC$
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Credentials file
|
||||||
|
|
||||||
|
Create:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ~/.smb
|
||||||
|
nano ~/.smb/svr52
|
||||||
|
```
|
||||||
|
|
||||||
|
Contents:
|
||||||
|
|
||||||
|
```text
|
||||||
|
username=ta52
|
||||||
|
password=costarica
|
||||||
|
```
|
||||||
|
|
||||||
|
Protect it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod 600 ~/.smb/svr52
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Create mountpoint
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ~/svr52
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# /etc/fstab
|
||||||
|
|
||||||
|
Append:
|
||||||
|
|
||||||
|
```fstab
|
||||||
|
//svr52/smb /home/milan/svr52 cifs credentials=/home/milan/.smb/svr52,uid=1000,gid=1000,_netdev,nofail,x-systemd.automount,x-systemd.idle-timeout=10min 0 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Explanation
|
||||||
|
|
||||||
|
* `credentials=...`
|
||||||
|
Uses the credentials file.
|
||||||
|
|
||||||
|
* `uid=1000,gid=1000`
|
||||||
|
Files appear owned by the normal user.
|
||||||
|
|
||||||
|
* `_netdev`
|
||||||
|
Marks this as a network filesystem.
|
||||||
|
|
||||||
|
* `nofail`
|
||||||
|
Boot continues even if the server is unreachable.
|
||||||
|
|
||||||
|
* `x-systemd.automount`
|
||||||
|
Do **not** mount during boot.
|
||||||
|
Mount only when the directory is first accessed.
|
||||||
|
|
||||||
|
* `x-systemd.idle-timeout=10min`
|
||||||
|
Automatically unmount after 10 minutes of inactivity.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Reload systemd
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Test
|
||||||
|
|
||||||
|
Unmount if currently mounted:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo umount ~/svr52
|
||||||
|
```
|
||||||
|
|
||||||
|
Start automount:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl start home-milan-svr52.automount
|
||||||
|
```
|
||||||
|
|
||||||
|
Status should show:
|
||||||
|
|
||||||
|
```
|
||||||
|
Active: active (waiting)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Verify automount
|
||||||
|
|
||||||
|
Before accessing:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
findmnt ~/svr52
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected:
|
||||||
|
|
||||||
|
```
|
||||||
|
autofs
|
||||||
|
```
|
||||||
|
|
||||||
|
Access the folder:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ls ~/svr52
|
||||||
|
```
|
||||||
|
|
||||||
|
Then verify:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
findmnt ~/svr52
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected:
|
||||||
|
|
||||||
|
```
|
||||||
|
autofs
|
||||||
|
└── cifs //svr52/smb
|
||||||
|
```
|
||||||
|
|
||||||
|
This confirms the automount triggered successfully.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Why automount is required
|
||||||
|
|
||||||
|
A normal fstab mount fails because:
|
||||||
|
|
||||||
|
1. systemd processes `/etc/fstab`
|
||||||
|
2. Tailscale has **not yet connected**
|
||||||
|
3. `svr52` cannot be reached
|
||||||
|
4. Samba mount fails
|
||||||
|
|
||||||
|
Automount fixes this because:
|
||||||
|
|
||||||
|
1. Boot finishes normally.
|
||||||
|
2. Tailscale connects.
|
||||||
|
3. User later opens:
|
||||||
|
|
||||||
|
```
|
||||||
|
~/svr52
|
||||||
|
```
|
||||||
|
|
||||||
|
4. systemd performs the mount only then.
|
||||||
|
|
||||||
|
This completely avoids boot-time race conditions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Useful commands
|
||||||
|
|
||||||
|
List shares:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
smbclient -L //svr52 -U ta52
|
||||||
|
```
|
||||||
|
|
||||||
|
Manual mount:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mount -a
|
||||||
|
```
|
||||||
|
|
||||||
|
Unmount:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo umount ~/svr52
|
||||||
|
```
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl status home-milan-svr52.automount
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify mount:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
findmnt ~/svr52
|
||||||
|
```
|
||||||
|
|
||||||
|
Reload systemd after editing fstab:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Current Working Configuration
|
||||||
|
|
||||||
|
* Client OS: Omarchy (Arch Linux)
|
||||||
|
* Transport: Tailscale
|
||||||
|
* Hostname: `svr52`
|
||||||
|
* Share: `smb`
|
||||||
|
* Credentials file: `~/.smb/svr52`
|
||||||
|
* Mount point: `/home/milan/svr52`
|
||||||
|
* Mount type: CIFS
|
||||||
|
* Mount strategy: `systemd` automount
|
||||||
|
* Idle timeout: 10 minutes
|
||||||
|
|
||||||
|
This configuration has been tested and confirmed working. The Samba share mounts automatically on first access after Tailscale is connected, eliminating boot-time failures caused by network startup timing.
|
||||||
|
|
||||||
10
smb/README.md
Normal file
10
smb/README.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# SMB Automount
|
||||||
|
|
||||||
|
This directory stores the non-secret pieces needed to restore SMB mounts.
|
||||||
|
|
||||||
|
1. Copy `fstab.fragment.example` to `fstab.fragment`.
|
||||||
|
2. Edit the server, share, mountpoint, and credentials path.
|
||||||
|
3. Store credentials outside this repository.
|
||||||
|
4. Run `INSTALL_SMB=1 ./install.sh` from the repository root.
|
||||||
|
|
||||||
|
Never commit Samba credentials.
|
||||||
2
smb/fstab.fragment.example
Normal file
2
smb/fstab.fragment.example
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Example only. Copy to smb/fstab.fragment and edit locally.
|
||||||
|
# //server/share /mnt/share cifs credentials=/home/milan/.smbcredentials,uid=1000,gid=1000,iocharset=utf8,nofail,x-systemd.automount 0 0
|
||||||
32
smb/install.sh
Executable file
32
smb/install.sh
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
FSTAB_FRAGMENT="$REPO_DIR/smb/fstab.fragment"
|
||||||
|
|
||||||
|
echo "Installing SMB support..."
|
||||||
|
yay -S --needed --noconfirm cifs-utils smbclient
|
||||||
|
|
||||||
|
if [[ ! -f "$FSTAB_FRAGMENT" ]]; then
|
||||||
|
echo "No smb/fstab.fragment found. Copy smb/fstab.fragment.example and edit it first."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
while read -r device mountpoint rest; do
|
||||||
|
[[ -n "${device:-}" ]] || continue
|
||||||
|
[[ "$device" != \#* ]] || continue
|
||||||
|
[[ -n "${mountpoint:-}" ]] || continue
|
||||||
|
|
||||||
|
sudo mkdir -p "$mountpoint"
|
||||||
|
|
||||||
|
if ! grep -Fq "$device $mountpoint " /etc/fstab; then
|
||||||
|
echo "$device $mountpoint $rest" | sudo tee -a /etc/fstab >/dev/null
|
||||||
|
echo "Added fstab entry for $mountpoint"
|
||||||
|
else
|
||||||
|
echo "fstab already contains $mountpoint"
|
||||||
|
fi
|
||||||
|
done < "$FSTAB_FRAGMENT"
|
||||||
|
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
echo "SMB setup complete."
|
||||||
16
tracked-configs.txt
Normal file
16
tracked-configs.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Repository path Home path
|
||||||
|
configs/omarchy .config/omarchy
|
||||||
|
configs/hypr .config/hypr
|
||||||
|
configs/waybar .config/waybar
|
||||||
|
configs/walker .config/walker
|
||||||
|
configs/ghostty .config/ghostty
|
||||||
|
configs/kitty .config/kitty
|
||||||
|
configs/mako .config/mako
|
||||||
|
configs/nvim .config/nvim
|
||||||
|
configs/fastfetch .config/fastfetch
|
||||||
|
configs/starship.toml .config/starship.toml
|
||||||
|
configs/mimeapps.list .config/mimeapps.list
|
||||||
|
|
||||||
|
# Uncomment after adding the matching files:
|
||||||
|
# bash/.bashrc .bashrc
|
||||||
|
# bash/.bash_aliases .bash_aliases
|
||||||
1
version.txt
Normal file
1
version.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Generated by ./backup.sh
|
||||||
Loading…
Reference in New Issue
Block a user