types,module,tests: run shellcheck on scripts before running them in NixOS tests

This commit is contained in:
Lily Foster 2023-01-30 15:36:51 -05:00 committed by lassulus
parent 9afae0ba36
commit 0accdf4e20
5 changed files with 38 additions and 25 deletions

View file

@ -1,5 +1,6 @@
{ lib ? import <nixpkgs/lib> { lib ? import <nixpkgs/lib>
, rootMountPoint ? "/mnt" , rootMountPoint ? "/mnt"
, checked ? false
}: }:
let let
types = import ./types { inherit lib rootMountPoint; }; types = import ./types { inherit lib rootMountPoint; };
@ -18,33 +19,27 @@ in
{ {
types = types; types = types;
create = cfg: types.diskoLib.create (eval cfg).config.devices; create = cfg: types.diskoLib.create (eval cfg).config.devices;
createScript = cfg: pkgs: pkgs.writeScript "disko-create" '' createScript = cfg: pkgs: (types.diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-create" ''
#!/usr/bin/env bash
export PATH=${lib.makeBinPath (types.diskoLib.packages (eval cfg).config.devices pkgs)}:$PATH export PATH=${lib.makeBinPath (types.diskoLib.packages (eval cfg).config.devices pkgs)}:$PATH
${types.diskoLib.create (eval cfg).config.devices} ${types.diskoLib.create (eval cfg).config.devices}
''; '';
createScriptNoDeps = cfg: pkgs: pkgs.writeScript "disko-create" '' createScriptNoDeps = cfg: pkgs: (types.diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-create" ''
#!/usr/bin/env bash
${types.diskoLib.create (eval cfg).config.devices} ${types.diskoLib.create (eval cfg).config.devices}
''; '';
mount = cfg: types.diskoLib.mount (eval cfg).config.devices; mount = cfg: types.diskoLib.mount (eval cfg).config.devices;
mountScript = cfg: pkgs: pkgs.writeScript "disko-mount" '' mountScript = cfg: pkgs: (types.diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-mount" ''
#!/usr/bin/env bash
export PATH=${lib.makeBinPath (types.diskoLib.packages (eval cfg).config.devices pkgs)}:$PATH export PATH=${lib.makeBinPath (types.diskoLib.packages (eval cfg).config.devices pkgs)}:$PATH
${types.diskoLib.mount (eval cfg).config.devices} ${types.diskoLib.mount (eval cfg).config.devices}
''; '';
mountScriptNoDeps = cfg: pkgs: pkgs.writeScript "disko-mount" '' mountScriptNoDeps = cfg: pkgs: (types.diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-mount" ''
#!/usr/bin/env bash
${types.diskoLib.mount (eval cfg).config.devices} ${types.diskoLib.mount (eval cfg).config.devices}
''; '';
zapCreateMount = cfg: types.diskoLib.zapCreateMount (eval cfg).config.devices; zapCreateMount = cfg: types.diskoLib.zapCreateMount (eval cfg).config.devices;
zapCreateMountScript = cfg: pkgs: pkgs.writeScript "disko-zap-create-mount" '' zapCreateMountScript = cfg: pkgs: (types.diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-zap-create-mount" ''
#!/usr/bin/env bash
export PATH=${lib.makeBinPath (types.diskoLib.packages (eval cfg).config.devices pkgs)}:$PATH export PATH=${lib.makeBinPath (types.diskoLib.packages (eval cfg).config.devices pkgs)}:$PATH
${types.diskoLib.zapCreateMount (eval cfg).config.devices} ${types.diskoLib.zapCreateMount (eval cfg).config.devices}
''; '';
zapCreateMountScriptNoDeps = cfg: pkgs: pkgs.writeScript "disko-zap-create-mount" '' zapCreateMountScriptNoDeps = cfg: pkgs: (types.diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko-zap-create-mount" ''
#!/usr/bin/env bash
${types.diskoLib.zapCreateMount (eval cfg).config.devices} ${types.diskoLib.zapCreateMount (eval cfg).config.devices}
''; '';
config = cfg: { imports = types.diskoLib.config (eval cfg).config.devices; }; config = cfg: { imports = types.diskoLib.config (eval cfg).config.devices; };

View file

@ -5,6 +5,7 @@ let
rootMountPoint = config.disko.rootMountPoint; rootMountPoint = config.disko.rootMountPoint;
}; };
cfg = config.disko; cfg = config.disko;
checked = cfg.checkScripts;
in in
{ {
options.disko = { options.disko = {
@ -27,26 +28,32 @@ in
type = lib.types.bool; type = lib.types.bool;
default = true; default = true;
}; };
checkScripts = lib.mkOption {
description = ''
Whether to run shellcheck on script outputs
'';
type = lib.types.bool;
default = false;
};
}; };
config = lib.mkIf (cfg.devices.disk != { }) { config = lib.mkIf (cfg.devices.disk != { }) {
system.build.formatScript = pkgs.writers.writeBash "disko-create" '' system.build.formatScript = (types.diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-create" ''
export PATH=${lib.makeBinPath (types.diskoLib.packages cfg.devices pkgs)}:$PATH export PATH=${lib.makeBinPath (types.diskoLib.packages cfg.devices pkgs)}:$PATH
${types.diskoLib.create cfg.devices} ${types.diskoLib.create cfg.devices}
''; '';
system.build.mountScript = pkgs.writers.writeBash "disko-mount" '' system.build.mountScript = (types.diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko-mount" ''
export PATH=${lib.makeBinPath (types.diskoLib.packages cfg.devices pkgs)}:$PATH export PATH=${lib.makeBinPath (types.diskoLib.packages cfg.devices pkgs)}:$PATH
${types.diskoLib.mount cfg.devices} ${types.diskoLib.mount cfg.devices}
''; '';
system.build.disko = pkgs.writers.writeBash "disko" '' system.build.disko = (types.diskoLib.writeCheckedBash { inherit pkgs checked; }) "disko" ''
export PATH=${lib.makeBinPath (types.diskoLib.packages cfg.devices pkgs)}:$PATH export PATH=${lib.makeBinPath (types.diskoLib.packages cfg.devices pkgs)}:$PATH
${types.diskoLib.zapCreateMount cfg.devices} ${types.diskoLib.zapCreateMount cfg.devices}
''; '';
# This is useful to skip copying executables uploading a script to an in-memory installer # This is useful to skip copying executables uploading a script to an in-memory installer
system.build.diskoNoDeps = pkgs.writeScript "disko" '' system.build.diskoNoDeps = (types.diskoLib.writeCheckedBash { inherit pkgs checked; noDeps = true; }) "disko" ''
#!/usr/bin/env bash
${types.diskoLib.zapCreateMount cfg.devices} ${types.diskoLib.zapCreateMount cfg.devices}
''; '';

View file

@ -11,8 +11,8 @@ let
disko-config = import configFile; disko-config = import configFile;
in in
{ {
"${name}-tsp-create" = pkgs.writeScript "create" ((pkgs.callPackage ../. { }).create disko-config); "${name}-tsp-create" = (pkgs.callPackage ../. { checked = true; }).createScript disko-config pkgs;
"${name}-tsp-mount" = pkgs.writeScript "mount" ((pkgs.callPackage ../. { }).mount disko-config); "${name}-tsp-mount" = (pkgs.callPackage ../. { checked = true; }).mountScript disko-config pkgs;
}; };
allTestFilenames = allTestFilenames =

View file

@ -24,10 +24,11 @@
inherit (pkgs) system; inherit (pkgs) system;
}; };
disks = [ "/dev/vda" "/dev/vdb" "/dev/vdc" "/dev/vdd" "/dev/vde" "/dev/vdf" ]; disks = [ "/dev/vda" "/dev/vdb" "/dev/vdc" "/dev/vdd" "/dev/vde" "/dev/vdf" ];
tsp-create = pkgs.writeScript "create" ((pkgs.callPackage ../. { }).create (import disko-config { disks = builtins.tail disks; inherit lib; })); tsp-generator = pkgs.callPackage ../. { checked = true; };
tsp-mount = pkgs.writeScript "mount" ((pkgs.callPackage ../. { }).mount (import disko-config { disks = builtins.tail disks; inherit lib; })); tsp-create = (tsp-generator.createScript (import disko-config { disks = builtins.tail disks; inherit lib; })) pkgs;
tsp-config = (pkgs.callPackage ../. { }).config (import disko-config { inherit disks; inherit lib; }); tsp-mount = (tsp-generator.mountScript (import disko-config { disks = builtins.tail disks; inherit lib; })) pkgs;
tsp-disko = pkgs.writeScript "disko" ((pkgs.callPackage ../. { }).zapCreateMount (import disko-config { disks = builtins.tail disks; inherit lib; })); tsp-disko = (tsp-generator.zapCreateMountScript (import disko-config { disks = builtins.tail disks; inherit lib; })) pkgs;
tsp-config = tsp-generator.config (import disko-config { inherit disks; inherit lib; });
num-disks = builtins.length (lib.attrNames (import disko-config { inherit lib; }).disk); num-disks = builtins.length (lib.attrNames (import disko-config { inherit lib; }).disk);
installed-system = { modulesPath, ... }: { installed-system = { modulesPath, ... }: {
imports = [ imports = [
@ -78,14 +79,15 @@
imports = [ ../module.nix ]; imports = [ ../module.nix ];
disko = { disko = {
enableConfig = false; enableConfig = false;
checkScripts = true;
devices = import disko-config { disks = builtins.tail disks; inherit lib; }; devices = import disko-config { disks = builtins.tail disks; inherit lib; };
}; };
}) })
(lib.optionalAttrs (testMode == "cli") { (lib.optionalAttrs (testMode == "cli") {
imports = [ (modulesPath + "/installer/cd-dvd/channel.nix") ]; imports = [ (modulesPath + "/installer/cd-dvd/channel.nix") ];
system.extraDependencies = [ system.extraDependencies = [
((pkgs.callPackage ../. { }).createScript (import disko-config { disks = builtins.tail disks; inherit lib; }) pkgs) ((pkgs.callPackage ../. { checked = true; }).createScript (import disko-config { disks = builtins.tail disks; inherit lib; }) pkgs)
((pkgs.callPackage ../. { }).mountScript (import disko-config { disks = builtins.tail disks; inherit lib; }) pkgs) ((pkgs.callPackage ../. { checked = true; }).mountScript (import disko-config { disks = builtins.tail disks; inherit lib; }) pkgs)
]; ];
}) })
(modulesPath + "/profiles/base.nix") (modulesPath + "/profiles/base.nix")

View file

@ -193,6 +193,15 @@ rec {
description = "Mount script"; description = "Mount script";
}; };
/* Writer for optionally checking bash scripts before writing them to the store
writeCheckedBash :: AttrSet -> str -> str -> derivation
*/
writeCheckedBash = { pkgs, checked ? false, noDeps ? false }: pkgs.writers.makeScriptWriter {
interpreter = if noDeps then "/usr/bin/env bash" else "${pkgs.bash}/bin/bash";
check = lib.optionalString checked "${pkgs.shellcheck}/bin/shellcheck";
};
/* Takes a disko device specification, returns an attrset with metadata /* Takes a disko device specification, returns an attrset with metadata