diff options
author | Alyssa Ross <hi@alyssa.is> | 2022-05-31 09:59:33 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2022-05-31 09:59:57 +0000 |
commit | 9ff36293d1e428cd7bf03e8d4b03611b6d361c28 (patch) | |
tree | 1ab51a42b868c55b83f6ccdb80371b9888739dd9 /nixos/modules/programs/tsm-client.nix | |
parent | 1c4fcd0d4b0541e674ee56ace1053e23e562cc80 (diff) | |
parent | ddc3c396a51918043bb0faa6f676abd9562be62c (diff) | |
download | nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.tar nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.tar.gz nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.tar.bz2 nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.tar.lz nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.tar.xz nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.tar.zst nixpkgs-9ff36293d1e428cd7bf03e8d4b03611b6d361c28.zip |
Last good Nixpkgs for Weston+nouveau? archive
I came this commit hash to terwiz[m] on IRC, who is trying to figure out what the last version of Spectrum that worked on their NUC with Nvidia graphics is.
Diffstat (limited to 'nixos/modules/programs/tsm-client.nix')
-rw-r--r-- | nixos/modules/programs/tsm-client.nix | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/nixos/modules/programs/tsm-client.nix b/nixos/modules/programs/tsm-client.nix new file mode 100644 index 00000000000..28db9625387 --- /dev/null +++ b/nixos/modules/programs/tsm-client.nix @@ -0,0 +1,287 @@ +{ config, lib, pkgs, ... }: + +let + + inherit (builtins) length map; + inherit (lib.attrsets) attrNames filterAttrs hasAttr mapAttrs mapAttrsToList optionalAttrs; + inherit (lib.modules) mkDefault mkIf; + inherit (lib.options) literalExpression mkEnableOption mkOption; + inherit (lib.strings) concatStringsSep optionalString toLower; + inherit (lib.types) addCheck attrsOf lines nonEmptyStr nullOr package path port str strMatching submodule; + + # Checks if given list of strings contains unique + # elements when compared without considering case. + # Type: checkIUnique :: [string] -> bool + # Example: checkIUnique ["foo" "Foo"] => false + checkIUnique = lst: + let + lenUniq = l: length (lib.lists.unique l); + in + lenUniq lst == lenUniq (map toLower lst); + + # TSM rejects servername strings longer than 64 chars. + servernameType = strMatching ".{1,64}"; + + serverOptions = { name, config, ... }: { + options.name = mkOption { + type = servernameType; + example = "mainTsmServer"; + description = '' + Local name of the IBM TSM server, + must be uncapitalized and no longer than 64 chars. + The value will be used for the + <literal>server</literal> + directive in <filename>dsm.sys</filename>. + ''; + }; + options.server = mkOption { + type = nonEmptyStr; + example = "tsmserver.company.com"; + description = '' + Host/domain name or IP address of the IBM TSM server. + The value will be used for the + <literal>tcpserveraddress</literal> + directive in <filename>dsm.sys</filename>. + ''; + }; + options.port = mkOption { + type = addCheck port (p: p<=32767); + default = 1500; # official default + description = '' + TCP port of the IBM TSM server. + The value will be used for the + <literal>tcpport</literal> + directive in <filename>dsm.sys</filename>. + TSM does not support ports above 32767. + ''; + }; + options.node = mkOption { + type = nonEmptyStr; + example = "MY-TSM-NODE"; + description = '' + Target node name on the IBM TSM server. + The value will be used for the + <literal>nodename</literal> + directive in <filename>dsm.sys</filename>. + ''; + }; + options.genPasswd = mkEnableOption '' + automatic client password generation. + This option influences the + <literal>passwordaccess</literal> + directive in <filename>dsm.sys</filename>. + The password will be stored in the directory + given by the option <option>passwdDir</option>. + <emphasis>Caution</emphasis>: + If this option is enabled and the server forces + to renew the password (e.g. on first connection), + a random password will be generated and stored + ''; + options.passwdDir = mkOption { + type = path; + example = "/home/alice/tsm-password"; + description = '' + Directory that holds the TSM + node's password information. + The value will be used for the + <literal>passworddir</literal> + directive in <filename>dsm.sys</filename>. + ''; + }; + options.includeExclude = mkOption { + type = lines; + default = ""; + example = '' + exclude.dir /nix/store + include.encrypt /home/.../* + ''; + description = '' + <literal>include.*</literal> and + <literal>exclude.*</literal> directives to be + used when sending files to the IBM TSM server. + The lines will be written into a file that the + <literal>inclexcl</literal> + directive in <filename>dsm.sys</filename> points to. + ''; + }; + options.extraConfig = mkOption { + # TSM option keys are case insensitive; + # we have to ensure there are no keys that + # differ only by upper and lower case. + type = addCheck + (attrsOf (nullOr str)) + (attrs: checkIUnique (attrNames attrs)); + default = {}; + example.compression = "yes"; + example.passwordaccess = null; + description = '' + Additional key-value pairs for the server stanza. + Values must be strings, or <literal>null</literal> + for the key not to be used in the stanza + (e.g. to overrule values generated by other options). + ''; + }; + options.text = mkOption { + type = lines; + example = literalExpression + ''lib.modules.mkAfter "compression no"''; + description = '' + Additional text lines for the server stanza. + This option can be used if certion configuration keys + must be used multiple times or ordered in a certain way + as the <option>extraConfig</option> option can't + control the order of lines in the resulting stanza. + Note that the <literal>server</literal> + line at the beginning of the stanza is + not part of this option's value. + ''; + }; + options.stanza = mkOption { + type = str; + internal = true; + visible = false; + description = "Server stanza text generated from the options."; + }; + config.name = mkDefault name; + # Client system-options file directives are explained here: + # https://www.ibm.com/docs/en/spectrum-protect/8.1.13?topic=commands-processing-options + config.extraConfig = + mapAttrs (lib.trivial.const mkDefault) ( + { + commmethod = "v6tcpip"; # uses v4 or v6, based on dns lookup result + tcpserveraddress = config.server; + tcpport = builtins.toString config.port; + nodename = config.node; + passwordaccess = if config.genPasswd then "generate" else "prompt"; + passworddir = ''"${config.passwdDir}"''; + } // optionalAttrs (config.includeExclude!="") { + inclexcl = ''"${pkgs.writeText "inclexcl.dsm.sys" config.includeExclude}"''; + } + ); + config.text = + let + attrset = filterAttrs (k: v: v!=null) config.extraConfig; + mkLine = k: v: k + optionalString (v!="") " ${v}"; + lines = mapAttrsToList mkLine attrset; + in + concatStringsSep "\n" lines; + config.stanza = '' + server ${config.name} + ${config.text} + ''; + }; + + options.programs.tsmClient = { + enable = mkEnableOption '' + IBM Spectrum Protect (Tivoli Storage Manager, TSM) + client command line applications with a + client system-options file "dsm.sys" + ''; + servers = mkOption { + type = attrsOf (submodule [ serverOptions ]); + default = {}; + example.mainTsmServer = { + server = "tsmserver.company.com"; + node = "MY-TSM-NODE"; + extraConfig.compression = "yes"; + }; + description = '' + Server definitions ("stanzas") + for the client system-options file. + ''; + }; + defaultServername = mkOption { + type = nullOr servernameType; + default = null; + example = "mainTsmServer"; + description = '' + If multiple server stanzas are declared with + <option>programs.tsmClient.servers</option>, + this option may be used to name a default + server stanza that IBM TSM uses in the absence of + a user-defined <filename>dsm.opt</filename> file. + This option translates to a + <literal>defaultserver</literal> configuration line. + ''; + }; + dsmSysText = mkOption { + type = lines; + readOnly = true; + description = '' + This configuration key contains the effective text + of the client system-options file "dsm.sys". + It should not be changed, but may be + used to feed the configuration into other + TSM-depending packages used on the system. + ''; + }; + package = mkOption { + type = package; + default = pkgs.tsm-client; + defaultText = literalExpression "pkgs.tsm-client"; + example = literalExpression "pkgs.tsm-client-withGui"; + description = '' + The TSM client derivation to be + added to the system environment. + It will called with <literal>.override</literal> + to add paths to the client system-options file. + ''; + }; + wrappedPackage = mkOption { + type = package; + readOnly = true; + description = '' + The TSM client derivation, wrapped with the path + to the client system-options file "dsm.sys". + This option is to provide the effective derivation + for other modules that want to call TSM executables. + ''; + }; + }; + + cfg = config.programs.tsmClient; + + assertions = [ + { + assertion = checkIUnique (mapAttrsToList (k: v: v.name) cfg.servers); + message = '' + TSM servernames contain duplicate name + (note that case doesn't matter!) + ''; + } + { + assertion = (cfg.defaultServername!=null)->(hasAttr cfg.defaultServername cfg.servers); + message = "TSM defaultServername not found in list of servers"; + } + ]; + + dsmSysText = '' + **** IBM Spectrum Protect (Tivoli Storage Manager) + **** client system-options file "dsm.sys". + **** Do not edit! + **** This file is generated by NixOS configuration. + + ${optionalString (cfg.defaultServername!=null) "defaultserver ${cfg.defaultServername}"} + + ${concatStringsSep "\n" (mapAttrsToList (k: v: v.stanza) cfg.servers)} + ''; + +in + +{ + + inherit options; + + config = mkIf cfg.enable { + inherit assertions; + programs.tsmClient.dsmSysText = dsmSysText; + programs.tsmClient.wrappedPackage = cfg.package.override rec { + dsmSysCli = pkgs.writeText "dsm.sys" cfg.dsmSysText; + dsmSysApi = dsmSysCli; + }; + environment.systemPackages = [ cfg.wrappedPackage ]; + }; + + meta.maintainers = [ lib.maintainers.yarny ]; + +} |