OpenAI ships an official Linux RPM now, so the community wrapper goes away: `panama app chatgpt-desktop` built codex-desktop from the upstream macOS disk image and ran a local rebuild daemon to keep it current, and the official package comes from a repository that upgrades with everything else. The app file, the help example and the dock's pinned id all move over, and a migration replaces the build on machines that already have it -- official package on before the community one comes off, so a failure part-way still leaves an app. The install itself does not follow upstream's instructions. Those are "download this RPM and install it", and the RPM's own root scriptlet is what writes the repository file and drops the signing key into /etc/pki/rpm-gpg -- so root runs an unverified download and then learns from it what to trust. That is the shape the repository audit forbids: no network response is executed as root without a verified digest or signature first. OpenAI publishes no key and no fingerprint anywhere an install could fetch and check them, so the key is pinned here instead. setup/keys/ carries it and says where it came from, including the honest part -- this is trust established on first use and then held, not trust verified against the publisher. setup/lib/ chatgpt-package verifies that copy's fingerprint, installs it, and writes the repository with gpgcheck and repo_gpgcheck on before anything is installed, so dnf checks the metadata signature and the package signature itself. It is byte for byte the repository the scriptlet would have written, so nothing churns afterwards, and every later upgrade goes through the same key. Both callers use it; a verification failure skips ChatGPT rather than installing it anyway. The contract proves the pinned key is the key the library names, that a missing, unreadable or mismatched key writes nothing at all, that what is written actually turns the checks on, and that neither caller hands root a downloaded RPM. Claude-Session: https://claude.ai/code/session_017zzbtfnMLoYrB8WesqANFY
65 lines
2.8 KiB
Bash
Executable File
65 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# replace the community ChatGPT Desktop build with the official OpenAI package
|
|
#
|
|
# `panama app chatgpt-desktop` used to build a community wrapper (codex-desktop)
|
|
# from the upstream macOS disk image, complete with a local rebuild daemon.
|
|
# OpenAI ships an official Linux RPM now, and the installer takes that instead;
|
|
# this repairs machines still carrying the community build. The official
|
|
# package goes on before the community one comes off, so a failure part-way
|
|
# leaves the machine with an app, never without one.
|
|
#
|
|
# Rules, because the runner cannot enforce them:
|
|
#
|
|
# * Safe to run twice. The marker records success, not intent.
|
|
# * Tolerant of the repair already being correct -- the user may have fixed
|
|
# it by hand, or a later ./install may have put it back.
|
|
# * Root work goes through `panama-sudo --reason "..."`, never bare sudo,
|
|
# so the password prompt names the repair.
|
|
# * Exit non-zero to be retried at the next login. Exit zero only when the
|
|
# machine is genuinely in the state this describes.
|
|
|
|
set -euo pipefail
|
|
|
|
PANAMA_PATH="${PANAMA_PATH:-$HOME/.local/share/Panama}"
|
|
|
|
# Machines that never had the community build are already correct. The official
|
|
# app is the installer's job, not this one's.
|
|
rpm -q codex-desktop >/dev/null 2>&1 || exit 0
|
|
|
|
# The same verified repository the installer establishes: the pinned signing
|
|
# key, then a repository that names it, so dnf checks OpenAI's signature before
|
|
# root installs anything. See setup/lib/chatgpt-package.
|
|
# shellcheck source=../setup/lib/chatgpt-package
|
|
source "$PANAMA_PATH/setup/lib/chatgpt-package"
|
|
|
|
sudo_cmd=(sudo)
|
|
if [[ -t 0 && -x "$PANAMA_PATH/bin/panama-sudo" ]]; then
|
|
sudo_cmd=(
|
|
"$PANAMA_PATH/bin/panama-sudo" --reason
|
|
"Replacing the community-built ChatGPT Desktop (codex-desktop) with the official OpenAI package"
|
|
--
|
|
)
|
|
fi
|
|
|
|
# The official package first, so the machine is never left without one.
|
|
if ! rpm -q chatgpt >/dev/null 2>&1; then
|
|
chatgpt_install_repository "${sudo_cmd[@]}"
|
|
"${sudo_cmd[@]}" dnf install -y chatgpt
|
|
fi
|
|
|
|
# The community package's updater is a user unit; stop it before dnf removes
|
|
# the unit file out from under it. Removal also takes the app in /opt, both
|
|
# binaries, and the polkit policy the local rebuilds needed.
|
|
systemctl --user disable --now codex-update-manager.service 2>/dev/null || true
|
|
"${sudo_cmd[@]}" dnf remove -y codex-desktop
|
|
systemctl --user daemon-reload 2>/dev/null || true
|
|
|
|
# The rebuild state the updater kept; the official package needs none of it.
|
|
rm -rf "${XDG_CACHE_HOME:-$HOME/.cache}/codex-update-manager" \
|
|
"${XDG_CACHE_HOME:-$HOME/.cache}/codex-runtimes" \
|
|
"${XDG_CONFIG_HOME:-$HOME/.config}/codex-update-manager" \
|
|
"${XDG_STATE_HOME:-$HOME/.local/state}/codex-update-manager"
|
|
|
|
echo "Replaced the community codex-desktop build with the official chatgpt package."
|