Skip to content

Commit

Permalink
Refactor and tidy the flake definition.
Browse files Browse the repository at this point in the history
This removes a bunch of duplication in the deploy/start-vm/diff scripts
left over from the introduction of the wpia-packit-private machine.
These script now only exist as one script, that accepts a machine name
as their argument.

In order to split up the `flake.nix` file, it makes use of the
[`flake-parts`][flake-parts] library. This library uses the same module
system as NixOS itself, but at the flake configuration level itself.

The deploy script is changed from using `nixos-rebuild switch` to our
own implementation of it. The primary goal of this is to ensure
the derivation of the built system gets deployed too, allowing us to
reliable diff the system state in the future.

[flake-parts]: https://flake.parts/
  • Loading branch information
plietar committed Oct 24, 2024
1 parent 08dc955 commit 47e5f50
Show file tree
Hide file tree
Showing 22 changed files with 365 additions and 240 deletions.
28 changes: 12 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,9 @@ curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix
### How do I deploy to the server?

```sh
nix run .#deploy
nix run .#deploy <hostname>
```

TODO: doing builds locally and then uploading them is pretty inefficient.
There's almost certainly a way to do the build remotely and not have to transfer
anything.

### How do I update outpack_server or Packit?

```
Expand All @@ -43,7 +39,7 @@ or master).
### How do I build the deployment?

```sh
nix build
nix build .#<hostname>
```

This is useful to check syntax and that everything builds, but you don't
Expand All @@ -52,28 +48,28 @@ typically need to do it. Deploying will do it implicitely.
### How do I visualize the effect of my changes?

```
nix run .#diff
nix run .#diff <machine>
```

This will download the system that is currently running on the server and
compare it with what would be deployed using [nix-diff](https://github.com/Gabriella439/nix-diff).

`nix-diff` will omit derivations' environment comparison if some dependencies
already differ. `nix run .#diff -- --environment` can help print all of these,
but is likely to be very verbose.
Alternatively, when opening a pull request on GitHub an action will run and
compute the difference against the main branch for all machines, and post the
result as a comment.

### How do I start a local VM?

```sh
nix run .#start-vm
nix run .#start-vm <hostname>
```

This starts a local VM running in QEMU. Handy to check everything works as
expected before deploying.

When starting, this command will obtain a Vault token and inject it into the VM
to be used for fetch GitHub client ID and secrets. If needed, you may be
prompted for your GitHub personal access token.
Before starting the local VM, this command will obtain a Vault token and inject
it into the VM to be used for fetching GitHub client ID and secrets. If needed,
you may be prompted for your GitHub personal access token.

Port 443 of the VM is exposed as port 8443, meaning you may visit
https://localhost:8443/ once the VM has started. nginx is configured using a
Expand All @@ -90,8 +86,8 @@ grant-role <instance> <github username> ADMIN
### How do I run the integration tests?

```sh
nix run .#vm-test
nix run .#vm-test -- --interactive
nix run .#integration-test
nix run .#integration-test -- --interactive
```

The second command starts a Python session which may be used to interact with the test machine.
Expand Down
31 changes: 31 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

158 changes: 21 additions & 137 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,149 +2,33 @@
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
inputs.disko.url = "github:nix-community/disko";
inputs.disko.inputs.nixpkgs.follows = "nixpkgs";

outputs = { nixpkgs, self, ... } @inputs:
let
pkgsArgs = {
overlays = [ self.overlays.default ];
config.allowUnfreePredicate = pkg: builtins.elem (nixpkgs.lib.getName pkg) [
inputs.flake-parts.url = "github:hercules-ci/flake-parts";

outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } ({ withSystem, lib, self, nixpkgs, ... }: {
imports = [
./packages
./machines
./scripts
./tests
];
perSystem = { system, pkgs, ... }: {
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
"vault"
"vault-bin"
];
};
in
{
overlays.default = (final: prev: {
packit = final.callPackage ./packages/packit { };
outpack_server = final.callPackage ./packages/outpack_server { };
packit-app = final.callPackage ./packages/packit/packit-app.nix { };
packit-api = final.callPackage ./packages/packit/packit-api.nix { };
fetch-secrets = final.writers.writePython3Bin "fetch-secrets"
{
libraries = [ final.python3.pkgs.hvac ];
} ./scripts/fetch-secrets.py;
});

nixosConfigurations.wpia-packit = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = { inherit inputs; };
modules = [
./machines/wpia-packit.nix
./hardware-configuration.nix
{ nixpkgs = pkgsArgs; }
devShells.default = pkgs.mkShell {
buildInputs = [
pkgs.nix-prefetch-github
pkgs.nixos-rebuild
pkgs.nix-diff
];
};

nixosConfigurations.wpia-packit-private = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = { inherit inputs; };
modules = [
./machines/wpia-packit-private.nix
./hardware-configuration.nix
{ nixpkgs = pkgsArgs; }
];
};

packages.x86_64-linux =
let pkgs = import nixpkgs ({ system = "x86_64-linux"; } // pkgsArgs);
in {
inherit (pkgs) outpack_server packit-app packit-api packit fetch-secrets;

default = self.nixosConfigurations.wpia-packit.config.system.build.toplevel;

deploy = pkgs.writeShellApplication {
name = "deploy-wpia-packit";
runtimeInputs = [ pkgs.nixos-rebuild ];
text = ''
nixos-rebuild switch \
--flake .#wpia-packit \
--target-host [email protected] \
--use-substitutes
'';
};

deploy-private = pkgs.writeShellApplication {
name = "deploy-wpia-packit-private";
runtimeInputs = [ pkgs.nixos-rebuild ];
text = ''
nixos-rebuild switch \
--flake .#wpia-packit-private \
--target-host [email protected] \
--use-substitutes
'';
};

update-ssh-keys = pkgs.writeShellApplication {
name = "update-ssh-keys";
runtimeInputs = [ pkgs.curl ];
text = builtins.readFile ./scripts/update-ssh-keys.sh;
};

diff = pkgs.writeShellApplication {
name = "diff";
runtimeInputs = [ pkgs.nix pkgs.nix-diff ];
text = ''
current=$(ssh [email protected] readlink /run/current-system)
nix-copy-closure --from [email protected] "$current"
# In theory .drvPath should allow us to use string interpolation
# instead of re-evaluating the flake, but for some reason it
# pulls all the build-time dependencies.
target=$(nix path-info --derivation .#nixosConfigurations.wpia-packit.config.system.build.toplevel)
nix-diff "$@" "$current" "$target"
'';
};

update = pkgs.writers.writePython3Bin "update" { } ./scripts/update.py;

start-vm = pkgs.writeShellApplication {
name = "start-vm";
runtimeInputs = [ pkgs.vault-bin ];
text =
let vaultUrl = self.nixosConfigurations.wpia-packit.config.vault.url;
in ''
token=$(vault print token)
if [[ -z $token ]]; then
echo "Logging in to ${vaultUrl}"
token=$(env VAULT_ADDR="${vaultUrl}" vault login -method=github -field=token)
fi
exec ${nixpkgs.lib.getExe self.nixosConfigurations.wpia-packit.config.system.build.vm} \
-fw_cfg name=opt/vault-token,string="$token" "$@"
'';
};

start-vm-private = pkgs.writeShellApplication {
name = "start-vm-private";
runtimeInputs = [ pkgs.vault-bin ];
text =
let vaultUrl = self.nixosConfigurations.wpia-packit-private.config.vault.url;
in ''
token=$(vault print token)
if [[ -z $token ]]; then
echo "Logging in to ${vaultUrl}"
token=$(env VAULT_ADDR="${vaultUrl}" vault login -method=github -field=token)
fi
exec ${nixpkgs.lib.getExe self.nixosConfigurations.wpia-packit-private.config.system.build.vm} \
-fw_cfg name=opt/vault-token,string="$token" "$@"
'';
};

vm-test = self.checks.x86_64-linux.default.driver;
};

checks.x86_64-linux.default =
let pkgs = import nixpkgs ({ system = "x86_64-linux"; } // pkgsArgs);
in pkgs.callPackage ./tests { inherit inputs; };

devShells.x86_64-linux.default =
let pkgs = import nixpkgs ({ system = "x86_64-linux"; } // pkgsArgs);
in pkgs.mkShell {
buildInputs = [
pkgs.nix-prefetch-github
pkgs.nixos-rebuild
];
};
};

systems = [ "x86_64-linux" ];
});
}
13 changes: 8 additions & 5 deletions machines/common/configuration.nix
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
{ lib, pkgs, inputs, ... }: {
{ self, config, lib, pkgs, self', inputs, ... }: {
imports = [
../../disk-config.nix
../../tools.nix
./tools.nix
../../modules/multi-packit.nix
../../modules/vault.nix
../../modules/outpack.nix
../../modules/packit-api.nix
../../modules/metrics-proxy.nix
./services.nix

inputs.disko.nixosModules.disko
];

Expand All @@ -25,12 +23,13 @@

networking.firewall.enable = true;
networking.firewall.allowedTCPPorts = [ 22 80 443 9000 ];
networking.domain = "dide.ic.ac.uk";

environment.systemPackages = [
pkgs.curl
pkgs.htop
pkgs.vim
pkgs.outpack_server
self'.packages.outpack_server
pkgs.gitMinimal
];

Expand All @@ -45,5 +44,9 @@

nix.settings.experimental-features = [ "nix-command" "flakes" ];

# Keep derivations when garbage collecting the Nix store. We use these
# derivations to run `nix-diff` against a running system.
nix.settings.keep-derivations = true;

system.stateVersion = "24.05";
}
File renamed without changes.
File renamed without changes.
29 changes: 15 additions & 14 deletions machines/common/services.nix
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,21 @@
};
};

environment.etc.static-metrics.source =
let
inherit (inputs) self;
rev = self.rev or self.dirtyRev or "unknown";
in
pkgs.writeTextDir "static-metrics.prom" ''
nixos_configuration_info{revision="${rev}", flake_hash="${self.narHash}"} 1
'';

services.prometheus.exporters = {
node =
let
inherit (inputs) self;
rev = self.rev or self.dirtyRev or "unknown";
staticMetrics = pkgs.writeTextDir "static-metrics.prom" ''
nixos_configuration_info{revision="${rev}", flake_hash="${self.narHash}"} 1
'';
in
{
enable = true;
enabledCollectors = [ "systemd" "textfile" ];
extraFlags = [ "--collector.textfile.directory=${staticMetrics}" ];
port = 9001;
};
node = {
enable = true;
enabledCollectors = [ "systemd" "textfile" ];
extraFlags = [ "--collector.textfile.directory=/etc/static-metrics" ];
port = 9001;
};
};
}
8 changes: 4 additions & 4 deletions tools.nix → machines/common/tools.nix
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{ pkgs, ... }:
{ pkgs, self', ... }:
let
grant-role = pkgs.writeShellApplication {
name = "grant-role";
runtimeInputs = [ pkgs.postgresql ];
text = builtins.readFile ./scripts/grant-role.sh;
text = builtins.readFile ../../scripts/grant-role.sh;
};

create-basic-user = pkgs.writeShellApplication {
Expand All @@ -12,13 +12,13 @@ let
pkgs.postgresql
pkgs.apacheHttpd
];
text = builtins.readFile ./scripts/create-basic-user.sh;
text = builtins.readFile ../../scripts/create-basic-user.sh;
};

flyway-packit = pkgs.runCommand "flyway-packit" { nativeBuildInputs = [ pkgs.makeWrapper ]; } ''
mkdir -p $out/bin
makeWrapper ${pkgs.flyway}/bin/flyway $out/bin/flyway-packit \
--add-flags -locations=filesystem:${pkgs.packit-api.src}/api/app/src/main/resources/db/migration
--add-flags -locations=filesystem:${self'.packages.packit-api.src}/api/app/src/main/resources/db/migration
'';
in
{
Expand Down
Loading

0 comments on commit 47e5f50

Please sign in to comment.