Drop the tool offering during this initial install

This commit is contained in:
David Heinemeier Hansson committed 2026-07-14 17:03:06 -07:00
1 parent 08b7460900
commit c77a7b555b
1 file changed
-319
-319
View File
@@ -1,262 +1,5 @@
#!/bin/bash
# The configurator normally runs under this small PTY proxy so Ctrl-T can work
# as a global tools shortcut even while gum owns the terminal in raw mode. The
# child configurator keeps stdout on the existing stream (so generated config and
# logs behave normally), while stderr and /dev/tty traffic are relayed through the
# PTY. Pressing Ctrl-T kills the current configurator screen, opens Tools, then
# starts the configurator over at keyboard selection.
if [[ -z "${OMARCHY_CONFIGURATOR_INNER:-}" && -z "${OMARCHY_CONFIGURATOR_NO_KEY_PROXY:-}" ]] && { [[ -t 0 ]] || [[ -t 2 ]]; }; then
OMARCHY_CONFIGURATOR_PYTHON=$(command -v python3 2>/dev/null || command -v python 2>/dev/null || true)
if [[ -n "$OMARCHY_CONFIGURATOR_PYTHON" ]]; then
export OMARCHY_CONFIGURATOR_SCRIPT
OMARCHY_CONFIGURATOR_SCRIPT=$(readlink -f "${BASH_SOURCE[0]}" 2>/dev/null || printf '%s' "${BASH_SOURCE[0]}")
exec "$OMARCHY_CONFIGURATOR_PYTHON" - "$@" <<'PY'
import errno
import fcntl
import os
import pty
import select
import signal
import sys
import termios
import time
CTRL_T = b"\x14"
SCRIPT = os.environ["OMARCHY_CONFIGURATOR_SCRIPT"]
ARGS = sys.argv[1:]
try:
tty_fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
except OSError:
env = os.environ.copy()
env["OMARCHY_CONFIGURATOR_INNER"] = "1"
os.execvpe("bash", ["bash", SCRIPT] + ARGS, env)
stdout_fd = os.dup(1)
original_tty = termios.tcgetattr(tty_fd)
current_master = None
current_pgid = None
def restore_tty():
try:
termios.tcsetattr(tty_fd, termios.TCSADRAIN, original_tty)
except termios.error:
pass
def write_tty(data):
if data:
os.write(tty_fd, data)
def copy_window_size(master):
try:
size = fcntl.ioctl(tty_fd, termios.TIOCGWINSZ, b"\0" * 8)
fcntl.ioctl(master, termios.TIOCSWINSZ, size)
except OSError:
pass
def on_winch(signum, frame):
if current_master is not None:
copy_window_size(current_master)
if current_pgid is not None:
try:
os.killpg(current_pgid, signal.SIGWINCH)
except OSError:
pass
def on_termination(signum, frame):
if current_pgid is not None:
try:
os.killpg(current_pgid, signum)
except OSError:
pass
restore_tty()
raise SystemExit(128 + signum)
def exit_code(status):
if os.WIFEXITED(status):
return os.WEXITSTATUS(status)
if os.WIFSIGNALED(status):
return 128 + os.WTERMSIG(status)
return 1
def spawn_child(tools_only=False):
global current_master, current_pgid
pid, master = pty.fork()
if pid == 0:
os.dup2(stdout_fd, 1)
try:
os.close(stdout_fd)
except OSError:
pass
env = os.environ.copy()
env["OMARCHY_CONFIGURATOR_INNER"] = "1"
env["OMARCHY_CONFIGURATOR_CTRL_T"] = "1"
if tools_only:
env["OMARCHY_CONFIGURATOR_TOOLS_ONLY"] = "1"
else:
env.pop("OMARCHY_CONFIGURATOR_TOOLS_ONLY", None)
os.execvpe("bash", ["bash", SCRIPT] + ARGS, env)
os.set_blocking(master, False)
current_master = master
current_pgid = pid
copy_window_size(master)
return pid, master
def wait_for_child(pid, timeout):
deadline = time.time() + timeout
while time.time() < deadline:
try:
done, status = os.waitpid(pid, os.WNOHANG)
except ChildProcessError:
return 0
if done == pid:
return exit_code(status)
time.sleep(0.05)
return None
def terminate_child(pid):
for sig, timeout in ((signal.SIGTERM, 0.5), (signal.SIGKILL, 0.2)):
try:
os.killpg(pid, sig)
except ProcessLookupError:
return 0
except OSError:
try:
os.kill(pid, sig)
except OSError:
return 0
code = wait_for_child(pid, timeout)
if code is not None:
return code
return 130
def drain_master(master):
while True:
try:
data = os.read(master, 4096)
except BlockingIOError:
return
except OSError:
return
if not data:
return
write_tty(data)
def relay_child(tools_only=False):
global current_master, current_pgid
pid, master = spawn_child(tools_only)
try:
while True:
try:
done, status = os.waitpid(pid, os.WNOHANG)
except ChildProcessError:
drain_master(master)
return 0
if done == pid:
drain_master(master)
return exit_code(status)
try:
readable, _, _ = select.select([tty_fd, master], [], [], 0.1)
except InterruptedError:
continue
if tty_fd in readable:
try:
data = os.read(tty_fd, 1024)
except OSError:
data = b""
if not data:
continue
if not tools_only and CTRL_T in data:
before = data.split(CTRL_T, 1)[0]
if before:
try:
os.write(master, before)
except OSError:
pass
terminate_child(pid)
drain_master(master)
return "tools"
try:
os.write(master, data)
except OSError:
pass
if master in readable:
try:
data = os.read(master, 4096)
except BlockingIOError:
continue
except OSError as exc:
if exc.errno != errno.EIO:
raise
data = b""
if data:
write_tty(data)
finally:
current_master = None
current_pgid = None
try:
os.close(master)
except OSError:
pass
signal.signal(signal.SIGWINCH, on_winch)
signal.signal(signal.SIGHUP, on_termination)
signal.signal(signal.SIGTERM, on_termination)
# Use raw-ish input so Ctrl-T/Ctrl-C can be intercepted and relayed, but keep
# the real terminal's output processing intact. Full raw mode disables ONLCR,
# causing gum/logo newlines to stair-step across the screen.
tty_attrs = termios.tcgetattr(tty_fd)
tty_attrs[0] &= ~(termios.BRKINT | termios.ICRNL | termios.INPCK | termios.ISTRIP | termios.IXON)
tty_attrs[2] |= termios.CS8
tty_attrs[3] &= ~(termios.ECHO | termios.ICANON | termios.IEXTEN | termios.ISIG)
tty_attrs[6][termios.VMIN] = 1
tty_attrs[6][termios.VTIME] = 0
termios.tcsetattr(tty_fd, termios.TCSADRAIN, tty_attrs)
try:
while True:
result = relay_child(tools_only=False)
if result == "tools":
relay_child(tools_only=True)
continue
raise SystemExit(result)
finally:
restore_tty()
try:
os.close(stdout_fd)
os.close(tty_fd)
except OSError:
pass
PY
fi
fi
unset OMARCHY_CONFIGURATOR_PYTHON
# Minimal live-ISO presentation helpers. Keep these local to the ISO: the
# installed Omarchy package owns target setup helpers, while the ISO owns the
# installer UI that runs before any target packages exist.
@@ -323,20 +66,10 @@ abort() {
exit 1
}
tools_hint() {
[[ -n "${OMARCHY_CONFIGURATOR_CTRL_T:-}" && -z "${OMARCHY_CONFIGURATOR_TOOLS_ONLY:-}" ]] || return 0
# Draw the shortcut as a fixed footer instead of in the form body. Keep the
# cursor where the active gum widget expects it; do not print a newline from
# the bottom row or the VT will scroll.
printf "\0337\033[%s;1H\033[2K%s\033[38;5;8mCtrl-T Tools\033[0m\0338" "$TERM_HEIGHT" "$PADDING_LEFT_SPACES"
}
step() {
clear_logo
echo
gum style --padding "0 0 0 $PADDING_LEFT" "$1"
tools_hint
echo
}
@@ -352,58 +85,6 @@ notice() {
echo
}
# Tools menu — recovery-style actions kept off the main install path.
# Inlines its own disk picker so Ctrl-T can open it before disk_form is defined
# further down in the script.
tools_menu() {
while true; do
step "Tools"
local choice
choice=$(gum choose --header "Pick a tool" \
"Open partition tool" \
"Drop to shell" \
"Reboot" \
"Power off" \
"Back to installer") || return 0
case "$choice" in
"Open partition tool")
local d disks
disks=$(lsblk -dpno NAME,TYPE 2>/dev/null | awk '$2=="disk"{print $1}' | grep -E '/dev/(sd|hd|vd|nvme|mmcblk|xv)' || true)
if [[ -z "$disks" ]]; then
notice "No suitable disks found" 2
continue
fi
d=$(echo "$disks" | gum choose --header "Select disk") || continue
clear
cfdisk "$d" || true
partprobe "$d" 2>/dev/null || true
sync
sleep 1
;;
"Drop to shell")
clear
echo "Type 'exit' to return to the tools menu."
bash --norc || true
;;
"Reboot")
reboot
;;
"Power off")
poweroff
;;
"Back to installer")
return 0
;;
esac
done
}
if [[ -n "${OMARCHY_CONFIGURATOR_TOOLS_ONLY:-}" ]]; then
tools_menu
exit 0
fi
# STEP 1: KEYBOARD LAYOUT
keyboard_form() {