Files
Scripts/netdrivelink.sh
2026-04-17 23:29:35 +03:00

286 lines
13 KiB
Bash

#!/bin/bash
# ═══════════════════════════════════════════════════════════════════
# netdrivelink.sh
# vanga homelab — Samba mounts + 2nd drive symlinks
# Works on: Arch, Debian, Ubuntu, Parrot, Kali, Mint
#
# curl -s https://git.edemilov.ru/edemilov/scripts/raw/branch/main/netdrivelink.sh | bash
# OR for interactive (recommended first time):
# bash <(curl -s https://git.edemilov.ru/edemilov/scripts/raw/branch/main/netdrivelink.sh)
# ═══════════════════════════════════════════════════════════════════
set -e
# ── Colors ──────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
info() { echo -e "${CYAN}[•]${NC} $1"; }
success() { echo -e "${GREEN}[✓]${NC} $1"; }
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
die() { echo -e "${RED}[✗]${NC} $1"; exit 1; }
header() { echo -e "\n${BOLD}${CYAN}── $1 ──────────────────────────────${NC}"; }
# ── Root check ──────────────────────────────────────────────────────
[[ $EUID -ne 0 ]] && die "Run as root: sudo bash netdrivelink.sh"
echo -e "${BOLD}"
echo " ╔══════════════════════════════════════════════╗"
echo " ║ vanga homelab — netdrivelink.sh ║"
echo " ║ Samba mounts + 2nd drive setup ║"
echo " ╚══════════════════════════════════════════════╝"
echo -e "${NC}"
# ── Detect distro & package manager ─────────────────────────────────
header "Detecting system"
detect_distro() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
DISTRO_ID="${ID,,}"
DISTRO_LIKE="${ID_LIKE,,}"
else
die "Cannot detect distro — /etc/os-release missing"
fi
if command -v pacman &>/dev/null; then
PKG_MGR="pacman"
INSTALL_CMD="pacman -S --noconfirm --needed"
CIFS_PKG="cifs-utils"
elif command -v apt-get &>/dev/null; then
PKG_MGR="apt"
INSTALL_CMD="apt-get install -y -qq"
CIFS_PKG="cifs-utils"
apt-get update -qq
elif command -v dnf &>/dev/null; then
PKG_MGR="dnf"
INSTALL_CMD="dnf install -y -q"
CIFS_PKG="cifs-utils"
else
die "Unsupported package manager"
fi
info "Distro: ${DISTRO_ID} | Package manager: ${PKG_MGR}"
}
detect_distro
# ── Install cifs-utils ───────────────────────────────────────────────
if ! command -v mount.cifs &>/dev/null; then
info "Installing cifs-utils..."
$INSTALL_CMD $CIFS_PKG
success "cifs-utils installed"
else
success "cifs-utils already installed"
fi
# ── Get current user (who will own the mounts) ──────────────────────
# Works even when script is run with sudo
REAL_USER="${SUDO_USER:-$(logname 2>/dev/null || echo $USER)}"
REAL_UID=$(id -u "$REAL_USER" 2>/dev/null || echo 1000)
REAL_GID=$(id -g "$REAL_USER" 2>/dev/null || echo 1000)
info "Mount owner: ${REAL_USER} (uid=${REAL_UID} gid=${REAL_GID})"
# ── Samba credentials ────────────────────────────────────────────────
header "Samba credentials"
CRED_FILE="/etc/samba/credentials.emilovi"
if [[ -f "$CRED_FILE" ]]; then
warn "Credentials file already exists: $CRED_FILE"
read -rp " Overwrite? [y/N]: " OVERWRITE
[[ "${OVERWRITE,,}" != "y" ]] && info "Keeping existing credentials" || WRITE_CRED=true
else
WRITE_CRED=true
fi
if [[ "$WRITE_CRED" == "true" ]]; then
read -rp " Samba username: " SAMBA_USER
read -rsp " Samba password: " SAMBA_PASS
echo ""
mkdir -p /etc/samba
cat > "$CRED_FILE" << EOF
username=${SAMBA_USER}
password=${SAMBA_PASS}
domain=WORKGROUP
EOF
chmod 600 "$CRED_FILE"
success "Credentials saved to $CRED_FILE (permissions: 600)"
fi
# ── Common mount options (exact copy of desktop pattern) ────────────
SAMBA_SERVER="10.0.99.100"
CIFS_OPTS="credentials=${CRED_FILE},uid=${REAL_UID},gid=${REAL_GID},vers=3.0,iocharset=utf8,cache=none,nofail,noauto,x-systemd.automount,x-systemd.idle-timeout=600"
# ── Define mounts ────────────────────────────────────────────────────
# Format: "share_name|mount_point"
MOUNTS=(
# Media — 12TB HDD
"Movies|/mnt/media/movies"
"TVShows|/mnt/media/tvshows"
"Music|/mnt/media/music"
"Audiobooks|/mnt/media/audiobooks"
"Ebooks|/mnt/media/ebooks"
# Shared — 4TB NVMe
"Family-Documents|/mnt/shared/documents"
"Family-Photos|/mnt/shared/photos"
"Family-Downloads|/mnt/shared/downloads"
# Users — 4TB NVMe
"Edemilov|/mnt/users/edemilov"
"Aemilova|/mnt/users/aemilova"
"Memilova|/mnt/users/memilova"
"Nemilova|/mnt/users/nemilova"
"Ediemilov|/mnt/users/ediemilov"
# Depo — HDD
"Depo|/mnt/depo"
# Isos
"Isos|/mnt/depo/isos"
# PCBackups
"PCBackups|/mnt/pcbackups"
)
# ── Create mount dirs ────────────────────────────────────────────────
header "Creating mount directories"
for MOUNT in "${MOUNTS[@]}"; do
MPOINT="${MOUNT##*|}"
mkdir -p "$MPOINT"
info " Created: $MPOINT"
done
success "All mount directories ready"
# ── Write fstab ──────────────────────────────────────────────────────
header "Configuring /etc/fstab"
FSTAB_MARKER="# vanga homelab Samba — ${SAMBA_SERVER}"
# Remove existing vanga block if present
if grep -q "$FSTAB_MARKER" /etc/fstab; then
warn "Existing vanga fstab entries found — replacing..."
# Use python3 to safely remove the block
python3 -c "
import re
with open('/etc/fstab', 'r') as f:
content = f.read()
# Remove from marker to next blank section
content = re.sub(r'# vanga homelab.*?(?=\n\n|\Z)', '', content, flags=re.DOTALL)
with open('/etc/fstab', 'w') as f:
f.write(content)
"
fi
# Append new entries
{
echo ""
echo "# ═══════════════════════════════════════════════════════"
echo "# vanga homelab Samba — ${SAMBA_SERVER}"
echo "# Generated by netdrivelink.sh on $(date '+%Y-%m-%d %H:%M')"
echo "# ═══════════════════════════════════════════════════════"
echo "# Media — 12TB HDD"
echo "//${SAMBA_SERVER}/Movies /mnt/media/movies cifs ${CIFS_OPTS} 0 0"
echo "//${SAMBA_SERVER}/TVShows /mnt/media/tvshows cifs ${CIFS_OPTS} 0 0"
echo "//${SAMBA_SERVER}/Music /mnt/media/music cifs ${CIFS_OPTS} 0 0"
echo "//${SAMBA_SERVER}/Audiobooks /mnt/media/audiobooks cifs ${CIFS_OPTS} 0 0"
echo "//${SAMBA_SERVER}/Ebooks /mnt/media/ebooks cifs ${CIFS_OPTS} 0 0"
echo "# Shared — 4TB NVMe"
echo "//${SAMBA_SERVER}/Family-Documents /mnt/shared/documents cifs ${CIFS_OPTS} 0 0"
echo "//${SAMBA_SERVER}/Family-Photos /mnt/shared/photos cifs ${CIFS_OPTS} 0 0"
echo "//${SAMBA_SERVER}/Family-Downloads /mnt/shared/downloads cifs ${CIFS_OPTS} 0 0"
echo "# Users — 4TB NVMe"
echo "//${SAMBA_SERVER}/Edemilov /mnt/users/edemilov cifs ${CIFS_OPTS} 0 0"
echo "//${SAMBA_SERVER}/Aemilova /mnt/users/aemilova cifs ${CIFS_OPTS} 0 0"
echo "//${SAMBA_SERVER}/Memilova /mnt/users/memilova cifs ${CIFS_OPTS} 0 0"
echo "//${SAMBA_SERVER}/Nemilova /mnt/users/nemilova cifs ${CIFS_OPTS} 0 0"
echo "//${SAMBA_SERVER}/Ediemilov /mnt/users/ediemilov cifs ${CIFS_OPTS} 0 0"
echo "# Depo — HDD"
echo "//${SAMBA_SERVER}/Depo /mnt/depo cifs ${CIFS_OPTS} 0 0"
echo "//${SAMBA_SERVER}/Isos /mnt/depo/isos cifs ${CIFS_OPTS} 0 0"
echo "# PCBackups"
echo "//${SAMBA_SERVER}/PCBackups /mnt/pcbackups cifs ${CIFS_OPTS} 0 0"
} >> /etc/fstab
success "fstab updated"
# ── Reload systemd to pick up new automount units ────────────────────
systemctl daemon-reload
success "systemd daemon reloaded"
# ── Test mount (Edemilov share only) ─────────────────────────────────
header "Testing connection"
info "Testing mount of /mnt/users/edemilov..."
if timeout 10 mount /mnt/users/edemilov 2>/dev/null; then
success "Samba connection working! ✓"
umount /mnt/users/edemilov
else
warn "Test mount failed — check credentials or server reachability"
warn "Ping test: $(ping -c1 -W2 ${SAMBA_SERVER} &>/dev/null && echo OK || echo FAILED)"
fi
# ── 2nd drive setup ──────────────────────────────────────────────────
header "2nd drive — /nvme-data symlinks"
NVME_DATA="/nvme-data"
HOME_DIR="/home/${REAL_USER}"
# Check if 2nd drive is mounted
if [[ ! -d "$NVME_DATA" ]]; then
warn "/nvme-data not found — skipping 2nd drive setup"
warn "Mount your 2nd drive first, then re-run this script"
else
info "Found $NVME_DATA — setting up folder structure and symlinks..."
# Create standard folders on the nvme drive
FOLDERS=("Documents" "Downloads" "Pictures" "Videos" "Projects" "Music" "Archive" "Scripts")
for FOLDER in "${FOLDERS[@]}"; do
mkdir -p "${NVME_DATA}/${FOLDER}"
chown "${REAL_USER}:${REAL_USER}" "${NVME_DATA}/${FOLDER}" 2>/dev/null || true
done
success "Folder structure created on /nvme-data"
# Symlink ~/XDG dirs → /nvme-data/X
SYMLINKS=(
"Documents"
"Downloads"
"Pictures"
"Videos"
"Projects"
"Music"
)
info "Creating symlinks in ${HOME_DIR}..."
for LINK in "${SYMLINKS[@]}"; do
TARGET="${NVME_DATA}/${LINK}"
LINKPATH="${HOME_DIR}/${LINK}"
if [[ -L "$LINKPATH" ]]; then
warn " Symlink already exists: ${LINK} → $(readlink $LINKPATH)"
elif [[ -d "$LINKPATH" ]]; then
warn " Real directory exists: $LINKPATH"
info " Moving contents to ${TARGET}..."
mv "${LINKPATH}"/* "${TARGET}/" 2>/dev/null || true
rmdir "${LINKPATH}" 2>/dev/null || rm -rf "${LINKPATH}"
ln -s "${TARGET}" "${LINKPATH}"
chown -h "${REAL_USER}:${REAL_USER}" "${LINKPATH}"
success " Migrated & linked: ~/${LINK} → ${TARGET}"
else
ln -s "${TARGET}" "${LINKPATH}"
chown -h "${REAL_USER}:${REAL_USER}" "${LINKPATH}"
success " Linked: ~/${LINK} → ${TARGET}"
fi
done
# Special: ~/Scripts → /nvme-data/Scripts
SCRIPTS_LINK="${HOME_DIR}/Scripts"
if [[ ! -L "$SCRIPTS_LINK" ]]; then
ln -s "${NVME_DATA}/Scripts" "${SCRIPTS_LINK}"
chown -h "${REAL_USER}:${REAL_USER}" "${SCRIPTS_LINK}"
success " Linked: ~/Scripts → /nvme-data/Scripts"
fi
fi
# ── Done ─────────────────────────────────────────────────────────────
echo ""
echo -e "${BOLD}${GREEN}═══════════════════════════════════════════════════${NC}"
echo -e "${BOLD} ✓ netdrivelink.sh complete!${NC}"
echo -e "${GREEN}═══════════════════════════════════════════════════${NC}"
echo ""
echo -e " ${CYAN}Mounts are automounted on first access${NC}"
echo -e " Try: ${YELLOW}ls /mnt/users/edemilov${NC}"
echo -e " Or: ${YELLOW}ls ~/Documents${NC} (if 2nd drive was found)"
echo ""
echo -e " ${CYAN}To manually trigger all mounts:${NC}"
echo -e " ${YELLOW}sudo mount -a${NC}"
echo ""