Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved flake support #129

Open
colinxs opened this issue Aug 15, 2021 · 4 comments
Open

Improved flake support #129

colinxs opened this issue Aug 15, 2021 · 4 comments

Comments

@colinxs
Copy link

colinxs commented Aug 15, 2021

I recently came across Arion and it's been fantastic. Thanks for making this package!

The only thing I've come across that's a bit awkward is the need to have arion-compose.nix and arion-pkgs.nix when using nixUnstable/flakes. Currently I have a dozen arion-{compose,pkgs}.nix scattered about that only contain a single line:

arion-pkgs.nix:

(builtins.getFlake (toString ./.)).legacyPackages.x86_64-linux

arion-compose.nix

(builtins.getFlake (toString ./.)).packages.x86_64-linux.arion-compose

Instead, it would be awesome if the following was possible:

arion --flake .#arion --flake /home/colinxs/fooflake#arion-foo up

This mimics the flake interface for nixos-rebuild, home-manager, and other tools in the Nix ecosystem.

Each flake.nix would look something like:

{
  inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
  inputs.flake-utils.url = "github:numtide/flake-utils";
  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachSystem [ "x86_64-linux" ] (system:
      let pkgs = nixpkgs.legacyPackages."${system}";
      in
      {
        packages.arion = {
          inherit pkgs;
          config = { pkgs, ... }: {
            config.services = {
              webserver = {
                service.useHostStore = true;
                service.command = [
                  "sh"
                  "-c"
                  ''
                    cd "$$WEB_ROOT"
                    ${pkgs.python3}/bin/python -m http.server
                  ''
                ];
                service.ports = [
                  "8000:8000" # host:container
                ];
                service.environment.WEB_ROOT =
                  "${pkgs.nix.doc}/share/doc/nix/manual";
              };
            };
          };
        };
      });
}

Now everything is fully contained in the flake.nix without having to have arion-{compose,pkgs}.nix and you could do cool things like:

arion --flake github:colinxs/arion#arion-foo up

I tried to implement this myself and got about halfway there, but I know nothing about Haskell lol. If someone could help on the Haskell side
I'd be happy to pitch in elsewhere.

@roberth
Copy link
Member

roberth commented Aug 15, 2021

Yes, this needs to be done. My thoughts so far:

We should use a new top-level flake attribute though, because arion projects aren't packages, and shouldn't even be derivations. There's a parallel with nixosConfigurations, but it's better to omit the "lib.nixosSystem" equivalent, because I don't consider the compose file derivation to be a sufficiently stable interface. There's no real need for it to be a derivation in the first place and it only complicates cross-system deployments.

Something like arionConfigurations.${system}.${projectName} makes sense for local development, but for real-world deployments, the user's "choice" of system should have no effect on what's deployed, so it should be a flat flake attr like arionConfigurations.${projectName}.
These can't coexist in the same attr, so we can change the first one to localArionConfigurations.${system}.${projectName}.

Arion modules can be imported at the project, service or NixOS level. The latter isn't arion-specific, so for reusable arion modules in flakes we only need arionProjectModules and arionServiceModules, analogous to nixosModules, which we'll also reuse.

I did think about putting the derivation in a flake attribute anyway, but I just don't think it's constant enough. It'd break uid and therefore cause issues with user volume mounts. I'd also like to implement setting config values via the command line, like an improved docker-compose --env, which makes the arion projects even more like functions and less like enumerable derivations.

@frantisekhanzlikbl
Copy link

frantisekhanzlikbl commented Jul 5, 2022

Just a tip for anyone who stumbles across this: since builtins.getFlake copies the whole repository into the nix store, it is not an acceptable solution for me due to performance reasons. flake-compat can be used to achieve the same result without the copying:

arion-compose.nix

(import
	(
		let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in
		fetchTarball {
			url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
			sha256 = lock.nodes.flake-compat.locked.narHash;
		}
	)
	{ src = ./.; }
).defaultNix.packages.x86_64-linux.arion-compose

@roberth
Copy link
Member

roberth commented Jul 5, 2022

builtins.getFlake copies the whole repository in to the nix store

It seems that NixOS/nix#6530 may solve this.

@roberth
Copy link
Member

roberth commented Jul 5, 2022

My thoughts so far:

We might actually skip the arionConfigurations attr and work with arionModules instead. arionConfiguration would only serve to finalize and instantiate configurations, which can be done equally well at the use site, such as the arion program, an Hercules CI effect, a deploy script in packages or apps, or a flake-parts module. This avoids the issues in my previous comment by promoting interaction with the modules, which are composable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants