diff --git a/bin/omarchy-region b/bin/omarchy-region index fc26fbab..ab68fcaa 100755 --- a/bin/omarchy-region +++ b/bin/omarchy-region @@ -36,11 +36,14 @@ if [[ $1 == "cn" ]]; then # Packages first against current mirrors, so a failed install leaves the machine Global. omarchy-update-pacman -Syu --noconfirm sudo env OMARCHY_REGION=cn OMARCHY_PATH="$OMARCHY_PATH" bash -e "$OMARCHY_PATH/install/config/region.sh" - # The refresh renders the cn profile: .cn mirrors first, USTC after, and ArchLinuxCN, whose keyring comes from it. - omarchy-refresh-pacman "$channel" + # Trust ArchLinuxCN before the refresh upgrades through it. + rendered=$(mktemp -d) + trap 'rm -rf "$rendered"' EXIT + omarchy-apply-pacman --render "$channel" "$rendered" mapfile -t profile_packages < <(grep -Ev '^[[:space:]]*(#|$)' "$OMARCHY_PATH/default/regions/cn/packages") - omarchy-pkg-add "${profile_packages[@]}" + sudo pacman --config "$rendered/pacman.conf" -Sy --noconfirm --needed "${profile_packages[@]}" sudo pacman-key --populate archlinuxcn + omarchy-refresh-pacman "$channel" if [[ ! -f $HOME/.local/share/fcitx5/rime/rime_ice.schema.yaml ]]; then # A running fcitx5 only sees the new Rime addon after a restart. systemctl --user try-restart omarchy-fcitx5.service diff --git a/docs/regions.md b/docs/regions.md index 84449e6d..b280f8f3 100644 --- a/docs/regions.md +++ b/docs/regions.md @@ -14,7 +14,7 @@ The China profile's `servers.sed` puts a `.omarchy.cn` twin ahead of every `.oma ## Switching an installed machine -`omarchy-region cn|global` switches at runtime. China installs the input method, runs `install/config/region.sh` (region file, developer-mirror drop-ins, locale), refreshes pacman on the current channel, installs the profile `packages` and populates the ArchLinuxCN keyring. Global undoes the drop-ins and the locale and refreshes pacman back to the channel defaults. Neither touches home directories. +`omarchy-region cn|global` switches at runtime. China installs the input method, runs `install/config/region.sh` (region file, developer-mirror drop-ins, locale), refreshes pacman on the current channel, installs the profile `packages` and populates the ArchLinuxCN keyring. China also sets up Rime Ice in the person's home. Global undoes the drop-ins and the locale, refreshes pacman back to the channel defaults, and removes the Claude Code API settings from the home; it keeps Rime. ## ISO builder contract @@ -25,7 +25,7 @@ Regional content comes from the same runtime used by the ISO: either the `--loca - `packages`: additional target packages, one name per line, with blank lines and `#` comments allowed. The builder bundles them in the offline repository, and the installer installs them only when China is chosen. The source manifest is not modified. - `pacman/`: repository fragments used by the runtime finalizer. The builder also adds the community repository to its writable online config to obtain regional packages; it does not change its Arch channel mirrors. - `timezone` (optional): one zone name, such as `Asia/Shanghai`. The setup form preselects it in the timezone list when the network geo guess is unavailable, which is always the case offline. Both callers pass it: the ISO configurator from its copy of the profile, and first-boot setup from `default/regions//timezone` for the region in `/etc/omarchy/region`. A successful geo guess still wins, and the person can choose any other zone. -- `environment.conf`, `cargo.toml`, `gemrc`, `maven-settings.xml`: developer-mirror drop-ins that `install/config/region.sh` symlinks into `/etc` and `/.cargo`. +- `environment.conf`, `cargo.toml`, `gemrc`: developer-mirror drop-ins that `install/config/region.sh` symlinks into `/etc` and `/.cargo`. `maven-settings.xml` stays in the profile; `MAVEN_ARGS` in `environment.conf` points at it. - `skel/` (optional): new-user defaults. The ISO installer overlays these onto target `/etc/skel` after the base settings packages and before user creation, including installations that defer user creation until first boot. It never overlays existing home directories. For China, the builder installs `archlinuxcn-keyring` using the existing Arch trust chain before downloading other regional packages. Signature or keyring failures abort the build; no unverified keyserver trust or online signature bypass is added. The keyring is also installed on the target from the offline package set, then initialized and populated before online repositories are enabled. The ISO's existing offline repository verification policy is unchanged. diff --git a/manual/51-unattended-installs.md b/manual/51-unattended-installs.md index 492aa2a9..b8f8901f 100644 --- a/manual/51-unattended-installs.md +++ b/manual/51-unattended-installs.md @@ -10,7 +10,7 @@ The files are exactly what the installer's own wizard writes, so the easiest way | File | Required | Purpose | |------|----------|---------| -| `user_configuration.json` | Yes | Disk, hostname, timezone, keyboard, and region (`omarchy_install.region`, `global` or `china`) | +| `user_configuration.json` | Yes | Disk, hostname, timezone, keyboard, and region (`omarchy_install.region`, `global` or `cn`) | | `user_credentials.json` | Yes | Username and password hash | | `user_full_name.txt` | No | Git full name | | `user_email_address.txt` | No | Git email | diff --git a/migrations/1791387144.sh b/migrations/1791387144.sh index d9c379b8..8abd63ed 100644 --- a/migrations/1791387144.sh +++ b/migrations/1791387144.sh @@ -2,10 +2,11 @@ echo "Rename the China region to cn and follow its moved profile" [[ $(cat /etc/omarchy/region 2>/dev/null) == "china" ]] || exit 0 -echo cn | sudo tee /etc/omarchy/region >/dev/null +# Links first, so a failure leaves china for the retry. for link in /etc/environment.d/90-omarchy-china.conf /.cargo/config.toml /etc/gemrc; do old=$(readlink "$link" || true) if [[ $old == */default/region/china/* ]]; then sudo ln -sfn "$OMARCHY_PATH/default/regions/cn/${old##*/}" "$link" fi done +echo cn | sudo tee /etc/omarchy/region >/dev/null diff --git a/test/shell.d/region-switch-test.sh b/test/shell.d/region-switch-test.sh index 45bafca9..2e1133a4 100755 --- a/test/shell.d/region-switch-test.sh +++ b/test/shell.d/region-switch-test.sh @@ -14,7 +14,7 @@ rewrite() { sed -e "s|/etc/|$root/etc/|g" -e "s| /\\.cargo/| $root/.cargo/|g" "$ rewrite "$ROOT/install/config/region.sh" "$sandbox/install/config/region.sh" rewrite "$ROOT/bin/omarchy-region" "$sandbox/bin/omarchy-region" -for command in omarchy-update-pacman omarchy-refresh-pacman locale-gen rime-ice-installer omarchy-setup-claude-api systemctl omarchy-system-logout pacman-key; do +for command in omarchy-update-pacman omarchy-refresh-pacman locale-gen rime-ice-installer omarchy-setup-claude-api systemctl omarchy-system-logout pacman-key pacman omarchy-apply-pacman; do printf '#!/bin/bash\necho "%s $*" >>"%s"\n' "$command" "$calls" >"$test_tmp/bin/$command" done printf '#!/bin/bash\necho "omarchy-pkg-add $*" >>"%s"\n[[ -z ${STUB_PKG_FAIL:-} ]]\n' "$calls" >"$test_tmp/bin/omarchy-pkg-add" @@ -22,7 +22,9 @@ printf '#!/bin/bash\necho "${STUB_CHANNEL:-stable}"\n' >"$test_tmp/bin/omarchy-v printf '#!/bin/bash\n[[ $1 == env ]] && shift\nexec env "$@"\n' >"$test_tmp/bin/sudo" printf '#!/bin/bash\necho "gum $*" >>"%s"\nexit "${GUM_ANSWER:-1}"\n' "$calls" >"$test_tmp/bin/gum" chmod +x "$test_tmp/bin"/* -export PATH="$test_tmp/bin:$sandbox/bin:$PATH" OMARCHY_PATH="$sandbox" HOME="$test_tmp/home" +mkdir -p "$test_tmp/tmp" +export PATH="$test_tmp/bin:$sandbox/bin:$PATH" OMARCHY_PATH="$sandbox" HOME="$test_tmp/home" TMPDIR="$test_tmp/tmp" +switch_calls() { sed "s|$test_tmp/tmp/[^/ ]*|RENDERED|g" "$calls"; } printf '#zh_CN.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\n' >"$root/etc/locale.gen" printf 'LANG=en_US.UTF-8\n' >"$root/etc/locale.conf" @@ -30,9 +32,10 @@ printf 'LANG=en_US.UTF-8\n' >"$root/etc/locale.conf" omarchy-region cn >/dev/null [[ $(omarchy-region) == "China" && $(<"$root/etc/omarchy/region") == "cn" && $(<"$root/etc/locale.conf") == "LANG=zh_CN.UTF-8" ]] || fail "switching to China records cn and sets the language" -[[ $(<"$calls") == $'omarchy-update-pacman -Syu --noconfirm\nomarchy-pkg-add fcitx5-configtool fcitx5-rime librime opencc rime-ice-installer\nlocale-gen \nomarchy-refresh-pacman stable\nomarchy-pkg-add archlinuxcn-keyring\npacman-key --populate archlinuxcn\nsystemctl --user try-restart omarchy-fcitx5.service\nrime-ice-installer --yes' ]] || - fail "China installs Rime against current packages, refreshes pacman into the cn profile, then trusts ArchLinuxCN and sets Rime Ice up" "$(<"$calls")" -pass "switching to China installs Rime, renders the cn profile on the current channel and trusts ArchLinuxCN" +[[ $(switch_calls) == $'omarchy-update-pacman -Syu --noconfirm\nomarchy-pkg-add fcitx5-configtool fcitx5-rime librime opencc rime-ice-installer\nlocale-gen \nomarchy-apply-pacman --render stable RENDERED\npacman --config RENDERED/pacman.conf -Sy --noconfirm --needed archlinuxcn-keyring\npacman-key --populate archlinuxcn\nomarchy-refresh-pacman stable\nsystemctl --user try-restart omarchy-fcitx5.service\nrime-ice-installer --yes' ]] || + fail "China installs Rime, trusts ArchLinuxCN through the rendered cn config, refreshes, then sets Rime Ice up" "$(switch_calls)" +[[ -z $(ls -A "$test_tmp/tmp") ]] || fail "the rendered config is removed" +pass "switching to China installs Rime, trusts ArchLinuxCN before the refresh upgrades through it" : >"$calls" mkdir -p "$HOME/.local/share/fcitx5/rime" && touch "$HOME/.local/share/fcitx5/rime/rime_ice.schema.yaml" @@ -89,3 +92,20 @@ bash -e "$rc_migration" >/dev/null [[ $(grep '^Server' "$root/etc/pacman.conf") == $'Server = https://pkgs.omarchy.cn/rc/$arch\nServer = https://pkgs.omarchy.org/rc/$arch' ]] || fail "the rc repository migration moves the .cn twin with its .org server" "$(grep '^Server' "$root/etc/pacman.conf")" pass "the rc repository migration moves the .cn twin with its .org server" + +rename_migration="$test_tmp/1791387144.sh" +rewrite "$ROOT/migrations/1791387144.sh" "$rename_migration" +rm -f "$root/etc/omarchy/region" "$root/etc/environment.d/90-omarchy-china.conf" +mkdir -p "$root/etc/environment.d" "$root/etc/omarchy" +echo china >"$root/etc/omarchy/region" +ln -sfn /usr/share/omarchy/default/region/china/environment.conf "$root/etc/environment.d/90-omarchy-china.conf" +printf '#!/bin/bash\nexit 1\n' >"$test_tmp/bin/ln" && chmod +x "$test_tmp/bin/ln" +if bash -e "$rename_migration" >/dev/null 2>&1; then + fail "a failed link repair fails the migration" +fi +[[ $(<"$root/etc/omarchy/region") == "china" ]] || fail "a failed link repair leaves china for the retry" +rm "$test_tmp/bin/ln" +bash -e "$rename_migration" >/dev/null +[[ $(<"$root/etc/omarchy/region") == "cn" && $(readlink "$root/etc/environment.d/90-omarchy-china.conf") == "$sandbox/default/regions/cn/environment.conf" ]] || + fail "the rename migration records cn and repoints the links" "$(readlink "$root/etc/environment.d/90-omarchy-china.conf")" +pass "the china rename migration repoints the links before it records cn, so a failure retries"