From d733df4484f44fae4dd3731fe36ee5211f327eff Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Sat, 15 Apr 2023 14:42:13 -0500 Subject: [PATCH] first --- .drone.yml | 36 ++++++ .gitignore | 1 + flake.lock | 42 ++++++ flake.nix | 368 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 447 insertions(+) create mode 100644 .drone.yml create mode 100644 .gitignore create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..1613bd8 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,36 @@ +--- +kind: secret +name: docker_username +get: + path: docker + name: username +--- +kind: secret +name: docker_password +get: + path: docker + name: password +--- +kind: pipeline +type: kubernetes +name: publish +steps: + - name: build + image: docker.io/jcollie/nixos-runner:latest + pull: always + commands: + - nix build .#nixos-runner + - echo -n "${plugin_password}" | podman login --username "${plugin_username}" --password-stdin "${plugin_registry}" + - image=$(podman load --input result | sed -n -e "s/Loaded image:.\\(.*\\)/\\1/p") + - podman images + - podman tag "${image}" "${plugin_registry}/${plugin_repository}:${DRONE_BUILD_NUMBER}-${DRONE_COMMIT_SHA:0:8}" + - podman tag "${image}" "${plugin_registry}/${plugin_repository}:latest" + - podman images + - podman logout "${plugin_registry}" + settings: + registry: docker.io + repository: jcollie/nixos-runner + username: + from_secret: docker_username + password: + from_secret: docker_password diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d6944e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/result* diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..de8bcca --- /dev/null +++ b/flake.lock @@ -0,0 +1,42 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1678901627, + "narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1680213900, + "narHash": "sha256-cIDr5WZIj3EkKyCgj/6j3HBH4Jj1W296z7HTcWj1aMA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e3652e0735fbec227f342712f180f4f21f0594f2", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-unstable", + "type": "indirect" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..12b2c64 --- /dev/null +++ b/flake.nix @@ -0,0 +1,368 @@ +{ + description = "nixos-runner"; + + inputs = { + nixpkgs = { + url = "nixpkgs/nixos-unstable"; + }; + flake-utils = { + url = "github:numtide/flake-utils"; + }; + }; + + outputs = { self, nixpkgs, flake-utils }@inputs: + (flake-utils.lib.eachDefaultSystem + (system: + let + pkgs = import nixpkgs { + inherit system; + }; + lib = pkgs.lib; + in + { + packages = { + nixos-runner = + let + bundleNixpkgs = true; + channelName = "nixpkgs"; + channelURL = "https://nixos.org/channels/nixos-unstable"; + defaultPkgs = [ + pkgs.bashInteractive + pkgs.coreutils-full + pkgs.gawk + pkgs.git + pkgs.gnugrep + pkgs.gnused + pkgs.nix + pkgs.nodejs-16_x + pkgs.podman + ]; + + flake-registry = null; + + users = { + root = { + uid = 0; + shell = "${pkgs.bashInteractive}/bin/bash"; + home = "/root"; + gid = 0; + groups = [ "root" ]; + description = "System administrator"; + }; + nobody = { + uid = 65534; + shell = "${pkgs.shadow}/bin/nologin"; + home = "/var/empty"; + gid = 65534; + groups = [ "nobody" ]; + description = "Unprivileged account (don't use!)"; + }; + } // lib.listToAttrs ( + map + ( + n: { + name = "nixbld${toString n}"; + value = { + uid = 30000 + n; + gid = 30000; + groups = [ "nixbld" ]; + description = "Nix build user ${toString n}"; + }; + } + ) + (lib.lists.range 1 32) + ); + + groups = { + root.gid = 0; + nixbld.gid = 30000; + nobody.gid = 65534; + }; + + userToPasswd = ( + k: + { uid + , gid ? 65534 + , home ? "/var/empty" + , description ? "" + , shell ? "/bin/false" + , groups ? [ ] + }: "${k}:x:${toString uid}:${toString gid}:${description}:${home}:${shell}" + ); + + passwdContents = ( + lib.concatStringsSep "\n" + (lib.attrValues (lib.mapAttrs userToPasswd users)) + ); + + userToShadow = k: { ... }: "${k}:!:1::::::"; + + shadowContents = ( + lib.concatStringsSep "\n" + (lib.attrValues (lib.mapAttrs userToShadow users)) + ); + + groupMemberMap = ( + let + # Create a flat list of user/group mappings + mappings = ( + builtins.foldl' + ( + acc: user: + let + groups = users.${user}.groups or [ ]; + in + acc ++ map + (group: { + inherit user group; + }) + groups + ) + [ ] + (lib.attrNames users) + ); + in + ( + builtins.foldl' + ( + acc: v: acc // { + ${v.group} = acc.${v.group} or [ ] ++ [ v.user ]; + } + ) + { } + mappings) + ); + + groupToGroup = k: { gid }: + let + members = groupMemberMap.${k} or [ ]; + in + "${k}:x:${toString gid}:${lib.concatStringsSep "," members}"; + + groupContents = ( + lib.concatStringsSep "\n" + (lib.attrValues (lib.mapAttrs groupToGroup groups)) + ); + + defaultNixConf = { + sandbox = "false"; + build-users-group = "nixbld"; + trusted-public-keys = [ + "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" + ]; + experimental-features = [ + "nix-command" + "flakes" + ]; + }; + + nixConfContents = (lib.concatStringsSep "\n" (lib.mapAttrsFlatten + (n: v: + let + vStr = if builtins.isList v then lib.concatStringsSep " " v else v; + in + "${n} = ${vStr}") + defaultNixConf)) + "\n"; + + containerSettings = '' + [engine] + init_path = "${pkgs.catatonit}/bin/catatonit" + helper_binaries_dir = [ "${pkgs.podman}/libexec/podman" ] + + [network] + cni_plugin_dirs = [ "${pkgs.cni-plugins}/bin" ] + network_backend = "netavark" + ''; + + containerStorage = '' + [storage] + driver = "overlay" + graphroot = "/var/lib/containers/storage" + runroot = "/run/containers/storage" + ''; + + containerRegistries = '' + [registries] + [registries.block] + registries = [ ] + + [registries.insecure] + registries = [ ] + + [registries.search] + registries = [ "docker.io", "quay.io" ] + ''; + + containerPolicy = builtins.toJSON { + default = [ + { + type = "insecureAcceptAnything"; + } + ]; + transports = { + docker-daemon = { + "" = [ + { + type = "insecureAcceptAnything"; + } + ]; + }; + }; + }; + + baseSystem = + let + nixpkgs = pkgs.path; + channel = pkgs.runCommand "channel-nixos" { inherit bundleNixpkgs; } '' + mkdir $out + if [ "$bundleNixpkgs" ]; then + ln -s ${nixpkgs} $out/nixpkgs + echo "[]" > $out/manifest.nix + fi + ''; + rootEnv = pkgs.buildPackages.buildEnv { + name = "root-profile-env"; + paths = defaultPkgs; + }; + manifest = pkgs.buildPackages.runCommand "manifest.nix" { } '' + cat > $out < $out/etc/passwd + echo "" >> $out/etc/passwd + cat $groupContentsPath > $out/etc/group + echo "" >> $out/etc/group + cat $shadowContentsPath > $out/etc/shadow + echo "" >> $out/etc/shadow + mkdir -p $out/usr + ln -s /nix/var/nix/profiles/share $out/usr/ + mkdir -p $out/nix/var/nix/gcroots + mkdir -p $out/tmp + mkdir -p $out/var/tmp + mkdir -p $out/etc/nix + cat $nixConfContentsPath > $out/etc/nix/nix.conf + mkdir -p $out/root + mkdir -p $out/nix/var/nix/profiles/per-user/root + + mkdir -p $out/etc/containers + mkdir -p $out/etc/containers/networks + mkdir -p $out/var/lib/containers/storage + mkdir -p $out/run/containers/storage + cat $containerSettingsPath > $out/etc/containers/containers.conf + cat $containerStoragePath > $out/etc/containers/storage.conf + cat $containerRegistriesPath > $out/etc/containers/registry.conf + cat $containerPolicyPath > $out/etc/containers/policy.json + + 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/root/.nix-profile + ln -s ${channel} $out/nix/var/nix/profiles/per-user/root/channels-1-link + ln -s $out/nix/var/nix/profiles/per-user/root/channels-1-link $out/nix/var/nix/profiles/per-user/root/channels + mkdir -p $out/root/.nix-defexpr + ln -s $out/nix/var/nix/profiles/per-user/root/channels $out/root/.nix-defexpr/channels + echo "${channelURL} ${channelName}" > $out/root/.nix-channels + mkdir -p $out/bin $out/usr/bin + ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env + ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh + '' + (lib.optionalString (flake-registry != null) '' + nixCacheDir="/root/.cache/nix" + mkdir -p $out$nixCacheDir + globalFlakeRegistryPath="$nixCacheDir/flake-registry.json" + ln -s ${flake-registry}/flake-registry.json $out$globalFlakeRegistryPath + mkdir -p $out/nix/var/nix/gcroots/auto + rootName=$(${pkgs.nix}/bin/nix --extra-experimental-features nix-command hash file --type sha1 --base32 <(echo -n $globalFlakeRegistryPath)) + ln -s $globalFlakeRegistryPath $out/nix/var/nix/gcroots/auto/$rootName + ''); + in + pkgs.dockerTools.buildLayeredImageWithNixDb { + name = "nixos-runner"; + tag = "latest"; + maxLayers = 2; + contents = [ + baseSystem + ] ++ defaultPkgs; + extraCommands = '' + rm -rf nix-support + ln -s /nix/var/nix/profiles nix/var/nix/gcroots/profiles + ''; + fakeRootCommands = '' + chmod 1777 tmp + chmod 1777 var/tmp + ''; + config = { + Cmd = [ "${pkgs.bashInteractive}/bin/bash" ]; + Env = [ + "USER=root" + "PATH=${lib.concatStringsSep ":" [ + "/root/.nix-profile/bin" + "/nix/var/nix/profiles/default/bin" + "/nix/var/nix/profiles/default/sbin" + ]}" + "MANPATH=${lib.concatStringsSep ":" [ + "/root/.nix-profile/share/man" + "/nix/var/nix/profiles/default/share/man" + ]}" + "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" + "GIT_SSL_CAINFO=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" + "NIX_SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" + "NIX_PATH=/nix/var/nix/profiles/per-user/root/channels:/root/.nix-defexpr/channels" + ]; + }; + }; + }; + } + ) + ); +}