From b49e4a904fbe20d30b5e3157de0348ae45b4037a Mon Sep 17 00:00:00 2001 From: Gabriele Modena Date: Wed, 8 Nov 2023 21:47:41 +0100 Subject: [PATCH 1/2] installer: manage application removal from config. Adds the capability to uninstall application that have been removed from `services.flatpak.packages` since the previous activation. --- README.md | 19 ++++++++- flake.lock | 83 ---------------------------------------- modules/home-manager.nix | 2 +- modules/installer.nix | 21 +++++++++- modules/nixos.nix | 2 +- 5 files changed, 39 insertions(+), 88 deletions(-) delete mode 100644 flake.lock diff --git a/README.md b/README.md index c17578c..0dac3b6 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ with homebrew on nix-darwin. the target system state description is not exhaustive, and there's room for divergence across builds and rollbacks. For a number of desktop application I want to be able to track the lastet version, or allow them to auto update. -For such applications, a convergent approach is a reasonable tradeoff wrt system reproducibility. YMMW. +For such applications, a convergent approach is a reasonable tradeoff wrt system reproducibility. YMMV. Flatpak applications are installed by systemd oneshot service triggered at system activation. Depending on the number of applications to install, this could increase activation time significantly. @@ -98,4 +98,19 @@ Auto updates trigger on system activation. Under the hood, updates are scheduled by realtime systemd timers. `onCalendar` accepts systemd's `update.auto.OnCalendar` expressions. Timers are persisted across sleep / resume cycles. -See https://wiki.archlinux.org/title/systemd/Timers for more information. \ No newline at end of file +See https://wiki.archlinux.org/title/systemd/Timers for more information. + +### Storage +Flatpaks are stored out of nix store at `/var/lib/flatpak` and `${HOME}/.local/share/flatpak/` for system +(`nixosModules`) and user (`homeManagerModules`) installation respectively. +Flatpaks isntallation are not generational: upon a system rebuild and rollbacks, changes in packages declaration +will result in downloading applications anew. + +Keeping flatpaks and nix store orthogonal is an explicit design choice, dictate by my use cases: +1. I want to track the latest version of all installed applications. +2. I am happy to trade network for storage. + +YMMV. + +If you need generational builds, [declarative-flatpak](https://github.com/GermanBread/declarative-flatpak) +might be a better fit. diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 2b0d1e9..0000000 --- a/flake.lock +++ /dev/null @@ -1,83 +0,0 @@ -{ - "nodes": { - "home-manager": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1695108154, - "narHash": "sha256-gSg7UTVtls2yO9lKtP0yb66XBHT1Fx5qZSZbGMpSn2c=", - "owner": "nix-community", - "repo": "home-manager", - "rev": "07682fff75d41f18327a871088d20af2710d4744", - "type": "github" - }, - "original": { - "owner": "nix-community", - "ref": "release-23.05", - "repo": "home-manager", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1697226376, - "narHash": "sha256-cumLLb1QOUtWieUnLGqo+ylNt3+fU8Lcv5Zl+tYbRUE=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "898cb2064b6e98b8c5499f37e81adbdf2925f7c5", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.05", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "home-manager": "home-manager", - "nixpkgs": "nixpkgs", - "utils": "utils" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1694529238, - "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/modules/home-manager.nix b/modules/home-manager.nix index 1242a9a..feca4cb 100644 --- a/modules/home-manager.nix +++ b/modules/home-manager.nix @@ -21,7 +21,7 @@ in }; Service = { Type = "oneshot"; - ExecStart = "${import ./installer.nix {inherit cfg pkgs; installation = installation; }}"; + ExecStart = "${import ./installer.nix {inherit cfg pkgs lib; installation = installation; }}"; }; }; diff --git a/modules/installer.nix b/modules/installer.nix index a9d9933..4314576 100644 --- a/modules/installer.nix +++ b/modules/installer.nix @@ -1,7 +1,22 @@ -{ cfg, pkgs, installation ? "system", ... }: +{ cfg, pkgs, lib, installation ? "system", ... }: let updateApplications = cfg.update.onActivation || cfg.update.auto.enable; + applicationsToKeep = lib.strings.concatStringsSep " " (map (builtins.getAttr "appId" ) cfg.packages); + flatpakUninstallCmd = installation: {}: '' + APPS_TO_KEEP=("${applicationsToKeep}") + # Get a list of currently installed Flatpak application IDs + INSTALLED_APPS=$(${pkgs.flatpak}/bin/flatpak --${installation} list --app --columns=application | ${pkgs.gawk}/bin/awk '{print ''$1}') + + # Iterate through the installed apps and uninstall those not present in the to keep list + for APP_ID in $INSTALLED_APPS; do + if [[ ! " ''${APPS_TO_KEEP[@]} " =~ " ''${APP_ID} " ]]; then + ${pkgs.flatpak}/bin/flatpak uninstall --${installation} -y ''$APP_ID + fi + done + + ''; + flatpakInstallCmd = installation: update: { appId, origin ? "flathub", commit ? null, ... }: '' ${pkgs.flatpak}/bin/flatpak --${installation} --noninteractive --no-auto-pin install \ ${if update && commit == null then ''--or-update'' else ''''} ${origin} ${appId} @@ -28,6 +43,10 @@ pkgs.writeShellScript "flatpak-managed-install" '' # Configure remotes ${mkFlatpakAddRemoteCmd installation cfg.remotes} + # Uninstall packages that have been removed from services.flatpak.packages + # since the previous activation. + ${flatpakUninstallCmd installation {}} + # Install packages ${mkFlatpakInstallCmd installation updateApplications cfg.packages} '' diff --git a/modules/nixos.nix b/modules/nixos.nix index 3d04885..08d0890 100644 --- a/modules/nixos.nix +++ b/modules/nixos.nix @@ -16,7 +16,7 @@ in ]; serviceConfig = { Type = "oneshot"; - ExecStart = "${import ./installer.nix {inherit cfg pkgs; installation = installation; }}"; + ExecStart = "${import ./installer.nix {inherit cfg pkgs lib; installation = installation; }}"; }; }; systemd.timers."flatpak-managed-install" = lib.mkIf config.services.flatpak.update.auto.enable { From 8b1c4898ae9f8e2c17764dfb4598286ed798ce76 Mon Sep 17 00:00:00 2001 From: Gabriele Modena Date: Wed, 8 Nov 2023 21:56:49 +0100 Subject: [PATCH 2/2] installer: fix formatting --- modules/installer.nix | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/installer.nix b/modules/installer.nix index 4314576..26eada7 100644 --- a/modules/installer.nix +++ b/modules/installer.nix @@ -2,18 +2,18 @@ let updateApplications = cfg.update.onActivation || cfg.update.auto.enable; - applicationsToKeep = lib.strings.concatStringsSep " " (map (builtins.getAttr "appId" ) cfg.packages); + applicationsToKeep = lib.strings.concatStringsSep " " (map (builtins.getAttr "appId") cfg.packages); flatpakUninstallCmd = installation: {}: '' - APPS_TO_KEEP=("${applicationsToKeep}") - # Get a list of currently installed Flatpak application IDs - INSTALLED_APPS=$(${pkgs.flatpak}/bin/flatpak --${installation} list --app --columns=application | ${pkgs.gawk}/bin/awk '{print ''$1}') - - # Iterate through the installed apps and uninstall those not present in the to keep list - for APP_ID in $INSTALLED_APPS; do - if [[ ! " ''${APPS_TO_KEEP[@]} " =~ " ''${APP_ID} " ]]; then - ${pkgs.flatpak}/bin/flatpak uninstall --${installation} -y ''$APP_ID - fi - done + APPS_TO_KEEP=("${applicationsToKeep}") + # Get a list of currently installed Flatpak application IDs + INSTALLED_APPS=$(${pkgs.flatpak}/bin/flatpak --${installation} list --app --columns=application | ${pkgs.gawk}/bin/awk '{print ''$1}') + + # Iterate through the installed apps and uninstall those not present in the to keep list + for APP_ID in $INSTALLED_APPS; do + if [[ ! " ''${APPS_TO_KEEP[@]} " =~ " ''${APP_ID} " ]]; then + ${pkgs.flatpak}/bin/flatpak uninstall --${installation} -y ''$APP_ID + fi + done '';