Giter Club home page Giter Club logo

nixinate's Introduction

Nixinate 🕶️

Nixinate is a proof of concept that generates a deployment script for each nixosConfiguration you already have in your flake, which can be ran via nix run, thanks to the apps attribute of the flake schema.

Usage

To add and configure nixinate in your own flake, you need to:

  1. Add the result of nixinate self to the apps attribute of your flake.
  2. Add and configure _module.args.nixinate to the nixosConfigurations you want to deploy

Below is a minimal example:

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
    nixinate.url = "github:matthewcroughan/nixinate";
  };

  outputs = { self, nixpkgs, nixinate }: {
    apps = nixinate.nixinate.x86_64-linux self;
    nixosConfigurations = {
      myMachine = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          (import ./my-configuration.nix)
          {
            _module.args.nixinate = {
              host = "itchy.scratchy.com";
              sshUser = "matthew";
              buildOn = "remote"; # valid args are "local" or "remote"
              substituteOnTarget = true; # if buildOn is "local" then it will substitute on the target, "-s"
              hermetic = false;
            };
          }
          # ... other configuration ...
        ];
      };
    };
  };
}

Each nixosConfiguration you have configured should have a deployment script in apps.nixinate, visible in nix flake show like this:

$ nix flake show
git+file:///etc/nixos
├───apps
│   └───nixinate
│       └───myMachine: app
└───nixosConfigurations
    └───myMachine: NixOS configuration

To finally execute the deployment script, use nix run .#apps.nixinate.myMachine

Example Run

[root@myMachine:/etc/nixos]# nix run .#apps.nixinate.myMachine
🚀 Deploying nixosConfigurations.myMachine from /nix/store/279p8aaclmng8kc3mdmrmi6q3n76r1i7-source
👤 SSH User: matthew
🌐 SSH Host: itchy.scratchy.com
🚀 Sending flake to myMachine via nix copy:
([email protected]) Password:
🤞 Activating configuration on myMachine via ssh:
([email protected]) Password:
[sudo] password for matthew:
building the system configuration...
activating the configuration...
setting up /etc...
reloading user units for matthew...
setting up tmpfiles
Connection to itchy.scratchy.com closed.

Available arguments via _module.args.nixinate

  • host string

    A string representing the hostname or IP address of a machine to connect to via ssh.

  • sshUser string

    A string representing the username a machine to connect to via ssh.

  • buildOn "remote" or "local"

    • "remote"

      Push the flake to the remote, build and activate entirely remotely, returning logs via SSH.

    • "local"

      Build the system closure locally, copy to the remote and activate.

  • hermetic bool

    Whether to copy Nix to the remote for usage when building and activating, instead of using the Nix which is already installed on the remote.

  • substituteOnTarget bool

    Whether to fetch closures and paths from the remote, even when building locally. This makes sense in most cases, because the remote will have already built a lot of the paths from the previous deployment. However, if the remote has a slow upload bandwidth, this would not be a good idea to enable.

Project Principles

  • No Premature Optimization: Make it work, then optimize it later if the optimization is taking a lot of time to figure out now.
  • KISS: Keep it simple, stupid. Unnecesary complexity should be avoided.

nixinate's People

Contributors

88maomao avatar fresheyeball avatar magicrb avatar matthewcroughan avatar mrvandalo avatar nixinator avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nixinate's Issues

unfree license, refusing to evaluate

Nixinate remote push failed because of an unfree package in an overlay at flake root, unsure how to workaround.

Here's the offending line (and flake):
https://codeberg.org/j0/configuration2/src/commit/13ffa4227609006149dfc53445a56dfdd7b3fd6c/flake.nix#L87

And the error:

🚀 Deploying nixosConfigurations.j0-laptop from /nix/store/x1amzn456dvdybcb2f65hj5zk66dyf4m-source
👤 SSH User: jo
🌐 SSH Host: 100.110.59.89
🔨 Building system closure locally, copying it to remote store and activating it:
+ NIX_SSHOPTS=-t
+ /nix/store/f5c6kjnh9439gdx3ds2smjmg0fck7szq-flock-0.2.3/bin/flock -w 60 /dev/shm/nixinate-j0-laptop /nix/store/cagvpvsk0w0crv7bg58si15mmzsf8zzs-nixos-rebuild/bin/nixos-rebuild switch --flake /nix/store/x1amzn456dvdybcb2f65hj5zk66dyf4m-source#j0-laptop --target-host [email protected] --use-remote-sudo
building the system configuration...
trace: warning: optionsDocBook is deprecated since 23.11 and will be removed in 24.05
trace: warning: optionsDocBook is deprecated since 23.11 and will be removed in 24.05
trace: warning: optionsDocBook is deprecated since 23.11 and will be removed in 24.05
trace: warning: mdadm: Neither MAILADDR nor PROGRAM has been set. This will cause the `mdmon` service to crash.
error: Package ‘tetrio-desktop-8.0.0’ in /nix/store/iarm76b9p60gbkxs0n3dww1r2f4gs650-source/pkgs/games/tetrio-desktop/default.nix:86 has an unfree license (‘unfree’), refusing to evaluate.

       a) To temporarily allow unfree packages, you can use an environment variable
          for a single invocation of the nix tools.

            $ export NIXPKGS_ALLOW_UNFREE=1

        Note: For `nix shell`, `nix build`, `nix develop` or any other Nix 2.4+
        (Flake) command, `--impure` must be passed in order to read this
        environment variable.

       b) For `nixos-rebuild` you can set
         { nixpkgs.config.allowUnfree = true; }
       in configuration.nix to override this.

       Alternatively you can configure a predicate to allow specific packages:
         { nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
             "tetrio-desktop"
           ];
         }

       c) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
         { allowUnfree = true; }
       to ~/.config/nixpkgs/config.nix.
(use '--show-trace' to show detailed location information)

Handle private inputs

Just switching to nixinate and run into some minor problem. I use inputs which are private and prefer buildOn = remote.
This results (of course) in an exeption "Permission Denied".
A fix at the moment for me is to run :

nix flake archive --json \
  | jq -r '.inputs.private_assets.path' \
  | xargs nix-copy-closure root@myMachine

But it would be to have a more convenient way right in the flake.nix to do this.
(of course coping every input makes no sense).

Alternatively I'll create a pull request describing this problem an a proper solution in the README.md or something (if wanted of course).

`nixinate is not a valid system type`

nix flake show:

git+file:///home/qd/Dropbox/dotfiles?ref=refs%2fheads%2fmain&rev=a03c76c10699de7315365dd6f0faa792e2a2fbff
├───apps
│   └───nixinate
│       ├───herc-agent: app
│       └───herc-agent-dry-run: app

Everything works (including deployment) except for nix flake check, which is borked.

qd@fw ~/D/dotfiles (main) [1]> nix flake check --show-trace
error: 'nixinate' is not a valid system type, at /nix/store/lamv8sjrhqznfacw4qxy4p4q2rjxi4yg-source/flake.nix:70:14

       … while checking flake output 'apps'

       at /nix/store/97c4ljj5afikynn9nsqzs5b6mwx79n1f-source/flake.nix:58:7:

           57|     in {
           58|       apps = nixinate.nixinate.${machines.common.system} self;
             |       ^
           59|

is there a way to increase ulimit ?

I get the following failures when trying to update my system.

building the system configuration...
error (ignored): error: opening directory '/tmp/nix-build-perl-5.36.0-env.drv-4': Too many open files
error (ignored): error: opening directory '/nix/store/lkpm61x3fsckk4cniy4clsgp62wg9xn6-perl-5.36.0-env.drv.chroot': Too many open files
error (ignored): error: opening directory '/nix/store/kqwhbsypilb7g7sky5a6v1l1r1cr89vi-perl-5.36.0-env.drv.chroot/nix/store/0h17z31z87cfggv77bakfk7cdk1r06fr-perl-5.36.0-env/lib/perl5/5.36.0': Too many open files
error: creating pipe: Too many open files

is there an attribute to increase the ulimit ?

Implement local builds

Some flakes may have closed source private git repos in its inputs, which means pushing the whole flake to the remote and building there is not hermetically possible. An argument should be possible to pass that makes building occur on the local machine and nix copy the closure over to the remote.

Example run in README is incorrect

A minor issue but it took me a few mins to realise. The example run uses the command:

[root@myMachine:/etc/nixos]# nix run .#apps.nixinate.myMachine

The apps prefix before .#apps.nixinate... is not necessary. It should be:

[root@myMachine:/etc/nixos]# nix run .#nixinate.myMachine

error: cannot fetch input examples

This error appears when a new input is being fetched.

error: cannot fetch input 'path:./examples?narHash=sha256-OsFQxO7h4YHrRQX8oHIjvgjTbeJx0oIP+pOIpfiwMiU=' because it uses a relative path

allow boot deployments

Would be cool to be able to not only nixos-rebuild switch but also nixos-rebuild boot when deploying to remote machines.

don't know how to build these path

hey I've just updated to the latest nixinate master and it seems to be giving me the following error

don't know how to build these paths:
  /nix/store/cw9hr92idq1p5iady76xm4si9jqha2yw-nixos-rebuild
error: build of '/nix/store/cw9hr92idq1p5iady76xm4si9jqha2yw-nixos-rebuild' failed

Do I need to change anything ?

error: attribute 'currentSystem' missing

when i run nix flake show in my flake, i get this error:

git+file:///home/jo/Projects/configuration2
├───apps
│   └───nixinate
error: attribute 'currentSystem' missing

       at /nix/store/jzbrxi44g3z3320b6k60nvp3kfw01ja1-source/pkgs/top-level/impure.nix:17:43:

           16|   # (build, in GNU Autotools parlance) platform.
           17|   localSystem ? { system = args.system or builtins.currentSystem; }
             |                                           ^
           18|
(use '--show-trace' to show detailed location information)

my flake is at https://codeberg.org/j0/configuration2

error: 'nixinate' is not a valid system type

When running nix flake check, it complains about nixinate not being a valid system type

❯ nix flake check
error: 'nixinate' is not a valid system type, at /nix/store/n3gxibvxm0i4zkdb5s6dkalwsyr5qni6-source/flake.nix:46:14
(use '--show-trace' to show detailed location information)

Add support for groups

it would be very helpful if you could great a group of hosts that can then be deployed at once.

Nix code example:

nixinate = {
  group.production.hosts = [ "hetznix" "swordfish" ];
  group.production.buildOn = "remote"; # available options are "remote", "local" or a specific host
};

`flock` not a dependency

I'm deploying my herc agent on digital ocean from itself, with a herc effect.

bug from logs

🚀 Deploying nixosConfigurations.herc-agent from /nix/store/dxbvs58xw7c7pzjq9xdgnj59d1a49nib-source
👤 SSH User: root
🌐 SSH Host: 142.93.190.80
🔨 Building system closure locally, copying it to remote store and activating it:
+++ NIX_SSHOPTS=-t
+++ flock -w 60 /dev/shm/nixinate-herc-agent -c '/nix/store/z7pwpz0fkdcnqhypmjqrqpj11m9ny8pc-nixos-rebuild/bin/nixos-rebuild  switch --flake /nix/store/dxbvs58xw7c7pzjq9xdgnj59d1a49nib-source#herc-agent --target-host [email protected] --use-remote-sudo -s'
/nix/store/4k148qpmy1b9xck6v4dah417k6w22p25-deploy-herc-agent.sh: line 6: flock: command not found

See my effect/default.nix at the relevant commit

It would be nice if flock was made explicit. I do not currently have a workaround. In the commit after the one I linked above, I tried to put flock in environment.systemPackages, which also did not work.

Btw, my agent says it has a flock, so maybe this is on the herc agent codebase...

[herc-admin@herc-agent:~]$ which flock
/run/current-system/sw/bin/flock

Edit, workaround

with agent.pkgs;
effects.runIf (ref == "refs/heads/main") (effects.mkEffect {
  effectScript = ''
    mkdir -p flockpath
    cp ${util-linux}/bin/flock flockpath/flock
    export PATH=$PATH:flockpath
    ${nixination.${agent.hostname}.program}
  '';

rsync to /run instead of /tmp

On NixOS /tmp is not a tmpfs, so state hangs around. If the nixinate user is changed, it will try to rsync to /tmp/nixinate where it will no longer work since the file was created by a user without the permissions of the last user that performed the deployment. This can be fixed with mktemp -p /run/user/$(id -u). This would make a temporary directory in /run for the current user, which would truly be temporary.

error: 'apps.nixinate' is not an attribute set

I get the error when I run nix flake show with the (adjusted) Example from the README.
I'm using nix version : nix (Nix) 2.15.1

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
    nixinate.url = "github:matthewcroughan/nixinate";
  };
  outputs = { self, nixpkgs, nixinate }: {
    apps = nixinate.nixinate.x86_64-linux self;
    nixosConfigurations = {
      myMachine = nixpkgs.lib.nixosSystem {
        modules = [
          {
            _module.args.nixinate = {
              host = "itchy.scratchy.com";
              sshUser = "root";
              buildOn = "remote"; # valid args are "local" or "remote"
              substituteOnTarget = true; # if buildOn is "local" then it will substitute on the target, "-s"
              hermetic = false;
            };
          }
        ];
      };
    };
  };
}

The error is :

git+file:///home/palo/dev/nixos/nixos-config?dir=nixinate
├───apps
│   └───nixinate
error: 'apps.nixinate' is not an attribute set

attempting to add any app to a nixinate flake results in an error

Create a flake using nixinate, then attempt to add an app

apps.x86_64-linux.exampleApp.type = "app";
apps.x86_64-linux.exampleApp.program = "echo hello";

the flake will no longer evaluate.

**error: attribute 'apps.x86_64-linux.deployEvilStaging.type' already defined**

Carry over --impure from initial nix run to nixinate evaluation

I have some scripts which require --impure mode to be enabled.

        {
          _module.args.nixinate = {
            host = "host";
            sshUser = "root";
            buildOn = "local";
            substituteOnTarget = false;
            hermetic = false;
            nixOptions = [ "--impure" ];
          };
        }
  1. Option: I would expect that 'nix run .#apps.nixinate.machine' now runs as impure without using the --impure option explicitly :
error:
       … in the left operand of the update (//) operator

         at /nix/store/7gzgi8zsnh06pv9cphb30yv9h1pyn4nk-source/flake.nix:84:20:

           83|                    )
           84|                    // nixpkgs.lib.genAttrs
             |                    ^
           85|                       (map (a: a + "-dry-run") validMachines)

       … while calling the 'listToAttrs' builtin

         at /nix/store/f0ddmw6s86y567yg06h5019z72szbzch-source/lib/attrsets.nix:1248:5:

         1247|     f:
         1248|     listToAttrs (map (n: nameValuePair n (f n)) names);
             |     ^
         1249|

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: access to absolute path '/etc/hostname' is forbidden in pure eval mode (use '--impure' to override)

My script tries to read /etc/hostname therefore we ran into problems here.

  1. Option: However if we decide to run 'nix run .#apps.nixinate.machine --impure' we bypass the error.
  2. Option: Just running 'nix run .#apps.nixinate.machine --impure' without settings the nixOption still fails with the pure eval mode error.

So I guess arguments passed to nix run don't really carry over when nixosConfigurations are evaluated/built atleast.
Maybe there is a way to read arguments passed to nix run during evaluation and concat them with the maybe provided nixOptions options?

nix copy just hangs with latest nix stable

testing with latest nixpkgs unstable, and nix run .#app.nixinate.my_host
just hangs on the line

/nix/store/yxyyb12wn2zxq8dasrv4r9dx7x7vwd2i-nix-2.15.1/bin/nix copy /nix/store/p9xgyp1y3vj1c2y3aar84nly4z4848qm-source --to ssh://yt@bee

I don't know since when it's been happening, just got his trying to deploy today.

Add support for deploying to a Mac (nix-darwin)

I'd like the ability to deploy to a remote Mac machine (say, a Mac mini server) from another Mac machine (say, a Macbook). nixinate is currently hardcoded to deploy nixosConfigurations.foo using nixos-rebuild. To support macOS, we simply want to be able to deploy darwinConfigurations.foo using darwin-rebuild; everything else would more or less remain the same. Here's a demonstration of what this looks like without nixinate:

      apps.aarch64-darwin.deploy-macmini = {
        type = "app";
        program =
          let
            host = "[email protected]";
            machine = "myhost";
            pkgs = inputs.nixpkgs.legacyPackages.aarch64-darwin;
          in
          (pkgs.writeShellApplication {
            name = "deploy-to-mac";
            text = ''
              set -x
              nix copy ${self} --to ssh://${host}
              ssh -t ${host} "darwin-rebuild switch --flake ${self}#${machine}"
            '';
          }) + "/bin/deploy-to-mac";
      };

NAR hash mismatch in input

here is the full log

🤞 Activating configuration non-hermetically on bee via ssh
+ /nix/store/85fcpkyv8qg4kpnv0p2nql2k7qp6q4ab-openssh-9.0p1/bin/ssh -t [email protected] 'sudo nixos-rebuild switch --flake /nix/store/ln57g0jd3pqmdwfkb8vmca17hcfm4awv-source#bee'
[sudo] password for yt:
error: NAR hash mismatch in input 'github:nixos/nixpkgs/72d1b0d0fac131df1ea254b65413c85609bdd2ee' (/nix/store/3jvygw6vzsazkfhxcd66w9gcg7y91c3k-source), expected 'sha256-dLqquYHvj6/EYPljULXJVUKcizB/8cbgdIL7aEXTDZY=', got 'sha256-g5Wo75ddDQmWnL70rJCMm+JJlvHbzPFUePUpuMNn5qk='
(use '--show-trace' to show detailed location information)

just started getting this today, no idea why.
I'm executing from a darwin machine to build a nix machine.
I'm not using the hermetic feature. I'm building on "remote" of course.
Not sure where this is coming from.

Hermetic cross system deployments fail

Currently, it is not possible to run an hermetic deployment from a x86_64-linux to an aarch64-linux machine. It fails with

/nix/store/5xr8ndqi3i7pxydh41lvx859mqfq1c0g-nixos-rebuild
/nix/store/5xr8ndqi3i7pxydh41lvx859mqfq1c0g-nixos-rebuild/bin/nixos-rebuild: line 373: /nix/store/qarssrazji0q9xp80xg8shsm2crckfr0-coreutils-9.0/bin/mktemp: cannot execute binary file: Exec format error

Hermetic deployment should copy and use cross compiled packages on the target machine.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.