mirror of
https://gitlab.com/TECHNOFAB/coder-templates.git
synced 2025-12-11 01:30:06 +01:00
chore: initial commit
This commit is contained in:
commit
8cf73a70ef
19 changed files with 1004 additions and 0 deletions
2
.envrc
Normal file
2
.envrc
Normal file
|
|
@ -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
|
||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
result
|
||||
5
.gitlab-ci.yml
Normal file
5
.gitlab-ci.yml
Normal file
|
|
@ -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
|
||||
9
README.md
Normal file
9
README.md
Normal file
|
|
@ -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.
|
||||
63
flake.lock
generated
Normal file
63
flake.lock
generated
Normal file
|
|
@ -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
|
||||
}
|
||||
35
flake.nix
Normal file
35
flake.nix
Normal file
|
|
@ -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"]
|
||||
];
|
||||
};
|
||||
}
|
||||
121
nix-kubernetes/coder.nix
Normal file
121
nix-kubernetes/coder.nix
Normal file
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
}
|
||||
8
nix-kubernetes/default.nix
Normal file
8
nix-kubernetes/default.nix
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
imports = [
|
||||
./parameters.nix
|
||||
./variables.nix
|
||||
./coder.nix
|
||||
./kubernetes.nix
|
||||
];
|
||||
}
|
||||
216
nix-kubernetes/kubernetes.nix
Normal file
216
nix-kubernetes/kubernetes.nix
Normal file
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
}
|
||||
112
nix-kubernetes/parameters.nix
Normal file
112
nix-kubernetes/parameters.nix
Normal file
|
|
@ -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/<name>
|
||||
'';
|
||||
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;
|
||||
};
|
||||
};
|
||||
}
|
||||
26
nix-kubernetes/variables.nix
Normal file
26
nix-kubernetes/variables.nix
Normal file
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
}
|
||||
28
nix/packages/flake.lock
generated
Normal file
28
nix/packages/flake.lock
generated
Normal file
|
|
@ -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
|
||||
}
|
||||
10
nix/packages/flake.nix
Normal file
10
nix/packages/flake.nix
Normal file
|
|
@ -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;};
|
||||
};
|
||||
}
|
||||
150
nix/packages/image.nix
Normal file
150
nix/packages/image.nix
Normal file
|
|
@ -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 <<EOF
|
||||
[
|
||||
${lib.concatStringsSep "\n" (builtins.map (drv: let
|
||||
outputs = drv.outputsToInstall or ["out"];
|
||||
in ''
|
||||
{
|
||||
${lib.concatStringsSep "\n" (builtins.map (output: ''
|
||||
${output} = { outPath = "${lib.getOutput output drv}"; };
|
||||
'')
|
||||
outputs)}
|
||||
outputs = [ ${lib.concatStringsSep " " (builtins.map (x: "\"${x}\"") outputs)} ];
|
||||
name = "${drv.name}";
|
||||
outPath = "${drv}";
|
||||
system = "${drv.system}";
|
||||
type = "derivation";
|
||||
meta = { };
|
||||
}
|
||||
'')
|
||||
packages)}
|
||||
]
|
||||
EOF
|
||||
'';
|
||||
profile = pkgs.buildPackages.runCommand "user-environment" {} ''
|
||||
mkdir $out
|
||||
cp -a ${rootEnv}/* $out/
|
||||
ln -s ${manifest} $out/manifest.nix
|
||||
'';
|
||||
|
||||
dirsToCreate = ["/etc/ssl/certs" "/etc/nix" "/usr" "/nix/var/nix/gcroots" "/bin" "/usr/bin" "/tmp" "/var/tmp" "/home/coder/.nix-defexpr" "/nix/var/nix/profiles/per-user/coder"];
|
||||
in
|
||||
pkgs.runCommand "base-system" {
|
||||
allowSubstitutes = false;
|
||||
preferLocalBuild = true;
|
||||
} ''
|
||||
env
|
||||
set -x
|
||||
mkdir -p ${lib.concatMapStringsSep " " (x: "$out${x}") dirsToCreate}
|
||||
|
||||
ln -s /nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt $out/etc/ssl/certs
|
||||
ln -s /nix/var/nix/profiles/share $out/usr/
|
||||
|
||||
echo "${nixConfContents}" > $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"
|
||||
];
|
||||
};
|
||||
}
|
||||
23
nix/packages/packages.nix
Normal file
23
nix/packages/packages.nix
Normal file
|
|
@ -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";
|
||||
};
|
||||
}
|
||||
71
nix/repo/ci.nix
Normal file
71
nix/repo/ci.nix
Normal file
|
|
@ -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
|
||||
''
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
23
nix/repo/devShells.nix
Normal file
23
nix/repo/devShells.nix
Normal file
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
82
nix/repo/flake.lock
generated
Normal file
82
nix/repo/flake.lock
generated
Normal file
|
|
@ -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
|
||||
}
|
||||
19
nix/repo/flake.nix
Normal file
19
nix/repo/flake.nix
Normal file
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue