# github.com/brianmcgee has lots of great ideas for going above and beyond for this { description = "Greg's homepage"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; flake-parts.url = "github:hercules-ci/flake-parts"; process-compose.url = "github:Platonic-Systems/process-compose-flake"; hooks.url = "github:cachix/git-hooks.nix"; }; outputs = { flake-parts, nixpkgs, ... }@inputs: let lib = nixpkgs.lib; providers = [ "qemu" "virtualbox-iso" "hyperv-iso" ]; distros = import ./distros; # Inserts the distro name into each element in the list insertNames = lib.attrsets.mapAttrsToList ( distro: val: (builtins.map (x: x // { inherit distro; }) val) ) distros; # Flattens all the distros into a single list flat = lib.lists.flatten insertNames; # Combines providers list with flattened list withProviders = lib.attrsets.mapCartesianProduct ({ d, provider }: d // { inherit provider; }) { d = flat; provider = providers; }; active = builtins.filter (x: (x ? eol) && (!x.eol)) withProviders; name = d: "-${d.distro}-${d.arch}-${d.provider}-${d.version}"; distroFile = d: "distros/${d.distro}/${d.version}/${d.arch}.pkrvars.hcl"; cmd = d: '' # This is a workaround for a goofy behavior in CI if [ -e "''${PACKER_CONFIG_DIR}" ]; then find "''${PACKER_CONFIG_DIR}" -name '*_linux_amd64' -exec chmod +x '{}' ";" fi packer init sources packer build -only=${d.provider}.${d.arch} -var-file=${distroFile d}''; in flake-parts.lib.mkFlake { inherit inputs; } { flake = { # Universal things }; systems = [ "x86_64-linux" "aarch64-linux" ]; perSystem = { pkgs, self', system, ... }@inputs': { _module.args.pkgs = import inputs.nixpkgs { inherit system; config.allowUnfree = true; }; devShells.default = pkgs.mkShell { buildInputs = self'.checks.pre-commit.enabledPackages; shellHook = self'.checks.pre-commit.shellHook; packages = (with pkgs; [ vagrant ]) ++ (with self'.packages; [ cache generate shellcheck validate ]) ++ (builtins.map (d: self'.packages."build${name d}") withProviders); # These commands will be shown in the motd that users read # upon entering the shell env = { EFI_DIR = "${pkgs.OVMF.fd}/FV/"; PACKER_CONFIG_DIR = "./packer_config"; STORAGE_URL = "http://s3.thehellings.lan:9000"; }; }; # This is not special, this is just flakes packages = let base = { runtimeInputs = with pkgs; [ cdrtools findutils packer qemu_full vagrant xorriso ]; }; build = d: let vp = x: if x.provider == "qemu" then "libvirt" else if x.provider == "virtualbox-iso" then "virtualbox" else if x.provider == "hyperv-iso" then "hyperv" else "unknown"; in pkgs.writeShellApplication ( base // { name = "build${name d}"; text = '' set -x ${cmd d} -except=upload -var headless=false sources/ vagrant box add --provider ${vp d} ./output/${vp d}/${d.distro}-${d.version}.box --name test_box --force ''; } ); cibuild = d: pkgs.writeShellApplication ( base // { name = "ci${name d}"; text = '' set -x ${cmd d} -except=upload sources/ ''; } ); upload = d: pkgs.writeShellApplication ( base // { name = "upload${name d}"; text = '' set -x ${cmd d} sources/ ''; } ); builds = lib.lists.foldr (d: acc: acc // { "build${name d}" = (build d); }) { } withProviders; uploads = lib.lists.foldr (d: acc: acc // { "upload${name d}" = (upload d); }) { } withProviders; cibuilds = lib.lists.foldr (d: acc: acc // { "ci${name d}" = (cibuild d); }) { } withProviders; qemu_list = builtins.map (d: { buildcmd = (name d); }) ( builtins.filter (x: x.provider == "qemu") active ); vbox_list = builtins.map (d: { buildcmd = (name d); }) ( builtins.filter (x: x.provider == "virtualbox-iso") active ); hyperv_list = builtins.map (d: { distro = distroFile d; }) ( builtins.filter (x: x.provider == "hyperv-iso") active ); in builds // uploads // cibuilds // { continue = ( import ./nix/continue.nix { inherit pkgs qemu_list vbox_list hyperv_list ; } ); cache = pkgs.callPackage (import ./nix/cache.nix) { inherit active distroFile; }; validate = pkgs.callPackage (import ./nix/validate.nix) { }; cache-restore = pkgs.writeShellApplication { name = "cache-restore"; runtimeInputs = with pkgs; [ jq minio-client packer ]; text = builtins.readFile ./cache-restore.sh; }; generate = pkgs.writeShellApplication { name = "generate"; runtimeInputs = with pkgs; [ bash coreutils curl jq pup ]; text = '' shopt -s globstar for vars in distros/**/*.pkrvars.hcl.sh; do bash "./''${vars}" done set -x echo "BUILD=$(date "+%Y.%m.%d.%H")" >> build.env ''; }; shellcheck = pkgs.writeShellApplication { name = "shellcheck"; runtimeInputs = with pkgs; [ shellcheck ]; text = '' scripts=() shopt -s globstar for f in **/*.sh; do scripts+=("$f") done shellcheck -e SC2239 "''${scripts[@]}" ''; }; }; checks = { pre-commit = inputs.hooks.lib.${inputs'.system}.run { src = ./.; hooks = { check-added-large-files.enable = true; check-case-conflicts.enable = true; check-merge-conflicts.enable = true; check-symlinks.enable = true; deadnix.enable = true; end-of-file-fixer.enable = true; fix-byte-order-marker.enable = true; mixed-line-endings.enable = true; nixfmt-rfc-style.enable = true; trim-trailing-whitespace.enable = true; }; }; }; }; }; }