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

Refactor and tidy the flake definition. #13

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,11 @@ jobs:
- uses: actions/checkout@v4
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- run: nix build -L
- run: |
hostnames=$(nix eval --raw ".#nixosConfigurations" --apply 'x: builtins.concatStringsSep " " (builtins.attrNames x)')
for h in $hostnames; do
attribute="nixosConfigurations.$h.config.system.build.toplevel"
nix build -L .#$attribute --no-link
done

- run: nix flake check -L
87 changes: 28 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,19 @@ You need Nix installed on your local machine. You can use the
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
```

## How do I deploy to the server?
## Standard operating procedures
- [Provisioning a new machine](playbooks/new-machine-provisioning.md)
- [Deploying a new instance](playbooks/new-packit-instance.md)
- [Wiping a Packit instance](playbooks/wipe-packit-instance.md)

## How do I?
### 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?
### How do I update outpack_server or Packit?

```
nix run .#update packit
Expand All @@ -34,40 +36,40 @@ It also accepts a `--branch` argument which may be used to specify a branch
name. Otherwise the default branch of the repository will be used (usually main
or master).

## How do I build the deployment?
### How do I build the deployment?

```sh
nix build
nix build .#nixosConfigurations.<hostname>.config.system.build.toplevel
```

This is useful to check syntax and that everything builds, but you don't
typically need to do it. Deploying will do it implicitely.

## How do I visualize the effect of my changes?
### 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?
### 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 @@ -81,11 +83,11 @@ the VM console.
grant-role <instance> <github username> ADMIN
```

## How do I run the integration tests?
### 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 Expand Up @@ -116,7 +118,7 @@ EOF
sudo udevadm control --reload-rules && sudo udevadm trigger
```

## How do I add new SSH keys?
### How do I add new SSH keys?

The keys are fetched from GitHub and committed into this repository as the
`authorized_keys` files. You can edit the `scripts/update-ssh-keys.sh` file to
Expand All @@ -130,36 +132,7 @@ nix run .#update-ssh-keys
Carefully review the changes to avoid locking yourself out and re-deploy to the
server.

## How do I add a new Packit instance?

Edit `services.nix` by adding a new entry to the `services.multi-packit.instances`
list.

You will need to customize the instance by configuring some of the
`services.packit-api.<name>` options. A GitHub organisation and team needs to
be specified. All members of this organisation/team will be allowed to access
the instance. The team can be omitted or left blank, in which case any member
of the organisation will have access.

The Packit application on Github manually needs to be granted permission, by
one of the organisation's admins, to access the organisation. See [the GitHub
documentation][github-oauth-org]. Because we use a single OAuth app for all
instances, this only needs to be done once per org, even if uses by multiple
instances.

[github-oauth-org]: https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-your-membership-in-organizations/requesting-organization-approval-for-oauth-apps

The initial user needs to be granted the ADMIN role manually.

1. Log in to the instance with your GitHub account.
1. SSH onto the server.
1. Run `grant-role <instance> <username> ADMIN` where `<instance>` is the name
of the instance and `<username>` is your GitHub username.
1. Log out and back in for the changes to take effect.

Afterwards permissions may be managed through the web UI.

## How do I add secrets to a machine?
### How do I add secrets to a machine?

All secrets are fetched from Vault. To add a new secret to a machine, add it
to the Vault and add an entry to the `vault.secrets` option.
Expand Down Expand Up @@ -187,7 +160,7 @@ nix run .#nixosConfigurations.<hostname>.config.vault.tool -- --root here
This will fetch all the secrets as the command on the server would have done,
but store them relative to the `here` folder.

## How do I inspect / edit the database?
### How do I inspect / edit the database?

If doing this on the production instance, start by thinking very carefully
about what you are about to do.
Expand All @@ -205,14 +178,10 @@ The database is initially populated by the packit-api service. During the first
start of a new instance, it can take a minute for the service to start and for
the database's tables to exist.

## How do I update NixOS?
### How do I update NixOS?

```sh
nix flake update
```

To switch to a new major version, you should edit the URL at the top of `flake.nix`.

## How do I provision a new machine?

See [`PROVISIONING.md`](PROVISIONING.md).
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" ];
});
}
Loading