diff --git a/modules/modules.nix b/modules/modules.nix index 9c8114b3c..17dcdec48 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -88,6 +88,7 @@ let ./programs/dircolors.nix ./programs/direnv.nix ./programs/discocss.nix + ./programs/distrobox.nix ./programs/earthly.nix ./programs/eclipse.nix ./programs/emacs.nix diff --git a/modules/programs/distrobox.nix b/modules/programs/distrobox.nix new file mode 100644 index 000000000..1e9f0ac09 --- /dev/null +++ b/modules/programs/distrobox.nix @@ -0,0 +1,96 @@ +{ lib, pkgs, config, ... }: +let + inherit (lib) generators types mkIf mkEnableOption mkPackageOption mkOption; + + cfg = config.programs.distrobox; + + formatter = pkgs.formats.ini { listsAsDuplicateKeys = true; }; +in { + meta.maintainers = with lib.hm.maintainers; [ aguirre-matteo ]; + + options.programs.distrobox = { + enable = mkEnableOption "distrobox"; + + package = mkPackageOption pkgs "distrobox" { }; + + containers = mkOption { + type = formatter.type; + default = { }; + example = '' + { + python-project = { + image = "fedora:40"; + additional_packages = "python3 git"; + init_hooks = "pip3 install numpy pandas torch torchvision"; + }; + + common-debian = { + image = "debian:13"; + entry = true; + additional_packages = "git"; + init_hooks = [ + "ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/docker" + "ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/docker-compose" + ]; + }; + + office = { + clone = "common-debian"; + additional_packages = "libreoffice onlyoffice"; + entry = true; + }; + + random-things = { + clone = "common-debian"; + entry = false; + }; + } + ''; + description = '' + A set of containers and all its respective configurations. Each option cat be either a + bool, string or a list of strings. If passed a list, the option will be repeated for each element. + See common-debian in the example config. All the available options for the containers can be found + in the distrobox-assemble documentation at . + ''; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "programs.distrobox" pkgs + lib.platforms.linux) + ]; + + home.packages = [ cfg.package ]; + + xdg.configFile."distrobox/containers.ini".source = + (formatter.generate "containers.ini" cfg.containers); + + systemd.user.services.distrobox-home-manager = { + Unit.Description = + "Build the containers declared in ~/.config/distrobox/containers.ini"; + Install.WantedBy = [ "default.target" ]; + + Service.ExecStart = "${pkgs.writeShellScript "distrobox-home-manager" '' + PATH=/run/current-system/sw/bin: + + containers_file=${config.xdg.configHome}/distrobox/containers.ini + prev_hash_file=${config.xdg.configHome}/distrobox/prev_hash + new_hash=$(sha256sum $containers_file | cut -f 1 -d " ") + + if [[ -f $prev_hash_file ]]; then + prev_hash=$(cat $prev_hash_file) + else + prev_hash=0 + fi + + if [[ $prev_hash != $new_hash ]]; then + rm -rf /tmp/storage-run-1000/containers + rm -rf /tmp/storage-run-1000/libpod/tmp + $HOME/.nix-profile/bin/distrobox-assemble create --file $containers_file + echo $new_hash > $prev_hash_file + fi + ''}"; + }; + }; +} diff --git a/tests/default.nix b/tests/default.nix index 12ac48ebf..e689a99f0 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -442,6 +442,7 @@ in import nmtSrc { ./modules/programs/bemenu ./modules/programs/boxxy ./modules/programs/cavalier + ./modules/programs/distrobox ./modules/programs/eww ./modules/programs/firefox ./modules/programs/firefox/firefox.nix diff --git a/tests/modules/programs/distrobox/default.nix b/tests/modules/programs/distrobox/default.nix new file mode 100644 index 000000000..2dbe7e46b --- /dev/null +++ b/tests/modules/programs/distrobox/default.nix @@ -0,0 +1 @@ +{ distrobox-example-config = ./example-config.nix; } diff --git a/tests/modules/programs/distrobox/example-config.ini b/tests/modules/programs/distrobox/example-config.ini new file mode 100644 index 000000000..31ce6682c --- /dev/null +++ b/tests/modules/programs/distrobox/example-config.ini @@ -0,0 +1,20 @@ +[common-debian] +additional_packages=git +entry=true +image=debian:13 +init_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/docker +init_hooks=ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/docker-compose + +[office] +additional_packages=libreoffice onlyoffice +clone=common-debian +entry=true + +[python-project] +additional_packages=python3 git +image=fedora:40 +init_hooks=pip3 install numpy pandas torch torchvision + +[random-things] +clone=common-debian +entry=false diff --git a/tests/modules/programs/distrobox/example-config.nix b/tests/modules/programs/distrobox/example-config.nix new file mode 100644 index 000000000..6046d0f7f --- /dev/null +++ b/tests/modules/programs/distrobox/example-config.nix @@ -0,0 +1,41 @@ +{ + programs.distrobox = { + enable = true; + containers = { + + python-project = { + image = "fedora:40"; + additional_packages = "python3 git"; + init_hooks = "pip3 install numpy pandas torch torchvision"; + }; + + common-debian = { + image = "debian:13"; + entry = true; + additional_packages = "git"; + init_hooks = [ + "ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/docker" + "ln -sf /usr/bin/distrobox-host-exec /usr/local/bin/docker-compose" + ]; + }; + + office = { + clone = "common-debian"; + additional_packages = "libreoffice onlyoffice"; + entry = true; + }; + + random-things = { + clone = "common-debian"; + entry = false; + }; + + }; + }; + + nmt.script = '' + assertFileExists home-files/.config/distrobox/containers.ini + assertFileContent home-files/.config/distrobox/containers.ini \ + ${./example-config.ini} + ''; +}