Files

125 lines
3.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=./lib.sh
source "$SCRIPT_DIR/lib.sh"
DEVICE=""
MOUNT_POINT="/srv/ops"
FS_TYPE="ext4"
AUTO_YES=false
FORCE_FORMAT=false
usage() {
cat <<USAGE
Usage: $(basename "$0") [options]
Prepare and mount an SSD for persistent monitoring data.
Options:
--device=/dev/sda1 Block device or partition to mount
--mount-point=PATH Mount path (default: /srv/ops)
--fs=ext4 Filesystem to create if blank (default: ext4)
--force-format Reformat even if filesystem exists (destructive)
--yes, -y Skip confirmation prompts
--help, -h Show help
Examples:
$(basename "$0") --device=/dev/sda1
$(basename "$0") --device=/dev/sda --force-format --yes
USAGE
}
for arg in "$@"; do
case "$arg" in
--device=*) DEVICE="${arg#*=}" ;;
--mount-point=*) MOUNT_POINT="${arg#*=}" ;;
--fs=*) FS_TYPE="${arg#*=}" ;;
--force-format) FORCE_FORMAT=true ;;
--yes|-y) AUTO_YES=true ;;
--help|-h) usage; exit 0 ;;
*) log_error "Unknown argument: $arg"; usage; exit 1 ;;
esac
done
require_cmd sudo lsblk blkid findmnt mount mountpoint grep awk sed
if [[ -z "$DEVICE" ]]; then
root_parent="/dev/$(lsblk -no PKNAME "$(findmnt -n -o SOURCE /)")"
DEVICE="$(lsblk -dpno NAME,TYPE | awk '$2 == "disk" {print $1}' | grep -v "^${root_parent}$" | head -n1 || true)"
if [[ -z "$DEVICE" ]]; then
log_error "Could not auto-detect a non-root disk. Specify --device=/dev/sdX1"
exit 1
fi
log_info "Auto-detected device: $DEVICE"
fi
if [[ ! -b "$DEVICE" ]]; then
log_error "Device does not exist or is not a block device: $DEVICE"
exit 1
fi
TARGET_DEVICE="$DEVICE"
if [[ "$(lsblk -no TYPE "$DEVICE")" == "disk" ]]; then
first_part="$(lsblk -ln -o NAME "$DEVICE" | sed -n '2p' || true)"
if [[ -n "$first_part" ]]; then
TARGET_DEVICE="/dev/${first_part}"
log_info "Using first partition on disk: $TARGET_DEVICE"
fi
fi
existing_fs="$(sudo blkid -s TYPE -o value "$TARGET_DEVICE" 2>/dev/null || true)"
if [[ -n "$existing_fs" && "$FORCE_FORMAT" != "true" ]]; then
log_info "Existing filesystem detected on $TARGET_DEVICE: $existing_fs"
log_info "Skipping format. Use --force-format to recreate filesystem."
else
if [[ -n "$existing_fs" && "$FORCE_FORMAT" == "true" ]]; then
prompt="Reformat $TARGET_DEVICE (current: $existing_fs)? This destroys existing data. Continue?"
else
prompt="Create new $FS_TYPE filesystem on $TARGET_DEVICE?"
fi
if ! confirm_action "$prompt" "$AUTO_YES"; then
log_info "Cancelled"
exit 0
fi
log_info "Formatting $TARGET_DEVICE as $FS_TYPE..."
sudo mkfs -t "$FS_TYPE" "$TARGET_DEVICE"
fi
uuid="$(sudo blkid -s UUID -o value "$TARGET_DEVICE" 2>/dev/null || true)"
if [[ -z "$uuid" ]]; then
log_error "Could not read UUID from $TARGET_DEVICE"
exit 1
fi
sudo mkdir -p "$MOUNT_POINT"
fstab_line="UUID=${uuid} ${MOUNT_POINT} ${FS_TYPE} defaults,noatime,nofail 0 2"
if grep -q "UUID=${uuid}" /etc/fstab; then
log_info "Existing fstab entry found for UUID=${uuid}; leaving as-is"
else
log_info "Adding mount to /etc/fstab"
printf '%s\n' "$fstab_line" | sudo tee -a /etc/fstab >/dev/null
fi
log_info "Mounting $MOUNT_POINT..."
if mountpoint -q "$MOUNT_POINT"; then
log_info "$MOUNT_POINT is already mounted"
else
sudo mount "$MOUNT_POINT"
fi
log_info "Creating monitoring data directories..."
sudo mkdir -p \
"$MOUNT_POINT/portainer/data" \
"$MOUNT_POINT/grafana/data" \
"$MOUNT_POINT/prometheus/data" \
"$MOUNT_POINT/prometheus/targets" \
"$MOUNT_POINT/uptime-kuma/data" \
"$MOUNT_POINT/backups"
log_success "SSD mount ready at $MOUNT_POINT"