Skip to content
Closed
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
9 changes: 8 additions & 1 deletion bin/omarchy-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ if [[ -z $COMMAND ]]; then
fi

if ! command -v snapper &>/dev/null; then
exit 127 # omarchy-update can use this to just ignore if snapper is not available
exit 127
fi

case "$COMMAND" in
Expand All @@ -29,6 +29,13 @@ create)
echo
;;
restore)
echo "⚠️ Snapshot restore will restore the ROOT filesystem only."
echo "⚠️ Your /home directory will NOT be affected."
echo ""
echo "If you need to restore /home:"
echo "1. Boot into the snapshot from limine menu"
echo "2. /home is NOT included in the snapshot restore"
echo ""
sudo limine-snapper-restore
;;
esac
29 changes: 29 additions & 0 deletions install/config/boot-permissions-fix.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

# Fix /boot permissions security issue
# The random seed file and /boot mount should not be world accessible
# See: https://github.com/basecamp/omarchy/issues/5377

echo "Fixing /boot permissions for better security..."

# Fix /boot directory permissions (should be 700)
sudo chmod 700 /boot 2>/dev/null || echo "Could not change /boot permissions"

# Fix random-seed file permissions if it exists
if [[ -f /boot/loader/random-seed ]]; then
sudo chmod 600 /boot/loader/random-seed 2>/dev/null || echo "Could not change random-seed permissions"
fi

# Ensure /boot is mounted with proper permissions
# Add to fstab if not already present with correct options
if ! grep -q "^/boot" /etc/fstab 2>/dev/null; then
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/etc/fstab typically has the device in column 1 and the mount point (e.g., /boot) in column 2, so grep -q "^/boot" will usually never match even when /boot is present. Parse the mountpoint column (e.g., with awk '$2=="/boot"{found=1} END{exit !found}' /etc/fstab) or use findmnt -n /boot to accurately detect whether /boot is configured.

Suggested change
if ! grep -q "^/boot" /etc/fstab 2>/dev/null; then
if ! awk '$2=="/boot"{found=1} END{exit !found}' /etc/fstab 2>/dev/null; then

Copilot uses AI. Check for mistakes.
echo "Warning: /boot is not in fstab, permissions may not persist"
fi

# Disable bootctl random seed generation warnings by setting correct permissions
if command -v bootctl &>/dev/null; then
# Run bootctl with proper environment to set correct permissions
sudo bootctl random-seed 2>/dev/null || true
fi

echo "Boot permissions fix complete!"
32 changes: 32 additions & 0 deletions install/config/snapper-home-config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

# Fix snapper /home config creation for chroot installations
# See: https://github.com/basecamp/omarchy/issues/5344

echo "Ensuring snapper /home config is created..."

# Check if /home is on a separate subvolume or btrfs
if mountpoint -q /home 2>/dev/null; then
# /home is a separate mount point
if ! sudo snapper list-configs 2>/dev/null | grep -q "home"; then
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The grep -q "home" / grep -q "root" checks are not anchored, so they can produce false positives (e.g., a config name like home2 would make the script think home exists). Match the config name exactly (consistent with migrations/1777007501.sh using ^home). Also quote $OMARCHY_PATH in the cp for the same reason as in the migration.

Copilot uses AI. Check for mistakes.
echo "Creating snapper config for /home..."
sudo snapper -c home create-config /home 2>/dev/null || echo "Warning: Could not create /home snapper config"
fi
elif [[ -d /home/.snapshots ]]; then
# /home has .snapshots subdirectory, ensure config exists
if ! sudo snapper list-configs 2>/dev/null | grep -q "home"; then
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The grep -q "home" / grep -q "root" checks are not anchored, so they can produce false positives (e.g., a config name like home2 would make the script think home exists). Match the config name exactly (consistent with migrations/1777007501.sh using ^home). Also quote $OMARCHY_PATH in the cp for the same reason as in the migration.

Copilot uses AI. Check for mistakes.
echo "Creating snapper config for /home subvolume..."
sudo snapper -c home create-config /home 2>/dev/null || echo "Warning: Could not create /home snapper config"
fi
else
echo "/home is not on a separate subvolume, skipping /home snapper config"
fi

# Also ensure root snapper config exists
if ! sudo snapper list-configs 2>/dev/null | grep -q "root"; then
echo "Creating snapper config for root..."
sudo snapper -c root create-config / 2>/dev/null || echo "Warning: Could not create root snapper config"
sudo cp $OMARCHY_PATH/default/snapper/root /etc/snapper/configs/root 2>/dev/null || true
Comment on lines +26 to +29
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The grep -q "home" / grep -q "root" checks are not anchored, so they can produce false positives (e.g., a config name like home2 would make the script think home exists). Match the config name exactly (consistent with migrations/1777007501.sh using ^home). Also quote $OMARCHY_PATH in the cp for the same reason as in the migration.

Copilot uses AI. Check for mistakes.
fi

echo "Snapper config check complete!"
25 changes: 25 additions & 0 deletions migrations/1777007500.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

# Fix /boot permissions security issue
# See: https://github.com/basecamp/omarchy/issues/5377

echo "Fixing /boot permissions for better security..."

# Fix /boot directory permissions (should be 700 for security)
sudo chmod 700 /boot 2>/dev/null || echo "Could not change /boot permissions"

# Fix random-seed file permissions if it exists
if [[ -f /boot/loader/random-seed ]]; then
sudo chmod 600 /boot/loader/random-seed 2>/dev/null || echo "Could not change random-seed permissions"
fi

# Verify the fix
if [[ $(stat -c %a /boot 2>/dev/null) == "700" ]]; then
echo "✓ /boot permissions fixed to 700"
fi

if [[ -f /boot/loader/random-seed ]] && [[ $(stat -c %a /boot/loader/random-seed 2>/dev/null) == "600" ]]; then
echo "✓ random-seed permissions fixed to 600"
fi

notify-send "Boot permissions fixed" "Security improvement applied to /boot"
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

notify-send commonly fails in non-GUI / non-user-session contexts (no DISPLAY/DBUS_SESSION_BUS_ADDRESS), which can create noisy errors or cause the migration runner to treat the migration as failed depending on how failures are handled. Guard it (check command -v notify-send and session env) and/or make it non-fatal (e.g., append || true).

Suggested change
notify-send "Boot permissions fixed" "Security improvement applied to /boot"
if command -v notify-send >/dev/null 2>&1 && [[ -n "${DISPLAY:-}" || -n "${DBUS_SESSION_BUS_ADDRESS:-}" ]]; then
notify-send "Boot permissions fixed" "Security improvement applied to /boot" || true
fi

Copilot uses AI. Check for mistakes.
38 changes: 38 additions & 0 deletions migrations/1777007501.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash

# Fix snapper /home config for chroot installations
# See: https://github.com/basecamp/omarchy/issues/5344

echo "Fixing snapper /home config..."

# Check if /home is on btrfs and has .snapshots
if [[ -d /home/.snapshots ]] || mountpoint -q /home 2>/dev/null; then
# Check if /home snapper config exists
if ! sudo snapper list-configs 2>/dev/null | grep -q "^home"; then
echo "Creating snapper config for /home..."
sudo snapper -c home create-config /home 2>/dev/null || echo "Warning: Could not create /home snapper config"

# Copy default config
if [[ -f /etc/snapper/configs/root ]]; then
sudo cp /etc/snapper/configs/root /etc/snapper/configs/home 2>/dev/null || true
# Modify for /home - don't create timeline snapshots
sudo sed -i 's|SUBVOLUME="/"|SUBVOLUME="/home"|' /etc/snapper/configs/home 2>/dev/null || true
sudo sed -i 's|TIMELINE_CREATE="yes"|TIMELINE_CREATE="no"|' /etc/snapper/configs/home 2>/dev/null || true
fi

echo "✓ Created snapper /home config"
else
echo "Snapper /home config already exists"
fi
else
echo "/home is not on btrfs or separate subvolume, skipping"
fi

# Ensure root config exists
if ! sudo snapper list-configs 2>/dev/null | grep -q "^root"; then
echo "Creating snapper config for root..."
sudo snapper -c root create-config / 2>/dev/null || true
sudo cp $OMARCHY_PATH/default/snapper/root /etc/snapper/configs/root 2>/dev/null || true
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$OMARCHY_PATH should be quoted to avoid word-splitting/globbing issues (paths with spaces will break the cp). Use quotes around the full source path.

Suggested change
sudo cp $OMARCHY_PATH/default/snapper/root /etc/snapper/configs/root 2>/dev/null || true
sudo cp "$OMARCHY_PATH/default/snapper/root" /etc/snapper/configs/root 2>/dev/null || true

Copilot uses AI. Check for mistakes.
fi

echo "Snapper config fix complete!"
49 changes: 49 additions & 0 deletions migrations/1777007502.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash

# Fix snapshot restore to exclude /home from restoration
# See: https://github.com/basecamp/omarchy/issues/5361

echo "Configuring snapshot restore to exclude /home..."

# Get absolute path for omarchy
OMARCHY_PATH="${OMARCHY_PATH:-$HOME/.local/share/omarchy}"

# Create a wrapper script that warns users about /home
WRAPPER="/usr/local/bin/omarchy-snapshot-restore-safe"
cat << 'WRAPPEREOF' | sudo tee "$WRAPPER" > /dev/null
#!/bin/bash
# Safe snapshot restore wrapper
# Warns users that /home will NOT be restored

echo "⚠️ WARNING: This will restore the ROOT filesystem only."
echo "⚠️ Your /home directory will NOT be affected."
echo ""
echo "To restore a snapshot:"
echo "1. Reboot and select the snapshot from limine menu"
echo "2. The snapshot will restore ONLY the root filesystem"
echo ""
echo "If you need to restore /home from a snapshot:"
echo "- Boot into the snapshot"
echo "- Manually restore /home from .snapshots subvolumes"
echo ""

if [[ -t 0 ]]; then
read -p "Continue with snapshot restore? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi

exec sudo limine-snapper-restore "$@"
WRAPPEREOF

sudo chmod +x "$WRAPPER"
Comment on lines +12 to +41
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cat > "$WRAPPER" writes into /usr/local/bin, which typically requires root. As written, this migration will fail for non-root runs (even though chmod uses sudo). Write the file via sudo (e.g., sudo tee "$WRAPPER" > /dev/null or write to a temp file then sudo mv into place) so the wrapper is reliably created.

Copilot uses AI. Check for mistakes.

echo ""
echo "✅ Snapshot restore is configured to restore ROOT only"
echo "✅ /home will NOT be restored during snapshot operations"
echo ""
echo "If you've already had /home data loss:"
echo "1. Check .snapshots directory for backup of /home"
echo "2. You may need to manually restore from those snapshots"