Skip to content

feat: add script to mount/unmount disks #1727

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions ansible/files/admin_api_scripts/mount-volume.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env bash

set -euo pipefail

DEVICE=${1:-}
MOUNT_POINT=${2:-}

if [[ -z "$DEVICE" || -z "$MOUNT_POINT" ]]; then
echo "Usage: $0 <device> <mount_point>"
echo "Example: sudo ./mount-volume.sh /dev/nvme1n1 /data/150008"
exit 1
fi

# Mount a block device to a specified mount point
# If the device is not formatted, format it as ext4
# Set ownership to postgres:postgres and permissions to 750
# Add the mount entry to /etc/fstab for persistence across reboots

OWNER="postgres:postgres"
PERMISSIONS="750"
FSTYPE="ext4"
MOUNT_OPTS="defaults"
FSTAB_FILE="/etc/fstab"

if [ ! -b "$DEVICE" ]; then
echo "Error: Block device '$DEVICE' does not exist."
exit 2
fi

if ! blkid "$DEVICE" >/dev/null 2>&1; then
echo "Device $DEVICE appears unformatted. Formatting as $FSTYPE..."
mkfs."$FSTYPE" -F "$DEVICE"
else
echo "$DEVICE already has a filesystem — skipping format."
fi

mkdir -p "$MOUNT_POINT"

e2fsck -pf "$DEVICE"

if ! mountpoint -q "$MOUNT_POINT"; then
echo "Mounting $DEVICE to $MOUNT_POINT"
mount -t "$FSTYPE" -o "$MOUNT_OPTS" "$DEVICE" "$MOUNT_POINT"
else
echo "$MOUNT_POINT is already mounted"
fi

echo "Setting ownership and permissions on $MOUNT_POINT"
chown "$OWNER" "$MOUNT_POINT"
chmod "$PERMISSIONS" "$MOUNT_POINT"

UUID=$(blkid -s UUID -o value "$DEVICE")
FSTAB_LINE="UUID=$UUID $MOUNT_POINT $FSTYPE $MOUNT_OPTS 0 2"

if ! grep -q "$UUID" "$FSTAB_FILE"; then
echo "Adding $FSTAB_LINE to $FSTAB_FILE"
echo "$FSTAB_LINE" >> "$FSTAB_FILE"
else
echo "UUID $UUID already in $FSTAB_FILE — skipping"
fi

echo "Mounted $DEVICE at $MOUNT_POINT with postgres:postgres and mode $PERMISSIONS"
43 changes: 43 additions & 0 deletions ansible/files/admin_api_scripts/unmount-volume.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bash

set -euo pipefail

MOUNT_POINT=${1:-}
DELETE_FLAG=${2:-}

if [[ -z "$MOUNT_POINT" ]]; then
echo "Usage: $0 <mount_point> [--delete-dir]"
echo "Unmount only: sudo ./unmount-volume.sh /data/150008"
echo "Unmount delete dir: sudo ./unmount-volume.sh /data/150008 --delete-dir"
exit 1
fi

# Unmount a block device from a specified mount point
# Remove the corresponding entry from /etc/fstab for persistence across reboots

FSTAB_FILE="/etc/fstab"
BACKUP_FILE="/etc/fstab.bak"

if mountpoint -q "$MOUNT_POINT"; then
echo "Unmounting $MOUNT_POINT"
umount "$MOUNT_POINT"
else
echo "$MOUNT_POINT is not currently mounted — skipping umount"
fi

UUID=$(findmnt -no UUID "$MOUNT_POINT" 2>/dev/null || true)

if [[ -n "$UUID" ]]; then
echo "Removing UUID=$UUID from $FSTAB_FILE"
cp "$FSTAB_FILE" "$BACKUP_FILE"
sed -i "/UUID=${UUID//\//\\/}/d" "$FSTAB_FILE"
else
echo "Could not find UUID for $MOUNT_POINT — skipping fstab cleanup"
fi

if [[ "$DELETE_FLAG" == "--delete-dir" ]]; then
echo "Deleting mount point directory: $MOUNT_POINT"
rm -rf "$MOUNT_POINT"
fi

echo "Unmount and cleanup complete for $MOUNT_POINT"
2 changes: 2 additions & 0 deletions ansible/files/adminapi.sudoers.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Cmnd_Alias GOTRUE = /bin/systemctl start gotrue.service, /bin/systemctl stop got
Cmnd_Alias PGBOUNCER = /bin/systemctl start pgbouncer.service, /bin/systemctl stop pgbouncer.service, /bin/systemctl restart pgbouncer.service, /bin/systemctl disable pgbouncer.service, /bin/systemctl enable pgbouncer.service, /bin/systemctl reload pgbouncer.service, /bin/systemctl try-restart pgbouncer.service

%adminapi ALL= NOPASSWD: /root/grow_fs.sh
%adminapi ALL= NOPASSWD: /root/mount-volume.sh
%adminapi ALL= NOPASSWD: /root/unmount-volume.sh
%adminapi ALL= NOPASSWD: /root/manage_readonly_mode.sh
%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/prepare.sh
%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/initiate.sh
Expand Down
2 changes: 2 additions & 0 deletions ansible/tasks/internal/admin-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
- { file: "grow_fs.sh" }
- { file: "manage_readonly_mode.sh" }
- { file: "pg_egress_collect.pl" }
- { file: "mount-volume.sh" }
- { file: "unmount-volume.sh" }

- name: give adminapi user permissions
copy:
Expand Down