diff --git a/.gitignore b/.gitignore index 96c5034..5f6290f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ dist-deps/ result .ghtoken cue.mod/gen +secrets.yaml diff --git a/renovate.json b/.renovaterc.json similarity index 64% rename from renovate.json rename to .renovaterc.json index 41dfb11..94cc05f 100644 --- a/renovate.json +++ b/.renovaterc.json @@ -8,7 +8,8 @@ "customType": "regex", "fileMatch": ["^flake.nix$"], "matchStrings": [ - "#\\s+renovate:\\s+(?.*?)(=(?.*?))? package=(?.*?) version=(?.*?)\\s+url = \"(?[^\"]*)\";\\s+digest = \"(?[^\"]*)\";" + "#\\s+renovate:\\s+(?.*?)(=(?.*?))? package=(?.*?) version=(?.*?)\\s+url = \"(?[^\"]*)\";\\s+digest = \"(?[^\"]*)\";", + "version = \"(?.*?)\";\\s+#\\s+renovate:\\s+(?.*?)(=(?.*?))? package=(?.*?)\\s+src\\s+=[^\\n]*?\\{\\s+url = \"(?[^\"]*)\";\\s+digest = \"(?[^\"]*)\";" ] }, { @@ -19,6 +20,13 @@ ], "datasourceTemplate": "github-release-attachments", "autoReplaceStringTemplate": "url = \"https://github.com/{{{depName}}}/releases/download/{{{newValue}}}/flux_{{{replace '^v' '' newValue}}}_linux_amd64.tar.gz\"; digest = \"{{{newDigest}}}\";" + }, + { + "customType": "regex", + "fileMatch": ["^versions.json$"], + "matchStrings": [ + "\"datasource\"\\s*:\\s*\"(?.*?)\"\\s*,\\s*\"package\"\\s*:\\s*\"(?.*?)\"\\s*,\\s*\"version\"\\s*:\\s*\"(?.*?)\"\\s*,\\s*\".*?(d|D)igest\"\\s*:\\s*\"(?.*?)\"" + ] } ], "enabledManagers": ["regex"], diff --git a/bgp-policy-labels.cue b/bgp-policy-labels.cue new file mode 100644 index 0000000..e0da940 --- /dev/null +++ b/bgp-policy-labels.cue @@ -0,0 +1,8 @@ +package netserv + +#BGPPolicyLabel: "pythoner6.dev/bgp-policy" + +#DefaultBGPPolicyLabels: { + (#BGPPolicyLabel): "default" + ... +} diff --git a/apps/cue.mod/module.cue b/cue.mod/module.cue similarity index 100% rename from apps/cue.mod/module.cue rename to cue.mod/module.cue diff --git a/apps/cue.mod/usr/k8s.io/api/core/v1/types.cue b/cue.mod/usr/k8s.io/api/core/v1/types.cue similarity index 100% rename from apps/cue.mod/usr/k8s.io/api/core/v1/types.cue rename to cue.mod/usr/k8s.io/api/core/v1/types.cue diff --git a/flake.nix b/flake.nix index f20b798..2896c6d 100644 --- a/flake.nix +++ b/flake.nix @@ -15,15 +15,31 @@ cue = import ./tools/cue.nix {inherit pkgs kubeVersion;}; utils = import ./tools/utils.nix {inherit pkgs;}; + versions = builtins.fromJSON (builtins.readFile ./versions.json); + stripv = v: builtins.head (builtins.match "^v?(.*)" v); + flux = pkgs.stdenv.mkDerivation { - name = "flux"; + pname = versions.flux.package; + version = versions.flux.version; src = utils.fetchurlHexDigest { - url = "https://github.com/fluxcd/flux2/releases/download/v2.2.2/flux_2.2.2_linux_amd64.tar.gz"; digest = "292945a94ae370b91fe004e1f41b16063fc87371a61a1fd29958dfd959140a60"; + url = "https://github.com/${versions.flux.package}/releases/download/${versions.flux.version}/flux_${stripv versions.flux.version}_linux_amd64.tar.gz"; + digest = versions.flux.digest; }; dontUnpack = true; installPhase = "set -e; mkdir -p $out/bin; tar -xzf $src -C $out/bin flux"; }; + talosctl = pkgs.stdenv.mkDerivation { + pname = "talosctl"; + version = versions.talos.version; + src = utils.fetchurlHexDigest { + url = "https://github.com/${versions.talos.package}/releases/download/${versions.talos.version}/talosctl-linux-amd64"; + digest = versions.talos.talosctlDigest; + }; + dontUnpack = true; + installPhase = "set -e; mkdir -p $out/bin; cp $src $out/bin/talosctl; chmod +x $out/bin/talosctl"; + }; + flux-manifests = pkgs.stdenv.mkDerivation { name = "flux-manifests"; dontUnpack = true; @@ -88,7 +104,20 @@ default = manifests; manifests = cue.synth { name = "netserv"; - src = ./apps; + #src = ./.; + #src = let x = lib.sources.sourceByRegex ./. [ + # #''^k8s/.*\.cue$'' + # #''^cue.mod/.*\.cue$'' + # #''^[^/]*\.cue$'' + # ''^.*\.cue$'' + # ''^k8s$'' + #]; in builtins.trace x x; + #src = lib.cleanSourceWith { + # filter = path: type: if type == "directory" then true else ; + # src = ./.; + #}; + src = lib.sources.sourceFilesBySuffices ./. [".cue"]; + appsSubdir = "k8s"; inherit charts; extraDefinitions = [ (cue.fromCrds "flux-crds" flux-manifests) @@ -108,7 +137,7 @@ }; devShells.${system} = { default = pkgs.mkShell { - buildInputs = with pkgs; [ pkgs.cue pkgs.timoni postgresql jq nodejs nodePackages.npm typescript kubernetes-helm flux umoci skopeo weave-gitops yq-go go xxd ]; + buildInputs = with pkgs; [ pkgs.cue pkgs.timoni postgresql jq nodejs nodePackages.npm typescript kubernetes-helm flux umoci skopeo weave-gitops yq-go go xxd talosctl ]; }; push = pkgs.mkShell { buildInputs = with pkgs; [ skopeo ]; diff --git a/apps/cert-manager/cert-manager.cue b/k8s/cert-manager/cert-manager.cue similarity index 100% rename from apps/cert-manager/cert-manager.cue rename to k8s/cert-manager/cert-manager.cue diff --git a/apps/cilium/cilium.cue b/k8s/cilium/cilium.cue similarity index 97% rename from apps/cilium/cilium.cue rename to k8s/cilium/cilium.cue index e22dcd9..4d2541a 100644 --- a/apps/cilium/cilium.cue +++ b/k8s/cilium/cilium.cue @@ -69,7 +69,7 @@ kustomizations: bgp: "manifest.yaml": { spec: blocks: [{cidr: "10.16.3.0/24"}] } default: bgppolicy.#CiliumBGPPeeringPolicy & { spec: { - nodeSelector: matchLabels: "pythoner6.dev/bgp-policy": "default" + nodeSelector: matchLabels: #DefaultBGPPolicyLabels virtualRouters: [{ localASN: 64514 exportPodCIDR: false diff --git a/apps/common.cue b/k8s/common.cue similarity index 100% rename from apps/common.cue rename to k8s/common.cue diff --git a/apps/external-secrets/es.cue b/k8s/external-secrets/es.cue similarity index 100% rename from apps/external-secrets/es.cue rename to k8s/external-secrets/es.cue diff --git a/apps/flux-components/flux.cue b/k8s/flux-components/flux.cue similarity index 100% rename from apps/flux-components/flux.cue rename to k8s/flux-components/flux.cue diff --git a/apps/synth_tool.cue b/k8s/synth_tool.cue similarity index 100% rename from apps/synth_tool.cue rename to k8s/synth_tool.cue diff --git a/talos/base.cue b/talos/base.cue new file mode 100644 index 0000000..d11290c --- /dev/null +++ b/talos/base.cue @@ -0,0 +1,44 @@ +package netserv + +_talosVersion: string +_kubeVersion: "1.29.0" + +#Config: { + _address: string + _controlplane: bool + _model: "rpi" | "m720q" + _endpoint: "10.16.2.10" + _installdisk: string + + machine: { + time: servers: ["time.cloudflare.com"] + if !_controlplane { + nodeLabels: #DefaultBGPPolicyLabels + } + network: { + nameservers: ["192.168.1.1"] + interfaces: [{ + dhcp: false, + addresses: [ "\(_address)/24" ] + routes: [{ + network: "0.0.0.0/0" + gateway: "10.16.2.2" + }] + if _controlplane { + vip: ip: _endpoint + } + }] + } + if !_controlplane { + install: wipe: true + } + } + cluster: { + proxy: disabled: true + network: { + podSubnets: ["172.16.0.0/16"] + serviceSubnets: ["172.17.0.0/16"] + cni: name: "none" + } + } +} diff --git a/talos/gen_tool.cue b/talos/gen_tool.cue new file mode 100644 index 0000000..1e6dece --- /dev/null +++ b/talos/gen_tool.cue @@ -0,0 +1,41 @@ +package netserv + +import ( + "tool/exec" + "tool/file" + "regexp" + "encoding/json" + "encoding/yaml" +) + +outputDir: string | *"output" @tag(outputDir) +_talosVersion : regexp.ReplaceAll("^v", json.Unmarshal(command.gen."versions.json".contents).talos.version, "") + +command: gen: { + mkdir: file.MkdirAll & { + path: outputDir + } + + "versions.json": file.Read & { + filename: "versions.json" + } + + for node in #Nodes { + "node-\(node._address)": exec.Run & { + $after: [mkdir] + _type: [if node._controlplane {"controlplane"}, "worker"][0] + cmd: [ + "talosctl", "gen", "config", "--force", + "--config-patch", yaml.Marshal(node), + "--with-secrets", "secrets.yaml", + "--install-image", "ghcr.io/siderolabs/installer:v\(_talosVersion)", + "--talos-version", "v\(_talosVersion)", + "--kubernetes-version", _kubeVersion, + "--install-disk", node._installdisk, + "--output-types", _type, + "--output", "\(outputDir)/\(_type)-\(node._address).yaml", + "netserv", "https://\(node._endpoint):6443", + ] + } + } +} diff --git a/talos/m720q.cue b/talos/m720q.cue new file mode 100644 index 0000000..30ee4b5 --- /dev/null +++ b/talos/m720q.cue @@ -0,0 +1,22 @@ +package netserv + +#Config: { + _model: string + if _model == "m720q" { + _installdisk: "/dev/nvme0n1" + machine: { + nodeLabels: ceph: "yes" + disks: [{ + device: "/dev/nvme0n2" + partitions: [{mountpoint: "/var/storage"}] + }] + network: interfaces: [{ + interface: "enp1s0" + }] + install: extraKernelArgs: [ + "net.ifnames=1", + "pcie_aspm=off", + ] + } + } +} diff --git a/talos/nodes.cue b/talos/nodes.cue new file mode 100644 index 0000000..8401b39 --- /dev/null +++ b/talos/nodes.cue @@ -0,0 +1,19 @@ +package netserv + +#Nodes: [ + for i in [1,2,3] { #Config & { + _address: "10.16.2.\(100 + i)" + _controlplane: true + _model: "rpi" + }} + for i in [1,2,3] { #Config & { + _address: "10.16.2.\(200 + i)" + _controlplane: false + _model: "rpi" + }} + for i in [1,2,3] { #Config & { + _address: "10.16.2.\(220 + i)" + _controlplane: false + _model: "m720q" + }} +] diff --git a/talos/rpi.cue b/talos/rpi.cue new file mode 100644 index 0000000..c7d6563 --- /dev/null +++ b/talos/rpi.cue @@ -0,0 +1,20 @@ +package netserv + +#Config: { + _model: string + _controlplane: bool + if _model == "rpi" { + _installdisk: [if _controlplane {"/dev/nvme0n1"}, "/dev/mmcblk0"][0] + machine: { + if !_controlplane { + disks: [{ + device: "/dev/nvme0n1" + partitions: [{mountpoint: "/var/storage"}] + }] + } + network: interfaces: [{ + deviceSelector: driver: "bcmgenet" + }] + } + } +} diff --git a/tools/cue.nix b/tools/cue.nix index 6eee5e7..01daba1 100644 --- a/tools/cue.nix +++ b/tools/cue.nix @@ -4,6 +4,7 @@ }; serialize = data: builtins.toJSON (builtins.toJSON data); getOpt = attrset: attr: default: if attrset ? ${attr} then attrset.${attr} else default; + lib = pkgs.lib; oci = import ./oci.nix {inherit pkgs;}; @@ -30,6 +31,16 @@ installPhase = "${./scripts/vendor_chart_crds.sh} ${builtins.toJSON (builtins.toJSON (if chart ? "crdValues" then chart.crdValues else {}))} ${kubeVersion}"; }; + #filterSources = src: lib.sources.sourceByRegex src (let + # f = remaining: transformed: let + # numRemaining = builtins.length remaining; + # in if numRemaining == 0 then transformed else let + # prefix = lib.lists.sublist 0 (numRemaining - 1) remaining; + # regex = "^" + (lib.strings.concatStringsSep "/" (prefix ++ [(lib.lists.last remaining) ''[^/]*$''])); + # in f prefix ([regex] ++ transformed); + # components = lib.path.subpath.components appPath; + #in f components [''^[^/]*$'']); + synthApp = { name, src, appPath, chartIndex, cuePackageName, extraManifests, cueDefinitions }: let inputs = { @@ -37,7 +48,8 @@ path = appPath; }; in pkgs.stdenv.mkDerivation { - inherit name src; + inherit name; + src = src; nativeBuildInputs = with pkgs; [ cue jq ]; installPhase = "${./scripts/synth.sh} <<< ${serialize inputs}"; }; @@ -73,16 +85,16 @@ in rec { }; }; - synth = { name, src, charts, cuePackageName ? name, extraManifests, extraDefinitions } @ args: + synth = { name, src, appsSubdir ? ".", charts, cuePackageName ? name, extraManifests, extraDefinitions } @ args: let apps = builtins.mapAttrs (appName: v: synthApp { inherit src cuePackageName; name = appName; + appPath = "${appsSubdir}/${appName}"; cueDefinitions = [fromK8s] ++ extraDefinitions ++ charts.cueDefinitions; chartIndex = charts.chartIndex; - appPath = appName; extraManifests = getOpt args.extraManifests appName null; - }) (pkgs.lib.attrsets.filterAttrs (n: v: v == "directory" && n != "cue.mod") (builtins.readDir src)); + }) (pkgs.lib.attrsets.filterAttrs (n: v: v == "directory" && n != "cue.mod") (builtins.readDir "${src}/${appsSubdir}")); in pkgs.stdenv.mkDerivation { inherit name; nativeBuildInputs = [ pkgs.jq ]; diff --git a/versions.json b/versions.json new file mode 100644 index 0000000..e56c4ce --- /dev/null +++ b/versions.json @@ -0,0 +1,14 @@ +{ + "talos": { + "datasource": "github-release-attachments", + "package": "siderolabs/talos", + "version": "v1.6.0", + "talosctlDigest": "3682def031e9b89e4fe4437b8b7cc9f383781f4c3173be9416cd65bc6e1333e7" + }, + "flux": { + "datasource": "github-release-attachments", + "package": "fluxcd/flux2", + "version": "v2.2.2", + "digest": "292945a94ae370b91fe004e1f41b16063fc87371a61a1fd29958dfd959140a60" + } +}