diff options
| author | sommerfeld <sommerfeld@sommerfeld.dev> | 2026-09-26 22:23:04 +0100 |
|---|---|---|
| committer | sommerfeld <sommerfeld@sommerfeld.dev> | 2026-09-26 22:23:04 +0100 |
| commit | deb462188fc2adc168c782fca51fae746a299cca (patch) | |
| tree | fd5a99dfd7647dace178040eb23d77e084309543 | |
| parent | 1f79a073474b41263f50c3c0b35dc17b5cdddcf7 (diff) | |
| download | dotfiles-deb462188fc2adc168c782fca51fae746a299cca.tar.gz dotfiles-deb462188fc2adc168c782fca51fae746a299cca.tar.bz2 dotfiles-deb462188fc2adc168c782fca51fae746a299cca.zip | |
Declare official Keybase APT setup for Canonical
| -rw-r--r-- | .chezmoiignore | 1 | ||||
| -rw-r--r-- | docs/canonical-laptop.md | 14 | ||||
| -rw-r--r-- | dot_config/autostart/keybase.desktop | 5 | ||||
| -rw-r--r-- | meta/canonical/apt.txt | 1 | ||||
| -rw-r--r-- | scripts/canonical.py | 35 | ||||
| -rw-r--r-- | tests/test_canonical.py | 29 |
6 files changed, 82 insertions, 3 deletions
diff --git a/.chezmoiignore b/.chezmoiignore index c054bca..a3bbf94 100644 --- a/.chezmoiignore +++ b/.chezmoiignore @@ -100,6 +100,7 @@ canonical-desktop.sh canonical-nvim-lock.sh .config/nix/nix.conf .config/autostart/dotfiles-*.desktop +.config/autostart/keybase.desktop .config/systemd/user/gpg-agent.service.d/canonical.conf .local/lib/dotfiles/ .local/share/gnome-shell/extensions/corporate-panel@dotfiles/ diff --git a/docs/canonical-laptop.md b/docs/canonical-laptop.md index 733e3ba..ef988e1 100644 --- a/docs/canonical-laptop.md +++ b/docs/canonical-laptop.md @@ -177,6 +177,20 @@ without using its cached output. Bootstrap does not need a manual crate prefetch compositors; it cannot inject keys into GNOME without virtual-keyboard protocol support. +## Keybase + +Keybase uses its [official APT installation](https://keybase.io/docs/the_app/install_linux). +It is declared in `meta/canonical/apt.txt`. When it is absent, package setup +downloads the official amd64 DEB over HTTPS and installs it with apt. That +package adds Keybase's update repository. An existing installation is retained +without downloading the bootstrap package again. Normal APT upgrades update it. + +The managed `~/.config/autostart/keybase.desktop` uses `/usr/bin/run_keybase -a` +to start the service and GUI in the tray at GNOME login. It uses the same +autostart filename as Keybase, so it does not add a second launcher. Open +`run_keybase` once to sign in. Test the tray icon and a notification from +another account. No Keybase Snap or Nix service is installed on this role. + ## Work Keys and Containers Transfer and import only the existing **work** secret key through a protected diff --git a/dot_config/autostart/keybase.desktop b/dot_config/autostart/keybase.desktop new file mode 100644 index 0000000..c5ef2db --- /dev/null +++ b/dot_config/autostart/keybase.desktop @@ -0,0 +1,5 @@ +[Desktop Entry] +Type=Application +Name=Keybase +Exec=/usr/bin/run_keybase -a +OnlyShowIn=GNOME; diff --git a/meta/canonical/apt.txt b/meta/canonical/apt.txt index 909470f..25c7551 100644 --- a/meta/canonical/apt.txt +++ b/meta/canonical/apt.txt @@ -10,3 +10,4 @@ python3-gi imv gnome-shell-ubuntu-extensions network-manager-openvpn-gnome +keybase diff --git a/scripts/canonical.py b/scripts/canonical.py index 35bfdcb..a4e0b5d 100644 --- a/scripts/canonical.py +++ b/scripts/canonical.py @@ -5,6 +5,7 @@ import json import os import platform import subprocess +import tempfile from pathlib import Path ROOT = Path(__file__).resolve().parents[1] @@ -74,6 +75,8 @@ def require_canonical() -> None: def install() -> None: subprocess.run(["sudo", "apt-get", "update"], check=True) + if "keybase" in packages("apt"): + install_keybase() subprocess.run(["sudo", "apt-get", "install", *packages("apt")], check=True) for command in snap_install_commands(): if subprocess.run( @@ -87,6 +90,38 @@ def install() -> None: subprocess.run(command, check=True) +def install_keybase() -> None: + status = subprocess.run( + ["dpkg-query", "-W", "-f=${Status}", "keybase"], + check=False, + capture_output=True, + text=True, + ) + if status.returncode == 0 and status.stdout == "install ok installed": + return + if platform.machine() != "x86_64": + raise SystemExit("The Keybase bootstrap package requires amd64.") + with tempfile.TemporaryDirectory(prefix="keybase-") as directory: + Path(directory).chmod(0o755) + package = str(Path(directory) / "keybase_amd64.deb") + subprocess.run( + [ + "curl", + "--fail", + "--location", + "--proto", + "=https", + "--proto-redir", + "=https", + "--output", + package, + "https://prerelease.keybase.io/keybase_amd64.deb", + ], + check=True, + ) + subprocess.run(["sudo", "apt-get", "install", package], check=True) + + def require_lab() -> None: marker = Path("/etc/canonical-lab") if not marker.is_file() or marker.stat().st_uid != 0: diff --git a/tests/test_canonical.py b/tests/test_canonical.py index 4097b3c..1a9be82 100644 --- a/tests/test_canonical.py +++ b/tests/test_canonical.py @@ -39,11 +39,34 @@ class PackageTests(unittest.TestCase): canonical.install() self.assertFalse(any("set" in call.args[0] for call in command.call_args_list)) - def test_keybase_is_not_installed_or_autostarted(self): + def test_keybase_is_installed_and_autostarted_through_apt(self): + self.assertIn("keybase", canonical.packages("apt")) self.assertNotIn("keybase", canonical.packages("snap")) - self.assertFalse( - (ROOT / "dot_config/autostart/dotfiles-keybase.desktop").exists() + entry = (ROOT / "dot_config/autostart/keybase.desktop").read_text() + self.assertIn("Exec=/usr/bin/run_keybase -a", entry) + self.assertIn("OnlyShowIn=GNOME;", entry) + + def test_installed_keybase_is_not_bootstrapped_again(self): + with patch.object(canonical.subprocess, "run") as run: + run.return_value = subprocess.CompletedProcess( + [], 0, "install ok installed" + ) + canonical.install_keybase() + self.assertEqual(run.call_count, 1) + + def test_missing_keybase_uses_official_bootstrap_package(self): + with ( + patch.object(canonical.platform, "machine", return_value="x86_64"), + patch.object(canonical.subprocess, "run") as run, + ): + run.return_value = subprocess.CompletedProcess([], 1, "") + canonical.install_keybase() + commands = [call.args[0] for call in run.call_args_list] + self.assertEqual( + commands[1][-1], "https://prerelease.keybase.io/keybase_amd64.deb" ) + self.assertEqual(commands[2][:3], ["sudo", "apt-get", "install"]) + self.assertTrue(commands[2][-1].endswith("/keybase_amd64.deb")) def test_extensions_install_without_shell_confirmation(self): with ( |
