From f8c47a4209dd7e7033407876882e390d7de0c60c Mon Sep 17 00:00:00 2001 From: fkzys Date: Sat, 2 May 2026 15:21:29 +0300 Subject: [PATCH 1/4] feat: add COMMAND config option allowing override the default one --- README.md | 1 + bin/atomic-upgrade | 6 ++-- etc/atomic.conf | 5 +++ lib/atomic/common.sh | 4 ++- man/atomic.conf.5 | 9 +++++ man/atomic.conf.5.md | 6 ++++ tests/test_config.sh | 33 +++++++++++++++++++ tests/test_upgrade.sh | 76 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 137 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 89e6c99..b3b3197 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,7 @@ Edit `/etc/atomic.conf`: | `MAPPER_NAME` | `root_crypt` | dm-crypt mapper name (fallback if auto-detection fails) | | `KERNEL_PKG` | `linux` | Kernel package (linux/linux-lts/linux-zen) | | `KERNEL_PARAMS` | *(security defaults)* | Kernel command line parameters | +| `COMMAND` | *(none)* | Default command in snapshot chroot (overrides built-in `pacman -Syu`) | | `SBCTL_SIGN` | `0` | Sign UKI files with sbctl for Secure Boot (`0`=off, `1`=on) | | `UPGRADE_GUARD` | `1` | Upgrade guard: block direct `pacman -Syu` (`0`=off, `1`=on) | | `HOME_COPY_FILES` | *(empty)* | Files to copy into isolated home subvolumes (see [Home isolation](#home-isolation)) | diff --git a/bin/atomic-upgrade b/bin/atomic-upgrade index f6ed9ac..e1bcfa4 100644 --- a/bin/atomic-upgrade +++ b/bin/atomic-upgrade @@ -106,9 +106,11 @@ if [[ -n "$CUSTOM_TAG" ]]; then fi fi -# Default chroot command +# Default chroot command: use COMMAND from config (or default in common.sh). +# Note: COMMAND uses simple word splitting; args with spaces inside +# are not supported (same limitation as HOME_COPY_FILES). if [[ ${#CHROOT_CMD[@]} -eq 0 ]]; then - CHROOT_CMD=(/usr/bin/pacman -Syu) + read -ra CHROOT_CMD <<< "$COMMAND" fi # Verify required variables are set diff --git a/etc/atomic.conf b/etc/atomic.conf index 2758349..ff7e7de 100644 --- a/etc/atomic.conf +++ b/etc/atomic.conf @@ -7,6 +7,11 @@ #KERNEL_PKG="linux" #KERNEL_PARAMS="rw slab_nomerge init_on_alloc=1 page_alloc.shuffle=1 pti=on vsyscall=none randomize_kstack_offset=on debugfs=off" +# Default command to run in the snapshot chroot (overrides built-in default) +# Command-line -- COMMAND... overrides this setting +# Note: args with spaces inside are not supported (simple word splitting) +#COMMAND="/usr/bin/pacman -Syu" + # Note: inline comments start at ' #' (space + hash). # Values containing a literal ' #' will be truncated at that point. diff --git a/lib/atomic/common.sh b/lib/atomic/common.sh index 3ffbeab..28684a2 100644 --- a/lib/atomic/common.sh +++ b/lib/atomic/common.sh @@ -29,6 +29,8 @@ UPGRADE_GUARD=1 HOME_COPY_FILES="" # Kernel security parameters KERNEL_PARAMS="rw slab_nomerge init_on_alloc=1 page_alloc.shuffle=1 pti=on vsyscall=none randomize_kstack_offset=on debugfs=off" +# Default chroot command (overridden by config or CLI -- COMMAND...) +COMMAND="/usr/bin/pacman -Syu" # ── Config loading (safe parser, no arbitrary code execution) ─────── @@ -46,7 +48,7 @@ load_config() { fi # Whitelist of allowed config keys - local -a allowed=(BTRFS_MOUNT NEW_ROOT ESP KEEP_GENERATIONS MAPPER_NAME KERNEL_PARAMS KERNEL_PKG SBCTL_SIGN UPGRADE_GUARD HOME_COPY_FILES) + local -a allowed=(BTRFS_MOUNT NEW_ROOT ESP KEEP_GENERATIONS MAPPER_NAME KERNEL_PARAMS KERNEL_PKG COMMAND SBCTL_SIGN UPGRADE_GUARD HOME_COPY_FILES) while IFS='=' read -r key value; do # Strip leading/trailing whitespace from key diff --git a/man/atomic.conf.5 b/man/atomic.conf.5 index 1365639..1713c64 100644 --- a/man/atomic.conf.5 +++ b/man/atomic.conf.5 @@ -71,6 +71,15 @@ device arguments. Default: \f[B]rw slab_nomerge init_on_alloc=1 page_alloc.shuffle=1 pti=on vsyscall=none randomize_kstack_offset=on debugfs=off\f[R]. .TP +\f[B]COMMAND\f[R] +Default command to run in the snapshot chroot, overriding the built\-in +default of \f[B]pacman \-Syu\f[R]. +Command\-line \f[B]\-\-\f[R] \f[I]COMMAND...\f[R] takes priority over +this setting. +Note: arguments with spaces inside are not supported due to simple word +splitting. +Default: \f[I](none)\f[R]. +.TP \f[B]SBCTL_SIGN\f[R] Enable UKI signing with \f[B]sbctl\f[R](8) for Secure Boot. Set to \f[B]1\f[R] to enable, \f[B]0\f[R] to disable. diff --git a/man/atomic.conf.5.md b/man/atomic.conf.5.md index da180bc..3b7fa0c 100644 --- a/man/atomic.conf.5.md +++ b/man/atomic.conf.5.md @@ -66,6 +66,12 @@ rejected entirely. page_alloc.shuffle=1 pti=on vsyscall=none randomize_kstack_offset=on debugfs=off**. +**COMMAND** +: Default command to run in the snapshot chroot, overriding the built-in + default of **pacman -Syu**. Command-line **-- COMMAND...** takes priority + over this setting. Note: arguments with spaces inside are not supported + due to simple word splitting. Default: *(none)*. + **SBCTL_SIGN** : Enable UKI signing with **sbctl**(8) for Secure Boot. Set to **1** to enable, **0** to disable. When disabled, UKI files are built unsigned. diff --git a/tests/test_config.sh b/tests/test_config.sh index 5f67ff3..0b006db 100644 --- a/tests/test_config.sh +++ b/tests/test_config.sh @@ -276,7 +276,40 @@ assert_eq "HOME_COPY_FILES absent → stays empty" "" "$HOME_COPY_FILES" # Restore HOME_COPY_FILES="" +# ── COMMAND config ─────────────────────────────────── +section "COMMAND config" + +# Test: COMMAND loaded from config +CONFIG_FILE="${TESTDIR}/command.conf" +cat > "$CONFIG_FILE" <<'EOF' +COMMAND=/usr/bin/pacman -Syu +EOF +COMMAND="" +load_config +assert_eq "COMMAND loaded from config" "/usr/bin/pacman -Syu" "$COMMAND" +COMMAND="" + +# Test: COMMAND with quotes +CONFIG_FILE="${TESTDIR}/command_quoted.conf" +cat > "$CONFIG_FILE" <<'EOF' +COMMAND="/usr/bin/pacman -S nvidia" +EOF +COMMAND="" +load_config +assert_eq "COMMAND with double quotes" "/usr/bin/pacman -S nvidia" "$COMMAND" +COMMAND="" + +# Test: COMMAND absent → stays empty +CONFIG_FILE="${TESTDIR}/command_absent.conf" +cat > "$CONFIG_FILE" <<'EOF' +KEEP_GENERATIONS=3 +EOF +COMMAND="" +load_config +assert_eq "COMMAND absent → stays empty" "" "$COMMAND" + +# # ── config key whitespace trimming ───────────── section "Config key whitespace trimming" diff --git a/tests/test_upgrade.sh b/tests/test_upgrade.sh index 0ebc0f1..c1d59e2 100644 --- a/tests/test_upgrade.sh +++ b/tests/test_upgrade.sh @@ -196,6 +196,82 @@ assert_eq "default cmd count" "CHROOT_CMD_COUNT=2" "$(echo "$_out" | grep '^CHRO assert_eq "default cmd[0]" "CHROOT_CMD_0=/usr/bin/pacman" "$(echo "$_out" | grep '^CHROOT_CMD_0=')" assert_eq "default cmd[1]" "CHROOT_CMD_1=-Syu" "$(echo "$_out" | grep '^CHROOT_CMD_1=')" +# ── Word splitting limitation: args with spaces ──────────── + +section "Word splitting limitation (space in args)" + +CONFIG_FILE="${TESTDIR}/word_split.conf" +cat > "$CONFIG_FILE" <<'EOF' +COMMAND=/usr/bin/pacman -S nvidia driver +EOF + +_TEST_SCRIPT_WS="${TESTDIR}/atomic-upgrade-word-split" +sed \ + -e 's|^\(export ATOMIC_UPGRADE=1\)$|\1\nCONFIG_FILE="${CONFIG_FILE:-/etc/atomic.conf}"|' \ + -e 's/^\(\[\[ \$EUID -eq 0 \]\]\)/# \1/' \ + -e '/^# Verify required variables are set$/i\ +if [[ "${ATOMIC_EXIT_AFTER_PARSE:-}" == "1" ]]; then\ + echo "PARSE_OK"\ + echo "CHROOT_CMD_COUNT=${#CHROOT_CMD[@]}"\ + for i in "${!CHROOT_CMD[@]}"; do\ + echo "CHROOT_CMD_${i}=${CHROOT_CMD[$i]}"\ + done\ + exit 0\ +fi\ +' \ + "$SCRIPT" > "$_TEST_SCRIPT_WS" +chmod +x "$_TEST_SCRIPT_WS" + +run_cmd env CONFIG_FILE="$CONFIG_FILE" ATOMIC_EXIT_AFTER_PARSE=1 bash "$_TEST_SCRIPT_WS" +assert_eq "word split: PARSE_OK" "0" "$_rc" +assert_eq "word split: count is 4" "CHROOT_CMD_COUNT=4" "$(echo "$_out" | grep '^CHROOT_CMD_COUNT=')" +assert_eq "word split: arg[2]" "CHROOT_CMD_2=nvidia" "$(echo "$_out" | grep '^CHROOT_CMD_2=')" +assert_eq "word split: arg[3]" "CHROOT_CMD_3=driver" "$(echo "$_out" | grep '^CHROOT_CMD_3=')" + +rm -f "$_TEST_SCRIPT_WS" + +# ── CLI -- COMMAND priority over config COMMAND= ──────────── + +section "CLI -- COMMAND priority over config COMMAND=" + +CONFIG_FILE="${TESTDIR}/cli_priority.conf" +cat > "$CONFIG_FILE" <<'EOF' +COMMAND=/usr/bin/pacman -Syu +EOF + +_TEST_SCRIPT_CLI="${TESTDIR}/atomic-upgrade-cli-priority" +sed \ + -e 's|^\(export ATOMIC_UPGRADE=1\)$|\1\nCONFIG_FILE="${CONFIG_FILE:-/etc/atomic.conf}"|' \ + -e 's/^\(\[\[ \$EUID -eq 0 \]\]\)/# \1/' \ + -e '/^# Verify required variables are set$/i\ +if [[ "${ATOMIC_EXIT_AFTER_PARSE:-}" == "1" ]]; then\ + echo "PARSE_OK"\ + echo "DRY_RUN=${DRY_RUN}"\ + echo "CUSTOM_TAG=${CUSTOM_TAG}"\ + echo "NO_GC=${NO_GC}"\ + echo "SEPARATE_HOME=${SEPARATE_HOME}"\ + echo "COPY_FILES=${COPY_FILES}"\ + echo "CHROOT_CMD_COUNT=${#CHROOT_CMD[@]}"\ + for i in "${!CHROOT_CMD[@]}"; do\ + echo "CHROOT_CMD_${i}=${CHROOT_CMD[$i]}"\ + done\ + echo "COMMAND_FROM_CONFIG=${COMMAND:-}"\ + exit 0\ +fi\ +' \ + "$SCRIPT" > "$_TEST_SCRIPT_CLI" +chmod +x "$_TEST_SCRIPT_CLI" + +run_cmd env CONFIG_FILE="$CONFIG_FILE" ATOMIC_EXIT_AFTER_PARSE=1 bash "$_TEST_SCRIPT_CLI" -- /usr/bin/pacman -S nvidia +assert_eq "CLI priority: PARSE_OK" "0" "$_rc" +assert_contains "CLI priority: uses CLI args" "CHROOT_CMD_0=/usr/bin/pacman" "$_out" +assert_contains "CLI priority: CLI arg[1]" "CHROOT_CMD_1=-S" "$_out" +assert_contains "CLI priority: CLI arg[2]" "CHROOT_CMD_2=nvidia" "$_out" +assert_eq "CLI priority: count is 3" "CHROOT_CMD_COUNT=3" "$(echo "$_out" | grep '^CHROOT_CMD_COUNT=')" +assert_contains "CLI priority: COMMAND loaded from config" "COMMAND_FROM_CONFIG=/usr/bin/pacman -Syu" "$_out" + +rm -f "$_TEST_SCRIPT_CLI" + # ── GEN_ID format validation ──────────────────────────────── section "GEN_ID format validation" From 6fcbebf1eec115577a947047084da9d3732b0cce Mon Sep 17 00:00:00 2001 From: fkzys Date: Sat, 2 May 2026 16:10:57 +0300 Subject: [PATCH 2/4] refactor: rename COMMAND -> CHROOT_COMMAND to avoid ambiguity --- README.md | 2 +- bin/atomic-upgrade | 2 +- etc/atomic.conf | 4 ++-- lib/atomic/common.sh | 6 +++--- man/atomic.conf.5.md | 4 ++-- tests/test_config.sh | 36 ++++++++++++++++++------------------ tests/test_upgrade.sh | 12 ++++++------ 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index b3b3197..c76b526 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ Edit `/etc/atomic.conf`: | `MAPPER_NAME` | `root_crypt` | dm-crypt mapper name (fallback if auto-detection fails) | | `KERNEL_PKG` | `linux` | Kernel package (linux/linux-lts/linux-zen) | | `KERNEL_PARAMS` | *(security defaults)* | Kernel command line parameters | -| `COMMAND` | *(none)* | Default command in snapshot chroot (overrides built-in `pacman -Syu`) | +| `CHROOT_COMMAND` | *(none)* | Default command in snapshot chroot (overrides built-in `pacman -Syu`) | | `SBCTL_SIGN` | `0` | Sign UKI files with sbctl for Secure Boot (`0`=off, `1`=on) | | `UPGRADE_GUARD` | `1` | Upgrade guard: block direct `pacman -Syu` (`0`=off, `1`=on) | | `HOME_COPY_FILES` | *(empty)* | Files to copy into isolated home subvolumes (see [Home isolation](#home-isolation)) | diff --git a/bin/atomic-upgrade b/bin/atomic-upgrade index e1bcfa4..ce0e73b 100644 --- a/bin/atomic-upgrade +++ b/bin/atomic-upgrade @@ -18,7 +18,7 @@ show_help() { cat << EOF atomic-upgrade v${VERSION} - Atomic system upgrades for Arch Linux -Usage: atomic-upgrade [OPTIONS] [-- COMMAND...] +Usage: atomic-upgrade [OPTIONS] [-- CHROOT_COMMAND...] Options: -n, --dry-run Show what would be done diff --git a/etc/atomic.conf b/etc/atomic.conf index ff7e7de..12e928d 100644 --- a/etc/atomic.conf +++ b/etc/atomic.conf @@ -8,9 +8,9 @@ #KERNEL_PARAMS="rw slab_nomerge init_on_alloc=1 page_alloc.shuffle=1 pti=on vsyscall=none randomize_kstack_offset=on debugfs=off" # Default command to run in the snapshot chroot (overrides built-in default) -# Command-line -- COMMAND... overrides this setting +# Command-line -- CHROOT_COMMAND... overrides this setting # Note: args with spaces inside are not supported (simple word splitting) -#COMMAND="/usr/bin/pacman -Syu" +#CHROOT_COMMAND="/usr/bin/pacman -Syu" # Note: inline comments start at ' #' (space + hash). # Values containing a literal ' #' will be truncated at that point. diff --git a/lib/atomic/common.sh b/lib/atomic/common.sh index 28684a2..1de176f 100644 --- a/lib/atomic/common.sh +++ b/lib/atomic/common.sh @@ -29,8 +29,8 @@ UPGRADE_GUARD=1 HOME_COPY_FILES="" # Kernel security parameters KERNEL_PARAMS="rw slab_nomerge init_on_alloc=1 page_alloc.shuffle=1 pti=on vsyscall=none randomize_kstack_offset=on debugfs=off" -# Default chroot command (overridden by config or CLI -- COMMAND...) -COMMAND="/usr/bin/pacman -Syu" +# Default chroot command (overridden by config or CLI -- CHROOT_COMMAND...) +CHROOT_COMMAND="/usr/bin/pacman -Syu" # ── Config loading (safe parser, no arbitrary code execution) ─────── @@ -48,7 +48,7 @@ load_config() { fi # Whitelist of allowed config keys - local -a allowed=(BTRFS_MOUNT NEW_ROOT ESP KEEP_GENERATIONS MAPPER_NAME KERNEL_PARAMS KERNEL_PKG COMMAND SBCTL_SIGN UPGRADE_GUARD HOME_COPY_FILES) + local -a allowed=(BTRFS_MOUNT NEW_ROOT ESP KEEP_GENERATIONS MAPPER_NAME KERNEL_PARAMS KERNEL_PKG CHROOT_COMMAND SBCTL_SIGN UPGRADE_GUARD HOME_COPY_FILES) while IFS='=' read -r key value; do # Strip leading/trailing whitespace from key diff --git a/man/atomic.conf.5.md b/man/atomic.conf.5.md index 3b7fa0c..66dc31f 100644 --- a/man/atomic.conf.5.md +++ b/man/atomic.conf.5.md @@ -66,9 +66,9 @@ rejected entirely. page_alloc.shuffle=1 pti=on vsyscall=none randomize_kstack_offset=on debugfs=off**. -**COMMAND** +**CHROOT_COMMAND** : Default command to run in the snapshot chroot, overriding the built-in - default of **pacman -Syu**. Command-line **-- COMMAND...** takes priority + default of **pacman -Syu**. Command-line **-- CHROOT_COMMAND...** takes priority over this setting. Note: arguments with spaces inside are not supported due to simple word splitting. Default: *(none)*. diff --git a/tests/test_config.sh b/tests/test_config.sh index 0b006db..f8444f8 100644 --- a/tests/test_config.sh +++ b/tests/test_config.sh @@ -276,38 +276,38 @@ assert_eq "HOME_COPY_FILES absent → stays empty" "" "$HOME_COPY_FILES" # Restore HOME_COPY_FILES="" -# ── COMMAND config ─────────────────────────────────── +# ── CHROOT_COMMAND config ─────────────────────────────────── -section "COMMAND config" +section "CHROOT_COMMAND config" -# Test: COMMAND loaded from config -CONFIG_FILE="${TESTDIR}/command.conf" +# Test: CHROOT_COMMAND loaded from config +CONFIG_FILE="${TESTDIR}/chroot_command.conf" cat > "$CONFIG_FILE" <<'EOF' -COMMAND=/usr/bin/pacman -Syu +CHROOT_COMMAND=/usr/bin/pacman -Syu EOF -COMMAND="" +CHROOT_COMMAND="" load_config -assert_eq "COMMAND loaded from config" "/usr/bin/pacman -Syu" "$COMMAND" -COMMAND="" +assert_eq "CHROOT_COMMAND loaded from config" "/usr/bin/pacman -Syu" "$CHROOT_COMMAND" +CHROOT_COMMAND="" -# Test: COMMAND with quotes -CONFIG_FILE="${TESTDIR}/command_quoted.conf" +# Test: CHROOT_COMMAND with quotes +CONFIG_FILE="${TESTDIR}/chroot_command_quoted.conf" cat > "$CONFIG_FILE" <<'EOF' -COMMAND="/usr/bin/pacman -S nvidia" +CHROOT_COMMAND="/usr/bin/pacman -S nvidia" EOF -COMMAND="" +CHROOT_COMMAND="" load_config -assert_eq "COMMAND with double quotes" "/usr/bin/pacman -S nvidia" "$COMMAND" -COMMAND="" +assert_eq "CHROOT_COMMAND with double quotes" "/usr/bin/pacman -S nvidia" "$CHROOT_COMMAND" +CHROOT_COMMAND="" -# Test: COMMAND absent → stays empty -CONFIG_FILE="${TESTDIR}/command_absent.conf" +# Test: CHROOT_COMMAND absent → stays empty +CONFIG_FILE="${TESTDIR}/chroot_command_absent.conf" cat > "$CONFIG_FILE" <<'EOF' KEEP_GENERATIONS=3 EOF -COMMAND="" +CHROOT_COMMAND="" load_config -assert_eq "COMMAND absent → stays empty" "" "$COMMAND" +assert_eq "CHROOT_COMMAND absent → stays empty" "" "$CHROOT_COMMAND" # # ── config key whitespace trimming ───────────── diff --git a/tests/test_upgrade.sh b/tests/test_upgrade.sh index c1d59e2..112a09a 100644 --- a/tests/test_upgrade.sh +++ b/tests/test_upgrade.sh @@ -202,7 +202,7 @@ section "Word splitting limitation (space in args)" CONFIG_FILE="${TESTDIR}/word_split.conf" cat > "$CONFIG_FILE" <<'EOF' -COMMAND=/usr/bin/pacman -S nvidia driver +CHROOT_COMMAND=/usr/bin/pacman -S nvidia driver EOF _TEST_SCRIPT_WS="${TESTDIR}/atomic-upgrade-word-split" @@ -230,13 +230,13 @@ assert_eq "word split: arg[3]" "CHROOT_CMD_3=driver" "$(echo "$_out" | grep '^CH rm -f "$_TEST_SCRIPT_WS" -# ── CLI -- COMMAND priority over config COMMAND= ──────────── +# ── CLI -- CHROOT_COMMAND priority over config CHROOT_COMMAND= ─────────── -section "CLI -- COMMAND priority over config COMMAND=" +section "CLI -- CHROOT_COMMAND priority over config CHROOT_COMMAND=" CONFIG_FILE="${TESTDIR}/cli_priority.conf" cat > "$CONFIG_FILE" <<'EOF' -COMMAND=/usr/bin/pacman -Syu +CHROOT_COMMAND=/usr/bin/pacman -Syu EOF _TEST_SCRIPT_CLI="${TESTDIR}/atomic-upgrade-cli-priority" @@ -255,7 +255,7 @@ if [[ "${ATOMIC_EXIT_AFTER_PARSE:-}" == "1" ]]; then\ for i in "${!CHROOT_CMD[@]}"; do\ echo "CHROOT_CMD_${i}=${CHROOT_CMD[$i]}"\ done\ - echo "COMMAND_FROM_CONFIG=${COMMAND:-}"\ + echo "CHROOT_COMMAND_FROM_CONFIG=${CHROOT_COMMAND:-}"\ exit 0\ fi\ ' \ @@ -268,7 +268,7 @@ assert_contains "CLI priority: uses CLI args" "CHROOT_CMD_0=/usr/bin/pacman" "$_ assert_contains "CLI priority: CLI arg[1]" "CHROOT_CMD_1=-S" "$_out" assert_contains "CLI priority: CLI arg[2]" "CHROOT_CMD_2=nvidia" "$_out" assert_eq "CLI priority: count is 3" "CHROOT_CMD_COUNT=3" "$(echo "$_out" | grep '^CHROOT_CMD_COUNT=')" -assert_contains "CLI priority: COMMAND loaded from config" "COMMAND_FROM_CONFIG=/usr/bin/pacman -Syu" "$_out" +assert_contains "CLI priority: CHROOT_COMMAND loaded from config" "CHROOT_COMMAND_FROM_CONFIG=/usr/bin/pacman -Syu" "$_out" rm -f "$_TEST_SCRIPT_CLI" From 092720e2db748d09f1e7d2ce349d9c9c394f212d Mon Sep 17 00:00:00 2001 From: fkzys Date: Sat, 2 May 2026 16:13:04 +0300 Subject: [PATCH 3/4] fix: add CHROOT_COMMAND fallback when the option is empty, warn when using quotes --- bin/atomic-upgrade | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/bin/atomic-upgrade b/bin/atomic-upgrade index ce0e73b..1e3c163 100644 --- a/bin/atomic-upgrade +++ b/bin/atomic-upgrade @@ -106,11 +106,18 @@ if [[ -n "$CUSTOM_TAG" ]]; then fi fi -# Default chroot command: use COMMAND from config (or default in common.sh). -# Note: COMMAND uses simple word splitting; args with spaces inside +# Default chroot command: use CHROOT_COMMAND from config (or default in common.sh). +# Note: CHROOT_COMMAND uses simple word splitting; args with spaces inside # are not supported (same limitation as HOME_COPY_FILES). if [[ ${#CHROOT_CMD[@]} -eq 0 ]]; then - read -ra CHROOT_CMD <<< "$COMMAND" + [[ -z "${CHROOT_COMMAND:-}" ]] && CHROOT_COMMAND="/usr/bin/pacman -Syu" + read -ra CHROOT_CMD <<< "$CHROOT_COMMAND" +fi + +# Warn if CHROOT_COMMAND contains quotes (word splitting doesn't process them) +if [[ "$CHROOT_COMMAND" =~ [\'\"] ]]; then + echo "WARN: CHROOT_COMMAND contains quotes, but word splitting doesn't process them." >&2 + echo "WARN: Use CLI instead: atomic-upgrade -- pacman -S 'nvidia dkms'" >&2 fi # Verify required variables are set From 9cf8b4dd22758c8570cb64e91a4543c8042be1e5 Mon Sep 17 00:00:00 2001 From: fkzys Date: Sat, 2 May 2026 16:36:09 +0300 Subject: [PATCH 4/4] docs(conf): move inline comment note to top of the file --- etc/atomic.conf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/etc/atomic.conf b/etc/atomic.conf index 12e928d..e5b04de 100644 --- a/etc/atomic.conf +++ b/etc/atomic.conf @@ -1,4 +1,8 @@ # /etc/atomic.conf + +# Note: inline comments start at ' #' (space + hash). +# Values containing a literal ' #' will be truncated at that point. + #BTRFS_MOUNT="/run/atomic/temp_root" #NEW_ROOT="/run/atomic/newroot" #ESP="/efi" @@ -12,9 +16,6 @@ # Note: args with spaces inside are not supported (simple word splitting) #CHROOT_COMMAND="/usr/bin/pacman -Syu" -# Note: inline comments start at ' #' (space + hash). -# Values containing a literal ' #' will be truncated at that point. - # Sign UKI files with sbctl for Secure Boot (requires sbctl) #SBCTL_SIGN=1