From a584d787d2264bddf3dfb446554e1568de3f64b4 Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 16:46:37 +0200 Subject: [PATCH 01/49] chore: initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..950a83c --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Coder Templates + From 6bd319fbe95a920468773aad1fcbb72cdf6f2eb9 Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 17:09:10 +0200 Subject: [PATCH 02/49] chore: add nix flake and image --- .envrc | 8 + .gitignore | 6 + flake.lock | 982 +++++++++++++++++++++++++++++++++++++++++++++++++++++ flake.nix | 77 +++++ image.nix | 17 + 5 files changed, 1090 insertions(+) create mode 100644 .envrc create mode 100644 .gitignore create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 image.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..6403885 --- /dev/null +++ b/.envrc @@ -0,0 +1,8 @@ +if ! has nix_direnv_version || ! nix_direnv_version 2.2.1; then + source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.2.1/direnvrc" "sha256-zelF0vLbEl5uaqrfIzbgNzJWGmLzCmYAkInj/LNxvKs=" +fi + +if ! use flake . --impure +then + echo "devenv could not be build. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 +fi diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3324e4a --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.idea/ +.devenv/ +.direnv/ +*.tf* +result +.pre-commit-config.yaml diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..4fd8c22 --- /dev/null +++ b/flake.lock @@ -0,0 +1,982 @@ +{ + "nodes": { + "attic": { + "inputs": { + "crane": "crane", + "flake-compat": "flake-compat_4", + "flake-utils": "flake-utils_4", + "nixpkgs": "nixpkgs_4", + "nixpkgs-stable": "nixpkgs-stable_3" + }, + "locked": { + "lastModified": 1710680783, + "narHash": "sha256-exrsUUk/VSCG2Y3Sr/dkST8vwICzab3fe8Je81t/SfM=", + "owner": "TECHNOFAB", + "repo": "attic", + "rev": "b6d8d5ca53ef15910042a39e81f35383370c1112", + "type": "gitlab" + }, + "original": { + "owner": "TECHNOFAB", + "repo": "attic", + "type": "gitlab" + } + }, + "cachix": { + "inputs": { + "devenv": "devenv_2", + "flake-compat": [ + "devenv", + "flake-compat" + ], + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "pre-commit-hooks": [ + "devenv", + "pre-commit-hooks" + ] + }, + "locked": { + "lastModified": 1712055811, + "narHash": "sha256-7FcfMm5A/f02yyzuavJe06zLa9hcMHsagE28ADcmQvk=", + "owner": "cachix", + "repo": "cachix", + "rev": "02e38da89851ec7fec3356a5c04bc8349cae0e30", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "cachix", + "type": "github" + } + }, + "crane": { + "inputs": { + "nixpkgs": [ + "nix-gitlab-ci", + "attic", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1702918879, + "narHash": "sha256-tWJqzajIvYcaRWxn+cLUB9L9Pv4dQ3Bfit/YjU5ze3g=", + "owner": "ipetkov", + "repo": "crane", + "rev": "7195c00c272fdd92fc74e7d5a0a2844b9fadb2fb", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "devenv": { + "inputs": { + "cachix": "cachix", + "flake-compat": "flake-compat_2", + "nix": "nix_2", + "nixpkgs": "nixpkgs_2", + "pre-commit-hooks": "pre-commit-hooks" + }, + "locked": { + "lastModified": 1713968789, + "narHash": "sha256-Gue8iwW3ZtCQs3EZKhk/i0uLaoUDfW1dpnaZ67MH64o=", + "owner": "cachix", + "repo": "devenv", + "rev": "b26b52a4dac68bdc305f6b9df948c97f49b2c3ee", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "devenv_2": { + "inputs": { + "flake-compat": [ + "devenv", + "cachix", + "flake-compat" + ], + "nix": "nix", + "nixpkgs": "nixpkgs", + "poetry2nix": "poetry2nix", + "pre-commit-hooks": [ + "devenv", + "cachix", + "pre-commit-hooks" + ] + }, + "locked": { + "lastModified": 1708704632, + "narHash": "sha256-w+dOIW60FKMaHI1q5714CSibk99JfYxm0CzTinYWr+Q=", + "owner": "cachix", + "repo": "devenv", + "rev": "2ee4450b0f4b95a1b90f2eb5ffea98b90e48c196", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "python-rewrite", + "repo": "devenv", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "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-compat_3": { + "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-compat_4": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_5": { + "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" + }, + "locked": { + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_2" + }, + "locked": { + "lastModified": 1704982712, + "narHash": "sha256-2Ptt+9h8dczgle2Oo6z5ni5rt/uLMG47UFTR1ry/wgg=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "07f6395285469419cf9d078f59b5b49993198c00", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_3": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_3" + }, + "locked": { + "lastModified": 1704982712, + "narHash": "sha256-2Ptt+9h8dczgle2Oo6z5ni5rt/uLMG47UFTR1ry/wgg=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "07f6395285469419cf9d078f59b5b49993198c00", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "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" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_4": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_5": { + "inputs": { + "systems": "systems_4" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "devenv", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "gitignore_2": { + "inputs": { + "nixpkgs": [ + "nix-devtools", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1703887061, + "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "gitignore_3": { + "inputs": { + "nixpkgs": [ + "nix-gitlab-ci", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1703887061, + "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nix": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": [ + "devenv", + "cachix", + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1712911606, + "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", + "owner": "domenkozar", + "repo": "nix", + "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "devenv-2.21", + "repo": "nix", + "type": "github" + } + }, + "nix-devtools": { + "inputs": { + "devenv": [ + "devenv" + ], + "flake-parts": "flake-parts_2", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks": "pre-commit-hooks_2", + "systems": [ + "systems" + ] + }, + "locked": { + "lastModified": 1709912203, + "narHash": "sha256-5kFeGMA1reDLUEaEETtpwp0myG06B3PCO/q8NtuKH7k=", + "owner": "TECHNOFAB", + "repo": "nix-devtools", + "rev": "059d3aa070c09ac48eb74489aa4c6852a5395f55", + "type": "gitlab" + }, + "original": { + "owner": "TECHNOFAB", + "repo": "nix-devtools", + "type": "gitlab" + } + }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "devenv", + "cachix", + "devenv", + "poetry2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688870561, + "narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "165b1650b753316aa7f1787f3005a8d2da0f5301", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-github-actions", + "type": "github" + } + }, + "nix-gitlab-ci": { + "inputs": { + "attic": "attic", + "devenv": [ + "devenv" + ], + "flake-parts": "flake-parts_3", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks": "pre-commit-hooks_3", + "systems": [ + "systems" + ] + }, + "locked": { + "lastModified": 1711224545, + "narHash": "sha256-eWzQ6VZ5R30aLQ7ifpasi0F0MdxdwErevZ2Z8tMPYXA=", + "owner": "TECHNOFAB", + "repo": "nix-gitlab-ci", + "rev": "c272bfd81206a2888920258ea6620fd7f5ed4f7c", + "type": "gitlab" + }, + "original": { + "owner": "TECHNOFAB", + "repo": "nix-gitlab-ci", + "type": "gitlab" + } + }, + "nix_2": { + "inputs": { + "flake-compat": [ + "devenv", + "flake-compat" + ], + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression_2" + }, + "locked": { + "lastModified": 1712911606, + "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", + "owner": "domenkozar", + "repo": "nix", + "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "devenv-2.21", + "repo": "nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1692808169, + "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1711703276, + "narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d8fe5e6c92d0d190646fb9f1056741a229980089", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib_2": { + "locked": { + "dir": "lib", + "lastModified": 1703961334, + "narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib_3": { + "locked": { + "dir": "lib", + "lastModified": 1703961334, + "narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "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-stable": { + "locked": { + "lastModified": 1710695816, + "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "614b4613980a522ba49f0d194531beddbb7220d3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_2": { + "locked": { + "lastModified": 1704874635, + "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_3": { + "locked": { + "lastModified": 1702780907, + "narHash": "sha256-blbrBBXjjZt6OKTcYX1jpe9SRof2P9ZYWPzq22tzXAA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1e2e384c5b7c50dbf8e9c441a9e58d85f408b01f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_4": { + "locked": { + "lastModified": 1704874635, + "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1713361204, + "narHash": "sha256-TA6EDunWTkc5FvDCqU3W2T3SFn0gRZqh6D/hJnM02MM=", + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "285676e87ad9f0ca23d8714a6ab61e7e027020c6", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1704842529, + "narHash": "sha256-OTeQA+F8d/Evad33JMfuXC89VMetQbsU4qcaePchGr4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "eabe8d3eface69f5bb16c18f8662a702f50c20d5", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1702539185, + "narHash": "sha256-KnIRG5NMdLIpEkZTnN5zovNYc0hhXjAgv6pfd5Z4c7U=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "aa9d4729cbc99dabacb50e3994dcefb3ea0f7447", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1704842529, + "narHash": "sha256-OTeQA+F8d/Evad33JMfuXC89VMetQbsU4qcaePchGr4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "eabe8d3eface69f5bb16c18f8662a702f50c20d5", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_6": { + "locked": { + "lastModified": 1713805509, + "narHash": "sha256-YgSEan4CcrjivCNO5ZNzhg7/8ViLkZ4CB/GrGBVSudo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1e1dc66fe68972a76679644a5577828b6a7e8be4", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "poetry2nix": { + "inputs": { + "flake-utils": "flake-utils", + "nix-github-actions": "nix-github-actions", + "nixpkgs": [ + "devenv", + "cachix", + "devenv", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1692876271, + "narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=", + "owner": "nix-community", + "repo": "poetry2nix", + "rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "poetry2nix", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": [ + "devenv", + "flake-compat" + ], + "flake-utils": "flake-utils_2", + "gitignore": "gitignore", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1713775815, + "narHash": "sha256-Wu9cdYTnGQQwtT20QQMg7jzkANKQjwBD9iccfGKkfls=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "2ac4dcbf55ed43f3be0bae15e181f08a57af24a4", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "pre-commit-hooks_2": { + "inputs": { + "flake-compat": "flake-compat_3", + "flake-utils": "flake-utils_3", + "gitignore": "gitignore_2", + "nixpkgs": "nixpkgs_3", + "nixpkgs-stable": "nixpkgs-stable_2" + }, + "locked": { + "lastModified": 1705229514, + "narHash": "sha256-itILy0zimR/iyUGq5Dgg0fiW8plRDyxF153LWGsg3Cw=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "ffa9a5b90b0acfaa03b1533b83eaf5dead819a05", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "pre-commit-hooks_3": { + "inputs": { + "flake-compat": "flake-compat_5", + "flake-utils": "flake-utils_5", + "gitignore": "gitignore_3", + "nixpkgs": "nixpkgs_5", + "nixpkgs-stable": "nixpkgs-stable_4" + }, + "locked": { + "lastModified": 1705229514, + "narHash": "sha256-itILy0zimR/iyUGq5Dgg0fiW8plRDyxF153LWGsg3Cw=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "ffa9a5b90b0acfaa03b1533b83eaf5dead819a05", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "flake-parts": "flake-parts", + "nix-devtools": "nix-devtools", + "nix-gitlab-ci": "nix-gitlab-ci", + "nixpkgs": "nixpkgs_6", + "systems": "systems_5" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "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" + } + }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_5": { + "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/flake.nix b/flake.nix new file mode 100644 index 0000000..ee8bccb --- /dev/null +++ b/flake.nix @@ -0,0 +1,77 @@ +{ + description = "Coder Templates"; + + outputs = { + self, + nixpkgs, + flake-parts, + systems, + ... + } @ inputs: + flake-parts.lib.mkFlake {inherit inputs;} { + imports = [ + inputs.devenv.flakeModule + inputs.nix-gitlab-ci.flakeModule + ]; + systems = import systems; + flake = { + }; + perSystem = { + config, + self', + inputs', + pkgs, + system, + ... + }: { + _module.args.pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + }; + + formatter = pkgs.alejandra; + devenv.shells.default = { + imports = [ + inputs.nix-devtools.devenvModule + ]; + packages = [ + pkgs.opentofu + pkgs.coder + ]; + + pre-commit.hooks = { + alejandra.enable = true; + }; + task = { + enable = true; + alias = ","; + tasks = {}; + }; + }; + + packages = { + nix-coder-image = pkgs.callPackage ./image.nix {}; + }; + }; + }; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + flake-parts.url = "github:hercules-ci/flake-parts"; + systems.url = "github:nix-systems/default"; + devenv.url = "github:cachix/devenv"; + nix-gitlab-ci = { + url = "gitlab:TECHNOFAB/nix-gitlab-ci"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.devenv.follows = "devenv"; + inputs.systems.follows = "systems"; + }; + nix-devtools = { + url = "gitlab:TECHNOFAB/nix-devtools"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.devenv.follows = "devenv"; + inputs.systems.follows = "systems"; + }; + }; +} diff --git a/image.nix b/image.nix new file mode 100644 index 0000000..f9b8abd --- /dev/null +++ b/image.nix @@ -0,0 +1,17 @@ +{ + lib, + pkgs, + ... +}: +pkgs.dockerTools.buildImage { + name = "nix-coder"; + tag = "latest"; + + copyToRoot = pkgs.buildEnv { + name = "image-root"; + paths = [pkgs.bashInteractive pkgs.home-manager pkgs.direnv]; + pathsToLink = ["/bin"]; + }; + + config.Cmd = ["/bin/bash"]; +} From 7cd71e7537cac99fc2a956244dfb607799c490cc Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 19:01:04 +0200 Subject: [PATCH 03/49] chore: add initial nix-kubernetes template --- .gitignore | 1 + flake.lock | 102 +++++++++++++++++++++++++- flake.nix | 34 ++++++++- nix-kubernetes/coder.nix | 42 +++++++++++ nix-kubernetes/default.nix | 24 +++++++ nix-kubernetes/kubernetes.nix | 130 ++++++++++++++++++++++++++++++++++ nix-kubernetes/parameters.nix | 78 ++++++++++++++++++++ nix-kubernetes/variables.nix | 16 +++++ 8 files changed, 425 insertions(+), 2 deletions(-) create mode 100644 nix-kubernetes/coder.nix create mode 100644 nix-kubernetes/default.nix create mode 100644 nix-kubernetes/kubernetes.nix create mode 100644 nix-kubernetes/parameters.nix create mode 100644 nix-kubernetes/variables.nix diff --git a/.gitignore b/.gitignore index 3324e4a..4ee2f34 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ *.tf* result .pre-commit-config.yaml +.terraform* diff --git a/flake.lock b/flake.lock index 4fd8c22..7a1c615 100644 --- a/flake.lock +++ b/flake.lock @@ -22,6 +22,38 @@ "type": "gitlab" } }, + "bats-assert": { + "flake": false, + "locked": { + "lastModified": 1636059754, + "narHash": "sha256-ewME0l27ZqfmAwJO4h5biTALc9bDLv7Bl3ftBzBuZwk=", + "owner": "bats-core", + "repo": "bats-assert", + "rev": "34551b1d7f8c7b677c1a66fc0ac140d6223409e5", + "type": "github" + }, + "original": { + "owner": "bats-core", + "repo": "bats-assert", + "type": "github" + } + }, + "bats-support": { + "flake": false, + "locked": { + "lastModified": 1548869839, + "narHash": "sha256-Gr4ntadr42F2Ks8Pte2D4wNDbijhujuoJi4OPZnTAZU=", + "owner": "bats-core", + "repo": "bats-support", + "rev": "d140a65044b2d6810381935ae7f0c94c7023c8c3", + "type": "github" + }, + "original": { + "owner": "bats-core", + "repo": "bats-support", + "type": "github" + } + }, "cachix": { "inputs": { "devenv": "devenv_2", @@ -348,6 +380,21 @@ "type": "github" } }, + "flake-utils_6": { + "locked": { + "lastModified": 1634851050, + "narHash": "sha256-N83GlSGPJJdcqhUxSCS/WwW5pksYf3VP1M13cDRTSVA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c91f3de5adaf1de973b797ef7485e441a65b8935", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "gitignore": { "inputs": { "nixpkgs": [ @@ -794,6 +841,21 @@ "type": "github" } }, + "nixpkgs_7": { + "locked": { + "lastModified": 1636823747, + "narHash": "sha256-oWo1nElRAOZqEf90Yek2ixdHyjD+gqtS/pAgwaQ9UhQ=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "f6a2ed2082d9a51668c86ba27d0b5496f7a2ea93", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "type": "github" + } + }, "poetry2nix": { "inputs": { "flake-utils": "flake-utils", @@ -898,7 +960,8 @@ "nix-devtools": "nix-devtools", "nix-gitlab-ci": "nix-gitlab-ci", "nixpkgs": "nixpkgs_6", - "systems": "systems_5" + "systems": "systems_5", + "terranix": "terranix" } }, "systems": { @@ -975,6 +1038,43 @@ "repo": "default", "type": "github" } + }, + "terranix": { + "inputs": { + "bats-assert": "bats-assert", + "bats-support": "bats-support", + "flake-utils": "flake-utils_6", + "nixpkgs": "nixpkgs_7", + "terranix-examples": "terranix-examples" + }, + "locked": { + "lastModified": 1695406838, + "narHash": "sha256-xiUfVD6rtsVWFotVtUW3Q1nQh4obKzgvpN1wqZuGXvM=", + "owner": "terranix", + "repo": "terranix", + "rev": "fc9077ca02ab5681935dbf0ecd725c4d889b9275", + "type": "github" + }, + "original": { + "owner": "terranix", + "repo": "terranix", + "type": "github" + } + }, + "terranix-examples": { + "locked": { + "lastModified": 1636300201, + "narHash": "sha256-0n1je1WpiR6XfCsvi8ZK7GrpEnMl+DpwhWaO1949Vbc=", + "owner": "terranix", + "repo": "terranix-examples", + "rev": "a934aa1cf88f6bd6c6ddb4c77b77ec6e1660bd5e", + "type": "github" + }, + "original": { + "owner": "terranix", + "repo": "terranix-examples", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index ee8bccb..5a7a9be 100644 --- a/flake.nix +++ b/flake.nix @@ -45,12 +45,42 @@ task = { enable = true; alias = ","; - tasks = {}; + tasks = { + "build" = { + requires.vars = ["TEMPLATE"]; + cmds = [ + "nix build .#{{ .TEMPLATE }}" + "install result {{ .TEMPLATE }}/template.tf.json" + ]; + }; + "validate" = { + desc = "Validate the resulting terraform files"; + deps = ["build"]; + requires.vars = ["TEMPLATE"]; + dir = "{{ .TEMPLATE }}"; + cmds = [ + "${pkgs.opentofu}/bin/tofu init" + "${pkgs.opentofu}/bin/tofu validate" + ]; + }; + "upload-to-coder" = { + desc = "Uploads the specified template to coder"; + deps = ["build" "validate"]; + requires.vars = ["TEMPLATE"]; + dir = "{{ .TEMPLATE }}"; + interactive = true; + cmd = ''${pkgs.coder}/bin/coder templates push "{{ .TEMPLATE }}"''; + }; + }; }; }; packages = { nix-coder-image = pkgs.callPackage ./image.nix {}; + nix-kubernetes = inputs.terranix.lib.terranixConfiguration { + inherit system; + modules = [./nix-kubernetes]; + }; }; }; }; @@ -73,5 +103,7 @@ inputs.devenv.follows = "devenv"; inputs.systems.follows = "systems"; }; + + terranix.url = "github:terranix/terranix"; }; } diff --git a/nix-kubernetes/coder.nix b/nix-kubernetes/coder.nix new file mode 100644 index 0000000..26fa0bd --- /dev/null +++ b/nix-kubernetes/coder.nix @@ -0,0 +1,42 @@ +{...}: { + locals."git_repo_folder" = let + split_repo = ''split("/", data.coder_parameter.git_repo.value)''; + in ''try(element(${split_repo}, length(${split_repo}) - 1), "")''; + + data = { + coder_external_auth."gitlab" = { + id = "gitlab"; + optional = false; + }; + coder_workspace."me" = {}; + }; + + resource = { + coder_agent."coder" = { + arch = "\${var.arch}"; + os = "linux"; + }; + coder_script."git_clone" = { + agent_id = "\${coder_agent.coder.id}"; + display_name = "Git Clone"; + icon = "/icon/git.svg"; + script = let + repo = ''''${data.coder_parameter.git_repo.value}''; + repo_folder = ''''${local.git_repo_folder}''; + in '' + #!/usr/bin/env bash + set -eux + + echo "Cloning repo \"${repo}\" if it does not exist" + mkdir -p ~/repos + pushd ~/repos + if [[ ! -z "${repo}" && ! -d "${repo_folder}" ]] then + git clone ${repo} ${repo_folder} + fi + popd + ''; + run_on_start = true; + start_blocks_login = true; + }; + }; +} diff --git a/nix-kubernetes/default.nix b/nix-kubernetes/default.nix new file mode 100644 index 0000000..ac0ae83 --- /dev/null +++ b/nix-kubernetes/default.nix @@ -0,0 +1,24 @@ +{...}: { + imports = [ + ./parameters.nix + ./variables.nix + ./coder.nix + ./kubernetes.nix + ]; + + terraform.required_providers = { + coder = { + source = "coder/coder"; + version = "0.21.0"; + }; + kubernetes = { + source = "hashicorp/kubernetes"; + version = "2.29.0"; + }; + }; + + provider = { + coder = {}; + kubernetes = {}; + }; +} diff --git a/nix-kubernetes/kubernetes.nix b/nix-kubernetes/kubernetes.nix new file mode 100644 index 0000000..128da0f --- /dev/null +++ b/nix-kubernetes/kubernetes.nix @@ -0,0 +1,130 @@ +{...}: { + resource = { + kubernetes_pod."workspace" = { + count = "\${data.coder_workspace.me.start_count}"; + metadata = { + name = "coder-\${lower(data.coder_workspace.me.owner)}-\${lower(data.coder_workspace.me.name)}"; + namespace = "\${var.namespace}"; + annotations."com.coder.user.email" = "\${data.coder_workspace.me.owner_email}"; + labels = { + "app.kubernetes.io/instance" = "coder-workspace-\${lower(data.coder_workspace.me.owner)}-\${lower(data.coder_workspace.me.name)}"; + "app.kubernetes.io/name" = "coder-workspace"; + "app.kubernetes.io/part-of" = "coder"; + "com.coder.resource" = "true"; + "com.coder.user.id" = "\${data.coder_workspace.me.owner_id}"; + "com.coder.user.name" = "\${data.coder_workspace.me.owner}"; + "com.coder.workspace.id" = "\${data.coder_workspace.me.id}"; + "com.coder.workspace.name" = "\${data.coder_workspace.me.name}"; + }; + }; + spec = { + affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution = { + weight = 1; + pod_affinity_term = { + topology_key = "kubernetes.io/hostname"; + label_selector.match_expressions = { + key = "app.kubernetes.io/name"; + operator = "In"; + values = ["coder-workspace"]; + }; + }; + }; + container = [ + { + name = "workspace"; + image = "registry.gitlab.com/technofab/coder-templates/coder-workspace:\${data.coder_parameter.image_tag.value}"; + command = ["/bin/sh" "-c" "\${resource.coder_agent.coder.init_script}"]; + env = [ + { + name = "CODER_AGENT_TOKEN"; + value = "\${resource.coder_agent.coder.token}"; + } + ]; + resources = { + requests = { + # TODO: allow configuring this via variables (template wide) + cpu = "250m"; + memory = "512Mi"; + }; + limits = { + cpu = "\${data.coder_parameter.cpu.value}"; + memory = "\${data.coder_parameter.memory.value}"; + }; + }; + security_context.run_as_user = "1000"; + volume_mount = [ + { + mount_path = "/home"; + name = "home"; + read_only = false; + } + { + mount_path = "/nix"; + name = "nix-store"; + read_only = false; + } + ]; + } + ]; + security_context = { + fs_group = "1000"; + run_as_user = "1000"; + }; + volume = [ + { + name = "home"; + persistent_volume_claim.claim_name = "\${resource.kubernetes_persistent_volume_claim.home.metadata.0.name}"; + } + { + name = "nix-store"; + persistent_volume_claim.claim_name = "\${resource.kubernetes_persistent_volume_claim.nix-store.metadata.0.name}"; + } + ]; + }; + }; + kubernetes_persistent_volume_claim."home" = { + metadata = { + name = "coder-home-\${lower(data.coder_workspace.me.owner)}-\${lower(data.coder_workspace.me.name)}"; + namespace = "\${var.namespace}"; + annotations."com.coder.user.email" = "\${data.coder_workspace.me.owner_email}"; + labels = { + "app.kubernetes.io/instance" = "coder-pvc-home-\${lower(data.coder_workspace.me.owner)}-\${lower(data.coder_workspace.me.name)}"; + "app.kubernetes.io/name" = "coder-pvc"; + "app.kubernetes.io/part-of" = "coder"; + "com.coder.resource" = "true"; + "com.coder.user.id" = "\${data.coder_workspace.me.owner_id}"; + "com.coder.user.name" = "\${data.coder_workspace.me.owner}"; + "com.coder.workspace.id" = "\${data.coder_workspace.me.id}"; + "com.coder.workspace.name" = "\${data.coder_workspace.me.name}"; + }; + }; + spec = { + access_modes = ["ReadWriteOnce"]; + resources.requests.storage = "\${data.coder_parameter.home_disk_size.value}Gi"; + }; + wait_until_bound = false; + }; + kubernetes_persistent_volume_claim."nix-store" = { + metadata = { + name = "coder-nix-store-\${lower(data.coder_workspace.me.owner)}-\${lower(data.coder_workspace.me.name)}"; + namespace = "\${var.namespace}"; + annotations."com.coder.user.email" = "\${data.coder_workspace.me.owner_email}"; + labels = { + "app.kubernetes.io/instance" = "coder-pvc-nix-store-\${lower(data.coder_workspace.me.owner)}-\${lower(data.coder_workspace.me.name)}"; + "app.kubernetes.io/name" = "coder-pvc"; + "app.kubernetes.io/part-of" = "coder"; + "com.coder.resource" = "true"; + "com.coder.user.id" = "\${data.coder_workspace.me.owner_id}"; + "com.coder.user.name" = "\${data.coder_workspace.me.owner}"; + "com.coder.workspace.id" = "\${data.coder_workspace.me.id}"; + "com.coder.workspace.name" = "\${data.coder_workspace.me.name}"; + }; + }; + spec = { + access_modes = ["ReadWriteOnce"]; + resources.requests.storage = "\${data.coder_parameter.nix_store_disk_size.value}Gi"; + }; + wait_until_bound = false; + }; + }; +} diff --git a/nix-kubernetes/parameters.nix b/nix-kubernetes/parameters.nix new file mode 100644 index 0000000..cd305f9 --- /dev/null +++ b/nix-kubernetes/parameters.nix @@ -0,0 +1,78 @@ +{...}: { + data.coder_parameter = { + git_repo = { + name = "Git Repository"; + description = '' + URI for a git repository which should automatically be cloned to ~/repos/ + ''; + default = ""; + order = 1; + type = "string"; + mutable = true; + }; + image_tag = { + name = "Image Tag"; + description = '' + Which container image tag should be used. + ''; + default = "latest"; + order = 2; + type = "string"; + mutable = true; + }; + cpu = { + name = "CPU"; + description = '' + CPU Limit for Kubernetes Pod. Kubernetes Notation (eg. 500m) + ''; + default = "500m"; + order = 3; + type = "string"; + mutable = true; + }; + memory = { + name = "Memory"; + description = '' + Memory Limit for Kubernetes Pod. Kubernetes Notation (eg. 1Gi) + ''; + default = "1Gi"; + order = 4; + type = "string"; + mutable = true; + }; + home_disk_size = { + name = "Home Disk Size"; + description = '' + Size for the /home PV in GB + ''; + default = 5; + order = 5; + type = "number"; + mutable = true; + validation = [ + { + min = 1; + max = 100; + monotonic = "increasing"; + } + ]; + }; + nix_store_disk_size = { + name = "Nix Store Disk Size"; + description = '' + Size for the /nix PV in GB. This might grow pretty big. + ''; + default = 5; + order = 6; + type = "number"; + mutable = true; + validation = [ + { + min = 1; + max = 100; + monotonic = "increasing"; + } + ]; + }; + }; +} diff --git a/nix-kubernetes/variables.nix b/nix-kubernetes/variables.nix new file mode 100644 index 0000000..33de9dd --- /dev/null +++ b/nix-kubernetes/variables.nix @@ -0,0 +1,16 @@ +{...}: { + variable = { + namespace = { + type = "string"; + description = "Kubernetes namespace (must exist prior to creating workspaces)"; + }; + arch = { + type = "string"; + description = "Architecture of the host"; + validation = { + condition = ''''${contains(["amd64", "arm64"], var.arch)}''; + error_message = "Invalid architecture selected"; + }; + }; + }; +} From b98a1e728c5125e3cc80ebb2a60ec65af9b3c643 Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 19:06:12 +0200 Subject: [PATCH 04/49] ci: add CI and rename image to nix-coder-image --- .gitlab-ci.yaml | 4 ++++ flake.nix | 28 ++++++++++++++++++++++++++++ nix-kubernetes/kubernetes.nix | 2 +- 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 .gitlab-ci.yaml diff --git a/.gitlab-ci.yaml b/.gitlab-ci.yaml new file mode 100644 index 0000000..f0acb3c --- /dev/null +++ b/.gitlab-ci.yaml @@ -0,0 +1,4 @@ +include: + - project: TECHNOFAB/nix-gitlab-ci + ref: main + file: gitlab-ci.yml diff --git a/flake.nix b/flake.nix index 5a7a9be..b450da0 100644 --- a/flake.nix +++ b/flake.nix @@ -82,6 +82,34 @@ modules = [./nix-kubernetes]; }; }; + + ci = { + stages = ["build" "upload"]; + jobs = { + "build" = { + stage = "build"; + script = [ + "nix build .#nix-coder-image" + ]; + after_script = [ + "install -D result dist/nix-coder-image.tar.gz" + ]; + artifacts.paths = ["dist/"]; + }; + "upload" = { + stage = "upload"; + needs = ["build"]; + deps = [pkgs.skopeo]; + script = [ + '' + skopeo --insecure-policy copy --dest-creds "''${CI_REGISTRY_USER}:''${CI_REGISTRY_PASSWORD}" --tmpdir /tmp \ + "docker-archive:dist/nix-coder-image.tar.gz" \ + "docker://''${CI_REGISTRY_IMAGE}/nix-coder-image:''${CI_COMMIT_SHORT_SHA}" + '' + ]; + }; + }; + }; }; }; diff --git a/nix-kubernetes/kubernetes.nix b/nix-kubernetes/kubernetes.nix index 128da0f..22170a7 100644 --- a/nix-kubernetes/kubernetes.nix +++ b/nix-kubernetes/kubernetes.nix @@ -32,7 +32,7 @@ container = [ { name = "workspace"; - image = "registry.gitlab.com/technofab/coder-templates/coder-workspace:\${data.coder_parameter.image_tag.value}"; + image = "registry.gitlab.com/technofab/coder-templates/nix-coder-image:\${data.coder_parameter.image_tag.value}"; command = ["/bin/sh" "-c" "\${resource.coder_agent.coder.init_script}"]; env = [ { From 09000ada9b45f9a9494d81fdfd3599f942c82f73 Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 19:07:52 +0200 Subject: [PATCH 05/49] ci: use correct yaml file ending --- .gitlab-ci.yaml => .gitlab-ci.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .gitlab-ci.yaml => .gitlab-ci.yml (100%) diff --git a/.gitlab-ci.yaml b/.gitlab-ci.yml similarity index 100% rename from .gitlab-ci.yaml rename to .gitlab-ci.yml From 5441a6284a941f1520a63e77ec1a5651757805da Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 21:41:43 +0200 Subject: [PATCH 06/49] ci: also build tf.json and tar file for each template --- flake.nix | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index b450da0..11df176 100644 --- a/flake.nix +++ b/flake.nix @@ -87,6 +87,19 @@ stages = ["build" "upload"]; jobs = { "build" = { + stage = "build"; + parallel.matrix = [ + {TEMPLATE = ["nix-kubernetes"];} + ]; + deps = [pkgs.gnutar]; + script = [ + "nix build .#\${TEMPLATE}" + "install result templates/\${TEMPLATE}.tf.json" + "tar -cf templates/\${TEMPLATE}.tar -C templates \${TEMPLATE}.tf.json" + ]; + artifacts.paths = ["templates/"]; + }; + "build:image" = { stage = "build"; script = [ "nix build .#nix-coder-image" @@ -98,8 +111,8 @@ }; "upload" = { stage = "upload"; - needs = ["build"]; deps = [pkgs.skopeo]; + needs = ["build:image"]; script = [ '' skopeo --insecure-policy copy --dest-creds "''${CI_REGISTRY_USER}:''${CI_REGISTRY_PASSWORD}" --tmpdir /tmp \ From c2a5f47341f41a0b7508e007a8a413a93ba46c02 Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 21:46:10 +0200 Subject: [PATCH 07/49] fix(CI): add missing -D arg for install --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 11df176..1e6516e 100644 --- a/flake.nix +++ b/flake.nix @@ -94,7 +94,7 @@ deps = [pkgs.gnutar]; script = [ "nix build .#\${TEMPLATE}" - "install result templates/\${TEMPLATE}.tf.json" + "install -D result templates/\${TEMPLATE}.tf.json" "tar -cf templates/\${TEMPLATE}.tar -C templates \${TEMPLATE}.tf.json" ]; artifacts.paths = ["templates/"]; From 8f931d2f43622bc61ba9097cc0bef9e158182a1f Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 22:12:55 +0200 Subject: [PATCH 08/49] ci: add multi arch image builds --- flake.nix | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/flake.nix b/flake.nix index 1e6516e..c63300a 100644 --- a/flake.nix +++ b/flake.nix @@ -22,6 +22,7 @@ inputs', pkgs, system, + lib, ... }: { _module.args.pkgs = import nixpkgs { @@ -37,6 +38,7 @@ packages = [ pkgs.opentofu pkgs.coder + pkgs.buildah ]; pre-commit.hooks = { @@ -85,7 +87,9 @@ ci = { stages = ["build" "upload"]; - jobs = { + jobs = let + SYSTEMS = ["aarch64-linux" "x86_64-linux"]; + in { "build" = { stage = "build"; parallel.matrix = [ @@ -101,23 +105,37 @@ }; "build:image" = { stage = "build"; + parallel.matrix = [ + {SYSTEM = SYSTEMS;} + ]; script = [ - "nix build .#nix-coder-image" + "nix build .#nix-coder-image --system $SYSTEM" ]; after_script = [ - "install -D result dist/nix-coder-image.tar.gz" + "install -D result dist/nix-coder-image_\${SYSTEM}.tar.gz" ]; artifacts.paths = ["dist/"]; }; "upload" = { stage = "upload"; - deps = [pkgs.skopeo]; + deps = [pkgs.buildah]; needs = ["build:image"]; + before_script = [ + ''export REGISTRY_AUTH_FILE=''${HOME}/auth.json'' + ''echo "$CI_REGISTRY_PASSWORD" | buildah login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY'' + '' + mkdir -p /etc/containers && + echo '{"default":[{"type":"insecureAcceptAnything"}]}' > /etc/containers/policy.json + '' + ]; script = [ '' - skopeo --insecure-policy copy --dest-creds "''${CI_REGISTRY_USER}:''${CI_REGISTRY_PASSWORD}" --tmpdir /tmp \ - "docker-archive:dist/nix-coder-image.tar.gz" \ - "docker://''${CI_REGISTRY_IMAGE}/nix-coder-image:''${CI_COMMIT_SHORT_SHA}" + buildah manifest create localhost/nix-coder-image \ + ${lib.concatStrings (builtins.map (sys: "docker-archive:dist/nix-coder-image_${sys} \\") SYSTEMS)} + '' + '' + buildah manifest push --all localhost/nix-coder-image \ + docker://''${CI_REGISTRY_IMAGE}/nix-coder-image:$CI_COMMIT_SHORT_SHA '' ]; }; From db049972eb9813dcbd5cf94f9e791f04f909fd62 Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 22:21:08 +0200 Subject: [PATCH 09/49] ci: add file endings to buildah manifest create --- flake.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index c63300a..764a2ec 100644 --- a/flake.nix +++ b/flake.nix @@ -131,7 +131,9 @@ script = [ '' buildah manifest create localhost/nix-coder-image \ - ${lib.concatStrings (builtins.map (sys: "docker-archive:dist/nix-coder-image_${sys} \\") SYSTEMS)} + ${lib.concatStrings ( + builtins.map (sys: "docker-archive:dist/nix-coder-image_${sys}.tar.gz \\") SYSTEMS + )} '' '' buildah manifest push --all localhost/nix-coder-image \ From 62aad664351f2f48bf49077d8f17466e71e8db6c Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 22:27:46 +0200 Subject: [PATCH 10/49] ci: create /var/tmp as buildah does not allow overriding the tmp dir --- flake.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/flake.nix b/flake.nix index 764a2ec..b8d4312 100644 --- a/flake.nix +++ b/flake.nix @@ -127,6 +127,7 @@ mkdir -p /etc/containers && echo '{"default":[{"type":"insecureAcceptAnything"}]}' > /etc/containers/policy.json '' + ''mkdir -p /var/tmp'' ]; script = [ '' From aebad80568f434bc933ab1c2a2c10b15ab22c6df Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 22:38:19 +0200 Subject: [PATCH 11/49] fix(CI): fix empty line breaking buildah manifest create command --- flake.nix | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/flake.nix b/flake.nix index b8d4312..d55f7ec 100644 --- a/flake.nix +++ b/flake.nix @@ -130,12 +130,10 @@ ''mkdir -p /var/tmp'' ]; script = [ - '' - buildah manifest create localhost/nix-coder-image \ - ${lib.concatStrings ( - builtins.map (sys: "docker-archive:dist/nix-coder-image_${sys}.tar.gz \\") SYSTEMS - )} - '' + (lib.concatStringsSep " " ( + ["buildah manifest create localhost/nix-coder-image"] + ++ builtins.map (sys: "docker-archive:dist/nix-coder-image_${sys}.tar.gz ") SYSTEMS + )) '' buildah manifest push --all localhost/nix-coder-image \ docker://''${CI_REGISTRY_IMAGE}/nix-coder-image:$CI_COMMIT_SHORT_SHA From e065b2416c911baf9038752930e0aa329f15b091 Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 22:58:06 +0200 Subject: [PATCH 12/49] fix(CI): turns out buildah does not accept more than 1 image argument --- flake.nix | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/flake.nix b/flake.nix index d55f7ec..2673360 100644 --- a/flake.nix +++ b/flake.nix @@ -129,16 +129,22 @@ '' ''mkdir -p /var/tmp'' ]; - script = [ - (lib.concatStringsSep " " ( - ["buildah manifest create localhost/nix-coder-image"] - ++ builtins.map (sys: "docker-archive:dist/nix-coder-image_${sys}.tar.gz ") SYSTEMS - )) - '' - buildah manifest push --all localhost/nix-coder-image \ - docker://''${CI_REGISTRY_IMAGE}/nix-coder-image:$CI_COMMIT_SHORT_SHA - '' - ]; + script = + [ + ''buildah manifest create localhost/nix-coder-image'' + ] + ++ ( + builtins.map (sys: '' + buildah manifest add localhost/nix-coder-image docker-archive:dist/nix-coder-image_${sys}.tar.gz + '') + SYSTEMS + ) + ++ [ + '' + buildah manifest push --all localhost/nix-coder-image \ + docker://''${CI_REGISTRY_IMAGE}/nix-coder-image:$CI_COMMIT_SHORT_SHA + '' + ]; }; }; }; From 48306fd0430b5a37e66cf25042a5014c26ae817d Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 24 Apr 2024 23:51:35 +0200 Subject: [PATCH 13/49] chore(image): add nix and busybox to base image --- image.nix | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/image.nix b/image.nix index f9b8abd..316fb61 100644 --- a/image.nix +++ b/image.nix @@ -9,7 +9,13 @@ pkgs.dockerTools.buildImage { copyToRoot = pkgs.buildEnv { name = "image-root"; - paths = [pkgs.bashInteractive pkgs.home-manager pkgs.direnv]; + paths = [ + pkgs.bashInteractive + pkgs.nixFlakes + pkgs.busybox + pkgs.home-manager + pkgs.direnv + ]; pathsToLink = ["/bin"]; }; From f4cf15c367c94c6ceb2e890bdac4e93cd550d19e Mon Sep 17 00:00:00 2001 From: technofab Date: Thu, 25 Apr 2024 00:07:30 +0200 Subject: [PATCH 14/49] =?UTF-8?q?chore(image):=20replace=20busybox=20?= =?UTF-8?q?=E2=86=92=20coreutils-full?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- image.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image.nix b/image.nix index 316fb61..ad0b4f7 100644 --- a/image.nix +++ b/image.nix @@ -12,7 +12,7 @@ pkgs.dockerTools.buildImage { paths = [ pkgs.bashInteractive pkgs.nixFlakes - pkgs.busybox + pkgs.coreutils-full pkgs.home-manager pkgs.direnv ]; From 89befec9cab9c0e9db5409b4b9f6538016c8daa1 Mon Sep 17 00:00:00 2001 From: technofab Date: Thu, 25 Apr 2024 00:42:29 +0200 Subject: [PATCH 15/49] chore(image): add curl --- image.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/image.nix b/image.nix index ad0b4f7..62d772e 100644 --- a/image.nix +++ b/image.nix @@ -13,6 +13,7 @@ pkgs.dockerTools.buildImage { pkgs.bashInteractive pkgs.nixFlakes pkgs.coreutils-full + pkgs.curl pkgs.home-manager pkgs.direnv ]; From 976c32ce5b45edbad8f1aaa6d824f3dfe8595511 Mon Sep 17 00:00:00 2001 From: technofab Date: Fri, 26 Apr 2024 20:44:44 +0200 Subject: [PATCH 16/49] chore(nix-kubernetes): mount tmpfs on /tmp --- nix-kubernetes/kubernetes.nix | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/nix-kubernetes/kubernetes.nix b/nix-kubernetes/kubernetes.nix index 22170a7..79ae7cc 100644 --- a/nix-kubernetes/kubernetes.nix +++ b/nix-kubernetes/kubernetes.nix @@ -29,6 +29,21 @@ }; }; }; + init_container = [ + { + name = "copy-nix-store"; + image = "registry.gitlab.com/technofab/coder-templates/nix-coder-image:\${data.coder_parameter.image_tag.value}"; + command = ["cp" "-nR" "/nix/." "/pv_nix"]; + security_context.run_as_user = "1000"; + volume_mount = [ + { + mount_path = "/pv_nix"; + name = "nix-store"; + read_only = false; + } + ]; + } + ]; container = [ { name = "workspace"; @@ -63,6 +78,11 @@ name = "nix-store"; read_only = false; } + { + mount_path = "/tmp"; + name = "tmp"; + read_only = false; + } ]; } ]; @@ -79,6 +99,14 @@ name = "nix-store"; persistent_volume_claim.claim_name = "\${resource.kubernetes_persistent_volume_claim.nix-store.metadata.0.name}"; } + { + name = "tmp"; + empty_dir = { + medium = "Memory"; + # not used for now + # sizeLimit = "200Mi"; + }; + } ]; }; }; From 0db1746a9e407638a060f006cbe9d9bc9f2ac0af Mon Sep 17 00:00:00 2001 From: technofab Date: Fri, 26 Apr 2024 20:45:24 +0200 Subject: [PATCH 17/49] fix(image): add CA certificates --- image.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/image.nix b/image.nix index 62d772e..219b32d 100644 --- a/image.nix +++ b/image.nix @@ -20,5 +20,8 @@ pkgs.dockerTools.buildImage { pathsToLink = ["/bin"]; }; - config.Cmd = ["/bin/bash"]; + config = { + Cmd = ["/bin/bash"]; + Env = ["SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"]; + }; } From cc11521d272cc88e249337c64cbdb1f67a04d5d3 Mon Sep 17 00:00:00 2001 From: technofab Date: Fri, 26 Apr 2024 21:19:57 +0200 Subject: [PATCH 18/49] fix(nix-kubernetes): add missing ${} for terraform --- nix-kubernetes/coder.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix-kubernetes/coder.nix b/nix-kubernetes/coder.nix index 26fa0bd..df6b32c 100644 --- a/nix-kubernetes/coder.nix +++ b/nix-kubernetes/coder.nix @@ -1,7 +1,7 @@ {...}: { locals."git_repo_folder" = let split_repo = ''split("/", data.coder_parameter.git_repo.value)''; - in ''try(element(${split_repo}, length(${split_repo}) - 1), "")''; + in ''''${try(element(${split_repo}, length(${split_repo}) - 1), "")}''; data = { coder_external_auth."gitlab" = { From e08b376bb77ee07864f487a10d6a19717689213e Mon Sep 17 00:00:00 2001 From: technofab Date: Fri, 26 Apr 2024 21:20:55 +0200 Subject: [PATCH 19/49] chore(nix-kubernetes): add runAsGroup to securityContext --- nix-kubernetes/kubernetes.nix | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/nix-kubernetes/kubernetes.nix b/nix-kubernetes/kubernetes.nix index 79ae7cc..482d017 100644 --- a/nix-kubernetes/kubernetes.nix +++ b/nix-kubernetes/kubernetes.nix @@ -66,7 +66,10 @@ memory = "\${data.coder_parameter.memory.value}"; }; }; - security_context.run_as_user = "1000"; + security_context = { + run_as_user = 1000; + run_as_group = 1000; + }; volume_mount = [ { mount_path = "/home"; @@ -87,8 +90,9 @@ } ]; security_context = { - fs_group = "1000"; - run_as_user = "1000"; + fs_group = 1000; + run_as_user = 1000; + run_as_group = 1000; }; volume = [ { From 166dbea57a502a0254148eb05f2ff13f7d03e4ad Mon Sep 17 00:00:00 2001 From: technofab Date: Fri, 26 Apr 2024 21:22:17 +0200 Subject: [PATCH 20/49] chore(image): add /etc/passwd, set $HOME and enable nix experimental features by default --- image.nix | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/image.nix b/image.nix index 219b32d..a1b545e 100644 --- a/image.nix +++ b/image.nix @@ -16,12 +16,17 @@ pkgs.dockerTools.buildImage { pkgs.curl pkgs.home-manager pkgs.direnv + (pkgs.writeTextDir "etc/nix/nix.conf" "experimental-features = nix-command flakes") + (pkgs.writeTextDir "etc/passwd" "coder:x:1000:1000::/home/coder:/bin/bash") ]; - pathsToLink = ["/bin"]; + pathsToLink = ["/bin" "/etc"]; }; config = { Cmd = ["/bin/bash"]; - Env = ["SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"]; + Env = [ + "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" + "HOME=/home/coder" + ]; }; } From 5ac20ae50634446cc92ff3d07e9a269b5018b157 Mon Sep 17 00:00:00 2001 From: technofab Date: Sat, 27 Apr 2024 15:11:09 +0200 Subject: [PATCH 21/49] fix(nix-kubernetes): remove shebang from git_clone script and hide pushd/popd output --- nix-kubernetes/coder.nix | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/nix-kubernetes/coder.nix b/nix-kubernetes/coder.nix index df6b32c..a49a679 100644 --- a/nix-kubernetes/coder.nix +++ b/nix-kubernetes/coder.nix @@ -24,16 +24,13 @@ repo = ''''${data.coder_parameter.git_repo.value}''; repo_folder = ''''${local.git_repo_folder}''; in '' - #!/usr/bin/env bash - set -eux - echo "Cloning repo \"${repo}\" if it does not exist" mkdir -p ~/repos - pushd ~/repos + pushd ~/repos >/dev/null if [[ ! -z "${repo}" && ! -d "${repo_folder}" ]] then git clone ${repo} ${repo_folder} fi - popd + popd >/dev/null ''; run_on_start = true; start_blocks_login = true; From 8fd40e2e6e8be516377360ba514e3f881be2d785 Mon Sep 17 00:00:00 2001 From: technofab Date: Sat, 27 Apr 2024 15:12:10 +0200 Subject: [PATCH 22/49] chore(image): create various directories, add normal bash and git and switch to layered image --- image.nix | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/image.nix b/image.nix index a1b545e..ff981ba 100644 --- a/image.nix +++ b/image.nix @@ -3,30 +3,40 @@ pkgs, ... }: -pkgs.dockerTools.buildImage { +pkgs.dockerTools.buildLayeredImage { name = "nix-coder"; tag = "latest"; - copyToRoot = pkgs.buildEnv { + contents = pkgs.buildEnv { name = "image-root"; paths = [ + pkgs.bash pkgs.bashInteractive - pkgs.nixFlakes + pkgs.nix pkgs.coreutils-full + pkgs.git pkgs.curl pkgs.home-manager pkgs.direnv (pkgs.writeTextDir "etc/nix/nix.conf" "experimental-features = nix-command flakes") (pkgs.writeTextDir "etc/passwd" "coder:x:1000:1000::/home/coder:/bin/bash") + (pkgs.writeTextDir "etc/shadow" "coder:!:::::::") + (pkgs.writeTextDir "etc/group" "coder:x:1000:") + (pkgs.writeTextDir "etc/gshadow" "coder:x::") ]; pathsToLink = ["/bin" "/etc"]; }; + maxLayers = 5; + fakeRootCommands = '' + mkdir -p ./home/coder ./tmp ./nix/var/nix + ''; config = { Cmd = ["/bin/bash"]; Env = [ "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" "HOME=/home/coder" + "USER=coder" ]; }; } From b12392dffc1d3c2105c4ac8993a941d1d5e1fe81 Mon Sep 17 00:00:00 2001 From: technofab Date: Sat, 27 Apr 2024 17:56:06 +0200 Subject: [PATCH 23/49] chore(image): add openssh --- image.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/image.nix b/image.nix index ff981ba..10bed46 100644 --- a/image.nix +++ b/image.nix @@ -14,6 +14,7 @@ pkgs.dockerTools.buildLayeredImage { pkgs.bashInteractive pkgs.nix pkgs.coreutils-full + pkgs.openssh pkgs.git pkgs.curl pkgs.home-manager From eb737c39b2f52f8e3b94d1cca2de2e07404b4800 Mon Sep 17 00:00:00 2001 From: technofab Date: Sat, 27 Apr 2024 19:52:11 +0200 Subject: [PATCH 24/49] chore(nix-kubernetes): clean up git_clone script --- nix-kubernetes/coder.nix | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/nix-kubernetes/coder.nix b/nix-kubernetes/coder.nix index a49a679..bf7de48 100644 --- a/nix-kubernetes/coder.nix +++ b/nix-kubernetes/coder.nix @@ -24,13 +24,17 @@ repo = ''''${data.coder_parameter.git_repo.value}''; repo_folder = ''''${local.git_repo_folder}''; in '' - echo "Cloning repo \"${repo}\" if it does not exist" mkdir -p ~/repos - pushd ~/repos >/dev/null - if [[ ! -z "${repo}" && ! -d "${repo_folder}" ]] then - git clone ${repo} ${repo_folder} - fi - popd >/dev/null + if [ ! -z "${repo}" ] then + echo "Cloning repo \"${repo}\" if it does not exist" + pushd ~/repos >/dev/null + if [[ ! -d "${repo_folder}" ]] then + git clone ${repo} ${repo_folder} + fi + popd >/dev/null + else + echo "No git repo specified, skipping..." + fi ''; run_on_start = true; start_blocks_login = true; From ba17b0ee0cabfc30e546730b47c6f57b83331a69 Mon Sep 17 00:00:00 2001 From: technofab Date: Sat, 27 Apr 2024 19:52:51 +0200 Subject: [PATCH 25/49] feat: add dotfile loading via home-manager --- image.nix | 5 +++-- nix-kubernetes/coder.nix | 15 +++++++++++++++ nix-kubernetes/kubernetes.nix | 4 ++++ nix-kubernetes/parameters.nix | 25 +++++++++++++++++++------ 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/image.nix b/image.nix index 10bed46..9736a4d 100644 --- a/image.nix +++ b/image.nix @@ -17,8 +17,9 @@ pkgs.dockerTools.buildLayeredImage { pkgs.openssh pkgs.git pkgs.curl - pkgs.home-manager - pkgs.direnv + (pkgs.writeShellScriptBin "reload-dotfiles" '' + ${pkgs.home-manager}/bin/home-manager switch --flake ''${DOTFILES_REPO:-$1} + '') (pkgs.writeTextDir "etc/nix/nix.conf" "experimental-features = nix-command flakes") (pkgs.writeTextDir "etc/passwd" "coder:x:1000:1000::/home/coder:/bin/bash") (pkgs.writeTextDir "etc/shadow" "coder:!:::::::") diff --git a/nix-kubernetes/coder.nix b/nix-kubernetes/coder.nix index bf7de48..227153e 100644 --- a/nix-kubernetes/coder.nix +++ b/nix-kubernetes/coder.nix @@ -39,5 +39,20 @@ run_on_start = true; start_blocks_login = true; }; + coder_script."home-manager" = { + agent_id = "\${coder_agent.coder.id}"; + display_name = "Home Manager"; + icon = "/emojis/1f3e0.png"; + script = '' + if [ ! -z "$DOTFILES_REPO" ] then + echo "Dotfiles present, reloading home-manager profile" + reload-dotfiles + else + echo "No dotfiles repo specified, skipping..." + fi + ''; + run_on_start = true; + start_blocks_login = true; + }; }; } diff --git a/nix-kubernetes/kubernetes.nix b/nix-kubernetes/kubernetes.nix index 482d017..1c5cc30 100644 --- a/nix-kubernetes/kubernetes.nix +++ b/nix-kubernetes/kubernetes.nix @@ -54,6 +54,10 @@ name = "CODER_AGENT_TOKEN"; value = "\${resource.coder_agent.coder.token}"; } + { + name = "DOTFILES_REPO"; + value = "\${data.coder_parameter.dotfiles_repo.value}"; + } ]; resources = { requests = { diff --git a/nix-kubernetes/parameters.nix b/nix-kubernetes/parameters.nix index cd305f9..630bfbb 100644 --- a/nix-kubernetes/parameters.nix +++ b/nix-kubernetes/parameters.nix @@ -1,12 +1,25 @@ {...}: { data.coder_parameter = { + dotfiles_repo = { + name = "Dotfiles Repository (passed to home-manager)"; + description = '' + Nix flake URI to your dotfiles repository, eg. + github:example/dotfiles#coder + + Your flake.nix has to expose a homeManagerConfiguration.coder in this case. + ''; + default = ""; + order = 1; + type = "string"; + mutable = true; + }; git_repo = { name = "Git Repository"; description = '' URI for a git repository which should automatically be cloned to ~/repos/ ''; default = ""; - order = 1; + order = 2; type = "string"; mutable = true; }; @@ -16,7 +29,7 @@ Which container image tag should be used. ''; default = "latest"; - order = 2; + order = 3; type = "string"; mutable = true; }; @@ -26,7 +39,7 @@ CPU Limit for Kubernetes Pod. Kubernetes Notation (eg. 500m) ''; default = "500m"; - order = 3; + order = 4; type = "string"; mutable = true; }; @@ -36,7 +49,7 @@ Memory Limit for Kubernetes Pod. Kubernetes Notation (eg. 1Gi) ''; default = "1Gi"; - order = 4; + order = 5; type = "string"; mutable = true; }; @@ -46,7 +59,7 @@ Size for the /home PV in GB ''; default = 5; - order = 5; + order = 6; type = "number"; mutable = true; validation = [ @@ -63,7 +76,7 @@ Size for the /nix PV in GB. This might grow pretty big. ''; default = 5; - order = 6; + order = 7; type = "number"; mutable = true; validation = [ From 67f511504865ce82bdf3fc4f0cd229c1cfcb104e Mon Sep 17 00:00:00 2001 From: technofab Date: Sat, 27 Apr 2024 21:05:36 +0200 Subject: [PATCH 26/49] fix(nix-kubernetes): add missing semicolons --- nix-kubernetes/coder.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nix-kubernetes/coder.nix b/nix-kubernetes/coder.nix index 227153e..35cc6c5 100644 --- a/nix-kubernetes/coder.nix +++ b/nix-kubernetes/coder.nix @@ -25,7 +25,7 @@ repo_folder = ''''${local.git_repo_folder}''; in '' mkdir -p ~/repos - if [ ! -z "${repo}" ] then + if [ ! -z "${repo}" ]; then echo "Cloning repo \"${repo}\" if it does not exist" pushd ~/repos >/dev/null if [[ ! -d "${repo_folder}" ]] then @@ -44,7 +44,7 @@ display_name = "Home Manager"; icon = "/emojis/1f3e0.png"; script = '' - if [ ! -z "$DOTFILES_REPO" ] then + if [ ! -z "$DOTFILES_REPO" ]; then echo "Dotfiles present, reloading home-manager profile" reload-dotfiles else From 058e2f73e8037e048b058cb86237f92fd63d09be Mon Sep 17 00:00:00 2001 From: technofab Date: Tue, 7 May 2024 00:48:23 +0200 Subject: [PATCH 27/49] fix(image): set ownership of most image contents to 1000:1000 to fix permission issues --- image.nix | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/image.nix b/image.nix index 9736a4d..7cc6798 100644 --- a/image.nix +++ b/image.nix @@ -20,7 +20,9 @@ pkgs.dockerTools.buildLayeredImage { (pkgs.writeShellScriptBin "reload-dotfiles" '' ${pkgs.home-manager}/bin/home-manager switch --flake ''${DOTFILES_REPO:-$1} '') - (pkgs.writeTextDir "etc/nix/nix.conf" "experimental-features = nix-command flakes") + (pkgs.writeTextDir "etc/nix/nix.conf" '' + experimental-features = nix-command flakes + '') (pkgs.writeTextDir "etc/passwd" "coder:x:1000:1000::/home/coder:/bin/bash") (pkgs.writeTextDir "etc/shadow" "coder:!:::::::") (pkgs.writeTextDir "etc/group" "coder:x:1000:") @@ -30,11 +32,17 @@ pkgs.dockerTools.buildLayeredImage { }; maxLayers = 5; + uid = 1000; + gid = 1000; fakeRootCommands = '' - mkdir -p ./home/coder ./tmp ./nix/var/nix + mkdir -p /home/coder /tmp /nix/var/nix + chown -R 1000:1000 / ''; + enableFakechroot = true; + config = { Cmd = ["/bin/bash"]; + User = "1000:1000"; Env = [ "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" "HOME=/home/coder" From be75e2cc006e9b96a63a55b58b03054f52a8ad01 Mon Sep 17 00:00:00 2001 From: technofab Date: Tue, 7 May 2024 01:03:00 +0200 Subject: [PATCH 28/49] fix(image): apparently fakechroot does not work well on aarch64-linux --- image.nix | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/image.nix b/image.nix index 7cc6798..46c27fc 100644 --- a/image.nix +++ b/image.nix @@ -35,10 +35,9 @@ pkgs.dockerTools.buildLayeredImage { uid = 1000; gid = 1000; fakeRootCommands = '' - mkdir -p /home/coder /tmp /nix/var/nix - chown -R 1000:1000 / + mkdir -p ./home/coder ./tmp ./nix/var/nix + chown -R 1000:1000 ./ ''; - enableFakechroot = true; config = { Cmd = ["/bin/bash"]; From 77fda07aa66b67669ac44f66118b5519796ab31d Mon Sep 17 00:00:00 2001 From: technofab Date: Tue, 7 May 2024 20:18:50 +0200 Subject: [PATCH 29/49] fix(nix-kubernetes): chown manually and remove fsGroup --- nix-kubernetes/kubernetes.nix | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/nix-kubernetes/kubernetes.nix b/nix-kubernetes/kubernetes.nix index 1c5cc30..128abba 100644 --- a/nix-kubernetes/kubernetes.nix +++ b/nix-kubernetes/kubernetes.nix @@ -30,6 +30,29 @@ }; }; init_container = [ + { + name = "chown"; + image = "alpine:3"; + command = ["chown" "1000:1000" "/mnt/nix" "/mnt/tmp" "/mnt/home"]; + security_context.run_as_user = "0"; + volume_mount = [ + { + mount_path = "/mnt/home"; + name = "home"; + read_only = false; + } + { + mount_path = "/mnt/nix"; + name = "nix-store"; + read_only = false; + } + { + mount_path = "/mnt/tmp"; + name = "tmp"; + read_only = false; + } + ]; + } { name = "copy-nix-store"; image = "registry.gitlab.com/technofab/coder-templates/nix-coder-image:\${data.coder_parameter.image_tag.value}"; @@ -94,7 +117,6 @@ } ]; security_context = { - fs_group = 1000; run_as_user = 1000; run_as_group = 1000; }; From 70601ffbd0e33034b6a0467aee26df3dd66b1345 Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 8 May 2024 13:35:41 +0200 Subject: [PATCH 30/49] chore(image): add ncurses and usrBinEnv --- image.nix | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/image.nix b/image.nix index 46c27fc..e259424 100644 --- a/image.nix +++ b/image.nix @@ -9,26 +9,28 @@ pkgs.dockerTools.buildLayeredImage { contents = pkgs.buildEnv { name = "image-root"; - paths = [ - pkgs.bash - pkgs.bashInteractive - pkgs.nix - pkgs.coreutils-full - pkgs.openssh - pkgs.git - pkgs.curl - (pkgs.writeShellScriptBin "reload-dotfiles" '' - ${pkgs.home-manager}/bin/home-manager switch --flake ''${DOTFILES_REPO:-$1} + paths = with pkgs; [ + bash + bashInteractive + nix + coreutils-full + openssh + git + curl + ncurses + dockerTools.usrBinEnv + (writeShellScriptBin "reload-dotfiles" '' + ${home-manager}/bin/home-manager switch --flake ''${DOTFILES_REPO:-$1} '') - (pkgs.writeTextDir "etc/nix/nix.conf" '' + (writeTextDir "etc/nix/nix.conf" '' experimental-features = nix-command flakes '') - (pkgs.writeTextDir "etc/passwd" "coder:x:1000:1000::/home/coder:/bin/bash") - (pkgs.writeTextDir "etc/shadow" "coder:!:::::::") - (pkgs.writeTextDir "etc/group" "coder:x:1000:") - (pkgs.writeTextDir "etc/gshadow" "coder:x::") + (writeTextDir "etc/passwd" "coder:x:1000:1000::/home/coder:/bin/bash") + (writeTextDir "etc/shadow" "coder:!:::::::") + (writeTextDir "etc/group" "coder:x:1000:") + (writeTextDir "etc/gshadow" "coder:x::") ]; - pathsToLink = ["/bin" "/etc"]; + pathsToLink = ["/bin" "/etc" "/usr"]; }; maxLayers = 5; From 1392cb7d0c01496a5ccd60221a714db29d7f38ba Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 8 May 2024 13:36:59 +0200 Subject: [PATCH 31/49] chore(nix-kubernetes): allow configuring cpu and memory request for template --- nix-kubernetes/kubernetes.nix | 5 ++--- nix-kubernetes/variables.nix | 10 ++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/nix-kubernetes/kubernetes.nix b/nix-kubernetes/kubernetes.nix index 128abba..27b9280 100644 --- a/nix-kubernetes/kubernetes.nix +++ b/nix-kubernetes/kubernetes.nix @@ -84,9 +84,8 @@ ]; resources = { requests = { - # TODO: allow configuring this via variables (template wide) - cpu = "250m"; - memory = "512Mi"; + cpu = "\${var.cpu_request}"; + memory = "\${var.memory_request}"; }; limits = { cpu = "\${data.coder_parameter.cpu.value}"; diff --git a/nix-kubernetes/variables.nix b/nix-kubernetes/variables.nix index 33de9dd..cfe1801 100644 --- a/nix-kubernetes/variables.nix +++ b/nix-kubernetes/variables.nix @@ -12,5 +12,15 @@ error_message = "Invalid architecture selected"; }; }; + cpu_request = { + type = "string"; + description = "CPU request to apply to workspaces. Kubernetes Notation (eg. 500m)"; + default = "0"; + }; + memory_request = { + type = "string"; + description = "Memory request to apply to workspaces. Kubernetes Notation (eg. 1Gi)"; + default = "0"; + }; }; } From 7da286dcfe7302e4f7535c60a4ce6739bd7a544b Mon Sep 17 00:00:00 2001 From: technofab Date: Wed, 8 May 2024 14:44:50 +0200 Subject: [PATCH 32/49] chore: add /etc/os-release for coder stat to work --- image.nix | 3 +++ nix-kubernetes/coder.nix | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/image.nix b/image.nix index e259424..e85f22b 100644 --- a/image.nix +++ b/image.nix @@ -25,6 +25,9 @@ pkgs.dockerTools.buildLayeredImage { (writeTextDir "etc/nix/nix.conf" '' experimental-features = nix-command flakes '') + (writeTextDir "etc/os-release" '' + ID=nixos + '') (writeTextDir "etc/passwd" "coder:x:1000:1000::/home/coder:/bin/bash") (writeTextDir "etc/shadow" "coder:!:::::::") (writeTextDir "etc/group" "coder:x:1000:") diff --git a/nix-kubernetes/coder.nix b/nix-kubernetes/coder.nix index 35cc6c5..9b637c1 100644 --- a/nix-kubernetes/coder.nix +++ b/nix-kubernetes/coder.nix @@ -15,6 +15,36 @@ coder_agent."coder" = { arch = "\${var.arch}"; os = "linux"; + metadata = [ + { + display_name = "Container CPU Usage"; + key = "0_cpu_usage"; + script = "coder stat cpu --host=false"; + interval = 10; + timeout = 1; + } + { + display_name = "Container RAM Usage"; + key = "1_ram_usage"; + script = "coder stat mem --host=false"; + interval = 10; + timeout = 1; + } + { + display_name = "Home Disk"; + key = "2_home_disk"; + script = "coder stat disk --path $${HOME}"; + interval = 60; + timeout = 1; + } + { + display_name = "Nix Store Disk"; + key = "3_nix_store_disk"; + script = "coder stat disk --path /nix"; + interval = 60; + timeout = 1; + } + ]; }; coder_script."git_clone" = { agent_id = "\${coder_agent.coder.id}"; From a4a331c3386f9b4c24bdbcaee1e79ffb20bd2300 Mon Sep 17 00:00:00 2001 From: technofab Date: Fri, 24 May 2024 15:53:29 +0200 Subject: [PATCH 33/49] chore: add tarball ttl option to reload-dotfiles to prevent caching --- image.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image.nix b/image.nix index e85f22b..28092c5 100644 --- a/image.nix +++ b/image.nix @@ -20,7 +20,7 @@ pkgs.dockerTools.buildLayeredImage { ncurses dockerTools.usrBinEnv (writeShellScriptBin "reload-dotfiles" '' - ${home-manager}/bin/home-manager switch --flake ''${DOTFILES_REPO:-$1} + ${home-manager}/bin/home-manager switch --flake ''${DOTFILES_REPO:-$1} --option tarball-ttl 0 '') (writeTextDir "etc/nix/nix.conf" '' experimental-features = nix-command flakes From 28e98a788d99292d85ae2f73f1912f1ecb8d935f Mon Sep 17 00:00:00 2001 From: technofab Date: Fri, 24 May 2024 17:02:17 +0200 Subject: [PATCH 34/49] chore: switch to gitMinimal to reduce image size --- image.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image.nix b/image.nix index 28092c5..69cacee 100644 --- a/image.nix +++ b/image.nix @@ -15,7 +15,7 @@ pkgs.dockerTools.buildLayeredImage { nix coreutils-full openssh - git + gitMinimal curl ncurses dockerTools.usrBinEnv From 387b3081a6ba7d3be0b3f30375fe78e8b9acd597 Mon Sep 17 00:00:00 2001 From: TECHNOFAB Date: Wed, 12 Jun 2024 12:49:35 +0000 Subject: [PATCH 35/49] fix(image): add grep --- image.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/image.nix b/image.nix index 69cacee..884cf0b 100644 --- a/image.nix +++ b/image.nix @@ -14,6 +14,7 @@ pkgs.dockerTools.buildLayeredImage { bashInteractive nix coreutils-full + gnugrep openssh gitMinimal curl From 9d511995b6512a75b4b35cbb5f1a7360d4a43ecb Mon Sep 17 00:00:00 2001 From: technofab Date: Thu, 3 Oct 2024 19:08:25 +0000 Subject: [PATCH 36/49] chore: update flake inputs and add treefmt-nix --- flake.lock | 744 +++++++++++++++++++---------------------------------- flake.nix | 58 ++--- 2 files changed, 297 insertions(+), 505 deletions(-) diff --git a/flake.lock b/flake.lock index 7a1c615..2117857 100644 --- a/flake.lock +++ b/flake.lock @@ -1,27 +1,5 @@ { "nodes": { - "attic": { - "inputs": { - "crane": "crane", - "flake-compat": "flake-compat_4", - "flake-utils": "flake-utils_4", - "nixpkgs": "nixpkgs_4", - "nixpkgs-stable": "nixpkgs-stable_3" - }, - "locked": { - "lastModified": 1710680783, - "narHash": "sha256-exrsUUk/VSCG2Y3Sr/dkST8vwICzab3fe8Je81t/SfM=", - "owner": "TECHNOFAB", - "repo": "attic", - "rev": "b6d8d5ca53ef15910042a39e81f35383370c1112", - "type": "gitlab" - }, - "original": { - "owner": "TECHNOFAB", - "repo": "attic", - "type": "gitlab" - } - }, "bats-assert": { "flake": false, "locked": { @@ -61,11 +39,47 @@ "devenv", "flake-compat" ], + "git-hooks": [ + "devenv", + "pre-commit-hooks" + ], "nixpkgs": [ "devenv", "nixpkgs" + ] + }, + "locked": { + "lastModified": 1724232775, + "narHash": "sha256-6u2DycIEgrgNYlLxyGqdFVmBNiKIitnQKJ1pbRP5oko=", + "owner": "cachix", + "repo": "cachix", + "rev": "03b6cb3f953097bff378fb8b9ea094bd091a4ec7", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "cachix", + "type": "github" + } + }, + "cachix_2": { + "inputs": { + "devenv": "devenv_3", + "flake-compat": [ + "devenv", + "cachix", + "devenv", + "flake-compat" + ], + "nixpkgs": [ + "devenv", + "cachix", + "devenv", + "nixpkgs" ], "pre-commit-hooks": [ + "devenv", + "cachix", "devenv", "pre-commit-hooks" ] @@ -84,42 +98,20 @@ "type": "github" } }, - "crane": { - "inputs": { - "nixpkgs": [ - "nix-gitlab-ci", - "attic", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1702918879, - "narHash": "sha256-tWJqzajIvYcaRWxn+cLUB9L9Pv4dQ3Bfit/YjU5ze3g=", - "owner": "ipetkov", - "repo": "crane", - "rev": "7195c00c272fdd92fc74e7d5a0a2844b9fadb2fb", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, "devenv": { "inputs": { "cachix": "cachix", "flake-compat": "flake-compat_2", - "nix": "nix_2", - "nixpkgs": "nixpkgs_2", - "pre-commit-hooks": "pre-commit-hooks" + "nix": "nix_3", + "nixpkgs": "nixpkgs_3", + "pre-commit-hooks": "pre-commit-hooks_2" }, "locked": { - "lastModified": 1713968789, - "narHash": "sha256-Gue8iwW3ZtCQs3EZKhk/i0uLaoUDfW1dpnaZ67MH64o=", + "lastModified": 1726417371, + "narHash": "sha256-tBq8w81ZV48tyFhLz5WQjqfoEShIXkOb6Rlzidcz8yQ=", "owner": "cachix", "repo": "devenv", - "rev": "b26b52a4dac68bdc305f6b9df948c97f49b2c3ee", + "rev": "1f55f89ca32d617b7a7c18422e3c364cb003df3d", "type": "github" }, "original": { @@ -130,15 +122,53 @@ }, "devenv_2": { "inputs": { + "cachix": "cachix_2", "flake-compat": [ "devenv", "cachix", "flake-compat" ], + "nix": "nix_2", + "nixpkgs": [ + "devenv", + "cachix", + "nixpkgs" + ], + "pre-commit-hooks": [ + "devenv", + "cachix", + "git-hooks" + ] + }, + "locked": { + "lastModified": 1723156315, + "narHash": "sha256-0JrfahRMJ37Rf1i0iOOn+8Z4CLvbcGNwa2ChOAVrp/8=", + "owner": "cachix", + "repo": "devenv", + "rev": "ff5eb4f2accbcda963af67f1a1159e3f6c7f5f91", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "devenv_3": { + "inputs": { + "flake-compat": [ + "devenv", + "cachix", + "devenv", + "cachix", + "flake-compat" + ], "nix": "nix", "nixpkgs": "nixpkgs", "poetry2nix": "poetry2nix", "pre-commit-hooks": [ + "devenv", + "cachix", "devenv", "cachix", "pre-commit-hooks" @@ -191,57 +221,13 @@ "type": "github" } }, - "flake-compat_3": { - "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-compat_4": { - "flake": false, - "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_5": { - "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" + "nixpkgs-lib": [ + "devenv", + "nix", + "nixpkgs" + ] }, "locked": { "lastModified": 1712014858, @@ -259,32 +245,14 @@ }, "flake-parts_2": { "inputs": { - "nixpkgs-lib": "nixpkgs-lib_2" + "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1704982712, - "narHash": "sha256-2Ptt+9h8dczgle2Oo6z5ni5rt/uLMG47UFTR1ry/wgg=", + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "07f6395285469419cf9d078f59b5b49993198c00", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_3": { - "inputs": { - "nixpkgs-lib": "nixpkgs-lib_3" - }, - "locked": { - "lastModified": 1704982712, - "narHash": "sha256-2Ptt+9h8dczgle2Oo6z5ni5rt/uLMG47UFTR1ry/wgg=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "07f6395285469419cf9d078f59b5b49993198c00", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", "type": "github" }, "original": { @@ -312,42 +280,6 @@ } }, "flake-utils_2": { - "inputs": { - "systems": "systems_2" - }, - "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" - } - }, - "flake-utils_3": { - "inputs": { - "systems": "systems_3" - }, - "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_4": { "locked": { "lastModified": 1667395993, "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", @@ -362,25 +294,7 @@ "type": "github" } }, - "flake-utils_5": { - "inputs": { - "systems": "systems_4" - }, - "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_6": { + "flake-utils_3": { "locked": { "lastModified": 1634851050, "narHash": "sha256-N83GlSGPJJdcqhUxSCS/WwW5pksYf3VP1M13cDRTSVA=", @@ -417,47 +331,19 @@ "type": "github" } }, - "gitignore_2": { - "inputs": { - "nixpkgs": [ - "nix-devtools", - "pre-commit-hooks", - "nixpkgs" - ] - }, + "libgit2": { + "flake": false, "locked": { - "lastModified": 1703887061, - "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", + "lastModified": 1697646580, + "narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=", + "owner": "libgit2", + "repo": "libgit2", + "rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5", "type": "github" }, "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "gitignore_3": { - "inputs": { - "nixpkgs": [ - "nix-gitlab-ci", - "pre-commit-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1703887061, - "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", + "owner": "libgit2", + "repo": "libgit2", "type": "github" } }, @@ -465,6 +351,8 @@ "inputs": { "flake-compat": "flake-compat", "nixpkgs": [ + "devenv", + "cachix", "devenv", "cachix", "devenv", @@ -488,28 +376,17 @@ } }, "nix-devtools": { - "inputs": { - "devenv": [ - "devenv" - ], - "flake-parts": "flake-parts_2", - "nixpkgs": [ - "nixpkgs" - ], - "pre-commit-hooks": "pre-commit-hooks_2", - "systems": [ - "systems" - ] - }, "locked": { - "lastModified": 1709912203, - "narHash": "sha256-5kFeGMA1reDLUEaEETtpwp0myG06B3PCO/q8NtuKH7k=", + "dir": "lib", + "lastModified": 1722613543, + "narHash": "sha256-P3UoMSECGwbMAWIwViPlbw2s8lIqsj3uFzO/G/5EfnI=", "owner": "TECHNOFAB", "repo": "nix-devtools", - "rev": "059d3aa070c09ac48eb74489aa4c6852a5395f55", + "rev": "a004f97ca84673c4438a8853ba3b5b3186903752", "type": "gitlab" }, "original": { + "dir": "lib", "owner": "TECHNOFAB", "repo": "nix-devtools", "type": "gitlab" @@ -518,6 +395,8 @@ "nix-github-actions": { "inputs": { "nixpkgs": [ + "devenv", + "cachix", "devenv", "cachix", "devenv", @@ -540,29 +419,17 @@ } }, "nix-gitlab-ci": { - "inputs": { - "attic": "attic", - "devenv": [ - "devenv" - ], - "flake-parts": "flake-parts_3", - "nixpkgs": [ - "nixpkgs" - ], - "pre-commit-hooks": "pre-commit-hooks_3", - "systems": [ - "systems" - ] - }, "locked": { - "lastModified": 1711224545, - "narHash": "sha256-eWzQ6VZ5R30aLQ7ifpasi0F0MdxdwErevZ2Z8tMPYXA=", + "dir": "lib", + "lastModified": 1726479668, + "narHash": "sha256-fp6lWU+xF7XpjrdtEKWgwAc4wIl0WVMrt69Rlx5K1fc=", "owner": "TECHNOFAB", "repo": "nix-gitlab-ci", - "rev": "c272bfd81206a2888920258ea6620fd7f5ed4f7c", + "rev": "6448bf59164a2e66aa8bfe5ed8e128ce9f4a4a8e", "type": "gitlab" }, "original": { + "dir": "lib", "owner": "TECHNOFAB", "repo": "nix-gitlab-ci", "type": "gitlab" @@ -571,10 +438,14 @@ "nix_2": { "inputs": { "flake-compat": [ + "devenv", + "cachix", "devenv", "flake-compat" ], "nixpkgs": [ + "devenv", + "cachix", "devenv", "nixpkgs" ], @@ -595,6 +466,34 @@ "type": "github" } }, + "nix_3": { + "inputs": { + "flake-compat": [ + "devenv", + "flake-compat" + ], + "flake-parts": "flake-parts", + "libgit2": "libgit2", + "nixpkgs": "nixpkgs_2", + "nixpkgs-23-11": "nixpkgs-23-11", + "nixpkgs-regression": "nixpkgs-regression_3", + "pre-commit-hooks": "pre-commit-hooks" + }, + "locked": { + "lastModified": 1725980365, + "narHash": "sha256-uDwWyizzlQ0HFzrhP6rVp2+2NNA+/TM5zT32dR8GUlg=", + "owner": "domenkozar", + "repo": "nix", + "rev": "1e61e9f40673f84c3b02573145492d8af581bec5", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "devenv-2.24", + "repo": "nix", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1692808169, @@ -611,6 +510,22 @@ "type": "github" } }, + "nixpkgs-23-11": { + "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": { "dir": "lib", @@ -629,42 +544,6 @@ "type": "github" } }, - "nixpkgs-lib_2": { - "locked": { - "dir": "lib", - "lastModified": 1703961334, - "narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9", - "type": "github" - }, - "original": { - "dir": "lib", - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-lib_3": { - "locked": { - "dir": "lib", - "lastModified": 1703961334, - "narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9", - "type": "github" - }, - "original": { - "dir": "lib", - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs-regression": { "locked": { "lastModified": 1643052045, @@ -697,77 +576,61 @@ "type": "github" } }, + "nixpkgs-regression_3": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, "nixpkgs-stable": { "locked": { - "lastModified": 1710695816, - "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", + "lastModified": 1720386169, + "narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "614b4613980a522ba49f0d194531beddbb7220d3", + "rev": "194846768975b7ad2c4988bdb82572c00222c0d7", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-23.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-stable_2": { - "locked": { - "lastModified": 1704874635, - "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-stable_3": { - "locked": { - "lastModified": 1702780907, - "narHash": "sha256-blbrBBXjjZt6OKTcYX1jpe9SRof2P9ZYWPzq22tzXAA=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "1e2e384c5b7c50dbf8e9c441a9e58d85f408b01f", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-stable_4": { - "locked": { - "lastModified": 1704874635, - "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.11", + "ref": "nixos-24.05", "repo": "nixpkgs", "type": "github" } }, "nixpkgs_2": { "locked": { - "lastModified": 1713361204, - "narHash": "sha256-TA6EDunWTkc5FvDCqU3W2T3SFn0gRZqh6D/hJnM02MM=", + "lastModified": 1717432640, + "narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "88269ab3044128b7c2f4c7d68448b2fb50456870", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1716977621, + "narHash": "sha256-Q1UQzYcMJH4RscmpTkjlgqQDX5yi1tZL0O345Ri6vXQ=", "owner": "cachix", "repo": "devenv-nixpkgs", - "rev": "285676e87ad9f0ca23d8714a6ab61e7e027020c6", + "rev": "4267e705586473d3e5c8d50299e71503f16a6fb6", "type": "github" }, "original": { @@ -777,55 +640,7 @@ "type": "github" } }, - "nixpkgs_3": { - "locked": { - "lastModified": 1704842529, - "narHash": "sha256-OTeQA+F8d/Evad33JMfuXC89VMetQbsU4qcaePchGr4=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "eabe8d3eface69f5bb16c18f8662a702f50c20d5", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs_4": { - "locked": { - "lastModified": 1702539185, - "narHash": "sha256-KnIRG5NMdLIpEkZTnN5zovNYc0hhXjAgv6pfd5Z4c7U=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "aa9d4729cbc99dabacb50e3994dcefb3ea0f7447", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_5": { - "locked": { - "lastModified": 1704842529, - "narHash": "sha256-OTeQA+F8d/Evad33JMfuXC89VMetQbsU4qcaePchGr4=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "eabe8d3eface69f5bb16c18f8662a702f50c20d5", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_6": { "locked": { "lastModified": 1713805509, "narHash": "sha256-YgSEan4CcrjivCNO5ZNzhg7/8ViLkZ4CB/GrGBVSudo=", @@ -841,7 +656,7 @@ "type": "github" } }, - "nixpkgs_7": { + "nixpkgs_5": { "locked": { "lastModified": 1636823747, "narHash": "sha256-oWo1nElRAOZqEf90Yek2ixdHyjD+gqtS/pAgwaQ9UhQ=", @@ -856,11 +671,29 @@ "type": "github" } }, + "nixpkgs_6": { + "locked": { + "lastModified": 1725103162, + "narHash": "sha256-Ym04C5+qovuQDYL/rKWSR+WESseQBbNAe5DsXNx5trY=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "12228ff1752d7b7624a54e9c1af4b222b3c1073b", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "poetry2nix": { "inputs": { "flake-utils": "flake-utils", "nix-github-actions": "nix-github-actions", "nixpkgs": [ + "devenv", + "cachix", "devenv", "cachix", "devenv", @@ -885,22 +718,30 @@ "inputs": { "flake-compat": [ "devenv", - "flake-compat" + "nix" ], "flake-utils": "flake-utils_2", - "gitignore": "gitignore", + "gitignore": [ + "devenv", + "nix" + ], "nixpkgs": [ "devenv", + "nix", "nixpkgs" ], - "nixpkgs-stable": "nixpkgs-stable" + "nixpkgs-stable": [ + "devenv", + "nix", + "nixpkgs" + ] }, "locked": { - "lastModified": 1713775815, - "narHash": "sha256-Wu9cdYTnGQQwtT20QQMg7jzkANKQjwBD9iccfGKkfls=", + "lastModified": 1712897695, + "narHash": "sha256-nMirxrGteNAl9sWiOhoN5tIHyjBbVi5e2tgZUgZlK3Y=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "2ac4dcbf55ed43f3be0bae15e181f08a57af24a4", + "rev": "40e6053ecb65fcbf12863338a6dcefb3f55f1bf8", "type": "github" }, "original": { @@ -911,40 +752,23 @@ }, "pre-commit-hooks_2": { "inputs": { - "flake-compat": "flake-compat_3", - "flake-utils": "flake-utils_3", - "gitignore": "gitignore_2", - "nixpkgs": "nixpkgs_3", - "nixpkgs-stable": "nixpkgs-stable_2" + "flake-compat": [ + "devenv", + "flake-compat" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1705229514, - "narHash": "sha256-itILy0zimR/iyUGq5Dgg0fiW8plRDyxF153LWGsg3Cw=", + "lastModified": 1725513492, + "narHash": "sha256-tyMUA6NgJSvvQuzB7A1Sf8+0XCHyfSPRx/b00o6K0uo=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "ffa9a5b90b0acfaa03b1533b83eaf5dead819a05", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, - "pre-commit-hooks_3": { - "inputs": { - "flake-compat": "flake-compat_5", - "flake-utils": "flake-utils_5", - "gitignore": "gitignore_3", - "nixpkgs": "nixpkgs_5", - "nixpkgs-stable": "nixpkgs-stable_4" - }, - "locked": { - "lastModified": 1705229514, - "narHash": "sha256-itILy0zimR/iyUGq5Dgg0fiW8plRDyxF153LWGsg3Cw=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "ffa9a5b90b0acfaa03b1533b83eaf5dead819a05", + "rev": "7570de7b9b504cfe92025dd1be797bf546f66528", "type": "github" }, "original": { @@ -956,12 +780,13 @@ "root": { "inputs": { "devenv": "devenv", - "flake-parts": "flake-parts", + "flake-parts": "flake-parts_2", "nix-devtools": "nix-devtools", "nix-gitlab-ci": "nix-gitlab-ci", - "nixpkgs": "nixpkgs_6", - "systems": "systems_5", - "terranix": "terranix" + "nixpkgs": "nixpkgs_4", + "systems": "systems_2", + "terranix": "terranix", + "treefmt-nix": "treefmt-nix" } }, "systems": { @@ -994,57 +819,12 @@ "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" - } - }, - "systems_4": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_5": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, "terranix": { "inputs": { "bats-assert": "bats-assert", "bats-support": "bats-support", - "flake-utils": "flake-utils_6", - "nixpkgs": "nixpkgs_7", + "flake-utils": "flake-utils_3", + "nixpkgs": "nixpkgs_5", "terranix-examples": "terranix-examples" }, "locked": { @@ -1075,6 +855,24 @@ "repo": "terranix-examples", "type": "github" } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": "nixpkgs_6" + }, + "locked": { + "lastModified": 1725271838, + "narHash": "sha256-VcqxWT0O/gMaeWTTjf1r4MOyG49NaNxW4GHTO3xuThE=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "9fb342d14b69aefdf46187f6bb80a4a0d97007cd", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 2673360..9a0e2f7 100644 --- a/flake.nix +++ b/flake.nix @@ -2,7 +2,6 @@ description = "Coder Templates"; outputs = { - self, nixpkgs, flake-parts, systems, @@ -12,38 +11,42 @@ imports = [ inputs.devenv.flakeModule inputs.nix-gitlab-ci.flakeModule + inputs.nix-devtools.flakeModule + inputs.treefmt-nix.flakeModule ]; systems = import systems; flake = { }; perSystem = { - config, - self', - inputs', pkgs, + config, system, - lib, ... }: { _module.args.pkgs = import nixpkgs { inherit system; config.allowUnfree = true; }; - - formatter = pkgs.alejandra; - devenv.shells.default = { - imports = [ - inputs.nix-devtools.devenvModule - ]; - packages = [ - pkgs.opentofu - pkgs.coder - pkgs.buildah - ]; - - pre-commit.hooks = { + treefmt = { + projectRootFile = "flake.nix"; + programs = { alejandra.enable = true; + mdformat.enable = true; }; + }; + + devenv.shells.default = { + packages = with pkgs; [ + opentofu + coder + buildah + ]; + + pre-commit.hooks.treefmt = { + enable = true; + packageOverrides.treefmt = config.treefmt.build.wrapper; + }; + task = { enable = true; alias = ","; @@ -95,7 +98,7 @@ parallel.matrix = [ {TEMPLATE = ["nix-kubernetes"];} ]; - deps = [pkgs.gnutar]; + nix.deps = [pkgs.gnutar]; script = [ "nix build .#\${TEMPLATE}" "install -D result templates/\${TEMPLATE}.tf.json" @@ -118,7 +121,7 @@ }; "upload" = { stage = "upload"; - deps = [pkgs.buildah]; + nix.deps = [pkgs.buildah]; needs = ["build:image"]; before_script = [ ''export REGISTRY_AUTH_FILE=''${HOME}/auth.json'' @@ -157,18 +160,9 @@ flake-parts.url = "github:hercules-ci/flake-parts"; systems.url = "github:nix-systems/default"; devenv.url = "github:cachix/devenv"; - nix-gitlab-ci = { - url = "gitlab:TECHNOFAB/nix-gitlab-ci"; - inputs.nixpkgs.follows = "nixpkgs"; - inputs.devenv.follows = "devenv"; - inputs.systems.follows = "systems"; - }; - nix-devtools = { - url = "gitlab:TECHNOFAB/nix-devtools"; - inputs.nixpkgs.follows = "nixpkgs"; - inputs.devenv.follows = "devenv"; - inputs.systems.follows = "systems"; - }; + nix-gitlab-ci.url = "gitlab:TECHNOFAB/nix-gitlab-ci?dir=lib"; + nix-devtools.url = "gitlab:TECHNOFAB/nix-devtools?dir=lib"; + treefmt-nix.url = "github:numtide/treefmt-nix"; terranix.url = "github:terranix/terranix"; }; From 0d2ac5cb2c61674647d34bd388f1c00f714bca92 Mon Sep 17 00:00:00 2001 From: technofab Date: Thu, 3 Oct 2024 19:09:58 +0000 Subject: [PATCH 37/49] feat: rewrite image to work like in nixos/nix/docker.nix allows nix store gc without breaking the image itself --- image.nix | 166 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 126 insertions(+), 40 deletions(-) diff --git a/image.nix b/image.nix index 884cf0b..4c7de69 100644 --- a/image.nix +++ b/image.nix @@ -2,56 +2,142 @@ lib, pkgs, ... -}: -pkgs.dockerTools.buildLayeredImage { - name = "nix-coder"; - tag = "latest"; - - contents = pkgs.buildEnv { - name = "image-root"; - paths = with pkgs; [ - bash - bashInteractive +}: let + baseSystem = let + packages = with pkgs; [ nix + bashInteractive coreutils-full + procps gnugrep openssh gitMinimal curl ncurses - dockerTools.usrBinEnv + + cacert.out + (writeShellScriptBin "reload-dotfiles" '' ${home-manager}/bin/home-manager switch --flake ''${DOTFILES_REPO:-$1} --option tarball-ttl 0 '') - (writeTextDir "etc/nix/nix.conf" '' - experimental-features = nix-command flakes - '') - (writeTextDir "etc/os-release" '' - ID=nixos - '') - (writeTextDir "etc/passwd" "coder:x:1000:1000::/home/coder:/bin/bash") - (writeTextDir "etc/shadow" "coder:!:::::::") - (writeTextDir "etc/group" "coder:x:1000:") - (writeTextDir "etc/gshadow" "coder:x::") ]; - pathsToLink = ["/bin" "/etc" "/usr"]; - }; - maxLayers = 5; + rootEnv = pkgs.buildPackages.buildEnv { + name = "root-profile-env"; + paths = packages; + }; - uid = 1000; - gid = 1000; - fakeRootCommands = '' - mkdir -p ./home/coder ./tmp ./nix/var/nix - chown -R 1000:1000 ./ - ''; + nixConf = { + sandbox = "false"; + experimental-features = "nix-command flakes"; + min-free = toString (100 * 1024 * 1024); + max-free = toString (1024 * 1024 * 1024); + }; - config = { - Cmd = ["/bin/bash"]; - User = "1000:1000"; - Env = [ - "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" - "HOME=/home/coder" - "USER=coder" - ]; - }; -} + nixConfContents = + (lib.concatStringsSep "\n" (lib.mapAttrsFlatten (n: v: let + vStr = + if builtins.isList v + then lib.concatStringsSep " " v + else v; + in "${n} = ${vStr}") + nixConf)) + + "\n"; + + manifest = pkgs.buildPackages.runCommand "manifest.nix" {} '' + cat > $out < $out/etc/nix/nix.conf + echo "ID=nixos" > $out/etc/os-release + + echo "coder:x:1000:1000::/home/coder:/bin/bash" > $out/etc/passwd + echo "coder:!:::::::" > $out/etc/shadow + echo "coder:x:1000:" > $out/etc/group + echo "coder:x::" > $out/etc/gshadow + echo "coder:100000:65536" > $out/etc/subuid + echo "coder:100000:65536" > $out/etc/subgid + + ln -s ${profile} $out/nix/var/nix/profiles/default-1-link + ln -s $out/nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default + ln -s /nix/var/nix/profiles/default $out/home/coder/.nix-profile + + ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env + ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh + ''; +in + pkgs.dockerTools.buildLayeredImageWithNixDb { + name = "nix-coder"; + tag = "latest"; + + contents = [baseSystem]; + maxLayers = 10; + + uid = 1000; + gid = 1000; + extraCommands = '' + ln -s /nix/var/nix/profiles nix/var/nix/gcroots/profiles + ''; + fakeRootCommands = '' + chown -R 1000:1000 ./ + chmod 1777 tmp + chmod 1777 var/tmp + ''; + + config = { + Cmd = ["/home/coder/.nix-profile/bin/bash"]; + User = "1000:1000"; + Env = [ + "USER=coder" + "HOME=/home/coder" + "TMPDIR=/tmp" + "XDG_RUNTIME_DIR=/tmp" + "PATH=${lib.concatStringsSep ":" [ + "/home/coder/.nix-profile/bin" + "/nix/var/nix/profiles/default/bin" + "/nix/var/nix/profiles/default/sbin" + ]}" + "SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" + "GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" + "NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" + "NIX_PATH=/nix/var/nix/profiles/per-user/coder/channels:/home/coder/.nix-defexpr/channels" + ]; + }; + } From 797fd521f261c805c9b7e4c7d0b79de697412b88 Mon Sep 17 00:00:00 2001 From: technofab Date: Fri, 4 Oct 2024 14:06:55 +0200 Subject: [PATCH 38/49] fix(image): symlink bash additionally to /bin/bash --- image.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/image.nix b/image.nix index 4c7de69..839bb2b 100644 --- a/image.nix +++ b/image.nix @@ -101,6 +101,7 @@ ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh + ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/bash ''; in pkgs.dockerTools.buildLayeredImageWithNixDb { From 59b9800e534be00a441d487a7faf07dde6807c76 Mon Sep 17 00:00:00 2001 From: technofab Date: Fri, 4 Oct 2024 17:59:16 +0200 Subject: [PATCH 39/49] chore(CI): remove after_script and copy image in normal script stage --- flake.nix | 2 -- 1 file changed, 2 deletions(-) diff --git a/flake.nix b/flake.nix index 9a0e2f7..905a1ab 100644 --- a/flake.nix +++ b/flake.nix @@ -113,8 +113,6 @@ ]; script = [ "nix build .#nix-coder-image --system $SYSTEM" - ]; - after_script = [ "install -D result dist/nix-coder-image_\${SYSTEM}.tar.gz" ]; artifacts.paths = ["dist/"]; From e8f02cfd7448fa9289f4281726ed2485f91cd446 Mon Sep 17 00:00:00 2001 From: technofab Date: Fri, 4 Oct 2024 21:01:11 +0200 Subject: [PATCH 40/49] fix(image): fix default profile link + stop linking it to user profile --- image.nix | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/image.nix b/image.nix index 839bb2b..1950ce4 100644 --- a/image.nix +++ b/image.nix @@ -96,8 +96,10 @@ echo "coder:100000:65536" > $out/etc/subgid ln -s ${profile} $out/nix/var/nix/profiles/default-1-link - ln -s $out/nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default - ln -s /nix/var/nix/profiles/default $out/home/coder/.nix-profile + ln -s /nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default + + # prevents the profiles from being cleaned up by the GC + ln -s /nix/var/nix/profiles $out/nix/var/nix/gcroots/profiles ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh @@ -113,9 +115,6 @@ in uid = 1000; gid = 1000; - extraCommands = '' - ln -s /nix/var/nix/profiles nix/var/nix/gcroots/profiles - ''; fakeRootCommands = '' chown -R 1000:1000 ./ chmod 1777 tmp @@ -123,7 +122,7 @@ in ''; config = { - Cmd = ["/home/coder/.nix-profile/bin/bash"]; + Cmd = ["/bin/bash"]; User = "1000:1000"; Env = [ "USER=coder" @@ -132,6 +131,8 @@ in "XDG_RUNTIME_DIR=/tmp" "PATH=${lib.concatStringsSep ":" [ "/home/coder/.nix-profile/bin" + # this makes all the packages defined at the top available + # in the workspace "/nix/var/nix/profiles/default/bin" "/nix/var/nix/profiles/default/sbin" ]}" From 278f52ea86f41b04ef079a371c9909560b103f75 Mon Sep 17 00:00:00 2001 From: technofab Date: Mon, 7 Oct 2024 13:26:03 +0200 Subject: [PATCH 41/49] docs(README): add some infos and a note regarding !1 --- README.md | 14 ++++++++++++++ flake.lock | 6 +++--- flake.nix | 7 ++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 950a83c..3411a76 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,16 @@ # Coder Templates +Templates for [Coder](https://coder.com), built with Nix (Terranix). + +> [!NOTE] +> !1 changed how the docker image is built. +> If `nix store gc` results in `/nix/var/nix/profiles/default` being deleted +> you might have to clear the /nix persistent volume to fix it. See the +> merge request's comments for more information. + +## Templates + +- Nix Kubernetes + > provisions a Coder workspace on Kubernetes, running a Nix-built image, + > which also contains Nix and supports Dotfiles management using home-manager. + > Nix-ception ;P diff --git a/flake.lock b/flake.lock index 2117857..c89bb04 100644 --- a/flake.lock +++ b/flake.lock @@ -642,11 +642,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1713805509, - "narHash": "sha256-YgSEan4CcrjivCNO5ZNzhg7/8ViLkZ4CB/GrGBVSudo=", + "lastModified": 1728249353, + "narHash": "sha256-7NBJm1jfMeAowE1J2oljYqWVvI9X7FyyxBY4O8uB/Os=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1e1dc66fe68972a76679644a5577828b6a7e8be4", + "rev": "c8a17040be4a20b29589cb4043a9e0c36af1930e", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 905a1ab..368551f 100644 --- a/flake.nix +++ b/flake.nix @@ -31,7 +31,12 @@ projectRootFile = "flake.nix"; programs = { alejandra.enable = true; - mdformat.enable = true; + mdformat = { + enable = true; + package = pkgs.mdformat.withPlugins (p: [ + p.mdformat-gfm-alerts + ]); + }; }; }; From 67d14dbbe9415bed4acc0bda7a44d763863e42f9 Mon Sep 17 00:00:00 2001 From: TECHNOFAB Date: Sun, 27 Oct 2024 18:05:57 +0100 Subject: [PATCH 42/49] feat: add support for changing the timezone in the container --- image.nix | 7 ++++++- nix-kubernetes/kubernetes.nix | 4 ++++ nix-kubernetes/parameters.nix | 10 ++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/image.nix b/image.nix index 1950ce4..604766a 100644 --- a/image.nix +++ b/image.nix @@ -14,6 +14,7 @@ gitMinimal curl ncurses + less cacert.out @@ -34,7 +35,7 @@ }; nixConfContents = - (lib.concatStringsSep "\n" (lib.mapAttrsFlatten (n: v: let + (lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: let vStr = if builtins.isList v then lib.concatStringsSep " " v @@ -95,6 +96,9 @@ echo "coder:100000:65536" > $out/etc/subuid echo "coder:100000:65536" > $out/etc/subgid + # support timezones + ln -s ${pkgs.tzdata}/share/zoneinfo $out/etc/zoneinfo + ln -s ${profile} $out/nix/var/nix/profiles/default-1-link ln -s /nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default @@ -129,6 +133,7 @@ in "HOME=/home/coder" "TMPDIR=/tmp" "XDG_RUNTIME_DIR=/tmp" + "TZDIR=/etc/zoneinfo" "PATH=${lib.concatStringsSep ":" [ "/home/coder/.nix-profile/bin" # this makes all the packages defined at the top available diff --git a/nix-kubernetes/kubernetes.nix b/nix-kubernetes/kubernetes.nix index 27b9280..6ebb6dd 100644 --- a/nix-kubernetes/kubernetes.nix +++ b/nix-kubernetes/kubernetes.nix @@ -81,6 +81,10 @@ name = "DOTFILES_REPO"; value = "\${data.coder_parameter.dotfiles_repo.value}"; } + { + name = "TZ"; + value = "\${data.coder_parameter.timezone.value}"; + } ]; resources = { requests = { diff --git a/nix-kubernetes/parameters.nix b/nix-kubernetes/parameters.nix index 630bfbb..63b659f 100644 --- a/nix-kubernetes/parameters.nix +++ b/nix-kubernetes/parameters.nix @@ -87,5 +87,15 @@ } ]; }; + timezone = { + name = "Timezone"; + description = '' + Content of the TZ environment variable. + ''; + default = ""; + order = 8; + type = "string"; + mutable = true; + }; }; } From c4b30329cb16d4c3c69381cc112be48a8cff300c Mon Sep 17 00:00:00 2001 From: technofab Date: Thu, 5 Jun 2025 19:37:17 +0200 Subject: [PATCH 43/49] ci: update nix-gitlab-ci --- .gitlab-ci.yml | 6 +++--- flake.lock | 7 ++++--- flake.nix | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f0acb3c..fce2c08 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ include: - - project: TECHNOFAB/nix-gitlab-ci - ref: main - file: gitlab-ci.yml + - component: gitlab.com/TECHNOFAB/nix-gitlab-ci/nix-gitlab-ci@2.1.0 + inputs: + version: 2.1.0 diff --git a/flake.lock b/flake.lock index c89bb04..0d00cdf 100644 --- a/flake.lock +++ b/flake.lock @@ -421,16 +421,17 @@ "nix-gitlab-ci": { "locked": { "dir": "lib", - "lastModified": 1726479668, - "narHash": "sha256-fp6lWU+xF7XpjrdtEKWgwAc4wIl0WVMrt69Rlx5K1fc=", + "lastModified": 1749124633, + "narHash": "sha256-vgYHrbAFRfgNYysW74Eam/S7KruYWMLCHG4U32xgHKY=", "owner": "TECHNOFAB", "repo": "nix-gitlab-ci", - "rev": "6448bf59164a2e66aa8bfe5ed8e128ce9f4a4a8e", + "rev": "f121b10dc9a7417906a886154e3065410a72462d", "type": "gitlab" }, "original": { "dir": "lib", "owner": "TECHNOFAB", + "ref": "2.1.0", "repo": "nix-gitlab-ci", "type": "gitlab" } diff --git a/flake.nix b/flake.nix index 368551f..bb050d3 100644 --- a/flake.nix +++ b/flake.nix @@ -163,7 +163,7 @@ flake-parts.url = "github:hercules-ci/flake-parts"; systems.url = "github:nix-systems/default"; devenv.url = "github:cachix/devenv"; - nix-gitlab-ci.url = "gitlab:TECHNOFAB/nix-gitlab-ci?dir=lib"; + nix-gitlab-ci.url = "gitlab:TECHNOFAB/nix-gitlab-ci/2.1.0?dir=lib"; nix-devtools.url = "gitlab:TECHNOFAB/nix-devtools?dir=lib"; treefmt-nix.url = "github:numtide/treefmt-nix"; From 9bbb4b929831f3f0f231ac1c82cef43ad970dfb9 Mon Sep 17 00:00:00 2001 From: technofab Date: Thu, 5 Jun 2025 19:42:47 +0200 Subject: [PATCH 44/49] feat(nix-kubernetes): add startup and shutdown tasks with home-manager --- nix-kubernetes/coder.nix | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/nix-kubernetes/coder.nix b/nix-kubernetes/coder.nix index 9b637c1..b370ee2 100644 --- a/nix-kubernetes/coder.nix +++ b/nix-kubernetes/coder.nix @@ -77,6 +77,12 @@ if [ ! -z "$DOTFILES_REPO" ]; then echo "Dotfiles present, reloading home-manager profile" reload-dotfiles + # the homeConfiguration can specify a program "coder_startup", run it + # here if it exists + if command -v coder_startup &> /dev/null; then + echo "Running startup tasks..." + coder_startup + fi else echo "No dotfiles repo specified, skipping..." fi @@ -84,5 +90,17 @@ run_on_start = true; start_blocks_login = true; }; + coder_script."home-manager-shutdown" = { + agent_id = "\${coder_agent.coder.id}"; + display_name = "Home Manager Shutdown"; + icon = "/emojis/1f3e0.png"; + script = '' + if command -v coder_shutdown &> /dev/null; then + echo "Running shutdown tasks..." + coder_shutdown + fi + ''; + run_on_stop = true; + }; }; } From e3ffee0188bd9d4aa64d7190ce3d518a22f391e6 Mon Sep 17 00:00:00 2001 From: technofab Date: Thu, 5 Jun 2025 19:44:31 +0200 Subject: [PATCH 45/49] chore(flake): add convco --- flake.nix | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index bb050d3..6bd9be0 100644 --- a/flake.nix +++ b/flake.nix @@ -47,9 +47,12 @@ buildah ]; - pre-commit.hooks.treefmt = { - enable = true; - packageOverrides.treefmt = config.treefmt.build.wrapper; + pre-commit.hooks = { + treefmt = { + enable = true; + packageOverrides.treefmt = config.treefmt.build.wrapper; + }; + convco.enable = true; }; task = { From 54804d21c4a2a2d3478e625855f44b9946147111 Mon Sep 17 00:00:00 2001 From: technofab Date: Fri, 1 Aug 2025 12:31:45 +0200 Subject: [PATCH 46/49] chore(nix-kubernetes): increase deletion/shutdown timeout this way the shutdown tasks, like "coder_shutdown" can take their time and not get killed instantly --- nix-kubernetes/kubernetes.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nix-kubernetes/kubernetes.nix b/nix-kubernetes/kubernetes.nix index 6ebb6dd..43aa124 100644 --- a/nix-kubernetes/kubernetes.nix +++ b/nix-kubernetes/kubernetes.nix @@ -17,7 +17,10 @@ "com.coder.workspace.name" = "\${data.coder_workspace.me.name}"; }; }; + # give the shutdown tasks enough time to run + timeouts.delete = "31m"; spec = { + termination_grace_period_seconds = 1800; affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution = { weight = 1; pod_affinity_term = { From cfcc9a221c4f37d865ddffeaf5aa9c4a7d22bfca Mon Sep 17 00:00:00 2001 From: technofab Date: Sat, 2 Aug 2025 17:56:46 +0200 Subject: [PATCH 47/49] feat: update coder provider and add NIX_CONFIG parameter --- nix-kubernetes/coder.nix | 1 + nix-kubernetes/default.nix | 2 +- nix-kubernetes/kubernetes.nix | 34 +++++++++++++++++++--------------- nix-kubernetes/parameters.nix | 11 +++++++++++ 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/nix-kubernetes/coder.nix b/nix-kubernetes/coder.nix index b370ee2..5a55d01 100644 --- a/nix-kubernetes/coder.nix +++ b/nix-kubernetes/coder.nix @@ -9,6 +9,7 @@ optional = false; }; coder_workspace."me" = {}; + coder_workspace_owner."me" = {}; }; resource = { diff --git a/nix-kubernetes/default.nix b/nix-kubernetes/default.nix index ac0ae83..346c446 100644 --- a/nix-kubernetes/default.nix +++ b/nix-kubernetes/default.nix @@ -9,7 +9,7 @@ terraform.required_providers = { coder = { source = "coder/coder"; - version = "0.21.0"; + version = "2.8.0"; }; kubernetes = { source = "hashicorp/kubernetes"; diff --git a/nix-kubernetes/kubernetes.nix b/nix-kubernetes/kubernetes.nix index 43aa124..b32b0e0 100644 --- a/nix-kubernetes/kubernetes.nix +++ b/nix-kubernetes/kubernetes.nix @@ -3,16 +3,16 @@ kubernetes_pod."workspace" = { count = "\${data.coder_workspace.me.start_count}"; metadata = { - name = "coder-\${lower(data.coder_workspace.me.owner)}-\${lower(data.coder_workspace.me.name)}"; + name = "coder-\${lower(data.coder_workspace_owner.me.name)}-\${lower(data.coder_workspace.me.name)}"; namespace = "\${var.namespace}"; - annotations."com.coder.user.email" = "\${data.coder_workspace.me.owner_email}"; + annotations."com.coder.user.email" = "\${data.coder_workspace_owner.me.email}"; labels = { - "app.kubernetes.io/instance" = "coder-workspace-\${lower(data.coder_workspace.me.owner)}-\${lower(data.coder_workspace.me.name)}"; + "app.kubernetes.io/instance" = "coder-workspace-\${lower(data.coder_workspace_owner.me.name)}-\${lower(data.coder_workspace.me.name)}"; "app.kubernetes.io/name" = "coder-workspace"; "app.kubernetes.io/part-of" = "coder"; "com.coder.resource" = "true"; - "com.coder.user.id" = "\${data.coder_workspace.me.owner_id}"; - "com.coder.user.name" = "\${data.coder_workspace.me.owner}"; + "com.coder.user.id" = "\${data.coder_workspace_owner.me.id}"; + "com.coder.user.name" = "\${data.coder_workspace_owner.me.name}"; "com.coder.workspace.id" = "\${data.coder_workspace.me.id}"; "com.coder.workspace.name" = "\${data.coder_workspace.me.name}"; }; @@ -88,6 +88,10 @@ name = "TZ"; value = "\${data.coder_parameter.timezone.value}"; } + { + name = "NIX_CONFIG"; + value = "\${data.coder_parameter.nix_config.value}"; + } ]; resources = { requests = { @@ -148,16 +152,16 @@ }; kubernetes_persistent_volume_claim."home" = { metadata = { - name = "coder-home-\${lower(data.coder_workspace.me.owner)}-\${lower(data.coder_workspace.me.name)}"; + name = "coder-home-\${lower(data.coder_workspace_owner.me.name)}-\${lower(data.coder_workspace.me.name)}"; namespace = "\${var.namespace}"; - annotations."com.coder.user.email" = "\${data.coder_workspace.me.owner_email}"; + annotations."com.coder.user.email" = "\${data.coder_workspace_owner.me.email}"; labels = { - "app.kubernetes.io/instance" = "coder-pvc-home-\${lower(data.coder_workspace.me.owner)}-\${lower(data.coder_workspace.me.name)}"; + "app.kubernetes.io/instance" = "coder-pvc-home-\${lower(data.coder_workspace_owner.me.name)}-\${lower(data.coder_workspace.me.name)}"; "app.kubernetes.io/name" = "coder-pvc"; "app.kubernetes.io/part-of" = "coder"; "com.coder.resource" = "true"; - "com.coder.user.id" = "\${data.coder_workspace.me.owner_id}"; - "com.coder.user.name" = "\${data.coder_workspace.me.owner}"; + "com.coder.user.id" = "\${data.coder_workspace_owner.me.id}"; + "com.coder.user.name" = "\${data.coder_workspace_owner.me.name}"; "com.coder.workspace.id" = "\${data.coder_workspace.me.id}"; "com.coder.workspace.name" = "\${data.coder_workspace.me.name}"; }; @@ -170,16 +174,16 @@ }; kubernetes_persistent_volume_claim."nix-store" = { metadata = { - name = "coder-nix-store-\${lower(data.coder_workspace.me.owner)}-\${lower(data.coder_workspace.me.name)}"; + name = "coder-nix-store-\${lower(data.coder_workspace_owner.me.name)}-\${lower(data.coder_workspace.me.name)}"; namespace = "\${var.namespace}"; - annotations."com.coder.user.email" = "\${data.coder_workspace.me.owner_email}"; + annotations."com.coder.user.email" = "\${data.coder_workspace_owner.me.email}"; labels = { - "app.kubernetes.io/instance" = "coder-pvc-nix-store-\${lower(data.coder_workspace.me.owner)}-\${lower(data.coder_workspace.me.name)}"; + "app.kubernetes.io/instance" = "coder-pvc-nix-store-\${lower(data.coder_workspace_owner.me.name)}-\${lower(data.coder_workspace.me.name)}"; "app.kubernetes.io/name" = "coder-pvc"; "app.kubernetes.io/part-of" = "coder"; "com.coder.resource" = "true"; - "com.coder.user.id" = "\${data.coder_workspace.me.owner_id}"; - "com.coder.user.name" = "\${data.coder_workspace.me.owner}"; + "com.coder.user.id" = "\${data.coder_workspace_owner.me.id}"; + "com.coder.user.name" = "\${data.coder_workspace_owner.me.name}"; "com.coder.workspace.id" = "\${data.coder_workspace.me.id}"; "com.coder.workspace.name" = "\${data.coder_workspace.me.name}"; }; diff --git a/nix-kubernetes/parameters.nix b/nix-kubernetes/parameters.nix index 63b659f..0fb0a2f 100644 --- a/nix-kubernetes/parameters.nix +++ b/nix-kubernetes/parameters.nix @@ -97,5 +97,16 @@ type = "string"; mutable = true; }; + nix_config = { + name = "Nix Config"; + description = '' + Nix config, will be put into $NIX_CONFIG + ''; + default = ""; + order = 9; + type = "string"; + form_type = "textarea"; + mutable = true; + }; }; } From 8cf73a70ef1d5dd8913245eba0717b7dbd9d43b8 Mon Sep 17 00:00:00 2001 From: technofab Date: Thu, 13 Nov 2025 21:47:52 +0100 Subject: [PATCH 48/49] chore: initial commit --- .envrc | 2 + .gitignore | 1 + .gitlab-ci.yml | 5 + README.md | 9 ++ flake.lock | 63 ++++++++++ flake.nix | 35 ++++++ nix-kubernetes/coder.nix | 121 +++++++++++++++++++ nix-kubernetes/default.nix | 8 ++ nix-kubernetes/kubernetes.nix | 216 ++++++++++++++++++++++++++++++++++ nix-kubernetes/parameters.nix | 112 ++++++++++++++++++ nix-kubernetes/variables.nix | 26 ++++ nix/packages/flake.lock | 28 +++++ nix/packages/flake.nix | 10 ++ nix/packages/image.nix | 150 +++++++++++++++++++++++ nix/packages/packages.nix | 23 ++++ nix/repo/ci.nix | 71 +++++++++++ nix/repo/devShells.nix | 23 ++++ nix/repo/flake.lock | 82 +++++++++++++ nix/repo/flake.nix | 19 +++ 19 files changed, 1004 insertions(+) create mode 100644 .envrc create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 README.md create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 nix-kubernetes/coder.nix create mode 100644 nix-kubernetes/default.nix create mode 100644 nix-kubernetes/kubernetes.nix create mode 100644 nix-kubernetes/parameters.nix create mode 100644 nix-kubernetes/variables.nix create mode 100644 nix/packages/flake.lock create mode 100644 nix/packages/flake.nix create mode 100644 nix/packages/image.nix create mode 100644 nix/packages/packages.nix create mode 100644 nix/repo/ci.nix create mode 100644 nix/repo/devShells.nix create mode 100644 nix/repo/flake.lock create mode 100644 nix/repo/flake.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..565a52a --- /dev/null +++ b/.envrc @@ -0,0 +1,2 @@ +source $(fetchurl https://gitlab.com/rensa-nix/direnv/-/raw/v0.3.0/direnvrc "sha256-u7+KEz684NnIZ+Vh5x5qLrt8rKdnUNexewBoeTcEVHQ=") +use ren //repo/devShells/default diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b2be92b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +result diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..e1db81f --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,5 @@ +# Generated by soonix, DO NOT EDIT +include: +- component: gitlab.com/TECHNOFAB/nix-gitlab-ci/nix-gitlab-ci@3.0.1 + inputs: + version: 3.0.1 diff --git a/README.md b/README.md new file mode 100644 index 0000000..c0a0bd2 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# Coder Templates + +Templates for [Coder](https://coder.com), built with [Tofunix](https://tofunix.projects.tf). + +## Templates + +- Nix Kubernetes + > provisions a Coder workspace on Kubernetes, running a Nix-built image, + > which also contains Nix and supports Dotfiles management using home-manager. diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..3fb2aac --- /dev/null +++ b/flake.lock @@ -0,0 +1,63 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1762596750, + "narHash": "sha256-rXXuz51Bq7DHBlfIjN7jO8Bu3du5TV+3DSADBX7/9YQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b6a8526db03f735b89dd5ff348f53f752e7ddc8e", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1754184128, + "narHash": "sha256-AjhoyBL4eSyXf01Bmc6DiuaMrJRNdWopmdnMY0Pa/M0=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "02e72200e6d56494f4a7c0da8118760736e41b60", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "ren": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "dir": "lib", + "lastModified": 1758738378, + "narHash": "sha256-NjzqdvQCDDdObEBH8x/vdhbdhrIB+N9E570uCdksGHY=", + "owner": "rensa-nix", + "repo": "core", + "rev": "abe19f9f13aff41de2b63304545c87d193d19ef4", + "type": "gitlab" + }, + "original": { + "dir": "lib", + "owner": "rensa-nix", + "repo": "core", + "type": "gitlab" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "ren": "ren" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..c28db2e --- /dev/null +++ b/flake.nix @@ -0,0 +1,35 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + ren.url = "gitlab:rensa-nix/core?dir=lib"; + }; + + outputs = { + ren, + self, + ... + } @ inputs: + ren.buildWith + { + inherit inputs; + cellsFrom = ./nix; + transformInputs = system: i: + i + // { + pkgs = import i.nixpkgs { + inherit system; + }; + }; + cellBlocks = with ren.blocks; [ + (simple "devShells") + (simple "ci") + (simple "packages") + ]; + } + { + packages = ren.select self [ + ["repo" "ci" "packages"] + ["packages" "packages"] + ]; + }; +} diff --git a/nix-kubernetes/coder.nix b/nix-kubernetes/coder.nix new file mode 100644 index 0000000..f324f75 --- /dev/null +++ b/nix-kubernetes/coder.nix @@ -0,0 +1,121 @@ +{ + ref, + utils, + ... +}: { + locals."git_repo_folder" = with utils; let + split_repo = split (quot "") ref.data.coder_parameter.git_repo.value; + in + try [ + (element split_repo "${rb (length split_repo)} - 1") + (quot "") + ]; + + data = { + coder_external_auth."gitlab" = { + id = "gitlab"; + optional = false; + }; + coder_workspace."me" = {}; + coder_workspace_owner."me" = {}; + }; + + resource = { + coder_agent."coder" = { + arch = ref.var.arch; + os = "linux"; + metadata = [ + { + display_name = "Container CPU Usage"; + key = "0_cpu_usage"; + script = "coder stat cpu --host=false"; + interval = 10; + timeout = 1; + } + { + display_name = "Container RAM Usage"; + key = "1_ram_usage"; + script = "coder stat mem --host=false"; + interval = 10; + timeout = 1; + } + { + display_name = "Home Disk"; + key = "2_home_disk"; + script = "coder stat disk --path $HOME"; + interval = 60; + timeout = 1; + } + { + display_name = "Nix Store Disk"; + key = "3_nix_store_disk"; + script = "coder stat disk --path /nix"; + interval = 60; + timeout = 1; + } + ]; + }; + coder_script."git_clone" = { + agent_id = ref.coder_agent.coder.id; + display_name = "Git Clone"; + icon = "/icon/git.svg"; + script = let + repo = ref.data.coder_parameter.git_repo.value; + repo_folder = ref.local.git_repo_folder; + in + # sh + '' + mkdir -p ~/repos + if [ ! -z "${repo}" ]; then + echo "Cloning repo \"${repo}\" if it does not exist" + pushd ~/repos >/dev/null + if [[ ! -d "${repo_folder}" ]] then + git clone ${repo} ${repo_folder} + fi + popd >/dev/null + else + echo "No git repo specified, skipping..." + fi + ''; + run_on_start = true; + start_blocks_login = true; + }; + coder_script."home-manager" = { + agent_id = ref.coder_agent.coder.id; + display_name = "Home Manager"; + icon = "/emojis/1f3e0.png"; + script = + # sh + '' + if [ ! -z "$DOTFILES_REPO" ]; then + echo "Dotfiles present, reloading home-manager profile" + reload-dotfiles + # the homeConfiguration can specify a program "coder_startup", run it + # here if it exists + if command -v coder_startup &> /dev/null; then + echo "Running startup tasks..." + coder_startup + fi + else + echo "No dotfiles repo specified, skipping..." + fi + ''; + run_on_start = true; + start_blocks_login = true; + }; + coder_script."home-manager-shutdown" = { + agent_id = ref.coder_agent.coder.id; + display_name = "Home Manager Shutdown"; + icon = "/emojis/1f3e0.png"; + script = + # sh + '' + if command -v coder_shutdown &> /dev/null; then + echo "Running shutdown tasks..." + coder_shutdown + fi + ''; + run_on_stop = true; + }; + }; +} diff --git a/nix-kubernetes/default.nix b/nix-kubernetes/default.nix new file mode 100644 index 0000000..fea682e --- /dev/null +++ b/nix-kubernetes/default.nix @@ -0,0 +1,8 @@ +{ + imports = [ + ./parameters.nix + ./variables.nix + ./coder.nix + ./kubernetes.nix + ]; +} diff --git a/nix-kubernetes/kubernetes.nix b/nix-kubernetes/kubernetes.nix new file mode 100644 index 0000000..ee91958 --- /dev/null +++ b/nix-kubernetes/kubernetes.nix @@ -0,0 +1,216 @@ +{ + ref, + utils, + ... +}: let + identifier = with utils; "${lower ref.data.coder_workspace_owner.me.name}-${lower ref.data.coder_workspace.me.name}"; +in { + resource = { + kubernetes_pod."workspace" = { + count = ref.data.coder_workspace.me.start_count; + metadata = [ + { + name = "coder-${identifier}"; + namespace = ref.var.namespace; + annotations."com.coder.user.email" = ref.data.coder_workspace_owner.me.email; + labels = { + "app.kubernetes.io/instance" = "coder-workspace-${identifier}"; + "app.kubernetes.io/name" = "coder-workspace"; + "app.kubernetes.io/part-of" = "coder"; + "com.coder.resource" = "true"; + "com.coder.user.id" = ref.data.coder_workspace_owner.me.id; + "com.coder.user.name" = ref.data.coder_workspace_owner.me.name; + "com.coder.workspace.id" = ref.data.coder_workspace.me.id; + "com.coder.workspace.name" = ref.data.coder_workspace.me.name; + }; + } + ]; + # give the shutdown tasks enough time to run + timeouts.delete = "31m"; + spec = [ + { + termination_grace_period_seconds = 1800; + affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution = { + weight = 1; + pod_affinity_term = { + topology_key = "kubernetes.io/hostname"; + label_selector.match_expressions = { + key = "app.kubernetes.io/name"; + operator = "In"; + values = ["coder-workspace"]; + }; + }; + }; + init_container = [ + { + name = "chown"; + image = "alpine:3"; + command = ["chown" "1000:1000" "/mnt/nix" "/mnt/tmp" "/mnt/home"]; + security_context.run_as_user = "0"; + volume_mount = [ + { + mount_path = "/mnt/home"; + name = "home"; + read_only = false; + } + { + mount_path = "/mnt/nix"; + name = "nix-store"; + read_only = false; + } + { + mount_path = "/mnt/tmp"; + name = "tmp"; + read_only = false; + } + ]; + } + { + name = "copy-nix-store"; + image = "registry.gitlab.com/technofab/coder-templates/nix-coder-image:${ref.data.coder_parameter.image_tag.value}"; + command = ["cp" "-nR" "/nix/." "/pv_nix"]; + security_context.run_as_user = "1000"; + volume_mount = [ + { + mount_path = "/pv_nix"; + name = "nix-store"; + read_only = false; + } + ]; + } + ]; + container = [ + { + name = "workspace"; + image = "registry.gitlab.com/technofab/coder-templates/nix-coder-image:${ref.data.coder_parameter.image_tag.value}"; + command = ["/bin/sh" "-c" "${ref.coder_agent.coder.init_script}"]; + env = [ + { + name = "CODER_AGENT_TOKEN"; + value = ref.coder_agent.coder.token; + } + { + name = "DOTFILES_REPO"; + value = ref.data.coder_parameter.dotfiles_repo.value; + } + { + name = "TZ"; + value = ref.data.coder_parameter.timezone.value; + } + { + name = "NIX_CONFIG"; + value = ref.data.coder_parameter.nix_config.value; + } + ]; + resources = { + requests = { + cpu = ref.var.cpu_request; + memory = ref.var.memory_request; + }; + limits = { + cpu = ref.data.coder_parameter.cpu.value; + memory = ref.data.coder_parameter.memory.value; + }; + }; + security_context = { + run_as_user = "1000"; + run_as_group = "1000"; + }; + volume_mount = [ + { + mount_path = "/home"; + name = "home"; + read_only = false; + } + { + mount_path = "/nix"; + name = "nix-store"; + read_only = false; + } + { + mount_path = "/tmp"; + name = "tmp"; + read_only = false; + } + ]; + } + ]; + security_context = { + run_as_user = "1000"; + run_as_group = "1000"; + }; + volume = [ + { + name = "home"; + persistent_volume_claim.claim_name = ref.kubernetes_persistent_volume_claim.home.metadata ".0.name"; + } + { + name = "nix-store"; + persistent_volume_claim.claim_name = ref.kubernetes_persistent_volume_claim.nix-store.metadata ".0.name"; + } + { + name = "tmp"; + empty_dir = { + medium = "Memory"; + # not used for now + # sizeLimit = "200Mi"; + }; + } + ]; + } + ]; + }; + kubernetes_persistent_volume_claim."home" = { + metadata = [ + { + name = "coder-home-${identifier}"; + namespace = ref.var.namespace; + annotations."com.coder.user.email" = ref.data.coder_workspace_owner.me.email; + labels = { + "app.kubernetes.io/instance" = "coder-pvc-home-${identifier}"; + "app.kubernetes.io/name" = "coder-pvc"; + "app.kubernetes.io/part-of" = "coder"; + "com.coder.resource" = "true"; + "com.coder.user.id" = ref.data.coder_workspace_owner.me.id; + "com.coder.user.name" = ref.data.coder_workspace_owner.me.name; + "com.coder.workspace.id" = ref.data.coder_workspace.me.id; + "com.coder.workspace.name" = ref.data.coder_workspace.me.name; + }; + } + ]; + spec = [ + { + access_modes = ["ReadWriteOnce"]; + resources.requests.storage = "${ref.data.coder_parameter.home_disk_size.value}Gi"; + } + ]; + wait_until_bound = false; + }; + kubernetes_persistent_volume_claim."nix-store" = { + metadata = [ + { + name = "coder-nix-store-${identifier}"; + namespace = ref.var.namespace; + annotations."com.coder.user.email" = ref.data.coder_workspace_owner.me.email; + labels = { + "app.kubernetes.io/instance" = "coder-pvc-nix-store-${identifier}"; + "app.kubernetes.io/name" = "coder-pvc"; + "app.kubernetes.io/part-of" = "coder"; + "com.coder.resource" = "true"; + "com.coder.user.id" = ref.data.coder_workspace_owner.me.id; + "com.coder.user.name" = ref.data.coder_workspace_owner.me.name; + "com.coder.workspace.id" = ref.data.coder_workspace.me.id; + "com.coder.workspace.name" = ref.data.coder_workspace.me.name; + }; + } + ]; + spec = [ + { + access_modes = ["ReadWriteOnce"]; + resources.requests.storage = "${ref.data.coder_parameter.nix_store_disk_size.value}Gi"; + } + ]; + wait_until_bound = false; + }; + }; +} diff --git a/nix-kubernetes/parameters.nix b/nix-kubernetes/parameters.nix new file mode 100644 index 0000000..18c88e6 --- /dev/null +++ b/nix-kubernetes/parameters.nix @@ -0,0 +1,112 @@ +{ + data.coder_parameter = { + "dotfiles_repo" = { + name = "Dotfiles Repository (passed to home-manager)"; + description = '' + Nix flake URI to your dotfiles repository, eg. + github:example/dotfiles#coder + + Your flake.nix has to expose a homeManagerConfiguration.coder in this case. + ''; + default = ""; + order = 1; + type = "string"; + mutable = true; + }; + "git_repo" = { + name = "Git Repository"; + description = '' + URI for a git repository which should automatically be cloned to ~/repos/ + ''; + default = ""; + order = 2; + type = "string"; + mutable = true; + }; + "image_tag" = { + name = "Image Tag"; + description = '' + Which container image tag should be used. + ''; + default = "latest"; + order = 3; + type = "string"; + mutable = true; + }; + "cpu" = { + name = "CPU"; + description = '' + CPU Limit for Kubernetes Pod. Kubernetes Notation (eg. 500m) + ''; + default = "500m"; + order = 4; + type = "string"; + mutable = true; + }; + "memory" = { + name = "Memory"; + description = '' + Memory Limit for Kubernetes Pod. Kubernetes Notation (eg. 1Gi) + ''; + default = "1Gi"; + order = 5; + type = "string"; + mutable = true; + }; + "home_disk_size" = { + name = "Home Disk Size"; + description = '' + Size for the /home PV in GB + ''; + default = "5"; + order = 6; + type = "number"; + mutable = true; + validation = [ + { + min = 1; + max = 100; + monotonic = "increasing"; + } + ]; + }; + "nix_store_disk_size" = { + name = "Nix Store Disk Size"; + description = '' + Size for the /nix PV in GB. This might grow pretty big. + ''; + default = "5"; + order = 7; + type = "number"; + mutable = true; + validation = [ + { + min = 1; + max = 100; + monotonic = "increasing"; + } + ]; + }; + "timezone" = { + name = "Timezone"; + description = '' + Content of the TZ environment variable. + ''; + default = ""; + order = 8; + type = "string"; + mutable = true; + }; + "nix_config" = { + name = "Nix Config"; + description = '' + Nix config, will be put into $NIX_CONFIG + ''; + default = ""; + order = 9; + type = "string"; + form_type = "textarea"; + mutable = true; + }; + }; +} diff --git a/nix-kubernetes/variables.nix b/nix-kubernetes/variables.nix new file mode 100644 index 0000000..4662a16 --- /dev/null +++ b/nix-kubernetes/variables.nix @@ -0,0 +1,26 @@ +{ + variable = { + "namespace" = { + type = "string"; + description = "Kubernetes namespace (must exist prior to creating workspaces)"; + }; + "arch" = { + type = "string"; + description = "Architecture of the host"; + validation = { + condition = ''''${contains(["amd64", "arm64"], var.arch)}''; + error_message = "Invalid architecture selected"; + }; + }; + "cpu_request" = { + type = "string"; + description = "CPU request to apply to workspaces. Kubernetes Notation (eg. 500m)"; + default = "0"; + }; + "memory_request" = { + type = "string"; + description = "Memory request to apply to workspaces. Kubernetes Notation (eg. 1Gi)"; + default = "0"; + }; + }; +} diff --git a/nix/packages/flake.lock b/nix/packages/flake.lock new file mode 100644 index 0000000..af7ba8d --- /dev/null +++ b/nix/packages/flake.lock @@ -0,0 +1,28 @@ +{ + "nodes": { + "root": { + "inputs": { + "tofunix-lib": "tofunix-lib" + } + }, + "tofunix-lib": { + "locked": { + "dir": "lib", + "lastModified": 1763036122, + "narHash": "sha256-AFsuSeZ6MjJk5kxfL09rmhKh+AxUICfQhactWAMzVmo=", + "owner": "TECHNOFAB", + "repo": "tofunix", + "rev": "69bffa53c525d6128b6a23743149e37c72d3d5ba", + "type": "gitlab" + }, + "original": { + "dir": "lib", + "owner": "TECHNOFAB", + "repo": "tofunix", + "type": "gitlab" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/nix/packages/flake.nix b/nix/packages/flake.nix new file mode 100644 index 0000000..6f4c53a --- /dev/null +++ b/nix/packages/flake.nix @@ -0,0 +1,10 @@ +{ + inputs = { + tofunix-lib.url = "gitlab:TECHNOFAB/tofunix?dir=lib"; + }; + outputs = i: + i + // { + tofulib = i.tofunix-lib.lib {inherit (i.parent) pkgs;}; + }; +} diff --git a/nix/packages/image.nix b/nix/packages/image.nix new file mode 100644 index 0000000..604766a --- /dev/null +++ b/nix/packages/image.nix @@ -0,0 +1,150 @@ +{ + lib, + pkgs, + ... +}: let + baseSystem = let + packages = with pkgs; [ + nix + bashInteractive + coreutils-full + procps + gnugrep + openssh + gitMinimal + curl + ncurses + less + + cacert.out + + (writeShellScriptBin "reload-dotfiles" '' + ${home-manager}/bin/home-manager switch --flake ''${DOTFILES_REPO:-$1} --option tarball-ttl 0 + '') + ]; + rootEnv = pkgs.buildPackages.buildEnv { + name = "root-profile-env"; + paths = packages; + }; + + nixConf = { + sandbox = "false"; + experimental-features = "nix-command flakes"; + min-free = toString (100 * 1024 * 1024); + max-free = toString (1024 * 1024 * 1024); + }; + + nixConfContents = + (lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: let + vStr = + if builtins.isList v + then lib.concatStringsSep " " v + else v; + in "${n} = ${vStr}") + nixConf)) + + "\n"; + + manifest = pkgs.buildPackages.runCommand "manifest.nix" {} '' + cat > $out < $out/etc/nix/nix.conf + echo "ID=nixos" > $out/etc/os-release + + echo "coder:x:1000:1000::/home/coder:/bin/bash" > $out/etc/passwd + echo "coder:!:::::::" > $out/etc/shadow + echo "coder:x:1000:" > $out/etc/group + echo "coder:x::" > $out/etc/gshadow + echo "coder:100000:65536" > $out/etc/subuid + echo "coder:100000:65536" > $out/etc/subgid + + # support timezones + ln -s ${pkgs.tzdata}/share/zoneinfo $out/etc/zoneinfo + + ln -s ${profile} $out/nix/var/nix/profiles/default-1-link + ln -s /nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default + + # prevents the profiles from being cleaned up by the GC + ln -s /nix/var/nix/profiles $out/nix/var/nix/gcroots/profiles + + ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env + ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh + ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/bash + ''; +in + pkgs.dockerTools.buildLayeredImageWithNixDb { + name = "nix-coder"; + tag = "latest"; + + contents = [baseSystem]; + maxLayers = 10; + + uid = 1000; + gid = 1000; + fakeRootCommands = '' + chown -R 1000:1000 ./ + chmod 1777 tmp + chmod 1777 var/tmp + ''; + + config = { + Cmd = ["/bin/bash"]; + User = "1000:1000"; + Env = [ + "USER=coder" + "HOME=/home/coder" + "TMPDIR=/tmp" + "XDG_RUNTIME_DIR=/tmp" + "TZDIR=/etc/zoneinfo" + "PATH=${lib.concatStringsSep ":" [ + "/home/coder/.nix-profile/bin" + # this makes all the packages defined at the top available + # in the workspace + "/nix/var/nix/profiles/default/bin" + "/nix/var/nix/profiles/default/sbin" + ]}" + "SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" + "GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" + "NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" + "NIX_PATH=/nix/var/nix/profiles/per-user/coder/channels:/home/coder/.nix-defexpr/channels" + ]; + }; + } diff --git a/nix/packages/packages.nix b/nix/packages/packages.nix new file mode 100644 index 0000000..8beda23 --- /dev/null +++ b/nix/packages/packages.nix @@ -0,0 +1,23 @@ +{inputs, ...}: let + inherit (inputs) self pkgs tofulib; +in rec { + nix-coder-image = pkgs.callPackage ./image.nix {}; + nix-kubernetes = nix-kubernetes-cli.tfjson; + nix-kubernetes-cli = tofulib.mkCliAio { + plugins = [ + (tofulib.mkOpentofuProvider { + owner = "coder"; + repo = "coder"; + version = "2.8.0"; + hash = "sha256-wnjgnD1c6U42ceizqfBG6SE4YXm7rZ7kyYkAdtE8t0k="; + }) + (tofulib.mkOpentofuProvider { + owner = "hashicorp"; + repo = "kubernetes"; + version = "2.29.0"; + hash = "sha256-r8DomSe+gUAbHuc8ciiuVl/6IeeIjJK6HFVaqAsnze8="; + }) + ]; + moduleConfig = "${self}/nix-kubernetes"; + }; +} diff --git a/nix/repo/ci.nix b/nix/repo/ci.nix new file mode 100644 index 0000000..7834b14 --- /dev/null +++ b/nix/repo/ci.nix @@ -0,0 +1,71 @@ +{inputs, ...}: let + inherit (inputs) pkgs cilib; + inherit (pkgs.lib) concatStringsSep; +in + cilib.mkCI { + pipelines."default" = { + stages = ["build" "upload"]; + jobs = let + SYSTEMS = ["aarch64-linux" "x86_64-linux"]; + TEMPLATES = ["nix-kubernetes"]; + in { + "build" = { + stage = "build"; + parallel.matrix = [ + {TEMPLATE = TEMPLATES;} + ]; + nix.deps = [pkgs.gnutar]; + script = [ + # sh + '' + nix build .#''${TEMPLATE} + install -D result templates/''${TEMPLATE}.tf.json + tar -cf templates/''${TEMPLATE}.tar -C templates ''${TEMPLATE}.tf.json + '' + ]; + artifacts.paths = ["templates/"]; + }; + "build:image" = { + stage = "build"; + parallel.matrix = [ + {SYSTEM = SYSTEMS;} + ]; + script = [ + # sh + '' + nix build .#nix-coder-image --system $SYSTEM + install -D result dist/nix-coder-image_''${SYSTEM}.tar.gz + '' + ]; + artifacts.paths = ["dist/"]; + }; + "upload" = { + stage = "upload"; + nix.deps = [pkgs.buildah]; + needs = ["build:image"]; + before_script = [ + # sh + '' + export REGISTRY_AUTH_FILE=''${HOME}/auth.json + echo "$CI_REGISTRY_PASSWORD" | buildah login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY + mkdir -p /etc/containers + echo '{"default":[{"type":"insecureAcceptAnything"}]}' > /etc/containers/policy.json + mkdir -p /var/tmp + '' + ]; + script = [ + # sh + '' + buildah manifest create localhost/nix-coder-image + ${concatStringsSep "\n" (map ( + sys: "buildah manifest add localhost/nix-coder-image docker-archive:dist/nix-coder-image_${sys}.tar.gz" + ) + SYSTEMS)} + buildah manifest push --all localhost/nix-coder-image \ + docker://''${CI_REGISTRY_IMAGE}/nix-coder-image:$CI_COMMIT_SHORT_SHA + '' + ]; + }; + }; + }; + } diff --git a/nix/repo/devShells.nix b/nix/repo/devShells.nix new file mode 100644 index 0000000..7628231 --- /dev/null +++ b/nix/repo/devShells.nix @@ -0,0 +1,23 @@ +{ + inputs, + cell, + ... +}: let + inherit (inputs) pkgs devshell treefmt soonix; + inherit (cell) ci; +in { + default = devshell.mkShell { + imports = [ + soonix.devshellModule + ]; + packages = [ + (treefmt.mkWrapper pkgs { + programs = { + alejandra.enable = true; + mdformat.enable = true; + }; + }) + ]; + soonix.hooks.ci = ci.soonix; + }; +} diff --git a/nix/repo/flake.lock b/nix/repo/flake.lock new file mode 100644 index 0000000..09a1bc6 --- /dev/null +++ b/nix/repo/flake.lock @@ -0,0 +1,82 @@ +{ + "nodes": { + "devshell-lib": { + "locked": { + "dir": "lib", + "lastModified": 1758204313, + "narHash": "sha256-ainbY0Oajb1HMdvy+A8QxF/P5qwcbEzJGEY5pzKdDdc=", + "owner": "rensa-nix", + "repo": "devshell", + "rev": "7d0c4bc78d9f017a739b0c7eb2f4e563118353e6", + "type": "gitlab" + }, + "original": { + "dir": "lib", + "owner": "rensa-nix", + "repo": "devshell", + "type": "gitlab" + } + }, + "nix-gitlab-ci-lib": { + "locked": { + "dir": "lib", + "lastModified": 1763066668, + "narHash": "sha256-mcNiuWf5R0qS7Be4EFAxPStl3SSYPhg4PSPAXgjKJj0=", + "owner": "TECHNOFAB", + "repo": "nix-gitlab-ci", + "rev": "524bdf9cdcfb8008c08d7e54a95992ebf05331d5", + "type": "gitlab" + }, + "original": { + "dir": "lib", + "owner": "TECHNOFAB", + "ref": "3.0.1", + "repo": "nix-gitlab-ci", + "type": "gitlab" + } + }, + "root": { + "inputs": { + "devshell-lib": "devshell-lib", + "nix-gitlab-ci-lib": "nix-gitlab-ci-lib", + "soonix-lib": "soonix-lib", + "treefmt-nix": "treefmt-nix" + } + }, + "soonix-lib": { + "locked": { + "dir": "lib", + "lastModified": 1758615778, + "narHash": "sha256-tggru+siXlLcLUjHtMojkJJWTS/8I3gm8nhnlz+qrTo=", + "owner": "TECHNOFAB", + "repo": "soonix", + "rev": "e04b71c07413251dcb52036b4a51c6c7c0dca2ad", + "type": "gitlab" + }, + "original": { + "dir": "lib", + "owner": "TECHNOFAB", + "repo": "soonix", + "type": "gitlab" + } + }, + "treefmt-nix": { + "flake": false, + "locked": { + "lastModified": 1762410071, + "narHash": "sha256-aF5fvoZeoXNPxT0bejFUBXeUjXfHLSL7g+mjR/p5TEg=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "97a30861b13c3731a84e09405414398fbf3e109f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/nix/repo/flake.nix b/nix/repo/flake.nix new file mode 100644 index 0000000..aa4a142 --- /dev/null +++ b/nix/repo/flake.nix @@ -0,0 +1,19 @@ +{ + inputs = { + devshell-lib.url = "gitlab:rensa-nix/devshell?dir=lib"; + soonix-lib.url = "gitlab:TECHNOFAB/soonix?dir=lib"; + nix-gitlab-ci-lib.url = "gitlab:TECHNOFAB/nix-gitlab-ci/3.0.1?dir=lib"; + treefmt-nix = { + url = "github:numtide/treefmt-nix"; + flake = false; + }; + }; + outputs = i: + i + // { + devshell = i.devshell-lib.lib {inherit (i.parent) pkgs;}; + soonix = i.soonix-lib.lib {inherit (i.parent) pkgs;}; + cilib = i.nix-gitlab-ci-lib.lib {inherit (i.parent) pkgs;}; + treefmt = import i.treefmt-nix; + }; +} From c16bc972648d07337428d93cb56daaae9eb01dde Mon Sep 17 00:00:00 2001 From: technofab Date: Tue, 18 Nov 2025 18:26:50 +0100 Subject: [PATCH 49/49] docs: add docs and improve README --- README.md | 4 ++- docs/images/logo.svg | 1 + docs/index.md | 11 ++++++ docs/style.css | 15 ++++++++ flake.nix | 2 ++ nix/packages/flake.lock | 6 ++-- nix/repo/ci.nix | 24 +++++++++++++ nix/repo/docs.nix | 80 +++++++++++++++++++++++++++++++++++++++++ nix/repo/flake.lock | 18 ++++++++++ nix/repo/flake.nix | 2 ++ 10 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 docs/images/logo.svg create mode 100644 docs/index.md create mode 100644 docs/style.css create mode 100644 nix/repo/docs.nix diff --git a/README.md b/README.md index c0a0bd2..d1350a8 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,10 @@ Templates for [Coder](https://coder.com), built with [Tofunix](https://tofunix.projects.tf). +Check [this Coder tutorial](https://coder.com/docs/tutorials/template-from-scratch#add-the-template-files-to-coder) for how to install the templates ("Dashboard" method recommended). + ## Templates -- Nix Kubernetes +- Nix Kubernetes ([Download tar](https://gitlab.com/TECHNOFAB/coder-templates/-/jobs/artifacts/main/raw/templates/nix-kubernetes.tar?job=build:%20%5Bnix-kubernetes%5D)) > provisions a Coder workspace on Kubernetes, running a Nix-built image, > which also contains Nix and supports Dotfiles management using home-manager. diff --git a/docs/images/logo.svg b/docs/images/logo.svg new file mode 100644 index 0000000..d6becf1 --- /dev/null +++ b/docs/images/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..b9db44c --- /dev/null +++ b/docs/index.md @@ -0,0 +1,11 @@ +# Coder Templates + +Templates for [Coder](https://coder.com), built with [Tofunix](https://tofunix.projects.tf). + +Check [this Coder tutorial](https://coder.com/docs/tutorials/template-from-scratch#add-the-template-files-to-coder) for how to install the templates ("Dashboard" method recommended). + +## Templates + +- [Nix Kubernetes](./parameters/nix-kubernetes.md) ([Download tar](https://gitlab.com/TECHNOFAB/coder-templates/-/jobs/artifacts/main/raw/templates/nix-kubernetes.tar?job=build:%20%5Bnix-kubernetes%5D)) + > provisions a Coder workspace on Kubernetes, running a Nix-built image, + > which also contains Nix and supports Dotfiles management using home-manager. diff --git a/docs/style.css b/docs/style.css new file mode 100644 index 0000000..b2ae4ff --- /dev/null +++ b/docs/style.css @@ -0,0 +1,15 @@ +.md-header__button.md-logo { + margin: 0; + padding-top: .2rem; + padding-bottom: .2rem; +} + +[dir="ltr"] .md-header__title { + margin-left: 0; +} + +.md-header__button.md-logo img, +.md-header__button.md-logo svg { + height: 2rem; +} + diff --git a/flake.nix b/flake.nix index c28db2e..fd3e3a8 100644 --- a/flake.nix +++ b/flake.nix @@ -22,6 +22,7 @@ }; cellBlocks = with ren.blocks; [ (simple "devShells") + (simple "docs") (simple "ci") (simple "packages") ]; @@ -29,6 +30,7 @@ { packages = ren.select self [ ["repo" "ci" "packages"] + ["repo" "docs"] ["packages" "packages"] ]; }; diff --git a/nix/packages/flake.lock b/nix/packages/flake.lock index af7ba8d..e5ea597 100644 --- a/nix/packages/flake.lock +++ b/nix/packages/flake.lock @@ -8,11 +8,11 @@ "tofunix-lib": { "locked": { "dir": "lib", - "lastModified": 1763036122, - "narHash": "sha256-AFsuSeZ6MjJk5kxfL09rmhKh+AxUICfQhactWAMzVmo=", + "lastModified": 1763484138, + "narHash": "sha256-4WuyFH0OxRD1urqKQR62LioYRStit63s4sFo18CDJOA=", "owner": "TECHNOFAB", "repo": "tofunix", - "rev": "69bffa53c525d6128b6a23743149e37c72d3d5ba", + "rev": "cb0605cf53f61286407345d1ee32395e54ba42d1", "type": "gitlab" }, "original": { diff --git a/nix/repo/ci.nix b/nix/repo/ci.nix index 7834b14..231be70 100644 --- a/nix/repo/ci.nix +++ b/nix/repo/ci.nix @@ -39,6 +39,30 @@ in ]; artifacts.paths = ["dist/"]; }; + "docs" = { + stage = "build"; + script = [ + # sh + '' + nix build .#docs:default + mkdir -p public + cp -r result/. public/ + '' + ]; + artifacts.paths = ["public"]; + }; + "pages" = { + nix.enable = false; + image = "alpine:latest"; + stage = "upload"; + script = ["true"]; + artifacts.paths = ["public"]; + rules = [ + { + "if" = "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"; + } + ]; + }; "upload" = { stage = "upload"; nix.deps = [pkgs.buildah]; diff --git a/nix/repo/docs.nix b/nix/repo/docs.nix new file mode 100644 index 0000000..7b87397 --- /dev/null +++ b/nix/repo/docs.nix @@ -0,0 +1,80 @@ +{inputs, ...}: let + inherit (inputs) cells doclib pkgs; + inherit (pkgs.lib) concatMapStringsSep; +in + (doclib.mkDocs { + docs."default" = { + base = "${inputs.self}"; + path = "${inputs.self}/docs"; + material = { + enable = true; + colors = { + primary = "green"; + accent = "light blue"; + }; + umami = { + enable = true; + src = "https://analytics.tf/umami"; + siteId = "dc8d1f6c-50f6-4019-9b0d-9b924dedb111"; + domains = ["coder-templates.projects.tf"]; + }; + }; + dynamic-nav = { + enable = true; + files."Parameters" = map (template: { + ${template} = + builtins.toFile "${template}.md" + # md + '' + # ${template} Parameters + + ${ + concatMapStringsSep "\n" (param: '' + ## ${param.name} + + ${param.description} + + Type: `${param.type}`
+ Mutable: `${ + if param.mutable + then "true" + else "false" + }`
+ ${ + if param.default != "" + then "Default: `${param.default}`
" + else "" + } + '') + (builtins.attrValues cells.packages.packages."${template}-cli".module.config.data.coder_parameter) + } + ''; + }) ["nix-kubernetes"]; + }; + config = { + site_name = "Coder Templates"; + site_url = "https://coder-templates.projects.tf"; + repo_name = "TECHNOFAB/coder-templates"; + repo_url = "https://gitlab.com/TECHNOFAB/coder-templates"; + extra_css = ["style.css"]; + theme = { + logo = "images/logo.svg"; + icon.repo = "simple/gitlab"; + favicon = "images/logo.svg"; + }; + nav = [ + {"Introduction" = "index.md";} + ]; + markdown_extensions = [ + { + "pymdownx.highlight".pygments_lang_class = true; + } + "pymdownx.inlinehilite" + "pymdownx.snippets" + "pymdownx.superfences" + "pymdownx.escapeall" + "fenced_code" + ]; + }; + }; + }).packages diff --git a/nix/repo/flake.lock b/nix/repo/flake.lock index 09a1bc6..d388b1b 100644 --- a/nix/repo/flake.lock +++ b/nix/repo/flake.lock @@ -35,10 +35,28 @@ "type": "gitlab" } }, + "nixmkdocs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1763481845, + "narHash": "sha256-Bp0+9rDmlPWMcnKqGx+BG4+o5KO8FuDAOvXRnXrm3Fo=", + "owner": "TECHNOFAB", + "repo": "nixmkdocs", + "rev": "73d59093df94a894d25bc4bf71880b6f00faa62f", + "type": "gitlab" + }, + "original": { + "dir": "lib", + "owner": "TECHNOFAB", + "repo": "nixmkdocs", + "type": "gitlab" + } + }, "root": { "inputs": { "devshell-lib": "devshell-lib", "nix-gitlab-ci-lib": "nix-gitlab-ci-lib", + "nixmkdocs-lib": "nixmkdocs-lib", "soonix-lib": "soonix-lib", "treefmt-nix": "treefmt-nix" } diff --git a/nix/repo/flake.nix b/nix/repo/flake.nix index aa4a142..60607ea 100644 --- a/nix/repo/flake.nix +++ b/nix/repo/flake.nix @@ -2,6 +2,7 @@ inputs = { devshell-lib.url = "gitlab:rensa-nix/devshell?dir=lib"; soonix-lib.url = "gitlab:TECHNOFAB/soonix?dir=lib"; + nixmkdocs-lib.url = "gitlab:TECHNOFAB/nixmkdocs?dir=lib"; nix-gitlab-ci-lib.url = "gitlab:TECHNOFAB/nix-gitlab-ci/3.0.1?dir=lib"; treefmt-nix = { url = "github:numtide/treefmt-nix"; @@ -13,6 +14,7 @@ // { devshell = i.devshell-lib.lib {inherit (i.parent) pkgs;}; soonix = i.soonix-lib.lib {inherit (i.parent) pkgs;}; + doclib = i.nixmkdocs-lib.lib {inherit (i.parent) pkgs;}; cilib = i.nix-gitlab-ci-lib.lib {inherit (i.parent) pkgs;}; treefmt = import i.treefmt-nix; };