Merge quattro and route refreshes through omarchy-update-pacman
Upstream now runs every Omarchy-owned pacman transaction through the hidden omarchy-update-pacman helper so a mid-transaction systemd reexec cannot kill it. Keep the deferred pre-refresh-pacman hook and the command-scoped sudo wrapper, and call the helper from the refresh and channel commands; the wrapper still applies to the helper's own sudo. The sudo boundary fixture copies the helper into its root and runs a systemd-run stand-in that execs the wrapped pacman step in place. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
commit
4bd593f4ed
105 files changed
+2541
-361
No files matched your search
@@ -15,8 +15,9 @@
|
||||
# start.
|
||||
#
|
||||
# Env: OMARCHY_SCREENRECORD_DEBUG=true appends gpu-screen-recorder's stderr (and
|
||||
# the picker target it was launched with) to /tmp/omarchy-screenrecord.log so
|
||||
# users can attach a log when reporting capture failures.
|
||||
# the picker target it was launched with) to
|
||||
# $XDG_RUNTIME_DIR/omarchy-screenrecord.log so users can attach a log when
|
||||
# reporting capture failures.
|
||||
|
||||
[[ -f ~/.config/user-dirs.dirs ]] && source ~/.config/user-dirs.dirs
|
||||
OUTPUT_DIR="${OMARCHY_SCREENRECORD_DIR:-${XDG_VIDEOS_DIR:-$HOME/Videos}}"
|
||||
@@ -34,9 +35,18 @@ WEBCAM_SIZE="medium"
|
||||
RESOLUTION=""
|
||||
FULLSCREEN="false"
|
||||
STOP_RECORDING="false"
|
||||
RECORDING_FILE="/tmp/omarchy-screenrecord-filename"
|
||||
REGION_FILE="${XDG_RUNTIME_DIR:-/tmp}/omarchy-screenrecord-region"
|
||||
LOG_FILE=$([[ ${OMARCHY_SCREENRECORD_DEBUG:-false} == "true" ]] && echo "/tmp/omarchy-screenrecord.log" || echo "/dev/null")
|
||||
# Both of these live in the per-user runtime directory, which is 0700. What
|
||||
# RECORDING_FILE holds is read back on stop and used as a path -- ffmpeg writes
|
||||
# beside it, `mv` replaces it, and `rm -f` deletes its preview -- so a name in
|
||||
# world-writable /tmp is a name any other local account can create first and
|
||||
# then point wherever it likes. The debug log carries the recorder's stderr and
|
||||
# the picked geometry, which is nobody else's business either. Fall back to
|
||||
# the state directory when there is no session runtime dir -- :-/tmp would put
|
||||
# both files back at the fixed names this comment describes.
|
||||
RUNTIME_DIR="${XDG_RUNTIME_DIR:-${XDG_STATE_HOME:-$HOME/.local/state}/omarchy}"
|
||||
RECORDING_FILE="$RUNTIME_DIR/omarchy-screenrecord-filename"
|
||||
REGION_FILE="$RUNTIME_DIR/omarchy-screenrecord-region"
|
||||
LOG_FILE=$([[ ${OMARCHY_SCREENRECORD_DEBUG:-false} == "true" ]] && echo "$RUNTIME_DIR/omarchy-screenrecord.log" || echo "/dev/null")
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
@@ -144,6 +154,11 @@ select_capture_target() {
|
||||
}
|
||||
|
||||
start_screenrecording() {
|
||||
mkdir -p "$RUNTIME_DIR" || return 1
|
||||
# XDG_STATE_HOME may be outside a private home; protect existing fallbacks too.
|
||||
if [[ -z ${XDG_RUNTIME_DIR:-} ]]; then
|
||||
chmod 700 "$RUNTIME_DIR" || return 1
|
||||
fi
|
||||
local capture_args=()
|
||||
local target
|
||||
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
set -euo pipefail
|
||||
|
||||
readonly MARGIN=40
|
||||
readonly REGION_FILE="${XDG_RUNTIME_DIR:-/tmp}/omarchy-screenrecord-region"
|
||||
# Has to resolve to whatever omarchy-capture-screenrecording writes, fallback
|
||||
# included, or a recording without a session runtime dir anchors the camera to
|
||||
# the whole monitor instead of the region it recorded.
|
||||
readonly REGION_FILE="${XDG_RUNTIME_DIR:-${XDG_STATE_HOME:-$HOME/.local/state}/omarchy}/omarchy-screenrecord-region"
|
||||
|
||||
usage() {
|
||||
echo "Usage: omarchy-capture-webcam-resize <smaller|larger|reset|small|medium|large>" >&2
|
||||
|
||||
@@ -47,7 +47,7 @@ validate_dev_checkout() {
|
||||
|
||||
link_dev_checkout() {
|
||||
local checkout="$1" required
|
||||
[[ -d $checkout/.git ]] || git clone https://github.com/basecamp/omarchy.git "$checkout"
|
||||
[[ -d $checkout/.git ]] || git clone https://github.com/omacom/omarchy.git "$checkout"
|
||||
|
||||
# Check the destination before changing /etc/omarchy.conf or sudo's path.
|
||||
# An existing checkout is not pulled automatically and may predate this policy.
|
||||
@@ -94,6 +94,10 @@ case "$channel" in
|
||||
;;
|
||||
esac
|
||||
|
||||
# A failure past this point leaves the channel switch half-applied, so say how
|
||||
# to pick it back up rather than dying silently under set -e.
|
||||
trap 'echo -e "\nThe channel switch did not complete. Review the error above, then rerun: omarchy-channel-set '"$channel"'" >&2' ERR
|
||||
|
||||
if [[ -z $dev_checkout && $OMARCHY_PATH != "/usr/share/omarchy" ]]; then
|
||||
leaving_dev=1
|
||||
fi
|
||||
@@ -107,7 +111,7 @@ fi
|
||||
|
||||
omarchy-refresh-pacman "$pacman_channel" defer-hook
|
||||
# --ask 4 accepts omarchy <-> omarchy-dev replacement prompts without file overwrites.
|
||||
sudo env OMARCHY_UPDATE_PACMAN=1 pacman -S --needed --noconfirm --ask 4 "${packages[@]}"
|
||||
omarchy-update-pacman -S --needed --noconfirm --ask 4 "${packages[@]}"
|
||||
|
||||
if [[ -z $dev_checkout ]]; then
|
||||
omarchy-dev-unlink --no-reboot
|
||||
|
||||
@@ -86,6 +86,10 @@ if ! agent_install; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $agent == "claude" ]]; then
|
||||
omarchy-install-chromium-claude 2>/dev/null || true
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$agent_file")"
|
||||
printf '%s\n' "$agent" >"$agent_file"
|
||||
|
||||
|
||||
@@ -11,6 +11,18 @@ if (( $# < 1 )); then
|
||||
fi
|
||||
|
||||
HOOK=$1
|
||||
|
||||
# Hook names are fixed labels chosen by Omarchy code (post-update, theme-set,
|
||||
# font-set). The name becomes a filename under the hooks directory. A slash
|
||||
# would turn it into directory levels, and a bare `.` or `..` would point bash
|
||||
# at the directory itself or its parent. Refuse those rather than follow them.
|
||||
# Dots inside a name (a..b) are fine; once slashes are out, only the whole
|
||||
# name being `.` or `..` can leave the directory.
|
||||
if [[ -z $HOOK || $HOOK == */* || $HOOK == "." || $HOOK == ".." ]]; then
|
||||
echo "Invalid hook name: $HOOK" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
HOOK_PATH="$HOME/.config/omarchy/hooks/$1"
|
||||
HOOK_DIR="$HOOK_PATH.d"
|
||||
shift
|
||||
|
||||
@@ -15,6 +15,17 @@ fi
|
||||
|
||||
HOOK_TYPE=$1
|
||||
HOOK_FILE=$2
|
||||
|
||||
# Hook types are the same labels omarchy-hook runs (post-update, theme-set).
|
||||
# The type becomes a directory under the hooks directory. A slash would turn
|
||||
# it into directory levels. A bare `.` or `..` is a name the runner already
|
||||
# refuses, so installing under it would write a hook nothing can run. Refuse
|
||||
# those rather than mkdir/cp into them. Dots inside a name (a..b) are fine.
|
||||
if [[ -z $HOOK_TYPE || $HOOK_TYPE == */* || $HOOK_TYPE == "." || $HOOK_TYPE == ".." ]]; then
|
||||
echo "Invalid hook name: $HOOK_TYPE" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
HOOK_DIR="$HOME/.config/omarchy/hooks/$HOOK_TYPE.d"
|
||||
HOOK_NAME=$(basename "$HOOK_FILE")
|
||||
HOOK_PATH="$HOOK_DIR/$HOOK_NAME"
|
||||
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Detect whether an Elgato Cam Link 4K is plugged in.
|
||||
|
||||
grep -qsx "Cam Link 4K" /sys/bus/usb/devices/*/product
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Install the Claude desktop app
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "Installing Claude..."
|
||||
omarchy-pkg-add claude-desktop
|
||||
|
||||
echo "Opening Claude..."
|
||||
setsid uwsm-app -- /usr/bin/claude-desktop >/dev/null 2>&1 &
|
||||
|
||||
echo ""
|
||||
echo "Claude has been installed."
|
||||
@@ -140,7 +140,10 @@ import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, sys.argv[1])
|
||||
from hermes_cli.main import _write_desktop_build_stamp
|
||||
if Path(sys.argv[1], "hermes_cli/main_desktop.py").is_file():
|
||||
from hermes_cli.main_desktop import _write_desktop_build_stamp
|
||||
else:
|
||||
from hermes_cli.main import _write_desktop_build_stamp
|
||||
|
||||
_write_desktop_build_stamp(Path(sys.argv[1]), source_mode=False)
|
||||
PY
|
||||
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Install the Claude extension for Chromium-based browsers
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if (( EUID == 0 )); then
|
||||
export PATH=/usr/bin:/bin
|
||||
fi
|
||||
|
||||
EXTENSION_ID="fcoeoabgfenejglbffodgkkbkcdhcgfn"
|
||||
EXTENSION_JSON='{ "external_update_url": "https://clients2.google.com/service/update2/crx" }'
|
||||
PACKAGED_PATH=/usr/bin/omarchy-install-chromium-claude
|
||||
|
||||
# Brave and Brave Origin share Chromium's external extension directory.
|
||||
# Seed all supported browsers, including those installed after choosing Claude.
|
||||
EXTENSION_DIRS=(
|
||||
/usr/share/chromium/extensions
|
||||
/usr/share/google-chrome/extensions
|
||||
/usr/share/microsoft-edge/extensions
|
||||
)
|
||||
|
||||
installed=true
|
||||
for dir in "${EXTENSION_DIRS[@]}"; do
|
||||
if [[ ! -f $dir/$EXTENSION_ID.json ]] || [[ $(cat "$dir/$EXTENSION_ID.json") != "$EXTENSION_JSON" ]]; then
|
||||
installed=false
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $installed == "true" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if (( EUID == 0 )); then
|
||||
for dir in "${EXTENSION_DIRS[@]}"; do
|
||||
printf '%s\n' "$EXTENSION_JSON" | install -D -m 0644 /dev/stdin "$dir/$EXTENSION_ID.json"
|
||||
done
|
||||
elif [[ -t 0 ]]; then
|
||||
exec sudo "$PACKAGED_PATH"
|
||||
else
|
||||
exec pkexec "$PACKAGED_PATH"
|
||||
fi
|
||||
@@ -10,7 +10,7 @@ set -e
|
||||
echo "Installing Xbox controller Bluetooth support..."
|
||||
|
||||
# Install xpadneo to ensure controllers work out of the box
|
||||
omarchy-pkg-add linux-headers xpadneo-dkms
|
||||
omarchy-pkg-add xpadneo-dkms
|
||||
|
||||
# Prevent xpad/xpadneo driver conflict
|
||||
echo blacklist xpad | sudo tee /etc/modprobe.d/blacklist-xpad.conf >/dev/null
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
source omarchy-restart-gum
|
||||
|
||||
cmd="$*"
|
||||
presentation_script="omarchy-show-logo; $cmd; if (( \$? != 130 )); then omarchy-show-done; fi"
|
||||
# 130 is the user bailing with Ctrl-C; anything else gets the Done/Failed prompt.
|
||||
presentation_script="omarchy-show-logo; $cmd; code=\$?; if (( code != 130 )); then omarchy-show-done \$code; fi"
|
||||
|
||||
exec setsid uwsm-app -- xdg-terminal-exec --app-id=org.omarchy.terminal --title=Omarchy -e bash -c "$presentation_script"
|
||||
@@ -24,6 +24,7 @@ if [[ -n $pkg_names ]]; then
|
||||
source omarchy-sudo-keepalive
|
||||
|
||||
echo "$pkg_names" | sed 's/^/aur\//' | tr '\n' ' ' | xargs yay -S --noconfirm
|
||||
code=$?
|
||||
sudo updatedb --prune-bind-mounts=no --add-prunepaths=/.snapshots
|
||||
omarchy-show-done
|
||||
omarchy-show-done $code
|
||||
fi
|
||||
@@ -22,5 +22,5 @@ if [[ -n $pkg_names ]]; then
|
||||
|
||||
# Convert newline-separated selections to space-separated for pacman
|
||||
echo "$pkg_names" | tr '\n' ' ' | xargs sudo pacman -S --noconfirm
|
||||
omarchy-show-done
|
||||
omarchy-show-done $?
|
||||
fi
|
||||
@@ -20,5 +20,5 @@ pkg_names=$(yay -Qqe | fzf "${fzf_args[@]}")
|
||||
if [[ -n $pkg_names ]]; then
|
||||
# Convert newline-separated selections to space-separated for yay
|
||||
echo "$pkg_names" | tr '\n' ' ' | xargs sudo pacman -Rns --noconfirm
|
||||
omarchy-show-done
|
||||
omarchy-show-done $?
|
||||
fi
|
||||
@@ -36,7 +36,8 @@ if [[ $hook_mode != "run-deferred" ]]; then
|
||||
echo "Setting channel to $channel"
|
||||
sudo cp -f "$OMARCHY_PATH/default/pacman/pacman-$channel.conf" /etc/pacman.conf
|
||||
sudo cp -f "$OMARCHY_PATH/default/pacman/mirrorlist-$channel" /etc/pacman.d/mirrorlist
|
||||
sudo env OMARCHY_UPDATE_PACMAN=1 pacman -Syyuu --noconfirm
|
||||
# Reset all package DBs and then update
|
||||
omarchy-update-pacman -Syyuu --noconfirm
|
||||
fi
|
||||
|
||||
# Keep the historical hook name, but finish every privileged refresh operation
|
||||
|
||||
@@ -11,8 +11,8 @@ set -e
|
||||
omarchy-refresh-pacman
|
||||
|
||||
# Downgrade any packages to the stable setup
|
||||
sudo env OMARCHY_UPDATE_PACMAN=1 pacman -Suu --noconfirm
|
||||
omarchy-update-pacman -Suu --noconfirm
|
||||
|
||||
# Ensure all packages are installed
|
||||
mapfile -t packages < <(grep -v '^#' "$OMARCHY_PATH/install/omarchy-base.packages" | grep -v '^$')
|
||||
sudo env OMARCHY_UPDATE_PACMAN=1 pacman -Syu --noconfirm --needed "${packages[@]}"
|
||||
omarchy-update-pacman -Syu --noconfirm --needed "${packages[@]}"
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Remove the Claude desktop app along with its configuration and caches.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
# -u so an unset HOME is an error rather than a set of rm -rf paths rooted at /.
|
||||
set -euo pipefail
|
||||
|
||||
# The app rewrites ~/.config/Claude for as long as it runs, so a removal that
|
||||
# leaves it running deletes the directory and watches it come straight back.
|
||||
pkill -x claude-desktop || true
|
||||
|
||||
omarchy-pkg-drop claude-desktop
|
||||
|
||||
# Not ~/.claude, ~/.claude.json, or ~/.cache/claude-cli-nodejs: those belong
|
||||
# to the Claude Code CLI, which ships in a different package that survives
|
||||
# this one. The desktop app keeps its state in its own Electron directories.
|
||||
rm -rf \
|
||||
"$HOME/.config/Claude" \
|
||||
"$HOME/.cache/Claude"
|
||||
|
||||
echo ""
|
||||
echo "Claude has been removed."
|
||||
@@ -1,6 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Display a "Done!" message and wait for user to press any key.
|
||||
# omarchy:summary=Display a "Done!" or "Failed!" message and wait for user to press any key.
|
||||
# omarchy:args=[exit-code]
|
||||
|
||||
code="${1:-0}"
|
||||
|
||||
# The device node is there whether or not a terminal is behind it, so opening
|
||||
# it is the only test that means anything.
|
||||
@@ -13,6 +16,10 @@ while read -rsn 1 -t 0.1 _ </dev/tty; do :; done
|
||||
|
||||
# Prompt on the terminal rather than stdout, or a caller that redirects us
|
||||
# leaves the user waiting on a prompt they were never shown.
|
||||
printf '\n\033[32m● \033[0mDone! Press any key to close...' >/dev/tty
|
||||
if (( code == 0 )); then
|
||||
printf '\n\033[32m● \033[0mDone! Press any key to close...' >/dev/tty
|
||||
else
|
||||
printf '\n\033[31m● \033[0mFailed (exit code %d)! Press any key to close...' "$code" >/dev/tty
|
||||
fi
|
||||
read -rsn 1 </dev/tty
|
||||
echo >/dev/tty
|
||||
+14
-1
@@ -21,6 +21,19 @@ if [[ -z $STATE_NAME ]]; then
|
||||
fi
|
||||
|
||||
case "$COMMAND" in
|
||||
set) touch "$STATE_DIR/$STATE_NAME" ;;
|
||||
set)
|
||||
# State names are fixed labels (reboot-required, restart-*-required). The
|
||||
# name becomes a filename under the state directory. A slash would turn it
|
||||
# into directory levels, and a bare `.` or `..` would touch the directory
|
||||
# itself or its parent. Refuse those. Dots inside a name (a..b) are fine;
|
||||
# once slashes are out, only the whole name being `.` or `..` can leave the
|
||||
# directory. clear needs no such guard: find -name matches basenames only,
|
||||
# so a pattern can never walk out of the directory.
|
||||
if [[ $STATE_NAME == */* || $STATE_NAME == "." || $STATE_NAME == ".." ]]; then
|
||||
echo "Invalid state name: $STATE_NAME" >&2
|
||||
exit 2
|
||||
fi
|
||||
touch "$STATE_DIR/$STATE_NAME"
|
||||
;;
|
||||
clear) find "$STATE_DIR" -maxdepth 1 -type f -name "$STATE_NAME" -delete ;;
|
||||
esac
|
||||
@@ -297,19 +297,34 @@ rebuild_next_boot() {
|
||||
umount "$next$esp_mount"
|
||||
}
|
||||
|
||||
# Both the staged system and the retained baseline must lose the old hashes.
|
||||
scrub_factory_accounts() {
|
||||
local root="$1" user users
|
||||
|
||||
users=$(awk -F: '$3 >= 1000 && $3 < 60000 { print $1 }' "$root/etc/passwd") || return 1
|
||||
for user in $users; do
|
||||
userdel --root "$root" "$user" 2>>"$LOG_FILE" || return 1
|
||||
rm -rf "${root:?}/home/$user" || return 1
|
||||
done
|
||||
|
||||
# passwd --lock preserves the hash. Replace it, then remove the backups
|
||||
# that userdel and usermod leave behind.
|
||||
usermod --root "$root" --password '!' root >>"$LOG_FILE" 2>&1 || return 1
|
||||
rm -f "$root/etc/"{shadow-,gshadow-,passwd-,group-,subuid-,subgid-}
|
||||
}
|
||||
|
||||
# Remove the seller's account material and machine identity from the retained
|
||||
# @factory baseline so it can neither be mounted for recovery nor restore the
|
||||
# seller's account on a future reset. Idempotent (a scrubbed baseline has no
|
||||
# uid>=1000 accounts left to remove).
|
||||
sanitize_factory_baseline() {
|
||||
local factory="$1" user
|
||||
local factory="$1"
|
||||
btrfs property set -ts "$factory" ro false
|
||||
|
||||
for user in $(awk -F: '$3 >= 1000 && $3 < 60000 { print $1 }' "$factory/etc/passwd"); do
|
||||
userdel --root "$factory" "$user" 2>>"$LOG_FILE" || true
|
||||
rm -rf "${factory:?}/home/$user"
|
||||
done
|
||||
passwd --root "$factory" --lock root >>"$LOG_FILE" 2>&1 || true
|
||||
if ! scrub_factory_accounts "$factory"; then
|
||||
btrfs property set -ts "$factory" ro true
|
||||
fail "could not remove account credentials from the factory baseline (see $LOG_FILE)"
|
||||
fi
|
||||
rm -f "$factory"/etc/ssh/ssh_host_*
|
||||
rm -f "$factory"/etc/NetworkManager/system-connections/*
|
||||
rm -rf "$factory"/var/lib/NetworkManager/* "$factory/var/lib/tailscale" "$factory/var/lib/iwd"
|
||||
@@ -337,17 +352,13 @@ stage_full_reset() {
|
||||
rm -rf "$next"/var/lib/NetworkManager/* "$next/var/lib/tailscale" "$next/var/lib/iwd"
|
||||
rm -f "$next/var/lib/sddm/state.conf" "$next/etc/sddm.conf.d/autologin.conf"
|
||||
|
||||
# A factory snapshot from a normal (normal) install contains the original
|
||||
# A factory snapshot from a normal install contains the original
|
||||
# user account; first-boot setup must start from none. A leftover account
|
||||
# would keep its password hash and group memberships (including wheel), so
|
||||
# failure here has to abort the reset, not be shrugged off.
|
||||
local user
|
||||
for user in $(awk -F: '$3 >= 1000 && $3 < 60000 { print $1 }' "$next/etc/passwd"); do
|
||||
log "Removing user $user from the factory system"
|
||||
userdel --root "$next" "$user" 2>>"$LOG_FILE" ||
|
||||
fail "could not remove user $user from the factory system (see $LOG_FILE)"
|
||||
done
|
||||
passwd --root "$next" --lock root >>"$LOG_FILE" 2>&1 || true
|
||||
log "Removing account credentials from the factory system"
|
||||
scrub_factory_accounts "$next" ||
|
||||
fail "could not remove account credentials from the factory system (see $LOG_FILE)"
|
||||
|
||||
# @factory itself survives the wipe as the baseline for future resets. If it
|
||||
# came from a normal install it still holds the seller's account and
|
||||
|
||||
@@ -8,7 +8,7 @@ gum style --border normal --padding "1 2" \
|
||||
"• You cannot stop the update once you start!" \
|
||||
"• Make sure you're connected to power or have a full battery" \
|
||||
"" \
|
||||
"What's new: https://github.com/basecamp/omarchy/releases/latest"
|
||||
"What's new: https://github.com/omacom/omarchy/releases/latest"
|
||||
|
||||
echo
|
||||
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
# omarchy:summary=Ensure the Omarchy and Arch keyring packages are installed and populated
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
# omarchy-update runs this under set -e as a trusted pre-step, so a failed recv
|
||||
# or a broken keyring has to stop this script here, not surface later as
|
||||
# signature errors in the middle of the main transaction.
|
||||
set -euo pipefail
|
||||
|
||||
if omarchy-pkg-missing omarchy-keyring || ! sudo pacman-key --list-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 &>/dev/null; then
|
||||
sudo pacman-key --recv-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 --keyserver keys.openpgp.org
|
||||
sudo pacman-key --lsign-key 40DFB630FF42BCFFB047046CF0134EE680CAC571
|
||||
@@ -19,4 +24,8 @@ fi
|
||||
# Always reinstall, as the keyring can be updated without a package version bump.
|
||||
echo -e "\e[32m\nUpdate Arch signing keys\e[0m"
|
||||
sudo pacman -Sy --noconfirm archlinux-keyring >/dev/null 2> >(grep -vE '^warning: archlinux-keyring-[^ ]+ is up to date -- reinstalling$' >&2)
|
||||
|
||||
# Say "correct" only once the key verifiably is: before the failure checks
|
||||
# above, a failed recv or reinstall still ended here with exit 0.
|
||||
sudo pacman-key --list-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 >/dev/null
|
||||
echo "Keys are correct"
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Run a pacman transaction for the Omarchy update flow, shielded from desktop session teardown.
|
||||
# omarchy:args=<pacman-args>
|
||||
# omarchy:hidden=true
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
# Upgrading systemd runs its post_upgrade scriptlet mid-transaction, which
|
||||
# reexecs both the system manager and every user manager. A pacman running
|
||||
# inside a user-session scope can be SIGKILLed by that reexec, abandoning the
|
||||
# transaction halfway. Registering the transaction as a PID 1 scope keeps it
|
||||
# out of the user manager's cgroups entirely, and system scopes survive the
|
||||
# system manager's own reexec.
|
||||
scope=()
|
||||
if [[ -d /run/systemd/system && ! -L /run/systemd/system ]]; then
|
||||
scope=(systemd-run --scope --quiet --collect)
|
||||
fi
|
||||
|
||||
# LC_ALL passes through so callers that parse pacman's stderr can pin the locale.
|
||||
env_args=(OMARCHY_UPDATE_PACMAN=1)
|
||||
if [[ -n ${LC_ALL:-} ]]; then
|
||||
env_args+=(LC_ALL="$LC_ALL")
|
||||
fi
|
||||
|
||||
exec sudo env "${env_args[@]}" "${scope[@]}" pacman "$@"
|
||||
@@ -10,7 +10,7 @@ set -e
|
||||
# a stream, because an upgrade without --noconfirm prompts on stderr. The
|
||||
# handler has already said why, so no heading here either.
|
||||
if [[ ${OMARCHY_UPDATE_CONFLICT:-} == 1 && ${OMARCHY_UPDATE_INTERACTIVE:-} == 1 ]]; then
|
||||
exec sudo env OMARCHY_UPDATE_PACMAN=1 pacman -Syu --overwrite '/usr/share/omarchy/*'
|
||||
exec omarchy-update-pacman -Syu --overwrite '/usr/share/omarchy/*'
|
||||
fi
|
||||
|
||||
echo -e "\e[32m\nUpdate system packages\e[0m"
|
||||
@@ -23,7 +23,7 @@ trap 'rm -f "$errors"' EXIT
|
||||
#
|
||||
# Progress bars stay on stdout. Errors are on stderr, kept for the conflict
|
||||
# handler below; LC_ALL=C is what keeps them parseable in any locale.
|
||||
if sudo env LC_ALL=C OMARCHY_UPDATE_PACMAN=1 pacman -Syu --noconfirm \
|
||||
if LC_ALL=C omarchy-update-pacman -Syu --noconfirm \
|
||||
--overwrite '/usr/share/omarchy/*' 2>"$errors"; then
|
||||
cat "$errors" >&2
|
||||
exit 0
|
||||
|
||||
@@ -965,7 +965,7 @@ populate_legacy_hypr_defaults() {
|
||||
tmp_dir=$(mktemp -d)
|
||||
archive_dir="$tmp_dir/archive"
|
||||
mkdir -p "$archive_dir"
|
||||
if curl -fsSL https://github.com/basecamp/omarchy/archive/refs/heads/master.tar.gz | tar -xz -C "$archive_dir" &&
|
||||
if curl -fsSL https://github.com/omacom/omarchy/archive/refs/heads/master.tar.gz | tar -xz -C "$archive_dir" &&
|
||||
[[ -d $archive_dir/omarchy-master/default/hypr ]]; then
|
||||
cp -a "$archive_dir/omarchy-master/default/hypr/." "$shim_hypr_dir/"
|
||||
fi
|
||||
@@ -1569,7 +1569,6 @@ refresh xournalpp/settings.xml 1c1a9efbf1b6dc7813bf3440fd5bf8409fc283e8d0192ca29
|
||||
# fastfetch/config.jsonc -> /etc/fastfetch/config.jsonc
|
||||
# fontconfig/fonts.conf -> /usr/share/fontconfig/conf.avail/50-omarchy.conf
|
||||
# mimeapps.list -> /usr/share/applications/mimeapps.list
|
||||
# omarchy.ttf -> /usr/share/fonts/omarchy/omarchy.ttf
|
||||
# systemd/user/bt-agent.service -> /usr/lib/systemd/user/bt-agent.service
|
||||
# systemd/user/omarchy-recover-internal-monitor.service -> /usr/lib/systemd/user/omarchy-recover-internal-monitor.service
|
||||
# systemd/user/omarchy-sleep-lock.service -> /usr/lib/systemd/user/omarchy-sleep-lock.service
|
||||
@@ -1602,7 +1601,6 @@ retire fontconfig/fonts.conf 6dec98b539388b95ecfdb3c7ab951001c712820eb0581002832
|
||||
retire fontconfig/fonts.conf 3545f6c5a8c1465df7a4e251b3c2047d4ba03654c86636794f64cb0d8ea8ef63
|
||||
retire fontconfig/fonts.conf 0f085b449f1cbe8eda3b59a6235bf2a3ddb6e982ab5d22fa642248916e63bafc
|
||||
retire mimeapps.list 3b574cef135b5deb7a8a0c7e17139037cf1fe155300e3809f60bed0e04120975
|
||||
retire omarchy.ttf e55e67119e82f56f92d90cbf54b7ccc1b2946b32c535a29370439d7ef5215966
|
||||
retire systemd/user/bt-agent.service 0406b577a1225dc2a9f86638d3c346eb3635168576f04050be50ebcc0be6be12
|
||||
retire systemd/user/omarchy-recover-internal-monitor.service b9b92cedc44cf3cb6216948629be55b53d16746e31896dc6469fd49ba55e82f4
|
||||
retire systemd/user/omarchy-recover-internal-monitor.service e1483079b9f2aefcd43b4722c75a31643e5f3bb5a2eada5f52f1d7d201e8c289
|
||||
@@ -2381,6 +2379,8 @@ cleanup_retired_services
|
||||
ensure_sleep_lock_service
|
||||
remove_retired_default_packages
|
||||
run_final_system_package_upgrade
|
||||
# This also retires the stock ~/.local/share/fonts/omarchy.ttf missed by the
|
||||
# former ~/.config retirement entry, through migration 1788848726.
|
||||
run_post_upgrade_migrations
|
||||
run_post_upgrade_update_steps
|
||||
refresh_current_theme_after_upgrade
|
||||
|
||||
+25
-2
@@ -1457,8 +1457,31 @@ To stop: omarchy-windows-vm stop"
|
||||
fi
|
||||
# If scale is less than 130%, don't set any scale (use default 100)
|
||||
|
||||
# Connect with RDP in fullscreen (auto-detects resolution)
|
||||
xfreerdp3 /u:"$WIN_USER" /p:"$WIN_PASS" /v:127.0.0.1:3389 -grab-keyboard /sound /microphone /clipboard /cert:ignore /title:"Windows VM - Omarchy" /dynamic-resolution /gfx:AVC444 /floatbar:sticky:off,default:visible,show:fullscreen $RDP_SCALE
|
||||
RDP_ARGS=(
|
||||
"/u:$WIN_USER"
|
||||
"/p:$WIN_PASS"
|
||||
/v:127.0.0.1:3389
|
||||
-grab-keyboard
|
||||
/sound
|
||||
/microphone
|
||||
/clipboard
|
||||
/cert:ignore
|
||||
"/title:Windows VM - Omarchy"
|
||||
/dynamic-resolution
|
||||
/gfx:AVC444
|
||||
/floatbar:sticky:off,default:visible,show:fullscreen
|
||||
)
|
||||
if [[ -n $RDP_SCALE ]]; then
|
||||
RDP_ARGS+=("$RDP_SCALE")
|
||||
fi
|
||||
|
||||
# Connect with RDP in fullscreen (auto-detects resolution). The arguments go
|
||||
# in over stdin rather than on the command line: /proc/<pid>/cmdline is
|
||||
# world-readable, so passing the VM password as /p:"$WIN_PASS" would show it
|
||||
# to every other user on the machine for as long as the session is open.
|
||||
# /args-from must stay the only argument here — FreeRDP rejects it outright
|
||||
# when it is combined with any other, so new flags belong in RDP_ARGS above.
|
||||
printf '%s\n' "${RDP_ARGS[@]}" | xfreerdp3 /args-from:stdin
|
||||
|
||||
# After RDP closes, stop the container unless --keep-alive was specified
|
||||
if [[ $KEEP_ALIVE = "false" ]]; then
|
||||
|
||||
Reference in new issue
Block a user