at 25.11-pre 3.0 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.programs.rush; 9 10 indent = 11 lines: 12 lib.pipe lines [ 13 (lib.splitString "\n") 14 (builtins.filter (line: line != "")) 15 (map (line: " " + line)) 16 (builtins.concatStringsSep "\n") 17 ]; 18in 19{ 20 meta.maintainers = pkgs.rush.meta.maintainers; 21 22 options.programs.rush = with lib.types; { 23 enable = lib.mkEnableOption "Restricted User Shell."; 24 25 package = lib.mkPackageOption pkgs "rush" { } // { 26 type = shellPackage; 27 }; 28 29 global = lib.mkOption { 30 type = lines; 31 description = "The `global` statement defines global settings."; 32 default = ""; 33 }; 34 35 rules = lib.mkOption { 36 type = attrsOf lines; 37 default = { }; 38 39 description = '' 40 The rule statement configures a GNU Rush rule. This is a block statement, which means that all 41 statements located between it and the next rule statement (or end of file, whichever occurs first) 42 modify the definition of that rule. 43 ''; 44 }; 45 46 shell = lib.mkOption { 47 readOnly = true; 48 type = either shellPackage path; 49 50 description = '' 51 The resolved shell path that users can inherit to set `rush` as their login shell. 52 This is a convenience option for use in user definitions. Example: 53 `users.users.alice = { inherit (config.programs.rush) shell; ... };` 54 ''; 55 }; 56 57 wrap = lib.mkOption { 58 type = bool; 59 default = config.security.enableWrappers; 60 defaultText = lib.literalExpression "config.security.enableWrappers"; 61 62 description = '' 63 Whether to wrap the `rush` binary with a SUID-enabled wrapper. 64 This is required if {option}`security.enableWrappers` is enabled in your configuration. 65 ''; 66 }; 67 }; 68 69 config = lib.mkIf cfg.enable ( 70 lib.mkMerge [ 71 (lib.mkIf cfg.wrap { 72 security.wrappers.rush = lib.mkDefault { 73 group = "root"; 74 owner = "root"; 75 permissions = "u+rx,g+x,o+x"; 76 setgid = false; 77 setuid = true; 78 source = lib.getExe cfg.package; 79 }; 80 }) 81 82 { 83 programs.rush.shell = if cfg.wrap then config.security.wrapperDir + "/rush" else cfg.package; 84 85 environment = { 86 shells = [ cfg.shell ]; 87 systemPackages = [ cfg.package ]; 88 89 etc."rush.rc".text = 90 lib.pipe 91 [ 92 "# This file was created by the module `programs.rush`;" 93 "rush 2.0" 94 (lib.optionalString (cfg.global != "") "global\n${indent cfg.global}") 95 (lib.optionals (cfg.rules != { }) ( 96 lib.mapAttrsToList (name: content: "rule ${name}\n${indent content}") cfg.rules 97 )) 98 ] 99 [ 100 (lib.flatten) 101 (builtins.filter (line: line != "")) 102 (builtins.concatStringsSep "\n\n") 103 (lib.mkDefault) 104 ]; 105 }; 106 } 107 ] 108 ); 109}