diff --git a/.github/actions/bump_version/action.yml b/.github/actions/bump_version/action.yml index 05610f5a69..9848d0b4d2 100644 --- a/.github/actions/bump_version/action.yml +++ b/.github/actions/bump_version/action.yml @@ -27,11 +27,7 @@ runs: run: | cd ${{ inputs.working-directory }} - current=$( - grep -E '^\s*version = "[^"]*";$' flake.nix | - sed -E 's/\s*version = "([^"]*)";/\1/' - ) - sed -i 's/version = "[^"]*";$/version = "${{ inputs.version }}";/' flake.nix + echo -n "${{ inputs.version }}" > version.txt commit_msg="flake: ${current} -> ${{ inputs.version }}" echo "commit-msg=${commit_msg}" | tee -a "$GITHUB_OUTPUT" @@ -42,6 +38,6 @@ runs: git config --global user.name "edgelessci" git config --global user.email "edgelessci@users.noreply.github.com" - git add flake.nix + git add version.txt git diff --staged --quiet || git commit -m "${commit_msg}" git push origin "$(git rev-parse --abbrev-ref HEAD)" diff --git a/.github/workflows/cluster_recreate.yml b/.github/workflows/cluster_recreate.yml index d97ff918ea..9af46f998c 100644 --- a/.github/workflows/cluster_recreate.yml +++ b/.github/workflows/cluster_recreate.yml @@ -28,7 +28,7 @@ jobs: - name: Destroy existing CI cluster continue-on-error: true run: | - nix run .#destroy-coco-aks -- --name="$azure_resource_group" + nix run .#scripts.destroy-coco-aks -- --name="$azure_resource_group" - name: Create CI cluster run: | - nix run .#create-coco-aks -- --name="$azure_resource_group" + nix run .#scripts.create-coco-aks -- --name="$azure_resource_group" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 34c34baec6..e07fd6a35f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -168,12 +168,12 @@ jobs: commit: false - name: Push containers with release tag run: | - nix run .#push-coordinator -- "$container_registry/nunki/coordinator" - nix run .#push-initializer -- "$container_registry/nunki/initializer" + nix run .#containers.push-coordinator -- "$container_registry/nunki/coordinator" + nix run .#containers.push-initializer -- "$container_registry/nunki/initializer" - name: Create portable coordinator resource definitions run: | mkdir -p workspace - nix run .#write-coordinator-yaml -- "${container_registry}/nunki/coordinator" > workspace/coordinator.yaml + nix run .#scripts.write-coordinator-yaml -- "${container_registry}/nunki/coordinator" > workspace/coordinator.yaml - name: Update coordinator policy hash run: | yq < workspace/coordinator.yaml \ diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 8e453c3d8b..2b3998d581 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -39,7 +39,7 @@ jobs: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - name: Run code generations & tidying run: | - nix run .#generate + nix run .#scripts.generate - name: Check for modifications, commit changes on renovate PRs uses: ./.github/actions/pushdiff with: @@ -60,7 +60,7 @@ jobs: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - name: Run govulncheck run: | - nix run .#govulncheck -- ./... + nix run .#scripts.govulncheck -- ./... golangci-lint: runs-on: ubuntu-22.04 @@ -75,4 +75,4 @@ jobs: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - name: Run golangci-lint run: | - nix run .#golangci-lint -- run + nix run .#scripts.golangci-lint -- run diff --git a/flake.nix b/flake.nix index 4e927a55b1..3b1314b015 100644 --- a/flake.nix +++ b/flake.nix @@ -22,14 +22,9 @@ let pkgs = import nixpkgs { inherit system; }; inherit (pkgs) lib; - - version = "0.2.0-pre"; - treefmtEval = treefmt-nix.lib.evalModule pkgs ./treefmt.nix; in { - packages = import ./packages { inherit pkgs version; }; - devShells.default = pkgs.mkShell { packages = with pkgs; [ golangci-lint @@ -44,7 +39,7 @@ formatting = treefmtEval.config.build.check self; }; - legacyPackages = pkgs; + legacyPackages = (import ./packages { inherit pkgs lib; }) // pkgs; }); nixConfig = { diff --git a/justfile b/justfile index facbd9b027..e0df7db601 100644 --- a/justfile +++ b/justfile @@ -3,19 +3,19 @@ default target=default_deploy_target: undeploy coordinator initializer openssl p # Build the coordinator, containerize and push it. coordinator: - nix run .#push-coordinator -- "$container_registry/nunki/coordinator" + nix run .#containers.push-coordinator -- "$container_registry/nunki/coordinator" # Build the openssl container and push it. openssl: - nix run .#push-openssl -- "$container_registry/nunki/openssl" + nix run .#containers.push-openssl -- "$container_registry/nunki/openssl" # Build the port-forwarder container and push it. port-forwarder: - nix run .#push-port-forwarder -- "$container_registry/nunki/port-forwarder" + nix run .#containers.push-port-forwarder -- "$container_registry/nunki/port-forwarder" # Build the initializer, containerize and push it. initializer: - nix run .#push-initializer -- "$container_registry/nunki/initializer" + nix run .#containers.push-initializer -- "$container_registry/nunki/initializer" default_deploy_target := "simple" workspace_dir := "workspace" @@ -31,13 +31,13 @@ generate target=default_deploy_target: rm -rf ./{{ workspace_dir }}/* cp -R ./deployments/{{ target }} ./{{ workspace_dir }}/deployment echo "{{ target }}${namespace_suffix-}" > ./{{ workspace_dir }}/just.namespace - nix run .#patch-nunki-image-hashes -- ./{{ workspace_dir }}/deployment + nix run .#scripts.patch-nunki-image-hashes -- ./{{ workspace_dir }}/deployment nix run .#kypatch images -- ./{{ workspace_dir }}/deployment \ --replace ghcr.io/edgelesssys ${container_registry} nix run .#kypatch namespace -- ./{{ workspace_dir }}/deployment \ --replace edg-default {{ target }}${namespace_suffix-} t=$(date +%s) - nix run .#cli -- generate \ + nix run .#nunki.cli -- generate \ -m ./{{ workspace_dir }}/manifest.json \ -p ./{{ workspace_dir }}/rules.rego \ -s ./{{ workspace_dir }}/genpolicy-msft.json \ @@ -66,22 +66,22 @@ undeploy: # Create a CoCo-enabled AKS cluster. create: - nix run .#create-coco-aks -- --name="$azure_resource_group" + nix run .#scripts.create-coco-aks -- --name="$azure_resource_group" # Set the manifest at the coordinator. set: #!/usr/bin/env bash set -euo pipefail ns=$(cat ./{{ workspace_dir }}/just.namespace) - nix run .#kubectl-wait-ready -- $ns coordinator - nix run .#kubectl-wait-ready -- $ns port-forwarder-coordinator + nix run .#scripts.kubectl-wait-ready -- $ns coordinator + nix run .#scripts.kubectl-wait-ready -- $ns port-forwarder-coordinator kubectl -n $ns port-forward pod/port-forwarder-coordinator 1313 & PID=$! trap "kill $PID" EXIT - nix run .#wait-for-port-listen -- 1313 + nix run .#scripts.wait-for-port-listen -- 1313 policy=$(<./{{ workspace_dir }}/just.coordinator-policy-hash) t=$(date +%s) - nix run .#cli -- set \ + nix run .#nunki.cli -- set \ -m ./{{ workspace_dir }}/manifest.json \ -c localhost:1313 \ --coordinator-policy-hash "${policy}" \ @@ -96,13 +96,13 @@ verify: set -euo pipefail rm -rf ./{{ workspace_dir }}/verify ns=$(cat ./{{ workspace_dir }}/just.namespace) - nix run .#kubectl-wait-ready -- $ns coordinator + nix run .#scripts.kubectl-wait-ready -- $ns coordinator kubectl -n $ns port-forward pod/port-forwarder-coordinator 1314:1313 & PID=$! trap "kill $PID" EXIT - nix run .#wait-for-port-listen -- 1314 + nix run .#scripts.wait-for-port-listen -- 1314 t=$(date +%s) - nix run .#cli -- verify \ + nix run .#nunki.cli -- verify \ -c localhost:1314 \ -o ./{{ workspace_dir }}/verify duration=$(( $(date +%s) - $t )) @@ -116,18 +116,18 @@ wait-for-workload target=default_deploy_target: ns=$(cat ./{{ workspace_dir }}/just.namespace) case {{ target }} in "simple") - nix run .#kubectl-wait-ready -- $ns workload + nix run .#scripts.kubectl-wait-ready -- $ns workload ;; "openssl") - nix run .#kubectl-wait-ready -- $ns openssl-backend - nix run .#kubectl-wait-ready -- $ns openssl-client - nix run .#kubectl-wait-ready -- $ns openssl-frontend + nix run .#scripts.kubectl-wait-ready -- $ns openssl-backend + nix run .#scripts.kubectl-wait-ready -- $ns openssl-client + nix run .#scripts.kubectl-wait-ready -- $ns openssl-frontend ;; "emojivoto") - nix run .#kubectl-wait-ready -- $ns emoji-svc - nix run .#kubectl-wait-ready -- $ns vote-bot - nix run .#kubectl-wait-ready -- $ns voting-svc - nix run .#kubectl-wait-ready -- $ns web-svc + nix run .#scripts.kubectl-wait-ready -- $ns emoji-svc + nix run .#scripts.kubectl-wait-ready -- $ns vote-bot + nix run .#scripts.kubectl-wait-ready -- $ns voting-svc + nix run .#scripts.kubectl-wait-ready -- $ns web-svc ;; *) echo "Please register workloads of new targets in wait-for-workload" @@ -150,11 +150,11 @@ get-credentials-ci: # Destroy a running AKS cluster. destroy: - nix run .#destroy-coco-aks -- --name="$azure_resource_group" + nix run .#scripts.destroy-coco-aks -- --name="$azure_resource_group" # Run code generators. codegen: - nix run .#generate + nix run .#scripts.generate # Format code. fmt: @@ -162,7 +162,7 @@ fmt: # Lint code. lint: - nix run .#golangci-lint -- run + nix run .#scripts.golangci-lint -- run demodir: undeploy coordinator initializer #!/usr/bin/env bash @@ -171,7 +171,7 @@ demodir: undeploy coordinator initializer nix build .#nunki.cli cp ./result-cli/bin/nunki "${d}/nunki" cp -R ./deployments/emojivoto "${d}/deployment" - nix run .#patch-nunki-image-hashes -- "${d}/deployment" + nix run .#scripts.patch-nunki-image-hashes -- "${d}/deployment" nix run .#kypatch images -- "${d}/deployment" \ --replace ghcr.io/edgelesssys ${container_registry} echo "Demo directory ready at ${d}" diff --git a/packages/azurecli.nix b/packages/by-name/azure-cli-with-extensions/package.nix similarity index 100% rename from packages/azurecli.nix rename to packages/by-name/azure-cli-with-extensions/package.nix diff --git a/packages/genpolicy_kata.nix b/packages/by-name/genpolicy-kata/package.nix similarity index 100% rename from packages/genpolicy_kata.nix rename to packages/by-name/genpolicy-kata/package.nix diff --git a/packages/genpolicy_msft_settings_dev.patch b/packages/by-name/genpolicy-msft/genpolicy_msft_settings_dev.patch similarity index 100% rename from packages/genpolicy_msft_settings_dev.patch rename to packages/by-name/genpolicy-msft/genpolicy_msft_settings_dev.patch diff --git a/packages/genpolicy_msft.nix b/packages/by-name/genpolicy-msft/package.nix similarity index 100% rename from packages/genpolicy_msft.nix rename to packages/by-name/genpolicy-msft/package.nix diff --git a/packages/kypatch.sh b/packages/by-name/kypatch/kypatch.sh similarity index 100% rename from packages/kypatch.sh rename to packages/by-name/kypatch/kypatch.sh diff --git a/packages/by-name/kypatch/package.nix b/packages/by-name/kypatch/package.nix new file mode 100644 index 0000000000..b0635879e8 --- /dev/null +++ b/packages/by-name/kypatch/package.nix @@ -0,0 +1,7 @@ +{ writeShellApplication, yq-go }: + +writeShellApplication { + name = "kypatch"; + runtimeInputs = [ yq-go ]; + text = builtins.readFile ./kypatch.sh; +} diff --git a/packages/by-name/nunki/package.nix b/packages/by-name/nunki/package.nix new file mode 100644 index 0000000000..0ccf755d04 --- /dev/null +++ b/packages/by-name/nunki/package.nix @@ -0,0 +1,64 @@ +{ lib +, buildGoModule +, genpolicy-msft +, genpolicy ? genpolicy-msft +}: + +buildGoModule rec { + pname = "nunki"; + version = builtins.readFile ../../../version.txt; + + outputs = subPackages ++ [ "out" ]; + + # The source of the main module of this repo. We filter for Go files so that + # changes in the other parts of this repo don't trigger a rebuild. + src = + let + inherit (lib) fileset path hasSuffix; + root = ../../../.; + in + fileset.toSource { + inherit root; + fileset = fileset.unions [ + (path.append root "go.mod") + (path.append root "go.sum") + (fileset.fileFilter (file: hasSuffix ".go" file.name) root) + ]; + }; + + proxyVendor = true; + vendorHash = "sha256-W6mphSRaIIGE9hp0Ga0+7syj1HkFaCKJykxfO2PbB9I="; + + subPackages = [ "coordinator" "initializer" "cli" ]; + + prePatch = '' + install -D ${lib.getExe genpolicy} cli/assets/genpolicy + install -D ${genpolicy.settings-dev}/genpolicy-settings.json cli/assets/genpolicy-settings.json + install -D ${genpolicy.rules}/genpolicy-rules.rego cli/assets/genpolicy-rules.rego + ''; + + CGO_ENABLED = 0; + ldflags = [ + "-s" + "-w" + "-X main.version=v${version}" + ]; + + preCheck = '' + export CGO_ENABLED=1 + ''; + + checkPhase = '' + runHook preCheck + go test -race ./... + runHook postCheck + ''; + + postInstall = '' + for sub in ${builtins.concatStringsSep " " subPackages}; do + install -Dm755 "$out/bin/$sub" "''${!sub}/bin/$sub" + done + mv "$cli/bin/cli" "$cli/bin/nunki" + ''; + meta.mainProgram = "nunki"; +} diff --git a/packages/containers.nix b/packages/containers.nix new file mode 100644 index 0000000000..4123c76260 --- /dev/null +++ b/packages/containers.nix @@ -0,0 +1,64 @@ +{ pkgs }: + +with pkgs; + +let + pushContainer = container: writeShellApplication { + name = "push-${container.name}"; + runtimeInputs = [ crane gzip ]; + text = '' + imageName="$1" + tmpdir=$(mktemp -d) + trap 'rm -rf $tmpdir' EXIT + gunzip < "${container}" > "$tmpdir/image.tar" + crane push "$tmpdir/image.tar" "$imageName:${container.imageTag}" + ''; + }; + + containers = { + coordinator = dockerTools.buildImage { + name = "coordinator"; + tag = "v${nunki.version}"; + copyToRoot = with dockerTools; [ caCertificates ]; + config = { + Cmd = [ "${nunki.coordinator}/bin/coordinator" ]; + Env = [ "PATH=/bin" ]; # This is only here for policy generation. + }; + }; + + initializer = dockerTools.buildImage { + name = "initializer"; + tag = "v${nunki.version}"; + copyToRoot = with dockerTools; [ caCertificates ]; + config = { + Cmd = [ "${nunki.initializer}/bin/initializer" ]; + Env = [ "PATH=/bin" ]; # This is only here for policy generation. + }; + }; + + openssl = dockerTools.buildImage { + name = "openssl"; + tag = "v${nunki.version}"; + copyToRoot = [ + bash + bashInteractive + coreutils + ncurses + openssl + procps + vim + ]; + config = { + Cmd = [ "bash" ]; + Env = [ "PATH=/bin" ]; # This is only here for policy generation. + }; + }; + + port-forwarder = dockerTools.buildImage { + name = "port-forwarder"; + tag = "v${nunki.version}"; + copyToRoot = [ bash socat ]; + }; + }; +in +containers // (lib.concatMapAttrs (name: container: { "push-${name}" = pushContainer container; }) containers) diff --git a/packages/default.nix b/packages/default.nix index 1528364121..6512b67a5b 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -1,302 +1,16 @@ -{ pkgs -, version -}: - -with pkgs; +{ lib, pkgs }: let - # The source of our local Go module. We filter for Go files so that - # changes in the other parts of this repo don't trigger a rebuild. - goFiles = lib.fileset.toSource { - root = ../.; - fileset = lib.fileset.unions [ - ../go.mod - ../go.sum - (lib.fileset.fileFilter (file: lib.hasSuffix ".go" file.name) ../.) - ]; - }; - - pushContainer = container: writeShellApplication { - name = "push"; - runtimeInputs = [ crane gzip ]; - text = '' - imageName="$1" - tmpdir=$(mktemp -d) - trap 'rm -rf $tmpdir' EXIT - gunzip < "${container}" > "$tmpdir/image.tar" - crane push "$tmpdir/image.tar" "$imageName:${container.imageTag}" - ''; + pkgs' = pkgs // self; + callPackages = lib.callPackagesWith pkgs'; + self = (lib.packagesFromDirectoryRecursive { + callPackage = lib.callPackageWith pkgs'; + directory = ./by-name; + }) // { + containers = callPackages ./containers.nix { pkgs = pkgs'; }; + scripts = callPackages ./scripts.nix { pkgs = pkgs'; }; + genpolicy-msft = pkgs.pkgsStatic.callPackage ./by-name/genpolicy-msft/package.nix { }; + genpolicy-kata = pkgs.pkgsStatic.callPackage ./by-name/genpolicy-kata/package.nix { }; }; in - -rec { - nunki = - let - subPackages = [ "coordinator" "initializer" "cli" ]; - in - lib.makeOverridable buildGoModule { - inherit version subPackages; - name = "nunki"; - - outputs = subPackages ++ [ "out" ]; - - src = goFiles; - proxyVendor = true; - vendorHash = "sha256-W6mphSRaIIGE9hp0Ga0+7syj1HkFaCKJykxfO2PbB9I="; - - prePatch = '' - install -D ${lib.getExe genpolicy} cli/assets/genpolicy - install -D ${genpolicy.settings-dev}/genpolicy-settings.json cli/assets/genpolicy-settings.json - install -D ${genpolicy.rules}/genpolicy-rules.rego cli/assets/genpolicy-rules.rego - ''; - - CGO_ENABLED = 0; - ldflags = [ - "-s" - "-w" - "-X main.version=v${version}" - ]; - - preCheck = '' - export CGO_ENABLED=1 - ''; - - checkPhase = '' - runHook preCheck - go test -race ./... - runHook postCheck - ''; - - postInstall = '' - for sub in ${builtins.concatStringsSep " " subPackages}; do - install -Dm755 "$out/bin/$sub" "''${!sub}/bin/$sub" - done - mv "$cli/bin/cli" "$cli/bin/nunki" - ''; - meta.mainProgram = "nunki"; - }; - inherit (nunki) cli; - - cli-release = (nunki.override (prevArgs: { - ldflags = prevArgs.ldflags ++ [ - "-X main.DefaultCoordinatorPolicyHash=${builtins.readFile ../cli/assets/coordinator-policy-hash}" - ]; - })).cli; - - coordinator = dockerTools.buildImage { - name = "coordinator"; - tag = "v${version}"; - copyToRoot = with dockerTools; [ caCertificates ]; - config = { - Cmd = [ "${nunki.coordinator}/bin/coordinator" ]; - Env = [ "PATH=/bin" ]; # This is only here for policy generation. - }; - }; - initializer = dockerTools.buildImage { - name = "initializer"; - tag = "v${version}"; - copyToRoot = with dockerTools; [ caCertificates ]; - config = { - Cmd = [ "${nunki.initializer}/bin/initializer" ]; - Env = [ "PATH=/bin" ]; # This is only here for policy generation. - }; - }; - - opensslContainer = dockerTools.buildImage { - name = "openssl"; - tag = "v${version}"; - copyToRoot = [ openssl bash coreutils ncurses bashInteractive vim procps ]; - config = { - Cmd = [ "bash" ]; - Env = [ "PATH=/bin" ]; # This is only here for policy generation. - }; - }; - port-forwarder = dockerTools.buildImage { - name = "port-forwarder"; - tag = "v${version}"; - copyToRoot = [ bash socat ]; - }; - - push-coordinator = pushContainer coordinator; - push-initializer = pushContainer initializer; - - push-openssl = pushContainer opensslContainer; - push-port-forwarder = pushContainer port-forwarder; - - azure-cli-with-extensions = callPackage ./azurecli.nix { }; - - create-coco-aks = writeShellApplication { - name = "create-coco-aks"; - runtimeInputs = [ azure-cli-with-extensions ]; - text = builtins.readFile ./create-coco-aks.sh; - }; - destroy-coco-aks = writeShellApplication { - name = "destroy-coco-aks"; - runtimeInputs = [ azure-cli-with-extensions ]; - text = builtins.readFile ./destroy-coco-aks.sh; - }; - - generate = writeShellApplication { - name = "generate"; - runtimeInputs = [ - go - protobuf - protoc-gen-go - protoc-gen-go-grpc - nix-update - ]; - text = '' - go mod tidy - go generate ./... - - # All binaries of the local Go module share the same builder, - # we only need to update one of them to update the vendorHash - # of the builder. - nix-update --version=skip --flake cli - ''; - }; - - genpolicy = genpolicy-msft; - genpolicy-msft = pkgsStatic.callPackage ./genpolicy_msft.nix { }; - genpolicy-kata = pkgsStatic.callPackage ./genpolicy_kata.nix { }; - - govulncheck = writeShellApplication { - name = "govulncheck"; - runtimeInputs = [ go pkgs.govulncheck ]; - text = ''govulncheck "$@"''; - }; - - golangci-lint = writeShellApplication { - name = "golangci-lint"; - runtimeInputs = [ go pkgs.golangci-lint ]; - text = ''golangci-lint "$@"''; - }; - - patch-nunki-image-hashes = writeShellApplication { - name = "patch-nunki-image-hashes"; - runtimeInputs = [ - coordinator - crane - initializer - kypatch - opensslContainer - port-forwarder - ]; - text = '' - targetPath=$1 - - tmpdir=$(mktemp -d) - trap 'rm -rf $tmpdir' EXIT - - gunzip < "${coordinator}" > "$tmpdir/coordinator.tar" - gunzip < "${initializer}" > "$tmpdir/initializer.tar" - gunzip < "${opensslContainer}" > "$tmpdir/openssl.tar" - gunzip < "${port-forwarder}" > "$tmpdir/port-forwarder.tar" - - coordHash=$(crane digest --tarball "$tmpdir/coordinator.tar") - initHash=$(crane digest --tarball "$tmpdir/initializer.tar") - opensslHash=$(crane digest --tarball "$tmpdir/openssl.tar") - forwarderHash=$(crane digest --tarball "$tmpdir/port-forwarder.tar") - - kypatch images "$targetPath" \ - --replace "nunki/coordinator:latest" "nunki/coordinator@$coordHash" \ - --replace "nunki/initializer:latest" "nunki/initializer@$initHash" \ - --replace "nunki/openssl:latest" "nunki/openssl@$opensslHash" \ - --replace "nunki/port-forwarder:latest" "nunki/port-forwarder@$forwarderHash" - ''; - }; - - kypatch = writeShellApplication { - name = "kypatch"; - runtimeInputs = [ yq-go ]; - text = builtins.readFile ./kypatch.sh; - }; - - kubectl-wait-ready = writeShellApplication { - name = "kubectl-wait-ready"; - runtimeInputs = [ kubectl ]; - text = '' - namespace=$1 - name=$2 - - echo "Waiting for $name.$namespace to become ready" >&2 - - timeout=180 - - interval=4 - while [ $timeout -gt 0 ]; do - if kubectl -n "$namespace" get pods -o custom-columns=LABELS:.metadata.labels | grep -q "app.kubernetes.io/name:$name"; then - break - fi - sleep "$interval" - timeout=$((timeout - interval)) - done - - kubectl wait \ - --namespace "$namespace" \ - --selector "app.kubernetes.io/name=$name" \ - --for=condition=Ready \ - --timeout="''${timeout}s" \ - pods - ''; - }; - - wait-for-port-listen = writeShellApplication { - name = "wait-for-port-listen"; - runtimeInputs = [ iproute2 ]; - text = '' - port=$1 - - function ss-listen-on-port() { - ss \ - --tcp \ - --numeric \ - --listening \ - --no-header \ - --ipv4 \ - src ":$port" - } - - tries=15 # 3 seconds - interval=0.2 - - while [[ "$tries" -gt 0 ]]; do - if [[ -n $(ss-listen-on-port) ]]; then - exit 0 - fi - sleep "$interval" - tries=$((tries - 1)) - done - - echo "Port $port did not reach state LISTENING" >&2 - exit 1 - ''; - }; - - # write-coordinator-yaml prints a Nunki Coordinator deployment including the default policy. - # It's intended for two purposes: (1) releasing a portable coordinator.yaml and (2) updating the embedded policy hash. - write-coordinator-yaml = writeShellApplication { - name = "write-coordinator-yaml"; - runtimeInputs = [ - yq-go - genpolicy - ]; - text = '' - imageRef=$1:v${version} - - tmpdir=$(mktemp -d) - trap 'rm -rf $tmpdir' EXIT - - # TODO(burgerdev): consider a dedicated coordinator template instead of the simple one - yq < deployments/simple/coordinator.yml > "$tmpdir/coordinator.yml" \ - "del(.metadata.namespace) | (select(.kind == \"Deployment\") | .spec.template.spec.containers[0].image) = \"$imageRef\"" - - pushd "$tmpdir" >/dev/null - cp ${genpolicy.settings}/genpolicy-settings.json . - cp ${genpolicy.rules-coordinator}/genpolicy-rules.rego rules.rego - genpolicy < "$tmpdir/coordinator.yml" - popd >/dev/null - ''; - }; - -} +self diff --git a/packages/scripts.nix b/packages/scripts.nix new file mode 100644 index 0000000000..b46fd8e93a --- /dev/null +++ b/packages/scripts.nix @@ -0,0 +1,166 @@ +{ pkgs }: + +with pkgs; + +{ + create-coco-aks = writeShellApplication { + name = "create-coco-aks"; + runtimeInputs = [ azure-cli-with-extensions ]; + text = builtins.readFile ./create-coco-aks.sh; + }; + + destroy-coco-aks = writeShellApplication { + name = "destroy-coco-aks"; + runtimeInputs = [ azure-cli-with-extensions ]; + text = builtins.readFile ./destroy-coco-aks.sh; + }; + + generate = writeShellApplication { + name = "generate"; + runtimeInputs = [ + go + protobuf + protoc-gen-go + protoc-gen-go-grpc + nix-update + ]; + text = '' + go mod tidy + go generate ./... + + # All binaries of the local Go module share the same builder, + # we only need to update one of them to update the vendorHash + # of the builder. + nix-update --version=skip --flake legacyPackages.x86_64-linux.nunki.cli + ''; + }; + + govulncheck = writeShellApplication { + name = "govulncheck"; + runtimeInputs = [ go pkgs.govulncheck ]; + text = ''govulncheck "$@"''; + }; + + golangci-lint = writeShellApplication { + name = "golangci-lint"; + runtimeInputs = [ go pkgs.golangci-lint ]; + text = ''golangci-lint "$@"''; + }; + + patch-nunki-image-hashes = writeShellApplication { + name = "patch-nunki-image-hashes"; + runtimeInputs = [ + crane + kypatch + ]; + text = '' + targetPath=$1 + + tmpdir=$(mktemp -d) + trap 'rm -rf $tmpdir' EXIT + + gunzip < "${containers.coordinator}" > "$tmpdir/coordinator.tar" + gunzip < "${containers.initializer}" > "$tmpdir/initializer.tar" + gunzip < "${containers.openssl}" > "$tmpdir/openssl.tar" + gunzip < "${containers.port-forwarder}" > "$tmpdir/port-forwarder.tar" + + coordHash=$(crane digest --tarball "$tmpdir/coordinator.tar") + initHash=$(crane digest --tarball "$tmpdir/initializer.tar") + opensslHash=$(crane digest --tarball "$tmpdir/openssl.tar") + forwarderHash=$(crane digest --tarball "$tmpdir/port-forwarder.tar") + + kypatch images "$targetPath" \ + --replace "nunki/coordinator:latest" "nunki/coordinator@$coordHash" \ + --replace "nunki/initializer:latest" "nunki/initializer@$initHash" \ + --replace "nunki/openssl:latest" "nunki/openssl@$opensslHash" \ + --replace "nunki/port-forwarder:latest" "nunki/port-forwarder@$forwarderHash" + ''; + }; + + kubectl-wait-ready = writeShellApplication { + name = "kubectl-wait-ready"; + runtimeInputs = [ kubectl ]; + text = '' + namespace=$1 + name=$2 + + echo "Waiting for $name.$namespace to become ready" >&2 + + timeout=180 + + interval=4 + while [ $timeout -gt 0 ]; do + if kubectl -n "$namespace" get pods -o custom-columns=LABELS:.metadata.labels | grep -q "app.kubernetes.io/name:$name"; then + break + fi + sleep "$interval" + timeout=$((timeout - interval)) + done + + kubectl wait \ + --namespace "$namespace" \ + --selector "app.kubernetes.io/name=$name" \ + --for=condition=Ready \ + --timeout="''${timeout}s" \ + pods + ''; + }; + + wait-for-port-listen = writeShellApplication { + name = "wait-for-port-listen"; + runtimeInputs = [ iproute2 ]; + text = '' + port=$1 + + function ss-listen-on-port() { + ss \ + --tcp \ + --numeric \ + --listening \ + --no-header \ + --ipv4 \ + src ":$port" + } + + tries=15 # 3 seconds + interval=0.2 + + while [[ "$tries" -gt 0 ]]; do + if [[ -n $(ss-listen-on-port) ]]; then + exit 0 + fi + sleep "$interval" + tries=$((tries - 1)) + done + + echo "Port $port did not reach state LISTENING" >&2 + exit 1 + ''; + }; + + # write-coordinator-yaml prints a Nunki Coordinator deployment including the default policy. + # It's intended for two purposes: (1) releasing a portable coordinator.yaml and (2) updating the embedded policy hash. + write-coordinator-yaml = writeShellApplication { + name = "write-coordinator-policy"; + runtimeInputs = [ + yq-go + genpolicy + ]; + text = '' + imageRef=$1:v${version} + + tmpdir=$(mktemp -d) + trap 'rm -rf $tmpdir' EXIT + + # TODO(burgerdev): consider a dedicated coordinator template instead of the simple one + yq < deployments/simple/coordinator.yml > "$tmpdir/coordinator.yml" \ + "del(.metadata.namespace) | (select(.kind == \"Deployment\") | .spec.template.spec.containers[0].image) = \"$imageRef\"" + + pushd "$tmpdir" >/dev/null + # TODO(burgerdev): this should not be dev, but there are unknown env vars + cp ${genpolicy.settings}/genpolicy-settings.json . + genpolicy < "$tmpdir/coordinator.yml" + popd >/dev/null + ''; + }; +} diff --git a/version.txt b/version.txt new file mode 100644 index 0000000000..2c3b9be017 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +0.2.0-pre \ No newline at end of file