diff options
-rw-r--r-- | flake.nix | 1 | ||||
-rw-r--r-- | lib/mk-sandbox-system.nix | 88 | ||||
-rw-r--r-- | readme.md | 93 |
3 files changed, 158 insertions, 24 deletions
@@ -4,6 +4,7 @@ | |||
4 | outputs = { self }: { | 4 | outputs = { self }: { |
5 | lib = { | 5 | lib = { |
6 | mkDevShell = import ./lib/mk-dev-shell.nix; | 6 | mkDevShell = import ./lib/mk-dev-shell.nix; |
7 | mkSandboxSystem = import ./lib/mk-sandbox-system.nix; | ||
7 | }; | 8 | }; |
8 | }; | 9 | }; |
9 | } | 10 | } |
diff --git a/lib/mk-sandbox-system.nix b/lib/mk-sandbox-system.nix new file mode 100644 index 0000000..6135a01 --- /dev/null +++ b/lib/mk-sandbox-system.nix | |||
@@ -0,0 +1,88 @@ | |||
1 | { nixpkgs | ||
2 | , system | ||
3 | , name ? "sandbox" | ||
4 | , user ? "dummy" | ||
5 | , config ? { } | ||
6 | }: | ||
7 | |||
8 | with nixpkgs.lib; | ||
9 | |||
10 | let | ||
11 | pkgs = import nixpkgs { inherit system; }; | ||
12 | |||
13 | in rec { | ||
14 | |||
15 | nixosConfigurations.${name} = nixosSystem { | ||
16 | inherit system; | ||
17 | |||
18 | modules = [ | ||
19 | (nixpkgs + "/nixos/modules/profiles/minimal.nix") | ||
20 | { environment.noXlibs = false; } # avoid mass rebuild | ||
21 | |||
22 | (nixpkgs + "/nixos/modules/profiles/qemu-guest.nix") | ||
23 | (nixpkgs + "/nixos/modules/virtualisation/qemu-vm.nix") | ||
24 | |||
25 | ({ config, lib, pkgs, ... }: { | ||
26 | |||
27 | system.stateVersion = mkDefault "22.05"; | ||
28 | |||
29 | networking = { | ||
30 | hostName = name; | ||
31 | firewall.enable = mkDefault false; | ||
32 | }; | ||
33 | |||
34 | users.users.${user} = { | ||
35 | isNormalUser = mkDefault true; | ||
36 | password = mkDefault ""; | ||
37 | extraGroups = mkDefault [ "wheel" ]; | ||
38 | }; | ||
39 | |||
40 | security.sudo.wheelNeedsPassword = mkDefault false; | ||
41 | |||
42 | services.getty = { | ||
43 | autologinUser = mkDefault user; | ||
44 | helpLine = mkDefault '' | ||
45 | Press <CTRL-a> <x> to terminate the virtual machine. | ||
46 | The working directory on the host is mounted to /mnt. | ||
47 | ''; | ||
48 | }; | ||
49 | |||
50 | virtualisation = { | ||
51 | graphics = mkDefault false; | ||
52 | diskImage = mkDefault "$(mktemp).qcow2"; | ||
53 | |||
54 | sharedDirectories.host = { | ||
55 | source = "$SHARED_CWD"; | ||
56 | target = "/mnt"; | ||
57 | }; | ||
58 | |||
59 | # Uncomment when this is merged: | ||
60 | # https://github.com/NixOS/nixpkgs/pull/200225 | ||
61 | #restrictNetwork = mkDefault true; | ||
62 | }; | ||
63 | }) | ||
64 | |||
65 | config | ||
66 | ]; | ||
67 | }; | ||
68 | |||
69 | packages.${name} = nixosConfigurations.${name}.config.system.build.vm; | ||
70 | |||
71 | apps.${name} = { | ||
72 | type = "app"; | ||
73 | program = toString (pkgs.writeShellScript "sandbox-vm" '' | ||
74 | # Isolate from network | ||
75 | # Stopgap solution until this is merged: | ||
76 | # https://github.com/NixOS/nixpkgs/pull/200225 | ||
77 | QEMU_NET_OPTS="restrict=yes,''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}" | ||
78 | export QEMU_NET_OPTS | ||
79 | |||
80 | # Save current directory for mounting in VM | ||
81 | SHARED_CWD=$PWD | ||
82 | export SHARED_CWD | ||
83 | |||
84 | ${packages.${name}}/bin/run-${name}-vm | ||
85 | ''); | ||
86 | }; | ||
87 | |||
88 | } | ||
@@ -23,36 +23,81 @@ Functions documentation provided as comments below. | |||
23 | outputs = { self, nixpkgs, flake-utils, flaky-utils }: | 23 | outputs = { self, nixpkgs, flake-utils, flaky-utils }: |
24 | flake-utils.lib.eachDefaultSystem (system: let | 24 | flake-utils.lib.eachDefaultSystem (system: let |
25 | pkgs = import nixpkgs { inherit system; }; | 25 | pkgs = import nixpkgs { inherit system; }; |
26 | in { | 26 | in pkgs.lib.fold pkgs.lib.recursiveUpdate { } [ |
27 | |||
28 | { | ||
29 | # Convenience development shell providing some tools. | ||
30 | # | ||
31 | # The binaries made available and the environment variable set are | ||
32 | # printed when entering the shell. | ||
33 | # | ||
34 | # The user's default shell is used instead of Bash (sacrifying a bit of | ||
35 | # reproducibility for convenience). | ||
36 | # | ||
37 | devShell = flaky-utils.lib.mkDevShell { | ||
38 | inherit pkgs; | ||
39 | |||
40 | tools = with pkgs; [ | ||
41 | postgresql_14 | ||
42 | pgcli | ||
43 | ]; | ||
44 | |||
45 | envVars = rec { | ||
46 | PGDATA = "$PWD/development_database/pgdata"; | ||
47 | PGHOST = "$PWD/development_database"; | ||
48 | PGPORT = "5432"; | ||
49 | PGDATABASE = "app"; | ||
50 | DATABASE_URL = "postgresql:///${PGDATABASE}?host=${PGHOST}"; | ||
51 | }; | ||
52 | |||
53 | shell = null; | ||
54 | }; | ||
55 | } | ||
27 | 56 | ||
28 | # Convenience development shell providing some tools. | 57 | # Convenience isolated environment using a QEMU virtual machine. |
29 | # | 58 | # |
30 | # The binaries made available and the environment variable set are printed | 59 | # This defines a triplet of nixosConfiguration, package and app with the |
31 | # when entering the shell. | 60 | # given name, so that the virtual machine can be launched using |
61 | # a command like `nix run .#sandbox`. | ||
32 | # | 62 | # |
33 | # The user's default shell is used instead of Bash (sacrifying a bit of | 63 | # By default, the VM is launched in the current console without a graphical |
34 | # reproducibility for convenience). | 64 | # interface, dropping to a shell for the default dummy user within. |
35 | # | 65 | # |
36 | devShell = flaky-utils.lib.mkDevShell { | 66 | # The current working directory from which the Flake is run is mounted and |
37 | inherit pkgs; | 67 | # made available within the virtual machine in /mnt. The root filesystem |
38 | 68 | # is ephemeral (written to a temporary file in /tmp). | |
39 | tools = with pkgs; [ | 69 | # |
40 | postgresql_14 | 70 | # The virtual machine's network is isolated by default: it cannot access |
41 | pgcli | 71 | # the Internet nor the host's local network. Ports may nevertheless be |
42 | ]; | 72 | # forwarded explicitly from host to guest and vice-versa. |
43 | 73 | # | |
44 | envVars = rec { | 74 | (flaky-utils.lib.mkSandboxSystem { |
45 | PGDATA = "$PWD/development_database/pgdata"; | 75 | inherit nixpkgs system; |
46 | PGHOST = "$PWD/development_database"; | 76 | |
47 | PGPORT = "5432"; | 77 | name = "sandbox"; |
48 | PGDATABASE = "app"; | 78 | user = "dummy"; |
49 | DATABASE_URL = "postgresql:///${PGDATABASE}?host=${PGHOST}"; | ||
50 | }; | ||
51 | 79 | ||
52 | shell = null; | 80 | config = { |
53 | }; | 81 | virtualisation.forwardPorts = [ |
82 | { from = "host"; host.port = 5432; guest.port = 5432; } # postgres | ||
83 | ]; | ||
84 | |||
85 | services.postgresql = { | ||
86 | enable = true; | ||
87 | enableTCPIP = true; | ||
88 | |||
89 | authentication = '' | ||
90 | host all all 0.0.0.0/0 trust | ||
91 | ''; | ||
92 | |||
93 | initialScript = pkgs.writeText "init.sql" '' | ||
94 | create role dummy login superuser; | ||
95 | ''; | ||
96 | }; | ||
97 | }; | ||
98 | }) | ||
54 | 99 | ||
55 | }); | 100 | ]); |
56 | } | 101 | } |
57 | ``` | 102 | ``` |
58 | 103 | ||