From c69f1f52e01b2f58ea6289ea32547d58c4cee6d1 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Wed, 9 Apr 2025 16:58:50 +0200 Subject: [PATCH 01/57] allow accessing test vms from fedi201, closes #286 (#297) Reviewed-on: https://git.fediversity.eu/Fediversity/Fediversity/pulls/297 Co-authored-by: Kiara Grouwstra Co-committed-by: Kiara Grouwstra --- infra/common/resource.nix | 6 +++++- infra/flake-part.nix | 24 ++++++++++++++++++++---- infra/machines/fedi201/fedipanel.nix | 18 ++++++++++++++++++ keys/default.nix | 1 + keys/panel-ssh-key.pub | 1 + panel/nix/configuration.nix | 3 +-- secrets/panel-ssh-key.age | Bin 0 -> 1271 bytes secrets/secrets.nix | 1 + 8 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 keys/panel-ssh-key.pub create mode 100644 secrets/panel-ssh-key.age diff --git a/infra/common/resource.nix b/infra/common/resource.nix index 15b5693b..4606ddf4 100644 --- a/infra/common/resource.nix +++ b/infra/common/resource.nix @@ -54,6 +54,10 @@ in ## FIXME: Remove direct root authentication once the NixOps4 NixOS provider ## supports users with password-less sudo. - users.users.root.openssh.authorizedKeys.keys = attrValues keys.contributors; + users.users.root.openssh.authorizedKeys.keys = attrValues keys.contributors ++ [ + # allow our panel vm access to the test machines + keys.panel + ]; + }; } diff --git a/infra/flake-part.nix b/infra/flake-part.nix index 6a69278e..c849dc46 100644 --- a/infra/flake-part.nix +++ b/infra/flake-part.nix @@ -22,10 +22,26 @@ let { vmName, isTestVm }: { _module.args = { inherit inputs; }; - imports = [ - ./common/resource.nix - (if isTestVm then ./test-machines + "/${vmName}" else ./machines + "/${vmName}") - ]; + imports = + [ + ./common/resource.nix + ] + ++ ( + if isTestVm then + [ + ./test-machines/${vmName} + { + nixos.module.users.users.root.openssh.authorizedKeys.keys = [ + # allow our panel vm access to the test machines + (import ../keys).panel + ]; + } + ] + else + [ + ./machines/${vmName} + ] + ); fediversityVm.name = vmName; }; diff --git a/infra/machines/fedi201/fedipanel.nix b/infra/machines/fedi201/fedipanel.nix index 4f90c473..5c4236fc 100644 --- a/infra/machines/fedi201/fedipanel.nix +++ b/infra/machines/fedi201/fedipanel.nix @@ -15,6 +15,24 @@ in defaults.email = "beheer@procolix.com"; }; + age.secrets.panel-ssh-key = { + owner = name; + mode = "400"; + }; + + programs.ssh.startAgent = true; + + home-manager = { + users.${name}.home = { + stateVersion = "25.05"; + file.".ssh/config" = { + text = '' + IdentityFile ${config.age.secrets.panel-ssh-key.path} + ''; + }; + }; + }; + services.${name} = { enable = true; production = true; diff --git a/keys/default.nix b/keys/default.nix index c51049cb..6e33783b 100644 --- a/keys/default.nix +++ b/keys/default.nix @@ -34,4 +34,5 @@ in { contributors = collectKeys ./contributors; systems = collectKeys ./systems; + panel = removeTrailingWhitespace (readFile ./panel-ssh-key.pub); } diff --git a/keys/panel-ssh-key.pub b/keys/panel-ssh-key.pub new file mode 100644 index 00000000..3f2d09a8 --- /dev/null +++ b/keys/panel-ssh-key.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICWfTPs64ImqGh3c/Y+3zqB9YVr5ApsKiS/aTLGXUTzb panel@fedi201 diff --git a/panel/nix/configuration.nix b/panel/nix/configuration.nix index 27359503..ecf06e0f 100644 --- a/panel/nix/configuration.nix +++ b/panel/nix/configuration.nix @@ -158,8 +158,7 @@ in }; users.users.${name} = { - isSystemUser = true; - group = name; + isNormalUser = true; }; users.groups.${name} = { }; diff --git a/secrets/panel-ssh-key.age b/secrets/panel-ssh-key.age new file mode 100644 index 0000000000000000000000000000000000000000..427d9972ece0589406e2f166004b80999f86c92d GIT binary patch literal 1271 zcmZY4`)?Bk0KjpAi$DoV3=V=wI&{Bqls>QR@wDw-d+pl0Ufb(y@WWkuy*}^VyX!{q zfeLOa=+t1q7&2jGpukW<#F;H1N)%0)86dT^=QL{5#1P!z4$lPadGHKIr}A&VPf#*#R({N23wF5d&e)?RHGn_yWOIStHdJAu#~XvGs^-m*|X+FchiO{Z2wJ zIW6TxT*3-C(5R7!W`N?L!vPRQz?*BJ;bbT-J7}|8cXFw0)?Z9R3KyuxM5og({!jDa zvY>j52*aqHgvDx+s-%YfPM+6fmlI+;#B>4`6wH!{xhk;;tfL--TFGHp7DOc(^As^C z;m6{^C}B$~(Nu!V`=~Y?F9^{(n&8N(Z??3QU^OGj#BE^GR@PD+-v*^6Sm(@fkxFnj zrog&zO_bFY>?j3mVGsUaOx6UfoaYTD zlgY@^K?nsaR1wDu;fWe{$&Fy!QQ* z#oXhkm+z3&k>r)#@2@$0;A5e8G&0^W?Vk6`7Pt?Yee!MRDyO`yUtJ7(CtCHLgTcn7 z)td^#cltx09lkj8v8G|;^IG@57nG+`Td($B*BzH{u8Q?8SbDef)Y2IXJGFmyHcuSi zR4ChfTUWpK>YFn+u7{eJZ=e49;O)e>?;aSO9BtkC@Lb=ml|A;4%>6$;Gi}AOo)-_E zUmBpd=Dt~SD>QC(|K7wcS$A{ek=Z}*i4S)#3hv4U)K^yTdN}mSS$g8&sRrC~ADrWz zJ_c{zva)9ua%=M13hS9)2i};~vhB!)X>V<~xbD*4quc)uwBO&6SoWyZ*>gtTzii(e z+}qu?xMOXgW!J){zn;BYnTF2&>ip>T-q^(D$?l_|et14G^Edy3_YNH$S=%?mV)&dL z`+_>QxBW)-=@WZC{b96_(PlTTl15H5;{zK$7`{p!@8@odi~6XR=Gt{^pg1%EJi2ps zylY_oo#y==neKBp!s}m}yZ%Jii3iM+#~zG*`Df>~D_;|vmt5>>8G6*&wD7|x(5)jE Y#-4k*{g33}JKs+%zK0HfSMN&w3#6^-jQ{`u literal 0 HcmV?d00001 diff --git a/secrets/secrets.nix b/secrets/secrets.nix index f2e30797..167234d4 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -28,6 +28,7 @@ concatMapAttrs forgejo-email-password = [ vm02116 ]; forgejo-runner-token = [ ]; panel-secret-key = [ fedi201 ]; + panel-ssh-key = [ fedi201 ]; wiki-basicauth-htpasswd = [ vm02187 ]; wiki-password = [ vm02187 ]; wiki-smtp-password = [ vm02187 ]; -- 2.48.1 From c27ec0a5b10a9e9af2b25e2145ed6968f44d1366 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Wed, 9 Apr 2025 16:55:24 +0200 Subject: [PATCH 02/57] set NIX_PATH, enables use of --- infra/common/nixos/default.nix | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/infra/common/nixos/default.nix b/infra/common/nixos/default.nix index b870ab03..c789a04e 100644 --- a/infra/common/nixos/default.nix +++ b/infra/common/nixos/default.nix @@ -1,8 +1,8 @@ -{ lib, ... }: +{ lib, pkgs, ... }: let inherit (lib) mkDefault; - + nixPath = "/run/current-system/nixpkgs"; in { imports = [ @@ -16,6 +16,15 @@ in system.stateVersion = "24.05"; # do not change nixpkgs.hostPlatform = mkDefault "x86_64-linux"; + # use flake's nixpkgs over channels + nix.nixPath = [ "nixpkgs=${nixPath}" ]; + system.extraSystemBuilderCmds = '' + ln -sv ${pkgs.path} $out/nixpkgs + ''; + systemd.tmpfiles.rules = [ + "L+ ${nixPath} - - - - ${pkgs.path}" + ]; + ## This is just nice to have, but it is also particularly important for the ## Forgejo CI runners because the Nix configuration in the actions is directly ## taken from here. -- 2.48.1 From f947e17d9667920e54e2ebbde07f7229e473cb20 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Tue, 1 Apr 2025 13:31:59 +0200 Subject: [PATCH 03/57] allow accessing test vms from fedi201's machine ssh key, closes #286 --- launch/.auto.tfvars.json | 1 + launch/.terraform/modules/mastodon.deploy | 1 + launch/.terraform/modules/modules.json | 1 + .../modules/peertube.deploy/LICENSE | 201 ++++++++++ .../modules/peertube.deploy/README.md | 113 ++++++ .../peertube.deploy/aws_image_nixos/README.md | 46 +++ .../peertube.deploy/aws_image_nixos/main.tf | 34 ++ .../aws_image_nixos/update-url-map | 51 +++ .../aws_image_nixos/url_map.nix | 2 + .../aws_image_nixos/url_map.tf | 353 ++++++++++++++++++ .../aws_image_nixos/versions.tf | 4 + .../peertube.deploy/deploy_nixos/README.md | 129 +++++++ .../peertube.deploy/deploy_nixos/main.tf | 221 +++++++++++ .../deploy_nixos/maybe-sudo.sh | 11 + .../deploy_nixos/nixos-deploy.sh | 135 +++++++ .../deploy_nixos/nixos-instantiate.sh | 94 +++++ .../deploy_nixos/unpack-keys.sh | 46 +++ .../peertube.deploy/deploy_nixos/versions.tf | 4 + .../examples/google/deploy_nixos.tf | 82 ++++ .../examples/google/image_nixos.tf | 25 ++ .../examples/google/image_nixos_custom.nix | 13 + .../examples/google/image_nixos_custom.tf | 21 ++ .../examples/google/provider.tf | 3 + .../hermetic_config/configuration.nix | 60 +++ .../examples/hermetic_config/default.tf | 27 ++ launch/.terraform/modules/peertube.deploy/fmt | 17 + .../google_image_nixos/README.md | 76 ++++ .../google_image_nixos/main.tf | 64 ++++ .../google_image_nixos/update-url-map | 47 +++ .../google_image_nixos/url_map.nix | 2 + .../google_image_nixos/url_map.tf | 17 + .../google_image_nixos/versions.tf | 4 + .../google_image_nixos_custom/README.md | 54 +++ .../google_image_nixos_custom/main.tf | 94 +++++ .../google_image_nixos_custom/nixos-build.sh | 35 ++ .../google_image_nixos_custom/versions.tf | 4 + .../nix/terraform-docs/default.nix | 26 ++ .../scripts/terraform-docs-updater | 37 ++ .../modules/peertube.deploy/shell.nix | 21 ++ .../modules/pixelfed.deploy/LICENSE | 201 ++++++++++ .../modules/pixelfed.deploy/README.md | 113 ++++++ .../pixelfed.deploy/aws_image_nixos/README.md | 46 +++ .../pixelfed.deploy/aws_image_nixos/main.tf | 34 ++ .../aws_image_nixos/update-url-map | 51 +++ .../aws_image_nixos/url_map.nix | 2 + .../aws_image_nixos/url_map.tf | 353 ++++++++++++++++++ .../aws_image_nixos/versions.tf | 4 + .../pixelfed.deploy/deploy_nixos/README.md | 129 +++++++ .../pixelfed.deploy/deploy_nixos/main.tf | 221 +++++++++++ .../deploy_nixos/maybe-sudo.sh | 11 + .../deploy_nixos/nixos-deploy.sh | 135 +++++++ .../deploy_nixos/nixos-instantiate.sh | 94 +++++ .../deploy_nixos/unpack-keys.sh | 46 +++ .../pixelfed.deploy/deploy_nixos/versions.tf | 4 + .../examples/google/deploy_nixos.tf | 82 ++++ .../examples/google/image_nixos.tf | 25 ++ .../examples/google/image_nixos_custom.nix | 13 + .../examples/google/image_nixos_custom.tf | 21 ++ .../examples/google/provider.tf | 3 + .../hermetic_config/configuration.nix | 60 +++ .../examples/hermetic_config/default.tf | 27 ++ launch/.terraform/modules/pixelfed.deploy/fmt | 17 + .../google_image_nixos/README.md | 76 ++++ .../google_image_nixos/main.tf | 64 ++++ .../google_image_nixos/update-url-map | 47 +++ .../google_image_nixos/url_map.nix | 2 + .../google_image_nixos/url_map.tf | 17 + .../google_image_nixos/versions.tf | 4 + .../google_image_nixos_custom/README.md | 54 +++ .../google_image_nixos_custom/main.tf | 94 +++++ .../google_image_nixos_custom/nixos-build.sh | 35 ++ .../google_image_nixos_custom/versions.tf | 4 + .../nix/terraform-docs/default.nix | 26 ++ .../scripts/terraform-docs-updater | 37 ++ .../modules/pixelfed.deploy/shell.nix | 21 ++ launch/.terraform/plugin_path | 3 + .../hashicorp/external/2.3.4/linux_amd64 | 1 + .../hashicorp/null/3.2.3/linux_amd64 | 1 + launch/module.auto.tfvars.json | 1 + launch/terraform.tfstate | 1 + launch/terraform.tfstate.backup | 1 + 81 files changed, 4357 insertions(+) create mode 100644 launch/.auto.tfvars.json create mode 120000 launch/.terraform/modules/mastodon.deploy create mode 100644 launch/.terraform/modules/modules.json create mode 100644 launch/.terraform/modules/peertube.deploy/LICENSE create mode 100644 launch/.terraform/modules/peertube.deploy/README.md create mode 100644 launch/.terraform/modules/peertube.deploy/aws_image_nixos/README.md create mode 100644 launch/.terraform/modules/peertube.deploy/aws_image_nixos/main.tf create mode 100755 launch/.terraform/modules/peertube.deploy/aws_image_nixos/update-url-map create mode 100644 launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.nix create mode 100644 launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.tf create mode 100644 launch/.terraform/modules/peertube.deploy/aws_image_nixos/versions.tf create mode 100644 launch/.terraform/modules/peertube.deploy/deploy_nixos/README.md create mode 100644 launch/.terraform/modules/peertube.deploy/deploy_nixos/main.tf create mode 100755 launch/.terraform/modules/peertube.deploy/deploy_nixos/maybe-sudo.sh create mode 100755 launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-deploy.sh create mode 100755 launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-instantiate.sh create mode 100755 launch/.terraform/modules/peertube.deploy/deploy_nixos/unpack-keys.sh create mode 100644 launch/.terraform/modules/peertube.deploy/deploy_nixos/versions.tf create mode 100644 launch/.terraform/modules/peertube.deploy/examples/google/deploy_nixos.tf create mode 100644 launch/.terraform/modules/peertube.deploy/examples/google/image_nixos.tf create mode 100644 launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.nix create mode 100644 launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.tf create mode 100644 launch/.terraform/modules/peertube.deploy/examples/google/provider.tf create mode 100644 launch/.terraform/modules/peertube.deploy/examples/hermetic_config/configuration.nix create mode 100644 launch/.terraform/modules/peertube.deploy/examples/hermetic_config/default.tf create mode 100755 launch/.terraform/modules/peertube.deploy/fmt create mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos/README.md create mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos/main.tf create mode 100755 launch/.terraform/modules/peertube.deploy/google_image_nixos/update-url-map create mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.nix create mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.tf create mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos/versions.tf create mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/README.md create mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/main.tf create mode 100755 launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/nixos-build.sh create mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/versions.tf create mode 100644 launch/.terraform/modules/peertube.deploy/nix/terraform-docs/default.nix create mode 100755 launch/.terraform/modules/peertube.deploy/scripts/terraform-docs-updater create mode 100644 launch/.terraform/modules/peertube.deploy/shell.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/LICENSE create mode 100644 launch/.terraform/modules/pixelfed.deploy/README.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/README.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/main.tf create mode 100755 launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/update-url-map create mode 100644 launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/versions.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/README.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/main.tf create mode 100755 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/maybe-sudo.sh create mode 100755 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-deploy.sh create mode 100755 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-instantiate.sh create mode 100755 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/unpack-keys.sh create mode 100644 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/versions.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/google/deploy_nixos.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/google/provider.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/configuration.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/default.tf create mode 100755 launch/.terraform/modules/pixelfed.deploy/fmt create mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos/README.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos/main.tf create mode 100755 launch/.terraform/modules/pixelfed.deploy/google_image_nixos/update-url-map create mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos/versions.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/README.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/main.tf create mode 100755 launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/nixos-build.sh create mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/versions.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/nix/terraform-docs/default.nix create mode 100755 launch/.terraform/modules/pixelfed.deploy/scripts/terraform-docs-updater create mode 100644 launch/.terraform/modules/pixelfed.deploy/shell.nix create mode 100644 launch/.terraform/plugin_path create mode 120000 launch/.terraform/providers/registry.opentofu.org/hashicorp/external/2.3.4/linux_amd64 create mode 120000 launch/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.3/linux_amd64 create mode 100644 launch/module.auto.tfvars.json create mode 100644 launch/terraform.tfstate create mode 100644 launch/terraform.tfstate.backup diff --git a/launch/.auto.tfvars.json b/launch/.auto.tfvars.json new file mode 100644 index 00000000..88a25b33 --- /dev/null +++ b/launch/.auto.tfvars.json @@ -0,0 +1 @@ +{"ssh_private_key_file": "/home/kiara/.ssh/id_ed25519", "deploy_environment": {"SSH_AUTH_SOCK": "/tmp/ssh-XXXXXXNmOXeE/agent.1456243"}} diff --git a/launch/.terraform/modules/mastodon.deploy b/launch/.terraform/modules/mastodon.deploy new file mode 120000 index 00000000..4c479922 --- /dev/null +++ b/launch/.terraform/modules/mastodon.deploy @@ -0,0 +1 @@ +/nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source \ No newline at end of file diff --git a/launch/.terraform/modules/modules.json b/launch/.terraform/modules/modules.json new file mode 100644 index 00000000..f7a11609 --- /dev/null +++ b/launch/.terraform/modules/modules.json @@ -0,0 +1 @@ +{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"mastodon","Source":"./vm","Dir":"vm"},{"Key":"mastodon.deploy","Source":"file:///nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source//deploy_nixos","Dir":".terraform/modules/mastodon.deploy/deploy_nixos"},{"Key":"peertube","Source":"./vm","Dir":"vm"},{"Key":"peertube.deploy","Source":"file:///nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source//deploy_nixos","Dir":".terraform/modules/peertube.deploy/deploy_nixos"},{"Key":"pixelfed","Source":"./vm","Dir":"vm"},{"Key":"pixelfed.deploy","Source":"file:///nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source//deploy_nixos","Dir":".terraform/modules/pixelfed.deploy/deploy_nixos"}]} \ No newline at end of file diff --git a/launch/.terraform/modules/peertube.deploy/LICENSE b/launch/.terraform/modules/peertube.deploy/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/launch/.terraform/modules/peertube.deploy/README.md b/launch/.terraform/modules/peertube.deploy/README.md new file mode 100644 index 00000000..443a0e87 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/README.md @@ -0,0 +1,113 @@ +# terraform-nixos + +[![built with nix](https://builtwithnix.org/badge.svg)](https://builtwithnix.org) + +This repository contains a set of Terraform Modules designed to deploy NixOS +machines. These modules are designed to work together and support different +deployment scenarios. + +## What is Terraform? + +[Terraform][terraform] is a tool that allows to declare infrastructures as +code. + +## What is Nix, nixpkgs and NixOS? + +[Nix][nix] is a build system and package manager that allows to manage whole +system configurations as code. nixpkgs is a set of 20k+ packages built with +Nix. NixOS is a Linux distribution built on top of nixpkgs. + +## What is a Terraform Module? + +A Terraform Module refers to a self-contained package of Terraform +configurations that are managed as a group. This repo contains a collection of +Terraform Modules which can be composed together to create useful +infrastructure patterns. + +## Terraform + Nix vs NixOps + +NixOps is a great tool for personal deployments. It handles a lot of things +like cloud resource creation, machine NixOS bootstrapping and deployment. + +The difficulty is when the cloud resources are not supported by NixOps. It +takes a lot of work to map all the cloud APIs. Compared to NixOps, Terraform +has become an industry standard and has thousands of people contributing new +cloud API mapping all the time. + +Another issue is when sharing the configuration as code with multiple +developers. Both NixOps and Terraform maintain a state file of "known applied" +configuration. Unlike NixOps, Terraform provides facilities to sync and lock +the state file so it's available by other users. + +The approach here is to use Terraform to create all the cloud resources. By +using the `google_image_nixos_custom` module it's possible to pre-build images in +auto-scaling scenarios. Or use a push model similar to NixOps with the generic +`deploy_nixos` module. + +So overall Terraform + Nix is more flexible and scales better. But it's also +more cumbersome to use as it requires to learn two languages instead of one +and the integration between both is also a bit clunky. + +## Terraform Modules + +The list of modules provided by this project: + +* [deploy_nixos](deploy_nixos#readme) - deploy NixOS onto running NixOS + machines +* [google_image_nixos](google_image_nixos#readme) - setup an official GCE + image into a Google Cloud Project. +* [google_image_nixos_custom](google_image_nixos_custom#readme) - build and + deploy a custom GCE image into a Google Cloud Project + +## Using these modules from your terraform configuration + +Terraform supports importing [modules](https://www.terraform.io/docs/configuration/modules.html) directly [from a GitHub repository](https://www.terraform.io/docs/modules/sources.html#github). + +For example, to use the [`deploy_nixos`](deploy_nixos#readme) module: + +``` +module "deploy_nixos" { + source = "github.com/tweag/terraform-nixos//deploy_nixos?ref=ced68729b6a0382dda02401c8f663c9b29c29368" + + … module-specific fields … +} +``` + +Beware the double `//`, which separates the github repository url from the +subdirectory that contains the module. `?ref=` specifies a specific git ref +of the repository, in this case the commit `ced687…`. + +## Examples + +To better understand how these modules can be used together, look into the +[./examples](examples) folder. + +## Related projects + +* [terraform-provider-nix](https://github.com/andrewchambers/terraform-provider-nix) + +## Future + +* Support other cloud providers. +* Support nixos-infect bootstrapping method. + +Contributions are welcome! + +## Thanks + +Thanks to [Digital Asset][digital-asset] for generously sponsoring this work! + +Thanks to [Tweag][tweag] for enabling this work and the continuous support! + +## License + +This code is released under the Apache 2.0 License. Please see +[LICENSE](LICENSE) for more details. + +Copyright © 2018 Tweag I/O. + + +[digital-asset]: https://www.digitalasset.com/ +[nix]: https://nixos.org/nix/ +[terraform]: https://www.terraform.io +[tweag]: https://www.tweag.io/ diff --git a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/README.md b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/README.md new file mode 100644 index 00000000..b36938de --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/README.md @@ -0,0 +1,46 @@ +# AWS Collection of NixOS AMIs + +This terraform module provides links to official NixOS AMIs on AWS. The AMIs are +released by the NixOS project. + +Since image names are unique, only one instance per version of the module is +supported. + +## Example + + provider "aws" { + region = "eu-west-1" + } + + module "nixos_image_1903" { + source = "path/to/aws_image_nixos" + release = "19.03" + } + + resource "aws_instance" "example" { + ami = module.nixos_image_1903.ami + instance_type = "t2.micro" + + ... + } + +## New NixOS releases + +Run the `./update-url-map` script to fetch new image releases. + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|:----:|:-----:|:-----:| +| region | The region to use. If not provided, current provider's region will be used. | string | `` | no | +| release | The NixOS version to use. For example, 18.09 | string | `latest` | no | +| type | The type of the AMI to use -- hvm-ebs, pv-ebs, or pv-s3. | string | `hvm-ebs` | no | +| url\_map | A map of release series to actual releases | map | `` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| ami | NixOS AMI on AWS | + diff --git a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/main.tf b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/main.tf new file mode 100644 index 00000000..dace86dc --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/main.tf @@ -0,0 +1,34 @@ +variable "release" { + type = string + default = "latest" + description = "The NixOS version to use. For example, 18.09" +} + +variable "region" { + type = string + default = "" + description = "The region to use. If not provided, current provider's region will be used." +} + +variable "type" { + type = string + default = "hvm-ebs" + description = "The type of the AMI to use -- hvm-ebs, pv-ebs, or pv-s3." +} + +# --- + +data "aws_region" "current" {} + +locals { + key = "${var.release}.${coalesce(var.region, data.aws_region.current.name)}.${var.type}" + ami = var.url_map[local.key] +} + +# --- + +output "ami" { + description = "NixOS AMI on AWS" + value = local.ami +} + diff --git a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/update-url-map b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/update-url-map new file mode 100755 index 00000000..3a2ce4cc --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/update-url-map @@ -0,0 +1,51 @@ +#!/usr/bin/env nix-shell +#!nix-shell -p python3 -i python +# vim: ft=python +# +# Run this script to update the list of EC2 images +# +import json +import io +from subprocess import check_output +from textwrap import dedent +from os import putenv + +putenv('NIX_PATH', 'nixpkgs=channel:nixpkgs-unstable') + +def render_tf(): + nix_eval = check_output(['nix-instantiate', '--json', '--strict', '--eval', './url_map.nix']) + url_map = json.loads(nix_eval) + + out = io.StringIO() + out.write(dedent("""\ + # DON'T EDIT, run '%s' instead + variable "url_map" { + type = map(string) + + default = { + """ % __file__)) + + for version, regions in url_map.items(): + for region, kinds in regions.items(): + for kind, ami in kinds.items(): + out.write(' "%s.%s.%s" = "%s"\n' % (version, region, kind, ami)) + + out.write(dedent("""\ + } + + description = "A map of release series to actual releases" + } + """)) + + return out.getvalue() + +url_map_tf = render_tf() + +with open("url_map.tf", "w") as f: + f.write(url_map_tf) + +print(url_map_tf) + +# Local Variables: +# mode: Python +# End: diff --git a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.nix b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.nix new file mode 100644 index 00000000..73b0b73e --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.nix @@ -0,0 +1,2 @@ +# Indirect link to where the image map is stored +import diff --git a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.tf b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.tf new file mode 100644 index 00000000..3a546a1b --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.tf @@ -0,0 +1,353 @@ +# DON'T EDIT, run './update-url-map' instead +variable "url_map" { + type = map(string) + + default = { + "14.04.ap-northeast-1.hvm-ebs" = "ami-71c6f470" + "14.04.ap-northeast-1.pv-ebs" = "ami-4dcbf84c" + "14.04.ap-northeast-1.pv-s3" = "ami-8fc4f68e" + "14.04.ap-southeast-1.hvm-ebs" = "ami-da280888" + "14.04.ap-southeast-1.pv-ebs" = "ami-7a9dbc28" + "14.04.ap-southeast-1.pv-s3" = "ami-c4290996" + "14.04.ap-southeast-2.hvm-ebs" = "ami-ab523e91" + "14.04.ap-southeast-2.pv-ebs" = "ami-6769055d" + "14.04.ap-southeast-2.pv-s3" = "ami-15533f2f" + "14.04.eu-central-1.hvm-ebs" = "ami-ba0234a7" + "14.04.eu-west-1.hvm-ebs" = "ami-96cb63e1" + "14.04.eu-west-1.pv-ebs" = "ami-b48c25c3" + "14.04.eu-west-1.pv-s3" = "ami-06cd6571" + "14.04.sa-east-1.hvm-ebs" = "ami-01b90e1c" + "14.04.sa-east-1.pv-ebs" = "ami-69e35474" + "14.04.sa-east-1.pv-s3" = "ami-61b90e7c" + "14.04.us-east-1.hvm-ebs" = "ami-58ba3a30" + "14.04.us-east-1.pv-ebs" = "ami-9e0583f6" + "14.04.us-east-1.pv-s3" = "ami-9cbe3ef4" + "14.04.us-west-1.hvm-ebs" = "ami-0bc3d74e" + "14.04.us-west-1.pv-ebs" = "ami-8b1703ce" + "14.04.us-west-1.pv-s3" = "ami-27ccd862" + "14.04.us-west-2.hvm-ebs" = "ami-3bf1bf0b" + "14.04.us-west-2.pv-ebs" = "ami-259bd515" + "14.04.us-west-2.pv-s3" = "ami-07094037" + "14.12.ap-northeast-1.hvm-ebs" = "ami-24435f25" + "14.12.ap-northeast-1.pv-ebs" = "ami-b0425eb1" + "14.12.ap-northeast-1.pv-s3" = "ami-fed3c6ff" + "14.12.ap-southeast-1.hvm-ebs" = "ami-6c765d3e" + "14.12.ap-southeast-1.pv-ebs" = "ami-6a765d38" + "14.12.ap-southeast-1.pv-s3" = "ami-d1bf9183" + "14.12.ap-southeast-2.hvm-ebs" = "ami-af86f395" + "14.12.ap-southeast-2.pv-ebs" = "ami-b386f389" + "14.12.ap-southeast-2.pv-s3" = "ami-69c5ae53" + "14.12.eu-central-1.hvm-ebs" = "ami-4a497a57" + "14.12.eu-central-1.pv-ebs" = "ami-4c497a51" + "14.12.eu-central-1.pv-s3" = "ami-60f2c27d" + "14.12.eu-west-1.hvm-ebs" = "ami-d126a5a6" + "14.12.eu-west-1.pv-ebs" = "ami-0126a576" + "14.12.eu-west-1.pv-s3" = "ami-deda5fa9" + "14.12.sa-east-1.hvm-ebs" = "ami-2d239e30" + "14.12.sa-east-1.pv-ebs" = "ami-35239e28" + "14.12.sa-east-1.pv-s3" = "ami-81e3519c" + "14.12.us-east-1.hvm-ebs" = "ami-0c463a64" + "14.12.us-east-1.pv-ebs" = "ami-ac473bc4" + "14.12.us-east-1.pv-s3" = "ami-00e18a68" + "14.12.us-west-1.hvm-ebs" = "ami-ca534a8f" + "14.12.us-west-1.pv-ebs" = "ami-3e534a7b" + "14.12.us-west-1.pv-s3" = "ami-2905196c" + "14.12.us-west-2.hvm-ebs" = "ami-fb9dc3cb" + "14.12.us-west-2.pv-ebs" = "ami-899dc3b9" + "14.12.us-west-2.pv-s3" = "ami-cb7f2dfb" + "15.09.ap-northeast-1.hvm-ebs" = "ami-58cac236" + "15.09.ap-northeast-1.hvm-s3" = "ami-39c8c057" + "15.09.ap-northeast-1.pv-ebs" = "ami-5ac9c134" + "15.09.ap-northeast-1.pv-s3" = "ami-03cec66d" + "15.09.ap-southeast-1.hvm-ebs" = "ami-2fc2094c" + "15.09.ap-southeast-1.hvm-s3" = "ami-9ec308fd" + "15.09.ap-southeast-1.pv-ebs" = "ami-95c00bf6" + "15.09.ap-southeast-1.pv-s3" = "ami-bfc00bdc" + "15.09.ap-southeast-2.hvm-ebs" = "ami-996c4cfa" + "15.09.ap-southeast-2.hvm-s3" = "ami-3f6e4e5c" + "15.09.ap-southeast-2.pv-ebs" = "ami-066d4d65" + "15.09.ap-southeast-2.pv-s3" = "ami-cc6e4eaf" + "15.09.eu-central-1.hvm-ebs" = "ami-3f8c6b50" + "15.09.eu-central-1.hvm-s3" = "ami-5b836434" + "15.09.eu-central-1.pv-ebs" = "ami-118c6b7e" + "15.09.eu-central-1.pv-s3" = "ami-2c977043" + "15.09.eu-west-1.hvm-ebs" = "ami-9cf04aef" + "15.09.eu-west-1.hvm-s3" = "ami-2bea5058" + "15.09.eu-west-1.pv-ebs" = "ami-c9e852ba" + "15.09.eu-west-1.pv-s3" = "ami-c6f64cb5" + "15.09.sa-east-1.hvm-ebs" = "ami-6e52df02" + "15.09.sa-east-1.hvm-s3" = "ami-1852df74" + "15.09.sa-east-1.pv-ebs" = "ami-4368e52f" + "15.09.sa-east-1.pv-s3" = "ami-f15ad79d" + "15.09.us-east-1.hvm-ebs" = "ami-84a6a0ee" + "15.09.us-east-1.hvm-s3" = "ami-06a7a16c" + "15.09.us-east-1.pv-ebs" = "ami-a4a1a7ce" + "15.09.us-east-1.pv-s3" = "ami-5ba8ae31" + "15.09.us-west-1.hvm-ebs" = "ami-22c8bb42" + "15.09.us-west-1.hvm-s3" = "ami-a2ccbfc2" + "15.09.us-west-1.pv-ebs" = "ami-10cebd70" + "15.09.us-west-1.pv-s3" = "ami-fa30429a" + "15.09.us-west-2.hvm-ebs" = "ami-ce57b9ae" + "15.09.us-west-2.hvm-s3" = "ami-2956b849" + "15.09.us-west-2.pv-ebs" = "ami-005fb160" + "15.09.us-west-2.pv-s3" = "ami-cd55bbad" + "16.03.ap-northeast-1.hvm-ebs" = "ami-40619d21" + "16.03.ap-northeast-1.hvm-s3" = "ami-ce629eaf" + "16.03.ap-northeast-1.pv-ebs" = "ami-ef639f8e" + "16.03.ap-northeast-1.pv-s3" = "ami-a1609cc0" + "16.03.ap-northeast-2.hvm-ebs" = "ami-deca00b0" + "16.03.ap-northeast-2.hvm-s3" = "ami-a3b77dcd" + "16.03.ap-northeast-2.pv-ebs" = "ami-7bcb0115" + "16.03.ap-northeast-2.pv-s3" = "ami-a2b77dcc" + "16.03.ap-south-1.hvm-ebs" = "ami-0dff9562" + "16.03.ap-south-1.hvm-s3" = "ami-13f69c7c" + "16.03.ap-south-1.pv-ebs" = "ami-0ef39961" + "16.03.ap-south-1.pv-s3" = "ami-e0c8a28f" + "16.03.ap-southeast-1.hvm-ebs" = "ami-5e964a3d" + "16.03.ap-southeast-1.hvm-s3" = "ami-4d964a2e" + "16.03.ap-southeast-1.pv-ebs" = "ami-ec9b478f" + "16.03.ap-southeast-1.pv-s3" = "ami-999b47fa" + "16.03.ap-southeast-2.hvm-ebs" = "ami-9f7359fc" + "16.03.ap-southeast-2.hvm-s3" = "ami-987359fb" + "16.03.ap-southeast-2.pv-ebs" = "ami-a2705ac1" + "16.03.ap-southeast-2.pv-s3" = "ami-a3705ac0" + "16.03.eu-central-1.hvm-ebs" = "ami-17a45178" + "16.03.eu-central-1.hvm-s3" = "ami-f9a55096" + "16.03.eu-central-1.pv-ebs" = "ami-c8a550a7" + "16.03.eu-central-1.pv-s3" = "ami-6ea45101" + "16.03.eu-west-1.hvm-ebs" = "ami-b5b3d5c6" + "16.03.eu-west-1.hvm-s3" = "ami-c986e0ba" + "16.03.eu-west-1.pv-ebs" = "ami-b083e5c3" + "16.03.eu-west-1.pv-s3" = "ami-3c83e54f" + "16.03.sa-east-1.hvm-ebs" = "ami-f6eb7f9a" + "16.03.sa-east-1.hvm-s3" = "ami-93e773ff" + "16.03.sa-east-1.pv-ebs" = "ami-cbb82ca7" + "16.03.sa-east-1.pv-s3" = "ami-abb82cc7" + "16.03.us-east-1.hvm-ebs" = "ami-c123a3d6" + "16.03.us-east-1.hvm-s3" = "ami-bc25a5ab" + "16.03.us-east-1.pv-ebs" = "ami-bd25a5aa" + "16.03.us-east-1.pv-s3" = "ami-a325a5b4" + "16.03.us-west-1.hvm-ebs" = "ami-748bcd14" + "16.03.us-west-1.hvm-s3" = "ami-a68dcbc6" + "16.03.us-west-1.pv-ebs" = "ami-048acc64" + "16.03.us-west-1.pv-s3" = "ami-208dcb40" + "16.03.us-west-2.hvm-ebs" = "ami-8263a0e2" + "16.03.us-west-2.hvm-s3" = "ami-925c9ff2" + "16.03.us-west-2.pv-ebs" = "ami-5e61a23e" + "16.03.us-west-2.pv-s3" = "ami-734c8f13" + "16.09.ap-northeast-1.hvm-ebs" = "ami-68453b0f" + "16.09.ap-northeast-1.hvm-s3" = "ami-f9bec09e" + "16.09.ap-northeast-1.pv-ebs" = "ami-254a3442" + "16.09.ap-northeast-1.pv-s3" = "ami-ef473988" + "16.09.ap-northeast-2.hvm-ebs" = "ami-18ae7f76" + "16.09.ap-northeast-2.hvm-s3" = "ami-9eac7df0" + "16.09.ap-northeast-2.pv-ebs" = "ami-57aa7b39" + "16.09.ap-northeast-2.pv-s3" = "ami-5cae7f32" + "16.09.ap-south-1.hvm-ebs" = "ami-b3f98fdc" + "16.09.ap-south-1.hvm-s3" = "ami-98e690f7" + "16.09.ap-south-1.pv-ebs" = "ami-aef98fc1" + "16.09.ap-south-1.pv-s3" = "ami-caf88ea5" + "16.09.ap-southeast-1.hvm-ebs" = "ami-80fb51e3" + "16.09.ap-southeast-1.hvm-s3" = "ami-2df3594e" + "16.09.ap-southeast-1.pv-ebs" = "ami-37f05a54" + "16.09.ap-southeast-1.pv-s3" = "ami-27f35944" + "16.09.ap-southeast-2.hvm-ebs" = "ami-57ece834" + "16.09.ap-southeast-2.hvm-s3" = "ami-87f4f0e4" + "16.09.ap-southeast-2.pv-ebs" = "ami-d8ede9bb" + "16.09.ap-southeast-2.pv-s3" = "ami-a6ebefc5" + "16.09.ca-central-1.hvm-ebs" = "ami-9f863bfb" + "16.09.ca-central-1.hvm-s3" = "ami-ea85388e" + "16.09.ca-central-1.pv-ebs" = "ami-ce8a37aa" + "16.09.ca-central-1.pv-s3" = "ami-448a3720" + "16.09.eu-central-1.hvm-ebs" = "ami-1b884774" + "16.09.eu-central-1.hvm-s3" = "ami-b08c43df" + "16.09.eu-central-1.pv-ebs" = "ami-888946e7" + "16.09.eu-central-1.pv-s3" = "ami-06874869" + "16.09.eu-west-1.hvm-ebs" = "ami-1ed3e76d" + "16.09.eu-west-1.hvm-s3" = "ami-73d1e500" + "16.09.eu-west-1.pv-ebs" = "ami-44c0f437" + "16.09.eu-west-1.pv-s3" = "ami-f3d8ec80" + "16.09.eu-west-2.hvm-ebs" = "ami-2c9c9648" + "16.09.eu-west-2.hvm-s3" = "ami-6b9e940f" + "16.09.eu-west-2.pv-ebs" = "ami-f1999395" + "16.09.eu-west-2.pv-s3" = "ami-bb9f95df" + "16.09.sa-east-1.hvm-ebs" = "ami-a11882cd" + "16.09.sa-east-1.hvm-s3" = "ami-7726bc1b" + "16.09.sa-east-1.pv-ebs" = "ami-9725bffb" + "16.09.sa-east-1.pv-s3" = "ami-b027bddc" + "16.09.us-east-1.hvm-ebs" = "ami-854ca593" + "16.09.us-east-1.hvm-s3" = "ami-2241a834" + "16.09.us-east-1.pv-ebs" = "ami-a441a8b2" + "16.09.us-east-1.pv-s3" = "ami-e841a8fe" + "16.09.us-east-2.hvm-ebs" = "ami-3f41645a" + "16.09.us-east-2.hvm-s3" = "ami-804065e5" + "16.09.us-east-2.pv-ebs" = "ami-f1466394" + "16.09.us-east-2.pv-s3" = "ami-05426760" + "16.09.us-west-1.hvm-ebs" = "ami-c2efbca2" + "16.09.us-west-1.hvm-s3" = "ami-d71042b7" + "16.09.us-west-1.pv-ebs" = "ami-04e8bb64" + "16.09.us-west-1.pv-s3" = "ami-31e9ba51" + "16.09.us-west-2.hvm-ebs" = "ami-6449f504" + "16.09.us-west-2.hvm-s3" = "ami-344af654" + "16.09.us-west-2.pv-ebs" = "ami-6d4af60d" + "16.09.us-west-2.pv-s3" = "ami-de48f4be" + "17.03.ap-northeast-1.hvm-ebs" = "ami-dbd0f7bc" + "17.03.ap-northeast-1.hvm-s3" = "ami-7cdff81b" + "17.03.ap-northeast-2.hvm-ebs" = "ami-c59a48ab" + "17.03.ap-northeast-2.hvm-s3" = "ami-0b944665" + "17.03.ap-south-1.hvm-ebs" = "ami-4f413220" + "17.03.ap-south-1.hvm-s3" = "ami-864033e9" + "17.03.ap-southeast-1.hvm-ebs" = "ami-e08c3383" + "17.03.ap-southeast-1.hvm-s3" = "ami-c28f30a1" + "17.03.ap-southeast-2.hvm-ebs" = "ami-fca9a69f" + "17.03.ap-southeast-2.hvm-s3" = "ami-3daaa55e" + "17.03.ca-central-1.hvm-ebs" = "ami-9b00bdff" + "17.03.ca-central-1.hvm-s3" = "ami-e800bd8c" + "17.03.eu-central-1.hvm-ebs" = "ami-5450803b" + "17.03.eu-central-1.hvm-s3" = "ami-6e2efe01" + "17.03.eu-west-1.hvm-ebs" = "ami-10754c76" + "17.03.eu-west-1.hvm-s3" = "ami-11734a77" + "17.03.eu-west-2.hvm-ebs" = "ami-ff1d099b" + "17.03.eu-west-2.hvm-s3" = "ami-fe1d099a" + "17.03.sa-east-1.hvm-ebs" = "ami-d95d3eb5" + "17.03.sa-east-1.hvm-s3" = "ami-fca2c190" + "17.03.us-east-1.hvm-ebs" = "ami-0940c61f" + "17.03.us-east-1.hvm-s3" = "ami-674fc971" + "17.03.us-east-2.hvm-ebs" = "ami-afc2e6ca" + "17.03.us-east-2.hvm-s3" = "ami-a1cde9c4" + "17.03.us-west-1.hvm-ebs" = "ami-587b2138" + "17.03.us-west-1.hvm-s3" = "ami-70411b10" + "17.03.us-west-2.hvm-ebs" = "ami-a93daac9" + "17.03.us-west-2.hvm-s3" = "ami-5139ae31" + "17.09.ap-northeast-1.hvm-ebs" = "ami-89b921ef" + "17.09.ap-northeast-2.hvm-ebs" = "ami-179b3b79" + "17.09.ap-south-1.hvm-ebs" = "ami-4e376021" + "17.09.ap-southeast-1.hvm-ebs" = "ami-84bccff8" + "17.09.ap-southeast-2.hvm-ebs" = "ami-0dc5386f" + "17.09.ca-central-1.hvm-ebs" = "ami-ca8207ae" + "17.09.eu-central-1.hvm-ebs" = "ami-266cfe49" + "17.09.eu-west-1.hvm-ebs" = "ami-a30192da" + "17.09.eu-west-2.hvm-ebs" = "ami-295a414d" + "17.09.eu-west-3.hvm-ebs" = "ami-8c0eb9f1" + "17.09.sa-east-1.hvm-ebs" = "ami-4762202b" + "17.09.us-east-1.hvm-ebs" = "ami-40bee63a" + "17.09.us-east-2.hvm-ebs" = "ami-9d84aff8" + "17.09.us-west-1.hvm-ebs" = "ami-d14142b1" + "17.09.us-west-2.hvm-ebs" = "ami-3eb40346" + "18.03.ap-northeast-1.hvm-ebs" = "ami-456511a8" + "18.03.ap-northeast-2.hvm-ebs" = "ami-3366d15d" + "18.03.ap-south-1.hvm-ebs" = "ami-6a390b05" + "18.03.ap-southeast-1.hvm-ebs" = "ami-aa0b4d40" + "18.03.ap-southeast-2.hvm-ebs" = "ami-d0f254b2" + "18.03.ca-central-1.hvm-ebs" = "ami-aca72ac8" + "18.03.eu-central-1.hvm-ebs" = "ami-09faf9e2" + "18.03.eu-west-1.hvm-ebs" = "ami-065c46ec" + "18.03.eu-west-2.hvm-ebs" = "ami-64f31903" + "18.03.eu-west-3.hvm-ebs" = "ami-5a8d3d27" + "18.03.sa-east-1.hvm-ebs" = "ami-163e1f7a" + "18.03.us-east-1.hvm-ebs" = "ami-8b3538f4" + "18.03.us-east-2.hvm-ebs" = "ami-150b3170" + "18.03.us-west-1.hvm-ebs" = "ami-ce06ebad" + "18.03.us-west-2.hvm-ebs" = "ami-586c3520" + "18.09.ap-northeast-1.hvm-ebs" = "ami-0cdba8e998f076547" + "18.09.ap-northeast-2.hvm-ebs" = "ami-0400a698e6a9f4a15" + "18.09.ap-south-1.hvm-ebs" = "ami-0880a678d3f555313" + "18.09.ap-southeast-1.hvm-ebs" = "ami-0892c7e24ebf2194f" + "18.09.ap-southeast-2.hvm-ebs" = "ami-010730f36424b0a2c" + "18.09.ca-central-1.hvm-ebs" = "ami-04f66113f76198f6c" + "18.09.eu-central-1.hvm-ebs" = "ami-07c9b884e679df4f8" + "18.09.eu-west-1.hvm-ebs" = "ami-0f412186fb8a0ec97" + "18.09.eu-west-2.hvm-ebs" = "ami-0dada3805ce43c55e" + "18.09.eu-west-3.hvm-ebs" = "ami-074df85565f2e02e2" + "18.09.sa-east-1.hvm-ebs" = "ami-0e4a8a47fd6db6112" + "18.09.us-east-1.hvm-ebs" = "ami-009c9c3f1af480ff3" + "18.09.us-east-2.hvm-ebs" = "ami-08199961085ea8bc6" + "18.09.us-west-1.hvm-ebs" = "ami-07aa7f56d612ddd38" + "18.09.us-west-2.hvm-ebs" = "ami-01c84b7c368ac24d1" + "19.03.ap-northeast-1.hvm-ebs" = "ami-00db62688900456a4" + "19.03.ap-northeast-2.hvm-ebs" = "ami-0485cdd1a5fdd2117" + "19.03.ap-south-1.hvm-ebs" = "ami-0303deb1b5890f878" + "19.03.ap-southeast-1.hvm-ebs" = "ami-0cff66114c652c262" + "19.03.ap-southeast-2.hvm-ebs" = "ami-054c73a7f8d773ea9" + "19.03.ca-central-1.hvm-ebs" = "ami-03f9fd0ef2e035ede" + "19.03.eu-central-1.hvm-ebs" = "ami-0022b8ea9efde5de4" + "19.03.eu-west-1.hvm-ebs" = "ami-0fe40176548ff0940" + "19.03.eu-west-2.hvm-ebs" = "ami-03a40fd3a02fe95ba" + "19.03.eu-west-3.hvm-ebs" = "ami-0436f9da0f20a638e" + "19.03.sa-east-1.hvm-ebs" = "ami-0c6a43c6e0ad1f4e2" + "19.03.us-east-1.hvm-ebs" = "ami-0efc58fb70ae9a217" + "19.03.us-east-2.hvm-ebs" = "ami-0abf711b1b34da1af" + "19.03.us-west-1.hvm-ebs" = "ami-07d126e8838c40ec5" + "19.03.us-west-2.hvm-ebs" = "ami-03f8a737546e47fb0" + "19.09.ap-east-1.hvm-ebs" = "ami-055b2348db2827ff1" + "19.09.ap-northeast-1.hvm-ebs" = "ami-02a62555ca182fb5b" + "19.09.ap-northeast-2.hvm-ebs" = "ami-0219dde0e6b7b7b93" + "19.09.ap-south-1.hvm-ebs" = "ami-066f7f2a895c821a1" + "19.09.ap-southeast-1.hvm-ebs" = "ami-0f71ae5d4b0b78d95" + "19.09.ap-southeast-2.hvm-ebs" = "ami-057bbf2b4bd62d210" + "19.09.ca-central-1.hvm-ebs" = "ami-07df50fc76702a36d" + "19.09.eu-central-1.hvm-ebs" = "ami-015f8efc2be419b79" + "19.09.eu-north-1.hvm-ebs" = "ami-07fc0a32d885e01ed" + "19.09.eu-west-1.hvm-ebs" = "ami-071082f0fa035374f" + "19.09.eu-west-2.hvm-ebs" = "ami-0d9dc33c54d1dc4c3" + "19.09.eu-west-3.hvm-ebs" = "ami-09566799591d1bfed" + "19.09.sa-east-1.hvm-ebs" = "ami-018aab68377227e06" + "19.09.us-east-1.hvm-ebs" = "ami-03330d8b51287412f" + "19.09.us-east-2.hvm-ebs" = "ami-0518b4c84972e967f" + "19.09.us-west-1.hvm-ebs" = "ami-06ad07e61a353b4a6" + "19.09.us-west-2.hvm-ebs" = "ami-0e31e30925cf3ce4e" + "20.03.ap-east-1.hvm-ebs" = "ami-0d18fdd309cdefa86" + "20.03.ap-northeast-1.hvm-ebs" = "ami-093d9cc49c191eb6c" + "20.03.ap-northeast-2.hvm-ebs" = "ami-0087df91a7b6ebd45" + "20.03.ap-south-1.hvm-ebs" = "ami-0a1a6b569af04af9d" + "20.03.ap-southeast-1.hvm-ebs" = "ami-0dbf353e168d155f7" + "20.03.ap-southeast-2.hvm-ebs" = "ami-04c0f3a75f63daddd" + "20.03.ca-central-1.hvm-ebs" = "ami-02365684a173255c7" + "20.03.eu-central-1.hvm-ebs" = "ami-0a1a94722dcbff94c" + "20.03.eu-north-1.hvm-ebs" = "ami-02699abfacbb6464b" + "20.03.eu-west-1.hvm-ebs" = "ami-02c34db5766cc7013" + "20.03.eu-west-2.hvm-ebs" = "ami-0e32bd8c7853883f1" + "20.03.eu-west-3.hvm-ebs" = "ami-061edb1356c1d69fd" + "20.03.sa-east-1.hvm-ebs" = "ami-09859378158ae971d" + "20.03.us-east-1.hvm-ebs" = "ami-0c5e7760748b74e85" + "20.03.us-east-2.hvm-ebs" = "ami-030296bb256764655" + "20.03.us-west-1.hvm-ebs" = "ami-050be818e0266b741" + "20.03.us-west-2.hvm-ebs" = "ami-06562f78dca68eda2" + "20.09.ap-east-1.hvm-ebs" = "ami-071f49713f86ea965" + "20.09.ap-northeast-1.hvm-ebs" = "ami-0beb18d632cf64e5a" + "20.09.ap-northeast-2.hvm-ebs" = "ami-0dd0316af578862db" + "20.09.ap-south-1.hvm-ebs" = "ami-008d15ced81c88aed" + "20.09.ap-southeast-1.hvm-ebs" = "ami-0db0304e23c535b2a" + "20.09.ap-southeast-2.hvm-ebs" = "ami-045983c4db7e36447" + "20.09.ca-central-1.hvm-ebs" = "ami-06d5ee429f153f856" + "20.09.eu-central-1.hvm-ebs" = "ami-01d4a0c2248cbfe38" + "20.09.eu-north-1.hvm-ebs" = "ami-0003f54dd99d68e0f" + "20.09.eu-west-1.hvm-ebs" = "ami-01a79d5ce435f4db3" + "20.09.eu-west-2.hvm-ebs" = "ami-0cbe14f32904e6331" + "20.09.eu-west-3.hvm-ebs" = "ami-07f493412d6213de6" + "20.09.sa-east-1.hvm-ebs" = "ami-05ded1ae35209b5a8" + "20.09.us-east-1.hvm-ebs" = "ami-068a62d478710462d" + "20.09.us-east-2.hvm-ebs" = "ami-01ac677ff61399caa" + "20.09.us-west-1.hvm-ebs" = "ami-04befdb203b4b17f6" + "20.09.us-west-2.hvm-ebs" = "ami-0fb7bd4a43261c6b2" + "latest.ap-east-1.hvm-ebs" = "ami-071f49713f86ea965" + "latest.ap-northeast-1.hvm-ebs" = "ami-0beb18d632cf64e5a" + "latest.ap-northeast-2.hvm-ebs" = "ami-0dd0316af578862db" + "latest.ap-south-1.hvm-ebs" = "ami-008d15ced81c88aed" + "latest.ap-southeast-1.hvm-ebs" = "ami-0db0304e23c535b2a" + "latest.ap-southeast-2.hvm-ebs" = "ami-045983c4db7e36447" + "latest.ca-central-1.hvm-ebs" = "ami-06d5ee429f153f856" + "latest.eu-central-1.hvm-ebs" = "ami-01d4a0c2248cbfe38" + "latest.eu-north-1.hvm-ebs" = "ami-0003f54dd99d68e0f" + "latest.eu-west-1.hvm-ebs" = "ami-01a79d5ce435f4db3" + "latest.eu-west-2.hvm-ebs" = "ami-0cbe14f32904e6331" + "latest.eu-west-3.hvm-ebs" = "ami-07f493412d6213de6" + "latest.sa-east-1.hvm-ebs" = "ami-05ded1ae35209b5a8" + "latest.us-east-1.hvm-ebs" = "ami-068a62d478710462d" + "latest.us-east-2.hvm-ebs" = "ami-01ac677ff61399caa" + "latest.us-west-1.hvm-ebs" = "ami-04befdb203b4b17f6" + "latest.us-west-2.hvm-ebs" = "ami-0fb7bd4a43261c6b2" + } + + description = "A map of release series to actual releases" +} diff --git a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/versions.tf b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/versions.tf new file mode 100644 index 00000000..ac97c6ac --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/versions.tf @@ -0,0 +1,4 @@ + +terraform { + required_version = ">= 0.12" +} diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/README.md b/launch/.terraform/modules/peertube.deploy/deploy_nixos/README.md new file mode 100644 index 00000000..a91f7af5 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/deploy_nixos/README.md @@ -0,0 +1,129 @@ +# deploy_nixos + +A Terraform module that knows how to deploy NixOS onto a target host. + +This allow to describe an infrastructure as code with Terraform and delegate +the machine configuration with NixOS. All directed by Terraform. + +The advantage of this method is that if any of the Nix code changes, the +difference will be detected on the next "terraform plan". + +## Usage + +Either pass a "config" which is a dynamic nixos configuration and a +"config_pwd", or a "nixos_config", a path to a nixos configuration.nix file. +If you have defined your NixOs configuration in a Flake, use "nixos_config" +to specify the name of the attribue and set "flake" to true. + +### Secret handling + +Keys can be passed to the "keys" attribute. Each key will be installed under +`/var/keys/${key}` with the content as the value. + +For services to access one of the keys, add the service user to the "keys" +group. + +The target machine needs `jq` installed prior to the deployment (as part of +the base image). If `jq` is not found it will try to use a version from +``. + +### Disabling sandboxing + +Unfortunately some time it's required to disable the nix sandboxing. To do so, +add `["--option", "sandbox", "false"]` to the "extra_build_args" parameter. + +If that doesn't work, make sure that your user is part of the nix +"trusted-users" list. + +### Non-root `target_user` + +It is possible to connect to the target host using a user that is not `root` +under certain conditions: + +* sudo needs to be installed on the machine +* the user needs password-less sudo access on the machine + +This would typically be provisioned in the base image. + +### Binary cache configuration + +One thing that might be surprising is that the binary caches (aka +substituters) are taken from the machine configuration. This implies that the +user Nix configuration will be ignored in that regard. + +## Dependencies + +* `bash` 4.0+ +* `nix` +* `openssh` +* `readlink` with `-f` (coreutils or busybox) + +## Known limitations + +The deployment machine requires Nix with access to a remote builder with the +same system as the target machine. + +Because Nix code is being evaluated at "terraform plan" time, deploying a lot +of machine in the same target will require a lot of RAM. + +All the secrets share the same "keys" group. + +When deploying as non-root, it assumes that passwordless `sudo` is available. + +The target host must already have NixOS installed. + +### config including computed values + +The module doesn't work when `` values from other resources are +interpolated with the "config" attribute. Because it happens at evaluation +time, terraform will render an empty drvPath. + +see also: +* https://github.com/hashicorp/terraform/issues/16380 +* https://github.com/hashicorp/terraform/issues/16762 +* https://github.com/hashicorp/terraform/issues/17034 + + +## Requirements + +| Name | Version | +|------|---------| +| terraform | >= 0.12 | + +## Providers + +| Name | Version | +|------|---------| +| external | n/a | +| null | n/a | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| NIX\_PATH | Allow to pass custom NIX\_PATH | `string` | `""` | no | +| build\_on\_target | Avoid building on the deployer. Must be true or false. Has no effect when deploying from an incompatible system. Unlike remote builders, this does not require the deploying user to be trusted by its host. | `string` | `false` | no | +| config | NixOS configuration to be evaluated. This argument is required unless 'nixos\_config' is given | `string` | `""` | no | +| config\_pwd | Directory to evaluate the configuration in. This argument is required if 'config' is given | `string` | `""` | no | +| extra\_build\_args | List of arguments to pass to the nix builder | `list(string)` | `[]` | no | +| extra\_eval\_args | List of arguments to pass to the nix evaluation | `list(string)` | `[]` | no | +| hermetic | Treat the provided nixos configuration as a hermetic expression and do not evaluate using the ambient system nixpkgs. Useful if you customize eval-modules or use a pinned nixpkgs. | `bool` | false | no | +| flake | Treat the provided nixos_config as the name of the NixOS configuration to use in the flake located in the current directory. Useful if you customize eval-modules or use a pinned nixpkgs. | `bool` | false | no | +| keys | A map of filename to content to upload as secrets in /var/keys | `map(string)` | `{}` | no | +| nixos\_config | Path to a NixOS configuration | `string` | `""` | no | +| ssh\_agent | Whether to use an SSH agent. True if not ssh\_private\_key is passed | `bool` | `null` | no | +| ssh\_private\_key | Content of private key used to connect to the target\_host | `string` | `""` | no | +| ssh\_private\_key\_file | Path to private key used to connect to the target\_host | `string` | `""` | no | +| target\_host | DNS host to deploy to | `string` | n/a | yes | +| target\_port | SSH port used to connect to the target\_host | `number` | `22` | no | +| target\_system | Nix system string | `string` | `"x86_64-linux"` | no | +| target\_user | SSH user used to connect to the target\_host | `string` | `"root"` | no | +| triggers | Triggers for deploy | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| id | random ID that changes on every nixos deployment | + + diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/main.tf b/launch/.terraform/modules/peertube.deploy/deploy_nixos/main.tf new file mode 100644 index 00000000..c217ce5c --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/deploy_nixos/main.tf @@ -0,0 +1,221 @@ +variable "target_host" { + type = string + description = "DNS host to deploy to" +} + +variable "target_user" { + type = string + description = "SSH user used to connect to the target_host" + default = "root" +} + +variable "target_port" { + type = number + description = "SSH port used to connect to the target_host" + default = 22 +} + +variable "ssh_private_key" { + type = string + description = "Content of private key used to connect to the target_host" + default = "" +} + +variable "ssh_private_key_file" { + type = string + description = "Path to private key used to connect to the target_host" + default = "" +} + +variable "ssh_agent" { + type = bool + description = "Whether to use an SSH agent. True if not ssh_private_key is passed" + default = null +} + +variable "NIX_PATH" { + type = string + description = "Allow to pass custom NIX_PATH" + default = "" +} + +variable "nixos_config" { + type = string + description = "Path to a NixOS configuration" + default = "" +} + +variable "config" { + type = string + description = "NixOS configuration to be evaluated. This argument is required unless 'nixos_config' is given" + default = "" +} + +variable "config_pwd" { + type = string + description = "Directory to evaluate the configuration in. This argument is required if 'config' is given" + default = "" +} + +variable "extra_eval_args" { + type = list(string) + description = "List of arguments to pass to the nix evaluation" + default = [] +} + +variable "extra_build_args" { + type = list(string) + description = "List of arguments to pass to the nix builder" + default = [] +} + +variable "build_on_target" { + type = string + description = "Avoid building on the deployer. Must be true or false. Has no effect when deploying from an incompatible system. Unlike remote builders, this does not require the deploying user to be trusted by its host." + default = false +} + +variable "triggers" { + type = map(string) + description = "Triggers for deploy" + default = {} +} + +variable "keys" { + type = map(string) + description = "A map of filename to content to upload as secrets in /var/keys" + default = {} +} + +variable "target_system" { + type = string + description = "Nix system string" + default = "x86_64-linux" +} + +variable "hermetic" { + type = bool + description = "Treat the provided nixos configuration as a hermetic expression and do not evaluate using the ambient system nixpkgs. Useful if you customize eval-modules or use a pinned nixpkgs." + default = false +} + +variable "flake" { + type = bool + description = "Treat the provided nixos_config as the NixOS configuration to use in the flake located in the current directory" + default = false +} + +variable "delete_older_than" { + type = string + description = "Can be a list of generation numbers, the special value old to delete all non-current generations, a value such as 30d to delete all generations older than the specified number of days (except for the generation that was active at that point in time), or a value such as +5 to keep the last 5 generations ignoring any newer than current, e.g., if 30 is the current generation +5 will delete generation 25 and all older generations." + default = "+1" +} + +variable "deploy_environment" { + type = map(string) + description = "Extra environment variables to be set during deployment." + default = {} +} + +# -------------------------------------------------------------------------- + +locals { + triggers = { + deploy_nixos_drv = data.external.nixos-instantiate.result["drv_path"] + deploy_nixos_keys = sha256(jsonencode(var.keys)) + } + + extra_build_args = concat([ + "--option", "substituters", data.external.nixos-instantiate.result["substituters"], + "--option", "trusted-public-keys", data.external.nixos-instantiate.result["trusted-public-keys"], + ], + var.extra_build_args, + ) + ssh_private_key_file = var.ssh_private_key_file == "" ? "-" : var.ssh_private_key_file + ssh_private_key = local.ssh_private_key_file == "-" ? var.ssh_private_key : file(local.ssh_private_key_file) + ssh_agent = var.ssh_agent == null ? (local.ssh_private_key != "") : var.ssh_agent + build_on_target = data.external.nixos-instantiate.result["currentSystem"] != var.target_system ? true : tobool(var.build_on_target) +} + +# used to detect changes in the configuration +data "external" "nixos-instantiate" { + program = concat([ + "${path.module}/nixos-instantiate.sh", + var.NIX_PATH == "" ? "-" : var.NIX_PATH, + var.config != "" ? var.config : var.nixos_config, + var.config_pwd == "" ? "." : var.config_pwd, + var.flake, + # end of positional arguments + # start of pass-through arguments + "--argstr", "system", var.target_system, + "--arg", "hermetic", var.hermetic + ], + var.extra_eval_args, + ) +} + +resource "null_resource" "deploy_nixos" { + triggers = merge(var.triggers, local.triggers) + + connection { + type = "ssh" + host = var.target_host + port = var.target_port + user = var.target_user + agent = local.ssh_agent + timeout = "100s" + private_key = local.ssh_private_key == "-" ? "" : local.ssh_private_key + } + + # copy the secret keys to the host + provisioner "file" { + content = jsonencode(var.keys) + destination = "packed-keys.json" + } + + # FIXME: move this to nixos-deploy.sh + provisioner "file" { + source = "${path.module}/unpack-keys.sh" + destination = "unpack-keys.sh" + } + + # FIXME: move this to nixos-deploy.sh + provisioner "file" { + source = "${path.module}/maybe-sudo.sh" + destination = "maybe-sudo.sh" + } + + provisioner "remote-exec" { + inline = [ + "chmod +x unpack-keys.sh maybe-sudo.sh", + "./maybe-sudo.sh ./unpack-keys.sh ./packed-keys.json", + ] + } + + # do the actual deployment + provisioner "local-exec" { + environment = var.deploy_environment + interpreter = concat([ + "${path.module}/nixos-deploy.sh", + data.external.nixos-instantiate.result["drv_path"], + data.external.nixos-instantiate.result["out_path"], + "${var.target_user}@${var.target_host}", + var.target_port, + local.build_on_target, + local.ssh_private_key == "" ? "-" : local.ssh_private_key, + "switch", + var.delete_older_than, + ], + local.extra_build_args + ) + command = "ignoreme" + } +} + +# -------------------------------------------------------------------------- + +output "id" { + description = "random ID that changes on every nixos deployment" + value = null_resource.deploy_nixos.id +} + diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/maybe-sudo.sh b/launch/.terraform/modules/peertube.deploy/deploy_nixos/maybe-sudo.sh new file mode 100755 index 00000000..989d8b2f --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/deploy_nixos/maybe-sudo.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# +# Run sudo if required +# +# Usage: ./maybe-sudo.sh [...args] +set -euo pipefail +if [[ "$UID" = 0 ]]; then + exec -- "$@" +else + exec sudo -- "$@" +fi diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-deploy.sh b/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-deploy.sh new file mode 100755 index 00000000..e0fcafb2 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-deploy.sh @@ -0,0 +1,135 @@ +#!/usr/bin/env bash +# nixos-deploy deploys a nixos-instantiate-generated drvPath to a target host +# +# Usage: nixos-deploy.sh [] ignoreme +set -euo pipefail + +### Defaults ### + +buildArgs=( + --option extra-binary-caches https://cache.nixos.org/ +) +profile=/nix/var/nix/profiles/system +# will be set later +sshOpts=( + -o "ControlMaster=auto" + -o "ControlPersist=60" + # Avoid issues with IP re-use. This disable TOFU security. + -o "StrictHostKeyChecking=no" + -o "UserKnownHostsFile=/dev/null" + -o "GlobalKnownHostsFile=/dev/null" + # interactive authentication is not possible + -o "BatchMode=yes" + # verbose output for easier debugging + -v +) + +### Argument parsing ### + +drvPath="$1" +outPath="$2" +targetHost="$3" +targetPort="$4" +buildOnTarget="$5" +sshPrivateKey="$6" +action="$7" +deleteOlderThan="$8" +shift 8 + +# remove the last argument +set -- "${@:1:$(($# - 1))}" +buildArgs+=("$@") + +sshOpts+=( -p "${targetPort}" ) + +workDir=$(mktemp -d) +trap 'rm -rf "$workDir"' EXIT + +if [[ -n "${sshPrivateKey}" && "${sshPrivateKey}" != "-" ]]; then + sshPrivateKeyFile="$workDir/ssh_key" + echo "$sshPrivateKey" > "$sshPrivateKeyFile" + chmod 0700 "$sshPrivateKeyFile" + sshOpts+=( -o "IdentityFile=${sshPrivateKeyFile}" ) +fi + +### Functions ### + +log() { + echo "--- $*" >&2 +} + +copyToTarget() { + NIX_SSHOPTS="${sshOpts[*]}" nix-copy-closure --to "$targetHost" "$@" +} + +# assumes that passwordless sudo is enabled on the server +targetHostCmd() { + # ${*@Q} escapes the arguments losslessly into space-separted quoted strings. + # `ssh` did not properly maintain the array nature of the command line, + # erroneously splitting arguments with internal spaces, even when using `--`. + # Tested with OpenSSH_7.9p1. + # + # shellcheck disable=SC2029 + ssh "${sshOpts[@]}" "$targetHost" "./maybe-sudo.sh ${*@Q}" +} + +# Setup a temporary ControlPath for this session. This speeds-up the +# operations by not re-creating SSH sessions between each command. At the end +# of the run, the session is forcefully terminated. +setupControlPath() { + sshOpts+=( + -o "ControlPath=$workDir/ssh_control" + ) + cleanupControlPath() { + local ret=$? + # Avoid failing during the shutdown + set +e + # Close ssh multiplex-master process gracefully + log "closing persistent ssh-connection" + ssh "${sshOpts[@]}" -O stop "$targetHost" + rm -rf "$workDir" + exit "$ret" + } + trap cleanupControlPath EXIT +} + +### Main ### + +log "$(env)" + +setupControlPath + +if [[ "${buildOnTarget:-false}" == true ]]; then + + # Upload derivation + log "uploading derivations" + copyToTarget "$drvPath" --gzip --use-substitutes + + # Build remotely + log "building on target" + set -x + targetHostCmd "nix-store" "--realize" "$drvPath" "${buildArgs[@]}" + +else + + # Build derivation + log "building on deployer" + outPath=$(nix-store --realize "$drvPath" "${buildArgs[@]}") + + # Upload build results + log "uploading build results" + copyToTarget "$outPath" --gzip --use-substitutes + +fi + +# Activate +log "activating configuration" +targetHostCmd nix-env --profile "$profile" --set "$outPath" +targetHostCmd "$outPath/bin/switch-to-configuration" "$action" + +# Cleanup previous generations +log "collecting old nix derivations" +# Deliberately not quoting $deleteOlderThan so the user can configure something like "1 2 3" +# to keep generations with those numbers +targetHostCmd "nix-env" "--profile" "$profile" "--delete-generations" $deleteOlderThan +targetHostCmd "nix-store" "--gc" diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-instantiate.sh b/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-instantiate.sh new file mode 100755 index 00000000..ad4763f0 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-instantiate.sh @@ -0,0 +1,94 @@ +#! /usr/bin/env bash +set -euo pipefail + +# Args +nix_path=$1 +config=$2 +config_pwd=$3 +flake=$4 +shift 4 + + +command=(nix-instantiate --show-trace --expr ' + { system, configuration, hermetic ? false, flake ? false, ... }: + let + importFromFlake = { nixosConfig }: + let + flake = (import ( + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/99f1c2157fba4bfe6211a321fd0ee43199025dbf.tar.gz"; + sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2"; } + ) { + src = ./.; + }).defaultNix; + in + builtins.getAttr nixosConfig flake.nixosConfigurations; + os = + if flake + then importFromFlake { nixosConfig = configuration; } + else if hermetic + then + ( + if builtins.isString configuration + # case: nixos_config i.e. file path + then import configuration + # case: config i.e. the module expression itself + else configuration + ) + else + import { inherit system configuration; }; + in { + inherit (builtins) currentSystem; + + substituters = + builtins.concatStringsSep " " os.config.nix.binaryCaches; + + trusted-public-keys = + builtins.concatStringsSep " " os.config.nix.binaryCachePublicKeys; + + drv_path = os.config.system.build.toplevel.drvPath; + out_path = os.config.system.build.toplevel; + }') + +if readlink --version | grep -q GNU; then + readlink="readlink -f" +else + if command -v greadlink &> /dev/null; then + readlink="greadlink -f" + else + echo "Warning: symlinks not supported because readlink is non GNU" >&2 + readlink="realpath" + fi +fi + +if [[ -f "$config" ]]; then + config=$($readlink "$config") + command+=(--argstr configuration "$config") +else + if $flake; then + command+=(--argstr configuration "$config" --arg flake true) + else + command+=(--arg configuration "$config") + fi +fi + +# add all extra CLI args as extra build arguments +command+=("$@") + +# Setting the NIX_PATH +if [[ -n "$nix_path" && "$nix_path" != "-" ]]; then + export NIX_PATH=$nix_path +fi + +# Changing directory +cd "$($readlink "$config_pwd")" + +# Instantiate +echo "running (instantiating): ${NIX_PATH:+NIX_PATH=$NIX_PATH} ${command[*]@Q}" -A out_path >&2 +"${command[@]}" -A out_path >/dev/null + +# Evaluate some more details, +# relying on preceding "Instantiate" command to perform the instantiation, +# because `--eval` is required but doesn't instantiate for some reason. +echo "running (evaluating): ${NIX_PATH:+NIX_PATH=$NIX_PATH} ${command[*]@Q}" --eval --strict --json >&2 +"${command[@]}" --eval --strict --json diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/unpack-keys.sh b/launch/.terraform/modules/peertube.deploy/deploy_nixos/unpack-keys.sh new file mode 100755 index 00000000..82ead0b8 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/deploy_nixos/unpack-keys.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# +# Unpacks the packed-keys.json into individual keys +set -euo pipefail +shopt -s nullglob + +keys_file=${1:-packed-keys.json} +keys_dir=/var/keys + +if [[ ! -f "$keys_file" ]]; then + echo "error: $keys_file not found" + exit 1 +fi + +# Fallback if jq is not installed +if ! type -p jq &>/dev/null; then + jqOut=$(nix-build '' -A jq) + jq() { + "$jqOut/bin/jq" "$@" + } +fi + +# cleanup +mkdir -m 0750 -p "$keys_dir" +chown -v root:keys "$keys_dir" +chmod -v 0750 "$keys_dir" +for key in "$keys_dir"/* ; do + rm -v "$key" +done + +if [[ $(< "$keys_file") = "{}" ]]; then + echo "no keys to unpack" + exit +fi + +echo "unpacking $keys_file" + +# extract the keys from .packed.json +for keyname in $(jq -S -r 'keys[]' "$keys_file"); do + echo "unpacking: $keyname" + jq -r ".\"$keyname\"" < "$keys_file" > "$keys_dir/$keyname" + chmod 0640 "$keys_dir/$keyname" + chown root:keys "$keys_dir/$keyname" +done + +echo "unpacking done" diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/versions.tf b/launch/.terraform/modules/peertube.deploy/deploy_nixos/versions.tf new file mode 100644 index 00000000..ac97c6ac --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/deploy_nixos/versions.tf @@ -0,0 +1,4 @@ + +terraform { + required_version = ">= 0.12" +} diff --git a/launch/.terraform/modules/peertube.deploy/examples/google/deploy_nixos.tf b/launch/.terraform/modules/peertube.deploy/examples/google/deploy_nixos.tf new file mode 100644 index 00000000..b77054c3 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/examples/google/deploy_nixos.tf @@ -0,0 +1,82 @@ +# Here we have an example of how a machine can be provisioned with some config +# after boot. This is useful in case one doesn't want to unecessarily destroy +# and create VMs in a pet scenario. + +data "google_compute_network" "default" { + name = "default" +} + +resource "google_compute_firewall" "deploy-nixos" { + name = "deploy-nixos" + network = data.google_compute_network.default.name + + allow { + protocol = "icmp" + } + + // Allow SSH access + allow { + protocol = "tcp" + ports = ["22"] + } + + // To vm tagged with: nixos + target_tags = ["nixos"] + direction = "INGRESS" + + // From anywhere. + source_ranges = ["0.0.0.0/0"] +} + +resource "google_compute_instance" "deploy-nixos" { + name = "deploy-nixos-example" + machine_type = "n1-standard-1" + zone = "us-central1-a" + + // Bind the firewall rules + tags = ["nixos"] + + boot_disk { + initialize_params { + // Start with an image the deployer can SSH into + image = module.nixos_image_custom.self_link + size = "20" + } + } + + network_interface { + network = "default" + + // Give it a public IP + access_config {} + } + + lifecycle { + // No need to re-deploy the machine if the image changed + // NixOS is already immutable + ignore_changes = [boot_disk] + } +} + +module "deploy_nixos" { + source = "../../deploy_nixos" + + // Deploy the given NixOS configuration. In this case it's the same as the + // original image. So if the configuration is changed later it will be + // deployed here. + nixos_config = "${path.module}/image_nixos_custom.nix" + + target_user = "root" + target_host = google_compute_instance.deploy-nixos.network_interface[0].access_config[0].nat_ip + + triggers = { + // Also re-deploy whenever the VM is re-created + instance_id = google_compute_instance.deploy-nixos.id + } + + // Pass some secrets. See the terraform-provider-secret to handle secrets + // in Terraform + keys = { + foo = "bar" + } +} diff --git a/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos.tf b/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos.tf new file mode 100644 index 00000000..3ee88645 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos.tf @@ -0,0 +1,25 @@ +# Here is a simple example that instantiates the google image and spins up an +# instance + +module "nixos_image_1809" { + source = "../../google_image_nixos" + nixos_version = "18.09" +} + +// This instance is not very useful since it doesn't contain any +// configuration. This could be fixed by passing a user metadata script. +resource "google_compute_instance" "image-nixos" { + name = "image-nixos" + machine_type = "n1-standard-1" + zone = "us-central1-a" + + boot_disk { + initialize_params { + image = module.nixos_image_1809.self_link + } + } + + network_interface { + network = "default" + } +} diff --git a/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.nix b/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.nix new file mode 100644 index 00000000..e67a92ff --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.nix @@ -0,0 +1,13 @@ +{ modulesPath, ... }: +{ + imports = [ + # Make sure to have this in all your configurations + "${toString modulesPath}/virtualisation/google-compute-image.nix" + ]; + + # Bake the deploy's SSH key into the image. This is not + # kosher Nix. + users.users.root.openssh.authorizedKeys.keyFiles = [ + (/. + builtins.getEnv("HOME") + "/.ssh/id_rsa.pub") + ]; +} diff --git a/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.tf b/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.tf new file mode 100644 index 00000000..243b4c44 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.tf @@ -0,0 +1,21 @@ +# create a random ID for the bucket +resource "random_id" "bucket" { + byte_length = 8 +} + +# create a bucket to upload the image into +resource "google_storage_bucket" "nixos-images" { + name = "nixos-images-${random_id.bucket.hex}" + location = "EU" +} + +# create a custom nixos base image the deployer can SSH into +# +# this could also include much more configuration and be used to feed the +# auto-scaler with system images +module "nixos_image_custom" { + source = "../../google_image_nixos_custom" + bucket_name = google_storage_bucket.nixos-images.name + + nixos_config = "${path.module}/image_nixos_custom.nix" +} diff --git a/launch/.terraform/modules/peertube.deploy/examples/google/provider.tf b/launch/.terraform/modules/peertube.deploy/examples/google/provider.tf new file mode 100644 index 00000000..910bae3e --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/examples/google/provider.tf @@ -0,0 +1,3 @@ +provider "google" { + project = "tweag-digital-assets" +} diff --git a/launch/.terraform/modules/peertube.deploy/examples/hermetic_config/configuration.nix b/launch/.terraform/modules/peertube.deploy/examples/hermetic_config/configuration.nix new file mode 100644 index 00000000..ea32c12f --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/examples/hermetic_config/configuration.nix @@ -0,0 +1,60 @@ +# A simple, hermetic NixOS configuration for an AWS EC2 instance that +# uses a nixpkgs pinned to a specific Git revision with an integrity +# hash to ensure that we construct a NixOS system as purely as +# possible. +# +# i.e. we explicitly specify which nixpkgs to use instead of relying +# on the nixpkgs supplied on the NIX_PATH. +# +# The primary benefit of this is that it removes deployment surprises +# when other developers supply a different nix-channel in the NIX_PATH +# of their environment (even if you only add the 20.09 channel, +# nix-channel --update can mutate that channel to a 20.09 with +# backported changes). +# +# The secondary benefit is that you guard the `nixpkgs` you use, with +# an integrity hash. +let + nixpkgs = + let + rev = "cd63096d6d887d689543a0b97743d28995bc9bc3"; + sha256 = "1wg61h4gndm3vcprdcg7rc4s1v3jkm5xd7lw8r2f67w502y94gcy"; + in + builtins.fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz"; + inherit sha256; + }; + + system = "x86_64-linux"; + + configuration = { config, pkgs, ... }: { + imports = [ + "${nixpkgs}/nixos/modules/virtualisation/amazon-image.nix" + ]; + + ec2.hvm = true; + + networking.firewall.allowedTCPPorts = [ 22 80 ]; + + environment.systemPackages = [ + pkgs.cloud-utils + ]; + + services.nginx = { + enable = true; + virtualHosts = { + "_" = { + root = pkgs.writeTextDir "html/index.html" '' + + +

This is a hermetic NixOS configuration!

+ + + ''; + }; + }; + }; + }; + +in + import "${nixpkgs}/nixos" { inherit system configuration; } diff --git a/launch/.terraform/modules/peertube.deploy/examples/hermetic_config/default.tf b/launch/.terraform/modules/peertube.deploy/examples/hermetic_config/default.tf new file mode 100644 index 00000000..f3fa7115 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/examples/hermetic_config/default.tf @@ -0,0 +1,27 @@ +provider "aws" { + region = "us-east-1" + profile = "yourprofile" +} + +resource "aws_instance" "hermetic-nixos-system" { + count = 1 + ami = "ami-068a62d478710462d" # NixOS 20.09 AMI + + instance_type = "t2.micro" + + key_name = "yourkeyname" + + tags = { + Name = "hermetic-nixos-system-example" + Description = "An example of a hermetic NixOS system deployed by Terraform" + } +} + +module "deploy_nixos" { + source = "github.com/awakesecurity/terraform-nixos//deploy_nixos?ref=c4b1ee6d24b54e92fa3439a12bce349a6805bcdd" + nixos_config = "${path.module}/configuration.nix" + hermetic = true + target_user = "root" + target_host = aws_instance.hermetic-nixos-system[0].public_ip + ssh_private_key_file = pathexpand("~/.ssh/yourkeyname.pem") +} diff --git a/launch/.terraform/modules/peertube.deploy/fmt b/launch/.terraform/modules/peertube.deploy/fmt new file mode 100755 index 00000000..fd5c9125 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/fmt @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# +set -euo pipefail + +cd "$(dirname "$0")" + +terraform fmt + +fmt_docs() { + ./scripts/terraform-docs-updater "$1" +} + +fmt_docs deploy_nixos +fmt_docs google_image_nixos +fmt_docs google_image_nixos_custom + +echo "." diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos/README.md b/launch/.terraform/modules/peertube.deploy/google_image_nixos/README.md new file mode 100644 index 00000000..593652b8 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/google_image_nixos/README.md @@ -0,0 +1,76 @@ +# `google_image_nixos` + +This terraform module creates a new image in the Google Cloud project using a +public tarballs of a NixOS release. Those tarballs are released by the NixOS +project. + +Since image names are unique, only one instance per version of the module is +supported per Google Cloud project. + +## Example + +```hcl +module "nixos_image_1809" { + source = "github.com/tweag/terraform-nixos/google_image_nixos" + nixos_version = "18.09" +} + +resource "google_compute_instance" "example" { + name = "example" + machine_type = "n1-standard-1" + zone = "us-central1-a" + + boot_disk { + initialize_params { + image = module.nixos_image_1809.self_link + } + } + + network_interface { + network = "default" + } +} +``` + +### Default configuration.nix + +A new configuration.nix can be passed trough the userdata. Here is the default +configuration to expand upon: + +```nix +{ modulesPath, ... }: +{ + imports = [ + "${toString modulesPath}/virtualisation/google-compute-image.nix" + ]; +} +``` + +## New NixOS releases + +Run the `./update-url-map` script to fetch new image releases. Please submit a +PR as well! + + +## Providers + +| Name | Version | +|------|---------| +| google | n/a | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:-----:| +| gcp\_project\_id | The ID of the project in which the resource belongs. If it is not provided, the provider project is used. | `string` | `""` | no | +| licenses | A list of license URIs to apply to this image. Changing this forces a new resource to be created. | `list(string)` |
[
"https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
]
| no | +| nixos\_version | The NixOS version to use. Eg: 18.09 | `string` | `"latest"` | no | +| url\_map | A map of release series to actual releases | `map(string)` |
{
"14.12": "https://nixos-cloud-images.storage.googleapis.com/nixos-14.12.471.1f09b77-x86_64-linux.raw.tar.gz",
"15.09": "https://nixos-cloud-images.storage.googleapis.com/nixos-15.09.425.7870f20-x86_64-linux.raw.tar.gz",
"16.03": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-16.03.847.8688c17-x86_64-linux.raw.tar.gz",
"17.03": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-17.03.1082.4aab5c5798-x86_64-linux.raw.tar.gz",
"18.03": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.03.132536.fdb5ba4cdf9-x86_64-linux.raw.tar.gz",
"18.09": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.09.1228.a4c4cbb613c-x86_64-linux.raw.tar.gz",
"20.03": "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz",
"latest": "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz"
}
| no | + +## Outputs + +| Name | Description | +|------|-------------| +| self\_link | Link to the NixOS Compute Image | + + diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos/main.tf b/launch/.terraform/modules/peertube.deploy/google_image_nixos/main.tf new file mode 100644 index 00000000..b42e28dd --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/google_image_nixos/main.tf @@ -0,0 +1,64 @@ +variable "nixos_version" { + type = string + default = "latest" + description = "The NixOS version to use. Eg: 18.09" +} + +variable "gcp_project_id" { + type = string + default = "" + description = "The ID of the project in which the resource belongs. If it is not provided, the provider project is used." +} + +variable "labels" { + type = map(string) + default = {} + description = "A map of labels applied to this image." +} + +variable "licenses" { + type = list(string) + + default = [ + "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx", + ] + + description = "A list of license URIs to apply to this image. Changing this forces a new resource to be created." +} + +# --- + +locals { + image_url = var.url_map[var.nixos_version] + + # Example: nixos-image-18-09-1228-a4c4cbb613c-x86-64-linux + # + # Remove a few things so that it matches the required regexp for image names + # (?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?) + image_name = replace( + replace(basename(local.image_url), ".raw.tar.gz", ""), + "/[._]+/", + "-", + ) +} + +resource "google_compute_image" "nixos" { + name = local.image_name + description = "NixOS ${var.nixos_version}" + family = "nixos" + project = var.gcp_project_id + labels = var.labels + licenses = var.licenses + + raw_disk { + source = local.image_url + } +} + +# --- + +output "self_link" { + description = "Link to the NixOS Compute Image" + value = google_compute_image.nixos.self_link +} + diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos/update-url-map b/launch/.terraform/modules/peertube.deploy/google_image_nixos/update-url-map new file mode 100755 index 00000000..4b9722ff --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/google_image_nixos/update-url-map @@ -0,0 +1,47 @@ +#!/usr/bin/env nix-shell +#!nix-shell -p ruby -i ruby +# vim: ft=ruby +# +# Run this script to update the list of GCE images +# +require "json" +require "uri" + +ENV['NIX_PATH'] = "nixpkgs=channel:nixpkgs-unstable" + +def render_tf + url_map=JSON.load(`nix-instantiate --json --strict --eval ./url_map.nix`) + + out = <<~HEADER + # DON'T EDIT, run $0 instead + variable "url_map" { + type = map(string) + + default = { + HEADER + + url_map.each_pair do |version, gs_url| + u = URI.parse(gs_url) + # convert the gs:// URL to HTTPS URL for Terraform to consume + # + # Eg: "gs://nixos-cloud-images/nixos-image-18.09-x86_64-linux.raw.tar.gz" + https_url = "https://#{u.host}.storage.googleapis.com#{u.path}" + + out += " %- 8s = %s\n" % [ version.inspect, https_url.inspect] + end + + out += <<~FOOTER + } + + description = "A map of release series to actual releases" + } + FOOTER +end + +url_map_tf = render_tf + +open("url_map.tf", "w") do |f| + f.write(url_map_tf) +end + +puts url_map_tf diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.nix b/launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.nix new file mode 100644 index 00000000..7b341ced --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.nix @@ -0,0 +1,2 @@ +# Indirect link to where the image map is stored +import diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.tf b/launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.tf new file mode 100644 index 00000000..aa898a67 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.tf @@ -0,0 +1,17 @@ +# DON'T EDIT, run $0 instead +variable "url_map" { + type = map(string) + + default = { + "14.12" = "https://nixos-cloud-images.storage.googleapis.com/nixos-14.12.471.1f09b77-x86_64-linux.raw.tar.gz" + "15.09" = "https://nixos-cloud-images.storage.googleapis.com/nixos-15.09.425.7870f20-x86_64-linux.raw.tar.gz" + "16.03" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-16.03.847.8688c17-x86_64-linux.raw.tar.gz" + "17.03" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-17.03.1082.4aab5c5798-x86_64-linux.raw.tar.gz" + "18.03" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.03.132536.fdb5ba4cdf9-x86_64-linux.raw.tar.gz" + "18.09" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.09.1228.a4c4cbb613c-x86_64-linux.raw.tar.gz" + "20.03" = "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz" + "latest" = "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz" + } + + description = "A map of release series to actual releases" +} diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos/versions.tf b/launch/.terraform/modules/peertube.deploy/google_image_nixos/versions.tf new file mode 100644 index 00000000..ac97c6ac --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/google_image_nixos/versions.tf @@ -0,0 +1,4 @@ + +terraform { + required_version = ">= 0.12" +} diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/README.md b/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/README.md new file mode 100644 index 00000000..ef2fafda --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/README.md @@ -0,0 +1,54 @@ +# google_cloud_image_nixos + +This terraform module builds and publishes custom NixOS Google Cloud images. + +## Runtime dependencies + +Because this module uses the "external" provider it needs the following +executables to be in the path to work properly: + +* bash +* nix +* `readlink -f` (busybox or coreutils) + +## Known limitations + +NixOS images are built at Terraform plan time. This can make the plan quite +slow. + +Building the image doesn't yield any output, unless the build is interrupted or +failed. + +When a new image is published, the old-one gets removed. This potentially +introduces a race-condition where other targets are trying to create new +instances with the old image. To reduce the race window, `create_before_destroy` is being used. See +https://github.com/hashicorp/terraform/issues/15485 for related discussions. + +Only x86_64-linux is currently supported. + + +## Providers + +| Name | Version | +|------|---------| +| external | n/a | +| google | n/a | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:-----:| +| NIX\_PATH | Allow to pass custom NIX\_PATH. Ignored if `-` or empty. | `string` | `"-"` | no | +| bucket\_name | Bucket where to store the image | `any` | n/a | yes | +| gcp\_project\_id | The ID of the project in which the resource belongs. If it is not provided, the provider project is used. | `string` | `""` | no | +| licenses | A list of license URIs to apply to this image. Changing this forces a new resource to be created. | `list(string)` |
[
"https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
]
| no | +| nixos\_config | Path to a nixos configuration.nix file | `any` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| NIX\_PATH | n/a | +| self\_link | n/a | + + diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/main.tf b/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/main.tf new file mode 100644 index 00000000..9ceaed5d --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/main.tf @@ -0,0 +1,94 @@ +variable "bucket_name" { + description = "Bucket where to store the image" +} + +variable "nixos_config" { + description = "Path to a nixos configuration.nix file" +} + +variable "NIX_PATH" { + type = string + description = "Allow to pass custom NIX_PATH. Ignored if `-` or empty." + default = "-" +} + +variable "gcp_project_id" { + type = string + default = "" + description = "The ID of the project in which the resource belongs. If it is not provided, the provider project is used." +} + +variable "licenses" { + type = list(string) + + default = [ + "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx", + ] + + description = "A list of license URIs to apply to this image. Changing this forces a new resource to be created." +} + +# ---------------------------------------------------- + +data "external" "nix_build" { + program = ["${path.module}/nixos-build.sh", var.NIX_PATH, var.nixos_config] +} + +locals { + out_path = data.external.nix_build.result.out_path + image_path = data.external.nix_build.result.image_path + + # 3x2d4rdm9kjzk9d9sz87rmhzvcphs23v + out_hash = element(split("-", basename(local.out_path)), 0) + + # Example: 3x2d4rdm9kjzk9d9sz87rmhzvcphs23v-19-03pre-git-x86-64-linux + # + # Remove a few things so that it matches the required regexp for image names + # (?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?) + image_name = "x${substr(local.out_hash, 0, 12)}-${replace( + replace( + basename(local.image_path), + "/\\.raw\\.tar\\.gz|nixos-image-/", + "", + ), + "/[._]+/", + "-", + )}" + + # 3x2d4rdm9kjzk9d9sz87rmhzvcphs23v-nixos-image-19.03pre-git-x86_64-linux.raw.tar.gz + image_filename = "${local.out_hash}-${basename(local.image_path)}" +} + +resource "google_storage_bucket_object" "nixos" { + name = "images/${local.image_filename}" + source = local.image_path + bucket = var.bucket_name + content_type = "application/tar+gzip" + + lifecycle { + create_before_destroy = true + } +} + +resource "google_compute_image" "nixos" { + name = local.image_name + family = "nixos" + project = var.gcp_project_id + licenses = var.licenses + + raw_disk { + source = "https://${var.bucket_name}.storage.googleapis.com/${google_storage_bucket_object.nixos.name}" + } + + lifecycle { + create_before_destroy = true + } +} + +output "self_link" { + value = google_compute_image.nixos.self_link +} + +output "NIX_PATH" { + value = var.NIX_PATH +} diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/nixos-build.sh b/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/nixos-build.sh new file mode 100755 index 00000000..270d6ca0 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/nixos-build.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# Special version of nix-build that integrates with the Terraform external +# provider +set -euo pipefail + +nix_path="${1}" +nixos_config=$(readlink -f "${2:-./configuration.nix}") + +shift +shift + +if [[ -n "$nix_path" && "$nix_path" != "-" ]]; then + export NIX_PATH=$nix_path +fi + +args=( + --arg configuration "$nixos_config" + --argstr system x86_64-linux + --no-out-link + -A config.system.build.googleComputeImage +) + +out_path=$(nix-build '' "${args[@]}" "$@") + +image_path= +for path in "$out_path"/*.tar.gz; do + image_path=$path +done + +cat </dev/null ; then + if [[ -f "$doc.bak" ]]; then + echo "$doc.bak file detected, aborting" >&2 + exit 1 + fi + + mv "$doc" "$doc.bak" + { + sed "/$BANNER_START/q" "$doc.bak" + terraform-docs md . + sed -n -e "/$BANNER_END/,\$p" "$doc.bak" + } > "$doc" + + rm "$doc.bak" +else + { + echo "$BANNER_START" + terraform-docs md . + echo "$BANNER_END" + } >> "$doc" +fi diff --git a/launch/.terraform/modules/peertube.deploy/shell.nix b/launch/.terraform/modules/peertube.deploy/shell.nix new file mode 100644 index 00000000..1d044982 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/shell.nix @@ -0,0 +1,21 @@ +with import {}; +let + tf = terraform.withPlugins(p: with p; [ + external + google + p.null + random + ]); + # https://github.com/NixOS/nixpkgs/pull/51579 + terraform-docs = callPackage ./nix/terraform-docs {}; +in +mkShell { + buildInputs = [ + tf + terraform-docs + ]; + + shellHook = '' + NIX_PATH=nixpkgs=channel:nixos-18.09 + ''; +} diff --git a/launch/.terraform/modules/pixelfed.deploy/LICENSE b/launch/.terraform/modules/pixelfed.deploy/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/launch/.terraform/modules/pixelfed.deploy/README.md b/launch/.terraform/modules/pixelfed.deploy/README.md new file mode 100644 index 00000000..443a0e87 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/README.md @@ -0,0 +1,113 @@ +# terraform-nixos + +[![built with nix](https://builtwithnix.org/badge.svg)](https://builtwithnix.org) + +This repository contains a set of Terraform Modules designed to deploy NixOS +machines. These modules are designed to work together and support different +deployment scenarios. + +## What is Terraform? + +[Terraform][terraform] is a tool that allows to declare infrastructures as +code. + +## What is Nix, nixpkgs and NixOS? + +[Nix][nix] is a build system and package manager that allows to manage whole +system configurations as code. nixpkgs is a set of 20k+ packages built with +Nix. NixOS is a Linux distribution built on top of nixpkgs. + +## What is a Terraform Module? + +A Terraform Module refers to a self-contained package of Terraform +configurations that are managed as a group. This repo contains a collection of +Terraform Modules which can be composed together to create useful +infrastructure patterns. + +## Terraform + Nix vs NixOps + +NixOps is a great tool for personal deployments. It handles a lot of things +like cloud resource creation, machine NixOS bootstrapping and deployment. + +The difficulty is when the cloud resources are not supported by NixOps. It +takes a lot of work to map all the cloud APIs. Compared to NixOps, Terraform +has become an industry standard and has thousands of people contributing new +cloud API mapping all the time. + +Another issue is when sharing the configuration as code with multiple +developers. Both NixOps and Terraform maintain a state file of "known applied" +configuration. Unlike NixOps, Terraform provides facilities to sync and lock +the state file so it's available by other users. + +The approach here is to use Terraform to create all the cloud resources. By +using the `google_image_nixos_custom` module it's possible to pre-build images in +auto-scaling scenarios. Or use a push model similar to NixOps with the generic +`deploy_nixos` module. + +So overall Terraform + Nix is more flexible and scales better. But it's also +more cumbersome to use as it requires to learn two languages instead of one +and the integration between both is also a bit clunky. + +## Terraform Modules + +The list of modules provided by this project: + +* [deploy_nixos](deploy_nixos#readme) - deploy NixOS onto running NixOS + machines +* [google_image_nixos](google_image_nixos#readme) - setup an official GCE + image into a Google Cloud Project. +* [google_image_nixos_custom](google_image_nixos_custom#readme) - build and + deploy a custom GCE image into a Google Cloud Project + +## Using these modules from your terraform configuration + +Terraform supports importing [modules](https://www.terraform.io/docs/configuration/modules.html) directly [from a GitHub repository](https://www.terraform.io/docs/modules/sources.html#github). + +For example, to use the [`deploy_nixos`](deploy_nixos#readme) module: + +``` +module "deploy_nixos" { + source = "github.com/tweag/terraform-nixos//deploy_nixos?ref=ced68729b6a0382dda02401c8f663c9b29c29368" + + … module-specific fields … +} +``` + +Beware the double `//`, which separates the github repository url from the +subdirectory that contains the module. `?ref=` specifies a specific git ref +of the repository, in this case the commit `ced687…`. + +## Examples + +To better understand how these modules can be used together, look into the +[./examples](examples) folder. + +## Related projects + +* [terraform-provider-nix](https://github.com/andrewchambers/terraform-provider-nix) + +## Future + +* Support other cloud providers. +* Support nixos-infect bootstrapping method. + +Contributions are welcome! + +## Thanks + +Thanks to [Digital Asset][digital-asset] for generously sponsoring this work! + +Thanks to [Tweag][tweag] for enabling this work and the continuous support! + +## License + +This code is released under the Apache 2.0 License. Please see +[LICENSE](LICENSE) for more details. + +Copyright © 2018 Tweag I/O. + + +[digital-asset]: https://www.digitalasset.com/ +[nix]: https://nixos.org/nix/ +[terraform]: https://www.terraform.io +[tweag]: https://www.tweag.io/ diff --git a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/README.md b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/README.md new file mode 100644 index 00000000..b36938de --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/README.md @@ -0,0 +1,46 @@ +# AWS Collection of NixOS AMIs + +This terraform module provides links to official NixOS AMIs on AWS. The AMIs are +released by the NixOS project. + +Since image names are unique, only one instance per version of the module is +supported. + +## Example + + provider "aws" { + region = "eu-west-1" + } + + module "nixos_image_1903" { + source = "path/to/aws_image_nixos" + release = "19.03" + } + + resource "aws_instance" "example" { + ami = module.nixos_image_1903.ami + instance_type = "t2.micro" + + ... + } + +## New NixOS releases + +Run the `./update-url-map` script to fetch new image releases. + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|:----:|:-----:|:-----:| +| region | The region to use. If not provided, current provider's region will be used. | string | `` | no | +| release | The NixOS version to use. For example, 18.09 | string | `latest` | no | +| type | The type of the AMI to use -- hvm-ebs, pv-ebs, or pv-s3. | string | `hvm-ebs` | no | +| url\_map | A map of release series to actual releases | map | `` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| ami | NixOS AMI on AWS | + diff --git a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/main.tf b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/main.tf new file mode 100644 index 00000000..dace86dc --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/main.tf @@ -0,0 +1,34 @@ +variable "release" { + type = string + default = "latest" + description = "The NixOS version to use. For example, 18.09" +} + +variable "region" { + type = string + default = "" + description = "The region to use. If not provided, current provider's region will be used." +} + +variable "type" { + type = string + default = "hvm-ebs" + description = "The type of the AMI to use -- hvm-ebs, pv-ebs, or pv-s3." +} + +# --- + +data "aws_region" "current" {} + +locals { + key = "${var.release}.${coalesce(var.region, data.aws_region.current.name)}.${var.type}" + ami = var.url_map[local.key] +} + +# --- + +output "ami" { + description = "NixOS AMI on AWS" + value = local.ami +} + diff --git a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/update-url-map b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/update-url-map new file mode 100755 index 00000000..3a2ce4cc --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/update-url-map @@ -0,0 +1,51 @@ +#!/usr/bin/env nix-shell +#!nix-shell -p python3 -i python +# vim: ft=python +# +# Run this script to update the list of EC2 images +# +import json +import io +from subprocess import check_output +from textwrap import dedent +from os import putenv + +putenv('NIX_PATH', 'nixpkgs=channel:nixpkgs-unstable') + +def render_tf(): + nix_eval = check_output(['nix-instantiate', '--json', '--strict', '--eval', './url_map.nix']) + url_map = json.loads(nix_eval) + + out = io.StringIO() + out.write(dedent("""\ + # DON'T EDIT, run '%s' instead + variable "url_map" { + type = map(string) + + default = { + """ % __file__)) + + for version, regions in url_map.items(): + for region, kinds in regions.items(): + for kind, ami in kinds.items(): + out.write(' "%s.%s.%s" = "%s"\n' % (version, region, kind, ami)) + + out.write(dedent("""\ + } + + description = "A map of release series to actual releases" + } + """)) + + return out.getvalue() + +url_map_tf = render_tf() + +with open("url_map.tf", "w") as f: + f.write(url_map_tf) + +print(url_map_tf) + +# Local Variables: +# mode: Python +# End: diff --git a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.nix b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.nix new file mode 100644 index 00000000..73b0b73e --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.nix @@ -0,0 +1,2 @@ +# Indirect link to where the image map is stored +import diff --git a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.tf b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.tf new file mode 100644 index 00000000..3a546a1b --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.tf @@ -0,0 +1,353 @@ +# DON'T EDIT, run './update-url-map' instead +variable "url_map" { + type = map(string) + + default = { + "14.04.ap-northeast-1.hvm-ebs" = "ami-71c6f470" + "14.04.ap-northeast-1.pv-ebs" = "ami-4dcbf84c" + "14.04.ap-northeast-1.pv-s3" = "ami-8fc4f68e" + "14.04.ap-southeast-1.hvm-ebs" = "ami-da280888" + "14.04.ap-southeast-1.pv-ebs" = "ami-7a9dbc28" + "14.04.ap-southeast-1.pv-s3" = "ami-c4290996" + "14.04.ap-southeast-2.hvm-ebs" = "ami-ab523e91" + "14.04.ap-southeast-2.pv-ebs" = "ami-6769055d" + "14.04.ap-southeast-2.pv-s3" = "ami-15533f2f" + "14.04.eu-central-1.hvm-ebs" = "ami-ba0234a7" + "14.04.eu-west-1.hvm-ebs" = "ami-96cb63e1" + "14.04.eu-west-1.pv-ebs" = "ami-b48c25c3" + "14.04.eu-west-1.pv-s3" = "ami-06cd6571" + "14.04.sa-east-1.hvm-ebs" = "ami-01b90e1c" + "14.04.sa-east-1.pv-ebs" = "ami-69e35474" + "14.04.sa-east-1.pv-s3" = "ami-61b90e7c" + "14.04.us-east-1.hvm-ebs" = "ami-58ba3a30" + "14.04.us-east-1.pv-ebs" = "ami-9e0583f6" + "14.04.us-east-1.pv-s3" = "ami-9cbe3ef4" + "14.04.us-west-1.hvm-ebs" = "ami-0bc3d74e" + "14.04.us-west-1.pv-ebs" = "ami-8b1703ce" + "14.04.us-west-1.pv-s3" = "ami-27ccd862" + "14.04.us-west-2.hvm-ebs" = "ami-3bf1bf0b" + "14.04.us-west-2.pv-ebs" = "ami-259bd515" + "14.04.us-west-2.pv-s3" = "ami-07094037" + "14.12.ap-northeast-1.hvm-ebs" = "ami-24435f25" + "14.12.ap-northeast-1.pv-ebs" = "ami-b0425eb1" + "14.12.ap-northeast-1.pv-s3" = "ami-fed3c6ff" + "14.12.ap-southeast-1.hvm-ebs" = "ami-6c765d3e" + "14.12.ap-southeast-1.pv-ebs" = "ami-6a765d38" + "14.12.ap-southeast-1.pv-s3" = "ami-d1bf9183" + "14.12.ap-southeast-2.hvm-ebs" = "ami-af86f395" + "14.12.ap-southeast-2.pv-ebs" = "ami-b386f389" + "14.12.ap-southeast-2.pv-s3" = "ami-69c5ae53" + "14.12.eu-central-1.hvm-ebs" = "ami-4a497a57" + "14.12.eu-central-1.pv-ebs" = "ami-4c497a51" + "14.12.eu-central-1.pv-s3" = "ami-60f2c27d" + "14.12.eu-west-1.hvm-ebs" = "ami-d126a5a6" + "14.12.eu-west-1.pv-ebs" = "ami-0126a576" + "14.12.eu-west-1.pv-s3" = "ami-deda5fa9" + "14.12.sa-east-1.hvm-ebs" = "ami-2d239e30" + "14.12.sa-east-1.pv-ebs" = "ami-35239e28" + "14.12.sa-east-1.pv-s3" = "ami-81e3519c" + "14.12.us-east-1.hvm-ebs" = "ami-0c463a64" + "14.12.us-east-1.pv-ebs" = "ami-ac473bc4" + "14.12.us-east-1.pv-s3" = "ami-00e18a68" + "14.12.us-west-1.hvm-ebs" = "ami-ca534a8f" + "14.12.us-west-1.pv-ebs" = "ami-3e534a7b" + "14.12.us-west-1.pv-s3" = "ami-2905196c" + "14.12.us-west-2.hvm-ebs" = "ami-fb9dc3cb" + "14.12.us-west-2.pv-ebs" = "ami-899dc3b9" + "14.12.us-west-2.pv-s3" = "ami-cb7f2dfb" + "15.09.ap-northeast-1.hvm-ebs" = "ami-58cac236" + "15.09.ap-northeast-1.hvm-s3" = "ami-39c8c057" + "15.09.ap-northeast-1.pv-ebs" = "ami-5ac9c134" + "15.09.ap-northeast-1.pv-s3" = "ami-03cec66d" + "15.09.ap-southeast-1.hvm-ebs" = "ami-2fc2094c" + "15.09.ap-southeast-1.hvm-s3" = "ami-9ec308fd" + "15.09.ap-southeast-1.pv-ebs" = "ami-95c00bf6" + "15.09.ap-southeast-1.pv-s3" = "ami-bfc00bdc" + "15.09.ap-southeast-2.hvm-ebs" = "ami-996c4cfa" + "15.09.ap-southeast-2.hvm-s3" = "ami-3f6e4e5c" + "15.09.ap-southeast-2.pv-ebs" = "ami-066d4d65" + "15.09.ap-southeast-2.pv-s3" = "ami-cc6e4eaf" + "15.09.eu-central-1.hvm-ebs" = "ami-3f8c6b50" + "15.09.eu-central-1.hvm-s3" = "ami-5b836434" + "15.09.eu-central-1.pv-ebs" = "ami-118c6b7e" + "15.09.eu-central-1.pv-s3" = "ami-2c977043" + "15.09.eu-west-1.hvm-ebs" = "ami-9cf04aef" + "15.09.eu-west-1.hvm-s3" = "ami-2bea5058" + "15.09.eu-west-1.pv-ebs" = "ami-c9e852ba" + "15.09.eu-west-1.pv-s3" = "ami-c6f64cb5" + "15.09.sa-east-1.hvm-ebs" = "ami-6e52df02" + "15.09.sa-east-1.hvm-s3" = "ami-1852df74" + "15.09.sa-east-1.pv-ebs" = "ami-4368e52f" + "15.09.sa-east-1.pv-s3" = "ami-f15ad79d" + "15.09.us-east-1.hvm-ebs" = "ami-84a6a0ee" + "15.09.us-east-1.hvm-s3" = "ami-06a7a16c" + "15.09.us-east-1.pv-ebs" = "ami-a4a1a7ce" + "15.09.us-east-1.pv-s3" = "ami-5ba8ae31" + "15.09.us-west-1.hvm-ebs" = "ami-22c8bb42" + "15.09.us-west-1.hvm-s3" = "ami-a2ccbfc2" + "15.09.us-west-1.pv-ebs" = "ami-10cebd70" + "15.09.us-west-1.pv-s3" = "ami-fa30429a" + "15.09.us-west-2.hvm-ebs" = "ami-ce57b9ae" + "15.09.us-west-2.hvm-s3" = "ami-2956b849" + "15.09.us-west-2.pv-ebs" = "ami-005fb160" + "15.09.us-west-2.pv-s3" = "ami-cd55bbad" + "16.03.ap-northeast-1.hvm-ebs" = "ami-40619d21" + "16.03.ap-northeast-1.hvm-s3" = "ami-ce629eaf" + "16.03.ap-northeast-1.pv-ebs" = "ami-ef639f8e" + "16.03.ap-northeast-1.pv-s3" = "ami-a1609cc0" + "16.03.ap-northeast-2.hvm-ebs" = "ami-deca00b0" + "16.03.ap-northeast-2.hvm-s3" = "ami-a3b77dcd" + "16.03.ap-northeast-2.pv-ebs" = "ami-7bcb0115" + "16.03.ap-northeast-2.pv-s3" = "ami-a2b77dcc" + "16.03.ap-south-1.hvm-ebs" = "ami-0dff9562" + "16.03.ap-south-1.hvm-s3" = "ami-13f69c7c" + "16.03.ap-south-1.pv-ebs" = "ami-0ef39961" + "16.03.ap-south-1.pv-s3" = "ami-e0c8a28f" + "16.03.ap-southeast-1.hvm-ebs" = "ami-5e964a3d" + "16.03.ap-southeast-1.hvm-s3" = "ami-4d964a2e" + "16.03.ap-southeast-1.pv-ebs" = "ami-ec9b478f" + "16.03.ap-southeast-1.pv-s3" = "ami-999b47fa" + "16.03.ap-southeast-2.hvm-ebs" = "ami-9f7359fc" + "16.03.ap-southeast-2.hvm-s3" = "ami-987359fb" + "16.03.ap-southeast-2.pv-ebs" = "ami-a2705ac1" + "16.03.ap-southeast-2.pv-s3" = "ami-a3705ac0" + "16.03.eu-central-1.hvm-ebs" = "ami-17a45178" + "16.03.eu-central-1.hvm-s3" = "ami-f9a55096" + "16.03.eu-central-1.pv-ebs" = "ami-c8a550a7" + "16.03.eu-central-1.pv-s3" = "ami-6ea45101" + "16.03.eu-west-1.hvm-ebs" = "ami-b5b3d5c6" + "16.03.eu-west-1.hvm-s3" = "ami-c986e0ba" + "16.03.eu-west-1.pv-ebs" = "ami-b083e5c3" + "16.03.eu-west-1.pv-s3" = "ami-3c83e54f" + "16.03.sa-east-1.hvm-ebs" = "ami-f6eb7f9a" + "16.03.sa-east-1.hvm-s3" = "ami-93e773ff" + "16.03.sa-east-1.pv-ebs" = "ami-cbb82ca7" + "16.03.sa-east-1.pv-s3" = "ami-abb82cc7" + "16.03.us-east-1.hvm-ebs" = "ami-c123a3d6" + "16.03.us-east-1.hvm-s3" = "ami-bc25a5ab" + "16.03.us-east-1.pv-ebs" = "ami-bd25a5aa" + "16.03.us-east-1.pv-s3" = "ami-a325a5b4" + "16.03.us-west-1.hvm-ebs" = "ami-748bcd14" + "16.03.us-west-1.hvm-s3" = "ami-a68dcbc6" + "16.03.us-west-1.pv-ebs" = "ami-048acc64" + "16.03.us-west-1.pv-s3" = "ami-208dcb40" + "16.03.us-west-2.hvm-ebs" = "ami-8263a0e2" + "16.03.us-west-2.hvm-s3" = "ami-925c9ff2" + "16.03.us-west-2.pv-ebs" = "ami-5e61a23e" + "16.03.us-west-2.pv-s3" = "ami-734c8f13" + "16.09.ap-northeast-1.hvm-ebs" = "ami-68453b0f" + "16.09.ap-northeast-1.hvm-s3" = "ami-f9bec09e" + "16.09.ap-northeast-1.pv-ebs" = "ami-254a3442" + "16.09.ap-northeast-1.pv-s3" = "ami-ef473988" + "16.09.ap-northeast-2.hvm-ebs" = "ami-18ae7f76" + "16.09.ap-northeast-2.hvm-s3" = "ami-9eac7df0" + "16.09.ap-northeast-2.pv-ebs" = "ami-57aa7b39" + "16.09.ap-northeast-2.pv-s3" = "ami-5cae7f32" + "16.09.ap-south-1.hvm-ebs" = "ami-b3f98fdc" + "16.09.ap-south-1.hvm-s3" = "ami-98e690f7" + "16.09.ap-south-1.pv-ebs" = "ami-aef98fc1" + "16.09.ap-south-1.pv-s3" = "ami-caf88ea5" + "16.09.ap-southeast-1.hvm-ebs" = "ami-80fb51e3" + "16.09.ap-southeast-1.hvm-s3" = "ami-2df3594e" + "16.09.ap-southeast-1.pv-ebs" = "ami-37f05a54" + "16.09.ap-southeast-1.pv-s3" = "ami-27f35944" + "16.09.ap-southeast-2.hvm-ebs" = "ami-57ece834" + "16.09.ap-southeast-2.hvm-s3" = "ami-87f4f0e4" + "16.09.ap-southeast-2.pv-ebs" = "ami-d8ede9bb" + "16.09.ap-southeast-2.pv-s3" = "ami-a6ebefc5" + "16.09.ca-central-1.hvm-ebs" = "ami-9f863bfb" + "16.09.ca-central-1.hvm-s3" = "ami-ea85388e" + "16.09.ca-central-1.pv-ebs" = "ami-ce8a37aa" + "16.09.ca-central-1.pv-s3" = "ami-448a3720" + "16.09.eu-central-1.hvm-ebs" = "ami-1b884774" + "16.09.eu-central-1.hvm-s3" = "ami-b08c43df" + "16.09.eu-central-1.pv-ebs" = "ami-888946e7" + "16.09.eu-central-1.pv-s3" = "ami-06874869" + "16.09.eu-west-1.hvm-ebs" = "ami-1ed3e76d" + "16.09.eu-west-1.hvm-s3" = "ami-73d1e500" + "16.09.eu-west-1.pv-ebs" = "ami-44c0f437" + "16.09.eu-west-1.pv-s3" = "ami-f3d8ec80" + "16.09.eu-west-2.hvm-ebs" = "ami-2c9c9648" + "16.09.eu-west-2.hvm-s3" = "ami-6b9e940f" + "16.09.eu-west-2.pv-ebs" = "ami-f1999395" + "16.09.eu-west-2.pv-s3" = "ami-bb9f95df" + "16.09.sa-east-1.hvm-ebs" = "ami-a11882cd" + "16.09.sa-east-1.hvm-s3" = "ami-7726bc1b" + "16.09.sa-east-1.pv-ebs" = "ami-9725bffb" + "16.09.sa-east-1.pv-s3" = "ami-b027bddc" + "16.09.us-east-1.hvm-ebs" = "ami-854ca593" + "16.09.us-east-1.hvm-s3" = "ami-2241a834" + "16.09.us-east-1.pv-ebs" = "ami-a441a8b2" + "16.09.us-east-1.pv-s3" = "ami-e841a8fe" + "16.09.us-east-2.hvm-ebs" = "ami-3f41645a" + "16.09.us-east-2.hvm-s3" = "ami-804065e5" + "16.09.us-east-2.pv-ebs" = "ami-f1466394" + "16.09.us-east-2.pv-s3" = "ami-05426760" + "16.09.us-west-1.hvm-ebs" = "ami-c2efbca2" + "16.09.us-west-1.hvm-s3" = "ami-d71042b7" + "16.09.us-west-1.pv-ebs" = "ami-04e8bb64" + "16.09.us-west-1.pv-s3" = "ami-31e9ba51" + "16.09.us-west-2.hvm-ebs" = "ami-6449f504" + "16.09.us-west-2.hvm-s3" = "ami-344af654" + "16.09.us-west-2.pv-ebs" = "ami-6d4af60d" + "16.09.us-west-2.pv-s3" = "ami-de48f4be" + "17.03.ap-northeast-1.hvm-ebs" = "ami-dbd0f7bc" + "17.03.ap-northeast-1.hvm-s3" = "ami-7cdff81b" + "17.03.ap-northeast-2.hvm-ebs" = "ami-c59a48ab" + "17.03.ap-northeast-2.hvm-s3" = "ami-0b944665" + "17.03.ap-south-1.hvm-ebs" = "ami-4f413220" + "17.03.ap-south-1.hvm-s3" = "ami-864033e9" + "17.03.ap-southeast-1.hvm-ebs" = "ami-e08c3383" + "17.03.ap-southeast-1.hvm-s3" = "ami-c28f30a1" + "17.03.ap-southeast-2.hvm-ebs" = "ami-fca9a69f" + "17.03.ap-southeast-2.hvm-s3" = "ami-3daaa55e" + "17.03.ca-central-1.hvm-ebs" = "ami-9b00bdff" + "17.03.ca-central-1.hvm-s3" = "ami-e800bd8c" + "17.03.eu-central-1.hvm-ebs" = "ami-5450803b" + "17.03.eu-central-1.hvm-s3" = "ami-6e2efe01" + "17.03.eu-west-1.hvm-ebs" = "ami-10754c76" + "17.03.eu-west-1.hvm-s3" = "ami-11734a77" + "17.03.eu-west-2.hvm-ebs" = "ami-ff1d099b" + "17.03.eu-west-2.hvm-s3" = "ami-fe1d099a" + "17.03.sa-east-1.hvm-ebs" = "ami-d95d3eb5" + "17.03.sa-east-1.hvm-s3" = "ami-fca2c190" + "17.03.us-east-1.hvm-ebs" = "ami-0940c61f" + "17.03.us-east-1.hvm-s3" = "ami-674fc971" + "17.03.us-east-2.hvm-ebs" = "ami-afc2e6ca" + "17.03.us-east-2.hvm-s3" = "ami-a1cde9c4" + "17.03.us-west-1.hvm-ebs" = "ami-587b2138" + "17.03.us-west-1.hvm-s3" = "ami-70411b10" + "17.03.us-west-2.hvm-ebs" = "ami-a93daac9" + "17.03.us-west-2.hvm-s3" = "ami-5139ae31" + "17.09.ap-northeast-1.hvm-ebs" = "ami-89b921ef" + "17.09.ap-northeast-2.hvm-ebs" = "ami-179b3b79" + "17.09.ap-south-1.hvm-ebs" = "ami-4e376021" + "17.09.ap-southeast-1.hvm-ebs" = "ami-84bccff8" + "17.09.ap-southeast-2.hvm-ebs" = "ami-0dc5386f" + "17.09.ca-central-1.hvm-ebs" = "ami-ca8207ae" + "17.09.eu-central-1.hvm-ebs" = "ami-266cfe49" + "17.09.eu-west-1.hvm-ebs" = "ami-a30192da" + "17.09.eu-west-2.hvm-ebs" = "ami-295a414d" + "17.09.eu-west-3.hvm-ebs" = "ami-8c0eb9f1" + "17.09.sa-east-1.hvm-ebs" = "ami-4762202b" + "17.09.us-east-1.hvm-ebs" = "ami-40bee63a" + "17.09.us-east-2.hvm-ebs" = "ami-9d84aff8" + "17.09.us-west-1.hvm-ebs" = "ami-d14142b1" + "17.09.us-west-2.hvm-ebs" = "ami-3eb40346" + "18.03.ap-northeast-1.hvm-ebs" = "ami-456511a8" + "18.03.ap-northeast-2.hvm-ebs" = "ami-3366d15d" + "18.03.ap-south-1.hvm-ebs" = "ami-6a390b05" + "18.03.ap-southeast-1.hvm-ebs" = "ami-aa0b4d40" + "18.03.ap-southeast-2.hvm-ebs" = "ami-d0f254b2" + "18.03.ca-central-1.hvm-ebs" = "ami-aca72ac8" + "18.03.eu-central-1.hvm-ebs" = "ami-09faf9e2" + "18.03.eu-west-1.hvm-ebs" = "ami-065c46ec" + "18.03.eu-west-2.hvm-ebs" = "ami-64f31903" + "18.03.eu-west-3.hvm-ebs" = "ami-5a8d3d27" + "18.03.sa-east-1.hvm-ebs" = "ami-163e1f7a" + "18.03.us-east-1.hvm-ebs" = "ami-8b3538f4" + "18.03.us-east-2.hvm-ebs" = "ami-150b3170" + "18.03.us-west-1.hvm-ebs" = "ami-ce06ebad" + "18.03.us-west-2.hvm-ebs" = "ami-586c3520" + "18.09.ap-northeast-1.hvm-ebs" = "ami-0cdba8e998f076547" + "18.09.ap-northeast-2.hvm-ebs" = "ami-0400a698e6a9f4a15" + "18.09.ap-south-1.hvm-ebs" = "ami-0880a678d3f555313" + "18.09.ap-southeast-1.hvm-ebs" = "ami-0892c7e24ebf2194f" + "18.09.ap-southeast-2.hvm-ebs" = "ami-010730f36424b0a2c" + "18.09.ca-central-1.hvm-ebs" = "ami-04f66113f76198f6c" + "18.09.eu-central-1.hvm-ebs" = "ami-07c9b884e679df4f8" + "18.09.eu-west-1.hvm-ebs" = "ami-0f412186fb8a0ec97" + "18.09.eu-west-2.hvm-ebs" = "ami-0dada3805ce43c55e" + "18.09.eu-west-3.hvm-ebs" = "ami-074df85565f2e02e2" + "18.09.sa-east-1.hvm-ebs" = "ami-0e4a8a47fd6db6112" + "18.09.us-east-1.hvm-ebs" = "ami-009c9c3f1af480ff3" + "18.09.us-east-2.hvm-ebs" = "ami-08199961085ea8bc6" + "18.09.us-west-1.hvm-ebs" = "ami-07aa7f56d612ddd38" + "18.09.us-west-2.hvm-ebs" = "ami-01c84b7c368ac24d1" + "19.03.ap-northeast-1.hvm-ebs" = "ami-00db62688900456a4" + "19.03.ap-northeast-2.hvm-ebs" = "ami-0485cdd1a5fdd2117" + "19.03.ap-south-1.hvm-ebs" = "ami-0303deb1b5890f878" + "19.03.ap-southeast-1.hvm-ebs" = "ami-0cff66114c652c262" + "19.03.ap-southeast-2.hvm-ebs" = "ami-054c73a7f8d773ea9" + "19.03.ca-central-1.hvm-ebs" = "ami-03f9fd0ef2e035ede" + "19.03.eu-central-1.hvm-ebs" = "ami-0022b8ea9efde5de4" + "19.03.eu-west-1.hvm-ebs" = "ami-0fe40176548ff0940" + "19.03.eu-west-2.hvm-ebs" = "ami-03a40fd3a02fe95ba" + "19.03.eu-west-3.hvm-ebs" = "ami-0436f9da0f20a638e" + "19.03.sa-east-1.hvm-ebs" = "ami-0c6a43c6e0ad1f4e2" + "19.03.us-east-1.hvm-ebs" = "ami-0efc58fb70ae9a217" + "19.03.us-east-2.hvm-ebs" = "ami-0abf711b1b34da1af" + "19.03.us-west-1.hvm-ebs" = "ami-07d126e8838c40ec5" + "19.03.us-west-2.hvm-ebs" = "ami-03f8a737546e47fb0" + "19.09.ap-east-1.hvm-ebs" = "ami-055b2348db2827ff1" + "19.09.ap-northeast-1.hvm-ebs" = "ami-02a62555ca182fb5b" + "19.09.ap-northeast-2.hvm-ebs" = "ami-0219dde0e6b7b7b93" + "19.09.ap-south-1.hvm-ebs" = "ami-066f7f2a895c821a1" + "19.09.ap-southeast-1.hvm-ebs" = "ami-0f71ae5d4b0b78d95" + "19.09.ap-southeast-2.hvm-ebs" = "ami-057bbf2b4bd62d210" + "19.09.ca-central-1.hvm-ebs" = "ami-07df50fc76702a36d" + "19.09.eu-central-1.hvm-ebs" = "ami-015f8efc2be419b79" + "19.09.eu-north-1.hvm-ebs" = "ami-07fc0a32d885e01ed" + "19.09.eu-west-1.hvm-ebs" = "ami-071082f0fa035374f" + "19.09.eu-west-2.hvm-ebs" = "ami-0d9dc33c54d1dc4c3" + "19.09.eu-west-3.hvm-ebs" = "ami-09566799591d1bfed" + "19.09.sa-east-1.hvm-ebs" = "ami-018aab68377227e06" + "19.09.us-east-1.hvm-ebs" = "ami-03330d8b51287412f" + "19.09.us-east-2.hvm-ebs" = "ami-0518b4c84972e967f" + "19.09.us-west-1.hvm-ebs" = "ami-06ad07e61a353b4a6" + "19.09.us-west-2.hvm-ebs" = "ami-0e31e30925cf3ce4e" + "20.03.ap-east-1.hvm-ebs" = "ami-0d18fdd309cdefa86" + "20.03.ap-northeast-1.hvm-ebs" = "ami-093d9cc49c191eb6c" + "20.03.ap-northeast-2.hvm-ebs" = "ami-0087df91a7b6ebd45" + "20.03.ap-south-1.hvm-ebs" = "ami-0a1a6b569af04af9d" + "20.03.ap-southeast-1.hvm-ebs" = "ami-0dbf353e168d155f7" + "20.03.ap-southeast-2.hvm-ebs" = "ami-04c0f3a75f63daddd" + "20.03.ca-central-1.hvm-ebs" = "ami-02365684a173255c7" + "20.03.eu-central-1.hvm-ebs" = "ami-0a1a94722dcbff94c" + "20.03.eu-north-1.hvm-ebs" = "ami-02699abfacbb6464b" + "20.03.eu-west-1.hvm-ebs" = "ami-02c34db5766cc7013" + "20.03.eu-west-2.hvm-ebs" = "ami-0e32bd8c7853883f1" + "20.03.eu-west-3.hvm-ebs" = "ami-061edb1356c1d69fd" + "20.03.sa-east-1.hvm-ebs" = "ami-09859378158ae971d" + "20.03.us-east-1.hvm-ebs" = "ami-0c5e7760748b74e85" + "20.03.us-east-2.hvm-ebs" = "ami-030296bb256764655" + "20.03.us-west-1.hvm-ebs" = "ami-050be818e0266b741" + "20.03.us-west-2.hvm-ebs" = "ami-06562f78dca68eda2" + "20.09.ap-east-1.hvm-ebs" = "ami-071f49713f86ea965" + "20.09.ap-northeast-1.hvm-ebs" = "ami-0beb18d632cf64e5a" + "20.09.ap-northeast-2.hvm-ebs" = "ami-0dd0316af578862db" + "20.09.ap-south-1.hvm-ebs" = "ami-008d15ced81c88aed" + "20.09.ap-southeast-1.hvm-ebs" = "ami-0db0304e23c535b2a" + "20.09.ap-southeast-2.hvm-ebs" = "ami-045983c4db7e36447" + "20.09.ca-central-1.hvm-ebs" = "ami-06d5ee429f153f856" + "20.09.eu-central-1.hvm-ebs" = "ami-01d4a0c2248cbfe38" + "20.09.eu-north-1.hvm-ebs" = "ami-0003f54dd99d68e0f" + "20.09.eu-west-1.hvm-ebs" = "ami-01a79d5ce435f4db3" + "20.09.eu-west-2.hvm-ebs" = "ami-0cbe14f32904e6331" + "20.09.eu-west-3.hvm-ebs" = "ami-07f493412d6213de6" + "20.09.sa-east-1.hvm-ebs" = "ami-05ded1ae35209b5a8" + "20.09.us-east-1.hvm-ebs" = "ami-068a62d478710462d" + "20.09.us-east-2.hvm-ebs" = "ami-01ac677ff61399caa" + "20.09.us-west-1.hvm-ebs" = "ami-04befdb203b4b17f6" + "20.09.us-west-2.hvm-ebs" = "ami-0fb7bd4a43261c6b2" + "latest.ap-east-1.hvm-ebs" = "ami-071f49713f86ea965" + "latest.ap-northeast-1.hvm-ebs" = "ami-0beb18d632cf64e5a" + "latest.ap-northeast-2.hvm-ebs" = "ami-0dd0316af578862db" + "latest.ap-south-1.hvm-ebs" = "ami-008d15ced81c88aed" + "latest.ap-southeast-1.hvm-ebs" = "ami-0db0304e23c535b2a" + "latest.ap-southeast-2.hvm-ebs" = "ami-045983c4db7e36447" + "latest.ca-central-1.hvm-ebs" = "ami-06d5ee429f153f856" + "latest.eu-central-1.hvm-ebs" = "ami-01d4a0c2248cbfe38" + "latest.eu-north-1.hvm-ebs" = "ami-0003f54dd99d68e0f" + "latest.eu-west-1.hvm-ebs" = "ami-01a79d5ce435f4db3" + "latest.eu-west-2.hvm-ebs" = "ami-0cbe14f32904e6331" + "latest.eu-west-3.hvm-ebs" = "ami-07f493412d6213de6" + "latest.sa-east-1.hvm-ebs" = "ami-05ded1ae35209b5a8" + "latest.us-east-1.hvm-ebs" = "ami-068a62d478710462d" + "latest.us-east-2.hvm-ebs" = "ami-01ac677ff61399caa" + "latest.us-west-1.hvm-ebs" = "ami-04befdb203b4b17f6" + "latest.us-west-2.hvm-ebs" = "ami-0fb7bd4a43261c6b2" + } + + description = "A map of release series to actual releases" +} diff --git a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/versions.tf b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/versions.tf new file mode 100644 index 00000000..ac97c6ac --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/versions.tf @@ -0,0 +1,4 @@ + +terraform { + required_version = ">= 0.12" +} diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/README.md b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/README.md new file mode 100644 index 00000000..a91f7af5 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/README.md @@ -0,0 +1,129 @@ +# deploy_nixos + +A Terraform module that knows how to deploy NixOS onto a target host. + +This allow to describe an infrastructure as code with Terraform and delegate +the machine configuration with NixOS. All directed by Terraform. + +The advantage of this method is that if any of the Nix code changes, the +difference will be detected on the next "terraform plan". + +## Usage + +Either pass a "config" which is a dynamic nixos configuration and a +"config_pwd", or a "nixos_config", a path to a nixos configuration.nix file. +If you have defined your NixOs configuration in a Flake, use "nixos_config" +to specify the name of the attribue and set "flake" to true. + +### Secret handling + +Keys can be passed to the "keys" attribute. Each key will be installed under +`/var/keys/${key}` with the content as the value. + +For services to access one of the keys, add the service user to the "keys" +group. + +The target machine needs `jq` installed prior to the deployment (as part of +the base image). If `jq` is not found it will try to use a version from +``. + +### Disabling sandboxing + +Unfortunately some time it's required to disable the nix sandboxing. To do so, +add `["--option", "sandbox", "false"]` to the "extra_build_args" parameter. + +If that doesn't work, make sure that your user is part of the nix +"trusted-users" list. + +### Non-root `target_user` + +It is possible to connect to the target host using a user that is not `root` +under certain conditions: + +* sudo needs to be installed on the machine +* the user needs password-less sudo access on the machine + +This would typically be provisioned in the base image. + +### Binary cache configuration + +One thing that might be surprising is that the binary caches (aka +substituters) are taken from the machine configuration. This implies that the +user Nix configuration will be ignored in that regard. + +## Dependencies + +* `bash` 4.0+ +* `nix` +* `openssh` +* `readlink` with `-f` (coreutils or busybox) + +## Known limitations + +The deployment machine requires Nix with access to a remote builder with the +same system as the target machine. + +Because Nix code is being evaluated at "terraform plan" time, deploying a lot +of machine in the same target will require a lot of RAM. + +All the secrets share the same "keys" group. + +When deploying as non-root, it assumes that passwordless `sudo` is available. + +The target host must already have NixOS installed. + +### config including computed values + +The module doesn't work when `` values from other resources are +interpolated with the "config" attribute. Because it happens at evaluation +time, terraform will render an empty drvPath. + +see also: +* https://github.com/hashicorp/terraform/issues/16380 +* https://github.com/hashicorp/terraform/issues/16762 +* https://github.com/hashicorp/terraform/issues/17034 + + +## Requirements + +| Name | Version | +|------|---------| +| terraform | >= 0.12 | + +## Providers + +| Name | Version | +|------|---------| +| external | n/a | +| null | n/a | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| NIX\_PATH | Allow to pass custom NIX\_PATH | `string` | `""` | no | +| build\_on\_target | Avoid building on the deployer. Must be true or false. Has no effect when deploying from an incompatible system. Unlike remote builders, this does not require the deploying user to be trusted by its host. | `string` | `false` | no | +| config | NixOS configuration to be evaluated. This argument is required unless 'nixos\_config' is given | `string` | `""` | no | +| config\_pwd | Directory to evaluate the configuration in. This argument is required if 'config' is given | `string` | `""` | no | +| extra\_build\_args | List of arguments to pass to the nix builder | `list(string)` | `[]` | no | +| extra\_eval\_args | List of arguments to pass to the nix evaluation | `list(string)` | `[]` | no | +| hermetic | Treat the provided nixos configuration as a hermetic expression and do not evaluate using the ambient system nixpkgs. Useful if you customize eval-modules or use a pinned nixpkgs. | `bool` | false | no | +| flake | Treat the provided nixos_config as the name of the NixOS configuration to use in the flake located in the current directory. Useful if you customize eval-modules or use a pinned nixpkgs. | `bool` | false | no | +| keys | A map of filename to content to upload as secrets in /var/keys | `map(string)` | `{}` | no | +| nixos\_config | Path to a NixOS configuration | `string` | `""` | no | +| ssh\_agent | Whether to use an SSH agent. True if not ssh\_private\_key is passed | `bool` | `null` | no | +| ssh\_private\_key | Content of private key used to connect to the target\_host | `string` | `""` | no | +| ssh\_private\_key\_file | Path to private key used to connect to the target\_host | `string` | `""` | no | +| target\_host | DNS host to deploy to | `string` | n/a | yes | +| target\_port | SSH port used to connect to the target\_host | `number` | `22` | no | +| target\_system | Nix system string | `string` | `"x86_64-linux"` | no | +| target\_user | SSH user used to connect to the target\_host | `string` | `"root"` | no | +| triggers | Triggers for deploy | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| id | random ID that changes on every nixos deployment | + + diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/main.tf b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/main.tf new file mode 100644 index 00000000..c217ce5c --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/main.tf @@ -0,0 +1,221 @@ +variable "target_host" { + type = string + description = "DNS host to deploy to" +} + +variable "target_user" { + type = string + description = "SSH user used to connect to the target_host" + default = "root" +} + +variable "target_port" { + type = number + description = "SSH port used to connect to the target_host" + default = 22 +} + +variable "ssh_private_key" { + type = string + description = "Content of private key used to connect to the target_host" + default = "" +} + +variable "ssh_private_key_file" { + type = string + description = "Path to private key used to connect to the target_host" + default = "" +} + +variable "ssh_agent" { + type = bool + description = "Whether to use an SSH agent. True if not ssh_private_key is passed" + default = null +} + +variable "NIX_PATH" { + type = string + description = "Allow to pass custom NIX_PATH" + default = "" +} + +variable "nixos_config" { + type = string + description = "Path to a NixOS configuration" + default = "" +} + +variable "config" { + type = string + description = "NixOS configuration to be evaluated. This argument is required unless 'nixos_config' is given" + default = "" +} + +variable "config_pwd" { + type = string + description = "Directory to evaluate the configuration in. This argument is required if 'config' is given" + default = "" +} + +variable "extra_eval_args" { + type = list(string) + description = "List of arguments to pass to the nix evaluation" + default = [] +} + +variable "extra_build_args" { + type = list(string) + description = "List of arguments to pass to the nix builder" + default = [] +} + +variable "build_on_target" { + type = string + description = "Avoid building on the deployer. Must be true or false. Has no effect when deploying from an incompatible system. Unlike remote builders, this does not require the deploying user to be trusted by its host." + default = false +} + +variable "triggers" { + type = map(string) + description = "Triggers for deploy" + default = {} +} + +variable "keys" { + type = map(string) + description = "A map of filename to content to upload as secrets in /var/keys" + default = {} +} + +variable "target_system" { + type = string + description = "Nix system string" + default = "x86_64-linux" +} + +variable "hermetic" { + type = bool + description = "Treat the provided nixos configuration as a hermetic expression and do not evaluate using the ambient system nixpkgs. Useful if you customize eval-modules or use a pinned nixpkgs." + default = false +} + +variable "flake" { + type = bool + description = "Treat the provided nixos_config as the NixOS configuration to use in the flake located in the current directory" + default = false +} + +variable "delete_older_than" { + type = string + description = "Can be a list of generation numbers, the special value old to delete all non-current generations, a value such as 30d to delete all generations older than the specified number of days (except for the generation that was active at that point in time), or a value such as +5 to keep the last 5 generations ignoring any newer than current, e.g., if 30 is the current generation +5 will delete generation 25 and all older generations." + default = "+1" +} + +variable "deploy_environment" { + type = map(string) + description = "Extra environment variables to be set during deployment." + default = {} +} + +# -------------------------------------------------------------------------- + +locals { + triggers = { + deploy_nixos_drv = data.external.nixos-instantiate.result["drv_path"] + deploy_nixos_keys = sha256(jsonencode(var.keys)) + } + + extra_build_args = concat([ + "--option", "substituters", data.external.nixos-instantiate.result["substituters"], + "--option", "trusted-public-keys", data.external.nixos-instantiate.result["trusted-public-keys"], + ], + var.extra_build_args, + ) + ssh_private_key_file = var.ssh_private_key_file == "" ? "-" : var.ssh_private_key_file + ssh_private_key = local.ssh_private_key_file == "-" ? var.ssh_private_key : file(local.ssh_private_key_file) + ssh_agent = var.ssh_agent == null ? (local.ssh_private_key != "") : var.ssh_agent + build_on_target = data.external.nixos-instantiate.result["currentSystem"] != var.target_system ? true : tobool(var.build_on_target) +} + +# used to detect changes in the configuration +data "external" "nixos-instantiate" { + program = concat([ + "${path.module}/nixos-instantiate.sh", + var.NIX_PATH == "" ? "-" : var.NIX_PATH, + var.config != "" ? var.config : var.nixos_config, + var.config_pwd == "" ? "." : var.config_pwd, + var.flake, + # end of positional arguments + # start of pass-through arguments + "--argstr", "system", var.target_system, + "--arg", "hermetic", var.hermetic + ], + var.extra_eval_args, + ) +} + +resource "null_resource" "deploy_nixos" { + triggers = merge(var.triggers, local.triggers) + + connection { + type = "ssh" + host = var.target_host + port = var.target_port + user = var.target_user + agent = local.ssh_agent + timeout = "100s" + private_key = local.ssh_private_key == "-" ? "" : local.ssh_private_key + } + + # copy the secret keys to the host + provisioner "file" { + content = jsonencode(var.keys) + destination = "packed-keys.json" + } + + # FIXME: move this to nixos-deploy.sh + provisioner "file" { + source = "${path.module}/unpack-keys.sh" + destination = "unpack-keys.sh" + } + + # FIXME: move this to nixos-deploy.sh + provisioner "file" { + source = "${path.module}/maybe-sudo.sh" + destination = "maybe-sudo.sh" + } + + provisioner "remote-exec" { + inline = [ + "chmod +x unpack-keys.sh maybe-sudo.sh", + "./maybe-sudo.sh ./unpack-keys.sh ./packed-keys.json", + ] + } + + # do the actual deployment + provisioner "local-exec" { + environment = var.deploy_environment + interpreter = concat([ + "${path.module}/nixos-deploy.sh", + data.external.nixos-instantiate.result["drv_path"], + data.external.nixos-instantiate.result["out_path"], + "${var.target_user}@${var.target_host}", + var.target_port, + local.build_on_target, + local.ssh_private_key == "" ? "-" : local.ssh_private_key, + "switch", + var.delete_older_than, + ], + local.extra_build_args + ) + command = "ignoreme" + } +} + +# -------------------------------------------------------------------------- + +output "id" { + description = "random ID that changes on every nixos deployment" + value = null_resource.deploy_nixos.id +} + diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/maybe-sudo.sh b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/maybe-sudo.sh new file mode 100755 index 00000000..989d8b2f --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/maybe-sudo.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# +# Run sudo if required +# +# Usage: ./maybe-sudo.sh [...args] +set -euo pipefail +if [[ "$UID" = 0 ]]; then + exec -- "$@" +else + exec sudo -- "$@" +fi diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-deploy.sh b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-deploy.sh new file mode 100755 index 00000000..e0fcafb2 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-deploy.sh @@ -0,0 +1,135 @@ +#!/usr/bin/env bash +# nixos-deploy deploys a nixos-instantiate-generated drvPath to a target host +# +# Usage: nixos-deploy.sh [] ignoreme +set -euo pipefail + +### Defaults ### + +buildArgs=( + --option extra-binary-caches https://cache.nixos.org/ +) +profile=/nix/var/nix/profiles/system +# will be set later +sshOpts=( + -o "ControlMaster=auto" + -o "ControlPersist=60" + # Avoid issues with IP re-use. This disable TOFU security. + -o "StrictHostKeyChecking=no" + -o "UserKnownHostsFile=/dev/null" + -o "GlobalKnownHostsFile=/dev/null" + # interactive authentication is not possible + -o "BatchMode=yes" + # verbose output for easier debugging + -v +) + +### Argument parsing ### + +drvPath="$1" +outPath="$2" +targetHost="$3" +targetPort="$4" +buildOnTarget="$5" +sshPrivateKey="$6" +action="$7" +deleteOlderThan="$8" +shift 8 + +# remove the last argument +set -- "${@:1:$(($# - 1))}" +buildArgs+=("$@") + +sshOpts+=( -p "${targetPort}" ) + +workDir=$(mktemp -d) +trap 'rm -rf "$workDir"' EXIT + +if [[ -n "${sshPrivateKey}" && "${sshPrivateKey}" != "-" ]]; then + sshPrivateKeyFile="$workDir/ssh_key" + echo "$sshPrivateKey" > "$sshPrivateKeyFile" + chmod 0700 "$sshPrivateKeyFile" + sshOpts+=( -o "IdentityFile=${sshPrivateKeyFile}" ) +fi + +### Functions ### + +log() { + echo "--- $*" >&2 +} + +copyToTarget() { + NIX_SSHOPTS="${sshOpts[*]}" nix-copy-closure --to "$targetHost" "$@" +} + +# assumes that passwordless sudo is enabled on the server +targetHostCmd() { + # ${*@Q} escapes the arguments losslessly into space-separted quoted strings. + # `ssh` did not properly maintain the array nature of the command line, + # erroneously splitting arguments with internal spaces, even when using `--`. + # Tested with OpenSSH_7.9p1. + # + # shellcheck disable=SC2029 + ssh "${sshOpts[@]}" "$targetHost" "./maybe-sudo.sh ${*@Q}" +} + +# Setup a temporary ControlPath for this session. This speeds-up the +# operations by not re-creating SSH sessions between each command. At the end +# of the run, the session is forcefully terminated. +setupControlPath() { + sshOpts+=( + -o "ControlPath=$workDir/ssh_control" + ) + cleanupControlPath() { + local ret=$? + # Avoid failing during the shutdown + set +e + # Close ssh multiplex-master process gracefully + log "closing persistent ssh-connection" + ssh "${sshOpts[@]}" -O stop "$targetHost" + rm -rf "$workDir" + exit "$ret" + } + trap cleanupControlPath EXIT +} + +### Main ### + +log "$(env)" + +setupControlPath + +if [[ "${buildOnTarget:-false}" == true ]]; then + + # Upload derivation + log "uploading derivations" + copyToTarget "$drvPath" --gzip --use-substitutes + + # Build remotely + log "building on target" + set -x + targetHostCmd "nix-store" "--realize" "$drvPath" "${buildArgs[@]}" + +else + + # Build derivation + log "building on deployer" + outPath=$(nix-store --realize "$drvPath" "${buildArgs[@]}") + + # Upload build results + log "uploading build results" + copyToTarget "$outPath" --gzip --use-substitutes + +fi + +# Activate +log "activating configuration" +targetHostCmd nix-env --profile "$profile" --set "$outPath" +targetHostCmd "$outPath/bin/switch-to-configuration" "$action" + +# Cleanup previous generations +log "collecting old nix derivations" +# Deliberately not quoting $deleteOlderThan so the user can configure something like "1 2 3" +# to keep generations with those numbers +targetHostCmd "nix-env" "--profile" "$profile" "--delete-generations" $deleteOlderThan +targetHostCmd "nix-store" "--gc" diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-instantiate.sh b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-instantiate.sh new file mode 100755 index 00000000..ad4763f0 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-instantiate.sh @@ -0,0 +1,94 @@ +#! /usr/bin/env bash +set -euo pipefail + +# Args +nix_path=$1 +config=$2 +config_pwd=$3 +flake=$4 +shift 4 + + +command=(nix-instantiate --show-trace --expr ' + { system, configuration, hermetic ? false, flake ? false, ... }: + let + importFromFlake = { nixosConfig }: + let + flake = (import ( + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/99f1c2157fba4bfe6211a321fd0ee43199025dbf.tar.gz"; + sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2"; } + ) { + src = ./.; + }).defaultNix; + in + builtins.getAttr nixosConfig flake.nixosConfigurations; + os = + if flake + then importFromFlake { nixosConfig = configuration; } + else if hermetic + then + ( + if builtins.isString configuration + # case: nixos_config i.e. file path + then import configuration + # case: config i.e. the module expression itself + else configuration + ) + else + import { inherit system configuration; }; + in { + inherit (builtins) currentSystem; + + substituters = + builtins.concatStringsSep " " os.config.nix.binaryCaches; + + trusted-public-keys = + builtins.concatStringsSep " " os.config.nix.binaryCachePublicKeys; + + drv_path = os.config.system.build.toplevel.drvPath; + out_path = os.config.system.build.toplevel; + }') + +if readlink --version | grep -q GNU; then + readlink="readlink -f" +else + if command -v greadlink &> /dev/null; then + readlink="greadlink -f" + else + echo "Warning: symlinks not supported because readlink is non GNU" >&2 + readlink="realpath" + fi +fi + +if [[ -f "$config" ]]; then + config=$($readlink "$config") + command+=(--argstr configuration "$config") +else + if $flake; then + command+=(--argstr configuration "$config" --arg flake true) + else + command+=(--arg configuration "$config") + fi +fi + +# add all extra CLI args as extra build arguments +command+=("$@") + +# Setting the NIX_PATH +if [[ -n "$nix_path" && "$nix_path" != "-" ]]; then + export NIX_PATH=$nix_path +fi + +# Changing directory +cd "$($readlink "$config_pwd")" + +# Instantiate +echo "running (instantiating): ${NIX_PATH:+NIX_PATH=$NIX_PATH} ${command[*]@Q}" -A out_path >&2 +"${command[@]}" -A out_path >/dev/null + +# Evaluate some more details, +# relying on preceding "Instantiate" command to perform the instantiation, +# because `--eval` is required but doesn't instantiate for some reason. +echo "running (evaluating): ${NIX_PATH:+NIX_PATH=$NIX_PATH} ${command[*]@Q}" --eval --strict --json >&2 +"${command[@]}" --eval --strict --json diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/unpack-keys.sh b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/unpack-keys.sh new file mode 100755 index 00000000..82ead0b8 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/unpack-keys.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# +# Unpacks the packed-keys.json into individual keys +set -euo pipefail +shopt -s nullglob + +keys_file=${1:-packed-keys.json} +keys_dir=/var/keys + +if [[ ! -f "$keys_file" ]]; then + echo "error: $keys_file not found" + exit 1 +fi + +# Fallback if jq is not installed +if ! type -p jq &>/dev/null; then + jqOut=$(nix-build '' -A jq) + jq() { + "$jqOut/bin/jq" "$@" + } +fi + +# cleanup +mkdir -m 0750 -p "$keys_dir" +chown -v root:keys "$keys_dir" +chmod -v 0750 "$keys_dir" +for key in "$keys_dir"/* ; do + rm -v "$key" +done + +if [[ $(< "$keys_file") = "{}" ]]; then + echo "no keys to unpack" + exit +fi + +echo "unpacking $keys_file" + +# extract the keys from .packed.json +for keyname in $(jq -S -r 'keys[]' "$keys_file"); do + echo "unpacking: $keyname" + jq -r ".\"$keyname\"" < "$keys_file" > "$keys_dir/$keyname" + chmod 0640 "$keys_dir/$keyname" + chown root:keys "$keys_dir/$keyname" +done + +echo "unpacking done" diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/versions.tf b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/versions.tf new file mode 100644 index 00000000..ac97c6ac --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/versions.tf @@ -0,0 +1,4 @@ + +terraform { + required_version = ">= 0.12" +} diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/google/deploy_nixos.tf b/launch/.terraform/modules/pixelfed.deploy/examples/google/deploy_nixos.tf new file mode 100644 index 00000000..b77054c3 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/examples/google/deploy_nixos.tf @@ -0,0 +1,82 @@ +# Here we have an example of how a machine can be provisioned with some config +# after boot. This is useful in case one doesn't want to unecessarily destroy +# and create VMs in a pet scenario. + +data "google_compute_network" "default" { + name = "default" +} + +resource "google_compute_firewall" "deploy-nixos" { + name = "deploy-nixos" + network = data.google_compute_network.default.name + + allow { + protocol = "icmp" + } + + // Allow SSH access + allow { + protocol = "tcp" + ports = ["22"] + } + + // To vm tagged with: nixos + target_tags = ["nixos"] + direction = "INGRESS" + + // From anywhere. + source_ranges = ["0.0.0.0/0"] +} + +resource "google_compute_instance" "deploy-nixos" { + name = "deploy-nixos-example" + machine_type = "n1-standard-1" + zone = "us-central1-a" + + // Bind the firewall rules + tags = ["nixos"] + + boot_disk { + initialize_params { + // Start with an image the deployer can SSH into + image = module.nixos_image_custom.self_link + size = "20" + } + } + + network_interface { + network = "default" + + // Give it a public IP + access_config {} + } + + lifecycle { + // No need to re-deploy the machine if the image changed + // NixOS is already immutable + ignore_changes = [boot_disk] + } +} + +module "deploy_nixos" { + source = "../../deploy_nixos" + + // Deploy the given NixOS configuration. In this case it's the same as the + // original image. So if the configuration is changed later it will be + // deployed here. + nixos_config = "${path.module}/image_nixos_custom.nix" + + target_user = "root" + target_host = google_compute_instance.deploy-nixos.network_interface[0].access_config[0].nat_ip + + triggers = { + // Also re-deploy whenever the VM is re-created + instance_id = google_compute_instance.deploy-nixos.id + } + + // Pass some secrets. See the terraform-provider-secret to handle secrets + // in Terraform + keys = { + foo = "bar" + } +} diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos.tf b/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos.tf new file mode 100644 index 00000000..3ee88645 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos.tf @@ -0,0 +1,25 @@ +# Here is a simple example that instantiates the google image and spins up an +# instance + +module "nixos_image_1809" { + source = "../../google_image_nixos" + nixos_version = "18.09" +} + +// This instance is not very useful since it doesn't contain any +// configuration. This could be fixed by passing a user metadata script. +resource "google_compute_instance" "image-nixos" { + name = "image-nixos" + machine_type = "n1-standard-1" + zone = "us-central1-a" + + boot_disk { + initialize_params { + image = module.nixos_image_1809.self_link + } + } + + network_interface { + network = "default" + } +} diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.nix b/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.nix new file mode 100644 index 00000000..e67a92ff --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.nix @@ -0,0 +1,13 @@ +{ modulesPath, ... }: +{ + imports = [ + # Make sure to have this in all your configurations + "${toString modulesPath}/virtualisation/google-compute-image.nix" + ]; + + # Bake the deploy's SSH key into the image. This is not + # kosher Nix. + users.users.root.openssh.authorizedKeys.keyFiles = [ + (/. + builtins.getEnv("HOME") + "/.ssh/id_rsa.pub") + ]; +} diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.tf b/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.tf new file mode 100644 index 00000000..243b4c44 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.tf @@ -0,0 +1,21 @@ +# create a random ID for the bucket +resource "random_id" "bucket" { + byte_length = 8 +} + +# create a bucket to upload the image into +resource "google_storage_bucket" "nixos-images" { + name = "nixos-images-${random_id.bucket.hex}" + location = "EU" +} + +# create a custom nixos base image the deployer can SSH into +# +# this could also include much more configuration and be used to feed the +# auto-scaler with system images +module "nixos_image_custom" { + source = "../../google_image_nixos_custom" + bucket_name = google_storage_bucket.nixos-images.name + + nixos_config = "${path.module}/image_nixos_custom.nix" +} diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/google/provider.tf b/launch/.terraform/modules/pixelfed.deploy/examples/google/provider.tf new file mode 100644 index 00000000..910bae3e --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/examples/google/provider.tf @@ -0,0 +1,3 @@ +provider "google" { + project = "tweag-digital-assets" +} diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/configuration.nix b/launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/configuration.nix new file mode 100644 index 00000000..ea32c12f --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/configuration.nix @@ -0,0 +1,60 @@ +# A simple, hermetic NixOS configuration for an AWS EC2 instance that +# uses a nixpkgs pinned to a specific Git revision with an integrity +# hash to ensure that we construct a NixOS system as purely as +# possible. +# +# i.e. we explicitly specify which nixpkgs to use instead of relying +# on the nixpkgs supplied on the NIX_PATH. +# +# The primary benefit of this is that it removes deployment surprises +# when other developers supply a different nix-channel in the NIX_PATH +# of their environment (even if you only add the 20.09 channel, +# nix-channel --update can mutate that channel to a 20.09 with +# backported changes). +# +# The secondary benefit is that you guard the `nixpkgs` you use, with +# an integrity hash. +let + nixpkgs = + let + rev = "cd63096d6d887d689543a0b97743d28995bc9bc3"; + sha256 = "1wg61h4gndm3vcprdcg7rc4s1v3jkm5xd7lw8r2f67w502y94gcy"; + in + builtins.fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz"; + inherit sha256; + }; + + system = "x86_64-linux"; + + configuration = { config, pkgs, ... }: { + imports = [ + "${nixpkgs}/nixos/modules/virtualisation/amazon-image.nix" + ]; + + ec2.hvm = true; + + networking.firewall.allowedTCPPorts = [ 22 80 ]; + + environment.systemPackages = [ + pkgs.cloud-utils + ]; + + services.nginx = { + enable = true; + virtualHosts = { + "_" = { + root = pkgs.writeTextDir "html/index.html" '' + + +

This is a hermetic NixOS configuration!

+ + + ''; + }; + }; + }; + }; + +in + import "${nixpkgs}/nixos" { inherit system configuration; } diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/default.tf b/launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/default.tf new file mode 100644 index 00000000..f3fa7115 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/default.tf @@ -0,0 +1,27 @@ +provider "aws" { + region = "us-east-1" + profile = "yourprofile" +} + +resource "aws_instance" "hermetic-nixos-system" { + count = 1 + ami = "ami-068a62d478710462d" # NixOS 20.09 AMI + + instance_type = "t2.micro" + + key_name = "yourkeyname" + + tags = { + Name = "hermetic-nixos-system-example" + Description = "An example of a hermetic NixOS system deployed by Terraform" + } +} + +module "deploy_nixos" { + source = "github.com/awakesecurity/terraform-nixos//deploy_nixos?ref=c4b1ee6d24b54e92fa3439a12bce349a6805bcdd" + nixos_config = "${path.module}/configuration.nix" + hermetic = true + target_user = "root" + target_host = aws_instance.hermetic-nixos-system[0].public_ip + ssh_private_key_file = pathexpand("~/.ssh/yourkeyname.pem") +} diff --git a/launch/.terraform/modules/pixelfed.deploy/fmt b/launch/.terraform/modules/pixelfed.deploy/fmt new file mode 100755 index 00000000..fd5c9125 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/fmt @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# +set -euo pipefail + +cd "$(dirname "$0")" + +terraform fmt + +fmt_docs() { + ./scripts/terraform-docs-updater "$1" +} + +fmt_docs deploy_nixos +fmt_docs google_image_nixos +fmt_docs google_image_nixos_custom + +echo "." diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/README.md b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/README.md new file mode 100644 index 00000000..593652b8 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/README.md @@ -0,0 +1,76 @@ +# `google_image_nixos` + +This terraform module creates a new image in the Google Cloud project using a +public tarballs of a NixOS release. Those tarballs are released by the NixOS +project. + +Since image names are unique, only one instance per version of the module is +supported per Google Cloud project. + +## Example + +```hcl +module "nixos_image_1809" { + source = "github.com/tweag/terraform-nixos/google_image_nixos" + nixos_version = "18.09" +} + +resource "google_compute_instance" "example" { + name = "example" + machine_type = "n1-standard-1" + zone = "us-central1-a" + + boot_disk { + initialize_params { + image = module.nixos_image_1809.self_link + } + } + + network_interface { + network = "default" + } +} +``` + +### Default configuration.nix + +A new configuration.nix can be passed trough the userdata. Here is the default +configuration to expand upon: + +```nix +{ modulesPath, ... }: +{ + imports = [ + "${toString modulesPath}/virtualisation/google-compute-image.nix" + ]; +} +``` + +## New NixOS releases + +Run the `./update-url-map` script to fetch new image releases. Please submit a +PR as well! + + +## Providers + +| Name | Version | +|------|---------| +| google | n/a | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:-----:| +| gcp\_project\_id | The ID of the project in which the resource belongs. If it is not provided, the provider project is used. | `string` | `""` | no | +| licenses | A list of license URIs to apply to this image. Changing this forces a new resource to be created. | `list(string)` |
[
"https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
]
| no | +| nixos\_version | The NixOS version to use. Eg: 18.09 | `string` | `"latest"` | no | +| url\_map | A map of release series to actual releases | `map(string)` |
{
"14.12": "https://nixos-cloud-images.storage.googleapis.com/nixos-14.12.471.1f09b77-x86_64-linux.raw.tar.gz",
"15.09": "https://nixos-cloud-images.storage.googleapis.com/nixos-15.09.425.7870f20-x86_64-linux.raw.tar.gz",
"16.03": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-16.03.847.8688c17-x86_64-linux.raw.tar.gz",
"17.03": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-17.03.1082.4aab5c5798-x86_64-linux.raw.tar.gz",
"18.03": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.03.132536.fdb5ba4cdf9-x86_64-linux.raw.tar.gz",
"18.09": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.09.1228.a4c4cbb613c-x86_64-linux.raw.tar.gz",
"20.03": "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz",
"latest": "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz"
}
| no | + +## Outputs + +| Name | Description | +|------|-------------| +| self\_link | Link to the NixOS Compute Image | + + diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/main.tf b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/main.tf new file mode 100644 index 00000000..b42e28dd --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/main.tf @@ -0,0 +1,64 @@ +variable "nixos_version" { + type = string + default = "latest" + description = "The NixOS version to use. Eg: 18.09" +} + +variable "gcp_project_id" { + type = string + default = "" + description = "The ID of the project in which the resource belongs. If it is not provided, the provider project is used." +} + +variable "labels" { + type = map(string) + default = {} + description = "A map of labels applied to this image." +} + +variable "licenses" { + type = list(string) + + default = [ + "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx", + ] + + description = "A list of license URIs to apply to this image. Changing this forces a new resource to be created." +} + +# --- + +locals { + image_url = var.url_map[var.nixos_version] + + # Example: nixos-image-18-09-1228-a4c4cbb613c-x86-64-linux + # + # Remove a few things so that it matches the required regexp for image names + # (?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?) + image_name = replace( + replace(basename(local.image_url), ".raw.tar.gz", ""), + "/[._]+/", + "-", + ) +} + +resource "google_compute_image" "nixos" { + name = local.image_name + description = "NixOS ${var.nixos_version}" + family = "nixos" + project = var.gcp_project_id + labels = var.labels + licenses = var.licenses + + raw_disk { + source = local.image_url + } +} + +# --- + +output "self_link" { + description = "Link to the NixOS Compute Image" + value = google_compute_image.nixos.self_link +} + diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/update-url-map b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/update-url-map new file mode 100755 index 00000000..4b9722ff --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/update-url-map @@ -0,0 +1,47 @@ +#!/usr/bin/env nix-shell +#!nix-shell -p ruby -i ruby +# vim: ft=ruby +# +# Run this script to update the list of GCE images +# +require "json" +require "uri" + +ENV['NIX_PATH'] = "nixpkgs=channel:nixpkgs-unstable" + +def render_tf + url_map=JSON.load(`nix-instantiate --json --strict --eval ./url_map.nix`) + + out = <<~HEADER + # DON'T EDIT, run $0 instead + variable "url_map" { + type = map(string) + + default = { + HEADER + + url_map.each_pair do |version, gs_url| + u = URI.parse(gs_url) + # convert the gs:// URL to HTTPS URL for Terraform to consume + # + # Eg: "gs://nixos-cloud-images/nixos-image-18.09-x86_64-linux.raw.tar.gz" + https_url = "https://#{u.host}.storage.googleapis.com#{u.path}" + + out += " %- 8s = %s\n" % [ version.inspect, https_url.inspect] + end + + out += <<~FOOTER + } + + description = "A map of release series to actual releases" + } + FOOTER +end + +url_map_tf = render_tf + +open("url_map.tf", "w") do |f| + f.write(url_map_tf) +end + +puts url_map_tf diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.nix b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.nix new file mode 100644 index 00000000..7b341ced --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.nix @@ -0,0 +1,2 @@ +# Indirect link to where the image map is stored +import diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.tf b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.tf new file mode 100644 index 00000000..aa898a67 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.tf @@ -0,0 +1,17 @@ +# DON'T EDIT, run $0 instead +variable "url_map" { + type = map(string) + + default = { + "14.12" = "https://nixos-cloud-images.storage.googleapis.com/nixos-14.12.471.1f09b77-x86_64-linux.raw.tar.gz" + "15.09" = "https://nixos-cloud-images.storage.googleapis.com/nixos-15.09.425.7870f20-x86_64-linux.raw.tar.gz" + "16.03" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-16.03.847.8688c17-x86_64-linux.raw.tar.gz" + "17.03" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-17.03.1082.4aab5c5798-x86_64-linux.raw.tar.gz" + "18.03" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.03.132536.fdb5ba4cdf9-x86_64-linux.raw.tar.gz" + "18.09" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.09.1228.a4c4cbb613c-x86_64-linux.raw.tar.gz" + "20.03" = "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz" + "latest" = "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz" + } + + description = "A map of release series to actual releases" +} diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/versions.tf b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/versions.tf new file mode 100644 index 00000000..ac97c6ac --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/versions.tf @@ -0,0 +1,4 @@ + +terraform { + required_version = ">= 0.12" +} diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/README.md b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/README.md new file mode 100644 index 00000000..ef2fafda --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/README.md @@ -0,0 +1,54 @@ +# google_cloud_image_nixos + +This terraform module builds and publishes custom NixOS Google Cloud images. + +## Runtime dependencies + +Because this module uses the "external" provider it needs the following +executables to be in the path to work properly: + +* bash +* nix +* `readlink -f` (busybox or coreutils) + +## Known limitations + +NixOS images are built at Terraform plan time. This can make the plan quite +slow. + +Building the image doesn't yield any output, unless the build is interrupted or +failed. + +When a new image is published, the old-one gets removed. This potentially +introduces a race-condition where other targets are trying to create new +instances with the old image. To reduce the race window, `create_before_destroy` is being used. See +https://github.com/hashicorp/terraform/issues/15485 for related discussions. + +Only x86_64-linux is currently supported. + + +## Providers + +| Name | Version | +|------|---------| +| external | n/a | +| google | n/a | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:-----:| +| NIX\_PATH | Allow to pass custom NIX\_PATH. Ignored if `-` or empty. | `string` | `"-"` | no | +| bucket\_name | Bucket where to store the image | `any` | n/a | yes | +| gcp\_project\_id | The ID of the project in which the resource belongs. If it is not provided, the provider project is used. | `string` | `""` | no | +| licenses | A list of license URIs to apply to this image. Changing this forces a new resource to be created. | `list(string)` |
[
"https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
]
| no | +| nixos\_config | Path to a nixos configuration.nix file | `any` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| NIX\_PATH | n/a | +| self\_link | n/a | + + diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/main.tf b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/main.tf new file mode 100644 index 00000000..9ceaed5d --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/main.tf @@ -0,0 +1,94 @@ +variable "bucket_name" { + description = "Bucket where to store the image" +} + +variable "nixos_config" { + description = "Path to a nixos configuration.nix file" +} + +variable "NIX_PATH" { + type = string + description = "Allow to pass custom NIX_PATH. Ignored if `-` or empty." + default = "-" +} + +variable "gcp_project_id" { + type = string + default = "" + description = "The ID of the project in which the resource belongs. If it is not provided, the provider project is used." +} + +variable "licenses" { + type = list(string) + + default = [ + "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx", + ] + + description = "A list of license URIs to apply to this image. Changing this forces a new resource to be created." +} + +# ---------------------------------------------------- + +data "external" "nix_build" { + program = ["${path.module}/nixos-build.sh", var.NIX_PATH, var.nixos_config] +} + +locals { + out_path = data.external.nix_build.result.out_path + image_path = data.external.nix_build.result.image_path + + # 3x2d4rdm9kjzk9d9sz87rmhzvcphs23v + out_hash = element(split("-", basename(local.out_path)), 0) + + # Example: 3x2d4rdm9kjzk9d9sz87rmhzvcphs23v-19-03pre-git-x86-64-linux + # + # Remove a few things so that it matches the required regexp for image names + # (?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?) + image_name = "x${substr(local.out_hash, 0, 12)}-${replace( + replace( + basename(local.image_path), + "/\\.raw\\.tar\\.gz|nixos-image-/", + "", + ), + "/[._]+/", + "-", + )}" + + # 3x2d4rdm9kjzk9d9sz87rmhzvcphs23v-nixos-image-19.03pre-git-x86_64-linux.raw.tar.gz + image_filename = "${local.out_hash}-${basename(local.image_path)}" +} + +resource "google_storage_bucket_object" "nixos" { + name = "images/${local.image_filename}" + source = local.image_path + bucket = var.bucket_name + content_type = "application/tar+gzip" + + lifecycle { + create_before_destroy = true + } +} + +resource "google_compute_image" "nixos" { + name = local.image_name + family = "nixos" + project = var.gcp_project_id + licenses = var.licenses + + raw_disk { + source = "https://${var.bucket_name}.storage.googleapis.com/${google_storage_bucket_object.nixos.name}" + } + + lifecycle { + create_before_destroy = true + } +} + +output "self_link" { + value = google_compute_image.nixos.self_link +} + +output "NIX_PATH" { + value = var.NIX_PATH +} diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/nixos-build.sh b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/nixos-build.sh new file mode 100755 index 00000000..270d6ca0 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/nixos-build.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# Special version of nix-build that integrates with the Terraform external +# provider +set -euo pipefail + +nix_path="${1}" +nixos_config=$(readlink -f "${2:-./configuration.nix}") + +shift +shift + +if [[ -n "$nix_path" && "$nix_path" != "-" ]]; then + export NIX_PATH=$nix_path +fi + +args=( + --arg configuration "$nixos_config" + --argstr system x86_64-linux + --no-out-link + -A config.system.build.googleComputeImage +) + +out_path=$(nix-build '' "${args[@]}" "$@") + +image_path= +for path in "$out_path"/*.tar.gz; do + image_path=$path +done + +cat </dev/null ; then + if [[ -f "$doc.bak" ]]; then + echo "$doc.bak file detected, aborting" >&2 + exit 1 + fi + + mv "$doc" "$doc.bak" + { + sed "/$BANNER_START/q" "$doc.bak" + terraform-docs md . + sed -n -e "/$BANNER_END/,\$p" "$doc.bak" + } > "$doc" + + rm "$doc.bak" +else + { + echo "$BANNER_START" + terraform-docs md . + echo "$BANNER_END" + } >> "$doc" +fi diff --git a/launch/.terraform/modules/pixelfed.deploy/shell.nix b/launch/.terraform/modules/pixelfed.deploy/shell.nix new file mode 100644 index 00000000..1d044982 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/shell.nix @@ -0,0 +1,21 @@ +with import {}; +let + tf = terraform.withPlugins(p: with p; [ + external + google + p.null + random + ]); + # https://github.com/NixOS/nixpkgs/pull/51579 + terraform-docs = callPackage ./nix/terraform-docs {}; +in +mkShell { + buildInputs = [ + tf + terraform-docs + ]; + + shellHook = '' + NIX_PATH=nixpkgs=channel:nixos-18.09 + ''; +} diff --git a/launch/.terraform/plugin_path b/launch/.terraform/plugin_path new file mode 100644 index 00000000..0a21d939 --- /dev/null +++ b/launch/.terraform/plugin_path @@ -0,0 +1,3 @@ +[ + "/nix/store/mnqkwjg5v6sx86an34b4cn075h0lapz3-opentofu-1.8.7/libexec/terraform-providers" +] \ No newline at end of file diff --git a/launch/.terraform/providers/registry.opentofu.org/hashicorp/external/2.3.4/linux_amd64 b/launch/.terraform/providers/registry.opentofu.org/hashicorp/external/2.3.4/linux_amd64 new file mode 120000 index 00000000..e74641a1 --- /dev/null +++ b/launch/.terraform/providers/registry.opentofu.org/hashicorp/external/2.3.4/linux_amd64 @@ -0,0 +1 @@ +/nix/store/mnqkwjg5v6sx86an34b4cn075h0lapz3-opentofu-1.8.7/libexec/terraform-providers/registry.opentofu.org/hashicorp/external/2.3.4/linux_amd64 \ No newline at end of file diff --git a/launch/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.3/linux_amd64 b/launch/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.3/linux_amd64 new file mode 120000 index 00000000..18952a18 --- /dev/null +++ b/launch/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.3/linux_amd64 @@ -0,0 +1 @@ +/nix/store/mnqkwjg5v6sx86an34b4cn075h0lapz3-opentofu-1.8.7/libexec/terraform-providers/registry.opentofu.org/hashicorp/null/3.2.3/linux_amd64 \ No newline at end of file diff --git a/launch/module.auto.tfvars.json b/launch/module.auto.tfvars.json new file mode 100644 index 00000000..50830494 --- /dev/null +++ b/launch/module.auto.tfvars.json @@ -0,0 +1 @@ +{"terraform-nixos": "/nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source"} diff --git a/launch/terraform.tfstate b/launch/terraform.tfstate new file mode 100644 index 00000000..6786b6b2 --- /dev/null +++ b/launch/terraform.tfstate @@ -0,0 +1 @@ +{"version":4,"terraform_version":"1.9.0","serial":68,"lineage":"acbbbabc-b0fa-9ac4-7e96-aaa2cfc9b223","outputs":{},"resources":[{"module":"module.mastodon[0]","mode":"data","type":"external","name":"pins","provider":"provider[\"registry.opentofu.org/hashicorp/external\"]","instances":[{"schema_version":0,"attributes":{"id":"-","program":["nix","eval","--json","-f","./../npins/default.nix"],"query":null,"result":{"agenix":"/nix/store/glsqq1xn5al7d528hvlbm4hl3ladxmka-source","disko":"/nix/store/7wf9q0mb1i43x9dr1qlyfaraq15n6sii-source","flake-inputs":"/nix/store/fqln0bcp6mp75k4sl0cav2f0np60lwhj-source","htmx":"/nix/store/mwqqk0qmldzvv4xj9kq2lbah2flhc44z-source","nix-unit":"/nix/store/yc260i6cp4q4mivlhrrypis34yp138sw-source","nixpkgs":"/nix/store/g9chc50nd98bm0pxhyhyyhg8ldj2fzzp-source","terraform-nixos":"/nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source"},"working_dir":null},"sensitive_attributes":[]}]},{"module":"module.mastodon[0].module.deploy","mode":"data","type":"external","name":"nixos-instantiate","provider":"provider[\"registry.opentofu.org/hashicorp/external\"]","instances":[{"schema_version":0,"attributes":{"id":"-","program":[".terraform/modules/mastodon.deploy/deploy_nixos/nixos-instantiate.sh","nixpkgs=/nix/store/g9chc50nd98bm0pxhyhyyhg8ldj2fzzp-source:sources=./../npins","import /nix/store/g9chc50nd98bm0pxhyhyyhg8ldj2fzzp-source/nixos/lib/eval-config.nix {\n system = \"x86_64-linux\";\n specialArgs = {\n sources = import ./../npins;\n terraform = builtins.fromJSON ''{\"domain\":\"fediversity.net\",\"hostname\":\"test06\",\"initialUser\":{\"displayName\":\"Testy McTestface\",\"email\":\"test@test.com\",\"password\":\"testtest\",\"username\":\"test\"}}'';\n };\n modules = [\n ./mastodon.nix\n ./shared.nix\n ];\n}\n",".","false","--argstr","system","x86_64-linux","--arg","hermetic","true"],"query":null,"result":{"currentSystem":"x86_64-linux","drv_path":"/nix/store/q7xraxg5jnavc79dww1qn21ik7caxb48-nixos-system-test06-25.05pre777917.b7ba7f9f45c5.drv","out_path":"/nix/store/g00cvr7h06p0m7z53v7gx3zf5fyr10bc-nixos-system-test06-25.05pre777917.b7ba7f9f45c5","substituters":"https://cache.nixos.org/","trusted-public-keys":"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="},"working_dir":null},"sensitive_attributes":[]}]},{"module":"module.mastodon[0].module.deploy","mode":"managed","type":"null_resource","name":"deploy_nixos","provider":"provider[\"registry.opentofu.org/hashicorp/null\"]","instances":[{"status":"tainted","schema_version":0,"attributes":{"id":"4793704995569904675","triggers":{"deploy_nixos_drv":"/nix/store/q7xraxg5jnavc79dww1qn21ik7caxb48-nixos-system-test06-25.05pre777917.b7ba7f9f45c5.drv","deploy_nixos_keys":"44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"}},"sensitive_attributes":[],"dependencies":["module.mastodon.data.external.pins","module.mastodon.module.deploy.data.external.nixos-instantiate"]}]}],"check_results":null} diff --git a/launch/terraform.tfstate.backup b/launch/terraform.tfstate.backup new file mode 100644 index 00000000..31f0d72c --- /dev/null +++ b/launch/terraform.tfstate.backup @@ -0,0 +1 @@ +{"version":4,"terraform_version":"1.9.0","serial":67,"lineage":"acbbbabc-b0fa-9ac4-7e96-aaa2cfc9b223","outputs":{},"resources":[{"module":"module.mastodon[0]","mode":"data","type":"external","name":"pins","provider":"provider[\"registry.opentofu.org/hashicorp/external\"]","instances":[{"schema_version":0,"attributes":{"id":"-","program":["nix","eval","--json","-f","./../npins/default.nix"],"query":null,"result":{"agenix":"/nix/store/glsqq1xn5al7d528hvlbm4hl3ladxmka-source","disko":"/nix/store/7wf9q0mb1i43x9dr1qlyfaraq15n6sii-source","flake-inputs":"/nix/store/fqln0bcp6mp75k4sl0cav2f0np60lwhj-source","htmx":"/nix/store/mwqqk0qmldzvv4xj9kq2lbah2flhc44z-source","nix-unit":"/nix/store/yc260i6cp4q4mivlhrrypis34yp138sw-source","nixpkgs":"/nix/store/g9chc50nd98bm0pxhyhyyhg8ldj2fzzp-source","terraform-nixos":"/nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source"},"working_dir":null},"sensitive_attributes":[]}]},{"module":"module.mastodon[0].module.deploy","mode":"data","type":"external","name":"nixos-instantiate","provider":"provider[\"registry.opentofu.org/hashicorp/external\"]","instances":[{"schema_version":0,"attributes":{"id":"-","program":[".terraform/modules/mastodon.deploy/deploy_nixos/nixos-instantiate.sh","nixpkgs=/nix/store/g9chc50nd98bm0pxhyhyyhg8ldj2fzzp-source:sources=./../npins","import /nix/store/g9chc50nd98bm0pxhyhyyhg8ldj2fzzp-source/nixos/lib/eval-config.nix {\n system = \"x86_64-linux\";\n specialArgs = {\n sources = import ./../npins;\n terraform = builtins.fromJSON ''{\"domain\":\"fediversity.net\",\"hostname\":\"test06\",\"initialUser\":{\"displayName\":\"Testy McTestface\",\"email\":\"test@test.com\",\"password\":\"testtest\",\"username\":\"test\"}}'';\n };\n modules = [\n ./mastodon.nix\n ./shared.nix\n ];\n}\n",".","false","--argstr","system","x86_64-linux","--arg","hermetic","true"],"query":null,"result":{"currentSystem":"x86_64-linux","drv_path":"/nix/store/q7xraxg5jnavc79dww1qn21ik7caxb48-nixos-system-test06-25.05pre777917.b7ba7f9f45c5.drv","out_path":"/nix/store/g00cvr7h06p0m7z53v7gx3zf5fyr10bc-nixos-system-test06-25.05pre777917.b7ba7f9f45c5","substituters":"https://cache.nixos.org/","trusted-public-keys":"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="},"working_dir":null},"sensitive_attributes":[]}]},{"module":"module.mastodon[0].module.deploy","mode":"managed","type":"null_resource","name":"deploy_nixos","provider":"provider[\"registry.opentofu.org/hashicorp/null\"]","instances":[{"status":"tainted","schema_version":0,"attributes":{"id":"1197266561618904114","triggers":{"deploy_nixos_drv":"/nix/store/q7xraxg5jnavc79dww1qn21ik7caxb48-nixos-system-test06-25.05pre777917.b7ba7f9f45c5.drv","deploy_nixos_keys":"44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"}},"sensitive_attributes":[],"dependencies":["module.mastodon.data.external.pins","module.mastodon.module.deploy.data.external.nixos-instantiate"]}]}],"check_results":null} -- 2.48.1 From 3eb6d9321606304540cb1c9a3190bfe5b7669340 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Mon, 24 Mar 2025 10:41:07 +0100 Subject: [PATCH 04/57] tf --- infra/machines/fedi201/fedipanel.nix | 18 +++ launch/.envrc | 10 ++ launch/.gitignore | 3 + launch/.terraform.lock.hcl | 16 +++ launch/.terraform/modules/deploy | 1 + launch/.terraform/modules/garage.deploy | 1 + launch/README.md | 9 ++ launch/default.nix | 22 ++++ launch/flake.lock | 158 ++++++++++++++++++++++++ launch/flake.nix | 125 +++++++++++++++++++ launch/main.tf | 84 +++++++++++++ launch/pass-ssh-key.sh | 15 +++ launch/resource.nix | 41 ++++++ launch/shell.nix | 1 + launch/tf.nix | 25 ++++ launch/vm/main.tf | 46 +++++++ npins/sources.json | 12 ++ panel/env.nix | 11 +- panel/nix/package.nix | 6 +- panel/src/panel/settings.py | 69 ++++++++++- panel/src/panel/views.py | 42 ++++--- 21 files changed, 692 insertions(+), 23 deletions(-) create mode 100644 launch/.envrc create mode 100644 launch/.gitignore create mode 100644 launch/.terraform.lock.hcl create mode 160000 launch/.terraform/modules/deploy create mode 160000 launch/.terraform/modules/garage.deploy create mode 100644 launch/README.md create mode 100644 launch/default.nix create mode 100644 launch/flake.lock create mode 100644 launch/flake.nix create mode 100644 launch/main.tf create mode 100755 launch/pass-ssh-key.sh create mode 100644 launch/resource.nix create mode 100644 launch/shell.nix create mode 100644 launch/tf.nix create mode 100644 launch/vm/main.tf diff --git a/infra/machines/fedi201/fedipanel.nix b/infra/machines/fedi201/fedipanel.nix index 5c4236fc..b49471bb 100644 --- a/infra/machines/fedi201/fedipanel.nix +++ b/infra/machines/fedi201/fedipanel.nix @@ -37,6 +37,24 @@ in enable = true; production = true; domain = "demo.fediversity.eu"; + # FIXME: make it work without this duplication + settings = + let + cfg = config.services.${name}; + in + { + STATIC_ROOT = "/var/lib/${name}/static"; + DEBUG = false; + ALLOWED_HOSTS = [ + cfg.domain + cfg.host + "localhost" + "[::1]" + ]; + CSRF_TRUSTED_ORIGINS = [ "https://${cfg.domain}" ]; + COMPRESS_OFFLINE = true; + LIBSASS_OUTPUT_STYLE = "compressed"; + }; secrets = { SECRET_KEY = config.age.secrets.panel-secret-key.path; }; diff --git a/launch/.envrc b/launch/.envrc new file mode 100644 index 00000000..26ef376b --- /dev/null +++ b/launch/.envrc @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# the shebang is ignored, but nice for editors + +# shellcheck shell=bash +if type -P lorri &>/dev/null; then + eval "$(lorri direnv --flake .)" +else + echo 'while direnv evaluated .envrc, could not find the command "lorri" [https://github.com/nix-community/lorri]' + use flake +fi diff --git a/launch/.gitignore b/launch/.gitignore new file mode 100644 index 00000000..0f8ba9b3 --- /dev/null +++ b/launch/.gitignore @@ -0,0 +1,3 @@ +.terraform/ +.terraform.tfstate.lock.info +terraform.tfstate* diff --git a/launch/.terraform.lock.hcl b/launch/.terraform.lock.hcl new file mode 100644 index 00000000..f90c28b6 --- /dev/null +++ b/launch/.terraform.lock.hcl @@ -0,0 +1,16 @@ +# This file is maintained automatically by "tofu init". +# Manual edits may be lost in future updates. + +provider "registry.opentofu.org/hashicorp/external" { + version = "2.3.4" + hashes = [ + "h1:F45RHS5NlHBWkfcW61rwkA7Z2P+p3Rxvq75XMhNeFHE=", + ] +} + +provider "registry.opentofu.org/hashicorp/null" { + version = "3.2.3" + hashes = [ + "h1:P9gA/YsRU4Q+STK6EkCOjTHYUop/+1LfIbX7QMNHfPk=", + ] +} diff --git a/launch/.terraform/modules/deploy b/launch/.terraform/modules/deploy new file mode 160000 index 00000000..657cc08c --- /dev/null +++ b/launch/.terraform/modules/deploy @@ -0,0 +1 @@ +Subproject commit 657cc08c2a22cf6500de70df5519ccb194449f0f diff --git a/launch/.terraform/modules/garage.deploy b/launch/.terraform/modules/garage.deploy new file mode 160000 index 00000000..657cc08c --- /dev/null +++ b/launch/.terraform/modules/garage.deploy @@ -0,0 +1 @@ +Subproject commit 657cc08c2a22cf6500de70df5519ccb194449f0f diff --git a/launch/README.md b/launch/README.md new file mode 100644 index 00000000..a30dbbfa --- /dev/null +++ b/launch/README.md @@ -0,0 +1,9 @@ +# service deployment + +## usage + +### updating TF modules + +```sh +echo "{\"nixos-anywhere\": $(nix-instantiate --eval --json -E '(import ../npins).nixos-anywhere.outPath')}" > .auto.tfvars.json +``` diff --git a/launch/default.nix b/launch/default.nix new file mode 100644 index 00000000..9a533dd8 --- /dev/null +++ b/launch/default.nix @@ -0,0 +1,22 @@ +{ + system ? builtins.currentSystem, + sources ? import ../npins, + pkgs ? import sources.nixpkgs { + inherit system; + }, +}@args: +let + inherit (pkgs) lib; +in +{ + shell = pkgs.mkShellNoCC { + packages = [ + pkgs.npins + pkgs.jq # implicit dep of nixos-anywhere TF: https://github.com/nix-community/nixos-anywhere/issues/416 + (import ./tf.nix { inherit lib pkgs; }) + ]; + }; +} +# re-export inputs so they can be overridden granularly +# (they can't be accessed from the outside any other way) +// args diff --git a/launch/flake.lock b/launch/flake.lock new file mode 100644 index 00000000..124c30b2 --- /dev/null +++ b/launch/flake.lock @@ -0,0 +1,158 @@ +{ + "nodes": { + "agenix": { + "inputs": { + "darwin": "darwin", + "home-manager": "home-manager", + "nixpkgs": "nixpkgs", + "systems": "systems" + }, + "locked": { + "lastModified": 1736955230, + "narHash": "sha256-uenf8fv2eG5bKM8C/UvFaiJMZ4IpUFaQxk9OH5t/1gA=", + "owner": "ryantm", + "repo": "agenix", + "rev": "e600439ec4c273cf11e06fe4d9d906fb98fa097c", + "type": "github" + }, + "original": { + "owner": "ryantm", + "repo": "agenix", + "type": "github" + } + }, + "darwin": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1700795494, + "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, + "disko": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1741786315, + "narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=", + "owner": "nix-community", + "repo": "disko", + "rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1703113217, + "narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1703013332, + "narHash": "sha256-+tFNwMvlXLbJZXiMHqYq77z/RfmpfpiI3yjL6o/Zo9M=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "54aac082a4d9bb5bbc5c4e899603abfb76a3f6d6", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1741402956, + "narHash": "sha256-y2hByvBM03s9T2fpeLjW6iprbxnhV9mJMmSwCHc41ZQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ed0b1881565c1ffef490c10d663d4f542031dad3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1742753982, + "narHash": "sha256-WYryX6lCrmh4AaEoBHA1zwTTs6vPtevT3/ywGyzz4SI=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "ec9c54e7a9feec999aa34a15781080bed5082306", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "agenix": "agenix", + "disko": "disko", + "nixpkgs": "nixpkgs_3" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/launch/flake.nix b/launch/flake.nix new file mode 100644 index 00000000..9d126b9e --- /dev/null +++ b/launch/flake.nix @@ -0,0 +1,125 @@ +{ + inputs = { + agenix.url = "github:ryantm/agenix"; + disko.url = "github:nix-community/disko"; + nixpkgs.url = "github:nixos/nixpkgs/release-24.11"; + }; + outputs = + inputs@{ nixpkgs, ... }: + let + system = "x86_64-linux"; + inherit (nixpkgs) lib; + in + { + nixosConfigurations = + let + ## NOTE: All of these secrets are publicly available in this source file + ## and will end up in the Nix store. We don't care as they are only ever + ## used for testing anyway. + ## + ## FIXME: Generate and store in NixOps4's state. + mastodonS3KeyConfig = + { pkgs, ... }: + { + s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GK3515373e4c851ebaad366558"; + s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7d37d093435a41f2aab8f13c19ba067d9776c90215f56614adad6ece597dbb34"; + }; + peertubeS3KeyConfig = + { pkgs, ... }: + { + s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GK1f9feea9960f6f95ff404c9b"; + s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7295c4201966a02c2c3d25b5cea4a5ff782966a2415e3a196f91924631191395"; + }; + pixelfedS3KeyConfig = + { pkgs, ... }: + { + s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GKb5615457d44214411e673b7b"; + s3SecretKeyFile = pkgs.writeText "s3SecretKey" "5be6799a88ca9b9d813d1a806b64f15efa49482dbe15339ddfaf7f19cf434987"; + }; + in + lib.mapAttrs + ( + _: module: + lib.nixosSystem { + inherit system; + specialArgs = { inherit system inputs; }; + modules = [ + inputs.disko.nixosModules.default + inputs.agenix.nixosModules.default + ../services/fediversity + ./resource.nix + module + { + nixpkgs = { inherit system; }; + } + ( + { pkgs, terraform, ... }: + let + inherit (terraform) hostname; + in + { + imports = [ + # FIXME: get VM details from TF + ../infra/test-machines/${hostname} + ]; + fediversityVm.name = hostname; + fediversity = { + inherit (terraform) domain; + temp.initialUser = { + inherit (terraform.initialUser) username email displayName; + # FIXME: disgusting, but nvm, this is going to be replaced by + # proper central authentication at some point + passwordFile = pkgs.writeText "password" terraform.initialUser.password; + }; + }; + } + ) + ]; + } + ) + { + garage = + { pkgs, ... }: + { + fediversity = { + garage.enable = true; + pixelfed = pixelfedS3KeyConfig { inherit pkgs; }; + mastodon = mastodonS3KeyConfig { inherit pkgs; }; + peertube = peertubeS3KeyConfig { inherit pkgs; }; + }; + }; + mastodon = + { pkgs, ... }: + { + fediversity = { + mastodon = mastodonS3KeyConfig { inherit pkgs; } // { + enable = true; + }; + temp.cores = 1; # FIXME: should come from NixOps4 eventually + }; + }; + peertube = + { pkgs, ... }: + { + fediversity = { + peertube = peertubeS3KeyConfig { inherit pkgs; } // { + enable = true; + ## NOTE: Only ever used for testing anyway. + ## + ## FIXME: Generate and store in NixOps4's state. + secretsFile = pkgs.writeText "secret" "574e093907d1157ac0f8e760a6deb1035402003af5763135bae9cbd6abe32b24"; + }; + }; + }; + pixelfed = + { pkgs, ... }: + { + fediversity = { + pixelfed = pixelfedS3KeyConfig { inherit pkgs; } // { + enable = true; + }; + }; + }; + }; + }; +} diff --git a/launch/main.tf b/launch/main.tf new file mode 100644 index 00000000..2e4aabcc --- /dev/null +++ b/launch/main.tf @@ -0,0 +1,84 @@ +variable "domain" { + type = string + default = "fediversity.net" +} + +variable "mastodon" { + type = object({ + enable = bool + }) + default = { + enable = false + } +} + +variable "pixelfed" { + type = object({ + enable = bool + }) + default = { + enable = false + } +} + +variable "peertube" { + type = object({ + enable = bool + }) + default = { + enable = false + } +} + +variable "initialUser" { + type = object({ + displayName = string + username = string + email = string + # TODO: mark (nested) credentials as sensitive + # https://discuss.hashicorp.com/t/is-it-possible-to-mark-an-attribute-of-an-object-as-sensitive/24649/2 + password = string + }) + default = { + displayName = "Testy McTestface" + username = "test" + email = "test@test.com" + password = "testtest" + } +} + +# module "garage" { +# source = "./vm" +# count = var.mastodon.enable || var.pixelfed.enable || var.peertube.enable ? 1 : 0 +# domain = var.domain +# hostname = "test01" +# config = "garage" +# initialUser = var.initialUser +# } + +module "mastodon" { + source = "./vm" + count = var.mastodon.enable ? 1 : 0 + domain = var.domain + hostname = "test02" + config = "mastodon" + initialUser = var.initialUser +} + +module "pixelfed" { + source = "./vm" + count = var.pixelfed.enable ? 1 : 0 + domain = var.domain + hostname = "test04" + config = "pixelfed" + initialUser = var.initialUser +} + +module "peertube" { + source = "./vm" + count = var.peertube.enable ? 1 : 0 + domain = var.domain + hostname = "test03" + config = "peertube" + initialUser = var.initialUser +} diff --git a/launch/pass-ssh-key.sh b/launch/pass-ssh-key.sh new file mode 100755 index 00000000..80f17dec --- /dev/null +++ b/launch/pass-ssh-key.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +export host="$host" + +mkdir -p etc/ssh + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +for keyname in ssh_host_ed25519_key ssh_host_ed25519_key.pub; do + if [[ $keyname == *.pub ]]; then + umask 0133 + else + umask 0177 + fi + cp "$SCRIPT_DIR/../infra/test-machines/${host}/${keyname}" ./etc/ssh/${keyname} +done diff --git a/launch/resource.nix b/launch/resource.nix new file mode 100644 index 00000000..04811271 --- /dev/null +++ b/launch/resource.nix @@ -0,0 +1,41 @@ +{ + lib, + config, + ... +}: + +let + inherit (lib) attrValues elem mkDefault; + inherit (lib.attrsets) concatMapAttrs optionalAttrs; + inherit (lib.strings) removeSuffix; + + secretsPrefix = ../secrets; + secrets = import (secretsPrefix + "/secrets.nix"); + keys = import ../keys; + +in +{ + fediversityVm.hostPublicKey = mkDefault keys.systems.${config.fediversityVm.name}; + + ## The configuration of the machine. We strive to keep in this file only the + ## options that really need to be injected from the resource. Everything else + ## should go into the `./nixos` subdirectory. + imports = [ + ../infra/common/options.nix + ../infra/common/nixos + ]; + + ## Read all the secrets, filter the ones that are supposed to be readable + ## with this host's public key, and add them correctly to the configuration + ## as `age.secrets..file`. + age.secrets = concatMapAttrs ( + name: secret: + optionalAttrs (elem config.fediversityVm.hostPublicKey secret.publicKeys) { + ${removeSuffix ".age" name}.file = secretsPrefix + "/${name}"; + } + ) secrets; + + ## FIXME: Remove direct root authentication once the NixOps4 NixOS provider + ## supports users with password-less sudo. + users.users.root.openssh.authorizedKeys.keys = attrValues keys.contributors; +} diff --git a/launch/shell.nix b/launch/shell.nix new file mode 100644 index 00000000..a6bdf202 --- /dev/null +++ b/launch/shell.nix @@ -0,0 +1 @@ +(import ./. { }).shell diff --git a/launch/tf.nix b/launch/tf.nix new file mode 100644 index 00000000..14ad72a7 --- /dev/null +++ b/launch/tf.nix @@ -0,0 +1,25 @@ +# FIXME: use overlays so this gets imported just once? +{ + lib, + pkgs, + ... +}: +let + tofuProvider = + provider: + provider.override (oldArgs: { + provider-source-address = + lib.replaceStrings [ "https://registry.terraform.io/providers" ] [ "registry.opentofu.org" ] + oldArgs.homepage; + }); + tf = pkgs.opentofu; + tfPlugins = ( + p: [ + p.null + p.external + ] + ); +in +# tf.withPlugins tfPlugins +# https://github.com/NixOS/nixpkgs/pull/358522 +tf.withPlugins (p: pkgs.lib.lists.map tofuProvider (tfPlugins p)) diff --git a/launch/vm/main.tf b/launch/vm/main.tf new file mode 100644 index 00000000..c616d0e0 --- /dev/null +++ b/launch/vm/main.tf @@ -0,0 +1,46 @@ +variable "domain" { + type = string +} + +variable "hostname" { + type = string +} + +variable "config" { + type = string +} + +variable "initialUser" { + type = object({ + displayName = string + username = string + password = string + email = string + }) +} + +module "deploy" { + # source = "github.com/nix-community/nixos-anywhere//terraform/all-in-one" + source = "github.com/KiaraGrouwstra/nixos-anywhere?ref=special-args-nested-flake-fixed//terraform/all-in-one" + nixos_system_attr = ".#nixosConfigurations.${var.config}.config.system.build.toplevel" + nixos_partitioner_attr = ".#nixosConfigurations.${var.config}.config.system.build.diskoScriptNoDeps" + # when instance id changes, it will trigger a reinstall + instance_id = var.hostname + target_user = "kiara" + target_host = "${var.hostname}.abundos.eu" + extra_files_script = "${path.module}/../pass-ssh-key.sh" + extra_environment = { + host = var.hostname + } + special_args = { + terraform = { + domain = var.domain + hostname = var.hostname + initialUser = var.initialUser + } + } + nix_options = { + show-trace = true + } + # build_on_remote = true +} diff --git a/npins/sources.json b/npins/sources.json index 45efd6b4..4701917c 100644 --- a/npins/sources.json +++ b/npins/sources.json @@ -27,6 +27,18 @@ "url": "https://github.com/nix-community/nix-unit/archive/2071bbb765681ac3d8194ec560c8b27ff2a3b541.tar.gz", "hash": "0blz1kcmn9vnr9q3iqp2mv13hv3pdccljmmc54f8j7ybf5v0wgmp" }, + "nixos-anywhere": { + "type": "Git", + "repository": { + "type": "GitHub", + "owner": "KiaraGrouwstra", + "repo": "nixos-anywhere" + }, + "branch": "special-args-nested-flake-fixed", + "revision": "bbf54831f177b4ae52b55758ac725583617c39f9", + "url": "https://github.com/KiaraGrouwstra/nixos-anywhere/archive/bbf54831f177b4ae52b55758ac725583617c39f9.tar.gz", + "hash": "11m8r632yp4s8sy106zk7a1inp44gvwq6hinjf2pczpr6a5hxanx" + }, "nixpkgs": { "type": "Channel", "name": "nixpkgs-unstable", diff --git a/panel/env.nix b/panel/env.nix index 07ce4193..87805588 100644 --- a/panel/env.nix +++ b/panel/env.nix @@ -7,12 +7,15 @@ let inherit (builtins) toString; in { + # locally: use a fixed relative reference, so we can use our newest files without copying to the store REPO_DIR = toString ../.; - # explicitly use nix, as e.g. lix does not have configurable-impure-env BIN_PATH = lib.makeBinPath [ - # explicitly use nix, as e.g. lix does not have configurable-impure-env - pkgs.nix - # nixops error maybe due to our flake git hook: executing 'git': No such file or directory + pkgs.lix + pkgs.bash + pkgs.coreutils + pkgs.openssh pkgs.git + pkgs.jq # implicit dep of nixos-anywhere TF: https://github.com/nix-community/nixos-anywhere/issues/416 + (import ../launch/tf.nix { inherit lib pkgs; }) ]; } diff --git a/panel/nix/package.nix b/panel/nix/package.nix index 9337887c..2f94fa8f 100644 --- a/panel/nix/package.nix +++ b/panel/nix/package.nix @@ -11,7 +11,7 @@ let root = ../src; fileset = intersection (gitTracked ../../.) ../src; }; - pyproject = with lib; fromTOML pyproject-toml; + pyproject = fromTOML pyproject-toml; # TODO: define this globally name = "panel"; # TODO: we may want this in a file so it's easier to read statically @@ -58,7 +58,9 @@ python3.pkgs.buildPythonPackage { mkdir -p $out/bin cp -v ${src}/manage.py $out/bin/manage.py chmod +x $out/bin/manage.py - wrapProgram $out/bin/manage.py --prefix PYTHONPATH : "$PYTHONPATH" + wrapProgram $out/bin/manage.py \ + --set REPO_DIR "${../..}" \ + --prefix PYTHONPATH : "$PYTHONPATH" cp ${sources.htmx}/dist/htmx.min.js* $out/${python3.sitePackages}/panel/static/ ''; } diff --git a/panel/src/panel/settings.py b/panel/src/panel/settings.py index b270612c..01c88963 100644 --- a/panel/src/panel/settings.py +++ b/panel/src/panel/settings.py @@ -10,7 +10,9 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/4.2/ref/settings/ """ +import re import sys +import subprocess import os import importlib.util import dj_database_url @@ -18,6 +20,8 @@ import dj_database_url from os import environ as env from pathlib import Path +STORE_PATTERN = re.compile("^/nix/store/[^/]+$") + # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -171,6 +175,54 @@ COMPRESS_PRECOMPILERS = [ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +LOGGING = { + "version": 1, + "disable_existing_loggers": False, + "filters": { + "require_debug_false": { + "()": "django.utils.log.RequireDebugFalse", + }, + "require_debug_true": { + "()": "django.utils.log.RequireDebugTrue", + }, + }, + "formatters": { + "django.server": { + "()": "django.utils.log.ServerFormatter", + "format": "[{server_time}] {message}", + "style": "{", + } + }, + "handlers": { + "console": { + "level": "INFO", + # "filters": ["require_debug_true"], + "class": "logging.StreamHandler", + }, + "django.server": { + "level": "INFO", + "class": "logging.StreamHandler", + "formatter": "django.server", + }, + "mail_admins": { + "level": "ERROR", + "filters": ["require_debug_false"], + "class": "django.utils.log.AdminEmailHandler", + }, + }, + "loggers": { + "django": { + "handlers": ["console", "mail_admins"], + "level": "INFO", + }, + "django.server": { + "handlers": ["django.server"], + "level": "INFO", + "propagate": False, + }, + }, +} + # Customization via user settings # This must be at the end, as it must be able to override the above # TODO(@fricklerhandwerk): @@ -186,6 +238,21 @@ if user_settings_file is not None: sys.modules["user_settings"] = module from user_settings import * # noqa: F403 # pyright: ignore [reportMissingImports] +def handle_double_hash(orig_path: str) -> str: + """Convert store paths to account for potentially double hashes. + + c.f. https://github.com/NixOS/nix/issues/10627 + """ + # local paths can stay as-is + if not STORE_PATTERN.match(orig_path): + return orig_path + # for /nix/store paths, account for double hashing + orig_name = orig_path.split("/")[-1] + cmd = ["find", "/nix/store/", "-maxdepth", "1", "-name", f"*{orig_name}"] + process = subprocess.run(cmd, capture_output=True) + fixed_name = process.stdout.decode("utf-8").split("\n")[0] + return fixed_name + # non-Django application settings # TODO(@fricklerhandwerk): @@ -196,4 +263,4 @@ if user_settings_file is not None: bin_path=env['BIN_PATH'] # path of the root flake to trigger nixops from, see #94. # to deploy this should be specified, for dev just use a relative path. -repo_dir = env["REPO_DIR"] +repo_dir = handle_double_hash(env["REPO_DIR"]) diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 5c423fc6..b9abf8cc 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -1,5 +1,6 @@ from enum import Enum import json +from os.path import expanduser import subprocess import os @@ -134,25 +135,34 @@ class DeploymentStatus(ConfigurationForm): }, } # serialize back and forth now we still need to manually inject the dummy user - deployment_params = json.dumps(dummy_user | json.loads(submission)) + deployment_params = dummy_user | json.loads(submission) env = { "PATH": settings.bin_path, + # used in nixos-anywhere for ssh-copy-id + "HOME": expanduser("~"), + } | { # pass in form info to our deployment - "DEPLOYMENT": deployment_params, + # FIXME: ensure sensitive info is protected + f"TF_VAR_{k}": v if isinstance(v, str) else json.dumps(v) for k, v in deployment_params.items() } + cwd = f"{settings.repo_dir}/launch" + # FIXME: move init to packaging phase cmd = [ - "nix", - "develop", - "--extra-experimental-features", - "configurable-impure-env", - "--command", - "nixops4", - "apply", - "test", + "tofu", + # f"-chdir={cwd}", + "init", + "-get=false", + "-input=false", + # "-plugin-dir=...", ] - deployment_result = subprocess.run( - cmd, - cwd=settings.repo_dir, - env=env, - ) - return deployment_result, json.loads(deployment_params) + subprocess.run(cmd, cwd=cwd, env=env) + cmd = [ + "tofu", + # f"-chdir={cwd}", + "apply", + f"-state={cwd}/terraform.tfstate", # FIXME: separate users' state + "--auto-approve", + ] + deployment_result = subprocess.run(cmd, cwd=cwd, env=env) + print(deployment_result) + return deployment_result, deployment_params -- 2.48.1 From 231c564c7a8a33a6903b319b5cd6b199e5e57e37 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Mon, 24 Mar 2025 20:28:06 +0100 Subject: [PATCH 05/57] deduplicate flake inputs --- flake.lock | 599 ++--------------------------------------------------- flake.nix | 23 +- 2 files changed, 39 insertions(+), 583 deletions(-) diff --git a/flake.lock b/flake.lock index ad891639..36aa7833 100644 --- a/flake.lock +++ b/flake.lock @@ -4,7 +4,9 @@ "inputs": { "darwin": "darwin", "home-manager": "home-manager", - "nixpkgs": "nixpkgs", + "nixpkgs": [ + "nixpkgs" + ], "systems": "systems" }, "locked": { @@ -38,23 +40,6 @@ "type": "github" } }, - "crane_2": { - "flake": false, - "locked": { - "lastModified": 1727316705, - "narHash": "sha256-/mumx8AQ5xFuCJqxCIOFCHTVlxHkMT21idpbgbm/TIE=", - "owner": "ipetkov", - "repo": "crane", - "rev": "5b03654ce046b5167e7b0bccbd8244cb56c16f0e", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "ref": "v0.19.0", - "repo": "crane", - "type": "github" - } - }, "darwin": { "inputs": { "nixpkgs": [ @@ -79,7 +64,9 @@ }, "disko": { "inputs": { - "nixpkgs": "nixpkgs_2" + "nixpkgs": [ + "nixpkgs" + ] }, "locked": { "lastModified": 1740485968, @@ -119,31 +106,6 @@ "type": "github" } }, - "dream2nix_2": { - "inputs": { - "nixpkgs": [ - "nixops4-nixos", - "nixops4", - "nix-cargo-integration", - "nixpkgs" - ], - "purescript-overlay": "purescript-overlay_2", - "pyproject-nix": "pyproject-nix_2" - }, - "locked": { - "lastModified": 1735160684, - "narHash": "sha256-n5CwhmqKxifuD4Sq4WuRP/h5LO6f23cGnSAuJemnd/4=", - "owner": "nix-community", - "repo": "dream2nix", - "rev": "8ce6284ff58208ed8961681276f82c2f8f978ef4", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "dream2nix", - "type": "github" - } - }, "flake-compat": { "flake": false, "locked": { @@ -208,38 +170,6 @@ "type": "github" } }, - "flake-compat_5": { - "flake": false, - "locked": { - "lastModified": 1733328505, - "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_6": { - "flake": false, - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, "flake-parts": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" @@ -316,47 +246,6 @@ "type": "github" } }, - "flake-parts_5": { - "inputs": { - "nixpkgs-lib": "nixpkgs-lib_4" - }, - "locked": { - "lastModified": 1738453229, - "narHash": "sha256-7H9XgNiGLKN1G1CgRh0vUL4AheZSYzPm+zmZ7vxbJdo=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "32ea77a06711b758da0ad9bd6a844c5740a87abd", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_6": { - "inputs": { - "nixpkgs-lib": [ - "nixops4-nixos", - "nixops4", - "nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1733312601, - "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, "flake-utils": { "inputs": { "systems": "systems_2" @@ -375,29 +264,11 @@ "type": "github" } }, - "flake-utils_2": { - "inputs": { - "systems": "systems_3" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "git-hooks": { "inputs": { "flake-compat": "flake-compat", "gitignore": "gitignore", - "nixpkgs": "nixpkgs_3" + "nixpkgs": "nixpkgs" }, "locked": { "lastModified": 1737465171, @@ -452,7 +323,7 @@ "inputs": { "flake-compat": "flake-compat_4", "gitignore": "gitignore_2", - "nixpkgs": "nixpkgs_5" + "nixpkgs": "nixpkgs_2" }, "locked": { "lastModified": 1737465171, @@ -468,45 +339,6 @@ "type": "github" } }, - "git-hooks-nix_3": { - "inputs": { - "flake-compat": [ - "nixops4-nixos", - "nixops4", - "nix" - ], - "gitignore": [ - "nixops4-nixos", - "nixops4", - "nix" - ], - "nixpkgs": [ - "nixops4-nixos", - "nixops4", - "nix", - "nixpkgs" - ], - "nixpkgs-stable": [ - "nixops4-nixos", - "nixops4", - "nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1734279981, - "narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, "gitignore": { "inputs": { "nixpkgs": [ @@ -587,22 +419,6 @@ "type": "github" } }, - "mk-naked-shell_2": { - "flake": false, - "locked": { - "lastModified": 1681286841, - "narHash": "sha256-3XlJrwlR0nBiREnuogoa5i1b4+w/XPe0z8bbrJASw0g=", - "owner": "yusdacra", - "repo": "mk-naked-shell", - "rev": "7612f828dd6f22b7fb332cc69440e839d7ffe6bd", - "type": "github" - }, - "original": { - "owner": "yusdacra", - "repo": "mk-naked-shell", - "type": "github" - } - }, "nix": { "inputs": { "flake-compat": "flake-compat_2", @@ -658,63 +474,6 @@ "type": "github" } }, - "nix-cargo-integration_2": { - "inputs": { - "crane": "crane_2", - "dream2nix": "dream2nix_2", - "mk-naked-shell": "mk-naked-shell_2", - "nixpkgs": [ - "nixops4-nixos", - "nixops4", - "nixpkgs" - ], - "parts": "parts_2", - "rust-overlay": "rust-overlay_2", - "treefmt": "treefmt_2" - }, - "locked": { - "lastModified": 1738390452, - "narHash": "sha256-o8kg4q1V2xV9ZlszAnizXJK2c+fbhAeLbGoTUa2u1Bw=", - "owner": "yusdacra", - "repo": "nix-cargo-integration", - "rev": "718d577808e3e31f445b6564d58b755294e72f42", - "type": "github" - }, - "original": { - "owner": "yusdacra", - "repo": "nix-cargo-integration", - "type": "github" - } - }, - "nix_2": { - "inputs": { - "flake-compat": "flake-compat_5", - "flake-parts": "flake-parts_6", - "git-hooks-nix": "git-hooks-nix_3", - "nixfmt": "nixfmt_2", - "nixpkgs": [ - "nixops4-nixos", - "nixops4", - "nixpkgs" - ], - "nixpkgs-23-11": "nixpkgs-23-11_2", - "nixpkgs-regression": "nixpkgs-regression_2" - }, - "locked": { - "lastModified": 1738382221, - "narHash": "sha256-3+qJBts5RTAtjCExo6bkqrttL+skpYZzPOVEzPSwVtc=", - "owner": "NixOS", - "repo": "nix", - "rev": "d949c8de7c7e84bb7537dc772609686c37033a3b", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "master", - "repo": "nix", - "type": "github" - } - }, "nixfmt": { "inputs": { "flake-utils": "flake-utils" @@ -733,30 +492,14 @@ "type": "github" } }, - "nixfmt_2": { - "inputs": { - "flake-utils": "flake-utils_2" - }, - "locked": { - "lastModified": 1736283758, - "narHash": "sha256-hrKhUp2V2fk/dvzTTHFqvtOg000G1e+jyIam+D4XqhA=", - "owner": "NixOS", - "repo": "nixfmt", - "rev": "8d4bd690c247004d90d8554f0b746b1231fe2436", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixfmt", - "type": "github" - } - }, "nixops4": { "inputs": { "flake-parts": "flake-parts_2", "nix": "nix", "nix-cargo-integration": "nix-cargo-integration", - "nixpkgs": "nixpkgs_4", + "nixpkgs": [ + "nixpkgs" + ], "nixpkgs-old": "nixpkgs-old" }, "locked": { @@ -777,13 +520,13 @@ "inputs": { "flake-parts": "flake-parts_4", "git-hooks-nix": "git-hooks-nix_2", - "nixops4": "nixops4_2", + "nixops4": [ + "nixops4" + ], "nixops4-nixos": [ "nixops4-nixos" ], "nixpkgs": [ - "nixops4-nixos", - "nixops4", "nixpkgs" ] }, @@ -801,40 +544,18 @@ "type": "github" } }, - "nixops4_2": { - "inputs": { - "flake-parts": "flake-parts_5", - "nix": "nix_2", - "nix-cargo-integration": "nix-cargo-integration_2", - "nixpkgs": "nixpkgs_6", - "nixpkgs-old": "nixpkgs-old_2" - }, - "locked": { - "lastModified": 1739444468, - "narHash": "sha256-brg21neEI7pUnSRksOx9IE8/Kcr8OmEg4NIxL0sSy+U=", - "owner": "nixops4", - "repo": "nixops4", - "rev": "fb601ee79d8c9e3e7aca98dd2334ea91da3ea7e0", - "type": "github" - }, - "original": { - "owner": "nixops4", - "repo": "nixops4", - "type": "github" - } - }, "nixpkgs": { "locked": { - "lastModified": 1703013332, - "narHash": "sha256-+tFNwMvlXLbJZXiMHqYq77z/RfmpfpiI3yjL6o/Zo9M=", + "lastModified": 1730768919, + "narHash": "sha256-8AKquNnnSaJRXZxc5YmF/WfmxiHX6MMZZasRP6RRQkE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "54aac082a4d9bb5bbc5c4e899603abfb76a3f6d6", + "rev": "a04d33c0c3f1a59a2c1cb0c6e34cd24500e5a1dc", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-unstable", + "ref": "nixpkgs-unstable", "repo": "nixpkgs", "type": "github" } @@ -855,22 +576,6 @@ "type": "github" } }, - "nixpkgs-23-11_2": { - "locked": { - "lastModified": 1717159533, - "narHash": "sha256-oamiKNfr2MS6yH64rUn99mIZjc45nGJlj9eGth/3Xuw=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446", - "type": "github" - } - }, "nixpkgs-lib": { "locked": { "lastModified": 1738452942, @@ -907,18 +612,6 @@ "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" } }, - "nixpkgs-lib_4": { - "locked": { - "lastModified": 1738452942, - "narHash": "sha256-vJzFZGaCpnmo7I6i416HaBLpC+hvcURh/BQwROcGIp8=", - "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" - }, - "original": { - "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" - } - }, "nixpkgs-old": { "locked": { "lastModified": 1735563628, @@ -935,22 +628,6 @@ "type": "github" } }, - "nixpkgs-old_2": { - "locked": { - "lastModified": 1735563628, - "narHash": "sha256-OnSAY7XDSx7CtDoqNh8jwVwh4xNL/2HaJxGjryLWzX8=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b134951a4c9f3c995fd7be05f3243f8ecd65d798", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-24.05", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs-regression": { "locked": { "lastModified": 1643052045, @@ -967,29 +644,13 @@ "type": "github" } }, - "nixpkgs-regression_2": { - "locked": { - "lastModified": 1643052045, - "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "github" - } - }, "nixpkgs_2": { "locked": { - "lastModified": 1738136902, - "narHash": "sha256-pUvLijVGARw4u793APze3j6mU1Zwdtz7hGkGGkD87qw=", + "lastModified": 1730768919, + "narHash": "sha256-8AKquNnnSaJRXZxc5YmF/WfmxiHX6MMZZasRP6RRQkE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9a5db3142ce450045840cc8d832b13b8a2018e0c", + "rev": "a04d33c0c3f1a59a2c1cb0c6e34cd24500e5a1dc", "type": "github" }, "original": { @@ -1000,70 +661,6 @@ } }, "nixpkgs_3": { - "locked": { - "lastModified": 1730768919, - "narHash": "sha256-8AKquNnnSaJRXZxc5YmF/WfmxiHX6MMZZasRP6RRQkE=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "a04d33c0c3f1a59a2c1cb0c6e34cd24500e5a1dc", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_4": { - "locked": { - "lastModified": 1738410390, - "narHash": "sha256-xvTo0Aw0+veek7hvEVLzErmJyQkEcRk6PSR4zsRQFEc=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "3a228057f5b619feb3186e986dbe76278d707b6e", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_5": { - "locked": { - "lastModified": 1730768919, - "narHash": "sha256-8AKquNnnSaJRXZxc5YmF/WfmxiHX6MMZZasRP6RRQkE=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "a04d33c0c3f1a59a2c1cb0c6e34cd24500e5a1dc", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_6": { - "locked": { - "lastModified": 1738410390, - "narHash": "sha256-xvTo0Aw0+veek7hvEVLzErmJyQkEcRk6PSR4zsRQFEc=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "3a228057f5b619feb3186e986dbe76278d707b6e", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_7": { "locked": { "lastModified": 1740463929, "narHash": "sha256-4Xhu/3aUdCKeLfdteEHMegx5ooKQvwPHNkOgNCXQrvc=", @@ -1101,29 +698,6 @@ "type": "github" } }, - "parts_2": { - "inputs": { - "nixpkgs-lib": [ - "nixops4-nixos", - "nixops4", - "nix-cargo-integration", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1736143030, - "narHash": "sha256-+hu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "b905f6fc23a9051a6e1b741e1438dbfc0634c6de", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, "purescript-overlay": { "inputs": { "flake-compat": "flake-compat_3", @@ -1149,32 +723,6 @@ "type": "github" } }, - "purescript-overlay_2": { - "inputs": { - "flake-compat": "flake-compat_6", - "nixpkgs": [ - "nixops4-nixos", - "nixops4", - "nix-cargo-integration", - "dream2nix", - "nixpkgs" - ], - "slimlock": "slimlock_2" - }, - "locked": { - "lastModified": 1728546539, - "narHash": "sha256-Sws7w0tlnjD+Bjck1nv29NjC5DbL6nH5auL9Ex9Iz2A=", - "owner": "thomashoneyman", - "repo": "purescript-overlay", - "rev": "4ad4c15d07bd899d7346b331f377606631eb0ee4", - "type": "github" - }, - "original": { - "owner": "thomashoneyman", - "repo": "purescript-overlay", - "type": "github" - } - }, "pyproject-nix": { "flake": false, "locked": { @@ -1192,23 +740,6 @@ "type": "github" } }, - "pyproject-nix_2": { - "flake": false, - "locked": { - "lastModified": 1702448246, - "narHash": "sha256-hFg5s/hoJFv7tDpiGvEvXP0UfFvFEDgTdyHIjDVHu1I=", - "owner": "davhau", - "repo": "pyproject.nix", - "rev": "5a06a2697b228c04dd2f35659b4b659ca74f7aeb", - "type": "github" - }, - "original": { - "owner": "davhau", - "ref": "dream2nix", - "repo": "pyproject.nix", - "type": "github" - } - }, "root": { "inputs": { "agenix": "agenix", @@ -1217,7 +748,7 @@ "git-hooks": "git-hooks", "nixops4": "nixops4", "nixops4-nixos": "nixops4-nixos", - "nixpkgs": "nixpkgs_7" + "nixpkgs": "nixpkgs_3" } }, "rust-overlay": { @@ -1242,29 +773,6 @@ "type": "github" } }, - "rust-overlay_2": { - "inputs": { - "nixpkgs": [ - "nixops4-nixos", - "nixops4", - "nix-cargo-integration", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1738376888, - "narHash": "sha256-S6ErHxkSm0iA7ZMsjjDaASWxbELYcdfv8BhOkkj1rHw=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "83284068670d5ae4a43641c4afb150f3446be70d", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, "slimlock": { "inputs": { "nixpkgs": [ @@ -1289,31 +797,6 @@ "type": "github" } }, - "slimlock_2": { - "inputs": { - "nixpkgs": [ - "nixops4-nixos", - "nixops4", - "nix-cargo-integration", - "dream2nix", - "purescript-overlay", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1688756706, - "narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=", - "owner": "thomashoneyman", - "repo": "slimlock", - "rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c", - "type": "github" - }, - "original": { - "owner": "thomashoneyman", - "repo": "slimlock", - "type": "github" - } - }, "systems": { "locked": { "lastModified": 1681028828, @@ -1344,21 +827,6 @@ "type": "github" } }, - "systems_3": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, "treefmt": { "inputs": { "nixpkgs": [ @@ -1380,29 +848,6 @@ "repo": "treefmt-nix", "type": "github" } - }, - "treefmt_2": { - "inputs": { - "nixpkgs": [ - "nixops4-nixos", - "nixops4", - "nix-cargo-integration", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1738070913, - "narHash": "sha256-j6jC12vCFsTGDmY2u1H12lMr62fnclNjuCtAdF1a4Nk=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "bebf27d00f7d10ba75332a0541ac43676985dea3", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 9e0a719b..a99a54ca 100644 --- a/flake.nix +++ b/flake.nix @@ -3,12 +3,23 @@ nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; flake-parts.url = "github:hercules-ci/flake-parts"; git-hooks.url = "github:cachix/git-hooks.nix"; - agenix.url = "github:ryantm/agenix"; - - disko.url = "github:nix-community/disko"; - - nixops4.url = "github:nixops4/nixops4"; - nixops4-nixos.url = "github:nixops4/nixops4-nixos"; + agenix = { + url = "github:ryantm/agenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + disko = { + url = "github:nix-community/disko"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nixops4 = { + url = "github:nixops4/nixops4"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nixops4-nixos = { + url = "github:nixops4/nixops4-nixos"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.nixops4.follows = "nixops4"; + }; }; outputs = -- 2.48.1 From be03794f5f173659bca97690816b473c8a649166 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Tue, 25 Mar 2025 08:42:55 +0100 Subject: [PATCH 06/57] make re-exports explicit again --- launch/default.nix | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/launch/default.nix b/launch/default.nix index 9a533dd8..8d01c0ef 100644 --- a/launch/default.nix +++ b/launch/default.nix @@ -4,7 +4,7 @@ pkgs ? import sources.nixpkgs { inherit system; }, -}@args: +}: let inherit (pkgs) lib; in @@ -16,7 +16,12 @@ in (import ./tf.nix { inherit lib pkgs; }) ]; }; + + # re-export inputs so they can be overridden granularly + # (they can't be accessed from the outside any other way) + inherit + sources + system + pkgs + ; } -# re-export inputs so they can be overridden granularly -# (they can't be accessed from the outside any other way) -// args -- 2.48.1 From fa770d4ef31d479cdca11a3523ed98c41d8ae712 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Tue, 25 Mar 2025 08:43:05 +0100 Subject: [PATCH 07/57] Revert "deduplicate flake inputs" This reverts commit 95769084cef8187bf21c3ddf01d94a71d07a106c. --- flake.lock | 595 +++++++++++++++++++++++++++++++++++++++++++++++++++-- flake.nix | 23 +-- 2 files changed, 581 insertions(+), 37 deletions(-) diff --git a/flake.lock b/flake.lock index 36aa7833..ad891639 100644 --- a/flake.lock +++ b/flake.lock @@ -4,9 +4,7 @@ "inputs": { "darwin": "darwin", "home-manager": "home-manager", - "nixpkgs": [ - "nixpkgs" - ], + "nixpkgs": "nixpkgs", "systems": "systems" }, "locked": { @@ -40,6 +38,23 @@ "type": "github" } }, + "crane_2": { + "flake": false, + "locked": { + "lastModified": 1727316705, + "narHash": "sha256-/mumx8AQ5xFuCJqxCIOFCHTVlxHkMT21idpbgbm/TIE=", + "owner": "ipetkov", + "repo": "crane", + "rev": "5b03654ce046b5167e7b0bccbd8244cb56c16f0e", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "ref": "v0.19.0", + "repo": "crane", + "type": "github" + } + }, "darwin": { "inputs": { "nixpkgs": [ @@ -64,9 +79,7 @@ }, "disko": { "inputs": { - "nixpkgs": [ - "nixpkgs" - ] + "nixpkgs": "nixpkgs_2" }, "locked": { "lastModified": 1740485968, @@ -106,6 +119,31 @@ "type": "github" } }, + "dream2nix_2": { + "inputs": { + "nixpkgs": [ + "nixops4-nixos", + "nixops4", + "nix-cargo-integration", + "nixpkgs" + ], + "purescript-overlay": "purescript-overlay_2", + "pyproject-nix": "pyproject-nix_2" + }, + "locked": { + "lastModified": 1735160684, + "narHash": "sha256-n5CwhmqKxifuD4Sq4WuRP/h5LO6f23cGnSAuJemnd/4=", + "owner": "nix-community", + "repo": "dream2nix", + "rev": "8ce6284ff58208ed8961681276f82c2f8f978ef4", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "dream2nix", + "type": "github" + } + }, "flake-compat": { "flake": false, "locked": { @@ -170,6 +208,38 @@ "type": "github" } }, + "flake-compat_5": { + "flake": false, + "locked": { + "lastModified": 1733328505, + "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_6": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "flake-parts": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" @@ -246,6 +316,47 @@ "type": "github" } }, + "flake-parts_5": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_4" + }, + "locked": { + "lastModified": 1738453229, + "narHash": "sha256-7H9XgNiGLKN1G1CgRh0vUL4AheZSYzPm+zmZ7vxbJdo=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "32ea77a06711b758da0ad9bd6a844c5740a87abd", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_6": { + "inputs": { + "nixpkgs-lib": [ + "nixops4-nixos", + "nixops4", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1733312601, + "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems_2" @@ -264,11 +375,29 @@ "type": "github" } }, + "flake-utils_2": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "git-hooks": { "inputs": { "flake-compat": "flake-compat", "gitignore": "gitignore", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs_3" }, "locked": { "lastModified": 1737465171, @@ -323,7 +452,7 @@ "inputs": { "flake-compat": "flake-compat_4", "gitignore": "gitignore_2", - "nixpkgs": "nixpkgs_2" + "nixpkgs": "nixpkgs_5" }, "locked": { "lastModified": 1737465171, @@ -339,6 +468,45 @@ "type": "github" } }, + "git-hooks-nix_3": { + "inputs": { + "flake-compat": [ + "nixops4-nixos", + "nixops4", + "nix" + ], + "gitignore": [ + "nixops4-nixos", + "nixops4", + "nix" + ], + "nixpkgs": [ + "nixops4-nixos", + "nixops4", + "nix", + "nixpkgs" + ], + "nixpkgs-stable": [ + "nixops4-nixos", + "nixops4", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1734279981, + "narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, "gitignore": { "inputs": { "nixpkgs": [ @@ -419,6 +587,22 @@ "type": "github" } }, + "mk-naked-shell_2": { + "flake": false, + "locked": { + "lastModified": 1681286841, + "narHash": "sha256-3XlJrwlR0nBiREnuogoa5i1b4+w/XPe0z8bbrJASw0g=", + "owner": "yusdacra", + "repo": "mk-naked-shell", + "rev": "7612f828dd6f22b7fb332cc69440e839d7ffe6bd", + "type": "github" + }, + "original": { + "owner": "yusdacra", + "repo": "mk-naked-shell", + "type": "github" + } + }, "nix": { "inputs": { "flake-compat": "flake-compat_2", @@ -474,6 +658,63 @@ "type": "github" } }, + "nix-cargo-integration_2": { + "inputs": { + "crane": "crane_2", + "dream2nix": "dream2nix_2", + "mk-naked-shell": "mk-naked-shell_2", + "nixpkgs": [ + "nixops4-nixos", + "nixops4", + "nixpkgs" + ], + "parts": "parts_2", + "rust-overlay": "rust-overlay_2", + "treefmt": "treefmt_2" + }, + "locked": { + "lastModified": 1738390452, + "narHash": "sha256-o8kg4q1V2xV9ZlszAnizXJK2c+fbhAeLbGoTUa2u1Bw=", + "owner": "yusdacra", + "repo": "nix-cargo-integration", + "rev": "718d577808e3e31f445b6564d58b755294e72f42", + "type": "github" + }, + "original": { + "owner": "yusdacra", + "repo": "nix-cargo-integration", + "type": "github" + } + }, + "nix_2": { + "inputs": { + "flake-compat": "flake-compat_5", + "flake-parts": "flake-parts_6", + "git-hooks-nix": "git-hooks-nix_3", + "nixfmt": "nixfmt_2", + "nixpkgs": [ + "nixops4-nixos", + "nixops4", + "nixpkgs" + ], + "nixpkgs-23-11": "nixpkgs-23-11_2", + "nixpkgs-regression": "nixpkgs-regression_2" + }, + "locked": { + "lastModified": 1738382221, + "narHash": "sha256-3+qJBts5RTAtjCExo6bkqrttL+skpYZzPOVEzPSwVtc=", + "owner": "NixOS", + "repo": "nix", + "rev": "d949c8de7c7e84bb7537dc772609686c37033a3b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "master", + "repo": "nix", + "type": "github" + } + }, "nixfmt": { "inputs": { "flake-utils": "flake-utils" @@ -492,14 +733,30 @@ "type": "github" } }, + "nixfmt_2": { + "inputs": { + "flake-utils": "flake-utils_2" + }, + "locked": { + "lastModified": 1736283758, + "narHash": "sha256-hrKhUp2V2fk/dvzTTHFqvtOg000G1e+jyIam+D4XqhA=", + "owner": "NixOS", + "repo": "nixfmt", + "rev": "8d4bd690c247004d90d8554f0b746b1231fe2436", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixfmt", + "type": "github" + } + }, "nixops4": { "inputs": { "flake-parts": "flake-parts_2", "nix": "nix", "nix-cargo-integration": "nix-cargo-integration", - "nixpkgs": [ - "nixpkgs" - ], + "nixpkgs": "nixpkgs_4", "nixpkgs-old": "nixpkgs-old" }, "locked": { @@ -520,13 +777,13 @@ "inputs": { "flake-parts": "flake-parts_4", "git-hooks-nix": "git-hooks-nix_2", - "nixops4": [ - "nixops4" - ], + "nixops4": "nixops4_2", "nixops4-nixos": [ "nixops4-nixos" ], "nixpkgs": [ + "nixops4-nixos", + "nixops4", "nixpkgs" ] }, @@ -544,18 +801,40 @@ "type": "github" } }, + "nixops4_2": { + "inputs": { + "flake-parts": "flake-parts_5", + "nix": "nix_2", + "nix-cargo-integration": "nix-cargo-integration_2", + "nixpkgs": "nixpkgs_6", + "nixpkgs-old": "nixpkgs-old_2" + }, + "locked": { + "lastModified": 1739444468, + "narHash": "sha256-brg21neEI7pUnSRksOx9IE8/Kcr8OmEg4NIxL0sSy+U=", + "owner": "nixops4", + "repo": "nixops4", + "rev": "fb601ee79d8c9e3e7aca98dd2334ea91da3ea7e0", + "type": "github" + }, + "original": { + "owner": "nixops4", + "repo": "nixops4", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1730768919, - "narHash": "sha256-8AKquNnnSaJRXZxc5YmF/WfmxiHX6MMZZasRP6RRQkE=", + "lastModified": 1703013332, + "narHash": "sha256-+tFNwMvlXLbJZXiMHqYq77z/RfmpfpiI3yjL6o/Zo9M=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a04d33c0c3f1a59a2c1cb0c6e34cd24500e5a1dc", + "rev": "54aac082a4d9bb5bbc5c4e899603abfb76a3f6d6", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-unstable", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } @@ -576,6 +855,22 @@ "type": "github" } }, + "nixpkgs-23-11_2": { + "locked": { + "lastModified": 1717159533, + "narHash": "sha256-oamiKNfr2MS6yH64rUn99mIZjc45nGJlj9eGth/3Xuw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446", + "type": "github" + } + }, "nixpkgs-lib": { "locked": { "lastModified": 1738452942, @@ -612,6 +907,18 @@ "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" } }, + "nixpkgs-lib_4": { + "locked": { + "lastModified": 1738452942, + "narHash": "sha256-vJzFZGaCpnmo7I6i416HaBLpC+hvcURh/BQwROcGIp8=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" + } + }, "nixpkgs-old": { "locked": { "lastModified": 1735563628, @@ -628,6 +935,22 @@ "type": "github" } }, + "nixpkgs-old_2": { + "locked": { + "lastModified": 1735563628, + "narHash": "sha256-OnSAY7XDSx7CtDoqNh8jwVwh4xNL/2HaJxGjryLWzX8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b134951a4c9f3c995fd7be05f3243f8ecd65d798", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs-regression": { "locked": { "lastModified": 1643052045, @@ -644,7 +967,39 @@ "type": "github" } }, + "nixpkgs-regression_2": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, "nixpkgs_2": { + "locked": { + "lastModified": 1738136902, + "narHash": "sha256-pUvLijVGARw4u793APze3j6mU1Zwdtz7hGkGGkD87qw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9a5db3142ce450045840cc8d832b13b8a2018e0c", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { "locked": { "lastModified": 1730768919, "narHash": "sha256-8AKquNnnSaJRXZxc5YmF/WfmxiHX6MMZZasRP6RRQkE=", @@ -660,7 +1015,55 @@ "type": "github" } }, - "nixpkgs_3": { + "nixpkgs_4": { + "locked": { + "lastModified": 1738410390, + "narHash": "sha256-xvTo0Aw0+veek7hvEVLzErmJyQkEcRk6PSR4zsRQFEc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3a228057f5b619feb3186e986dbe76278d707b6e", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1730768919, + "narHash": "sha256-8AKquNnnSaJRXZxc5YmF/WfmxiHX6MMZZasRP6RRQkE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a04d33c0c3f1a59a2c1cb0c6e34cd24500e5a1dc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_6": { + "locked": { + "lastModified": 1738410390, + "narHash": "sha256-xvTo0Aw0+veek7hvEVLzErmJyQkEcRk6PSR4zsRQFEc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3a228057f5b619feb3186e986dbe76278d707b6e", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_7": { "locked": { "lastModified": 1740463929, "narHash": "sha256-4Xhu/3aUdCKeLfdteEHMegx5ooKQvwPHNkOgNCXQrvc=", @@ -698,6 +1101,29 @@ "type": "github" } }, + "parts_2": { + "inputs": { + "nixpkgs-lib": [ + "nixops4-nixos", + "nixops4", + "nix-cargo-integration", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1736143030, + "narHash": "sha256-+hu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "b905f6fc23a9051a6e1b741e1438dbfc0634c6de", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "purescript-overlay": { "inputs": { "flake-compat": "flake-compat_3", @@ -723,6 +1149,32 @@ "type": "github" } }, + "purescript-overlay_2": { + "inputs": { + "flake-compat": "flake-compat_6", + "nixpkgs": [ + "nixops4-nixos", + "nixops4", + "nix-cargo-integration", + "dream2nix", + "nixpkgs" + ], + "slimlock": "slimlock_2" + }, + "locked": { + "lastModified": 1728546539, + "narHash": "sha256-Sws7w0tlnjD+Bjck1nv29NjC5DbL6nH5auL9Ex9Iz2A=", + "owner": "thomashoneyman", + "repo": "purescript-overlay", + "rev": "4ad4c15d07bd899d7346b331f377606631eb0ee4", + "type": "github" + }, + "original": { + "owner": "thomashoneyman", + "repo": "purescript-overlay", + "type": "github" + } + }, "pyproject-nix": { "flake": false, "locked": { @@ -740,6 +1192,23 @@ "type": "github" } }, + "pyproject-nix_2": { + "flake": false, + "locked": { + "lastModified": 1702448246, + "narHash": "sha256-hFg5s/hoJFv7tDpiGvEvXP0UfFvFEDgTdyHIjDVHu1I=", + "owner": "davhau", + "repo": "pyproject.nix", + "rev": "5a06a2697b228c04dd2f35659b4b659ca74f7aeb", + "type": "github" + }, + "original": { + "owner": "davhau", + "ref": "dream2nix", + "repo": "pyproject.nix", + "type": "github" + } + }, "root": { "inputs": { "agenix": "agenix", @@ -748,7 +1217,7 @@ "git-hooks": "git-hooks", "nixops4": "nixops4", "nixops4-nixos": "nixops4-nixos", - "nixpkgs": "nixpkgs_3" + "nixpkgs": "nixpkgs_7" } }, "rust-overlay": { @@ -773,6 +1242,29 @@ "type": "github" } }, + "rust-overlay_2": { + "inputs": { + "nixpkgs": [ + "nixops4-nixos", + "nixops4", + "nix-cargo-integration", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1738376888, + "narHash": "sha256-S6ErHxkSm0iA7ZMsjjDaASWxbELYcdfv8BhOkkj1rHw=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "83284068670d5ae4a43641c4afb150f3446be70d", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, "slimlock": { "inputs": { "nixpkgs": [ @@ -797,6 +1289,31 @@ "type": "github" } }, + "slimlock_2": { + "inputs": { + "nixpkgs": [ + "nixops4-nixos", + "nixops4", + "nix-cargo-integration", + "dream2nix", + "purescript-overlay", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688756706, + "narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=", + "owner": "thomashoneyman", + "repo": "slimlock", + "rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c", + "type": "github" + }, + "original": { + "owner": "thomashoneyman", + "repo": "slimlock", + "type": "github" + } + }, "systems": { "locked": { "lastModified": 1681028828, @@ -827,6 +1344,21 @@ "type": "github" } }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "treefmt": { "inputs": { "nixpkgs": [ @@ -848,6 +1380,29 @@ "repo": "treefmt-nix", "type": "github" } + }, + "treefmt_2": { + "inputs": { + "nixpkgs": [ + "nixops4-nixos", + "nixops4", + "nix-cargo-integration", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1738070913, + "narHash": "sha256-j6jC12vCFsTGDmY2u1H12lMr62fnclNjuCtAdF1a4Nk=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "bebf27d00f7d10ba75332a0541ac43676985dea3", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index a99a54ca..9e0a719b 100644 --- a/flake.nix +++ b/flake.nix @@ -3,23 +3,12 @@ nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; flake-parts.url = "github:hercules-ci/flake-parts"; git-hooks.url = "github:cachix/git-hooks.nix"; - agenix = { - url = "github:ryantm/agenix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - disko = { - url = "github:nix-community/disko"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - nixops4 = { - url = "github:nixops4/nixops4"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - nixops4-nixos = { - url = "github:nixops4/nixops4-nixos"; - inputs.nixpkgs.follows = "nixpkgs"; - inputs.nixops4.follows = "nixops4"; - }; + agenix.url = "github:ryantm/agenix"; + + disko.url = "github:nix-community/disko"; + + nixops4.url = "github:nixops4/nixops4"; + nixops4-nixos.url = "github:nixops4/nixops4-nixos"; }; outputs = -- 2.48.1 From d599d5b640fbf9788a9223d2f3738eba1853aadd Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Tue, 25 Mar 2025 15:47:17 +0100 Subject: [PATCH 08/57] switch launch shell to root flake's nixpkgs, see #279 --- launch/.terraform.lock.hcl | 4 ++-- launch/default.nix | 6 +++++- npins/sources.json | 12 ++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/launch/.terraform.lock.hcl b/launch/.terraform.lock.hcl index f90c28b6..33548dcd 100644 --- a/launch/.terraform.lock.hcl +++ b/launch/.terraform.lock.hcl @@ -4,13 +4,13 @@ provider "registry.opentofu.org/hashicorp/external" { version = "2.3.4" hashes = [ - "h1:F45RHS5NlHBWkfcW61rwkA7Z2P+p3Rxvq75XMhNeFHE=", + "h1:HfVaWMC7Tz+tRfoWZtGCX2MATcgX3HsexoirWdi/voo=", ] } provider "registry.opentofu.org/hashicorp/null" { version = "3.2.3" hashes = [ - "h1:P9gA/YsRU4Q+STK6EkCOjTHYUop/+1LfIbX7QMNHfPk=", + "h1:qTlGDGC3RmXIPLgwsIh4LHG/DrAR6T6L+Wn6egnQnwE=", ] } diff --git a/launch/default.nix b/launch/default.nix index 8d01c0ef..8518f575 100644 --- a/launch/default.nix +++ b/launch/default.nix @@ -1,7 +1,11 @@ { system ? builtins.currentSystem, sources ? import ../npins, - pkgs ? import sources.nixpkgs { + inputs ? import sources.flake-inputs { + root = ../.; + }, + # match the same version of opentofu that is deployed by the root flake + pkgs ? import inputs.nixpkgs { inherit system; }, }: diff --git a/npins/sources.json b/npins/sources.json index 4701917c..c1177097 100644 --- a/npins/sources.json +++ b/npins/sources.json @@ -1,5 +1,17 @@ { "pins": { + "flake-inputs": { + "type": "Git", + "repository": { + "type": "GitHub", + "owner": "fricklerhandwerk", + "repo": "flake-inputs" + }, + "branch": "main", + "revision": "559574c9cbb8af262f3944b67d60fbf0f6ad03c3", + "url": "https://github.com/fricklerhandwerk/flake-inputs/archive/559574c9cbb8af262f3944b67d60fbf0f6ad03c3.tar.gz", + "hash": "0gbhmp6x2vdzvfnsvqzal3g8f8hx2ia6r73aibc78kazf78m67x6" + }, "htmx": { "type": "GitRelease", "repository": { -- 2.48.1 From 817c7245570b953d8176d486896266059a83ee0e Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Tue, 25 Mar 2025 16:04:19 +0100 Subject: [PATCH 09/57] use flake-sourced nixos-anywhere in tf, to reproduce modules for nix --- launch/main.tf | 8 ++++++++ launch/vm/main.tf | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/launch/main.tf b/launch/main.tf index 2e4aabcc..3fd5a5b5 100644 --- a/launch/main.tf +++ b/launch/main.tf @@ -1,3 +1,7 @@ +variable "nixos-anywhere" { + type = string +} + variable "domain" { type = string default = "fediversity.net" @@ -54,6 +58,7 @@ variable "initialUser" { # hostname = "test01" # config = "garage" # initialUser = var.initialUser +# nixos-anywhere = var.nixos-anywhere # } module "mastodon" { @@ -63,6 +68,7 @@ module "mastodon" { hostname = "test02" config = "mastodon" initialUser = var.initialUser + nixos-anywhere = var.nixos-anywhere } module "pixelfed" { @@ -72,6 +78,7 @@ module "pixelfed" { hostname = "test04" config = "pixelfed" initialUser = var.initialUser + nixos-anywhere = var.nixos-anywhere } module "peertube" { @@ -81,4 +88,5 @@ module "peertube" { hostname = "test03" config = "peertube" initialUser = var.initialUser + nixos-anywhere = var.nixos-anywhere } diff --git a/launch/vm/main.tf b/launch/vm/main.tf index c616d0e0..76c18af5 100644 --- a/launch/vm/main.tf +++ b/launch/vm/main.tf @@ -1,3 +1,7 @@ +variable "nixos-anywhere" { + type = string +} + variable "domain" { type = string } @@ -21,7 +25,7 @@ variable "initialUser" { module "deploy" { # source = "github.com/nix-community/nixos-anywhere//terraform/all-in-one" - source = "github.com/KiaraGrouwstra/nixos-anywhere?ref=special-args-nested-flake-fixed//terraform/all-in-one" + source = "${var.nixos-anywhere}//terraform/all-in-one" nixos_system_attr = ".#nixosConfigurations.${var.config}.config.system.build.toplevel" nixos_partitioner_attr = ".#nixosConfigurations.${var.config}.config.system.build.diskoScriptNoDeps" # when instance id changes, it will trigger a reinstall -- 2.48.1 From c1aa71e3194a8bf5fea06dd45086b73989b4ca8b Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Wed, 26 Mar 2025 09:57:02 +0100 Subject: [PATCH 10/57] properly pass repo dir for prod, be it with hard-coded TF init --- flake.nix | 5 +- launch/.gitignore | 2 +- launch/.terraform/modules/modules.json | 2 +- .../modules/peertube.deploy/CONTRIBUTING.md | 23 + .../modules/peertube.deploy/docs/INDEX.md | 11 + .../modules/peertube.deploy/docs/SUMMARY.md | 26 + .../modules/peertube.deploy/docs/book.toml | 6 + .../modules/peertube.deploy/docs/cli.md | 63 ++ .../peertube.deploy/docs/flake-module.nix | 21 + .../modules/peertube.deploy/docs/howtos.md | 1 + .../peertube.deploy/docs/howtos/INDEX.md | 29 + .../docs/howtos/custom-kexec.md | 40 + .../docs/howtos/disko-modes.md | 19 + .../docs/howtos/extra-files.md | 114 +++ .../peertube.deploy/docs/howtos/ipv6.md | 23 + .../docs/howtos/limited-ram.md | 29 + .../peertube.deploy/docs/howtos/nix-path.md | 57 ++ .../peertube.deploy/docs/howtos/no-os.md | 71 ++ .../peertube.deploy/docs/howtos/secrets.md | 76 ++ .../peertube.deploy/docs/howtos/terraform.md | 23 + .../docs/howtos/use-without-flakes.md | 82 ++ .../modules/peertube.deploy/docs/logo.png | Bin 0 -> 29405 bytes .../modules/peertube.deploy/docs/logo.svg | 133 +++ .../peertube.deploy/docs/quickstart.md | 334 +++++++ .../modules/peertube.deploy/docs/reference.md | 137 +++ .../peertube.deploy/docs/requirements.md | 39 + .../modules/peertube.deploy/flake.lock | 132 +++ .../modules/peertube.deploy/flake.nix | 55 ++ .../peertube.deploy/scripts/create-release.sh | 38 + .../modules/peertube.deploy/src/default.nix | 63 ++ .../peertube.deploy/src/flake-module.nix | 11 + .../modules/peertube.deploy/src/get-facts.sh | 23 + .../peertube.deploy/src/nixos-anywhere.sh | 880 ++++++++++++++++++ .../peertube.deploy/terraform/README.md | 21 + .../peertube.deploy/terraform/all-in-one.md | 235 +++++ .../terraform/all-in-one/main.tf | 64 ++ .../terraform/all-in-one/variables.tf | 151 +++ .../peertube.deploy/terraform/install.md | 91 ++ .../peertube.deploy/terraform/install/main.tf | 35 + .../terraform/install/providers.tf | 5 + .../terraform/install/run-nixos-anywhere.sh | 92 ++ .../terraform/install/variables.tf | 123 +++ .../peertube.deploy/terraform/nix-build.md | 47 + .../terraform/nix-build/main.tf | 17 + .../terraform/nix-build/nix-build.sh | 57 ++ .../terraform/nix-build/variables.tf | 22 + .../terraform/nixos-rebuild.md | 66 ++ .../terraform/nixos-rebuild/deploy.sh | 68 ++ .../terraform/nixos-rebuild/main.tf | 11 + .../terraform/nixos-rebuild/variables.tf | 39 + .../peertube.deploy/terraform/update-docs.sh | 14 + .../peertube.deploy/tests/flake-module.nix | 33 + .../tests/from-nixos-build-on-remote.nix | 56 ++ .../tests/from-nixos-generate-config.nix | 71 ++ .../tests/from-nixos-separated-phases.nix | 52 ++ .../tests/from-nixos-with-sudo.nix | 40 + .../peertube.deploy/tests/from-nixos.nix | 76 ++ .../peertube.deploy/tests/lib/test-base.nix | 20 + .../tests/modules/installer.nix | 22 + .../tests/modules/ssh-keys/ssh | 7 + .../tests/modules/ssh-keys/ssh.pub | 1 + .../tests/modules/system-to-install.nix | 47 + .../peertube.deploy/treefmt/flake-module.nix | 23 + .../modules/pixelfed.deploy/CONTRIBUTING.md | 23 + .../modules/pixelfed.deploy/docs/INDEX.md | 11 + .../modules/pixelfed.deploy/docs/SUMMARY.md | 26 + .../modules/pixelfed.deploy/docs/book.toml | 6 + .../modules/pixelfed.deploy/docs/cli.md | 63 ++ .../pixelfed.deploy/docs/flake-module.nix | 21 + .../modules/pixelfed.deploy/docs/howtos.md | 1 + .../pixelfed.deploy/docs/howtos/INDEX.md | 29 + .../docs/howtos/custom-kexec.md | 40 + .../docs/howtos/disko-modes.md | 19 + .../docs/howtos/extra-files.md | 114 +++ .../pixelfed.deploy/docs/howtos/ipv6.md | 23 + .../docs/howtos/limited-ram.md | 29 + .../pixelfed.deploy/docs/howtos/nix-path.md | 57 ++ .../pixelfed.deploy/docs/howtos/no-os.md | 71 ++ .../pixelfed.deploy/docs/howtos/secrets.md | 76 ++ .../pixelfed.deploy/docs/howtos/terraform.md | 23 + .../docs/howtos/use-without-flakes.md | 82 ++ .../modules/pixelfed.deploy/docs/logo.png | Bin 0 -> 29405 bytes .../modules/pixelfed.deploy/docs/logo.svg | 133 +++ .../pixelfed.deploy/docs/quickstart.md | 334 +++++++ .../modules/pixelfed.deploy/docs/reference.md | 137 +++ .../pixelfed.deploy/docs/requirements.md | 39 + .../modules/pixelfed.deploy/flake.lock | 132 +++ .../modules/pixelfed.deploy/flake.nix | 55 ++ .../pixelfed.deploy/scripts/create-release.sh | 38 + .../modules/pixelfed.deploy/src/default.nix | 63 ++ .../pixelfed.deploy/src/flake-module.nix | 11 + .../modules/pixelfed.deploy/src/get-facts.sh | 23 + .../pixelfed.deploy/src/nixos-anywhere.sh | 880 ++++++++++++++++++ .../pixelfed.deploy/terraform/README.md | 21 + .../pixelfed.deploy/terraform/all-in-one.md | 235 +++++ .../terraform/all-in-one/main.tf | 64 ++ .../terraform/all-in-one/variables.tf | 151 +++ .../pixelfed.deploy/terraform/install.md | 91 ++ .../pixelfed.deploy/terraform/install/main.tf | 35 + .../terraform/install/providers.tf | 5 + .../terraform/install/run-nixos-anywhere.sh | 92 ++ .../terraform/install/variables.tf | 123 +++ .../pixelfed.deploy/terraform/nix-build.md | 47 + .../terraform/nix-build/main.tf | 17 + .../terraform/nix-build/nix-build.sh | 57 ++ .../terraform/nix-build/variables.tf | 22 + .../terraform/nixos-rebuild.md | 66 ++ .../terraform/nixos-rebuild/deploy.sh | 68 ++ .../terraform/nixos-rebuild/main.tf | 11 + .../terraform/nixos-rebuild/variables.tf | 39 + .../pixelfed.deploy/terraform/update-docs.sh | 14 + .../pixelfed.deploy/tests/flake-module.nix | 33 + .../tests/from-nixos-build-on-remote.nix | 56 ++ .../tests/from-nixos-generate-config.nix | 71 ++ .../tests/from-nixos-separated-phases.nix | 52 ++ .../tests/from-nixos-with-sudo.nix | 40 + .../pixelfed.deploy/tests/from-nixos.nix | 76 ++ .../pixelfed.deploy/tests/lib/test-base.nix | 20 + .../tests/modules/installer.nix | 22 + .../tests/modules/ssh-keys/ssh | 7 + .../tests/modules/ssh-keys/ssh.pub | 1 + .../tests/modules/system-to-install.nix | 47 + .../pixelfed.deploy/treefmt/flake-module.nix | 23 + launch/.terraform/plugin_path | 1 - launch/tf-env.nix | 36 + panel/default.nix | 17 +- panel/env.nix | 5 - panel/nix/configuration.nix | 1 + panel/nix/package.nix | 3 +- panel/src/panel/settings.py | 17 +- 130 files changed, 8388 insertions(+), 31 deletions(-) create mode 100644 launch/.terraform/modules/peertube.deploy/CONTRIBUTING.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/INDEX.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/SUMMARY.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/book.toml create mode 100644 launch/.terraform/modules/peertube.deploy/docs/cli.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/flake-module.nix create mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/INDEX.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/custom-kexec.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/disko-modes.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/extra-files.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/ipv6.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/limited-ram.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/nix-path.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/no-os.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/secrets.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/terraform.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/use-without-flakes.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/logo.png create mode 100644 launch/.terraform/modules/peertube.deploy/docs/logo.svg create mode 100644 launch/.terraform/modules/peertube.deploy/docs/quickstart.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/reference.md create mode 100644 launch/.terraform/modules/peertube.deploy/docs/requirements.md create mode 100644 launch/.terraform/modules/peertube.deploy/flake.lock create mode 100644 launch/.terraform/modules/peertube.deploy/flake.nix create mode 100755 launch/.terraform/modules/peertube.deploy/scripts/create-release.sh create mode 100644 launch/.terraform/modules/peertube.deploy/src/default.nix create mode 100644 launch/.terraform/modules/peertube.deploy/src/flake-module.nix create mode 100755 launch/.terraform/modules/peertube.deploy/src/get-facts.sh create mode 100755 launch/.terraform/modules/peertube.deploy/src/nixos-anywhere.sh create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/README.md create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/all-in-one.md create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/all-in-one/main.tf create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/all-in-one/variables.tf create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/install.md create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/install/main.tf create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/install/providers.tf create mode 100755 launch/.terraform/modules/peertube.deploy/terraform/install/run-nixos-anywhere.sh create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/install/variables.tf create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/nix-build.md create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/nix-build/main.tf create mode 100755 launch/.terraform/modules/peertube.deploy/terraform/nix-build/nix-build.sh create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/nix-build/variables.tf create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild.md create mode 100755 launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/deploy.sh create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/main.tf create mode 100644 launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/variables.tf create mode 100755 launch/.terraform/modules/peertube.deploy/terraform/update-docs.sh create mode 100644 launch/.terraform/modules/peertube.deploy/tests/flake-module.nix create mode 100644 launch/.terraform/modules/peertube.deploy/tests/from-nixos-build-on-remote.nix create mode 100644 launch/.terraform/modules/peertube.deploy/tests/from-nixos-generate-config.nix create mode 100644 launch/.terraform/modules/peertube.deploy/tests/from-nixos-separated-phases.nix create mode 100644 launch/.terraform/modules/peertube.deploy/tests/from-nixos-with-sudo.nix create mode 100644 launch/.terraform/modules/peertube.deploy/tests/from-nixos.nix create mode 100644 launch/.terraform/modules/peertube.deploy/tests/lib/test-base.nix create mode 100644 launch/.terraform/modules/peertube.deploy/tests/modules/installer.nix create mode 100644 launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh create mode 100644 launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh.pub create mode 100644 launch/.terraform/modules/peertube.deploy/tests/modules/system-to-install.nix create mode 100644 launch/.terraform/modules/peertube.deploy/treefmt/flake-module.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/CONTRIBUTING.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/INDEX.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/SUMMARY.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/book.toml create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/cli.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/flake-module.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/INDEX.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/custom-kexec.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/disko-modes.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/extra-files.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/ipv6.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/limited-ram.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/nix-path.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/no-os.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/secrets.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/terraform.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/use-without-flakes.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/logo.png create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/logo.svg create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/quickstart.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/reference.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/requirements.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/flake.lock create mode 100644 launch/.terraform/modules/pixelfed.deploy/flake.nix create mode 100755 launch/.terraform/modules/pixelfed.deploy/scripts/create-release.sh create mode 100644 launch/.terraform/modules/pixelfed.deploy/src/default.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/src/flake-module.nix create mode 100755 launch/.terraform/modules/pixelfed.deploy/src/get-facts.sh create mode 100755 launch/.terraform/modules/pixelfed.deploy/src/nixos-anywhere.sh create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/README.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/main.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/variables.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/install.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/install/main.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/install/providers.tf create mode 100755 launch/.terraform/modules/pixelfed.deploy/terraform/install/run-nixos-anywhere.sh create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/install/variables.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/nix-build.md create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/main.tf create mode 100755 launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/nix-build.sh create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/variables.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild.md create mode 100755 launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/deploy.sh create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/main.tf create mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/variables.tf create mode 100755 launch/.terraform/modules/pixelfed.deploy/terraform/update-docs.sh create mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/flake-module.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-build-on-remote.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-generate-config.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-separated-phases.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-with-sudo.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/from-nixos.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/lib/test-base.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/modules/installer.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh create mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh.pub create mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/modules/system-to-install.nix create mode 100644 launch/.terraform/modules/pixelfed.deploy/treefmt/flake-module.nix create mode 100644 launch/tf-env.nix diff --git a/flake.nix b/flake.nix index 9e0a719b..dba9e55b 100644 --- a/flake.nix +++ b/flake.nix @@ -43,7 +43,10 @@ pre-commit.settings.hooks = let ## Add a directory here if pre-commit hooks shouldn't apply to it. - optout = [ "npins" ]; + optout = [ + "npins" + "launch/.terraform" + ]; excludes = map (dir: "^${dir}/") optout; addExcludes = lib.mapAttrs (_: c: c // { inherit excludes; }); in diff --git a/launch/.gitignore b/launch/.gitignore index 0f8ba9b3..c0b634d3 100644 --- a/launch/.gitignore +++ b/launch/.gitignore @@ -1,3 +1,3 @@ -.terraform/ +# .terraform/ .terraform.tfstate.lock.info terraform.tfstate* diff --git a/launch/.terraform/modules/modules.json b/launch/.terraform/modules/modules.json index f7a11609..aa12893a 100644 --- a/launch/.terraform/modules/modules.json +++ b/launch/.terraform/modules/modules.json @@ -1 +1 @@ -{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"mastodon","Source":"./vm","Dir":"vm"},{"Key":"mastodon.deploy","Source":"file:///nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source//deploy_nixos","Dir":".terraform/modules/mastodon.deploy/deploy_nixos"},{"Key":"peertube","Source":"./vm","Dir":"vm"},{"Key":"peertube.deploy","Source":"file:///nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source//deploy_nixos","Dir":".terraform/modules/peertube.deploy/deploy_nixos"},{"Key":"pixelfed","Source":"./vm","Dir":"vm"},{"Key":"pixelfed.deploy","Source":"file:///nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source//deploy_nixos","Dir":".terraform/modules/pixelfed.deploy/deploy_nixos"}]} \ No newline at end of file +{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"mastodon","Source":"./vm","Dir":"vm"},{"Key":"mastodon.deploy","Source":"file:///nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source//deploy_nixos","Dir":".terraform/modules/mastodon.deploy/deploy_nixos"},{"Key":"peertube","Source":"./vm","Dir":"vm"},{"Key":"peertube.deploy","Source":"file:///nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source//deploy_nixos","Dir":".terraform/modules/peertube.deploy/deploy_nixos"},{"Key":"pixelfed","Source":"./vm","Dir":"vm"},{"Key":"pixelfed.deploy","Source":"file:///nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source//deploy_nixos","Dir":".terraform/modules/pixelfed.deploy/deploy_nixos"}]} diff --git a/launch/.terraform/modules/peertube.deploy/CONTRIBUTING.md b/launch/.terraform/modules/peertube.deploy/CONTRIBUTING.md new file mode 100644 index 00000000..3aeefa73 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/CONTRIBUTING.md @@ -0,0 +1,23 @@ +To run `nixos-anywhere` from the repo: + +```console +nix run . -- --help +``` + +To format the code: + +```console +nix fmt +``` + +To run all tests: + +```console +nix flake check -vL +``` + +To run an individual test: + +``` +nix build .#checks.x86_64-linux.from-nixos -vL +``` diff --git a/launch/.terraform/modules/peertube.deploy/docs/INDEX.md b/launch/.terraform/modules/peertube.deploy/docs/INDEX.md new file mode 100644 index 00000000..67d48751 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/INDEX.md @@ -0,0 +1,11 @@ +# Table of Content: - nixos-anywhere + +**_Install NixOS everywhere via ssh_** + + + +- [README](../README.md) +- [Quickstart](./quickstart.md) +- [System Requirements](./requirements.md) +- [How to Guide](./howtos/INDEX.md) +- [Reference](./reference.md) diff --git a/launch/.terraform/modules/peertube.deploy/docs/SUMMARY.md b/launch/.terraform/modules/peertube.deploy/docs/SUMMARY.md new file mode 100644 index 00000000..3bfaea5b --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/SUMMARY.md @@ -0,0 +1,26 @@ +# Summary: - nixos-anywhere + +**_Install NixOS everywhere via ssh_** + + + +The **nixos-anywhere** tool allows you to pre-configure the whole process of +installing NixOS, and run the install remotely with a single CLI command. + +Refer to the following documentation for more information. + +[System Requirements](./requirements.md): CPU and memory requirements + +[Quickstart](./quickstart.md): Instructions for a typical installation + +[How to Guide](./howtos/INDEX.md): Instructions for non-typical use cases + +- [Installing on a machine with no operating system](./howtos/no-os.md) +- [Using your own kexec image](./howtos/custom-kexec.md) +- [Secrets and full disk encryption](./howtos/secrets.md) +- [Use without flakes](./howtos/use-without-flakes.md) +- [Terraform](./howtos/terraform.md) +- [Nix-channels / `NIX_PATH`](./howtos/nix-path.md) +- [IPv6-only targets](./howtos/ipv6.md) + +[Reference](./reference.md): Reference Guide diff --git a/launch/.terraform/modules/peertube.deploy/docs/book.toml b/launch/.terraform/modules/peertube.deploy/docs/book.toml new file mode 100644 index 00000000..d053de4e --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/book.toml @@ -0,0 +1,6 @@ +[book] +authors = [ ] +language = "en" +multilingual = false +src = "." +title = "nixos-anywhere - install NixOS everywhere" diff --git a/launch/.terraform/modules/peertube.deploy/docs/cli.md b/launch/.terraform/modules/peertube.deploy/docs/cli.md new file mode 100644 index 00000000..d2577552 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/cli.md @@ -0,0 +1,63 @@ +# CLI + +``` +Usage: nixos-anywhere [options] [] + +Options: + +* -f, --flake + set the flake to install the system from. +* --target-host + specified the SSH target host to deploy onto. +* -i + selects which SSH private key file to use. +* -p, --ssh-port + set the ssh port to connect with +* --ssh-option + set an ssh option +* -L, --print-build-logs + print full build logs +* --env-password + set a password used by ssh-copy-id, the password should be set by + the environment variable SSHPASS +* -s, --store-paths + set the store paths to the disko-script and nixos-system directly + if this is given, flake is not needed +* --no-reboot + do not reboot after installation, allowing further customization of the target installation. +* --kexec + use another kexec tarball to bootstrap NixOS +* --kexec-extra-flags + extra flags to add into the call to kexec, e.g. "--no-sync" +* --ssh-store-setting + ssh store settings appended to the store URI, e.g. "compress true". needs to be URI encoded. +* --post-kexec-ssh-port + after kexec is executed, use a custom ssh port to connect. Defaults to 22 +* --copy-host-keys + copy over existing /etc/ssh/ssh_host_* host keys to the installation +* --stop-after-disko + exit after disko formatting, you can then proceed to install manually or some other way +* --extra-files + contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten + Copied files will be owned by root. See documentation for details. +* --disk-encryption-keys + copy the contents of the file or pipe in local_path to remote_path in the installer environment, + after kexec but before installation. Can be repeated. +* --no-substitute-on-destination + disable passing --substitute-on-destination to nix-copy +* --debug + enable debug output +* --option + nix option to pass to every nix related command +* --from + URL of the source Nix store to copy the nixos and disko closure from +* --build-on-remote + build the closure on the remote machine instead of locally and copy-closuring it +* --vm-test + build the system and test the disk configuration inside a VM without installing it to the target. +* --build-on auto|remote|local + sets the build on settings to auto, remote or local. Default is auto. + auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build + local: will build on the local host + remote: will build on the remote host +``` diff --git a/launch/.terraform/modules/peertube.deploy/docs/flake-module.nix b/launch/.terraform/modules/peertube.deploy/docs/flake-module.nix new file mode 100644 index 00000000..2afe9d50 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/flake-module.nix @@ -0,0 +1,21 @@ +{ + perSystem = + { pkgs, lib, ... }: + { + packages.docs = + pkgs.runCommand "nixos-anywhere-docs" + { + passthru.serve = pkgs.writeShellScriptBin "serve" '' + set -euo pipefail + cd docs + workdir=$(${pkgs.coreutils}/bin/mktemp -d) + trap 'rm -rf "$workdir"' EXIT + ${pkgs.mdbook}/bin/mdbook serve --dest-dir "$workdir" + ''; + } + '' + cp -r ${lib.cleanSource ./.}/* . + ${pkgs.mdbook}/bin/mdbook build --dest-dir "$out" + ''; + }; +} diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos.md b/launch/.terraform/modules/peertube.deploy/docs/howtos.md new file mode 100644 index 00000000..bfa55ce1 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/howtos.md @@ -0,0 +1 @@ +# How to Guide diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/INDEX.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/INDEX.md new file mode 100644 index 00000000..2d356638 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/howtos/INDEX.md @@ -0,0 +1,29 @@ +# How To Guide: nixos-anywhere + +**_Install NixOS everywhere via ssh_** + + + +[Documentation Index](./INDEX.md) + +## Contents + +[Installing on a machine with no operating system](./no-os.md) + +[Kexec on systems with limited RAM](./limited-ram.md) + +[Copying files to the new installation](./extra-files.md) + +[Using your own kexec image](./custom-kexec.md) + +[Repair installations without wiping data](./disko-modes.md) + +[Secrets and full disk encryption](./secrets.md) + +[Use without flakes](./use-without-flakes.md) + +[Terraform](./terraform.md) + +[Nix-channels / `NIX_PATH`](./nix-path.md) + +[IPv6-only targets](./ipv6.md) diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/custom-kexec.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/custom-kexec.md new file mode 100644 index 00000000..5935a5f3 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/howtos/custom-kexec.md @@ -0,0 +1,40 @@ +# Using your own kexec image + +By default, `nixos-anywhere` downloads the kexec image from the +[NixOS images repository](https://github.com/nix-community/nixos-images#kexec-tarballs). + +However, you can provide your own `kexec` image file if you need to use a +different one. This is particularly useful for architectures other than `x86_64` +and `aarch64`, since they don't have a pre-build image. + +To do this, use the `--kexec` command line switch followed by the path to your +image file. The image will be uploaded prior to execution. + +Here's an example command that demonstrates how to use a custom kexec image with +`nixos-anywhere`: + +``` +nix run github:nix-community/nixos-anywhere -- \ + --kexec "$(nix build --print-out-paths github:nix-community/nixos-images#packages.aarch64-linux.kexec-installer-nixos-unstable-noninteractive)/nixos-kexec-installer-noninteractive-aarch64-linux.tar.gz" \ + --flake 'github:your-user/your-repo#your-system' \ + root@yourip +``` + +Make sure to replace `github:your-user/your-repo#your-system` with the +appropriate Flake URL representing your NixOS configuration. + +The example above assumes that your local machine can build for aarch64 in one +of the following ways: + +- Natively + +- Through a remote builder + +- By emulating the architecture with qemu using the following NixOS + configuration: + +```nix +{ + boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; +} +``` diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/disko-modes.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/disko-modes.md new file mode 100644 index 00000000..501f93f1 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/howtos/disko-modes.md @@ -0,0 +1,19 @@ +# Repair installations without wiping data + +By default, nixos-anywhere will reformat all configured disks before running the +installation. However it is also possible to mount the filesystems of an +existing installation and run `nixos-install`. This is useful to recover from a +misconfigured NixOS installation by first booting into a NixOS installer or +recovery system. + +To only mount existing filesystems, add `--disko-mode mount` to +`nixos-anywhere`: + +``` +nix run github:nix-community/nixos-anywhere -- --disko-mode mount --flake # --target-host root@ +``` + +1. This will first boot into a nixos-installer +2. Mounts disks with disko +3. Runs nixos-install based on the provided flake +4. Reboots the machine. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/extra-files.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/extra-files.md new file mode 100644 index 00000000..ca067d4c --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/howtos/extra-files.md @@ -0,0 +1,114 @@ +# Copying files to the new installation + +The `--extra-files ` option allows copying files to the target host after +installation. + +The contents of the `` is recursively copied and overwrites the targets +root (/). The contents _must_ be in a structure and permissioned as it should be +on the target. + +In this way, there is no need to repeatedly pass arguments (eg: a fictional +argument: `--copy `) to `nixos-anywhere` to complete the intended +outcome. + +The path and directory structure passed to `--extra-files` should be prepared +beforehand. + +This allows a simple programmatic invocation of `nixos-anywhere` for multiple +hosts. + +## Simple Example + +You want `/etc/ssh/ssh_host_*` and `/persist` from the local system on the +target. The `` contents will look like this: + +```console +$ cd /tmp +$ root=$(mktemp -d) +$ sudo cp --verbose --archive --parents /etc/ssh/ssh_host_* ${root} +$ cp --verbose --archive --link /persist ${root} +``` + +The directory structure would look like this: + +```console +drwx------ myuser1 users 20 tmp.d6nx5QUwPN +drwxr-xr-x root root 6 ├── etc +drwx------ myuser1 users 160 │ └── ssh +.rw------- root root 399 │ ├── ssh_host_ed25519_key +.rw-r--r-- root root 91 │ ├── ssh_host_ed25519_key.pub +drwxr-xr-x myuser1 users 22 └── persist +drwxr-xr-x myuser1 users 14 ├── all +drwxr-xr-x myuser1 users 22 │ ├── my +.rw-r--r-- myuser1 users 6 │ │ ├── test3 +drwxr-xr-x myuser1 users 10 │ │ └── things +.rw-r--r-- myuser1 users 6 │ │ └── test4 +.rw-r--r-- myuser1 users 6 │ └── test2 +drwxr-xr-x myuser1 users 0 ├── blah +.rw-r--r-- myuser1 users 6 └── test +``` + +**NOTE**: Permissions will be copied, but ownership on the target will be root. + +Then pass $root like: + +> nixos-anywhere --flake ".#" --extra-files $root --target-host root@newhost + +## Programmatic Example + +```sh +for host in host1 host2 host3; do + root="target/${host}" + install -d -m755 ${root}/etc/ssh + ssh-keygen -A -C root@${host} -f ${root} + nixos-anywhere --extra-files "${root}" --flake ".#${host}" --target-host "root@${host}" +done +``` + +## Considerations + +### Ownership + +The new system may have differing UNIX user and group id's for users created +during installation. + +When the files are extracted on the remote the copied data will be owned by +root. + +If you wish to change the ownership after the files are copied onto the system, +you can use the `--chown` option. + +For example, if you did `--chown /home/myuser/.ssh 1000:100`, this would equate +to running `chown -R /home/myuser/.ssh 1000:100` where the uid is 1000 and the +gid is 100. **Only do this when you can _guarantee_ what the uid and gid will +be.** + +### Symbolic Links + +Do not create symbolic links to reference data to copy. + +GNU `tar` is used to do the copy over ssh. It is an archival tool used to +re/store directory structures as is. Thus `tar` copies symbolic links created +with `ln -s` by default. It does not follow them to copy the underlying file. + +### Hard links + +**NOTE**: hard links can only be created on the same filesystem. + +If you have larger persistent data to copy to the target. GNU `tar` will copy +data referenced by hard links created with `ln`. A hard link does not create +another copy the data. + +To copy a directory tree to the new target you can use the `cp` command with the +`--link` option which creates hard links. + +#### Example + +```sh +cd /tmp +root=$(mktemp -d) +cp --verbose --archive --link --parents /persist/home/myuser ${root} +``` + +`--parents` will create the directory structure of the source at the +destination. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/ipv6.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/ipv6.md new file mode 100644 index 00000000..64eb7a6a --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/howtos/ipv6.md @@ -0,0 +1,23 @@ +# NixOS-anywhere on IPv6-only targets + +As GitHub engineers still haven't enabled the IPv6 switch, the kexec image +hosted on GitHub, cannot be used unfortunately on IPv6-only hosts. However it is +possible to use an IPv6 proxy for GitHub content like that: + +``` +nixos-anywhere \ + --kexec https://gh-v6.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz \ +... +``` + +This proxy is hosted by [numtide](https://numtide.com/). It also works for IPv4. + +Alternatively it is also possible to reference a local file: + +``` +nixos-anywhere \ + --kexec ./nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz \ +... +``` + +This tarball will be then uploaded via sftp to the target. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/limited-ram.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/limited-ram.md new file mode 100644 index 00000000..0cbac65e --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/howtos/limited-ram.md @@ -0,0 +1,29 @@ +# Kexec on Systems with Limited RAM + +When working with nixos-anywhere on systems with limited RAM (around 1GB), you +can use the `--no-disko-deps` option to reduce memory usage during installation. + +## How it works + +The `--no-disko-deps` option uploads only the disko partitioning script without +including its dependencies. This significantly reduces memory usage because: + +1. The installer normally stores all dependencies in memory +2. Partitioning tools can be quite large when bundled with their dependencies + +## Usage example + +```bash +nix run github:nix-community/nixos-anywhere -- --no-disko-deps --flake # --target-host root@ +``` + +## Trade-off + +While this approach saves memory, it means the partitioning tools will be +whatever versions are available on the target system, rather than the specific +versions defined in your NixOS configuration. This could potentially lead to +version inconsistencies between the partitioning tools and the NixOS system +being installed. + +This trade-off is usually acceptable for memory-constrained environments where +installation would otherwise fail due to insufficient RAM. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/nix-path.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/nix-path.md new file mode 100644 index 00000000..1505af93 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/howtos/nix-path.md @@ -0,0 +1,57 @@ +# Nix-channels / `NIX_PATH` + +nixos-anywhere does not install channels onto the new system by default to save +time and disk space. This for example results in errors like: + +``` +(stack trace truncated; use '--show-trace' to show the full trace) + +error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I) + +at «none»:0: (source not available) +``` + +when using tools like nix-shell/nix-env that rely on `NIX_PATH` being set. + +# Solution 1: Set the `NIX_PATH` via nixos configuration (recommended) + +Instead of stateful channels, one can also populate the `NIX_PATH` using nixos +configuration instead: + +```nix +{ + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + # ... other inputs + + outputs = inputs@{ nixpkgs, ... }: + { + nixosConfigurations.yoursystem = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; # adapt to your actual system + modules = [ + # This line will populate NIX_PATH + { nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ]; } + # ... other modules and your configuration.nix + ]; + }; + }; +} +``` + +Advantage: This solution will be automatically kept up-to-date every time the +flake is updated. + +In your shell you will see something in your `$NIX_PATH`: + +```shellSession +$ echo $NIX_PATH +/root/.nix-defexpr/channels:nixpkgs=/nix/store/8b61j28rpy11dg8hanbs2x710d8w3v0d-source +``` + +# Solution 2: Manually add the channel + +On the installed machine, run: + +```shellSession +$ nix-channel --add https://nixos.org/channels/nixos-unstable nixos +$ nix-channel --update +``` diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/no-os.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/no-os.md new file mode 100644 index 00000000..1c07cb0a --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/howtos/no-os.md @@ -0,0 +1,71 @@ +# Installing on a machine with no operating system + +If your machine doesn't currently have an operating system installed, you can +still run `nixos-anywhere` remotely to automate the install. To do this, you +would first need to boot the target machine from the standard NixOS installer. +You can either boot from a USB or use `netboot`. + +The +[NixOS installation guide](https://nixos.org/manual/nixos/stable/index.html#sec-booting-from-usb) +has detailed instructions on how to boot the installer. + +When you run `nixos-anywhere`, it will determine whether a NixOS installer is +present by checking whether the `/etc/os-release` file contains the identifier +`VARIANT_ID=installer`. This identifier is available on releases NixOS 23.05 or +later. + +If an installer is detected, `nixos-anywhere` will not attempt to `kexec` into +its own image. This is particularly useful for targets that don't have enough +RAM for `kexec` or don't support `kexec`. + +NixOS starts an SSH server on the installer by default, but you need to set a +password in order to access it. To set a password for the `nixos` user, run the +following command in a terminal on the NixOS machine: + +``` +passwd +``` + +If you don't know the IP address of the installer on your network, you can find +it by running the following command: + +``` +$ ip addr +1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + inet6 ::1/128 scope host + valid_lft forever preferred_lft forever +2: eth0: mtu 1500 qdisc fq_codel state UP group default qlen 1000 + link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff + altname enp0s3 + altname ens3 + inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0 + valid_lft 86385sec preferred_lft 75585sec + inet6 fec0::5054:ff:fe12:3456/64 scope site dynamic mngtmpaddr noprefixroute + valid_lft 86385sec preferred_lft 14385sec + inet6 fe80::5054:ff:fe12:3456/64 scope link + valid_lft forever preferred_lft forever +``` + +This will display the IP addresses assigned to your network interface(s), +including the IP address of the installer. In the example output below, the +installer's IP addresses are `10.0.2.15`, `fec0::5054:ff:fe12:3456`, and +`fe80::5054:ff:fe12:3456%eth0`: + +To test if you can connect and your password works, you can use the following +SSH command (replace the IP address with your own): + +``` +ssh -v nixos@fec0::5054:ff:fe12:3456 +``` + +You can then use the IP address to run `nixos-anywhere` like this: + +``` +nix run github:nix-community/nixos-anywhere -- --flake '.#myconfig' --target-host nixos@fec0::5054:ff:fe12:3456 +``` + +This example assumes a flake in the current directory containing a configuration +named `myconfig`. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/secrets.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/secrets.md new file mode 100644 index 00000000..8d95ee78 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/howtos/secrets.md @@ -0,0 +1,76 @@ +# Secrets and full disk encryption + +The `nixos-anywhere` utility offers the capability to install secrets onto a +target machine. This feature is particularly beneficial when you want to +bootstrap secrets management tools such as +[sops-nix](https://github.com/Mic92/sops-nix) or +[agenix](https://github.com/ryantm/agenix), which rely on machine-specific +secrets to decrypt other uploaded secrets. + +## Example: Decrypting an OpenSSH Host Key with pass + +In this example, we demonstrate how to use a script to decrypt an OpenSSH host +key from the `pass` password manager and subsequently pass it to +`nixos-anywhere` during the installation process: + +```bash +#!/usr/bin/env bash + +# Create a temporary directory +temp=$(mktemp -d) + +# Function to cleanup temporary directory on exit +cleanup() { + rm -rf "$temp" +} +trap cleanup EXIT + +# Create the directory where sshd expects to find the host keys +install -d -m755 "$temp/etc/ssh" + +# Decrypt your private key from the password store and copy it to the temporary directory +pass ssh_host_ed25519_key > "$temp/etc/ssh/ssh_host_ed25519_key" + +# Set the correct permissions so sshd will accept the key +chmod 600 "$temp/etc/ssh/ssh_host_ed25519_key" + +# Install NixOS to the host system with our secrets +nixos-anywhere --extra-files "$temp" --flake '.#your-host' --target-host root@yourip +``` + +## Example: Uploading Disk Encryption Secrets + +In a similar vein, `nixos-anywhere` can upload disk encryption secrets, which +are necessary during formatting with disko. Here's an example that demonstrates +how to provide your disk encryption password as a file or via the `pass` utility +to `nixos-anywhere`: + +```bash +# Write your disk encryption password to a file +echo "my-super-safe-password" > /tmp/disk-1.key + +# Call nixos-anywhere with disk encryption keys +nixos-anywhere \ + --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ + --disk-encryption-keys /tmp/disk-2.key <(pass my-disk-encryption-password) \ + --flake '.#your-host' \ + root@yourip +``` + +In the above example, replace `"my-super-safe-password"` with your actual +encryption password, and `my-disk-encryption-password` with the relevant entry +in your pass password store. Also, ensure to replace `'.#your-host'` and +`root@yourip` with your actual flake and IP address, respectively. + +## Example: Using existing SSH host keys + +If the system contains existing trusted `/etc/ssh/ssh_host_*` SSH host keys and +certificates, `nixos-anywhere` can copy them in case they are necessary during +installation and system activation. + +``` +nixos-anywhere --copy-host-keys --flake '.#your-host' root@yourip +``` + +This would copy `/etc/ssh/ssh_host_*` to `/mnt` after kexec but before +installation, ignoring files that already exist in destination. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/terraform.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/terraform.md new file mode 100644 index 00000000..87974932 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/howtos/terraform.md @@ -0,0 +1,23 @@ +# Terraform + +The nixos-anywhere terraform modules allow you to use Terraform for installing +and updating NixOS. It simplifies the deployment process by integrating +nixos-anywhere functionality. + +Our terraform module requires the +[null](https://registry.terraform.io/providers/hashicorp/null/latest) and +[external](https://registry.terraform.io/providers/hashicorp/external/latest) +provider. + +You can get these by from nixpkgs like this: + +```nix +nix-shell -p '(pkgs.terraform.withPlugins (p: [ p.null p.external ]))' +``` + +You can add this expression the `packages` list in your devshell in flake.nix or +in shell.nix. + +Checkout out the +[module reference](https://github.com/nix-community/nixos-anywhere/tree/main/terraform) +for examples and module parameter on how to use the modules. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/use-without-flakes.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/use-without-flakes.md new file mode 100644 index 00000000..33419a9e --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/howtos/use-without-flakes.md @@ -0,0 +1,82 @@ +# Use without flakes + +First, +[import the disko NixOS module](https://github.com/nix-community/disko/blob/master/docs/HowTo.md#installing-nixos-module) +in your NixOS configuration and define disko devices as described in the +[examples](https://github.com/nix-community/disko/tree/master/example). + +Let's assume that your NixOS configuration lives in `configuration.nix` and your +target machine is called `machine`: + +## 1. Download your favourite disk layout: + +See https://github.com/nix-community/disko-templates/ for more examples: + +The example below will work with both UEFI and BIOS-based systems. + +```bash +curl https://raw.githubusercontent.com/nix-community/disko-templates/main/single-disk-ext4/disko-config.nix > ./disko-config.nix +``` + +## 2. Get a hardware-configuration.nix from on the target machine + +- **Option 1**: If NixOS is not installed, boot into an installer without first + installing NixOS. +- **Option 2**: Use the kexec tarball method, as described + [here](https://github.com/nix-community/nixos-images#kexec-tarballs). + +- **Generate Configuration**: Run the following command on the target machine: + + ```bash + nixos-generate-config --no-filesystems --dir /tmp/config + ``` + +This creates the necessary configuration files under `/tmp/config/`. Copy +`/tmp/config/nixos/hardware-configuration.nix` to your local machine into the +same directory as `disko-config.nix`. + +## 3. Set NixOS version to use + +```nix +# default.nix +let + # replace nixos-24.11 with your preferred nixos version or revision from here: https://status.nixos.org/ + nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-24.11.tar.gz"; +in +import (nixpkgs + "/nixos/lib/eval-config.nix") { + modules = [ ./configuration.nix ]; +} +``` + +## 4. Write a NixOS configuration + +```nix +# configuration.nix +{ + imports = [ + "${fetchTarball "https://github.com/nix-community/disko/tarball/master"}/module.nix" + ./disko-config.nix + ./hardware-configuration.nix + ]; + # Replace this with the system of the installation target you want to install!!! + disko.devices.disk.main.device = "/dev/sda"; + + # Set this to the NixOS version that you have set in the previous step. + # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion . + system.stateVersion = "24.11"; +} +``` + +## 5. Build and deploy with nixos-anywhere + +Your current directory now should contain the following files from the previous +step: + +- `configuration.nix`, `default.nix`, `disko-config.nix` and + `hardware-configuration.nix` + +Run `nixos-anywhere` as follows: + +```bash +nixos-anywhere --store-paths $(nix-build -A config.system.build.formatScript -A config.system.build.toplevel --no-out-link) root@machine +``` diff --git a/launch/.terraform/modules/peertube.deploy/docs/logo.png b/launch/.terraform/modules/peertube.deploy/docs/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..434ad443ac1a065b53f74353187f7baaa45bcf29 GIT binary patch literal 29405 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/launch/.terraform/modules/peertube.deploy/docs/quickstart.md b/launch/.terraform/modules/peertube.deploy/docs/quickstart.md new file mode 100644 index 00000000..5eb1a10e --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/quickstart.md @@ -0,0 +1,334 @@ +# Quickstart Guide: nixos-anywhere + +**_Install NixOS everywhere via ssh_** + + + +[Documentation Index](./INDEX.md) + +## Introduction + +This guide documents a simple installation of NixOS using **nixos-anywhere** on +a target machine running x86_64 Linux with +[kexec](https://man7.org/linux/man-pages/man8/kexec.8.html) support. The example +used in this guide installs NixOS on a Hetzner cloud machine. The configuration +may be different for some other instances. We will be including further examples +in the [How To Guide](./howtos/INDEX.md) as and when they are available. + +You will need: + +- A [flake](https://wiki.nixos.org/wiki/Flakes) that controls the actions to be + performed +- A disk configuration containing details of the file system that will be + created on the new server. +- A target machine that is reachable via SSH, either using keys or a password, + and the privilege to either log in directly as root or a user with + password-less sudo. + +**nixos-anywhere** doesn’t need to be installed. You can run it directly from +[the Github repository.](https://github.com/nix-community/nixos-anywhere) + +Details of the flake, the disk configuration and the CLI command are discussed +below. + +## Steps required to run nixos-anywhere + +### 1. Enable Flakes + +Check if your nix has flakes enabled by running `nix flake`. It will tell you if +it's not. To enable flakes, refer to the +[NixOS Wiki](https://wiki.nixos.org/wiki/Flakes#enable-flakes). + +### 2. Initialize a Flake + +The easiest way to start is to copy our +[example flake.nix](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix) +into a new directory. This example is tailored for a virtual machine setup +similar to one on [Hetzner Cloud](https://www.hetzner.com/cloud), so you might +need to adapt it for your setup. + +If you already have a flake, you can use it by adding +[disko configuration](https://github.com/nix-community/disko?tab=readme-ov-file#how-to-use-disko) +to it. + +### 3. Configure your SSH key + +If you cloned +[our nixos-anywhere-example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/configuration.nix) +you will also replace the SSH key like this: In your configuration, locate the +line that reads: + +```bash +# change this to your ssh key + "CHANGE" +``` + +Replace the text `CHANGE` with your own SSH key. This is crucial, as you will +not be able to log into the target machine post-installation without it. If you +have a .pem file you can run + +```bash +ssh-keygen -y -f /path/to/your/key.pem +``` + +then paste the result in between the quotes like "ssh-rsa AAA..." + +### 4. Configure Storage + +In the same directory, create a file called `disk-config.nix`. This file will +define the disk layout for the +[disko](https://github.com/nix-community/disko/blob/master/docs/INDEX.md) tool, +which is used by nixos-anywhere to partition, format, and mount the disks. + +For a basic installation, you can copy the contents from the example provided +[here](https://github.com/nix-community/nixos-anywhere-examples/blob/main/disk-config.nix). +This configuration sets up a standard GPT (GUID Partition Table) that is +compatible with both EFI and BIOS systems and mounts the disk as `/dev/sda`. You +may need to adjust `/dev/sda` to match the correct disk on your machine. To +identify the disk, run the `lsblk` command and replace `sda` with the actual +disk name. + +For example, on this machine, we would select `/dev/nvme0n1` as the disk: + +``` +NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS +nvme0n1 259:0 0 1.8T 0 disk +``` + +If this setup does not match your requirements, you can choose an example that +better suits your disk layout from the +[disko examples](https://github.com/nix-community/disko/tree/master/example). +For more detailed information, refer to the +[disko documentation](https://github.com/nix-community/disko). + +### 5. Lock your Flake + +``` +nix flake lock +``` + +This will download your flake dependencies and make a `flake.lock` file that +describes how to reproducibly build your system. + +Optionally, you can commit these files to a repo such as Github, or you can +simply reference your local directory when you run **nixos-anywhere**. This +example uses a local directory on the source machine. + +### 6. Connectivity to the Target Machine + +**nixos-anywhere** will create a temporary SSH key to use for the installation. +If your SSH key is not found, you will be asked for your password. If you are +using a non-root user, you must have access to sudo without a password. To avoid +SSH password prompts, set the `SSHPASS` environment variable to your password +and add `--env-password` to the `nixos-anywhere` command. If providing a +specific SSH key through `-i` (identity_file), this key will then be used for +the installation and no temporary SSH key will be created. + +### 7. (Optional) Test your NixOS and Disko configuration + +Skip this step and continue with Step 8, if you don't have a hardware +configuration (hardware-configuration.nix or facter.json) generated yet or make +sure you don't import non-existing hardware-configuration.nix or facter.json +during running the vm test. + +The following command will automatically test your nixos configuration and run +disko inside a virtual machine, where + +- `` is the path to the directory or repository + containing `flake.nix` and `disk-config.nix` + +- `` must match the name that immediately follows the text + `nixosConfigurations.` in the flake, as indicated by the comment in the + [example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix). + +``` +nix run github:nix-community/nixos-anywhere -- --flake # --vm-test +``` + +### 8. Prepare Hardware Configuration + +If you're not using a virtual machine, it's recommended to allow +`nixos-anywhere` to generate a hardware configuration during installation. This +ensures that essential drivers, such as those required for disk detection, are +properly configured. + +To enable `nixos-anywhere` to integrate its generated configuration into your +NixOS setup, you need to include an import for the hardware configuration +beforehand. + +Here’s an example: + +```diff + nixosConfigurations.generic = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + disko.nixosModules.disko + ./configuration.nix ++ ./hardware-configuration.nix + ]; + }; +``` + +When running `nixos-anywhere`, this file is automatically generated by including +the following flags in your command: +`--generate-hardware-config nixos-generate-config ./hardware-configuration.nix`. +The second flag, `./hardware-configuration.nix`, specifies where +`nixos-generate-config` will store the configuration. Adjust this path to +reflect the location where you want the `hardware-configuration.nix` for this +machine to be saved. + +#### 8.1 nixos-facter + +As an alternative to `nixos-generate-config`, you can use the experimental +[nixos-facter](https://github.com/numtide/nixos-facter) command, which offers +more comprehensive hardware reports and advanced configuration options. + +To use `nixos-facter`, add the following to your flake inputs: + +```diff + { ++ inputs.nixos-facter-modules.url = "github:numtide/nixos-facter-modules"; + } +``` + +Next, import the module into your configuration and specify `facter.json` as the +path where the hardware report will be saved: + +```diff + nixosConfigurations.generic-nixos-facter = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + disko.nixosModules.disko + ./configuration.nix ++ nixos-facter-modules.nixosModules.facter ++ { config.facter.reportPath = ./facter.json } + ]; + }; +``` + +To generate the configuration for `nixos-facter` with `nixos-anywhere`, use the +following flags: `--generate-hardware-config nixos-facter ./facter.json`. The +second flag, `./facter.json`, specifies where `nixos-generate-config` will store +the hardware report. Adjust this path to suit the location where you want the +`facter.json` to be saved. + +### 9. Run it + +You can now run **nixos-anywhere** from the command line as shown below, where: + +- `` is the path to the directory or repository + containing `flake.nix` and `disk-config.nix` + +- `` must match the name that immediately follows the text + `nixosConfigurations.` in the flake, as indicated by the comment in the + [example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix). + +- `` is the IP address of the target machine. + +``` +nix run github:nix-community/nixos-anywhere -- --flake # --target-host root@ +``` + +The command would look  like this if you had created your files in a directory +named `/home/mydir/test` and the IP address of your target machine is +`37.27.18.135`: + +``` +nix run github:nix-community/nixos-anywhere -- --flake /home/mydir/test#hetzner-cloud --target-host root@37.27.18.135 +``` + +If you also need to generate hardware configuration amend flags for +nixos-generate-config: + +``` +nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-generate-config ./hardware-configuration.nix --flake # --target-host root@ +``` + +Or these flags if you are using nixos-facter instead: + +``` +nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-facter ./facter.json --flake # --target-host root@ +``` + +Adjust the location of `./hardware-configuration.nix` and `./facter.json` +accordingly. + +**nixos-anywhere** will then run, showing various output messages at each stage. +It may take some time to complete, depending on Internet speeds. It should +finish by showing the messages below before returning to the command prompt. + +``` +Installation finished. No error reported. +Warning: Permanently added '' (ED25519) to the list of known hosts +``` + +When this happens, the target server will have been overwritten with a new +installation of NixOS. Note that the server's public SSH key will have changed. + +If you have previously accessed this server using SSH, you may see the following +message the next time you try to log in to the target. + +``` +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! +Someone could be eavesdropping on you right now (man-in-the-middle attack)! +It is also possible that a host key has just been changed. +The fingerprint for the ED25519 key sent by the remote host is +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. +Please contact your system administrator. +Add correct host key in ~/.ssh/known_hosts to get rid of this message. +Offending ECDSA key in ~/.ssh/known_hosts:6 + remove with: + ssh-keygen -f ~/.ssh/known_hosts" -R "" +Host key for has changed and you have requested strict checking. +Host key verification failed. +``` + +This is because the `known_hosts` file in the `.ssh` directory now contains a +mismatch, since the server has been overwritten. To solve this, use a text +editor to remove the old entry from the `known_hosts` file (or use the command +`ssh-keygen -R `). The next connection attempt will then treat this +as a new server. + +The error message line `Offending ECDSA key in ~/.ssh/known_hosts:6` gives the +line number that needs to be removed from the `known_hosts` file (line 6 in this +example). + +# Finished! + +**nixos-anywhere**'s job is now done, as it is a tool to install NixOS onto the +target machine. + +Any future changes to the configuration should be made to your flake. You would +reference this flake when using the NixOS `nixos-rebuild` command or a separate +3rd party deployment tool of your choice i.e. +[deploy-rs](https://github.com/serokell/deploy-rs), +[colmena](https://github.com/zhaofengli/colmena), +[nixinate](https://github.com/MatthewCroughan/nixinate), +[clan](https://clan.lol/) (author's choice). + +To update on the machine locally (replace `` with your flake +i.e. `.#` if your flake is in the current directory): + +``` +nixos-rebuild switch --flake +``` + +To update remotely you will need to have configured an +[ssh server](https://search.nixos.org/options?show=services.sshd.enable) and +your ssh key for the +[root user](https://search.nixos.org/options?show=users.users.%3Cname%3E.openssh.authorizedKeys.keys): + +``` +nixos-rebuild switch --flake --target-host "root@" +``` + +See the Nix documentation for use of the flake +[URL-like syntax](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake#url-like-syntax). + +For more information on different use cases of **nixos-anywhere** please refer +to the [How to Guide](./howtos/INDEX.md), and for more technical information and +explanation of known error messages, refer to the +[Reference Manual](./reference.md). diff --git a/launch/.terraform/modules/peertube.deploy/docs/reference.md b/launch/.terraform/modules/peertube.deploy/docs/reference.md new file mode 100644 index 00000000..83916572 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/reference.md @@ -0,0 +1,137 @@ +# Reference Manual: nixos-anywhere + +**_Install NixOS everywhere via ssh_** + + + +[Documentation Index](./INDEX.md) + +TODO: Populate this guide properly + +## Contents + +[Command Line Usage](#command-line-usage) + +[Explanation of known error messages](#explanation-of-known-error-messages) + +## Command Line Usage + + + +``` +Usage: nixos-anywhere [options] [] + +Options: + +* -f, --flake + set the flake to install the system from. i.e. + nixos-anywhere --flake .#mymachine + Also supports variants: + nixos-anywhere --flake .#nixosConfigurations.mymachine.config.virtualisation.vmVariant +* --target-host + set the SSH target host to deploy onto. +* -i + selects which SSH private key file to use. +* -p, --ssh-port + set the ssh port to connect with +* --ssh-option + set an ssh option +* -L, --print-build-logs + print full build logs +* --env-password + set a password used by ssh-copy-id, the password should be set by + the environment variable SSHPASS +* -s, --store-paths + set the store paths to the disko-script and nixos-system directly + if this is given, flake is not needed +* --kexec + use another kexec tarball to bootstrap NixOS +* --kexec-extra-flags + extra flags to add into the call to kexec, e.g. "--no-sync" +* --ssh-store-setting + ssh store settings appended to the store URI, e.g. "compress true". needs to be URI encoded. +* --post-kexec-ssh-port + after kexec is executed, use a custom ssh port to connect. Defaults to 22 +* --copy-host-keys + copy over existing /etc/ssh/ssh_host_* host keys to the installation +* --extra-files + contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten + Copied files will be owned by root unless specified by --chown option. See documentation for details. +* --chown + change ownership of recursively. Recommended to use uid:gid as opposed to username:groupname for ownership. + Option can be specified more than once. +* --disk-encryption-keys + copy the contents of the file or pipe in local_path to remote_path in the installer environment, + after kexec but before installation. Can be repeated. +* --no-substitute-on-destination + disable passing --substitute-on-destination to nix-copy +* --debug + enable debug output +* --show-trace + show nix build traces +* --option + nix option to pass to every nix related command +* --from + URL of the source Nix store to copy the nixos and disko closure from +* --build-on-remote + build the closure on the remote machine instead of locally and copy-closuring it +* --vm-test + build the system and test the disk configuration inside a VM without installing it to the target. +* --generate-hardware-config nixos-facter|nixos-generate-config + generate a hardware-configuration.nix file using the specified backend and write it to the specified path. + The backend can be either 'nixos-facter' or 'nixos-generate-config'. +* --phases + comma separated list of phases to run. Default is: kexec,disko,install,reboot + kexec: kexec into the nixos installer + disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode + install: install the system + reboot: unmount the filesystems, export any ZFS pools and reboot the machine +* --disko-mode disko|mount|format + set the disko mode to format, mount or destroy. Default is disko. + disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode +* --no-disko-deps + This will only upload the disko script and not the partitioning tools dependencies. + Installers usually have dependencies available. + Use this option if your target machine has not enough RAM to store the dependencies in memory. +* --build-on auto|remote|local + sets the build on settings to auto, remote or local. Default is auto. + auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build + local: will build on the local host + remote: will build on the remote host +``` + +## Explanation of known error messages + +TODO: Add additional error messages and meanings. Fill in missing explanations + +This section lists known error messages and their explanations. Some +explanations may refer to the following CLI syntax: + +`nix run github:nix-community/nixos-anywhere -- --flake # root@` + +This list is not comprehensive. It's possible you may encounter errors that +originate from the underlying operating system. These should be documented in +the relevant operating system manual. + +| Id | Message | Explanation | +| -- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 1 | Failure unpacking initrd | You don't have enough RAM to hold `kexec` | +| 2 | Flake  does not provide attribute | The configuration name you specified in your flake URI is not defined as a NixOS configuration in your flake eg if your URI was mydir#myconfig, then myconfig should be included in the flake as `nixosConfigurations.myconfig` | +| 3 | Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri. | As for error #2 | +| | For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri | | +| 4 | Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already | TODO: Explain | +| 5 | ssh-host must be set |  has not been supplied | +| 6 | and must be existing store-paths | This occurs if the -s switch has been used to specify the disko script and store path correctly, and the scripts cannot be found at the given URI | +| 7 | flake must be set | This occurs if both the -flake option (use a flake) and the -s option (specify paths directly) have been omitted. Either one or the other must be specified. | +| 8 | no tar command found, but required to unpack kexec tarball | The destination machine does not have a `tar` command available. This is needed to unpack the `kexec`. | +| 9 | no setsid command found, but required to run the kexec script under a new session | The destination machine does not have the `setsid` command available | +| 10 | This script requires Linux as the operating system, but got | The destination machine is not running Linux | +| 11 | The default kexec image only support x86_64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information. | By default, `nixos-anywhere` uses its own `kexec` image, which will only run on x86_64 CPUs. For other CPU types, you can use your own `kexec` image instead. Refer to the [How To Guide](./howtos#using-your-own-kexec-image) for instructions. | +| 12 | Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri. | This is a `disko` error. As for Error #2 | +| | For example, to use the output diskoConfigurations.foo from the flake.nix, append \"#foo\" to the flake-uri. | | +| 13 | mode must be either create, mount or zap_create_mount | This is a `disko` error. The `disko` switches have not been used correctly. This could happen if you supplied your own `disko` script using the -s option | +| 14 | disko config must be an existing file or flake must be set | This is a `disko` error. This will happen if the `disko.devices` entry in your flake doesn't match the name of a file in the same location as your flake. | +| | | | +| | | | +| | | | +| | | | diff --git a/launch/.terraform/modules/peertube.deploy/docs/requirements.md b/launch/.terraform/modules/peertube.deploy/docs/requirements.md new file mode 100644 index 00000000..67b14f4d --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/docs/requirements.md @@ -0,0 +1,39 @@ +# System Requirements: nixos-anywhere + +**_Install NixOS everywhere via ssh_** + + + +[Documentation Index](./INDEX.md) + +## Requirements + +### Source Machine + +1. **Supported Systems:** + - Linux or macOS computers with Nix installed. + - NixOS + - Windows systems using WSL2. + +2. **Nix Installation:** If Nix is not yet installed on your system, refer to + the [nix installation page](https://nixos.org/download#download-nix). + +### Destination Machine + +The machine must be reachable over the public internet or local network. +Nixos-anywhere does not support wifi networks. If a VPN is needed, define a +custom installer via the --kexec flag which connects to your VPN. + +1. **Direct Boot Option:** + - Must be already running a NixOS installer. + +2. **Alternative Boot Options:** If not booting directly from a NixOS installer + image: + - **Architecture & Support:** Must be operating on: + - x86-64 or aarch64 Linux systems with kexec support. Note: While most + x86-64 Linux systems support kexec, if you're using an architecture other + than those mentioned, you may need to specify a + [different kexec image](./howtos/INDEX.md#using-your-own-kexec-image) + manually. + - **Memory Requirements:** + - At least 1 GB of RAM (excluding swap space). diff --git a/launch/.terraform/modules/peertube.deploy/flake.lock b/launch/.terraform/modules/peertube.deploy/flake.lock new file mode 100644 index 00000000..5a7232ca --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/flake.lock @@ -0,0 +1,132 @@ +{ + "nodes": { + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1741786315, + "narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=", + "owner": "nix-community", + "repo": "disko", + "rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "master", + "repo": "disko", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1741352980, + "narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixos-images": { + "inputs": { + "nixos-stable": [ + "nixos-stable" + ], + "nixos-unstable": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1741866599, + "narHash": "sha256-Re/T1Cjmiis0tdphj/Wjqt+c2RlMw/il7LBWzvwQPz0=", + "owner": "nix-community", + "repo": "nixos-images", + "rev": "63285ff93fc1daa2caac9f86e2302ae4edc5e84f", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-images", + "type": "github" + } + }, + "nixos-stable": { + "locked": { + "lastModified": 1741862977, + "narHash": "sha256-prZ0M8vE/ghRGGZcflvxCu40ObKaB+ikn74/xQoNrGQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "cdd2ef009676ac92b715ff26630164bb88fec4e0", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1742051767, + "narHash": "sha256-JpyjnalnIqJ7cvP8HzaoJN9/i2bDx83dToodHHjGuNg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "ec886d10b507760c90ed01e2eac7f0679d0a47ae", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "disko": "disko", + "flake-parts": "flake-parts", + "nixos-images": "nixos-images", + "nixos-stable": "nixos-stable", + "nixpkgs": "nixpkgs", + "treefmt-nix": "treefmt-nix" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1739829690, + "narHash": "sha256-mL1szCeIsjh6Khn3nH2cYtwO5YXG6gBiTw1A30iGeDU=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "3d0579f5cc93436052d94b73925b48973a104204", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/launch/.terraform/modules/peertube.deploy/flake.nix b/launch/.terraform/modules/peertube.deploy/flake.nix new file mode 100644 index 00000000..d60191cc --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/flake.nix @@ -0,0 +1,55 @@ +{ + description = "A universal nixos installer, just needs ssh access to the target system"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small"; + flake-parts = { + url = "github:hercules-ci/flake-parts"; + inputs.nixpkgs-lib.follows = "nixpkgs"; + }; + + # used for testing + disko = { + url = "github:nix-community/disko/master"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nixos-stable.url = "github:NixOS/nixpkgs/nixos-24.11"; + nixos-images.url = "github:nix-community/nixos-images"; + nixos-images.inputs.nixos-unstable.follows = "nixpkgs"; + nixos-images.inputs.nixos-stable.follows = "nixos-stable"; + + # used for development + treefmt-nix = { + url = "github:numtide/treefmt-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = + inputs: + inputs.flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ + "x86_64-linux" + "x86_64-darwin" + "aarch64-linux" + "aarch64-darwin" + ]; + imports = [ + ./src/flake-module.nix + ./tests/flake-module.nix + ./docs/flake-module.nix + # allow to disable treefmt in downstream flakes + ] ++ inputs.nixpkgs.lib.optional (inputs.treefmt-nix ? flakeModule) ./treefmt/flake-module.nix; + + perSystem = + { self', lib, ... }: + { + checks = + let + packages = lib.mapAttrs' (n: lib.nameValuePair "package-${n}") self'.packages; + devShells = lib.mapAttrs' (n: lib.nameValuePair "devShell-${n}") self'.devShells; + in + packages // devShells; + }; + }; +} diff --git a/launch/.terraform/modules/peertube.deploy/scripts/create-release.sh b/launch/.terraform/modules/peertube.deploy/scripts/create-release.sh new file mode 100755 index 00000000..7f203035 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/scripts/create-release.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env nix +#! nix shell nixpkgs#bash nixpkgs#gnused --command bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" +cd "$SCRIPT_DIR/.." + +version=${1:-} +if [[ -z $version ]]; then + echo "USAGE: $0 version" >&2 + exit 1 +fi + +if [[ "$(git symbolic-ref --short HEAD)" != "main" ]]; then + echo "must be on main branch" >&2 + exit 1 +fi + +# ensure we are up-to-date +uncommitted_changes=$(git diff --compact-summary) +if [[ -n $uncommitted_changes ]]; then + echo -e "There are uncommitted changes, exiting:\n${uncommitted_changes}" >&2 + exit 1 +fi +git pull git@github.com:nix-community/nixos-anywhere main +unpushed_commits=$(git log --format=oneline origin/main..main) +if [[ $unpushed_commits != "" ]]; then + echo -e "\nThere are unpushed changes, exiting:\n$unpushed_commits" >&2 + exit 1 +fi +sed -i -e "s!version = \".*\";!version = \"${version}\";!" src/default.nix +git add src/default.nix +nix-shell -p nix-fast-build --command "nix-fast-build --eval-workers 2" +git commit -m "bump version ${version}" +git tag "${version}" + +echo "now run 'git push --tags origin main'" diff --git a/launch/.terraform/modules/peertube.deploy/src/default.nix b/launch/.terraform/modules/peertube.deploy/src/default.nix new file mode 100644 index 00000000..c1719320 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/src/default.nix @@ -0,0 +1,63 @@ +{ + stdenv, + openssh, + gitMinimal, + nixVersions, + nix, + coreutils, + curl, + gnugrep, + gnutar, + gawk, + findutils, + gnused, + sshpass, + terraform-docs, + lib, + makeWrapper, + mkShellNoCC, +}: +let + runtimeDeps = [ + gitMinimal # for git flakes + # pinned because nix-copy-closure hangs if ControlPath provided for SSH: https://github.com/NixOS/nix/issues/8480 + (if lib.versionAtLeast nix.version "2.16" then nix else nixVersions.nix_2_16) + coreutils + curl # when uploading tarballs + gnugrep + gawk + findutils + gnused # needed by ssh-copy-id + sshpass # used to provide password for ssh-copy-id + gnutar # used to upload extra-files + ]; +in +stdenv.mkDerivation { + pname = "nixos-anywhere"; + version = "1.8.0"; + src = ./..; + nativeBuildInputs = [ makeWrapper ]; + installPhase = '' + install -D --target-directory=$out/libexec/nixos-anywhere/ -m 0755 src/*.sh + + # We prefer the system's openssh over our own, since it might come with features not present in ours: + # https://github.com/nix-community/nixos-anywhere/issues/62 + makeShellWrapper $out/libexec/nixos-anywhere/nixos-anywhere.sh $out/bin/nixos-anywhere \ + --prefix PATH : ${lib.makeBinPath runtimeDeps} --suffix PATH : ${lib.makeBinPath [ openssh ]} + ''; + + # Dependencies for our devshell + passthru.devShell = mkShellNoCC { + packages = runtimeDeps ++ [ + openssh + terraform-docs + ]; + }; + + meta = with lib; { + description = "Install nixos everywhere via ssh"; + homepage = "https://github.com/nix-community/nixos-anywhere"; + license = licenses.mit; + platforms = platforms.all; + }; +} diff --git a/launch/.terraform/modules/peertube.deploy/src/flake-module.nix b/launch/.terraform/modules/peertube.deploy/src/flake-module.nix new file mode 100644 index 00000000..d131219d --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/src/flake-module.nix @@ -0,0 +1,11 @@ +{ + perSystem = + { config, pkgs, ... }: + { + packages = { + nixos-anywhere = pkgs.callPackage ./. { }; + default = config.packages.nixos-anywhere; + }; + devShells.default = config.packages.nixos-anywhere.devShell; + }; +} diff --git a/launch/.terraform/modules/peertube.deploy/src/get-facts.sh b/launch/.terraform/modules/peertube.deploy/src/get-facts.sh new file mode 100755 index 00000000..80434422 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/src/get-facts.sh @@ -0,0 +1,23 @@ +#!/bin/sh +set -efu "${enableDebug:-}" +has() { + command -v "$1" >/dev/null && echo "y" || echo "n" +} +isNixos=$(if test -f /etc/os-release && grep -Eq 'ID(_LIKE)?="?nixos"?' /etc/os-release; then echo "y"; else echo "n"; fi) +cat </dev/null 2>/dev/null || ! ip -6 r g :: >/dev/null 2>/dev/null; then echo "n"; else echo "y"; fi) +hasTar=$(has tar) +hasCpio=$(has cpio) +hasSudo=$(has sudo) +hasDoas=$(has doas) +hasWget=$(has wget) +hasCurl=$(has curl) +hasSetsid=$(has setsid) +hasNixOSFacter=$(command -v nixos-facter >/dev/null && echo "y" || echo "n") +FACTS diff --git a/launch/.terraform/modules/peertube.deploy/src/nixos-anywhere.sh b/launch/.terraform/modules/peertube.deploy/src/nixos-anywhere.sh new file mode 100755 index 00000000..c6cadb98 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/src/nixos-anywhere.sh @@ -0,0 +1,880 @@ +#!/usr/bin/env bash +set -euo pipefail + +here=$(dirname "${BASH_SOURCE[0]}") +flake="" +flakeAttr="" +kexecUrl="" +kexecExtraFlags="" +sshStoreSettings="" +enableDebug="" +nixBuildFlags=() +diskoAttr="" +diskoScript="" +diskoMode="disko" +diskoDeps=y +nixosSystem="" +extraFiles="" +vmTest="n" +nixOptions=( + --extra-experimental-features 'nix-command flakes' + "--no-write-lock-file" +) +SSH_PRIVATE_KEY=${SSH_PRIVATE_KEY-} + +declare -A phases +phases[kexec]=1 +phases[disko]=1 +phases[install]=1 +phases[reboot]=1 + +hardwareConfigBackend=none +hardwareConfigPath= +sshPrivateKeyFile= +if [ -t 0 ]; then # stdin is a tty, we allow interactive input to ssh i.e. passwords + sshTtyParam="-t" +else + sshTtyParam="-T" +fi +sshConnection= +postKexecSshPort=22 +buildOnRemote=n +buildOn=auto +envPassword=n + +# Facts set by get-facts.sh +isOs= +isArch= +isKexec= +isInstaller= +isContainer= +hasIpv6Only= +hasTar= +hasCpio= +hasSudo= +hasDoas= +hasWget= +hasCurl= +hasSetsid= +hasNixOSFacter= + +sshKeyDir=$(mktemp -d) +trap 'rm -rf "$sshKeyDir"' EXIT +mkdir -p "$sshKeyDir" + +declare -A diskEncryptionKeys=() +declare -A extraFilesOwnership=() +declare -a nixCopyOptions=() +declare -a sshArgs=() + +showUsage() { + cat <] + +Options: + +* -f, --flake + set the flake to install the system from. i.e. + nixos-anywhere --flake .#mymachine + Also supports variants: + nixos-anywhere --flake .#nixosConfigurations.mymachine.config.virtualisation.vmVariant +* --target-host + set the SSH target host to deploy onto. +* -i + selects which SSH private key file to use. +* -p, --ssh-port + set the ssh port to connect with +* --ssh-option + set an ssh option +* -L, --print-build-logs + print full build logs +* --env-password + set a password used by ssh-copy-id, the password should be set by + the environment variable SSHPASS +* -s, --store-paths + set the store paths to the disko-script and nixos-system directly + if this is given, flake is not needed +* --kexec + use another kexec tarball to bootstrap NixOS +* --kexec-extra-flags + extra flags to add into the call to kexec, e.g. "--no-sync" +* --ssh-store-setting + ssh store settings appended to the store URI, e.g. "compress true". needs to be URI encoded. +* --post-kexec-ssh-port + after kexec is executed, use a custom ssh port to connect. Defaults to 22 +* --copy-host-keys + copy over existing /etc/ssh/ssh_host_* host keys to the installation +* --extra-files + contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten + Copied files will be owned by root unless specified by --chown option. See documentation for details. +* --chown + change ownership of recursively. Recommended to use uid:gid as opposed to username:groupname for ownership. + Option can be specified more than once. +* --disk-encryption-keys + copy the contents of the file or pipe in local_path to remote_path in the installer environment, + after kexec but before installation. Can be repeated. +* --no-substitute-on-destination + disable passing --substitute-on-destination to nix-copy +* --debug + enable debug output +* --show-trace + show nix build traces +* --option + nix option to pass to every nix related command +* --from + URL of the source Nix store to copy the nixos and disko closure from +* --build-on-remote + build the closure on the remote machine instead of locally and copy-closuring it +* --vm-test + build the system and test the disk configuration inside a VM without installing it to the target. +* --generate-hardware-config nixos-facter|nixos-generate-config + generate a hardware-configuration.nix file using the specified backend and write it to the specified path. + The backend can be either 'nixos-facter' or 'nixos-generate-config'. +* --phases + comma separated list of phases to run. Default is: kexec,disko,install,reboot + kexec: kexec into the nixos installer + disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode + install: install the system + reboot: unmount the filesystems, export any ZFS pools and reboot the machine +* --disko-mode disko|mount|format + set the disko mode to format, mount or destroy. Default is disko. + disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode +* --no-disko-deps + This will only upload the disko script and not the partitioning tools dependencies. + Installers usually have dependencies available. + Use this option if your target machine has not enough RAM to store the dependencies in memory. +* --build-on auto|remote|local + sets the build on settings to auto, remote or local. Default is auto. + auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build + local: will build on the local host + remote: will build on the remote host +USAGE +} + +abort() { + echo "aborted: $*" >&2 + exit 1 +} + +step() { + echo "### $* ###" +} + +parseArgs() { + local substituteOnDestination=y + local printBuildLogs=n + local buildOnRemote=n + while [[ $# -gt 0 ]]; do + case "$1" in + -f | --flake) + flake=$2 + shift + ;; + --target-host) + sshConnection=$2 + shift + ;; + -i) + sshPrivateKeyFile=$2 + shift + ;; + -p | --ssh-port) + sshArgs+=("-p" "$2") + shift + ;; + --ssh-option) + sshArgs+=("-o" "$2") + shift + ;; + -L | --print-build-logs) + printBuildLogs=y + ;; + -s | --store-paths) + diskoScript=$(readlink -f "$2") + nixosSystem=$(readlink -f "$3") + shift + shift + ;; + --generate-hardware-config) + if [[ $# -lt 3 ]]; then + abort "Missing arguments for --generate-hardware-config " + fi + case "$2" in + nixos-facter | nixos-generate-config) + hardwareConfigBackend=$2 + ;; + *) + abort "Unknown hardware config backend: $2" + ;; + esac + hardwareConfigPath=$3 + shift + shift + ;; + -t | --tty) + echo "the '$1' flag is deprecated, a tty is now detected automatically" >&2 + ;; + --help) + showUsage + exit 0 + ;; + --kexec) + kexecUrl=$2 + shift + ;; + --kexec-extra-flags) + kexecExtraFlags=$2 + shift + ;; + --ssh-store-setting) + key=$2 + shift + value=$2 + shift + sshStoreSettings+="$sshStoreSettings$key=$value&" + shift + ;; + --post-kexec-ssh-port) + postKexecSshPort=$2 + shift + ;; + --copy-host-keys) + copyHostKeys=y + ;; + --show-trace) + nixBuildFlags+=("--show-trace") + ;; + --debug) + enableDebug="-x" + printBuildLogs=y + set -x + ;; + --disko-mode) + case "$2" in + format | mount | disko) + diskoMode=$2 + ;; + *) + abort "Supported values for --disko-mode are disko, mount and format. Unknown mode : $2" + ;; + esac + + shift + ;; + --no-disko-deps) + diskoDeps=n + ;; + --build-on) + case "$2" in + auto | local | remote) + buildOn=$2 + ;; + *) + abort "Supported values for --build-on are auto, local and remote. Unknown mode : $2" + ;; + esac + + shift + ;; + --extra-files) + extraFiles=$2 + shift + ;; + --chown) + extraFilesOwnership["$2"]="$3" + shift + shift + ;; + --disk-encryption-keys) + diskEncryptionKeys["$2"]="$3" + shift + shift + ;; + --phases) + phases[kexec]=0 + phases[disko]=0 + phases[install]=0 + phases[reboot]=0 + IFS=, read -r -a phaseList <<<"$2" + for phase in "${phaseList[@]}"; do + if [[ ${phases[$phase]:-unset} == unset ]]; then + abort "Unknown phase: $phase" + fi + phases[$phase]=1 + done + shift + ;; + --stop-after-disko) + echo "WARNING: --stop-after-disko is deprecated, use --phases kexec,disko instead" 2>&1 + phases[kexec]=1 + phases[disko]=1 + phases[install]=0 + phases[reboot]=0 + ;; + --no-reboot) + echo "WARNING: --no-reboot is deprecated, use --phases kexec,disko,install instead" 2>&1 + phases[kexec]=1 + phases[disko]=1 + phases[install]=1 + phases[reboot]=0 + ;; + --from) + nixCopyOptions+=("--from" "$2") + shift + ;; + --option) + key=$2 + shift + value=$2 + shift + nixOptions+=("--option" "$key" "$value") + ;; + --no-substitute-on-destination) + substituteOnDestination=n + ;; + --build-on-remote) + echo "WARNING: --build-on-remote is deprecated, use --build-on remote instead" 2>&1 + buildOnRemote=y + buildOn="remote" + ;; + --env-password) + envPassword=y + ;; + --vm-test) + vmTest=y + ;; + *) + if [[ -z ${sshConnection} ]]; then + sshConnection="$1" + else + showUsage + exit 1 + fi + ;; + esac + shift + done + + diskoAttr="${diskoMode}Script" + + if [[ ${diskoDeps} == "n" ]]; then + diskoAttr="${diskoAttr}NoDeps" + fi + + if [[ ${printBuildLogs} == "y" ]]; then + nixOptions+=("-L") + fi + + if [[ $substituteOnDestination == "y" ]]; then + nixCopyOptions+=("--substitute-on-destination") + fi + + if [[ $vmTest == "n" ]] && [[ -z ${sshConnection} ]]; then + abort "ssh-host must be set" + fi + + if [[ $buildOn == "local" ]] && [[ $buildOnRemote == "y" ]]; then + abort "Conflicting flags: --build-on local and --build-on-remote used." + fi + + if [[ -n ${flake} ]]; then + if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then + flake="${BASH_REMATCH[1]}" + flakeAttr="${BASH_REMATCH[2]}" + fi + if [[ -z ${flakeAttr} ]]; then + echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri." >&2 + echo 'For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri.' >&2 + exit 1 + fi + + # Support .#foo shorthand + if [[ $flakeAttr != nixosConfigurations.* ]]; then + flakeAttr="nixosConfigurations.\"$flakeAttr\".config" + fi + fi + +} + +# ssh wrapper +runSshNoTty() { + ssh -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@" +} +runSshTimeout() { + timeout 10 ssh -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@" +} +runSsh() { + ssh "$sshTtyParam" -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@" +} + +nixCopy() { + NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $sshKeyDir/nixos-anywhere ${sshArgs[*]}" nix copy \ + "${nixOptions[@]}" \ + "${nixCopyOptions[@]}" \ + "$@" +} +nixBuild() { + NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $sshKeyDir/nixos-anywhere ${sshArgs[*]}" nix build \ + --print-out-paths \ + --no-link \ + "${nixBuildFlags[@]}" \ + "${nixOptions[@]}" \ + "$@" +} + +runVmTest() { + if [[ -z ${flakeAttr} ]]; then + echo "--vm-test is not supported with --store-paths" >&2 + echo "Please use --flake instead or build config.system.build.installTest of your nixos configuration manually" >&2 + exit 1 + fi + + if [[ ${buildOn} == "remote" ]]; then + echo "--vm-test is not supported with --build-on-remote" >&2 + exit 1 + fi + if [[ -n ${extraFiles} ]]; then + echo "--vm-test is not supported with --extra-files" >&2 + exit 1 + fi + if [ ${#diskEncryptionKeys[@]} -gt 0 ]; then + echo "--vm-test is not supported with --disk-encryption-keys" >&2 + exit 1 + fi + nix build \ + --print-out-paths \ + --no-link \ + -L \ + "${nixBuildFlags[@]}" \ + "${nixOptions[@]}" \ + "${flake}#${flakeAttr}.system.build.installTest" +} + +uploadSshKey() { + # ssh-copy-id requires this directory + mkdir -p "$HOME/.ssh/" + if [[ -n ${sshPrivateKeyFile} ]]; then + cp "$sshPrivateKeyFile" "$sshKeyDir/nixos-anywhere" + ssh-keygen -y -f "$sshKeyDir/nixos-anywhere" >"$sshKeyDir/nixos-anywhere.pub" + else + # we generate a temporary ssh keypair that we can use during nixos-anywhere + ssh-keygen -t ed25519 -f "$sshKeyDir"/nixos-anywhere -P "" -C "nixos-anywhere" >/dev/null + fi + + declare -a sshCopyIdArgs + if [[ -n ${sshPrivateKeyFile} ]]; then + unset SSH_AUTH_SOCK # don't use system agent if key was supplied + sshCopyIdArgs+=(-o "IdentityFile=${sshPrivateKeyFile}" -f) + fi + + step Uploading install SSH keys + until + if [[ ${envPassword} == y ]]; then + sshpass -e \ + ssh-copy-id \ + -i "$sshKeyDir"/nixos-anywhere.pub \ + -o ConnectTimeout=10 \ + -o UserKnownHostsFile=/dev/null \ + -o IdentitiesOnly=yes \ + -o StrictHostKeyChecking=no \ + "${sshCopyIdArgs[@]}" \ + "${sshArgs[@]}" \ + "$sshConnection" + else + ssh-copy-id \ + -i "$sshKeyDir"/nixos-anywhere.pub \ + -o ConnectTimeout=10 \ + -o UserKnownHostsFile=/dev/null \ + -o StrictHostKeyChecking=no \ + "${sshCopyIdArgs[@]}" \ + "${sshArgs[@]}" \ + "$sshConnection" + fi + do + sleep 3 + done +} + +importFacts() { + step Gathering machine facts + local facts filteredFacts + if ! facts=$(runSsh -o ConnectTimeout=10 enableDebug=$enableDebug sh -- <"$here"/get-facts.sh); then + exit 1 + fi + filteredFacts=$(echo "$facts" | grep -E '^(has|is)[A-Za-z0-9_]+=\S+') + if [[ -z $filteredFacts ]]; then + abort "Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already" + fi + # make facts available in script + # shellcheck disable=SC2046 + export $(echo "$filteredFacts" | xargs) + + for var in isOs isArch isKexec isInstaller isContainer hasIpv6Only hasTar hasCpio hasSudo hasDoas hasWget hasCurl hasSetsid; do + if [[ -z ${!var} ]]; then + abort "Failed to retrieve fact $var from host" + fi + done +} + +checkBuildLocally() { + local system extraPlatforms machineSystem + system="$(nix --extra-experimental-features 'nix-command flakes' config show system)" + extraPlatforms="$(nix --extra-experimental-features 'nix-command flakes' config show extra-platforms)" + + if [[ $# -gt 0 ]]; then + machineSystem=$1 + elif [[ -n ${nixosSystem} ]]; then + machineSystem="$(cat "${nixosSystem}"/system)" + else + machineSystem="$(nix --extra-experimental-features 'nix-command flakes' eval --raw "${flake}"#"${flakeAttr}".pkgs.system 2>/dev/null || echo "unknown")" + if [[ ${machineSystem} == "unknown" ]]; then + buildOn=auto + return + fi + fi + + if [[ ${system} == "${machineSystem}" ]]; then + buildOn=local + return + fi + + if [[ ${extraPlatforms} == "*${machineSystem}*" ]]; then + buildOn=local + return + fi + + local entropy + entropy="$(date +'%Y%m%d%H%M%S')" + if nix build \ + -L \ + "${nixOptions[@]}" \ + --expr \ + "derivation { system = \"$system\"; name = \"env-$entropy\"; builder = \"/bin/sh\"; args = [ \"-c\" \"echo > \$out\" ]; }"; then + # The local build failed + buildOn=local + fi + + buildOn=remote +} + +generateHardwareConfig() { + local maybeSudo="$maybeSudo" + mkdir -p "$(dirname "$hardwareConfigPath")" + case "$hardwareConfigBackend" in + nixos-facter) + if [[ ${isInstaller} == "y" ]]; then + if [[ ${hasNixOSFacter} == "n" ]]; then + abort "nixos-facter is not available in booted installer, use nixos-generate-config. For nixos-facter, you may want to boot an installer image from here instead: https://github.com/nix-community/nixos-images" + fi + else + maybeSudo="" + fi + + step "Generating hardware-configuration.nix using nixos-facter" + runSshNoTty -o ConnectTimeout=10 ${maybeSudo} "nixos-facter" >"$hardwareConfigPath" + ;; + nixos-generate-config) + step "Generating hardware-configuration.nix using nixos-generate-config" + runSshNoTty -o ConnectTimeout=10 nixos-generate-config --show-hardware-config --no-filesystems >"$hardwareConfigPath" + ;; + *) + abort "Unknown hardware config backend: $hardwareConfigBackend" + ;; + esac + + # to make sure nix knows about the new file + if command -v git >/dev/null; then + # handle relative paths + hardwareConfigPath="$(realpath "$hardwareConfigPath")" + pushd "$(dirname "$hardwareConfigPath")" + if git rev-parse --is-inside-work-tree >/dev/null; then + git add --intent-to-add --force -- "$hardwareConfigPath" + fi + popd + fi +} + +runKexec() { + if [[ ${isKexec} == "y" ]] || [[ ${isInstaller} == "y" ]]; then + return + fi + + if [[ ${isContainer} != "none" ]]; then + echo "WARNING: This script does not support running from a '${isContainer}' container. kexec will likely not work" >&2 + fi + + if [[ $kexecUrl == "" ]]; then + case "${isArch}" in + x86_64 | aarch64) + kexecUrl="https://github.com/nix-community/nixos-images/releases/download/nixos-24.11/nixos-kexec-installer-noninteractive-${isArch}-linux.tar.gz" + ;; + *) + abort "Unsupported architecture: ${isArch}. Our default kexec images only support x86_64 and aarch64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information." + ;; + esac + fi + + step Switching system into kexec + runSsh sh < $path" <"${diskEncryptionKeys[$path]}" + done + if [[ -n ${diskoScript} ]]; then + nixCopy --to "ssh://$sshConnection?$sshStoreSettings" "$diskoScript" + elif [[ ${buildOn} == "remote" ]]; then + step Building disko script + # We need to do a nix copy first because nix build doesn't have --no-check-sigs + # Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359 + nixCopy --to "ssh://$sshConnection?$sshStoreSettings" "${flake}#${flakeAttr}.system.build.${diskoMode}Script" \ + --derivation --no-check-sigs + # If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store` + diskoScript=$( + nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}" \ + --eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir%2Fnixos-anywhere&$sshStoreSettings" + ) + fi + + step Formatting hard drive with disko + runSsh "$diskoScript" +} + +nixosInstall() { + local nixosSystem=$1 + if [[ -n ${nixosSystem} ]]; then + step Uploading the system closure + nixCopy --to "ssh://$sshConnection?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" "$nixosSystem" + elif [[ ${buildOn} == "remote" ]]; then + step Building the system closure + # We need to do a nix copy first because nix build doesn't have --no-check-sigs + # Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359 + nixCopy --to "ssh://$sshConnection?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" "${flake}#${flakeAttr}.system.build.toplevel" \ + --derivation --no-check-sigs + # If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store` + nixosSystem=$( + nixBuild "${flake}#${flakeAttr}.system.build.toplevel" \ + --eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir%2Fnixos-anywhere&remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" + ) + fi + + if [[ -n ${extraFiles} ]]; then + step Copying extra files + tar -C "$extraFiles" -cpf- . | runSsh "tar -C /mnt -xf- --no-same-owner" + + runSsh "chmod 755 /mnt" # tar also changes permissions of /mnt + fi + + if [[ ${#extraFilesOwnership[@]} -gt 0 ]]; then + # shellcheck disable=SC2016 + printf "%s\n" "${!extraFilesOwnership[@]}" "${extraFilesOwnership[@]}" | pr -2t | runSsh 'while read file ownership; do chown -R "$ownership" "/mnt/$file"; done' + fi + + step Installing NixOS + runSsh sh </dev/null && [ "\$(zpool list)" != "no pools available" ]; then + # we always want to export the zfs pools so people can boot from it without force import + umount -Rv /mnt/ + swapoff -a + zpool export -a || true + fi + nohup sh -c 'sleep 6 && reboot' >/dev/null & +fi +SSH + +} + +main() { + parseArgs "$@" + + if [[ ${vmTest} == y ]]; then + if [[ ${hardwareConfigBackend} != "none" ]]; then + abort "--vm-test is not supported with --generate-hardware-config. You need to generate the hardware configuration before you can run the VM test." >&2 + fi + runVmTest + exit 0 + fi + + if [[ ${buildOn} == "auto" ]]; then + checkBuildLocally + fi + + # parse flake nixos-install style syntax, get the system attr + if [[ -n ${flake} ]]; then + if [[ ${buildOn} == "local" ]] && [[ ${hardwareConfigBackend} == "none" ]]; then + if [[ ${phases[disko]} == 1 ]]; then + diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}") + fi + if [[ ${phases[install]} == 1 ]]; then + nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel") + fi + fi + elif [[ -n ${diskoScript} ]] && [[ -n ${nixosSystem} ]]; then + if [[ ! -e ${diskoScript} ]] || [[ ! -e ${nixosSystem} ]]; then + abort "${diskoScript} and ${nixosSystem} must be existing store-paths" + fi + else + abort "--flake or --store-paths must be set" + fi + + if [[ -n ${SSH_PRIVATE_KEY} ]] && [[ -z ${sshPrivateKeyFile} ]]; then + # $sshKeyDir is getting deleted on trap EXIT + sshPrivateKeyFile="$sshKeyDir/from-env" + ( + umask 077 + printf '%s\n' "$SSH_PRIVATE_KEY" >"$sshPrivateKeyFile" + ) + fi + + sshSettings=$(ssh "${sshArgs[@]}" -G "${sshConnection}") + sshUser=$(echo "$sshSettings" | awk '/^user / { print $2 }') + sshHost=$(echo "$sshSettings" | awk '/^hostname / { print $2 }') + + uploadSshKey + + importFacts + + if [[ ${hasTar-n} == "n" ]]; then + abort "no tar command found, but required to unpack kexec tarball" + fi + + if [[ ${hasCpio-n} == "n" ]]; then + abort "no cpio command found, but required to build the new initrd" + fi + + if [[ ${hasSetsid-n} == "n" ]]; then + abort "no setsid command found, but required to run the kexec script under a new session" + fi + + maybeSudo="" + if [[ ${hasSudo-n} == "y" ]]; then + maybeSudo="sudo" + elif [[ ${hasDoas-n} == "y" ]]; then + maybeSudo="doas" + fi + + if [[ ${isOs} != "Linux" ]]; then + abort "This script requires Linux as the operating system, but got $isOs" + fi + + if [[ ${phases[kexec]} == 1 ]]; then + runKexec + fi + + if [[ ${hardwareConfigBackend} != "none" ]]; then + generateHardwareConfig + fi + + # Before we do not have a valid hardware configuration we don't know the machine system + if [[ ${buildOn} == "auto" ]]; then + local remoteSystem + remoteSystem=$(runSshNoTty -o ConnectTimeout=10 nix --extra-experimental-features nix-command config show system) + checkBuildLocally "${remoteSystem}" + # if we cannot figure it out at this point, we will build on the remote host + if [[ ${buildOn} == "auto" ]]; then + buildOn=remote + fi + fi + + if [[ ${buildOn} != "remote" ]] && [[ -n ${flake} ]] && [[ -z ${diskoScript} ]]; then + if [[ ${phases[disko]} == 1 ]]; then + diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}") + fi + if [[ ${phases[install]} == 1 ]]; then + nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel") + fi + fi + + # Installation will fail if non-root user is used for installer. + # Switch to root user by copying authorized_keys. + if [[ ${isInstaller} == "y" ]] && [[ ${sshUser} != "root" ]]; then + # Allow copy to fail if authorized_keys does not exist, like if using /etc/ssh/authorized_keys.d/ + runSsh "${maybeSudo} mkdir -p /root/.ssh; ${maybeSudo} cp ~/.ssh/authorized_keys /root/.ssh || true" + sshConnection="root@${sshHost}" + fi + + if [[ ${phases[disko]} == 1 ]]; then + runDisko "$diskoScript" + fi + + if [[ ${phases[install]} == 1 ]]; then + nixosInstall "$nixosSystem" + fi + + if [[ ${phases[reboot]} == 1 ]]; then + step Waiting for the machine to become unreachable due to reboot + while runSshTimeout -- exit 0; do sleep 1; done + fi + + step "Done!" +} + +main "$@" diff --git a/launch/.terraform/modules/peertube.deploy/terraform/README.md b/launch/.terraform/modules/peertube.deploy/terraform/README.md new file mode 100644 index 00000000..2d66b1a8 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/README.md @@ -0,0 +1,21 @@ +# NixOS-Anywhere Terraform Modules Overview + +The nixos-Anywhere terraform modules allow you to use Terraform for installing +and updating NixOS. It simplifies the deployment process by integrating +nixos-anywhere functionality. + +Here's a brief overview of each module: + +- **[All-in-One](all-in-one.md)**: This is a consolidated module that first + installs NixOS using nixos-anywhere and then keeps it updated with + nixos-rebuild. If you choose this, you won't need additional deployment tools + like colmena. +- **[Install](install.md)**: This module focuses solely on installing NixOS via + nixos-anywhere. +- **[NixOS-Rebuild](nixos-rebuild.md)**: Use this module to remotely update an + existing NixOS machine using nixos-rebuild. +- **[Nix-Build](nix-build.md)**: This is a handy helper module designed to build + a flake attribute or an attribute from a nix file. + +For detailed information and usage examples, click on the respective module +links above. diff --git a/launch/.terraform/modules/peertube.deploy/terraform/all-in-one.md b/launch/.terraform/modules/peertube.deploy/terraform/all-in-one.md new file mode 100644 index 00000000..c7279cf2 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/all-in-one.md @@ -0,0 +1,235 @@ +# All-in-one + +Combines the install and nixos-rebuild module in one interface to install NixOS +with nixos-anywhere and then keep it up-to-date with nixos-rebuild. + +## Example + +```hcl +locals { + ipv4 = "192.0.2.1" +} + +module "deploy" { + source = "github.com/nix-community/nixos-anywhere//terraform/all-in-one" + # with flakes + nixos_system_attr = ".#nixosConfigurations.mymachine.config.system.build.toplevel" + nixos_partitioner_attr = ".#nixosConfigurations.mymachine.config.system.build.diskoScript" + # without flakes + # file can use (pkgs.nixos []) function from nixpkgs + #file = "${path.module}/../.." + #nixos_system_attr = "config.system.build.toplevel" + #nixos_partitioner_attr = "config.system.build.diskoScript" + + target_host = local.ipv4 + # when instance id changes, it will trigger a reinstall + instance_id = local.ipv4 + # useful if something goes wrong + # debug_logging = true + # build the closure on the remote machine instead of locally + # build_on_remote = true + # script is below + extra_files_script = "${path.module}/decrypt-ssh-secrets.sh" + disk_encryption_key_scripts = [{ + path = "/tmp/secret.key" + # script is below + script = "${path.module}/decrypt-zfs-key.sh" + }] + # Optional, arguments passed to special_args here will be available from a NixOS module in this example the `terraform` argument: + # { terraform, ... }: { + # networking.interfaces.enp0s3.ipv4.addresses = [{ address = terraform.ip; prefixLength = 24; }]; + # } + # Note that this will means that your NixOS configuration will always depend on terraform! + # Skip to `Pass data persistently to the NixOS` for an alternative approach + #special_args = { + # terraform = { + # ip = "192.0.2.0" + # } + #} +} +``` + +_Note:_ You need to mark scripts as executable (`chmod +x`) + +### ./decrypt-ssh-secrets.sh + +```bash +#!/usr/bin/env bash + +mkdir -p etc/ssh var/lib/secrets + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +umask 0177 +sops --extract '["initrd_ssh_key"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >./var/lib/secrets/initrd_ssh_key + +# restore umask +umask 0022 + +for keyname in ssh_host_rsa_key ssh_host_rsa_key.pub ssh_host_ed25519_key ssh_host_ed25519_key.pub; do + if [[ $keyname == *.pub ]]; then + umask 0133 + else + umask 0177 + fi + sops --extract '["'$keyname'"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >"./etc/ssh/$keyname" +done +``` + +### ./decrypt-zfs-key.sh + +```bash +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +cd "$SCRIPT_DIR" +sops --extract '["zfs-key"]' --decrypt "$SCRIPT_DIR/secrets.yaml" +``` + +## See also + +- [nixos-wiki setup](https://github.com/NixOS/nixos-wiki-infra/blob/main/terraform/nixos-wiki/main.tf) + for hetzner-cloud + +## Pass data persistently to the NixOS + +This guide outlines how to pass data from Terraform to NixOS by generating a +file during Terraform execution and including it in your NixOS configuration. +This approach works well if your Terraform and NixOS configurations are stored +in the same Git repository. + +### Why Use This Method? + +This method provides a straightforward way to transfer values from Terraform to +NixOS without relying on special_args. + +- **Advantages**: + - You can continue to use nix build or nixos-rebuild to evaluate your + configuration without interruption. Simplifies configuration management by + centralizing state in a single repository. +- **Disadvantages**: + - Deploying new machines requires tracking additional state. Every time + Terraform updates the JSON file, you'll need to commit these changes to your + repository. + +### Implementation + +Add the following snippet to your Terraform configuration to create and manage a +JSON file containing the necessary variables for NixOS. This file will be +automatically added to your Git repository, ensuring the data persists. + +Assuming you have your terraform and nixos configuration in the same git +repository. You can use the following snippet to `git add` a file generated by +`terraform` during execution to pass data from terraform to NixOS. These changes +should be committed afterwards. This is an alternative over using +`special_args`. Advantage: you can still use nix build or nixos-rebuild on your +flake to evaluate your configuration. Disadvantage: Deploying new machines also +means you need to track additional state and make additional commits whenever +terraform updates the json file. + +```hcl +locals { + nixos_vars_file = "nixos-vars.json" # Path to the JSON file containing NixOS variables + nixos_vars = { + ip = "192.0.2.0" # Replace with actual variables + } +} +resource "local_file" "nixos_vars" { + content = jsonencode(local.nixos_vars) # Converts variables to JSON + filename = local.nixos_vars_file # Specifies the output file path + file_permission = "600" + + # Automatically adds the generated file to Git + provisioner "local-exec" { + interpreter = ["bash", "-c"] + command = "git add -f '${local.nixos_vars_file}'" + } +} +``` + +After applying the Terraform changes, ensure you commit the updated +`nixos-vars.json` file to your Git repository: + +```bash +git commit -m "Update NixOS variables from Terraform" +``` + +You can import this json file into your configuration like this: + +```nix +let + nixosVars = builtins.fromJSON (builtins.readFile ./nixos-vars.json); +in +{ + # Example usage of imported variables + networking.hostName = "example-machine"; + networking.interfaces.eth0.ipv4.addresses = [ + { + address = nixosVars.ip; # Use the IP from nixos-vars.json + prefixLength = 24; + } + ]; +} +``` + + + +## Requirements + +No requirements. + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +| -------------------------------------------------------------------------------------- | ---------------- | ------- | +| [install](#module_install) | ../install | n/a | +| [nixos-rebuild](#module_nixos-rebuild) | ../nixos-rebuild | n/a | +| [partitioner-build](#module_partitioner-build) | ../nix-build | n/a | +| [system-build](#module_system-build) | ../nix-build | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +| --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | :------: | +| [debug\_logging](#input_debug_logging) | Enable debug logging | `bool` | `false` | no | +| [deployment\_ssh\_key](#input_deployment_ssh_key) | Content of private key used to deploy to the target\_host after initial installation. To ensure maximum security, it is advisable to connect to your host using ssh-agent instead of relying on this variable | `string` | `null` | no | +| [disk\_encryption\_key\_scripts](#input_disk_encryption_key_scripts) | Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system |
list(object({
path = string
script = string
}))
| `[]` | no | +| [extra\_environment](#input_extra_environment) | Extra environment variables to be set during installation. This can be useful to set extra variables for the extra\_files\_script or disk\_encryption\_key\_scripts | `map(string)` | `{}` | no | +| [extra\_files\_script](#input_extra_files_script) | A script that should place files in the current directory that will be copied to the targets / directory | `string` | `null` | no | +| [file](#input_file) | Nix file containing the nixos\_system\_attr and nixos\_partitioner\_attr. Use this if you are not using flake | `string` | `null` | no | +| [install\_port](#input_install_port) | SSH port used to connect to the target\_host, before installing NixOS. If null than the value of `target_port` is used | `string` | `null` | no | +| [install\_ssh\_key](#input_install_ssh_key) | Content of private key used to connect to the target\_host during initial installation | `string` | `null` | no | +| [install\_user](#input_install_user) | SSH user used to connect to the target\_host, before installing NixOS. If null than the value of `target_host` is used | `string` | `null` | no | +| [instance\_id](#input_instance_id) | The instance id of the target\_host, used to track when to reinstall the machine | `string` | `null` | no | +| [kexec\_tarball\_url](#input_kexec_tarball_url) | NixOS kexec installer tarball url | `string` | `null` | no | +| [nix\_options](#input_nix_options) | the options of nix | `map(string)` | `{}` | no | +| [nixos\_facter\_path](#input_nixos_facter_path) | Path to which to write a `facter.json` generated by `nixos-facter`. | `string` | `""` | no | +| [nixos\_generate\_config\_path](#input_nixos_generate_config_path) | Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. | `string` | `""` | no | +| [nixos\_partitioner\_attr](#input_nixos_partitioner_attr) | Nixos partitioner and mount script i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.diskoNoDeps or just your-evaluated.config.system.build.diskNoDeps. `config.system.build.diskNoDeps` is provided by the disko nixos module | `string` | n/a | yes | +| [nixos\_system\_attr](#input_nixos_system_attr) | The nixos system to deploy i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.toplevel or just your-evaluated-nixos.config.system.build.toplevel if you are not using flakes | `string` | n/a | yes | +| [no\_reboot](#input_no_reboot) | DEPRECATED: Use `phases` instead. Do not reboot after installation | `bool` | `false` | no | +| [phases](#input_phases) | Phases to run. See `nixos-anywhere --help` for more information | `set(string)` |
[
"kexec",
"disko",
"install",
"reboot"
]
| no | +| [special\_args](#input_special_args) | A map exposed as NixOS's `specialArgs` thru a file. | `any` | `{}` | no | +| [build\_on\_remote](#input_build_on_remote) | Build the closure on the remote machine instead of building it locally and copying it over | `bool` | `false` | no | +| [stop\_after\_disko](#input_stop_after_disko) | DEPRECATED: Use `phases` instead. Exit after disko formatting | `bool` | `false` | no | +| [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes | +| [target\_port](#input_target_port) | SSH port used to connect to the target\_host after installing NixOS. If install\_port is not set than this port is also used before installing. | `number` | `22` | no | +| [target\_user](#input_target_user) | SSH user used to connect to the target\_host after installing NixOS. If install\_user is not set than this user is also used before installing. | `string` | `"root"` | no | + +## Outputs + +| Name | Description | +| ----------------------------------------------------- | ----------- | +| [result](#output_result) | n/a | + + diff --git a/launch/.terraform/modules/peertube.deploy/terraform/all-in-one/main.tf b/launch/.terraform/modules/peertube.deploy/terraform/all-in-one/main.tf new file mode 100644 index 00000000..fa5d7eb3 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/all-in-one/main.tf @@ -0,0 +1,64 @@ +module "system-build" { + source = "../nix-build" + attribute = var.nixos_system_attr + file = var.file + nix_options = var.nix_options + special_args = var.special_args +} + +module "partitioner-build" { + source = "../nix-build" + attribute = var.nixos_partitioner_attr + file = var.file + nix_options = var.nix_options + special_args = var.special_args +} + +locals { + install_user = var.install_user == null ? var.target_user : var.install_user + install_port = var.install_port == null ? var.target_port : var.install_port +} + +module "install" { + source = "../install" + kexec_tarball_url = var.kexec_tarball_url + target_user = local.install_user + target_host = var.target_host + target_port = local.install_port + nixos_partitioner = module.partitioner-build.result.out + nixos_system = module.system-build.result.out + ssh_private_key = var.install_ssh_key + debug_logging = var.debug_logging + extra_files_script = var.extra_files_script + disk_encryption_key_scripts = var.disk_encryption_key_scripts + extra_environment = var.extra_environment + instance_id = var.instance_id + phases = var.phases + nixos_generate_config_path = var.nixos_generate_config_path + nixos_facter_path = var.nixos_facter_path + build_on_remote = var.build_on_remote + # deprecated attributes + stop_after_disko = var.stop_after_disko + no_reboot = var.no_reboot +} + +module "nixos-rebuild" { + depends_on = [ + module.install + ] + + # Do not execute this step if var.stop_after_disko == true + count = var.stop_after_disko ? 0 : 1 + + source = "../nixos-rebuild" + nixos_system = module.system-build.result.out + ssh_private_key = var.deployment_ssh_key + target_host = var.target_host + target_user = var.target_user + target_port = var.target_port + install_bootloader = var.install_bootloader +} + +output "result" { + value = module.system-build.result +} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/all-in-one/variables.tf b/launch/.terraform/modules/peertube.deploy/terraform/all-in-one/variables.tf new file mode 100644 index 00000000..3ca27922 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/all-in-one/variables.tf @@ -0,0 +1,151 @@ +variable "kexec_tarball_url" { + type = string + description = "NixOS kexec installer tarball url" + default = null +} + +# To make this re-usable we maybe should accept a store path here? +variable "nixos_partitioner_attr" { + type = string + description = "Nixos partitioner and mount script i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.diskoNoDeps or just your-evaluated.config.system.build.diskNoDeps. `config.system.build.diskNoDeps` is provided by the disko nixos module" +} + +# To make this re-usable we maybe should accept a store path here? +variable "nixos_system_attr" { + type = string + description = "The nixos system to deploy i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.toplevel or just your-evaluated-nixos.config.system.build.toplevel if you are not using flakes" +} + +variable "file" { + type = string + description = "Nix file containing the nixos_system_attr and nixos_partitioner_attr. Use this if you are not using flake" + default = null +} + +variable "target_host" { + type = string + description = "DNS host to deploy to" +} + +variable "install_user" { + type = string + description = "SSH user used to connect to the target_host, before installing NixOS. If null than the value of `target_host` is used" + default = null +} + +variable "install_port" { + type = string + description = "SSH port used to connect to the target_host, before installing NixOS. If null than the value of `target_port` is used" + default = null +} + +variable "target_user" { + type = string + description = "SSH user used to connect to the target_host after installing NixOS. If install_user is not set than this user is also used before installing." + default = "root" +} + +variable "target_port" { + type = number + description = "SSH port used to connect to the target_host after installing NixOS. If install_port is not set than this port is also used before installing." + default = 22 +} + +variable "instance_id" { + type = string + description = "The instance id of the target_host, used to track when to reinstall the machine" + default = null +} + +variable "install_ssh_key" { + type = string + description = "Content of private key used to connect to the target_host during initial installation" + default = null +} + +variable "deployment_ssh_key" { + type = string + description = "Content of private key used to deploy to the target_host after initial installation. To ensure maximum security, it is advisable to connect to your host using ssh-agent instead of relying on this variable" + default = null +} + +variable "debug_logging" { + type = bool + description = "Enable debug logging" + default = false +} + +variable "stop_after_disko" { + type = bool + description = "DEPRECATED: Use `phases` instead. Exit after disko formatting" + default = false +} + +variable "no_reboot" { + type = bool + description = "DEPRECATED: Use `phases` instead. Do not reboot after installation" + default = false +} + +variable "phases" { + type = set(string) + description = "Phases to run. See `nixos-anywhere --help` for more information" + default = ["kexec", "disko", "install", "reboot"] +} + +variable "extra_files_script" { + type = string + description = "A script that should place files in the current directory that will be copied to the targets / directory" + default = null +} + +variable "disk_encryption_key_scripts" { + type = list(object({ + path = string + script = string + })) + description = "Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system" + default = [] +} + +variable "extra_environment" { + type = map(string) + description = "Extra environment variables to be set during installation. This can be useful to set extra variables for the extra_files_script or disk_encryption_key_scripts" + default = {} +} + +variable "nix_options" { + type = map(string) + description = "the options of nix" + default = {} +} + +variable "nixos_generate_config_path" { + type = string + description = "Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`." + default = "" +} + +variable "nixos_facter_path" { + type = string + description = "Path to which to write a `facter.json` generated by `nixos-facter`." + default = "" +} + +variable "special_args" { + type = any + default = {} + description = "A map exposed as NixOS's `specialArgs` thru a file." +} + +variable "build_on_remote" { + type = bool + description = "Build the closure on the remote machine instead of building it locally and copying it over" + default = false +} + +variable "install_bootloader" { + type = bool + description = "Install/re-install the bootloader" + default = false +} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/install.md b/launch/.terraform/modules/peertube.deploy/terraform/install.md new file mode 100644 index 00000000..eb3439fc --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/install.md @@ -0,0 +1,91 @@ +# Install + +Install NixOS with nixos-anywhere + +## Example + +```hcl +locals { + ipv4 = "192.0.2.1" +} + +module "system-build" { + source = "github.com/nix-community/nixos-anywhere//terraform/nix-build" + # with flakes + attribute = ".#nixosConfigurations.mymachine.config.system.build.toplevel" + # without flakes + # file can use (pkgs.nixos []) function from nixpkgs + #file = "${path.module}/../.." + #attribute = "config.system.build.toplevel" +} + +module "disko" { + source = "github.com/nix-community/nixos-anywhere//terraform/nix-build" + # with flakes + attribute = ".#nixosConfigurations.mymachine.config.system.build.diskoScript" + # without flakes + # file can use (pkgs.nixos []) function from nixpkgs + #file = "${path.module}/../.." + #attribute = "config.system.build.diskoScript" +} + +module "install" { + source = "github.com/nix-community/nixos-anywhere//terraform/install" + nixos_system = module.system-build.result.out + nixos_partitioner = module.disko.result.out + target_host = local.ipv4 +} +``` + + + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +| --------------------------------------------------- | ------- | +| [null](#provider_null) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +| ------------------------------------------------------------------------------------------------------------------- | -------- | +| [null_resource.nixos-remote](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +| --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | :------: | +| [build\_on\_remote](#input_build_on_remote) | Build the closure on the remote machine instead of building it locally and copying it over | `bool` | `false` | no | +| [debug\_logging](#input_debug_logging) | Enable debug logging | `bool` | `false` | no | +| [disk\_encryption\_key\_scripts](#input_disk_encryption_key_scripts) | Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system |
list(object({
path = string
script = string
}))
| `[]` | no | +| [extra\_environment](#input_extra_environment) | Extra environment variables to be set during installation. This can be useful to set extra variables for the extra\_files\_script or disk\_encryption\_key\_scripts | `map(string)` | `{}` | no | +| [extra\_files\_script](#input_extra_files_script) | A script that should place files in the current directory that will be copied to the targets / directory | `string` | `null` | no | +| [flake](#input_flake) | The flake to install the system from | `string` | `""` | no | +| [instance\_id](#input_instance_id) | The instance id of the target\_host, used to track when to reinstall the machine | `string` | `null` | no | +| [kexec\_tarball\_url](#input_kexec_tarball_url) | NixOS kexec installer tarball url | `string` | `null` | no | +| [nixos\_facter\_path](#input_nixos_facter_path) | Path to which to write a `facter.json` generated by `nixos-facter`. This option cannot be set at the same time as `nixos_generate_config_path`. | `string` | `""` | no | +| [nixos\_generate\_config\_path](#input_nixos_generate_config_path) | Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. This option cannot be set at the same time as `nixos_facter_path`. | `string` | `""` | no | +| [nixos\_partitioner](#input_nixos_partitioner) | nixos partitioner and mount script | `string` | `""` | no | +| [nixos\_system](#input_nixos_system) | The nixos system to deploy | `string` | `""` | no | +| [no\_reboot](#input_no_reboot) | DEPRECATED: Use `phases` instead. Do not reboot after installation | `bool` | `false` | no | +| [phases](#input_phases) | Phases to run. See `nixos-anywhere --help` for more information | `list(string)` |
[
"kexec",
"disko",
"install",
"reboot"
]
| no | +| [ssh\_private\_key](#input_ssh_private_key) | Content of private key used to connect to the target\_host | `string` | `""` | no | +| [stop\_after\_disko](#input_stop_after_disko) | DEPRECATED: Use `phases` instead. Exit after disko formatting | `bool` | `false` | no | +| [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes | +| [target\_pass](#input_target_pass) | Password used to connect to the target\_host | `string` | `null` | no | +| [target\_port](#input_target_port) | SSH port used to connect to the target\_host | `number` | `22` | no | +| [target\_user](#input_target_user) | SSH user used to connect to the target\_host | `string` | `"root"` | no | + +## Outputs + +No outputs. + + diff --git a/launch/.terraform/modules/peertube.deploy/terraform/install/main.tf b/launch/.terraform/modules/peertube.deploy/terraform/install/main.tf new file mode 100644 index 00000000..9f1816ac --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/install/main.tf @@ -0,0 +1,35 @@ +locals { + disk_encryption_key_scripts = [for k in var.disk_encryption_key_scripts : "\"${k.path}\" \"${k.script}\""] + removed_phases = setunion(var.stop_after_disko ? ["install"] : [], (var.no_reboot ? ["reboot"] : [])) + phases = setsubtract(var.phases, local.removed_phases) + arguments = jsonencode({ + ssh_private_key = var.ssh_private_key + debug_logging = var.debug_logging + kexec_tarball_url = var.kexec_tarball_url + nixos_partitioner = var.nixos_partitioner + nixos_system = var.nixos_system + target_user = var.target_user + target_host = var.target_host + target_port = var.target_port + target_pass = var.target_pass + extra_files_script = var.extra_files_script + build_on_remote = var.build_on_remote + flake = var.flake + phases = join(",", local.phases) + nixos_generate_config_path = var.nixos_generate_config_path + nixos_facter_path = var.nixos_facter_path + }) +} + +resource "null_resource" "nixos-remote" { + triggers = { + instance_id = var.instance_id + } + provisioner "local-exec" { + environment = merge({ + ARGUMENTS = local.arguments + }, var.extra_environment) + command = "${path.module}/run-nixos-anywhere.sh ${join(" ", local.disk_encryption_key_scripts)}" + quiet = var.debug_logging + } +} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/install/providers.tf b/launch/.terraform/modules/peertube.deploy/terraform/install/providers.tf new file mode 100644 index 00000000..c3e00a54 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/install/providers.tf @@ -0,0 +1,5 @@ +terraform { + required_providers { + null = { source = "hashicorp/null" } + } +} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/install/run-nixos-anywhere.sh b/launch/.terraform/modules/peertube.deploy/terraform/install/run-nixos-anywhere.sh new file mode 100755 index 00000000..1d259a1e --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/install/run-nixos-anywhere.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +declare -A input + +while IFS= read -r -d '' key && IFS= read -r -d '' value; do + input[$key]=$value +done < <(jq -j 'to_entries[] | (.key, "\u0000", .value, "\u0000")' <<<"${ARGUMENTS}") + +args=() + +if [[ ${input[debug_logging]} == "true" ]]; then + set -x + declare -p input + args+=("--debug") +fi +if [[ ${input[kexec_tarball_url]} != "null" ]]; then + args+=("--kexec" "${input[kexec_tarball_url]}") +fi +if [[ ${input[build_on_remote]} == "true" ]]; then + args+=("--build-on-remote") +fi +if [[ -n ${input[flake]} ]]; then + args+=("--flake" "${input[flake]}") +else + args+=("--store-paths" "${input[nixos_partitioner]}" "${input[nixos_system]}") +fi +if [[ -n ${input[nixos_generate_config_path]} ]]; then + if [[ -n ${input[nixos_facter_path]} ]]; then + echo "cannot set both variables 'nixos_generate_config_path' and 'nixos_facter_path'!" >&2 + exit 1 + fi + args+=("--generate-hardware-config" "nixos-generate-config" "${input[nixos_generate_config_path]}") +elif [[ -n ${input[nixos_facter_path]} ]]; then + args+=("--generate-hardware-config" "nixos-facter" "${input[nixos_facter_path]}") +fi +args+=(--phases "${input[phases]}") +if [[ ${input[ssh_private_key]} != null ]]; then + export SSH_PRIVATE_KEY="${input[ssh_private_key]}" +fi +if [[ ${input[target_pass]} != null ]]; then + export SSHPASS=${input[target_pass]} + args+=("--env-password") +fi + +tmpdir=$(mktemp -d) +cleanup() { + rm -rf "${tmpdir}" +} +trap cleanup EXIT + +if [[ ${input[extra_files_script]} != "null" ]]; then + if [[ ! -f ${input[extra_files_script]} ]]; then + echo "extra_files_script '${input[extra_files_script]}' does not exist" + exit 1 + fi + if [[ ! -x ${input[extra_files_script]} ]]; then + echo "extra_files_script '${input[extra_files_script]}' is not executable" + exit 1 + fi + extra_files_script=$(realpath "${input[extra_files_script]}") + mkdir "${tmpdir}/extra-files" + pushd "${tmpdir}/extra-files" + $extra_files_script + popd + args+=("--extra-files" "${tmpdir}/extra-files") +fi + +args+=("-p" "${input[target_port]}") +args+=("${input[target_user]}@${input[target_host]}") + +keyIdx=0 +while [[ $# -gt 0 ]]; do + if [[ ! -f $2 ]]; then + echo "Script file '$2' does not exist" + exit 1 + fi + if [[ ! -x $2 ]]; then + echo "Script file '$2' is not executable" + exit 1 + fi + mkdir -p "${tmpdir}/keys" + "$2" >"${tmpdir}/keys/$keyIdx" + args+=("--disk-encryption-keys" "$1" "${tmpdir}/keys/$keyIdx") + shift + shift + keyIdx=$((keyIdx + 1)) +done + +nix run --extra-experimental-features 'nix-command flakes' "path:${SCRIPT_DIR}/../..#nixos-anywhere" -- "${args[@]}" diff --git a/launch/.terraform/modules/peertube.deploy/terraform/install/variables.tf b/launch/.terraform/modules/peertube.deploy/terraform/install/variables.tf new file mode 100644 index 00000000..cd07bf70 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/install/variables.tf @@ -0,0 +1,123 @@ +variable "kexec_tarball_url" { + type = string + description = "NixOS kexec installer tarball url" + default = null +} + +# To make this re-usable we maybe should accept a store path here? +variable "nixos_partitioner" { + type = string + description = "nixos partitioner and mount script" + default = "" +} + +# To make this re-usable we maybe should accept a store path here? +variable "nixos_system" { + type = string + description = "The nixos system to deploy" + default = "" +} + +variable "target_host" { + type = string + description = "DNS host to deploy to" +} + +variable "target_user" { + type = string + description = "SSH user used to connect to the target_host" + default = "root" +} + +variable "target_port" { + type = number + description = "SSH port used to connect to the target_host" + default = 22 +} + +variable "target_pass" { + type = string + description = "Password used to connect to the target_host" + default = null +} + +variable "ssh_private_key" { + type = string + description = "Content of private key used to connect to the target_host" + default = "" +} + +variable "instance_id" { + type = string + description = "The instance id of the target_host, used to track when to reinstall the machine" + default = null +} + +variable "debug_logging" { + type = bool + description = "Enable debug logging" + default = false +} + +variable "extra_files_script" { + type = string + description = "A script that should place files in the current directory that will be copied to the targets / directory" + default = null +} + +variable "disk_encryption_key_scripts" { + type = list(object({ + path = string + script = string + })) + description = "Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system" + default = [] +} + +variable "extra_environment" { + type = map(string) + description = "Extra environment variables to be set during installation. This can be useful to set extra variables for the extra_files_script or disk_encryption_key_scripts" + default = {} +} + +variable "stop_after_disko" { + type = bool + description = "DEPRECATED: Use `phases` instead. Exit after disko formatting" + default = false +} + +variable "no_reboot" { + type = bool + description = "DEPRECATED: Use `phases` instead. Do not reboot after installation" + default = false +} + +variable "phases" { + type = list(string) + description = "Phases to run. See `nixos-anywhere --help` for more information" + default = ["kexec", "disko", "install", "reboot"] +} + +variable "build_on_remote" { + type = bool + description = "Build the closure on the remote machine instead of building it locally and copying it over" + default = false +} + +variable "flake" { + type = string + description = "The flake to install the system from" + default = "" +} + +variable "nixos_generate_config_path" { + type = string + description = "Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. This option cannot be set at the same time as `nixos_facter_path`." + default = "" +} + +variable "nixos_facter_path" { + type = string + description = "Path to which to write a `facter.json` generated by `nixos-facter`. This option cannot be set at the same time as `nixos_generate_config_path`." + default = "" +} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nix-build.md b/launch/.terraform/modules/peertube.deploy/terraform/nix-build.md new file mode 100644 index 00000000..fe63af12 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/nix-build.md @@ -0,0 +1,47 @@ +# Nix-build + +Small helper module to run do build a flake attribute or attribute from a nix +file. + +## Example + +- See [install](install.md) or [nixos-rebuild](nixos-rebuild.md) + + + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +| --------------------------------------------------------------- | ------- | +| [external](#provider_external) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +| --------------------------------------------------------------------------------------------------------------------------- | ----------- | +| [external_external.nix-build](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +| ---------------------------------------------------------------------- | --------------------------------------------------- | ------------- | ------- | :------: | +| [attribute](#input_attribute) | the attribute to build, can also be a flake | `string` | n/a | yes | +| [file](#input_file) | the nix file to evaluate, if not run in flake mode | `string` | `null` | no | +| [nix\_options](#input_nix_options) | the options of nix | `map(string)` | `{}` | no | +| [special\_args](#input_special_args) | A map exposed as NixOS's `specialArgs` thru a file. | `any` | `{}` | no | + +## Outputs + +| Name | Description | +| ----------------------------------------------------- | ----------- | +| [result](#output_result) | n/a | + + diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nix-build/main.tf b/launch/.terraform/modules/peertube.deploy/terraform/nix-build/main.tf new file mode 100644 index 00000000..7a3c335f --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/nix-build/main.tf @@ -0,0 +1,17 @@ +locals { + nix_options = jsonencode({ + options = { for k, v in var.nix_options : k => v } + }) +} +data "external" "nix-build" { + program = [ "${path.module}/nix-build.sh" ] + query = { + attribute = var.attribute + file = var.file + nix_options = local.nix_options + special_args = jsonencode(var.special_args) + } +} +output "result" { + value = data.external.nix-build.result +} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nix-build/nix-build.sh b/launch/.terraform/modules/peertube.deploy/terraform/nix-build/nix-build.sh new file mode 100755 index 00000000..0e22357e --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/nix-build/nix-build.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +set -efu + +declare file attribute nix_options special_args +eval "$(jq -r '@sh "attribute=\(.attribute) file=\(.file) nix_options=\(.nix_options) special_args=\(.special_args)"')" +if [ "${nix_options}" != '{"options":{}}' ]; then + options=$(echo "${nix_options}" | jq -r '.options | to_entries | map("--option \(.key) \(.value)") | join(" ")') +else + options="" +fi +if [[ ${special_args-} == "{}" ]]; then + # no special arguments, proceed as normal + if [[ -n ${file-} ]] && [[ -e ${file-} ]]; then + # shellcheck disable=SC2086 + out=$(nix build --no-link --json $options -f "$file" "$attribute") + else + # shellcheck disable=SC2086 + out=$(nix build --no-link --json ${options} "$attribute") + fi +else + if [[ ${file-} != 'null' ]]; then + echo "special_args are currently only supported when using flakes!" >&2 + exit 1 + fi + # pass the args in a pure fashion by extending the original config + rest="$(echo "${attribute}" | cut -d "#" -f 2)" + # e.g. config_path=nixosConfigurations.aarch64-linux.myconfig + config_path="${rest%.config.*}" + # e.g. config_attribute=config.system.build.toplevel + config_attribute="config.${rest#*.config.}" + + # grab flake nar from error message + flake_rel="$(echo "${attribute}" | cut -d "#" -f 1)" + # e.g. flake_rel="." + flake_dir="$(readlink -f "${flake_rel}")" + flake_path="${flake_dir}/flake.nix" + flake_json="$(nix flake prefetch "${flake_dir}" --json)" + flake_nar="$(echo "$flake_json" | jq -r '.hash')" + store_path="$(echo "${flake_json}" | jq -r '.storePath')" + # while we have a store path now, for a repo this reflects its root level, + # so search for the largest child segment yielding a match in that store dir. + iter_path="${flake_path}" + while [[ ${iter_path} != "/" ]]; do + parent="$(dirname "${iter_path}")" + child_segment="${flake_path//$parent/}" + if [[ -f "${store_path}${child_segment}" ]]; then + target_segment="${child_segment}" + fi + iter_path="${parent}" + done + # substitute variables into the template + nix_expr="(builtins.getFlake ''file://${flake_dir}?dir=${target_segment//\/flake.nix/}&narHash=${flake_nar}'').${config_path}.extendModules { specialArgs = builtins.fromJSON ''${special_args}''; }" + # inject `special_args` into nixos config's `specialArgs` + # shellcheck disable=SC2086 + out=$(nix build --no-link --json ${options} --expr "${nix_expr}" "${config_attribute}") +fi +printf '%s' "$out" | jq -c '.[].outputs' diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nix-build/variables.tf b/launch/.terraform/modules/peertube.deploy/terraform/nix-build/variables.tf new file mode 100644 index 00000000..bad23f73 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/nix-build/variables.tf @@ -0,0 +1,22 @@ +variable "attribute" { + type = string + description = "the attribute to build, can also be a flake" +} + +variable "file" { + type = string + description = "the nix file to evaluate, if not run in flake mode" + default = null +} + +variable "nix_options" { + type = map(string) + description = "the options of nix" + default = {} +} + +variable "special_args" { + type = any + default = {} + description = "A map exposed as NixOS's `specialArgs` thru a file." +} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild.md b/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild.md new file mode 100644 index 00000000..0be26bb7 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild.md @@ -0,0 +1,66 @@ +# Nixos-rebuild + +Update NixOS machine with nixos-rebuild on a remote machine + +## Example + +```hcl +locals { + ipv4 = "192.0.2.1" +} + +module "system-build" { + source = "github.com/nix-community/nixos-anywhere//terraform/nix-build" + # with flakes + attribute = ".#nixosConfigurations.mymachine.config.system.build.toplevel" + # without flakes + # file can use (pkgs.nixos []) function from nixpkgs + #file = "${path.module}/../.." + #attribute = "config.system.build.toplevel" +} + +module "deploy" { + source = "github.com/nix-community/nixos-anywhere//terraform/nixos-rebuild" + nixos_system = module.system-build.result.out + target_host = local.ipv4 +} +``` + + + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +| --------------------------------------------------- | ------- | +| [null](#provider_null) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +| -------------------------------------------------------------------------------------------------------------------- | -------- | +| [null_resource.nixos-rebuild](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------- | -------- | :------: | +| [ignore\_systemd\_errors](#input_ignore_systemd_errors) | Ignore systemd errors happening during deploy | `bool` | `false` | no | +| [nixos\_system](#input_nixos_system) | The nixos system to deploy | `string` | n/a | yes | +| [ssh\_private\_key](#input_ssh_private_key) | Content of private key used to connect to the target\_host. If set to - no key is passed to openssh and ssh will use its own configuration | `string` | `"-"` | no | +| [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes | +| [target\_port](#input_target_port) | SSH port used to connect to the target\_host | `number` | `22` | no | +| [target\_user](#input_target_user) | User to deploy as | `string` | `"root"` | no | + +## Outputs + +No outputs. + + diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/deploy.sh b/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/deploy.sh new file mode 100755 index 00000000..61da6e1c --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/deploy.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +set -uex -o pipefail + +if [ "$#" -ne 6 ]; then + echo "USAGE: $0 NIXOS_SYSTEM TARGET_USER TARGET_HOST TARGET_PORT IGNORE_SYSTEMD_ERRORS INSTALL_BOOTLOADER" >&2 + exit 1 +fi + +NIXOS_SYSTEM=$1 +TARGET_USER=$2 +TARGET_HOST=$3 +TARGET_PORT=$4 +IGNORE_SYSTEMD_ERRORS=$5 +INSTALL_BOOTLOADER=$6 + +shift 6 + +TARGET="${TARGET_USER}@${TARGET_HOST}" + +workDir=$(mktemp -d) +trap 'rm -rf "$workDir"' EXIT + +sshOpts=(-p "${TARGET_PORT}") +sshOpts+=(-o UserKnownHostsFile=/dev/null) +sshOpts+=(-o StrictHostKeyChecking=no) + +set +x +if [[ -n ${SSH_KEY+x} && ${SSH_KEY} != "-" ]]; then + sshPrivateKeyFile="$workDir/ssh_key" + # Create the file with 0700 - umask calculation: 777 - 700 = 077 + ( + umask 077 + echo "$SSH_KEY" >"$sshPrivateKeyFile" + ) + unset SSH_AUTH_SOCK # don't use system agent if key was supplied + sshOpts+=(-o "IdentityFile=${sshPrivateKeyFile}") +fi +set -x + +try=1 +until NIX_SSHOPTS="${sshOpts[*]}" nix copy -s --experimental-features nix-command --to "ssh://$TARGET" "$NIXOS_SYSTEM"; do + if [[ $try -gt 10 ]]; then + echo "retries exhausted" >&2 + exit 1 + fi + sleep 10 + try=$((try + 1)) +done + +if [[ $INSTALL_BOOTLOADER == "true" ]]; then + extra_env='NIXOS_INSTALL_BOOTLOADER=1' +else + extra_env='' +fi + +switchCommand="nix-env -p /nix/var/nix/profiles/system --set $(printf "%q" "$NIXOS_SYSTEM"); $extra_env /nix/var/nix/profiles/system/bin/switch-to-configuration switch" + +if [[ $TARGET_USER != "root" ]]; then + switchCommand="sudo bash -c '$switchCommand'" +fi +deploy_status=0 +# shellcheck disable=SC2029 +ssh "${sshOpts[@]}" "$TARGET" "$switchCommand" || deploy_status="$?" +if [[ $IGNORE_SYSTEMD_ERRORS == "true" && $deploy_status == "4" ]]; then + exit 0 +fi +exit "$deploy_status" diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/main.tf b/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/main.tf new file mode 100644 index 00000000..84461c80 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/main.tf @@ -0,0 +1,11 @@ +resource "null_resource" "nixos-rebuild" { + triggers = { + store_path = var.nixos_system + } + provisioner "local-exec" { + environment = { + SSH_KEY = var.ssh_private_key + } + command = "${path.module}/deploy.sh ${var.nixos_system} ${var.target_user} ${var.target_host} ${var.target_port} ${var.ignore_systemd_errors} ${var.install_bootloader}" + } +} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/variables.tf b/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/variables.tf new file mode 100644 index 00000000..90e0b0c6 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/variables.tf @@ -0,0 +1,39 @@ +variable "nixos_system" { + type = string + description = "The nixos system to deploy" +} + +variable "target_host" { + type = string + description = "DNS host to deploy to" +} + +variable "target_user" { + type = string + default = "root" + description = "User to deploy as" +} + +variable "target_port" { + type = number + description = "SSH port used to connect to the target_host" + default = 22 +} + +variable "ssh_private_key" { + type = string + description = "Content of private key used to connect to the target_host. If set to - no key is passed to openssh and ssh will use its own configuration" + default = "-" +} + +variable "ignore_systemd_errors" { + type = bool + description = "Ignore systemd errors happening during deploy" + default = false +} + +variable "install_bootloader" { + type = bool + description = "Install/re-install the bootloader" + default = false +} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/update-docs.sh b/launch/.terraform/modules/peertube.deploy/terraform/update-docs.sh new file mode 100755 index 00000000..b67d98ad --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/terraform/update-docs.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" +files=() +find "${SCRIPT_DIR}"/* -type d | while read -r i; do + module_name=$(basename "$i") + markdown_file="${SCRIPT_DIR}/${module_name}.md" + terraform-docs --config "${SCRIPT_DIR}/.terraform-docs.yml" markdown table --output-file "${markdown_file}" --output-mode inject "${module_name}" + files+=("${markdown_file}") +done +cd .. +nix fmt -- --no-cache diff --git a/launch/.terraform/modules/peertube.deploy/tests/flake-module.nix b/launch/.terraform/modules/peertube.deploy/tests/flake-module.nix new file mode 100644 index 00000000..784175f4 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/tests/flake-module.nix @@ -0,0 +1,33 @@ +{ withSystem, inputs, ... }: + +{ + flake.checks.x86_64-linux = withSystem "x86_64-linux" ( + { + pkgs, + system, + inputs', + config, + ... + }: + let + testInputsUnstable = { + inherit pkgs; + inherit (inputs.disko.nixosModules) disko; + nixos-anywhere = config.packages.nixos-anywhere; + kexec-installer = "${inputs'.nixos-images.packages.kexec-installer-nixos-unstable-noninteractive}/nixos-kexec-installer-noninteractive-${system}.tar.gz"; + }; + testInputsStable = testInputsUnstable // { + kexec-installer = "${inputs'.nixos-images.packages.kexec-installer-nixos-stable-noninteractive}/nixos-kexec-installer-noninteractive-${system}.tar.gz"; + }; + in + { + from-nixos = import ./from-nixos.nix testInputsUnstable; + from-nixos-stable = import ./from-nixos.nix testInputsStable; + from-nixos-with-sudo = import ./from-nixos-with-sudo.nix testInputsUnstable; + from-nixos-with-sudo-stable = import ./from-nixos-with-sudo.nix testInputsStable; + from-nixos-with-generated-config = import ./from-nixos-generate-config.nix testInputsUnstable; + from-nixos-build-on-remote = import ./from-nixos-build-on-remote.nix testInputsUnstable; + from-nixos-separated-phases = import ./from-nixos-separated-phases.nix testInputsUnstable; + } + ); +} diff --git a/launch/.terraform/modules/peertube.deploy/tests/from-nixos-build-on-remote.nix b/launch/.terraform/modules/peertube.deploy/tests/from-nixos-build-on-remote.nix new file mode 100644 index 00000000..52617133 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/tests/from-nixos-build-on-remote.nix @@ -0,0 +1,56 @@ +(import ./lib/test-base.nix) ( + { pkgs, ... }: + { + name = "from-nixos-build-on-remote"; + nodes = { + installer = ./modules/installer.nix; + installed = { + services.openssh.enable = true; + virtualisation.memorySize = 1024; + + users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; + }; + }; + testScript = '' + def create_test_machine( + oldmachine=None, **kwargs + ): # taken from + start_command = [ + "${pkgs.qemu_test}/bin/qemu-kvm", + "-cpu", + "max", + "-m", + "1024", + "-virtfs", + "local,path=/nix/store,security_model=none,mount_tag=nix-store", + "-drive", + f"file={oldmachine.state_dir}/installed.qcow2,id=drive1,if=none,index=1,werror=report", + "-device", + "virtio-blk-pci,drive=drive1", + ] + machine = create_machine(start_command=" ".join(start_command), **kwargs) + driver.machines.append(machine) + return machine + start_all() + + installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --build-on-remote \ + --kexec /etc/nixos-anywhere/kexec-installer \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + root@installed >&2 + """) + try: + installed.shutdown() + except BrokenPipeError: + # qemu has already exited + pass + new_machine = create_test_machine(oldmachine=installed, name="after_install") + new_machine.start() + hostname = new_machine.succeed("hostname").strip() + assert "nixos-anywhere" == hostname, f"'nixos-anywhere' != '{hostname}'" + ''; + } +) diff --git a/launch/.terraform/modules/peertube.deploy/tests/from-nixos-generate-config.nix b/launch/.terraform/modules/peertube.deploy/tests/from-nixos-generate-config.nix new file mode 100644 index 00000000..5b4d65dd --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/tests/from-nixos-generate-config.nix @@ -0,0 +1,71 @@ +(import ./lib/test-base.nix) { + name = "from-nixos-generate-config"; + nodes = { + installer = + { pkgs, ... }: + { + imports = [ + ./modules/installer.nix + ]; + environment.systemPackages = [ pkgs.jq ]; + }; + installed = { + services.openssh.enable = true; + virtualisation.memorySize = 1024; + + users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; + }; + }; + testScript = '' + start_all() + installer.fail("test -f /tmp/hw/config.nix") + installer.succeed("echo super-secret > /tmp/disk-1.key") + output = installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --kexec /etc/nixos-anywhere/kexec-installer \ + --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ + --disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \ + --phases kexec,disko \ + --generate-hardware-config nixos-generate-config /tmp/hw/config.nix \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + root@installed >&2 + echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat /tmp/disk-1.key)'" + echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat /tmp/disk-2.key)'" + """) + + installer.succeed("cat /tmp/hw/config.nix >&2") + installer.succeed("nix-instantiate --parse /tmp/hw/config.nix") + + assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}" + assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}" + + installer.fail("test -f /test/hw/config.json") + + output = installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --kexec /etc/nixos-anywhere/kexec-installer \ + --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ + --disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \ + --phases kexec,disko \ + --generate-hardware-config nixos-facter /tmp/hw/config.json \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + installed >&2 + echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat /tmp/disk-1.key)'" + echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat /tmp/disk-2.key)'" + """) + + installer.succeed("cat /tmp/hw/config.json >&2") + installer.succeed("jq < /tmp/hw/config.json") + + assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}" + assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}" + ''; +} diff --git a/launch/.terraform/modules/peertube.deploy/tests/from-nixos-separated-phases.nix b/launch/.terraform/modules/peertube.deploy/tests/from-nixos-separated-phases.nix new file mode 100644 index 00000000..2b267b69 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/tests/from-nixos-separated-phases.nix @@ -0,0 +1,52 @@ +(import ./lib/test-base.nix) { + name = "from-nixos-separated-phases"; + nodes = { + installer = ./modules/installer.nix; + installed = { + services.openssh.enable = true; + virtualisation.memorySize = 1024; + + users.users.nixos = { + isNormalUser = true; + openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; + extraGroups = [ "wheel" ]; + }; + security.sudo.enable = true; + security.sudo.wheelNeedsPassword = false; + }; + }; + testScript = '' + start_all() + + with subtest("Kexec Phase"): + installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --kexec /etc/nixos-anywhere/kexec-installer \ + --phases kexec \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + nixos@installed >&2 + """) + + with subtest("Disko Phase"): + output = installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --phases disko \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + installed >&2 + """) + + with subtest("Install Phase"): + installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --phases install \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + root@installed >&2 + """) + ''; +} diff --git a/launch/.terraform/modules/peertube.deploy/tests/from-nixos-with-sudo.nix b/launch/.terraform/modules/peertube.deploy/tests/from-nixos-with-sudo.nix new file mode 100644 index 00000000..839dec38 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/tests/from-nixos-with-sudo.nix @@ -0,0 +1,40 @@ +(import ./lib/test-base.nix) { + name = "from-nixos-with-sudo"; + nodes = { + installer = ./modules/installer.nix; + installed = { + services.openssh.enable = true; + virtualisation.memorySize = 1024; + + users.users.nixos = { + isNormalUser = true; + openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; + extraGroups = [ "wheel" ]; + }; + security.sudo.enable = true; + security.sudo.wheelNeedsPassword = false; + }; + }; + testScript = '' + start_all() + installer.succeed("echo super-secret > /tmp/disk-1.key") + output = installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --kexec /etc/nixos-anywhere/kexec-installer \ + --phases kexec,disko \ + --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ + --disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + nixos@installed >&2 + echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat /tmp/disk-1.key)'" + echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat /tmp/disk-2.key)'" + """) + + assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}" + assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}" + ''; +} diff --git a/launch/.terraform/modules/peertube.deploy/tests/from-nixos.nix b/launch/.terraform/modules/peertube.deploy/tests/from-nixos.nix new file mode 100644 index 00000000..0f3d1344 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/tests/from-nixos.nix @@ -0,0 +1,76 @@ +(import ./lib/test-base.nix) ( + { pkgs, ... }: + { + name = "from-nixos"; + nodes = { + installer = ./modules/installer.nix; + installed = { + services.openssh.enable = true; + virtualisation.memorySize = 1024; + + users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; + }; + }; + testScript = '' + def create_test_machine( + oldmachine=None, **kwargs + ): # taken from + start_command = [ + "${pkgs.qemu_test}/bin/qemu-kvm", + "-cpu", + "max", + "-m", + "1024", + "-virtfs", + "local,path=/nix/store,security_model=none,mount_tag=nix-store", + "-drive", + f"file={oldmachine.state_dir}/installed.qcow2,id=drive1,if=none,index=1,werror=report", + "-device", + "virtio-blk-pci,drive=drive1", + ] + machine = create_machine(start_command=" ".join(start_command), **kwargs) + driver.machines.append(machine) + return machine + start_all() + installer.succeed("mkdir -p /tmp/extra-files/var/lib/secrets") + installer.succeed("echo value > /tmp/extra-files/var/lib/secrets/key") + installer.succeed("mkdir -p /tmp/extra-files/home/user/.ssh") + installer.succeed("echo secretkey > /tmp/extra-files/home/user/.ssh/id_ed25519") + installer.succeed("echo publickey > /tmp/extra-files/home/user/.ssh/id_ed25519.pub") + installer.succeed("chmod 600 /tmp/extra-files/home/user/.ssh/id_ed25519") + ssh_key_path = "/etc/ssh/ssh_host_ed25519_key.pub" + ssh_key_output = installer.wait_until_succeeds(f""" + ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat {ssh_key_path} + """) + installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --kexec /etc/nixos-anywhere/kexec-installer \ + --extra-files /tmp/extra-files \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + --chown /home/user 1000:100 \ + --copy-host-keys \ + root@installed >&2 + """) + try: + installed.shutdown() + except BrokenPipeError: + # qemu has already exited + pass + new_machine = create_test_machine(oldmachine=installed, name="after_install") + new_machine.start() + hostname = new_machine.succeed("hostname").strip() + assert "nixos-anywhere" == hostname, f"'nixos-anywhere' != '{hostname}'" + content = new_machine.succeed("cat /var/lib/secrets/key").strip() + assert "value" == content, f"secret does not have expected value: {content}" + ssh_key_content = new_machine.succeed(f"cat {ssh_key_path}").strip() + assert ssh_key_content in ssh_key_output, "SSH host identity changed" + priv_key_perms = new_machine.succeed("stat -c %a /home/user/.ssh/id_ed25519").strip() + assert priv_key_perms == "600", f"unexpected permissions for private key: {priv_key_perms}" + user_dir_ownership = new_machine.succeed("stat -c %u:%g /home/user").strip() + assert user_dir_ownership == "1000:100", f"unexpected user home dir permissions: {user_dir_ownership}" + ''; + } +) diff --git a/launch/.terraform/modules/peertube.deploy/tests/lib/test-base.nix b/launch/.terraform/modules/peertube.deploy/tests/lib/test-base.nix new file mode 100644 index 00000000..169d1fd2 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/tests/lib/test-base.nix @@ -0,0 +1,20 @@ +test: +{ + pkgs ? import { }, + nixos-anywhere ? pkgs.callPackage ../../src { }, + disko ? "${builtins.fetchTarball "https://github.com/nix-community/disko/archive/master.tar.gz"}/module.nix", + kexec-installer ? builtins.fetchurl "https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-${pkgs.stdenv.hostPlatform.system}.tar.gz", + ... +}: +let + inherit (pkgs) lib; + nixos-lib = import (pkgs.path + "/nixos/lib") { }; +in +(nixos-lib.runTest { + hostPkgs = pkgs; + # speed-up evaluation + defaults.documentation.enable = lib.mkDefault false; + # to accept external dependencies such as disko + node.specialArgs.inputs = { inherit nixos-anywhere disko kexec-installer; }; + imports = [ test ]; +}).config.result diff --git a/launch/.terraform/modules/peertube.deploy/tests/modules/installer.nix b/launch/.terraform/modules/peertube.deploy/tests/modules/installer.nix new file mode 100644 index 00000000..e5c22d4d --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/tests/modules/installer.nix @@ -0,0 +1,22 @@ +{ pkgs, inputs, ... }: +let + disko = inputs.disko; + kexec-installer = inputs.kexec-installer; + system-to-install = pkgs.nixos [ + ./system-to-install.nix + disko + ]; +in +{ + system.activationScripts.rsa-key = '' + ${pkgs.coreutils}/bin/install -D -m600 ${./ssh-keys/ssh} /root/.ssh/install_key + ''; + + environment.systemPackages = [ inputs.nixos-anywhere ]; + + environment.etc = { + "nixos-anywhere/disko".source = system-to-install.config.system.build.diskoScriptNoDeps; + "nixos-anywhere/system-to-install".source = system-to-install.config.system.build.toplevel; + "nixos-anywhere/kexec-installer".source = kexec-installer; + }; +} diff --git a/launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh b/launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh new file mode 100644 index 00000000..db6049c5 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACDM4kPg4V7DMYceuA8VIUdBvw30gM9qagERA8v1VGBBBQAAAJDpULAq6VCw +KgAAAAtzc2gtZWQyNTUxOQAAACDM4kPg4V7DMYceuA8VIUdBvw30gM9qagERA8v1VGBBBQ +AAAECpjfl5WMMIDvEyZJTeXzRNFzpDpj4fqdIXHZauKAlE5MziQ+DhXsMxhx64DxUhR0G/ +DfSAz2pqAREDy/VUYEEFAAAACWxhc3NAbW9ycwECAwQ= +-----END OPENSSH PRIVATE KEY----- diff --git a/launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh.pub b/launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh.pub new file mode 100644 index 00000000..e77d393e --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMziQ+DhXsMxhx64DxUhR0G/DfSAz2pqAREDy/VUYEEF diff --git a/launch/.terraform/modules/peertube.deploy/tests/modules/system-to-install.nix b/launch/.terraform/modules/peertube.deploy/tests/modules/system-to-install.nix new file mode 100644 index 00000000..1181c944 --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/tests/modules/system-to-install.nix @@ -0,0 +1,47 @@ +{ modulesPath, self, ... }: +{ + imports = [ + (modulesPath + "/testing/test-instrumentation.nix") + (modulesPath + "/profiles/qemu-guest.nix") + (modulesPath + "/profiles/minimal.nix") + ]; + networking.hostName = "nixos-anywhere"; + documentation.enable = false; + hardware.enableAllFirmware = false; + networking.hostId = "8425e349"; # from profiles/base.nix, needed for zfs + boot.zfs.devNodes = "/dev/disk/by-uuid"; # needed because /dev/disk/by-id is empty in qemu-vms + disko.devices = { + disk = { + vda = { + device = "/dev/vda"; + type = "disk"; + content = { + type = "gpt"; + partitions = { + boot = { + size = "1M"; + type = "EF02"; + }; + ESP = { + size = "100M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/launch/.terraform/modules/peertube.deploy/treefmt/flake-module.nix b/launch/.terraform/modules/peertube.deploy/treefmt/flake-module.nix new file mode 100644 index 00000000..3e92a8ed --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy/treefmt/flake-module.nix @@ -0,0 +1,23 @@ +{ inputs, ... }: +{ + imports = [ + inputs.treefmt-nix.flakeModule + ]; + perSystem = + { config, pkgs, ... }: + { + treefmt = { + projectRootFile = "flake.nix"; + programs.mdsh.enable = true; + programs.nixpkgs-fmt.enable = true; + programs.shellcheck.enable = true; + programs.shfmt.enable = true; + programs.deno.enable = !pkgs.deno.meta.broken; + settings.formatter.shellcheck.options = [ + "-s" + "bash" + ]; + }; + formatter = config.treefmt.build.wrapper; + }; +} diff --git a/launch/.terraform/modules/pixelfed.deploy/CONTRIBUTING.md b/launch/.terraform/modules/pixelfed.deploy/CONTRIBUTING.md new file mode 100644 index 00000000..3aeefa73 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/CONTRIBUTING.md @@ -0,0 +1,23 @@ +To run `nixos-anywhere` from the repo: + +```console +nix run . -- --help +``` + +To format the code: + +```console +nix fmt +``` + +To run all tests: + +```console +nix flake check -vL +``` + +To run an individual test: + +``` +nix build .#checks.x86_64-linux.from-nixos -vL +``` diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/INDEX.md b/launch/.terraform/modules/pixelfed.deploy/docs/INDEX.md new file mode 100644 index 00000000..67d48751 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/INDEX.md @@ -0,0 +1,11 @@ +# Table of Content: - nixos-anywhere + +**_Install NixOS everywhere via ssh_** + + + +- [README](../README.md) +- [Quickstart](./quickstart.md) +- [System Requirements](./requirements.md) +- [How to Guide](./howtos/INDEX.md) +- [Reference](./reference.md) diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/SUMMARY.md b/launch/.terraform/modules/pixelfed.deploy/docs/SUMMARY.md new file mode 100644 index 00000000..3bfaea5b --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/SUMMARY.md @@ -0,0 +1,26 @@ +# Summary: - nixos-anywhere + +**_Install NixOS everywhere via ssh_** + + + +The **nixos-anywhere** tool allows you to pre-configure the whole process of +installing NixOS, and run the install remotely with a single CLI command. + +Refer to the following documentation for more information. + +[System Requirements](./requirements.md): CPU and memory requirements + +[Quickstart](./quickstart.md): Instructions for a typical installation + +[How to Guide](./howtos/INDEX.md): Instructions for non-typical use cases + +- [Installing on a machine with no operating system](./howtos/no-os.md) +- [Using your own kexec image](./howtos/custom-kexec.md) +- [Secrets and full disk encryption](./howtos/secrets.md) +- [Use without flakes](./howtos/use-without-flakes.md) +- [Terraform](./howtos/terraform.md) +- [Nix-channels / `NIX_PATH`](./howtos/nix-path.md) +- [IPv6-only targets](./howtos/ipv6.md) + +[Reference](./reference.md): Reference Guide diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/book.toml b/launch/.terraform/modules/pixelfed.deploy/docs/book.toml new file mode 100644 index 00000000..d053de4e --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/book.toml @@ -0,0 +1,6 @@ +[book] +authors = [ ] +language = "en" +multilingual = false +src = "." +title = "nixos-anywhere - install NixOS everywhere" diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/cli.md b/launch/.terraform/modules/pixelfed.deploy/docs/cli.md new file mode 100644 index 00000000..d2577552 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/cli.md @@ -0,0 +1,63 @@ +# CLI + +``` +Usage: nixos-anywhere [options] [] + +Options: + +* -f, --flake + set the flake to install the system from. +* --target-host + specified the SSH target host to deploy onto. +* -i + selects which SSH private key file to use. +* -p, --ssh-port + set the ssh port to connect with +* --ssh-option + set an ssh option +* -L, --print-build-logs + print full build logs +* --env-password + set a password used by ssh-copy-id, the password should be set by + the environment variable SSHPASS +* -s, --store-paths + set the store paths to the disko-script and nixos-system directly + if this is given, flake is not needed +* --no-reboot + do not reboot after installation, allowing further customization of the target installation. +* --kexec + use another kexec tarball to bootstrap NixOS +* --kexec-extra-flags + extra flags to add into the call to kexec, e.g. "--no-sync" +* --ssh-store-setting + ssh store settings appended to the store URI, e.g. "compress true". needs to be URI encoded. +* --post-kexec-ssh-port + after kexec is executed, use a custom ssh port to connect. Defaults to 22 +* --copy-host-keys + copy over existing /etc/ssh/ssh_host_* host keys to the installation +* --stop-after-disko + exit after disko formatting, you can then proceed to install manually or some other way +* --extra-files + contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten + Copied files will be owned by root. See documentation for details. +* --disk-encryption-keys + copy the contents of the file or pipe in local_path to remote_path in the installer environment, + after kexec but before installation. Can be repeated. +* --no-substitute-on-destination + disable passing --substitute-on-destination to nix-copy +* --debug + enable debug output +* --option + nix option to pass to every nix related command +* --from + URL of the source Nix store to copy the nixos and disko closure from +* --build-on-remote + build the closure on the remote machine instead of locally and copy-closuring it +* --vm-test + build the system and test the disk configuration inside a VM without installing it to the target. +* --build-on auto|remote|local + sets the build on settings to auto, remote or local. Default is auto. + auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build + local: will build on the local host + remote: will build on the remote host +``` diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/flake-module.nix b/launch/.terraform/modules/pixelfed.deploy/docs/flake-module.nix new file mode 100644 index 00000000..2afe9d50 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/flake-module.nix @@ -0,0 +1,21 @@ +{ + perSystem = + { pkgs, lib, ... }: + { + packages.docs = + pkgs.runCommand "nixos-anywhere-docs" + { + passthru.serve = pkgs.writeShellScriptBin "serve" '' + set -euo pipefail + cd docs + workdir=$(${pkgs.coreutils}/bin/mktemp -d) + trap 'rm -rf "$workdir"' EXIT + ${pkgs.mdbook}/bin/mdbook serve --dest-dir "$workdir" + ''; + } + '' + cp -r ${lib.cleanSource ./.}/* . + ${pkgs.mdbook}/bin/mdbook build --dest-dir "$out" + ''; + }; +} diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos.md new file mode 100644 index 00000000..bfa55ce1 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/howtos.md @@ -0,0 +1 @@ +# How to Guide diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/INDEX.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/INDEX.md new file mode 100644 index 00000000..2d356638 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/INDEX.md @@ -0,0 +1,29 @@ +# How To Guide: nixos-anywhere + +**_Install NixOS everywhere via ssh_** + + + +[Documentation Index](./INDEX.md) + +## Contents + +[Installing on a machine with no operating system](./no-os.md) + +[Kexec on systems with limited RAM](./limited-ram.md) + +[Copying files to the new installation](./extra-files.md) + +[Using your own kexec image](./custom-kexec.md) + +[Repair installations without wiping data](./disko-modes.md) + +[Secrets and full disk encryption](./secrets.md) + +[Use without flakes](./use-without-flakes.md) + +[Terraform](./terraform.md) + +[Nix-channels / `NIX_PATH`](./nix-path.md) + +[IPv6-only targets](./ipv6.md) diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/custom-kexec.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/custom-kexec.md new file mode 100644 index 00000000..5935a5f3 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/custom-kexec.md @@ -0,0 +1,40 @@ +# Using your own kexec image + +By default, `nixos-anywhere` downloads the kexec image from the +[NixOS images repository](https://github.com/nix-community/nixos-images#kexec-tarballs). + +However, you can provide your own `kexec` image file if you need to use a +different one. This is particularly useful for architectures other than `x86_64` +and `aarch64`, since they don't have a pre-build image. + +To do this, use the `--kexec` command line switch followed by the path to your +image file. The image will be uploaded prior to execution. + +Here's an example command that demonstrates how to use a custom kexec image with +`nixos-anywhere`: + +``` +nix run github:nix-community/nixos-anywhere -- \ + --kexec "$(nix build --print-out-paths github:nix-community/nixos-images#packages.aarch64-linux.kexec-installer-nixos-unstable-noninteractive)/nixos-kexec-installer-noninteractive-aarch64-linux.tar.gz" \ + --flake 'github:your-user/your-repo#your-system' \ + root@yourip +``` + +Make sure to replace `github:your-user/your-repo#your-system` with the +appropriate Flake URL representing your NixOS configuration. + +The example above assumes that your local machine can build for aarch64 in one +of the following ways: + +- Natively + +- Through a remote builder + +- By emulating the architecture with qemu using the following NixOS + configuration: + +```nix +{ + boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; +} +``` diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/disko-modes.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/disko-modes.md new file mode 100644 index 00000000..501f93f1 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/disko-modes.md @@ -0,0 +1,19 @@ +# Repair installations without wiping data + +By default, nixos-anywhere will reformat all configured disks before running the +installation. However it is also possible to mount the filesystems of an +existing installation and run `nixos-install`. This is useful to recover from a +misconfigured NixOS installation by first booting into a NixOS installer or +recovery system. + +To only mount existing filesystems, add `--disko-mode mount` to +`nixos-anywhere`: + +``` +nix run github:nix-community/nixos-anywhere -- --disko-mode mount --flake # --target-host root@ +``` + +1. This will first boot into a nixos-installer +2. Mounts disks with disko +3. Runs nixos-install based on the provided flake +4. Reboots the machine. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/extra-files.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/extra-files.md new file mode 100644 index 00000000..ca067d4c --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/extra-files.md @@ -0,0 +1,114 @@ +# Copying files to the new installation + +The `--extra-files ` option allows copying files to the target host after +installation. + +The contents of the `` is recursively copied and overwrites the targets +root (/). The contents _must_ be in a structure and permissioned as it should be +on the target. + +In this way, there is no need to repeatedly pass arguments (eg: a fictional +argument: `--copy `) to `nixos-anywhere` to complete the intended +outcome. + +The path and directory structure passed to `--extra-files` should be prepared +beforehand. + +This allows a simple programmatic invocation of `nixos-anywhere` for multiple +hosts. + +## Simple Example + +You want `/etc/ssh/ssh_host_*` and `/persist` from the local system on the +target. The `` contents will look like this: + +```console +$ cd /tmp +$ root=$(mktemp -d) +$ sudo cp --verbose --archive --parents /etc/ssh/ssh_host_* ${root} +$ cp --verbose --archive --link /persist ${root} +``` + +The directory structure would look like this: + +```console +drwx------ myuser1 users 20 tmp.d6nx5QUwPN +drwxr-xr-x root root 6 ├── etc +drwx------ myuser1 users 160 │ └── ssh +.rw------- root root 399 │ ├── ssh_host_ed25519_key +.rw-r--r-- root root 91 │ ├── ssh_host_ed25519_key.pub +drwxr-xr-x myuser1 users 22 └── persist +drwxr-xr-x myuser1 users 14 ├── all +drwxr-xr-x myuser1 users 22 │ ├── my +.rw-r--r-- myuser1 users 6 │ │ ├── test3 +drwxr-xr-x myuser1 users 10 │ │ └── things +.rw-r--r-- myuser1 users 6 │ │ └── test4 +.rw-r--r-- myuser1 users 6 │ └── test2 +drwxr-xr-x myuser1 users 0 ├── blah +.rw-r--r-- myuser1 users 6 └── test +``` + +**NOTE**: Permissions will be copied, but ownership on the target will be root. + +Then pass $root like: + +> nixos-anywhere --flake ".#" --extra-files $root --target-host root@newhost + +## Programmatic Example + +```sh +for host in host1 host2 host3; do + root="target/${host}" + install -d -m755 ${root}/etc/ssh + ssh-keygen -A -C root@${host} -f ${root} + nixos-anywhere --extra-files "${root}" --flake ".#${host}" --target-host "root@${host}" +done +``` + +## Considerations + +### Ownership + +The new system may have differing UNIX user and group id's for users created +during installation. + +When the files are extracted on the remote the copied data will be owned by +root. + +If you wish to change the ownership after the files are copied onto the system, +you can use the `--chown` option. + +For example, if you did `--chown /home/myuser/.ssh 1000:100`, this would equate +to running `chown -R /home/myuser/.ssh 1000:100` where the uid is 1000 and the +gid is 100. **Only do this when you can _guarantee_ what the uid and gid will +be.** + +### Symbolic Links + +Do not create symbolic links to reference data to copy. + +GNU `tar` is used to do the copy over ssh. It is an archival tool used to +re/store directory structures as is. Thus `tar` copies symbolic links created +with `ln -s` by default. It does not follow them to copy the underlying file. + +### Hard links + +**NOTE**: hard links can only be created on the same filesystem. + +If you have larger persistent data to copy to the target. GNU `tar` will copy +data referenced by hard links created with `ln`. A hard link does not create +another copy the data. + +To copy a directory tree to the new target you can use the `cp` command with the +`--link` option which creates hard links. + +#### Example + +```sh +cd /tmp +root=$(mktemp -d) +cp --verbose --archive --link --parents /persist/home/myuser ${root} +``` + +`--parents` will create the directory structure of the source at the +destination. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/ipv6.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/ipv6.md new file mode 100644 index 00000000..64eb7a6a --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/ipv6.md @@ -0,0 +1,23 @@ +# NixOS-anywhere on IPv6-only targets + +As GitHub engineers still haven't enabled the IPv6 switch, the kexec image +hosted on GitHub, cannot be used unfortunately on IPv6-only hosts. However it is +possible to use an IPv6 proxy for GitHub content like that: + +``` +nixos-anywhere \ + --kexec https://gh-v6.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz \ +... +``` + +This proxy is hosted by [numtide](https://numtide.com/). It also works for IPv4. + +Alternatively it is also possible to reference a local file: + +``` +nixos-anywhere \ + --kexec ./nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz \ +... +``` + +This tarball will be then uploaded via sftp to the target. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/limited-ram.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/limited-ram.md new file mode 100644 index 00000000..0cbac65e --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/limited-ram.md @@ -0,0 +1,29 @@ +# Kexec on Systems with Limited RAM + +When working with nixos-anywhere on systems with limited RAM (around 1GB), you +can use the `--no-disko-deps` option to reduce memory usage during installation. + +## How it works + +The `--no-disko-deps` option uploads only the disko partitioning script without +including its dependencies. This significantly reduces memory usage because: + +1. The installer normally stores all dependencies in memory +2. Partitioning tools can be quite large when bundled with their dependencies + +## Usage example + +```bash +nix run github:nix-community/nixos-anywhere -- --no-disko-deps --flake # --target-host root@ +``` + +## Trade-off + +While this approach saves memory, it means the partitioning tools will be +whatever versions are available on the target system, rather than the specific +versions defined in your NixOS configuration. This could potentially lead to +version inconsistencies between the partitioning tools and the NixOS system +being installed. + +This trade-off is usually acceptable for memory-constrained environments where +installation would otherwise fail due to insufficient RAM. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/nix-path.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/nix-path.md new file mode 100644 index 00000000..1505af93 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/nix-path.md @@ -0,0 +1,57 @@ +# Nix-channels / `NIX_PATH` + +nixos-anywhere does not install channels onto the new system by default to save +time and disk space. This for example results in errors like: + +``` +(stack trace truncated; use '--show-trace' to show the full trace) + +error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I) + +at «none»:0: (source not available) +``` + +when using tools like nix-shell/nix-env that rely on `NIX_PATH` being set. + +# Solution 1: Set the `NIX_PATH` via nixos configuration (recommended) + +Instead of stateful channels, one can also populate the `NIX_PATH` using nixos +configuration instead: + +```nix +{ + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + # ... other inputs + + outputs = inputs@{ nixpkgs, ... }: + { + nixosConfigurations.yoursystem = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; # adapt to your actual system + modules = [ + # This line will populate NIX_PATH + { nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ]; } + # ... other modules and your configuration.nix + ]; + }; + }; +} +``` + +Advantage: This solution will be automatically kept up-to-date every time the +flake is updated. + +In your shell you will see something in your `$NIX_PATH`: + +```shellSession +$ echo $NIX_PATH +/root/.nix-defexpr/channels:nixpkgs=/nix/store/8b61j28rpy11dg8hanbs2x710d8w3v0d-source +``` + +# Solution 2: Manually add the channel + +On the installed machine, run: + +```shellSession +$ nix-channel --add https://nixos.org/channels/nixos-unstable nixos +$ nix-channel --update +``` diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/no-os.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/no-os.md new file mode 100644 index 00000000..1c07cb0a --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/no-os.md @@ -0,0 +1,71 @@ +# Installing on a machine with no operating system + +If your machine doesn't currently have an operating system installed, you can +still run `nixos-anywhere` remotely to automate the install. To do this, you +would first need to boot the target machine from the standard NixOS installer. +You can either boot from a USB or use `netboot`. + +The +[NixOS installation guide](https://nixos.org/manual/nixos/stable/index.html#sec-booting-from-usb) +has detailed instructions on how to boot the installer. + +When you run `nixos-anywhere`, it will determine whether a NixOS installer is +present by checking whether the `/etc/os-release` file contains the identifier +`VARIANT_ID=installer`. This identifier is available on releases NixOS 23.05 or +later. + +If an installer is detected, `nixos-anywhere` will not attempt to `kexec` into +its own image. This is particularly useful for targets that don't have enough +RAM for `kexec` or don't support `kexec`. + +NixOS starts an SSH server on the installer by default, but you need to set a +password in order to access it. To set a password for the `nixos` user, run the +following command in a terminal on the NixOS machine: + +``` +passwd +``` + +If you don't know the IP address of the installer on your network, you can find +it by running the following command: + +``` +$ ip addr +1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + inet6 ::1/128 scope host + valid_lft forever preferred_lft forever +2: eth0: mtu 1500 qdisc fq_codel state UP group default qlen 1000 + link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff + altname enp0s3 + altname ens3 + inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0 + valid_lft 86385sec preferred_lft 75585sec + inet6 fec0::5054:ff:fe12:3456/64 scope site dynamic mngtmpaddr noprefixroute + valid_lft 86385sec preferred_lft 14385sec + inet6 fe80::5054:ff:fe12:3456/64 scope link + valid_lft forever preferred_lft forever +``` + +This will display the IP addresses assigned to your network interface(s), +including the IP address of the installer. In the example output below, the +installer's IP addresses are `10.0.2.15`, `fec0::5054:ff:fe12:3456`, and +`fe80::5054:ff:fe12:3456%eth0`: + +To test if you can connect and your password works, you can use the following +SSH command (replace the IP address with your own): + +``` +ssh -v nixos@fec0::5054:ff:fe12:3456 +``` + +You can then use the IP address to run `nixos-anywhere` like this: + +``` +nix run github:nix-community/nixos-anywhere -- --flake '.#myconfig' --target-host nixos@fec0::5054:ff:fe12:3456 +``` + +This example assumes a flake in the current directory containing a configuration +named `myconfig`. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/secrets.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/secrets.md new file mode 100644 index 00000000..8d95ee78 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/secrets.md @@ -0,0 +1,76 @@ +# Secrets and full disk encryption + +The `nixos-anywhere` utility offers the capability to install secrets onto a +target machine. This feature is particularly beneficial when you want to +bootstrap secrets management tools such as +[sops-nix](https://github.com/Mic92/sops-nix) or +[agenix](https://github.com/ryantm/agenix), which rely on machine-specific +secrets to decrypt other uploaded secrets. + +## Example: Decrypting an OpenSSH Host Key with pass + +In this example, we demonstrate how to use a script to decrypt an OpenSSH host +key from the `pass` password manager and subsequently pass it to +`nixos-anywhere` during the installation process: + +```bash +#!/usr/bin/env bash + +# Create a temporary directory +temp=$(mktemp -d) + +# Function to cleanup temporary directory on exit +cleanup() { + rm -rf "$temp" +} +trap cleanup EXIT + +# Create the directory where sshd expects to find the host keys +install -d -m755 "$temp/etc/ssh" + +# Decrypt your private key from the password store and copy it to the temporary directory +pass ssh_host_ed25519_key > "$temp/etc/ssh/ssh_host_ed25519_key" + +# Set the correct permissions so sshd will accept the key +chmod 600 "$temp/etc/ssh/ssh_host_ed25519_key" + +# Install NixOS to the host system with our secrets +nixos-anywhere --extra-files "$temp" --flake '.#your-host' --target-host root@yourip +``` + +## Example: Uploading Disk Encryption Secrets + +In a similar vein, `nixos-anywhere` can upload disk encryption secrets, which +are necessary during formatting with disko. Here's an example that demonstrates +how to provide your disk encryption password as a file or via the `pass` utility +to `nixos-anywhere`: + +```bash +# Write your disk encryption password to a file +echo "my-super-safe-password" > /tmp/disk-1.key + +# Call nixos-anywhere with disk encryption keys +nixos-anywhere \ + --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ + --disk-encryption-keys /tmp/disk-2.key <(pass my-disk-encryption-password) \ + --flake '.#your-host' \ + root@yourip +``` + +In the above example, replace `"my-super-safe-password"` with your actual +encryption password, and `my-disk-encryption-password` with the relevant entry +in your pass password store. Also, ensure to replace `'.#your-host'` and +`root@yourip` with your actual flake and IP address, respectively. + +## Example: Using existing SSH host keys + +If the system contains existing trusted `/etc/ssh/ssh_host_*` SSH host keys and +certificates, `nixos-anywhere` can copy them in case they are necessary during +installation and system activation. + +``` +nixos-anywhere --copy-host-keys --flake '.#your-host' root@yourip +``` + +This would copy `/etc/ssh/ssh_host_*` to `/mnt` after kexec but before +installation, ignoring files that already exist in destination. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/terraform.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/terraform.md new file mode 100644 index 00000000..87974932 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/terraform.md @@ -0,0 +1,23 @@ +# Terraform + +The nixos-anywhere terraform modules allow you to use Terraform for installing +and updating NixOS. It simplifies the deployment process by integrating +nixos-anywhere functionality. + +Our terraform module requires the +[null](https://registry.terraform.io/providers/hashicorp/null/latest) and +[external](https://registry.terraform.io/providers/hashicorp/external/latest) +provider. + +You can get these by from nixpkgs like this: + +```nix +nix-shell -p '(pkgs.terraform.withPlugins (p: [ p.null p.external ]))' +``` + +You can add this expression the `packages` list in your devshell in flake.nix or +in shell.nix. + +Checkout out the +[module reference](https://github.com/nix-community/nixos-anywhere/tree/main/terraform) +for examples and module parameter on how to use the modules. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/use-without-flakes.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/use-without-flakes.md new file mode 100644 index 00000000..33419a9e --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/use-without-flakes.md @@ -0,0 +1,82 @@ +# Use without flakes + +First, +[import the disko NixOS module](https://github.com/nix-community/disko/blob/master/docs/HowTo.md#installing-nixos-module) +in your NixOS configuration and define disko devices as described in the +[examples](https://github.com/nix-community/disko/tree/master/example). + +Let's assume that your NixOS configuration lives in `configuration.nix` and your +target machine is called `machine`: + +## 1. Download your favourite disk layout: + +See https://github.com/nix-community/disko-templates/ for more examples: + +The example below will work with both UEFI and BIOS-based systems. + +```bash +curl https://raw.githubusercontent.com/nix-community/disko-templates/main/single-disk-ext4/disko-config.nix > ./disko-config.nix +``` + +## 2. Get a hardware-configuration.nix from on the target machine + +- **Option 1**: If NixOS is not installed, boot into an installer without first + installing NixOS. +- **Option 2**: Use the kexec tarball method, as described + [here](https://github.com/nix-community/nixos-images#kexec-tarballs). + +- **Generate Configuration**: Run the following command on the target machine: + + ```bash + nixos-generate-config --no-filesystems --dir /tmp/config + ``` + +This creates the necessary configuration files under `/tmp/config/`. Copy +`/tmp/config/nixos/hardware-configuration.nix` to your local machine into the +same directory as `disko-config.nix`. + +## 3. Set NixOS version to use + +```nix +# default.nix +let + # replace nixos-24.11 with your preferred nixos version or revision from here: https://status.nixos.org/ + nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-24.11.tar.gz"; +in +import (nixpkgs + "/nixos/lib/eval-config.nix") { + modules = [ ./configuration.nix ]; +} +``` + +## 4. Write a NixOS configuration + +```nix +# configuration.nix +{ + imports = [ + "${fetchTarball "https://github.com/nix-community/disko/tarball/master"}/module.nix" + ./disko-config.nix + ./hardware-configuration.nix + ]; + # Replace this with the system of the installation target you want to install!!! + disko.devices.disk.main.device = "/dev/sda"; + + # Set this to the NixOS version that you have set in the previous step. + # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion . + system.stateVersion = "24.11"; +} +``` + +## 5. Build and deploy with nixos-anywhere + +Your current directory now should contain the following files from the previous +step: + +- `configuration.nix`, `default.nix`, `disko-config.nix` and + `hardware-configuration.nix` + +Run `nixos-anywhere` as follows: + +```bash +nixos-anywhere --store-paths $(nix-build -A config.system.build.formatScript -A config.system.build.toplevel --no-out-link) root@machine +``` diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/logo.png b/launch/.terraform/modules/pixelfed.deploy/docs/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..434ad443ac1a065b53f74353187f7baaa45bcf29 GIT binary patch literal 29405 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/quickstart.md b/launch/.terraform/modules/pixelfed.deploy/docs/quickstart.md new file mode 100644 index 00000000..5eb1a10e --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/quickstart.md @@ -0,0 +1,334 @@ +# Quickstart Guide: nixos-anywhere + +**_Install NixOS everywhere via ssh_** + + + +[Documentation Index](./INDEX.md) + +## Introduction + +This guide documents a simple installation of NixOS using **nixos-anywhere** on +a target machine running x86_64 Linux with +[kexec](https://man7.org/linux/man-pages/man8/kexec.8.html) support. The example +used in this guide installs NixOS on a Hetzner cloud machine. The configuration +may be different for some other instances. We will be including further examples +in the [How To Guide](./howtos/INDEX.md) as and when they are available. + +You will need: + +- A [flake](https://wiki.nixos.org/wiki/Flakes) that controls the actions to be + performed +- A disk configuration containing details of the file system that will be + created on the new server. +- A target machine that is reachable via SSH, either using keys or a password, + and the privilege to either log in directly as root or a user with + password-less sudo. + +**nixos-anywhere** doesn’t need to be installed. You can run it directly from +[the Github repository.](https://github.com/nix-community/nixos-anywhere) + +Details of the flake, the disk configuration and the CLI command are discussed +below. + +## Steps required to run nixos-anywhere + +### 1. Enable Flakes + +Check if your nix has flakes enabled by running `nix flake`. It will tell you if +it's not. To enable flakes, refer to the +[NixOS Wiki](https://wiki.nixos.org/wiki/Flakes#enable-flakes). + +### 2. Initialize a Flake + +The easiest way to start is to copy our +[example flake.nix](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix) +into a new directory. This example is tailored for a virtual machine setup +similar to one on [Hetzner Cloud](https://www.hetzner.com/cloud), so you might +need to adapt it for your setup. + +If you already have a flake, you can use it by adding +[disko configuration](https://github.com/nix-community/disko?tab=readme-ov-file#how-to-use-disko) +to it. + +### 3. Configure your SSH key + +If you cloned +[our nixos-anywhere-example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/configuration.nix) +you will also replace the SSH key like this: In your configuration, locate the +line that reads: + +```bash +# change this to your ssh key + "CHANGE" +``` + +Replace the text `CHANGE` with your own SSH key. This is crucial, as you will +not be able to log into the target machine post-installation without it. If you +have a .pem file you can run + +```bash +ssh-keygen -y -f /path/to/your/key.pem +``` + +then paste the result in between the quotes like "ssh-rsa AAA..." + +### 4. Configure Storage + +In the same directory, create a file called `disk-config.nix`. This file will +define the disk layout for the +[disko](https://github.com/nix-community/disko/blob/master/docs/INDEX.md) tool, +which is used by nixos-anywhere to partition, format, and mount the disks. + +For a basic installation, you can copy the contents from the example provided +[here](https://github.com/nix-community/nixos-anywhere-examples/blob/main/disk-config.nix). +This configuration sets up a standard GPT (GUID Partition Table) that is +compatible with both EFI and BIOS systems and mounts the disk as `/dev/sda`. You +may need to adjust `/dev/sda` to match the correct disk on your machine. To +identify the disk, run the `lsblk` command and replace `sda` with the actual +disk name. + +For example, on this machine, we would select `/dev/nvme0n1` as the disk: + +``` +NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS +nvme0n1 259:0 0 1.8T 0 disk +``` + +If this setup does not match your requirements, you can choose an example that +better suits your disk layout from the +[disko examples](https://github.com/nix-community/disko/tree/master/example). +For more detailed information, refer to the +[disko documentation](https://github.com/nix-community/disko). + +### 5. Lock your Flake + +``` +nix flake lock +``` + +This will download your flake dependencies and make a `flake.lock` file that +describes how to reproducibly build your system. + +Optionally, you can commit these files to a repo such as Github, or you can +simply reference your local directory when you run **nixos-anywhere**. This +example uses a local directory on the source machine. + +### 6. Connectivity to the Target Machine + +**nixos-anywhere** will create a temporary SSH key to use for the installation. +If your SSH key is not found, you will be asked for your password. If you are +using a non-root user, you must have access to sudo without a password. To avoid +SSH password prompts, set the `SSHPASS` environment variable to your password +and add `--env-password` to the `nixos-anywhere` command. If providing a +specific SSH key through `-i` (identity_file), this key will then be used for +the installation and no temporary SSH key will be created. + +### 7. (Optional) Test your NixOS and Disko configuration + +Skip this step and continue with Step 8, if you don't have a hardware +configuration (hardware-configuration.nix or facter.json) generated yet or make +sure you don't import non-existing hardware-configuration.nix or facter.json +during running the vm test. + +The following command will automatically test your nixos configuration and run +disko inside a virtual machine, where + +- `` is the path to the directory or repository + containing `flake.nix` and `disk-config.nix` + +- `` must match the name that immediately follows the text + `nixosConfigurations.` in the flake, as indicated by the comment in the + [example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix). + +``` +nix run github:nix-community/nixos-anywhere -- --flake # --vm-test +``` + +### 8. Prepare Hardware Configuration + +If you're not using a virtual machine, it's recommended to allow +`nixos-anywhere` to generate a hardware configuration during installation. This +ensures that essential drivers, such as those required for disk detection, are +properly configured. + +To enable `nixos-anywhere` to integrate its generated configuration into your +NixOS setup, you need to include an import for the hardware configuration +beforehand. + +Here’s an example: + +```diff + nixosConfigurations.generic = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + disko.nixosModules.disko + ./configuration.nix ++ ./hardware-configuration.nix + ]; + }; +``` + +When running `nixos-anywhere`, this file is automatically generated by including +the following flags in your command: +`--generate-hardware-config nixos-generate-config ./hardware-configuration.nix`. +The second flag, `./hardware-configuration.nix`, specifies where +`nixos-generate-config` will store the configuration. Adjust this path to +reflect the location where you want the `hardware-configuration.nix` for this +machine to be saved. + +#### 8.1 nixos-facter + +As an alternative to `nixos-generate-config`, you can use the experimental +[nixos-facter](https://github.com/numtide/nixos-facter) command, which offers +more comprehensive hardware reports and advanced configuration options. + +To use `nixos-facter`, add the following to your flake inputs: + +```diff + { ++ inputs.nixos-facter-modules.url = "github:numtide/nixos-facter-modules"; + } +``` + +Next, import the module into your configuration and specify `facter.json` as the +path where the hardware report will be saved: + +```diff + nixosConfigurations.generic-nixos-facter = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + disko.nixosModules.disko + ./configuration.nix ++ nixos-facter-modules.nixosModules.facter ++ { config.facter.reportPath = ./facter.json } + ]; + }; +``` + +To generate the configuration for `nixos-facter` with `nixos-anywhere`, use the +following flags: `--generate-hardware-config nixos-facter ./facter.json`. The +second flag, `./facter.json`, specifies where `nixos-generate-config` will store +the hardware report. Adjust this path to suit the location where you want the +`facter.json` to be saved. + +### 9. Run it + +You can now run **nixos-anywhere** from the command line as shown below, where: + +- `` is the path to the directory or repository + containing `flake.nix` and `disk-config.nix` + +- `` must match the name that immediately follows the text + `nixosConfigurations.` in the flake, as indicated by the comment in the + [example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix). + +- `` is the IP address of the target machine. + +``` +nix run github:nix-community/nixos-anywhere -- --flake # --target-host root@ +``` + +The command would look  like this if you had created your files in a directory +named `/home/mydir/test` and the IP address of your target machine is +`37.27.18.135`: + +``` +nix run github:nix-community/nixos-anywhere -- --flake /home/mydir/test#hetzner-cloud --target-host root@37.27.18.135 +``` + +If you also need to generate hardware configuration amend flags for +nixos-generate-config: + +``` +nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-generate-config ./hardware-configuration.nix --flake # --target-host root@ +``` + +Or these flags if you are using nixos-facter instead: + +``` +nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-facter ./facter.json --flake # --target-host root@ +``` + +Adjust the location of `./hardware-configuration.nix` and `./facter.json` +accordingly. + +**nixos-anywhere** will then run, showing various output messages at each stage. +It may take some time to complete, depending on Internet speeds. It should +finish by showing the messages below before returning to the command prompt. + +``` +Installation finished. No error reported. +Warning: Permanently added '' (ED25519) to the list of known hosts +``` + +When this happens, the target server will have been overwritten with a new +installation of NixOS. Note that the server's public SSH key will have changed. + +If you have previously accessed this server using SSH, you may see the following +message the next time you try to log in to the target. + +``` +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! +Someone could be eavesdropping on you right now (man-in-the-middle attack)! +It is also possible that a host key has just been changed. +The fingerprint for the ED25519 key sent by the remote host is +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. +Please contact your system administrator. +Add correct host key in ~/.ssh/known_hosts to get rid of this message. +Offending ECDSA key in ~/.ssh/known_hosts:6 + remove with: + ssh-keygen -f ~/.ssh/known_hosts" -R "" +Host key for has changed and you have requested strict checking. +Host key verification failed. +``` + +This is because the `known_hosts` file in the `.ssh` directory now contains a +mismatch, since the server has been overwritten. To solve this, use a text +editor to remove the old entry from the `known_hosts` file (or use the command +`ssh-keygen -R `). The next connection attempt will then treat this +as a new server. + +The error message line `Offending ECDSA key in ~/.ssh/known_hosts:6` gives the +line number that needs to be removed from the `known_hosts` file (line 6 in this +example). + +# Finished! + +**nixos-anywhere**'s job is now done, as it is a tool to install NixOS onto the +target machine. + +Any future changes to the configuration should be made to your flake. You would +reference this flake when using the NixOS `nixos-rebuild` command or a separate +3rd party deployment tool of your choice i.e. +[deploy-rs](https://github.com/serokell/deploy-rs), +[colmena](https://github.com/zhaofengli/colmena), +[nixinate](https://github.com/MatthewCroughan/nixinate), +[clan](https://clan.lol/) (author's choice). + +To update on the machine locally (replace `` with your flake +i.e. `.#` if your flake is in the current directory): + +``` +nixos-rebuild switch --flake +``` + +To update remotely you will need to have configured an +[ssh server](https://search.nixos.org/options?show=services.sshd.enable) and +your ssh key for the +[root user](https://search.nixos.org/options?show=users.users.%3Cname%3E.openssh.authorizedKeys.keys): + +``` +nixos-rebuild switch --flake --target-host "root@" +``` + +See the Nix documentation for use of the flake +[URL-like syntax](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake#url-like-syntax). + +For more information on different use cases of **nixos-anywhere** please refer +to the [How to Guide](./howtos/INDEX.md), and for more technical information and +explanation of known error messages, refer to the +[Reference Manual](./reference.md). diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/reference.md b/launch/.terraform/modules/pixelfed.deploy/docs/reference.md new file mode 100644 index 00000000..83916572 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/reference.md @@ -0,0 +1,137 @@ +# Reference Manual: nixos-anywhere + +**_Install NixOS everywhere via ssh_** + + + +[Documentation Index](./INDEX.md) + +TODO: Populate this guide properly + +## Contents + +[Command Line Usage](#command-line-usage) + +[Explanation of known error messages](#explanation-of-known-error-messages) + +## Command Line Usage + + + +``` +Usage: nixos-anywhere [options] [] + +Options: + +* -f, --flake + set the flake to install the system from. i.e. + nixos-anywhere --flake .#mymachine + Also supports variants: + nixos-anywhere --flake .#nixosConfigurations.mymachine.config.virtualisation.vmVariant +* --target-host + set the SSH target host to deploy onto. +* -i + selects which SSH private key file to use. +* -p, --ssh-port + set the ssh port to connect with +* --ssh-option + set an ssh option +* -L, --print-build-logs + print full build logs +* --env-password + set a password used by ssh-copy-id, the password should be set by + the environment variable SSHPASS +* -s, --store-paths + set the store paths to the disko-script and nixos-system directly + if this is given, flake is not needed +* --kexec + use another kexec tarball to bootstrap NixOS +* --kexec-extra-flags + extra flags to add into the call to kexec, e.g. "--no-sync" +* --ssh-store-setting + ssh store settings appended to the store URI, e.g. "compress true". needs to be URI encoded. +* --post-kexec-ssh-port + after kexec is executed, use a custom ssh port to connect. Defaults to 22 +* --copy-host-keys + copy over existing /etc/ssh/ssh_host_* host keys to the installation +* --extra-files + contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten + Copied files will be owned by root unless specified by --chown option. See documentation for details. +* --chown + change ownership of recursively. Recommended to use uid:gid as opposed to username:groupname for ownership. + Option can be specified more than once. +* --disk-encryption-keys + copy the contents of the file or pipe in local_path to remote_path in the installer environment, + after kexec but before installation. Can be repeated. +* --no-substitute-on-destination + disable passing --substitute-on-destination to nix-copy +* --debug + enable debug output +* --show-trace + show nix build traces +* --option + nix option to pass to every nix related command +* --from + URL of the source Nix store to copy the nixos and disko closure from +* --build-on-remote + build the closure on the remote machine instead of locally and copy-closuring it +* --vm-test + build the system and test the disk configuration inside a VM without installing it to the target. +* --generate-hardware-config nixos-facter|nixos-generate-config + generate a hardware-configuration.nix file using the specified backend and write it to the specified path. + The backend can be either 'nixos-facter' or 'nixos-generate-config'. +* --phases + comma separated list of phases to run. Default is: kexec,disko,install,reboot + kexec: kexec into the nixos installer + disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode + install: install the system + reboot: unmount the filesystems, export any ZFS pools and reboot the machine +* --disko-mode disko|mount|format + set the disko mode to format, mount or destroy. Default is disko. + disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode +* --no-disko-deps + This will only upload the disko script and not the partitioning tools dependencies. + Installers usually have dependencies available. + Use this option if your target machine has not enough RAM to store the dependencies in memory. +* --build-on auto|remote|local + sets the build on settings to auto, remote or local. Default is auto. + auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build + local: will build on the local host + remote: will build on the remote host +``` + +## Explanation of known error messages + +TODO: Add additional error messages and meanings. Fill in missing explanations + +This section lists known error messages and their explanations. Some +explanations may refer to the following CLI syntax: + +`nix run github:nix-community/nixos-anywhere -- --flake # root@` + +This list is not comprehensive. It's possible you may encounter errors that +originate from the underlying operating system. These should be documented in +the relevant operating system manual. + +| Id | Message | Explanation | +| -- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 1 | Failure unpacking initrd | You don't have enough RAM to hold `kexec` | +| 2 | Flake  does not provide attribute | The configuration name you specified in your flake URI is not defined as a NixOS configuration in your flake eg if your URI was mydir#myconfig, then myconfig should be included in the flake as `nixosConfigurations.myconfig` | +| 3 | Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri. | As for error #2 | +| | For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri | | +| 4 | Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already | TODO: Explain | +| 5 | ssh-host must be set |  has not been supplied | +| 6 | and must be existing store-paths | This occurs if the -s switch has been used to specify the disko script and store path correctly, and the scripts cannot be found at the given URI | +| 7 | flake must be set | This occurs if both the -flake option (use a flake) and the -s option (specify paths directly) have been omitted. Either one or the other must be specified. | +| 8 | no tar command found, but required to unpack kexec tarball | The destination machine does not have a `tar` command available. This is needed to unpack the `kexec`. | +| 9 | no setsid command found, but required to run the kexec script under a new session | The destination machine does not have the `setsid` command available | +| 10 | This script requires Linux as the operating system, but got | The destination machine is not running Linux | +| 11 | The default kexec image only support x86_64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information. | By default, `nixos-anywhere` uses its own `kexec` image, which will only run on x86_64 CPUs. For other CPU types, you can use your own `kexec` image instead. Refer to the [How To Guide](./howtos#using-your-own-kexec-image) for instructions. | +| 12 | Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri. | This is a `disko` error. As for Error #2 | +| | For example, to use the output diskoConfigurations.foo from the flake.nix, append \"#foo\" to the flake-uri. | | +| 13 | mode must be either create, mount or zap_create_mount | This is a `disko` error. The `disko` switches have not been used correctly. This could happen if you supplied your own `disko` script using the -s option | +| 14 | disko config must be an existing file or flake must be set | This is a `disko` error. This will happen if the `disko.devices` entry in your flake doesn't match the name of a file in the same location as your flake. | +| | | | +| | | | +| | | | +| | | | diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/requirements.md b/launch/.terraform/modules/pixelfed.deploy/docs/requirements.md new file mode 100644 index 00000000..67b14f4d --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/docs/requirements.md @@ -0,0 +1,39 @@ +# System Requirements: nixos-anywhere + +**_Install NixOS everywhere via ssh_** + + + +[Documentation Index](./INDEX.md) + +## Requirements + +### Source Machine + +1. **Supported Systems:** + - Linux or macOS computers with Nix installed. + - NixOS + - Windows systems using WSL2. + +2. **Nix Installation:** If Nix is not yet installed on your system, refer to + the [nix installation page](https://nixos.org/download#download-nix). + +### Destination Machine + +The machine must be reachable over the public internet or local network. +Nixos-anywhere does not support wifi networks. If a VPN is needed, define a +custom installer via the --kexec flag which connects to your VPN. + +1. **Direct Boot Option:** + - Must be already running a NixOS installer. + +2. **Alternative Boot Options:** If not booting directly from a NixOS installer + image: + - **Architecture & Support:** Must be operating on: + - x86-64 or aarch64 Linux systems with kexec support. Note: While most + x86-64 Linux systems support kexec, if you're using an architecture other + than those mentioned, you may need to specify a + [different kexec image](./howtos/INDEX.md#using-your-own-kexec-image) + manually. + - **Memory Requirements:** + - At least 1 GB of RAM (excluding swap space). diff --git a/launch/.terraform/modules/pixelfed.deploy/flake.lock b/launch/.terraform/modules/pixelfed.deploy/flake.lock new file mode 100644 index 00000000..5a7232ca --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/flake.lock @@ -0,0 +1,132 @@ +{ + "nodes": { + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1741786315, + "narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=", + "owner": "nix-community", + "repo": "disko", + "rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "master", + "repo": "disko", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1741352980, + "narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixos-images": { + "inputs": { + "nixos-stable": [ + "nixos-stable" + ], + "nixos-unstable": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1741866599, + "narHash": "sha256-Re/T1Cjmiis0tdphj/Wjqt+c2RlMw/il7LBWzvwQPz0=", + "owner": "nix-community", + "repo": "nixos-images", + "rev": "63285ff93fc1daa2caac9f86e2302ae4edc5e84f", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-images", + "type": "github" + } + }, + "nixos-stable": { + "locked": { + "lastModified": 1741862977, + "narHash": "sha256-prZ0M8vE/ghRGGZcflvxCu40ObKaB+ikn74/xQoNrGQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "cdd2ef009676ac92b715ff26630164bb88fec4e0", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1742051767, + "narHash": "sha256-JpyjnalnIqJ7cvP8HzaoJN9/i2bDx83dToodHHjGuNg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "ec886d10b507760c90ed01e2eac7f0679d0a47ae", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "disko": "disko", + "flake-parts": "flake-parts", + "nixos-images": "nixos-images", + "nixos-stable": "nixos-stable", + "nixpkgs": "nixpkgs", + "treefmt-nix": "treefmt-nix" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1739829690, + "narHash": "sha256-mL1szCeIsjh6Khn3nH2cYtwO5YXG6gBiTw1A30iGeDU=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "3d0579f5cc93436052d94b73925b48973a104204", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/launch/.terraform/modules/pixelfed.deploy/flake.nix b/launch/.terraform/modules/pixelfed.deploy/flake.nix new file mode 100644 index 00000000..d60191cc --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/flake.nix @@ -0,0 +1,55 @@ +{ + description = "A universal nixos installer, just needs ssh access to the target system"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small"; + flake-parts = { + url = "github:hercules-ci/flake-parts"; + inputs.nixpkgs-lib.follows = "nixpkgs"; + }; + + # used for testing + disko = { + url = "github:nix-community/disko/master"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nixos-stable.url = "github:NixOS/nixpkgs/nixos-24.11"; + nixos-images.url = "github:nix-community/nixos-images"; + nixos-images.inputs.nixos-unstable.follows = "nixpkgs"; + nixos-images.inputs.nixos-stable.follows = "nixos-stable"; + + # used for development + treefmt-nix = { + url = "github:numtide/treefmt-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = + inputs: + inputs.flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ + "x86_64-linux" + "x86_64-darwin" + "aarch64-linux" + "aarch64-darwin" + ]; + imports = [ + ./src/flake-module.nix + ./tests/flake-module.nix + ./docs/flake-module.nix + # allow to disable treefmt in downstream flakes + ] ++ inputs.nixpkgs.lib.optional (inputs.treefmt-nix ? flakeModule) ./treefmt/flake-module.nix; + + perSystem = + { self', lib, ... }: + { + checks = + let + packages = lib.mapAttrs' (n: lib.nameValuePair "package-${n}") self'.packages; + devShells = lib.mapAttrs' (n: lib.nameValuePair "devShell-${n}") self'.devShells; + in + packages // devShells; + }; + }; +} diff --git a/launch/.terraform/modules/pixelfed.deploy/scripts/create-release.sh b/launch/.terraform/modules/pixelfed.deploy/scripts/create-release.sh new file mode 100755 index 00000000..7f203035 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/scripts/create-release.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env nix +#! nix shell nixpkgs#bash nixpkgs#gnused --command bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" +cd "$SCRIPT_DIR/.." + +version=${1:-} +if [[ -z $version ]]; then + echo "USAGE: $0 version" >&2 + exit 1 +fi + +if [[ "$(git symbolic-ref --short HEAD)" != "main" ]]; then + echo "must be on main branch" >&2 + exit 1 +fi + +# ensure we are up-to-date +uncommitted_changes=$(git diff --compact-summary) +if [[ -n $uncommitted_changes ]]; then + echo -e "There are uncommitted changes, exiting:\n${uncommitted_changes}" >&2 + exit 1 +fi +git pull git@github.com:nix-community/nixos-anywhere main +unpushed_commits=$(git log --format=oneline origin/main..main) +if [[ $unpushed_commits != "" ]]; then + echo -e "\nThere are unpushed changes, exiting:\n$unpushed_commits" >&2 + exit 1 +fi +sed -i -e "s!version = \".*\";!version = \"${version}\";!" src/default.nix +git add src/default.nix +nix-shell -p nix-fast-build --command "nix-fast-build --eval-workers 2" +git commit -m "bump version ${version}" +git tag "${version}" + +echo "now run 'git push --tags origin main'" diff --git a/launch/.terraform/modules/pixelfed.deploy/src/default.nix b/launch/.terraform/modules/pixelfed.deploy/src/default.nix new file mode 100644 index 00000000..c1719320 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/src/default.nix @@ -0,0 +1,63 @@ +{ + stdenv, + openssh, + gitMinimal, + nixVersions, + nix, + coreutils, + curl, + gnugrep, + gnutar, + gawk, + findutils, + gnused, + sshpass, + terraform-docs, + lib, + makeWrapper, + mkShellNoCC, +}: +let + runtimeDeps = [ + gitMinimal # for git flakes + # pinned because nix-copy-closure hangs if ControlPath provided for SSH: https://github.com/NixOS/nix/issues/8480 + (if lib.versionAtLeast nix.version "2.16" then nix else nixVersions.nix_2_16) + coreutils + curl # when uploading tarballs + gnugrep + gawk + findutils + gnused # needed by ssh-copy-id + sshpass # used to provide password for ssh-copy-id + gnutar # used to upload extra-files + ]; +in +stdenv.mkDerivation { + pname = "nixos-anywhere"; + version = "1.8.0"; + src = ./..; + nativeBuildInputs = [ makeWrapper ]; + installPhase = '' + install -D --target-directory=$out/libexec/nixos-anywhere/ -m 0755 src/*.sh + + # We prefer the system's openssh over our own, since it might come with features not present in ours: + # https://github.com/nix-community/nixos-anywhere/issues/62 + makeShellWrapper $out/libexec/nixos-anywhere/nixos-anywhere.sh $out/bin/nixos-anywhere \ + --prefix PATH : ${lib.makeBinPath runtimeDeps} --suffix PATH : ${lib.makeBinPath [ openssh ]} + ''; + + # Dependencies for our devshell + passthru.devShell = mkShellNoCC { + packages = runtimeDeps ++ [ + openssh + terraform-docs + ]; + }; + + meta = with lib; { + description = "Install nixos everywhere via ssh"; + homepage = "https://github.com/nix-community/nixos-anywhere"; + license = licenses.mit; + platforms = platforms.all; + }; +} diff --git a/launch/.terraform/modules/pixelfed.deploy/src/flake-module.nix b/launch/.terraform/modules/pixelfed.deploy/src/flake-module.nix new file mode 100644 index 00000000..d131219d --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/src/flake-module.nix @@ -0,0 +1,11 @@ +{ + perSystem = + { config, pkgs, ... }: + { + packages = { + nixos-anywhere = pkgs.callPackage ./. { }; + default = config.packages.nixos-anywhere; + }; + devShells.default = config.packages.nixos-anywhere.devShell; + }; +} diff --git a/launch/.terraform/modules/pixelfed.deploy/src/get-facts.sh b/launch/.terraform/modules/pixelfed.deploy/src/get-facts.sh new file mode 100755 index 00000000..80434422 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/src/get-facts.sh @@ -0,0 +1,23 @@ +#!/bin/sh +set -efu "${enableDebug:-}" +has() { + command -v "$1" >/dev/null && echo "y" || echo "n" +} +isNixos=$(if test -f /etc/os-release && grep -Eq 'ID(_LIKE)?="?nixos"?' /etc/os-release; then echo "y"; else echo "n"; fi) +cat </dev/null 2>/dev/null || ! ip -6 r g :: >/dev/null 2>/dev/null; then echo "n"; else echo "y"; fi) +hasTar=$(has tar) +hasCpio=$(has cpio) +hasSudo=$(has sudo) +hasDoas=$(has doas) +hasWget=$(has wget) +hasCurl=$(has curl) +hasSetsid=$(has setsid) +hasNixOSFacter=$(command -v nixos-facter >/dev/null && echo "y" || echo "n") +FACTS diff --git a/launch/.terraform/modules/pixelfed.deploy/src/nixos-anywhere.sh b/launch/.terraform/modules/pixelfed.deploy/src/nixos-anywhere.sh new file mode 100755 index 00000000..c6cadb98 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/src/nixos-anywhere.sh @@ -0,0 +1,880 @@ +#!/usr/bin/env bash +set -euo pipefail + +here=$(dirname "${BASH_SOURCE[0]}") +flake="" +flakeAttr="" +kexecUrl="" +kexecExtraFlags="" +sshStoreSettings="" +enableDebug="" +nixBuildFlags=() +diskoAttr="" +diskoScript="" +diskoMode="disko" +diskoDeps=y +nixosSystem="" +extraFiles="" +vmTest="n" +nixOptions=( + --extra-experimental-features 'nix-command flakes' + "--no-write-lock-file" +) +SSH_PRIVATE_KEY=${SSH_PRIVATE_KEY-} + +declare -A phases +phases[kexec]=1 +phases[disko]=1 +phases[install]=1 +phases[reboot]=1 + +hardwareConfigBackend=none +hardwareConfigPath= +sshPrivateKeyFile= +if [ -t 0 ]; then # stdin is a tty, we allow interactive input to ssh i.e. passwords + sshTtyParam="-t" +else + sshTtyParam="-T" +fi +sshConnection= +postKexecSshPort=22 +buildOnRemote=n +buildOn=auto +envPassword=n + +# Facts set by get-facts.sh +isOs= +isArch= +isKexec= +isInstaller= +isContainer= +hasIpv6Only= +hasTar= +hasCpio= +hasSudo= +hasDoas= +hasWget= +hasCurl= +hasSetsid= +hasNixOSFacter= + +sshKeyDir=$(mktemp -d) +trap 'rm -rf "$sshKeyDir"' EXIT +mkdir -p "$sshKeyDir" + +declare -A diskEncryptionKeys=() +declare -A extraFilesOwnership=() +declare -a nixCopyOptions=() +declare -a sshArgs=() + +showUsage() { + cat <] + +Options: + +* -f, --flake + set the flake to install the system from. i.e. + nixos-anywhere --flake .#mymachine + Also supports variants: + nixos-anywhere --flake .#nixosConfigurations.mymachine.config.virtualisation.vmVariant +* --target-host + set the SSH target host to deploy onto. +* -i + selects which SSH private key file to use. +* -p, --ssh-port + set the ssh port to connect with +* --ssh-option + set an ssh option +* -L, --print-build-logs + print full build logs +* --env-password + set a password used by ssh-copy-id, the password should be set by + the environment variable SSHPASS +* -s, --store-paths + set the store paths to the disko-script and nixos-system directly + if this is given, flake is not needed +* --kexec + use another kexec tarball to bootstrap NixOS +* --kexec-extra-flags + extra flags to add into the call to kexec, e.g. "--no-sync" +* --ssh-store-setting + ssh store settings appended to the store URI, e.g. "compress true". needs to be URI encoded. +* --post-kexec-ssh-port + after kexec is executed, use a custom ssh port to connect. Defaults to 22 +* --copy-host-keys + copy over existing /etc/ssh/ssh_host_* host keys to the installation +* --extra-files + contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten + Copied files will be owned by root unless specified by --chown option. See documentation for details. +* --chown + change ownership of recursively. Recommended to use uid:gid as opposed to username:groupname for ownership. + Option can be specified more than once. +* --disk-encryption-keys + copy the contents of the file or pipe in local_path to remote_path in the installer environment, + after kexec but before installation. Can be repeated. +* --no-substitute-on-destination + disable passing --substitute-on-destination to nix-copy +* --debug + enable debug output +* --show-trace + show nix build traces +* --option + nix option to pass to every nix related command +* --from + URL of the source Nix store to copy the nixos and disko closure from +* --build-on-remote + build the closure on the remote machine instead of locally and copy-closuring it +* --vm-test + build the system and test the disk configuration inside a VM without installing it to the target. +* --generate-hardware-config nixos-facter|nixos-generate-config + generate a hardware-configuration.nix file using the specified backend and write it to the specified path. + The backend can be either 'nixos-facter' or 'nixos-generate-config'. +* --phases + comma separated list of phases to run. Default is: kexec,disko,install,reboot + kexec: kexec into the nixos installer + disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode + install: install the system + reboot: unmount the filesystems, export any ZFS pools and reboot the machine +* --disko-mode disko|mount|format + set the disko mode to format, mount or destroy. Default is disko. + disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode +* --no-disko-deps + This will only upload the disko script and not the partitioning tools dependencies. + Installers usually have dependencies available. + Use this option if your target machine has not enough RAM to store the dependencies in memory. +* --build-on auto|remote|local + sets the build on settings to auto, remote or local. Default is auto. + auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build + local: will build on the local host + remote: will build on the remote host +USAGE +} + +abort() { + echo "aborted: $*" >&2 + exit 1 +} + +step() { + echo "### $* ###" +} + +parseArgs() { + local substituteOnDestination=y + local printBuildLogs=n + local buildOnRemote=n + while [[ $# -gt 0 ]]; do + case "$1" in + -f | --flake) + flake=$2 + shift + ;; + --target-host) + sshConnection=$2 + shift + ;; + -i) + sshPrivateKeyFile=$2 + shift + ;; + -p | --ssh-port) + sshArgs+=("-p" "$2") + shift + ;; + --ssh-option) + sshArgs+=("-o" "$2") + shift + ;; + -L | --print-build-logs) + printBuildLogs=y + ;; + -s | --store-paths) + diskoScript=$(readlink -f "$2") + nixosSystem=$(readlink -f "$3") + shift + shift + ;; + --generate-hardware-config) + if [[ $# -lt 3 ]]; then + abort "Missing arguments for --generate-hardware-config " + fi + case "$2" in + nixos-facter | nixos-generate-config) + hardwareConfigBackend=$2 + ;; + *) + abort "Unknown hardware config backend: $2" + ;; + esac + hardwareConfigPath=$3 + shift + shift + ;; + -t | --tty) + echo "the '$1' flag is deprecated, a tty is now detected automatically" >&2 + ;; + --help) + showUsage + exit 0 + ;; + --kexec) + kexecUrl=$2 + shift + ;; + --kexec-extra-flags) + kexecExtraFlags=$2 + shift + ;; + --ssh-store-setting) + key=$2 + shift + value=$2 + shift + sshStoreSettings+="$sshStoreSettings$key=$value&" + shift + ;; + --post-kexec-ssh-port) + postKexecSshPort=$2 + shift + ;; + --copy-host-keys) + copyHostKeys=y + ;; + --show-trace) + nixBuildFlags+=("--show-trace") + ;; + --debug) + enableDebug="-x" + printBuildLogs=y + set -x + ;; + --disko-mode) + case "$2" in + format | mount | disko) + diskoMode=$2 + ;; + *) + abort "Supported values for --disko-mode are disko, mount and format. Unknown mode : $2" + ;; + esac + + shift + ;; + --no-disko-deps) + diskoDeps=n + ;; + --build-on) + case "$2" in + auto | local | remote) + buildOn=$2 + ;; + *) + abort "Supported values for --build-on are auto, local and remote. Unknown mode : $2" + ;; + esac + + shift + ;; + --extra-files) + extraFiles=$2 + shift + ;; + --chown) + extraFilesOwnership["$2"]="$3" + shift + shift + ;; + --disk-encryption-keys) + diskEncryptionKeys["$2"]="$3" + shift + shift + ;; + --phases) + phases[kexec]=0 + phases[disko]=0 + phases[install]=0 + phases[reboot]=0 + IFS=, read -r -a phaseList <<<"$2" + for phase in "${phaseList[@]}"; do + if [[ ${phases[$phase]:-unset} == unset ]]; then + abort "Unknown phase: $phase" + fi + phases[$phase]=1 + done + shift + ;; + --stop-after-disko) + echo "WARNING: --stop-after-disko is deprecated, use --phases kexec,disko instead" 2>&1 + phases[kexec]=1 + phases[disko]=1 + phases[install]=0 + phases[reboot]=0 + ;; + --no-reboot) + echo "WARNING: --no-reboot is deprecated, use --phases kexec,disko,install instead" 2>&1 + phases[kexec]=1 + phases[disko]=1 + phases[install]=1 + phases[reboot]=0 + ;; + --from) + nixCopyOptions+=("--from" "$2") + shift + ;; + --option) + key=$2 + shift + value=$2 + shift + nixOptions+=("--option" "$key" "$value") + ;; + --no-substitute-on-destination) + substituteOnDestination=n + ;; + --build-on-remote) + echo "WARNING: --build-on-remote is deprecated, use --build-on remote instead" 2>&1 + buildOnRemote=y + buildOn="remote" + ;; + --env-password) + envPassword=y + ;; + --vm-test) + vmTest=y + ;; + *) + if [[ -z ${sshConnection} ]]; then + sshConnection="$1" + else + showUsage + exit 1 + fi + ;; + esac + shift + done + + diskoAttr="${diskoMode}Script" + + if [[ ${diskoDeps} == "n" ]]; then + diskoAttr="${diskoAttr}NoDeps" + fi + + if [[ ${printBuildLogs} == "y" ]]; then + nixOptions+=("-L") + fi + + if [[ $substituteOnDestination == "y" ]]; then + nixCopyOptions+=("--substitute-on-destination") + fi + + if [[ $vmTest == "n" ]] && [[ -z ${sshConnection} ]]; then + abort "ssh-host must be set" + fi + + if [[ $buildOn == "local" ]] && [[ $buildOnRemote == "y" ]]; then + abort "Conflicting flags: --build-on local and --build-on-remote used." + fi + + if [[ -n ${flake} ]]; then + if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then + flake="${BASH_REMATCH[1]}" + flakeAttr="${BASH_REMATCH[2]}" + fi + if [[ -z ${flakeAttr} ]]; then + echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri." >&2 + echo 'For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri.' >&2 + exit 1 + fi + + # Support .#foo shorthand + if [[ $flakeAttr != nixosConfigurations.* ]]; then + flakeAttr="nixosConfigurations.\"$flakeAttr\".config" + fi + fi + +} + +# ssh wrapper +runSshNoTty() { + ssh -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@" +} +runSshTimeout() { + timeout 10 ssh -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@" +} +runSsh() { + ssh "$sshTtyParam" -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@" +} + +nixCopy() { + NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $sshKeyDir/nixos-anywhere ${sshArgs[*]}" nix copy \ + "${nixOptions[@]}" \ + "${nixCopyOptions[@]}" \ + "$@" +} +nixBuild() { + NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $sshKeyDir/nixos-anywhere ${sshArgs[*]}" nix build \ + --print-out-paths \ + --no-link \ + "${nixBuildFlags[@]}" \ + "${nixOptions[@]}" \ + "$@" +} + +runVmTest() { + if [[ -z ${flakeAttr} ]]; then + echo "--vm-test is not supported with --store-paths" >&2 + echo "Please use --flake instead or build config.system.build.installTest of your nixos configuration manually" >&2 + exit 1 + fi + + if [[ ${buildOn} == "remote" ]]; then + echo "--vm-test is not supported with --build-on-remote" >&2 + exit 1 + fi + if [[ -n ${extraFiles} ]]; then + echo "--vm-test is not supported with --extra-files" >&2 + exit 1 + fi + if [ ${#diskEncryptionKeys[@]} -gt 0 ]; then + echo "--vm-test is not supported with --disk-encryption-keys" >&2 + exit 1 + fi + nix build \ + --print-out-paths \ + --no-link \ + -L \ + "${nixBuildFlags[@]}" \ + "${nixOptions[@]}" \ + "${flake}#${flakeAttr}.system.build.installTest" +} + +uploadSshKey() { + # ssh-copy-id requires this directory + mkdir -p "$HOME/.ssh/" + if [[ -n ${sshPrivateKeyFile} ]]; then + cp "$sshPrivateKeyFile" "$sshKeyDir/nixos-anywhere" + ssh-keygen -y -f "$sshKeyDir/nixos-anywhere" >"$sshKeyDir/nixos-anywhere.pub" + else + # we generate a temporary ssh keypair that we can use during nixos-anywhere + ssh-keygen -t ed25519 -f "$sshKeyDir"/nixos-anywhere -P "" -C "nixos-anywhere" >/dev/null + fi + + declare -a sshCopyIdArgs + if [[ -n ${sshPrivateKeyFile} ]]; then + unset SSH_AUTH_SOCK # don't use system agent if key was supplied + sshCopyIdArgs+=(-o "IdentityFile=${sshPrivateKeyFile}" -f) + fi + + step Uploading install SSH keys + until + if [[ ${envPassword} == y ]]; then + sshpass -e \ + ssh-copy-id \ + -i "$sshKeyDir"/nixos-anywhere.pub \ + -o ConnectTimeout=10 \ + -o UserKnownHostsFile=/dev/null \ + -o IdentitiesOnly=yes \ + -o StrictHostKeyChecking=no \ + "${sshCopyIdArgs[@]}" \ + "${sshArgs[@]}" \ + "$sshConnection" + else + ssh-copy-id \ + -i "$sshKeyDir"/nixos-anywhere.pub \ + -o ConnectTimeout=10 \ + -o UserKnownHostsFile=/dev/null \ + -o StrictHostKeyChecking=no \ + "${sshCopyIdArgs[@]}" \ + "${sshArgs[@]}" \ + "$sshConnection" + fi + do + sleep 3 + done +} + +importFacts() { + step Gathering machine facts + local facts filteredFacts + if ! facts=$(runSsh -o ConnectTimeout=10 enableDebug=$enableDebug sh -- <"$here"/get-facts.sh); then + exit 1 + fi + filteredFacts=$(echo "$facts" | grep -E '^(has|is)[A-Za-z0-9_]+=\S+') + if [[ -z $filteredFacts ]]; then + abort "Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already" + fi + # make facts available in script + # shellcheck disable=SC2046 + export $(echo "$filteredFacts" | xargs) + + for var in isOs isArch isKexec isInstaller isContainer hasIpv6Only hasTar hasCpio hasSudo hasDoas hasWget hasCurl hasSetsid; do + if [[ -z ${!var} ]]; then + abort "Failed to retrieve fact $var from host" + fi + done +} + +checkBuildLocally() { + local system extraPlatforms machineSystem + system="$(nix --extra-experimental-features 'nix-command flakes' config show system)" + extraPlatforms="$(nix --extra-experimental-features 'nix-command flakes' config show extra-platforms)" + + if [[ $# -gt 0 ]]; then + machineSystem=$1 + elif [[ -n ${nixosSystem} ]]; then + machineSystem="$(cat "${nixosSystem}"/system)" + else + machineSystem="$(nix --extra-experimental-features 'nix-command flakes' eval --raw "${flake}"#"${flakeAttr}".pkgs.system 2>/dev/null || echo "unknown")" + if [[ ${machineSystem} == "unknown" ]]; then + buildOn=auto + return + fi + fi + + if [[ ${system} == "${machineSystem}" ]]; then + buildOn=local + return + fi + + if [[ ${extraPlatforms} == "*${machineSystem}*" ]]; then + buildOn=local + return + fi + + local entropy + entropy="$(date +'%Y%m%d%H%M%S')" + if nix build \ + -L \ + "${nixOptions[@]}" \ + --expr \ + "derivation { system = \"$system\"; name = \"env-$entropy\"; builder = \"/bin/sh\"; args = [ \"-c\" \"echo > \$out\" ]; }"; then + # The local build failed + buildOn=local + fi + + buildOn=remote +} + +generateHardwareConfig() { + local maybeSudo="$maybeSudo" + mkdir -p "$(dirname "$hardwareConfigPath")" + case "$hardwareConfigBackend" in + nixos-facter) + if [[ ${isInstaller} == "y" ]]; then + if [[ ${hasNixOSFacter} == "n" ]]; then + abort "nixos-facter is not available in booted installer, use nixos-generate-config. For nixos-facter, you may want to boot an installer image from here instead: https://github.com/nix-community/nixos-images" + fi + else + maybeSudo="" + fi + + step "Generating hardware-configuration.nix using nixos-facter" + runSshNoTty -o ConnectTimeout=10 ${maybeSudo} "nixos-facter" >"$hardwareConfigPath" + ;; + nixos-generate-config) + step "Generating hardware-configuration.nix using nixos-generate-config" + runSshNoTty -o ConnectTimeout=10 nixos-generate-config --show-hardware-config --no-filesystems >"$hardwareConfigPath" + ;; + *) + abort "Unknown hardware config backend: $hardwareConfigBackend" + ;; + esac + + # to make sure nix knows about the new file + if command -v git >/dev/null; then + # handle relative paths + hardwareConfigPath="$(realpath "$hardwareConfigPath")" + pushd "$(dirname "$hardwareConfigPath")" + if git rev-parse --is-inside-work-tree >/dev/null; then + git add --intent-to-add --force -- "$hardwareConfigPath" + fi + popd + fi +} + +runKexec() { + if [[ ${isKexec} == "y" ]] || [[ ${isInstaller} == "y" ]]; then + return + fi + + if [[ ${isContainer} != "none" ]]; then + echo "WARNING: This script does not support running from a '${isContainer}' container. kexec will likely not work" >&2 + fi + + if [[ $kexecUrl == "" ]]; then + case "${isArch}" in + x86_64 | aarch64) + kexecUrl="https://github.com/nix-community/nixos-images/releases/download/nixos-24.11/nixos-kexec-installer-noninteractive-${isArch}-linux.tar.gz" + ;; + *) + abort "Unsupported architecture: ${isArch}. Our default kexec images only support x86_64 and aarch64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information." + ;; + esac + fi + + step Switching system into kexec + runSsh sh < $path" <"${diskEncryptionKeys[$path]}" + done + if [[ -n ${diskoScript} ]]; then + nixCopy --to "ssh://$sshConnection?$sshStoreSettings" "$diskoScript" + elif [[ ${buildOn} == "remote" ]]; then + step Building disko script + # We need to do a nix copy first because nix build doesn't have --no-check-sigs + # Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359 + nixCopy --to "ssh://$sshConnection?$sshStoreSettings" "${flake}#${flakeAttr}.system.build.${diskoMode}Script" \ + --derivation --no-check-sigs + # If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store` + diskoScript=$( + nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}" \ + --eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir%2Fnixos-anywhere&$sshStoreSettings" + ) + fi + + step Formatting hard drive with disko + runSsh "$diskoScript" +} + +nixosInstall() { + local nixosSystem=$1 + if [[ -n ${nixosSystem} ]]; then + step Uploading the system closure + nixCopy --to "ssh://$sshConnection?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" "$nixosSystem" + elif [[ ${buildOn} == "remote" ]]; then + step Building the system closure + # We need to do a nix copy first because nix build doesn't have --no-check-sigs + # Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359 + nixCopy --to "ssh://$sshConnection?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" "${flake}#${flakeAttr}.system.build.toplevel" \ + --derivation --no-check-sigs + # If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store` + nixosSystem=$( + nixBuild "${flake}#${flakeAttr}.system.build.toplevel" \ + --eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir%2Fnixos-anywhere&remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" + ) + fi + + if [[ -n ${extraFiles} ]]; then + step Copying extra files + tar -C "$extraFiles" -cpf- . | runSsh "tar -C /mnt -xf- --no-same-owner" + + runSsh "chmod 755 /mnt" # tar also changes permissions of /mnt + fi + + if [[ ${#extraFilesOwnership[@]} -gt 0 ]]; then + # shellcheck disable=SC2016 + printf "%s\n" "${!extraFilesOwnership[@]}" "${extraFilesOwnership[@]}" | pr -2t | runSsh 'while read file ownership; do chown -R "$ownership" "/mnt/$file"; done' + fi + + step Installing NixOS + runSsh sh </dev/null && [ "\$(zpool list)" != "no pools available" ]; then + # we always want to export the zfs pools so people can boot from it without force import + umount -Rv /mnt/ + swapoff -a + zpool export -a || true + fi + nohup sh -c 'sleep 6 && reboot' >/dev/null & +fi +SSH + +} + +main() { + parseArgs "$@" + + if [[ ${vmTest} == y ]]; then + if [[ ${hardwareConfigBackend} != "none" ]]; then + abort "--vm-test is not supported with --generate-hardware-config. You need to generate the hardware configuration before you can run the VM test." >&2 + fi + runVmTest + exit 0 + fi + + if [[ ${buildOn} == "auto" ]]; then + checkBuildLocally + fi + + # parse flake nixos-install style syntax, get the system attr + if [[ -n ${flake} ]]; then + if [[ ${buildOn} == "local" ]] && [[ ${hardwareConfigBackend} == "none" ]]; then + if [[ ${phases[disko]} == 1 ]]; then + diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}") + fi + if [[ ${phases[install]} == 1 ]]; then + nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel") + fi + fi + elif [[ -n ${diskoScript} ]] && [[ -n ${nixosSystem} ]]; then + if [[ ! -e ${diskoScript} ]] || [[ ! -e ${nixosSystem} ]]; then + abort "${diskoScript} and ${nixosSystem} must be existing store-paths" + fi + else + abort "--flake or --store-paths must be set" + fi + + if [[ -n ${SSH_PRIVATE_KEY} ]] && [[ -z ${sshPrivateKeyFile} ]]; then + # $sshKeyDir is getting deleted on trap EXIT + sshPrivateKeyFile="$sshKeyDir/from-env" + ( + umask 077 + printf '%s\n' "$SSH_PRIVATE_KEY" >"$sshPrivateKeyFile" + ) + fi + + sshSettings=$(ssh "${sshArgs[@]}" -G "${sshConnection}") + sshUser=$(echo "$sshSettings" | awk '/^user / { print $2 }') + sshHost=$(echo "$sshSettings" | awk '/^hostname / { print $2 }') + + uploadSshKey + + importFacts + + if [[ ${hasTar-n} == "n" ]]; then + abort "no tar command found, but required to unpack kexec tarball" + fi + + if [[ ${hasCpio-n} == "n" ]]; then + abort "no cpio command found, but required to build the new initrd" + fi + + if [[ ${hasSetsid-n} == "n" ]]; then + abort "no setsid command found, but required to run the kexec script under a new session" + fi + + maybeSudo="" + if [[ ${hasSudo-n} == "y" ]]; then + maybeSudo="sudo" + elif [[ ${hasDoas-n} == "y" ]]; then + maybeSudo="doas" + fi + + if [[ ${isOs} != "Linux" ]]; then + abort "This script requires Linux as the operating system, but got $isOs" + fi + + if [[ ${phases[kexec]} == 1 ]]; then + runKexec + fi + + if [[ ${hardwareConfigBackend} != "none" ]]; then + generateHardwareConfig + fi + + # Before we do not have a valid hardware configuration we don't know the machine system + if [[ ${buildOn} == "auto" ]]; then + local remoteSystem + remoteSystem=$(runSshNoTty -o ConnectTimeout=10 nix --extra-experimental-features nix-command config show system) + checkBuildLocally "${remoteSystem}" + # if we cannot figure it out at this point, we will build on the remote host + if [[ ${buildOn} == "auto" ]]; then + buildOn=remote + fi + fi + + if [[ ${buildOn} != "remote" ]] && [[ -n ${flake} ]] && [[ -z ${diskoScript} ]]; then + if [[ ${phases[disko]} == 1 ]]; then + diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}") + fi + if [[ ${phases[install]} == 1 ]]; then + nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel") + fi + fi + + # Installation will fail if non-root user is used for installer. + # Switch to root user by copying authorized_keys. + if [[ ${isInstaller} == "y" ]] && [[ ${sshUser} != "root" ]]; then + # Allow copy to fail if authorized_keys does not exist, like if using /etc/ssh/authorized_keys.d/ + runSsh "${maybeSudo} mkdir -p /root/.ssh; ${maybeSudo} cp ~/.ssh/authorized_keys /root/.ssh || true" + sshConnection="root@${sshHost}" + fi + + if [[ ${phases[disko]} == 1 ]]; then + runDisko "$diskoScript" + fi + + if [[ ${phases[install]} == 1 ]]; then + nixosInstall "$nixosSystem" + fi + + if [[ ${phases[reboot]} == 1 ]]; then + step Waiting for the machine to become unreachable due to reboot + while runSshTimeout -- exit 0; do sleep 1; done + fi + + step "Done!" +} + +main "$@" diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/README.md b/launch/.terraform/modules/pixelfed.deploy/terraform/README.md new file mode 100644 index 00000000..2d66b1a8 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/README.md @@ -0,0 +1,21 @@ +# NixOS-Anywhere Terraform Modules Overview + +The nixos-Anywhere terraform modules allow you to use Terraform for installing +and updating NixOS. It simplifies the deployment process by integrating +nixos-anywhere functionality. + +Here's a brief overview of each module: + +- **[All-in-One](all-in-one.md)**: This is a consolidated module that first + installs NixOS using nixos-anywhere and then keeps it updated with + nixos-rebuild. If you choose this, you won't need additional deployment tools + like colmena. +- **[Install](install.md)**: This module focuses solely on installing NixOS via + nixos-anywhere. +- **[NixOS-Rebuild](nixos-rebuild.md)**: Use this module to remotely update an + existing NixOS machine using nixos-rebuild. +- **[Nix-Build](nix-build.md)**: This is a handy helper module designed to build + a flake attribute or an attribute from a nix file. + +For detailed information and usage examples, click on the respective module +links above. diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one.md b/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one.md new file mode 100644 index 00000000..c7279cf2 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one.md @@ -0,0 +1,235 @@ +# All-in-one + +Combines the install and nixos-rebuild module in one interface to install NixOS +with nixos-anywhere and then keep it up-to-date with nixos-rebuild. + +## Example + +```hcl +locals { + ipv4 = "192.0.2.1" +} + +module "deploy" { + source = "github.com/nix-community/nixos-anywhere//terraform/all-in-one" + # with flakes + nixos_system_attr = ".#nixosConfigurations.mymachine.config.system.build.toplevel" + nixos_partitioner_attr = ".#nixosConfigurations.mymachine.config.system.build.diskoScript" + # without flakes + # file can use (pkgs.nixos []) function from nixpkgs + #file = "${path.module}/../.." + #nixos_system_attr = "config.system.build.toplevel" + #nixos_partitioner_attr = "config.system.build.diskoScript" + + target_host = local.ipv4 + # when instance id changes, it will trigger a reinstall + instance_id = local.ipv4 + # useful if something goes wrong + # debug_logging = true + # build the closure on the remote machine instead of locally + # build_on_remote = true + # script is below + extra_files_script = "${path.module}/decrypt-ssh-secrets.sh" + disk_encryption_key_scripts = [{ + path = "/tmp/secret.key" + # script is below + script = "${path.module}/decrypt-zfs-key.sh" + }] + # Optional, arguments passed to special_args here will be available from a NixOS module in this example the `terraform` argument: + # { terraform, ... }: { + # networking.interfaces.enp0s3.ipv4.addresses = [{ address = terraform.ip; prefixLength = 24; }]; + # } + # Note that this will means that your NixOS configuration will always depend on terraform! + # Skip to `Pass data persistently to the NixOS` for an alternative approach + #special_args = { + # terraform = { + # ip = "192.0.2.0" + # } + #} +} +``` + +_Note:_ You need to mark scripts as executable (`chmod +x`) + +### ./decrypt-ssh-secrets.sh + +```bash +#!/usr/bin/env bash + +mkdir -p etc/ssh var/lib/secrets + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +umask 0177 +sops --extract '["initrd_ssh_key"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >./var/lib/secrets/initrd_ssh_key + +# restore umask +umask 0022 + +for keyname in ssh_host_rsa_key ssh_host_rsa_key.pub ssh_host_ed25519_key ssh_host_ed25519_key.pub; do + if [[ $keyname == *.pub ]]; then + umask 0133 + else + umask 0177 + fi + sops --extract '["'$keyname'"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >"./etc/ssh/$keyname" +done +``` + +### ./decrypt-zfs-key.sh + +```bash +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +cd "$SCRIPT_DIR" +sops --extract '["zfs-key"]' --decrypt "$SCRIPT_DIR/secrets.yaml" +``` + +## See also + +- [nixos-wiki setup](https://github.com/NixOS/nixos-wiki-infra/blob/main/terraform/nixos-wiki/main.tf) + for hetzner-cloud + +## Pass data persistently to the NixOS + +This guide outlines how to pass data from Terraform to NixOS by generating a +file during Terraform execution and including it in your NixOS configuration. +This approach works well if your Terraform and NixOS configurations are stored +in the same Git repository. + +### Why Use This Method? + +This method provides a straightforward way to transfer values from Terraform to +NixOS without relying on special_args. + +- **Advantages**: + - You can continue to use nix build or nixos-rebuild to evaluate your + configuration without interruption. Simplifies configuration management by + centralizing state in a single repository. +- **Disadvantages**: + - Deploying new machines requires tracking additional state. Every time + Terraform updates the JSON file, you'll need to commit these changes to your + repository. + +### Implementation + +Add the following snippet to your Terraform configuration to create and manage a +JSON file containing the necessary variables for NixOS. This file will be +automatically added to your Git repository, ensuring the data persists. + +Assuming you have your terraform and nixos configuration in the same git +repository. You can use the following snippet to `git add` a file generated by +`terraform` during execution to pass data from terraform to NixOS. These changes +should be committed afterwards. This is an alternative over using +`special_args`. Advantage: you can still use nix build or nixos-rebuild on your +flake to evaluate your configuration. Disadvantage: Deploying new machines also +means you need to track additional state and make additional commits whenever +terraform updates the json file. + +```hcl +locals { + nixos_vars_file = "nixos-vars.json" # Path to the JSON file containing NixOS variables + nixos_vars = { + ip = "192.0.2.0" # Replace with actual variables + } +} +resource "local_file" "nixos_vars" { + content = jsonencode(local.nixos_vars) # Converts variables to JSON + filename = local.nixos_vars_file # Specifies the output file path + file_permission = "600" + + # Automatically adds the generated file to Git + provisioner "local-exec" { + interpreter = ["bash", "-c"] + command = "git add -f '${local.nixos_vars_file}'" + } +} +``` + +After applying the Terraform changes, ensure you commit the updated +`nixos-vars.json` file to your Git repository: + +```bash +git commit -m "Update NixOS variables from Terraform" +``` + +You can import this json file into your configuration like this: + +```nix +let + nixosVars = builtins.fromJSON (builtins.readFile ./nixos-vars.json); +in +{ + # Example usage of imported variables + networking.hostName = "example-machine"; + networking.interfaces.eth0.ipv4.addresses = [ + { + address = nixosVars.ip; # Use the IP from nixos-vars.json + prefixLength = 24; + } + ]; +} +``` + + + +## Requirements + +No requirements. + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +| -------------------------------------------------------------------------------------- | ---------------- | ------- | +| [install](#module_install) | ../install | n/a | +| [nixos-rebuild](#module_nixos-rebuild) | ../nixos-rebuild | n/a | +| [partitioner-build](#module_partitioner-build) | ../nix-build | n/a | +| [system-build](#module_system-build) | ../nix-build | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +| --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | :------: | +| [debug\_logging](#input_debug_logging) | Enable debug logging | `bool` | `false` | no | +| [deployment\_ssh\_key](#input_deployment_ssh_key) | Content of private key used to deploy to the target\_host after initial installation. To ensure maximum security, it is advisable to connect to your host using ssh-agent instead of relying on this variable | `string` | `null` | no | +| [disk\_encryption\_key\_scripts](#input_disk_encryption_key_scripts) | Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system |
list(object({
path = string
script = string
}))
| `[]` | no | +| [extra\_environment](#input_extra_environment) | Extra environment variables to be set during installation. This can be useful to set extra variables for the extra\_files\_script or disk\_encryption\_key\_scripts | `map(string)` | `{}` | no | +| [extra\_files\_script](#input_extra_files_script) | A script that should place files in the current directory that will be copied to the targets / directory | `string` | `null` | no | +| [file](#input_file) | Nix file containing the nixos\_system\_attr and nixos\_partitioner\_attr. Use this if you are not using flake | `string` | `null` | no | +| [install\_port](#input_install_port) | SSH port used to connect to the target\_host, before installing NixOS. If null than the value of `target_port` is used | `string` | `null` | no | +| [install\_ssh\_key](#input_install_ssh_key) | Content of private key used to connect to the target\_host during initial installation | `string` | `null` | no | +| [install\_user](#input_install_user) | SSH user used to connect to the target\_host, before installing NixOS. If null than the value of `target_host` is used | `string` | `null` | no | +| [instance\_id](#input_instance_id) | The instance id of the target\_host, used to track when to reinstall the machine | `string` | `null` | no | +| [kexec\_tarball\_url](#input_kexec_tarball_url) | NixOS kexec installer tarball url | `string` | `null` | no | +| [nix\_options](#input_nix_options) | the options of nix | `map(string)` | `{}` | no | +| [nixos\_facter\_path](#input_nixos_facter_path) | Path to which to write a `facter.json` generated by `nixos-facter`. | `string` | `""` | no | +| [nixos\_generate\_config\_path](#input_nixos_generate_config_path) | Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. | `string` | `""` | no | +| [nixos\_partitioner\_attr](#input_nixos_partitioner_attr) | Nixos partitioner and mount script i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.diskoNoDeps or just your-evaluated.config.system.build.diskNoDeps. `config.system.build.diskNoDeps` is provided by the disko nixos module | `string` | n/a | yes | +| [nixos\_system\_attr](#input_nixos_system_attr) | The nixos system to deploy i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.toplevel or just your-evaluated-nixos.config.system.build.toplevel if you are not using flakes | `string` | n/a | yes | +| [no\_reboot](#input_no_reboot) | DEPRECATED: Use `phases` instead. Do not reboot after installation | `bool` | `false` | no | +| [phases](#input_phases) | Phases to run. See `nixos-anywhere --help` for more information | `set(string)` |
[
"kexec",
"disko",
"install",
"reboot"
]
| no | +| [special\_args](#input_special_args) | A map exposed as NixOS's `specialArgs` thru a file. | `any` | `{}` | no | +| [build\_on\_remote](#input_build_on_remote) | Build the closure on the remote machine instead of building it locally and copying it over | `bool` | `false` | no | +| [stop\_after\_disko](#input_stop_after_disko) | DEPRECATED: Use `phases` instead. Exit after disko formatting | `bool` | `false` | no | +| [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes | +| [target\_port](#input_target_port) | SSH port used to connect to the target\_host after installing NixOS. If install\_port is not set than this port is also used before installing. | `number` | `22` | no | +| [target\_user](#input_target_user) | SSH user used to connect to the target\_host after installing NixOS. If install\_user is not set than this user is also used before installing. | `string` | `"root"` | no | + +## Outputs + +| Name | Description | +| ----------------------------------------------------- | ----------- | +| [result](#output_result) | n/a | + + diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/main.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/main.tf new file mode 100644 index 00000000..fa5d7eb3 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/main.tf @@ -0,0 +1,64 @@ +module "system-build" { + source = "../nix-build" + attribute = var.nixos_system_attr + file = var.file + nix_options = var.nix_options + special_args = var.special_args +} + +module "partitioner-build" { + source = "../nix-build" + attribute = var.nixos_partitioner_attr + file = var.file + nix_options = var.nix_options + special_args = var.special_args +} + +locals { + install_user = var.install_user == null ? var.target_user : var.install_user + install_port = var.install_port == null ? var.target_port : var.install_port +} + +module "install" { + source = "../install" + kexec_tarball_url = var.kexec_tarball_url + target_user = local.install_user + target_host = var.target_host + target_port = local.install_port + nixos_partitioner = module.partitioner-build.result.out + nixos_system = module.system-build.result.out + ssh_private_key = var.install_ssh_key + debug_logging = var.debug_logging + extra_files_script = var.extra_files_script + disk_encryption_key_scripts = var.disk_encryption_key_scripts + extra_environment = var.extra_environment + instance_id = var.instance_id + phases = var.phases + nixos_generate_config_path = var.nixos_generate_config_path + nixos_facter_path = var.nixos_facter_path + build_on_remote = var.build_on_remote + # deprecated attributes + stop_after_disko = var.stop_after_disko + no_reboot = var.no_reboot +} + +module "nixos-rebuild" { + depends_on = [ + module.install + ] + + # Do not execute this step if var.stop_after_disko == true + count = var.stop_after_disko ? 0 : 1 + + source = "../nixos-rebuild" + nixos_system = module.system-build.result.out + ssh_private_key = var.deployment_ssh_key + target_host = var.target_host + target_user = var.target_user + target_port = var.target_port + install_bootloader = var.install_bootloader +} + +output "result" { + value = module.system-build.result +} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/variables.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/variables.tf new file mode 100644 index 00000000..3ca27922 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/variables.tf @@ -0,0 +1,151 @@ +variable "kexec_tarball_url" { + type = string + description = "NixOS kexec installer tarball url" + default = null +} + +# To make this re-usable we maybe should accept a store path here? +variable "nixos_partitioner_attr" { + type = string + description = "Nixos partitioner and mount script i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.diskoNoDeps or just your-evaluated.config.system.build.diskNoDeps. `config.system.build.diskNoDeps` is provided by the disko nixos module" +} + +# To make this re-usable we maybe should accept a store path here? +variable "nixos_system_attr" { + type = string + description = "The nixos system to deploy i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.toplevel or just your-evaluated-nixos.config.system.build.toplevel if you are not using flakes" +} + +variable "file" { + type = string + description = "Nix file containing the nixos_system_attr and nixos_partitioner_attr. Use this if you are not using flake" + default = null +} + +variable "target_host" { + type = string + description = "DNS host to deploy to" +} + +variable "install_user" { + type = string + description = "SSH user used to connect to the target_host, before installing NixOS. If null than the value of `target_host` is used" + default = null +} + +variable "install_port" { + type = string + description = "SSH port used to connect to the target_host, before installing NixOS. If null than the value of `target_port` is used" + default = null +} + +variable "target_user" { + type = string + description = "SSH user used to connect to the target_host after installing NixOS. If install_user is not set than this user is also used before installing." + default = "root" +} + +variable "target_port" { + type = number + description = "SSH port used to connect to the target_host after installing NixOS. If install_port is not set than this port is also used before installing." + default = 22 +} + +variable "instance_id" { + type = string + description = "The instance id of the target_host, used to track when to reinstall the machine" + default = null +} + +variable "install_ssh_key" { + type = string + description = "Content of private key used to connect to the target_host during initial installation" + default = null +} + +variable "deployment_ssh_key" { + type = string + description = "Content of private key used to deploy to the target_host after initial installation. To ensure maximum security, it is advisable to connect to your host using ssh-agent instead of relying on this variable" + default = null +} + +variable "debug_logging" { + type = bool + description = "Enable debug logging" + default = false +} + +variable "stop_after_disko" { + type = bool + description = "DEPRECATED: Use `phases` instead. Exit after disko formatting" + default = false +} + +variable "no_reboot" { + type = bool + description = "DEPRECATED: Use `phases` instead. Do not reboot after installation" + default = false +} + +variable "phases" { + type = set(string) + description = "Phases to run. See `nixos-anywhere --help` for more information" + default = ["kexec", "disko", "install", "reboot"] +} + +variable "extra_files_script" { + type = string + description = "A script that should place files in the current directory that will be copied to the targets / directory" + default = null +} + +variable "disk_encryption_key_scripts" { + type = list(object({ + path = string + script = string + })) + description = "Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system" + default = [] +} + +variable "extra_environment" { + type = map(string) + description = "Extra environment variables to be set during installation. This can be useful to set extra variables for the extra_files_script or disk_encryption_key_scripts" + default = {} +} + +variable "nix_options" { + type = map(string) + description = "the options of nix" + default = {} +} + +variable "nixos_generate_config_path" { + type = string + description = "Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`." + default = "" +} + +variable "nixos_facter_path" { + type = string + description = "Path to which to write a `facter.json` generated by `nixos-facter`." + default = "" +} + +variable "special_args" { + type = any + default = {} + description = "A map exposed as NixOS's `specialArgs` thru a file." +} + +variable "build_on_remote" { + type = bool + description = "Build the closure on the remote machine instead of building it locally and copying it over" + default = false +} + +variable "install_bootloader" { + type = bool + description = "Install/re-install the bootloader" + default = false +} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/install.md b/launch/.terraform/modules/pixelfed.deploy/terraform/install.md new file mode 100644 index 00000000..eb3439fc --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/install.md @@ -0,0 +1,91 @@ +# Install + +Install NixOS with nixos-anywhere + +## Example + +```hcl +locals { + ipv4 = "192.0.2.1" +} + +module "system-build" { + source = "github.com/nix-community/nixos-anywhere//terraform/nix-build" + # with flakes + attribute = ".#nixosConfigurations.mymachine.config.system.build.toplevel" + # without flakes + # file can use (pkgs.nixos []) function from nixpkgs + #file = "${path.module}/../.." + #attribute = "config.system.build.toplevel" +} + +module "disko" { + source = "github.com/nix-community/nixos-anywhere//terraform/nix-build" + # with flakes + attribute = ".#nixosConfigurations.mymachine.config.system.build.diskoScript" + # without flakes + # file can use (pkgs.nixos []) function from nixpkgs + #file = "${path.module}/../.." + #attribute = "config.system.build.diskoScript" +} + +module "install" { + source = "github.com/nix-community/nixos-anywhere//terraform/install" + nixos_system = module.system-build.result.out + nixos_partitioner = module.disko.result.out + target_host = local.ipv4 +} +``` + + + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +| --------------------------------------------------- | ------- | +| [null](#provider_null) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +| ------------------------------------------------------------------------------------------------------------------- | -------- | +| [null_resource.nixos-remote](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +| --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | :------: | +| [build\_on\_remote](#input_build_on_remote) | Build the closure on the remote machine instead of building it locally and copying it over | `bool` | `false` | no | +| [debug\_logging](#input_debug_logging) | Enable debug logging | `bool` | `false` | no | +| [disk\_encryption\_key\_scripts](#input_disk_encryption_key_scripts) | Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system |
list(object({
path = string
script = string
}))
| `[]` | no | +| [extra\_environment](#input_extra_environment) | Extra environment variables to be set during installation. This can be useful to set extra variables for the extra\_files\_script or disk\_encryption\_key\_scripts | `map(string)` | `{}` | no | +| [extra\_files\_script](#input_extra_files_script) | A script that should place files in the current directory that will be copied to the targets / directory | `string` | `null` | no | +| [flake](#input_flake) | The flake to install the system from | `string` | `""` | no | +| [instance\_id](#input_instance_id) | The instance id of the target\_host, used to track when to reinstall the machine | `string` | `null` | no | +| [kexec\_tarball\_url](#input_kexec_tarball_url) | NixOS kexec installer tarball url | `string` | `null` | no | +| [nixos\_facter\_path](#input_nixos_facter_path) | Path to which to write a `facter.json` generated by `nixos-facter`. This option cannot be set at the same time as `nixos_generate_config_path`. | `string` | `""` | no | +| [nixos\_generate\_config\_path](#input_nixos_generate_config_path) | Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. This option cannot be set at the same time as `nixos_facter_path`. | `string` | `""` | no | +| [nixos\_partitioner](#input_nixos_partitioner) | nixos partitioner and mount script | `string` | `""` | no | +| [nixos\_system](#input_nixos_system) | The nixos system to deploy | `string` | `""` | no | +| [no\_reboot](#input_no_reboot) | DEPRECATED: Use `phases` instead. Do not reboot after installation | `bool` | `false` | no | +| [phases](#input_phases) | Phases to run. See `nixos-anywhere --help` for more information | `list(string)` |
[
"kexec",
"disko",
"install",
"reboot"
]
| no | +| [ssh\_private\_key](#input_ssh_private_key) | Content of private key used to connect to the target\_host | `string` | `""` | no | +| [stop\_after\_disko](#input_stop_after_disko) | DEPRECATED: Use `phases` instead. Exit after disko formatting | `bool` | `false` | no | +| [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes | +| [target\_pass](#input_target_pass) | Password used to connect to the target\_host | `string` | `null` | no | +| [target\_port](#input_target_port) | SSH port used to connect to the target\_host | `number` | `22` | no | +| [target\_user](#input_target_user) | SSH user used to connect to the target\_host | `string` | `"root"` | no | + +## Outputs + +No outputs. + + diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/install/main.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/install/main.tf new file mode 100644 index 00000000..9f1816ac --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/install/main.tf @@ -0,0 +1,35 @@ +locals { + disk_encryption_key_scripts = [for k in var.disk_encryption_key_scripts : "\"${k.path}\" \"${k.script}\""] + removed_phases = setunion(var.stop_after_disko ? ["install"] : [], (var.no_reboot ? ["reboot"] : [])) + phases = setsubtract(var.phases, local.removed_phases) + arguments = jsonencode({ + ssh_private_key = var.ssh_private_key + debug_logging = var.debug_logging + kexec_tarball_url = var.kexec_tarball_url + nixos_partitioner = var.nixos_partitioner + nixos_system = var.nixos_system + target_user = var.target_user + target_host = var.target_host + target_port = var.target_port + target_pass = var.target_pass + extra_files_script = var.extra_files_script + build_on_remote = var.build_on_remote + flake = var.flake + phases = join(",", local.phases) + nixos_generate_config_path = var.nixos_generate_config_path + nixos_facter_path = var.nixos_facter_path + }) +} + +resource "null_resource" "nixos-remote" { + triggers = { + instance_id = var.instance_id + } + provisioner "local-exec" { + environment = merge({ + ARGUMENTS = local.arguments + }, var.extra_environment) + command = "${path.module}/run-nixos-anywhere.sh ${join(" ", local.disk_encryption_key_scripts)}" + quiet = var.debug_logging + } +} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/install/providers.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/install/providers.tf new file mode 100644 index 00000000..c3e00a54 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/install/providers.tf @@ -0,0 +1,5 @@ +terraform { + required_providers { + null = { source = "hashicorp/null" } + } +} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/install/run-nixos-anywhere.sh b/launch/.terraform/modules/pixelfed.deploy/terraform/install/run-nixos-anywhere.sh new file mode 100755 index 00000000..1d259a1e --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/install/run-nixos-anywhere.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +declare -A input + +while IFS= read -r -d '' key && IFS= read -r -d '' value; do + input[$key]=$value +done < <(jq -j 'to_entries[] | (.key, "\u0000", .value, "\u0000")' <<<"${ARGUMENTS}") + +args=() + +if [[ ${input[debug_logging]} == "true" ]]; then + set -x + declare -p input + args+=("--debug") +fi +if [[ ${input[kexec_tarball_url]} != "null" ]]; then + args+=("--kexec" "${input[kexec_tarball_url]}") +fi +if [[ ${input[build_on_remote]} == "true" ]]; then + args+=("--build-on-remote") +fi +if [[ -n ${input[flake]} ]]; then + args+=("--flake" "${input[flake]}") +else + args+=("--store-paths" "${input[nixos_partitioner]}" "${input[nixos_system]}") +fi +if [[ -n ${input[nixos_generate_config_path]} ]]; then + if [[ -n ${input[nixos_facter_path]} ]]; then + echo "cannot set both variables 'nixos_generate_config_path' and 'nixos_facter_path'!" >&2 + exit 1 + fi + args+=("--generate-hardware-config" "nixos-generate-config" "${input[nixos_generate_config_path]}") +elif [[ -n ${input[nixos_facter_path]} ]]; then + args+=("--generate-hardware-config" "nixos-facter" "${input[nixos_facter_path]}") +fi +args+=(--phases "${input[phases]}") +if [[ ${input[ssh_private_key]} != null ]]; then + export SSH_PRIVATE_KEY="${input[ssh_private_key]}" +fi +if [[ ${input[target_pass]} != null ]]; then + export SSHPASS=${input[target_pass]} + args+=("--env-password") +fi + +tmpdir=$(mktemp -d) +cleanup() { + rm -rf "${tmpdir}" +} +trap cleanup EXIT + +if [[ ${input[extra_files_script]} != "null" ]]; then + if [[ ! -f ${input[extra_files_script]} ]]; then + echo "extra_files_script '${input[extra_files_script]}' does not exist" + exit 1 + fi + if [[ ! -x ${input[extra_files_script]} ]]; then + echo "extra_files_script '${input[extra_files_script]}' is not executable" + exit 1 + fi + extra_files_script=$(realpath "${input[extra_files_script]}") + mkdir "${tmpdir}/extra-files" + pushd "${tmpdir}/extra-files" + $extra_files_script + popd + args+=("--extra-files" "${tmpdir}/extra-files") +fi + +args+=("-p" "${input[target_port]}") +args+=("${input[target_user]}@${input[target_host]}") + +keyIdx=0 +while [[ $# -gt 0 ]]; do + if [[ ! -f $2 ]]; then + echo "Script file '$2' does not exist" + exit 1 + fi + if [[ ! -x $2 ]]; then + echo "Script file '$2' is not executable" + exit 1 + fi + mkdir -p "${tmpdir}/keys" + "$2" >"${tmpdir}/keys/$keyIdx" + args+=("--disk-encryption-keys" "$1" "${tmpdir}/keys/$keyIdx") + shift + shift + keyIdx=$((keyIdx + 1)) +done + +nix run --extra-experimental-features 'nix-command flakes' "path:${SCRIPT_DIR}/../..#nixos-anywhere" -- "${args[@]}" diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/install/variables.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/install/variables.tf new file mode 100644 index 00000000..cd07bf70 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/install/variables.tf @@ -0,0 +1,123 @@ +variable "kexec_tarball_url" { + type = string + description = "NixOS kexec installer tarball url" + default = null +} + +# To make this re-usable we maybe should accept a store path here? +variable "nixos_partitioner" { + type = string + description = "nixos partitioner and mount script" + default = "" +} + +# To make this re-usable we maybe should accept a store path here? +variable "nixos_system" { + type = string + description = "The nixos system to deploy" + default = "" +} + +variable "target_host" { + type = string + description = "DNS host to deploy to" +} + +variable "target_user" { + type = string + description = "SSH user used to connect to the target_host" + default = "root" +} + +variable "target_port" { + type = number + description = "SSH port used to connect to the target_host" + default = 22 +} + +variable "target_pass" { + type = string + description = "Password used to connect to the target_host" + default = null +} + +variable "ssh_private_key" { + type = string + description = "Content of private key used to connect to the target_host" + default = "" +} + +variable "instance_id" { + type = string + description = "The instance id of the target_host, used to track when to reinstall the machine" + default = null +} + +variable "debug_logging" { + type = bool + description = "Enable debug logging" + default = false +} + +variable "extra_files_script" { + type = string + description = "A script that should place files in the current directory that will be copied to the targets / directory" + default = null +} + +variable "disk_encryption_key_scripts" { + type = list(object({ + path = string + script = string + })) + description = "Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system" + default = [] +} + +variable "extra_environment" { + type = map(string) + description = "Extra environment variables to be set during installation. This can be useful to set extra variables for the extra_files_script or disk_encryption_key_scripts" + default = {} +} + +variable "stop_after_disko" { + type = bool + description = "DEPRECATED: Use `phases` instead. Exit after disko formatting" + default = false +} + +variable "no_reboot" { + type = bool + description = "DEPRECATED: Use `phases` instead. Do not reboot after installation" + default = false +} + +variable "phases" { + type = list(string) + description = "Phases to run. See `nixos-anywhere --help` for more information" + default = ["kexec", "disko", "install", "reboot"] +} + +variable "build_on_remote" { + type = bool + description = "Build the closure on the remote machine instead of building it locally and copying it over" + default = false +} + +variable "flake" { + type = string + description = "The flake to install the system from" + default = "" +} + +variable "nixos_generate_config_path" { + type = string + description = "Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. This option cannot be set at the same time as `nixos_facter_path`." + default = "" +} + +variable "nixos_facter_path" { + type = string + description = "Path to which to write a `facter.json` generated by `nixos-facter`. This option cannot be set at the same time as `nixos_generate_config_path`." + default = "" +} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build.md b/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build.md new file mode 100644 index 00000000..fe63af12 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build.md @@ -0,0 +1,47 @@ +# Nix-build + +Small helper module to run do build a flake attribute or attribute from a nix +file. + +## Example + +- See [install](install.md) or [nixos-rebuild](nixos-rebuild.md) + + + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +| --------------------------------------------------------------- | ------- | +| [external](#provider_external) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +| --------------------------------------------------------------------------------------------------------------------------- | ----------- | +| [external_external.nix-build](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +| ---------------------------------------------------------------------- | --------------------------------------------------- | ------------- | ------- | :------: | +| [attribute](#input_attribute) | the attribute to build, can also be a flake | `string` | n/a | yes | +| [file](#input_file) | the nix file to evaluate, if not run in flake mode | `string` | `null` | no | +| [nix\_options](#input_nix_options) | the options of nix | `map(string)` | `{}` | no | +| [special\_args](#input_special_args) | A map exposed as NixOS's `specialArgs` thru a file. | `any` | `{}` | no | + +## Outputs + +| Name | Description | +| ----------------------------------------------------- | ----------- | +| [result](#output_result) | n/a | + + diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/main.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/main.tf new file mode 100644 index 00000000..7a3c335f --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/main.tf @@ -0,0 +1,17 @@ +locals { + nix_options = jsonencode({ + options = { for k, v in var.nix_options : k => v } + }) +} +data "external" "nix-build" { + program = [ "${path.module}/nix-build.sh" ] + query = { + attribute = var.attribute + file = var.file + nix_options = local.nix_options + special_args = jsonencode(var.special_args) + } +} +output "result" { + value = data.external.nix-build.result +} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/nix-build.sh b/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/nix-build.sh new file mode 100755 index 00000000..0e22357e --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/nix-build.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +set -efu + +declare file attribute nix_options special_args +eval "$(jq -r '@sh "attribute=\(.attribute) file=\(.file) nix_options=\(.nix_options) special_args=\(.special_args)"')" +if [ "${nix_options}" != '{"options":{}}' ]; then + options=$(echo "${nix_options}" | jq -r '.options | to_entries | map("--option \(.key) \(.value)") | join(" ")') +else + options="" +fi +if [[ ${special_args-} == "{}" ]]; then + # no special arguments, proceed as normal + if [[ -n ${file-} ]] && [[ -e ${file-} ]]; then + # shellcheck disable=SC2086 + out=$(nix build --no-link --json $options -f "$file" "$attribute") + else + # shellcheck disable=SC2086 + out=$(nix build --no-link --json ${options} "$attribute") + fi +else + if [[ ${file-} != 'null' ]]; then + echo "special_args are currently only supported when using flakes!" >&2 + exit 1 + fi + # pass the args in a pure fashion by extending the original config + rest="$(echo "${attribute}" | cut -d "#" -f 2)" + # e.g. config_path=nixosConfigurations.aarch64-linux.myconfig + config_path="${rest%.config.*}" + # e.g. config_attribute=config.system.build.toplevel + config_attribute="config.${rest#*.config.}" + + # grab flake nar from error message + flake_rel="$(echo "${attribute}" | cut -d "#" -f 1)" + # e.g. flake_rel="." + flake_dir="$(readlink -f "${flake_rel}")" + flake_path="${flake_dir}/flake.nix" + flake_json="$(nix flake prefetch "${flake_dir}" --json)" + flake_nar="$(echo "$flake_json" | jq -r '.hash')" + store_path="$(echo "${flake_json}" | jq -r '.storePath')" + # while we have a store path now, for a repo this reflects its root level, + # so search for the largest child segment yielding a match in that store dir. + iter_path="${flake_path}" + while [[ ${iter_path} != "/" ]]; do + parent="$(dirname "${iter_path}")" + child_segment="${flake_path//$parent/}" + if [[ -f "${store_path}${child_segment}" ]]; then + target_segment="${child_segment}" + fi + iter_path="${parent}" + done + # substitute variables into the template + nix_expr="(builtins.getFlake ''file://${flake_dir}?dir=${target_segment//\/flake.nix/}&narHash=${flake_nar}'').${config_path}.extendModules { specialArgs = builtins.fromJSON ''${special_args}''; }" + # inject `special_args` into nixos config's `specialArgs` + # shellcheck disable=SC2086 + out=$(nix build --no-link --json ${options} --expr "${nix_expr}" "${config_attribute}") +fi +printf '%s' "$out" | jq -c '.[].outputs' diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/variables.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/variables.tf new file mode 100644 index 00000000..bad23f73 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/variables.tf @@ -0,0 +1,22 @@ +variable "attribute" { + type = string + description = "the attribute to build, can also be a flake" +} + +variable "file" { + type = string + description = "the nix file to evaluate, if not run in flake mode" + default = null +} + +variable "nix_options" { + type = map(string) + description = "the options of nix" + default = {} +} + +variable "special_args" { + type = any + default = {} + description = "A map exposed as NixOS's `specialArgs` thru a file." +} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild.md b/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild.md new file mode 100644 index 00000000..0be26bb7 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild.md @@ -0,0 +1,66 @@ +# Nixos-rebuild + +Update NixOS machine with nixos-rebuild on a remote machine + +## Example + +```hcl +locals { + ipv4 = "192.0.2.1" +} + +module "system-build" { + source = "github.com/nix-community/nixos-anywhere//terraform/nix-build" + # with flakes + attribute = ".#nixosConfigurations.mymachine.config.system.build.toplevel" + # without flakes + # file can use (pkgs.nixos []) function from nixpkgs + #file = "${path.module}/../.." + #attribute = "config.system.build.toplevel" +} + +module "deploy" { + source = "github.com/nix-community/nixos-anywhere//terraform/nixos-rebuild" + nixos_system = module.system-build.result.out + target_host = local.ipv4 +} +``` + + + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +| --------------------------------------------------- | ------- | +| [null](#provider_null) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +| -------------------------------------------------------------------------------------------------------------------- | -------- | +| [null_resource.nixos-rebuild](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------- | -------- | :------: | +| [ignore\_systemd\_errors](#input_ignore_systemd_errors) | Ignore systemd errors happening during deploy | `bool` | `false` | no | +| [nixos\_system](#input_nixos_system) | The nixos system to deploy | `string` | n/a | yes | +| [ssh\_private\_key](#input_ssh_private_key) | Content of private key used to connect to the target\_host. If set to - no key is passed to openssh and ssh will use its own configuration | `string` | `"-"` | no | +| [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes | +| [target\_port](#input_target_port) | SSH port used to connect to the target\_host | `number` | `22` | no | +| [target\_user](#input_target_user) | User to deploy as | `string` | `"root"` | no | + +## Outputs + +No outputs. + + diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/deploy.sh b/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/deploy.sh new file mode 100755 index 00000000..61da6e1c --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/deploy.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +set -uex -o pipefail + +if [ "$#" -ne 6 ]; then + echo "USAGE: $0 NIXOS_SYSTEM TARGET_USER TARGET_HOST TARGET_PORT IGNORE_SYSTEMD_ERRORS INSTALL_BOOTLOADER" >&2 + exit 1 +fi + +NIXOS_SYSTEM=$1 +TARGET_USER=$2 +TARGET_HOST=$3 +TARGET_PORT=$4 +IGNORE_SYSTEMD_ERRORS=$5 +INSTALL_BOOTLOADER=$6 + +shift 6 + +TARGET="${TARGET_USER}@${TARGET_HOST}" + +workDir=$(mktemp -d) +trap 'rm -rf "$workDir"' EXIT + +sshOpts=(-p "${TARGET_PORT}") +sshOpts+=(-o UserKnownHostsFile=/dev/null) +sshOpts+=(-o StrictHostKeyChecking=no) + +set +x +if [[ -n ${SSH_KEY+x} && ${SSH_KEY} != "-" ]]; then + sshPrivateKeyFile="$workDir/ssh_key" + # Create the file with 0700 - umask calculation: 777 - 700 = 077 + ( + umask 077 + echo "$SSH_KEY" >"$sshPrivateKeyFile" + ) + unset SSH_AUTH_SOCK # don't use system agent if key was supplied + sshOpts+=(-o "IdentityFile=${sshPrivateKeyFile}") +fi +set -x + +try=1 +until NIX_SSHOPTS="${sshOpts[*]}" nix copy -s --experimental-features nix-command --to "ssh://$TARGET" "$NIXOS_SYSTEM"; do + if [[ $try -gt 10 ]]; then + echo "retries exhausted" >&2 + exit 1 + fi + sleep 10 + try=$((try + 1)) +done + +if [[ $INSTALL_BOOTLOADER == "true" ]]; then + extra_env='NIXOS_INSTALL_BOOTLOADER=1' +else + extra_env='' +fi + +switchCommand="nix-env -p /nix/var/nix/profiles/system --set $(printf "%q" "$NIXOS_SYSTEM"); $extra_env /nix/var/nix/profiles/system/bin/switch-to-configuration switch" + +if [[ $TARGET_USER != "root" ]]; then + switchCommand="sudo bash -c '$switchCommand'" +fi +deploy_status=0 +# shellcheck disable=SC2029 +ssh "${sshOpts[@]}" "$TARGET" "$switchCommand" || deploy_status="$?" +if [[ $IGNORE_SYSTEMD_ERRORS == "true" && $deploy_status == "4" ]]; then + exit 0 +fi +exit "$deploy_status" diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/main.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/main.tf new file mode 100644 index 00000000..84461c80 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/main.tf @@ -0,0 +1,11 @@ +resource "null_resource" "nixos-rebuild" { + triggers = { + store_path = var.nixos_system + } + provisioner "local-exec" { + environment = { + SSH_KEY = var.ssh_private_key + } + command = "${path.module}/deploy.sh ${var.nixos_system} ${var.target_user} ${var.target_host} ${var.target_port} ${var.ignore_systemd_errors} ${var.install_bootloader}" + } +} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/variables.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/variables.tf new file mode 100644 index 00000000..90e0b0c6 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/variables.tf @@ -0,0 +1,39 @@ +variable "nixos_system" { + type = string + description = "The nixos system to deploy" +} + +variable "target_host" { + type = string + description = "DNS host to deploy to" +} + +variable "target_user" { + type = string + default = "root" + description = "User to deploy as" +} + +variable "target_port" { + type = number + description = "SSH port used to connect to the target_host" + default = 22 +} + +variable "ssh_private_key" { + type = string + description = "Content of private key used to connect to the target_host. If set to - no key is passed to openssh and ssh will use its own configuration" + default = "-" +} + +variable "ignore_systemd_errors" { + type = bool + description = "Ignore systemd errors happening during deploy" + default = false +} + +variable "install_bootloader" { + type = bool + description = "Install/re-install the bootloader" + default = false +} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/update-docs.sh b/launch/.terraform/modules/pixelfed.deploy/terraform/update-docs.sh new file mode 100755 index 00000000..b67d98ad --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/terraform/update-docs.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" +files=() +find "${SCRIPT_DIR}"/* -type d | while read -r i; do + module_name=$(basename "$i") + markdown_file="${SCRIPT_DIR}/${module_name}.md" + terraform-docs --config "${SCRIPT_DIR}/.terraform-docs.yml" markdown table --output-file "${markdown_file}" --output-mode inject "${module_name}" + files+=("${markdown_file}") +done +cd .. +nix fmt -- --no-cache diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/flake-module.nix b/launch/.terraform/modules/pixelfed.deploy/tests/flake-module.nix new file mode 100644 index 00000000..784175f4 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/tests/flake-module.nix @@ -0,0 +1,33 @@ +{ withSystem, inputs, ... }: + +{ + flake.checks.x86_64-linux = withSystem "x86_64-linux" ( + { + pkgs, + system, + inputs', + config, + ... + }: + let + testInputsUnstable = { + inherit pkgs; + inherit (inputs.disko.nixosModules) disko; + nixos-anywhere = config.packages.nixos-anywhere; + kexec-installer = "${inputs'.nixos-images.packages.kexec-installer-nixos-unstable-noninteractive}/nixos-kexec-installer-noninteractive-${system}.tar.gz"; + }; + testInputsStable = testInputsUnstable // { + kexec-installer = "${inputs'.nixos-images.packages.kexec-installer-nixos-stable-noninteractive}/nixos-kexec-installer-noninteractive-${system}.tar.gz"; + }; + in + { + from-nixos = import ./from-nixos.nix testInputsUnstable; + from-nixos-stable = import ./from-nixos.nix testInputsStable; + from-nixos-with-sudo = import ./from-nixos-with-sudo.nix testInputsUnstable; + from-nixos-with-sudo-stable = import ./from-nixos-with-sudo.nix testInputsStable; + from-nixos-with-generated-config = import ./from-nixos-generate-config.nix testInputsUnstable; + from-nixos-build-on-remote = import ./from-nixos-build-on-remote.nix testInputsUnstable; + from-nixos-separated-phases = import ./from-nixos-separated-phases.nix testInputsUnstable; + } + ); +} diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-build-on-remote.nix b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-build-on-remote.nix new file mode 100644 index 00000000..52617133 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-build-on-remote.nix @@ -0,0 +1,56 @@ +(import ./lib/test-base.nix) ( + { pkgs, ... }: + { + name = "from-nixos-build-on-remote"; + nodes = { + installer = ./modules/installer.nix; + installed = { + services.openssh.enable = true; + virtualisation.memorySize = 1024; + + users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; + }; + }; + testScript = '' + def create_test_machine( + oldmachine=None, **kwargs + ): # taken from + start_command = [ + "${pkgs.qemu_test}/bin/qemu-kvm", + "-cpu", + "max", + "-m", + "1024", + "-virtfs", + "local,path=/nix/store,security_model=none,mount_tag=nix-store", + "-drive", + f"file={oldmachine.state_dir}/installed.qcow2,id=drive1,if=none,index=1,werror=report", + "-device", + "virtio-blk-pci,drive=drive1", + ] + machine = create_machine(start_command=" ".join(start_command), **kwargs) + driver.machines.append(machine) + return machine + start_all() + + installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --build-on-remote \ + --kexec /etc/nixos-anywhere/kexec-installer \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + root@installed >&2 + """) + try: + installed.shutdown() + except BrokenPipeError: + # qemu has already exited + pass + new_machine = create_test_machine(oldmachine=installed, name="after_install") + new_machine.start() + hostname = new_machine.succeed("hostname").strip() + assert "nixos-anywhere" == hostname, f"'nixos-anywhere' != '{hostname}'" + ''; + } +) diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-generate-config.nix b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-generate-config.nix new file mode 100644 index 00000000..5b4d65dd --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-generate-config.nix @@ -0,0 +1,71 @@ +(import ./lib/test-base.nix) { + name = "from-nixos-generate-config"; + nodes = { + installer = + { pkgs, ... }: + { + imports = [ + ./modules/installer.nix + ]; + environment.systemPackages = [ pkgs.jq ]; + }; + installed = { + services.openssh.enable = true; + virtualisation.memorySize = 1024; + + users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; + }; + }; + testScript = '' + start_all() + installer.fail("test -f /tmp/hw/config.nix") + installer.succeed("echo super-secret > /tmp/disk-1.key") + output = installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --kexec /etc/nixos-anywhere/kexec-installer \ + --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ + --disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \ + --phases kexec,disko \ + --generate-hardware-config nixos-generate-config /tmp/hw/config.nix \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + root@installed >&2 + echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat /tmp/disk-1.key)'" + echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat /tmp/disk-2.key)'" + """) + + installer.succeed("cat /tmp/hw/config.nix >&2") + installer.succeed("nix-instantiate --parse /tmp/hw/config.nix") + + assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}" + assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}" + + installer.fail("test -f /test/hw/config.json") + + output = installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --kexec /etc/nixos-anywhere/kexec-installer \ + --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ + --disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \ + --phases kexec,disko \ + --generate-hardware-config nixos-facter /tmp/hw/config.json \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + installed >&2 + echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat /tmp/disk-1.key)'" + echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat /tmp/disk-2.key)'" + """) + + installer.succeed("cat /tmp/hw/config.json >&2") + installer.succeed("jq < /tmp/hw/config.json") + + assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}" + assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}" + ''; +} diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-separated-phases.nix b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-separated-phases.nix new file mode 100644 index 00000000..2b267b69 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-separated-phases.nix @@ -0,0 +1,52 @@ +(import ./lib/test-base.nix) { + name = "from-nixos-separated-phases"; + nodes = { + installer = ./modules/installer.nix; + installed = { + services.openssh.enable = true; + virtualisation.memorySize = 1024; + + users.users.nixos = { + isNormalUser = true; + openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; + extraGroups = [ "wheel" ]; + }; + security.sudo.enable = true; + security.sudo.wheelNeedsPassword = false; + }; + }; + testScript = '' + start_all() + + with subtest("Kexec Phase"): + installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --kexec /etc/nixos-anywhere/kexec-installer \ + --phases kexec \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + nixos@installed >&2 + """) + + with subtest("Disko Phase"): + output = installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --phases disko \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + installed >&2 + """) + + with subtest("Install Phase"): + installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --phases install \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + root@installed >&2 + """) + ''; +} diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-with-sudo.nix b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-with-sudo.nix new file mode 100644 index 00000000..839dec38 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-with-sudo.nix @@ -0,0 +1,40 @@ +(import ./lib/test-base.nix) { + name = "from-nixos-with-sudo"; + nodes = { + installer = ./modules/installer.nix; + installed = { + services.openssh.enable = true; + virtualisation.memorySize = 1024; + + users.users.nixos = { + isNormalUser = true; + openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; + extraGroups = [ "wheel" ]; + }; + security.sudo.enable = true; + security.sudo.wheelNeedsPassword = false; + }; + }; + testScript = '' + start_all() + installer.succeed("echo super-secret > /tmp/disk-1.key") + output = installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --kexec /etc/nixos-anywhere/kexec-installer \ + --phases kexec,disko \ + --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ + --disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + nixos@installed >&2 + echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat /tmp/disk-1.key)'" + echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat /tmp/disk-2.key)'" + """) + + assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}" + assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}" + ''; +} diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos.nix b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos.nix new file mode 100644 index 00000000..0f3d1344 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos.nix @@ -0,0 +1,76 @@ +(import ./lib/test-base.nix) ( + { pkgs, ... }: + { + name = "from-nixos"; + nodes = { + installer = ./modules/installer.nix; + installed = { + services.openssh.enable = true; + virtualisation.memorySize = 1024; + + users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; + }; + }; + testScript = '' + def create_test_machine( + oldmachine=None, **kwargs + ): # taken from + start_command = [ + "${pkgs.qemu_test}/bin/qemu-kvm", + "-cpu", + "max", + "-m", + "1024", + "-virtfs", + "local,path=/nix/store,security_model=none,mount_tag=nix-store", + "-drive", + f"file={oldmachine.state_dir}/installed.qcow2,id=drive1,if=none,index=1,werror=report", + "-device", + "virtio-blk-pci,drive=drive1", + ] + machine = create_machine(start_command=" ".join(start_command), **kwargs) + driver.machines.append(machine) + return machine + start_all() + installer.succeed("mkdir -p /tmp/extra-files/var/lib/secrets") + installer.succeed("echo value > /tmp/extra-files/var/lib/secrets/key") + installer.succeed("mkdir -p /tmp/extra-files/home/user/.ssh") + installer.succeed("echo secretkey > /tmp/extra-files/home/user/.ssh/id_ed25519") + installer.succeed("echo publickey > /tmp/extra-files/home/user/.ssh/id_ed25519.pub") + installer.succeed("chmod 600 /tmp/extra-files/home/user/.ssh/id_ed25519") + ssh_key_path = "/etc/ssh/ssh_host_ed25519_key.pub" + ssh_key_output = installer.wait_until_succeeds(f""" + ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + root@installed cat {ssh_key_path} + """) + installer.succeed(""" + nixos-anywhere \ + -i /root/.ssh/install_key \ + --debug \ + --kexec /etc/nixos-anywhere/kexec-installer \ + --extra-files /tmp/extra-files \ + --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ + --chown /home/user 1000:100 \ + --copy-host-keys \ + root@installed >&2 + """) + try: + installed.shutdown() + except BrokenPipeError: + # qemu has already exited + pass + new_machine = create_test_machine(oldmachine=installed, name="after_install") + new_machine.start() + hostname = new_machine.succeed("hostname").strip() + assert "nixos-anywhere" == hostname, f"'nixos-anywhere' != '{hostname}'" + content = new_machine.succeed("cat /var/lib/secrets/key").strip() + assert "value" == content, f"secret does not have expected value: {content}" + ssh_key_content = new_machine.succeed(f"cat {ssh_key_path}").strip() + assert ssh_key_content in ssh_key_output, "SSH host identity changed" + priv_key_perms = new_machine.succeed("stat -c %a /home/user/.ssh/id_ed25519").strip() + assert priv_key_perms == "600", f"unexpected permissions for private key: {priv_key_perms}" + user_dir_ownership = new_machine.succeed("stat -c %u:%g /home/user").strip() + assert user_dir_ownership == "1000:100", f"unexpected user home dir permissions: {user_dir_ownership}" + ''; + } +) diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/lib/test-base.nix b/launch/.terraform/modules/pixelfed.deploy/tests/lib/test-base.nix new file mode 100644 index 00000000..169d1fd2 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/tests/lib/test-base.nix @@ -0,0 +1,20 @@ +test: +{ + pkgs ? import { }, + nixos-anywhere ? pkgs.callPackage ../../src { }, + disko ? "${builtins.fetchTarball "https://github.com/nix-community/disko/archive/master.tar.gz"}/module.nix", + kexec-installer ? builtins.fetchurl "https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-${pkgs.stdenv.hostPlatform.system}.tar.gz", + ... +}: +let + inherit (pkgs) lib; + nixos-lib = import (pkgs.path + "/nixos/lib") { }; +in +(nixos-lib.runTest { + hostPkgs = pkgs; + # speed-up evaluation + defaults.documentation.enable = lib.mkDefault false; + # to accept external dependencies such as disko + node.specialArgs.inputs = { inherit nixos-anywhere disko kexec-installer; }; + imports = [ test ]; +}).config.result diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/modules/installer.nix b/launch/.terraform/modules/pixelfed.deploy/tests/modules/installer.nix new file mode 100644 index 00000000..e5c22d4d --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/tests/modules/installer.nix @@ -0,0 +1,22 @@ +{ pkgs, inputs, ... }: +let + disko = inputs.disko; + kexec-installer = inputs.kexec-installer; + system-to-install = pkgs.nixos [ + ./system-to-install.nix + disko + ]; +in +{ + system.activationScripts.rsa-key = '' + ${pkgs.coreutils}/bin/install -D -m600 ${./ssh-keys/ssh} /root/.ssh/install_key + ''; + + environment.systemPackages = [ inputs.nixos-anywhere ]; + + environment.etc = { + "nixos-anywhere/disko".source = system-to-install.config.system.build.diskoScriptNoDeps; + "nixos-anywhere/system-to-install".source = system-to-install.config.system.build.toplevel; + "nixos-anywhere/kexec-installer".source = kexec-installer; + }; +} diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh b/launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh new file mode 100644 index 00000000..db6049c5 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACDM4kPg4V7DMYceuA8VIUdBvw30gM9qagERA8v1VGBBBQAAAJDpULAq6VCw +KgAAAAtzc2gtZWQyNTUxOQAAACDM4kPg4V7DMYceuA8VIUdBvw30gM9qagERA8v1VGBBBQ +AAAECpjfl5WMMIDvEyZJTeXzRNFzpDpj4fqdIXHZauKAlE5MziQ+DhXsMxhx64DxUhR0G/ +DfSAz2pqAREDy/VUYEEFAAAACWxhc3NAbW9ycwECAwQ= +-----END OPENSSH PRIVATE KEY----- diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh.pub b/launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh.pub new file mode 100644 index 00000000..e77d393e --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMziQ+DhXsMxhx64DxUhR0G/DfSAz2pqAREDy/VUYEEF diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/modules/system-to-install.nix b/launch/.terraform/modules/pixelfed.deploy/tests/modules/system-to-install.nix new file mode 100644 index 00000000..1181c944 --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/tests/modules/system-to-install.nix @@ -0,0 +1,47 @@ +{ modulesPath, self, ... }: +{ + imports = [ + (modulesPath + "/testing/test-instrumentation.nix") + (modulesPath + "/profiles/qemu-guest.nix") + (modulesPath + "/profiles/minimal.nix") + ]; + networking.hostName = "nixos-anywhere"; + documentation.enable = false; + hardware.enableAllFirmware = false; + networking.hostId = "8425e349"; # from profiles/base.nix, needed for zfs + boot.zfs.devNodes = "/dev/disk/by-uuid"; # needed because /dev/disk/by-id is empty in qemu-vms + disko.devices = { + disk = { + vda = { + device = "/dev/vda"; + type = "disk"; + content = { + type = "gpt"; + partitions = { + boot = { + size = "1M"; + type = "EF02"; + }; + ESP = { + size = "100M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/launch/.terraform/modules/pixelfed.deploy/treefmt/flake-module.nix b/launch/.terraform/modules/pixelfed.deploy/treefmt/flake-module.nix new file mode 100644 index 00000000..3e92a8ed --- /dev/null +++ b/launch/.terraform/modules/pixelfed.deploy/treefmt/flake-module.nix @@ -0,0 +1,23 @@ +{ inputs, ... }: +{ + imports = [ + inputs.treefmt-nix.flakeModule + ]; + perSystem = + { config, pkgs, ... }: + { + treefmt = { + projectRootFile = "flake.nix"; + programs.mdsh.enable = true; + programs.nixpkgs-fmt.enable = true; + programs.shellcheck.enable = true; + programs.shfmt.enable = true; + programs.deno.enable = !pkgs.deno.meta.broken; + settings.formatter.shellcheck.options = [ + "-s" + "bash" + ]; + }; + formatter = config.treefmt.build.wrapper; + }; +} diff --git a/launch/.terraform/plugin_path b/launch/.terraform/plugin_path index 0a21d939..9d621c4b 100644 --- a/launch/.terraform/plugin_path +++ b/launch/.terraform/plugin_path @@ -1,3 +1,2 @@ [ "/nix/store/mnqkwjg5v6sx86an34b4cn075h0lapz3-opentofu-1.8.7/libexec/terraform-providers" -] \ No newline at end of file diff --git a/launch/tf-env.nix b/launch/tf-env.nix new file mode 100644 index 00000000..eb1e3161 --- /dev/null +++ b/launch/tf-env.nix @@ -0,0 +1,36 @@ +{ + lib, + pkgs, + sources ? import ../npins, + ... +}: +pkgs.stdenv.mkDerivation { + name = "tf-repo"; + src = ../.; + buildInputs = [ + (import ./tf.nix { inherit lib pkgs; }) + ]; + buildPhase = '' + runHook preBuild + pushd launch/ + + # pass nixos-anywhere path to TF through variable + # when switching TF to nix take this directly from `inputs` + # https://codeberg.org/kiara/e2ed-hetzner/commit/84b2a349d3e48ea2a17340bceff762d834fd4046 + # echo "{\"nixos-anywhere\": \"${sources.nixos-anywhere}\"}" > .auto.tfvars.json + + # point to the relevant providers + # tofu init -input=false + + popd + runHook postBuild + ''; + # FIXME: can the above even work without a connection? + installPhase = '' + runHook preInstall + + cp -r . $out + + runHook postInstall + ''; +} diff --git a/panel/default.nix b/panel/default.nix index 767802be..06d1a487 100644 --- a/panel/default.nix +++ b/panel/default.nix @@ -20,11 +20,18 @@ in pkgs.npins manage ]; - env = import ./env.nix { inherit lib pkgs; } // { - NPINS_DIRECTORY = toString ../npins; - CREDENTIALS_DIRECTORY = toString ./.credentials; - DATABASE_URL = "sqlite:///${toString ./src}/db.sqlite3"; - }; + env = + let + inherit (builtins) toString; + in + import ./env.nix { inherit lib pkgs; } + // { + NPINS_DIRECTORY = toString ../npins; + CREDENTIALS_DIRECTORY = toString ./.credentials; + DATABASE_URL = "sqlite:///${toString ./src}/db.sqlite3"; + # locally: use a fixed relative reference, so we can use our newest files without copying to the store + REPO_DIR = toString ../.; + }; shellHook = '' ln -sf ${sources.htmx}/dist/htmx.js src/panel/static/htmx.min.js # in production, secrets are passed via CREDENTIALS_DIRECTORY by systemd. diff --git a/panel/env.nix b/panel/env.nix index 87805588..99a286d8 100644 --- a/panel/env.nix +++ b/panel/env.nix @@ -3,12 +3,7 @@ pkgs, ... }: -let - inherit (builtins) toString; -in { - # locally: use a fixed relative reference, so we can use our newest files without copying to the store - REPO_DIR = toString ../.; BIN_PATH = lib.makeBinPath [ pkgs.lix pkgs.bash diff --git a/panel/nix/configuration.nix b/panel/nix/configuration.nix index ecf06e0f..16d510fe 100644 --- a/panel/nix/configuration.nix +++ b/panel/nix/configuration.nix @@ -29,6 +29,7 @@ let ((pkgs.formats.pythonVars { }).generate "settings.py" cfg.settings) (builtins.toFile "extra-settings.py" cfg.extra-settings) ]; + REPO_DIR = import ../../launch/tf-env.nix { inherit lib pkgs; }; }; python-environment = pkgs.python3.withPackages ( diff --git a/panel/nix/package.nix b/panel/nix/package.nix index 2f94fa8f..0acd9796 100644 --- a/panel/nix/package.nix +++ b/panel/nix/package.nix @@ -1,5 +1,6 @@ { lib, + pkgs, sqlite, python3, sources ? import ../../npins, @@ -59,7 +60,7 @@ python3.pkgs.buildPythonPackage { cp -v ${src}/manage.py $out/bin/manage.py chmod +x $out/bin/manage.py wrapProgram $out/bin/manage.py \ - --set REPO_DIR "${../..}" \ + --set REPO_DIR "${import ../../launch/tf-env.nix { inherit lib pkgs; }}" \ --prefix PYTHONPATH : "$PYTHONPATH" cp ${sources.htmx}/dist/htmx.min.js* $out/${python3.sitePackages}/panel/static/ ''; diff --git a/panel/src/panel/settings.py b/panel/src/panel/settings.py index 01c88963..ccdb8308 100644 --- a/panel/src/panel/settings.py +++ b/panel/src/panel/settings.py @@ -238,21 +238,6 @@ if user_settings_file is not None: sys.modules["user_settings"] = module from user_settings import * # noqa: F403 # pyright: ignore [reportMissingImports] -def handle_double_hash(orig_path: str) -> str: - """Convert store paths to account for potentially double hashes. - - c.f. https://github.com/NixOS/nix/issues/10627 - """ - # local paths can stay as-is - if not STORE_PATTERN.match(orig_path): - return orig_path - # for /nix/store paths, account for double hashing - orig_name = orig_path.split("/")[-1] - cmd = ["find", "/nix/store/", "-maxdepth", "1", "-name", f"*{orig_name}"] - process = subprocess.run(cmd, capture_output=True) - fixed_name = process.stdout.decode("utf-8").split("\n")[0] - return fixed_name - # non-Django application settings # TODO(@fricklerhandwerk): @@ -263,4 +248,4 @@ def handle_double_hash(orig_path: str) -> str: bin_path=env['BIN_PATH'] # path of the root flake to trigger nixops from, see #94. # to deploy this should be specified, for dev just use a relative path. -repo_dir = handle_double_hash(env["REPO_DIR"]) +repo_dir = env["REPO_DIR"] -- 2.48.1 From b3e783d4a54538a88d0898478460987b7451d304 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Wed, 26 Mar 2025 10:17:19 +0100 Subject: [PATCH 11/57] move tf init out of python over read-only nix env --- launch/README.md | 7 +++++++ panel/src/panel/views.py | 9 --------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/launch/README.md b/launch/README.md index a30dbbfa..ee636f0a 100644 --- a/launch/README.md +++ b/launch/README.md @@ -7,3 +7,10 @@ ```sh echo "{\"nixos-anywhere\": $(nix-instantiate --eval --json -E '(import ../npins).nixos-anywhere.outPath')}" > .auto.tfvars.json ``` + +### local development + +```sh +$ nix-shell +$ tofu init +``` diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index b9abf8cc..45358e46 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -147,15 +147,6 @@ class DeploymentStatus(ConfigurationForm): } cwd = f"{settings.repo_dir}/launch" # FIXME: move init to packaging phase - cmd = [ - "tofu", - # f"-chdir={cwd}", - "init", - "-get=false", - "-input=false", - # "-plugin-dir=...", - ] - subprocess.run(cmd, cwd=cwd, env=env) cmd = [ "tofu", # f"-chdir={cwd}", -- 2.48.1 From 225f2a5be6902924c1b48e1e83985ac0a3c848a0 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Wed, 26 Mar 2025 10:18:56 +0100 Subject: [PATCH 12/57] skip tf lock in views.py over read-only nix env --- panel/src/panel/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 45358e46..9bbe20bb 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -153,6 +153,7 @@ class DeploymentStatus(ConfigurationForm): "apply", f"-state={cwd}/terraform.tfstate", # FIXME: separate users' state "--auto-approve", + "-lock=false", ] deployment_result = subprocess.run(cmd, cwd=cwd, env=env) print(deployment_result) -- 2.48.1 From c841c4e9fdae4560e875b3dca4a8401246edfb6c Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Wed, 26 Mar 2025 10:53:28 +0100 Subject: [PATCH 13/57] specify XDG_CACHE_HOME, workaround to error writing to /var/empty/.cache --- panel/src/panel/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 9bbe20bb..373fb2bf 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -140,6 +140,7 @@ class DeploymentStatus(ConfigurationForm): "PATH": settings.bin_path, # used in nixos-anywhere for ssh-copy-id "HOME": expanduser("~"), + "XDG_CACHE_HOME": "/tmp", } | { # pass in form info to our deployment # FIXME: ensure sensitive info is protected -- 2.48.1 From 727b62f588bbcb41fff4b4ca3c6baac980a7b879 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Thu, 27 Mar 2025 10:06:54 +0100 Subject: [PATCH 14/57] update --- launch/flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launch/flake.lock b/launch/flake.lock index 124c30b2..e1b4f6df 100644 --- a/launch/flake.lock +++ b/launch/flake.lock @@ -116,11 +116,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1742753982, - "narHash": "sha256-WYryX6lCrmh4AaEoBHA1zwTTs6vPtevT3/ywGyzz4SI=", + "lastModified": 1743046730, + "narHash": "sha256-3ON6kKBQ4pz/IVZylcbw28K/Jm5cym4V/Z+VmPzR9/4=", "owner": "nixos", "repo": "nixpkgs", - "rev": "ec9c54e7a9feec999aa34a15781080bed5082306", + "rev": "67545051fd77a131ebab477fbf2bb4d9473edd35", "type": "github" }, "original": { -- 2.48.1 From 195a8d4de872c9787cfb4877d4b38daa4e7b0682 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Thu, 27 Mar 2025 10:07:34 +0100 Subject: [PATCH 15/57] document updating TF module --- launch/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/launch/README.md b/launch/README.md index ee636f0a..8bed71b8 100644 --- a/launch/README.md +++ b/launch/README.md @@ -5,12 +5,15 @@ ### updating TF modules ```sh -echo "{\"nixos-anywhere\": $(nix-instantiate --eval --json -E '(import ../npins).nixos-anywhere.outPath')}" > .auto.tfvars.json +$ npins update nixos-anywhere +$ cd launch/ +$ echo "{\"nixos-anywhere\": $(nix-instantiate --eval --json -E '(import ../npins).nixos-anywhere.outPath')}" > .auto.tfvars.json ``` ### local development ```sh $ nix-shell +$ rm -rf .terraform/ $ tofu init ``` -- 2.48.1 From 29664fef8c877cbe026fea684279bf71e25b91b4 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Fri, 28 Mar 2025 21:08:55 +0100 Subject: [PATCH 16/57] get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes seemingly gets further when a similar command is tried from terminal. as per https://github.com/NixOS/nix/issues/8752#issuecomment-1694714693, this may have to do with aligning the current working directory. --- launch/.terraform/modules/deploy | 1 - launch/.terraform/modules/garage.deploy | 1 - .../modules/peertube.deploy/CONTRIBUTING.md | 23 - .../modules/peertube.deploy/docs/INDEX.md | 11 - .../modules/peertube.deploy/docs/SUMMARY.md | 26 - .../modules/peertube.deploy/docs/book.toml | 6 - .../modules/peertube.deploy/docs/cli.md | 63 -- .../peertube.deploy/docs/flake-module.nix | 21 - .../modules/peertube.deploy/docs/howtos.md | 1 - .../peertube.deploy/docs/howtos/INDEX.md | 29 - .../docs/howtos/custom-kexec.md | 40 - .../docs/howtos/disko-modes.md | 19 - .../docs/howtos/extra-files.md | 114 --- .../peertube.deploy/docs/howtos/ipv6.md | 23 - .../docs/howtos/limited-ram.md | 29 - .../peertube.deploy/docs/howtos/nix-path.md | 57 -- .../peertube.deploy/docs/howtos/no-os.md | 71 -- .../peertube.deploy/docs/howtos/secrets.md | 76 -- .../peertube.deploy/docs/howtos/terraform.md | 23 - .../docs/howtos/use-without-flakes.md | 82 -- .../modules/peertube.deploy/docs/logo.png | Bin 29405 -> 0 bytes .../modules/peertube.deploy/docs/logo.svg | 133 --- .../peertube.deploy/docs/quickstart.md | 334 ------- .../modules/peertube.deploy/docs/reference.md | 137 --- .../peertube.deploy/docs/requirements.md | 39 - .../modules/peertube.deploy/flake.lock | 132 --- .../modules/peertube.deploy/flake.nix | 55 -- .../peertube.deploy/scripts/create-release.sh | 38 - .../modules/peertube.deploy/src/default.nix | 63 -- .../peertube.deploy/src/flake-module.nix | 11 - .../modules/peertube.deploy/src/get-facts.sh | 23 - .../peertube.deploy/src/nixos-anywhere.sh | 880 ------------------ .../peertube.deploy/terraform/README.md | 21 - .../peertube.deploy/terraform/all-in-one.md | 235 ----- .../terraform/all-in-one/main.tf | 64 -- .../terraform/all-in-one/variables.tf | 151 --- .../peertube.deploy/terraform/install.md | 91 -- .../peertube.deploy/terraform/install/main.tf | 35 - .../terraform/install/providers.tf | 5 - .../terraform/install/run-nixos-anywhere.sh | 92 -- .../terraform/install/variables.tf | 123 --- .../peertube.deploy/terraform/nix-build.md | 47 - .../terraform/nix-build/main.tf | 17 - .../terraform/nix-build/nix-build.sh | 57 -- .../terraform/nix-build/variables.tf | 22 - .../terraform/nixos-rebuild.md | 66 -- .../terraform/nixos-rebuild/deploy.sh | 68 -- .../terraform/nixos-rebuild/main.tf | 11 - .../terraform/nixos-rebuild/variables.tf | 39 - .../peertube.deploy/terraform/update-docs.sh | 14 - .../peertube.deploy/tests/flake-module.nix | 33 - .../tests/from-nixos-build-on-remote.nix | 56 -- .../tests/from-nixos-generate-config.nix | 71 -- .../tests/from-nixos-separated-phases.nix | 52 -- .../tests/from-nixos-with-sudo.nix | 40 - .../peertube.deploy/tests/from-nixos.nix | 76 -- .../peertube.deploy/tests/lib/test-base.nix | 20 - .../tests/modules/installer.nix | 22 - .../tests/modules/ssh-keys/ssh | 7 - .../tests/modules/ssh-keys/ssh.pub | 1 - .../tests/modules/system-to-install.nix | 47 - .../peertube.deploy/treefmt/flake-module.nix | 23 - ...d to a Nix language value' for non-flakes) | 1 + .../modules/pixelfed.deploy/CONTRIBUTING.md | 23 - .../modules/pixelfed.deploy/docs/INDEX.md | 11 - .../modules/pixelfed.deploy/docs/SUMMARY.md | 26 - .../modules/pixelfed.deploy/docs/book.toml | 6 - .../modules/pixelfed.deploy/docs/cli.md | 63 -- .../pixelfed.deploy/docs/flake-module.nix | 21 - .../modules/pixelfed.deploy/docs/howtos.md | 1 - .../pixelfed.deploy/docs/howtos/INDEX.md | 29 - .../docs/howtos/custom-kexec.md | 40 - .../docs/howtos/disko-modes.md | 19 - .../docs/howtos/extra-files.md | 114 --- .../pixelfed.deploy/docs/howtos/ipv6.md | 23 - .../docs/howtos/limited-ram.md | 29 - .../pixelfed.deploy/docs/howtos/nix-path.md | 57 -- .../pixelfed.deploy/docs/howtos/no-os.md | 71 -- .../pixelfed.deploy/docs/howtos/secrets.md | 76 -- .../pixelfed.deploy/docs/howtos/terraform.md | 23 - .../docs/howtos/use-without-flakes.md | 82 -- .../modules/pixelfed.deploy/docs/logo.png | Bin 29405 -> 0 bytes .../modules/pixelfed.deploy/docs/logo.svg | 133 --- .../pixelfed.deploy/docs/quickstart.md | 334 ------- .../modules/pixelfed.deploy/docs/reference.md | 137 --- .../pixelfed.deploy/docs/requirements.md | 39 - .../modules/pixelfed.deploy/flake.lock | 132 --- .../modules/pixelfed.deploy/flake.nix | 55 -- .../pixelfed.deploy/scripts/create-release.sh | 38 - .../modules/pixelfed.deploy/src/default.nix | 63 -- .../pixelfed.deploy/src/flake-module.nix | 11 - .../modules/pixelfed.deploy/src/get-facts.sh | 23 - .../pixelfed.deploy/src/nixos-anywhere.sh | 880 ------------------ .../pixelfed.deploy/terraform/README.md | 21 - .../pixelfed.deploy/terraform/all-in-one.md | 235 ----- .../terraform/all-in-one/main.tf | 64 -- .../terraform/all-in-one/variables.tf | 151 --- .../pixelfed.deploy/terraform/install.md | 91 -- .../pixelfed.deploy/terraform/install/main.tf | 35 - .../terraform/install/providers.tf | 5 - .../terraform/install/run-nixos-anywhere.sh | 92 -- .../terraform/install/variables.tf | 123 --- .../pixelfed.deploy/terraform/nix-build.md | 47 - .../terraform/nix-build/main.tf | 17 - .../terraform/nix-build/nix-build.sh | 57 -- .../terraform/nix-build/variables.tf | 22 - .../terraform/nixos-rebuild.md | 66 -- .../terraform/nixos-rebuild/deploy.sh | 68 -- .../terraform/nixos-rebuild/main.tf | 11 - .../terraform/nixos-rebuild/variables.tf | 39 - .../pixelfed.deploy/terraform/update-docs.sh | 14 - .../pixelfed.deploy/tests/flake-module.nix | 33 - .../tests/from-nixos-build-on-remote.nix | 56 -- .../tests/from-nixos-generate-config.nix | 71 -- .../tests/from-nixos-separated-phases.nix | 52 -- .../tests/from-nixos-with-sudo.nix | 40 - .../pixelfed.deploy/tests/from-nixos.nix | 76 -- .../pixelfed.deploy/tests/lib/test-base.nix | 20 - .../tests/modules/installer.nix | 22 - .../tests/modules/ssh-keys/ssh | 7 - .../tests/modules/ssh-keys/ssh.pub | 1 - .../tests/modules/system-to-install.nix | 47 - .../pixelfed.deploy/treefmt/flake-module.nix | 23 - launch/garage.nix | 37 + launch/mastodon.nix | 20 + launch/peertube.nix | 23 + launch/pixelfed.nix | 19 + launch/shared.nix | 45 + launch/vm/main.tf | 5 +- npins/sources.json | 35 +- 130 files changed, 179 insertions(+), 8338 deletions(-) delete mode 160000 launch/.terraform/modules/deploy delete mode 160000 launch/.terraform/modules/garage.deploy delete mode 100644 launch/.terraform/modules/peertube.deploy/CONTRIBUTING.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/INDEX.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/SUMMARY.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/book.toml delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/cli.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/flake-module.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/INDEX.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/custom-kexec.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/disko-modes.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/extra-files.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/ipv6.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/limited-ram.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/nix-path.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/no-os.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/secrets.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/terraform.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/howtos/use-without-flakes.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/logo.png delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/logo.svg delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/quickstart.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/reference.md delete mode 100644 launch/.terraform/modules/peertube.deploy/docs/requirements.md delete mode 100644 launch/.terraform/modules/peertube.deploy/flake.lock delete mode 100644 launch/.terraform/modules/peertube.deploy/flake.nix delete mode 100755 launch/.terraform/modules/peertube.deploy/scripts/create-release.sh delete mode 100644 launch/.terraform/modules/peertube.deploy/src/default.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/src/flake-module.nix delete mode 100755 launch/.terraform/modules/peertube.deploy/src/get-facts.sh delete mode 100755 launch/.terraform/modules/peertube.deploy/src/nixos-anywhere.sh delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/README.md delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/all-in-one.md delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/all-in-one/main.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/all-in-one/variables.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/install.md delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/install/main.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/install/providers.tf delete mode 100755 launch/.terraform/modules/peertube.deploy/terraform/install/run-nixos-anywhere.sh delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/install/variables.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/nix-build.md delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/nix-build/main.tf delete mode 100755 launch/.terraform/modules/peertube.deploy/terraform/nix-build/nix-build.sh delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/nix-build/variables.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild.md delete mode 100755 launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/deploy.sh delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/main.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/variables.tf delete mode 100755 launch/.terraform/modules/peertube.deploy/terraform/update-docs.sh delete mode 100644 launch/.terraform/modules/peertube.deploy/tests/flake-module.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/tests/from-nixos-build-on-remote.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/tests/from-nixos-generate-config.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/tests/from-nixos-separated-phases.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/tests/from-nixos-with-sudo.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/tests/from-nixos.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/tests/lib/test-base.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/tests/modules/installer.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh delete mode 100644 launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh.pub delete mode 100644 launch/.terraform/modules/peertube.deploy/tests/modules/system-to-install.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/treefmt/flake-module.nix create mode 120000 launch/.terraform/modules/peertube.deploy~f00c14b (get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes) delete mode 100644 launch/.terraform/modules/pixelfed.deploy/CONTRIBUTING.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/INDEX.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/SUMMARY.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/book.toml delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/cli.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/flake-module.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/INDEX.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/custom-kexec.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/disko-modes.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/extra-files.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/ipv6.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/limited-ram.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/nix-path.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/no-os.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/secrets.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/terraform.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/howtos/use-without-flakes.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/logo.png delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/logo.svg delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/quickstart.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/reference.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/docs/requirements.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/flake.lock delete mode 100644 launch/.terraform/modules/pixelfed.deploy/flake.nix delete mode 100755 launch/.terraform/modules/pixelfed.deploy/scripts/create-release.sh delete mode 100644 launch/.terraform/modules/pixelfed.deploy/src/default.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/src/flake-module.nix delete mode 100755 launch/.terraform/modules/pixelfed.deploy/src/get-facts.sh delete mode 100755 launch/.terraform/modules/pixelfed.deploy/src/nixos-anywhere.sh delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/README.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/main.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/variables.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/install.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/install/main.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/install/providers.tf delete mode 100755 launch/.terraform/modules/pixelfed.deploy/terraform/install/run-nixos-anywhere.sh delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/install/variables.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/nix-build.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/main.tf delete mode 100755 launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/nix-build.sh delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/variables.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild.md delete mode 100755 launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/deploy.sh delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/main.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/variables.tf delete mode 100755 launch/.terraform/modules/pixelfed.deploy/terraform/update-docs.sh delete mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/flake-module.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-build-on-remote.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-generate-config.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-separated-phases.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-with-sudo.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/from-nixos.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/lib/test-base.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/modules/installer.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh delete mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh.pub delete mode 100644 launch/.terraform/modules/pixelfed.deploy/tests/modules/system-to-install.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/treefmt/flake-module.nix create mode 100644 launch/garage.nix create mode 100644 launch/mastodon.nix create mode 100644 launch/peertube.nix create mode 100644 launch/pixelfed.nix create mode 100644 launch/shared.nix diff --git a/launch/.terraform/modules/deploy b/launch/.terraform/modules/deploy deleted file mode 160000 index 657cc08c..00000000 --- a/launch/.terraform/modules/deploy +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 657cc08c2a22cf6500de70df5519ccb194449f0f diff --git a/launch/.terraform/modules/garage.deploy b/launch/.terraform/modules/garage.deploy deleted file mode 160000 index 657cc08c..00000000 --- a/launch/.terraform/modules/garage.deploy +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 657cc08c2a22cf6500de70df5519ccb194449f0f diff --git a/launch/.terraform/modules/peertube.deploy/CONTRIBUTING.md b/launch/.terraform/modules/peertube.deploy/CONTRIBUTING.md deleted file mode 100644 index 3aeefa73..00000000 --- a/launch/.terraform/modules/peertube.deploy/CONTRIBUTING.md +++ /dev/null @@ -1,23 +0,0 @@ -To run `nixos-anywhere` from the repo: - -```console -nix run . -- --help -``` - -To format the code: - -```console -nix fmt -``` - -To run all tests: - -```console -nix flake check -vL -``` - -To run an individual test: - -``` -nix build .#checks.x86_64-linux.from-nixos -vL -``` diff --git a/launch/.terraform/modules/peertube.deploy/docs/INDEX.md b/launch/.terraform/modules/peertube.deploy/docs/INDEX.md deleted file mode 100644 index 67d48751..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/INDEX.md +++ /dev/null @@ -1,11 +0,0 @@ -# Table of Content: - nixos-anywhere - -**_Install NixOS everywhere via ssh_** - - - -- [README](../README.md) -- [Quickstart](./quickstart.md) -- [System Requirements](./requirements.md) -- [How to Guide](./howtos/INDEX.md) -- [Reference](./reference.md) diff --git a/launch/.terraform/modules/peertube.deploy/docs/SUMMARY.md b/launch/.terraform/modules/peertube.deploy/docs/SUMMARY.md deleted file mode 100644 index 3bfaea5b..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/SUMMARY.md +++ /dev/null @@ -1,26 +0,0 @@ -# Summary: - nixos-anywhere - -**_Install NixOS everywhere via ssh_** - - - -The **nixos-anywhere** tool allows you to pre-configure the whole process of -installing NixOS, and run the install remotely with a single CLI command. - -Refer to the following documentation for more information. - -[System Requirements](./requirements.md): CPU and memory requirements - -[Quickstart](./quickstart.md): Instructions for a typical installation - -[How to Guide](./howtos/INDEX.md): Instructions for non-typical use cases - -- [Installing on a machine with no operating system](./howtos/no-os.md) -- [Using your own kexec image](./howtos/custom-kexec.md) -- [Secrets and full disk encryption](./howtos/secrets.md) -- [Use without flakes](./howtos/use-without-flakes.md) -- [Terraform](./howtos/terraform.md) -- [Nix-channels / `NIX_PATH`](./howtos/nix-path.md) -- [IPv6-only targets](./howtos/ipv6.md) - -[Reference](./reference.md): Reference Guide diff --git a/launch/.terraform/modules/peertube.deploy/docs/book.toml b/launch/.terraform/modules/peertube.deploy/docs/book.toml deleted file mode 100644 index d053de4e..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/book.toml +++ /dev/null @@ -1,6 +0,0 @@ -[book] -authors = [ ] -language = "en" -multilingual = false -src = "." -title = "nixos-anywhere - install NixOS everywhere" diff --git a/launch/.terraform/modules/peertube.deploy/docs/cli.md b/launch/.terraform/modules/peertube.deploy/docs/cli.md deleted file mode 100644 index d2577552..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/cli.md +++ /dev/null @@ -1,63 +0,0 @@ -# CLI - -``` -Usage: nixos-anywhere [options] [] - -Options: - -* -f, --flake - set the flake to install the system from. -* --target-host - specified the SSH target host to deploy onto. -* -i - selects which SSH private key file to use. -* -p, --ssh-port - set the ssh port to connect with -* --ssh-option - set an ssh option -* -L, --print-build-logs - print full build logs -* --env-password - set a password used by ssh-copy-id, the password should be set by - the environment variable SSHPASS -* -s, --store-paths - set the store paths to the disko-script and nixos-system directly - if this is given, flake is not needed -* --no-reboot - do not reboot after installation, allowing further customization of the target installation. -* --kexec - use another kexec tarball to bootstrap NixOS -* --kexec-extra-flags - extra flags to add into the call to kexec, e.g. "--no-sync" -* --ssh-store-setting - ssh store settings appended to the store URI, e.g. "compress true". needs to be URI encoded. -* --post-kexec-ssh-port - after kexec is executed, use a custom ssh port to connect. Defaults to 22 -* --copy-host-keys - copy over existing /etc/ssh/ssh_host_* host keys to the installation -* --stop-after-disko - exit after disko formatting, you can then proceed to install manually or some other way -* --extra-files - contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten - Copied files will be owned by root. See documentation for details. -* --disk-encryption-keys - copy the contents of the file or pipe in local_path to remote_path in the installer environment, - after kexec but before installation. Can be repeated. -* --no-substitute-on-destination - disable passing --substitute-on-destination to nix-copy -* --debug - enable debug output -* --option - nix option to pass to every nix related command -* --from - URL of the source Nix store to copy the nixos and disko closure from -* --build-on-remote - build the closure on the remote machine instead of locally and copy-closuring it -* --vm-test - build the system and test the disk configuration inside a VM without installing it to the target. -* --build-on auto|remote|local - sets the build on settings to auto, remote or local. Default is auto. - auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build - local: will build on the local host - remote: will build on the remote host -``` diff --git a/launch/.terraform/modules/peertube.deploy/docs/flake-module.nix b/launch/.terraform/modules/peertube.deploy/docs/flake-module.nix deleted file mode 100644 index 2afe9d50..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/flake-module.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ - perSystem = - { pkgs, lib, ... }: - { - packages.docs = - pkgs.runCommand "nixos-anywhere-docs" - { - passthru.serve = pkgs.writeShellScriptBin "serve" '' - set -euo pipefail - cd docs - workdir=$(${pkgs.coreutils}/bin/mktemp -d) - trap 'rm -rf "$workdir"' EXIT - ${pkgs.mdbook}/bin/mdbook serve --dest-dir "$workdir" - ''; - } - '' - cp -r ${lib.cleanSource ./.}/* . - ${pkgs.mdbook}/bin/mdbook build --dest-dir "$out" - ''; - }; -} diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos.md b/launch/.terraform/modules/peertube.deploy/docs/howtos.md deleted file mode 100644 index bfa55ce1..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/howtos.md +++ /dev/null @@ -1 +0,0 @@ -# How to Guide diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/INDEX.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/INDEX.md deleted file mode 100644 index 2d356638..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/howtos/INDEX.md +++ /dev/null @@ -1,29 +0,0 @@ -# How To Guide: nixos-anywhere - -**_Install NixOS everywhere via ssh_** - - - -[Documentation Index](./INDEX.md) - -## Contents - -[Installing on a machine with no operating system](./no-os.md) - -[Kexec on systems with limited RAM](./limited-ram.md) - -[Copying files to the new installation](./extra-files.md) - -[Using your own kexec image](./custom-kexec.md) - -[Repair installations without wiping data](./disko-modes.md) - -[Secrets and full disk encryption](./secrets.md) - -[Use without flakes](./use-without-flakes.md) - -[Terraform](./terraform.md) - -[Nix-channels / `NIX_PATH`](./nix-path.md) - -[IPv6-only targets](./ipv6.md) diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/custom-kexec.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/custom-kexec.md deleted file mode 100644 index 5935a5f3..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/howtos/custom-kexec.md +++ /dev/null @@ -1,40 +0,0 @@ -# Using your own kexec image - -By default, `nixos-anywhere` downloads the kexec image from the -[NixOS images repository](https://github.com/nix-community/nixos-images#kexec-tarballs). - -However, you can provide your own `kexec` image file if you need to use a -different one. This is particularly useful for architectures other than `x86_64` -and `aarch64`, since they don't have a pre-build image. - -To do this, use the `--kexec` command line switch followed by the path to your -image file. The image will be uploaded prior to execution. - -Here's an example command that demonstrates how to use a custom kexec image with -`nixos-anywhere`: - -``` -nix run github:nix-community/nixos-anywhere -- \ - --kexec "$(nix build --print-out-paths github:nix-community/nixos-images#packages.aarch64-linux.kexec-installer-nixos-unstable-noninteractive)/nixos-kexec-installer-noninteractive-aarch64-linux.tar.gz" \ - --flake 'github:your-user/your-repo#your-system' \ - root@yourip -``` - -Make sure to replace `github:your-user/your-repo#your-system` with the -appropriate Flake URL representing your NixOS configuration. - -The example above assumes that your local machine can build for aarch64 in one -of the following ways: - -- Natively - -- Through a remote builder - -- By emulating the architecture with qemu using the following NixOS - configuration: - -```nix -{ - boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; -} -``` diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/disko-modes.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/disko-modes.md deleted file mode 100644 index 501f93f1..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/howtos/disko-modes.md +++ /dev/null @@ -1,19 +0,0 @@ -# Repair installations without wiping data - -By default, nixos-anywhere will reformat all configured disks before running the -installation. However it is also possible to mount the filesystems of an -existing installation and run `nixos-install`. This is useful to recover from a -misconfigured NixOS installation by first booting into a NixOS installer or -recovery system. - -To only mount existing filesystems, add `--disko-mode mount` to -`nixos-anywhere`: - -``` -nix run github:nix-community/nixos-anywhere -- --disko-mode mount --flake # --target-host root@ -``` - -1. This will first boot into a nixos-installer -2. Mounts disks with disko -3. Runs nixos-install based on the provided flake -4. Reboots the machine. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/extra-files.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/extra-files.md deleted file mode 100644 index ca067d4c..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/howtos/extra-files.md +++ /dev/null @@ -1,114 +0,0 @@ -# Copying files to the new installation - -The `--extra-files ` option allows copying files to the target host after -installation. - -The contents of the `` is recursively copied and overwrites the targets -root (/). The contents _must_ be in a structure and permissioned as it should be -on the target. - -In this way, there is no need to repeatedly pass arguments (eg: a fictional -argument: `--copy `) to `nixos-anywhere` to complete the intended -outcome. - -The path and directory structure passed to `--extra-files` should be prepared -beforehand. - -This allows a simple programmatic invocation of `nixos-anywhere` for multiple -hosts. - -## Simple Example - -You want `/etc/ssh/ssh_host_*` and `/persist` from the local system on the -target. The `` contents will look like this: - -```console -$ cd /tmp -$ root=$(mktemp -d) -$ sudo cp --verbose --archive --parents /etc/ssh/ssh_host_* ${root} -$ cp --verbose --archive --link /persist ${root} -``` - -The directory structure would look like this: - -```console -drwx------ myuser1 users 20 tmp.d6nx5QUwPN -drwxr-xr-x root root 6 ├── etc -drwx------ myuser1 users 160 │ └── ssh -.rw------- root root 399 │ ├── ssh_host_ed25519_key -.rw-r--r-- root root 91 │ ├── ssh_host_ed25519_key.pub -drwxr-xr-x myuser1 users 22 └── persist -drwxr-xr-x myuser1 users 14 ├── all -drwxr-xr-x myuser1 users 22 │ ├── my -.rw-r--r-- myuser1 users 6 │ │ ├── test3 -drwxr-xr-x myuser1 users 10 │ │ └── things -.rw-r--r-- myuser1 users 6 │ │ └── test4 -.rw-r--r-- myuser1 users 6 │ └── test2 -drwxr-xr-x myuser1 users 0 ├── blah -.rw-r--r-- myuser1 users 6 └── test -``` - -**NOTE**: Permissions will be copied, but ownership on the target will be root. - -Then pass $root like: - -> nixos-anywhere --flake ".#" --extra-files $root --target-host root@newhost - -## Programmatic Example - -```sh -for host in host1 host2 host3; do - root="target/${host}" - install -d -m755 ${root}/etc/ssh - ssh-keygen -A -C root@${host} -f ${root} - nixos-anywhere --extra-files "${root}" --flake ".#${host}" --target-host "root@${host}" -done -``` - -## Considerations - -### Ownership - -The new system may have differing UNIX user and group id's for users created -during installation. - -When the files are extracted on the remote the copied data will be owned by -root. - -If you wish to change the ownership after the files are copied onto the system, -you can use the `--chown` option. - -For example, if you did `--chown /home/myuser/.ssh 1000:100`, this would equate -to running `chown -R /home/myuser/.ssh 1000:100` where the uid is 1000 and the -gid is 100. **Only do this when you can _guarantee_ what the uid and gid will -be.** - -### Symbolic Links - -Do not create symbolic links to reference data to copy. - -GNU `tar` is used to do the copy over ssh. It is an archival tool used to -re/store directory structures as is. Thus `tar` copies symbolic links created -with `ln -s` by default. It does not follow them to copy the underlying file. - -### Hard links - -**NOTE**: hard links can only be created on the same filesystem. - -If you have larger persistent data to copy to the target. GNU `tar` will copy -data referenced by hard links created with `ln`. A hard link does not create -another copy the data. - -To copy a directory tree to the new target you can use the `cp` command with the -`--link` option which creates hard links. - -#### Example - -```sh -cd /tmp -root=$(mktemp -d) -cp --verbose --archive --link --parents /persist/home/myuser ${root} -``` - -`--parents` will create the directory structure of the source at the -destination. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/ipv6.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/ipv6.md deleted file mode 100644 index 64eb7a6a..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/howtos/ipv6.md +++ /dev/null @@ -1,23 +0,0 @@ -# NixOS-anywhere on IPv6-only targets - -As GitHub engineers still haven't enabled the IPv6 switch, the kexec image -hosted on GitHub, cannot be used unfortunately on IPv6-only hosts. However it is -possible to use an IPv6 proxy for GitHub content like that: - -``` -nixos-anywhere \ - --kexec https://gh-v6.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz \ -... -``` - -This proxy is hosted by [numtide](https://numtide.com/). It also works for IPv4. - -Alternatively it is also possible to reference a local file: - -``` -nixos-anywhere \ - --kexec ./nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz \ -... -``` - -This tarball will be then uploaded via sftp to the target. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/limited-ram.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/limited-ram.md deleted file mode 100644 index 0cbac65e..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/howtos/limited-ram.md +++ /dev/null @@ -1,29 +0,0 @@ -# Kexec on Systems with Limited RAM - -When working with nixos-anywhere on systems with limited RAM (around 1GB), you -can use the `--no-disko-deps` option to reduce memory usage during installation. - -## How it works - -The `--no-disko-deps` option uploads only the disko partitioning script without -including its dependencies. This significantly reduces memory usage because: - -1. The installer normally stores all dependencies in memory -2. Partitioning tools can be quite large when bundled with their dependencies - -## Usage example - -```bash -nix run github:nix-community/nixos-anywhere -- --no-disko-deps --flake # --target-host root@ -``` - -## Trade-off - -While this approach saves memory, it means the partitioning tools will be -whatever versions are available on the target system, rather than the specific -versions defined in your NixOS configuration. This could potentially lead to -version inconsistencies between the partitioning tools and the NixOS system -being installed. - -This trade-off is usually acceptable for memory-constrained environments where -installation would otherwise fail due to insufficient RAM. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/nix-path.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/nix-path.md deleted file mode 100644 index 1505af93..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/howtos/nix-path.md +++ /dev/null @@ -1,57 +0,0 @@ -# Nix-channels / `NIX_PATH` - -nixos-anywhere does not install channels onto the new system by default to save -time and disk space. This for example results in errors like: - -``` -(stack trace truncated; use '--show-trace' to show the full trace) - -error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I) - -at «none»:0: (source not available) -``` - -when using tools like nix-shell/nix-env that rely on `NIX_PATH` being set. - -# Solution 1: Set the `NIX_PATH` via nixos configuration (recommended) - -Instead of stateful channels, one can also populate the `NIX_PATH` using nixos -configuration instead: - -```nix -{ - inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - # ... other inputs - - outputs = inputs@{ nixpkgs, ... }: - { - nixosConfigurations.yoursystem = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; # adapt to your actual system - modules = [ - # This line will populate NIX_PATH - { nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ]; } - # ... other modules and your configuration.nix - ]; - }; - }; -} -``` - -Advantage: This solution will be automatically kept up-to-date every time the -flake is updated. - -In your shell you will see something in your `$NIX_PATH`: - -```shellSession -$ echo $NIX_PATH -/root/.nix-defexpr/channels:nixpkgs=/nix/store/8b61j28rpy11dg8hanbs2x710d8w3v0d-source -``` - -# Solution 2: Manually add the channel - -On the installed machine, run: - -```shellSession -$ nix-channel --add https://nixos.org/channels/nixos-unstable nixos -$ nix-channel --update -``` diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/no-os.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/no-os.md deleted file mode 100644 index 1c07cb0a..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/howtos/no-os.md +++ /dev/null @@ -1,71 +0,0 @@ -# Installing on a machine with no operating system - -If your machine doesn't currently have an operating system installed, you can -still run `nixos-anywhere` remotely to automate the install. To do this, you -would first need to boot the target machine from the standard NixOS installer. -You can either boot from a USB or use `netboot`. - -The -[NixOS installation guide](https://nixos.org/manual/nixos/stable/index.html#sec-booting-from-usb) -has detailed instructions on how to boot the installer. - -When you run `nixos-anywhere`, it will determine whether a NixOS installer is -present by checking whether the `/etc/os-release` file contains the identifier -`VARIANT_ID=installer`. This identifier is available on releases NixOS 23.05 or -later. - -If an installer is detected, `nixos-anywhere` will not attempt to `kexec` into -its own image. This is particularly useful for targets that don't have enough -RAM for `kexec` or don't support `kexec`. - -NixOS starts an SSH server on the installer by default, but you need to set a -password in order to access it. To set a password for the `nixos` user, run the -following command in a terminal on the NixOS machine: - -``` -passwd -``` - -If you don't know the IP address of the installer on your network, you can find -it by running the following command: - -``` -$ ip addr -1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 - link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 - inet 127.0.0.1/8 scope host lo - valid_lft forever preferred_lft forever - inet6 ::1/128 scope host - valid_lft forever preferred_lft forever -2: eth0: mtu 1500 qdisc fq_codel state UP group default qlen 1000 - link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff - altname enp0s3 - altname ens3 - inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0 - valid_lft 86385sec preferred_lft 75585sec - inet6 fec0::5054:ff:fe12:3456/64 scope site dynamic mngtmpaddr noprefixroute - valid_lft 86385sec preferred_lft 14385sec - inet6 fe80::5054:ff:fe12:3456/64 scope link - valid_lft forever preferred_lft forever -``` - -This will display the IP addresses assigned to your network interface(s), -including the IP address of the installer. In the example output below, the -installer's IP addresses are `10.0.2.15`, `fec0::5054:ff:fe12:3456`, and -`fe80::5054:ff:fe12:3456%eth0`: - -To test if you can connect and your password works, you can use the following -SSH command (replace the IP address with your own): - -``` -ssh -v nixos@fec0::5054:ff:fe12:3456 -``` - -You can then use the IP address to run `nixos-anywhere` like this: - -``` -nix run github:nix-community/nixos-anywhere -- --flake '.#myconfig' --target-host nixos@fec0::5054:ff:fe12:3456 -``` - -This example assumes a flake in the current directory containing a configuration -named `myconfig`. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/secrets.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/secrets.md deleted file mode 100644 index 8d95ee78..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/howtos/secrets.md +++ /dev/null @@ -1,76 +0,0 @@ -# Secrets and full disk encryption - -The `nixos-anywhere` utility offers the capability to install secrets onto a -target machine. This feature is particularly beneficial when you want to -bootstrap secrets management tools such as -[sops-nix](https://github.com/Mic92/sops-nix) or -[agenix](https://github.com/ryantm/agenix), which rely on machine-specific -secrets to decrypt other uploaded secrets. - -## Example: Decrypting an OpenSSH Host Key with pass - -In this example, we demonstrate how to use a script to decrypt an OpenSSH host -key from the `pass` password manager and subsequently pass it to -`nixos-anywhere` during the installation process: - -```bash -#!/usr/bin/env bash - -# Create a temporary directory -temp=$(mktemp -d) - -# Function to cleanup temporary directory on exit -cleanup() { - rm -rf "$temp" -} -trap cleanup EXIT - -# Create the directory where sshd expects to find the host keys -install -d -m755 "$temp/etc/ssh" - -# Decrypt your private key from the password store and copy it to the temporary directory -pass ssh_host_ed25519_key > "$temp/etc/ssh/ssh_host_ed25519_key" - -# Set the correct permissions so sshd will accept the key -chmod 600 "$temp/etc/ssh/ssh_host_ed25519_key" - -# Install NixOS to the host system with our secrets -nixos-anywhere --extra-files "$temp" --flake '.#your-host' --target-host root@yourip -``` - -## Example: Uploading Disk Encryption Secrets - -In a similar vein, `nixos-anywhere` can upload disk encryption secrets, which -are necessary during formatting with disko. Here's an example that demonstrates -how to provide your disk encryption password as a file or via the `pass` utility -to `nixos-anywhere`: - -```bash -# Write your disk encryption password to a file -echo "my-super-safe-password" > /tmp/disk-1.key - -# Call nixos-anywhere with disk encryption keys -nixos-anywhere \ - --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ - --disk-encryption-keys /tmp/disk-2.key <(pass my-disk-encryption-password) \ - --flake '.#your-host' \ - root@yourip -``` - -In the above example, replace `"my-super-safe-password"` with your actual -encryption password, and `my-disk-encryption-password` with the relevant entry -in your pass password store. Also, ensure to replace `'.#your-host'` and -`root@yourip` with your actual flake and IP address, respectively. - -## Example: Using existing SSH host keys - -If the system contains existing trusted `/etc/ssh/ssh_host_*` SSH host keys and -certificates, `nixos-anywhere` can copy them in case they are necessary during -installation and system activation. - -``` -nixos-anywhere --copy-host-keys --flake '.#your-host' root@yourip -``` - -This would copy `/etc/ssh/ssh_host_*` to `/mnt` after kexec but before -installation, ignoring files that already exist in destination. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/terraform.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/terraform.md deleted file mode 100644 index 87974932..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/howtos/terraform.md +++ /dev/null @@ -1,23 +0,0 @@ -# Terraform - -The nixos-anywhere terraform modules allow you to use Terraform for installing -and updating NixOS. It simplifies the deployment process by integrating -nixos-anywhere functionality. - -Our terraform module requires the -[null](https://registry.terraform.io/providers/hashicorp/null/latest) and -[external](https://registry.terraform.io/providers/hashicorp/external/latest) -provider. - -You can get these by from nixpkgs like this: - -```nix -nix-shell -p '(pkgs.terraform.withPlugins (p: [ p.null p.external ]))' -``` - -You can add this expression the `packages` list in your devshell in flake.nix or -in shell.nix. - -Checkout out the -[module reference](https://github.com/nix-community/nixos-anywhere/tree/main/terraform) -for examples and module parameter on how to use the modules. diff --git a/launch/.terraform/modules/peertube.deploy/docs/howtos/use-without-flakes.md b/launch/.terraform/modules/peertube.deploy/docs/howtos/use-without-flakes.md deleted file mode 100644 index 33419a9e..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/howtos/use-without-flakes.md +++ /dev/null @@ -1,82 +0,0 @@ -# Use without flakes - -First, -[import the disko NixOS module](https://github.com/nix-community/disko/blob/master/docs/HowTo.md#installing-nixos-module) -in your NixOS configuration and define disko devices as described in the -[examples](https://github.com/nix-community/disko/tree/master/example). - -Let's assume that your NixOS configuration lives in `configuration.nix` and your -target machine is called `machine`: - -## 1. Download your favourite disk layout: - -See https://github.com/nix-community/disko-templates/ for more examples: - -The example below will work with both UEFI and BIOS-based systems. - -```bash -curl https://raw.githubusercontent.com/nix-community/disko-templates/main/single-disk-ext4/disko-config.nix > ./disko-config.nix -``` - -## 2. Get a hardware-configuration.nix from on the target machine - -- **Option 1**: If NixOS is not installed, boot into an installer without first - installing NixOS. -- **Option 2**: Use the kexec tarball method, as described - [here](https://github.com/nix-community/nixos-images#kexec-tarballs). - -- **Generate Configuration**: Run the following command on the target machine: - - ```bash - nixos-generate-config --no-filesystems --dir /tmp/config - ``` - -This creates the necessary configuration files under `/tmp/config/`. Copy -`/tmp/config/nixos/hardware-configuration.nix` to your local machine into the -same directory as `disko-config.nix`. - -## 3. Set NixOS version to use - -```nix -# default.nix -let - # replace nixos-24.11 with your preferred nixos version or revision from here: https://status.nixos.org/ - nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-24.11.tar.gz"; -in -import (nixpkgs + "/nixos/lib/eval-config.nix") { - modules = [ ./configuration.nix ]; -} -``` - -## 4. Write a NixOS configuration - -```nix -# configuration.nix -{ - imports = [ - "${fetchTarball "https://github.com/nix-community/disko/tarball/master"}/module.nix" - ./disko-config.nix - ./hardware-configuration.nix - ]; - # Replace this with the system of the installation target you want to install!!! - disko.devices.disk.main.device = "/dev/sda"; - - # Set this to the NixOS version that you have set in the previous step. - # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion . - system.stateVersion = "24.11"; -} -``` - -## 5. Build and deploy with nixos-anywhere - -Your current directory now should contain the following files from the previous -step: - -- `configuration.nix`, `default.nix`, `disko-config.nix` and - `hardware-configuration.nix` - -Run `nixos-anywhere` as follows: - -```bash -nixos-anywhere --store-paths $(nix-build -A config.system.build.formatScript -A config.system.build.toplevel --no-out-link) root@machine -``` diff --git a/launch/.terraform/modules/peertube.deploy/docs/logo.png b/launch/.terraform/modules/peertube.deploy/docs/logo.png deleted file mode 100644 index 434ad443ac1a065b53f74353187f7baaa45bcf29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29405 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/launch/.terraform/modules/peertube.deploy/docs/quickstart.md b/launch/.terraform/modules/peertube.deploy/docs/quickstart.md deleted file mode 100644 index 5eb1a10e..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/quickstart.md +++ /dev/null @@ -1,334 +0,0 @@ -# Quickstart Guide: nixos-anywhere - -**_Install NixOS everywhere via ssh_** - - - -[Documentation Index](./INDEX.md) - -## Introduction - -This guide documents a simple installation of NixOS using **nixos-anywhere** on -a target machine running x86_64 Linux with -[kexec](https://man7.org/linux/man-pages/man8/kexec.8.html) support. The example -used in this guide installs NixOS on a Hetzner cloud machine. The configuration -may be different for some other instances. We will be including further examples -in the [How To Guide](./howtos/INDEX.md) as and when they are available. - -You will need: - -- A [flake](https://wiki.nixos.org/wiki/Flakes) that controls the actions to be - performed -- A disk configuration containing details of the file system that will be - created on the new server. -- A target machine that is reachable via SSH, either using keys or a password, - and the privilege to either log in directly as root or a user with - password-less sudo. - -**nixos-anywhere** doesn’t need to be installed. You can run it directly from -[the Github repository.](https://github.com/nix-community/nixos-anywhere) - -Details of the flake, the disk configuration and the CLI command are discussed -below. - -## Steps required to run nixos-anywhere - -### 1. Enable Flakes - -Check if your nix has flakes enabled by running `nix flake`. It will tell you if -it's not. To enable flakes, refer to the -[NixOS Wiki](https://wiki.nixos.org/wiki/Flakes#enable-flakes). - -### 2. Initialize a Flake - -The easiest way to start is to copy our -[example flake.nix](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix) -into a new directory. This example is tailored for a virtual machine setup -similar to one on [Hetzner Cloud](https://www.hetzner.com/cloud), so you might -need to adapt it for your setup. - -If you already have a flake, you can use it by adding -[disko configuration](https://github.com/nix-community/disko?tab=readme-ov-file#how-to-use-disko) -to it. - -### 3. Configure your SSH key - -If you cloned -[our nixos-anywhere-example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/configuration.nix) -you will also replace the SSH key like this: In your configuration, locate the -line that reads: - -```bash -# change this to your ssh key - "CHANGE" -``` - -Replace the text `CHANGE` with your own SSH key. This is crucial, as you will -not be able to log into the target machine post-installation without it. If you -have a .pem file you can run - -```bash -ssh-keygen -y -f /path/to/your/key.pem -``` - -then paste the result in between the quotes like "ssh-rsa AAA..." - -### 4. Configure Storage - -In the same directory, create a file called `disk-config.nix`. This file will -define the disk layout for the -[disko](https://github.com/nix-community/disko/blob/master/docs/INDEX.md) tool, -which is used by nixos-anywhere to partition, format, and mount the disks. - -For a basic installation, you can copy the contents from the example provided -[here](https://github.com/nix-community/nixos-anywhere-examples/blob/main/disk-config.nix). -This configuration sets up a standard GPT (GUID Partition Table) that is -compatible with both EFI and BIOS systems and mounts the disk as `/dev/sda`. You -may need to adjust `/dev/sda` to match the correct disk on your machine. To -identify the disk, run the `lsblk` command and replace `sda` with the actual -disk name. - -For example, on this machine, we would select `/dev/nvme0n1` as the disk: - -``` -NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS -nvme0n1 259:0 0 1.8T 0 disk -``` - -If this setup does not match your requirements, you can choose an example that -better suits your disk layout from the -[disko examples](https://github.com/nix-community/disko/tree/master/example). -For more detailed information, refer to the -[disko documentation](https://github.com/nix-community/disko). - -### 5. Lock your Flake - -``` -nix flake lock -``` - -This will download your flake dependencies and make a `flake.lock` file that -describes how to reproducibly build your system. - -Optionally, you can commit these files to a repo such as Github, or you can -simply reference your local directory when you run **nixos-anywhere**. This -example uses a local directory on the source machine. - -### 6. Connectivity to the Target Machine - -**nixos-anywhere** will create a temporary SSH key to use for the installation. -If your SSH key is not found, you will be asked for your password. If you are -using a non-root user, you must have access to sudo without a password. To avoid -SSH password prompts, set the `SSHPASS` environment variable to your password -and add `--env-password` to the `nixos-anywhere` command. If providing a -specific SSH key through `-i` (identity_file), this key will then be used for -the installation and no temporary SSH key will be created. - -### 7. (Optional) Test your NixOS and Disko configuration - -Skip this step and continue with Step 8, if you don't have a hardware -configuration (hardware-configuration.nix or facter.json) generated yet or make -sure you don't import non-existing hardware-configuration.nix or facter.json -during running the vm test. - -The following command will automatically test your nixos configuration and run -disko inside a virtual machine, where - -- `` is the path to the directory or repository - containing `flake.nix` and `disk-config.nix` - -- `` must match the name that immediately follows the text - `nixosConfigurations.` in the flake, as indicated by the comment in the - [example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix). - -``` -nix run github:nix-community/nixos-anywhere -- --flake # --vm-test -``` - -### 8. Prepare Hardware Configuration - -If you're not using a virtual machine, it's recommended to allow -`nixos-anywhere` to generate a hardware configuration during installation. This -ensures that essential drivers, such as those required for disk detection, are -properly configured. - -To enable `nixos-anywhere` to integrate its generated configuration into your -NixOS setup, you need to include an import for the hardware configuration -beforehand. - -Here’s an example: - -```diff - nixosConfigurations.generic = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [ - disko.nixosModules.disko - ./configuration.nix -+ ./hardware-configuration.nix - ]; - }; -``` - -When running `nixos-anywhere`, this file is automatically generated by including -the following flags in your command: -`--generate-hardware-config nixos-generate-config ./hardware-configuration.nix`. -The second flag, `./hardware-configuration.nix`, specifies where -`nixos-generate-config` will store the configuration. Adjust this path to -reflect the location where you want the `hardware-configuration.nix` for this -machine to be saved. - -#### 8.1 nixos-facter - -As an alternative to `nixos-generate-config`, you can use the experimental -[nixos-facter](https://github.com/numtide/nixos-facter) command, which offers -more comprehensive hardware reports and advanced configuration options. - -To use `nixos-facter`, add the following to your flake inputs: - -```diff - { -+ inputs.nixos-facter-modules.url = "github:numtide/nixos-facter-modules"; - } -``` - -Next, import the module into your configuration and specify `facter.json` as the -path where the hardware report will be saved: - -```diff - nixosConfigurations.generic-nixos-facter = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [ - disko.nixosModules.disko - ./configuration.nix -+ nixos-facter-modules.nixosModules.facter -+ { config.facter.reportPath = ./facter.json } - ]; - }; -``` - -To generate the configuration for `nixos-facter` with `nixos-anywhere`, use the -following flags: `--generate-hardware-config nixos-facter ./facter.json`. The -second flag, `./facter.json`, specifies where `nixos-generate-config` will store -the hardware report. Adjust this path to suit the location where you want the -`facter.json` to be saved. - -### 9. Run it - -You can now run **nixos-anywhere** from the command line as shown below, where: - -- `` is the path to the directory or repository - containing `flake.nix` and `disk-config.nix` - -- `` must match the name that immediately follows the text - `nixosConfigurations.` in the flake, as indicated by the comment in the - [example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix). - -- `` is the IP address of the target machine. - -``` -nix run github:nix-community/nixos-anywhere -- --flake # --target-host root@ -``` - -The command would look  like this if you had created your files in a directory -named `/home/mydir/test` and the IP address of your target machine is -`37.27.18.135`: - -``` -nix run github:nix-community/nixos-anywhere -- --flake /home/mydir/test#hetzner-cloud --target-host root@37.27.18.135 -``` - -If you also need to generate hardware configuration amend flags for -nixos-generate-config: - -``` -nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-generate-config ./hardware-configuration.nix --flake # --target-host root@ -``` - -Or these flags if you are using nixos-facter instead: - -``` -nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-facter ./facter.json --flake # --target-host root@ -``` - -Adjust the location of `./hardware-configuration.nix` and `./facter.json` -accordingly. - -**nixos-anywhere** will then run, showing various output messages at each stage. -It may take some time to complete, depending on Internet speeds. It should -finish by showing the messages below before returning to the command prompt. - -``` -Installation finished. No error reported. -Warning: Permanently added '' (ED25519) to the list of known hosts -``` - -When this happens, the target server will have been overwritten with a new -installation of NixOS. Note that the server's public SSH key will have changed. - -If you have previously accessed this server using SSH, you may see the following -message the next time you try to log in to the target. - -``` -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! -Someone could be eavesdropping on you right now (man-in-the-middle attack)! -It is also possible that a host key has just been changed. -The fingerprint for the ED25519 key sent by the remote host is -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. -Please contact your system administrator. -Add correct host key in ~/.ssh/known_hosts to get rid of this message. -Offending ECDSA key in ~/.ssh/known_hosts:6 - remove with: - ssh-keygen -f ~/.ssh/known_hosts" -R "" -Host key for has changed and you have requested strict checking. -Host key verification failed. -``` - -This is because the `known_hosts` file in the `.ssh` directory now contains a -mismatch, since the server has been overwritten. To solve this, use a text -editor to remove the old entry from the `known_hosts` file (or use the command -`ssh-keygen -R `). The next connection attempt will then treat this -as a new server. - -The error message line `Offending ECDSA key in ~/.ssh/known_hosts:6` gives the -line number that needs to be removed from the `known_hosts` file (line 6 in this -example). - -# Finished! - -**nixos-anywhere**'s job is now done, as it is a tool to install NixOS onto the -target machine. - -Any future changes to the configuration should be made to your flake. You would -reference this flake when using the NixOS `nixos-rebuild` command or a separate -3rd party deployment tool of your choice i.e. -[deploy-rs](https://github.com/serokell/deploy-rs), -[colmena](https://github.com/zhaofengli/colmena), -[nixinate](https://github.com/MatthewCroughan/nixinate), -[clan](https://clan.lol/) (author's choice). - -To update on the machine locally (replace `` with your flake -i.e. `.#` if your flake is in the current directory): - -``` -nixos-rebuild switch --flake -``` - -To update remotely you will need to have configured an -[ssh server](https://search.nixos.org/options?show=services.sshd.enable) and -your ssh key for the -[root user](https://search.nixos.org/options?show=users.users.%3Cname%3E.openssh.authorizedKeys.keys): - -``` -nixos-rebuild switch --flake --target-host "root@" -``` - -See the Nix documentation for use of the flake -[URL-like syntax](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake#url-like-syntax). - -For more information on different use cases of **nixos-anywhere** please refer -to the [How to Guide](./howtos/INDEX.md), and for more technical information and -explanation of known error messages, refer to the -[Reference Manual](./reference.md). diff --git a/launch/.terraform/modules/peertube.deploy/docs/reference.md b/launch/.terraform/modules/peertube.deploy/docs/reference.md deleted file mode 100644 index 83916572..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/reference.md +++ /dev/null @@ -1,137 +0,0 @@ -# Reference Manual: nixos-anywhere - -**_Install NixOS everywhere via ssh_** - - - -[Documentation Index](./INDEX.md) - -TODO: Populate this guide properly - -## Contents - -[Command Line Usage](#command-line-usage) - -[Explanation of known error messages](#explanation-of-known-error-messages) - -## Command Line Usage - - - -``` -Usage: nixos-anywhere [options] [] - -Options: - -* -f, --flake - set the flake to install the system from. i.e. - nixos-anywhere --flake .#mymachine - Also supports variants: - nixos-anywhere --flake .#nixosConfigurations.mymachine.config.virtualisation.vmVariant -* --target-host - set the SSH target host to deploy onto. -* -i - selects which SSH private key file to use. -* -p, --ssh-port - set the ssh port to connect with -* --ssh-option - set an ssh option -* -L, --print-build-logs - print full build logs -* --env-password - set a password used by ssh-copy-id, the password should be set by - the environment variable SSHPASS -* -s, --store-paths - set the store paths to the disko-script and nixos-system directly - if this is given, flake is not needed -* --kexec - use another kexec tarball to bootstrap NixOS -* --kexec-extra-flags - extra flags to add into the call to kexec, e.g. "--no-sync" -* --ssh-store-setting - ssh store settings appended to the store URI, e.g. "compress true". needs to be URI encoded. -* --post-kexec-ssh-port - after kexec is executed, use a custom ssh port to connect. Defaults to 22 -* --copy-host-keys - copy over existing /etc/ssh/ssh_host_* host keys to the installation -* --extra-files - contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten - Copied files will be owned by root unless specified by --chown option. See documentation for details. -* --chown - change ownership of recursively. Recommended to use uid:gid as opposed to username:groupname for ownership. - Option can be specified more than once. -* --disk-encryption-keys - copy the contents of the file or pipe in local_path to remote_path in the installer environment, - after kexec but before installation. Can be repeated. -* --no-substitute-on-destination - disable passing --substitute-on-destination to nix-copy -* --debug - enable debug output -* --show-trace - show nix build traces -* --option - nix option to pass to every nix related command -* --from - URL of the source Nix store to copy the nixos and disko closure from -* --build-on-remote - build the closure on the remote machine instead of locally and copy-closuring it -* --vm-test - build the system and test the disk configuration inside a VM without installing it to the target. -* --generate-hardware-config nixos-facter|nixos-generate-config - generate a hardware-configuration.nix file using the specified backend and write it to the specified path. - The backend can be either 'nixos-facter' or 'nixos-generate-config'. -* --phases - comma separated list of phases to run. Default is: kexec,disko,install,reboot - kexec: kexec into the nixos installer - disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode - install: install the system - reboot: unmount the filesystems, export any ZFS pools and reboot the machine -* --disko-mode disko|mount|format - set the disko mode to format, mount or destroy. Default is disko. - disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode -* --no-disko-deps - This will only upload the disko script and not the partitioning tools dependencies. - Installers usually have dependencies available. - Use this option if your target machine has not enough RAM to store the dependencies in memory. -* --build-on auto|remote|local - sets the build on settings to auto, remote or local. Default is auto. - auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build - local: will build on the local host - remote: will build on the remote host -``` - -## Explanation of known error messages - -TODO: Add additional error messages and meanings. Fill in missing explanations - -This section lists known error messages and their explanations. Some -explanations may refer to the following CLI syntax: - -`nix run github:nix-community/nixos-anywhere -- --flake # root@` - -This list is not comprehensive. It's possible you may encounter errors that -originate from the underlying operating system. These should be documented in -the relevant operating system manual. - -| Id | Message | Explanation | -| -- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| 1 | Failure unpacking initrd | You don't have enough RAM to hold `kexec` | -| 2 | Flake  does not provide attribute | The configuration name you specified in your flake URI is not defined as a NixOS configuration in your flake eg if your URI was mydir#myconfig, then myconfig should be included in the flake as `nixosConfigurations.myconfig` | -| 3 | Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri. | As for error #2 | -| | For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri | | -| 4 | Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already | TODO: Explain | -| 5 | ssh-host must be set |  has not been supplied | -| 6 | and must be existing store-paths | This occurs if the -s switch has been used to specify the disko script and store path correctly, and the scripts cannot be found at the given URI | -| 7 | flake must be set | This occurs if both the -flake option (use a flake) and the -s option (specify paths directly) have been omitted. Either one or the other must be specified. | -| 8 | no tar command found, but required to unpack kexec tarball | The destination machine does not have a `tar` command available. This is needed to unpack the `kexec`. | -| 9 | no setsid command found, but required to run the kexec script under a new session | The destination machine does not have the `setsid` command available | -| 10 | This script requires Linux as the operating system, but got | The destination machine is not running Linux | -| 11 | The default kexec image only support x86_64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information. | By default, `nixos-anywhere` uses its own `kexec` image, which will only run on x86_64 CPUs. For other CPU types, you can use your own `kexec` image instead. Refer to the [How To Guide](./howtos#using-your-own-kexec-image) for instructions. | -| 12 | Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri. | This is a `disko` error. As for Error #2 | -| | For example, to use the output diskoConfigurations.foo from the flake.nix, append \"#foo\" to the flake-uri. | | -| 13 | mode must be either create, mount or zap_create_mount | This is a `disko` error. The `disko` switches have not been used correctly. This could happen if you supplied your own `disko` script using the -s option | -| 14 | disko config must be an existing file or flake must be set | This is a `disko` error. This will happen if the `disko.devices` entry in your flake doesn't match the name of a file in the same location as your flake. | -| | | | -| | | | -| | | | -| | | | diff --git a/launch/.terraform/modules/peertube.deploy/docs/requirements.md b/launch/.terraform/modules/peertube.deploy/docs/requirements.md deleted file mode 100644 index 67b14f4d..00000000 --- a/launch/.terraform/modules/peertube.deploy/docs/requirements.md +++ /dev/null @@ -1,39 +0,0 @@ -# System Requirements: nixos-anywhere - -**_Install NixOS everywhere via ssh_** - - - -[Documentation Index](./INDEX.md) - -## Requirements - -### Source Machine - -1. **Supported Systems:** - - Linux or macOS computers with Nix installed. - - NixOS - - Windows systems using WSL2. - -2. **Nix Installation:** If Nix is not yet installed on your system, refer to - the [nix installation page](https://nixos.org/download#download-nix). - -### Destination Machine - -The machine must be reachable over the public internet or local network. -Nixos-anywhere does not support wifi networks. If a VPN is needed, define a -custom installer via the --kexec flag which connects to your VPN. - -1. **Direct Boot Option:** - - Must be already running a NixOS installer. - -2. **Alternative Boot Options:** If not booting directly from a NixOS installer - image: - - **Architecture & Support:** Must be operating on: - - x86-64 or aarch64 Linux systems with kexec support. Note: While most - x86-64 Linux systems support kexec, if you're using an architecture other - than those mentioned, you may need to specify a - [different kexec image](./howtos/INDEX.md#using-your-own-kexec-image) - manually. - - **Memory Requirements:** - - At least 1 GB of RAM (excluding swap space). diff --git a/launch/.terraform/modules/peertube.deploy/flake.lock b/launch/.terraform/modules/peertube.deploy/flake.lock deleted file mode 100644 index 5a7232ca..00000000 --- a/launch/.terraform/modules/peertube.deploy/flake.lock +++ /dev/null @@ -1,132 +0,0 @@ -{ - "nodes": { - "disko": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1741786315, - "narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=", - "owner": "nix-community", - "repo": "disko", - "rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de", - "type": "github" - }, - "original": { - "owner": "nix-community", - "ref": "master", - "repo": "disko", - "type": "github" - } - }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1741352980, - "narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "nixos-images": { - "inputs": { - "nixos-stable": [ - "nixos-stable" - ], - "nixos-unstable": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1741866599, - "narHash": "sha256-Re/T1Cjmiis0tdphj/Wjqt+c2RlMw/il7LBWzvwQPz0=", - "owner": "nix-community", - "repo": "nixos-images", - "rev": "63285ff93fc1daa2caac9f86e2302ae4edc5e84f", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixos-images", - "type": "github" - } - }, - "nixos-stable": { - "locked": { - "lastModified": 1741862977, - "narHash": "sha256-prZ0M8vE/ghRGGZcflvxCu40ObKaB+ikn74/xQoNrGQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "cdd2ef009676ac92b715ff26630164bb88fec4e0", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-24.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1742051767, - "narHash": "sha256-JpyjnalnIqJ7cvP8HzaoJN9/i2bDx83dToodHHjGuNg=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "ec886d10b507760c90ed01e2eac7f0679d0a47ae", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable-small", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "disko": "disko", - "flake-parts": "flake-parts", - "nixos-images": "nixos-images", - "nixos-stable": "nixos-stable", - "nixpkgs": "nixpkgs", - "treefmt-nix": "treefmt-nix" - } - }, - "treefmt-nix": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1739829690, - "narHash": "sha256-mL1szCeIsjh6Khn3nH2cYtwO5YXG6gBiTw1A30iGeDU=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "3d0579f5cc93436052d94b73925b48973a104204", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/launch/.terraform/modules/peertube.deploy/flake.nix b/launch/.terraform/modules/peertube.deploy/flake.nix deleted file mode 100644 index d60191cc..00000000 --- a/launch/.terraform/modules/peertube.deploy/flake.nix +++ /dev/null @@ -1,55 +0,0 @@ -{ - description = "A universal nixos installer, just needs ssh access to the target system"; - - inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small"; - flake-parts = { - url = "github:hercules-ci/flake-parts"; - inputs.nixpkgs-lib.follows = "nixpkgs"; - }; - - # used for testing - disko = { - url = "github:nix-community/disko/master"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - nixos-stable.url = "github:NixOS/nixpkgs/nixos-24.11"; - nixos-images.url = "github:nix-community/nixos-images"; - nixos-images.inputs.nixos-unstable.follows = "nixpkgs"; - nixos-images.inputs.nixos-stable.follows = "nixos-stable"; - - # used for development - treefmt-nix = { - url = "github:numtide/treefmt-nix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - }; - - outputs = - inputs: - inputs.flake-parts.lib.mkFlake { inherit inputs; } { - systems = [ - "x86_64-linux" - "x86_64-darwin" - "aarch64-linux" - "aarch64-darwin" - ]; - imports = [ - ./src/flake-module.nix - ./tests/flake-module.nix - ./docs/flake-module.nix - # allow to disable treefmt in downstream flakes - ] ++ inputs.nixpkgs.lib.optional (inputs.treefmt-nix ? flakeModule) ./treefmt/flake-module.nix; - - perSystem = - { self', lib, ... }: - { - checks = - let - packages = lib.mapAttrs' (n: lib.nameValuePair "package-${n}") self'.packages; - devShells = lib.mapAttrs' (n: lib.nameValuePair "devShell-${n}") self'.devShells; - in - packages // devShells; - }; - }; -} diff --git a/launch/.terraform/modules/peertube.deploy/scripts/create-release.sh b/launch/.terraform/modules/peertube.deploy/scripts/create-release.sh deleted file mode 100755 index 7f203035..00000000 --- a/launch/.terraform/modules/peertube.deploy/scripts/create-release.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env nix -#! nix shell nixpkgs#bash nixpkgs#gnused --command bash - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" -cd "$SCRIPT_DIR/.." - -version=${1:-} -if [[ -z $version ]]; then - echo "USAGE: $0 version" >&2 - exit 1 -fi - -if [[ "$(git symbolic-ref --short HEAD)" != "main" ]]; then - echo "must be on main branch" >&2 - exit 1 -fi - -# ensure we are up-to-date -uncommitted_changes=$(git diff --compact-summary) -if [[ -n $uncommitted_changes ]]; then - echo -e "There are uncommitted changes, exiting:\n${uncommitted_changes}" >&2 - exit 1 -fi -git pull git@github.com:nix-community/nixos-anywhere main -unpushed_commits=$(git log --format=oneline origin/main..main) -if [[ $unpushed_commits != "" ]]; then - echo -e "\nThere are unpushed changes, exiting:\n$unpushed_commits" >&2 - exit 1 -fi -sed -i -e "s!version = \".*\";!version = \"${version}\";!" src/default.nix -git add src/default.nix -nix-shell -p nix-fast-build --command "nix-fast-build --eval-workers 2" -git commit -m "bump version ${version}" -git tag "${version}" - -echo "now run 'git push --tags origin main'" diff --git a/launch/.terraform/modules/peertube.deploy/src/default.nix b/launch/.terraform/modules/peertube.deploy/src/default.nix deleted file mode 100644 index c1719320..00000000 --- a/launch/.terraform/modules/peertube.deploy/src/default.nix +++ /dev/null @@ -1,63 +0,0 @@ -{ - stdenv, - openssh, - gitMinimal, - nixVersions, - nix, - coreutils, - curl, - gnugrep, - gnutar, - gawk, - findutils, - gnused, - sshpass, - terraform-docs, - lib, - makeWrapper, - mkShellNoCC, -}: -let - runtimeDeps = [ - gitMinimal # for git flakes - # pinned because nix-copy-closure hangs if ControlPath provided for SSH: https://github.com/NixOS/nix/issues/8480 - (if lib.versionAtLeast nix.version "2.16" then nix else nixVersions.nix_2_16) - coreutils - curl # when uploading tarballs - gnugrep - gawk - findutils - gnused # needed by ssh-copy-id - sshpass # used to provide password for ssh-copy-id - gnutar # used to upload extra-files - ]; -in -stdenv.mkDerivation { - pname = "nixos-anywhere"; - version = "1.8.0"; - src = ./..; - nativeBuildInputs = [ makeWrapper ]; - installPhase = '' - install -D --target-directory=$out/libexec/nixos-anywhere/ -m 0755 src/*.sh - - # We prefer the system's openssh over our own, since it might come with features not present in ours: - # https://github.com/nix-community/nixos-anywhere/issues/62 - makeShellWrapper $out/libexec/nixos-anywhere/nixos-anywhere.sh $out/bin/nixos-anywhere \ - --prefix PATH : ${lib.makeBinPath runtimeDeps} --suffix PATH : ${lib.makeBinPath [ openssh ]} - ''; - - # Dependencies for our devshell - passthru.devShell = mkShellNoCC { - packages = runtimeDeps ++ [ - openssh - terraform-docs - ]; - }; - - meta = with lib; { - description = "Install nixos everywhere via ssh"; - homepage = "https://github.com/nix-community/nixos-anywhere"; - license = licenses.mit; - platforms = platforms.all; - }; -} diff --git a/launch/.terraform/modules/peertube.deploy/src/flake-module.nix b/launch/.terraform/modules/peertube.deploy/src/flake-module.nix deleted file mode 100644 index d131219d..00000000 --- a/launch/.terraform/modules/peertube.deploy/src/flake-module.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ - perSystem = - { config, pkgs, ... }: - { - packages = { - nixos-anywhere = pkgs.callPackage ./. { }; - default = config.packages.nixos-anywhere; - }; - devShells.default = config.packages.nixos-anywhere.devShell; - }; -} diff --git a/launch/.terraform/modules/peertube.deploy/src/get-facts.sh b/launch/.terraform/modules/peertube.deploy/src/get-facts.sh deleted file mode 100755 index 80434422..00000000 --- a/launch/.terraform/modules/peertube.deploy/src/get-facts.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -set -efu "${enableDebug:-}" -has() { - command -v "$1" >/dev/null && echo "y" || echo "n" -} -isNixos=$(if test -f /etc/os-release && grep -Eq 'ID(_LIKE)?="?nixos"?' /etc/os-release; then echo "y"; else echo "n"; fi) -cat </dev/null 2>/dev/null || ! ip -6 r g :: >/dev/null 2>/dev/null; then echo "n"; else echo "y"; fi) -hasTar=$(has tar) -hasCpio=$(has cpio) -hasSudo=$(has sudo) -hasDoas=$(has doas) -hasWget=$(has wget) -hasCurl=$(has curl) -hasSetsid=$(has setsid) -hasNixOSFacter=$(command -v nixos-facter >/dev/null && echo "y" || echo "n") -FACTS diff --git a/launch/.terraform/modules/peertube.deploy/src/nixos-anywhere.sh b/launch/.terraform/modules/peertube.deploy/src/nixos-anywhere.sh deleted file mode 100755 index c6cadb98..00000000 --- a/launch/.terraform/modules/peertube.deploy/src/nixos-anywhere.sh +++ /dev/null @@ -1,880 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -here=$(dirname "${BASH_SOURCE[0]}") -flake="" -flakeAttr="" -kexecUrl="" -kexecExtraFlags="" -sshStoreSettings="" -enableDebug="" -nixBuildFlags=() -diskoAttr="" -diskoScript="" -diskoMode="disko" -diskoDeps=y -nixosSystem="" -extraFiles="" -vmTest="n" -nixOptions=( - --extra-experimental-features 'nix-command flakes' - "--no-write-lock-file" -) -SSH_PRIVATE_KEY=${SSH_PRIVATE_KEY-} - -declare -A phases -phases[kexec]=1 -phases[disko]=1 -phases[install]=1 -phases[reboot]=1 - -hardwareConfigBackend=none -hardwareConfigPath= -sshPrivateKeyFile= -if [ -t 0 ]; then # stdin is a tty, we allow interactive input to ssh i.e. passwords - sshTtyParam="-t" -else - sshTtyParam="-T" -fi -sshConnection= -postKexecSshPort=22 -buildOnRemote=n -buildOn=auto -envPassword=n - -# Facts set by get-facts.sh -isOs= -isArch= -isKexec= -isInstaller= -isContainer= -hasIpv6Only= -hasTar= -hasCpio= -hasSudo= -hasDoas= -hasWget= -hasCurl= -hasSetsid= -hasNixOSFacter= - -sshKeyDir=$(mktemp -d) -trap 'rm -rf "$sshKeyDir"' EXIT -mkdir -p "$sshKeyDir" - -declare -A diskEncryptionKeys=() -declare -A extraFilesOwnership=() -declare -a nixCopyOptions=() -declare -a sshArgs=() - -showUsage() { - cat <] - -Options: - -* -f, --flake - set the flake to install the system from. i.e. - nixos-anywhere --flake .#mymachine - Also supports variants: - nixos-anywhere --flake .#nixosConfigurations.mymachine.config.virtualisation.vmVariant -* --target-host - set the SSH target host to deploy onto. -* -i - selects which SSH private key file to use. -* -p, --ssh-port - set the ssh port to connect with -* --ssh-option - set an ssh option -* -L, --print-build-logs - print full build logs -* --env-password - set a password used by ssh-copy-id, the password should be set by - the environment variable SSHPASS -* -s, --store-paths - set the store paths to the disko-script and nixos-system directly - if this is given, flake is not needed -* --kexec - use another kexec tarball to bootstrap NixOS -* --kexec-extra-flags - extra flags to add into the call to kexec, e.g. "--no-sync" -* --ssh-store-setting - ssh store settings appended to the store URI, e.g. "compress true". needs to be URI encoded. -* --post-kexec-ssh-port - after kexec is executed, use a custom ssh port to connect. Defaults to 22 -* --copy-host-keys - copy over existing /etc/ssh/ssh_host_* host keys to the installation -* --extra-files - contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten - Copied files will be owned by root unless specified by --chown option. See documentation for details. -* --chown - change ownership of recursively. Recommended to use uid:gid as opposed to username:groupname for ownership. - Option can be specified more than once. -* --disk-encryption-keys - copy the contents of the file or pipe in local_path to remote_path in the installer environment, - after kexec but before installation. Can be repeated. -* --no-substitute-on-destination - disable passing --substitute-on-destination to nix-copy -* --debug - enable debug output -* --show-trace - show nix build traces -* --option - nix option to pass to every nix related command -* --from - URL of the source Nix store to copy the nixos and disko closure from -* --build-on-remote - build the closure on the remote machine instead of locally and copy-closuring it -* --vm-test - build the system and test the disk configuration inside a VM without installing it to the target. -* --generate-hardware-config nixos-facter|nixos-generate-config - generate a hardware-configuration.nix file using the specified backend and write it to the specified path. - The backend can be either 'nixos-facter' or 'nixos-generate-config'. -* --phases - comma separated list of phases to run. Default is: kexec,disko,install,reboot - kexec: kexec into the nixos installer - disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode - install: install the system - reboot: unmount the filesystems, export any ZFS pools and reboot the machine -* --disko-mode disko|mount|format - set the disko mode to format, mount or destroy. Default is disko. - disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode -* --no-disko-deps - This will only upload the disko script and not the partitioning tools dependencies. - Installers usually have dependencies available. - Use this option if your target machine has not enough RAM to store the dependencies in memory. -* --build-on auto|remote|local - sets the build on settings to auto, remote or local. Default is auto. - auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build - local: will build on the local host - remote: will build on the remote host -USAGE -} - -abort() { - echo "aborted: $*" >&2 - exit 1 -} - -step() { - echo "### $* ###" -} - -parseArgs() { - local substituteOnDestination=y - local printBuildLogs=n - local buildOnRemote=n - while [[ $# -gt 0 ]]; do - case "$1" in - -f | --flake) - flake=$2 - shift - ;; - --target-host) - sshConnection=$2 - shift - ;; - -i) - sshPrivateKeyFile=$2 - shift - ;; - -p | --ssh-port) - sshArgs+=("-p" "$2") - shift - ;; - --ssh-option) - sshArgs+=("-o" "$2") - shift - ;; - -L | --print-build-logs) - printBuildLogs=y - ;; - -s | --store-paths) - diskoScript=$(readlink -f "$2") - nixosSystem=$(readlink -f "$3") - shift - shift - ;; - --generate-hardware-config) - if [[ $# -lt 3 ]]; then - abort "Missing arguments for --generate-hardware-config " - fi - case "$2" in - nixos-facter | nixos-generate-config) - hardwareConfigBackend=$2 - ;; - *) - abort "Unknown hardware config backend: $2" - ;; - esac - hardwareConfigPath=$3 - shift - shift - ;; - -t | --tty) - echo "the '$1' flag is deprecated, a tty is now detected automatically" >&2 - ;; - --help) - showUsage - exit 0 - ;; - --kexec) - kexecUrl=$2 - shift - ;; - --kexec-extra-flags) - kexecExtraFlags=$2 - shift - ;; - --ssh-store-setting) - key=$2 - shift - value=$2 - shift - sshStoreSettings+="$sshStoreSettings$key=$value&" - shift - ;; - --post-kexec-ssh-port) - postKexecSshPort=$2 - shift - ;; - --copy-host-keys) - copyHostKeys=y - ;; - --show-trace) - nixBuildFlags+=("--show-trace") - ;; - --debug) - enableDebug="-x" - printBuildLogs=y - set -x - ;; - --disko-mode) - case "$2" in - format | mount | disko) - diskoMode=$2 - ;; - *) - abort "Supported values for --disko-mode are disko, mount and format. Unknown mode : $2" - ;; - esac - - shift - ;; - --no-disko-deps) - diskoDeps=n - ;; - --build-on) - case "$2" in - auto | local | remote) - buildOn=$2 - ;; - *) - abort "Supported values for --build-on are auto, local and remote. Unknown mode : $2" - ;; - esac - - shift - ;; - --extra-files) - extraFiles=$2 - shift - ;; - --chown) - extraFilesOwnership["$2"]="$3" - shift - shift - ;; - --disk-encryption-keys) - diskEncryptionKeys["$2"]="$3" - shift - shift - ;; - --phases) - phases[kexec]=0 - phases[disko]=0 - phases[install]=0 - phases[reboot]=0 - IFS=, read -r -a phaseList <<<"$2" - for phase in "${phaseList[@]}"; do - if [[ ${phases[$phase]:-unset} == unset ]]; then - abort "Unknown phase: $phase" - fi - phases[$phase]=1 - done - shift - ;; - --stop-after-disko) - echo "WARNING: --stop-after-disko is deprecated, use --phases kexec,disko instead" 2>&1 - phases[kexec]=1 - phases[disko]=1 - phases[install]=0 - phases[reboot]=0 - ;; - --no-reboot) - echo "WARNING: --no-reboot is deprecated, use --phases kexec,disko,install instead" 2>&1 - phases[kexec]=1 - phases[disko]=1 - phases[install]=1 - phases[reboot]=0 - ;; - --from) - nixCopyOptions+=("--from" "$2") - shift - ;; - --option) - key=$2 - shift - value=$2 - shift - nixOptions+=("--option" "$key" "$value") - ;; - --no-substitute-on-destination) - substituteOnDestination=n - ;; - --build-on-remote) - echo "WARNING: --build-on-remote is deprecated, use --build-on remote instead" 2>&1 - buildOnRemote=y - buildOn="remote" - ;; - --env-password) - envPassword=y - ;; - --vm-test) - vmTest=y - ;; - *) - if [[ -z ${sshConnection} ]]; then - sshConnection="$1" - else - showUsage - exit 1 - fi - ;; - esac - shift - done - - diskoAttr="${diskoMode}Script" - - if [[ ${diskoDeps} == "n" ]]; then - diskoAttr="${diskoAttr}NoDeps" - fi - - if [[ ${printBuildLogs} == "y" ]]; then - nixOptions+=("-L") - fi - - if [[ $substituteOnDestination == "y" ]]; then - nixCopyOptions+=("--substitute-on-destination") - fi - - if [[ $vmTest == "n" ]] && [[ -z ${sshConnection} ]]; then - abort "ssh-host must be set" - fi - - if [[ $buildOn == "local" ]] && [[ $buildOnRemote == "y" ]]; then - abort "Conflicting flags: --build-on local and --build-on-remote used." - fi - - if [[ -n ${flake} ]]; then - if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then - flake="${BASH_REMATCH[1]}" - flakeAttr="${BASH_REMATCH[2]}" - fi - if [[ -z ${flakeAttr} ]]; then - echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri." >&2 - echo 'For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri.' >&2 - exit 1 - fi - - # Support .#foo shorthand - if [[ $flakeAttr != nixosConfigurations.* ]]; then - flakeAttr="nixosConfigurations.\"$flakeAttr\".config" - fi - fi - -} - -# ssh wrapper -runSshNoTty() { - ssh -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@" -} -runSshTimeout() { - timeout 10 ssh -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@" -} -runSsh() { - ssh "$sshTtyParam" -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@" -} - -nixCopy() { - NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $sshKeyDir/nixos-anywhere ${sshArgs[*]}" nix copy \ - "${nixOptions[@]}" \ - "${nixCopyOptions[@]}" \ - "$@" -} -nixBuild() { - NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $sshKeyDir/nixos-anywhere ${sshArgs[*]}" nix build \ - --print-out-paths \ - --no-link \ - "${nixBuildFlags[@]}" \ - "${nixOptions[@]}" \ - "$@" -} - -runVmTest() { - if [[ -z ${flakeAttr} ]]; then - echo "--vm-test is not supported with --store-paths" >&2 - echo "Please use --flake instead or build config.system.build.installTest of your nixos configuration manually" >&2 - exit 1 - fi - - if [[ ${buildOn} == "remote" ]]; then - echo "--vm-test is not supported with --build-on-remote" >&2 - exit 1 - fi - if [[ -n ${extraFiles} ]]; then - echo "--vm-test is not supported with --extra-files" >&2 - exit 1 - fi - if [ ${#diskEncryptionKeys[@]} -gt 0 ]; then - echo "--vm-test is not supported with --disk-encryption-keys" >&2 - exit 1 - fi - nix build \ - --print-out-paths \ - --no-link \ - -L \ - "${nixBuildFlags[@]}" \ - "${nixOptions[@]}" \ - "${flake}#${flakeAttr}.system.build.installTest" -} - -uploadSshKey() { - # ssh-copy-id requires this directory - mkdir -p "$HOME/.ssh/" - if [[ -n ${sshPrivateKeyFile} ]]; then - cp "$sshPrivateKeyFile" "$sshKeyDir/nixos-anywhere" - ssh-keygen -y -f "$sshKeyDir/nixos-anywhere" >"$sshKeyDir/nixos-anywhere.pub" - else - # we generate a temporary ssh keypair that we can use during nixos-anywhere - ssh-keygen -t ed25519 -f "$sshKeyDir"/nixos-anywhere -P "" -C "nixos-anywhere" >/dev/null - fi - - declare -a sshCopyIdArgs - if [[ -n ${sshPrivateKeyFile} ]]; then - unset SSH_AUTH_SOCK # don't use system agent if key was supplied - sshCopyIdArgs+=(-o "IdentityFile=${sshPrivateKeyFile}" -f) - fi - - step Uploading install SSH keys - until - if [[ ${envPassword} == y ]]; then - sshpass -e \ - ssh-copy-id \ - -i "$sshKeyDir"/nixos-anywhere.pub \ - -o ConnectTimeout=10 \ - -o UserKnownHostsFile=/dev/null \ - -o IdentitiesOnly=yes \ - -o StrictHostKeyChecking=no \ - "${sshCopyIdArgs[@]}" \ - "${sshArgs[@]}" \ - "$sshConnection" - else - ssh-copy-id \ - -i "$sshKeyDir"/nixos-anywhere.pub \ - -o ConnectTimeout=10 \ - -o UserKnownHostsFile=/dev/null \ - -o StrictHostKeyChecking=no \ - "${sshCopyIdArgs[@]}" \ - "${sshArgs[@]}" \ - "$sshConnection" - fi - do - sleep 3 - done -} - -importFacts() { - step Gathering machine facts - local facts filteredFacts - if ! facts=$(runSsh -o ConnectTimeout=10 enableDebug=$enableDebug sh -- <"$here"/get-facts.sh); then - exit 1 - fi - filteredFacts=$(echo "$facts" | grep -E '^(has|is)[A-Za-z0-9_]+=\S+') - if [[ -z $filteredFacts ]]; then - abort "Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already" - fi - # make facts available in script - # shellcheck disable=SC2046 - export $(echo "$filteredFacts" | xargs) - - for var in isOs isArch isKexec isInstaller isContainer hasIpv6Only hasTar hasCpio hasSudo hasDoas hasWget hasCurl hasSetsid; do - if [[ -z ${!var} ]]; then - abort "Failed to retrieve fact $var from host" - fi - done -} - -checkBuildLocally() { - local system extraPlatforms machineSystem - system="$(nix --extra-experimental-features 'nix-command flakes' config show system)" - extraPlatforms="$(nix --extra-experimental-features 'nix-command flakes' config show extra-platforms)" - - if [[ $# -gt 0 ]]; then - machineSystem=$1 - elif [[ -n ${nixosSystem} ]]; then - machineSystem="$(cat "${nixosSystem}"/system)" - else - machineSystem="$(nix --extra-experimental-features 'nix-command flakes' eval --raw "${flake}"#"${flakeAttr}".pkgs.system 2>/dev/null || echo "unknown")" - if [[ ${machineSystem} == "unknown" ]]; then - buildOn=auto - return - fi - fi - - if [[ ${system} == "${machineSystem}" ]]; then - buildOn=local - return - fi - - if [[ ${extraPlatforms} == "*${machineSystem}*" ]]; then - buildOn=local - return - fi - - local entropy - entropy="$(date +'%Y%m%d%H%M%S')" - if nix build \ - -L \ - "${nixOptions[@]}" \ - --expr \ - "derivation { system = \"$system\"; name = \"env-$entropy\"; builder = \"/bin/sh\"; args = [ \"-c\" \"echo > \$out\" ]; }"; then - # The local build failed - buildOn=local - fi - - buildOn=remote -} - -generateHardwareConfig() { - local maybeSudo="$maybeSudo" - mkdir -p "$(dirname "$hardwareConfigPath")" - case "$hardwareConfigBackend" in - nixos-facter) - if [[ ${isInstaller} == "y" ]]; then - if [[ ${hasNixOSFacter} == "n" ]]; then - abort "nixos-facter is not available in booted installer, use nixos-generate-config. For nixos-facter, you may want to boot an installer image from here instead: https://github.com/nix-community/nixos-images" - fi - else - maybeSudo="" - fi - - step "Generating hardware-configuration.nix using nixos-facter" - runSshNoTty -o ConnectTimeout=10 ${maybeSudo} "nixos-facter" >"$hardwareConfigPath" - ;; - nixos-generate-config) - step "Generating hardware-configuration.nix using nixos-generate-config" - runSshNoTty -o ConnectTimeout=10 nixos-generate-config --show-hardware-config --no-filesystems >"$hardwareConfigPath" - ;; - *) - abort "Unknown hardware config backend: $hardwareConfigBackend" - ;; - esac - - # to make sure nix knows about the new file - if command -v git >/dev/null; then - # handle relative paths - hardwareConfigPath="$(realpath "$hardwareConfigPath")" - pushd "$(dirname "$hardwareConfigPath")" - if git rev-parse --is-inside-work-tree >/dev/null; then - git add --intent-to-add --force -- "$hardwareConfigPath" - fi - popd - fi -} - -runKexec() { - if [[ ${isKexec} == "y" ]] || [[ ${isInstaller} == "y" ]]; then - return - fi - - if [[ ${isContainer} != "none" ]]; then - echo "WARNING: This script does not support running from a '${isContainer}' container. kexec will likely not work" >&2 - fi - - if [[ $kexecUrl == "" ]]; then - case "${isArch}" in - x86_64 | aarch64) - kexecUrl="https://github.com/nix-community/nixos-images/releases/download/nixos-24.11/nixos-kexec-installer-noninteractive-${isArch}-linux.tar.gz" - ;; - *) - abort "Unsupported architecture: ${isArch}. Our default kexec images only support x86_64 and aarch64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information." - ;; - esac - fi - - step Switching system into kexec - runSsh sh < $path" <"${diskEncryptionKeys[$path]}" - done - if [[ -n ${diskoScript} ]]; then - nixCopy --to "ssh://$sshConnection?$sshStoreSettings" "$diskoScript" - elif [[ ${buildOn} == "remote" ]]; then - step Building disko script - # We need to do a nix copy first because nix build doesn't have --no-check-sigs - # Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359 - nixCopy --to "ssh://$sshConnection?$sshStoreSettings" "${flake}#${flakeAttr}.system.build.${diskoMode}Script" \ - --derivation --no-check-sigs - # If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store` - diskoScript=$( - nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}" \ - --eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir%2Fnixos-anywhere&$sshStoreSettings" - ) - fi - - step Formatting hard drive with disko - runSsh "$diskoScript" -} - -nixosInstall() { - local nixosSystem=$1 - if [[ -n ${nixosSystem} ]]; then - step Uploading the system closure - nixCopy --to "ssh://$sshConnection?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" "$nixosSystem" - elif [[ ${buildOn} == "remote" ]]; then - step Building the system closure - # We need to do a nix copy first because nix build doesn't have --no-check-sigs - # Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359 - nixCopy --to "ssh://$sshConnection?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" "${flake}#${flakeAttr}.system.build.toplevel" \ - --derivation --no-check-sigs - # If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store` - nixosSystem=$( - nixBuild "${flake}#${flakeAttr}.system.build.toplevel" \ - --eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir%2Fnixos-anywhere&remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" - ) - fi - - if [[ -n ${extraFiles} ]]; then - step Copying extra files - tar -C "$extraFiles" -cpf- . | runSsh "tar -C /mnt -xf- --no-same-owner" - - runSsh "chmod 755 /mnt" # tar also changes permissions of /mnt - fi - - if [[ ${#extraFilesOwnership[@]} -gt 0 ]]; then - # shellcheck disable=SC2016 - printf "%s\n" "${!extraFilesOwnership[@]}" "${extraFilesOwnership[@]}" | pr -2t | runSsh 'while read file ownership; do chown -R "$ownership" "/mnt/$file"; done' - fi - - step Installing NixOS - runSsh sh </dev/null && [ "\$(zpool list)" != "no pools available" ]; then - # we always want to export the zfs pools so people can boot from it without force import - umount -Rv /mnt/ - swapoff -a - zpool export -a || true - fi - nohup sh -c 'sleep 6 && reboot' >/dev/null & -fi -SSH - -} - -main() { - parseArgs "$@" - - if [[ ${vmTest} == y ]]; then - if [[ ${hardwareConfigBackend} != "none" ]]; then - abort "--vm-test is not supported with --generate-hardware-config. You need to generate the hardware configuration before you can run the VM test." >&2 - fi - runVmTest - exit 0 - fi - - if [[ ${buildOn} == "auto" ]]; then - checkBuildLocally - fi - - # parse flake nixos-install style syntax, get the system attr - if [[ -n ${flake} ]]; then - if [[ ${buildOn} == "local" ]] && [[ ${hardwareConfigBackend} == "none" ]]; then - if [[ ${phases[disko]} == 1 ]]; then - diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}") - fi - if [[ ${phases[install]} == 1 ]]; then - nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel") - fi - fi - elif [[ -n ${diskoScript} ]] && [[ -n ${nixosSystem} ]]; then - if [[ ! -e ${diskoScript} ]] || [[ ! -e ${nixosSystem} ]]; then - abort "${diskoScript} and ${nixosSystem} must be existing store-paths" - fi - else - abort "--flake or --store-paths must be set" - fi - - if [[ -n ${SSH_PRIVATE_KEY} ]] && [[ -z ${sshPrivateKeyFile} ]]; then - # $sshKeyDir is getting deleted on trap EXIT - sshPrivateKeyFile="$sshKeyDir/from-env" - ( - umask 077 - printf '%s\n' "$SSH_PRIVATE_KEY" >"$sshPrivateKeyFile" - ) - fi - - sshSettings=$(ssh "${sshArgs[@]}" -G "${sshConnection}") - sshUser=$(echo "$sshSettings" | awk '/^user / { print $2 }') - sshHost=$(echo "$sshSettings" | awk '/^hostname / { print $2 }') - - uploadSshKey - - importFacts - - if [[ ${hasTar-n} == "n" ]]; then - abort "no tar command found, but required to unpack kexec tarball" - fi - - if [[ ${hasCpio-n} == "n" ]]; then - abort "no cpio command found, but required to build the new initrd" - fi - - if [[ ${hasSetsid-n} == "n" ]]; then - abort "no setsid command found, but required to run the kexec script under a new session" - fi - - maybeSudo="" - if [[ ${hasSudo-n} == "y" ]]; then - maybeSudo="sudo" - elif [[ ${hasDoas-n} == "y" ]]; then - maybeSudo="doas" - fi - - if [[ ${isOs} != "Linux" ]]; then - abort "This script requires Linux as the operating system, but got $isOs" - fi - - if [[ ${phases[kexec]} == 1 ]]; then - runKexec - fi - - if [[ ${hardwareConfigBackend} != "none" ]]; then - generateHardwareConfig - fi - - # Before we do not have a valid hardware configuration we don't know the machine system - if [[ ${buildOn} == "auto" ]]; then - local remoteSystem - remoteSystem=$(runSshNoTty -o ConnectTimeout=10 nix --extra-experimental-features nix-command config show system) - checkBuildLocally "${remoteSystem}" - # if we cannot figure it out at this point, we will build on the remote host - if [[ ${buildOn} == "auto" ]]; then - buildOn=remote - fi - fi - - if [[ ${buildOn} != "remote" ]] && [[ -n ${flake} ]] && [[ -z ${diskoScript} ]]; then - if [[ ${phases[disko]} == 1 ]]; then - diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}") - fi - if [[ ${phases[install]} == 1 ]]; then - nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel") - fi - fi - - # Installation will fail if non-root user is used for installer. - # Switch to root user by copying authorized_keys. - if [[ ${isInstaller} == "y" ]] && [[ ${sshUser} != "root" ]]; then - # Allow copy to fail if authorized_keys does not exist, like if using /etc/ssh/authorized_keys.d/ - runSsh "${maybeSudo} mkdir -p /root/.ssh; ${maybeSudo} cp ~/.ssh/authorized_keys /root/.ssh || true" - sshConnection="root@${sshHost}" - fi - - if [[ ${phases[disko]} == 1 ]]; then - runDisko "$diskoScript" - fi - - if [[ ${phases[install]} == 1 ]]; then - nixosInstall "$nixosSystem" - fi - - if [[ ${phases[reboot]} == 1 ]]; then - step Waiting for the machine to become unreachable due to reboot - while runSshTimeout -- exit 0; do sleep 1; done - fi - - step "Done!" -} - -main "$@" diff --git a/launch/.terraform/modules/peertube.deploy/terraform/README.md b/launch/.terraform/modules/peertube.deploy/terraform/README.md deleted file mode 100644 index 2d66b1a8..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# NixOS-Anywhere Terraform Modules Overview - -The nixos-Anywhere terraform modules allow you to use Terraform for installing -and updating NixOS. It simplifies the deployment process by integrating -nixos-anywhere functionality. - -Here's a brief overview of each module: - -- **[All-in-One](all-in-one.md)**: This is a consolidated module that first - installs NixOS using nixos-anywhere and then keeps it updated with - nixos-rebuild. If you choose this, you won't need additional deployment tools - like colmena. -- **[Install](install.md)**: This module focuses solely on installing NixOS via - nixos-anywhere. -- **[NixOS-Rebuild](nixos-rebuild.md)**: Use this module to remotely update an - existing NixOS machine using nixos-rebuild. -- **[Nix-Build](nix-build.md)**: This is a handy helper module designed to build - a flake attribute or an attribute from a nix file. - -For detailed information and usage examples, click on the respective module -links above. diff --git a/launch/.terraform/modules/peertube.deploy/terraform/all-in-one.md b/launch/.terraform/modules/peertube.deploy/terraform/all-in-one.md deleted file mode 100644 index c7279cf2..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/all-in-one.md +++ /dev/null @@ -1,235 +0,0 @@ -# All-in-one - -Combines the install and nixos-rebuild module in one interface to install NixOS -with nixos-anywhere and then keep it up-to-date with nixos-rebuild. - -## Example - -```hcl -locals { - ipv4 = "192.0.2.1" -} - -module "deploy" { - source = "github.com/nix-community/nixos-anywhere//terraform/all-in-one" - # with flakes - nixos_system_attr = ".#nixosConfigurations.mymachine.config.system.build.toplevel" - nixos_partitioner_attr = ".#nixosConfigurations.mymachine.config.system.build.diskoScript" - # without flakes - # file can use (pkgs.nixos []) function from nixpkgs - #file = "${path.module}/../.." - #nixos_system_attr = "config.system.build.toplevel" - #nixos_partitioner_attr = "config.system.build.diskoScript" - - target_host = local.ipv4 - # when instance id changes, it will trigger a reinstall - instance_id = local.ipv4 - # useful if something goes wrong - # debug_logging = true - # build the closure on the remote machine instead of locally - # build_on_remote = true - # script is below - extra_files_script = "${path.module}/decrypt-ssh-secrets.sh" - disk_encryption_key_scripts = [{ - path = "/tmp/secret.key" - # script is below - script = "${path.module}/decrypt-zfs-key.sh" - }] - # Optional, arguments passed to special_args here will be available from a NixOS module in this example the `terraform` argument: - # { terraform, ... }: { - # networking.interfaces.enp0s3.ipv4.addresses = [{ address = terraform.ip; prefixLength = 24; }]; - # } - # Note that this will means that your NixOS configuration will always depend on terraform! - # Skip to `Pass data persistently to the NixOS` for an alternative approach - #special_args = { - # terraform = { - # ip = "192.0.2.0" - # } - #} -} -``` - -_Note:_ You need to mark scripts as executable (`chmod +x`) - -### ./decrypt-ssh-secrets.sh - -```bash -#!/usr/bin/env bash - -mkdir -p etc/ssh var/lib/secrets - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - -umask 0177 -sops --extract '["initrd_ssh_key"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >./var/lib/secrets/initrd_ssh_key - -# restore umask -umask 0022 - -for keyname in ssh_host_rsa_key ssh_host_rsa_key.pub ssh_host_ed25519_key ssh_host_ed25519_key.pub; do - if [[ $keyname == *.pub ]]; then - umask 0133 - else - umask 0177 - fi - sops --extract '["'$keyname'"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >"./etc/ssh/$keyname" -done -``` - -### ./decrypt-zfs-key.sh - -```bash -#!/usr/bin/env bash - -set -euo pipefail - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -cd "$SCRIPT_DIR" -sops --extract '["zfs-key"]' --decrypt "$SCRIPT_DIR/secrets.yaml" -``` - -## See also - -- [nixos-wiki setup](https://github.com/NixOS/nixos-wiki-infra/blob/main/terraform/nixos-wiki/main.tf) - for hetzner-cloud - -## Pass data persistently to the NixOS - -This guide outlines how to pass data from Terraform to NixOS by generating a -file during Terraform execution and including it in your NixOS configuration. -This approach works well if your Terraform and NixOS configurations are stored -in the same Git repository. - -### Why Use This Method? - -This method provides a straightforward way to transfer values from Terraform to -NixOS without relying on special_args. - -- **Advantages**: - - You can continue to use nix build or nixos-rebuild to evaluate your - configuration without interruption. Simplifies configuration management by - centralizing state in a single repository. -- **Disadvantages**: - - Deploying new machines requires tracking additional state. Every time - Terraform updates the JSON file, you'll need to commit these changes to your - repository. - -### Implementation - -Add the following snippet to your Terraform configuration to create and manage a -JSON file containing the necessary variables for NixOS. This file will be -automatically added to your Git repository, ensuring the data persists. - -Assuming you have your terraform and nixos configuration in the same git -repository. You can use the following snippet to `git add` a file generated by -`terraform` during execution to pass data from terraform to NixOS. These changes -should be committed afterwards. This is an alternative over using -`special_args`. Advantage: you can still use nix build or nixos-rebuild on your -flake to evaluate your configuration. Disadvantage: Deploying new machines also -means you need to track additional state and make additional commits whenever -terraform updates the json file. - -```hcl -locals { - nixos_vars_file = "nixos-vars.json" # Path to the JSON file containing NixOS variables - nixos_vars = { - ip = "192.0.2.0" # Replace with actual variables - } -} -resource "local_file" "nixos_vars" { - content = jsonencode(local.nixos_vars) # Converts variables to JSON - filename = local.nixos_vars_file # Specifies the output file path - file_permission = "600" - - # Automatically adds the generated file to Git - provisioner "local-exec" { - interpreter = ["bash", "-c"] - command = "git add -f '${local.nixos_vars_file}'" - } -} -``` - -After applying the Terraform changes, ensure you commit the updated -`nixos-vars.json` file to your Git repository: - -```bash -git commit -m "Update NixOS variables from Terraform" -``` - -You can import this json file into your configuration like this: - -```nix -let - nixosVars = builtins.fromJSON (builtins.readFile ./nixos-vars.json); -in -{ - # Example usage of imported variables - networking.hostName = "example-machine"; - networking.interfaces.eth0.ipv4.addresses = [ - { - address = nixosVars.ip; # Use the IP from nixos-vars.json - prefixLength = 24; - } - ]; -} -``` - - - -## Requirements - -No requirements. - -## Providers - -No providers. - -## Modules - -| Name | Source | Version | -| -------------------------------------------------------------------------------------- | ---------------- | ------- | -| [install](#module_install) | ../install | n/a | -| [nixos-rebuild](#module_nixos-rebuild) | ../nixos-rebuild | n/a | -| [partitioner-build](#module_partitioner-build) | ../nix-build | n/a | -| [system-build](#module_system-build) | ../nix-build | n/a | - -## Resources - -No resources. - -## Inputs - -| Name | Description | Type | Default | Required | -| --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | :------: | -| [debug\_logging](#input_debug_logging) | Enable debug logging | `bool` | `false` | no | -| [deployment\_ssh\_key](#input_deployment_ssh_key) | Content of private key used to deploy to the target\_host after initial installation. To ensure maximum security, it is advisable to connect to your host using ssh-agent instead of relying on this variable | `string` | `null` | no | -| [disk\_encryption\_key\_scripts](#input_disk_encryption_key_scripts) | Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system |
list(object({
path = string
script = string
}))
| `[]` | no | -| [extra\_environment](#input_extra_environment) | Extra environment variables to be set during installation. This can be useful to set extra variables for the extra\_files\_script or disk\_encryption\_key\_scripts | `map(string)` | `{}` | no | -| [extra\_files\_script](#input_extra_files_script) | A script that should place files in the current directory that will be copied to the targets / directory | `string` | `null` | no | -| [file](#input_file) | Nix file containing the nixos\_system\_attr and nixos\_partitioner\_attr. Use this if you are not using flake | `string` | `null` | no | -| [install\_port](#input_install_port) | SSH port used to connect to the target\_host, before installing NixOS. If null than the value of `target_port` is used | `string` | `null` | no | -| [install\_ssh\_key](#input_install_ssh_key) | Content of private key used to connect to the target\_host during initial installation | `string` | `null` | no | -| [install\_user](#input_install_user) | SSH user used to connect to the target\_host, before installing NixOS. If null than the value of `target_host` is used | `string` | `null` | no | -| [instance\_id](#input_instance_id) | The instance id of the target\_host, used to track when to reinstall the machine | `string` | `null` | no | -| [kexec\_tarball\_url](#input_kexec_tarball_url) | NixOS kexec installer tarball url | `string` | `null` | no | -| [nix\_options](#input_nix_options) | the options of nix | `map(string)` | `{}` | no | -| [nixos\_facter\_path](#input_nixos_facter_path) | Path to which to write a `facter.json` generated by `nixos-facter`. | `string` | `""` | no | -| [nixos\_generate\_config\_path](#input_nixos_generate_config_path) | Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. | `string` | `""` | no | -| [nixos\_partitioner\_attr](#input_nixos_partitioner_attr) | Nixos partitioner and mount script i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.diskoNoDeps or just your-evaluated.config.system.build.diskNoDeps. `config.system.build.diskNoDeps` is provided by the disko nixos module | `string` | n/a | yes | -| [nixos\_system\_attr](#input_nixos_system_attr) | The nixos system to deploy i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.toplevel or just your-evaluated-nixos.config.system.build.toplevel if you are not using flakes | `string` | n/a | yes | -| [no\_reboot](#input_no_reboot) | DEPRECATED: Use `phases` instead. Do not reboot after installation | `bool` | `false` | no | -| [phases](#input_phases) | Phases to run. See `nixos-anywhere --help` for more information | `set(string)` |
[
"kexec",
"disko",
"install",
"reboot"
]
| no | -| [special\_args](#input_special_args) | A map exposed as NixOS's `specialArgs` thru a file. | `any` | `{}` | no | -| [build\_on\_remote](#input_build_on_remote) | Build the closure on the remote machine instead of building it locally and copying it over | `bool` | `false` | no | -| [stop\_after\_disko](#input_stop_after_disko) | DEPRECATED: Use `phases` instead. Exit after disko formatting | `bool` | `false` | no | -| [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes | -| [target\_port](#input_target_port) | SSH port used to connect to the target\_host after installing NixOS. If install\_port is not set than this port is also used before installing. | `number` | `22` | no | -| [target\_user](#input_target_user) | SSH user used to connect to the target\_host after installing NixOS. If install\_user is not set than this user is also used before installing. | `string` | `"root"` | no | - -## Outputs - -| Name | Description | -| ----------------------------------------------------- | ----------- | -| [result](#output_result) | n/a | - - diff --git a/launch/.terraform/modules/peertube.deploy/terraform/all-in-one/main.tf b/launch/.terraform/modules/peertube.deploy/terraform/all-in-one/main.tf deleted file mode 100644 index fa5d7eb3..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/all-in-one/main.tf +++ /dev/null @@ -1,64 +0,0 @@ -module "system-build" { - source = "../nix-build" - attribute = var.nixos_system_attr - file = var.file - nix_options = var.nix_options - special_args = var.special_args -} - -module "partitioner-build" { - source = "../nix-build" - attribute = var.nixos_partitioner_attr - file = var.file - nix_options = var.nix_options - special_args = var.special_args -} - -locals { - install_user = var.install_user == null ? var.target_user : var.install_user - install_port = var.install_port == null ? var.target_port : var.install_port -} - -module "install" { - source = "../install" - kexec_tarball_url = var.kexec_tarball_url - target_user = local.install_user - target_host = var.target_host - target_port = local.install_port - nixos_partitioner = module.partitioner-build.result.out - nixos_system = module.system-build.result.out - ssh_private_key = var.install_ssh_key - debug_logging = var.debug_logging - extra_files_script = var.extra_files_script - disk_encryption_key_scripts = var.disk_encryption_key_scripts - extra_environment = var.extra_environment - instance_id = var.instance_id - phases = var.phases - nixos_generate_config_path = var.nixos_generate_config_path - nixos_facter_path = var.nixos_facter_path - build_on_remote = var.build_on_remote - # deprecated attributes - stop_after_disko = var.stop_after_disko - no_reboot = var.no_reboot -} - -module "nixos-rebuild" { - depends_on = [ - module.install - ] - - # Do not execute this step if var.stop_after_disko == true - count = var.stop_after_disko ? 0 : 1 - - source = "../nixos-rebuild" - nixos_system = module.system-build.result.out - ssh_private_key = var.deployment_ssh_key - target_host = var.target_host - target_user = var.target_user - target_port = var.target_port - install_bootloader = var.install_bootloader -} - -output "result" { - value = module.system-build.result -} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/all-in-one/variables.tf b/launch/.terraform/modules/peertube.deploy/terraform/all-in-one/variables.tf deleted file mode 100644 index 3ca27922..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/all-in-one/variables.tf +++ /dev/null @@ -1,151 +0,0 @@ -variable "kexec_tarball_url" { - type = string - description = "NixOS kexec installer tarball url" - default = null -} - -# To make this re-usable we maybe should accept a store path here? -variable "nixos_partitioner_attr" { - type = string - description = "Nixos partitioner and mount script i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.diskoNoDeps or just your-evaluated.config.system.build.diskNoDeps. `config.system.build.diskNoDeps` is provided by the disko nixos module" -} - -# To make this re-usable we maybe should accept a store path here? -variable "nixos_system_attr" { - type = string - description = "The nixos system to deploy i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.toplevel or just your-evaluated-nixos.config.system.build.toplevel if you are not using flakes" -} - -variable "file" { - type = string - description = "Nix file containing the nixos_system_attr and nixos_partitioner_attr. Use this if you are not using flake" - default = null -} - -variable "target_host" { - type = string - description = "DNS host to deploy to" -} - -variable "install_user" { - type = string - description = "SSH user used to connect to the target_host, before installing NixOS. If null than the value of `target_host` is used" - default = null -} - -variable "install_port" { - type = string - description = "SSH port used to connect to the target_host, before installing NixOS. If null than the value of `target_port` is used" - default = null -} - -variable "target_user" { - type = string - description = "SSH user used to connect to the target_host after installing NixOS. If install_user is not set than this user is also used before installing." - default = "root" -} - -variable "target_port" { - type = number - description = "SSH port used to connect to the target_host after installing NixOS. If install_port is not set than this port is also used before installing." - default = 22 -} - -variable "instance_id" { - type = string - description = "The instance id of the target_host, used to track when to reinstall the machine" - default = null -} - -variable "install_ssh_key" { - type = string - description = "Content of private key used to connect to the target_host during initial installation" - default = null -} - -variable "deployment_ssh_key" { - type = string - description = "Content of private key used to deploy to the target_host after initial installation. To ensure maximum security, it is advisable to connect to your host using ssh-agent instead of relying on this variable" - default = null -} - -variable "debug_logging" { - type = bool - description = "Enable debug logging" - default = false -} - -variable "stop_after_disko" { - type = bool - description = "DEPRECATED: Use `phases` instead. Exit after disko formatting" - default = false -} - -variable "no_reboot" { - type = bool - description = "DEPRECATED: Use `phases` instead. Do not reboot after installation" - default = false -} - -variable "phases" { - type = set(string) - description = "Phases to run. See `nixos-anywhere --help` for more information" - default = ["kexec", "disko", "install", "reboot"] -} - -variable "extra_files_script" { - type = string - description = "A script that should place files in the current directory that will be copied to the targets / directory" - default = null -} - -variable "disk_encryption_key_scripts" { - type = list(object({ - path = string - script = string - })) - description = "Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system" - default = [] -} - -variable "extra_environment" { - type = map(string) - description = "Extra environment variables to be set during installation. This can be useful to set extra variables for the extra_files_script or disk_encryption_key_scripts" - default = {} -} - -variable "nix_options" { - type = map(string) - description = "the options of nix" - default = {} -} - -variable "nixos_generate_config_path" { - type = string - description = "Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`." - default = "" -} - -variable "nixos_facter_path" { - type = string - description = "Path to which to write a `facter.json` generated by `nixos-facter`." - default = "" -} - -variable "special_args" { - type = any - default = {} - description = "A map exposed as NixOS's `specialArgs` thru a file." -} - -variable "build_on_remote" { - type = bool - description = "Build the closure on the remote machine instead of building it locally and copying it over" - default = false -} - -variable "install_bootloader" { - type = bool - description = "Install/re-install the bootloader" - default = false -} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/install.md b/launch/.terraform/modules/peertube.deploy/terraform/install.md deleted file mode 100644 index eb3439fc..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/install.md +++ /dev/null @@ -1,91 +0,0 @@ -# Install - -Install NixOS with nixos-anywhere - -## Example - -```hcl -locals { - ipv4 = "192.0.2.1" -} - -module "system-build" { - source = "github.com/nix-community/nixos-anywhere//terraform/nix-build" - # with flakes - attribute = ".#nixosConfigurations.mymachine.config.system.build.toplevel" - # without flakes - # file can use (pkgs.nixos []) function from nixpkgs - #file = "${path.module}/../.." - #attribute = "config.system.build.toplevel" -} - -module "disko" { - source = "github.com/nix-community/nixos-anywhere//terraform/nix-build" - # with flakes - attribute = ".#nixosConfigurations.mymachine.config.system.build.diskoScript" - # without flakes - # file can use (pkgs.nixos []) function from nixpkgs - #file = "${path.module}/../.." - #attribute = "config.system.build.diskoScript" -} - -module "install" { - source = "github.com/nix-community/nixos-anywhere//terraform/install" - nixos_system = module.system-build.result.out - nixos_partitioner = module.disko.result.out - target_host = local.ipv4 -} -``` - - - -## Requirements - -No requirements. - -## Providers - -| Name | Version | -| --------------------------------------------------- | ------- | -| [null](#provider_null) | n/a | - -## Modules - -No modules. - -## Resources - -| Name | Type | -| ------------------------------------------------------------------------------------------------------------------- | -------- | -| [null_resource.nixos-remote](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | - -## Inputs - -| Name | Description | Type | Default | Required | -| --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | :------: | -| [build\_on\_remote](#input_build_on_remote) | Build the closure on the remote machine instead of building it locally and copying it over | `bool` | `false` | no | -| [debug\_logging](#input_debug_logging) | Enable debug logging | `bool` | `false` | no | -| [disk\_encryption\_key\_scripts](#input_disk_encryption_key_scripts) | Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system |
list(object({
path = string
script = string
}))
| `[]` | no | -| [extra\_environment](#input_extra_environment) | Extra environment variables to be set during installation. This can be useful to set extra variables for the extra\_files\_script or disk\_encryption\_key\_scripts | `map(string)` | `{}` | no | -| [extra\_files\_script](#input_extra_files_script) | A script that should place files in the current directory that will be copied to the targets / directory | `string` | `null` | no | -| [flake](#input_flake) | The flake to install the system from | `string` | `""` | no | -| [instance\_id](#input_instance_id) | The instance id of the target\_host, used to track when to reinstall the machine | `string` | `null` | no | -| [kexec\_tarball\_url](#input_kexec_tarball_url) | NixOS kexec installer tarball url | `string` | `null` | no | -| [nixos\_facter\_path](#input_nixos_facter_path) | Path to which to write a `facter.json` generated by `nixos-facter`. This option cannot be set at the same time as `nixos_generate_config_path`. | `string` | `""` | no | -| [nixos\_generate\_config\_path](#input_nixos_generate_config_path) | Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. This option cannot be set at the same time as `nixos_facter_path`. | `string` | `""` | no | -| [nixos\_partitioner](#input_nixos_partitioner) | nixos partitioner and mount script | `string` | `""` | no | -| [nixos\_system](#input_nixos_system) | The nixos system to deploy | `string` | `""` | no | -| [no\_reboot](#input_no_reboot) | DEPRECATED: Use `phases` instead. Do not reboot after installation | `bool` | `false` | no | -| [phases](#input_phases) | Phases to run. See `nixos-anywhere --help` for more information | `list(string)` |
[
"kexec",
"disko",
"install",
"reboot"
]
| no | -| [ssh\_private\_key](#input_ssh_private_key) | Content of private key used to connect to the target\_host | `string` | `""` | no | -| [stop\_after\_disko](#input_stop_after_disko) | DEPRECATED: Use `phases` instead. Exit after disko formatting | `bool` | `false` | no | -| [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes | -| [target\_pass](#input_target_pass) | Password used to connect to the target\_host | `string` | `null` | no | -| [target\_port](#input_target_port) | SSH port used to connect to the target\_host | `number` | `22` | no | -| [target\_user](#input_target_user) | SSH user used to connect to the target\_host | `string` | `"root"` | no | - -## Outputs - -No outputs. - - diff --git a/launch/.terraform/modules/peertube.deploy/terraform/install/main.tf b/launch/.terraform/modules/peertube.deploy/terraform/install/main.tf deleted file mode 100644 index 9f1816ac..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/install/main.tf +++ /dev/null @@ -1,35 +0,0 @@ -locals { - disk_encryption_key_scripts = [for k in var.disk_encryption_key_scripts : "\"${k.path}\" \"${k.script}\""] - removed_phases = setunion(var.stop_after_disko ? ["install"] : [], (var.no_reboot ? ["reboot"] : [])) - phases = setsubtract(var.phases, local.removed_phases) - arguments = jsonencode({ - ssh_private_key = var.ssh_private_key - debug_logging = var.debug_logging - kexec_tarball_url = var.kexec_tarball_url - nixos_partitioner = var.nixos_partitioner - nixos_system = var.nixos_system - target_user = var.target_user - target_host = var.target_host - target_port = var.target_port - target_pass = var.target_pass - extra_files_script = var.extra_files_script - build_on_remote = var.build_on_remote - flake = var.flake - phases = join(",", local.phases) - nixos_generate_config_path = var.nixos_generate_config_path - nixos_facter_path = var.nixos_facter_path - }) -} - -resource "null_resource" "nixos-remote" { - triggers = { - instance_id = var.instance_id - } - provisioner "local-exec" { - environment = merge({ - ARGUMENTS = local.arguments - }, var.extra_environment) - command = "${path.module}/run-nixos-anywhere.sh ${join(" ", local.disk_encryption_key_scripts)}" - quiet = var.debug_logging - } -} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/install/providers.tf b/launch/.terraform/modules/peertube.deploy/terraform/install/providers.tf deleted file mode 100644 index c3e00a54..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/install/providers.tf +++ /dev/null @@ -1,5 +0,0 @@ -terraform { - required_providers { - null = { source = "hashicorp/null" } - } -} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/install/run-nixos-anywhere.sh b/launch/.terraform/modules/peertube.deploy/terraform/install/run-nixos-anywhere.sh deleted file mode 100755 index 1d259a1e..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/install/run-nixos-anywhere.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" - -declare -A input - -while IFS= read -r -d '' key && IFS= read -r -d '' value; do - input[$key]=$value -done < <(jq -j 'to_entries[] | (.key, "\u0000", .value, "\u0000")' <<<"${ARGUMENTS}") - -args=() - -if [[ ${input[debug_logging]} == "true" ]]; then - set -x - declare -p input - args+=("--debug") -fi -if [[ ${input[kexec_tarball_url]} != "null" ]]; then - args+=("--kexec" "${input[kexec_tarball_url]}") -fi -if [[ ${input[build_on_remote]} == "true" ]]; then - args+=("--build-on-remote") -fi -if [[ -n ${input[flake]} ]]; then - args+=("--flake" "${input[flake]}") -else - args+=("--store-paths" "${input[nixos_partitioner]}" "${input[nixos_system]}") -fi -if [[ -n ${input[nixos_generate_config_path]} ]]; then - if [[ -n ${input[nixos_facter_path]} ]]; then - echo "cannot set both variables 'nixos_generate_config_path' and 'nixos_facter_path'!" >&2 - exit 1 - fi - args+=("--generate-hardware-config" "nixos-generate-config" "${input[nixos_generate_config_path]}") -elif [[ -n ${input[nixos_facter_path]} ]]; then - args+=("--generate-hardware-config" "nixos-facter" "${input[nixos_facter_path]}") -fi -args+=(--phases "${input[phases]}") -if [[ ${input[ssh_private_key]} != null ]]; then - export SSH_PRIVATE_KEY="${input[ssh_private_key]}" -fi -if [[ ${input[target_pass]} != null ]]; then - export SSHPASS=${input[target_pass]} - args+=("--env-password") -fi - -tmpdir=$(mktemp -d) -cleanup() { - rm -rf "${tmpdir}" -} -trap cleanup EXIT - -if [[ ${input[extra_files_script]} != "null" ]]; then - if [[ ! -f ${input[extra_files_script]} ]]; then - echo "extra_files_script '${input[extra_files_script]}' does not exist" - exit 1 - fi - if [[ ! -x ${input[extra_files_script]} ]]; then - echo "extra_files_script '${input[extra_files_script]}' is not executable" - exit 1 - fi - extra_files_script=$(realpath "${input[extra_files_script]}") - mkdir "${tmpdir}/extra-files" - pushd "${tmpdir}/extra-files" - $extra_files_script - popd - args+=("--extra-files" "${tmpdir}/extra-files") -fi - -args+=("-p" "${input[target_port]}") -args+=("${input[target_user]}@${input[target_host]}") - -keyIdx=0 -while [[ $# -gt 0 ]]; do - if [[ ! -f $2 ]]; then - echo "Script file '$2' does not exist" - exit 1 - fi - if [[ ! -x $2 ]]; then - echo "Script file '$2' is not executable" - exit 1 - fi - mkdir -p "${tmpdir}/keys" - "$2" >"${tmpdir}/keys/$keyIdx" - args+=("--disk-encryption-keys" "$1" "${tmpdir}/keys/$keyIdx") - shift - shift - keyIdx=$((keyIdx + 1)) -done - -nix run --extra-experimental-features 'nix-command flakes' "path:${SCRIPT_DIR}/../..#nixos-anywhere" -- "${args[@]}" diff --git a/launch/.terraform/modules/peertube.deploy/terraform/install/variables.tf b/launch/.terraform/modules/peertube.deploy/terraform/install/variables.tf deleted file mode 100644 index cd07bf70..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/install/variables.tf +++ /dev/null @@ -1,123 +0,0 @@ -variable "kexec_tarball_url" { - type = string - description = "NixOS kexec installer tarball url" - default = null -} - -# To make this re-usable we maybe should accept a store path here? -variable "nixos_partitioner" { - type = string - description = "nixos partitioner and mount script" - default = "" -} - -# To make this re-usable we maybe should accept a store path here? -variable "nixos_system" { - type = string - description = "The nixos system to deploy" - default = "" -} - -variable "target_host" { - type = string - description = "DNS host to deploy to" -} - -variable "target_user" { - type = string - description = "SSH user used to connect to the target_host" - default = "root" -} - -variable "target_port" { - type = number - description = "SSH port used to connect to the target_host" - default = 22 -} - -variable "target_pass" { - type = string - description = "Password used to connect to the target_host" - default = null -} - -variable "ssh_private_key" { - type = string - description = "Content of private key used to connect to the target_host" - default = "" -} - -variable "instance_id" { - type = string - description = "The instance id of the target_host, used to track when to reinstall the machine" - default = null -} - -variable "debug_logging" { - type = bool - description = "Enable debug logging" - default = false -} - -variable "extra_files_script" { - type = string - description = "A script that should place files in the current directory that will be copied to the targets / directory" - default = null -} - -variable "disk_encryption_key_scripts" { - type = list(object({ - path = string - script = string - })) - description = "Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system" - default = [] -} - -variable "extra_environment" { - type = map(string) - description = "Extra environment variables to be set during installation. This can be useful to set extra variables for the extra_files_script or disk_encryption_key_scripts" - default = {} -} - -variable "stop_after_disko" { - type = bool - description = "DEPRECATED: Use `phases` instead. Exit after disko formatting" - default = false -} - -variable "no_reboot" { - type = bool - description = "DEPRECATED: Use `phases` instead. Do not reboot after installation" - default = false -} - -variable "phases" { - type = list(string) - description = "Phases to run. See `nixos-anywhere --help` for more information" - default = ["kexec", "disko", "install", "reboot"] -} - -variable "build_on_remote" { - type = bool - description = "Build the closure on the remote machine instead of building it locally and copying it over" - default = false -} - -variable "flake" { - type = string - description = "The flake to install the system from" - default = "" -} - -variable "nixos_generate_config_path" { - type = string - description = "Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. This option cannot be set at the same time as `nixos_facter_path`." - default = "" -} - -variable "nixos_facter_path" { - type = string - description = "Path to which to write a `facter.json` generated by `nixos-facter`. This option cannot be set at the same time as `nixos_generate_config_path`." - default = "" -} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nix-build.md b/launch/.terraform/modules/peertube.deploy/terraform/nix-build.md deleted file mode 100644 index fe63af12..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/nix-build.md +++ /dev/null @@ -1,47 +0,0 @@ -# Nix-build - -Small helper module to run do build a flake attribute or attribute from a nix -file. - -## Example - -- See [install](install.md) or [nixos-rebuild](nixos-rebuild.md) - - - -## Requirements - -No requirements. - -## Providers - -| Name | Version | -| --------------------------------------------------------------- | ------- | -| [external](#provider_external) | n/a | - -## Modules - -No modules. - -## Resources - -| Name | Type | -| --------------------------------------------------------------------------------------------------------------------------- | ----------- | -| [external_external.nix-build](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -| ---------------------------------------------------------------------- | --------------------------------------------------- | ------------- | ------- | :------: | -| [attribute](#input_attribute) | the attribute to build, can also be a flake | `string` | n/a | yes | -| [file](#input_file) | the nix file to evaluate, if not run in flake mode | `string` | `null` | no | -| [nix\_options](#input_nix_options) | the options of nix | `map(string)` | `{}` | no | -| [special\_args](#input_special_args) | A map exposed as NixOS's `specialArgs` thru a file. | `any` | `{}` | no | - -## Outputs - -| Name | Description | -| ----------------------------------------------------- | ----------- | -| [result](#output_result) | n/a | - - diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nix-build/main.tf b/launch/.terraform/modules/peertube.deploy/terraform/nix-build/main.tf deleted file mode 100644 index 7a3c335f..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/nix-build/main.tf +++ /dev/null @@ -1,17 +0,0 @@ -locals { - nix_options = jsonencode({ - options = { for k, v in var.nix_options : k => v } - }) -} -data "external" "nix-build" { - program = [ "${path.module}/nix-build.sh" ] - query = { - attribute = var.attribute - file = var.file - nix_options = local.nix_options - special_args = jsonencode(var.special_args) - } -} -output "result" { - value = data.external.nix-build.result -} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nix-build/nix-build.sh b/launch/.terraform/modules/peertube.deploy/terraform/nix-build/nix-build.sh deleted file mode 100755 index 0e22357e..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/nix-build/nix-build.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash -set -efu - -declare file attribute nix_options special_args -eval "$(jq -r '@sh "attribute=\(.attribute) file=\(.file) nix_options=\(.nix_options) special_args=\(.special_args)"')" -if [ "${nix_options}" != '{"options":{}}' ]; then - options=$(echo "${nix_options}" | jq -r '.options | to_entries | map("--option \(.key) \(.value)") | join(" ")') -else - options="" -fi -if [[ ${special_args-} == "{}" ]]; then - # no special arguments, proceed as normal - if [[ -n ${file-} ]] && [[ -e ${file-} ]]; then - # shellcheck disable=SC2086 - out=$(nix build --no-link --json $options -f "$file" "$attribute") - else - # shellcheck disable=SC2086 - out=$(nix build --no-link --json ${options} "$attribute") - fi -else - if [[ ${file-} != 'null' ]]; then - echo "special_args are currently only supported when using flakes!" >&2 - exit 1 - fi - # pass the args in a pure fashion by extending the original config - rest="$(echo "${attribute}" | cut -d "#" -f 2)" - # e.g. config_path=nixosConfigurations.aarch64-linux.myconfig - config_path="${rest%.config.*}" - # e.g. config_attribute=config.system.build.toplevel - config_attribute="config.${rest#*.config.}" - - # grab flake nar from error message - flake_rel="$(echo "${attribute}" | cut -d "#" -f 1)" - # e.g. flake_rel="." - flake_dir="$(readlink -f "${flake_rel}")" - flake_path="${flake_dir}/flake.nix" - flake_json="$(nix flake prefetch "${flake_dir}" --json)" - flake_nar="$(echo "$flake_json" | jq -r '.hash')" - store_path="$(echo "${flake_json}" | jq -r '.storePath')" - # while we have a store path now, for a repo this reflects its root level, - # so search for the largest child segment yielding a match in that store dir. - iter_path="${flake_path}" - while [[ ${iter_path} != "/" ]]; do - parent="$(dirname "${iter_path}")" - child_segment="${flake_path//$parent/}" - if [[ -f "${store_path}${child_segment}" ]]; then - target_segment="${child_segment}" - fi - iter_path="${parent}" - done - # substitute variables into the template - nix_expr="(builtins.getFlake ''file://${flake_dir}?dir=${target_segment//\/flake.nix/}&narHash=${flake_nar}'').${config_path}.extendModules { specialArgs = builtins.fromJSON ''${special_args}''; }" - # inject `special_args` into nixos config's `specialArgs` - # shellcheck disable=SC2086 - out=$(nix build --no-link --json ${options} --expr "${nix_expr}" "${config_attribute}") -fi -printf '%s' "$out" | jq -c '.[].outputs' diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nix-build/variables.tf b/launch/.terraform/modules/peertube.deploy/terraform/nix-build/variables.tf deleted file mode 100644 index bad23f73..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/nix-build/variables.tf +++ /dev/null @@ -1,22 +0,0 @@ -variable "attribute" { - type = string - description = "the attribute to build, can also be a flake" -} - -variable "file" { - type = string - description = "the nix file to evaluate, if not run in flake mode" - default = null -} - -variable "nix_options" { - type = map(string) - description = "the options of nix" - default = {} -} - -variable "special_args" { - type = any - default = {} - description = "A map exposed as NixOS's `specialArgs` thru a file." -} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild.md b/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild.md deleted file mode 100644 index 0be26bb7..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild.md +++ /dev/null @@ -1,66 +0,0 @@ -# Nixos-rebuild - -Update NixOS machine with nixos-rebuild on a remote machine - -## Example - -```hcl -locals { - ipv4 = "192.0.2.1" -} - -module "system-build" { - source = "github.com/nix-community/nixos-anywhere//terraform/nix-build" - # with flakes - attribute = ".#nixosConfigurations.mymachine.config.system.build.toplevel" - # without flakes - # file can use (pkgs.nixos []) function from nixpkgs - #file = "${path.module}/../.." - #attribute = "config.system.build.toplevel" -} - -module "deploy" { - source = "github.com/nix-community/nixos-anywhere//terraform/nixos-rebuild" - nixos_system = module.system-build.result.out - target_host = local.ipv4 -} -``` - - - -## Requirements - -No requirements. - -## Providers - -| Name | Version | -| --------------------------------------------------- | ------- | -| [null](#provider_null) | n/a | - -## Modules - -No modules. - -## Resources - -| Name | Type | -| -------------------------------------------------------------------------------------------------------------------- | -------- | -| [null_resource.nixos-rebuild](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | - -## Inputs - -| Name | Description | Type | Default | Required | -| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------- | -------- | :------: | -| [ignore\_systemd\_errors](#input_ignore_systemd_errors) | Ignore systemd errors happening during deploy | `bool` | `false` | no | -| [nixos\_system](#input_nixos_system) | The nixos system to deploy | `string` | n/a | yes | -| [ssh\_private\_key](#input_ssh_private_key) | Content of private key used to connect to the target\_host. If set to - no key is passed to openssh and ssh will use its own configuration | `string` | `"-"` | no | -| [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes | -| [target\_port](#input_target_port) | SSH port used to connect to the target\_host | `number` | `22` | no | -| [target\_user](#input_target_user) | User to deploy as | `string` | `"root"` | no | - -## Outputs - -No outputs. - - diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/deploy.sh b/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/deploy.sh deleted file mode 100755 index 61da6e1c..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/deploy.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash - -set -uex -o pipefail - -if [ "$#" -ne 6 ]; then - echo "USAGE: $0 NIXOS_SYSTEM TARGET_USER TARGET_HOST TARGET_PORT IGNORE_SYSTEMD_ERRORS INSTALL_BOOTLOADER" >&2 - exit 1 -fi - -NIXOS_SYSTEM=$1 -TARGET_USER=$2 -TARGET_HOST=$3 -TARGET_PORT=$4 -IGNORE_SYSTEMD_ERRORS=$5 -INSTALL_BOOTLOADER=$6 - -shift 6 - -TARGET="${TARGET_USER}@${TARGET_HOST}" - -workDir=$(mktemp -d) -trap 'rm -rf "$workDir"' EXIT - -sshOpts=(-p "${TARGET_PORT}") -sshOpts+=(-o UserKnownHostsFile=/dev/null) -sshOpts+=(-o StrictHostKeyChecking=no) - -set +x -if [[ -n ${SSH_KEY+x} && ${SSH_KEY} != "-" ]]; then - sshPrivateKeyFile="$workDir/ssh_key" - # Create the file with 0700 - umask calculation: 777 - 700 = 077 - ( - umask 077 - echo "$SSH_KEY" >"$sshPrivateKeyFile" - ) - unset SSH_AUTH_SOCK # don't use system agent if key was supplied - sshOpts+=(-o "IdentityFile=${sshPrivateKeyFile}") -fi -set -x - -try=1 -until NIX_SSHOPTS="${sshOpts[*]}" nix copy -s --experimental-features nix-command --to "ssh://$TARGET" "$NIXOS_SYSTEM"; do - if [[ $try -gt 10 ]]; then - echo "retries exhausted" >&2 - exit 1 - fi - sleep 10 - try=$((try + 1)) -done - -if [[ $INSTALL_BOOTLOADER == "true" ]]; then - extra_env='NIXOS_INSTALL_BOOTLOADER=1' -else - extra_env='' -fi - -switchCommand="nix-env -p /nix/var/nix/profiles/system --set $(printf "%q" "$NIXOS_SYSTEM"); $extra_env /nix/var/nix/profiles/system/bin/switch-to-configuration switch" - -if [[ $TARGET_USER != "root" ]]; then - switchCommand="sudo bash -c '$switchCommand'" -fi -deploy_status=0 -# shellcheck disable=SC2029 -ssh "${sshOpts[@]}" "$TARGET" "$switchCommand" || deploy_status="$?" -if [[ $IGNORE_SYSTEMD_ERRORS == "true" && $deploy_status == "4" ]]; then - exit 0 -fi -exit "$deploy_status" diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/main.tf b/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/main.tf deleted file mode 100644 index 84461c80..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/main.tf +++ /dev/null @@ -1,11 +0,0 @@ -resource "null_resource" "nixos-rebuild" { - triggers = { - store_path = var.nixos_system - } - provisioner "local-exec" { - environment = { - SSH_KEY = var.ssh_private_key - } - command = "${path.module}/deploy.sh ${var.nixos_system} ${var.target_user} ${var.target_host} ${var.target_port} ${var.ignore_systemd_errors} ${var.install_bootloader}" - } -} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/variables.tf b/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/variables.tf deleted file mode 100644 index 90e0b0c6..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/variables.tf +++ /dev/null @@ -1,39 +0,0 @@ -variable "nixos_system" { - type = string - description = "The nixos system to deploy" -} - -variable "target_host" { - type = string - description = "DNS host to deploy to" -} - -variable "target_user" { - type = string - default = "root" - description = "User to deploy as" -} - -variable "target_port" { - type = number - description = "SSH port used to connect to the target_host" - default = 22 -} - -variable "ssh_private_key" { - type = string - description = "Content of private key used to connect to the target_host. If set to - no key is passed to openssh and ssh will use its own configuration" - default = "-" -} - -variable "ignore_systemd_errors" { - type = bool - description = "Ignore systemd errors happening during deploy" - default = false -} - -variable "install_bootloader" { - type = bool - description = "Install/re-install the bootloader" - default = false -} diff --git a/launch/.terraform/modules/peertube.deploy/terraform/update-docs.sh b/launch/.terraform/modules/peertube.deploy/terraform/update-docs.sh deleted file mode 100755 index b67d98ad..00000000 --- a/launch/.terraform/modules/peertube.deploy/terraform/update-docs.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd "$SCRIPT_DIR" -files=() -find "${SCRIPT_DIR}"/* -type d | while read -r i; do - module_name=$(basename "$i") - markdown_file="${SCRIPT_DIR}/${module_name}.md" - terraform-docs --config "${SCRIPT_DIR}/.terraform-docs.yml" markdown table --output-file "${markdown_file}" --output-mode inject "${module_name}" - files+=("${markdown_file}") -done -cd .. -nix fmt -- --no-cache diff --git a/launch/.terraform/modules/peertube.deploy/tests/flake-module.nix b/launch/.terraform/modules/peertube.deploy/tests/flake-module.nix deleted file mode 100644 index 784175f4..00000000 --- a/launch/.terraform/modules/peertube.deploy/tests/flake-module.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ withSystem, inputs, ... }: - -{ - flake.checks.x86_64-linux = withSystem "x86_64-linux" ( - { - pkgs, - system, - inputs', - config, - ... - }: - let - testInputsUnstable = { - inherit pkgs; - inherit (inputs.disko.nixosModules) disko; - nixos-anywhere = config.packages.nixos-anywhere; - kexec-installer = "${inputs'.nixos-images.packages.kexec-installer-nixos-unstable-noninteractive}/nixos-kexec-installer-noninteractive-${system}.tar.gz"; - }; - testInputsStable = testInputsUnstable // { - kexec-installer = "${inputs'.nixos-images.packages.kexec-installer-nixos-stable-noninteractive}/nixos-kexec-installer-noninteractive-${system}.tar.gz"; - }; - in - { - from-nixos = import ./from-nixos.nix testInputsUnstable; - from-nixos-stable = import ./from-nixos.nix testInputsStable; - from-nixos-with-sudo = import ./from-nixos-with-sudo.nix testInputsUnstable; - from-nixos-with-sudo-stable = import ./from-nixos-with-sudo.nix testInputsStable; - from-nixos-with-generated-config = import ./from-nixos-generate-config.nix testInputsUnstable; - from-nixos-build-on-remote = import ./from-nixos-build-on-remote.nix testInputsUnstable; - from-nixos-separated-phases = import ./from-nixos-separated-phases.nix testInputsUnstable; - } - ); -} diff --git a/launch/.terraform/modules/peertube.deploy/tests/from-nixos-build-on-remote.nix b/launch/.terraform/modules/peertube.deploy/tests/from-nixos-build-on-remote.nix deleted file mode 100644 index 52617133..00000000 --- a/launch/.terraform/modules/peertube.deploy/tests/from-nixos-build-on-remote.nix +++ /dev/null @@ -1,56 +0,0 @@ -(import ./lib/test-base.nix) ( - { pkgs, ... }: - { - name = "from-nixos-build-on-remote"; - nodes = { - installer = ./modules/installer.nix; - installed = { - services.openssh.enable = true; - virtualisation.memorySize = 1024; - - users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; - }; - }; - testScript = '' - def create_test_machine( - oldmachine=None, **kwargs - ): # taken from - start_command = [ - "${pkgs.qemu_test}/bin/qemu-kvm", - "-cpu", - "max", - "-m", - "1024", - "-virtfs", - "local,path=/nix/store,security_model=none,mount_tag=nix-store", - "-drive", - f"file={oldmachine.state_dir}/installed.qcow2,id=drive1,if=none,index=1,werror=report", - "-device", - "virtio-blk-pci,drive=drive1", - ] - machine = create_machine(start_command=" ".join(start_command), **kwargs) - driver.machines.append(machine) - return machine - start_all() - - installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --build-on-remote \ - --kexec /etc/nixos-anywhere/kexec-installer \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - root@installed >&2 - """) - try: - installed.shutdown() - except BrokenPipeError: - # qemu has already exited - pass - new_machine = create_test_machine(oldmachine=installed, name="after_install") - new_machine.start() - hostname = new_machine.succeed("hostname").strip() - assert "nixos-anywhere" == hostname, f"'nixos-anywhere' != '{hostname}'" - ''; - } -) diff --git a/launch/.terraform/modules/peertube.deploy/tests/from-nixos-generate-config.nix b/launch/.terraform/modules/peertube.deploy/tests/from-nixos-generate-config.nix deleted file mode 100644 index 5b4d65dd..00000000 --- a/launch/.terraform/modules/peertube.deploy/tests/from-nixos-generate-config.nix +++ /dev/null @@ -1,71 +0,0 @@ -(import ./lib/test-base.nix) { - name = "from-nixos-generate-config"; - nodes = { - installer = - { pkgs, ... }: - { - imports = [ - ./modules/installer.nix - ]; - environment.systemPackages = [ pkgs.jq ]; - }; - installed = { - services.openssh.enable = true; - virtualisation.memorySize = 1024; - - users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; - }; - }; - testScript = '' - start_all() - installer.fail("test -f /tmp/hw/config.nix") - installer.succeed("echo super-secret > /tmp/disk-1.key") - output = installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --kexec /etc/nixos-anywhere/kexec-installer \ - --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ - --disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \ - --phases kexec,disko \ - --generate-hardware-config nixos-generate-config /tmp/hw/config.nix \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - root@installed >&2 - echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat /tmp/disk-1.key)'" - echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat /tmp/disk-2.key)'" - """) - - installer.succeed("cat /tmp/hw/config.nix >&2") - installer.succeed("nix-instantiate --parse /tmp/hw/config.nix") - - assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}" - assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}" - - installer.fail("test -f /test/hw/config.json") - - output = installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --kexec /etc/nixos-anywhere/kexec-installer \ - --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ - --disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \ - --phases kexec,disko \ - --generate-hardware-config nixos-facter /tmp/hw/config.json \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - installed >&2 - echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat /tmp/disk-1.key)'" - echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat /tmp/disk-2.key)'" - """) - - installer.succeed("cat /tmp/hw/config.json >&2") - installer.succeed("jq < /tmp/hw/config.json") - - assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}" - assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}" - ''; -} diff --git a/launch/.terraform/modules/peertube.deploy/tests/from-nixos-separated-phases.nix b/launch/.terraform/modules/peertube.deploy/tests/from-nixos-separated-phases.nix deleted file mode 100644 index 2b267b69..00000000 --- a/launch/.terraform/modules/peertube.deploy/tests/from-nixos-separated-phases.nix +++ /dev/null @@ -1,52 +0,0 @@ -(import ./lib/test-base.nix) { - name = "from-nixos-separated-phases"; - nodes = { - installer = ./modules/installer.nix; - installed = { - services.openssh.enable = true; - virtualisation.memorySize = 1024; - - users.users.nixos = { - isNormalUser = true; - openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; - extraGroups = [ "wheel" ]; - }; - security.sudo.enable = true; - security.sudo.wheelNeedsPassword = false; - }; - }; - testScript = '' - start_all() - - with subtest("Kexec Phase"): - installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --kexec /etc/nixos-anywhere/kexec-installer \ - --phases kexec \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - nixos@installed >&2 - """) - - with subtest("Disko Phase"): - output = installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --phases disko \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - installed >&2 - """) - - with subtest("Install Phase"): - installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --phases install \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - root@installed >&2 - """) - ''; -} diff --git a/launch/.terraform/modules/peertube.deploy/tests/from-nixos-with-sudo.nix b/launch/.terraform/modules/peertube.deploy/tests/from-nixos-with-sudo.nix deleted file mode 100644 index 839dec38..00000000 --- a/launch/.terraform/modules/peertube.deploy/tests/from-nixos-with-sudo.nix +++ /dev/null @@ -1,40 +0,0 @@ -(import ./lib/test-base.nix) { - name = "from-nixos-with-sudo"; - nodes = { - installer = ./modules/installer.nix; - installed = { - services.openssh.enable = true; - virtualisation.memorySize = 1024; - - users.users.nixos = { - isNormalUser = true; - openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; - extraGroups = [ "wheel" ]; - }; - security.sudo.enable = true; - security.sudo.wheelNeedsPassword = false; - }; - }; - testScript = '' - start_all() - installer.succeed("echo super-secret > /tmp/disk-1.key") - output = installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --kexec /etc/nixos-anywhere/kexec-installer \ - --phases kexec,disko \ - --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ - --disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - nixos@installed >&2 - echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat /tmp/disk-1.key)'" - echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat /tmp/disk-2.key)'" - """) - - assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}" - assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}" - ''; -} diff --git a/launch/.terraform/modules/peertube.deploy/tests/from-nixos.nix b/launch/.terraform/modules/peertube.deploy/tests/from-nixos.nix deleted file mode 100644 index 0f3d1344..00000000 --- a/launch/.terraform/modules/peertube.deploy/tests/from-nixos.nix +++ /dev/null @@ -1,76 +0,0 @@ -(import ./lib/test-base.nix) ( - { pkgs, ... }: - { - name = "from-nixos"; - nodes = { - installer = ./modules/installer.nix; - installed = { - services.openssh.enable = true; - virtualisation.memorySize = 1024; - - users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; - }; - }; - testScript = '' - def create_test_machine( - oldmachine=None, **kwargs - ): # taken from - start_command = [ - "${pkgs.qemu_test}/bin/qemu-kvm", - "-cpu", - "max", - "-m", - "1024", - "-virtfs", - "local,path=/nix/store,security_model=none,mount_tag=nix-store", - "-drive", - f"file={oldmachine.state_dir}/installed.qcow2,id=drive1,if=none,index=1,werror=report", - "-device", - "virtio-blk-pci,drive=drive1", - ] - machine = create_machine(start_command=" ".join(start_command), **kwargs) - driver.machines.append(machine) - return machine - start_all() - installer.succeed("mkdir -p /tmp/extra-files/var/lib/secrets") - installer.succeed("echo value > /tmp/extra-files/var/lib/secrets/key") - installer.succeed("mkdir -p /tmp/extra-files/home/user/.ssh") - installer.succeed("echo secretkey > /tmp/extra-files/home/user/.ssh/id_ed25519") - installer.succeed("echo publickey > /tmp/extra-files/home/user/.ssh/id_ed25519.pub") - installer.succeed("chmod 600 /tmp/extra-files/home/user/.ssh/id_ed25519") - ssh_key_path = "/etc/ssh/ssh_host_ed25519_key.pub" - ssh_key_output = installer.wait_until_succeeds(f""" - ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat {ssh_key_path} - """) - installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --kexec /etc/nixos-anywhere/kexec-installer \ - --extra-files /tmp/extra-files \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - --chown /home/user 1000:100 \ - --copy-host-keys \ - root@installed >&2 - """) - try: - installed.shutdown() - except BrokenPipeError: - # qemu has already exited - pass - new_machine = create_test_machine(oldmachine=installed, name="after_install") - new_machine.start() - hostname = new_machine.succeed("hostname").strip() - assert "nixos-anywhere" == hostname, f"'nixos-anywhere' != '{hostname}'" - content = new_machine.succeed("cat /var/lib/secrets/key").strip() - assert "value" == content, f"secret does not have expected value: {content}" - ssh_key_content = new_machine.succeed(f"cat {ssh_key_path}").strip() - assert ssh_key_content in ssh_key_output, "SSH host identity changed" - priv_key_perms = new_machine.succeed("stat -c %a /home/user/.ssh/id_ed25519").strip() - assert priv_key_perms == "600", f"unexpected permissions for private key: {priv_key_perms}" - user_dir_ownership = new_machine.succeed("stat -c %u:%g /home/user").strip() - assert user_dir_ownership == "1000:100", f"unexpected user home dir permissions: {user_dir_ownership}" - ''; - } -) diff --git a/launch/.terraform/modules/peertube.deploy/tests/lib/test-base.nix b/launch/.terraform/modules/peertube.deploy/tests/lib/test-base.nix deleted file mode 100644 index 169d1fd2..00000000 --- a/launch/.terraform/modules/peertube.deploy/tests/lib/test-base.nix +++ /dev/null @@ -1,20 +0,0 @@ -test: -{ - pkgs ? import { }, - nixos-anywhere ? pkgs.callPackage ../../src { }, - disko ? "${builtins.fetchTarball "https://github.com/nix-community/disko/archive/master.tar.gz"}/module.nix", - kexec-installer ? builtins.fetchurl "https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-${pkgs.stdenv.hostPlatform.system}.tar.gz", - ... -}: -let - inherit (pkgs) lib; - nixos-lib = import (pkgs.path + "/nixos/lib") { }; -in -(nixos-lib.runTest { - hostPkgs = pkgs; - # speed-up evaluation - defaults.documentation.enable = lib.mkDefault false; - # to accept external dependencies such as disko - node.specialArgs.inputs = { inherit nixos-anywhere disko kexec-installer; }; - imports = [ test ]; -}).config.result diff --git a/launch/.terraform/modules/peertube.deploy/tests/modules/installer.nix b/launch/.terraform/modules/peertube.deploy/tests/modules/installer.nix deleted file mode 100644 index e5c22d4d..00000000 --- a/launch/.terraform/modules/peertube.deploy/tests/modules/installer.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ pkgs, inputs, ... }: -let - disko = inputs.disko; - kexec-installer = inputs.kexec-installer; - system-to-install = pkgs.nixos [ - ./system-to-install.nix - disko - ]; -in -{ - system.activationScripts.rsa-key = '' - ${pkgs.coreutils}/bin/install -D -m600 ${./ssh-keys/ssh} /root/.ssh/install_key - ''; - - environment.systemPackages = [ inputs.nixos-anywhere ]; - - environment.etc = { - "nixos-anywhere/disko".source = system-to-install.config.system.build.diskoScriptNoDeps; - "nixos-anywhere/system-to-install".source = system-to-install.config.system.build.toplevel; - "nixos-anywhere/kexec-installer".source = kexec-installer; - }; -} diff --git a/launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh b/launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh deleted file mode 100644 index db6049c5..00000000 --- a/launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN OPENSSH PRIVATE KEY----- -b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW -QyNTUxOQAAACDM4kPg4V7DMYceuA8VIUdBvw30gM9qagERA8v1VGBBBQAAAJDpULAq6VCw -KgAAAAtzc2gtZWQyNTUxOQAAACDM4kPg4V7DMYceuA8VIUdBvw30gM9qagERA8v1VGBBBQ -AAAECpjfl5WMMIDvEyZJTeXzRNFzpDpj4fqdIXHZauKAlE5MziQ+DhXsMxhx64DxUhR0G/ -DfSAz2pqAREDy/VUYEEFAAAACWxhc3NAbW9ycwECAwQ= ------END OPENSSH PRIVATE KEY----- diff --git a/launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh.pub b/launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh.pub deleted file mode 100644 index e77d393e..00000000 --- a/launch/.terraform/modules/peertube.deploy/tests/modules/ssh-keys/ssh.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMziQ+DhXsMxhx64DxUhR0G/DfSAz2pqAREDy/VUYEEF diff --git a/launch/.terraform/modules/peertube.deploy/tests/modules/system-to-install.nix b/launch/.terraform/modules/peertube.deploy/tests/modules/system-to-install.nix deleted file mode 100644 index 1181c944..00000000 --- a/launch/.terraform/modules/peertube.deploy/tests/modules/system-to-install.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ modulesPath, self, ... }: -{ - imports = [ - (modulesPath + "/testing/test-instrumentation.nix") - (modulesPath + "/profiles/qemu-guest.nix") - (modulesPath + "/profiles/minimal.nix") - ]; - networking.hostName = "nixos-anywhere"; - documentation.enable = false; - hardware.enableAllFirmware = false; - networking.hostId = "8425e349"; # from profiles/base.nix, needed for zfs - boot.zfs.devNodes = "/dev/disk/by-uuid"; # needed because /dev/disk/by-id is empty in qemu-vms - disko.devices = { - disk = { - vda = { - device = "/dev/vda"; - type = "disk"; - content = { - type = "gpt"; - partitions = { - boot = { - size = "1M"; - type = "EF02"; - }; - ESP = { - size = "100M"; - type = "EF00"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - }; - }; - root = { - size = "100%"; - content = { - type = "filesystem"; - format = "ext4"; - mountpoint = "/"; - }; - }; - }; - }; - }; - }; - }; -} diff --git a/launch/.terraform/modules/peertube.deploy/treefmt/flake-module.nix b/launch/.terraform/modules/peertube.deploy/treefmt/flake-module.nix deleted file mode 100644 index 3e92a8ed..00000000 --- a/launch/.terraform/modules/peertube.deploy/treefmt/flake-module.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ inputs, ... }: -{ - imports = [ - inputs.treefmt-nix.flakeModule - ]; - perSystem = - { config, pkgs, ... }: - { - treefmt = { - projectRootFile = "flake.nix"; - programs.mdsh.enable = true; - programs.nixpkgs-fmt.enable = true; - programs.shellcheck.enable = true; - programs.shfmt.enable = true; - programs.deno.enable = !pkgs.deno.meta.broken; - settings.formatter.shellcheck.options = [ - "-s" - "bash" - ]; - }; - formatter = config.treefmt.build.wrapper; - }; -} diff --git a/launch/.terraform/modules/peertube.deploy~f00c14b (get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes) b/launch/.terraform/modules/peertube.deploy~f00c14b (get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes) new file mode 120000 index 00000000..ba6efefb --- /dev/null +++ b/launch/.terraform/modules/peertube.deploy~f00c14b (get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes) @@ -0,0 +1 @@ +/nix/store/q68mw6lmjjhrvcrhb0pcm9i0v6m3v7cn-source \ No newline at end of file diff --git a/launch/.terraform/modules/pixelfed.deploy/CONTRIBUTING.md b/launch/.terraform/modules/pixelfed.deploy/CONTRIBUTING.md deleted file mode 100644 index 3aeefa73..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/CONTRIBUTING.md +++ /dev/null @@ -1,23 +0,0 @@ -To run `nixos-anywhere` from the repo: - -```console -nix run . -- --help -``` - -To format the code: - -```console -nix fmt -``` - -To run all tests: - -```console -nix flake check -vL -``` - -To run an individual test: - -``` -nix build .#checks.x86_64-linux.from-nixos -vL -``` diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/INDEX.md b/launch/.terraform/modules/pixelfed.deploy/docs/INDEX.md deleted file mode 100644 index 67d48751..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/INDEX.md +++ /dev/null @@ -1,11 +0,0 @@ -# Table of Content: - nixos-anywhere - -**_Install NixOS everywhere via ssh_** - - - -- [README](../README.md) -- [Quickstart](./quickstart.md) -- [System Requirements](./requirements.md) -- [How to Guide](./howtos/INDEX.md) -- [Reference](./reference.md) diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/SUMMARY.md b/launch/.terraform/modules/pixelfed.deploy/docs/SUMMARY.md deleted file mode 100644 index 3bfaea5b..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/SUMMARY.md +++ /dev/null @@ -1,26 +0,0 @@ -# Summary: - nixos-anywhere - -**_Install NixOS everywhere via ssh_** - - - -The **nixos-anywhere** tool allows you to pre-configure the whole process of -installing NixOS, and run the install remotely with a single CLI command. - -Refer to the following documentation for more information. - -[System Requirements](./requirements.md): CPU and memory requirements - -[Quickstart](./quickstart.md): Instructions for a typical installation - -[How to Guide](./howtos/INDEX.md): Instructions for non-typical use cases - -- [Installing on a machine with no operating system](./howtos/no-os.md) -- [Using your own kexec image](./howtos/custom-kexec.md) -- [Secrets and full disk encryption](./howtos/secrets.md) -- [Use without flakes](./howtos/use-without-flakes.md) -- [Terraform](./howtos/terraform.md) -- [Nix-channels / `NIX_PATH`](./howtos/nix-path.md) -- [IPv6-only targets](./howtos/ipv6.md) - -[Reference](./reference.md): Reference Guide diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/book.toml b/launch/.terraform/modules/pixelfed.deploy/docs/book.toml deleted file mode 100644 index d053de4e..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/book.toml +++ /dev/null @@ -1,6 +0,0 @@ -[book] -authors = [ ] -language = "en" -multilingual = false -src = "." -title = "nixos-anywhere - install NixOS everywhere" diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/cli.md b/launch/.terraform/modules/pixelfed.deploy/docs/cli.md deleted file mode 100644 index d2577552..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/cli.md +++ /dev/null @@ -1,63 +0,0 @@ -# CLI - -``` -Usage: nixos-anywhere [options] [] - -Options: - -* -f, --flake - set the flake to install the system from. -* --target-host - specified the SSH target host to deploy onto. -* -i - selects which SSH private key file to use. -* -p, --ssh-port - set the ssh port to connect with -* --ssh-option - set an ssh option -* -L, --print-build-logs - print full build logs -* --env-password - set a password used by ssh-copy-id, the password should be set by - the environment variable SSHPASS -* -s, --store-paths - set the store paths to the disko-script and nixos-system directly - if this is given, flake is not needed -* --no-reboot - do not reboot after installation, allowing further customization of the target installation. -* --kexec - use another kexec tarball to bootstrap NixOS -* --kexec-extra-flags - extra flags to add into the call to kexec, e.g. "--no-sync" -* --ssh-store-setting - ssh store settings appended to the store URI, e.g. "compress true". needs to be URI encoded. -* --post-kexec-ssh-port - after kexec is executed, use a custom ssh port to connect. Defaults to 22 -* --copy-host-keys - copy over existing /etc/ssh/ssh_host_* host keys to the installation -* --stop-after-disko - exit after disko formatting, you can then proceed to install manually or some other way -* --extra-files - contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten - Copied files will be owned by root. See documentation for details. -* --disk-encryption-keys - copy the contents of the file or pipe in local_path to remote_path in the installer environment, - after kexec but before installation. Can be repeated. -* --no-substitute-on-destination - disable passing --substitute-on-destination to nix-copy -* --debug - enable debug output -* --option - nix option to pass to every nix related command -* --from - URL of the source Nix store to copy the nixos and disko closure from -* --build-on-remote - build the closure on the remote machine instead of locally and copy-closuring it -* --vm-test - build the system and test the disk configuration inside a VM without installing it to the target. -* --build-on auto|remote|local - sets the build on settings to auto, remote or local. Default is auto. - auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build - local: will build on the local host - remote: will build on the remote host -``` diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/flake-module.nix b/launch/.terraform/modules/pixelfed.deploy/docs/flake-module.nix deleted file mode 100644 index 2afe9d50..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/flake-module.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ - perSystem = - { pkgs, lib, ... }: - { - packages.docs = - pkgs.runCommand "nixos-anywhere-docs" - { - passthru.serve = pkgs.writeShellScriptBin "serve" '' - set -euo pipefail - cd docs - workdir=$(${pkgs.coreutils}/bin/mktemp -d) - trap 'rm -rf "$workdir"' EXIT - ${pkgs.mdbook}/bin/mdbook serve --dest-dir "$workdir" - ''; - } - '' - cp -r ${lib.cleanSource ./.}/* . - ${pkgs.mdbook}/bin/mdbook build --dest-dir "$out" - ''; - }; -} diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos.md deleted file mode 100644 index bfa55ce1..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/howtos.md +++ /dev/null @@ -1 +0,0 @@ -# How to Guide diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/INDEX.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/INDEX.md deleted file mode 100644 index 2d356638..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/INDEX.md +++ /dev/null @@ -1,29 +0,0 @@ -# How To Guide: nixos-anywhere - -**_Install NixOS everywhere via ssh_** - - - -[Documentation Index](./INDEX.md) - -## Contents - -[Installing on a machine with no operating system](./no-os.md) - -[Kexec on systems with limited RAM](./limited-ram.md) - -[Copying files to the new installation](./extra-files.md) - -[Using your own kexec image](./custom-kexec.md) - -[Repair installations without wiping data](./disko-modes.md) - -[Secrets and full disk encryption](./secrets.md) - -[Use without flakes](./use-without-flakes.md) - -[Terraform](./terraform.md) - -[Nix-channels / `NIX_PATH`](./nix-path.md) - -[IPv6-only targets](./ipv6.md) diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/custom-kexec.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/custom-kexec.md deleted file mode 100644 index 5935a5f3..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/custom-kexec.md +++ /dev/null @@ -1,40 +0,0 @@ -# Using your own kexec image - -By default, `nixos-anywhere` downloads the kexec image from the -[NixOS images repository](https://github.com/nix-community/nixos-images#kexec-tarballs). - -However, you can provide your own `kexec` image file if you need to use a -different one. This is particularly useful for architectures other than `x86_64` -and `aarch64`, since they don't have a pre-build image. - -To do this, use the `--kexec` command line switch followed by the path to your -image file. The image will be uploaded prior to execution. - -Here's an example command that demonstrates how to use a custom kexec image with -`nixos-anywhere`: - -``` -nix run github:nix-community/nixos-anywhere -- \ - --kexec "$(nix build --print-out-paths github:nix-community/nixos-images#packages.aarch64-linux.kexec-installer-nixos-unstable-noninteractive)/nixos-kexec-installer-noninteractive-aarch64-linux.tar.gz" \ - --flake 'github:your-user/your-repo#your-system' \ - root@yourip -``` - -Make sure to replace `github:your-user/your-repo#your-system` with the -appropriate Flake URL representing your NixOS configuration. - -The example above assumes that your local machine can build for aarch64 in one -of the following ways: - -- Natively - -- Through a remote builder - -- By emulating the architecture with qemu using the following NixOS - configuration: - -```nix -{ - boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; -} -``` diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/disko-modes.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/disko-modes.md deleted file mode 100644 index 501f93f1..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/disko-modes.md +++ /dev/null @@ -1,19 +0,0 @@ -# Repair installations without wiping data - -By default, nixos-anywhere will reformat all configured disks before running the -installation. However it is also possible to mount the filesystems of an -existing installation and run `nixos-install`. This is useful to recover from a -misconfigured NixOS installation by first booting into a NixOS installer or -recovery system. - -To only mount existing filesystems, add `--disko-mode mount` to -`nixos-anywhere`: - -``` -nix run github:nix-community/nixos-anywhere -- --disko-mode mount --flake # --target-host root@ -``` - -1. This will first boot into a nixos-installer -2. Mounts disks with disko -3. Runs nixos-install based on the provided flake -4. Reboots the machine. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/extra-files.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/extra-files.md deleted file mode 100644 index ca067d4c..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/extra-files.md +++ /dev/null @@ -1,114 +0,0 @@ -# Copying files to the new installation - -The `--extra-files ` option allows copying files to the target host after -installation. - -The contents of the `` is recursively copied and overwrites the targets -root (/). The contents _must_ be in a structure and permissioned as it should be -on the target. - -In this way, there is no need to repeatedly pass arguments (eg: a fictional -argument: `--copy `) to `nixos-anywhere` to complete the intended -outcome. - -The path and directory structure passed to `--extra-files` should be prepared -beforehand. - -This allows a simple programmatic invocation of `nixos-anywhere` for multiple -hosts. - -## Simple Example - -You want `/etc/ssh/ssh_host_*` and `/persist` from the local system on the -target. The `` contents will look like this: - -```console -$ cd /tmp -$ root=$(mktemp -d) -$ sudo cp --verbose --archive --parents /etc/ssh/ssh_host_* ${root} -$ cp --verbose --archive --link /persist ${root} -``` - -The directory structure would look like this: - -```console -drwx------ myuser1 users 20 tmp.d6nx5QUwPN -drwxr-xr-x root root 6 ├── etc -drwx------ myuser1 users 160 │ └── ssh -.rw------- root root 399 │ ├── ssh_host_ed25519_key -.rw-r--r-- root root 91 │ ├── ssh_host_ed25519_key.pub -drwxr-xr-x myuser1 users 22 └── persist -drwxr-xr-x myuser1 users 14 ├── all -drwxr-xr-x myuser1 users 22 │ ├── my -.rw-r--r-- myuser1 users 6 │ │ ├── test3 -drwxr-xr-x myuser1 users 10 │ │ └── things -.rw-r--r-- myuser1 users 6 │ │ └── test4 -.rw-r--r-- myuser1 users 6 │ └── test2 -drwxr-xr-x myuser1 users 0 ├── blah -.rw-r--r-- myuser1 users 6 └── test -``` - -**NOTE**: Permissions will be copied, but ownership on the target will be root. - -Then pass $root like: - -> nixos-anywhere --flake ".#" --extra-files $root --target-host root@newhost - -## Programmatic Example - -```sh -for host in host1 host2 host3; do - root="target/${host}" - install -d -m755 ${root}/etc/ssh - ssh-keygen -A -C root@${host} -f ${root} - nixos-anywhere --extra-files "${root}" --flake ".#${host}" --target-host "root@${host}" -done -``` - -## Considerations - -### Ownership - -The new system may have differing UNIX user and group id's for users created -during installation. - -When the files are extracted on the remote the copied data will be owned by -root. - -If you wish to change the ownership after the files are copied onto the system, -you can use the `--chown` option. - -For example, if you did `--chown /home/myuser/.ssh 1000:100`, this would equate -to running `chown -R /home/myuser/.ssh 1000:100` where the uid is 1000 and the -gid is 100. **Only do this when you can _guarantee_ what the uid and gid will -be.** - -### Symbolic Links - -Do not create symbolic links to reference data to copy. - -GNU `tar` is used to do the copy over ssh. It is an archival tool used to -re/store directory structures as is. Thus `tar` copies symbolic links created -with `ln -s` by default. It does not follow them to copy the underlying file. - -### Hard links - -**NOTE**: hard links can only be created on the same filesystem. - -If you have larger persistent data to copy to the target. GNU `tar` will copy -data referenced by hard links created with `ln`. A hard link does not create -another copy the data. - -To copy a directory tree to the new target you can use the `cp` command with the -`--link` option which creates hard links. - -#### Example - -```sh -cd /tmp -root=$(mktemp -d) -cp --verbose --archive --link --parents /persist/home/myuser ${root} -``` - -`--parents` will create the directory structure of the source at the -destination. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/ipv6.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/ipv6.md deleted file mode 100644 index 64eb7a6a..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/ipv6.md +++ /dev/null @@ -1,23 +0,0 @@ -# NixOS-anywhere on IPv6-only targets - -As GitHub engineers still haven't enabled the IPv6 switch, the kexec image -hosted on GitHub, cannot be used unfortunately on IPv6-only hosts. However it is -possible to use an IPv6 proxy for GitHub content like that: - -``` -nixos-anywhere \ - --kexec https://gh-v6.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz \ -... -``` - -This proxy is hosted by [numtide](https://numtide.com/). It also works for IPv4. - -Alternatively it is also possible to reference a local file: - -``` -nixos-anywhere \ - --kexec ./nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz \ -... -``` - -This tarball will be then uploaded via sftp to the target. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/limited-ram.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/limited-ram.md deleted file mode 100644 index 0cbac65e..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/limited-ram.md +++ /dev/null @@ -1,29 +0,0 @@ -# Kexec on Systems with Limited RAM - -When working with nixos-anywhere on systems with limited RAM (around 1GB), you -can use the `--no-disko-deps` option to reduce memory usage during installation. - -## How it works - -The `--no-disko-deps` option uploads only the disko partitioning script without -including its dependencies. This significantly reduces memory usage because: - -1. The installer normally stores all dependencies in memory -2. Partitioning tools can be quite large when bundled with their dependencies - -## Usage example - -```bash -nix run github:nix-community/nixos-anywhere -- --no-disko-deps --flake # --target-host root@ -``` - -## Trade-off - -While this approach saves memory, it means the partitioning tools will be -whatever versions are available on the target system, rather than the specific -versions defined in your NixOS configuration. This could potentially lead to -version inconsistencies between the partitioning tools and the NixOS system -being installed. - -This trade-off is usually acceptable for memory-constrained environments where -installation would otherwise fail due to insufficient RAM. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/nix-path.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/nix-path.md deleted file mode 100644 index 1505af93..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/nix-path.md +++ /dev/null @@ -1,57 +0,0 @@ -# Nix-channels / `NIX_PATH` - -nixos-anywhere does not install channels onto the new system by default to save -time and disk space. This for example results in errors like: - -``` -(stack trace truncated; use '--show-trace' to show the full trace) - -error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I) - -at «none»:0: (source not available) -``` - -when using tools like nix-shell/nix-env that rely on `NIX_PATH` being set. - -# Solution 1: Set the `NIX_PATH` via nixos configuration (recommended) - -Instead of stateful channels, one can also populate the `NIX_PATH` using nixos -configuration instead: - -```nix -{ - inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - # ... other inputs - - outputs = inputs@{ nixpkgs, ... }: - { - nixosConfigurations.yoursystem = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; # adapt to your actual system - modules = [ - # This line will populate NIX_PATH - { nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ]; } - # ... other modules and your configuration.nix - ]; - }; - }; -} -``` - -Advantage: This solution will be automatically kept up-to-date every time the -flake is updated. - -In your shell you will see something in your `$NIX_PATH`: - -```shellSession -$ echo $NIX_PATH -/root/.nix-defexpr/channels:nixpkgs=/nix/store/8b61j28rpy11dg8hanbs2x710d8w3v0d-source -``` - -# Solution 2: Manually add the channel - -On the installed machine, run: - -```shellSession -$ nix-channel --add https://nixos.org/channels/nixos-unstable nixos -$ nix-channel --update -``` diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/no-os.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/no-os.md deleted file mode 100644 index 1c07cb0a..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/no-os.md +++ /dev/null @@ -1,71 +0,0 @@ -# Installing on a machine with no operating system - -If your machine doesn't currently have an operating system installed, you can -still run `nixos-anywhere` remotely to automate the install. To do this, you -would first need to boot the target machine from the standard NixOS installer. -You can either boot from a USB or use `netboot`. - -The -[NixOS installation guide](https://nixos.org/manual/nixos/stable/index.html#sec-booting-from-usb) -has detailed instructions on how to boot the installer. - -When you run `nixos-anywhere`, it will determine whether a NixOS installer is -present by checking whether the `/etc/os-release` file contains the identifier -`VARIANT_ID=installer`. This identifier is available on releases NixOS 23.05 or -later. - -If an installer is detected, `nixos-anywhere` will not attempt to `kexec` into -its own image. This is particularly useful for targets that don't have enough -RAM for `kexec` or don't support `kexec`. - -NixOS starts an SSH server on the installer by default, but you need to set a -password in order to access it. To set a password for the `nixos` user, run the -following command in a terminal on the NixOS machine: - -``` -passwd -``` - -If you don't know the IP address of the installer on your network, you can find -it by running the following command: - -``` -$ ip addr -1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 - link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 - inet 127.0.0.1/8 scope host lo - valid_lft forever preferred_lft forever - inet6 ::1/128 scope host - valid_lft forever preferred_lft forever -2: eth0: mtu 1500 qdisc fq_codel state UP group default qlen 1000 - link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff - altname enp0s3 - altname ens3 - inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0 - valid_lft 86385sec preferred_lft 75585sec - inet6 fec0::5054:ff:fe12:3456/64 scope site dynamic mngtmpaddr noprefixroute - valid_lft 86385sec preferred_lft 14385sec - inet6 fe80::5054:ff:fe12:3456/64 scope link - valid_lft forever preferred_lft forever -``` - -This will display the IP addresses assigned to your network interface(s), -including the IP address of the installer. In the example output below, the -installer's IP addresses are `10.0.2.15`, `fec0::5054:ff:fe12:3456`, and -`fe80::5054:ff:fe12:3456%eth0`: - -To test if you can connect and your password works, you can use the following -SSH command (replace the IP address with your own): - -``` -ssh -v nixos@fec0::5054:ff:fe12:3456 -``` - -You can then use the IP address to run `nixos-anywhere` like this: - -``` -nix run github:nix-community/nixos-anywhere -- --flake '.#myconfig' --target-host nixos@fec0::5054:ff:fe12:3456 -``` - -This example assumes a flake in the current directory containing a configuration -named `myconfig`. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/secrets.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/secrets.md deleted file mode 100644 index 8d95ee78..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/secrets.md +++ /dev/null @@ -1,76 +0,0 @@ -# Secrets and full disk encryption - -The `nixos-anywhere` utility offers the capability to install secrets onto a -target machine. This feature is particularly beneficial when you want to -bootstrap secrets management tools such as -[sops-nix](https://github.com/Mic92/sops-nix) or -[agenix](https://github.com/ryantm/agenix), which rely on machine-specific -secrets to decrypt other uploaded secrets. - -## Example: Decrypting an OpenSSH Host Key with pass - -In this example, we demonstrate how to use a script to decrypt an OpenSSH host -key from the `pass` password manager and subsequently pass it to -`nixos-anywhere` during the installation process: - -```bash -#!/usr/bin/env bash - -# Create a temporary directory -temp=$(mktemp -d) - -# Function to cleanup temporary directory on exit -cleanup() { - rm -rf "$temp" -} -trap cleanup EXIT - -# Create the directory where sshd expects to find the host keys -install -d -m755 "$temp/etc/ssh" - -# Decrypt your private key from the password store and copy it to the temporary directory -pass ssh_host_ed25519_key > "$temp/etc/ssh/ssh_host_ed25519_key" - -# Set the correct permissions so sshd will accept the key -chmod 600 "$temp/etc/ssh/ssh_host_ed25519_key" - -# Install NixOS to the host system with our secrets -nixos-anywhere --extra-files "$temp" --flake '.#your-host' --target-host root@yourip -``` - -## Example: Uploading Disk Encryption Secrets - -In a similar vein, `nixos-anywhere` can upload disk encryption secrets, which -are necessary during formatting with disko. Here's an example that demonstrates -how to provide your disk encryption password as a file or via the `pass` utility -to `nixos-anywhere`: - -```bash -# Write your disk encryption password to a file -echo "my-super-safe-password" > /tmp/disk-1.key - -# Call nixos-anywhere with disk encryption keys -nixos-anywhere \ - --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ - --disk-encryption-keys /tmp/disk-2.key <(pass my-disk-encryption-password) \ - --flake '.#your-host' \ - root@yourip -``` - -In the above example, replace `"my-super-safe-password"` with your actual -encryption password, and `my-disk-encryption-password` with the relevant entry -in your pass password store. Also, ensure to replace `'.#your-host'` and -`root@yourip` with your actual flake and IP address, respectively. - -## Example: Using existing SSH host keys - -If the system contains existing trusted `/etc/ssh/ssh_host_*` SSH host keys and -certificates, `nixos-anywhere` can copy them in case they are necessary during -installation and system activation. - -``` -nixos-anywhere --copy-host-keys --flake '.#your-host' root@yourip -``` - -This would copy `/etc/ssh/ssh_host_*` to `/mnt` after kexec but before -installation, ignoring files that already exist in destination. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/terraform.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/terraform.md deleted file mode 100644 index 87974932..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/terraform.md +++ /dev/null @@ -1,23 +0,0 @@ -# Terraform - -The nixos-anywhere terraform modules allow you to use Terraform for installing -and updating NixOS. It simplifies the deployment process by integrating -nixos-anywhere functionality. - -Our terraform module requires the -[null](https://registry.terraform.io/providers/hashicorp/null/latest) and -[external](https://registry.terraform.io/providers/hashicorp/external/latest) -provider. - -You can get these by from nixpkgs like this: - -```nix -nix-shell -p '(pkgs.terraform.withPlugins (p: [ p.null p.external ]))' -``` - -You can add this expression the `packages` list in your devshell in flake.nix or -in shell.nix. - -Checkout out the -[module reference](https://github.com/nix-community/nixos-anywhere/tree/main/terraform) -for examples and module parameter on how to use the modules. diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/use-without-flakes.md b/launch/.terraform/modules/pixelfed.deploy/docs/howtos/use-without-flakes.md deleted file mode 100644 index 33419a9e..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/howtos/use-without-flakes.md +++ /dev/null @@ -1,82 +0,0 @@ -# Use without flakes - -First, -[import the disko NixOS module](https://github.com/nix-community/disko/blob/master/docs/HowTo.md#installing-nixos-module) -in your NixOS configuration and define disko devices as described in the -[examples](https://github.com/nix-community/disko/tree/master/example). - -Let's assume that your NixOS configuration lives in `configuration.nix` and your -target machine is called `machine`: - -## 1. Download your favourite disk layout: - -See https://github.com/nix-community/disko-templates/ for more examples: - -The example below will work with both UEFI and BIOS-based systems. - -```bash -curl https://raw.githubusercontent.com/nix-community/disko-templates/main/single-disk-ext4/disko-config.nix > ./disko-config.nix -``` - -## 2. Get a hardware-configuration.nix from on the target machine - -- **Option 1**: If NixOS is not installed, boot into an installer without first - installing NixOS. -- **Option 2**: Use the kexec tarball method, as described - [here](https://github.com/nix-community/nixos-images#kexec-tarballs). - -- **Generate Configuration**: Run the following command on the target machine: - - ```bash - nixos-generate-config --no-filesystems --dir /tmp/config - ``` - -This creates the necessary configuration files under `/tmp/config/`. Copy -`/tmp/config/nixos/hardware-configuration.nix` to your local machine into the -same directory as `disko-config.nix`. - -## 3. Set NixOS version to use - -```nix -# default.nix -let - # replace nixos-24.11 with your preferred nixos version or revision from here: https://status.nixos.org/ - nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-24.11.tar.gz"; -in -import (nixpkgs + "/nixos/lib/eval-config.nix") { - modules = [ ./configuration.nix ]; -} -``` - -## 4. Write a NixOS configuration - -```nix -# configuration.nix -{ - imports = [ - "${fetchTarball "https://github.com/nix-community/disko/tarball/master"}/module.nix" - ./disko-config.nix - ./hardware-configuration.nix - ]; - # Replace this with the system of the installation target you want to install!!! - disko.devices.disk.main.device = "/dev/sda"; - - # Set this to the NixOS version that you have set in the previous step. - # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion . - system.stateVersion = "24.11"; -} -``` - -## 5. Build and deploy with nixos-anywhere - -Your current directory now should contain the following files from the previous -step: - -- `configuration.nix`, `default.nix`, `disko-config.nix` and - `hardware-configuration.nix` - -Run `nixos-anywhere` as follows: - -```bash -nixos-anywhere --store-paths $(nix-build -A config.system.build.formatScript -A config.system.build.toplevel --no-out-link) root@machine -``` diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/logo.png b/launch/.terraform/modules/pixelfed.deploy/docs/logo.png deleted file mode 100644 index 434ad443ac1a065b53f74353187f7baaa45bcf29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29405 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/quickstart.md b/launch/.terraform/modules/pixelfed.deploy/docs/quickstart.md deleted file mode 100644 index 5eb1a10e..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/quickstart.md +++ /dev/null @@ -1,334 +0,0 @@ -# Quickstart Guide: nixos-anywhere - -**_Install NixOS everywhere via ssh_** - - - -[Documentation Index](./INDEX.md) - -## Introduction - -This guide documents a simple installation of NixOS using **nixos-anywhere** on -a target machine running x86_64 Linux with -[kexec](https://man7.org/linux/man-pages/man8/kexec.8.html) support. The example -used in this guide installs NixOS on a Hetzner cloud machine. The configuration -may be different for some other instances. We will be including further examples -in the [How To Guide](./howtos/INDEX.md) as and when they are available. - -You will need: - -- A [flake](https://wiki.nixos.org/wiki/Flakes) that controls the actions to be - performed -- A disk configuration containing details of the file system that will be - created on the new server. -- A target machine that is reachable via SSH, either using keys or a password, - and the privilege to either log in directly as root or a user with - password-less sudo. - -**nixos-anywhere** doesn’t need to be installed. You can run it directly from -[the Github repository.](https://github.com/nix-community/nixos-anywhere) - -Details of the flake, the disk configuration and the CLI command are discussed -below. - -## Steps required to run nixos-anywhere - -### 1. Enable Flakes - -Check if your nix has flakes enabled by running `nix flake`. It will tell you if -it's not. To enable flakes, refer to the -[NixOS Wiki](https://wiki.nixos.org/wiki/Flakes#enable-flakes). - -### 2. Initialize a Flake - -The easiest way to start is to copy our -[example flake.nix](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix) -into a new directory. This example is tailored for a virtual machine setup -similar to one on [Hetzner Cloud](https://www.hetzner.com/cloud), so you might -need to adapt it for your setup. - -If you already have a flake, you can use it by adding -[disko configuration](https://github.com/nix-community/disko?tab=readme-ov-file#how-to-use-disko) -to it. - -### 3. Configure your SSH key - -If you cloned -[our nixos-anywhere-example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/configuration.nix) -you will also replace the SSH key like this: In your configuration, locate the -line that reads: - -```bash -# change this to your ssh key - "CHANGE" -``` - -Replace the text `CHANGE` with your own SSH key. This is crucial, as you will -not be able to log into the target machine post-installation without it. If you -have a .pem file you can run - -```bash -ssh-keygen -y -f /path/to/your/key.pem -``` - -then paste the result in between the quotes like "ssh-rsa AAA..." - -### 4. Configure Storage - -In the same directory, create a file called `disk-config.nix`. This file will -define the disk layout for the -[disko](https://github.com/nix-community/disko/blob/master/docs/INDEX.md) tool, -which is used by nixos-anywhere to partition, format, and mount the disks. - -For a basic installation, you can copy the contents from the example provided -[here](https://github.com/nix-community/nixos-anywhere-examples/blob/main/disk-config.nix). -This configuration sets up a standard GPT (GUID Partition Table) that is -compatible with both EFI and BIOS systems and mounts the disk as `/dev/sda`. You -may need to adjust `/dev/sda` to match the correct disk on your machine. To -identify the disk, run the `lsblk` command and replace `sda` with the actual -disk name. - -For example, on this machine, we would select `/dev/nvme0n1` as the disk: - -``` -NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS -nvme0n1 259:0 0 1.8T 0 disk -``` - -If this setup does not match your requirements, you can choose an example that -better suits your disk layout from the -[disko examples](https://github.com/nix-community/disko/tree/master/example). -For more detailed information, refer to the -[disko documentation](https://github.com/nix-community/disko). - -### 5. Lock your Flake - -``` -nix flake lock -``` - -This will download your flake dependencies and make a `flake.lock` file that -describes how to reproducibly build your system. - -Optionally, you can commit these files to a repo such as Github, or you can -simply reference your local directory when you run **nixos-anywhere**. This -example uses a local directory on the source machine. - -### 6. Connectivity to the Target Machine - -**nixos-anywhere** will create a temporary SSH key to use for the installation. -If your SSH key is not found, you will be asked for your password. If you are -using a non-root user, you must have access to sudo without a password. To avoid -SSH password prompts, set the `SSHPASS` environment variable to your password -and add `--env-password` to the `nixos-anywhere` command. If providing a -specific SSH key through `-i` (identity_file), this key will then be used for -the installation and no temporary SSH key will be created. - -### 7. (Optional) Test your NixOS and Disko configuration - -Skip this step and continue with Step 8, if you don't have a hardware -configuration (hardware-configuration.nix or facter.json) generated yet or make -sure you don't import non-existing hardware-configuration.nix or facter.json -during running the vm test. - -The following command will automatically test your nixos configuration and run -disko inside a virtual machine, where - -- `` is the path to the directory or repository - containing `flake.nix` and `disk-config.nix` - -- `` must match the name that immediately follows the text - `nixosConfigurations.` in the flake, as indicated by the comment in the - [example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix). - -``` -nix run github:nix-community/nixos-anywhere -- --flake # --vm-test -``` - -### 8. Prepare Hardware Configuration - -If you're not using a virtual machine, it's recommended to allow -`nixos-anywhere` to generate a hardware configuration during installation. This -ensures that essential drivers, such as those required for disk detection, are -properly configured. - -To enable `nixos-anywhere` to integrate its generated configuration into your -NixOS setup, you need to include an import for the hardware configuration -beforehand. - -Here’s an example: - -```diff - nixosConfigurations.generic = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [ - disko.nixosModules.disko - ./configuration.nix -+ ./hardware-configuration.nix - ]; - }; -``` - -When running `nixos-anywhere`, this file is automatically generated by including -the following flags in your command: -`--generate-hardware-config nixos-generate-config ./hardware-configuration.nix`. -The second flag, `./hardware-configuration.nix`, specifies where -`nixos-generate-config` will store the configuration. Adjust this path to -reflect the location where you want the `hardware-configuration.nix` for this -machine to be saved. - -#### 8.1 nixos-facter - -As an alternative to `nixos-generate-config`, you can use the experimental -[nixos-facter](https://github.com/numtide/nixos-facter) command, which offers -more comprehensive hardware reports and advanced configuration options. - -To use `nixos-facter`, add the following to your flake inputs: - -```diff - { -+ inputs.nixos-facter-modules.url = "github:numtide/nixos-facter-modules"; - } -``` - -Next, import the module into your configuration and specify `facter.json` as the -path where the hardware report will be saved: - -```diff - nixosConfigurations.generic-nixos-facter = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [ - disko.nixosModules.disko - ./configuration.nix -+ nixos-facter-modules.nixosModules.facter -+ { config.facter.reportPath = ./facter.json } - ]; - }; -``` - -To generate the configuration for `nixos-facter` with `nixos-anywhere`, use the -following flags: `--generate-hardware-config nixos-facter ./facter.json`. The -second flag, `./facter.json`, specifies where `nixos-generate-config` will store -the hardware report. Adjust this path to suit the location where you want the -`facter.json` to be saved. - -### 9. Run it - -You can now run **nixos-anywhere** from the command line as shown below, where: - -- `` is the path to the directory or repository - containing `flake.nix` and `disk-config.nix` - -- `` must match the name that immediately follows the text - `nixosConfigurations.` in the flake, as indicated by the comment in the - [example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix). - -- `` is the IP address of the target machine. - -``` -nix run github:nix-community/nixos-anywhere -- --flake # --target-host root@ -``` - -The command would look  like this if you had created your files in a directory -named `/home/mydir/test` and the IP address of your target machine is -`37.27.18.135`: - -``` -nix run github:nix-community/nixos-anywhere -- --flake /home/mydir/test#hetzner-cloud --target-host root@37.27.18.135 -``` - -If you also need to generate hardware configuration amend flags for -nixos-generate-config: - -``` -nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-generate-config ./hardware-configuration.nix --flake # --target-host root@ -``` - -Or these flags if you are using nixos-facter instead: - -``` -nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-facter ./facter.json --flake # --target-host root@ -``` - -Adjust the location of `./hardware-configuration.nix` and `./facter.json` -accordingly. - -**nixos-anywhere** will then run, showing various output messages at each stage. -It may take some time to complete, depending on Internet speeds. It should -finish by showing the messages below before returning to the command prompt. - -``` -Installation finished. No error reported. -Warning: Permanently added '' (ED25519) to the list of known hosts -``` - -When this happens, the target server will have been overwritten with a new -installation of NixOS. Note that the server's public SSH key will have changed. - -If you have previously accessed this server using SSH, you may see the following -message the next time you try to log in to the target. - -``` -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! -Someone could be eavesdropping on you right now (man-in-the-middle attack)! -It is also possible that a host key has just been changed. -The fingerprint for the ED25519 key sent by the remote host is -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. -Please contact your system administrator. -Add correct host key in ~/.ssh/known_hosts to get rid of this message. -Offending ECDSA key in ~/.ssh/known_hosts:6 - remove with: - ssh-keygen -f ~/.ssh/known_hosts" -R "" -Host key for has changed and you have requested strict checking. -Host key verification failed. -``` - -This is because the `known_hosts` file in the `.ssh` directory now contains a -mismatch, since the server has been overwritten. To solve this, use a text -editor to remove the old entry from the `known_hosts` file (or use the command -`ssh-keygen -R `). The next connection attempt will then treat this -as a new server. - -The error message line `Offending ECDSA key in ~/.ssh/known_hosts:6` gives the -line number that needs to be removed from the `known_hosts` file (line 6 in this -example). - -# Finished! - -**nixos-anywhere**'s job is now done, as it is a tool to install NixOS onto the -target machine. - -Any future changes to the configuration should be made to your flake. You would -reference this flake when using the NixOS `nixos-rebuild` command or a separate -3rd party deployment tool of your choice i.e. -[deploy-rs](https://github.com/serokell/deploy-rs), -[colmena](https://github.com/zhaofengli/colmena), -[nixinate](https://github.com/MatthewCroughan/nixinate), -[clan](https://clan.lol/) (author's choice). - -To update on the machine locally (replace `` with your flake -i.e. `.#` if your flake is in the current directory): - -``` -nixos-rebuild switch --flake -``` - -To update remotely you will need to have configured an -[ssh server](https://search.nixos.org/options?show=services.sshd.enable) and -your ssh key for the -[root user](https://search.nixos.org/options?show=users.users.%3Cname%3E.openssh.authorizedKeys.keys): - -``` -nixos-rebuild switch --flake --target-host "root@" -``` - -See the Nix documentation for use of the flake -[URL-like syntax](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake#url-like-syntax). - -For more information on different use cases of **nixos-anywhere** please refer -to the [How to Guide](./howtos/INDEX.md), and for more technical information and -explanation of known error messages, refer to the -[Reference Manual](./reference.md). diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/reference.md b/launch/.terraform/modules/pixelfed.deploy/docs/reference.md deleted file mode 100644 index 83916572..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/reference.md +++ /dev/null @@ -1,137 +0,0 @@ -# Reference Manual: nixos-anywhere - -**_Install NixOS everywhere via ssh_** - - - -[Documentation Index](./INDEX.md) - -TODO: Populate this guide properly - -## Contents - -[Command Line Usage](#command-line-usage) - -[Explanation of known error messages](#explanation-of-known-error-messages) - -## Command Line Usage - - - -``` -Usage: nixos-anywhere [options] [] - -Options: - -* -f, --flake - set the flake to install the system from. i.e. - nixos-anywhere --flake .#mymachine - Also supports variants: - nixos-anywhere --flake .#nixosConfigurations.mymachine.config.virtualisation.vmVariant -* --target-host - set the SSH target host to deploy onto. -* -i - selects which SSH private key file to use. -* -p, --ssh-port - set the ssh port to connect with -* --ssh-option - set an ssh option -* -L, --print-build-logs - print full build logs -* --env-password - set a password used by ssh-copy-id, the password should be set by - the environment variable SSHPASS -* -s, --store-paths - set the store paths to the disko-script and nixos-system directly - if this is given, flake is not needed -* --kexec - use another kexec tarball to bootstrap NixOS -* --kexec-extra-flags - extra flags to add into the call to kexec, e.g. "--no-sync" -* --ssh-store-setting - ssh store settings appended to the store URI, e.g. "compress true". needs to be URI encoded. -* --post-kexec-ssh-port - after kexec is executed, use a custom ssh port to connect. Defaults to 22 -* --copy-host-keys - copy over existing /etc/ssh/ssh_host_* host keys to the installation -* --extra-files - contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten - Copied files will be owned by root unless specified by --chown option. See documentation for details. -* --chown - change ownership of recursively. Recommended to use uid:gid as opposed to username:groupname for ownership. - Option can be specified more than once. -* --disk-encryption-keys - copy the contents of the file or pipe in local_path to remote_path in the installer environment, - after kexec but before installation. Can be repeated. -* --no-substitute-on-destination - disable passing --substitute-on-destination to nix-copy -* --debug - enable debug output -* --show-trace - show nix build traces -* --option - nix option to pass to every nix related command -* --from - URL of the source Nix store to copy the nixos and disko closure from -* --build-on-remote - build the closure on the remote machine instead of locally and copy-closuring it -* --vm-test - build the system and test the disk configuration inside a VM without installing it to the target. -* --generate-hardware-config nixos-facter|nixos-generate-config - generate a hardware-configuration.nix file using the specified backend and write it to the specified path. - The backend can be either 'nixos-facter' or 'nixos-generate-config'. -* --phases - comma separated list of phases to run. Default is: kexec,disko,install,reboot - kexec: kexec into the nixos installer - disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode - install: install the system - reboot: unmount the filesystems, export any ZFS pools and reboot the machine -* --disko-mode disko|mount|format - set the disko mode to format, mount or destroy. Default is disko. - disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode -* --no-disko-deps - This will only upload the disko script and not the partitioning tools dependencies. - Installers usually have dependencies available. - Use this option if your target machine has not enough RAM to store the dependencies in memory. -* --build-on auto|remote|local - sets the build on settings to auto, remote or local. Default is auto. - auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build - local: will build on the local host - remote: will build on the remote host -``` - -## Explanation of known error messages - -TODO: Add additional error messages and meanings. Fill in missing explanations - -This section lists known error messages and their explanations. Some -explanations may refer to the following CLI syntax: - -`nix run github:nix-community/nixos-anywhere -- --flake # root@` - -This list is not comprehensive. It's possible you may encounter errors that -originate from the underlying operating system. These should be documented in -the relevant operating system manual. - -| Id | Message | Explanation | -| -- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| 1 | Failure unpacking initrd | You don't have enough RAM to hold `kexec` | -| 2 | Flake  does not provide attribute | The configuration name you specified in your flake URI is not defined as a NixOS configuration in your flake eg if your URI was mydir#myconfig, then myconfig should be included in the flake as `nixosConfigurations.myconfig` | -| 3 | Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri. | As for error #2 | -| | For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri | | -| 4 | Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already | TODO: Explain | -| 5 | ssh-host must be set |  has not been supplied | -| 6 | and must be existing store-paths | This occurs if the -s switch has been used to specify the disko script and store path correctly, and the scripts cannot be found at the given URI | -| 7 | flake must be set | This occurs if both the -flake option (use a flake) and the -s option (specify paths directly) have been omitted. Either one or the other must be specified. | -| 8 | no tar command found, but required to unpack kexec tarball | The destination machine does not have a `tar` command available. This is needed to unpack the `kexec`. | -| 9 | no setsid command found, but required to run the kexec script under a new session | The destination machine does not have the `setsid` command available | -| 10 | This script requires Linux as the operating system, but got | The destination machine is not running Linux | -| 11 | The default kexec image only support x86_64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information. | By default, `nixos-anywhere` uses its own `kexec` image, which will only run on x86_64 CPUs. For other CPU types, you can use your own `kexec` image instead. Refer to the [How To Guide](./howtos#using-your-own-kexec-image) for instructions. | -| 12 | Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri. | This is a `disko` error. As for Error #2 | -| | For example, to use the output diskoConfigurations.foo from the flake.nix, append \"#foo\" to the flake-uri. | | -| 13 | mode must be either create, mount or zap_create_mount | This is a `disko` error. The `disko` switches have not been used correctly. This could happen if you supplied your own `disko` script using the -s option | -| 14 | disko config must be an existing file or flake must be set | This is a `disko` error. This will happen if the `disko.devices` entry in your flake doesn't match the name of a file in the same location as your flake. | -| | | | -| | | | -| | | | -| | | | diff --git a/launch/.terraform/modules/pixelfed.deploy/docs/requirements.md b/launch/.terraform/modules/pixelfed.deploy/docs/requirements.md deleted file mode 100644 index 67b14f4d..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/docs/requirements.md +++ /dev/null @@ -1,39 +0,0 @@ -# System Requirements: nixos-anywhere - -**_Install NixOS everywhere via ssh_** - - - -[Documentation Index](./INDEX.md) - -## Requirements - -### Source Machine - -1. **Supported Systems:** - - Linux or macOS computers with Nix installed. - - NixOS - - Windows systems using WSL2. - -2. **Nix Installation:** If Nix is not yet installed on your system, refer to - the [nix installation page](https://nixos.org/download#download-nix). - -### Destination Machine - -The machine must be reachable over the public internet or local network. -Nixos-anywhere does not support wifi networks. If a VPN is needed, define a -custom installer via the --kexec flag which connects to your VPN. - -1. **Direct Boot Option:** - - Must be already running a NixOS installer. - -2. **Alternative Boot Options:** If not booting directly from a NixOS installer - image: - - **Architecture & Support:** Must be operating on: - - x86-64 or aarch64 Linux systems with kexec support. Note: While most - x86-64 Linux systems support kexec, if you're using an architecture other - than those mentioned, you may need to specify a - [different kexec image](./howtos/INDEX.md#using-your-own-kexec-image) - manually. - - **Memory Requirements:** - - At least 1 GB of RAM (excluding swap space). diff --git a/launch/.terraform/modules/pixelfed.deploy/flake.lock b/launch/.terraform/modules/pixelfed.deploy/flake.lock deleted file mode 100644 index 5a7232ca..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/flake.lock +++ /dev/null @@ -1,132 +0,0 @@ -{ - "nodes": { - "disko": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1741786315, - "narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=", - "owner": "nix-community", - "repo": "disko", - "rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de", - "type": "github" - }, - "original": { - "owner": "nix-community", - "ref": "master", - "repo": "disko", - "type": "github" - } - }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1741352980, - "narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "nixos-images": { - "inputs": { - "nixos-stable": [ - "nixos-stable" - ], - "nixos-unstable": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1741866599, - "narHash": "sha256-Re/T1Cjmiis0tdphj/Wjqt+c2RlMw/il7LBWzvwQPz0=", - "owner": "nix-community", - "repo": "nixos-images", - "rev": "63285ff93fc1daa2caac9f86e2302ae4edc5e84f", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixos-images", - "type": "github" - } - }, - "nixos-stable": { - "locked": { - "lastModified": 1741862977, - "narHash": "sha256-prZ0M8vE/ghRGGZcflvxCu40ObKaB+ikn74/xQoNrGQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "cdd2ef009676ac92b715ff26630164bb88fec4e0", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-24.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1742051767, - "narHash": "sha256-JpyjnalnIqJ7cvP8HzaoJN9/i2bDx83dToodHHjGuNg=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "ec886d10b507760c90ed01e2eac7f0679d0a47ae", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable-small", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "disko": "disko", - "flake-parts": "flake-parts", - "nixos-images": "nixos-images", - "nixos-stable": "nixos-stable", - "nixpkgs": "nixpkgs", - "treefmt-nix": "treefmt-nix" - } - }, - "treefmt-nix": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1739829690, - "narHash": "sha256-mL1szCeIsjh6Khn3nH2cYtwO5YXG6gBiTw1A30iGeDU=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "3d0579f5cc93436052d94b73925b48973a104204", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/launch/.terraform/modules/pixelfed.deploy/flake.nix b/launch/.terraform/modules/pixelfed.deploy/flake.nix deleted file mode 100644 index d60191cc..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/flake.nix +++ /dev/null @@ -1,55 +0,0 @@ -{ - description = "A universal nixos installer, just needs ssh access to the target system"; - - inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small"; - flake-parts = { - url = "github:hercules-ci/flake-parts"; - inputs.nixpkgs-lib.follows = "nixpkgs"; - }; - - # used for testing - disko = { - url = "github:nix-community/disko/master"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - nixos-stable.url = "github:NixOS/nixpkgs/nixos-24.11"; - nixos-images.url = "github:nix-community/nixos-images"; - nixos-images.inputs.nixos-unstable.follows = "nixpkgs"; - nixos-images.inputs.nixos-stable.follows = "nixos-stable"; - - # used for development - treefmt-nix = { - url = "github:numtide/treefmt-nix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - }; - - outputs = - inputs: - inputs.flake-parts.lib.mkFlake { inherit inputs; } { - systems = [ - "x86_64-linux" - "x86_64-darwin" - "aarch64-linux" - "aarch64-darwin" - ]; - imports = [ - ./src/flake-module.nix - ./tests/flake-module.nix - ./docs/flake-module.nix - # allow to disable treefmt in downstream flakes - ] ++ inputs.nixpkgs.lib.optional (inputs.treefmt-nix ? flakeModule) ./treefmt/flake-module.nix; - - perSystem = - { self', lib, ... }: - { - checks = - let - packages = lib.mapAttrs' (n: lib.nameValuePair "package-${n}") self'.packages; - devShells = lib.mapAttrs' (n: lib.nameValuePair "devShell-${n}") self'.devShells; - in - packages // devShells; - }; - }; -} diff --git a/launch/.terraform/modules/pixelfed.deploy/scripts/create-release.sh b/launch/.terraform/modules/pixelfed.deploy/scripts/create-release.sh deleted file mode 100755 index 7f203035..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/scripts/create-release.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env nix -#! nix shell nixpkgs#bash nixpkgs#gnused --command bash - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" -cd "$SCRIPT_DIR/.." - -version=${1:-} -if [[ -z $version ]]; then - echo "USAGE: $0 version" >&2 - exit 1 -fi - -if [[ "$(git symbolic-ref --short HEAD)" != "main" ]]; then - echo "must be on main branch" >&2 - exit 1 -fi - -# ensure we are up-to-date -uncommitted_changes=$(git diff --compact-summary) -if [[ -n $uncommitted_changes ]]; then - echo -e "There are uncommitted changes, exiting:\n${uncommitted_changes}" >&2 - exit 1 -fi -git pull git@github.com:nix-community/nixos-anywhere main -unpushed_commits=$(git log --format=oneline origin/main..main) -if [[ $unpushed_commits != "" ]]; then - echo -e "\nThere are unpushed changes, exiting:\n$unpushed_commits" >&2 - exit 1 -fi -sed -i -e "s!version = \".*\";!version = \"${version}\";!" src/default.nix -git add src/default.nix -nix-shell -p nix-fast-build --command "nix-fast-build --eval-workers 2" -git commit -m "bump version ${version}" -git tag "${version}" - -echo "now run 'git push --tags origin main'" diff --git a/launch/.terraform/modules/pixelfed.deploy/src/default.nix b/launch/.terraform/modules/pixelfed.deploy/src/default.nix deleted file mode 100644 index c1719320..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/src/default.nix +++ /dev/null @@ -1,63 +0,0 @@ -{ - stdenv, - openssh, - gitMinimal, - nixVersions, - nix, - coreutils, - curl, - gnugrep, - gnutar, - gawk, - findutils, - gnused, - sshpass, - terraform-docs, - lib, - makeWrapper, - mkShellNoCC, -}: -let - runtimeDeps = [ - gitMinimal # for git flakes - # pinned because nix-copy-closure hangs if ControlPath provided for SSH: https://github.com/NixOS/nix/issues/8480 - (if lib.versionAtLeast nix.version "2.16" then nix else nixVersions.nix_2_16) - coreutils - curl # when uploading tarballs - gnugrep - gawk - findutils - gnused # needed by ssh-copy-id - sshpass # used to provide password for ssh-copy-id - gnutar # used to upload extra-files - ]; -in -stdenv.mkDerivation { - pname = "nixos-anywhere"; - version = "1.8.0"; - src = ./..; - nativeBuildInputs = [ makeWrapper ]; - installPhase = '' - install -D --target-directory=$out/libexec/nixos-anywhere/ -m 0755 src/*.sh - - # We prefer the system's openssh over our own, since it might come with features not present in ours: - # https://github.com/nix-community/nixos-anywhere/issues/62 - makeShellWrapper $out/libexec/nixos-anywhere/nixos-anywhere.sh $out/bin/nixos-anywhere \ - --prefix PATH : ${lib.makeBinPath runtimeDeps} --suffix PATH : ${lib.makeBinPath [ openssh ]} - ''; - - # Dependencies for our devshell - passthru.devShell = mkShellNoCC { - packages = runtimeDeps ++ [ - openssh - terraform-docs - ]; - }; - - meta = with lib; { - description = "Install nixos everywhere via ssh"; - homepage = "https://github.com/nix-community/nixos-anywhere"; - license = licenses.mit; - platforms = platforms.all; - }; -} diff --git a/launch/.terraform/modules/pixelfed.deploy/src/flake-module.nix b/launch/.terraform/modules/pixelfed.deploy/src/flake-module.nix deleted file mode 100644 index d131219d..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/src/flake-module.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ - perSystem = - { config, pkgs, ... }: - { - packages = { - nixos-anywhere = pkgs.callPackage ./. { }; - default = config.packages.nixos-anywhere; - }; - devShells.default = config.packages.nixos-anywhere.devShell; - }; -} diff --git a/launch/.terraform/modules/pixelfed.deploy/src/get-facts.sh b/launch/.terraform/modules/pixelfed.deploy/src/get-facts.sh deleted file mode 100755 index 80434422..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/src/get-facts.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -set -efu "${enableDebug:-}" -has() { - command -v "$1" >/dev/null && echo "y" || echo "n" -} -isNixos=$(if test -f /etc/os-release && grep -Eq 'ID(_LIKE)?="?nixos"?' /etc/os-release; then echo "y"; else echo "n"; fi) -cat </dev/null 2>/dev/null || ! ip -6 r g :: >/dev/null 2>/dev/null; then echo "n"; else echo "y"; fi) -hasTar=$(has tar) -hasCpio=$(has cpio) -hasSudo=$(has sudo) -hasDoas=$(has doas) -hasWget=$(has wget) -hasCurl=$(has curl) -hasSetsid=$(has setsid) -hasNixOSFacter=$(command -v nixos-facter >/dev/null && echo "y" || echo "n") -FACTS diff --git a/launch/.terraform/modules/pixelfed.deploy/src/nixos-anywhere.sh b/launch/.terraform/modules/pixelfed.deploy/src/nixos-anywhere.sh deleted file mode 100755 index c6cadb98..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/src/nixos-anywhere.sh +++ /dev/null @@ -1,880 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -here=$(dirname "${BASH_SOURCE[0]}") -flake="" -flakeAttr="" -kexecUrl="" -kexecExtraFlags="" -sshStoreSettings="" -enableDebug="" -nixBuildFlags=() -diskoAttr="" -diskoScript="" -diskoMode="disko" -diskoDeps=y -nixosSystem="" -extraFiles="" -vmTest="n" -nixOptions=( - --extra-experimental-features 'nix-command flakes' - "--no-write-lock-file" -) -SSH_PRIVATE_KEY=${SSH_PRIVATE_KEY-} - -declare -A phases -phases[kexec]=1 -phases[disko]=1 -phases[install]=1 -phases[reboot]=1 - -hardwareConfigBackend=none -hardwareConfigPath= -sshPrivateKeyFile= -if [ -t 0 ]; then # stdin is a tty, we allow interactive input to ssh i.e. passwords - sshTtyParam="-t" -else - sshTtyParam="-T" -fi -sshConnection= -postKexecSshPort=22 -buildOnRemote=n -buildOn=auto -envPassword=n - -# Facts set by get-facts.sh -isOs= -isArch= -isKexec= -isInstaller= -isContainer= -hasIpv6Only= -hasTar= -hasCpio= -hasSudo= -hasDoas= -hasWget= -hasCurl= -hasSetsid= -hasNixOSFacter= - -sshKeyDir=$(mktemp -d) -trap 'rm -rf "$sshKeyDir"' EXIT -mkdir -p "$sshKeyDir" - -declare -A diskEncryptionKeys=() -declare -A extraFilesOwnership=() -declare -a nixCopyOptions=() -declare -a sshArgs=() - -showUsage() { - cat <] - -Options: - -* -f, --flake - set the flake to install the system from. i.e. - nixos-anywhere --flake .#mymachine - Also supports variants: - nixos-anywhere --flake .#nixosConfigurations.mymachine.config.virtualisation.vmVariant -* --target-host - set the SSH target host to deploy onto. -* -i - selects which SSH private key file to use. -* -p, --ssh-port - set the ssh port to connect with -* --ssh-option - set an ssh option -* -L, --print-build-logs - print full build logs -* --env-password - set a password used by ssh-copy-id, the password should be set by - the environment variable SSHPASS -* -s, --store-paths - set the store paths to the disko-script and nixos-system directly - if this is given, flake is not needed -* --kexec - use another kexec tarball to bootstrap NixOS -* --kexec-extra-flags - extra flags to add into the call to kexec, e.g. "--no-sync" -* --ssh-store-setting - ssh store settings appended to the store URI, e.g. "compress true". needs to be URI encoded. -* --post-kexec-ssh-port - after kexec is executed, use a custom ssh port to connect. Defaults to 22 -* --copy-host-keys - copy over existing /etc/ssh/ssh_host_* host keys to the installation -* --extra-files - contents of local are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten - Copied files will be owned by root unless specified by --chown option. See documentation for details. -* --chown - change ownership of recursively. Recommended to use uid:gid as opposed to username:groupname for ownership. - Option can be specified more than once. -* --disk-encryption-keys - copy the contents of the file or pipe in local_path to remote_path in the installer environment, - after kexec but before installation. Can be repeated. -* --no-substitute-on-destination - disable passing --substitute-on-destination to nix-copy -* --debug - enable debug output -* --show-trace - show nix build traces -* --option - nix option to pass to every nix related command -* --from - URL of the source Nix store to copy the nixos and disko closure from -* --build-on-remote - build the closure on the remote machine instead of locally and copy-closuring it -* --vm-test - build the system and test the disk configuration inside a VM without installing it to the target. -* --generate-hardware-config nixos-facter|nixos-generate-config - generate a hardware-configuration.nix file using the specified backend and write it to the specified path. - The backend can be either 'nixos-facter' or 'nixos-generate-config'. -* --phases - comma separated list of phases to run. Default is: kexec,disko,install,reboot - kexec: kexec into the nixos installer - disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode - install: install the system - reboot: unmount the filesystems, export any ZFS pools and reboot the machine -* --disko-mode disko|mount|format - set the disko mode to format, mount or destroy. Default is disko. - disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode -* --no-disko-deps - This will only upload the disko script and not the partitioning tools dependencies. - Installers usually have dependencies available. - Use this option if your target machine has not enough RAM to store the dependencies in memory. -* --build-on auto|remote|local - sets the build on settings to auto, remote or local. Default is auto. - auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build - local: will build on the local host - remote: will build on the remote host -USAGE -} - -abort() { - echo "aborted: $*" >&2 - exit 1 -} - -step() { - echo "### $* ###" -} - -parseArgs() { - local substituteOnDestination=y - local printBuildLogs=n - local buildOnRemote=n - while [[ $# -gt 0 ]]; do - case "$1" in - -f | --flake) - flake=$2 - shift - ;; - --target-host) - sshConnection=$2 - shift - ;; - -i) - sshPrivateKeyFile=$2 - shift - ;; - -p | --ssh-port) - sshArgs+=("-p" "$2") - shift - ;; - --ssh-option) - sshArgs+=("-o" "$2") - shift - ;; - -L | --print-build-logs) - printBuildLogs=y - ;; - -s | --store-paths) - diskoScript=$(readlink -f "$2") - nixosSystem=$(readlink -f "$3") - shift - shift - ;; - --generate-hardware-config) - if [[ $# -lt 3 ]]; then - abort "Missing arguments for --generate-hardware-config " - fi - case "$2" in - nixos-facter | nixos-generate-config) - hardwareConfigBackend=$2 - ;; - *) - abort "Unknown hardware config backend: $2" - ;; - esac - hardwareConfigPath=$3 - shift - shift - ;; - -t | --tty) - echo "the '$1' flag is deprecated, a tty is now detected automatically" >&2 - ;; - --help) - showUsage - exit 0 - ;; - --kexec) - kexecUrl=$2 - shift - ;; - --kexec-extra-flags) - kexecExtraFlags=$2 - shift - ;; - --ssh-store-setting) - key=$2 - shift - value=$2 - shift - sshStoreSettings+="$sshStoreSettings$key=$value&" - shift - ;; - --post-kexec-ssh-port) - postKexecSshPort=$2 - shift - ;; - --copy-host-keys) - copyHostKeys=y - ;; - --show-trace) - nixBuildFlags+=("--show-trace") - ;; - --debug) - enableDebug="-x" - printBuildLogs=y - set -x - ;; - --disko-mode) - case "$2" in - format | mount | disko) - diskoMode=$2 - ;; - *) - abort "Supported values for --disko-mode are disko, mount and format. Unknown mode : $2" - ;; - esac - - shift - ;; - --no-disko-deps) - diskoDeps=n - ;; - --build-on) - case "$2" in - auto | local | remote) - buildOn=$2 - ;; - *) - abort "Supported values for --build-on are auto, local and remote. Unknown mode : $2" - ;; - esac - - shift - ;; - --extra-files) - extraFiles=$2 - shift - ;; - --chown) - extraFilesOwnership["$2"]="$3" - shift - shift - ;; - --disk-encryption-keys) - diskEncryptionKeys["$2"]="$3" - shift - shift - ;; - --phases) - phases[kexec]=0 - phases[disko]=0 - phases[install]=0 - phases[reboot]=0 - IFS=, read -r -a phaseList <<<"$2" - for phase in "${phaseList[@]}"; do - if [[ ${phases[$phase]:-unset} == unset ]]; then - abort "Unknown phase: $phase" - fi - phases[$phase]=1 - done - shift - ;; - --stop-after-disko) - echo "WARNING: --stop-after-disko is deprecated, use --phases kexec,disko instead" 2>&1 - phases[kexec]=1 - phases[disko]=1 - phases[install]=0 - phases[reboot]=0 - ;; - --no-reboot) - echo "WARNING: --no-reboot is deprecated, use --phases kexec,disko,install instead" 2>&1 - phases[kexec]=1 - phases[disko]=1 - phases[install]=1 - phases[reboot]=0 - ;; - --from) - nixCopyOptions+=("--from" "$2") - shift - ;; - --option) - key=$2 - shift - value=$2 - shift - nixOptions+=("--option" "$key" "$value") - ;; - --no-substitute-on-destination) - substituteOnDestination=n - ;; - --build-on-remote) - echo "WARNING: --build-on-remote is deprecated, use --build-on remote instead" 2>&1 - buildOnRemote=y - buildOn="remote" - ;; - --env-password) - envPassword=y - ;; - --vm-test) - vmTest=y - ;; - *) - if [[ -z ${sshConnection} ]]; then - sshConnection="$1" - else - showUsage - exit 1 - fi - ;; - esac - shift - done - - diskoAttr="${diskoMode}Script" - - if [[ ${diskoDeps} == "n" ]]; then - diskoAttr="${diskoAttr}NoDeps" - fi - - if [[ ${printBuildLogs} == "y" ]]; then - nixOptions+=("-L") - fi - - if [[ $substituteOnDestination == "y" ]]; then - nixCopyOptions+=("--substitute-on-destination") - fi - - if [[ $vmTest == "n" ]] && [[ -z ${sshConnection} ]]; then - abort "ssh-host must be set" - fi - - if [[ $buildOn == "local" ]] && [[ $buildOnRemote == "y" ]]; then - abort "Conflicting flags: --build-on local and --build-on-remote used." - fi - - if [[ -n ${flake} ]]; then - if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then - flake="${BASH_REMATCH[1]}" - flakeAttr="${BASH_REMATCH[2]}" - fi - if [[ -z ${flakeAttr} ]]; then - echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri." >&2 - echo 'For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri.' >&2 - exit 1 - fi - - # Support .#foo shorthand - if [[ $flakeAttr != nixosConfigurations.* ]]; then - flakeAttr="nixosConfigurations.\"$flakeAttr\".config" - fi - fi - -} - -# ssh wrapper -runSshNoTty() { - ssh -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@" -} -runSshTimeout() { - timeout 10 ssh -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@" -} -runSsh() { - ssh "$sshTtyParam" -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@" -} - -nixCopy() { - NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $sshKeyDir/nixos-anywhere ${sshArgs[*]}" nix copy \ - "${nixOptions[@]}" \ - "${nixCopyOptions[@]}" \ - "$@" -} -nixBuild() { - NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $sshKeyDir/nixos-anywhere ${sshArgs[*]}" nix build \ - --print-out-paths \ - --no-link \ - "${nixBuildFlags[@]}" \ - "${nixOptions[@]}" \ - "$@" -} - -runVmTest() { - if [[ -z ${flakeAttr} ]]; then - echo "--vm-test is not supported with --store-paths" >&2 - echo "Please use --flake instead or build config.system.build.installTest of your nixos configuration manually" >&2 - exit 1 - fi - - if [[ ${buildOn} == "remote" ]]; then - echo "--vm-test is not supported with --build-on-remote" >&2 - exit 1 - fi - if [[ -n ${extraFiles} ]]; then - echo "--vm-test is not supported with --extra-files" >&2 - exit 1 - fi - if [ ${#diskEncryptionKeys[@]} -gt 0 ]; then - echo "--vm-test is not supported with --disk-encryption-keys" >&2 - exit 1 - fi - nix build \ - --print-out-paths \ - --no-link \ - -L \ - "${nixBuildFlags[@]}" \ - "${nixOptions[@]}" \ - "${flake}#${flakeAttr}.system.build.installTest" -} - -uploadSshKey() { - # ssh-copy-id requires this directory - mkdir -p "$HOME/.ssh/" - if [[ -n ${sshPrivateKeyFile} ]]; then - cp "$sshPrivateKeyFile" "$sshKeyDir/nixos-anywhere" - ssh-keygen -y -f "$sshKeyDir/nixos-anywhere" >"$sshKeyDir/nixos-anywhere.pub" - else - # we generate a temporary ssh keypair that we can use during nixos-anywhere - ssh-keygen -t ed25519 -f "$sshKeyDir"/nixos-anywhere -P "" -C "nixos-anywhere" >/dev/null - fi - - declare -a sshCopyIdArgs - if [[ -n ${sshPrivateKeyFile} ]]; then - unset SSH_AUTH_SOCK # don't use system agent if key was supplied - sshCopyIdArgs+=(-o "IdentityFile=${sshPrivateKeyFile}" -f) - fi - - step Uploading install SSH keys - until - if [[ ${envPassword} == y ]]; then - sshpass -e \ - ssh-copy-id \ - -i "$sshKeyDir"/nixos-anywhere.pub \ - -o ConnectTimeout=10 \ - -o UserKnownHostsFile=/dev/null \ - -o IdentitiesOnly=yes \ - -o StrictHostKeyChecking=no \ - "${sshCopyIdArgs[@]}" \ - "${sshArgs[@]}" \ - "$sshConnection" - else - ssh-copy-id \ - -i "$sshKeyDir"/nixos-anywhere.pub \ - -o ConnectTimeout=10 \ - -o UserKnownHostsFile=/dev/null \ - -o StrictHostKeyChecking=no \ - "${sshCopyIdArgs[@]}" \ - "${sshArgs[@]}" \ - "$sshConnection" - fi - do - sleep 3 - done -} - -importFacts() { - step Gathering machine facts - local facts filteredFacts - if ! facts=$(runSsh -o ConnectTimeout=10 enableDebug=$enableDebug sh -- <"$here"/get-facts.sh); then - exit 1 - fi - filteredFacts=$(echo "$facts" | grep -E '^(has|is)[A-Za-z0-9_]+=\S+') - if [[ -z $filteredFacts ]]; then - abort "Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already" - fi - # make facts available in script - # shellcheck disable=SC2046 - export $(echo "$filteredFacts" | xargs) - - for var in isOs isArch isKexec isInstaller isContainer hasIpv6Only hasTar hasCpio hasSudo hasDoas hasWget hasCurl hasSetsid; do - if [[ -z ${!var} ]]; then - abort "Failed to retrieve fact $var from host" - fi - done -} - -checkBuildLocally() { - local system extraPlatforms machineSystem - system="$(nix --extra-experimental-features 'nix-command flakes' config show system)" - extraPlatforms="$(nix --extra-experimental-features 'nix-command flakes' config show extra-platforms)" - - if [[ $# -gt 0 ]]; then - machineSystem=$1 - elif [[ -n ${nixosSystem} ]]; then - machineSystem="$(cat "${nixosSystem}"/system)" - else - machineSystem="$(nix --extra-experimental-features 'nix-command flakes' eval --raw "${flake}"#"${flakeAttr}".pkgs.system 2>/dev/null || echo "unknown")" - if [[ ${machineSystem} == "unknown" ]]; then - buildOn=auto - return - fi - fi - - if [[ ${system} == "${machineSystem}" ]]; then - buildOn=local - return - fi - - if [[ ${extraPlatforms} == "*${machineSystem}*" ]]; then - buildOn=local - return - fi - - local entropy - entropy="$(date +'%Y%m%d%H%M%S')" - if nix build \ - -L \ - "${nixOptions[@]}" \ - --expr \ - "derivation { system = \"$system\"; name = \"env-$entropy\"; builder = \"/bin/sh\"; args = [ \"-c\" \"echo > \$out\" ]; }"; then - # The local build failed - buildOn=local - fi - - buildOn=remote -} - -generateHardwareConfig() { - local maybeSudo="$maybeSudo" - mkdir -p "$(dirname "$hardwareConfigPath")" - case "$hardwareConfigBackend" in - nixos-facter) - if [[ ${isInstaller} == "y" ]]; then - if [[ ${hasNixOSFacter} == "n" ]]; then - abort "nixos-facter is not available in booted installer, use nixos-generate-config. For nixos-facter, you may want to boot an installer image from here instead: https://github.com/nix-community/nixos-images" - fi - else - maybeSudo="" - fi - - step "Generating hardware-configuration.nix using nixos-facter" - runSshNoTty -o ConnectTimeout=10 ${maybeSudo} "nixos-facter" >"$hardwareConfigPath" - ;; - nixos-generate-config) - step "Generating hardware-configuration.nix using nixos-generate-config" - runSshNoTty -o ConnectTimeout=10 nixos-generate-config --show-hardware-config --no-filesystems >"$hardwareConfigPath" - ;; - *) - abort "Unknown hardware config backend: $hardwareConfigBackend" - ;; - esac - - # to make sure nix knows about the new file - if command -v git >/dev/null; then - # handle relative paths - hardwareConfigPath="$(realpath "$hardwareConfigPath")" - pushd "$(dirname "$hardwareConfigPath")" - if git rev-parse --is-inside-work-tree >/dev/null; then - git add --intent-to-add --force -- "$hardwareConfigPath" - fi - popd - fi -} - -runKexec() { - if [[ ${isKexec} == "y" ]] || [[ ${isInstaller} == "y" ]]; then - return - fi - - if [[ ${isContainer} != "none" ]]; then - echo "WARNING: This script does not support running from a '${isContainer}' container. kexec will likely not work" >&2 - fi - - if [[ $kexecUrl == "" ]]; then - case "${isArch}" in - x86_64 | aarch64) - kexecUrl="https://github.com/nix-community/nixos-images/releases/download/nixos-24.11/nixos-kexec-installer-noninteractive-${isArch}-linux.tar.gz" - ;; - *) - abort "Unsupported architecture: ${isArch}. Our default kexec images only support x86_64 and aarch64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information." - ;; - esac - fi - - step Switching system into kexec - runSsh sh < $path" <"${diskEncryptionKeys[$path]}" - done - if [[ -n ${diskoScript} ]]; then - nixCopy --to "ssh://$sshConnection?$sshStoreSettings" "$diskoScript" - elif [[ ${buildOn} == "remote" ]]; then - step Building disko script - # We need to do a nix copy first because nix build doesn't have --no-check-sigs - # Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359 - nixCopy --to "ssh://$sshConnection?$sshStoreSettings" "${flake}#${flakeAttr}.system.build.${diskoMode}Script" \ - --derivation --no-check-sigs - # If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store` - diskoScript=$( - nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}" \ - --eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir%2Fnixos-anywhere&$sshStoreSettings" - ) - fi - - step Formatting hard drive with disko - runSsh "$diskoScript" -} - -nixosInstall() { - local nixosSystem=$1 - if [[ -n ${nixosSystem} ]]; then - step Uploading the system closure - nixCopy --to "ssh://$sshConnection?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" "$nixosSystem" - elif [[ ${buildOn} == "remote" ]]; then - step Building the system closure - # We need to do a nix copy first because nix build doesn't have --no-check-sigs - # Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359 - nixCopy --to "ssh://$sshConnection?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" "${flake}#${flakeAttr}.system.build.toplevel" \ - --derivation --no-check-sigs - # If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store` - nixosSystem=$( - nixBuild "${flake}#${flakeAttr}.system.build.toplevel" \ - --eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir%2Fnixos-anywhere&remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" - ) - fi - - if [[ -n ${extraFiles} ]]; then - step Copying extra files - tar -C "$extraFiles" -cpf- . | runSsh "tar -C /mnt -xf- --no-same-owner" - - runSsh "chmod 755 /mnt" # tar also changes permissions of /mnt - fi - - if [[ ${#extraFilesOwnership[@]} -gt 0 ]]; then - # shellcheck disable=SC2016 - printf "%s\n" "${!extraFilesOwnership[@]}" "${extraFilesOwnership[@]}" | pr -2t | runSsh 'while read file ownership; do chown -R "$ownership" "/mnt/$file"; done' - fi - - step Installing NixOS - runSsh sh </dev/null && [ "\$(zpool list)" != "no pools available" ]; then - # we always want to export the zfs pools so people can boot from it without force import - umount -Rv /mnt/ - swapoff -a - zpool export -a || true - fi - nohup sh -c 'sleep 6 && reboot' >/dev/null & -fi -SSH - -} - -main() { - parseArgs "$@" - - if [[ ${vmTest} == y ]]; then - if [[ ${hardwareConfigBackend} != "none" ]]; then - abort "--vm-test is not supported with --generate-hardware-config. You need to generate the hardware configuration before you can run the VM test." >&2 - fi - runVmTest - exit 0 - fi - - if [[ ${buildOn} == "auto" ]]; then - checkBuildLocally - fi - - # parse flake nixos-install style syntax, get the system attr - if [[ -n ${flake} ]]; then - if [[ ${buildOn} == "local" ]] && [[ ${hardwareConfigBackend} == "none" ]]; then - if [[ ${phases[disko]} == 1 ]]; then - diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}") - fi - if [[ ${phases[install]} == 1 ]]; then - nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel") - fi - fi - elif [[ -n ${diskoScript} ]] && [[ -n ${nixosSystem} ]]; then - if [[ ! -e ${diskoScript} ]] || [[ ! -e ${nixosSystem} ]]; then - abort "${diskoScript} and ${nixosSystem} must be existing store-paths" - fi - else - abort "--flake or --store-paths must be set" - fi - - if [[ -n ${SSH_PRIVATE_KEY} ]] && [[ -z ${sshPrivateKeyFile} ]]; then - # $sshKeyDir is getting deleted on trap EXIT - sshPrivateKeyFile="$sshKeyDir/from-env" - ( - umask 077 - printf '%s\n' "$SSH_PRIVATE_KEY" >"$sshPrivateKeyFile" - ) - fi - - sshSettings=$(ssh "${sshArgs[@]}" -G "${sshConnection}") - sshUser=$(echo "$sshSettings" | awk '/^user / { print $2 }') - sshHost=$(echo "$sshSettings" | awk '/^hostname / { print $2 }') - - uploadSshKey - - importFacts - - if [[ ${hasTar-n} == "n" ]]; then - abort "no tar command found, but required to unpack kexec tarball" - fi - - if [[ ${hasCpio-n} == "n" ]]; then - abort "no cpio command found, but required to build the new initrd" - fi - - if [[ ${hasSetsid-n} == "n" ]]; then - abort "no setsid command found, but required to run the kexec script under a new session" - fi - - maybeSudo="" - if [[ ${hasSudo-n} == "y" ]]; then - maybeSudo="sudo" - elif [[ ${hasDoas-n} == "y" ]]; then - maybeSudo="doas" - fi - - if [[ ${isOs} != "Linux" ]]; then - abort "This script requires Linux as the operating system, but got $isOs" - fi - - if [[ ${phases[kexec]} == 1 ]]; then - runKexec - fi - - if [[ ${hardwareConfigBackend} != "none" ]]; then - generateHardwareConfig - fi - - # Before we do not have a valid hardware configuration we don't know the machine system - if [[ ${buildOn} == "auto" ]]; then - local remoteSystem - remoteSystem=$(runSshNoTty -o ConnectTimeout=10 nix --extra-experimental-features nix-command config show system) - checkBuildLocally "${remoteSystem}" - # if we cannot figure it out at this point, we will build on the remote host - if [[ ${buildOn} == "auto" ]]; then - buildOn=remote - fi - fi - - if [[ ${buildOn} != "remote" ]] && [[ -n ${flake} ]] && [[ -z ${diskoScript} ]]; then - if [[ ${phases[disko]} == 1 ]]; then - diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}") - fi - if [[ ${phases[install]} == 1 ]]; then - nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel") - fi - fi - - # Installation will fail if non-root user is used for installer. - # Switch to root user by copying authorized_keys. - if [[ ${isInstaller} == "y" ]] && [[ ${sshUser} != "root" ]]; then - # Allow copy to fail if authorized_keys does not exist, like if using /etc/ssh/authorized_keys.d/ - runSsh "${maybeSudo} mkdir -p /root/.ssh; ${maybeSudo} cp ~/.ssh/authorized_keys /root/.ssh || true" - sshConnection="root@${sshHost}" - fi - - if [[ ${phases[disko]} == 1 ]]; then - runDisko "$diskoScript" - fi - - if [[ ${phases[install]} == 1 ]]; then - nixosInstall "$nixosSystem" - fi - - if [[ ${phases[reboot]} == 1 ]]; then - step Waiting for the machine to become unreachable due to reboot - while runSshTimeout -- exit 0; do sleep 1; done - fi - - step "Done!" -} - -main "$@" diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/README.md b/launch/.terraform/modules/pixelfed.deploy/terraform/README.md deleted file mode 100644 index 2d66b1a8..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# NixOS-Anywhere Terraform Modules Overview - -The nixos-Anywhere terraform modules allow you to use Terraform for installing -and updating NixOS. It simplifies the deployment process by integrating -nixos-anywhere functionality. - -Here's a brief overview of each module: - -- **[All-in-One](all-in-one.md)**: This is a consolidated module that first - installs NixOS using nixos-anywhere and then keeps it updated with - nixos-rebuild. If you choose this, you won't need additional deployment tools - like colmena. -- **[Install](install.md)**: This module focuses solely on installing NixOS via - nixos-anywhere. -- **[NixOS-Rebuild](nixos-rebuild.md)**: Use this module to remotely update an - existing NixOS machine using nixos-rebuild. -- **[Nix-Build](nix-build.md)**: This is a handy helper module designed to build - a flake attribute or an attribute from a nix file. - -For detailed information and usage examples, click on the respective module -links above. diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one.md b/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one.md deleted file mode 100644 index c7279cf2..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one.md +++ /dev/null @@ -1,235 +0,0 @@ -# All-in-one - -Combines the install and nixos-rebuild module in one interface to install NixOS -with nixos-anywhere and then keep it up-to-date with nixos-rebuild. - -## Example - -```hcl -locals { - ipv4 = "192.0.2.1" -} - -module "deploy" { - source = "github.com/nix-community/nixos-anywhere//terraform/all-in-one" - # with flakes - nixos_system_attr = ".#nixosConfigurations.mymachine.config.system.build.toplevel" - nixos_partitioner_attr = ".#nixosConfigurations.mymachine.config.system.build.diskoScript" - # without flakes - # file can use (pkgs.nixos []) function from nixpkgs - #file = "${path.module}/../.." - #nixos_system_attr = "config.system.build.toplevel" - #nixos_partitioner_attr = "config.system.build.diskoScript" - - target_host = local.ipv4 - # when instance id changes, it will trigger a reinstall - instance_id = local.ipv4 - # useful if something goes wrong - # debug_logging = true - # build the closure on the remote machine instead of locally - # build_on_remote = true - # script is below - extra_files_script = "${path.module}/decrypt-ssh-secrets.sh" - disk_encryption_key_scripts = [{ - path = "/tmp/secret.key" - # script is below - script = "${path.module}/decrypt-zfs-key.sh" - }] - # Optional, arguments passed to special_args here will be available from a NixOS module in this example the `terraform` argument: - # { terraform, ... }: { - # networking.interfaces.enp0s3.ipv4.addresses = [{ address = terraform.ip; prefixLength = 24; }]; - # } - # Note that this will means that your NixOS configuration will always depend on terraform! - # Skip to `Pass data persistently to the NixOS` for an alternative approach - #special_args = { - # terraform = { - # ip = "192.0.2.0" - # } - #} -} -``` - -_Note:_ You need to mark scripts as executable (`chmod +x`) - -### ./decrypt-ssh-secrets.sh - -```bash -#!/usr/bin/env bash - -mkdir -p etc/ssh var/lib/secrets - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - -umask 0177 -sops --extract '["initrd_ssh_key"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >./var/lib/secrets/initrd_ssh_key - -# restore umask -umask 0022 - -for keyname in ssh_host_rsa_key ssh_host_rsa_key.pub ssh_host_ed25519_key ssh_host_ed25519_key.pub; do - if [[ $keyname == *.pub ]]; then - umask 0133 - else - umask 0177 - fi - sops --extract '["'$keyname'"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >"./etc/ssh/$keyname" -done -``` - -### ./decrypt-zfs-key.sh - -```bash -#!/usr/bin/env bash - -set -euo pipefail - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -cd "$SCRIPT_DIR" -sops --extract '["zfs-key"]' --decrypt "$SCRIPT_DIR/secrets.yaml" -``` - -## See also - -- [nixos-wiki setup](https://github.com/NixOS/nixos-wiki-infra/blob/main/terraform/nixos-wiki/main.tf) - for hetzner-cloud - -## Pass data persistently to the NixOS - -This guide outlines how to pass data from Terraform to NixOS by generating a -file during Terraform execution and including it in your NixOS configuration. -This approach works well if your Terraform and NixOS configurations are stored -in the same Git repository. - -### Why Use This Method? - -This method provides a straightforward way to transfer values from Terraform to -NixOS without relying on special_args. - -- **Advantages**: - - You can continue to use nix build or nixos-rebuild to evaluate your - configuration without interruption. Simplifies configuration management by - centralizing state in a single repository. -- **Disadvantages**: - - Deploying new machines requires tracking additional state. Every time - Terraform updates the JSON file, you'll need to commit these changes to your - repository. - -### Implementation - -Add the following snippet to your Terraform configuration to create and manage a -JSON file containing the necessary variables for NixOS. This file will be -automatically added to your Git repository, ensuring the data persists. - -Assuming you have your terraform and nixos configuration in the same git -repository. You can use the following snippet to `git add` a file generated by -`terraform` during execution to pass data from terraform to NixOS. These changes -should be committed afterwards. This is an alternative over using -`special_args`. Advantage: you can still use nix build or nixos-rebuild on your -flake to evaluate your configuration. Disadvantage: Deploying new machines also -means you need to track additional state and make additional commits whenever -terraform updates the json file. - -```hcl -locals { - nixos_vars_file = "nixos-vars.json" # Path to the JSON file containing NixOS variables - nixos_vars = { - ip = "192.0.2.0" # Replace with actual variables - } -} -resource "local_file" "nixos_vars" { - content = jsonencode(local.nixos_vars) # Converts variables to JSON - filename = local.nixos_vars_file # Specifies the output file path - file_permission = "600" - - # Automatically adds the generated file to Git - provisioner "local-exec" { - interpreter = ["bash", "-c"] - command = "git add -f '${local.nixos_vars_file}'" - } -} -``` - -After applying the Terraform changes, ensure you commit the updated -`nixos-vars.json` file to your Git repository: - -```bash -git commit -m "Update NixOS variables from Terraform" -``` - -You can import this json file into your configuration like this: - -```nix -let - nixosVars = builtins.fromJSON (builtins.readFile ./nixos-vars.json); -in -{ - # Example usage of imported variables - networking.hostName = "example-machine"; - networking.interfaces.eth0.ipv4.addresses = [ - { - address = nixosVars.ip; # Use the IP from nixos-vars.json - prefixLength = 24; - } - ]; -} -``` - - - -## Requirements - -No requirements. - -## Providers - -No providers. - -## Modules - -| Name | Source | Version | -| -------------------------------------------------------------------------------------- | ---------------- | ------- | -| [install](#module_install) | ../install | n/a | -| [nixos-rebuild](#module_nixos-rebuild) | ../nixos-rebuild | n/a | -| [partitioner-build](#module_partitioner-build) | ../nix-build | n/a | -| [system-build](#module_system-build) | ../nix-build | n/a | - -## Resources - -No resources. - -## Inputs - -| Name | Description | Type | Default | Required | -| --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | :------: | -| [debug\_logging](#input_debug_logging) | Enable debug logging | `bool` | `false` | no | -| [deployment\_ssh\_key](#input_deployment_ssh_key) | Content of private key used to deploy to the target\_host after initial installation. To ensure maximum security, it is advisable to connect to your host using ssh-agent instead of relying on this variable | `string` | `null` | no | -| [disk\_encryption\_key\_scripts](#input_disk_encryption_key_scripts) | Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system |
list(object({
path = string
script = string
}))
| `[]` | no | -| [extra\_environment](#input_extra_environment) | Extra environment variables to be set during installation. This can be useful to set extra variables for the extra\_files\_script or disk\_encryption\_key\_scripts | `map(string)` | `{}` | no | -| [extra\_files\_script](#input_extra_files_script) | A script that should place files in the current directory that will be copied to the targets / directory | `string` | `null` | no | -| [file](#input_file) | Nix file containing the nixos\_system\_attr and nixos\_partitioner\_attr. Use this if you are not using flake | `string` | `null` | no | -| [install\_port](#input_install_port) | SSH port used to connect to the target\_host, before installing NixOS. If null than the value of `target_port` is used | `string` | `null` | no | -| [install\_ssh\_key](#input_install_ssh_key) | Content of private key used to connect to the target\_host during initial installation | `string` | `null` | no | -| [install\_user](#input_install_user) | SSH user used to connect to the target\_host, before installing NixOS. If null than the value of `target_host` is used | `string` | `null` | no | -| [instance\_id](#input_instance_id) | The instance id of the target\_host, used to track when to reinstall the machine | `string` | `null` | no | -| [kexec\_tarball\_url](#input_kexec_tarball_url) | NixOS kexec installer tarball url | `string` | `null` | no | -| [nix\_options](#input_nix_options) | the options of nix | `map(string)` | `{}` | no | -| [nixos\_facter\_path](#input_nixos_facter_path) | Path to which to write a `facter.json` generated by `nixos-facter`. | `string` | `""` | no | -| [nixos\_generate\_config\_path](#input_nixos_generate_config_path) | Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. | `string` | `""` | no | -| [nixos\_partitioner\_attr](#input_nixos_partitioner_attr) | Nixos partitioner and mount script i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.diskoNoDeps or just your-evaluated.config.system.build.diskNoDeps. `config.system.build.diskNoDeps` is provided by the disko nixos module | `string` | n/a | yes | -| [nixos\_system\_attr](#input_nixos_system_attr) | The nixos system to deploy i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.toplevel or just your-evaluated-nixos.config.system.build.toplevel if you are not using flakes | `string` | n/a | yes | -| [no\_reboot](#input_no_reboot) | DEPRECATED: Use `phases` instead. Do not reboot after installation | `bool` | `false` | no | -| [phases](#input_phases) | Phases to run. See `nixos-anywhere --help` for more information | `set(string)` |
[
"kexec",
"disko",
"install",
"reboot"
]
| no | -| [special\_args](#input_special_args) | A map exposed as NixOS's `specialArgs` thru a file. | `any` | `{}` | no | -| [build\_on\_remote](#input_build_on_remote) | Build the closure on the remote machine instead of building it locally and copying it over | `bool` | `false` | no | -| [stop\_after\_disko](#input_stop_after_disko) | DEPRECATED: Use `phases` instead. Exit after disko formatting | `bool` | `false` | no | -| [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes | -| [target\_port](#input_target_port) | SSH port used to connect to the target\_host after installing NixOS. If install\_port is not set than this port is also used before installing. | `number` | `22` | no | -| [target\_user](#input_target_user) | SSH user used to connect to the target\_host after installing NixOS. If install\_user is not set than this user is also used before installing. | `string` | `"root"` | no | - -## Outputs - -| Name | Description | -| ----------------------------------------------------- | ----------- | -| [result](#output_result) | n/a | - - diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/main.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/main.tf deleted file mode 100644 index fa5d7eb3..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/main.tf +++ /dev/null @@ -1,64 +0,0 @@ -module "system-build" { - source = "../nix-build" - attribute = var.nixos_system_attr - file = var.file - nix_options = var.nix_options - special_args = var.special_args -} - -module "partitioner-build" { - source = "../nix-build" - attribute = var.nixos_partitioner_attr - file = var.file - nix_options = var.nix_options - special_args = var.special_args -} - -locals { - install_user = var.install_user == null ? var.target_user : var.install_user - install_port = var.install_port == null ? var.target_port : var.install_port -} - -module "install" { - source = "../install" - kexec_tarball_url = var.kexec_tarball_url - target_user = local.install_user - target_host = var.target_host - target_port = local.install_port - nixos_partitioner = module.partitioner-build.result.out - nixos_system = module.system-build.result.out - ssh_private_key = var.install_ssh_key - debug_logging = var.debug_logging - extra_files_script = var.extra_files_script - disk_encryption_key_scripts = var.disk_encryption_key_scripts - extra_environment = var.extra_environment - instance_id = var.instance_id - phases = var.phases - nixos_generate_config_path = var.nixos_generate_config_path - nixos_facter_path = var.nixos_facter_path - build_on_remote = var.build_on_remote - # deprecated attributes - stop_after_disko = var.stop_after_disko - no_reboot = var.no_reboot -} - -module "nixos-rebuild" { - depends_on = [ - module.install - ] - - # Do not execute this step if var.stop_after_disko == true - count = var.stop_after_disko ? 0 : 1 - - source = "../nixos-rebuild" - nixos_system = module.system-build.result.out - ssh_private_key = var.deployment_ssh_key - target_host = var.target_host - target_user = var.target_user - target_port = var.target_port - install_bootloader = var.install_bootloader -} - -output "result" { - value = module.system-build.result -} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/variables.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/variables.tf deleted file mode 100644 index 3ca27922..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/all-in-one/variables.tf +++ /dev/null @@ -1,151 +0,0 @@ -variable "kexec_tarball_url" { - type = string - description = "NixOS kexec installer tarball url" - default = null -} - -# To make this re-usable we maybe should accept a store path here? -variable "nixos_partitioner_attr" { - type = string - description = "Nixos partitioner and mount script i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.diskoNoDeps or just your-evaluated.config.system.build.diskNoDeps. `config.system.build.diskNoDeps` is provided by the disko nixos module" -} - -# To make this re-usable we maybe should accept a store path here? -variable "nixos_system_attr" { - type = string - description = "The nixos system to deploy i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.toplevel or just your-evaluated-nixos.config.system.build.toplevel if you are not using flakes" -} - -variable "file" { - type = string - description = "Nix file containing the nixos_system_attr and nixos_partitioner_attr. Use this if you are not using flake" - default = null -} - -variable "target_host" { - type = string - description = "DNS host to deploy to" -} - -variable "install_user" { - type = string - description = "SSH user used to connect to the target_host, before installing NixOS. If null than the value of `target_host` is used" - default = null -} - -variable "install_port" { - type = string - description = "SSH port used to connect to the target_host, before installing NixOS. If null than the value of `target_port` is used" - default = null -} - -variable "target_user" { - type = string - description = "SSH user used to connect to the target_host after installing NixOS. If install_user is not set than this user is also used before installing." - default = "root" -} - -variable "target_port" { - type = number - description = "SSH port used to connect to the target_host after installing NixOS. If install_port is not set than this port is also used before installing." - default = 22 -} - -variable "instance_id" { - type = string - description = "The instance id of the target_host, used to track when to reinstall the machine" - default = null -} - -variable "install_ssh_key" { - type = string - description = "Content of private key used to connect to the target_host during initial installation" - default = null -} - -variable "deployment_ssh_key" { - type = string - description = "Content of private key used to deploy to the target_host after initial installation. To ensure maximum security, it is advisable to connect to your host using ssh-agent instead of relying on this variable" - default = null -} - -variable "debug_logging" { - type = bool - description = "Enable debug logging" - default = false -} - -variable "stop_after_disko" { - type = bool - description = "DEPRECATED: Use `phases` instead. Exit after disko formatting" - default = false -} - -variable "no_reboot" { - type = bool - description = "DEPRECATED: Use `phases` instead. Do not reboot after installation" - default = false -} - -variable "phases" { - type = set(string) - description = "Phases to run. See `nixos-anywhere --help` for more information" - default = ["kexec", "disko", "install", "reboot"] -} - -variable "extra_files_script" { - type = string - description = "A script that should place files in the current directory that will be copied to the targets / directory" - default = null -} - -variable "disk_encryption_key_scripts" { - type = list(object({ - path = string - script = string - })) - description = "Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system" - default = [] -} - -variable "extra_environment" { - type = map(string) - description = "Extra environment variables to be set during installation. This can be useful to set extra variables for the extra_files_script or disk_encryption_key_scripts" - default = {} -} - -variable "nix_options" { - type = map(string) - description = "the options of nix" - default = {} -} - -variable "nixos_generate_config_path" { - type = string - description = "Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`." - default = "" -} - -variable "nixos_facter_path" { - type = string - description = "Path to which to write a `facter.json` generated by `nixos-facter`." - default = "" -} - -variable "special_args" { - type = any - default = {} - description = "A map exposed as NixOS's `specialArgs` thru a file." -} - -variable "build_on_remote" { - type = bool - description = "Build the closure on the remote machine instead of building it locally and copying it over" - default = false -} - -variable "install_bootloader" { - type = bool - description = "Install/re-install the bootloader" - default = false -} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/install.md b/launch/.terraform/modules/pixelfed.deploy/terraform/install.md deleted file mode 100644 index eb3439fc..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/install.md +++ /dev/null @@ -1,91 +0,0 @@ -# Install - -Install NixOS with nixos-anywhere - -## Example - -```hcl -locals { - ipv4 = "192.0.2.1" -} - -module "system-build" { - source = "github.com/nix-community/nixos-anywhere//terraform/nix-build" - # with flakes - attribute = ".#nixosConfigurations.mymachine.config.system.build.toplevel" - # without flakes - # file can use (pkgs.nixos []) function from nixpkgs - #file = "${path.module}/../.." - #attribute = "config.system.build.toplevel" -} - -module "disko" { - source = "github.com/nix-community/nixos-anywhere//terraform/nix-build" - # with flakes - attribute = ".#nixosConfigurations.mymachine.config.system.build.diskoScript" - # without flakes - # file can use (pkgs.nixos []) function from nixpkgs - #file = "${path.module}/../.." - #attribute = "config.system.build.diskoScript" -} - -module "install" { - source = "github.com/nix-community/nixos-anywhere//terraform/install" - nixos_system = module.system-build.result.out - nixos_partitioner = module.disko.result.out - target_host = local.ipv4 -} -``` - - - -## Requirements - -No requirements. - -## Providers - -| Name | Version | -| --------------------------------------------------- | ------- | -| [null](#provider_null) | n/a | - -## Modules - -No modules. - -## Resources - -| Name | Type | -| ------------------------------------------------------------------------------------------------------------------- | -------- | -| [null_resource.nixos-remote](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | - -## Inputs - -| Name | Description | Type | Default | Required | -| --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | :------: | -| [build\_on\_remote](#input_build_on_remote) | Build the closure on the remote machine instead of building it locally and copying it over | `bool` | `false` | no | -| [debug\_logging](#input_debug_logging) | Enable debug logging | `bool` | `false` | no | -| [disk\_encryption\_key\_scripts](#input_disk_encryption_key_scripts) | Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system |
list(object({
path = string
script = string
}))
| `[]` | no | -| [extra\_environment](#input_extra_environment) | Extra environment variables to be set during installation. This can be useful to set extra variables for the extra\_files\_script or disk\_encryption\_key\_scripts | `map(string)` | `{}` | no | -| [extra\_files\_script](#input_extra_files_script) | A script that should place files in the current directory that will be copied to the targets / directory | `string` | `null` | no | -| [flake](#input_flake) | The flake to install the system from | `string` | `""` | no | -| [instance\_id](#input_instance_id) | The instance id of the target\_host, used to track when to reinstall the machine | `string` | `null` | no | -| [kexec\_tarball\_url](#input_kexec_tarball_url) | NixOS kexec installer tarball url | `string` | `null` | no | -| [nixos\_facter\_path](#input_nixos_facter_path) | Path to which to write a `facter.json` generated by `nixos-facter`. This option cannot be set at the same time as `nixos_generate_config_path`. | `string` | `""` | no | -| [nixos\_generate\_config\_path](#input_nixos_generate_config_path) | Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. This option cannot be set at the same time as `nixos_facter_path`. | `string` | `""` | no | -| [nixos\_partitioner](#input_nixos_partitioner) | nixos partitioner and mount script | `string` | `""` | no | -| [nixos\_system](#input_nixos_system) | The nixos system to deploy | `string` | `""` | no | -| [no\_reboot](#input_no_reboot) | DEPRECATED: Use `phases` instead. Do not reboot after installation | `bool` | `false` | no | -| [phases](#input_phases) | Phases to run. See `nixos-anywhere --help` for more information | `list(string)` |
[
"kexec",
"disko",
"install",
"reboot"
]
| no | -| [ssh\_private\_key](#input_ssh_private_key) | Content of private key used to connect to the target\_host | `string` | `""` | no | -| [stop\_after\_disko](#input_stop_after_disko) | DEPRECATED: Use `phases` instead. Exit after disko formatting | `bool` | `false` | no | -| [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes | -| [target\_pass](#input_target_pass) | Password used to connect to the target\_host | `string` | `null` | no | -| [target\_port](#input_target_port) | SSH port used to connect to the target\_host | `number` | `22` | no | -| [target\_user](#input_target_user) | SSH user used to connect to the target\_host | `string` | `"root"` | no | - -## Outputs - -No outputs. - - diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/install/main.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/install/main.tf deleted file mode 100644 index 9f1816ac..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/install/main.tf +++ /dev/null @@ -1,35 +0,0 @@ -locals { - disk_encryption_key_scripts = [for k in var.disk_encryption_key_scripts : "\"${k.path}\" \"${k.script}\""] - removed_phases = setunion(var.stop_after_disko ? ["install"] : [], (var.no_reboot ? ["reboot"] : [])) - phases = setsubtract(var.phases, local.removed_phases) - arguments = jsonencode({ - ssh_private_key = var.ssh_private_key - debug_logging = var.debug_logging - kexec_tarball_url = var.kexec_tarball_url - nixos_partitioner = var.nixos_partitioner - nixos_system = var.nixos_system - target_user = var.target_user - target_host = var.target_host - target_port = var.target_port - target_pass = var.target_pass - extra_files_script = var.extra_files_script - build_on_remote = var.build_on_remote - flake = var.flake - phases = join(",", local.phases) - nixos_generate_config_path = var.nixos_generate_config_path - nixos_facter_path = var.nixos_facter_path - }) -} - -resource "null_resource" "nixos-remote" { - triggers = { - instance_id = var.instance_id - } - provisioner "local-exec" { - environment = merge({ - ARGUMENTS = local.arguments - }, var.extra_environment) - command = "${path.module}/run-nixos-anywhere.sh ${join(" ", local.disk_encryption_key_scripts)}" - quiet = var.debug_logging - } -} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/install/providers.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/install/providers.tf deleted file mode 100644 index c3e00a54..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/install/providers.tf +++ /dev/null @@ -1,5 +0,0 @@ -terraform { - required_providers { - null = { source = "hashicorp/null" } - } -} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/install/run-nixos-anywhere.sh b/launch/.terraform/modules/pixelfed.deploy/terraform/install/run-nixos-anywhere.sh deleted file mode 100755 index 1d259a1e..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/install/run-nixos-anywhere.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" - -declare -A input - -while IFS= read -r -d '' key && IFS= read -r -d '' value; do - input[$key]=$value -done < <(jq -j 'to_entries[] | (.key, "\u0000", .value, "\u0000")' <<<"${ARGUMENTS}") - -args=() - -if [[ ${input[debug_logging]} == "true" ]]; then - set -x - declare -p input - args+=("--debug") -fi -if [[ ${input[kexec_tarball_url]} != "null" ]]; then - args+=("--kexec" "${input[kexec_tarball_url]}") -fi -if [[ ${input[build_on_remote]} == "true" ]]; then - args+=("--build-on-remote") -fi -if [[ -n ${input[flake]} ]]; then - args+=("--flake" "${input[flake]}") -else - args+=("--store-paths" "${input[nixos_partitioner]}" "${input[nixos_system]}") -fi -if [[ -n ${input[nixos_generate_config_path]} ]]; then - if [[ -n ${input[nixos_facter_path]} ]]; then - echo "cannot set both variables 'nixos_generate_config_path' and 'nixos_facter_path'!" >&2 - exit 1 - fi - args+=("--generate-hardware-config" "nixos-generate-config" "${input[nixos_generate_config_path]}") -elif [[ -n ${input[nixos_facter_path]} ]]; then - args+=("--generate-hardware-config" "nixos-facter" "${input[nixos_facter_path]}") -fi -args+=(--phases "${input[phases]}") -if [[ ${input[ssh_private_key]} != null ]]; then - export SSH_PRIVATE_KEY="${input[ssh_private_key]}" -fi -if [[ ${input[target_pass]} != null ]]; then - export SSHPASS=${input[target_pass]} - args+=("--env-password") -fi - -tmpdir=$(mktemp -d) -cleanup() { - rm -rf "${tmpdir}" -} -trap cleanup EXIT - -if [[ ${input[extra_files_script]} != "null" ]]; then - if [[ ! -f ${input[extra_files_script]} ]]; then - echo "extra_files_script '${input[extra_files_script]}' does not exist" - exit 1 - fi - if [[ ! -x ${input[extra_files_script]} ]]; then - echo "extra_files_script '${input[extra_files_script]}' is not executable" - exit 1 - fi - extra_files_script=$(realpath "${input[extra_files_script]}") - mkdir "${tmpdir}/extra-files" - pushd "${tmpdir}/extra-files" - $extra_files_script - popd - args+=("--extra-files" "${tmpdir}/extra-files") -fi - -args+=("-p" "${input[target_port]}") -args+=("${input[target_user]}@${input[target_host]}") - -keyIdx=0 -while [[ $# -gt 0 ]]; do - if [[ ! -f $2 ]]; then - echo "Script file '$2' does not exist" - exit 1 - fi - if [[ ! -x $2 ]]; then - echo "Script file '$2' is not executable" - exit 1 - fi - mkdir -p "${tmpdir}/keys" - "$2" >"${tmpdir}/keys/$keyIdx" - args+=("--disk-encryption-keys" "$1" "${tmpdir}/keys/$keyIdx") - shift - shift - keyIdx=$((keyIdx + 1)) -done - -nix run --extra-experimental-features 'nix-command flakes' "path:${SCRIPT_DIR}/../..#nixos-anywhere" -- "${args[@]}" diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/install/variables.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/install/variables.tf deleted file mode 100644 index cd07bf70..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/install/variables.tf +++ /dev/null @@ -1,123 +0,0 @@ -variable "kexec_tarball_url" { - type = string - description = "NixOS kexec installer tarball url" - default = null -} - -# To make this re-usable we maybe should accept a store path here? -variable "nixos_partitioner" { - type = string - description = "nixos partitioner and mount script" - default = "" -} - -# To make this re-usable we maybe should accept a store path here? -variable "nixos_system" { - type = string - description = "The nixos system to deploy" - default = "" -} - -variable "target_host" { - type = string - description = "DNS host to deploy to" -} - -variable "target_user" { - type = string - description = "SSH user used to connect to the target_host" - default = "root" -} - -variable "target_port" { - type = number - description = "SSH port used to connect to the target_host" - default = 22 -} - -variable "target_pass" { - type = string - description = "Password used to connect to the target_host" - default = null -} - -variable "ssh_private_key" { - type = string - description = "Content of private key used to connect to the target_host" - default = "" -} - -variable "instance_id" { - type = string - description = "The instance id of the target_host, used to track when to reinstall the machine" - default = null -} - -variable "debug_logging" { - type = bool - description = "Enable debug logging" - default = false -} - -variable "extra_files_script" { - type = string - description = "A script that should place files in the current directory that will be copied to the targets / directory" - default = null -} - -variable "disk_encryption_key_scripts" { - type = list(object({ - path = string - script = string - })) - description = "Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system" - default = [] -} - -variable "extra_environment" { - type = map(string) - description = "Extra environment variables to be set during installation. This can be useful to set extra variables for the extra_files_script or disk_encryption_key_scripts" - default = {} -} - -variable "stop_after_disko" { - type = bool - description = "DEPRECATED: Use `phases` instead. Exit after disko formatting" - default = false -} - -variable "no_reboot" { - type = bool - description = "DEPRECATED: Use `phases` instead. Do not reboot after installation" - default = false -} - -variable "phases" { - type = list(string) - description = "Phases to run. See `nixos-anywhere --help` for more information" - default = ["kexec", "disko", "install", "reboot"] -} - -variable "build_on_remote" { - type = bool - description = "Build the closure on the remote machine instead of building it locally and copying it over" - default = false -} - -variable "flake" { - type = string - description = "The flake to install the system from" - default = "" -} - -variable "nixos_generate_config_path" { - type = string - description = "Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. This option cannot be set at the same time as `nixos_facter_path`." - default = "" -} - -variable "nixos_facter_path" { - type = string - description = "Path to which to write a `facter.json` generated by `nixos-facter`. This option cannot be set at the same time as `nixos_generate_config_path`." - default = "" -} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build.md b/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build.md deleted file mode 100644 index fe63af12..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build.md +++ /dev/null @@ -1,47 +0,0 @@ -# Nix-build - -Small helper module to run do build a flake attribute or attribute from a nix -file. - -## Example - -- See [install](install.md) or [nixos-rebuild](nixos-rebuild.md) - - - -## Requirements - -No requirements. - -## Providers - -| Name | Version | -| --------------------------------------------------------------- | ------- | -| [external](#provider_external) | n/a | - -## Modules - -No modules. - -## Resources - -| Name | Type | -| --------------------------------------------------------------------------------------------------------------------------- | ----------- | -| [external_external.nix-build](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -| ---------------------------------------------------------------------- | --------------------------------------------------- | ------------- | ------- | :------: | -| [attribute](#input_attribute) | the attribute to build, can also be a flake | `string` | n/a | yes | -| [file](#input_file) | the nix file to evaluate, if not run in flake mode | `string` | `null` | no | -| [nix\_options](#input_nix_options) | the options of nix | `map(string)` | `{}` | no | -| [special\_args](#input_special_args) | A map exposed as NixOS's `specialArgs` thru a file. | `any` | `{}` | no | - -## Outputs - -| Name | Description | -| ----------------------------------------------------- | ----------- | -| [result](#output_result) | n/a | - - diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/main.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/main.tf deleted file mode 100644 index 7a3c335f..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/main.tf +++ /dev/null @@ -1,17 +0,0 @@ -locals { - nix_options = jsonencode({ - options = { for k, v in var.nix_options : k => v } - }) -} -data "external" "nix-build" { - program = [ "${path.module}/nix-build.sh" ] - query = { - attribute = var.attribute - file = var.file - nix_options = local.nix_options - special_args = jsonencode(var.special_args) - } -} -output "result" { - value = data.external.nix-build.result -} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/nix-build.sh b/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/nix-build.sh deleted file mode 100755 index 0e22357e..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/nix-build.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash -set -efu - -declare file attribute nix_options special_args -eval "$(jq -r '@sh "attribute=\(.attribute) file=\(.file) nix_options=\(.nix_options) special_args=\(.special_args)"')" -if [ "${nix_options}" != '{"options":{}}' ]; then - options=$(echo "${nix_options}" | jq -r '.options | to_entries | map("--option \(.key) \(.value)") | join(" ")') -else - options="" -fi -if [[ ${special_args-} == "{}" ]]; then - # no special arguments, proceed as normal - if [[ -n ${file-} ]] && [[ -e ${file-} ]]; then - # shellcheck disable=SC2086 - out=$(nix build --no-link --json $options -f "$file" "$attribute") - else - # shellcheck disable=SC2086 - out=$(nix build --no-link --json ${options} "$attribute") - fi -else - if [[ ${file-} != 'null' ]]; then - echo "special_args are currently only supported when using flakes!" >&2 - exit 1 - fi - # pass the args in a pure fashion by extending the original config - rest="$(echo "${attribute}" | cut -d "#" -f 2)" - # e.g. config_path=nixosConfigurations.aarch64-linux.myconfig - config_path="${rest%.config.*}" - # e.g. config_attribute=config.system.build.toplevel - config_attribute="config.${rest#*.config.}" - - # grab flake nar from error message - flake_rel="$(echo "${attribute}" | cut -d "#" -f 1)" - # e.g. flake_rel="." - flake_dir="$(readlink -f "${flake_rel}")" - flake_path="${flake_dir}/flake.nix" - flake_json="$(nix flake prefetch "${flake_dir}" --json)" - flake_nar="$(echo "$flake_json" | jq -r '.hash')" - store_path="$(echo "${flake_json}" | jq -r '.storePath')" - # while we have a store path now, for a repo this reflects its root level, - # so search for the largest child segment yielding a match in that store dir. - iter_path="${flake_path}" - while [[ ${iter_path} != "/" ]]; do - parent="$(dirname "${iter_path}")" - child_segment="${flake_path//$parent/}" - if [[ -f "${store_path}${child_segment}" ]]; then - target_segment="${child_segment}" - fi - iter_path="${parent}" - done - # substitute variables into the template - nix_expr="(builtins.getFlake ''file://${flake_dir}?dir=${target_segment//\/flake.nix/}&narHash=${flake_nar}'').${config_path}.extendModules { specialArgs = builtins.fromJSON ''${special_args}''; }" - # inject `special_args` into nixos config's `specialArgs` - # shellcheck disable=SC2086 - out=$(nix build --no-link --json ${options} --expr "${nix_expr}" "${config_attribute}") -fi -printf '%s' "$out" | jq -c '.[].outputs' diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/variables.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/variables.tf deleted file mode 100644 index bad23f73..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/nix-build/variables.tf +++ /dev/null @@ -1,22 +0,0 @@ -variable "attribute" { - type = string - description = "the attribute to build, can also be a flake" -} - -variable "file" { - type = string - description = "the nix file to evaluate, if not run in flake mode" - default = null -} - -variable "nix_options" { - type = map(string) - description = "the options of nix" - default = {} -} - -variable "special_args" { - type = any - default = {} - description = "A map exposed as NixOS's `specialArgs` thru a file." -} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild.md b/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild.md deleted file mode 100644 index 0be26bb7..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild.md +++ /dev/null @@ -1,66 +0,0 @@ -# Nixos-rebuild - -Update NixOS machine with nixos-rebuild on a remote machine - -## Example - -```hcl -locals { - ipv4 = "192.0.2.1" -} - -module "system-build" { - source = "github.com/nix-community/nixos-anywhere//terraform/nix-build" - # with flakes - attribute = ".#nixosConfigurations.mymachine.config.system.build.toplevel" - # without flakes - # file can use (pkgs.nixos []) function from nixpkgs - #file = "${path.module}/../.." - #attribute = "config.system.build.toplevel" -} - -module "deploy" { - source = "github.com/nix-community/nixos-anywhere//terraform/nixos-rebuild" - nixos_system = module.system-build.result.out - target_host = local.ipv4 -} -``` - - - -## Requirements - -No requirements. - -## Providers - -| Name | Version | -| --------------------------------------------------- | ------- | -| [null](#provider_null) | n/a | - -## Modules - -No modules. - -## Resources - -| Name | Type | -| -------------------------------------------------------------------------------------------------------------------- | -------- | -| [null_resource.nixos-rebuild](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | - -## Inputs - -| Name | Description | Type | Default | Required | -| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------- | -------- | :------: | -| [ignore\_systemd\_errors](#input_ignore_systemd_errors) | Ignore systemd errors happening during deploy | `bool` | `false` | no | -| [nixos\_system](#input_nixos_system) | The nixos system to deploy | `string` | n/a | yes | -| [ssh\_private\_key](#input_ssh_private_key) | Content of private key used to connect to the target\_host. If set to - no key is passed to openssh and ssh will use its own configuration | `string` | `"-"` | no | -| [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes | -| [target\_port](#input_target_port) | SSH port used to connect to the target\_host | `number` | `22` | no | -| [target\_user](#input_target_user) | User to deploy as | `string` | `"root"` | no | - -## Outputs - -No outputs. - - diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/deploy.sh b/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/deploy.sh deleted file mode 100755 index 61da6e1c..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/deploy.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash - -set -uex -o pipefail - -if [ "$#" -ne 6 ]; then - echo "USAGE: $0 NIXOS_SYSTEM TARGET_USER TARGET_HOST TARGET_PORT IGNORE_SYSTEMD_ERRORS INSTALL_BOOTLOADER" >&2 - exit 1 -fi - -NIXOS_SYSTEM=$1 -TARGET_USER=$2 -TARGET_HOST=$3 -TARGET_PORT=$4 -IGNORE_SYSTEMD_ERRORS=$5 -INSTALL_BOOTLOADER=$6 - -shift 6 - -TARGET="${TARGET_USER}@${TARGET_HOST}" - -workDir=$(mktemp -d) -trap 'rm -rf "$workDir"' EXIT - -sshOpts=(-p "${TARGET_PORT}") -sshOpts+=(-o UserKnownHostsFile=/dev/null) -sshOpts+=(-o StrictHostKeyChecking=no) - -set +x -if [[ -n ${SSH_KEY+x} && ${SSH_KEY} != "-" ]]; then - sshPrivateKeyFile="$workDir/ssh_key" - # Create the file with 0700 - umask calculation: 777 - 700 = 077 - ( - umask 077 - echo "$SSH_KEY" >"$sshPrivateKeyFile" - ) - unset SSH_AUTH_SOCK # don't use system agent if key was supplied - sshOpts+=(-o "IdentityFile=${sshPrivateKeyFile}") -fi -set -x - -try=1 -until NIX_SSHOPTS="${sshOpts[*]}" nix copy -s --experimental-features nix-command --to "ssh://$TARGET" "$NIXOS_SYSTEM"; do - if [[ $try -gt 10 ]]; then - echo "retries exhausted" >&2 - exit 1 - fi - sleep 10 - try=$((try + 1)) -done - -if [[ $INSTALL_BOOTLOADER == "true" ]]; then - extra_env='NIXOS_INSTALL_BOOTLOADER=1' -else - extra_env='' -fi - -switchCommand="nix-env -p /nix/var/nix/profiles/system --set $(printf "%q" "$NIXOS_SYSTEM"); $extra_env /nix/var/nix/profiles/system/bin/switch-to-configuration switch" - -if [[ $TARGET_USER != "root" ]]; then - switchCommand="sudo bash -c '$switchCommand'" -fi -deploy_status=0 -# shellcheck disable=SC2029 -ssh "${sshOpts[@]}" "$TARGET" "$switchCommand" || deploy_status="$?" -if [[ $IGNORE_SYSTEMD_ERRORS == "true" && $deploy_status == "4" ]]; then - exit 0 -fi -exit "$deploy_status" diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/main.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/main.tf deleted file mode 100644 index 84461c80..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/main.tf +++ /dev/null @@ -1,11 +0,0 @@ -resource "null_resource" "nixos-rebuild" { - triggers = { - store_path = var.nixos_system - } - provisioner "local-exec" { - environment = { - SSH_KEY = var.ssh_private_key - } - command = "${path.module}/deploy.sh ${var.nixos_system} ${var.target_user} ${var.target_host} ${var.target_port} ${var.ignore_systemd_errors} ${var.install_bootloader}" - } -} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/variables.tf b/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/variables.tf deleted file mode 100644 index 90e0b0c6..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/nixos-rebuild/variables.tf +++ /dev/null @@ -1,39 +0,0 @@ -variable "nixos_system" { - type = string - description = "The nixos system to deploy" -} - -variable "target_host" { - type = string - description = "DNS host to deploy to" -} - -variable "target_user" { - type = string - default = "root" - description = "User to deploy as" -} - -variable "target_port" { - type = number - description = "SSH port used to connect to the target_host" - default = 22 -} - -variable "ssh_private_key" { - type = string - description = "Content of private key used to connect to the target_host. If set to - no key is passed to openssh and ssh will use its own configuration" - default = "-" -} - -variable "ignore_systemd_errors" { - type = bool - description = "Ignore systemd errors happening during deploy" - default = false -} - -variable "install_bootloader" { - type = bool - description = "Install/re-install the bootloader" - default = false -} diff --git a/launch/.terraform/modules/pixelfed.deploy/terraform/update-docs.sh b/launch/.terraform/modules/pixelfed.deploy/terraform/update-docs.sh deleted file mode 100755 index b67d98ad..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/terraform/update-docs.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd "$SCRIPT_DIR" -files=() -find "${SCRIPT_DIR}"/* -type d | while read -r i; do - module_name=$(basename "$i") - markdown_file="${SCRIPT_DIR}/${module_name}.md" - terraform-docs --config "${SCRIPT_DIR}/.terraform-docs.yml" markdown table --output-file "${markdown_file}" --output-mode inject "${module_name}" - files+=("${markdown_file}") -done -cd .. -nix fmt -- --no-cache diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/flake-module.nix b/launch/.terraform/modules/pixelfed.deploy/tests/flake-module.nix deleted file mode 100644 index 784175f4..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/tests/flake-module.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ withSystem, inputs, ... }: - -{ - flake.checks.x86_64-linux = withSystem "x86_64-linux" ( - { - pkgs, - system, - inputs', - config, - ... - }: - let - testInputsUnstable = { - inherit pkgs; - inherit (inputs.disko.nixosModules) disko; - nixos-anywhere = config.packages.nixos-anywhere; - kexec-installer = "${inputs'.nixos-images.packages.kexec-installer-nixos-unstable-noninteractive}/nixos-kexec-installer-noninteractive-${system}.tar.gz"; - }; - testInputsStable = testInputsUnstable // { - kexec-installer = "${inputs'.nixos-images.packages.kexec-installer-nixos-stable-noninteractive}/nixos-kexec-installer-noninteractive-${system}.tar.gz"; - }; - in - { - from-nixos = import ./from-nixos.nix testInputsUnstable; - from-nixos-stable = import ./from-nixos.nix testInputsStable; - from-nixos-with-sudo = import ./from-nixos-with-sudo.nix testInputsUnstable; - from-nixos-with-sudo-stable = import ./from-nixos-with-sudo.nix testInputsStable; - from-nixos-with-generated-config = import ./from-nixos-generate-config.nix testInputsUnstable; - from-nixos-build-on-remote = import ./from-nixos-build-on-remote.nix testInputsUnstable; - from-nixos-separated-phases = import ./from-nixos-separated-phases.nix testInputsUnstable; - } - ); -} diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-build-on-remote.nix b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-build-on-remote.nix deleted file mode 100644 index 52617133..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-build-on-remote.nix +++ /dev/null @@ -1,56 +0,0 @@ -(import ./lib/test-base.nix) ( - { pkgs, ... }: - { - name = "from-nixos-build-on-remote"; - nodes = { - installer = ./modules/installer.nix; - installed = { - services.openssh.enable = true; - virtualisation.memorySize = 1024; - - users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; - }; - }; - testScript = '' - def create_test_machine( - oldmachine=None, **kwargs - ): # taken from - start_command = [ - "${pkgs.qemu_test}/bin/qemu-kvm", - "-cpu", - "max", - "-m", - "1024", - "-virtfs", - "local,path=/nix/store,security_model=none,mount_tag=nix-store", - "-drive", - f"file={oldmachine.state_dir}/installed.qcow2,id=drive1,if=none,index=1,werror=report", - "-device", - "virtio-blk-pci,drive=drive1", - ] - machine = create_machine(start_command=" ".join(start_command), **kwargs) - driver.machines.append(machine) - return machine - start_all() - - installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --build-on-remote \ - --kexec /etc/nixos-anywhere/kexec-installer \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - root@installed >&2 - """) - try: - installed.shutdown() - except BrokenPipeError: - # qemu has already exited - pass - new_machine = create_test_machine(oldmachine=installed, name="after_install") - new_machine.start() - hostname = new_machine.succeed("hostname").strip() - assert "nixos-anywhere" == hostname, f"'nixos-anywhere' != '{hostname}'" - ''; - } -) diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-generate-config.nix b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-generate-config.nix deleted file mode 100644 index 5b4d65dd..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-generate-config.nix +++ /dev/null @@ -1,71 +0,0 @@ -(import ./lib/test-base.nix) { - name = "from-nixos-generate-config"; - nodes = { - installer = - { pkgs, ... }: - { - imports = [ - ./modules/installer.nix - ]; - environment.systemPackages = [ pkgs.jq ]; - }; - installed = { - services.openssh.enable = true; - virtualisation.memorySize = 1024; - - users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; - }; - }; - testScript = '' - start_all() - installer.fail("test -f /tmp/hw/config.nix") - installer.succeed("echo super-secret > /tmp/disk-1.key") - output = installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --kexec /etc/nixos-anywhere/kexec-installer \ - --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ - --disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \ - --phases kexec,disko \ - --generate-hardware-config nixos-generate-config /tmp/hw/config.nix \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - root@installed >&2 - echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat /tmp/disk-1.key)'" - echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat /tmp/disk-2.key)'" - """) - - installer.succeed("cat /tmp/hw/config.nix >&2") - installer.succeed("nix-instantiate --parse /tmp/hw/config.nix") - - assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}" - assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}" - - installer.fail("test -f /test/hw/config.json") - - output = installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --kexec /etc/nixos-anywhere/kexec-installer \ - --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ - --disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \ - --phases kexec,disko \ - --generate-hardware-config nixos-facter /tmp/hw/config.json \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - installed >&2 - echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat /tmp/disk-1.key)'" - echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat /tmp/disk-2.key)'" - """) - - installer.succeed("cat /tmp/hw/config.json >&2") - installer.succeed("jq < /tmp/hw/config.json") - - assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}" - assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}" - ''; -} diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-separated-phases.nix b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-separated-phases.nix deleted file mode 100644 index 2b267b69..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-separated-phases.nix +++ /dev/null @@ -1,52 +0,0 @@ -(import ./lib/test-base.nix) { - name = "from-nixos-separated-phases"; - nodes = { - installer = ./modules/installer.nix; - installed = { - services.openssh.enable = true; - virtualisation.memorySize = 1024; - - users.users.nixos = { - isNormalUser = true; - openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; - extraGroups = [ "wheel" ]; - }; - security.sudo.enable = true; - security.sudo.wheelNeedsPassword = false; - }; - }; - testScript = '' - start_all() - - with subtest("Kexec Phase"): - installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --kexec /etc/nixos-anywhere/kexec-installer \ - --phases kexec \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - nixos@installed >&2 - """) - - with subtest("Disko Phase"): - output = installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --phases disko \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - installed >&2 - """) - - with subtest("Install Phase"): - installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --phases install \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - root@installed >&2 - """) - ''; -} diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-with-sudo.nix b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-with-sudo.nix deleted file mode 100644 index 839dec38..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos-with-sudo.nix +++ /dev/null @@ -1,40 +0,0 @@ -(import ./lib/test-base.nix) { - name = "from-nixos-with-sudo"; - nodes = { - installer = ./modules/installer.nix; - installed = { - services.openssh.enable = true; - virtualisation.memorySize = 1024; - - users.users.nixos = { - isNormalUser = true; - openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; - extraGroups = [ "wheel" ]; - }; - security.sudo.enable = true; - security.sudo.wheelNeedsPassword = false; - }; - }; - testScript = '' - start_all() - installer.succeed("echo super-secret > /tmp/disk-1.key") - output = installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --kexec /etc/nixos-anywhere/kexec-installer \ - --phases kexec,disko \ - --disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \ - --disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - nixos@installed >&2 - echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat /tmp/disk-1.key)'" - echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat /tmp/disk-2.key)'" - """) - - assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}" - assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}" - ''; -} diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos.nix b/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos.nix deleted file mode 100644 index 0f3d1344..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/tests/from-nixos.nix +++ /dev/null @@ -1,76 +0,0 @@ -(import ./lib/test-base.nix) ( - { pkgs, ... }: - { - name = "from-nixos"; - nodes = { - installer = ./modules/installer.nix; - installed = { - services.openssh.enable = true; - virtualisation.memorySize = 1024; - - users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ]; - }; - }; - testScript = '' - def create_test_machine( - oldmachine=None, **kwargs - ): # taken from - start_command = [ - "${pkgs.qemu_test}/bin/qemu-kvm", - "-cpu", - "max", - "-m", - "1024", - "-virtfs", - "local,path=/nix/store,security_model=none,mount_tag=nix-store", - "-drive", - f"file={oldmachine.state_dir}/installed.qcow2,id=drive1,if=none,index=1,werror=report", - "-device", - "virtio-blk-pci,drive=drive1", - ] - machine = create_machine(start_command=" ".join(start_command), **kwargs) - driver.machines.append(machine) - return machine - start_all() - installer.succeed("mkdir -p /tmp/extra-files/var/lib/secrets") - installer.succeed("echo value > /tmp/extra-files/var/lib/secrets/key") - installer.succeed("mkdir -p /tmp/extra-files/home/user/.ssh") - installer.succeed("echo secretkey > /tmp/extra-files/home/user/.ssh/id_ed25519") - installer.succeed("echo publickey > /tmp/extra-files/home/user/.ssh/id_ed25519.pub") - installer.succeed("chmod 600 /tmp/extra-files/home/user/.ssh/id_ed25519") - ssh_key_path = "/etc/ssh/ssh_host_ed25519_key.pub" - ssh_key_output = installer.wait_until_succeeds(f""" - ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ - root@installed cat {ssh_key_path} - """) - installer.succeed(""" - nixos-anywhere \ - -i /root/.ssh/install_key \ - --debug \ - --kexec /etc/nixos-anywhere/kexec-installer \ - --extra-files /tmp/extra-files \ - --store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \ - --chown /home/user 1000:100 \ - --copy-host-keys \ - root@installed >&2 - """) - try: - installed.shutdown() - except BrokenPipeError: - # qemu has already exited - pass - new_machine = create_test_machine(oldmachine=installed, name="after_install") - new_machine.start() - hostname = new_machine.succeed("hostname").strip() - assert "nixos-anywhere" == hostname, f"'nixos-anywhere' != '{hostname}'" - content = new_machine.succeed("cat /var/lib/secrets/key").strip() - assert "value" == content, f"secret does not have expected value: {content}" - ssh_key_content = new_machine.succeed(f"cat {ssh_key_path}").strip() - assert ssh_key_content in ssh_key_output, "SSH host identity changed" - priv_key_perms = new_machine.succeed("stat -c %a /home/user/.ssh/id_ed25519").strip() - assert priv_key_perms == "600", f"unexpected permissions for private key: {priv_key_perms}" - user_dir_ownership = new_machine.succeed("stat -c %u:%g /home/user").strip() - assert user_dir_ownership == "1000:100", f"unexpected user home dir permissions: {user_dir_ownership}" - ''; - } -) diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/lib/test-base.nix b/launch/.terraform/modules/pixelfed.deploy/tests/lib/test-base.nix deleted file mode 100644 index 169d1fd2..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/tests/lib/test-base.nix +++ /dev/null @@ -1,20 +0,0 @@ -test: -{ - pkgs ? import { }, - nixos-anywhere ? pkgs.callPackage ../../src { }, - disko ? "${builtins.fetchTarball "https://github.com/nix-community/disko/archive/master.tar.gz"}/module.nix", - kexec-installer ? builtins.fetchurl "https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-${pkgs.stdenv.hostPlatform.system}.tar.gz", - ... -}: -let - inherit (pkgs) lib; - nixos-lib = import (pkgs.path + "/nixos/lib") { }; -in -(nixos-lib.runTest { - hostPkgs = pkgs; - # speed-up evaluation - defaults.documentation.enable = lib.mkDefault false; - # to accept external dependencies such as disko - node.specialArgs.inputs = { inherit nixos-anywhere disko kexec-installer; }; - imports = [ test ]; -}).config.result diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/modules/installer.nix b/launch/.terraform/modules/pixelfed.deploy/tests/modules/installer.nix deleted file mode 100644 index e5c22d4d..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/tests/modules/installer.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ pkgs, inputs, ... }: -let - disko = inputs.disko; - kexec-installer = inputs.kexec-installer; - system-to-install = pkgs.nixos [ - ./system-to-install.nix - disko - ]; -in -{ - system.activationScripts.rsa-key = '' - ${pkgs.coreutils}/bin/install -D -m600 ${./ssh-keys/ssh} /root/.ssh/install_key - ''; - - environment.systemPackages = [ inputs.nixos-anywhere ]; - - environment.etc = { - "nixos-anywhere/disko".source = system-to-install.config.system.build.diskoScriptNoDeps; - "nixos-anywhere/system-to-install".source = system-to-install.config.system.build.toplevel; - "nixos-anywhere/kexec-installer".source = kexec-installer; - }; -} diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh b/launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh deleted file mode 100644 index db6049c5..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN OPENSSH PRIVATE KEY----- -b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW -QyNTUxOQAAACDM4kPg4V7DMYceuA8VIUdBvw30gM9qagERA8v1VGBBBQAAAJDpULAq6VCw -KgAAAAtzc2gtZWQyNTUxOQAAACDM4kPg4V7DMYceuA8VIUdBvw30gM9qagERA8v1VGBBBQ -AAAECpjfl5WMMIDvEyZJTeXzRNFzpDpj4fqdIXHZauKAlE5MziQ+DhXsMxhx64DxUhR0G/ -DfSAz2pqAREDy/VUYEEFAAAACWxhc3NAbW9ycwECAwQ= ------END OPENSSH PRIVATE KEY----- diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh.pub b/launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh.pub deleted file mode 100644 index e77d393e..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/tests/modules/ssh-keys/ssh.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMziQ+DhXsMxhx64DxUhR0G/DfSAz2pqAREDy/VUYEEF diff --git a/launch/.terraform/modules/pixelfed.deploy/tests/modules/system-to-install.nix b/launch/.terraform/modules/pixelfed.deploy/tests/modules/system-to-install.nix deleted file mode 100644 index 1181c944..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/tests/modules/system-to-install.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ modulesPath, self, ... }: -{ - imports = [ - (modulesPath + "/testing/test-instrumentation.nix") - (modulesPath + "/profiles/qemu-guest.nix") - (modulesPath + "/profiles/minimal.nix") - ]; - networking.hostName = "nixos-anywhere"; - documentation.enable = false; - hardware.enableAllFirmware = false; - networking.hostId = "8425e349"; # from profiles/base.nix, needed for zfs - boot.zfs.devNodes = "/dev/disk/by-uuid"; # needed because /dev/disk/by-id is empty in qemu-vms - disko.devices = { - disk = { - vda = { - device = "/dev/vda"; - type = "disk"; - content = { - type = "gpt"; - partitions = { - boot = { - size = "1M"; - type = "EF02"; - }; - ESP = { - size = "100M"; - type = "EF00"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - }; - }; - root = { - size = "100%"; - content = { - type = "filesystem"; - format = "ext4"; - mountpoint = "/"; - }; - }; - }; - }; - }; - }; - }; -} diff --git a/launch/.terraform/modules/pixelfed.deploy/treefmt/flake-module.nix b/launch/.terraform/modules/pixelfed.deploy/treefmt/flake-module.nix deleted file mode 100644 index 3e92a8ed..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/treefmt/flake-module.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ inputs, ... }: -{ - imports = [ - inputs.treefmt-nix.flakeModule - ]; - perSystem = - { config, pkgs, ... }: - { - treefmt = { - projectRootFile = "flake.nix"; - programs.mdsh.enable = true; - programs.nixpkgs-fmt.enable = true; - programs.shellcheck.enable = true; - programs.shfmt.enable = true; - programs.deno.enable = !pkgs.deno.meta.broken; - settings.formatter.shellcheck.options = [ - "-s" - "bash" - ]; - }; - formatter = config.treefmt.build.wrapper; - }; -} diff --git a/launch/garage.nix b/launch/garage.nix new file mode 100644 index 00000000..b79614f4 --- /dev/null +++ b/launch/garage.nix @@ -0,0 +1,37 @@ +let + ## NOTE: All of these secrets are publicly available in this source file + ## and will end up in the Nix store. We don't care as they are only ever + ## used for testing anyway. + ## + ## FIXME: Generate and store in NixOps4's state. + mastodonS3KeyConfig = + { pkgs, ... }: + { + s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GK3515373e4c851ebaad366558"; + s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7d37d093435a41f2aab8f13c19ba067d9776c90215f56614adad6ece597dbb34"; + }; + peertubeS3KeyConfig = + { pkgs, ... }: + { + s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GK1f9feea9960f6f95ff404c9b"; + s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7295c4201966a02c2c3d25b5cea4a5ff782966a2415e3a196f91924631191395"; + }; + pixelfedS3KeyConfig = + { pkgs, ... }: + { + s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GKb5615457d44214411e673b7b"; + s3SecretKeyFile = pkgs.writeText "s3SecretKey" "5be6799a88ca9b9d813d1a806b64f15efa49482dbe15339ddfaf7f19cf434987"; + }; +in +import ./shared.nix { + module = + { pkgs, ... }: + { + fediversity = { + garage.enable = true; + pixelfed = pixelfedS3KeyConfig { inherit pkgs; }; + mastodon = mastodonS3KeyConfig { inherit pkgs; }; + peertube = peertubeS3KeyConfig { inherit pkgs; }; + }; + }; +} diff --git a/launch/mastodon.nix b/launch/mastodon.nix new file mode 100644 index 00000000..def88630 --- /dev/null +++ b/launch/mastodon.nix @@ -0,0 +1,20 @@ +let + mastodonS3KeyConfig = + { pkgs, ... }: + { + s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GK3515373e4c851ebaad366558"; + s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7d37d093435a41f2aab8f13c19ba067d9776c90215f56614adad6ece597dbb34"; + }; +in +import ./shared.nix { + module = + { pkgs, ... }: + { + fediversity = { + mastodon = mastodonS3KeyConfig { inherit pkgs; } // { + enable = true; + }; + temp.cores = 1; # FIXME: should come from NixOps4 eventually + }; + }; +} diff --git a/launch/peertube.nix b/launch/peertube.nix new file mode 100644 index 00000000..df58c0a7 --- /dev/null +++ b/launch/peertube.nix @@ -0,0 +1,23 @@ +let + peertubeS3KeyConfig = + { pkgs, ... }: + { + s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GK1f9feea9960f6f95ff404c9b"; + s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7295c4201966a02c2c3d25b5cea4a5ff782966a2415e3a196f91924631191395"; + }; +in +import ./shared.nix { + module = + { pkgs, ... }: + { + fediversity = { + peertube = peertubeS3KeyConfig { inherit pkgs; } // { + enable = true; + ## NOTE: Only ever used for testing anyway. + ## + ## FIXME: Generate and store in NixOps4's state. + secretsFile = pkgs.writeText "secret" "574e093907d1157ac0f8e760a6deb1035402003af5763135bae9cbd6abe32b24"; + }; + }; + }; +} diff --git a/launch/pixelfed.nix b/launch/pixelfed.nix new file mode 100644 index 00000000..6fdaf65a --- /dev/null +++ b/launch/pixelfed.nix @@ -0,0 +1,19 @@ +let + pixelfedS3KeyConfig = + { pkgs, ... }: + { + s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GKb5615457d44214411e673b7b"; + s3SecretKeyFile = pkgs.writeText "s3SecretKey" "5be6799a88ca9b9d813d1a806b64f15efa49482dbe15339ddfaf7f19cf434987"; + }; +in +import ./shared.nix { + module = + { pkgs, ... }: + { + fediversity = { + pixelfed = pixelfedS3KeyConfig { inherit pkgs; } // { + enable = true; + }; + }; + }; +} diff --git a/launch/shared.nix b/launch/shared.nix new file mode 100644 index 00000000..f3d18344 --- /dev/null +++ b/launch/shared.nix @@ -0,0 +1,45 @@ +{ + system ? "x86_64-linux", + sources ? import ../npins, + pkgs ? import sources.nixpkgs { + inherit system; + config = { }; + overlays = [ (import ../panel/nix/overlay.nix) ]; + }, + module, + ... +}: +import "${sources.nixpkgs}/nixos/lib/eval-config.nix" { + modules = [ + "${sources.disko}/module.nix" + "${sources.agenix}/modules/age.nix" + ../services/fediversity + ./resource.nix + # FIXME: get VM details from TF + module + ( + { + terraform, + ... + }: + let + inherit (terraform) hostname; + in + { + imports = [ + ../infra/test-machines/${hostname} + ]; + fediversityVm.name = hostname; + fediversity = { + inherit (terraform) domain; + temp.initialUser = { + inherit (terraform.initialUser) username email displayName; + # FIXME: disgusting, but nvm, this is going to be replaced by + # proper central authentication at some point + passwordFile = pkgs.writeText "password" terraform.initialUser.password; + }; + }; + } + ) + ]; +} diff --git a/launch/vm/main.tf b/launch/vm/main.tf index 76c18af5..5bc084b6 100644 --- a/launch/vm/main.tf +++ b/launch/vm/main.tf @@ -26,8 +26,9 @@ variable "initialUser" { module "deploy" { # source = "github.com/nix-community/nixos-anywhere//terraform/all-in-one" source = "${var.nixos-anywhere}//terraform/all-in-one" - nixos_system_attr = ".#nixosConfigurations.${var.config}.config.system.build.toplevel" - nixos_partitioner_attr = ".#nixosConfigurations.${var.config}.config.system.build.diskoScriptNoDeps" + file = "${path.module}/../${var.config}.nix" + nixos_system_attr = "config.system.build.toplevel" + nixos_partitioner_attr = "config.system.build.diskoScript" # when instance id changes, it will trigger a reinstall instance_id = var.hostname target_user = "kiara" diff --git a/npins/sources.json b/npins/sources.json index c1177097..dc876731 100644 --- a/npins/sources.json +++ b/npins/sources.json @@ -1,5 +1,32 @@ { "pins": { + "agenix": { + "type": "Git", + "repository": { + "type": "GitHub", + "owner": "ryantm", + "repo": "agenix" + }, + "branch": "main", + "revision": "e600439ec4c273cf11e06fe4d9d906fb98fa097c", + "url": "https://github.com/ryantm/agenix/archive/e600439ec4c273cf11e06fe4d9d906fb98fa097c.tar.gz", + "hash": "006ngydiykjgqs85cl19h9klq8kaqm5zs0ng51dnwy7nzgqxzsdr" + }, + "disko": { + "type": "GitRelease", + "repository": { + "type": "GitHub", + "owner": "nix-community", + "repo": "disko" + }, + "pre_releases": false, + "version_upper_bound": null, + "release_prefix": null, + "version": "v1.11.0", + "revision": "cdf8deded8813edfa6e65544f69fdd3a59fa2bb4", + "url": "https://api.github.com/repos/nix-community/disko/tarball/v1.11.0", + "hash": "13brimg7z7k9y36n4jc1pssqyw94nd8qvgfjv53z66lv4xkhin92" + }, "flake-inputs": { "type": "Git", "repository": { @@ -47,9 +74,9 @@ "repo": "nixos-anywhere" }, "branch": "special-args-nested-flake-fixed", - "revision": "bbf54831f177b4ae52b55758ac725583617c39f9", - "url": "https://github.com/KiaraGrouwstra/nixos-anywhere/archive/bbf54831f177b4ae52b55758ac725583617c39f9.tar.gz", - "hash": "11m8r632yp4s8sy106zk7a1inp44gvwq6hinjf2pczpr6a5hxanx" + "revision": "6986a78788d9b32354ab11b3881edf0caf1ae727", + "url": "https://github.com/KiaraGrouwstra/nixos-anywhere/archive/6986a78788d9b32354ab11b3881edf0caf1ae727.tar.gz", + "hash": "13j1l8dj9w22ch5z3iyzx5z6hrrx6c75m5gnkpa4d4wgiznx90r9" }, "nixpkgs": { "type": "Channel", @@ -59,4 +86,4 @@ } }, "version": 3 -} \ No newline at end of file +} -- 2.48.1 From b4a65169c686d7b993d1315c1d46343f9756125b Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Fri, 28 Mar 2025 21:22:42 +0100 Subject: [PATCH 17/57] rm launch flake, as i seem to have reached similar progress without it --- launch/flake.lock | 158 ---------------------------------------------- launch/flake.nix | 125 ------------------------------------ 2 files changed, 283 deletions(-) delete mode 100644 launch/flake.lock delete mode 100644 launch/flake.nix diff --git a/launch/flake.lock b/launch/flake.lock deleted file mode 100644 index e1b4f6df..00000000 --- a/launch/flake.lock +++ /dev/null @@ -1,158 +0,0 @@ -{ - "nodes": { - "agenix": { - "inputs": { - "darwin": "darwin", - "home-manager": "home-manager", - "nixpkgs": "nixpkgs", - "systems": "systems" - }, - "locked": { - "lastModified": 1736955230, - "narHash": "sha256-uenf8fv2eG5bKM8C/UvFaiJMZ4IpUFaQxk9OH5t/1gA=", - "owner": "ryantm", - "repo": "agenix", - "rev": "e600439ec4c273cf11e06fe4d9d906fb98fa097c", - "type": "github" - }, - "original": { - "owner": "ryantm", - "repo": "agenix", - "type": "github" - } - }, - "darwin": { - "inputs": { - "nixpkgs": [ - "agenix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1700795494, - "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=", - "owner": "lnl7", - "repo": "nix-darwin", - "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d", - "type": "github" - }, - "original": { - "owner": "lnl7", - "ref": "master", - "repo": "nix-darwin", - "type": "github" - } - }, - "disko": { - "inputs": { - "nixpkgs": "nixpkgs_2" - }, - "locked": { - "lastModified": 1741786315, - "narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=", - "owner": "nix-community", - "repo": "disko", - "rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "disko", - "type": "github" - } - }, - "home-manager": { - "inputs": { - "nixpkgs": [ - "agenix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1703113217, - "narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=", - "owner": "nix-community", - "repo": "home-manager", - "rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "home-manager", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1703013332, - "narHash": "sha256-+tFNwMvlXLbJZXiMHqYq77z/RfmpfpiI3yjL6o/Zo9M=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "54aac082a4d9bb5bbc5c4e899603abfb76a3f6d6", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1741402956, - "narHash": "sha256-y2hByvBM03s9T2fpeLjW6iprbxnhV9mJMmSwCHc41ZQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "ed0b1881565c1ffef490c10d663d4f542031dad3", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1743046730, - "narHash": "sha256-3ON6kKBQ4pz/IVZylcbw28K/Jm5cym4V/Z+VmPzR9/4=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "67545051fd77a131ebab477fbf2bb4d9473edd35", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "release-24.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "agenix": "agenix", - "disko": "disko", - "nixpkgs": "nixpkgs_3" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/launch/flake.nix b/launch/flake.nix deleted file mode 100644 index 9d126b9e..00000000 --- a/launch/flake.nix +++ /dev/null @@ -1,125 +0,0 @@ -{ - inputs = { - agenix.url = "github:ryantm/agenix"; - disko.url = "github:nix-community/disko"; - nixpkgs.url = "github:nixos/nixpkgs/release-24.11"; - }; - outputs = - inputs@{ nixpkgs, ... }: - let - system = "x86_64-linux"; - inherit (nixpkgs) lib; - in - { - nixosConfigurations = - let - ## NOTE: All of these secrets are publicly available in this source file - ## and will end up in the Nix store. We don't care as they are only ever - ## used for testing anyway. - ## - ## FIXME: Generate and store in NixOps4's state. - mastodonS3KeyConfig = - { pkgs, ... }: - { - s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GK3515373e4c851ebaad366558"; - s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7d37d093435a41f2aab8f13c19ba067d9776c90215f56614adad6ece597dbb34"; - }; - peertubeS3KeyConfig = - { pkgs, ... }: - { - s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GK1f9feea9960f6f95ff404c9b"; - s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7295c4201966a02c2c3d25b5cea4a5ff782966a2415e3a196f91924631191395"; - }; - pixelfedS3KeyConfig = - { pkgs, ... }: - { - s3AccessKeyFile = pkgs.writeText "s3AccessKey" "GKb5615457d44214411e673b7b"; - s3SecretKeyFile = pkgs.writeText "s3SecretKey" "5be6799a88ca9b9d813d1a806b64f15efa49482dbe15339ddfaf7f19cf434987"; - }; - in - lib.mapAttrs - ( - _: module: - lib.nixosSystem { - inherit system; - specialArgs = { inherit system inputs; }; - modules = [ - inputs.disko.nixosModules.default - inputs.agenix.nixosModules.default - ../services/fediversity - ./resource.nix - module - { - nixpkgs = { inherit system; }; - } - ( - { pkgs, terraform, ... }: - let - inherit (terraform) hostname; - in - { - imports = [ - # FIXME: get VM details from TF - ../infra/test-machines/${hostname} - ]; - fediversityVm.name = hostname; - fediversity = { - inherit (terraform) domain; - temp.initialUser = { - inherit (terraform.initialUser) username email displayName; - # FIXME: disgusting, but nvm, this is going to be replaced by - # proper central authentication at some point - passwordFile = pkgs.writeText "password" terraform.initialUser.password; - }; - }; - } - ) - ]; - } - ) - { - garage = - { pkgs, ... }: - { - fediversity = { - garage.enable = true; - pixelfed = pixelfedS3KeyConfig { inherit pkgs; }; - mastodon = mastodonS3KeyConfig { inherit pkgs; }; - peertube = peertubeS3KeyConfig { inherit pkgs; }; - }; - }; - mastodon = - { pkgs, ... }: - { - fediversity = { - mastodon = mastodonS3KeyConfig { inherit pkgs; } // { - enable = true; - }; - temp.cores = 1; # FIXME: should come from NixOps4 eventually - }; - }; - peertube = - { pkgs, ... }: - { - fediversity = { - peertube = peertubeS3KeyConfig { inherit pkgs; } // { - enable = true; - ## NOTE: Only ever used for testing anyway. - ## - ## FIXME: Generate and store in NixOps4's state. - secretsFile = pkgs.writeText "secret" "574e093907d1157ac0f8e760a6deb1035402003af5763135bae9cbd6abe32b24"; - }; - }; - }; - pixelfed = - { pkgs, ... }: - { - fediversity = { - pixelfed = pixelfedS3KeyConfig { inherit pkgs; } // { - enable = true; - }; - }; - }; - }; - }; -} -- 2.48.1 From fc4fc609826a95a749901d2118048316d2a814e0 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 30 Mar 2025 10:41:16 +0200 Subject: [PATCH 18/57] update nixos-anywhere to fix error 'installable ... does not correspond to a Nix language value' --- ... not correspond to a Nix language value' for non-flakes) | 2 +- npins/sources.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/launch/.terraform/modules/peertube.deploy~f00c14b (get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes) b/launch/.terraform/modules/peertube.deploy~f00c14b (get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes) index ba6efefb..17167407 120000 --- a/launch/.terraform/modules/peertube.deploy~f00c14b (get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes) +++ b/launch/.terraform/modules/peertube.deploy~f00c14b (get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes) @@ -1 +1 @@ -/nix/store/q68mw6lmjjhrvcrhb0pcm9i0v6m3v7cn-source \ No newline at end of file +/nix/store/ca7wwzypz3lhvmrb2a1i72pf7d2vh6mw-source \ No newline at end of file diff --git a/npins/sources.json b/npins/sources.json index dc876731..0251295b 100644 --- a/npins/sources.json +++ b/npins/sources.json @@ -74,9 +74,9 @@ "repo": "nixos-anywhere" }, "branch": "special-args-nested-flake-fixed", - "revision": "6986a78788d9b32354ab11b3881edf0caf1ae727", - "url": "https://github.com/KiaraGrouwstra/nixos-anywhere/archive/6986a78788d9b32354ab11b3881edf0caf1ae727.tar.gz", - "hash": "13j1l8dj9w22ch5z3iyzx5z6hrrx6c75m5gnkpa4d4wgiznx90r9" + "revision": "5aa35145f045eb23fa8773821d5626bcf54dbe0e", + "url": "https://github.com/KiaraGrouwstra/nixos-anywhere/archive/5aa35145f045eb23fa8773821d5626bcf54dbe0e.tar.gz", + "hash": "0m67iyd04wl183il1cfi623xpxcvbbpc5x1gh74478qc3fgr0g54" }, "nixpkgs": { "type": "Channel", -- 2.48.1 From de27ec1fb28bbc7cdcd86ca50a4d525561cccea8 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 30 Mar 2025 10:42:35 +0200 Subject: [PATCH 19/57] rm comment --- panel/src/panel/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 373fb2bf..5d4d06f1 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -147,7 +147,6 @@ class DeploymentStatus(ConfigurationForm): f"TF_VAR_{k}": v if isinstance(v, str) else json.dumps(v) for k, v in deployment_params.items() } cwd = f"{settings.repo_dir}/launch" - # FIXME: move init to packaging phase cmd = [ "tofu", # f"-chdir={cwd}", -- 2.48.1 From 0350f684276a761ec6bbaf0729268b16001a3f01 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 30 Mar 2025 12:45:24 +0200 Subject: [PATCH 20/57] untrack TF generated provider/module stuff - local dev now requires following launch/README.md --- launch/.gitignore | 2 +- .../hashicorp/external/2.3.4/linux_amd64 | 1 - .../registry.opentofu.org/hashicorp/null/3.2.3/linux_amd64 | 1 - launch/tf-env.nix | 4 ++-- 4 files changed, 3 insertions(+), 5 deletions(-) delete mode 120000 launch/.terraform/providers/registry.opentofu.org/hashicorp/external/2.3.4/linux_amd64 delete mode 120000 launch/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.3/linux_amd64 diff --git a/launch/.gitignore b/launch/.gitignore index c0b634d3..0f8ba9b3 100644 --- a/launch/.gitignore +++ b/launch/.gitignore @@ -1,3 +1,3 @@ -# .terraform/ +.terraform/ .terraform.tfstate.lock.info terraform.tfstate* diff --git a/launch/.terraform/providers/registry.opentofu.org/hashicorp/external/2.3.4/linux_amd64 b/launch/.terraform/providers/registry.opentofu.org/hashicorp/external/2.3.4/linux_amd64 deleted file mode 120000 index e74641a1..00000000 --- a/launch/.terraform/providers/registry.opentofu.org/hashicorp/external/2.3.4/linux_amd64 +++ /dev/null @@ -1 +0,0 @@ -/nix/store/mnqkwjg5v6sx86an34b4cn075h0lapz3-opentofu-1.8.7/libexec/terraform-providers/registry.opentofu.org/hashicorp/external/2.3.4/linux_amd64 \ No newline at end of file diff --git a/launch/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.3/linux_amd64 b/launch/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.3/linux_amd64 deleted file mode 120000 index 18952a18..00000000 --- a/launch/.terraform/providers/registry.opentofu.org/hashicorp/null/3.2.3/linux_amd64 +++ /dev/null @@ -1 +0,0 @@ -/nix/store/mnqkwjg5v6sx86an34b4cn075h0lapz3-opentofu-1.8.7/libexec/terraform-providers/registry.opentofu.org/hashicorp/null/3.2.3/linux_amd64 \ No newline at end of file diff --git a/launch/tf-env.nix b/launch/tf-env.nix index eb1e3161..817c6e23 100644 --- a/launch/tf-env.nix +++ b/launch/tf-env.nix @@ -17,10 +17,10 @@ pkgs.stdenv.mkDerivation { # pass nixos-anywhere path to TF through variable # when switching TF to nix take this directly from `inputs` # https://codeberg.org/kiara/e2ed-hetzner/commit/84b2a349d3e48ea2a17340bceff762d834fd4046 - # echo "{\"nixos-anywhere\": \"${sources.nixos-anywhere}\"}" > .auto.tfvars.json + echo "{\"nixos-anywhere\": \"${sources.nixos-anywhere}\"}" > .auto.tfvars.json # point to the relevant providers - # tofu init -input=false + tofu init -input=false popd runHook postBuild -- 2.48.1 From 76e05949562e7c81605b572337e7651dec193507 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 30 Mar 2025 12:48:53 +0200 Subject: [PATCH 21/57] for now gitignore .auto.tfvars.json used to track TF module of nixos-anywhere in case we want that file for something else, we can move this (and its ignore) to something separate. --- launch/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/launch/.gitignore b/launch/.gitignore index 0f8ba9b3..6ff139e0 100644 --- a/launch/.gitignore +++ b/launch/.gitignore @@ -1,3 +1,4 @@ +.auto.tfvars.json .terraform/ .terraform.tfstate.lock.info terraform.tfstate* -- 2.48.1 From e02e399a02ba1ff30b60ec9ed0fe1a534ca70d0d Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 30 Mar 2025 13:12:32 +0200 Subject: [PATCH 22/57] use a mutable HOME in TF for nixos-anywhere to make a `.ssh` dir in - will this not backfire? --- panel/src/panel/views.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 5d4d06f1..def63da9 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -138,8 +138,10 @@ class DeploymentStatus(ConfigurationForm): deployment_params = dummy_user | json.loads(submission) env = { "PATH": settings.bin_path, - # used in nixos-anywhere for ssh-copy-id - "HOME": expanduser("~"), + # used in nixos-anywhere for ssh-copy-id to make `.ssh` in for ssh-copy-id. + # run thru subprocess, HOME points to the read-only `/var/empty`. + # in local dev, it will just reject the `/tmp` and make it in HOME after all. + "HOME": "/tmp", "XDG_CACHE_HOME": "/tmp", } | { # pass in form info to our deployment -- 2.48.1 From c93f16bcb23b1c0b8d4e3d2d38f6298afa98ea6a Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Tue, 1 Apr 2025 11:56:54 +0200 Subject: [PATCH 23/57] change ssh user to root --- launch/vm/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launch/vm/main.tf b/launch/vm/main.tf index 5bc084b6..e4eb9b88 100644 --- a/launch/vm/main.tf +++ b/launch/vm/main.tf @@ -31,7 +31,7 @@ module "deploy" { nixos_partitioner_attr = "config.system.build.diskoScript" # when instance id changes, it will trigger a reinstall instance_id = var.hostname - target_user = "kiara" + target_user = "root" target_host = "${var.hostname}.abundos.eu" extra_files_script = "${path.module}/../pass-ssh-key.sh" extra_environment = { -- 2.48.1 From 182106cd898fdde1437f0f84ca95b7a54a0e2129 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Thu, 3 Apr 2025 13:49:12 +0200 Subject: [PATCH 24/57] update nixpkgs to unstable - resolves manual deploy error on bootloader already on newer version --- npins/sources.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npins/sources.json b/npins/sources.json index 0251295b..7e1df4f9 100644 --- a/npins/sources.json +++ b/npins/sources.json @@ -81,8 +81,8 @@ "nixpkgs": { "type": "Channel", "name": "nixpkgs-unstable", - "url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.05pre711046.8edf06bea5bc/nixexprs.tar.xz", - "hash": "1mwsn0rvfm603svrq3pca4c51zlix5gkyr4gl6pxhhq3q6xs5s8y" + "url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.05pre777917.b7ba7f9f45c5/nixexprs.tar.xz", + "hash": "0jb6b7sv66bn06pchj2l88z0i5dlz0c2vb3z6pjjlq2p8q11zigg" } }, "version": 3 -- 2.48.1 From 3270cc89e74b2aed63c0d3998198a140fa1420a1 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 5 Apr 2025 16:03:01 +0200 Subject: [PATCH 25/57] update mastodon host --- launch/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launch/main.tf b/launch/main.tf index 3fd5a5b5..3e8a3355 100644 --- a/launch/main.tf +++ b/launch/main.tf @@ -65,7 +65,7 @@ module "mastodon" { source = "./vm" count = var.mastodon.enable ? 1 : 0 domain = var.domain - hostname = "test02" + hostname = "test06" config = "mastodon" initialUser = var.initialUser nixos-anywhere = var.nixos-anywhere -- 2.48.1 From 551e860b5bc3d4c86187098cfcf13adabf5220e3 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 5 Apr 2025 16:04:23 +0200 Subject: [PATCH 26/57] use root user as in #301 - given #297 seems to actually deploy! --- flake.lock | 21 +++++++++++++++++++++ flake.nix | 2 ++ infra/common/resource.nix | 1 + infra/machines/fedi201/fedipanel.nix | 1 + launch/resource.nix | 5 ++++- panel/nix/configuration.nix | 2 +- panel/src/panel/views.py | 4 ++-- 7 files changed, 32 insertions(+), 4 deletions(-) diff --git a/flake.lock b/flake.lock index ad891639..e955e13c 100644 --- a/flake.lock +++ b/flake.lock @@ -571,6 +571,26 @@ "type": "github" } }, + "home-manager_2": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1743860185, + "narHash": "sha256-TkhfJ+vH+iGxLQL6RJLObMmldAQpysVJ+p1WnnKyIeQ=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "b5e29565131802cc8adee7dccede794226da8614", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, "mk-naked-shell": { "flake": false, "locked": { @@ -1215,6 +1235,7 @@ "disko": "disko", "flake-parts": "flake-parts", "git-hooks": "git-hooks", + "home-manager": "home-manager_2", "nixops4": "nixops4", "nixops4-nixos": "nixops4-nixos", "nixpkgs": "nixpkgs_7" diff --git a/flake.nix b/flake.nix index dba9e55b..377448b3 100644 --- a/flake.nix +++ b/flake.nix @@ -3,6 +3,8 @@ nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; flake-parts.url = "github:hercules-ci/flake-parts"; git-hooks.url = "github:cachix/git-hooks.nix"; + home-manager.url = "github:nix-community/home-manager"; + home-manager.inputs.nixpkgs.follows = "nixpkgs"; agenix.url = "github:ryantm/agenix"; disko.url = "github:nix-community/disko"; diff --git a/infra/common/resource.nix b/infra/common/resource.nix index 4606ddf4..bc17e743 100644 --- a/infra/common/resource.nix +++ b/infra/common/resource.nix @@ -34,6 +34,7 @@ in imports = [ inputs.agenix.nixosModules.default inputs.disko.nixosModules.default + inputs.home-manager.nixosModules.home-manager ./options.nix ./nixos ]; diff --git a/infra/machines/fedi201/fedipanel.nix b/infra/machines/fedi201/fedipanel.nix index b49471bb..c3cc7a33 100644 --- a/infra/machines/fedi201/fedipanel.nix +++ b/infra/machines/fedi201/fedipanel.nix @@ -1,5 +1,6 @@ { config, + pkgs, ... }: let diff --git a/launch/resource.nix b/launch/resource.nix index 04811271..6b03305b 100644 --- a/launch/resource.nix +++ b/launch/resource.nix @@ -37,5 +37,8 @@ in ## FIXME: Remove direct root authentication once the NixOps4 NixOS provider ## supports users with password-less sudo. - users.users.root.openssh.authorizedKeys.keys = attrValues keys.contributors; + users.users.root.openssh.authorizedKeys.keys = attrValues keys.contributors ++ [ + # allow our panel vm access to the test machines + keys.systems.fedi201 + ]; } diff --git a/panel/nix/configuration.nix b/panel/nix/configuration.nix index 16d510fe..54653c18 100644 --- a/panel/nix/configuration.nix +++ b/panel/nix/configuration.nix @@ -186,7 +186,7 @@ in ''; serviceConfig = { Restart = "always"; - User = name; + User = "root"; WorkingDirectory = "/var/lib/${name}"; StateDirectory = name; RuntimeDirectory = name; diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index def63da9..52abcb70 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -103,7 +103,7 @@ class DeploymentStatus(ConfigurationForm): # Check for deploy button if "deploy" in self.request.POST.keys(): deployment_result, deployment_params = self.deployment(obj) - deployment_succeeded = deployment_result.returncode == 0 + deployment_succeeded = deployment_result == 0 return render(self.request, "partials/deployment_result.html", { "deployment_succeeded": deployment_succeeded, @@ -157,6 +157,6 @@ class DeploymentStatus(ConfigurationForm): "--auto-approve", "-lock=false", ] - deployment_result = subprocess.run(cmd, cwd=cwd, env=env) + deployment_result = subprocess.run(cmd, cwd=cwd, env=env, user="root") print(deployment_result) return deployment_result, deployment_params -- 2.48.1 From eb3b1425d019387f5e4d0e7ca376a252f180d121 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 5 Apr 2025 16:18:48 +0200 Subject: [PATCH 27/57] leave subprocess user implicit --- panel/src/panel/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 52abcb70..55effa77 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -157,6 +157,6 @@ class DeploymentStatus(ConfigurationForm): "--auto-approve", "-lock=false", ] - deployment_result = subprocess.run(cmd, cwd=cwd, env=env, user="root") + deployment_result = subprocess.run(cmd, cwd=cwd, env=env) print(deployment_result) return deployment_result, deployment_params -- 2.48.1 From 2b0ee4e52d745609a37edeebeb4e96d7ccdd1407 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 6 Apr 2025 11:22:39 +0200 Subject: [PATCH 28/57] add ssh key to not need root user --- launch/resource.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launch/resource.nix b/launch/resource.nix index 6b03305b..7ae3f99f 100644 --- a/launch/resource.nix +++ b/launch/resource.nix @@ -39,6 +39,6 @@ in ## supports users with password-less sudo. users.users.root.openssh.authorizedKeys.keys = attrValues keys.contributors ++ [ # allow our panel vm access to the test machines - keys.systems.fedi201 + keys.panel ]; } -- 2.48.1 From 79e58e21f4bb7bea6ee2f4ceb81685a019f87ee0 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 6 Apr 2025 22:21:04 +0200 Subject: [PATCH 29/57] nixos-anywhere -> terraform-nixos intended to swap out nixos-anywhere for terraform-nixos, over: - don't need nixos-anywhere to install nixos; we preload nixos to VMs - [awkward non-flake usage](https://nix-community.github.io/nixos-anywhere/howtos/use-without-flakes.html#3-set-nixos-version-to-use) - seemed not to pick up on config changes, as observed by test VMs losing their panel keys after TF sync however, it seems that terraform-nixos has its own flaws: - its output using a random id, i.e. forcing to push even on no changes - so far did not get ssh authentication to work --- launch/README.md | 4 +-- launch/default.nix | 2 +- launch/main.tf | 10 +++---- launch/mastodon.nix | 20 +++++++------- launch/peertube.nix | 26 ++++++++--------- launch/pixelfed.nix | 18 ++++++------ launch/shared.nix | 54 +++++++++++++----------------------- launch/tf-env.nix | 4 +-- launch/vm/main.tf | 60 +++++++++++++++++++++------------------- npins/sources.json | 24 ++++++++-------- panel/env.nix | 2 +- panel/src/panel/views.py | 2 +- 12 files changed, 107 insertions(+), 119 deletions(-) diff --git a/launch/README.md b/launch/README.md index 8bed71b8..237b293a 100644 --- a/launch/README.md +++ b/launch/README.md @@ -5,9 +5,9 @@ ### updating TF modules ```sh -$ npins update nixos-anywhere +$ npins update terraform-nixos $ cd launch/ -$ echo "{\"nixos-anywhere\": $(nix-instantiate --eval --json -E '(import ../npins).nixos-anywhere.outPath')}" > .auto.tfvars.json +$ echo "{\"terraform-nixos\": $(nix-instantiate --eval --json -E '(import ../npins).terraform-nixos.outPath')}" > .auto.tfvars.json ``` ### local development diff --git a/launch/default.nix b/launch/default.nix index 8518f575..5194d628 100644 --- a/launch/default.nix +++ b/launch/default.nix @@ -16,7 +16,7 @@ in shell = pkgs.mkShellNoCC { packages = [ pkgs.npins - pkgs.jq # implicit dep of nixos-anywhere TF: https://github.com/nix-community/nixos-anywhere/issues/416 + pkgs.gnugrep # used in terraform-nixos (import ./tf.nix { inherit lib pkgs; }) ]; }; diff --git a/launch/main.tf b/launch/main.tf index 3e8a3355..e705d8e7 100644 --- a/launch/main.tf +++ b/launch/main.tf @@ -1,4 +1,4 @@ -variable "nixos-anywhere" { +variable "terraform-nixos" { type = string } @@ -58,7 +58,7 @@ variable "initialUser" { # hostname = "test01" # config = "garage" # initialUser = var.initialUser -# nixos-anywhere = var.nixos-anywhere +# terraform-nixos = var.terraform-nixos # } module "mastodon" { @@ -68,7 +68,7 @@ module "mastodon" { hostname = "test06" config = "mastodon" initialUser = var.initialUser - nixos-anywhere = var.nixos-anywhere + terraform-nixos = var.terraform-nixos } module "pixelfed" { @@ -78,7 +78,7 @@ module "pixelfed" { hostname = "test04" config = "pixelfed" initialUser = var.initialUser - nixos-anywhere = var.nixos-anywhere + terraform-nixos = var.terraform-nixos } module "peertube" { @@ -88,5 +88,5 @@ module "peertube" { hostname = "test03" config = "peertube" initialUser = var.initialUser - nixos-anywhere = var.nixos-anywhere + terraform-nixos = var.terraform-nixos } diff --git a/launch/mastodon.nix b/launch/mastodon.nix index def88630..43abbf40 100644 --- a/launch/mastodon.nix +++ b/launch/mastodon.nix @@ -1,3 +1,4 @@ +{ pkgs, ... }: let mastodonS3KeyConfig = { pkgs, ... }: @@ -6,15 +7,14 @@ let s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7d37d093435a41f2aab8f13c19ba067d9776c90215f56614adad6ece597dbb34"; }; in -import ./shared.nix { - module = - { pkgs, ... }: - { - fediversity = { - mastodon = mastodonS3KeyConfig { inherit pkgs; } // { - enable = true; - }; - temp.cores = 1; # FIXME: should come from NixOps4 eventually - }; +{ + imports = [ + ./shared.nix + ]; + fediversity = { + mastodon = mastodonS3KeyConfig { inherit pkgs; } // { + enable = true; }; + temp.cores = 1; # FIXME: should come from NixOps4 eventually + }; } diff --git a/launch/peertube.nix b/launch/peertube.nix index df58c0a7..4a650650 100644 --- a/launch/peertube.nix +++ b/launch/peertube.nix @@ -1,3 +1,4 @@ +{ pkgs, ... }: let peertubeS3KeyConfig = { pkgs, ... }: @@ -6,18 +7,17 @@ let s3SecretKeyFile = pkgs.writeText "s3SecretKey" "7295c4201966a02c2c3d25b5cea4a5ff782966a2415e3a196f91924631191395"; }; in -import ./shared.nix { - module = - { pkgs, ... }: - { - fediversity = { - peertube = peertubeS3KeyConfig { inherit pkgs; } // { - enable = true; - ## NOTE: Only ever used for testing anyway. - ## - ## FIXME: Generate and store in NixOps4's state. - secretsFile = pkgs.writeText "secret" "574e093907d1157ac0f8e760a6deb1035402003af5763135bae9cbd6abe32b24"; - }; - }; +{ + imports = [ + ./shared.nix + ]; + fediversity = { + peertube = peertubeS3KeyConfig { inherit pkgs; } // { + enable = true; + ## NOTE: Only ever used for testing anyway. + ## + ## FIXME: Generate and store in NixOps4's state. + secretsFile = pkgs.writeText "secret" "574e093907d1157ac0f8e760a6deb1035402003af5763135bae9cbd6abe32b24"; }; + }; } diff --git a/launch/pixelfed.nix b/launch/pixelfed.nix index 6fdaf65a..28679801 100644 --- a/launch/pixelfed.nix +++ b/launch/pixelfed.nix @@ -1,3 +1,4 @@ +{ pkgs, ... }: let pixelfedS3KeyConfig = { pkgs, ... }: @@ -6,14 +7,13 @@ let s3SecretKeyFile = pkgs.writeText "s3SecretKey" "5be6799a88ca9b9d813d1a806b64f15efa49482dbe15339ddfaf7f19cf434987"; }; in -import ./shared.nix { - module = - { pkgs, ... }: - { - fediversity = { - pixelfed = pixelfedS3KeyConfig { inherit pkgs; } // { - enable = true; - }; - }; +{ + imports = [ + ./shared.nix + ]; + fediversity = { + pixelfed = pixelfedS3KeyConfig { inherit pkgs; } // { + enable = true; }; + }; } diff --git a/launch/shared.nix b/launch/shared.nix index f3d18344..2fe1f6a0 100644 --- a/launch/shared.nix +++ b/launch/shared.nix @@ -1,45 +1,29 @@ { - system ? "x86_64-linux", - sources ? import ../npins, - pkgs ? import sources.nixpkgs { - inherit system; - config = { }; - overlays = [ (import ../panel/nix/overlay.nix) ]; - }, - module, + pkgs, + terraform, + sources, ... }: -import "${sources.nixpkgs}/nixos/lib/eval-config.nix" { - modules = [ +let + inherit (terraform) hostname; +in +{ + imports = [ "${sources.disko}/module.nix" "${sources.agenix}/modules/age.nix" ../services/fediversity ./resource.nix # FIXME: get VM details from TF - module - ( - { - terraform, - ... - }: - let - inherit (terraform) hostname; - in - { - imports = [ - ../infra/test-machines/${hostname} - ]; - fediversityVm.name = hostname; - fediversity = { - inherit (terraform) domain; - temp.initialUser = { - inherit (terraform.initialUser) username email displayName; - # FIXME: disgusting, but nvm, this is going to be replaced by - # proper central authentication at some point - passwordFile = pkgs.writeText "password" terraform.initialUser.password; - }; - }; - } - ) + ../infra/test-machines/${hostname} ]; + fediversityVm.name = hostname; + fediversity = { + inherit (terraform) domain; + temp.initialUser = { + inherit (terraform.initialUser) username email displayName; + # FIXME: disgusting, but nvm, this is going to be replaced by + # proper central authentication at some point + passwordFile = pkgs.writeText "password" terraform.initialUser.password; + }; + }; } diff --git a/launch/tf-env.nix b/launch/tf-env.nix index 817c6e23..3f68f3c6 100644 --- a/launch/tf-env.nix +++ b/launch/tf-env.nix @@ -14,10 +14,10 @@ pkgs.stdenv.mkDerivation { runHook preBuild pushd launch/ - # pass nixos-anywhere path to TF through variable + # pass terraform-nixos path to TF through variable # when switching TF to nix take this directly from `inputs` # https://codeberg.org/kiara/e2ed-hetzner/commit/84b2a349d3e48ea2a17340bceff762d834fd4046 - echo "{\"nixos-anywhere\": \"${sources.nixos-anywhere}\"}" > .auto.tfvars.json + echo "{\"terraform-nixos\": \"${sources.terraform-nixos}\"}" > .auto.tfvars.json # point to the relevant providers tofu init -input=false diff --git a/launch/vm/main.tf b/launch/vm/main.tf index e4eb9b88..c49a91bf 100644 --- a/launch/vm/main.tf +++ b/launch/vm/main.tf @@ -1,4 +1,8 @@ -variable "nixos-anywhere" { +variable "terraform-nixos" { + type = string +} + +variable "config" { type = string } @@ -10,10 +14,6 @@ variable "hostname" { type = string } -variable "config" { - type = string -} - variable "initialUser" { type = object({ displayName = string @@ -24,28 +24,32 @@ variable "initialUser" { } module "deploy" { - # source = "github.com/nix-community/nixos-anywhere//terraform/all-in-one" - source = "${var.nixos-anywhere}//terraform/all-in-one" - file = "${path.module}/../${var.config}.nix" - nixos_system_attr = "config.system.build.toplevel" - nixos_partitioner_attr = "config.system.build.diskoScript" - # when instance id changes, it will trigger a reinstall - instance_id = var.hostname - target_user = "root" + source = "${var.terraform-nixos}//deploy_nixos" target_host = "${var.hostname}.abundos.eu" - extra_files_script = "${path.module}/../pass-ssh-key.sh" - extra_environment = { - host = var.hostname - } - special_args = { - terraform = { - domain = var.domain - hostname = var.hostname - initialUser = var.initialUser - } - } - nix_options = { - show-trace = true - } - # build_on_remote = true + target_user= "root" # FIXME: #24 + target_system = "x86_64-linux" + NIX_PATH = "nixpkgs=${data.external.pins.result["nixpkgs"]}:sources=${path.root}/../npins" + nixos_config = "${path.root}/${var.config}.nix" + extra_eval_args = [ + "--arg", + "specialArgs", + <<-EOT + { + sources = import ; + terraform = builtins.fromJSON ''${jsonencode({ + domain = var.domain + hostname = var.hostname + initialUser = var.initialUser + })}''; + } + EOT + ] + # build_on_target = false + # triggers = { + # # pins = data.external.pins.result + # } +} + +data "external" "pins" { + program = ["nix", "eval", "--json", "-f", "${path.root}/../npins/default.nix"] } diff --git a/npins/sources.json b/npins/sources.json index 7e1df4f9..21b4dcf0 100644 --- a/npins/sources.json +++ b/npins/sources.json @@ -66,23 +66,23 @@ "url": "https://github.com/nix-community/nix-unit/archive/2071bbb765681ac3d8194ec560c8b27ff2a3b541.tar.gz", "hash": "0blz1kcmn9vnr9q3iqp2mv13hv3pdccljmmc54f8j7ybf5v0wgmp" }, - "nixos-anywhere": { - "type": "Git", - "repository": { - "type": "GitHub", - "owner": "KiaraGrouwstra", - "repo": "nixos-anywhere" - }, - "branch": "special-args-nested-flake-fixed", - "revision": "5aa35145f045eb23fa8773821d5626bcf54dbe0e", - "url": "https://github.com/KiaraGrouwstra/nixos-anywhere/archive/5aa35145f045eb23fa8773821d5626bcf54dbe0e.tar.gz", - "hash": "0m67iyd04wl183il1cfi623xpxcvbbpc5x1gh74478qc3fgr0g54" - }, "nixpkgs": { "type": "Channel", "name": "nixpkgs-unstable", "url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.05pre777917.b7ba7f9f45c5/nixexprs.tar.xz", "hash": "0jb6b7sv66bn06pchj2l88z0i5dlz0c2vb3z6pjjlq2p8q11zigg" + }, + "terraform-nixos": { + "type": "Git", + "repository": { + "type": "GitHub", + "owner": "KiaraGrouwstra", + "repo": "terraform-nixos" + }, + "branch": "special-args", + "revision": "e3e120e80dbbb53b4bfda4380d02e74eef4b5ffd", + "url": "https://github.com/KiaraGrouwstra/terraform-nixos/archive/e3e120e80dbbb53b4bfda4380d02e74eef4b5ffd.tar.gz", + "hash": "03z8xxsbkv2mwfkd8w6dj3jlckrsgbi5wpp680dlyrzlw78zvf8b" } }, "version": 3 diff --git a/panel/env.nix b/panel/env.nix index 99a286d8..9482b2a0 100644 --- a/panel/env.nix +++ b/panel/env.nix @@ -10,7 +10,7 @@ pkgs.coreutils pkgs.openssh pkgs.git - pkgs.jq # implicit dep of nixos-anywhere TF: https://github.com/nix-community/nixos-anywhere/issues/416 + pkgs.gnugrep # used in terraform-nixos (import ../launch/tf.nix { inherit lib pkgs; }) ]; } diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 55effa77..bab35088 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -138,7 +138,7 @@ class DeploymentStatus(ConfigurationForm): deployment_params = dummy_user | json.loads(submission) env = { "PATH": settings.bin_path, - # used in nixos-anywhere for ssh-copy-id to make `.ssh` in for ssh-copy-id. + # used in terraform for ssh-copy-id to make `.ssh` in for ssh-copy-id. # run thru subprocess, HOME points to the read-only `/var/empty`. # in local dev, it will just reject the `/tmp` and make it in HOME after all. "HOME": "/tmp", -- 2.48.1 From 1da2e9e4970ae13fac5b190a5b9ac8d5571deebc Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Thu, 10 Apr 2025 09:00:21 +0200 Subject: [PATCH 30/57] special-args -> hermetic --- launch/.gitignore | 1 + launch/.terraform/modules/mastodon.deploy | 2 +- launch/.terraform/modules/modules.json | 2 +- .../deploy_nixos/nixos-deploy.sh | 2 - ...d to a Nix language value' for non-flakes) | 1 - .../deploy_nixos/nixos-deploy.sh | 2 - launch/.terraform/plugin_path | 1 + launch/README.md | 2 +- launch/main.tf | 17 +++++++ launch/mastodon.nix | 3 -- launch/module.auto.tfvars.json | 2 +- launch/peertube.nix | 3 -- launch/pixelfed.nix | 3 -- launch/terraform.tfstate | 1 - launch/terraform.tfstate.backup | 1 - launch/tf-env.nix | 2 +- launch/vm/main.tf | 49 ++++++++++++++----- npins/sources.json | 10 ++-- 18 files changed, 65 insertions(+), 39 deletions(-) delete mode 120000 launch/.terraform/modules/peertube.deploy~f00c14b (get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes) delete mode 100644 launch/terraform.tfstate delete mode 100644 launch/terraform.tfstate.backup diff --git a/launch/.gitignore b/launch/.gitignore index 6ff139e0..42b97838 100644 --- a/launch/.gitignore +++ b/launch/.gitignore @@ -1,4 +1,5 @@ .auto.tfvars.json +module.auto.tfvars.json .terraform/ .terraform.tfstate.lock.info terraform.tfstate* diff --git a/launch/.terraform/modules/mastodon.deploy b/launch/.terraform/modules/mastodon.deploy index 4c479922..ec6dad7d 120000 --- a/launch/.terraform/modules/mastodon.deploy +++ b/launch/.terraform/modules/mastodon.deploy @@ -1 +1 @@ -/nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source \ No newline at end of file +/nix/store/8mh14khb56hqyslxhla0nzdzi2wp6wp7-source \ No newline at end of file diff --git a/launch/.terraform/modules/modules.json b/launch/.terraform/modules/modules.json index aa12893a..6526e512 100644 --- a/launch/.terraform/modules/modules.json +++ b/launch/.terraform/modules/modules.json @@ -1 +1 @@ -{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"mastodon","Source":"./vm","Dir":"vm"},{"Key":"mastodon.deploy","Source":"file:///nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source//deploy_nixos","Dir":".terraform/modules/mastodon.deploy/deploy_nixos"},{"Key":"peertube","Source":"./vm","Dir":"vm"},{"Key":"peertube.deploy","Source":"file:///nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source//deploy_nixos","Dir":".terraform/modules/peertube.deploy/deploy_nixos"},{"Key":"pixelfed","Source":"./vm","Dir":"vm"},{"Key":"pixelfed.deploy","Source":"file:///nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source//deploy_nixos","Dir":".terraform/modules/pixelfed.deploy/deploy_nixos"}]} +{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"mastodon","Source":"./vm","Dir":"vm"},{"Key":"mastodon.deploy","Source":"file:///nix/store/8mh14khb56hqyslxhla0nzdzi2wp6wp7-source//deploy_nixos","Dir":".terraform/modules/mastodon.deploy/deploy_nixos"},{"Key":"peertube","Source":"./vm","Dir":"vm"},{"Key":"peertube.deploy","Source":"file:///nix/store/8mh14khb56hqyslxhla0nzdzi2wp6wp7-source//deploy_nixos","Dir":".terraform/modules/peertube.deploy/deploy_nixos"},{"Key":"pixelfed","Source":"./vm","Dir":"vm"},{"Key":"pixelfed.deploy","Source":"file:///nix/store/8mh14khb56hqyslxhla0nzdzi2wp6wp7-source//deploy_nixos","Dir":".terraform/modules/pixelfed.deploy/deploy_nixos"}]} \ No newline at end of file diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-deploy.sh b/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-deploy.sh index e0fcafb2..319651bb 100755 --- a/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-deploy.sh +++ b/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-deploy.sh @@ -95,8 +95,6 @@ setupControlPath() { ### Main ### -log "$(env)" - setupControlPath if [[ "${buildOnTarget:-false}" == true ]]; then diff --git a/launch/.terraform/modules/peertube.deploy~f00c14b (get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes) b/launch/.terraform/modules/peertube.deploy~f00c14b (get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes) deleted file mode 120000 index 17167407..00000000 --- a/launch/.terraform/modules/peertube.deploy~f00c14b (get TF in prod to the same 'installable ... does not correspond to a Nix language value' for non-flakes) +++ /dev/null @@ -1 +0,0 @@ -/nix/store/ca7wwzypz3lhvmrb2a1i72pf7d2vh6mw-source \ No newline at end of file diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-deploy.sh b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-deploy.sh index e0fcafb2..319651bb 100755 --- a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-deploy.sh +++ b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-deploy.sh @@ -95,8 +95,6 @@ setupControlPath() { ### Main ### -log "$(env)" - setupControlPath if [[ "${buildOnTarget:-false}" == true ]]; then diff --git a/launch/.terraform/plugin_path b/launch/.terraform/plugin_path index 9d621c4b..0a21d939 100644 --- a/launch/.terraform/plugin_path +++ b/launch/.terraform/plugin_path @@ -1,2 +1,3 @@ [ "/nix/store/mnqkwjg5v6sx86an34b4cn075h0lapz3-opentofu-1.8.7/libexec/terraform-providers" +] \ No newline at end of file diff --git a/launch/README.md b/launch/README.md index 237b293a..a3c83086 100644 --- a/launch/README.md +++ b/launch/README.md @@ -7,7 +7,7 @@ ```sh $ npins update terraform-nixos $ cd launch/ -$ echo "{\"terraform-nixos\": $(nix-instantiate --eval --json -E '(import ../npins).terraform-nixos.outPath')}" > .auto.tfvars.json +$ echo "{\"terraform-nixos\": $(nix-instantiate --eval --json -E '(import ../npins).terraform-nixos.outPath')}" > module.auto.tfvars.json ``` ### local development diff --git a/launch/main.tf b/launch/main.tf index e705d8e7..fc1a7692 100644 --- a/launch/main.tf +++ b/launch/main.tf @@ -51,6 +51,19 @@ variable "initialUser" { } } +# TODO: could this straight-up be added in the child module instead? +variable "ssh_private_key_file" { + type = string + description = "Path to private key used to connect to the target_host" + default = "" +} + +variable "deploy_environment" { + type = map(string) + description = "Extra environment variables to be set during deployment." + default = {} +} + # module "garage" { # source = "./vm" # count = var.mastodon.enable || var.pixelfed.enable || var.peertube.enable ? 1 : 0 @@ -59,6 +72,7 @@ variable "initialUser" { # config = "garage" # initialUser = var.initialUser # terraform-nixos = var.terraform-nixos +# ssh_private_key_file = var.ssh_private_key_file # } module "mastodon" { @@ -69,6 +83,7 @@ module "mastodon" { config = "mastodon" initialUser = var.initialUser terraform-nixos = var.terraform-nixos + ssh_private_key_file = var.ssh_private_key_file } module "pixelfed" { @@ -79,6 +94,7 @@ module "pixelfed" { config = "pixelfed" initialUser = var.initialUser terraform-nixos = var.terraform-nixos + ssh_private_key_file = var.ssh_private_key_file } module "peertube" { @@ -89,4 +105,5 @@ module "peertube" { config = "peertube" initialUser = var.initialUser terraform-nixos = var.terraform-nixos + ssh_private_key_file = var.ssh_private_key_file } diff --git a/launch/mastodon.nix b/launch/mastodon.nix index 43abbf40..26682f50 100644 --- a/launch/mastodon.nix +++ b/launch/mastodon.nix @@ -8,9 +8,6 @@ let }; in { - imports = [ - ./shared.nix - ]; fediversity = { mastodon = mastodonS3KeyConfig { inherit pkgs; } // { enable = true; diff --git a/launch/module.auto.tfvars.json b/launch/module.auto.tfvars.json index 50830494..0d108435 100644 --- a/launch/module.auto.tfvars.json +++ b/launch/module.auto.tfvars.json @@ -1 +1 @@ -{"terraform-nixos": "/nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source"} +{"terraform-nixos": "/nix/store/8mh14khb56hqyslxhla0nzdzi2wp6wp7-source"} diff --git a/launch/peertube.nix b/launch/peertube.nix index 4a650650..4124568a 100644 --- a/launch/peertube.nix +++ b/launch/peertube.nix @@ -8,9 +8,6 @@ let }; in { - imports = [ - ./shared.nix - ]; fediversity = { peertube = peertubeS3KeyConfig { inherit pkgs; } // { enable = true; diff --git a/launch/pixelfed.nix b/launch/pixelfed.nix index 28679801..75790409 100644 --- a/launch/pixelfed.nix +++ b/launch/pixelfed.nix @@ -8,9 +8,6 @@ let }; in { - imports = [ - ./shared.nix - ]; fediversity = { pixelfed = pixelfedS3KeyConfig { inherit pkgs; } // { enable = true; diff --git a/launch/terraform.tfstate b/launch/terraform.tfstate deleted file mode 100644 index 6786b6b2..00000000 --- a/launch/terraform.tfstate +++ /dev/null @@ -1 +0,0 @@ -{"version":4,"terraform_version":"1.9.0","serial":68,"lineage":"acbbbabc-b0fa-9ac4-7e96-aaa2cfc9b223","outputs":{},"resources":[{"module":"module.mastodon[0]","mode":"data","type":"external","name":"pins","provider":"provider[\"registry.opentofu.org/hashicorp/external\"]","instances":[{"schema_version":0,"attributes":{"id":"-","program":["nix","eval","--json","-f","./../npins/default.nix"],"query":null,"result":{"agenix":"/nix/store/glsqq1xn5al7d528hvlbm4hl3ladxmka-source","disko":"/nix/store/7wf9q0mb1i43x9dr1qlyfaraq15n6sii-source","flake-inputs":"/nix/store/fqln0bcp6mp75k4sl0cav2f0np60lwhj-source","htmx":"/nix/store/mwqqk0qmldzvv4xj9kq2lbah2flhc44z-source","nix-unit":"/nix/store/yc260i6cp4q4mivlhrrypis34yp138sw-source","nixpkgs":"/nix/store/g9chc50nd98bm0pxhyhyyhg8ldj2fzzp-source","terraform-nixos":"/nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source"},"working_dir":null},"sensitive_attributes":[]}]},{"module":"module.mastodon[0].module.deploy","mode":"data","type":"external","name":"nixos-instantiate","provider":"provider[\"registry.opentofu.org/hashicorp/external\"]","instances":[{"schema_version":0,"attributes":{"id":"-","program":[".terraform/modules/mastodon.deploy/deploy_nixos/nixos-instantiate.sh","nixpkgs=/nix/store/g9chc50nd98bm0pxhyhyyhg8ldj2fzzp-source:sources=./../npins","import /nix/store/g9chc50nd98bm0pxhyhyyhg8ldj2fzzp-source/nixos/lib/eval-config.nix {\n system = \"x86_64-linux\";\n specialArgs = {\n sources = import ./../npins;\n terraform = builtins.fromJSON ''{\"domain\":\"fediversity.net\",\"hostname\":\"test06\",\"initialUser\":{\"displayName\":\"Testy McTestface\",\"email\":\"test@test.com\",\"password\":\"testtest\",\"username\":\"test\"}}'';\n };\n modules = [\n ./mastodon.nix\n ./shared.nix\n ];\n}\n",".","false","--argstr","system","x86_64-linux","--arg","hermetic","true"],"query":null,"result":{"currentSystem":"x86_64-linux","drv_path":"/nix/store/q7xraxg5jnavc79dww1qn21ik7caxb48-nixos-system-test06-25.05pre777917.b7ba7f9f45c5.drv","out_path":"/nix/store/g00cvr7h06p0m7z53v7gx3zf5fyr10bc-nixos-system-test06-25.05pre777917.b7ba7f9f45c5","substituters":"https://cache.nixos.org/","trusted-public-keys":"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="},"working_dir":null},"sensitive_attributes":[]}]},{"module":"module.mastodon[0].module.deploy","mode":"managed","type":"null_resource","name":"deploy_nixos","provider":"provider[\"registry.opentofu.org/hashicorp/null\"]","instances":[{"status":"tainted","schema_version":0,"attributes":{"id":"4793704995569904675","triggers":{"deploy_nixos_drv":"/nix/store/q7xraxg5jnavc79dww1qn21ik7caxb48-nixos-system-test06-25.05pre777917.b7ba7f9f45c5.drv","deploy_nixos_keys":"44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"}},"sensitive_attributes":[],"dependencies":["module.mastodon.data.external.pins","module.mastodon.module.deploy.data.external.nixos-instantiate"]}]}],"check_results":null} diff --git a/launch/terraform.tfstate.backup b/launch/terraform.tfstate.backup deleted file mode 100644 index 31f0d72c..00000000 --- a/launch/terraform.tfstate.backup +++ /dev/null @@ -1 +0,0 @@ -{"version":4,"terraform_version":"1.9.0","serial":67,"lineage":"acbbbabc-b0fa-9ac4-7e96-aaa2cfc9b223","outputs":{},"resources":[{"module":"module.mastodon[0]","mode":"data","type":"external","name":"pins","provider":"provider[\"registry.opentofu.org/hashicorp/external\"]","instances":[{"schema_version":0,"attributes":{"id":"-","program":["nix","eval","--json","-f","./../npins/default.nix"],"query":null,"result":{"agenix":"/nix/store/glsqq1xn5al7d528hvlbm4hl3ladxmka-source","disko":"/nix/store/7wf9q0mb1i43x9dr1qlyfaraq15n6sii-source","flake-inputs":"/nix/store/fqln0bcp6mp75k4sl0cav2f0np60lwhj-source","htmx":"/nix/store/mwqqk0qmldzvv4xj9kq2lbah2flhc44z-source","nix-unit":"/nix/store/yc260i6cp4q4mivlhrrypis34yp138sw-source","nixpkgs":"/nix/store/g9chc50nd98bm0pxhyhyyhg8ldj2fzzp-source","terraform-nixos":"/nix/store/xvgm4swq8yss14fmizx0dn288gf4zw7i-source"},"working_dir":null},"sensitive_attributes":[]}]},{"module":"module.mastodon[0].module.deploy","mode":"data","type":"external","name":"nixos-instantiate","provider":"provider[\"registry.opentofu.org/hashicorp/external\"]","instances":[{"schema_version":0,"attributes":{"id":"-","program":[".terraform/modules/mastodon.deploy/deploy_nixos/nixos-instantiate.sh","nixpkgs=/nix/store/g9chc50nd98bm0pxhyhyyhg8ldj2fzzp-source:sources=./../npins","import /nix/store/g9chc50nd98bm0pxhyhyyhg8ldj2fzzp-source/nixos/lib/eval-config.nix {\n system = \"x86_64-linux\";\n specialArgs = {\n sources = import ./../npins;\n terraform = builtins.fromJSON ''{\"domain\":\"fediversity.net\",\"hostname\":\"test06\",\"initialUser\":{\"displayName\":\"Testy McTestface\",\"email\":\"test@test.com\",\"password\":\"testtest\",\"username\":\"test\"}}'';\n };\n modules = [\n ./mastodon.nix\n ./shared.nix\n ];\n}\n",".","false","--argstr","system","x86_64-linux","--arg","hermetic","true"],"query":null,"result":{"currentSystem":"x86_64-linux","drv_path":"/nix/store/q7xraxg5jnavc79dww1qn21ik7caxb48-nixos-system-test06-25.05pre777917.b7ba7f9f45c5.drv","out_path":"/nix/store/g00cvr7h06p0m7z53v7gx3zf5fyr10bc-nixos-system-test06-25.05pre777917.b7ba7f9f45c5","substituters":"https://cache.nixos.org/","trusted-public-keys":"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="},"working_dir":null},"sensitive_attributes":[]}]},{"module":"module.mastodon[0].module.deploy","mode":"managed","type":"null_resource","name":"deploy_nixos","provider":"provider[\"registry.opentofu.org/hashicorp/null\"]","instances":[{"status":"tainted","schema_version":0,"attributes":{"id":"1197266561618904114","triggers":{"deploy_nixos_drv":"/nix/store/q7xraxg5jnavc79dww1qn21ik7caxb48-nixos-system-test06-25.05pre777917.b7ba7f9f45c5.drv","deploy_nixos_keys":"44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"}},"sensitive_attributes":[],"dependencies":["module.mastodon.data.external.pins","module.mastodon.module.deploy.data.external.nixos-instantiate"]}]}],"check_results":null} diff --git a/launch/tf-env.nix b/launch/tf-env.nix index 3f68f3c6..2c720795 100644 --- a/launch/tf-env.nix +++ b/launch/tf-env.nix @@ -17,8 +17,8 @@ pkgs.stdenv.mkDerivation { # pass terraform-nixos path to TF through variable # when switching TF to nix take this directly from `inputs` # https://codeberg.org/kiara/e2ed-hetzner/commit/84b2a349d3e48ea2a17340bceff762d834fd4046 - echo "{\"terraform-nixos\": \"${sources.terraform-nixos}\"}" > .auto.tfvars.json + echo "{\"terraform-nixos\": \"${sources.terraform-nixos}\"}" > module.auto.tfvars.json # point to the relevant providers tofu init -input=false diff --git a/launch/vm/main.tf b/launch/vm/main.tf index c49a91bf..5ea1caf4 100644 --- a/launch/vm/main.tf +++ b/launch/vm/main.tf @@ -23,27 +23,50 @@ variable "initialUser" { }) } +variable "ssh_private_key_file" { + type = string + description = "Path to private key used to connect to the target_host" + default = "" +} + +variable "deploy_environment" { + type = map(string) + description = "Extra environment variables to be set during deployment." + default = {} +} + +locals { + system = "x86_64-linux" + nixpkgs = data.external.pins.result["nixpkgs"] + sources = "${path.root}/../npins" +} + module "deploy" { source = "${var.terraform-nixos}//deploy_nixos" + ssh_private_key_file = var.ssh_private_key_file target_host = "${var.hostname}.abundos.eu" target_user= "root" # FIXME: #24 - target_system = "x86_64-linux" - NIX_PATH = "nixpkgs=${data.external.pins.result["nixpkgs"]}:sources=${path.root}/../npins" - nixos_config = "${path.root}/${var.config}.nix" - extra_eval_args = [ - "--arg", - "specialArgs", - <<-EOT - { - sources = import ; + target_system = local.system + NIX_PATH = "nixpkgs=${local.nixpkgs}:sources=${local.sources}" + hermetic = true + config_pwd = path.root + config = <<-EOT + import ${data.external.pins.result["nixpkgs"]}/nixos/lib/eval-config.nix { + system = "${local.system}"; + specialArgs = { + sources = import ${path.root}/../npins; terraform = builtins.fromJSON ''${jsonencode({ domain = var.domain hostname = var.hostname initialUser = var.initialUser })}''; - } - EOT - ] + }; + modules = [ + ${path.root}/${var.config}.nix + ${path.root}/shared.nix + ]; + } + EOT # build_on_target = false # triggers = { # # pins = data.external.pins.result @@ -51,5 +74,5 @@ module "deploy" { } data "external" "pins" { - program = ["nix", "eval", "--json", "-f", "${path.root}/../npins/default.nix"] + program = ["nix", "eval", "--json", "-f", "${path.root}/../npins"] } diff --git a/npins/sources.json b/npins/sources.json index 21b4dcf0..24541c01 100644 --- a/npins/sources.json +++ b/npins/sources.json @@ -79,11 +79,11 @@ "owner": "KiaraGrouwstra", "repo": "terraform-nixos" }, - "branch": "special-args", - "revision": "e3e120e80dbbb53b4bfda4380d02e74eef4b5ffd", - "url": "https://github.com/KiaraGrouwstra/terraform-nixos/archive/e3e120e80dbbb53b4bfda4380d02e74eef4b5ffd.tar.gz", - "hash": "03z8xxsbkv2mwfkd8w6dj3jlckrsgbi5wpp680dlyrzlw78zvf8b" + "branch": "env-hermetic", + "revision": "cc28d99966d0c742265d1551c622383fd775dd30", + "url": "https://github.com/KiaraGrouwstra/terraform-nixos/archive/cc28d99966d0c742265d1551c622383fd775dd30.tar.gz", + "hash": "17a01my75ccxpn5h40w3855hkj2mkfm0q0chxwxcnq8g9hh67waj" } }, "version": 3 -} +} \ No newline at end of file -- 2.48.1 From ce0e8e39f20458a14408bd44a33ce6e3530ee8c4 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Thu, 10 Apr 2025 09:03:58 +0200 Subject: [PATCH 31/57] un-track .terraform --- launch/.terraform/modules/mastodon.deploy | 1 - launch/.terraform/modules/modules.json | 1 - .../modules/peertube.deploy/LICENSE | 201 ---------- .../modules/peertube.deploy/README.md | 113 ------ .../peertube.deploy/aws_image_nixos/README.md | 46 --- .../peertube.deploy/aws_image_nixos/main.tf | 34 -- .../aws_image_nixos/update-url-map | 51 --- .../aws_image_nixos/url_map.nix | 2 - .../aws_image_nixos/url_map.tf | 353 ------------------ .../aws_image_nixos/versions.tf | 4 - .../peertube.deploy/deploy_nixos/README.md | 129 ------- .../peertube.deploy/deploy_nixos/main.tf | 221 ----------- .../deploy_nixos/maybe-sudo.sh | 11 - .../deploy_nixos/nixos-deploy.sh | 133 ------- .../deploy_nixos/nixos-instantiate.sh | 94 ----- .../deploy_nixos/unpack-keys.sh | 46 --- .../peertube.deploy/deploy_nixos/versions.tf | 4 - .../examples/google/deploy_nixos.tf | 82 ---- .../examples/google/image_nixos.tf | 25 -- .../examples/google/image_nixos_custom.nix | 13 - .../examples/google/image_nixos_custom.tf | 21 -- .../examples/google/provider.tf | 3 - .../hermetic_config/configuration.nix | 60 --- .../examples/hermetic_config/default.tf | 27 -- launch/.terraform/modules/peertube.deploy/fmt | 17 - .../google_image_nixos/README.md | 76 ---- .../google_image_nixos/main.tf | 64 ---- .../google_image_nixos/update-url-map | 47 --- .../google_image_nixos/url_map.nix | 2 - .../google_image_nixos/url_map.tf | 17 - .../google_image_nixos/versions.tf | 4 - .../google_image_nixos_custom/README.md | 54 --- .../google_image_nixos_custom/main.tf | 94 ----- .../google_image_nixos_custom/nixos-build.sh | 35 -- .../google_image_nixos_custom/versions.tf | 4 - .../nix/terraform-docs/default.nix | 26 -- .../scripts/terraform-docs-updater | 37 -- .../modules/peertube.deploy/shell.nix | 21 -- .../modules/pixelfed.deploy/LICENSE | 201 ---------- .../modules/pixelfed.deploy/README.md | 113 ------ .../pixelfed.deploy/aws_image_nixos/README.md | 46 --- .../pixelfed.deploy/aws_image_nixos/main.tf | 34 -- .../aws_image_nixos/update-url-map | 51 --- .../aws_image_nixos/url_map.nix | 2 - .../aws_image_nixos/url_map.tf | 353 ------------------ .../aws_image_nixos/versions.tf | 4 - .../pixelfed.deploy/deploy_nixos/README.md | 129 ------- .../pixelfed.deploy/deploy_nixos/main.tf | 221 ----------- .../deploy_nixos/maybe-sudo.sh | 11 - .../deploy_nixos/nixos-deploy.sh | 133 ------- .../deploy_nixos/nixos-instantiate.sh | 94 ----- .../deploy_nixos/unpack-keys.sh | 46 --- .../pixelfed.deploy/deploy_nixos/versions.tf | 4 - .../examples/google/deploy_nixos.tf | 82 ---- .../examples/google/image_nixos.tf | 25 -- .../examples/google/image_nixos_custom.nix | 13 - .../examples/google/image_nixos_custom.tf | 21 -- .../examples/google/provider.tf | 3 - .../hermetic_config/configuration.nix | 60 --- .../examples/hermetic_config/default.tf | 27 -- launch/.terraform/modules/pixelfed.deploy/fmt | 17 - .../google_image_nixos/README.md | 76 ---- .../google_image_nixos/main.tf | 64 ---- .../google_image_nixos/update-url-map | 47 --- .../google_image_nixos/url_map.nix | 2 - .../google_image_nixos/url_map.tf | 17 - .../google_image_nixos/versions.tf | 4 - .../google_image_nixos_custom/README.md | 54 --- .../google_image_nixos_custom/main.tf | 94 ----- .../google_image_nixos_custom/nixos-build.sh | 35 -- .../google_image_nixos_custom/versions.tf | 4 - .../nix/terraform-docs/default.nix | 26 -- .../scripts/terraform-docs-updater | 37 -- .../modules/pixelfed.deploy/shell.nix | 21 -- launch/.terraform/plugin_path | 3 - 75 files changed, 4347 deletions(-) delete mode 120000 launch/.terraform/modules/mastodon.deploy delete mode 100644 launch/.terraform/modules/modules.json delete mode 100644 launch/.terraform/modules/peertube.deploy/LICENSE delete mode 100644 launch/.terraform/modules/peertube.deploy/README.md delete mode 100644 launch/.terraform/modules/peertube.deploy/aws_image_nixos/README.md delete mode 100644 launch/.terraform/modules/peertube.deploy/aws_image_nixos/main.tf delete mode 100755 launch/.terraform/modules/peertube.deploy/aws_image_nixos/update-url-map delete mode 100644 launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/aws_image_nixos/versions.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/deploy_nixos/README.md delete mode 100644 launch/.terraform/modules/peertube.deploy/deploy_nixos/main.tf delete mode 100755 launch/.terraform/modules/peertube.deploy/deploy_nixos/maybe-sudo.sh delete mode 100755 launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-deploy.sh delete mode 100755 launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-instantiate.sh delete mode 100755 launch/.terraform/modules/peertube.deploy/deploy_nixos/unpack-keys.sh delete mode 100644 launch/.terraform/modules/peertube.deploy/deploy_nixos/versions.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/examples/google/deploy_nixos.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/examples/google/image_nixos.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/examples/google/provider.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/examples/hermetic_config/configuration.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/examples/hermetic_config/default.tf delete mode 100755 launch/.terraform/modules/peertube.deploy/fmt delete mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos/README.md delete mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos/main.tf delete mode 100755 launch/.terraform/modules/peertube.deploy/google_image_nixos/update-url-map delete mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.nix delete mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos/versions.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/README.md delete mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/main.tf delete mode 100755 launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/nixos-build.sh delete mode 100644 launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/versions.tf delete mode 100644 launch/.terraform/modules/peertube.deploy/nix/terraform-docs/default.nix delete mode 100755 launch/.terraform/modules/peertube.deploy/scripts/terraform-docs-updater delete mode 100644 launch/.terraform/modules/peertube.deploy/shell.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/LICENSE delete mode 100644 launch/.terraform/modules/pixelfed.deploy/README.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/README.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/main.tf delete mode 100755 launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/update-url-map delete mode 100644 launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/versions.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/README.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/main.tf delete mode 100755 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/maybe-sudo.sh delete mode 100755 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-deploy.sh delete mode 100755 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-instantiate.sh delete mode 100755 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/unpack-keys.sh delete mode 100644 launch/.terraform/modules/pixelfed.deploy/deploy_nixos/versions.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/google/deploy_nixos.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/google/provider.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/configuration.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/default.tf delete mode 100755 launch/.terraform/modules/pixelfed.deploy/fmt delete mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos/README.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos/main.tf delete mode 100755 launch/.terraform/modules/pixelfed.deploy/google_image_nixos/update-url-map delete mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.nix delete mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos/versions.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/README.md delete mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/main.tf delete mode 100755 launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/nixos-build.sh delete mode 100644 launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/versions.tf delete mode 100644 launch/.terraform/modules/pixelfed.deploy/nix/terraform-docs/default.nix delete mode 100755 launch/.terraform/modules/pixelfed.deploy/scripts/terraform-docs-updater delete mode 100644 launch/.terraform/modules/pixelfed.deploy/shell.nix delete mode 100644 launch/.terraform/plugin_path diff --git a/launch/.terraform/modules/mastodon.deploy b/launch/.terraform/modules/mastodon.deploy deleted file mode 120000 index ec6dad7d..00000000 --- a/launch/.terraform/modules/mastodon.deploy +++ /dev/null @@ -1 +0,0 @@ -/nix/store/8mh14khb56hqyslxhla0nzdzi2wp6wp7-source \ No newline at end of file diff --git a/launch/.terraform/modules/modules.json b/launch/.terraform/modules/modules.json deleted file mode 100644 index 6526e512..00000000 --- a/launch/.terraform/modules/modules.json +++ /dev/null @@ -1 +0,0 @@ -{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"mastodon","Source":"./vm","Dir":"vm"},{"Key":"mastodon.deploy","Source":"file:///nix/store/8mh14khb56hqyslxhla0nzdzi2wp6wp7-source//deploy_nixos","Dir":".terraform/modules/mastodon.deploy/deploy_nixos"},{"Key":"peertube","Source":"./vm","Dir":"vm"},{"Key":"peertube.deploy","Source":"file:///nix/store/8mh14khb56hqyslxhla0nzdzi2wp6wp7-source//deploy_nixos","Dir":".terraform/modules/peertube.deploy/deploy_nixos"},{"Key":"pixelfed","Source":"./vm","Dir":"vm"},{"Key":"pixelfed.deploy","Source":"file:///nix/store/8mh14khb56hqyslxhla0nzdzi2wp6wp7-source//deploy_nixos","Dir":".terraform/modules/pixelfed.deploy/deploy_nixos"}]} \ No newline at end of file diff --git a/launch/.terraform/modules/peertube.deploy/LICENSE b/launch/.terraform/modules/peertube.deploy/LICENSE deleted file mode 100644 index 261eeb9e..00000000 --- a/launch/.terraform/modules/peertube.deploy/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/launch/.terraform/modules/peertube.deploy/README.md b/launch/.terraform/modules/peertube.deploy/README.md deleted file mode 100644 index 443a0e87..00000000 --- a/launch/.terraform/modules/peertube.deploy/README.md +++ /dev/null @@ -1,113 +0,0 @@ -# terraform-nixos - -[![built with nix](https://builtwithnix.org/badge.svg)](https://builtwithnix.org) - -This repository contains a set of Terraform Modules designed to deploy NixOS -machines. These modules are designed to work together and support different -deployment scenarios. - -## What is Terraform? - -[Terraform][terraform] is a tool that allows to declare infrastructures as -code. - -## What is Nix, nixpkgs and NixOS? - -[Nix][nix] is a build system and package manager that allows to manage whole -system configurations as code. nixpkgs is a set of 20k+ packages built with -Nix. NixOS is a Linux distribution built on top of nixpkgs. - -## What is a Terraform Module? - -A Terraform Module refers to a self-contained package of Terraform -configurations that are managed as a group. This repo contains a collection of -Terraform Modules which can be composed together to create useful -infrastructure patterns. - -## Terraform + Nix vs NixOps - -NixOps is a great tool for personal deployments. It handles a lot of things -like cloud resource creation, machine NixOS bootstrapping and deployment. - -The difficulty is when the cloud resources are not supported by NixOps. It -takes a lot of work to map all the cloud APIs. Compared to NixOps, Terraform -has become an industry standard and has thousands of people contributing new -cloud API mapping all the time. - -Another issue is when sharing the configuration as code with multiple -developers. Both NixOps and Terraform maintain a state file of "known applied" -configuration. Unlike NixOps, Terraform provides facilities to sync and lock -the state file so it's available by other users. - -The approach here is to use Terraform to create all the cloud resources. By -using the `google_image_nixos_custom` module it's possible to pre-build images in -auto-scaling scenarios. Or use a push model similar to NixOps with the generic -`deploy_nixos` module. - -So overall Terraform + Nix is more flexible and scales better. But it's also -more cumbersome to use as it requires to learn two languages instead of one -and the integration between both is also a bit clunky. - -## Terraform Modules - -The list of modules provided by this project: - -* [deploy_nixos](deploy_nixos#readme) - deploy NixOS onto running NixOS - machines -* [google_image_nixos](google_image_nixos#readme) - setup an official GCE - image into a Google Cloud Project. -* [google_image_nixos_custom](google_image_nixos_custom#readme) - build and - deploy a custom GCE image into a Google Cloud Project - -## Using these modules from your terraform configuration - -Terraform supports importing [modules](https://www.terraform.io/docs/configuration/modules.html) directly [from a GitHub repository](https://www.terraform.io/docs/modules/sources.html#github). - -For example, to use the [`deploy_nixos`](deploy_nixos#readme) module: - -``` -module "deploy_nixos" { - source = "github.com/tweag/terraform-nixos//deploy_nixos?ref=ced68729b6a0382dda02401c8f663c9b29c29368" - - … module-specific fields … -} -``` - -Beware the double `//`, which separates the github repository url from the -subdirectory that contains the module. `?ref=` specifies a specific git ref -of the repository, in this case the commit `ced687…`. - -## Examples - -To better understand how these modules can be used together, look into the -[./examples](examples) folder. - -## Related projects - -* [terraform-provider-nix](https://github.com/andrewchambers/terraform-provider-nix) - -## Future - -* Support other cloud providers. -* Support nixos-infect bootstrapping method. - -Contributions are welcome! - -## Thanks - -Thanks to [Digital Asset][digital-asset] for generously sponsoring this work! - -Thanks to [Tweag][tweag] for enabling this work and the continuous support! - -## License - -This code is released under the Apache 2.0 License. Please see -[LICENSE](LICENSE) for more details. - -Copyright © 2018 Tweag I/O. - - -[digital-asset]: https://www.digitalasset.com/ -[nix]: https://nixos.org/nix/ -[terraform]: https://www.terraform.io -[tweag]: https://www.tweag.io/ diff --git a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/README.md b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/README.md deleted file mode 100644 index b36938de..00000000 --- a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# AWS Collection of NixOS AMIs - -This terraform module provides links to official NixOS AMIs on AWS. The AMIs are -released by the NixOS project. - -Since image names are unique, only one instance per version of the module is -supported. - -## Example - - provider "aws" { - region = "eu-west-1" - } - - module "nixos_image_1903" { - source = "path/to/aws_image_nixos" - release = "19.03" - } - - resource "aws_instance" "example" { - ami = module.nixos_image_1903.ami - instance_type = "t2.micro" - - ... - } - -## New NixOS releases - -Run the `./update-url-map` script to fetch new image releases. - - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|:----:|:-----:|:-----:| -| region | The region to use. If not provided, current provider's region will be used. | string | `` | no | -| release | The NixOS version to use. For example, 18.09 | string | `latest` | no | -| type | The type of the AMI to use -- hvm-ebs, pv-ebs, or pv-s3. | string | `hvm-ebs` | no | -| url\_map | A map of release series to actual releases | map | `` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| ami | NixOS AMI on AWS | - diff --git a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/main.tf b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/main.tf deleted file mode 100644 index dace86dc..00000000 --- a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/main.tf +++ /dev/null @@ -1,34 +0,0 @@ -variable "release" { - type = string - default = "latest" - description = "The NixOS version to use. For example, 18.09" -} - -variable "region" { - type = string - default = "" - description = "The region to use. If not provided, current provider's region will be used." -} - -variable "type" { - type = string - default = "hvm-ebs" - description = "The type of the AMI to use -- hvm-ebs, pv-ebs, or pv-s3." -} - -# --- - -data "aws_region" "current" {} - -locals { - key = "${var.release}.${coalesce(var.region, data.aws_region.current.name)}.${var.type}" - ami = var.url_map[local.key] -} - -# --- - -output "ami" { - description = "NixOS AMI on AWS" - value = local.ami -} - diff --git a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/update-url-map b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/update-url-map deleted file mode 100755 index 3a2ce4cc..00000000 --- a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/update-url-map +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env nix-shell -#!nix-shell -p python3 -i python -# vim: ft=python -# -# Run this script to update the list of EC2 images -# -import json -import io -from subprocess import check_output -from textwrap import dedent -from os import putenv - -putenv('NIX_PATH', 'nixpkgs=channel:nixpkgs-unstable') - -def render_tf(): - nix_eval = check_output(['nix-instantiate', '--json', '--strict', '--eval', './url_map.nix']) - url_map = json.loads(nix_eval) - - out = io.StringIO() - out.write(dedent("""\ - # DON'T EDIT, run '%s' instead - variable "url_map" { - type = map(string) - - default = { - """ % __file__)) - - for version, regions in url_map.items(): - for region, kinds in regions.items(): - for kind, ami in kinds.items(): - out.write(' "%s.%s.%s" = "%s"\n' % (version, region, kind, ami)) - - out.write(dedent("""\ - } - - description = "A map of release series to actual releases" - } - """)) - - return out.getvalue() - -url_map_tf = render_tf() - -with open("url_map.tf", "w") as f: - f.write(url_map_tf) - -print(url_map_tf) - -# Local Variables: -# mode: Python -# End: diff --git a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.nix b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.nix deleted file mode 100644 index 73b0b73e..00000000 --- a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.nix +++ /dev/null @@ -1,2 +0,0 @@ -# Indirect link to where the image map is stored -import diff --git a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.tf b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.tf deleted file mode 100644 index 3a546a1b..00000000 --- a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/url_map.tf +++ /dev/null @@ -1,353 +0,0 @@ -# DON'T EDIT, run './update-url-map' instead -variable "url_map" { - type = map(string) - - default = { - "14.04.ap-northeast-1.hvm-ebs" = "ami-71c6f470" - "14.04.ap-northeast-1.pv-ebs" = "ami-4dcbf84c" - "14.04.ap-northeast-1.pv-s3" = "ami-8fc4f68e" - "14.04.ap-southeast-1.hvm-ebs" = "ami-da280888" - "14.04.ap-southeast-1.pv-ebs" = "ami-7a9dbc28" - "14.04.ap-southeast-1.pv-s3" = "ami-c4290996" - "14.04.ap-southeast-2.hvm-ebs" = "ami-ab523e91" - "14.04.ap-southeast-2.pv-ebs" = "ami-6769055d" - "14.04.ap-southeast-2.pv-s3" = "ami-15533f2f" - "14.04.eu-central-1.hvm-ebs" = "ami-ba0234a7" - "14.04.eu-west-1.hvm-ebs" = "ami-96cb63e1" - "14.04.eu-west-1.pv-ebs" = "ami-b48c25c3" - "14.04.eu-west-1.pv-s3" = "ami-06cd6571" - "14.04.sa-east-1.hvm-ebs" = "ami-01b90e1c" - "14.04.sa-east-1.pv-ebs" = "ami-69e35474" - "14.04.sa-east-1.pv-s3" = "ami-61b90e7c" - "14.04.us-east-1.hvm-ebs" = "ami-58ba3a30" - "14.04.us-east-1.pv-ebs" = "ami-9e0583f6" - "14.04.us-east-1.pv-s3" = "ami-9cbe3ef4" - "14.04.us-west-1.hvm-ebs" = "ami-0bc3d74e" - "14.04.us-west-1.pv-ebs" = "ami-8b1703ce" - "14.04.us-west-1.pv-s3" = "ami-27ccd862" - "14.04.us-west-2.hvm-ebs" = "ami-3bf1bf0b" - "14.04.us-west-2.pv-ebs" = "ami-259bd515" - "14.04.us-west-2.pv-s3" = "ami-07094037" - "14.12.ap-northeast-1.hvm-ebs" = "ami-24435f25" - "14.12.ap-northeast-1.pv-ebs" = "ami-b0425eb1" - "14.12.ap-northeast-1.pv-s3" = "ami-fed3c6ff" - "14.12.ap-southeast-1.hvm-ebs" = "ami-6c765d3e" - "14.12.ap-southeast-1.pv-ebs" = "ami-6a765d38" - "14.12.ap-southeast-1.pv-s3" = "ami-d1bf9183" - "14.12.ap-southeast-2.hvm-ebs" = "ami-af86f395" - "14.12.ap-southeast-2.pv-ebs" = "ami-b386f389" - "14.12.ap-southeast-2.pv-s3" = "ami-69c5ae53" - "14.12.eu-central-1.hvm-ebs" = "ami-4a497a57" - "14.12.eu-central-1.pv-ebs" = "ami-4c497a51" - "14.12.eu-central-1.pv-s3" = "ami-60f2c27d" - "14.12.eu-west-1.hvm-ebs" = "ami-d126a5a6" - "14.12.eu-west-1.pv-ebs" = "ami-0126a576" - "14.12.eu-west-1.pv-s3" = "ami-deda5fa9" - "14.12.sa-east-1.hvm-ebs" = "ami-2d239e30" - "14.12.sa-east-1.pv-ebs" = "ami-35239e28" - "14.12.sa-east-1.pv-s3" = "ami-81e3519c" - "14.12.us-east-1.hvm-ebs" = "ami-0c463a64" - "14.12.us-east-1.pv-ebs" = "ami-ac473bc4" - "14.12.us-east-1.pv-s3" = "ami-00e18a68" - "14.12.us-west-1.hvm-ebs" = "ami-ca534a8f" - "14.12.us-west-1.pv-ebs" = "ami-3e534a7b" - "14.12.us-west-1.pv-s3" = "ami-2905196c" - "14.12.us-west-2.hvm-ebs" = "ami-fb9dc3cb" - "14.12.us-west-2.pv-ebs" = "ami-899dc3b9" - "14.12.us-west-2.pv-s3" = "ami-cb7f2dfb" - "15.09.ap-northeast-1.hvm-ebs" = "ami-58cac236" - "15.09.ap-northeast-1.hvm-s3" = "ami-39c8c057" - "15.09.ap-northeast-1.pv-ebs" = "ami-5ac9c134" - "15.09.ap-northeast-1.pv-s3" = "ami-03cec66d" - "15.09.ap-southeast-1.hvm-ebs" = "ami-2fc2094c" - "15.09.ap-southeast-1.hvm-s3" = "ami-9ec308fd" - "15.09.ap-southeast-1.pv-ebs" = "ami-95c00bf6" - "15.09.ap-southeast-1.pv-s3" = "ami-bfc00bdc" - "15.09.ap-southeast-2.hvm-ebs" = "ami-996c4cfa" - "15.09.ap-southeast-2.hvm-s3" = "ami-3f6e4e5c" - "15.09.ap-southeast-2.pv-ebs" = "ami-066d4d65" - "15.09.ap-southeast-2.pv-s3" = "ami-cc6e4eaf" - "15.09.eu-central-1.hvm-ebs" = "ami-3f8c6b50" - "15.09.eu-central-1.hvm-s3" = "ami-5b836434" - "15.09.eu-central-1.pv-ebs" = "ami-118c6b7e" - "15.09.eu-central-1.pv-s3" = "ami-2c977043" - "15.09.eu-west-1.hvm-ebs" = "ami-9cf04aef" - "15.09.eu-west-1.hvm-s3" = "ami-2bea5058" - "15.09.eu-west-1.pv-ebs" = "ami-c9e852ba" - "15.09.eu-west-1.pv-s3" = "ami-c6f64cb5" - "15.09.sa-east-1.hvm-ebs" = "ami-6e52df02" - "15.09.sa-east-1.hvm-s3" = "ami-1852df74" - "15.09.sa-east-1.pv-ebs" = "ami-4368e52f" - "15.09.sa-east-1.pv-s3" = "ami-f15ad79d" - "15.09.us-east-1.hvm-ebs" = "ami-84a6a0ee" - "15.09.us-east-1.hvm-s3" = "ami-06a7a16c" - "15.09.us-east-1.pv-ebs" = "ami-a4a1a7ce" - "15.09.us-east-1.pv-s3" = "ami-5ba8ae31" - "15.09.us-west-1.hvm-ebs" = "ami-22c8bb42" - "15.09.us-west-1.hvm-s3" = "ami-a2ccbfc2" - "15.09.us-west-1.pv-ebs" = "ami-10cebd70" - "15.09.us-west-1.pv-s3" = "ami-fa30429a" - "15.09.us-west-2.hvm-ebs" = "ami-ce57b9ae" - "15.09.us-west-2.hvm-s3" = "ami-2956b849" - "15.09.us-west-2.pv-ebs" = "ami-005fb160" - "15.09.us-west-2.pv-s3" = "ami-cd55bbad" - "16.03.ap-northeast-1.hvm-ebs" = "ami-40619d21" - "16.03.ap-northeast-1.hvm-s3" = "ami-ce629eaf" - "16.03.ap-northeast-1.pv-ebs" = "ami-ef639f8e" - "16.03.ap-northeast-1.pv-s3" = "ami-a1609cc0" - "16.03.ap-northeast-2.hvm-ebs" = "ami-deca00b0" - "16.03.ap-northeast-2.hvm-s3" = "ami-a3b77dcd" - "16.03.ap-northeast-2.pv-ebs" = "ami-7bcb0115" - "16.03.ap-northeast-2.pv-s3" = "ami-a2b77dcc" - "16.03.ap-south-1.hvm-ebs" = "ami-0dff9562" - "16.03.ap-south-1.hvm-s3" = "ami-13f69c7c" - "16.03.ap-south-1.pv-ebs" = "ami-0ef39961" - "16.03.ap-south-1.pv-s3" = "ami-e0c8a28f" - "16.03.ap-southeast-1.hvm-ebs" = "ami-5e964a3d" - "16.03.ap-southeast-1.hvm-s3" = "ami-4d964a2e" - "16.03.ap-southeast-1.pv-ebs" = "ami-ec9b478f" - "16.03.ap-southeast-1.pv-s3" = "ami-999b47fa" - "16.03.ap-southeast-2.hvm-ebs" = "ami-9f7359fc" - "16.03.ap-southeast-2.hvm-s3" = "ami-987359fb" - "16.03.ap-southeast-2.pv-ebs" = "ami-a2705ac1" - "16.03.ap-southeast-2.pv-s3" = "ami-a3705ac0" - "16.03.eu-central-1.hvm-ebs" = "ami-17a45178" - "16.03.eu-central-1.hvm-s3" = "ami-f9a55096" - "16.03.eu-central-1.pv-ebs" = "ami-c8a550a7" - "16.03.eu-central-1.pv-s3" = "ami-6ea45101" - "16.03.eu-west-1.hvm-ebs" = "ami-b5b3d5c6" - "16.03.eu-west-1.hvm-s3" = "ami-c986e0ba" - "16.03.eu-west-1.pv-ebs" = "ami-b083e5c3" - "16.03.eu-west-1.pv-s3" = "ami-3c83e54f" - "16.03.sa-east-1.hvm-ebs" = "ami-f6eb7f9a" - "16.03.sa-east-1.hvm-s3" = "ami-93e773ff" - "16.03.sa-east-1.pv-ebs" = "ami-cbb82ca7" - "16.03.sa-east-1.pv-s3" = "ami-abb82cc7" - "16.03.us-east-1.hvm-ebs" = "ami-c123a3d6" - "16.03.us-east-1.hvm-s3" = "ami-bc25a5ab" - "16.03.us-east-1.pv-ebs" = "ami-bd25a5aa" - "16.03.us-east-1.pv-s3" = "ami-a325a5b4" - "16.03.us-west-1.hvm-ebs" = "ami-748bcd14" - "16.03.us-west-1.hvm-s3" = "ami-a68dcbc6" - "16.03.us-west-1.pv-ebs" = "ami-048acc64" - "16.03.us-west-1.pv-s3" = "ami-208dcb40" - "16.03.us-west-2.hvm-ebs" = "ami-8263a0e2" - "16.03.us-west-2.hvm-s3" = "ami-925c9ff2" - "16.03.us-west-2.pv-ebs" = "ami-5e61a23e" - "16.03.us-west-2.pv-s3" = "ami-734c8f13" - "16.09.ap-northeast-1.hvm-ebs" = "ami-68453b0f" - "16.09.ap-northeast-1.hvm-s3" = "ami-f9bec09e" - "16.09.ap-northeast-1.pv-ebs" = "ami-254a3442" - "16.09.ap-northeast-1.pv-s3" = "ami-ef473988" - "16.09.ap-northeast-2.hvm-ebs" = "ami-18ae7f76" - "16.09.ap-northeast-2.hvm-s3" = "ami-9eac7df0" - "16.09.ap-northeast-2.pv-ebs" = "ami-57aa7b39" - "16.09.ap-northeast-2.pv-s3" = "ami-5cae7f32" - "16.09.ap-south-1.hvm-ebs" = "ami-b3f98fdc" - "16.09.ap-south-1.hvm-s3" = "ami-98e690f7" - "16.09.ap-south-1.pv-ebs" = "ami-aef98fc1" - "16.09.ap-south-1.pv-s3" = "ami-caf88ea5" - "16.09.ap-southeast-1.hvm-ebs" = "ami-80fb51e3" - "16.09.ap-southeast-1.hvm-s3" = "ami-2df3594e" - "16.09.ap-southeast-1.pv-ebs" = "ami-37f05a54" - "16.09.ap-southeast-1.pv-s3" = "ami-27f35944" - "16.09.ap-southeast-2.hvm-ebs" = "ami-57ece834" - "16.09.ap-southeast-2.hvm-s3" = "ami-87f4f0e4" - "16.09.ap-southeast-2.pv-ebs" = "ami-d8ede9bb" - "16.09.ap-southeast-2.pv-s3" = "ami-a6ebefc5" - "16.09.ca-central-1.hvm-ebs" = "ami-9f863bfb" - "16.09.ca-central-1.hvm-s3" = "ami-ea85388e" - "16.09.ca-central-1.pv-ebs" = "ami-ce8a37aa" - "16.09.ca-central-1.pv-s3" = "ami-448a3720" - "16.09.eu-central-1.hvm-ebs" = "ami-1b884774" - "16.09.eu-central-1.hvm-s3" = "ami-b08c43df" - "16.09.eu-central-1.pv-ebs" = "ami-888946e7" - "16.09.eu-central-1.pv-s3" = "ami-06874869" - "16.09.eu-west-1.hvm-ebs" = "ami-1ed3e76d" - "16.09.eu-west-1.hvm-s3" = "ami-73d1e500" - "16.09.eu-west-1.pv-ebs" = "ami-44c0f437" - "16.09.eu-west-1.pv-s3" = "ami-f3d8ec80" - "16.09.eu-west-2.hvm-ebs" = "ami-2c9c9648" - "16.09.eu-west-2.hvm-s3" = "ami-6b9e940f" - "16.09.eu-west-2.pv-ebs" = "ami-f1999395" - "16.09.eu-west-2.pv-s3" = "ami-bb9f95df" - "16.09.sa-east-1.hvm-ebs" = "ami-a11882cd" - "16.09.sa-east-1.hvm-s3" = "ami-7726bc1b" - "16.09.sa-east-1.pv-ebs" = "ami-9725bffb" - "16.09.sa-east-1.pv-s3" = "ami-b027bddc" - "16.09.us-east-1.hvm-ebs" = "ami-854ca593" - "16.09.us-east-1.hvm-s3" = "ami-2241a834" - "16.09.us-east-1.pv-ebs" = "ami-a441a8b2" - "16.09.us-east-1.pv-s3" = "ami-e841a8fe" - "16.09.us-east-2.hvm-ebs" = "ami-3f41645a" - "16.09.us-east-2.hvm-s3" = "ami-804065e5" - "16.09.us-east-2.pv-ebs" = "ami-f1466394" - "16.09.us-east-2.pv-s3" = "ami-05426760" - "16.09.us-west-1.hvm-ebs" = "ami-c2efbca2" - "16.09.us-west-1.hvm-s3" = "ami-d71042b7" - "16.09.us-west-1.pv-ebs" = "ami-04e8bb64" - "16.09.us-west-1.pv-s3" = "ami-31e9ba51" - "16.09.us-west-2.hvm-ebs" = "ami-6449f504" - "16.09.us-west-2.hvm-s3" = "ami-344af654" - "16.09.us-west-2.pv-ebs" = "ami-6d4af60d" - "16.09.us-west-2.pv-s3" = "ami-de48f4be" - "17.03.ap-northeast-1.hvm-ebs" = "ami-dbd0f7bc" - "17.03.ap-northeast-1.hvm-s3" = "ami-7cdff81b" - "17.03.ap-northeast-2.hvm-ebs" = "ami-c59a48ab" - "17.03.ap-northeast-2.hvm-s3" = "ami-0b944665" - "17.03.ap-south-1.hvm-ebs" = "ami-4f413220" - "17.03.ap-south-1.hvm-s3" = "ami-864033e9" - "17.03.ap-southeast-1.hvm-ebs" = "ami-e08c3383" - "17.03.ap-southeast-1.hvm-s3" = "ami-c28f30a1" - "17.03.ap-southeast-2.hvm-ebs" = "ami-fca9a69f" - "17.03.ap-southeast-2.hvm-s3" = "ami-3daaa55e" - "17.03.ca-central-1.hvm-ebs" = "ami-9b00bdff" - "17.03.ca-central-1.hvm-s3" = "ami-e800bd8c" - "17.03.eu-central-1.hvm-ebs" = "ami-5450803b" - "17.03.eu-central-1.hvm-s3" = "ami-6e2efe01" - "17.03.eu-west-1.hvm-ebs" = "ami-10754c76" - "17.03.eu-west-1.hvm-s3" = "ami-11734a77" - "17.03.eu-west-2.hvm-ebs" = "ami-ff1d099b" - "17.03.eu-west-2.hvm-s3" = "ami-fe1d099a" - "17.03.sa-east-1.hvm-ebs" = "ami-d95d3eb5" - "17.03.sa-east-1.hvm-s3" = "ami-fca2c190" - "17.03.us-east-1.hvm-ebs" = "ami-0940c61f" - "17.03.us-east-1.hvm-s3" = "ami-674fc971" - "17.03.us-east-2.hvm-ebs" = "ami-afc2e6ca" - "17.03.us-east-2.hvm-s3" = "ami-a1cde9c4" - "17.03.us-west-1.hvm-ebs" = "ami-587b2138" - "17.03.us-west-1.hvm-s3" = "ami-70411b10" - "17.03.us-west-2.hvm-ebs" = "ami-a93daac9" - "17.03.us-west-2.hvm-s3" = "ami-5139ae31" - "17.09.ap-northeast-1.hvm-ebs" = "ami-89b921ef" - "17.09.ap-northeast-2.hvm-ebs" = "ami-179b3b79" - "17.09.ap-south-1.hvm-ebs" = "ami-4e376021" - "17.09.ap-southeast-1.hvm-ebs" = "ami-84bccff8" - "17.09.ap-southeast-2.hvm-ebs" = "ami-0dc5386f" - "17.09.ca-central-1.hvm-ebs" = "ami-ca8207ae" - "17.09.eu-central-1.hvm-ebs" = "ami-266cfe49" - "17.09.eu-west-1.hvm-ebs" = "ami-a30192da" - "17.09.eu-west-2.hvm-ebs" = "ami-295a414d" - "17.09.eu-west-3.hvm-ebs" = "ami-8c0eb9f1" - "17.09.sa-east-1.hvm-ebs" = "ami-4762202b" - "17.09.us-east-1.hvm-ebs" = "ami-40bee63a" - "17.09.us-east-2.hvm-ebs" = "ami-9d84aff8" - "17.09.us-west-1.hvm-ebs" = "ami-d14142b1" - "17.09.us-west-2.hvm-ebs" = "ami-3eb40346" - "18.03.ap-northeast-1.hvm-ebs" = "ami-456511a8" - "18.03.ap-northeast-2.hvm-ebs" = "ami-3366d15d" - "18.03.ap-south-1.hvm-ebs" = "ami-6a390b05" - "18.03.ap-southeast-1.hvm-ebs" = "ami-aa0b4d40" - "18.03.ap-southeast-2.hvm-ebs" = "ami-d0f254b2" - "18.03.ca-central-1.hvm-ebs" = "ami-aca72ac8" - "18.03.eu-central-1.hvm-ebs" = "ami-09faf9e2" - "18.03.eu-west-1.hvm-ebs" = "ami-065c46ec" - "18.03.eu-west-2.hvm-ebs" = "ami-64f31903" - "18.03.eu-west-3.hvm-ebs" = "ami-5a8d3d27" - "18.03.sa-east-1.hvm-ebs" = "ami-163e1f7a" - "18.03.us-east-1.hvm-ebs" = "ami-8b3538f4" - "18.03.us-east-2.hvm-ebs" = "ami-150b3170" - "18.03.us-west-1.hvm-ebs" = "ami-ce06ebad" - "18.03.us-west-2.hvm-ebs" = "ami-586c3520" - "18.09.ap-northeast-1.hvm-ebs" = "ami-0cdba8e998f076547" - "18.09.ap-northeast-2.hvm-ebs" = "ami-0400a698e6a9f4a15" - "18.09.ap-south-1.hvm-ebs" = "ami-0880a678d3f555313" - "18.09.ap-southeast-1.hvm-ebs" = "ami-0892c7e24ebf2194f" - "18.09.ap-southeast-2.hvm-ebs" = "ami-010730f36424b0a2c" - "18.09.ca-central-1.hvm-ebs" = "ami-04f66113f76198f6c" - "18.09.eu-central-1.hvm-ebs" = "ami-07c9b884e679df4f8" - "18.09.eu-west-1.hvm-ebs" = "ami-0f412186fb8a0ec97" - "18.09.eu-west-2.hvm-ebs" = "ami-0dada3805ce43c55e" - "18.09.eu-west-3.hvm-ebs" = "ami-074df85565f2e02e2" - "18.09.sa-east-1.hvm-ebs" = "ami-0e4a8a47fd6db6112" - "18.09.us-east-1.hvm-ebs" = "ami-009c9c3f1af480ff3" - "18.09.us-east-2.hvm-ebs" = "ami-08199961085ea8bc6" - "18.09.us-west-1.hvm-ebs" = "ami-07aa7f56d612ddd38" - "18.09.us-west-2.hvm-ebs" = "ami-01c84b7c368ac24d1" - "19.03.ap-northeast-1.hvm-ebs" = "ami-00db62688900456a4" - "19.03.ap-northeast-2.hvm-ebs" = "ami-0485cdd1a5fdd2117" - "19.03.ap-south-1.hvm-ebs" = "ami-0303deb1b5890f878" - "19.03.ap-southeast-1.hvm-ebs" = "ami-0cff66114c652c262" - "19.03.ap-southeast-2.hvm-ebs" = "ami-054c73a7f8d773ea9" - "19.03.ca-central-1.hvm-ebs" = "ami-03f9fd0ef2e035ede" - "19.03.eu-central-1.hvm-ebs" = "ami-0022b8ea9efde5de4" - "19.03.eu-west-1.hvm-ebs" = "ami-0fe40176548ff0940" - "19.03.eu-west-2.hvm-ebs" = "ami-03a40fd3a02fe95ba" - "19.03.eu-west-3.hvm-ebs" = "ami-0436f9da0f20a638e" - "19.03.sa-east-1.hvm-ebs" = "ami-0c6a43c6e0ad1f4e2" - "19.03.us-east-1.hvm-ebs" = "ami-0efc58fb70ae9a217" - "19.03.us-east-2.hvm-ebs" = "ami-0abf711b1b34da1af" - "19.03.us-west-1.hvm-ebs" = "ami-07d126e8838c40ec5" - "19.03.us-west-2.hvm-ebs" = "ami-03f8a737546e47fb0" - "19.09.ap-east-1.hvm-ebs" = "ami-055b2348db2827ff1" - "19.09.ap-northeast-1.hvm-ebs" = "ami-02a62555ca182fb5b" - "19.09.ap-northeast-2.hvm-ebs" = "ami-0219dde0e6b7b7b93" - "19.09.ap-south-1.hvm-ebs" = "ami-066f7f2a895c821a1" - "19.09.ap-southeast-1.hvm-ebs" = "ami-0f71ae5d4b0b78d95" - "19.09.ap-southeast-2.hvm-ebs" = "ami-057bbf2b4bd62d210" - "19.09.ca-central-1.hvm-ebs" = "ami-07df50fc76702a36d" - "19.09.eu-central-1.hvm-ebs" = "ami-015f8efc2be419b79" - "19.09.eu-north-1.hvm-ebs" = "ami-07fc0a32d885e01ed" - "19.09.eu-west-1.hvm-ebs" = "ami-071082f0fa035374f" - "19.09.eu-west-2.hvm-ebs" = "ami-0d9dc33c54d1dc4c3" - "19.09.eu-west-3.hvm-ebs" = "ami-09566799591d1bfed" - "19.09.sa-east-1.hvm-ebs" = "ami-018aab68377227e06" - "19.09.us-east-1.hvm-ebs" = "ami-03330d8b51287412f" - "19.09.us-east-2.hvm-ebs" = "ami-0518b4c84972e967f" - "19.09.us-west-1.hvm-ebs" = "ami-06ad07e61a353b4a6" - "19.09.us-west-2.hvm-ebs" = "ami-0e31e30925cf3ce4e" - "20.03.ap-east-1.hvm-ebs" = "ami-0d18fdd309cdefa86" - "20.03.ap-northeast-1.hvm-ebs" = "ami-093d9cc49c191eb6c" - "20.03.ap-northeast-2.hvm-ebs" = "ami-0087df91a7b6ebd45" - "20.03.ap-south-1.hvm-ebs" = "ami-0a1a6b569af04af9d" - "20.03.ap-southeast-1.hvm-ebs" = "ami-0dbf353e168d155f7" - "20.03.ap-southeast-2.hvm-ebs" = "ami-04c0f3a75f63daddd" - "20.03.ca-central-1.hvm-ebs" = "ami-02365684a173255c7" - "20.03.eu-central-1.hvm-ebs" = "ami-0a1a94722dcbff94c" - "20.03.eu-north-1.hvm-ebs" = "ami-02699abfacbb6464b" - "20.03.eu-west-1.hvm-ebs" = "ami-02c34db5766cc7013" - "20.03.eu-west-2.hvm-ebs" = "ami-0e32bd8c7853883f1" - "20.03.eu-west-3.hvm-ebs" = "ami-061edb1356c1d69fd" - "20.03.sa-east-1.hvm-ebs" = "ami-09859378158ae971d" - "20.03.us-east-1.hvm-ebs" = "ami-0c5e7760748b74e85" - "20.03.us-east-2.hvm-ebs" = "ami-030296bb256764655" - "20.03.us-west-1.hvm-ebs" = "ami-050be818e0266b741" - "20.03.us-west-2.hvm-ebs" = "ami-06562f78dca68eda2" - "20.09.ap-east-1.hvm-ebs" = "ami-071f49713f86ea965" - "20.09.ap-northeast-1.hvm-ebs" = "ami-0beb18d632cf64e5a" - "20.09.ap-northeast-2.hvm-ebs" = "ami-0dd0316af578862db" - "20.09.ap-south-1.hvm-ebs" = "ami-008d15ced81c88aed" - "20.09.ap-southeast-1.hvm-ebs" = "ami-0db0304e23c535b2a" - "20.09.ap-southeast-2.hvm-ebs" = "ami-045983c4db7e36447" - "20.09.ca-central-1.hvm-ebs" = "ami-06d5ee429f153f856" - "20.09.eu-central-1.hvm-ebs" = "ami-01d4a0c2248cbfe38" - "20.09.eu-north-1.hvm-ebs" = "ami-0003f54dd99d68e0f" - "20.09.eu-west-1.hvm-ebs" = "ami-01a79d5ce435f4db3" - "20.09.eu-west-2.hvm-ebs" = "ami-0cbe14f32904e6331" - "20.09.eu-west-3.hvm-ebs" = "ami-07f493412d6213de6" - "20.09.sa-east-1.hvm-ebs" = "ami-05ded1ae35209b5a8" - "20.09.us-east-1.hvm-ebs" = "ami-068a62d478710462d" - "20.09.us-east-2.hvm-ebs" = "ami-01ac677ff61399caa" - "20.09.us-west-1.hvm-ebs" = "ami-04befdb203b4b17f6" - "20.09.us-west-2.hvm-ebs" = "ami-0fb7bd4a43261c6b2" - "latest.ap-east-1.hvm-ebs" = "ami-071f49713f86ea965" - "latest.ap-northeast-1.hvm-ebs" = "ami-0beb18d632cf64e5a" - "latest.ap-northeast-2.hvm-ebs" = "ami-0dd0316af578862db" - "latest.ap-south-1.hvm-ebs" = "ami-008d15ced81c88aed" - "latest.ap-southeast-1.hvm-ebs" = "ami-0db0304e23c535b2a" - "latest.ap-southeast-2.hvm-ebs" = "ami-045983c4db7e36447" - "latest.ca-central-1.hvm-ebs" = "ami-06d5ee429f153f856" - "latest.eu-central-1.hvm-ebs" = "ami-01d4a0c2248cbfe38" - "latest.eu-north-1.hvm-ebs" = "ami-0003f54dd99d68e0f" - "latest.eu-west-1.hvm-ebs" = "ami-01a79d5ce435f4db3" - "latest.eu-west-2.hvm-ebs" = "ami-0cbe14f32904e6331" - "latest.eu-west-3.hvm-ebs" = "ami-07f493412d6213de6" - "latest.sa-east-1.hvm-ebs" = "ami-05ded1ae35209b5a8" - "latest.us-east-1.hvm-ebs" = "ami-068a62d478710462d" - "latest.us-east-2.hvm-ebs" = "ami-01ac677ff61399caa" - "latest.us-west-1.hvm-ebs" = "ami-04befdb203b4b17f6" - "latest.us-west-2.hvm-ebs" = "ami-0fb7bd4a43261c6b2" - } - - description = "A map of release series to actual releases" -} diff --git a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/versions.tf b/launch/.terraform/modules/peertube.deploy/aws_image_nixos/versions.tf deleted file mode 100644 index ac97c6ac..00000000 --- a/launch/.terraform/modules/peertube.deploy/aws_image_nixos/versions.tf +++ /dev/null @@ -1,4 +0,0 @@ - -terraform { - required_version = ">= 0.12" -} diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/README.md b/launch/.terraform/modules/peertube.deploy/deploy_nixos/README.md deleted file mode 100644 index a91f7af5..00000000 --- a/launch/.terraform/modules/peertube.deploy/deploy_nixos/README.md +++ /dev/null @@ -1,129 +0,0 @@ -# deploy_nixos - -A Terraform module that knows how to deploy NixOS onto a target host. - -This allow to describe an infrastructure as code with Terraform and delegate -the machine configuration with NixOS. All directed by Terraform. - -The advantage of this method is that if any of the Nix code changes, the -difference will be detected on the next "terraform plan". - -## Usage - -Either pass a "config" which is a dynamic nixos configuration and a -"config_pwd", or a "nixos_config", a path to a nixos configuration.nix file. -If you have defined your NixOs configuration in a Flake, use "nixos_config" -to specify the name of the attribue and set "flake" to true. - -### Secret handling - -Keys can be passed to the "keys" attribute. Each key will be installed under -`/var/keys/${key}` with the content as the value. - -For services to access one of the keys, add the service user to the "keys" -group. - -The target machine needs `jq` installed prior to the deployment (as part of -the base image). If `jq` is not found it will try to use a version from -``. - -### Disabling sandboxing - -Unfortunately some time it's required to disable the nix sandboxing. To do so, -add `["--option", "sandbox", "false"]` to the "extra_build_args" parameter. - -If that doesn't work, make sure that your user is part of the nix -"trusted-users" list. - -### Non-root `target_user` - -It is possible to connect to the target host using a user that is not `root` -under certain conditions: - -* sudo needs to be installed on the machine -* the user needs password-less sudo access on the machine - -This would typically be provisioned in the base image. - -### Binary cache configuration - -One thing that might be surprising is that the binary caches (aka -substituters) are taken from the machine configuration. This implies that the -user Nix configuration will be ignored in that regard. - -## Dependencies - -* `bash` 4.0+ -* `nix` -* `openssh` -* `readlink` with `-f` (coreutils or busybox) - -## Known limitations - -The deployment machine requires Nix with access to a remote builder with the -same system as the target machine. - -Because Nix code is being evaluated at "terraform plan" time, deploying a lot -of machine in the same target will require a lot of RAM. - -All the secrets share the same "keys" group. - -When deploying as non-root, it assumes that passwordless `sudo` is available. - -The target host must already have NixOS installed. - -### config including computed values - -The module doesn't work when `` values from other resources are -interpolated with the "config" attribute. Because it happens at evaluation -time, terraform will render an empty drvPath. - -see also: -* https://github.com/hashicorp/terraform/issues/16380 -* https://github.com/hashicorp/terraform/issues/16762 -* https://github.com/hashicorp/terraform/issues/17034 - - -## Requirements - -| Name | Version | -|------|---------| -| terraform | >= 0.12 | - -## Providers - -| Name | Version | -|------|---------| -| external | n/a | -| null | n/a | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| NIX\_PATH | Allow to pass custom NIX\_PATH | `string` | `""` | no | -| build\_on\_target | Avoid building on the deployer. Must be true or false. Has no effect when deploying from an incompatible system. Unlike remote builders, this does not require the deploying user to be trusted by its host. | `string` | `false` | no | -| config | NixOS configuration to be evaluated. This argument is required unless 'nixos\_config' is given | `string` | `""` | no | -| config\_pwd | Directory to evaluate the configuration in. This argument is required if 'config' is given | `string` | `""` | no | -| extra\_build\_args | List of arguments to pass to the nix builder | `list(string)` | `[]` | no | -| extra\_eval\_args | List of arguments to pass to the nix evaluation | `list(string)` | `[]` | no | -| hermetic | Treat the provided nixos configuration as a hermetic expression and do not evaluate using the ambient system nixpkgs. Useful if you customize eval-modules or use a pinned nixpkgs. | `bool` | false | no | -| flake | Treat the provided nixos_config as the name of the NixOS configuration to use in the flake located in the current directory. Useful if you customize eval-modules or use a pinned nixpkgs. | `bool` | false | no | -| keys | A map of filename to content to upload as secrets in /var/keys | `map(string)` | `{}` | no | -| nixos\_config | Path to a NixOS configuration | `string` | `""` | no | -| ssh\_agent | Whether to use an SSH agent. True if not ssh\_private\_key is passed | `bool` | `null` | no | -| ssh\_private\_key | Content of private key used to connect to the target\_host | `string` | `""` | no | -| ssh\_private\_key\_file | Path to private key used to connect to the target\_host | `string` | `""` | no | -| target\_host | DNS host to deploy to | `string` | n/a | yes | -| target\_port | SSH port used to connect to the target\_host | `number` | `22` | no | -| target\_system | Nix system string | `string` | `"x86_64-linux"` | no | -| target\_user | SSH user used to connect to the target\_host | `string` | `"root"` | no | -| triggers | Triggers for deploy | `map(string)` | `{}` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| id | random ID that changes on every nixos deployment | - - diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/main.tf b/launch/.terraform/modules/peertube.deploy/deploy_nixos/main.tf deleted file mode 100644 index c217ce5c..00000000 --- a/launch/.terraform/modules/peertube.deploy/deploy_nixos/main.tf +++ /dev/null @@ -1,221 +0,0 @@ -variable "target_host" { - type = string - description = "DNS host to deploy to" -} - -variable "target_user" { - type = string - description = "SSH user used to connect to the target_host" - default = "root" -} - -variable "target_port" { - type = number - description = "SSH port used to connect to the target_host" - default = 22 -} - -variable "ssh_private_key" { - type = string - description = "Content of private key used to connect to the target_host" - default = "" -} - -variable "ssh_private_key_file" { - type = string - description = "Path to private key used to connect to the target_host" - default = "" -} - -variable "ssh_agent" { - type = bool - description = "Whether to use an SSH agent. True if not ssh_private_key is passed" - default = null -} - -variable "NIX_PATH" { - type = string - description = "Allow to pass custom NIX_PATH" - default = "" -} - -variable "nixos_config" { - type = string - description = "Path to a NixOS configuration" - default = "" -} - -variable "config" { - type = string - description = "NixOS configuration to be evaluated. This argument is required unless 'nixos_config' is given" - default = "" -} - -variable "config_pwd" { - type = string - description = "Directory to evaluate the configuration in. This argument is required if 'config' is given" - default = "" -} - -variable "extra_eval_args" { - type = list(string) - description = "List of arguments to pass to the nix evaluation" - default = [] -} - -variable "extra_build_args" { - type = list(string) - description = "List of arguments to pass to the nix builder" - default = [] -} - -variable "build_on_target" { - type = string - description = "Avoid building on the deployer. Must be true or false. Has no effect when deploying from an incompatible system. Unlike remote builders, this does not require the deploying user to be trusted by its host." - default = false -} - -variable "triggers" { - type = map(string) - description = "Triggers for deploy" - default = {} -} - -variable "keys" { - type = map(string) - description = "A map of filename to content to upload as secrets in /var/keys" - default = {} -} - -variable "target_system" { - type = string - description = "Nix system string" - default = "x86_64-linux" -} - -variable "hermetic" { - type = bool - description = "Treat the provided nixos configuration as a hermetic expression and do not evaluate using the ambient system nixpkgs. Useful if you customize eval-modules or use a pinned nixpkgs." - default = false -} - -variable "flake" { - type = bool - description = "Treat the provided nixos_config as the NixOS configuration to use in the flake located in the current directory" - default = false -} - -variable "delete_older_than" { - type = string - description = "Can be a list of generation numbers, the special value old to delete all non-current generations, a value such as 30d to delete all generations older than the specified number of days (except for the generation that was active at that point in time), or a value such as +5 to keep the last 5 generations ignoring any newer than current, e.g., if 30 is the current generation +5 will delete generation 25 and all older generations." - default = "+1" -} - -variable "deploy_environment" { - type = map(string) - description = "Extra environment variables to be set during deployment." - default = {} -} - -# -------------------------------------------------------------------------- - -locals { - triggers = { - deploy_nixos_drv = data.external.nixos-instantiate.result["drv_path"] - deploy_nixos_keys = sha256(jsonencode(var.keys)) - } - - extra_build_args = concat([ - "--option", "substituters", data.external.nixos-instantiate.result["substituters"], - "--option", "trusted-public-keys", data.external.nixos-instantiate.result["trusted-public-keys"], - ], - var.extra_build_args, - ) - ssh_private_key_file = var.ssh_private_key_file == "" ? "-" : var.ssh_private_key_file - ssh_private_key = local.ssh_private_key_file == "-" ? var.ssh_private_key : file(local.ssh_private_key_file) - ssh_agent = var.ssh_agent == null ? (local.ssh_private_key != "") : var.ssh_agent - build_on_target = data.external.nixos-instantiate.result["currentSystem"] != var.target_system ? true : tobool(var.build_on_target) -} - -# used to detect changes in the configuration -data "external" "nixos-instantiate" { - program = concat([ - "${path.module}/nixos-instantiate.sh", - var.NIX_PATH == "" ? "-" : var.NIX_PATH, - var.config != "" ? var.config : var.nixos_config, - var.config_pwd == "" ? "." : var.config_pwd, - var.flake, - # end of positional arguments - # start of pass-through arguments - "--argstr", "system", var.target_system, - "--arg", "hermetic", var.hermetic - ], - var.extra_eval_args, - ) -} - -resource "null_resource" "deploy_nixos" { - triggers = merge(var.triggers, local.triggers) - - connection { - type = "ssh" - host = var.target_host - port = var.target_port - user = var.target_user - agent = local.ssh_agent - timeout = "100s" - private_key = local.ssh_private_key == "-" ? "" : local.ssh_private_key - } - - # copy the secret keys to the host - provisioner "file" { - content = jsonencode(var.keys) - destination = "packed-keys.json" - } - - # FIXME: move this to nixos-deploy.sh - provisioner "file" { - source = "${path.module}/unpack-keys.sh" - destination = "unpack-keys.sh" - } - - # FIXME: move this to nixos-deploy.sh - provisioner "file" { - source = "${path.module}/maybe-sudo.sh" - destination = "maybe-sudo.sh" - } - - provisioner "remote-exec" { - inline = [ - "chmod +x unpack-keys.sh maybe-sudo.sh", - "./maybe-sudo.sh ./unpack-keys.sh ./packed-keys.json", - ] - } - - # do the actual deployment - provisioner "local-exec" { - environment = var.deploy_environment - interpreter = concat([ - "${path.module}/nixos-deploy.sh", - data.external.nixos-instantiate.result["drv_path"], - data.external.nixos-instantiate.result["out_path"], - "${var.target_user}@${var.target_host}", - var.target_port, - local.build_on_target, - local.ssh_private_key == "" ? "-" : local.ssh_private_key, - "switch", - var.delete_older_than, - ], - local.extra_build_args - ) - command = "ignoreme" - } -} - -# -------------------------------------------------------------------------- - -output "id" { - description = "random ID that changes on every nixos deployment" - value = null_resource.deploy_nixos.id -} - diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/maybe-sudo.sh b/launch/.terraform/modules/peertube.deploy/deploy_nixos/maybe-sudo.sh deleted file mode 100755 index 989d8b2f..00000000 --- a/launch/.terraform/modules/peertube.deploy/deploy_nixos/maybe-sudo.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -# -# Run sudo if required -# -# Usage: ./maybe-sudo.sh [...args] -set -euo pipefail -if [[ "$UID" = 0 ]]; then - exec -- "$@" -else - exec sudo -- "$@" -fi diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-deploy.sh b/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-deploy.sh deleted file mode 100755 index 319651bb..00000000 --- a/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-deploy.sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env bash -# nixos-deploy deploys a nixos-instantiate-generated drvPath to a target host -# -# Usage: nixos-deploy.sh [] ignoreme -set -euo pipefail - -### Defaults ### - -buildArgs=( - --option extra-binary-caches https://cache.nixos.org/ -) -profile=/nix/var/nix/profiles/system -# will be set later -sshOpts=( - -o "ControlMaster=auto" - -o "ControlPersist=60" - # Avoid issues with IP re-use. This disable TOFU security. - -o "StrictHostKeyChecking=no" - -o "UserKnownHostsFile=/dev/null" - -o "GlobalKnownHostsFile=/dev/null" - # interactive authentication is not possible - -o "BatchMode=yes" - # verbose output for easier debugging - -v -) - -### Argument parsing ### - -drvPath="$1" -outPath="$2" -targetHost="$3" -targetPort="$4" -buildOnTarget="$5" -sshPrivateKey="$6" -action="$7" -deleteOlderThan="$8" -shift 8 - -# remove the last argument -set -- "${@:1:$(($# - 1))}" -buildArgs+=("$@") - -sshOpts+=( -p "${targetPort}" ) - -workDir=$(mktemp -d) -trap 'rm -rf "$workDir"' EXIT - -if [[ -n "${sshPrivateKey}" && "${sshPrivateKey}" != "-" ]]; then - sshPrivateKeyFile="$workDir/ssh_key" - echo "$sshPrivateKey" > "$sshPrivateKeyFile" - chmod 0700 "$sshPrivateKeyFile" - sshOpts+=( -o "IdentityFile=${sshPrivateKeyFile}" ) -fi - -### Functions ### - -log() { - echo "--- $*" >&2 -} - -copyToTarget() { - NIX_SSHOPTS="${sshOpts[*]}" nix-copy-closure --to "$targetHost" "$@" -} - -# assumes that passwordless sudo is enabled on the server -targetHostCmd() { - # ${*@Q} escapes the arguments losslessly into space-separted quoted strings. - # `ssh` did not properly maintain the array nature of the command line, - # erroneously splitting arguments with internal spaces, even when using `--`. - # Tested with OpenSSH_7.9p1. - # - # shellcheck disable=SC2029 - ssh "${sshOpts[@]}" "$targetHost" "./maybe-sudo.sh ${*@Q}" -} - -# Setup a temporary ControlPath for this session. This speeds-up the -# operations by not re-creating SSH sessions between each command. At the end -# of the run, the session is forcefully terminated. -setupControlPath() { - sshOpts+=( - -o "ControlPath=$workDir/ssh_control" - ) - cleanupControlPath() { - local ret=$? - # Avoid failing during the shutdown - set +e - # Close ssh multiplex-master process gracefully - log "closing persistent ssh-connection" - ssh "${sshOpts[@]}" -O stop "$targetHost" - rm -rf "$workDir" - exit "$ret" - } - trap cleanupControlPath EXIT -} - -### Main ### - -setupControlPath - -if [[ "${buildOnTarget:-false}" == true ]]; then - - # Upload derivation - log "uploading derivations" - copyToTarget "$drvPath" --gzip --use-substitutes - - # Build remotely - log "building on target" - set -x - targetHostCmd "nix-store" "--realize" "$drvPath" "${buildArgs[@]}" - -else - - # Build derivation - log "building on deployer" - outPath=$(nix-store --realize "$drvPath" "${buildArgs[@]}") - - # Upload build results - log "uploading build results" - copyToTarget "$outPath" --gzip --use-substitutes - -fi - -# Activate -log "activating configuration" -targetHostCmd nix-env --profile "$profile" --set "$outPath" -targetHostCmd "$outPath/bin/switch-to-configuration" "$action" - -# Cleanup previous generations -log "collecting old nix derivations" -# Deliberately not quoting $deleteOlderThan so the user can configure something like "1 2 3" -# to keep generations with those numbers -targetHostCmd "nix-env" "--profile" "$profile" "--delete-generations" $deleteOlderThan -targetHostCmd "nix-store" "--gc" diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-instantiate.sh b/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-instantiate.sh deleted file mode 100755 index ad4763f0..00000000 --- a/launch/.terraform/modules/peertube.deploy/deploy_nixos/nixos-instantiate.sh +++ /dev/null @@ -1,94 +0,0 @@ -#! /usr/bin/env bash -set -euo pipefail - -# Args -nix_path=$1 -config=$2 -config_pwd=$3 -flake=$4 -shift 4 - - -command=(nix-instantiate --show-trace --expr ' - { system, configuration, hermetic ? false, flake ? false, ... }: - let - importFromFlake = { nixosConfig }: - let - flake = (import ( - fetchTarball { - url = "https://github.com/edolstra/flake-compat/archive/99f1c2157fba4bfe6211a321fd0ee43199025dbf.tar.gz"; - sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2"; } - ) { - src = ./.; - }).defaultNix; - in - builtins.getAttr nixosConfig flake.nixosConfigurations; - os = - if flake - then importFromFlake { nixosConfig = configuration; } - else if hermetic - then - ( - if builtins.isString configuration - # case: nixos_config i.e. file path - then import configuration - # case: config i.e. the module expression itself - else configuration - ) - else - import { inherit system configuration; }; - in { - inherit (builtins) currentSystem; - - substituters = - builtins.concatStringsSep " " os.config.nix.binaryCaches; - - trusted-public-keys = - builtins.concatStringsSep " " os.config.nix.binaryCachePublicKeys; - - drv_path = os.config.system.build.toplevel.drvPath; - out_path = os.config.system.build.toplevel; - }') - -if readlink --version | grep -q GNU; then - readlink="readlink -f" -else - if command -v greadlink &> /dev/null; then - readlink="greadlink -f" - else - echo "Warning: symlinks not supported because readlink is non GNU" >&2 - readlink="realpath" - fi -fi - -if [[ -f "$config" ]]; then - config=$($readlink "$config") - command+=(--argstr configuration "$config") -else - if $flake; then - command+=(--argstr configuration "$config" --arg flake true) - else - command+=(--arg configuration "$config") - fi -fi - -# add all extra CLI args as extra build arguments -command+=("$@") - -# Setting the NIX_PATH -if [[ -n "$nix_path" && "$nix_path" != "-" ]]; then - export NIX_PATH=$nix_path -fi - -# Changing directory -cd "$($readlink "$config_pwd")" - -# Instantiate -echo "running (instantiating): ${NIX_PATH:+NIX_PATH=$NIX_PATH} ${command[*]@Q}" -A out_path >&2 -"${command[@]}" -A out_path >/dev/null - -# Evaluate some more details, -# relying on preceding "Instantiate" command to perform the instantiation, -# because `--eval` is required but doesn't instantiate for some reason. -echo "running (evaluating): ${NIX_PATH:+NIX_PATH=$NIX_PATH} ${command[*]@Q}" --eval --strict --json >&2 -"${command[@]}" --eval --strict --json diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/unpack-keys.sh b/launch/.terraform/modules/peertube.deploy/deploy_nixos/unpack-keys.sh deleted file mode 100755 index 82ead0b8..00000000 --- a/launch/.terraform/modules/peertube.deploy/deploy_nixos/unpack-keys.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash -# -# Unpacks the packed-keys.json into individual keys -set -euo pipefail -shopt -s nullglob - -keys_file=${1:-packed-keys.json} -keys_dir=/var/keys - -if [[ ! -f "$keys_file" ]]; then - echo "error: $keys_file not found" - exit 1 -fi - -# Fallback if jq is not installed -if ! type -p jq &>/dev/null; then - jqOut=$(nix-build '' -A jq) - jq() { - "$jqOut/bin/jq" "$@" - } -fi - -# cleanup -mkdir -m 0750 -p "$keys_dir" -chown -v root:keys "$keys_dir" -chmod -v 0750 "$keys_dir" -for key in "$keys_dir"/* ; do - rm -v "$key" -done - -if [[ $(< "$keys_file") = "{}" ]]; then - echo "no keys to unpack" - exit -fi - -echo "unpacking $keys_file" - -# extract the keys from .packed.json -for keyname in $(jq -S -r 'keys[]' "$keys_file"); do - echo "unpacking: $keyname" - jq -r ".\"$keyname\"" < "$keys_file" > "$keys_dir/$keyname" - chmod 0640 "$keys_dir/$keyname" - chown root:keys "$keys_dir/$keyname" -done - -echo "unpacking done" diff --git a/launch/.terraform/modules/peertube.deploy/deploy_nixos/versions.tf b/launch/.terraform/modules/peertube.deploy/deploy_nixos/versions.tf deleted file mode 100644 index ac97c6ac..00000000 --- a/launch/.terraform/modules/peertube.deploy/deploy_nixos/versions.tf +++ /dev/null @@ -1,4 +0,0 @@ - -terraform { - required_version = ">= 0.12" -} diff --git a/launch/.terraform/modules/peertube.deploy/examples/google/deploy_nixos.tf b/launch/.terraform/modules/peertube.deploy/examples/google/deploy_nixos.tf deleted file mode 100644 index b77054c3..00000000 --- a/launch/.terraform/modules/peertube.deploy/examples/google/deploy_nixos.tf +++ /dev/null @@ -1,82 +0,0 @@ -# Here we have an example of how a machine can be provisioned with some config -# after boot. This is useful in case one doesn't want to unecessarily destroy -# and create VMs in a pet scenario. - -data "google_compute_network" "default" { - name = "default" -} - -resource "google_compute_firewall" "deploy-nixos" { - name = "deploy-nixos" - network = data.google_compute_network.default.name - - allow { - protocol = "icmp" - } - - // Allow SSH access - allow { - protocol = "tcp" - ports = ["22"] - } - - // To vm tagged with: nixos - target_tags = ["nixos"] - direction = "INGRESS" - - // From anywhere. - source_ranges = ["0.0.0.0/0"] -} - -resource "google_compute_instance" "deploy-nixos" { - name = "deploy-nixos-example" - machine_type = "n1-standard-1" - zone = "us-central1-a" - - // Bind the firewall rules - tags = ["nixos"] - - boot_disk { - initialize_params { - // Start with an image the deployer can SSH into - image = module.nixos_image_custom.self_link - size = "20" - } - } - - network_interface { - network = "default" - - // Give it a public IP - access_config {} - } - - lifecycle { - // No need to re-deploy the machine if the image changed - // NixOS is already immutable - ignore_changes = [boot_disk] - } -} - -module "deploy_nixos" { - source = "../../deploy_nixos" - - // Deploy the given NixOS configuration. In this case it's the same as the - // original image. So if the configuration is changed later it will be - // deployed here. - nixos_config = "${path.module}/image_nixos_custom.nix" - - target_user = "root" - target_host = google_compute_instance.deploy-nixos.network_interface[0].access_config[0].nat_ip - - triggers = { - // Also re-deploy whenever the VM is re-created - instance_id = google_compute_instance.deploy-nixos.id - } - - // Pass some secrets. See the terraform-provider-secret to handle secrets - // in Terraform - keys = { - foo = "bar" - } -} diff --git a/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos.tf b/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos.tf deleted file mode 100644 index 3ee88645..00000000 --- a/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos.tf +++ /dev/null @@ -1,25 +0,0 @@ -# Here is a simple example that instantiates the google image and spins up an -# instance - -module "nixos_image_1809" { - source = "../../google_image_nixos" - nixos_version = "18.09" -} - -// This instance is not very useful since it doesn't contain any -// configuration. This could be fixed by passing a user metadata script. -resource "google_compute_instance" "image-nixos" { - name = "image-nixos" - machine_type = "n1-standard-1" - zone = "us-central1-a" - - boot_disk { - initialize_params { - image = module.nixos_image_1809.self_link - } - } - - network_interface { - network = "default" - } -} diff --git a/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.nix b/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.nix deleted file mode 100644 index e67a92ff..00000000 --- a/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ modulesPath, ... }: -{ - imports = [ - # Make sure to have this in all your configurations - "${toString modulesPath}/virtualisation/google-compute-image.nix" - ]; - - # Bake the deploy's SSH key into the image. This is not - # kosher Nix. - users.users.root.openssh.authorizedKeys.keyFiles = [ - (/. + builtins.getEnv("HOME") + "/.ssh/id_rsa.pub") - ]; -} diff --git a/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.tf b/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.tf deleted file mode 100644 index 243b4c44..00000000 --- a/launch/.terraform/modules/peertube.deploy/examples/google/image_nixos_custom.tf +++ /dev/null @@ -1,21 +0,0 @@ -# create a random ID for the bucket -resource "random_id" "bucket" { - byte_length = 8 -} - -# create a bucket to upload the image into -resource "google_storage_bucket" "nixos-images" { - name = "nixos-images-${random_id.bucket.hex}" - location = "EU" -} - -# create a custom nixos base image the deployer can SSH into -# -# this could also include much more configuration and be used to feed the -# auto-scaler with system images -module "nixos_image_custom" { - source = "../../google_image_nixos_custom" - bucket_name = google_storage_bucket.nixos-images.name - - nixos_config = "${path.module}/image_nixos_custom.nix" -} diff --git a/launch/.terraform/modules/peertube.deploy/examples/google/provider.tf b/launch/.terraform/modules/peertube.deploy/examples/google/provider.tf deleted file mode 100644 index 910bae3e..00000000 --- a/launch/.terraform/modules/peertube.deploy/examples/google/provider.tf +++ /dev/null @@ -1,3 +0,0 @@ -provider "google" { - project = "tweag-digital-assets" -} diff --git a/launch/.terraform/modules/peertube.deploy/examples/hermetic_config/configuration.nix b/launch/.terraform/modules/peertube.deploy/examples/hermetic_config/configuration.nix deleted file mode 100644 index ea32c12f..00000000 --- a/launch/.terraform/modules/peertube.deploy/examples/hermetic_config/configuration.nix +++ /dev/null @@ -1,60 +0,0 @@ -# A simple, hermetic NixOS configuration for an AWS EC2 instance that -# uses a nixpkgs pinned to a specific Git revision with an integrity -# hash to ensure that we construct a NixOS system as purely as -# possible. -# -# i.e. we explicitly specify which nixpkgs to use instead of relying -# on the nixpkgs supplied on the NIX_PATH. -# -# The primary benefit of this is that it removes deployment surprises -# when other developers supply a different nix-channel in the NIX_PATH -# of their environment (even if you only add the 20.09 channel, -# nix-channel --update can mutate that channel to a 20.09 with -# backported changes). -# -# The secondary benefit is that you guard the `nixpkgs` you use, with -# an integrity hash. -let - nixpkgs = - let - rev = "cd63096d6d887d689543a0b97743d28995bc9bc3"; - sha256 = "1wg61h4gndm3vcprdcg7rc4s1v3jkm5xd7lw8r2f67w502y94gcy"; - in - builtins.fetchTarball { - url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz"; - inherit sha256; - }; - - system = "x86_64-linux"; - - configuration = { config, pkgs, ... }: { - imports = [ - "${nixpkgs}/nixos/modules/virtualisation/amazon-image.nix" - ]; - - ec2.hvm = true; - - networking.firewall.allowedTCPPorts = [ 22 80 ]; - - environment.systemPackages = [ - pkgs.cloud-utils - ]; - - services.nginx = { - enable = true; - virtualHosts = { - "_" = { - root = pkgs.writeTextDir "html/index.html" '' - - -

This is a hermetic NixOS configuration!

- - - ''; - }; - }; - }; - }; - -in - import "${nixpkgs}/nixos" { inherit system configuration; } diff --git a/launch/.terraform/modules/peertube.deploy/examples/hermetic_config/default.tf b/launch/.terraform/modules/peertube.deploy/examples/hermetic_config/default.tf deleted file mode 100644 index f3fa7115..00000000 --- a/launch/.terraform/modules/peertube.deploy/examples/hermetic_config/default.tf +++ /dev/null @@ -1,27 +0,0 @@ -provider "aws" { - region = "us-east-1" - profile = "yourprofile" -} - -resource "aws_instance" "hermetic-nixos-system" { - count = 1 - ami = "ami-068a62d478710462d" # NixOS 20.09 AMI - - instance_type = "t2.micro" - - key_name = "yourkeyname" - - tags = { - Name = "hermetic-nixos-system-example" - Description = "An example of a hermetic NixOS system deployed by Terraform" - } -} - -module "deploy_nixos" { - source = "github.com/awakesecurity/terraform-nixos//deploy_nixos?ref=c4b1ee6d24b54e92fa3439a12bce349a6805bcdd" - nixos_config = "${path.module}/configuration.nix" - hermetic = true - target_user = "root" - target_host = aws_instance.hermetic-nixos-system[0].public_ip - ssh_private_key_file = pathexpand("~/.ssh/yourkeyname.pem") -} diff --git a/launch/.terraform/modules/peertube.deploy/fmt b/launch/.terraform/modules/peertube.deploy/fmt deleted file mode 100755 index fd5c9125..00000000 --- a/launch/.terraform/modules/peertube.deploy/fmt +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash -# -set -euo pipefail - -cd "$(dirname "$0")" - -terraform fmt - -fmt_docs() { - ./scripts/terraform-docs-updater "$1" -} - -fmt_docs deploy_nixos -fmt_docs google_image_nixos -fmt_docs google_image_nixos_custom - -echo "." diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos/README.md b/launch/.terraform/modules/peertube.deploy/google_image_nixos/README.md deleted file mode 100644 index 593652b8..00000000 --- a/launch/.terraform/modules/peertube.deploy/google_image_nixos/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# `google_image_nixos` - -This terraform module creates a new image in the Google Cloud project using a -public tarballs of a NixOS release. Those tarballs are released by the NixOS -project. - -Since image names are unique, only one instance per version of the module is -supported per Google Cloud project. - -## Example - -```hcl -module "nixos_image_1809" { - source = "github.com/tweag/terraform-nixos/google_image_nixos" - nixos_version = "18.09" -} - -resource "google_compute_instance" "example" { - name = "example" - machine_type = "n1-standard-1" - zone = "us-central1-a" - - boot_disk { - initialize_params { - image = module.nixos_image_1809.self_link - } - } - - network_interface { - network = "default" - } -} -``` - -### Default configuration.nix - -A new configuration.nix can be passed trough the userdata. Here is the default -configuration to expand upon: - -```nix -{ modulesPath, ... }: -{ - imports = [ - "${toString modulesPath}/virtualisation/google-compute-image.nix" - ]; -} -``` - -## New NixOS releases - -Run the `./update-url-map` script to fetch new image releases. Please submit a -PR as well! - - -## Providers - -| Name | Version | -|------|---------| -| google | n/a | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:-----:| -| gcp\_project\_id | The ID of the project in which the resource belongs. If it is not provided, the provider project is used. | `string` | `""` | no | -| licenses | A list of license URIs to apply to this image. Changing this forces a new resource to be created. | `list(string)` |
[
"https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
]
| no | -| nixos\_version | The NixOS version to use. Eg: 18.09 | `string` | `"latest"` | no | -| url\_map | A map of release series to actual releases | `map(string)` |
{
"14.12": "https://nixos-cloud-images.storage.googleapis.com/nixos-14.12.471.1f09b77-x86_64-linux.raw.tar.gz",
"15.09": "https://nixos-cloud-images.storage.googleapis.com/nixos-15.09.425.7870f20-x86_64-linux.raw.tar.gz",
"16.03": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-16.03.847.8688c17-x86_64-linux.raw.tar.gz",
"17.03": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-17.03.1082.4aab5c5798-x86_64-linux.raw.tar.gz",
"18.03": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.03.132536.fdb5ba4cdf9-x86_64-linux.raw.tar.gz",
"18.09": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.09.1228.a4c4cbb613c-x86_64-linux.raw.tar.gz",
"20.03": "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz",
"latest": "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz"
}
| no | - -## Outputs - -| Name | Description | -|------|-------------| -| self\_link | Link to the NixOS Compute Image | - - diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos/main.tf b/launch/.terraform/modules/peertube.deploy/google_image_nixos/main.tf deleted file mode 100644 index b42e28dd..00000000 --- a/launch/.terraform/modules/peertube.deploy/google_image_nixos/main.tf +++ /dev/null @@ -1,64 +0,0 @@ -variable "nixos_version" { - type = string - default = "latest" - description = "The NixOS version to use. Eg: 18.09" -} - -variable "gcp_project_id" { - type = string - default = "" - description = "The ID of the project in which the resource belongs. If it is not provided, the provider project is used." -} - -variable "labels" { - type = map(string) - default = {} - description = "A map of labels applied to this image." -} - -variable "licenses" { - type = list(string) - - default = [ - "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx", - ] - - description = "A list of license URIs to apply to this image. Changing this forces a new resource to be created." -} - -# --- - -locals { - image_url = var.url_map[var.nixos_version] - - # Example: nixos-image-18-09-1228-a4c4cbb613c-x86-64-linux - # - # Remove a few things so that it matches the required regexp for image names - # (?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?) - image_name = replace( - replace(basename(local.image_url), ".raw.tar.gz", ""), - "/[._]+/", - "-", - ) -} - -resource "google_compute_image" "nixos" { - name = local.image_name - description = "NixOS ${var.nixos_version}" - family = "nixos" - project = var.gcp_project_id - labels = var.labels - licenses = var.licenses - - raw_disk { - source = local.image_url - } -} - -# --- - -output "self_link" { - description = "Link to the NixOS Compute Image" - value = google_compute_image.nixos.self_link -} - diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos/update-url-map b/launch/.terraform/modules/peertube.deploy/google_image_nixos/update-url-map deleted file mode 100755 index 4b9722ff..00000000 --- a/launch/.terraform/modules/peertube.deploy/google_image_nixos/update-url-map +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env nix-shell -#!nix-shell -p ruby -i ruby -# vim: ft=ruby -# -# Run this script to update the list of GCE images -# -require "json" -require "uri" - -ENV['NIX_PATH'] = "nixpkgs=channel:nixpkgs-unstable" - -def render_tf - url_map=JSON.load(`nix-instantiate --json --strict --eval ./url_map.nix`) - - out = <<~HEADER - # DON'T EDIT, run $0 instead - variable "url_map" { - type = map(string) - - default = { - HEADER - - url_map.each_pair do |version, gs_url| - u = URI.parse(gs_url) - # convert the gs:// URL to HTTPS URL for Terraform to consume - # - # Eg: "gs://nixos-cloud-images/nixos-image-18.09-x86_64-linux.raw.tar.gz" - https_url = "https://#{u.host}.storage.googleapis.com#{u.path}" - - out += " %- 8s = %s\n" % [ version.inspect, https_url.inspect] - end - - out += <<~FOOTER - } - - description = "A map of release series to actual releases" - } - FOOTER -end - -url_map_tf = render_tf - -open("url_map.tf", "w") do |f| - f.write(url_map_tf) -end - -puts url_map_tf diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.nix b/launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.nix deleted file mode 100644 index 7b341ced..00000000 --- a/launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.nix +++ /dev/null @@ -1,2 +0,0 @@ -# Indirect link to where the image map is stored -import diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.tf b/launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.tf deleted file mode 100644 index aa898a67..00000000 --- a/launch/.terraform/modules/peertube.deploy/google_image_nixos/url_map.tf +++ /dev/null @@ -1,17 +0,0 @@ -# DON'T EDIT, run $0 instead -variable "url_map" { - type = map(string) - - default = { - "14.12" = "https://nixos-cloud-images.storage.googleapis.com/nixos-14.12.471.1f09b77-x86_64-linux.raw.tar.gz" - "15.09" = "https://nixos-cloud-images.storage.googleapis.com/nixos-15.09.425.7870f20-x86_64-linux.raw.tar.gz" - "16.03" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-16.03.847.8688c17-x86_64-linux.raw.tar.gz" - "17.03" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-17.03.1082.4aab5c5798-x86_64-linux.raw.tar.gz" - "18.03" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.03.132536.fdb5ba4cdf9-x86_64-linux.raw.tar.gz" - "18.09" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.09.1228.a4c4cbb613c-x86_64-linux.raw.tar.gz" - "20.03" = "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz" - "latest" = "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz" - } - - description = "A map of release series to actual releases" -} diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos/versions.tf b/launch/.terraform/modules/peertube.deploy/google_image_nixos/versions.tf deleted file mode 100644 index ac97c6ac..00000000 --- a/launch/.terraform/modules/peertube.deploy/google_image_nixos/versions.tf +++ /dev/null @@ -1,4 +0,0 @@ - -terraform { - required_version = ">= 0.12" -} diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/README.md b/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/README.md deleted file mode 100644 index ef2fafda..00000000 --- a/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# google_cloud_image_nixos - -This terraform module builds and publishes custom NixOS Google Cloud images. - -## Runtime dependencies - -Because this module uses the "external" provider it needs the following -executables to be in the path to work properly: - -* bash -* nix -* `readlink -f` (busybox or coreutils) - -## Known limitations - -NixOS images are built at Terraform plan time. This can make the plan quite -slow. - -Building the image doesn't yield any output, unless the build is interrupted or -failed. - -When a new image is published, the old-one gets removed. This potentially -introduces a race-condition where other targets are trying to create new -instances with the old image. To reduce the race window, `create_before_destroy` is being used. See -https://github.com/hashicorp/terraform/issues/15485 for related discussions. - -Only x86_64-linux is currently supported. - - -## Providers - -| Name | Version | -|------|---------| -| external | n/a | -| google | n/a | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:-----:| -| NIX\_PATH | Allow to pass custom NIX\_PATH. Ignored if `-` or empty. | `string` | `"-"` | no | -| bucket\_name | Bucket where to store the image | `any` | n/a | yes | -| gcp\_project\_id | The ID of the project in which the resource belongs. If it is not provided, the provider project is used. | `string` | `""` | no | -| licenses | A list of license URIs to apply to this image. Changing this forces a new resource to be created. | `list(string)` |
[
"https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
]
| no | -| nixos\_config | Path to a nixos configuration.nix file | `any` | n/a | yes | - -## Outputs - -| Name | Description | -|------|-------------| -| NIX\_PATH | n/a | -| self\_link | n/a | - - diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/main.tf b/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/main.tf deleted file mode 100644 index 9ceaed5d..00000000 --- a/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/main.tf +++ /dev/null @@ -1,94 +0,0 @@ -variable "bucket_name" { - description = "Bucket where to store the image" -} - -variable "nixos_config" { - description = "Path to a nixos configuration.nix file" -} - -variable "NIX_PATH" { - type = string - description = "Allow to pass custom NIX_PATH. Ignored if `-` or empty." - default = "-" -} - -variable "gcp_project_id" { - type = string - default = "" - description = "The ID of the project in which the resource belongs. If it is not provided, the provider project is used." -} - -variable "licenses" { - type = list(string) - - default = [ - "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx", - ] - - description = "A list of license URIs to apply to this image. Changing this forces a new resource to be created." -} - -# ---------------------------------------------------- - -data "external" "nix_build" { - program = ["${path.module}/nixos-build.sh", var.NIX_PATH, var.nixos_config] -} - -locals { - out_path = data.external.nix_build.result.out_path - image_path = data.external.nix_build.result.image_path - - # 3x2d4rdm9kjzk9d9sz87rmhzvcphs23v - out_hash = element(split("-", basename(local.out_path)), 0) - - # Example: 3x2d4rdm9kjzk9d9sz87rmhzvcphs23v-19-03pre-git-x86-64-linux - # - # Remove a few things so that it matches the required regexp for image names - # (?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?) - image_name = "x${substr(local.out_hash, 0, 12)}-${replace( - replace( - basename(local.image_path), - "/\\.raw\\.tar\\.gz|nixos-image-/", - "", - ), - "/[._]+/", - "-", - )}" - - # 3x2d4rdm9kjzk9d9sz87rmhzvcphs23v-nixos-image-19.03pre-git-x86_64-linux.raw.tar.gz - image_filename = "${local.out_hash}-${basename(local.image_path)}" -} - -resource "google_storage_bucket_object" "nixos" { - name = "images/${local.image_filename}" - source = local.image_path - bucket = var.bucket_name - content_type = "application/tar+gzip" - - lifecycle { - create_before_destroy = true - } -} - -resource "google_compute_image" "nixos" { - name = local.image_name - family = "nixos" - project = var.gcp_project_id - licenses = var.licenses - - raw_disk { - source = "https://${var.bucket_name}.storage.googleapis.com/${google_storage_bucket_object.nixos.name}" - } - - lifecycle { - create_before_destroy = true - } -} - -output "self_link" { - value = google_compute_image.nixos.self_link -} - -output "NIX_PATH" { - value = var.NIX_PATH -} diff --git a/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/nixos-build.sh b/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/nixos-build.sh deleted file mode 100755 index 270d6ca0..00000000 --- a/launch/.terraform/modules/peertube.deploy/google_image_nixos_custom/nixos-build.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash -# Special version of nix-build that integrates with the Terraform external -# provider -set -euo pipefail - -nix_path="${1}" -nixos_config=$(readlink -f "${2:-./configuration.nix}") - -shift -shift - -if [[ -n "$nix_path" && "$nix_path" != "-" ]]; then - export NIX_PATH=$nix_path -fi - -args=( - --arg configuration "$nixos_config" - --argstr system x86_64-linux - --no-out-link - -A config.system.build.googleComputeImage -) - -out_path=$(nix-build '' "${args[@]}" "$@") - -image_path= -for path in "$out_path"/*.tar.gz; do - image_path=$path -done - -cat </dev/null ; then - if [[ -f "$doc.bak" ]]; then - echo "$doc.bak file detected, aborting" >&2 - exit 1 - fi - - mv "$doc" "$doc.bak" - { - sed "/$BANNER_START/q" "$doc.bak" - terraform-docs md . - sed -n -e "/$BANNER_END/,\$p" "$doc.bak" - } > "$doc" - - rm "$doc.bak" -else - { - echo "$BANNER_START" - terraform-docs md . - echo "$BANNER_END" - } >> "$doc" -fi diff --git a/launch/.terraform/modules/peertube.deploy/shell.nix b/launch/.terraform/modules/peertube.deploy/shell.nix deleted file mode 100644 index 1d044982..00000000 --- a/launch/.terraform/modules/peertube.deploy/shell.nix +++ /dev/null @@ -1,21 +0,0 @@ -with import {}; -let - tf = terraform.withPlugins(p: with p; [ - external - google - p.null - random - ]); - # https://github.com/NixOS/nixpkgs/pull/51579 - terraform-docs = callPackage ./nix/terraform-docs {}; -in -mkShell { - buildInputs = [ - tf - terraform-docs - ]; - - shellHook = '' - NIX_PATH=nixpkgs=channel:nixos-18.09 - ''; -} diff --git a/launch/.terraform/modules/pixelfed.deploy/LICENSE b/launch/.terraform/modules/pixelfed.deploy/LICENSE deleted file mode 100644 index 261eeb9e..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/launch/.terraform/modules/pixelfed.deploy/README.md b/launch/.terraform/modules/pixelfed.deploy/README.md deleted file mode 100644 index 443a0e87..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/README.md +++ /dev/null @@ -1,113 +0,0 @@ -# terraform-nixos - -[![built with nix](https://builtwithnix.org/badge.svg)](https://builtwithnix.org) - -This repository contains a set of Terraform Modules designed to deploy NixOS -machines. These modules are designed to work together and support different -deployment scenarios. - -## What is Terraform? - -[Terraform][terraform] is a tool that allows to declare infrastructures as -code. - -## What is Nix, nixpkgs and NixOS? - -[Nix][nix] is a build system and package manager that allows to manage whole -system configurations as code. nixpkgs is a set of 20k+ packages built with -Nix. NixOS is a Linux distribution built on top of nixpkgs. - -## What is a Terraform Module? - -A Terraform Module refers to a self-contained package of Terraform -configurations that are managed as a group. This repo contains a collection of -Terraform Modules which can be composed together to create useful -infrastructure patterns. - -## Terraform + Nix vs NixOps - -NixOps is a great tool for personal deployments. It handles a lot of things -like cloud resource creation, machine NixOS bootstrapping and deployment. - -The difficulty is when the cloud resources are not supported by NixOps. It -takes a lot of work to map all the cloud APIs. Compared to NixOps, Terraform -has become an industry standard and has thousands of people contributing new -cloud API mapping all the time. - -Another issue is when sharing the configuration as code with multiple -developers. Both NixOps and Terraform maintain a state file of "known applied" -configuration. Unlike NixOps, Terraform provides facilities to sync and lock -the state file so it's available by other users. - -The approach here is to use Terraform to create all the cloud resources. By -using the `google_image_nixos_custom` module it's possible to pre-build images in -auto-scaling scenarios. Or use a push model similar to NixOps with the generic -`deploy_nixos` module. - -So overall Terraform + Nix is more flexible and scales better. But it's also -more cumbersome to use as it requires to learn two languages instead of one -and the integration between both is also a bit clunky. - -## Terraform Modules - -The list of modules provided by this project: - -* [deploy_nixos](deploy_nixos#readme) - deploy NixOS onto running NixOS - machines -* [google_image_nixos](google_image_nixos#readme) - setup an official GCE - image into a Google Cloud Project. -* [google_image_nixos_custom](google_image_nixos_custom#readme) - build and - deploy a custom GCE image into a Google Cloud Project - -## Using these modules from your terraform configuration - -Terraform supports importing [modules](https://www.terraform.io/docs/configuration/modules.html) directly [from a GitHub repository](https://www.terraform.io/docs/modules/sources.html#github). - -For example, to use the [`deploy_nixos`](deploy_nixos#readme) module: - -``` -module "deploy_nixos" { - source = "github.com/tweag/terraform-nixos//deploy_nixos?ref=ced68729b6a0382dda02401c8f663c9b29c29368" - - … module-specific fields … -} -``` - -Beware the double `//`, which separates the github repository url from the -subdirectory that contains the module. `?ref=` specifies a specific git ref -of the repository, in this case the commit `ced687…`. - -## Examples - -To better understand how these modules can be used together, look into the -[./examples](examples) folder. - -## Related projects - -* [terraform-provider-nix](https://github.com/andrewchambers/terraform-provider-nix) - -## Future - -* Support other cloud providers. -* Support nixos-infect bootstrapping method. - -Contributions are welcome! - -## Thanks - -Thanks to [Digital Asset][digital-asset] for generously sponsoring this work! - -Thanks to [Tweag][tweag] for enabling this work and the continuous support! - -## License - -This code is released under the Apache 2.0 License. Please see -[LICENSE](LICENSE) for more details. - -Copyright © 2018 Tweag I/O. - - -[digital-asset]: https://www.digitalasset.com/ -[nix]: https://nixos.org/nix/ -[terraform]: https://www.terraform.io -[tweag]: https://www.tweag.io/ diff --git a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/README.md b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/README.md deleted file mode 100644 index b36938de..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# AWS Collection of NixOS AMIs - -This terraform module provides links to official NixOS AMIs on AWS. The AMIs are -released by the NixOS project. - -Since image names are unique, only one instance per version of the module is -supported. - -## Example - - provider "aws" { - region = "eu-west-1" - } - - module "nixos_image_1903" { - source = "path/to/aws_image_nixos" - release = "19.03" - } - - resource "aws_instance" "example" { - ami = module.nixos_image_1903.ami - instance_type = "t2.micro" - - ... - } - -## New NixOS releases - -Run the `./update-url-map` script to fetch new image releases. - - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|:----:|:-----:|:-----:| -| region | The region to use. If not provided, current provider's region will be used. | string | `` | no | -| release | The NixOS version to use. For example, 18.09 | string | `latest` | no | -| type | The type of the AMI to use -- hvm-ebs, pv-ebs, or pv-s3. | string | `hvm-ebs` | no | -| url\_map | A map of release series to actual releases | map | `` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| ami | NixOS AMI on AWS | - diff --git a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/main.tf b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/main.tf deleted file mode 100644 index dace86dc..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/main.tf +++ /dev/null @@ -1,34 +0,0 @@ -variable "release" { - type = string - default = "latest" - description = "The NixOS version to use. For example, 18.09" -} - -variable "region" { - type = string - default = "" - description = "The region to use. If not provided, current provider's region will be used." -} - -variable "type" { - type = string - default = "hvm-ebs" - description = "The type of the AMI to use -- hvm-ebs, pv-ebs, or pv-s3." -} - -# --- - -data "aws_region" "current" {} - -locals { - key = "${var.release}.${coalesce(var.region, data.aws_region.current.name)}.${var.type}" - ami = var.url_map[local.key] -} - -# --- - -output "ami" { - description = "NixOS AMI on AWS" - value = local.ami -} - diff --git a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/update-url-map b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/update-url-map deleted file mode 100755 index 3a2ce4cc..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/update-url-map +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env nix-shell -#!nix-shell -p python3 -i python -# vim: ft=python -# -# Run this script to update the list of EC2 images -# -import json -import io -from subprocess import check_output -from textwrap import dedent -from os import putenv - -putenv('NIX_PATH', 'nixpkgs=channel:nixpkgs-unstable') - -def render_tf(): - nix_eval = check_output(['nix-instantiate', '--json', '--strict', '--eval', './url_map.nix']) - url_map = json.loads(nix_eval) - - out = io.StringIO() - out.write(dedent("""\ - # DON'T EDIT, run '%s' instead - variable "url_map" { - type = map(string) - - default = { - """ % __file__)) - - for version, regions in url_map.items(): - for region, kinds in regions.items(): - for kind, ami in kinds.items(): - out.write(' "%s.%s.%s" = "%s"\n' % (version, region, kind, ami)) - - out.write(dedent("""\ - } - - description = "A map of release series to actual releases" - } - """)) - - return out.getvalue() - -url_map_tf = render_tf() - -with open("url_map.tf", "w") as f: - f.write(url_map_tf) - -print(url_map_tf) - -# Local Variables: -# mode: Python -# End: diff --git a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.nix b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.nix deleted file mode 100644 index 73b0b73e..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.nix +++ /dev/null @@ -1,2 +0,0 @@ -# Indirect link to where the image map is stored -import diff --git a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.tf b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.tf deleted file mode 100644 index 3a546a1b..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/url_map.tf +++ /dev/null @@ -1,353 +0,0 @@ -# DON'T EDIT, run './update-url-map' instead -variable "url_map" { - type = map(string) - - default = { - "14.04.ap-northeast-1.hvm-ebs" = "ami-71c6f470" - "14.04.ap-northeast-1.pv-ebs" = "ami-4dcbf84c" - "14.04.ap-northeast-1.pv-s3" = "ami-8fc4f68e" - "14.04.ap-southeast-1.hvm-ebs" = "ami-da280888" - "14.04.ap-southeast-1.pv-ebs" = "ami-7a9dbc28" - "14.04.ap-southeast-1.pv-s3" = "ami-c4290996" - "14.04.ap-southeast-2.hvm-ebs" = "ami-ab523e91" - "14.04.ap-southeast-2.pv-ebs" = "ami-6769055d" - "14.04.ap-southeast-2.pv-s3" = "ami-15533f2f" - "14.04.eu-central-1.hvm-ebs" = "ami-ba0234a7" - "14.04.eu-west-1.hvm-ebs" = "ami-96cb63e1" - "14.04.eu-west-1.pv-ebs" = "ami-b48c25c3" - "14.04.eu-west-1.pv-s3" = "ami-06cd6571" - "14.04.sa-east-1.hvm-ebs" = "ami-01b90e1c" - "14.04.sa-east-1.pv-ebs" = "ami-69e35474" - "14.04.sa-east-1.pv-s3" = "ami-61b90e7c" - "14.04.us-east-1.hvm-ebs" = "ami-58ba3a30" - "14.04.us-east-1.pv-ebs" = "ami-9e0583f6" - "14.04.us-east-1.pv-s3" = "ami-9cbe3ef4" - "14.04.us-west-1.hvm-ebs" = "ami-0bc3d74e" - "14.04.us-west-1.pv-ebs" = "ami-8b1703ce" - "14.04.us-west-1.pv-s3" = "ami-27ccd862" - "14.04.us-west-2.hvm-ebs" = "ami-3bf1bf0b" - "14.04.us-west-2.pv-ebs" = "ami-259bd515" - "14.04.us-west-2.pv-s3" = "ami-07094037" - "14.12.ap-northeast-1.hvm-ebs" = "ami-24435f25" - "14.12.ap-northeast-1.pv-ebs" = "ami-b0425eb1" - "14.12.ap-northeast-1.pv-s3" = "ami-fed3c6ff" - "14.12.ap-southeast-1.hvm-ebs" = "ami-6c765d3e" - "14.12.ap-southeast-1.pv-ebs" = "ami-6a765d38" - "14.12.ap-southeast-1.pv-s3" = "ami-d1bf9183" - "14.12.ap-southeast-2.hvm-ebs" = "ami-af86f395" - "14.12.ap-southeast-2.pv-ebs" = "ami-b386f389" - "14.12.ap-southeast-2.pv-s3" = "ami-69c5ae53" - "14.12.eu-central-1.hvm-ebs" = "ami-4a497a57" - "14.12.eu-central-1.pv-ebs" = "ami-4c497a51" - "14.12.eu-central-1.pv-s3" = "ami-60f2c27d" - "14.12.eu-west-1.hvm-ebs" = "ami-d126a5a6" - "14.12.eu-west-1.pv-ebs" = "ami-0126a576" - "14.12.eu-west-1.pv-s3" = "ami-deda5fa9" - "14.12.sa-east-1.hvm-ebs" = "ami-2d239e30" - "14.12.sa-east-1.pv-ebs" = "ami-35239e28" - "14.12.sa-east-1.pv-s3" = "ami-81e3519c" - "14.12.us-east-1.hvm-ebs" = "ami-0c463a64" - "14.12.us-east-1.pv-ebs" = "ami-ac473bc4" - "14.12.us-east-1.pv-s3" = "ami-00e18a68" - "14.12.us-west-1.hvm-ebs" = "ami-ca534a8f" - "14.12.us-west-1.pv-ebs" = "ami-3e534a7b" - "14.12.us-west-1.pv-s3" = "ami-2905196c" - "14.12.us-west-2.hvm-ebs" = "ami-fb9dc3cb" - "14.12.us-west-2.pv-ebs" = "ami-899dc3b9" - "14.12.us-west-2.pv-s3" = "ami-cb7f2dfb" - "15.09.ap-northeast-1.hvm-ebs" = "ami-58cac236" - "15.09.ap-northeast-1.hvm-s3" = "ami-39c8c057" - "15.09.ap-northeast-1.pv-ebs" = "ami-5ac9c134" - "15.09.ap-northeast-1.pv-s3" = "ami-03cec66d" - "15.09.ap-southeast-1.hvm-ebs" = "ami-2fc2094c" - "15.09.ap-southeast-1.hvm-s3" = "ami-9ec308fd" - "15.09.ap-southeast-1.pv-ebs" = "ami-95c00bf6" - "15.09.ap-southeast-1.pv-s3" = "ami-bfc00bdc" - "15.09.ap-southeast-2.hvm-ebs" = "ami-996c4cfa" - "15.09.ap-southeast-2.hvm-s3" = "ami-3f6e4e5c" - "15.09.ap-southeast-2.pv-ebs" = "ami-066d4d65" - "15.09.ap-southeast-2.pv-s3" = "ami-cc6e4eaf" - "15.09.eu-central-1.hvm-ebs" = "ami-3f8c6b50" - "15.09.eu-central-1.hvm-s3" = "ami-5b836434" - "15.09.eu-central-1.pv-ebs" = "ami-118c6b7e" - "15.09.eu-central-1.pv-s3" = "ami-2c977043" - "15.09.eu-west-1.hvm-ebs" = "ami-9cf04aef" - "15.09.eu-west-1.hvm-s3" = "ami-2bea5058" - "15.09.eu-west-1.pv-ebs" = "ami-c9e852ba" - "15.09.eu-west-1.pv-s3" = "ami-c6f64cb5" - "15.09.sa-east-1.hvm-ebs" = "ami-6e52df02" - "15.09.sa-east-1.hvm-s3" = "ami-1852df74" - "15.09.sa-east-1.pv-ebs" = "ami-4368e52f" - "15.09.sa-east-1.pv-s3" = "ami-f15ad79d" - "15.09.us-east-1.hvm-ebs" = "ami-84a6a0ee" - "15.09.us-east-1.hvm-s3" = "ami-06a7a16c" - "15.09.us-east-1.pv-ebs" = "ami-a4a1a7ce" - "15.09.us-east-1.pv-s3" = "ami-5ba8ae31" - "15.09.us-west-1.hvm-ebs" = "ami-22c8bb42" - "15.09.us-west-1.hvm-s3" = "ami-a2ccbfc2" - "15.09.us-west-1.pv-ebs" = "ami-10cebd70" - "15.09.us-west-1.pv-s3" = "ami-fa30429a" - "15.09.us-west-2.hvm-ebs" = "ami-ce57b9ae" - "15.09.us-west-2.hvm-s3" = "ami-2956b849" - "15.09.us-west-2.pv-ebs" = "ami-005fb160" - "15.09.us-west-2.pv-s3" = "ami-cd55bbad" - "16.03.ap-northeast-1.hvm-ebs" = "ami-40619d21" - "16.03.ap-northeast-1.hvm-s3" = "ami-ce629eaf" - "16.03.ap-northeast-1.pv-ebs" = "ami-ef639f8e" - "16.03.ap-northeast-1.pv-s3" = "ami-a1609cc0" - "16.03.ap-northeast-2.hvm-ebs" = "ami-deca00b0" - "16.03.ap-northeast-2.hvm-s3" = "ami-a3b77dcd" - "16.03.ap-northeast-2.pv-ebs" = "ami-7bcb0115" - "16.03.ap-northeast-2.pv-s3" = "ami-a2b77dcc" - "16.03.ap-south-1.hvm-ebs" = "ami-0dff9562" - "16.03.ap-south-1.hvm-s3" = "ami-13f69c7c" - "16.03.ap-south-1.pv-ebs" = "ami-0ef39961" - "16.03.ap-south-1.pv-s3" = "ami-e0c8a28f" - "16.03.ap-southeast-1.hvm-ebs" = "ami-5e964a3d" - "16.03.ap-southeast-1.hvm-s3" = "ami-4d964a2e" - "16.03.ap-southeast-1.pv-ebs" = "ami-ec9b478f" - "16.03.ap-southeast-1.pv-s3" = "ami-999b47fa" - "16.03.ap-southeast-2.hvm-ebs" = "ami-9f7359fc" - "16.03.ap-southeast-2.hvm-s3" = "ami-987359fb" - "16.03.ap-southeast-2.pv-ebs" = "ami-a2705ac1" - "16.03.ap-southeast-2.pv-s3" = "ami-a3705ac0" - "16.03.eu-central-1.hvm-ebs" = "ami-17a45178" - "16.03.eu-central-1.hvm-s3" = "ami-f9a55096" - "16.03.eu-central-1.pv-ebs" = "ami-c8a550a7" - "16.03.eu-central-1.pv-s3" = "ami-6ea45101" - "16.03.eu-west-1.hvm-ebs" = "ami-b5b3d5c6" - "16.03.eu-west-1.hvm-s3" = "ami-c986e0ba" - "16.03.eu-west-1.pv-ebs" = "ami-b083e5c3" - "16.03.eu-west-1.pv-s3" = "ami-3c83e54f" - "16.03.sa-east-1.hvm-ebs" = "ami-f6eb7f9a" - "16.03.sa-east-1.hvm-s3" = "ami-93e773ff" - "16.03.sa-east-1.pv-ebs" = "ami-cbb82ca7" - "16.03.sa-east-1.pv-s3" = "ami-abb82cc7" - "16.03.us-east-1.hvm-ebs" = "ami-c123a3d6" - "16.03.us-east-1.hvm-s3" = "ami-bc25a5ab" - "16.03.us-east-1.pv-ebs" = "ami-bd25a5aa" - "16.03.us-east-1.pv-s3" = "ami-a325a5b4" - "16.03.us-west-1.hvm-ebs" = "ami-748bcd14" - "16.03.us-west-1.hvm-s3" = "ami-a68dcbc6" - "16.03.us-west-1.pv-ebs" = "ami-048acc64" - "16.03.us-west-1.pv-s3" = "ami-208dcb40" - "16.03.us-west-2.hvm-ebs" = "ami-8263a0e2" - "16.03.us-west-2.hvm-s3" = "ami-925c9ff2" - "16.03.us-west-2.pv-ebs" = "ami-5e61a23e" - "16.03.us-west-2.pv-s3" = "ami-734c8f13" - "16.09.ap-northeast-1.hvm-ebs" = "ami-68453b0f" - "16.09.ap-northeast-1.hvm-s3" = "ami-f9bec09e" - "16.09.ap-northeast-1.pv-ebs" = "ami-254a3442" - "16.09.ap-northeast-1.pv-s3" = "ami-ef473988" - "16.09.ap-northeast-2.hvm-ebs" = "ami-18ae7f76" - "16.09.ap-northeast-2.hvm-s3" = "ami-9eac7df0" - "16.09.ap-northeast-2.pv-ebs" = "ami-57aa7b39" - "16.09.ap-northeast-2.pv-s3" = "ami-5cae7f32" - "16.09.ap-south-1.hvm-ebs" = "ami-b3f98fdc" - "16.09.ap-south-1.hvm-s3" = "ami-98e690f7" - "16.09.ap-south-1.pv-ebs" = "ami-aef98fc1" - "16.09.ap-south-1.pv-s3" = "ami-caf88ea5" - "16.09.ap-southeast-1.hvm-ebs" = "ami-80fb51e3" - "16.09.ap-southeast-1.hvm-s3" = "ami-2df3594e" - "16.09.ap-southeast-1.pv-ebs" = "ami-37f05a54" - "16.09.ap-southeast-1.pv-s3" = "ami-27f35944" - "16.09.ap-southeast-2.hvm-ebs" = "ami-57ece834" - "16.09.ap-southeast-2.hvm-s3" = "ami-87f4f0e4" - "16.09.ap-southeast-2.pv-ebs" = "ami-d8ede9bb" - "16.09.ap-southeast-2.pv-s3" = "ami-a6ebefc5" - "16.09.ca-central-1.hvm-ebs" = "ami-9f863bfb" - "16.09.ca-central-1.hvm-s3" = "ami-ea85388e" - "16.09.ca-central-1.pv-ebs" = "ami-ce8a37aa" - "16.09.ca-central-1.pv-s3" = "ami-448a3720" - "16.09.eu-central-1.hvm-ebs" = "ami-1b884774" - "16.09.eu-central-1.hvm-s3" = "ami-b08c43df" - "16.09.eu-central-1.pv-ebs" = "ami-888946e7" - "16.09.eu-central-1.pv-s3" = "ami-06874869" - "16.09.eu-west-1.hvm-ebs" = "ami-1ed3e76d" - "16.09.eu-west-1.hvm-s3" = "ami-73d1e500" - "16.09.eu-west-1.pv-ebs" = "ami-44c0f437" - "16.09.eu-west-1.pv-s3" = "ami-f3d8ec80" - "16.09.eu-west-2.hvm-ebs" = "ami-2c9c9648" - "16.09.eu-west-2.hvm-s3" = "ami-6b9e940f" - "16.09.eu-west-2.pv-ebs" = "ami-f1999395" - "16.09.eu-west-2.pv-s3" = "ami-bb9f95df" - "16.09.sa-east-1.hvm-ebs" = "ami-a11882cd" - "16.09.sa-east-1.hvm-s3" = "ami-7726bc1b" - "16.09.sa-east-1.pv-ebs" = "ami-9725bffb" - "16.09.sa-east-1.pv-s3" = "ami-b027bddc" - "16.09.us-east-1.hvm-ebs" = "ami-854ca593" - "16.09.us-east-1.hvm-s3" = "ami-2241a834" - "16.09.us-east-1.pv-ebs" = "ami-a441a8b2" - "16.09.us-east-1.pv-s3" = "ami-e841a8fe" - "16.09.us-east-2.hvm-ebs" = "ami-3f41645a" - "16.09.us-east-2.hvm-s3" = "ami-804065e5" - "16.09.us-east-2.pv-ebs" = "ami-f1466394" - "16.09.us-east-2.pv-s3" = "ami-05426760" - "16.09.us-west-1.hvm-ebs" = "ami-c2efbca2" - "16.09.us-west-1.hvm-s3" = "ami-d71042b7" - "16.09.us-west-1.pv-ebs" = "ami-04e8bb64" - "16.09.us-west-1.pv-s3" = "ami-31e9ba51" - "16.09.us-west-2.hvm-ebs" = "ami-6449f504" - "16.09.us-west-2.hvm-s3" = "ami-344af654" - "16.09.us-west-2.pv-ebs" = "ami-6d4af60d" - "16.09.us-west-2.pv-s3" = "ami-de48f4be" - "17.03.ap-northeast-1.hvm-ebs" = "ami-dbd0f7bc" - "17.03.ap-northeast-1.hvm-s3" = "ami-7cdff81b" - "17.03.ap-northeast-2.hvm-ebs" = "ami-c59a48ab" - "17.03.ap-northeast-2.hvm-s3" = "ami-0b944665" - "17.03.ap-south-1.hvm-ebs" = "ami-4f413220" - "17.03.ap-south-1.hvm-s3" = "ami-864033e9" - "17.03.ap-southeast-1.hvm-ebs" = "ami-e08c3383" - "17.03.ap-southeast-1.hvm-s3" = "ami-c28f30a1" - "17.03.ap-southeast-2.hvm-ebs" = "ami-fca9a69f" - "17.03.ap-southeast-2.hvm-s3" = "ami-3daaa55e" - "17.03.ca-central-1.hvm-ebs" = "ami-9b00bdff" - "17.03.ca-central-1.hvm-s3" = "ami-e800bd8c" - "17.03.eu-central-1.hvm-ebs" = "ami-5450803b" - "17.03.eu-central-1.hvm-s3" = "ami-6e2efe01" - "17.03.eu-west-1.hvm-ebs" = "ami-10754c76" - "17.03.eu-west-1.hvm-s3" = "ami-11734a77" - "17.03.eu-west-2.hvm-ebs" = "ami-ff1d099b" - "17.03.eu-west-2.hvm-s3" = "ami-fe1d099a" - "17.03.sa-east-1.hvm-ebs" = "ami-d95d3eb5" - "17.03.sa-east-1.hvm-s3" = "ami-fca2c190" - "17.03.us-east-1.hvm-ebs" = "ami-0940c61f" - "17.03.us-east-1.hvm-s3" = "ami-674fc971" - "17.03.us-east-2.hvm-ebs" = "ami-afc2e6ca" - "17.03.us-east-2.hvm-s3" = "ami-a1cde9c4" - "17.03.us-west-1.hvm-ebs" = "ami-587b2138" - "17.03.us-west-1.hvm-s3" = "ami-70411b10" - "17.03.us-west-2.hvm-ebs" = "ami-a93daac9" - "17.03.us-west-2.hvm-s3" = "ami-5139ae31" - "17.09.ap-northeast-1.hvm-ebs" = "ami-89b921ef" - "17.09.ap-northeast-2.hvm-ebs" = "ami-179b3b79" - "17.09.ap-south-1.hvm-ebs" = "ami-4e376021" - "17.09.ap-southeast-1.hvm-ebs" = "ami-84bccff8" - "17.09.ap-southeast-2.hvm-ebs" = "ami-0dc5386f" - "17.09.ca-central-1.hvm-ebs" = "ami-ca8207ae" - "17.09.eu-central-1.hvm-ebs" = "ami-266cfe49" - "17.09.eu-west-1.hvm-ebs" = "ami-a30192da" - "17.09.eu-west-2.hvm-ebs" = "ami-295a414d" - "17.09.eu-west-3.hvm-ebs" = "ami-8c0eb9f1" - "17.09.sa-east-1.hvm-ebs" = "ami-4762202b" - "17.09.us-east-1.hvm-ebs" = "ami-40bee63a" - "17.09.us-east-2.hvm-ebs" = "ami-9d84aff8" - "17.09.us-west-1.hvm-ebs" = "ami-d14142b1" - "17.09.us-west-2.hvm-ebs" = "ami-3eb40346" - "18.03.ap-northeast-1.hvm-ebs" = "ami-456511a8" - "18.03.ap-northeast-2.hvm-ebs" = "ami-3366d15d" - "18.03.ap-south-1.hvm-ebs" = "ami-6a390b05" - "18.03.ap-southeast-1.hvm-ebs" = "ami-aa0b4d40" - "18.03.ap-southeast-2.hvm-ebs" = "ami-d0f254b2" - "18.03.ca-central-1.hvm-ebs" = "ami-aca72ac8" - "18.03.eu-central-1.hvm-ebs" = "ami-09faf9e2" - "18.03.eu-west-1.hvm-ebs" = "ami-065c46ec" - "18.03.eu-west-2.hvm-ebs" = "ami-64f31903" - "18.03.eu-west-3.hvm-ebs" = "ami-5a8d3d27" - "18.03.sa-east-1.hvm-ebs" = "ami-163e1f7a" - "18.03.us-east-1.hvm-ebs" = "ami-8b3538f4" - "18.03.us-east-2.hvm-ebs" = "ami-150b3170" - "18.03.us-west-1.hvm-ebs" = "ami-ce06ebad" - "18.03.us-west-2.hvm-ebs" = "ami-586c3520" - "18.09.ap-northeast-1.hvm-ebs" = "ami-0cdba8e998f076547" - "18.09.ap-northeast-2.hvm-ebs" = "ami-0400a698e6a9f4a15" - "18.09.ap-south-1.hvm-ebs" = "ami-0880a678d3f555313" - "18.09.ap-southeast-1.hvm-ebs" = "ami-0892c7e24ebf2194f" - "18.09.ap-southeast-2.hvm-ebs" = "ami-010730f36424b0a2c" - "18.09.ca-central-1.hvm-ebs" = "ami-04f66113f76198f6c" - "18.09.eu-central-1.hvm-ebs" = "ami-07c9b884e679df4f8" - "18.09.eu-west-1.hvm-ebs" = "ami-0f412186fb8a0ec97" - "18.09.eu-west-2.hvm-ebs" = "ami-0dada3805ce43c55e" - "18.09.eu-west-3.hvm-ebs" = "ami-074df85565f2e02e2" - "18.09.sa-east-1.hvm-ebs" = "ami-0e4a8a47fd6db6112" - "18.09.us-east-1.hvm-ebs" = "ami-009c9c3f1af480ff3" - "18.09.us-east-2.hvm-ebs" = "ami-08199961085ea8bc6" - "18.09.us-west-1.hvm-ebs" = "ami-07aa7f56d612ddd38" - "18.09.us-west-2.hvm-ebs" = "ami-01c84b7c368ac24d1" - "19.03.ap-northeast-1.hvm-ebs" = "ami-00db62688900456a4" - "19.03.ap-northeast-2.hvm-ebs" = "ami-0485cdd1a5fdd2117" - "19.03.ap-south-1.hvm-ebs" = "ami-0303deb1b5890f878" - "19.03.ap-southeast-1.hvm-ebs" = "ami-0cff66114c652c262" - "19.03.ap-southeast-2.hvm-ebs" = "ami-054c73a7f8d773ea9" - "19.03.ca-central-1.hvm-ebs" = "ami-03f9fd0ef2e035ede" - "19.03.eu-central-1.hvm-ebs" = "ami-0022b8ea9efde5de4" - "19.03.eu-west-1.hvm-ebs" = "ami-0fe40176548ff0940" - "19.03.eu-west-2.hvm-ebs" = "ami-03a40fd3a02fe95ba" - "19.03.eu-west-3.hvm-ebs" = "ami-0436f9da0f20a638e" - "19.03.sa-east-1.hvm-ebs" = "ami-0c6a43c6e0ad1f4e2" - "19.03.us-east-1.hvm-ebs" = "ami-0efc58fb70ae9a217" - "19.03.us-east-2.hvm-ebs" = "ami-0abf711b1b34da1af" - "19.03.us-west-1.hvm-ebs" = "ami-07d126e8838c40ec5" - "19.03.us-west-2.hvm-ebs" = "ami-03f8a737546e47fb0" - "19.09.ap-east-1.hvm-ebs" = "ami-055b2348db2827ff1" - "19.09.ap-northeast-1.hvm-ebs" = "ami-02a62555ca182fb5b" - "19.09.ap-northeast-2.hvm-ebs" = "ami-0219dde0e6b7b7b93" - "19.09.ap-south-1.hvm-ebs" = "ami-066f7f2a895c821a1" - "19.09.ap-southeast-1.hvm-ebs" = "ami-0f71ae5d4b0b78d95" - "19.09.ap-southeast-2.hvm-ebs" = "ami-057bbf2b4bd62d210" - "19.09.ca-central-1.hvm-ebs" = "ami-07df50fc76702a36d" - "19.09.eu-central-1.hvm-ebs" = "ami-015f8efc2be419b79" - "19.09.eu-north-1.hvm-ebs" = "ami-07fc0a32d885e01ed" - "19.09.eu-west-1.hvm-ebs" = "ami-071082f0fa035374f" - "19.09.eu-west-2.hvm-ebs" = "ami-0d9dc33c54d1dc4c3" - "19.09.eu-west-3.hvm-ebs" = "ami-09566799591d1bfed" - "19.09.sa-east-1.hvm-ebs" = "ami-018aab68377227e06" - "19.09.us-east-1.hvm-ebs" = "ami-03330d8b51287412f" - "19.09.us-east-2.hvm-ebs" = "ami-0518b4c84972e967f" - "19.09.us-west-1.hvm-ebs" = "ami-06ad07e61a353b4a6" - "19.09.us-west-2.hvm-ebs" = "ami-0e31e30925cf3ce4e" - "20.03.ap-east-1.hvm-ebs" = "ami-0d18fdd309cdefa86" - "20.03.ap-northeast-1.hvm-ebs" = "ami-093d9cc49c191eb6c" - "20.03.ap-northeast-2.hvm-ebs" = "ami-0087df91a7b6ebd45" - "20.03.ap-south-1.hvm-ebs" = "ami-0a1a6b569af04af9d" - "20.03.ap-southeast-1.hvm-ebs" = "ami-0dbf353e168d155f7" - "20.03.ap-southeast-2.hvm-ebs" = "ami-04c0f3a75f63daddd" - "20.03.ca-central-1.hvm-ebs" = "ami-02365684a173255c7" - "20.03.eu-central-1.hvm-ebs" = "ami-0a1a94722dcbff94c" - "20.03.eu-north-1.hvm-ebs" = "ami-02699abfacbb6464b" - "20.03.eu-west-1.hvm-ebs" = "ami-02c34db5766cc7013" - "20.03.eu-west-2.hvm-ebs" = "ami-0e32bd8c7853883f1" - "20.03.eu-west-3.hvm-ebs" = "ami-061edb1356c1d69fd" - "20.03.sa-east-1.hvm-ebs" = "ami-09859378158ae971d" - "20.03.us-east-1.hvm-ebs" = "ami-0c5e7760748b74e85" - "20.03.us-east-2.hvm-ebs" = "ami-030296bb256764655" - "20.03.us-west-1.hvm-ebs" = "ami-050be818e0266b741" - "20.03.us-west-2.hvm-ebs" = "ami-06562f78dca68eda2" - "20.09.ap-east-1.hvm-ebs" = "ami-071f49713f86ea965" - "20.09.ap-northeast-1.hvm-ebs" = "ami-0beb18d632cf64e5a" - "20.09.ap-northeast-2.hvm-ebs" = "ami-0dd0316af578862db" - "20.09.ap-south-1.hvm-ebs" = "ami-008d15ced81c88aed" - "20.09.ap-southeast-1.hvm-ebs" = "ami-0db0304e23c535b2a" - "20.09.ap-southeast-2.hvm-ebs" = "ami-045983c4db7e36447" - "20.09.ca-central-1.hvm-ebs" = "ami-06d5ee429f153f856" - "20.09.eu-central-1.hvm-ebs" = "ami-01d4a0c2248cbfe38" - "20.09.eu-north-1.hvm-ebs" = "ami-0003f54dd99d68e0f" - "20.09.eu-west-1.hvm-ebs" = "ami-01a79d5ce435f4db3" - "20.09.eu-west-2.hvm-ebs" = "ami-0cbe14f32904e6331" - "20.09.eu-west-3.hvm-ebs" = "ami-07f493412d6213de6" - "20.09.sa-east-1.hvm-ebs" = "ami-05ded1ae35209b5a8" - "20.09.us-east-1.hvm-ebs" = "ami-068a62d478710462d" - "20.09.us-east-2.hvm-ebs" = "ami-01ac677ff61399caa" - "20.09.us-west-1.hvm-ebs" = "ami-04befdb203b4b17f6" - "20.09.us-west-2.hvm-ebs" = "ami-0fb7bd4a43261c6b2" - "latest.ap-east-1.hvm-ebs" = "ami-071f49713f86ea965" - "latest.ap-northeast-1.hvm-ebs" = "ami-0beb18d632cf64e5a" - "latest.ap-northeast-2.hvm-ebs" = "ami-0dd0316af578862db" - "latest.ap-south-1.hvm-ebs" = "ami-008d15ced81c88aed" - "latest.ap-southeast-1.hvm-ebs" = "ami-0db0304e23c535b2a" - "latest.ap-southeast-2.hvm-ebs" = "ami-045983c4db7e36447" - "latest.ca-central-1.hvm-ebs" = "ami-06d5ee429f153f856" - "latest.eu-central-1.hvm-ebs" = "ami-01d4a0c2248cbfe38" - "latest.eu-north-1.hvm-ebs" = "ami-0003f54dd99d68e0f" - "latest.eu-west-1.hvm-ebs" = "ami-01a79d5ce435f4db3" - "latest.eu-west-2.hvm-ebs" = "ami-0cbe14f32904e6331" - "latest.eu-west-3.hvm-ebs" = "ami-07f493412d6213de6" - "latest.sa-east-1.hvm-ebs" = "ami-05ded1ae35209b5a8" - "latest.us-east-1.hvm-ebs" = "ami-068a62d478710462d" - "latest.us-east-2.hvm-ebs" = "ami-01ac677ff61399caa" - "latest.us-west-1.hvm-ebs" = "ami-04befdb203b4b17f6" - "latest.us-west-2.hvm-ebs" = "ami-0fb7bd4a43261c6b2" - } - - description = "A map of release series to actual releases" -} diff --git a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/versions.tf b/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/versions.tf deleted file mode 100644 index ac97c6ac..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/aws_image_nixos/versions.tf +++ /dev/null @@ -1,4 +0,0 @@ - -terraform { - required_version = ">= 0.12" -} diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/README.md b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/README.md deleted file mode 100644 index a91f7af5..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/README.md +++ /dev/null @@ -1,129 +0,0 @@ -# deploy_nixos - -A Terraform module that knows how to deploy NixOS onto a target host. - -This allow to describe an infrastructure as code with Terraform and delegate -the machine configuration with NixOS. All directed by Terraform. - -The advantage of this method is that if any of the Nix code changes, the -difference will be detected on the next "terraform plan". - -## Usage - -Either pass a "config" which is a dynamic nixos configuration and a -"config_pwd", or a "nixos_config", a path to a nixos configuration.nix file. -If you have defined your NixOs configuration in a Flake, use "nixos_config" -to specify the name of the attribue and set "flake" to true. - -### Secret handling - -Keys can be passed to the "keys" attribute. Each key will be installed under -`/var/keys/${key}` with the content as the value. - -For services to access one of the keys, add the service user to the "keys" -group. - -The target machine needs `jq` installed prior to the deployment (as part of -the base image). If `jq` is not found it will try to use a version from -``. - -### Disabling sandboxing - -Unfortunately some time it's required to disable the nix sandboxing. To do so, -add `["--option", "sandbox", "false"]` to the "extra_build_args" parameter. - -If that doesn't work, make sure that your user is part of the nix -"trusted-users" list. - -### Non-root `target_user` - -It is possible to connect to the target host using a user that is not `root` -under certain conditions: - -* sudo needs to be installed on the machine -* the user needs password-less sudo access on the machine - -This would typically be provisioned in the base image. - -### Binary cache configuration - -One thing that might be surprising is that the binary caches (aka -substituters) are taken from the machine configuration. This implies that the -user Nix configuration will be ignored in that regard. - -## Dependencies - -* `bash` 4.0+ -* `nix` -* `openssh` -* `readlink` with `-f` (coreutils or busybox) - -## Known limitations - -The deployment machine requires Nix with access to a remote builder with the -same system as the target machine. - -Because Nix code is being evaluated at "terraform plan" time, deploying a lot -of machine in the same target will require a lot of RAM. - -All the secrets share the same "keys" group. - -When deploying as non-root, it assumes that passwordless `sudo` is available. - -The target host must already have NixOS installed. - -### config including computed values - -The module doesn't work when `` values from other resources are -interpolated with the "config" attribute. Because it happens at evaluation -time, terraform will render an empty drvPath. - -see also: -* https://github.com/hashicorp/terraform/issues/16380 -* https://github.com/hashicorp/terraform/issues/16762 -* https://github.com/hashicorp/terraform/issues/17034 - - -## Requirements - -| Name | Version | -|------|---------| -| terraform | >= 0.12 | - -## Providers - -| Name | Version | -|------|---------| -| external | n/a | -| null | n/a | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| NIX\_PATH | Allow to pass custom NIX\_PATH | `string` | `""` | no | -| build\_on\_target | Avoid building on the deployer. Must be true or false. Has no effect when deploying from an incompatible system. Unlike remote builders, this does not require the deploying user to be trusted by its host. | `string` | `false` | no | -| config | NixOS configuration to be evaluated. This argument is required unless 'nixos\_config' is given | `string` | `""` | no | -| config\_pwd | Directory to evaluate the configuration in. This argument is required if 'config' is given | `string` | `""` | no | -| extra\_build\_args | List of arguments to pass to the nix builder | `list(string)` | `[]` | no | -| extra\_eval\_args | List of arguments to pass to the nix evaluation | `list(string)` | `[]` | no | -| hermetic | Treat the provided nixos configuration as a hermetic expression and do not evaluate using the ambient system nixpkgs. Useful if you customize eval-modules or use a pinned nixpkgs. | `bool` | false | no | -| flake | Treat the provided nixos_config as the name of the NixOS configuration to use in the flake located in the current directory. Useful if you customize eval-modules or use a pinned nixpkgs. | `bool` | false | no | -| keys | A map of filename to content to upload as secrets in /var/keys | `map(string)` | `{}` | no | -| nixos\_config | Path to a NixOS configuration | `string` | `""` | no | -| ssh\_agent | Whether to use an SSH agent. True if not ssh\_private\_key is passed | `bool` | `null` | no | -| ssh\_private\_key | Content of private key used to connect to the target\_host | `string` | `""` | no | -| ssh\_private\_key\_file | Path to private key used to connect to the target\_host | `string` | `""` | no | -| target\_host | DNS host to deploy to | `string` | n/a | yes | -| target\_port | SSH port used to connect to the target\_host | `number` | `22` | no | -| target\_system | Nix system string | `string` | `"x86_64-linux"` | no | -| target\_user | SSH user used to connect to the target\_host | `string` | `"root"` | no | -| triggers | Triggers for deploy | `map(string)` | `{}` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| id | random ID that changes on every nixos deployment | - - diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/main.tf b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/main.tf deleted file mode 100644 index c217ce5c..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/main.tf +++ /dev/null @@ -1,221 +0,0 @@ -variable "target_host" { - type = string - description = "DNS host to deploy to" -} - -variable "target_user" { - type = string - description = "SSH user used to connect to the target_host" - default = "root" -} - -variable "target_port" { - type = number - description = "SSH port used to connect to the target_host" - default = 22 -} - -variable "ssh_private_key" { - type = string - description = "Content of private key used to connect to the target_host" - default = "" -} - -variable "ssh_private_key_file" { - type = string - description = "Path to private key used to connect to the target_host" - default = "" -} - -variable "ssh_agent" { - type = bool - description = "Whether to use an SSH agent. True if not ssh_private_key is passed" - default = null -} - -variable "NIX_PATH" { - type = string - description = "Allow to pass custom NIX_PATH" - default = "" -} - -variable "nixos_config" { - type = string - description = "Path to a NixOS configuration" - default = "" -} - -variable "config" { - type = string - description = "NixOS configuration to be evaluated. This argument is required unless 'nixos_config' is given" - default = "" -} - -variable "config_pwd" { - type = string - description = "Directory to evaluate the configuration in. This argument is required if 'config' is given" - default = "" -} - -variable "extra_eval_args" { - type = list(string) - description = "List of arguments to pass to the nix evaluation" - default = [] -} - -variable "extra_build_args" { - type = list(string) - description = "List of arguments to pass to the nix builder" - default = [] -} - -variable "build_on_target" { - type = string - description = "Avoid building on the deployer. Must be true or false. Has no effect when deploying from an incompatible system. Unlike remote builders, this does not require the deploying user to be trusted by its host." - default = false -} - -variable "triggers" { - type = map(string) - description = "Triggers for deploy" - default = {} -} - -variable "keys" { - type = map(string) - description = "A map of filename to content to upload as secrets in /var/keys" - default = {} -} - -variable "target_system" { - type = string - description = "Nix system string" - default = "x86_64-linux" -} - -variable "hermetic" { - type = bool - description = "Treat the provided nixos configuration as a hermetic expression and do not evaluate using the ambient system nixpkgs. Useful if you customize eval-modules or use a pinned nixpkgs." - default = false -} - -variable "flake" { - type = bool - description = "Treat the provided nixos_config as the NixOS configuration to use in the flake located in the current directory" - default = false -} - -variable "delete_older_than" { - type = string - description = "Can be a list of generation numbers, the special value old to delete all non-current generations, a value such as 30d to delete all generations older than the specified number of days (except for the generation that was active at that point in time), or a value such as +5 to keep the last 5 generations ignoring any newer than current, e.g., if 30 is the current generation +5 will delete generation 25 and all older generations." - default = "+1" -} - -variable "deploy_environment" { - type = map(string) - description = "Extra environment variables to be set during deployment." - default = {} -} - -# -------------------------------------------------------------------------- - -locals { - triggers = { - deploy_nixos_drv = data.external.nixos-instantiate.result["drv_path"] - deploy_nixos_keys = sha256(jsonencode(var.keys)) - } - - extra_build_args = concat([ - "--option", "substituters", data.external.nixos-instantiate.result["substituters"], - "--option", "trusted-public-keys", data.external.nixos-instantiate.result["trusted-public-keys"], - ], - var.extra_build_args, - ) - ssh_private_key_file = var.ssh_private_key_file == "" ? "-" : var.ssh_private_key_file - ssh_private_key = local.ssh_private_key_file == "-" ? var.ssh_private_key : file(local.ssh_private_key_file) - ssh_agent = var.ssh_agent == null ? (local.ssh_private_key != "") : var.ssh_agent - build_on_target = data.external.nixos-instantiate.result["currentSystem"] != var.target_system ? true : tobool(var.build_on_target) -} - -# used to detect changes in the configuration -data "external" "nixos-instantiate" { - program = concat([ - "${path.module}/nixos-instantiate.sh", - var.NIX_PATH == "" ? "-" : var.NIX_PATH, - var.config != "" ? var.config : var.nixos_config, - var.config_pwd == "" ? "." : var.config_pwd, - var.flake, - # end of positional arguments - # start of pass-through arguments - "--argstr", "system", var.target_system, - "--arg", "hermetic", var.hermetic - ], - var.extra_eval_args, - ) -} - -resource "null_resource" "deploy_nixos" { - triggers = merge(var.triggers, local.triggers) - - connection { - type = "ssh" - host = var.target_host - port = var.target_port - user = var.target_user - agent = local.ssh_agent - timeout = "100s" - private_key = local.ssh_private_key == "-" ? "" : local.ssh_private_key - } - - # copy the secret keys to the host - provisioner "file" { - content = jsonencode(var.keys) - destination = "packed-keys.json" - } - - # FIXME: move this to nixos-deploy.sh - provisioner "file" { - source = "${path.module}/unpack-keys.sh" - destination = "unpack-keys.sh" - } - - # FIXME: move this to nixos-deploy.sh - provisioner "file" { - source = "${path.module}/maybe-sudo.sh" - destination = "maybe-sudo.sh" - } - - provisioner "remote-exec" { - inline = [ - "chmod +x unpack-keys.sh maybe-sudo.sh", - "./maybe-sudo.sh ./unpack-keys.sh ./packed-keys.json", - ] - } - - # do the actual deployment - provisioner "local-exec" { - environment = var.deploy_environment - interpreter = concat([ - "${path.module}/nixos-deploy.sh", - data.external.nixos-instantiate.result["drv_path"], - data.external.nixos-instantiate.result["out_path"], - "${var.target_user}@${var.target_host}", - var.target_port, - local.build_on_target, - local.ssh_private_key == "" ? "-" : local.ssh_private_key, - "switch", - var.delete_older_than, - ], - local.extra_build_args - ) - command = "ignoreme" - } -} - -# -------------------------------------------------------------------------- - -output "id" { - description = "random ID that changes on every nixos deployment" - value = null_resource.deploy_nixos.id -} - diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/maybe-sudo.sh b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/maybe-sudo.sh deleted file mode 100755 index 989d8b2f..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/maybe-sudo.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -# -# Run sudo if required -# -# Usage: ./maybe-sudo.sh [...args] -set -euo pipefail -if [[ "$UID" = 0 ]]; then - exec -- "$@" -else - exec sudo -- "$@" -fi diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-deploy.sh b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-deploy.sh deleted file mode 100755 index 319651bb..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-deploy.sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env bash -# nixos-deploy deploys a nixos-instantiate-generated drvPath to a target host -# -# Usage: nixos-deploy.sh [] ignoreme -set -euo pipefail - -### Defaults ### - -buildArgs=( - --option extra-binary-caches https://cache.nixos.org/ -) -profile=/nix/var/nix/profiles/system -# will be set later -sshOpts=( - -o "ControlMaster=auto" - -o "ControlPersist=60" - # Avoid issues with IP re-use. This disable TOFU security. - -o "StrictHostKeyChecking=no" - -o "UserKnownHostsFile=/dev/null" - -o "GlobalKnownHostsFile=/dev/null" - # interactive authentication is not possible - -o "BatchMode=yes" - # verbose output for easier debugging - -v -) - -### Argument parsing ### - -drvPath="$1" -outPath="$2" -targetHost="$3" -targetPort="$4" -buildOnTarget="$5" -sshPrivateKey="$6" -action="$7" -deleteOlderThan="$8" -shift 8 - -# remove the last argument -set -- "${@:1:$(($# - 1))}" -buildArgs+=("$@") - -sshOpts+=( -p "${targetPort}" ) - -workDir=$(mktemp -d) -trap 'rm -rf "$workDir"' EXIT - -if [[ -n "${sshPrivateKey}" && "${sshPrivateKey}" != "-" ]]; then - sshPrivateKeyFile="$workDir/ssh_key" - echo "$sshPrivateKey" > "$sshPrivateKeyFile" - chmod 0700 "$sshPrivateKeyFile" - sshOpts+=( -o "IdentityFile=${sshPrivateKeyFile}" ) -fi - -### Functions ### - -log() { - echo "--- $*" >&2 -} - -copyToTarget() { - NIX_SSHOPTS="${sshOpts[*]}" nix-copy-closure --to "$targetHost" "$@" -} - -# assumes that passwordless sudo is enabled on the server -targetHostCmd() { - # ${*@Q} escapes the arguments losslessly into space-separted quoted strings. - # `ssh` did not properly maintain the array nature of the command line, - # erroneously splitting arguments with internal spaces, even when using `--`. - # Tested with OpenSSH_7.9p1. - # - # shellcheck disable=SC2029 - ssh "${sshOpts[@]}" "$targetHost" "./maybe-sudo.sh ${*@Q}" -} - -# Setup a temporary ControlPath for this session. This speeds-up the -# operations by not re-creating SSH sessions between each command. At the end -# of the run, the session is forcefully terminated. -setupControlPath() { - sshOpts+=( - -o "ControlPath=$workDir/ssh_control" - ) - cleanupControlPath() { - local ret=$? - # Avoid failing during the shutdown - set +e - # Close ssh multiplex-master process gracefully - log "closing persistent ssh-connection" - ssh "${sshOpts[@]}" -O stop "$targetHost" - rm -rf "$workDir" - exit "$ret" - } - trap cleanupControlPath EXIT -} - -### Main ### - -setupControlPath - -if [[ "${buildOnTarget:-false}" == true ]]; then - - # Upload derivation - log "uploading derivations" - copyToTarget "$drvPath" --gzip --use-substitutes - - # Build remotely - log "building on target" - set -x - targetHostCmd "nix-store" "--realize" "$drvPath" "${buildArgs[@]}" - -else - - # Build derivation - log "building on deployer" - outPath=$(nix-store --realize "$drvPath" "${buildArgs[@]}") - - # Upload build results - log "uploading build results" - copyToTarget "$outPath" --gzip --use-substitutes - -fi - -# Activate -log "activating configuration" -targetHostCmd nix-env --profile "$profile" --set "$outPath" -targetHostCmd "$outPath/bin/switch-to-configuration" "$action" - -# Cleanup previous generations -log "collecting old nix derivations" -# Deliberately not quoting $deleteOlderThan so the user can configure something like "1 2 3" -# to keep generations with those numbers -targetHostCmd "nix-env" "--profile" "$profile" "--delete-generations" $deleteOlderThan -targetHostCmd "nix-store" "--gc" diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-instantiate.sh b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-instantiate.sh deleted file mode 100755 index ad4763f0..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/nixos-instantiate.sh +++ /dev/null @@ -1,94 +0,0 @@ -#! /usr/bin/env bash -set -euo pipefail - -# Args -nix_path=$1 -config=$2 -config_pwd=$3 -flake=$4 -shift 4 - - -command=(nix-instantiate --show-trace --expr ' - { system, configuration, hermetic ? false, flake ? false, ... }: - let - importFromFlake = { nixosConfig }: - let - flake = (import ( - fetchTarball { - url = "https://github.com/edolstra/flake-compat/archive/99f1c2157fba4bfe6211a321fd0ee43199025dbf.tar.gz"; - sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2"; } - ) { - src = ./.; - }).defaultNix; - in - builtins.getAttr nixosConfig flake.nixosConfigurations; - os = - if flake - then importFromFlake { nixosConfig = configuration; } - else if hermetic - then - ( - if builtins.isString configuration - # case: nixos_config i.e. file path - then import configuration - # case: config i.e. the module expression itself - else configuration - ) - else - import { inherit system configuration; }; - in { - inherit (builtins) currentSystem; - - substituters = - builtins.concatStringsSep " " os.config.nix.binaryCaches; - - trusted-public-keys = - builtins.concatStringsSep " " os.config.nix.binaryCachePublicKeys; - - drv_path = os.config.system.build.toplevel.drvPath; - out_path = os.config.system.build.toplevel; - }') - -if readlink --version | grep -q GNU; then - readlink="readlink -f" -else - if command -v greadlink &> /dev/null; then - readlink="greadlink -f" - else - echo "Warning: symlinks not supported because readlink is non GNU" >&2 - readlink="realpath" - fi -fi - -if [[ -f "$config" ]]; then - config=$($readlink "$config") - command+=(--argstr configuration "$config") -else - if $flake; then - command+=(--argstr configuration "$config" --arg flake true) - else - command+=(--arg configuration "$config") - fi -fi - -# add all extra CLI args as extra build arguments -command+=("$@") - -# Setting the NIX_PATH -if [[ -n "$nix_path" && "$nix_path" != "-" ]]; then - export NIX_PATH=$nix_path -fi - -# Changing directory -cd "$($readlink "$config_pwd")" - -# Instantiate -echo "running (instantiating): ${NIX_PATH:+NIX_PATH=$NIX_PATH} ${command[*]@Q}" -A out_path >&2 -"${command[@]}" -A out_path >/dev/null - -# Evaluate some more details, -# relying on preceding "Instantiate" command to perform the instantiation, -# because `--eval` is required but doesn't instantiate for some reason. -echo "running (evaluating): ${NIX_PATH:+NIX_PATH=$NIX_PATH} ${command[*]@Q}" --eval --strict --json >&2 -"${command[@]}" --eval --strict --json diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/unpack-keys.sh b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/unpack-keys.sh deleted file mode 100755 index 82ead0b8..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/unpack-keys.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash -# -# Unpacks the packed-keys.json into individual keys -set -euo pipefail -shopt -s nullglob - -keys_file=${1:-packed-keys.json} -keys_dir=/var/keys - -if [[ ! -f "$keys_file" ]]; then - echo "error: $keys_file not found" - exit 1 -fi - -# Fallback if jq is not installed -if ! type -p jq &>/dev/null; then - jqOut=$(nix-build '' -A jq) - jq() { - "$jqOut/bin/jq" "$@" - } -fi - -# cleanup -mkdir -m 0750 -p "$keys_dir" -chown -v root:keys "$keys_dir" -chmod -v 0750 "$keys_dir" -for key in "$keys_dir"/* ; do - rm -v "$key" -done - -if [[ $(< "$keys_file") = "{}" ]]; then - echo "no keys to unpack" - exit -fi - -echo "unpacking $keys_file" - -# extract the keys from .packed.json -for keyname in $(jq -S -r 'keys[]' "$keys_file"); do - echo "unpacking: $keyname" - jq -r ".\"$keyname\"" < "$keys_file" > "$keys_dir/$keyname" - chmod 0640 "$keys_dir/$keyname" - chown root:keys "$keys_dir/$keyname" -done - -echo "unpacking done" diff --git a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/versions.tf b/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/versions.tf deleted file mode 100644 index ac97c6ac..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/deploy_nixos/versions.tf +++ /dev/null @@ -1,4 +0,0 @@ - -terraform { - required_version = ">= 0.12" -} diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/google/deploy_nixos.tf b/launch/.terraform/modules/pixelfed.deploy/examples/google/deploy_nixos.tf deleted file mode 100644 index b77054c3..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/examples/google/deploy_nixos.tf +++ /dev/null @@ -1,82 +0,0 @@ -# Here we have an example of how a machine can be provisioned with some config -# after boot. This is useful in case one doesn't want to unecessarily destroy -# and create VMs in a pet scenario. - -data "google_compute_network" "default" { - name = "default" -} - -resource "google_compute_firewall" "deploy-nixos" { - name = "deploy-nixos" - network = data.google_compute_network.default.name - - allow { - protocol = "icmp" - } - - // Allow SSH access - allow { - protocol = "tcp" - ports = ["22"] - } - - // To vm tagged with: nixos - target_tags = ["nixos"] - direction = "INGRESS" - - // From anywhere. - source_ranges = ["0.0.0.0/0"] -} - -resource "google_compute_instance" "deploy-nixos" { - name = "deploy-nixos-example" - machine_type = "n1-standard-1" - zone = "us-central1-a" - - // Bind the firewall rules - tags = ["nixos"] - - boot_disk { - initialize_params { - // Start with an image the deployer can SSH into - image = module.nixos_image_custom.self_link - size = "20" - } - } - - network_interface { - network = "default" - - // Give it a public IP - access_config {} - } - - lifecycle { - // No need to re-deploy the machine if the image changed - // NixOS is already immutable - ignore_changes = [boot_disk] - } -} - -module "deploy_nixos" { - source = "../../deploy_nixos" - - // Deploy the given NixOS configuration. In this case it's the same as the - // original image. So if the configuration is changed later it will be - // deployed here. - nixos_config = "${path.module}/image_nixos_custom.nix" - - target_user = "root" - target_host = google_compute_instance.deploy-nixos.network_interface[0].access_config[0].nat_ip - - triggers = { - // Also re-deploy whenever the VM is re-created - instance_id = google_compute_instance.deploy-nixos.id - } - - // Pass some secrets. See the terraform-provider-secret to handle secrets - // in Terraform - keys = { - foo = "bar" - } -} diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos.tf b/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos.tf deleted file mode 100644 index 3ee88645..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos.tf +++ /dev/null @@ -1,25 +0,0 @@ -# Here is a simple example that instantiates the google image and spins up an -# instance - -module "nixos_image_1809" { - source = "../../google_image_nixos" - nixos_version = "18.09" -} - -// This instance is not very useful since it doesn't contain any -// configuration. This could be fixed by passing a user metadata script. -resource "google_compute_instance" "image-nixos" { - name = "image-nixos" - machine_type = "n1-standard-1" - zone = "us-central1-a" - - boot_disk { - initialize_params { - image = module.nixos_image_1809.self_link - } - } - - network_interface { - network = "default" - } -} diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.nix b/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.nix deleted file mode 100644 index e67a92ff..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ modulesPath, ... }: -{ - imports = [ - # Make sure to have this in all your configurations - "${toString modulesPath}/virtualisation/google-compute-image.nix" - ]; - - # Bake the deploy's SSH key into the image. This is not - # kosher Nix. - users.users.root.openssh.authorizedKeys.keyFiles = [ - (/. + builtins.getEnv("HOME") + "/.ssh/id_rsa.pub") - ]; -} diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.tf b/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.tf deleted file mode 100644 index 243b4c44..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/examples/google/image_nixos_custom.tf +++ /dev/null @@ -1,21 +0,0 @@ -# create a random ID for the bucket -resource "random_id" "bucket" { - byte_length = 8 -} - -# create a bucket to upload the image into -resource "google_storage_bucket" "nixos-images" { - name = "nixos-images-${random_id.bucket.hex}" - location = "EU" -} - -# create a custom nixos base image the deployer can SSH into -# -# this could also include much more configuration and be used to feed the -# auto-scaler with system images -module "nixos_image_custom" { - source = "../../google_image_nixos_custom" - bucket_name = google_storage_bucket.nixos-images.name - - nixos_config = "${path.module}/image_nixos_custom.nix" -} diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/google/provider.tf b/launch/.terraform/modules/pixelfed.deploy/examples/google/provider.tf deleted file mode 100644 index 910bae3e..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/examples/google/provider.tf +++ /dev/null @@ -1,3 +0,0 @@ -provider "google" { - project = "tweag-digital-assets" -} diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/configuration.nix b/launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/configuration.nix deleted file mode 100644 index ea32c12f..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/configuration.nix +++ /dev/null @@ -1,60 +0,0 @@ -# A simple, hermetic NixOS configuration for an AWS EC2 instance that -# uses a nixpkgs pinned to a specific Git revision with an integrity -# hash to ensure that we construct a NixOS system as purely as -# possible. -# -# i.e. we explicitly specify which nixpkgs to use instead of relying -# on the nixpkgs supplied on the NIX_PATH. -# -# The primary benefit of this is that it removes deployment surprises -# when other developers supply a different nix-channel in the NIX_PATH -# of their environment (even if you only add the 20.09 channel, -# nix-channel --update can mutate that channel to a 20.09 with -# backported changes). -# -# The secondary benefit is that you guard the `nixpkgs` you use, with -# an integrity hash. -let - nixpkgs = - let - rev = "cd63096d6d887d689543a0b97743d28995bc9bc3"; - sha256 = "1wg61h4gndm3vcprdcg7rc4s1v3jkm5xd7lw8r2f67w502y94gcy"; - in - builtins.fetchTarball { - url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz"; - inherit sha256; - }; - - system = "x86_64-linux"; - - configuration = { config, pkgs, ... }: { - imports = [ - "${nixpkgs}/nixos/modules/virtualisation/amazon-image.nix" - ]; - - ec2.hvm = true; - - networking.firewall.allowedTCPPorts = [ 22 80 ]; - - environment.systemPackages = [ - pkgs.cloud-utils - ]; - - services.nginx = { - enable = true; - virtualHosts = { - "_" = { - root = pkgs.writeTextDir "html/index.html" '' - - -

This is a hermetic NixOS configuration!

- - - ''; - }; - }; - }; - }; - -in - import "${nixpkgs}/nixos" { inherit system configuration; } diff --git a/launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/default.tf b/launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/default.tf deleted file mode 100644 index f3fa7115..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/examples/hermetic_config/default.tf +++ /dev/null @@ -1,27 +0,0 @@ -provider "aws" { - region = "us-east-1" - profile = "yourprofile" -} - -resource "aws_instance" "hermetic-nixos-system" { - count = 1 - ami = "ami-068a62d478710462d" # NixOS 20.09 AMI - - instance_type = "t2.micro" - - key_name = "yourkeyname" - - tags = { - Name = "hermetic-nixos-system-example" - Description = "An example of a hermetic NixOS system deployed by Terraform" - } -} - -module "deploy_nixos" { - source = "github.com/awakesecurity/terraform-nixos//deploy_nixos?ref=c4b1ee6d24b54e92fa3439a12bce349a6805bcdd" - nixos_config = "${path.module}/configuration.nix" - hermetic = true - target_user = "root" - target_host = aws_instance.hermetic-nixos-system[0].public_ip - ssh_private_key_file = pathexpand("~/.ssh/yourkeyname.pem") -} diff --git a/launch/.terraform/modules/pixelfed.deploy/fmt b/launch/.terraform/modules/pixelfed.deploy/fmt deleted file mode 100755 index fd5c9125..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/fmt +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash -# -set -euo pipefail - -cd "$(dirname "$0")" - -terraform fmt - -fmt_docs() { - ./scripts/terraform-docs-updater "$1" -} - -fmt_docs deploy_nixos -fmt_docs google_image_nixos -fmt_docs google_image_nixos_custom - -echo "." diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/README.md b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/README.md deleted file mode 100644 index 593652b8..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# `google_image_nixos` - -This terraform module creates a new image in the Google Cloud project using a -public tarballs of a NixOS release. Those tarballs are released by the NixOS -project. - -Since image names are unique, only one instance per version of the module is -supported per Google Cloud project. - -## Example - -```hcl -module "nixos_image_1809" { - source = "github.com/tweag/terraform-nixos/google_image_nixos" - nixos_version = "18.09" -} - -resource "google_compute_instance" "example" { - name = "example" - machine_type = "n1-standard-1" - zone = "us-central1-a" - - boot_disk { - initialize_params { - image = module.nixos_image_1809.self_link - } - } - - network_interface { - network = "default" - } -} -``` - -### Default configuration.nix - -A new configuration.nix can be passed trough the userdata. Here is the default -configuration to expand upon: - -```nix -{ modulesPath, ... }: -{ - imports = [ - "${toString modulesPath}/virtualisation/google-compute-image.nix" - ]; -} -``` - -## New NixOS releases - -Run the `./update-url-map` script to fetch new image releases. Please submit a -PR as well! - - -## Providers - -| Name | Version | -|------|---------| -| google | n/a | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:-----:| -| gcp\_project\_id | The ID of the project in which the resource belongs. If it is not provided, the provider project is used. | `string` | `""` | no | -| licenses | A list of license URIs to apply to this image. Changing this forces a new resource to be created. | `list(string)` |
[
"https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
]
| no | -| nixos\_version | The NixOS version to use. Eg: 18.09 | `string` | `"latest"` | no | -| url\_map | A map of release series to actual releases | `map(string)` |
{
"14.12": "https://nixos-cloud-images.storage.googleapis.com/nixos-14.12.471.1f09b77-x86_64-linux.raw.tar.gz",
"15.09": "https://nixos-cloud-images.storage.googleapis.com/nixos-15.09.425.7870f20-x86_64-linux.raw.tar.gz",
"16.03": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-16.03.847.8688c17-x86_64-linux.raw.tar.gz",
"17.03": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-17.03.1082.4aab5c5798-x86_64-linux.raw.tar.gz",
"18.03": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.03.132536.fdb5ba4cdf9-x86_64-linux.raw.tar.gz",
"18.09": "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.09.1228.a4c4cbb613c-x86_64-linux.raw.tar.gz",
"20.03": "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz",
"latest": "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz"
}
| no | - -## Outputs - -| Name | Description | -|------|-------------| -| self\_link | Link to the NixOS Compute Image | - - diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/main.tf b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/main.tf deleted file mode 100644 index b42e28dd..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/main.tf +++ /dev/null @@ -1,64 +0,0 @@ -variable "nixos_version" { - type = string - default = "latest" - description = "The NixOS version to use. Eg: 18.09" -} - -variable "gcp_project_id" { - type = string - default = "" - description = "The ID of the project in which the resource belongs. If it is not provided, the provider project is used." -} - -variable "labels" { - type = map(string) - default = {} - description = "A map of labels applied to this image." -} - -variable "licenses" { - type = list(string) - - default = [ - "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx", - ] - - description = "A list of license URIs to apply to this image. Changing this forces a new resource to be created." -} - -# --- - -locals { - image_url = var.url_map[var.nixos_version] - - # Example: nixos-image-18-09-1228-a4c4cbb613c-x86-64-linux - # - # Remove a few things so that it matches the required regexp for image names - # (?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?) - image_name = replace( - replace(basename(local.image_url), ".raw.tar.gz", ""), - "/[._]+/", - "-", - ) -} - -resource "google_compute_image" "nixos" { - name = local.image_name - description = "NixOS ${var.nixos_version}" - family = "nixos" - project = var.gcp_project_id - labels = var.labels - licenses = var.licenses - - raw_disk { - source = local.image_url - } -} - -# --- - -output "self_link" { - description = "Link to the NixOS Compute Image" - value = google_compute_image.nixos.self_link -} - diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/update-url-map b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/update-url-map deleted file mode 100755 index 4b9722ff..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/update-url-map +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env nix-shell -#!nix-shell -p ruby -i ruby -# vim: ft=ruby -# -# Run this script to update the list of GCE images -# -require "json" -require "uri" - -ENV['NIX_PATH'] = "nixpkgs=channel:nixpkgs-unstable" - -def render_tf - url_map=JSON.load(`nix-instantiate --json --strict --eval ./url_map.nix`) - - out = <<~HEADER - # DON'T EDIT, run $0 instead - variable "url_map" { - type = map(string) - - default = { - HEADER - - url_map.each_pair do |version, gs_url| - u = URI.parse(gs_url) - # convert the gs:// URL to HTTPS URL for Terraform to consume - # - # Eg: "gs://nixos-cloud-images/nixos-image-18.09-x86_64-linux.raw.tar.gz" - https_url = "https://#{u.host}.storage.googleapis.com#{u.path}" - - out += " %- 8s = %s\n" % [ version.inspect, https_url.inspect] - end - - out += <<~FOOTER - } - - description = "A map of release series to actual releases" - } - FOOTER -end - -url_map_tf = render_tf - -open("url_map.tf", "w") do |f| - f.write(url_map_tf) -end - -puts url_map_tf diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.nix b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.nix deleted file mode 100644 index 7b341ced..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.nix +++ /dev/null @@ -1,2 +0,0 @@ -# Indirect link to where the image map is stored -import diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.tf b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.tf deleted file mode 100644 index aa898a67..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/url_map.tf +++ /dev/null @@ -1,17 +0,0 @@ -# DON'T EDIT, run $0 instead -variable "url_map" { - type = map(string) - - default = { - "14.12" = "https://nixos-cloud-images.storage.googleapis.com/nixos-14.12.471.1f09b77-x86_64-linux.raw.tar.gz" - "15.09" = "https://nixos-cloud-images.storage.googleapis.com/nixos-15.09.425.7870f20-x86_64-linux.raw.tar.gz" - "16.03" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-16.03.847.8688c17-x86_64-linux.raw.tar.gz" - "17.03" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-17.03.1082.4aab5c5798-x86_64-linux.raw.tar.gz" - "18.03" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.03.132536.fdb5ba4cdf9-x86_64-linux.raw.tar.gz" - "18.09" = "https://nixos-cloud-images.storage.googleapis.com/nixos-image-18.09.1228.a4c4cbb613c-x86_64-linux.raw.tar.gz" - "20.03" = "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz" - "latest" = "https://nixos-images.storage.googleapis.com/google-cloud-nixos-20.03.1639.73e73c7d6b5.raw.tar.gz" - } - - description = "A map of release series to actual releases" -} diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/versions.tf b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/versions.tf deleted file mode 100644 index ac97c6ac..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos/versions.tf +++ /dev/null @@ -1,4 +0,0 @@ - -terraform { - required_version = ">= 0.12" -} diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/README.md b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/README.md deleted file mode 100644 index ef2fafda..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# google_cloud_image_nixos - -This terraform module builds and publishes custom NixOS Google Cloud images. - -## Runtime dependencies - -Because this module uses the "external" provider it needs the following -executables to be in the path to work properly: - -* bash -* nix -* `readlink -f` (busybox or coreutils) - -## Known limitations - -NixOS images are built at Terraform plan time. This can make the plan quite -slow. - -Building the image doesn't yield any output, unless the build is interrupted or -failed. - -When a new image is published, the old-one gets removed. This potentially -introduces a race-condition where other targets are trying to create new -instances with the old image. To reduce the race window, `create_before_destroy` is being used. See -https://github.com/hashicorp/terraform/issues/15485 for related discussions. - -Only x86_64-linux is currently supported. - - -## Providers - -| Name | Version | -|------|---------| -| external | n/a | -| google | n/a | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:-----:| -| NIX\_PATH | Allow to pass custom NIX\_PATH. Ignored if `-` or empty. | `string` | `"-"` | no | -| bucket\_name | Bucket where to store the image | `any` | n/a | yes | -| gcp\_project\_id | The ID of the project in which the resource belongs. If it is not provided, the provider project is used. | `string` | `""` | no | -| licenses | A list of license URIs to apply to this image. Changing this forces a new resource to be created. | `list(string)` |
[
"https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
]
| no | -| nixos\_config | Path to a nixos configuration.nix file | `any` | n/a | yes | - -## Outputs - -| Name | Description | -|------|-------------| -| NIX\_PATH | n/a | -| self\_link | n/a | - - diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/main.tf b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/main.tf deleted file mode 100644 index 9ceaed5d..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/main.tf +++ /dev/null @@ -1,94 +0,0 @@ -variable "bucket_name" { - description = "Bucket where to store the image" -} - -variable "nixos_config" { - description = "Path to a nixos configuration.nix file" -} - -variable "NIX_PATH" { - type = string - description = "Allow to pass custom NIX_PATH. Ignored if `-` or empty." - default = "-" -} - -variable "gcp_project_id" { - type = string - default = "" - description = "The ID of the project in which the resource belongs. If it is not provided, the provider project is used." -} - -variable "licenses" { - type = list(string) - - default = [ - "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx", - ] - - description = "A list of license URIs to apply to this image. Changing this forces a new resource to be created." -} - -# ---------------------------------------------------- - -data "external" "nix_build" { - program = ["${path.module}/nixos-build.sh", var.NIX_PATH, var.nixos_config] -} - -locals { - out_path = data.external.nix_build.result.out_path - image_path = data.external.nix_build.result.image_path - - # 3x2d4rdm9kjzk9d9sz87rmhzvcphs23v - out_hash = element(split("-", basename(local.out_path)), 0) - - # Example: 3x2d4rdm9kjzk9d9sz87rmhzvcphs23v-19-03pre-git-x86-64-linux - # - # Remove a few things so that it matches the required regexp for image names - # (?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?) - image_name = "x${substr(local.out_hash, 0, 12)}-${replace( - replace( - basename(local.image_path), - "/\\.raw\\.tar\\.gz|nixos-image-/", - "", - ), - "/[._]+/", - "-", - )}" - - # 3x2d4rdm9kjzk9d9sz87rmhzvcphs23v-nixos-image-19.03pre-git-x86_64-linux.raw.tar.gz - image_filename = "${local.out_hash}-${basename(local.image_path)}" -} - -resource "google_storage_bucket_object" "nixos" { - name = "images/${local.image_filename}" - source = local.image_path - bucket = var.bucket_name - content_type = "application/tar+gzip" - - lifecycle { - create_before_destroy = true - } -} - -resource "google_compute_image" "nixos" { - name = local.image_name - family = "nixos" - project = var.gcp_project_id - licenses = var.licenses - - raw_disk { - source = "https://${var.bucket_name}.storage.googleapis.com/${google_storage_bucket_object.nixos.name}" - } - - lifecycle { - create_before_destroy = true - } -} - -output "self_link" { - value = google_compute_image.nixos.self_link -} - -output "NIX_PATH" { - value = var.NIX_PATH -} diff --git a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/nixos-build.sh b/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/nixos-build.sh deleted file mode 100755 index 270d6ca0..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/google_image_nixos_custom/nixos-build.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash -# Special version of nix-build that integrates with the Terraform external -# provider -set -euo pipefail - -nix_path="${1}" -nixos_config=$(readlink -f "${2:-./configuration.nix}") - -shift -shift - -if [[ -n "$nix_path" && "$nix_path" != "-" ]]; then - export NIX_PATH=$nix_path -fi - -args=( - --arg configuration "$nixos_config" - --argstr system x86_64-linux - --no-out-link - -A config.system.build.googleComputeImage -) - -out_path=$(nix-build '' "${args[@]}" "$@") - -image_path= -for path in "$out_path"/*.tar.gz; do - image_path=$path -done - -cat </dev/null ; then - if [[ -f "$doc.bak" ]]; then - echo "$doc.bak file detected, aborting" >&2 - exit 1 - fi - - mv "$doc" "$doc.bak" - { - sed "/$BANNER_START/q" "$doc.bak" - terraform-docs md . - sed -n -e "/$BANNER_END/,\$p" "$doc.bak" - } > "$doc" - - rm "$doc.bak" -else - { - echo "$BANNER_START" - terraform-docs md . - echo "$BANNER_END" - } >> "$doc" -fi diff --git a/launch/.terraform/modules/pixelfed.deploy/shell.nix b/launch/.terraform/modules/pixelfed.deploy/shell.nix deleted file mode 100644 index 1d044982..00000000 --- a/launch/.terraform/modules/pixelfed.deploy/shell.nix +++ /dev/null @@ -1,21 +0,0 @@ -with import {}; -let - tf = terraform.withPlugins(p: with p; [ - external - google - p.null - random - ]); - # https://github.com/NixOS/nixpkgs/pull/51579 - terraform-docs = callPackage ./nix/terraform-docs {}; -in -mkShell { - buildInputs = [ - tf - terraform-docs - ]; - - shellHook = '' - NIX_PATH=nixpkgs=channel:nixos-18.09 - ''; -} diff --git a/launch/.terraform/plugin_path b/launch/.terraform/plugin_path deleted file mode 100644 index 0a21d939..00000000 --- a/launch/.terraform/plugin_path +++ /dev/null @@ -1,3 +0,0 @@ -[ - "/nix/store/mnqkwjg5v6sx86an34b4cn075h0lapz3-opentofu-1.8.7/libexec/terraform-providers" -] \ No newline at end of file -- 2.48.1 From 4f83f51e17e99ae33d014d1c5fdd4a5641d80f05 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Thu, 10 Apr 2025 10:07:30 +0200 Subject: [PATCH 32/57] rm .auto.tfvars.json, as the local ssh key and socket are not relevant deployed --- launch/.auto.tfvars.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 launch/.auto.tfvars.json diff --git a/launch/.auto.tfvars.json b/launch/.auto.tfvars.json deleted file mode 100644 index 88a25b33..00000000 --- a/launch/.auto.tfvars.json +++ /dev/null @@ -1 +0,0 @@ -{"ssh_private_key_file": "/home/kiara/.ssh/id_ed25519", "deploy_environment": {"SSH_AUTH_SOCK": "/tmp/ssh-XXXXXXNmOXeE/agent.1456243"}} -- 2.48.1 From 8f785d7582017677fc7d4fbe8dc0e19cba987834 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Thu, 10 Apr 2025 11:12:39 +0200 Subject: [PATCH 33/57] point deployed TF to panel ssh key --- infra/machines/fedi201/fedipanel.nix | 4 +++- panel/src/panel/views.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/infra/machines/fedi201/fedipanel.nix b/infra/machines/fedi201/fedipanel.nix index c3cc7a33..9660e1ad 100644 --- a/infra/machines/fedi201/fedipanel.nix +++ b/infra/machines/fedi201/fedipanel.nix @@ -1,6 +1,5 @@ { config, - pkgs, ... }: let @@ -55,6 +54,9 @@ in CSRF_TRUSTED_ORIGINS = [ "https://${cfg.domain}" ]; COMPRESS_OFFLINE = true; LIBSASS_OUTPUT_STYLE = "compressed"; + ENV_VARS = { + ssh_private_key_file = config.age.secrets.panel-ssh-key.path; + }; }; secrets = { SECRET_KEY = config.age.secrets.panel-secret-key.path; diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index bab35088..a023aa29 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -146,7 +146,7 @@ class DeploymentStatus(ConfigurationForm): } | { # pass in form info to our deployment # FIXME: ensure sensitive info is protected - f"TF_VAR_{k}": v if isinstance(v, str) else json.dumps(v) for k, v in deployment_params.items() + f"TF_VAR_{k}": v if isinstance(v, str) else json.dumps(v) for k, v in (settings.ENV_VARS | deployment_params).items() } cwd = f"{settings.repo_dir}/launch" cmd = [ -- 2.48.1 From 8a50680b9ff53e1b96aa2381a04ff7b2ea447054 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Thu, 10 Apr 2025 14:01:07 +0200 Subject: [PATCH 34/57] document dev process --- launch/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/launch/README.md b/launch/README.md index a3c83086..94cea9eb 100644 --- a/launch/README.md +++ b/launch/README.md @@ -14,6 +14,10 @@ $ echo "{\"terraform-nixos\": $(nix-instantiate --eval --json -E '(import ../npi ```sh $ nix-shell +$ eval "$(ssh-agent -s)" +# set your ssh key, e.g.: +$ ssh_key="$(readlink -f ~/.ssh/id_ed25519)" +$ echo "{\"ssh_private_key_file\": \"${ssh_key}\", \"deploy_environment\": {\"SSH_AUTH_SOCK\": \"${SSH_AUTH_SOCK}\"}}" > .auto.tfvars.json $ rm -rf .terraform/ $ tofu init ``` -- 2.48.1 From f87275e384ee8e275365895f1b6a095b76226b81 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 09:33:18 +0200 Subject: [PATCH 35/57] use proper logger --- panel/src/panel/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index a023aa29..db460764 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -2,6 +2,7 @@ from enum import Enum import json from os.path import expanduser import subprocess +import logging import os from django.urls import reverse_lazy @@ -158,5 +159,5 @@ class DeploymentStatus(ConfigurationForm): "-lock=false", ] deployment_result = subprocess.run(cmd, cwd=cwd, env=env) - print(deployment_result) + logging.info(deployment_result) return deployment_result, deployment_params -- 2.48.1 From 1a8d940a903f19e9d0bbe95318e18ecb60951e10 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 09:56:00 +0200 Subject: [PATCH 36/57] log to file --- .gitignore | 1 + panel/default.nix | 1 + panel/nix/configuration.nix | 1 + panel/src/panel/settings.py | 10 +++++++++- 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7aa68143..53f806b1 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ result* *screenshot.png output todo +log/ diff --git a/panel/default.nix b/panel/default.nix index 06d1a487..6c214660 100644 --- a/panel/default.nix +++ b/panel/default.nix @@ -31,6 +31,7 @@ in DATABASE_URL = "sqlite:///${toString ./src}/db.sqlite3"; # locally: use a fixed relative reference, so we can use our newest files without copying to the store REPO_DIR = toString ../.; + LOGGING_DIR = "../log"; }; shellHook = '' ln -sf ${sources.htmx}/dist/htmx.js src/panel/static/htmx.min.js diff --git a/panel/nix/configuration.nix b/panel/nix/configuration.nix index 54653c18..b9b72899 100644 --- a/panel/nix/configuration.nix +++ b/panel/nix/configuration.nix @@ -30,6 +30,7 @@ let (builtins.toFile "extra-settings.py" cfg.extra-settings) ]; REPO_DIR = import ../../launch/tf-env.nix { inherit lib pkgs; }; + LOGGING_DIR = "/var/log/${name}"; }; python-environment = pkgs.python3.withPackages ( diff --git a/panel/src/panel/settings.py b/panel/src/panel/settings.py index ccdb8308..cb313c53 100644 --- a/panel/src/panel/settings.py +++ b/panel/src/panel/settings.py @@ -175,6 +175,9 @@ COMPRESS_PRECOMPILERS = [ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +logging_dir = env["LOGGING_DIR"] +os.makedirs(logging_dir, mode=0o700, exist_ok=True) + LOGGING = { "version": 1, "disable_existing_loggers": False, @@ -209,10 +212,15 @@ LOGGING = { "filters": ["require_debug_false"], "class": "django.utils.log.AdminEmailHandler", }, + "file": { + "level": "INFO", + "class": "logging.FileHandler", + "filename": f"{logging_dir}/info.log", + }, }, "loggers": { "django": { - "handlers": ["console", "mail_admins"], + "handlers": ["console", "mail_admins", "file"], "level": "INFO", }, "django.server": { -- 2.48.1 From 265d79aeef256094e2be277a8e3c0ce6bfcf967d Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 10:27:11 +0200 Subject: [PATCH 37/57] local vars --- infra/machines/fedi201/fedipanel.nix | 9 ++++++--- panel/env.nix | 1 + panel/src/panel/settings.py | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/infra/machines/fedi201/fedipanel.nix b/infra/machines/fedi201/fedipanel.nix index 9660e1ad..01996096 100644 --- a/infra/machines/fedi201/fedipanel.nix +++ b/infra/machines/fedi201/fedipanel.nix @@ -1,5 +1,6 @@ { config, + lib, ... }: let @@ -54,10 +55,12 @@ in CSRF_TRUSTED_ORIGINS = [ "https://${cfg.domain}" ]; COMPRESS_OFFLINE = true; LIBSASS_OUTPUT_STYLE = "compressed"; - ENV_VARS = { - ssh_private_key_file = config.age.secrets.panel-ssh-key.path; - }; }; + environment = { + TF_VARS = lib.strings.toJSON { + ssh_private_key_file = config.age.secrets.panel-ssh-key.path; + }; + }; secrets = { SECRET_KEY = config.age.secrets.panel-secret-key.path; }; diff --git a/panel/env.nix b/panel/env.nix index 9482b2a0..ea8a1048 100644 --- a/panel/env.nix +++ b/panel/env.nix @@ -13,4 +13,5 @@ pkgs.gnugrep # used in terraform-nixos (import ../launch/tf.nix { inherit lib pkgs; }) ]; + TF_VARS = lib.strings.toJSON { }; } diff --git a/panel/src/panel/settings.py b/panel/src/panel/settings.py index cb313c53..46275178 100644 --- a/panel/src/panel/settings.py +++ b/panel/src/panel/settings.py @@ -14,6 +14,7 @@ import re import sys import subprocess import os +import json import importlib.util import dj_database_url @@ -257,3 +258,6 @@ bin_path=env['BIN_PATH'] # path of the root flake to trigger nixops from, see #94. # to deploy this should be specified, for dev just use a relative path. repo_dir = env["REPO_DIR"] + +ENV_VARS = json.loads(env["TF_VARS"]) | { +} -- 2.48.1 From 553753218e4729b3bc63e7423772f858ad98f4cf Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 11:33:59 +0200 Subject: [PATCH 38/57] pass vars separately --- infra/machines/fedi201/fedipanel.nix | 6 ------ panel/env.nix | 2 +- panel/nix/configuration.nix | 1 + panel/src/panel/settings.py | 3 ++- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/infra/machines/fedi201/fedipanel.nix b/infra/machines/fedi201/fedipanel.nix index 01996096..b49471bb 100644 --- a/infra/machines/fedi201/fedipanel.nix +++ b/infra/machines/fedi201/fedipanel.nix @@ -1,6 +1,5 @@ { config, - lib, ... }: let @@ -56,11 +55,6 @@ in COMPRESS_OFFLINE = true; LIBSASS_OUTPUT_STYLE = "compressed"; }; - environment = { - TF_VARS = lib.strings.toJSON { - ssh_private_key_file = config.age.secrets.panel-ssh-key.path; - }; - }; secrets = { SECRET_KEY = config.age.secrets.panel-secret-key.path; }; diff --git a/panel/env.nix b/panel/env.nix index ea8a1048..e98622a5 100644 --- a/panel/env.nix +++ b/panel/env.nix @@ -13,5 +13,5 @@ pkgs.gnugrep # used in terraform-nixos (import ../launch/tf.nix { inherit lib pkgs; }) ]; - TF_VARS = lib.strings.toJSON { }; + SSH_PRIVATE_KEY_FILE = ""; } diff --git a/panel/nix/configuration.nix b/panel/nix/configuration.nix index b9b72899..5d2cf719 100644 --- a/panel/nix/configuration.nix +++ b/panel/nix/configuration.nix @@ -31,6 +31,7 @@ let ]; REPO_DIR = import ../../launch/tf-env.nix { inherit lib pkgs; }; LOGGING_DIR = "/var/log/${name}"; + SSH_PRIVATE_KEY_FILE = config.age.secrets.panel-ssh-key.path; }; python-environment = pkgs.python3.withPackages ( diff --git a/panel/src/panel/settings.py b/panel/src/panel/settings.py index 46275178..ac914f0c 100644 --- a/panel/src/panel/settings.py +++ b/panel/src/panel/settings.py @@ -259,5 +259,6 @@ bin_path=env['BIN_PATH'] # to deploy this should be specified, for dev just use a relative path. repo_dir = env["REPO_DIR"] -ENV_VARS = json.loads(env["TF_VARS"]) | { +ENV_VARS = { + "ssh_private_key_file": env["SSH_PRIVATE_KEY_FILE"], } -- 2.48.1 From b0942bd174d5874a1fef7417587cf3c5637c6f21 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 11:36:18 +0200 Subject: [PATCH 39/57] Revert "log to file" This reverts commit 1a8d940a903f19e9d0bbe95318e18ecb60951e10. --- .gitignore | 1 - panel/default.nix | 1 - panel/nix/configuration.nix | 1 - panel/src/panel/settings.py | 10 +--------- 4 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 53f806b1..7aa68143 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,3 @@ result* *screenshot.png output todo -log/ diff --git a/panel/default.nix b/panel/default.nix index 6c214660..06d1a487 100644 --- a/panel/default.nix +++ b/panel/default.nix @@ -31,7 +31,6 @@ in DATABASE_URL = "sqlite:///${toString ./src}/db.sqlite3"; # locally: use a fixed relative reference, so we can use our newest files without copying to the store REPO_DIR = toString ../.; - LOGGING_DIR = "../log"; }; shellHook = '' ln -sf ${sources.htmx}/dist/htmx.js src/panel/static/htmx.min.js diff --git a/panel/nix/configuration.nix b/panel/nix/configuration.nix index 5d2cf719..bfab0e4e 100644 --- a/panel/nix/configuration.nix +++ b/panel/nix/configuration.nix @@ -30,7 +30,6 @@ let (builtins.toFile "extra-settings.py" cfg.extra-settings) ]; REPO_DIR = import ../../launch/tf-env.nix { inherit lib pkgs; }; - LOGGING_DIR = "/var/log/${name}"; SSH_PRIVATE_KEY_FILE = config.age.secrets.panel-ssh-key.path; }; diff --git a/panel/src/panel/settings.py b/panel/src/panel/settings.py index ac914f0c..f13cd510 100644 --- a/panel/src/panel/settings.py +++ b/panel/src/panel/settings.py @@ -176,9 +176,6 @@ COMPRESS_PRECOMPILERS = [ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' -logging_dir = env["LOGGING_DIR"] -os.makedirs(logging_dir, mode=0o700, exist_ok=True) - LOGGING = { "version": 1, "disable_existing_loggers": False, @@ -213,15 +210,10 @@ LOGGING = { "filters": ["require_debug_false"], "class": "django.utils.log.AdminEmailHandler", }, - "file": { - "level": "INFO", - "class": "logging.FileHandler", - "filename": f"{logging_dir}/info.log", - }, }, "loggers": { "django": { - "handlers": ["console", "mail_admins", "file"], + "handlers": ["console", "mail_admins"], "level": "INFO", }, "django.server": { -- 2.48.1 From a41405775e23231a5d842d72989c138ac4fdaa8e Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 12:31:36 +0200 Subject: [PATCH 40/57] get ssh socket in prod --- panel/nix/configuration.nix | 8 +++----- panel/src/panel/settings.py | 5 +++++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/panel/nix/configuration.nix b/panel/nix/configuration.nix index bfab0e4e..6061e559 100644 --- a/panel/nix/configuration.nix +++ b/panel/nix/configuration.nix @@ -159,16 +159,14 @@ in }; }; - users.users.${name} = { - isNormalUser = true; - }; + users.users.${name}.isNormalUser = true; - users.groups.${name} = { }; systemd.services.${name} = { description = "${name} ASGI server"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; path = [ + pkgs.openssh python-environment manage-service ]; @@ -187,7 +185,7 @@ in ''; serviceConfig = { Restart = "always"; - User = "root"; + User = name; WorkingDirectory = "/var/lib/${name}"; StateDirectory = name; RuntimeDirectory = name; diff --git a/panel/src/panel/settings.py b/panel/src/panel/settings.py index f13cd510..d05dfbd1 100644 --- a/panel/src/panel/settings.py +++ b/panel/src/panel/settings.py @@ -251,6 +251,11 @@ bin_path=env['BIN_PATH'] # to deploy this should be specified, for dev just use a relative path. repo_dir = env["REPO_DIR"] +output = subprocess.run(["ssh-agent"], capture_output=True, text=True, env={"PATH": bin_path}).stdout +ssh_auth_sock = re.search("(?<==)([^;]*)", output)[1] ENV_VARS = { "ssh_private_key_file": env["SSH_PRIVATE_KEY_FILE"], + "deploy_environment": { + "SSH_AUTH_SOCK": ssh_auth_sock, + }, } -- 2.48.1 From 81011d00624c7294f07aeb0846bb7cedbb6b5720 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 12:31:47 +0200 Subject: [PATCH 41/57] pass deploy env vars thru --- launch/main.tf | 4 ++++ launch/vm/main.tf | 1 + 2 files changed, 5 insertions(+) diff --git a/launch/main.tf b/launch/main.tf index fc1a7692..4370a1c2 100644 --- a/launch/main.tf +++ b/launch/main.tf @@ -73,6 +73,7 @@ variable "deploy_environment" { # initialUser = var.initialUser # terraform-nixos = var.terraform-nixos # ssh_private_key_file = var.ssh_private_key_file +# deploy_environment = var.deploy_environment # } module "mastodon" { @@ -84,6 +85,7 @@ module "mastodon" { initialUser = var.initialUser terraform-nixos = var.terraform-nixos ssh_private_key_file = var.ssh_private_key_file + deploy_environment = var.deploy_environment } module "pixelfed" { @@ -95,6 +97,7 @@ module "pixelfed" { initialUser = var.initialUser terraform-nixos = var.terraform-nixos ssh_private_key_file = var.ssh_private_key_file + deploy_environment = var.deploy_environment } module "peertube" { @@ -106,4 +109,5 @@ module "peertube" { initialUser = var.initialUser terraform-nixos = var.terraform-nixos ssh_private_key_file = var.ssh_private_key_file + deploy_environment = var.deploy_environment } diff --git a/launch/vm/main.tf b/launch/vm/main.tf index 5ea1caf4..e356f0f6 100644 --- a/launch/vm/main.tf +++ b/launch/vm/main.tf @@ -48,6 +48,7 @@ module "deploy" { target_user= "root" # FIXME: #24 target_system = local.system NIX_PATH = "nixpkgs=${local.nixpkgs}:sources=${local.sources}" + deploy_environment = var.deploy_environment hermetic = true config_pwd = path.root config = <<-EOT -- 2.48.1 From 9c53abfb4c6ab4b4a611eb3d586ccd6b491fe79a Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 13:38:19 +0200 Subject: [PATCH 42/57] fix logging levels so info gets shown too, not just warn --- panel/src/panel/settings.py | 17 ++++++++--------- panel/src/panel/views.py | 2 ++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/panel/src/panel/settings.py b/panel/src/panel/settings.py index d05dfbd1..91aa5824 100644 --- a/panel/src/panel/settings.py +++ b/panel/src/panel/settings.py @@ -192,13 +192,17 @@ LOGGING = { "()": "django.utils.log.ServerFormatter", "format": "[{server_time}] {message}", "style": "{", - } + }, + "standard": { + "format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s" + }, }, "handlers": { "console": { "level": "INFO", # "filters": ["require_debug_true"], "class": "logging.StreamHandler", + "formatter": "standard", }, "django.server": { "level": "INFO", @@ -212,14 +216,9 @@ LOGGING = { }, }, "loggers": { - "django": { - "handlers": ["console", "mail_admins"], - "level": "INFO", - }, - "django.server": { - "handlers": ["django.server"], - "level": "INFO", - "propagate": False, + "": { + "handlers": ["console"], + "level": "DEBUG" if DEBUG else "INFO", }, }, } diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index db460764..9615b035 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -15,6 +15,8 @@ from django.shortcuts import render from panel import models, settings from panel.configuration import forms +logger = logging.getLogger(__name__) + class Index(TemplateView): template_name = 'index.html' -- 2.48.1 From d4860c8aedad48d8bf95c4a10ecb8296e81bcf65 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 14:08:55 +0200 Subject: [PATCH 43/57] switch subprocess output to logger --- panel/src/panel/settings.py | 4 ++++ panel/src/panel/views.py | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/panel/src/panel/settings.py b/panel/src/panel/settings.py index 91aa5824..27398b47 100644 --- a/panel/src/panel/settings.py +++ b/panel/src/panel/settings.py @@ -223,6 +223,10 @@ LOGGING = { }, } +SECONDS_PER_MINUTE = 60 +DEPLOY_TIMEOUT_MINUTES = 25 +DEPLOY_TIMEOUT_SECONDS = DEPLOY_TIMEOUT_MINUTES * SECONDS_PER_MINUTE + # Customization via user settings # This must be at the end, as it must be able to override the above # TODO(@fricklerhandwerk): diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 9615b035..96279c8c 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -1,6 +1,7 @@ from enum import Enum import json from os.path import expanduser +from subprocess import Popen, PIPE, STDOUT import subprocess import logging import os @@ -160,6 +161,11 @@ class DeploymentStatus(ConfigurationForm): "--auto-approve", "-lock=false", ] - deployment_result = subprocess.run(cmd, cwd=cwd, env=env) - logging.info(deployment_result) + popen = Popen(cmd, cwd=cwd, env=env, stdout=PIPE, stderr=STDOUT) + with popen.stdout: + for line in iter(popen.stdout.readline, b''): + logger.info(line.decode('utf-8').strip()) + # FIXME catch subprocess.TimeoutExpired + deployment_result = popen.wait(timeout=settings.DEPLOY_TIMEOUT_SECONDS) + logger.info(f"deployment_result: {deployment_result}") return deployment_result, deployment_params -- 2.48.1 From 1983508fb17b4b8ca2b27536d64e382fd5cdbf9a Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 14:10:55 +0200 Subject: [PATCH 44/57] Reapply "log to file" This reverts commit b0942bd174d5874a1fef7417587cf3c5637c6f21. --- .gitignore | 1 + panel/default.nix | 1 + panel/nix/configuration.nix | 1 + panel/src/panel/settings.py | 10 +++++++++- 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7aa68143..53f806b1 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ result* *screenshot.png output todo +log/ diff --git a/panel/default.nix b/panel/default.nix index 06d1a487..6c214660 100644 --- a/panel/default.nix +++ b/panel/default.nix @@ -31,6 +31,7 @@ in DATABASE_URL = "sqlite:///${toString ./src}/db.sqlite3"; # locally: use a fixed relative reference, so we can use our newest files without copying to the store REPO_DIR = toString ../.; + LOGGING_DIR = "../log"; }; shellHook = '' ln -sf ${sources.htmx}/dist/htmx.js src/panel/static/htmx.min.js diff --git a/panel/nix/configuration.nix b/panel/nix/configuration.nix index 6061e559..4cc4e9ea 100644 --- a/panel/nix/configuration.nix +++ b/panel/nix/configuration.nix @@ -30,6 +30,7 @@ let (builtins.toFile "extra-settings.py" cfg.extra-settings) ]; REPO_DIR = import ../../launch/tf-env.nix { inherit lib pkgs; }; + LOGGING_DIR = "/var/log/${name}"; SSH_PRIVATE_KEY_FILE = config.age.secrets.panel-ssh-key.path; }; diff --git a/panel/src/panel/settings.py b/panel/src/panel/settings.py index 27398b47..52761d60 100644 --- a/panel/src/panel/settings.py +++ b/panel/src/panel/settings.py @@ -176,6 +176,9 @@ COMPRESS_PRECOMPILERS = [ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +logging_dir = env["LOGGING_DIR"] +os.makedirs(logging_dir, mode=0o700, exist_ok=True) + LOGGING = { "version": 1, "disable_existing_loggers": False, @@ -214,10 +217,15 @@ LOGGING = { "filters": ["require_debug_false"], "class": "django.utils.log.AdminEmailHandler", }, + "file": { + "level": "INFO", + "class": "logging.FileHandler", + "filename": f"{logging_dir}/info.log", + }, }, "loggers": { "": { - "handlers": ["console"], + "handlers": ["console", "file"], "level": "DEBUG" if DEBUG else "INFO", }, }, -- 2.48.1 From 60093212d71c4330a28d2008b175a290b94edcdd Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 14:36:21 +0200 Subject: [PATCH 45/57] Revert "Reapply "log to file"" This reverts commit 1983508fb17b4b8ca2b27536d64e382fd5cdbf9a. --- .gitignore | 1 - panel/default.nix | 1 - panel/nix/configuration.nix | 1 - panel/src/panel/settings.py | 10 +--------- 4 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 53f806b1..7aa68143 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,3 @@ result* *screenshot.png output todo -log/ diff --git a/panel/default.nix b/panel/default.nix index 6c214660..06d1a487 100644 --- a/panel/default.nix +++ b/panel/default.nix @@ -31,7 +31,6 @@ in DATABASE_URL = "sqlite:///${toString ./src}/db.sqlite3"; # locally: use a fixed relative reference, so we can use our newest files without copying to the store REPO_DIR = toString ../.; - LOGGING_DIR = "../log"; }; shellHook = '' ln -sf ${sources.htmx}/dist/htmx.js src/panel/static/htmx.min.js diff --git a/panel/nix/configuration.nix b/panel/nix/configuration.nix index 4cc4e9ea..6061e559 100644 --- a/panel/nix/configuration.nix +++ b/panel/nix/configuration.nix @@ -30,7 +30,6 @@ let (builtins.toFile "extra-settings.py" cfg.extra-settings) ]; REPO_DIR = import ../../launch/tf-env.nix { inherit lib pkgs; }; - LOGGING_DIR = "/var/log/${name}"; SSH_PRIVATE_KEY_FILE = config.age.secrets.panel-ssh-key.path; }; diff --git a/panel/src/panel/settings.py b/panel/src/panel/settings.py index 52761d60..27398b47 100644 --- a/panel/src/panel/settings.py +++ b/panel/src/panel/settings.py @@ -176,9 +176,6 @@ COMPRESS_PRECOMPILERS = [ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' -logging_dir = env["LOGGING_DIR"] -os.makedirs(logging_dir, mode=0o700, exist_ok=True) - LOGGING = { "version": 1, "disable_existing_loggers": False, @@ -217,15 +214,10 @@ LOGGING = { "filters": ["require_debug_false"], "class": "django.utils.log.AdminEmailHandler", }, - "file": { - "level": "INFO", - "class": "logging.FileHandler", - "filename": f"{logging_dir}/info.log", - }, }, "loggers": { "": { - "handlers": ["console", "file"], + "handlers": ["console"], "level": "DEBUG" if DEBUG else "INFO", }, }, -- 2.48.1 From 45c53ec1502cb3d0d819c47bfa7a3fa7d2e4bdee Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 14:36:25 +0200 Subject: [PATCH 46/57] Revert "switch subprocess output to logger" This reverts commit d4860c8aedad48d8bf95c4a10ecb8296e81bcf65. --- panel/src/panel/settings.py | 4 ---- panel/src/panel/views.py | 10 ++-------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/panel/src/panel/settings.py b/panel/src/panel/settings.py index 27398b47..91aa5824 100644 --- a/panel/src/panel/settings.py +++ b/panel/src/panel/settings.py @@ -223,10 +223,6 @@ LOGGING = { }, } -SECONDS_PER_MINUTE = 60 -DEPLOY_TIMEOUT_MINUTES = 25 -DEPLOY_TIMEOUT_SECONDS = DEPLOY_TIMEOUT_MINUTES * SECONDS_PER_MINUTE - # Customization via user settings # This must be at the end, as it must be able to override the above # TODO(@fricklerhandwerk): diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 96279c8c..9615b035 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -1,7 +1,6 @@ from enum import Enum import json from os.path import expanduser -from subprocess import Popen, PIPE, STDOUT import subprocess import logging import os @@ -161,11 +160,6 @@ class DeploymentStatus(ConfigurationForm): "--auto-approve", "-lock=false", ] - popen = Popen(cmd, cwd=cwd, env=env, stdout=PIPE, stderr=STDOUT) - with popen.stdout: - for line in iter(popen.stdout.readline, b''): - logger.info(line.decode('utf-8').strip()) - # FIXME catch subprocess.TimeoutExpired - deployment_result = popen.wait(timeout=settings.DEPLOY_TIMEOUT_SECONDS) - logger.info(f"deployment_result: {deployment_result}") + deployment_result = subprocess.run(cmd, cwd=cwd, env=env) + logging.info(deployment_result) return deployment_result, deployment_params -- 2.48.1 From 2cc96eb530d7e47403781395b8bb654e8a0cfd91 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 16:45:52 +0200 Subject: [PATCH 47/57] configure debug printing --- panel/src/panel/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 9615b035..68749fe3 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -146,11 +146,13 @@ class DeploymentStatus(ConfigurationForm): # in local dev, it will just reject the `/tmp` and make it in HOME after all. "HOME": "/tmp", "XDG_CACHE_HOME": "/tmp", + # "TF_LOG": "info", } | { # pass in form info to our deployment # FIXME: ensure sensitive info is protected f"TF_VAR_{k}": v if isinstance(v, str) else json.dumps(v) for k, v in (settings.ENV_VARS | deployment_params).items() } + logger.info("env: %s", env) cwd = f"{settings.repo_dir}/launch" cmd = [ "tofu", @@ -161,5 +163,5 @@ class DeploymentStatus(ConfigurationForm): "-lock=false", ] deployment_result = subprocess.run(cmd, cwd=cwd, env=env) - logging.info(deployment_result) + logger.debug("deployment_result: %s", deployment_result) return deployment_result, deployment_params -- 2.48.1 From 3418d0e76dc5793483cd03c4a691ea6bf91849bd Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 22:11:23 +0200 Subject: [PATCH 48/57] get terraform-nixos working deployed --- launch/module.auto.tfvars.json | 2 +- launch/vm/main.tf | 3 ++- npins/sources.json | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/launch/module.auto.tfvars.json b/launch/module.auto.tfvars.json index 0d108435..131e4db7 100644 --- a/launch/module.auto.tfvars.json +++ b/launch/module.auto.tfvars.json @@ -1 +1 @@ -{"terraform-nixos": "/nix/store/8mh14khb56hqyslxhla0nzdzi2wp6wp7-source"} +{"terraform-nixos": "/nix/store/7rx25dwsw2xv9462rk2vkwy4qv33w76x-source"} diff --git a/launch/vm/main.tf b/launch/vm/main.tf index e356f0f6..3407dc07 100644 --- a/launch/vm/main.tf +++ b/launch/vm/main.tf @@ -68,7 +68,8 @@ module "deploy" { ]; } EOT - # build_on_target = false + perform_gc = false + build_on_target = false # triggers = { # # pins = data.external.pins.result # } diff --git a/npins/sources.json b/npins/sources.json index 24541c01..80035ee4 100644 --- a/npins/sources.json +++ b/npins/sources.json @@ -79,10 +79,10 @@ "owner": "KiaraGrouwstra", "repo": "terraform-nixos" }, - "branch": "env-hermetic", - "revision": "cc28d99966d0c742265d1551c622383fd775dd30", - "url": "https://github.com/KiaraGrouwstra/terraform-nixos/archive/cc28d99966d0c742265d1551c622383fd775dd30.tar.gz", - "hash": "17a01my75ccxpn5h40w3855hkj2mkfm0q0chxwxcnq8g9hh67waj" + "branch": "fediversity", + "revision": "54c57ae2e8c312c1b9f69524462d588966ed23b4", + "url": "https://github.com/KiaraGrouwstra/terraform-nixos/archive/54c57ae2e8c312c1b9f69524462d588966ed23b4.tar.gz", + "hash": "1yxps17ac5sljd1ri2p1q1x9h8dcxfpcf0hh6wcpic8ydwy45qql" } }, "version": 3 -- 2.48.1 From d955e39f4c1da5cb51bf1b66de77a820e25c86f5 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sat, 12 Apr 2025 22:18:21 +0200 Subject: [PATCH 49/57] simplify tf --- launch/main.tf | 49 +++++++++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/launch/main.tf b/launch/main.tf index 4370a1c2..c1ac39c8 100644 --- a/launch/main.tf +++ b/launch/main.tf @@ -64,6 +64,23 @@ variable "deploy_environment" { default = {} } +locals { + applications = { + mastodon = { + cfg = var.mastodon + hostname = "test06" + } + pixelfed = { + cfg = var.pixelfed + hostname = "test04" + } + peertube = { + cfg = var.peertube + hostname = "test03" + } + } +} + # module "garage" { # source = "./vm" # count = var.mastodon.enable || var.pixelfed.enable || var.peertube.enable ? 1 : 0 @@ -76,38 +93,14 @@ variable "deploy_environment" { # deploy_environment = var.deploy_environment # } -module "mastodon" { +module "nixos" { source = "./vm" - count = var.mastodon.enable ? 1 : 0 domain = var.domain - hostname = "test06" - config = "mastodon" - initialUser = var.initialUser - terraform-nixos = var.terraform-nixos - ssh_private_key_file = var.ssh_private_key_file - deploy_environment = var.deploy_environment -} - -module "pixelfed" { - source = "./vm" - count = var.pixelfed.enable ? 1 : 0 - domain = var.domain - hostname = "test04" - config = "pixelfed" - initialUser = var.initialUser - terraform-nixos = var.terraform-nixos - ssh_private_key_file = var.ssh_private_key_file - deploy_environment = var.deploy_environment -} - -module "peertube" { - source = "./vm" - count = var.peertube.enable ? 1 : 0 - domain = var.domain - hostname = "test03" - config = "peertube" initialUser = var.initialUser terraform-nixos = var.terraform-nixos ssh_private_key_file = var.ssh_private_key_file deploy_environment = var.deploy_environment + for_each = { for name, inst in local.applications : name => inst if inst.cfg.enable } + config = each.key + hostname = each.value.hostname } -- 2.48.1 From ef214ced106304c6329fa769fd4079878117da73 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 13 Apr 2025 13:11:04 +0200 Subject: [PATCH 50/57] merge tf modules --- launch/garage.nix | 19 +++++------ launch/main.tf | 70 ++++++++++++++++++++++++++++++----------- launch/shared.nix | 5 ++- launch/vm/main.tf | 80 ----------------------------------------------- 4 files changed, 61 insertions(+), 113 deletions(-) delete mode 100644 launch/vm/main.tf diff --git a/launch/garage.nix b/launch/garage.nix index b79614f4..559ca37f 100644 --- a/launch/garage.nix +++ b/launch/garage.nix @@ -1,3 +1,4 @@ +{ pkgs, ... }: let ## NOTE: All of these secrets are publicly available in this source file ## and will end up in the Nix store. We don't care as they are only ever @@ -23,15 +24,11 @@ let s3SecretKeyFile = pkgs.writeText "s3SecretKey" "5be6799a88ca9b9d813d1a806b64f15efa49482dbe15339ddfaf7f19cf434987"; }; in -import ./shared.nix { - module = - { pkgs, ... }: - { - fediversity = { - garage.enable = true; - pixelfed = pixelfedS3KeyConfig { inherit pkgs; }; - mastodon = mastodonS3KeyConfig { inherit pkgs; }; - peertube = peertubeS3KeyConfig { inherit pkgs; }; - }; - }; +{ + fediversity = { + garage.enable = true; + pixelfed = pixelfedS3KeyConfig { inherit pkgs; }; + mastodon = mastodonS3KeyConfig { inherit pkgs; }; + peertube = peertubeS3KeyConfig { inherit pkgs; }; + }; } diff --git a/launch/main.tf b/launch/main.tf index c1ac39c8..3cdcc9e4 100644 --- a/launch/main.tf +++ b/launch/main.tf @@ -65,6 +65,11 @@ variable "deploy_environment" { } locals { + system = "x86_64-linux" + pins = data.external.pins.result + peripheral_services = { + garage = "test01" + } applications = { mastodon = { cfg = var.mastodon @@ -79,28 +84,55 @@ locals { hostname = "test03" } } + peripheral = { for name, inst in local.peripheral_services : name => { + hostname = inst + cfg = { + enable = anytrue([for _, app in local.applications: app.cfg.enable]) + } + } + } } -# module "garage" { -# source = "./vm" -# count = var.mastodon.enable || var.pixelfed.enable || var.peertube.enable ? 1 : 0 -# domain = var.domain -# hostname = "test01" -# config = "garage" -# initialUser = var.initialUser -# terraform-nixos = var.terraform-nixos -# ssh_private_key_file = var.ssh_private_key_file -# deploy_environment = var.deploy_environment -# } +data "external" "pins" { + program = ["nix", "eval", "--json", "-f", "${path.root}/../npins"] +} -module "nixos" { - source = "./vm" - domain = var.domain - initialUser = var.initialUser - terraform-nixos = var.terraform-nixos +module "deploy" { + source = "${var.terraform-nixos}//deploy_nixos" + for_each = {for name, inst in merge( + local.peripheral, + local.applications, + ) : name => inst if inst.cfg.enable} ssh_private_key_file = var.ssh_private_key_file + target_host = "${each.value.hostname}.abundos.eu" + target_user= "root" # FIXME: #24 + target_system = local.system + NIX_PATH = join(":", [for name, path in local.pins : "${name}=${path}"]) deploy_environment = var.deploy_environment - for_each = { for name, inst in local.applications : name => inst if inst.cfg.enable } - config = each.key - hostname = each.value.hostname + hermetic = true + config_pwd = path.root + config = <<-EOT + let + terraform = builtins.fromJSON ''${jsonencode({ + domain = var.domain + hostname = each.value.hostname + initialUser = var.initialUser + })}''; + in + import { + system = "${local.system}"; + specialArgs = { inherit terraform; }; + modules = [ + # ${path.root}/options.nix + ${path.root}/shared.nix + ${path.root}/${each.key}.nix + # (terraform) + ]; + } + EOT + perform_gc = false + build_on_target = false + triggers = { + pins = jsonencode(local.pins) + } } diff --git a/launch/shared.nix b/launch/shared.nix index 2fe1f6a0..70d69831 100644 --- a/launch/shared.nix +++ b/launch/shared.nix @@ -1,7 +1,6 @@ { pkgs, terraform, - sources, ... }: let @@ -9,8 +8,8 @@ let in { imports = [ - "${sources.disko}/module.nix" - "${sources.agenix}/modules/age.nix" + + ../services/fediversity ./resource.nix # FIXME: get VM details from TF diff --git a/launch/vm/main.tf b/launch/vm/main.tf deleted file mode 100644 index 3407dc07..00000000 --- a/launch/vm/main.tf +++ /dev/null @@ -1,80 +0,0 @@ -variable "terraform-nixos" { - type = string -} - -variable "config" { - type = string -} - -variable "domain" { - type = string -} - -variable "hostname" { - type = string -} - -variable "initialUser" { - type = object({ - displayName = string - username = string - password = string - email = string - }) -} - -variable "ssh_private_key_file" { - type = string - description = "Path to private key used to connect to the target_host" - default = "" -} - -variable "deploy_environment" { - type = map(string) - description = "Extra environment variables to be set during deployment." - default = {} -} - -locals { - system = "x86_64-linux" - nixpkgs = data.external.pins.result["nixpkgs"] - sources = "${path.root}/../npins" -} - -module "deploy" { - source = "${var.terraform-nixos}//deploy_nixos" - ssh_private_key_file = var.ssh_private_key_file - target_host = "${var.hostname}.abundos.eu" - target_user= "root" # FIXME: #24 - target_system = local.system - NIX_PATH = "nixpkgs=${local.nixpkgs}:sources=${local.sources}" - deploy_environment = var.deploy_environment - hermetic = true - config_pwd = path.root - config = <<-EOT - import ${data.external.pins.result["nixpkgs"]}/nixos/lib/eval-config.nix { - system = "${local.system}"; - specialArgs = { - sources = import ${path.root}/../npins; - terraform = builtins.fromJSON ''${jsonencode({ - domain = var.domain - hostname = var.hostname - initialUser = var.initialUser - })}''; - }; - modules = [ - ${path.root}/${var.config}.nix - ${path.root}/shared.nix - ]; - } - EOT - perform_gc = false - build_on_target = false - # triggers = { - # # pins = data.external.pins.result - # } -} - -data "external" "pins" { - program = ["nix", "eval", "--json", "-f", "${path.root}/../npins"] -} -- 2.48.1 From 9f689faa327a529d1c9c0d2d9c6f496b84b549bc Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 13 Apr 2025 12:36:17 +0200 Subject: [PATCH 51/57] special_args -> nix_path + module --- launch/options.nix | 53 ++++++++++++++++++++++++++++++++++++++++++++++ launch/shared.nix | 10 ++++----- 2 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 launch/options.nix diff --git a/launch/options.nix b/launch/options.nix new file mode 100644 index 00000000..c090b372 --- /dev/null +++ b/launch/options.nix @@ -0,0 +1,53 @@ +{ + lib, + ... +}: +let + inherit (lib) types mkOption; + inherit (types) str enum submodule; +in +{ + options.terraform = { + domain = mkOption { + type = enum [ + "fediversity.net" + ]; + description = '' + Apex domain under which the services will be deployed. + ''; + default = "fediversity.net"; + }; + hostname = mkOption { + type = str; + description = '' + Internal name of the host, e.g. test01 + ''; + }; + initialUser = mkOption { + description = '' + Some services require an initial user to access them. + This option sets the credentials for such an initial user. + ''; + type = submodule { + options = { + displayName = mkOption { + type = str; + description = "Display name of the user"; + }; + username = mkOption { + type = str; + description = "Username for login"; + }; + email = mkOption { + type = str; + description = "User's email address"; + }; + password = mkOption { + type = str; + description = "Password for login"; + }; + }; + }; + }; + }; +} diff --git a/launch/shared.nix b/launch/shared.nix index 70d69831..fd7436c6 100644 --- a/launch/shared.nix +++ b/launch/shared.nix @@ -1,10 +1,10 @@ { pkgs, - terraform, + config, ... }: let - inherit (terraform) hostname; + inherit (config.terraform) hostname domain initialUser; in { imports = [ @@ -17,12 +17,12 @@ in ]; fediversityVm.name = hostname; fediversity = { - inherit (terraform) domain; + inherit domain; temp.initialUser = { - inherit (terraform.initialUser) username email displayName; + inherit (initialUser) username email displayName; # FIXME: disgusting, but nvm, this is going to be replaced by # proper central authentication at some point - passwordFile = pkgs.writeText "password" terraform.initialUser.password; + passwordFile = pkgs.writeText "password" initialUser.password; }; }; } -- 2.48.1 From 1f5977468c81ceb684bdc058ffc94e7fc788a8fe Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 13 Apr 2025 13:24:45 +0200 Subject: [PATCH 52/57] ditch hermetic to simplify - still gets infinite recursion --- launch/main.tf | 14 +++++--------- launch/shared.nix | 2 -- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/launch/main.tf b/launch/main.tf index 3cdcc9e4..d620f3ac 100644 --- a/launch/main.tf +++ b/launch/main.tf @@ -109,24 +109,20 @@ module "deploy" { target_system = local.system NIX_PATH = join(":", [for name, path in local.pins : "${name}=${path}"]) deploy_environment = var.deploy_environment - hermetic = true config_pwd = path.root config = <<-EOT - let + { terraform = builtins.fromJSON ''${jsonencode({ domain = var.domain hostname = each.value.hostname initialUser = var.initialUser })}''; - in - import { - system = "${local.system}"; - specialArgs = { inherit terraform; }; - modules = [ - # ${path.root}/options.nix + imports = [ + ${path.root}/options.nix ${path.root}/shared.nix ${path.root}/${each.key}.nix - # (terraform) + # FIXME: get VM details from TF + ${path.root}./infra/test-machines/${each.value.hostname} ]; } EOT diff --git a/launch/shared.nix b/launch/shared.nix index fd7436c6..46d6ccc5 100644 --- a/launch/shared.nix +++ b/launch/shared.nix @@ -12,8 +12,6 @@ in ../services/fediversity ./resource.nix - # FIXME: get VM details from TF - ../infra/test-machines/${hostname} ]; fediversityVm.name = hostname; fediversity = { -- 2.48.1 From 385c811a39be9903c74abcb7e24bd36bfc789d42 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 13 Apr 2025 21:09:20 +0200 Subject: [PATCH 53/57] limit parallelism for testing to prevent out-of-memory errors --- panel/src/panel/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 68749fe3..b799cc88 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -161,6 +161,7 @@ class DeploymentStatus(ConfigurationForm): f"-state={cwd}/terraform.tfstate", # FIXME: separate users' state "--auto-approve", "-lock=false", + "-parallelism=1" # limit OOM risk ] deployment_result = subprocess.run(cmd, cwd=cwd, env=env) logger.debug("deployment_result: %s", deployment_result) -- 2.48.1 From 6a4eb906581591043bca5e60e03970e2165a5d8c Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 13 Apr 2025 21:14:33 +0200 Subject: [PATCH 54/57] in-source tf deployment logic --- launch/.gitignore | 2 +- launch/README.md | 7 +- launch/default.nix | 2 +- launch/main.tf | 140 +++++++++++++++++++++------------ launch/module.auto.tfvars.json | 1 - launch/tf-env.nix | 12 +-- npins/sources.json | 12 --- panel/env.nix | 2 +- 8 files changed, 99 insertions(+), 79 deletions(-) delete mode 100644 launch/module.auto.tfvars.json diff --git a/launch/.gitignore b/launch/.gitignore index 42b97838..5ab952ce 100644 --- a/launch/.gitignore +++ b/launch/.gitignore @@ -1,5 +1,5 @@ .auto.tfvars.json -module.auto.tfvars.json +.npins.json .terraform/ .terraform.tfstate.lock.info terraform.tfstate* diff --git a/launch/README.md b/launch/README.md index 94cea9eb..4c24dae6 100644 --- a/launch/README.md +++ b/launch/README.md @@ -2,12 +2,13 @@ ## usage -### updating TF modules +<-- TODO: port to just --> + +### updating npins ```sh -$ npins update terraform-nixos $ cd launch/ -$ echo "{\"terraform-nixos\": $(nix-instantiate --eval --json -E '(import ../npins).terraform-nixos.outPath')}" > module.auto.tfvars.json +$ echo "$(nix eval --json -f ../npins)" > .npins.json ``` ### local development diff --git a/launch/default.nix b/launch/default.nix index 5194d628..bb96db72 100644 --- a/launch/default.nix +++ b/launch/default.nix @@ -16,7 +16,7 @@ in shell = pkgs.mkShellNoCC { packages = [ pkgs.npins - pkgs.gnugrep # used in terraform-nixos + pkgs.jaq # tf (import ./tf.nix { inherit lib pkgs; }) ]; }; diff --git a/launch/main.tf b/launch/main.tf index d620f3ac..de0cf60e 100644 --- a/launch/main.tf +++ b/launch/main.tf @@ -1,7 +1,3 @@ -variable "terraform-nixos" { - type = string -} - variable "domain" { type = string default = "fediversity.net" @@ -51,7 +47,6 @@ variable "initialUser" { } } -# TODO: could this straight-up be added in the child module instead? variable "ssh_private_key_file" { type = string description = "Path to private key used to connect to the target_host" @@ -66,11 +61,11 @@ variable "deploy_environment" { locals { system = "x86_64-linux" - pins = data.external.pins.result - peripheral_services = { + pins = jsondecode(file("${path.module}/.npins.json")) + peripheral_configs = { garage = "test01" } - applications = { + application_configs = { mastodon = { cfg = var.mastodon hostname = "test06" @@ -84,51 +79,98 @@ locals { hostname = "test03" } } - peripheral = { for name, inst in local.peripheral_services : name => { + peripherals = { for name, inst in local.peripheral_configs : name => { hostname = inst cfg = { - enable = anytrue([for _, app in local.applications: app.cfg.enable]) + enable = anytrue([for _, app in local.application_configs: app.cfg.enable]) } } } -} - -data "external" "pins" { - program = ["nix", "eval", "--json", "-f", "${path.root}/../npins"] -} - -module "deploy" { - source = "${var.terraform-nixos}//deploy_nixos" - for_each = {for name, inst in merge( - local.peripheral, - local.applications, - ) : name => inst if inst.cfg.enable} - ssh_private_key_file = var.ssh_private_key_file - target_host = "${each.value.hostname}.abundos.eu" - target_user= "root" # FIXME: #24 - target_system = local.system - NIX_PATH = join(":", [for name, path in local.pins : "${name}=${path}"]) - deploy_environment = var.deploy_environment - config_pwd = path.root - config = <<-EOT - { - terraform = builtins.fromJSON ''${jsonencode({ - domain = var.domain - hostname = each.value.hostname - initialUser = var.initialUser - })}''; - imports = [ - ${path.root}/options.nix - ${path.root}/shared.nix - ${path.root}/${each.key}.nix - # FIXME: get VM details from TF - ${path.root}./infra/test-machines/${each.value.hostname} - ]; - } - EOT - perform_gc = false - build_on_target = false - triggers = { - pins = jsonencode(local.pins) + applications = { for name, inst in local.application_configs : name => merge(inst, { + # depends_on = [for name in local.peripheral_configs : module.deploy[name]] + }) + } +} + +# FIXME settle for pwd when in /nix/store? +# FIXME calculate separately to reduce false positives +data "external" "hash" { + program = ["echo", "{\"hash\":\"$(nix-hash ..)\"}"] +} + +# merge instantiate/deploy, cuz i don't want 24+s instantiates when nothing changed. +# terraform-nixos separates these to only deploy if instantiate changed. +# FIXME find a better solution for this. current considerations were: +# - `resource null_resource` cannot have outputs, while we want info from the instantiation (unless built on host?). +# - `data external` always runs, which is undesirable for steps like deploy/instantiation. +# FIXME null_resource docs recommend terraform_data over null_resource +resource "null_resource" "deploy_nixos" { + for_each = {for name, inst in merge( + local.peripherals, + local.applications, + ) : name => inst if inst.cfg.enable} + + triggers = data.external.hash.result + + provisioner "local-exec" { + working_dir = path.root + environment = merge(var.deploy_environment, { + NIX_PATH = join(":", [for name, path in local.pins : "${name}=${path}"]), + }) + # TODO: refactor back to command="ignoreme" interpreter=concat([]) to protect sensitive data from error logs? + # TODO: build on target? + command = <<-EOF + set -euo pipefail + + # INSTANTIATE + command=( + nix-instantiate + --expr + 'let + os = import { + system = "${local.system}"; + configuration = { + terraform = builtins.fromJSON "${replace(jsonencode({ + domain = var.domain + hostname = each.value.hostname + initialUser = var.initialUser + }), "\"", "\\\"")}"; + imports = [ + ${path.root}/options.nix + ${path.root}/shared.nix + ${path.root}/${each.key}.nix + # FIXME: get VM details from TF + ${path.root}/../infra/test-machines/${each.value.hostname} + ]; + }; + }; + in { + substituters = builtins.concatStringsSep " " os.config.nix.binaryCaches; + trusted_public_keys = builtins.concatStringsSep " " os.config.nix.binaryCachePublicKeys; + drv_path = os.config.system.build.toplevel.drvPath; + out_path = os.config.system.build.toplevel; + }' + ) + "$${command[@]}" -A out_path + json="$("$${command[@]}" --eval --strict --json)" + + # DEPLOY + declare substituters trusted_public_keys drv_path + eval "export $(echo $json | jaq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" + host="root@${each.value.hostname}.abundos.eu" # FIXME: #24 + buildArgs=( + --option extra-binary-caches https://cache.nixos.org/ + --option substituters $substituters + --option trusted-public-keys $trusted_public_keys + ) + sshOpts=( + -o StrictHostKeyChecking=no + -o BatchMode=yes + -o "IdentityFile='${var.ssh_private_key_file}'" + ) + outPath=$(nix-store --realize "$drv_path" "$${buildArgs[@]}") + NIX_SSHOPTS="$${sshOpts[*]}" nix-copy-closure --to "$host" "$outPath" --gzip --use-substitutes + ssh "$${sshOpts[@]}" "$host" "nix-env --profile /nix/var/nix/profiles/system --set $outPath; $outPath/bin/switch-to-configuration switch" + EOF } } diff --git a/launch/module.auto.tfvars.json b/launch/module.auto.tfvars.json deleted file mode 100644 index 131e4db7..00000000 --- a/launch/module.auto.tfvars.json +++ /dev/null @@ -1 +0,0 @@ -{"terraform-nixos": "/nix/store/7rx25dwsw2xv9462rk2vkwy4qv33w76x-source"} diff --git a/launch/tf-env.nix b/launch/tf-env.nix index 2c720795..9924a917 100644 --- a/launch/tf-env.nix +++ b/launch/tf-env.nix @@ -13,24 +13,14 @@ pkgs.stdenv.mkDerivation { buildPhase = '' runHook preBuild pushd launch/ - - # pass terraform-nixos path to TF through variable - # when switching TF to nix take this directly from `inputs` - # https://codeberg.org/kiara/e2ed-hetzner/commit/84b2a349d3e48ea2a17340bceff762d834fd4046 - - echo "{\"terraform-nixos\": \"${sources.terraform-nixos}\"}" > module.auto.tfvars.json - # point to the relevant providers + echo '${lib.strings.toJSON sources}' > .npins.json tofu init -input=false - popd runHook postBuild ''; - # FIXME: can the above even work without a connection? installPhase = '' runHook preInstall - cp -r . $out - runHook postInstall ''; } diff --git a/npins/sources.json b/npins/sources.json index 80035ee4..bedab8ae 100644 --- a/npins/sources.json +++ b/npins/sources.json @@ -71,18 +71,6 @@ "name": "nixpkgs-unstable", "url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.05pre777917.b7ba7f9f45c5/nixexprs.tar.xz", "hash": "0jb6b7sv66bn06pchj2l88z0i5dlz0c2vb3z6pjjlq2p8q11zigg" - }, - "terraform-nixos": { - "type": "Git", - "repository": { - "type": "GitHub", - "owner": "KiaraGrouwstra", - "repo": "terraform-nixos" - }, - "branch": "fediversity", - "revision": "54c57ae2e8c312c1b9f69524462d588966ed23b4", - "url": "https://github.com/KiaraGrouwstra/terraform-nixos/archive/54c57ae2e8c312c1b9f69524462d588966ed23b4.tar.gz", - "hash": "1yxps17ac5sljd1ri2p1q1x9h8dcxfpcf0hh6wcpic8ydwy45qql" } }, "version": 3 diff --git a/panel/env.nix b/panel/env.nix index e98622a5..90d15d7a 100644 --- a/panel/env.nix +++ b/panel/env.nix @@ -10,7 +10,7 @@ pkgs.coreutils pkgs.openssh pkgs.git - pkgs.gnugrep # used in terraform-nixos + pkgs.jaq # tf (import ../launch/tf.nix { inherit lib pkgs; }) ]; SSH_PRIVATE_KEY_FILE = ""; -- 2.48.1 From c91361e7d598fa824d5ba228632ebf06effecadd Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 13 Apr 2025 21:42:46 +0200 Subject: [PATCH 55/57] update peertube vm --- launch/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launch/main.tf b/launch/main.tf index de0cf60e..cafd0eb2 100644 --- a/launch/main.tf +++ b/launch/main.tf @@ -76,7 +76,7 @@ locals { } peertube = { cfg = var.peertube - hostname = "test03" + hostname = "test05" } } peripherals = { for name, inst in local.peripheral_configs : name => { -- 2.48.1 From 6a105c2fce35c7bea58c78a8bc56917e623d80f4 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 13 Apr 2025 21:44:14 +0200 Subject: [PATCH 56/57] null_resource -> terraform_data --- launch/main.tf | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/launch/main.tf b/launch/main.tf index cafd0eb2..14a4116d 100644 --- a/launch/main.tf +++ b/launch/main.tf @@ -98,19 +98,26 @@ data "external" "hash" { program = ["echo", "{\"hash\":\"$(nix-hash ..)\"}"] } -# merge instantiate/deploy, cuz i don't want 24+s instantiates when nothing changed. +# merged instantiate/deploy to prevent 24+s instantiates when nothing changed. # terraform-nixos separates these to only deploy if instantiate changed. # FIXME find a better solution for this. current considerations were: -# - `resource null_resource` cannot have outputs, while we want info from the instantiation (unless built on host?). -# - `data external` always runs, which is undesirable for steps like deploy/instantiation. -# FIXME null_resource docs recommend terraform_data over null_resource -resource "null_resource" "deploy_nixos" { +# - generic resources cannot have outputs, while we want info from the instantiation (unless built on host?). +# - `data` always runs, which is slow for deploy/instantiation. +resource "terraform_data" "nixos" { for_each = {for name, inst in merge( local.peripherals, local.applications, ) : name => inst if inst.cfg.enable} - triggers = data.external.hash.result + triggers_replace = [ + data.external.hash.result, + var.deploy_environment, + var.domain, + var.initialUser, + local.system, + each.key, + each.value, + ] provisioner "local-exec" { working_dir = path.root -- 2.48.1 From a746ec50cdcace0f7da1e159b5ae49e3f66eb8e9 Mon Sep 17 00:00:00 2001 From: Kiara Grouwstra Date: Sun, 13 Apr 2025 21:53:18 +0200 Subject: [PATCH 57/57] rm depends_on --- launch/main.tf | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/launch/main.tf b/launch/main.tf index 14a4116d..0a65edd1 100644 --- a/launch/main.tf +++ b/launch/main.tf @@ -86,10 +86,6 @@ locals { } } } - applications = { for name, inst in local.application_configs : name => merge(inst, { - # depends_on = [for name in local.peripheral_configs : module.deploy[name]] - }) - } } # FIXME settle for pwd when in /nix/store? @@ -106,7 +102,7 @@ data "external" "hash" { resource "terraform_data" "nixos" { for_each = {for name, inst in merge( local.peripherals, - local.applications, + local.application_configs, ) : name => inst if inst.cfg.enable} triggers_replace = [ -- 2.48.1