uboot: (firmwareOdroidC2/C4) don't invoke patch tool, use patches = [] instead

https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh#L948
this can do it nicely.

Signed-off-by: Anton Arapov <anton@deadbeef.mx>
This commit is contained in:
Anton Arapov 2021-04-03 12:58:10 +02:00 committed by Alan Daniels
commit 56de2bcd43
30691 changed files with 3076956 additions and 0 deletions

View file

@ -0,0 +1,57 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.cachix-agent;
in {
meta.maintainers = [ lib.maintainers.domenkozar ];
options.services.cachix-agent = {
enable = mkEnableOption "Cachix Deploy Agent: https://docs.cachix.org/deploy/";
name = mkOption {
type = types.str;
description = "Agent name, usually same as the hostname";
default = config.networking.hostName;
defaultText = "config.networking.hostName";
};
profile = mkOption {
type = types.nullOr types.str;
default = null;
description = "Profile name, defaults to 'system' (NixOS).";
};
package = mkOption {
type = types.package;
default = pkgs.cachix;
defaultText = literalExpression "pkgs.cachix";
description = "Cachix Client package to use.";
};
credentialsFile = mkOption {
type = types.path;
default = "/etc/cachix-agent.token";
description = ''
Required file that needs to contain CACHIX_AGENT_TOKEN=...
'';
};
};
config = mkIf cfg.enable {
systemd.services.cachix-agent = {
description = "Cachix Deploy Agent";
after = ["network-online.target"];
path = [ config.nix.package ];
wantedBy = [ "multi-user.target" ];
# don't restart while changing
reloadIfChanged = true;
serviceConfig = {
Restart = "on-failure";
EnvironmentFile = cfg.credentialsFile;
ExecStart = "${cfg.package}/bin/cachix deploy agent ${cfg.name} ${if cfg.profile != null then profile else ""}";
};
};
};
}

View file

@ -0,0 +1,194 @@
{ config, lib, pkgs, ... }:
with lib;
let cfg = config.services.cloud-init;
path = with pkgs; [
cloud-init
iproute2
nettools
openssh
shadow
util-linux
] ++ optional cfg.btrfs.enable btrfs-progs
++ optional cfg.ext4.enable e2fsprogs
;
in
{
options = {
services.cloud-init = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable the cloud-init service. This services reads
configuration metadata in a cloud environment and configures
the machine according to this metadata.
This configuration is not completely compatible with the
NixOS way of doing configuration, as configuration done by
cloud-init might be overriden by a subsequent nixos-rebuild
call. However, some parts of cloud-init fall outside of
NixOS's responsibility, like filesystem resizing and ssh
public key provisioning, and cloud-init is useful for that
parts. Thus, be wary that using cloud-init in NixOS might
come as some cost.
'';
};
btrfs.enable = mkOption {
type = types.bool;
default = false;
description = ''
Allow the cloud-init service to operate `btrfs` filesystem.
'';
};
ext4.enable = mkOption {
type = types.bool;
default = true;
description = ''
Allow the cloud-init service to operate `ext4` filesystem.
'';
};
network.enable = mkOption {
type = types.bool;
default = false;
description = ''
Allow the cloud-init service to configure network interfaces
through systemd-networkd.
'';
};
config = mkOption {
type = types.str;
default = ''
system_info:
distro: nixos
network:
renderers: [ 'networkd' ]
users:
- root
disable_root: false
preserve_hostname: false
cloud_init_modules:
- migrator
- seed_random
- bootcmd
- write-files
- growpart
- resizefs
- update_etc_hosts
- ca-certs
- rsyslog
- users-groups
cloud_config_modules:
- disk_setup
- mounts
- ssh-import-id
- set-passwords
- timezone
- disable-ec2-metadata
- runcmd
- ssh
cloud_final_modules:
- rightscale_userdata
- scripts-vendor
- scripts-per-once
- scripts-per-boot
- scripts-per-instance
- scripts-user
- ssh-authkey-fingerprints
- keys-to-console
- phone-home
- final-message
- power-state-change
'';
description = "cloud-init configuration.";
};
};
};
config = mkIf cfg.enable {
environment.etc."cloud/cloud.cfg".text = cfg.config;
systemd.network.enable = cfg.network.enable;
systemd.services.cloud-init-local =
{ description = "Initial cloud-init job (pre-networking)";
wantedBy = [ "multi-user.target" ];
before = ["systemd-networkd.service"];
path = path;
serviceConfig =
{ Type = "oneshot";
ExecStart = "${pkgs.cloud-init}/bin/cloud-init init --local";
RemainAfterExit = "yes";
TimeoutSec = "infinity";
StandardOutput = "journal+console";
};
};
systemd.services.cloud-init =
{ description = "Initial cloud-init job (metadata service crawler)";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" "cloud-init-local.service"
"sshd.service" "sshd-keygen.service" ];
after = [ "network-online.target" "cloud-init-local.service" ];
before = [ "sshd.service" "sshd-keygen.service" ];
requires = [ "network.target"];
path = path;
serviceConfig =
{ Type = "oneshot";
ExecStart = "${pkgs.cloud-init}/bin/cloud-init init";
RemainAfterExit = "yes";
TimeoutSec = "infinity";
StandardOutput = "journal+console";
};
};
systemd.services.cloud-config =
{ description = "Apply the settings specified in cloud-config";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" "syslog.target" "cloud-config.target" ];
path = path;
serviceConfig =
{ Type = "oneshot";
ExecStart = "${pkgs.cloud-init}/bin/cloud-init modules --mode=config";
RemainAfterExit = "yes";
TimeoutSec = "infinity";
StandardOutput = "journal+console";
};
};
systemd.services.cloud-final =
{ description = "Execute cloud user/final scripts";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" "syslog.target" "cloud-config.service" "rc-local.service" ];
requires = [ "cloud-config.target" ];
path = path;
serviceConfig =
{ Type = "oneshot";
ExecStart = "${pkgs.cloud-init}/bin/cloud-init modules --mode=final";
RemainAfterExit = "yes";
TimeoutSec = "infinity";
StandardOutput = "journal+console";
};
};
systemd.targets.cloud-config =
{ description = "Cloud-config availability";
requires = [ "cloud-init-local.service" "cloud-init.service" ];
};
};
}

View file

@ -0,0 +1,139 @@
# D-Bus configuration and system bus daemon.
{ config, lib, options, pkgs, ... }:
with lib;
let
cfg = config.services.dbus;
homeDir = "/run/dbus";
configDir = pkgs.makeDBusConf {
inherit (cfg) apparmor;
suidHelper = "${config.security.wrapperDir}/dbus-daemon-launch-helper";
serviceDirectories = cfg.packages;
};
in
{
###### interface
options = {
services.dbus = {
enable = mkOption {
type = types.bool;
default = false;
internal = true;
description = ''
Whether to start the D-Bus message bus daemon, which is
required by many other system services and applications.
'';
};
packages = mkOption {
type = types.listOf types.path;
default = [ ];
description = ''
Packages whose D-Bus configuration files should be included in
the configuration of the D-Bus system-wide or session-wide
message bus. Specifically, files in the following directories
will be included into their respective DBus configuration paths:
<filename><replaceable>pkg</replaceable>/etc/dbus-1/system.d</filename>
<filename><replaceable>pkg</replaceable>/share/dbus-1/system.d</filename>
<filename><replaceable>pkg</replaceable>/share/dbus-1/system-services</filename>
<filename><replaceable>pkg</replaceable>/etc/dbus-1/session.d</filename>
<filename><replaceable>pkg</replaceable>/share/dbus-1/session.d</filename>
<filename><replaceable>pkg</replaceable>/share/dbus-1/services</filename>
'';
};
apparmor = mkOption {
type = types.enum [ "enabled" "disabled" "required" ];
description = ''
AppArmor mode for dbus.
<literal>enabled</literal> enables mediation when it's
supported in the kernel, <literal>disabled</literal>
always disables AppArmor even with kernel support, and
<literal>required</literal> fails when AppArmor was not found
in the kernel.
'';
default = "disabled";
};
socketActivated = mkOption {
type = types.nullOr types.bool;
default = null;
visible = false;
description = ''
Removed option, do not use.
'';
};
};
};
###### implementation
config = mkIf cfg.enable {
warnings = optional (cfg.socketActivated != null) (
let
files = showFiles options.services.dbus.socketActivated.files;
in
"The option 'services.dbus.socketActivated' in ${files} no longer has"
+ " any effect and can be safely removed: the user D-Bus session is"
+ " now always socket activated."
);
environment.systemPackages = [ pkgs.dbus.daemon pkgs.dbus ];
environment.etc."dbus-1".source = configDir;
users.users.messagebus = {
uid = config.ids.uids.messagebus;
description = "D-Bus system message bus daemon user";
home = homeDir;
group = "messagebus";
};
users.groups.messagebus.gid = config.ids.gids.messagebus;
systemd.packages = [ pkgs.dbus.daemon ];
security.wrappers.dbus-daemon-launch-helper = {
source = "${pkgs.dbus.daemon}/libexec/dbus-daemon-launch-helper";
owner = "root";
group = "messagebus";
setuid = true;
setgid = false;
permissions = "u+rx,g+rx,o-rx";
};
services.dbus.packages = [
pkgs.dbus.out
config.system.path
];
systemd.services.dbus = {
# Don't restart dbus-daemon. Bad things tend to happen if we do.
reloadIfChanged = true;
restartTriggers = [ configDir ];
environment = { LD_LIBRARY_PATH = config.system.nssModules.path; };
};
systemd.user = {
services.dbus = {
# Don't restart dbus-daemon. Bad things tend to happen if we do.
reloadIfChanged = true;
restartTriggers = [ configDir ];
};
sockets.dbus.wantedBy = [ "sockets.target" ];
};
environment.pathsToLink = [ "/etc/dbus-1" "/share/dbus-1" ];
};
}

View file

@ -0,0 +1,160 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.earlyoom;
inherit (lib)
mkDefault mkEnableOption mkIf mkOption types
mkRemovedOptionModule literalExpression
escapeShellArg concatStringsSep optional optionalString;
in
{
options.services.earlyoom = {
enable = mkEnableOption "Early out of memory killing";
freeMemThreshold = mkOption {
type = types.ints.between 1 100;
default = 10;
description = ''
Minimum available memory (in percent).
If the available memory falls below this threshold (and the analog is true for
<option>freeSwapThreshold</option>) the killing begins.
SIGTERM is sent first to the process that uses the most memory; then, if the available
memory falls below <option>freeMemKillThreshold</option> (and the analog is true for
<option>freeSwapKillThreshold</option>), SIGKILL is sent.
See <link xlink:href="https://github.com/rfjakob/earlyoom#command-line-options">README</link> for details.
'';
};
freeMemKillThreshold = mkOption {
type = types.nullOr (types.ints.between 1 100);
default = null;
description = ''
Minimum available memory (in percent) before sending SIGKILL.
If unset, this defaults to half of <option>freeMemThreshold</option>.
See the description of <xref linkend="opt-services.earlyoom.freeMemThreshold"/>.
'';
};
freeSwapThreshold = mkOption {
type = types.ints.between 1 100;
default = 10;
description = ''
Minimum free swap space (in percent) before sending SIGTERM.
See the description of <xref linkend="opt-services.earlyoom.freeMemThreshold"/>.
'';
};
freeSwapKillThreshold = mkOption {
type = types.nullOr (types.ints.between 1 100);
default = null;
description = ''
Minimum free swap space (in percent) before sending SIGKILL.
If unset, this defaults to half of <option>freeSwapThreshold</option>.
See the description of <xref linkend="opt-services.earlyoom.freeMemThreshold"/>.
'';
};
enableDebugInfo = mkOption {
type = types.bool;
default = false;
description = ''
Enable debugging messages.
'';
};
enableNotifications = mkOption {
type = types.bool;
default = false;
description = ''
Send notifications about killed processes via the system d-bus.
WARNING: enabling this option (while convenient) should *not* be done on a
machine where you do not trust the other users as it allows any other
local user to DoS your session by spamming notifications.
To actually see the notifications in your GUI session, you need to have
<literal>systembus-notify</literal> running as your user, which this
option handles by enabling <option>services.systembus-notify</option>.
See <link xlink:href="https://github.com/rfjakob/earlyoom#notifications">README</link> for details.
'';
};
killHook = mkOption {
type = types.nullOr types.path;
default = null;
example = literalExpression ''
pkgs.writeShellScript "earlyoom-kill-hook" '''
echo "Process $EARLYOOM_NAME ($EARLYOOM_PID) was killed" >> /path/to/log
'''
'';
description = ''
An absolute path to an executable to be run for each process killed.
Some environment variables are available, see
<link xlink:href="https://github.com/rfjakob/earlyoom#notifications">README</link> and
<link xlink:href="https://github.com/rfjakob/earlyoom/blob/master/MANPAGE.md#-n-pathtoscript">the man page</link>
for details.
'';
};
reportInterval = mkOption {
type = types.int;
default = 3600;
example = 0;
description = "Interval (in seconds) at which a memory report is printed (set to 0 to disable).";
};
extraArgs = mkOption {
type = types.listOf types.str;
default = [];
example = [ "-g" "--prefer '(^|/)(java|chromium)$'" ];
description = "Extra command-line arguments to be passed to earlyoom.";
};
};
imports = [
(mkRemovedOptionModule [ "services" "earlyoom" "useKernelOOMKiller" ] ''
This option is deprecated and ignored by earlyoom since 1.2.
'')
(mkRemovedOptionModule [ "services" "earlyoom" "notificationsCommand" ] ''
This option was removed in earlyoom 1.6, but was reimplemented in 1.7
and is available as the new option `services.earlyoom.killHook`.
'')
(mkRemovedOptionModule [ "services" "earlyoom" "ignoreOOMScoreAdjust" ] ''
This option is deprecated and ignored by earlyoom since 1.7.
'')
];
config = mkIf cfg.enable {
services.systembus-notify.enable = mkDefault cfg.enableNotifications;
systemd.services.earlyoom = {
description = "Early OOM Daemon for Linux";
wantedBy = [ "multi-user.target" ];
path = optional cfg.enableNotifications pkgs.dbus;
serviceConfig = {
StandardError = "journal";
ExecStart = concatStringsSep " " ([
"${pkgs.earlyoom}/bin/earlyoom"
("-m ${toString cfg.freeMemThreshold}"
+ optionalString (cfg.freeMemKillThreshold != null) ",${toString cfg.freeMemKillThreshold}")
("-s ${toString cfg.freeSwapThreshold}"
+ optionalString (cfg.freeSwapKillThreshold != null) ",${toString cfg.freeSwapKillThreshold}")
"-r ${toString cfg.reportInterval}"
]
++ optional cfg.enableDebugInfo "-d"
++ optional cfg.enableNotifications "-n"
++ optional (cfg.killHook != null) "-N ${escapeShellArg cfg.killHook}"
++ cfg.extraArgs
);
};
};
};
}

View file

@ -0,0 +1,75 @@
{config, lib, ...}:
let
inherit (lib) mkOption mkIf types length attrNames;
cfg = config.services.kerberos_server;
kerberos = config.krb5.kerberos;
aclEntry = {
options = {
principal = mkOption {
type = types.str;
description = "Which principal the rule applies to";
};
access = mkOption {
type = types.either
(types.listOf (types.enum ["add" "cpw" "delete" "get" "list" "modify"]))
(types.enum ["all"]);
default = "all";
description = "The changes the principal is allowed to make.";
};
target = mkOption {
type = types.str;
default = "*";
description = "The principals that 'access' applies to.";
};
};
};
realm = {
options = {
acl = mkOption {
type = types.listOf (types.submodule aclEntry);
default = [
{ principal = "*/admin"; access = "all"; }
{ principal = "admin"; access = "all"; }
];
description = ''
The privileges granted to a user.
'';
};
};
};
in
{
imports = [
./mit.nix
./heimdal.nix
];
###### interface
options = {
services.kerberos_server = {
enable = lib.mkEnableOption "the kerberos authentification server";
realms = mkOption {
type = types.attrsOf (types.submodule realm);
description = ''
The realm(s) to serve keys for.
'';
};
};
};
###### implementation
config = mkIf cfg.enable {
environment.systemPackages = [ kerberos ];
assertions = [{
assertion = length (attrNames cfg.realms) <= 1;
message = "Only one realm per server is currently supported.";
}];
};
}

View file

@ -0,0 +1,68 @@
{ pkgs, config, lib, ... } :
let
inherit (lib) mkIf concatStringsSep concatMapStrings toList mapAttrs
mapAttrsToList;
cfg = config.services.kerberos_server;
kerberos = config.krb5.kerberos;
stateDir = "/var/heimdal";
aclFiles = mapAttrs
(name: {acl, ...}: pkgs.writeText "${name}.acl" (concatMapStrings ((
{principal, access, target, ...} :
"${principal}\t${concatStringsSep "," (toList access)}\t${target}\n"
)) acl)) cfg.realms;
kdcConfigs = mapAttrsToList (name: value: ''
database = {
dbname = ${stateDir}/heimdal
acl_file = ${value}
}
'') aclFiles;
kdcConfFile = pkgs.writeText "kdc.conf" ''
[kdc]
${concatStringsSep "\n" kdcConfigs}
'';
in
{
# No documentation about correct triggers, so guessing at them.
config = mkIf (cfg.enable && kerberos == pkgs.heimdal) {
systemd.services.kadmind = {
description = "Kerberos Administration Daemon";
wantedBy = [ "multi-user.target" ];
preStart = ''
mkdir -m 0755 -p ${stateDir}
'';
serviceConfig.ExecStart =
"${kerberos}/libexec/heimdal/kadmind --config-file=/etc/heimdal-kdc/kdc.conf";
restartTriggers = [ kdcConfFile ];
};
systemd.services.kdc = {
description = "Key Distribution Center daemon";
wantedBy = [ "multi-user.target" ];
preStart = ''
mkdir -m 0755 -p ${stateDir}
'';
serviceConfig.ExecStart =
"${kerberos}/libexec/heimdal/kdc --config-file=/etc/heimdal-kdc/kdc.conf";
restartTriggers = [ kdcConfFile ];
};
systemd.services.kpasswdd = {
description = "Kerberos Password Changing daemon";
wantedBy = [ "multi-user.target" ];
preStart = ''
mkdir -m 0755 -p ${stateDir}
'';
serviceConfig.ExecStart = "${kerberos}/libexec/heimdal/kpasswdd";
restartTriggers = [ kdcConfFile ];
};
environment.etc = {
# Can be set via the --config-file option to KDC
"heimdal-kdc/kdc.conf".source = kdcConfFile;
};
};
}

View file

@ -0,0 +1,68 @@
{ pkgs, config, lib, ... } :
let
inherit (lib) mkIf concatStrings concatStringsSep concatMapStrings toList
mapAttrs mapAttrsToList;
cfg = config.services.kerberos_server;
kerberos = config.krb5.kerberos;
stateDir = "/var/lib/krb5kdc";
PIDFile = "/run/kdc.pid";
aclMap = {
add = "a"; cpw = "c"; delete = "d"; get = "i"; list = "l"; modify = "m";
all = "*";
};
aclFiles = mapAttrs
(name: {acl, ...}: (pkgs.writeText "${name}.acl" (concatMapStrings (
{principal, access, target, ...} :
let access_code = map (a: aclMap.${a}) (toList access); in
"${principal} ${concatStrings access_code} ${target}\n"
) acl))) cfg.realms;
kdcConfigs = mapAttrsToList (name: value: ''
${name} = {
acl_file = ${value}
}
'') aclFiles;
kdcConfFile = pkgs.writeText "kdc.conf" ''
[realms]
${concatStringsSep "\n" kdcConfigs}
'';
env = {
# What Debian uses, could possibly link directly to Nix store?
KRB5_KDC_PROFILE = "/etc/krb5kdc/kdc.conf";
};
in
{
config = mkIf (cfg.enable && kerberos == pkgs.krb5Full) {
systemd.services.kadmind = {
description = "Kerberos Administration Daemon";
wantedBy = [ "multi-user.target" ];
preStart = ''
mkdir -m 0755 -p ${stateDir}
'';
serviceConfig.ExecStart = "${kerberos}/bin/kadmind -nofork";
restartTriggers = [ kdcConfFile ];
environment = env;
};
systemd.services.kdc = {
description = "Key Distribution Center daemon";
wantedBy = [ "multi-user.target" ];
preStart = ''
mkdir -m 0755 -p ${stateDir}
'';
serviceConfig = {
Type = "forking";
PIDFile = PIDFile;
ExecStart = "${kerberos}/bin/krb5kdc -P ${PIDFile}";
};
restartTriggers = [ kdcConfFile ];
environment = env;
};
environment.etc = {
"krb5kdc/kdc.conf".source = kdcConfFile;
};
environment.variables = env;
};
}

View file

@ -0,0 +1,35 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.localtimed;
in {
options = {
services.localtimed = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable <literal>localtimed</literal>, a simple daemon for keeping the
system timezone up-to-date based on the current location. It uses
geoclue2 to determine the current location.
'';
};
};
};
config = mkIf cfg.enable {
services.geoclue2.appConfig.localtimed = {
isAllowed = true;
isSystem = true;
};
# Install the polkit rules.
environment.systemPackages = [ pkgs.localtime ];
# Install the systemd unit.
systemd.packages = [ pkgs.localtime ];
systemd.services.localtime.wantedBy = [ "multi-user.target" ];
};
}

View file

@ -0,0 +1,34 @@
# We basically use nscd as a proxy for forwarding nss requests to appropriate
# nss modules, as we run nscd with LD_LIBRARY_PATH set to the directory
# containing all such modules
# Note that we can not use `enable-cache no` As this will actually cause nscd
# to just reject the nss requests it receives, which then causes glibc to
# fallback to trying to handle the request by itself. Which won't work as glibc
# is not aware of the path in which the nss modules live. As a workaround, we
# have `enable-cache yes` with an explicit ttl of 0
server-user nscd
enable-cache passwd yes
positive-time-to-live passwd 0
negative-time-to-live passwd 0
shared passwd yes
enable-cache group yes
positive-time-to-live group 0
negative-time-to-live group 0
shared group yes
enable-cache netgroup yes
positive-time-to-live netgroup 0
negative-time-to-live netgroup 0
shared netgroup yes
enable-cache hosts yes
positive-time-to-live hosts 0
negative-time-to-live hosts 0
shared hosts yes
enable-cache services yes
positive-time-to-live services 0
negative-time-to-live services 0
shared services yes

View file

@ -0,0 +1,96 @@
{ config, lib, pkgs, ... }:
with lib;
let
nssModulesPath = config.system.nssModules.path;
cfg = config.services.nscd;
in
{
###### interface
options = {
services.nscd = {
enable = mkOption {
type = types.bool;
default = true;
description = ''
Whether to enable the Name Service Cache Daemon.
Disabling this is strongly discouraged, as this effectively disables NSS Lookups
from all non-glibc NSS modules, including the ones provided by systemd.
'';
};
config = mkOption {
type = types.lines;
default = builtins.readFile ./nscd.conf;
description = "Configuration to use for Name Service Cache Daemon.";
};
package = mkOption {
type = types.package;
default = if pkgs.stdenv.hostPlatform.libc == "glibc"
then pkgs.stdenv.cc.libc.bin
else pkgs.glibc.bin;
defaultText = lib.literalExpression ''
if pkgs.stdenv.hostPlatform.libc == "glibc"
then pkgs.stdenv.cc.libc.bin
else pkgs.glibc.bin;
'';
description = "package containing the nscd binary to be used by the service";
};
};
};
###### implementation
config = mkIf cfg.enable {
environment.etc."nscd.conf".text = cfg.config;
systemd.services.nscd =
{ description = "Name Service Cache Daemon";
before = [ "nss-lookup.target" "nss-user-lookup.target" ];
wants = [ "nss-lookup.target" "nss-user-lookup.target" ];
wantedBy = [ "multi-user.target" ];
environment = { LD_LIBRARY_PATH = nssModulesPath; };
restartTriggers = [
config.environment.etc.hosts.source
config.environment.etc."nsswitch.conf".source
config.environment.etc."nscd.conf".source
];
# We use DynamicUser because in default configurations nscd doesn't
# create any files that need to survive restarts. However, in some
# configurations, nscd needs to be started as root; it will drop
# privileges after all the NSS modules have read their configuration
# files. So prefix the ExecStart command with "!" to prevent systemd
# from dropping privileges early. See ExecStart in systemd.service(5).
serviceConfig =
{ ExecStart = "!@${cfg.package}/bin/nscd nscd";
Type = "forking";
DynamicUser = true;
RuntimeDirectory = "nscd";
PIDFile = "/run/nscd/nscd.pid";
Restart = "always";
ExecReload =
[ "${cfg.package}/bin/nscd --invalidate passwd"
"${cfg.package}/bin/nscd --invalidate group"
"${cfg.package}/bin/nscd --invalidate hosts"
];
};
};
};
}

View file

@ -0,0 +1,62 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.saslauthd;
in
{
###### interface
options = {
services.saslauthd = {
enable = mkEnableOption "saslauthd, the Cyrus SASL authentication daemon";
package = mkOption {
default = pkgs.cyrus_sasl.bin;
defaultText = literalExpression "pkgs.cyrus_sasl.bin";
type = types.package;
description = "Cyrus SASL package to use.";
};
mechanism = mkOption {
type = types.str;
default = "pam";
description = "Auth mechanism to use";
};
config = mkOption {
type = types.lines;
default = "";
description = "Configuration to use for Cyrus SASL authentication daemon.";
};
};
};
###### implementation
config = mkIf cfg.enable {
systemd.services.saslauthd = {
description = "Cyrus SASL authentication daemon";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "@${cfg.package}/sbin/saslauthd saslauthd -a ${cfg.mechanism} -O ${pkgs.writeText "saslauthd.conf" cfg.config}";
Type = "forking";
PIDFile = "/run/saslauthd/saslauthd.pid";
Restart = "always";
};
};
};
}

View file

@ -0,0 +1,173 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.self-deploy;
workingDirectory = "/var/lib/nixos-self-deploy";
repositoryDirectory = "${workingDirectory}/repo";
outPath = "${workingDirectory}/system";
gitWithRepo = "git -C ${repositoryDirectory}";
renderNixArgs = args:
let
toArg = key: value:
if builtins.isString value
then " --argstr ${lib.escapeShellArg key} ${lib.escapeShellArg value}"
else " --arg ${lib.escapeShellArg key} ${lib.escapeShellArg (toString value)}";
in
lib.concatStrings (lib.mapAttrsToList toArg args);
isPathType = x: lib.strings.isCoercibleToString x && builtins.substring 0 1 (toString x) == "/";
in
{
options.services.self-deploy = {
enable = lib.mkEnableOption "self-deploy";
nixFile = lib.mkOption {
type = lib.types.path;
default = "/default.nix";
description = ''
Path to nix file in repository. Leading '/' refers to root of
git repository.
'';
};
nixAttribute = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
Attribute of `nixFile` that builds the current system.
'';
};
nixArgs = lib.mkOption {
type = lib.types.attrs;
default = { };
description = ''
Arguments to `nix-build` passed as `--argstr` or `--arg` depending on
the type.
'';
};
switchCommand = lib.mkOption {
type = lib.types.enum [ "boot" "switch" "dry-activate" "test" ];
default = "switch";
description = ''
The `switch-to-configuration` subcommand used.
'';
};
repository = lib.mkOption {
type = with lib.types; oneOf [ path str ];
description = ''
The repository to fetch from. Must be properly formatted for git.
If this value is set to a path (must begin with `/`) then it's
assumed that the repository is local and the resulting service
won't wait for the network to be up.
If the repository will be fetched over SSH, you must add an
entry to `programs.ssh.knownHosts` for the SSH host for the fetch
to be successful.
'';
};
sshKeyFile = lib.mkOption {
type = with lib.types; nullOr path;
default = null;
description = ''
Path to SSH private key used to fetch private repositories over
SSH.
'';
};
branch = lib.mkOption {
type = lib.types.str;
default = "master";
description = ''
Branch to track
Technically speaking any ref can be specified here, as this is
passed directly to a `git fetch`, but for the use-case of
continuous deployment you're likely to want to specify a branch.
'';
};
startAt = lib.mkOption {
type = with lib.types; either str (listOf str);
default = "hourly";
description = ''
The schedule on which to run the `self-deploy` service. Format
specified by `systemd.time 7`.
This value can also be a list of `systemd.time 7` formatted
strings, in which case the service will be started on multiple
schedules.
'';
};
};
config = lib.mkIf cfg.enable {
systemd.services.self-deploy = {
inherit (cfg) startAt;
wantedBy = [ "multi-user.target" ];
requires = lib.mkIf (!(isPathType cfg.repository)) [ "network-online.target" ];
environment.GIT_SSH_COMMAND = lib.mkIf (!(isNull cfg.sshKeyFile))
"${pkgs.openssh}/bin/ssh -i ${lib.escapeShellArg cfg.sshKeyFile}";
restartIfChanged = false;
path = with pkgs; [
git
nix
] ++ lib.optionals (cfg.switchCommand == "boot") [ systemd ];
script = ''
if [ ! -e ${repositoryDirectory} ]; then
mkdir --parents ${repositoryDirectory}
git init ${repositoryDirectory}
fi
${gitWithRepo} fetch ${lib.escapeShellArg cfg.repository} ${lib.escapeShellArg cfg.branch}
${gitWithRepo} checkout FETCH_HEAD
nix-build${renderNixArgs cfg.nixArgs} ${lib.cli.toGNUCommandLineShell { } {
attr = cfg.nixAttribute;
out-link = outPath;
}} ${lib.escapeShellArg "${repositoryDirectory}${cfg.nixFile}"}
${lib.optionalString (cfg.switchCommand != "test")
"nix-env --profile /nix/var/nix/profiles/system --set ${outPath}"}
${outPath}/bin/switch-to-configuration ${cfg.switchCommand}
rm ${outPath}
${gitWithRepo} gc --prune=all
${lib.optionalString (cfg.switchCommand == "boot") "systemctl reboot"}
'';
};
};
}

View file

@ -0,0 +1,27 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.systembus-notify;
inherit (lib) mkEnableOption mkIf;
in
{
options.services.systembus-notify = {
enable = mkEnableOption ''
System bus notification support
WARNING: enabling this option (while convenient) should *not* be done on a
machine where you do not trust the other users as it allows any other
local user to DoS your session by spamming notifications.
'';
};
config = mkIf cfg.enable {
systemd = {
packages = with pkgs; [ systembus-notify ];
user.services.systembus-notify.wantedBy = [ "graphical-session.target" ];
};
};
}

View file

@ -0,0 +1,60 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.uptimed;
stateDir = "/var/lib/uptimed";
in
{
options = {
services.uptimed = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable <literal>uptimed</literal>, allowing you to track
your highest uptimes.
'';
};
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.uptimed ];
users.users.uptimed = {
description = "Uptimed daemon user";
home = stateDir;
uid = config.ids.uids.uptimed;
group = "uptimed";
};
users.groups.uptimed = {};
systemd.services.uptimed = {
unitConfig.Documentation = "man:uptimed(8) man:uprecords(1)";
description = "uptimed service";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Restart = "on-failure";
User = "uptimed";
Nice = 19;
IOSchedulingClass = "idle";
PrivateTmp = "yes";
PrivateNetwork = "yes";
NoNewPrivileges = "yes";
StateDirectory = [ "uptimed" ];
InaccessibleDirectories = "/home";
ExecStart = "${pkgs.uptimed}/sbin/uptimed -f -p ${stateDir}/pid";
};
preStart = ''
if ! test -f ${stateDir}/bootid ; then
${pkgs.uptimed}/sbin/uptimed -b
fi
'';
};
};
}