mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-07-14 14:10:33 +03:00
Merge remote-tracking branch 'upstream/master' into hardened-stdenv
This commit is contained in:
commit
63c7b4f9a7
701 changed files with 12952 additions and 15151 deletions
|
@ -9,11 +9,36 @@ let
|
|||
|
||||
systemWide = cfg.enable && cfg.systemWide;
|
||||
nonSystemWide = cfg.enable && !cfg.systemWide;
|
||||
hasZeroconf = let z = cfg.zeroconf; in z.publish.enable || z.discovery.enable;
|
||||
|
||||
overriddenPackage = cfg.package.override
|
||||
(optionalAttrs hasZeroconf { zeroconfSupport = true; });
|
||||
binary = "${getBin overriddenPackage}/bin/pulseaudio";
|
||||
binaryNoDaemon = "${binary} --daemonize=no";
|
||||
|
||||
# Forces 32bit pulseaudio and alsaPlugins to be built/supported for apps
|
||||
# using 32bit alsa on 64bit linux.
|
||||
enable32BitAlsaPlugins = cfg.support32Bit && stdenv.isx86_64 && (pkgs_i686.alsaLib != null && pkgs_i686.libpulseaudio != null);
|
||||
|
||||
|
||||
myConfigFile =
|
||||
let
|
||||
addModuleIf = cond: mod: optionalString cond "load-module ${mod}";
|
||||
allAnon = optional cfg.tcp.anonymousClients.allowAll "auth-anonymous=1";
|
||||
ipAnon = let a = cfg.tcp.anonymousClients.allowedIpRanges;
|
||||
in optional (a != []) ''auth-ip-acl=${concatStringsSep ";" a}'';
|
||||
in writeTextFile {
|
||||
name = "default.pa";
|
||||
text = ''
|
||||
.include ${cfg.configFile}
|
||||
${addModuleIf cfg.zeroconf.publish.enable "module-zeroconf-publish"}
|
||||
${addModuleIf cfg.zeroconf.discovery.enable "module-zeroconf-discover"}
|
||||
${addModuleIf cfg.tcp.enable (concatStringsSep " "
|
||||
([ "load-module module-native-protocol-tcp" ] ++ allAnon ++ ipAnon))}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
ids = config.ids;
|
||||
|
||||
uid = ids.uids.pulseaudio;
|
||||
|
@ -26,7 +51,7 @@ let
|
|||
# are built with PulseAudio support (like KDE).
|
||||
clientConf = writeText "client.conf" ''
|
||||
autospawn=${if nonSystemWide then "yes" else "no"}
|
||||
${optionalString nonSystemWide "daemon-binary=${cfg.package.out}/bin/pulseaudio"}
|
||||
${optionalString nonSystemWide "daemon-binary=${binary}"}
|
||||
${cfg.extraClientConf}
|
||||
'';
|
||||
|
||||
|
@ -44,7 +69,7 @@ let
|
|||
hint.description "Default Audio Device (via PulseAudio)"
|
||||
}
|
||||
ctl_type.pulse {
|
||||
libs.native = ${alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ;
|
||||
libs.native = ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ;
|
||||
${lib.optionalString enable32BitAlsaPlugins
|
||||
"libs.32Bit = ${pkgs_i686.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ;"}
|
||||
}
|
||||
|
@ -89,16 +114,25 @@ in {
|
|||
};
|
||||
|
||||
configFile = mkOption {
|
||||
type = types.path;
|
||||
type = types.nullOr types.path;
|
||||
description = ''
|
||||
The path to the configuration the PulseAudio server
|
||||
The path to the default configuration options the PulseAudio server
|
||||
should use. By default, the "default.pa" configuration
|
||||
from the PulseAudio distribution is used.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Literal string to append to <literal>configFile</literal>
|
||||
and the config file generated by the pulseaudio module.
|
||||
'';
|
||||
};
|
||||
|
||||
extraClientConf = mkOption {
|
||||
type = types.str;
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra configuration appended to pulse/client.conf file.
|
||||
|
@ -127,6 +161,31 @@ in {
|
|||
'';
|
||||
};
|
||||
};
|
||||
|
||||
zeroconf = {
|
||||
discovery.enable =
|
||||
mkEnableOption "discovery of pulseaudio sinks in the local network";
|
||||
publish.enable =
|
||||
mkEnableOption "publishing the pulseaudio sink in the local network";
|
||||
};
|
||||
|
||||
# TODO: enable by default?
|
||||
tcp = {
|
||||
enable = mkEnableOption "tcp streaming support";
|
||||
|
||||
anonymousClients = {
|
||||
allowAll = mkEnableOption "all anonymous clients to stream to the server";
|
||||
allowedIpRanges = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = literalExample ''[ "127.0.0.1" "192.168.1.0/24" ]'';
|
||||
description = ''
|
||||
A list of IP subnets that are allowed to stream to the server.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -139,11 +198,11 @@ in {
|
|||
source = clientConf;
|
||||
};
|
||||
|
||||
hardware.pulseaudio.configFile = mkDefault "${getBin cfg.package}/etc/pulse/default.pa";
|
||||
hardware.pulseaudio.configFile = mkDefault "${getBin overriddenPackage}/etc/pulse/default.pa";
|
||||
}
|
||||
|
||||
(mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
environment.systemPackages = [ overriddenPackage ];
|
||||
|
||||
environment.etc = singleton {
|
||||
target = "asound.conf";
|
||||
|
@ -152,12 +211,21 @@ in {
|
|||
|
||||
# Allow PulseAudio to get realtime priority using rtkit.
|
||||
security.rtkit.enable = true;
|
||||
|
||||
})
|
||||
|
||||
(mkIf hasZeroconf {
|
||||
services.avahi.enable = true;
|
||||
})
|
||||
(mkIf cfg.zeroconf.publish.enable {
|
||||
services.avahi.publish.enable = true;
|
||||
services.avahi.publish.userServices = true;
|
||||
})
|
||||
|
||||
(mkIf nonSystemWide {
|
||||
environment.etc = singleton {
|
||||
target = "pulse/default.pa";
|
||||
source = cfg.configFile;
|
||||
source = myConfigFile;
|
||||
};
|
||||
|
||||
systemd.user = {
|
||||
|
@ -167,10 +235,12 @@ in {
|
|||
wantedBy = [ "default.target" ];
|
||||
serviceConfig = {
|
||||
Type = "notify";
|
||||
ExecStart = "${getBin cfg.package}/bin/pulseaudio --daemonize=no";
|
||||
ExecStart = binaryNoDaemon;
|
||||
Restart = "on-failure";
|
||||
RestartSec = "500ms";
|
||||
};
|
||||
environment = { DISPLAY = ":${toString config.services.xserver.display}"; };
|
||||
restartIfChanged = true;
|
||||
};
|
||||
|
||||
sockets.pulseaudio = {
|
||||
|
@ -205,8 +275,9 @@ in {
|
|||
environment.PULSE_RUNTIME_PATH = stateDir;
|
||||
serviceConfig = {
|
||||
Type = "notify";
|
||||
ExecStart = "${getBin cfg.package}/bin/pulseaudio --daemonize=no --log-level=${cfg.daemon.logLevel} --system -n --file=${cfg.configFile}";
|
||||
ExecStart = "${binaryNoDaemon} --log-level=${cfg.daemon.logLevel} --system -n --file=${myConfigFile}";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "500ms";
|
||||
};
|
||||
};
|
||||
})
|
||||
|
|
|
@ -473,7 +473,7 @@
|
|||
./services/web-servers/lighttpd/gitweb.nix
|
||||
./services/web-servers/lighttpd/inginious.nix
|
||||
./services/web-servers/nginx/default.nix
|
||||
./services/web-servers/phpfpm/default.nix
|
||||
./services/web-servers/phpfpm.nix
|
||||
./services/web-servers/shellinabox.nix
|
||||
./services/web-servers/tomcat.nix
|
||||
./services/web-servers/uwsgi.nix
|
||||
|
|
|
@ -100,6 +100,12 @@ in
|
|||
Password used for SMTP auth. (STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE)
|
||||
'';
|
||||
};
|
||||
|
||||
setSendmail = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to set the system sendmail to ssmtp's.";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
@ -122,6 +128,13 @@ in
|
|||
'';
|
||||
|
||||
environment.systemPackages = [pkgs.ssmtp];
|
||||
|
||||
services.mail.sendmailSetuidWrapper = mkIf cfg.setSendmail {
|
||||
program = "sendmail";
|
||||
source = "${pkgs.ssmtp}/bin/sendmail";
|
||||
setuid = false;
|
||||
setgid = false;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ let
|
|||
set -g status-keys ${cfg.keyMode}
|
||||
set -g mode-keys ${cfg.keyMode}
|
||||
|
||||
${if cfg.keyMode == "vi" then ''
|
||||
${if cfg.keyMode == "vi" && cfg.customPaneNavigationAndResize then ''
|
||||
bind h select-pane -L
|
||||
bind j select-pane -D
|
||||
bind k select-pane -U
|
||||
|
@ -86,6 +86,13 @@ in {
|
|||
description = "Use 24 hour clock.";
|
||||
};
|
||||
|
||||
customPaneNavigationAndResize = mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
type = types.bool;
|
||||
description = "Override the hjkl and HJKL bindings for pane navigation and resizing in VI mode.";
|
||||
};
|
||||
|
||||
escapeTime = mkOption {
|
||||
default = 500;
|
||||
example = 0;
|
||||
|
|
|
@ -47,6 +47,7 @@ in {
|
|||
};
|
||||
|
||||
configuration = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = ''
|
||||
The configuration that Mopidy should use.
|
||||
|
|
|
@ -67,33 +67,33 @@ in {
|
|||
};
|
||||
|
||||
packages = mkOption {
|
||||
default = [ pkgs.stdenv pkgs.jre config.programs.ssh.package pkgs.nix ];
|
||||
default = [ pkgs.stdenv pkgs.jre pkgs.git config.programs.ssh.package pkgs.nix ];
|
||||
type = types.listOf types.package;
|
||||
description = ''
|
||||
Packages to add to PATH for the Go.CD server's process.
|
||||
'';
|
||||
};
|
||||
|
||||
heapSize = mkOption {
|
||||
initialJavaHeapSize = mkOption {
|
||||
default = "512m";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Specifies the java heap memory size for the Go.CD server's java process.
|
||||
Specifies the initial java heap memory size for the Go.CD server's java process.
|
||||
'';
|
||||
};
|
||||
|
||||
maxMemory = mkOption {
|
||||
maxJavaHeapMemory = mkOption {
|
||||
default = "1024m";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Specifies the java maximum memory size for the Go.CD server's java process.
|
||||
Specifies the java maximum heap memory size for the Go.CD server's java process.
|
||||
'';
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
default = [
|
||||
"-Xms${cfg.heapSize}"
|
||||
"-Xmx${cfg.maxMemory}"
|
||||
"-Xms${cfg.initialJavaHeapSize}"
|
||||
"-Xmx${cfg.maxJavaHeapMemory}"
|
||||
"-Dcruise.listen.host=${cfg.listenAddress}"
|
||||
"-Duser.language=en"
|
||||
"-Djruby.rack.request.size.threshold.bytes=30000000"
|
||||
|
|
|
@ -51,12 +51,6 @@ in
|
|||
description = "Logging verbosity level.";
|
||||
};
|
||||
|
||||
watchdogTimeout = mkOption {
|
||||
type = types.int;
|
||||
default = 10;
|
||||
description = "Set watchdog timeout value in seconds.";
|
||||
};
|
||||
|
||||
filterWorkers = mkOption {
|
||||
type = types.int;
|
||||
default = 1;
|
||||
|
@ -140,7 +134,6 @@ in
|
|||
"-w ${toString cfg.filterWorkers} " +
|
||||
ops havePluginPath "--pluginpath ${pluginPath} " +
|
||||
"${verbosityFlag} " +
|
||||
"--watchdog-timeout ${toString cfg.watchdogTimeout} " +
|
||||
"-f ${writeText "logstash.conf" ''
|
||||
input {
|
||||
${cfg.inputConfig}
|
||||
|
|
|
@ -75,7 +75,7 @@ in
|
|||
|
||||
bindUnixSockets = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = ["/run/rmilter.sock"];
|
||||
default = ["/run/rmilter/rmilter.sock"];
|
||||
description = ''
|
||||
Unix domain sockets to listen for MTA requests.
|
||||
'';
|
||||
|
@ -114,7 +114,7 @@ in
|
|||
|
||||
servers = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = ["r:/run/rspamd.sock"];
|
||||
default = ["r:/run/rspamd/rspamd.sock"];
|
||||
description = ''
|
||||
Spamd socket definitions.
|
||||
Is server name is prefixed with r: it is rspamd server.
|
||||
|
@ -197,7 +197,7 @@ milter_default_action = accept
|
|||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.rmilter}/bin/rmilter ${optionalString cfg.debug "-d"} -n -c ${rmilterConfigFile}";
|
||||
ExecReload = "/bin/kill -USR1 $MAINPID";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
PermissionsStartOnly = true;
|
||||
|
@ -212,10 +212,10 @@ milter_default_action = accept
|
|||
description = "Rmilter service socket";
|
||||
wantedBy = [ "sockets.target" ];
|
||||
socketConfig = {
|
||||
ListenStream = cfg.bindUnixSockets ++ cfg.bindInetSockets;
|
||||
SocketUser = cfg.user;
|
||||
SocketGroup = cfg.group;
|
||||
SocketMode = "0660";
|
||||
ListenStream = cfg.bindUnixSockets ++ cfg.bindInetSockets;
|
||||
SocketUser = cfg.user;
|
||||
SocketGroup = cfg.group;
|
||||
SocketMode = "0666";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ let
|
|||
|
||||
mkBindSockets = socks: concatStringsSep "\n" (map (each: " bind_socket = \"${each}\"") socks);
|
||||
|
||||
rspamdConf =
|
||||
rspamdConfFile = pkgs.writeText "rspamd.conf"
|
||||
''
|
||||
.include "$CONFDIR/common.conf"
|
||||
|
||||
|
@ -18,8 +18,7 @@ let
|
|||
}
|
||||
|
||||
logging {
|
||||
type = "file";
|
||||
filename = "$LOGDIR/rspamd.log";
|
||||
type = "syslog";
|
||||
.include "$CONFDIR/logging.inc"
|
||||
}
|
||||
|
||||
|
@ -33,7 +32,6 @@ let
|
|||
.include "$CONFDIR/worker-controller.inc"
|
||||
}
|
||||
'';
|
||||
rspamdConfFile = pkgs.writeText "rspamd.conf" rspamdConf;
|
||||
|
||||
in
|
||||
|
||||
|
@ -45,10 +43,7 @@ in
|
|||
|
||||
services.rspamd = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "Whether to run the rspamd daemon.";
|
||||
};
|
||||
enable = mkEnableOption "Whether to run the rspamd daemon.";
|
||||
|
||||
debug = mkOption {
|
||||
default = false;
|
||||
|
@ -58,7 +53,7 @@ in
|
|||
bindSocket = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"/run/rspamd.sock mode=0666 owner=${cfg.user}"
|
||||
"/run/rspamd/rspamd.sock mode=0666 owner=${cfg.user}"
|
||||
];
|
||||
description = ''
|
||||
List of sockets to listen, in format acceptable by rspamd
|
||||
|
@ -97,7 +92,6 @@ in
|
|||
'';
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -128,18 +122,15 @@ in
|
|||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.rspamd}/bin/rspamd ${optionalString cfg.debug "-d"} --user=${cfg.user} --group=${cfg.group} --pid=/run/rspamd.pid -c ${rspamdConfFile} -f";
|
||||
RuntimeDirectory = "/var/lib/rspamd";
|
||||
PermissionsStartOnly = true;
|
||||
Restart = "always";
|
||||
RuntimeDirectory = "rspamd";
|
||||
PrivateTmp = true;
|
||||
};
|
||||
|
||||
preStart = ''
|
||||
${pkgs.coreutils}/bin/mkdir -p /var/{lib,log}/rspamd
|
||||
${pkgs.coreutils}/bin/mkdir -p /var/lib/rspamd
|
||||
${pkgs.coreutils}/bin/chown ${cfg.user}:${cfg.group} /var/lib/rspamd
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -522,10 +522,12 @@ in {
|
|||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = ''
|
||||
mkdir -p /var/lib/matrix-synapse
|
||||
chmod 700 /var/lib/matrix-synapse
|
||||
chown -R matrix-synapse:matrix-synapse /var/lib/matrix-synapse
|
||||
${cfg.package}/bin/homeserver --config-path ${configFile} --keys-directory /var/lib/matrix-synapse/ --generate-keys
|
||||
if ! test -e /var/lib/matrix-synapse; then
|
||||
mkdir -p /var/lib/matrix-synapse
|
||||
chmod 700 /var/lib/matrix-synapse
|
||||
chown -R matrix-synapse:matrix-synapse /var/lib/matrix-synapse
|
||||
${cfg.package}/bin/homeserver --config-path ${configFile} --keys-directory /var/lib/matrix-synapse/ --generate-keys
|
||||
fi
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
|
|
|
@ -72,6 +72,7 @@ let
|
|||
postgresqlConfig = pkgs.writeText "postgres.yaml" cfg.postgresqlConfig;
|
||||
nginxConfig = pkgs.writeText "nginx.yaml" cfg.nginxConfig;
|
||||
mongoConfig = pkgs.writeText "mongo.yaml" cfg.mongoConfig;
|
||||
jmxConfig = pkgs.writeText "jmx.yaml" cfg.jmxConfig;
|
||||
|
||||
etcfiles =
|
||||
[ { source = ddConf;
|
||||
|
@ -94,6 +95,10 @@ let
|
|||
(optional (cfg.mongoConfig != null)
|
||||
{ source = mongoConfig;
|
||||
target = "dd-agent/conf.d/mongo.yaml";
|
||||
}) ++
|
||||
(optional (cfg.jmxConfig != null)
|
||||
{ source = jmxConfig;
|
||||
target = "dd-agent/conf.d/jmx.yaml";
|
||||
});
|
||||
|
||||
in {
|
||||
|
@ -141,6 +146,13 @@ in {
|
|||
default = null;
|
||||
type = types.uniq (types.nullOr types.string);
|
||||
};
|
||||
|
||||
jmxConfig = mkOption {
|
||||
description = "JMX integration configuration";
|
||||
default = null;
|
||||
type = types.uniq (types.nullOr types.string);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
@ -167,7 +179,7 @@ in {
|
|||
Restart = "always";
|
||||
RestartSec = 2;
|
||||
};
|
||||
restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig ];
|
||||
restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig jmxConfig ];
|
||||
};
|
||||
|
||||
systemd.services.dogstatsd = {
|
||||
|
@ -183,7 +195,21 @@ in {
|
|||
Restart = "always";
|
||||
RestartSec = 2;
|
||||
};
|
||||
restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig ];
|
||||
restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig jmxConfig ];
|
||||
};
|
||||
|
||||
systemd.services.dd-jmxfetch = lib.mkIf (cfg.jmxConfig != null) {
|
||||
description = "Datadog JMX Fetcher";
|
||||
path = [ pkgs."dd-agent" pkgs.python pkgs.sysstat pkgs.procps pkgs.jdk ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.dd-agent}/bin/dd-jmxfetch";
|
||||
User = "datadog";
|
||||
Group = "datadog";
|
||||
Restart = "always";
|
||||
RestartSec = 2;
|
||||
};
|
||||
restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig jmxConfig ];
|
||||
};
|
||||
|
||||
environment.etc = etcfiles;
|
||||
|
|
|
@ -101,9 +101,22 @@ let
|
|||
# Perform a reverse-path test to refuse spoofers
|
||||
# For now, we just drop, as the raw table doesn't have a log-refuse yet
|
||||
${optionalString (kernelHasRPFilter && cfg.checkReversePath) ''
|
||||
if ! ip46tables -A PREROUTING -t raw -m rpfilter --invert -j DROP; then
|
||||
echo "<2>failed to initialise rpfilter support" >&2
|
||||
fi
|
||||
# Clean up rpfilter rules
|
||||
ip46tables -t raw -D PREROUTING -j nixos-fw-rpfilter 2> /dev/null || true
|
||||
ip46tables -t raw -F nixos-fw-rpfilter 2> /dev/null || true
|
||||
ip46tables -t raw -N nixos-fw-rpfilter 2> /dev/null || true
|
||||
|
||||
ip46tables -t raw -A nixos-fw-rpfilter -m rpfilter -j RETURN
|
||||
|
||||
# Allows this host to act as a DHCPv4 server
|
||||
iptables -t raw -A nixos-fw-rpfilter -s 0.0.0.0 -d 255.255.255.255 -p udp --sport 68 --dport 67 -j RETURN
|
||||
|
||||
${optionalString cfg.logReversePathDrops ''
|
||||
ip46tables -t raw -A nixos-fw-rpfilter -j LOG --log-level info --log-prefix "rpfilter drop: "
|
||||
''}
|
||||
ip46tables -t raw -A nixos-fw-rpfilter -j DROP
|
||||
|
||||
ip46tables -t raw -A PREROUTING -j nixos-fw-rpfilter
|
||||
''}
|
||||
|
||||
# Accept all traffic on the trusted interfaces.
|
||||
|
@ -188,9 +201,7 @@ let
|
|||
ip46tables -D INPUT -j nixos-fw 2>/dev/null || true
|
||||
|
||||
${optionalString (kernelHasRPFilter && cfg.checkReversePath) ''
|
||||
if ! ip46tables -D PREROUTING -t raw -m rpfilter --invert -j DROP; then
|
||||
echo "<2>failed to stop rpfilter support" >&2
|
||||
fi
|
||||
ip46tables -t raw -D PREROUTING -j nixos-fw-rpfilter 2>/dev/null || true
|
||||
''}
|
||||
|
||||
${cfg.extraStopCommands}
|
||||
|
@ -376,6 +387,16 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
networking.firewall.logReversePathDrops = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description =
|
||||
''
|
||||
Logs dropped packets failing the reverse path filter test if
|
||||
the option networking.firewall.checkReversePath is enabled.
|
||||
'';
|
||||
};
|
||||
|
||||
networking.firewall.connectionTrackingModules = mkOption {
|
||||
default = [ "ftp" ];
|
||||
example = [ "ftp" "irc" "sane" "sip" "tftp" "amanda" "h323" "netbios_sn" "pptp" "snmp" ];
|
||||
|
|
|
@ -114,8 +114,8 @@ in
|
|||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
systemd.services.syncthing = mkIf cfg.systemService
|
||||
header // {
|
||||
systemd.services = mkIf cfg.systemService {
|
||||
syncthing = header // {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = service // {
|
||||
User = cfg.user;
|
||||
|
@ -124,6 +124,7 @@ in
|
|||
ExecStart = "${cfg.package}/bin/syncthing -no-browser -home=${cfg.dataDir}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.services.syncthing =
|
||||
header // {
|
||||
|
|
|
@ -157,6 +157,7 @@ in
|
|||
serviceConfig = {
|
||||
Type = "simple";
|
||||
PIDFile = "/run/tinc.${network}.pid";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
preStart = ''
|
||||
mkdir -p /etc/tinc/${network}/hosts
|
||||
|
|
|
@ -17,6 +17,7 @@ let
|
|||
else cfg.database.port;
|
||||
|
||||
poolName = "tt-rss";
|
||||
phpfpmSocketName = "/var/run/phpfpm/${poolName}.sock";
|
||||
virtualHostName = "tt-rss";
|
||||
|
||||
tt-rss-config = pkgs.writeText "config.php" ''
|
||||
|
@ -448,23 +449,21 @@ let
|
|||
root = "/var/lib/tt-rss";
|
||||
in mkIf cfg.enable {
|
||||
|
||||
services.phpfpm.pools = if cfg.pool == "${poolName}" then {
|
||||
"${poolName}" = {
|
||||
listen = "/var/run/phpfpm/${poolName}.sock";
|
||||
extraConfig = ''
|
||||
listen.owner = nginx
|
||||
listen.group = nginx
|
||||
listen.mode = 0600
|
||||
user = nginx
|
||||
pm = dynamic
|
||||
pm.max_children = 75
|
||||
pm.start_servers = 10
|
||||
pm.min_spare_servers = 5
|
||||
pm.max_spare_servers = 20
|
||||
pm.max_requests = 500
|
||||
catch_workers_output = 1
|
||||
'';
|
||||
};
|
||||
services.phpfpm.poolConfigs = if cfg.pool == "${poolName}" then {
|
||||
"${poolName}" = ''
|
||||
listen = "${phpfpmSocketName}";
|
||||
listen.owner = nginx
|
||||
listen.group = nginx
|
||||
listen.mode = 0600
|
||||
user = nginx
|
||||
pm = dynamic
|
||||
pm.max_children = 75
|
||||
pm.start_servers = 10
|
||||
pm.min_spare_servers = 5
|
||||
pm.max_spare_servers = 20
|
||||
pm.max_requests = 500
|
||||
catch_workers_output = 1
|
||||
'';
|
||||
} else {};
|
||||
|
||||
# TODO: Re-enable after https://github.com/NixOS/nixpkgs/pull/15862 is merged
|
||||
|
@ -486,7 +485,7 @@ let
|
|||
# locations."~ \.php$" = {
|
||||
# extraConfig = ''
|
||||
# fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
# fastcgi_pass unix:${config.services.phpfpm.pools."${cfg.pool}".listen};
|
||||
# fastcgi_pass unix:${phpfpmSocketName};
|
||||
# fastcgi_index index.php;
|
||||
# fastcgi_param SCRIPT_FILENAME ${root}/$fastcgi_script_name;
|
||||
|
||||
|
|
|
@ -63,6 +63,11 @@ in
|
|||
}
|
||||
'';
|
||||
|
||||
systemd.services.lighttpd.preStart = ''
|
||||
mkdir -p /var/cache/cgit
|
||||
chown lighttpd:lighttpd /var/cache/cgit
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -224,12 +224,6 @@ in
|
|||
description = "Lighttpd Web Server";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = ''
|
||||
${if cfg.cgit.enable then ''
|
||||
mkdir -p /var/cache/cgit
|
||||
chown lighttpd:lighttpd /var/cache/cgit
|
||||
'' else ""}
|
||||
'';
|
||||
serviceConfig.ExecStart = "${pkgs.lighttpd}/sbin/lighttpd -D -f ${configFile}";
|
||||
# SIGINT => graceful shutdown
|
||||
serviceConfig.KillSignal = "SIGINT";
|
||||
|
|
|
@ -9,12 +9,6 @@ let
|
|||
|
||||
pidFile = "${stateDir}/phpfpm.pid";
|
||||
|
||||
mkPool = n: p: ''
|
||||
[${n}]
|
||||
listen = ${p.listen}
|
||||
${p.extraConfig}
|
||||
'';
|
||||
|
||||
cfgFile = pkgs.writeText "phpfpm.conf" ''
|
||||
[global]
|
||||
pid = ${pidFile}
|
||||
|
@ -22,7 +16,7 @@ let
|
|||
daemonize = yes
|
||||
${cfg.extraConfig}
|
||||
|
||||
${concatStringsSep "\n" (mapAttrsToList mkPool cfg.pools)}
|
||||
${concatStringsSep "\n" (mapAttrsToList (n: v: "[${n}]\n${v}") cfg.poolConfigs)}
|
||||
'';
|
||||
|
||||
phpIni = pkgs.writeText "php.ini" ''
|
||||
|
@ -67,19 +61,33 @@ in {
|
|||
"Options appended to the PHP configuration file <filename>php.ini</filename>.";
|
||||
};
|
||||
|
||||
pools = mkOption {
|
||||
type = types.attrsOf (types.submodule (import ./pool-options.nix {
|
||||
inherit lib;
|
||||
}));
|
||||
poolConfigs = mkOption {
|
||||
type = types.attrsOf types.lines;
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{ mypool = '''
|
||||
listen = /run/phpfpm/mypool
|
||||
user = nobody
|
||||
pm = dynamic
|
||||
pm.max_children = 75
|
||||
pm.start_servers = 10
|
||||
pm.min_spare_servers = 5
|
||||
pm.max_spare_servers = 20
|
||||
pm.max_requests = 500
|
||||
''';
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
If no pools are defined, the phpfpm service is disabled.
|
||||
A mapping between PHP FPM pool names and their configurations.
|
||||
See the documentation on <literal>php-fpm.conf</literal> for
|
||||
details on configuration directives. If no pools are defined,
|
||||
the phpfpm service is disabled.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.pools != {}) {
|
||||
config = mkIf (cfg.poolConfigs != {}) {
|
||||
|
||||
systemd.services.phpfpm = {
|
||||
wantedBy = [ "multi-user.target" ];
|
|
@ -1,35 +0,0 @@
|
|||
{ lib }:
|
||||
|
||||
with lib; {
|
||||
|
||||
options = {
|
||||
|
||||
listen = mkOption {
|
||||
type = types.str;
|
||||
example = "/path/to/unix/socket";
|
||||
description = ''
|
||||
The address on which to accept FastCGI requests.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
example = ''
|
||||
user = nobody
|
||||
pm = dynamic
|
||||
pm.max_children = 75
|
||||
pm.start_servers = 10
|
||||
pm.min_spare_servers = 5
|
||||
pm.max_spare_servers = 20
|
||||
pm.max_requests = 500
|
||||
'';
|
||||
|
||||
description = ''
|
||||
Extra lines that go into the pool configuration.
|
||||
See the documentation on <literal>php-fpm.conf</literal> for
|
||||
details on configuration directives.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ in {
|
|||
|
||||
environment.gnome3.packageSet = mkOption {
|
||||
default = null;
|
||||
example = literalExample "pkgs.gnome3_18";
|
||||
example = literalExample "pkgs.gnome3_20";
|
||||
description = "Which GNOME 3 package set to use.";
|
||||
apply = p: if p == null then pkgs.gnome3 else p;
|
||||
};
|
||||
|
|
|
@ -148,7 +148,7 @@ in
|
|||
kde5.kde-gtk-config
|
||||
|
||||
pkgs.phonon-backend-gstreamer
|
||||
pkgs.kde5.phonon-backend-gstreamer
|
||||
pkgs.qt5.phonon-backend-gstreamer
|
||||
]
|
||||
|
||||
# Plasma 5.5 and later has a Breeze GTK theme.
|
||||
|
@ -214,7 +214,7 @@ in
|
|||
services.xserver.displayManager.sddm = {
|
||||
theme = "breeze";
|
||||
themes = [
|
||||
kde5.extra-cmake-modules # for the setup-hook
|
||||
kde5.ecm # for the setup-hook
|
||||
kde5.plasma-workspace
|
||||
kde5.breeze-icons
|
||||
(kde5.oxygen-icons or kde5.oxygen-icons5)
|
||||
|
|
|
@ -18,6 +18,7 @@ in
|
|||
./i3.nix
|
||||
./jwm.nix
|
||||
./metacity.nix
|
||||
./mwm.nix
|
||||
./openbox.nix
|
||||
./pekwm.nix
|
||||
./notion.nix
|
||||
|
|
25
nixos/modules/services/x11/window-managers/mwm.nix
Normal file
25
nixos/modules/services/x11/window-managers/mwm.nix
Normal file
|
@ -0,0 +1,25 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.xserver.windowManager.mwm;
|
||||
in
|
||||
{
|
||||
###### interface
|
||||
options = {
|
||||
services.xserver.windowManager.mwm.enable = mkEnableOption "mwm";
|
||||
};
|
||||
|
||||
###### implementation
|
||||
config = mkIf cfg.enable {
|
||||
services.xserver.windowManager.session = singleton {
|
||||
name = "mwm";
|
||||
start = ''
|
||||
${pkgs.motif}/bin/mwm &
|
||||
waitPID=$!
|
||||
'';
|
||||
};
|
||||
environment.systemPackages = [ pkgs.motif ];
|
||||
};
|
||||
}
|
|
@ -14,9 +14,6 @@ let
|
|||
# Map video driver names to driver packages. FIXME: move into card-specific modules.
|
||||
knownVideoDrivers = {
|
||||
virtualbox = { modules = [ kernelPackages.virtualboxGuestAdditions ]; driverName = "vboxvideo"; };
|
||||
ati = { modules = with pkgs.xorg; [ xf86videoati glamoregl ]; };
|
||||
intel = { modules = with pkgs.xorg; [ xf86videointel glamoregl ]; };
|
||||
modesetting = { modules = []; };
|
||||
};
|
||||
|
||||
fontsForXServer =
|
||||
|
@ -512,7 +509,7 @@ in
|
|||
XKB_BINDIR = "${xorg.xkbcomp}/bin"; # Needed for the Xkb extension.
|
||||
XORG_DRI_DRIVER_PATH = "/run/opengl-driver/lib/dri"; # !!! Depends on the driver selected at runtime.
|
||||
LD_LIBRARY_PATH = concatStringsSep ":" (
|
||||
[ "${xorg.libX11.out}/lib" "${xorg.libXext.out}/lib" ]
|
||||
[ "${xorg.libX11.out}/lib" "${xorg.libXext.out}/lib" "/run/opengl-driver/lib" ]
|
||||
++ concatLists (catAttrs "libPath" cfg.drivers));
|
||||
} // cfg.displayManager.job.environment;
|
||||
|
||||
|
|
|
@ -22,6 +22,33 @@ sub atomicSymlink {
|
|||
# current configuration.
|
||||
atomicSymlink $etc, $static or die;
|
||||
|
||||
# Returns 1 if the argument points to the files in /etc/static. That
|
||||
# means either argument is a symlink to a file in /etc/static or a
|
||||
# directory with all children being static.
|
||||
sub isStatic {
|
||||
my $path = shift;
|
||||
|
||||
if (-l $path) {
|
||||
my $target = readlink $path;
|
||||
return substr($target, 0, length "/etc/static/") eq "/etc/static/";
|
||||
}
|
||||
|
||||
if (-d $path) {
|
||||
opendir DIR, "$path" or return 0;
|
||||
my @names = readdir DIR or die;
|
||||
closedir DIR;
|
||||
|
||||
foreach my $name (@names) {
|
||||
next if $name eq "." || $name eq "..";
|
||||
unless (isStatic("$path/$name")) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Remove dangling symlinks that point to /etc/static. These are
|
||||
# configuration files that existed in a previous configuration but not
|
||||
|
@ -63,6 +90,16 @@ sub link {
|
|||
my $target = "/etc/$fn";
|
||||
File::Path::make_path(dirname $target);
|
||||
$created{$fn} = 1;
|
||||
|
||||
# Rename doesn't work if target is directory.
|
||||
if (-l $_ && -d $target) {
|
||||
if (isStatic $target) {
|
||||
rmtree $target or warn;
|
||||
} else {
|
||||
warn "$target directory contains user files. Symlinking may fail.";
|
||||
}
|
||||
}
|
||||
|
||||
if (-e "$_.mode") {
|
||||
my $mode = read_file("$_.mode"); chomp $mode;
|
||||
if ($mode eq "direct-symlink") {
|
||||
|
|
|
@ -6,37 +6,212 @@ let
|
|||
|
||||
# The container's init script, a small wrapper around the regular
|
||||
# NixOS stage-2 init script.
|
||||
containerInit = pkgs.writeScript "container-init"
|
||||
containerInit = (cfg:
|
||||
let
|
||||
renderExtraVeth = (name: cfg:
|
||||
''
|
||||
echo "Bringing ${name} up"
|
||||
ip link set dev ${name} up
|
||||
${optionalString (cfg . "localAddress" or null != null) ''
|
||||
echo "Setting ip for ${name}"
|
||||
ip addr add ${cfg . "localAddress"} dev ${name}
|
||||
''}
|
||||
${optionalString (cfg . "localAddress6" or null != null) ''
|
||||
echo "Setting ip6 for ${name}"
|
||||
ip -6 addr add ${cfg . "localAddress6"} dev ${name}
|
||||
''}
|
||||
${optionalString (cfg . "hostAddress" or null != null) ''
|
||||
echo "Setting route to host for ${name}"
|
||||
ip route add ${cfg . "hostAddress"} dev ${name}
|
||||
''}
|
||||
${optionalString (cfg . "hostAddress6" or null != null) ''
|
||||
echo "Setting route6 to host for ${name}"
|
||||
ip -6 route add ${cfg . "hostAddress6"} dev ${name}
|
||||
''}
|
||||
''
|
||||
);
|
||||
in
|
||||
pkgs.writeScript "container-init"
|
||||
''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
|
||||
# Initialise the container side of the veth pair.
|
||||
if [ "$PRIVATE_NETWORK" = 1 ]; then
|
||||
|
||||
ip link set host0 name eth0
|
||||
ip link set dev eth0 up
|
||||
|
||||
if [ -n "$LOCAL_ADDRESS" ]; then
|
||||
ip addr add $LOCAL_ADDRESS dev eth0
|
||||
fi
|
||||
if [ -n "$LOCAL_ADDRESS6" ]; then
|
||||
ip -6 addr add $LOCAL_ADDRESS6 dev eth0
|
||||
fi
|
||||
if [ -n "$HOST_ADDRESS" ]; then
|
||||
ip route add $HOST_ADDRESS dev eth0
|
||||
ip route add default via $HOST_ADDRESS
|
||||
fi
|
||||
if [ -n "$HOST_ADDRESS6" ]; then
|
||||
ip -6 route add $HOST_ADDRESS6 dev eth0
|
||||
ip -6 route add default via $HOST_ADDRESS6
|
||||
fi
|
||||
|
||||
${concatStringsSep "\n" (mapAttrsToList renderExtraVeth cfg . "extraVeths" or {})}
|
||||
ip a
|
||||
ip r
|
||||
fi
|
||||
|
||||
# Start the regular stage 1 script.
|
||||
exec "$1"
|
||||
''
|
||||
);
|
||||
|
||||
nspawnExtraVethArgs = (name: cfg: "--network-veth-extra=${name}");
|
||||
startScript = (cfg:
|
||||
''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
mkdir -p -m 0755 "$root/etc" "$root/var/lib"
|
||||
mkdir -p -m 0700 "$root/var/lib/private" "$root/root" /run/containers
|
||||
if ! [ -e "$root/etc/os-release" ]; then
|
||||
touch "$root/etc/os-release"
|
||||
fi
|
||||
|
||||
if ! [ -e "$root/etc/machine-id" ]; then
|
||||
touch "$root/etc/machine-id"
|
||||
fi
|
||||
|
||||
mkdir -p -m 0755 \
|
||||
"/nix/var/nix/profiles/per-container/$INSTANCE" \
|
||||
"/nix/var/nix/gcroots/per-container/$INSTANCE"
|
||||
|
||||
cp --remove-destination /etc/resolv.conf "$root/etc/resolv.conf"
|
||||
|
||||
# Initialise the container side of the veth pair.
|
||||
if [ "$PRIVATE_NETWORK" = 1 ]; then
|
||||
|
||||
ip link set host0 name eth0
|
||||
ip link set dev eth0 up
|
||||
|
||||
if [ -n "$LOCAL_ADDRESS" ]; then
|
||||
ip addr add $LOCAL_ADDRESS dev eth0
|
||||
fi
|
||||
if [ -n "$LOCAL_ADDRESS6" ]; then
|
||||
ip -6 addr add $LOCAL_ADDRESS6 dev eth0
|
||||
fi
|
||||
if [ -n "$HOST_ADDRESS" ]; then
|
||||
ip route add $HOST_ADDRESS dev eth0
|
||||
ip route add default via $HOST_ADDRESS
|
||||
fi
|
||||
if [ -n "$HOST_ADDRESS6" ]; then
|
||||
ip -6 route add $HOST_ADDRESS6 dev eth0
|
||||
ip -6 route add default via $HOST_ADDRESS6
|
||||
extraFlags+=" --network-veth"
|
||||
if [ -n "$HOST_BRIDGE" ]; then
|
||||
extraFlags+=" --network-bridge=$HOST_BRIDGE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start the regular stage 1 script, passing the bind-mounted
|
||||
# notification socket from the host to allow the container
|
||||
# systemd to signal readiness to the host systemd.
|
||||
NOTIFY_SOCKET=/var/lib/private/host-notify exec "$1"
|
||||
'';
|
||||
${if cfg . "extraVeths" or null != null then
|
||||
''extraFlags+=" ${concatStringsSep " " (mapAttrsToList nspawnExtraVethArgs cfg . "extraVeths" or {})}"''
|
||||
else
|
||||
''# No extra veth pairs to create''
|
||||
}
|
||||
|
||||
for iface in $INTERFACES; do
|
||||
extraFlags+=" --network-interface=$iface"
|
||||
done
|
||||
|
||||
for iface in $MACVLANS; do
|
||||
extraFlags+=" --network-macvlan=$iface"
|
||||
done
|
||||
|
||||
# If the host is 64-bit and the container is 32-bit, add a
|
||||
# --personality flag.
|
||||
${optionalString (config.nixpkgs.system == "x86_64-linux") ''
|
||||
if [ "$(< ''${SYSTEM_PATH:-/nix/var/nix/profiles/per-container/$INSTANCE/system}/system)" = i686-linux ]; then
|
||||
extraFlags+=" --personality=x86"
|
||||
fi
|
||||
''}
|
||||
|
||||
# Run systemd-nspawn without startup notification (we'll
|
||||
# wait for the container systemd to signal readiness).
|
||||
EXIT_ON_REBOOT=1 \
|
||||
exec ${config.systemd.package}/bin/systemd-nspawn \
|
||||
--keep-unit \
|
||||
-M "$INSTANCE" -D "$root" $extraFlags \
|
||||
$EXTRA_NSPAWN_FLAGS \
|
||||
--notify-ready=yes \
|
||||
--bind-ro=/nix/store \
|
||||
--bind-ro=/nix/var/nix/db \
|
||||
--bind-ro=/nix/var/nix/daemon-socket \
|
||||
--bind="/nix/var/nix/profiles/per-container/$INSTANCE:/nix/var/nix/profiles" \
|
||||
--bind="/nix/var/nix/gcroots/per-container/$INSTANCE:/nix/var/nix/gcroots" \
|
||||
--setenv PRIVATE_NETWORK="$PRIVATE_NETWORK" \
|
||||
--setenv HOST_BRIDGE="$HOST_BRIDGE" \
|
||||
--setenv HOST_ADDRESS="$HOST_ADDRESS" \
|
||||
--setenv LOCAL_ADDRESS="$LOCAL_ADDRESS" \
|
||||
--setenv HOST_ADDRESS6="$HOST_ADDRESS6" \
|
||||
--setenv LOCAL_ADDRESS6="$LOCAL_ADDRESS6" \
|
||||
--setenv PATH="$PATH" \
|
||||
${containerInit cfg} "''${SYSTEM_PATH:-/nix/var/nix/profiles/system}/init"
|
||||
''
|
||||
);
|
||||
|
||||
preStartScript = (cfg:
|
||||
''
|
||||
# Clean up existing machined registration and interfaces.
|
||||
machinectl terminate "$INSTANCE" 2> /dev/null || true
|
||||
|
||||
if [ "$PRIVATE_NETWORK" = 1 ]; then
|
||||
ip link del dev "ve-$INSTANCE" 2> /dev/null || true
|
||||
ip link del dev "vb-$INSTANCE" 2> /dev/null || true
|
||||
fi
|
||||
|
||||
${concatStringsSep "\n" (
|
||||
mapAttrsToList (name: cfg:
|
||||
''ip link del dev ${name} 2> /dev/null || true ''
|
||||
) cfg . "extraVeths" or {}
|
||||
)}
|
||||
''
|
||||
);
|
||||
postStartScript = (cfg:
|
||||
let
|
||||
ipcall = (cfg: ipcmd: variable: attribute:
|
||||
if cfg . attribute or null == null then
|
||||
''
|
||||
if [ -n "${variable}" ]; then
|
||||
${ipcmd} add ${variable} dev $ifaceHost
|
||||
fi
|
||||
''
|
||||
else
|
||||
''${ipcmd} add ${cfg . attribute} dev $ifaceHost''
|
||||
);
|
||||
renderExtraVeth = (name: cfg:
|
||||
if cfg . "hostBridge" or null != null then
|
||||
''
|
||||
# Add ${name} to bridge ${cfg.hostBridge}
|
||||
ip link set dev ${name} master ${cfg.hostBridge} up
|
||||
''
|
||||
else
|
||||
''
|
||||
# Set IPs and routes for ${name}
|
||||
${optionalString (cfg . "hostAddress" or null != null) ''
|
||||
ip addr add ${cfg . "hostAddress"} dev ${name}
|
||||
''}
|
||||
${optionalString (cfg . "hostAddress6" or null != null) ''
|
||||
ip -6 addr add ${cfg . "hostAddress6"} dev ${name}
|
||||
''}
|
||||
${optionalString (cfg . "localAddress" or null != null) ''
|
||||
ip route add ${cfg . "localAddress"} dev ${name}
|
||||
''}
|
||||
${optionalString (cfg . "localAddress6" or null != null) ''
|
||||
ip -6 route add ${cfg . "localAddress6"} dev ${name}
|
||||
''}
|
||||
''
|
||||
);
|
||||
in
|
||||
''
|
||||
if [ "$PRIVATE_NETWORK" = 1 ]; then
|
||||
if [ -z "$HOST_BRIDGE" ]; then
|
||||
ifaceHost=ve-$INSTANCE
|
||||
ip link set dev $ifaceHost up
|
||||
|
||||
${ipcall cfg "ip addr" "$HOST_ADDRESS" "hostAddress"}
|
||||
${ipcall cfg "ip -6 addr" "$HOST_ADDRESS6" "hostAddress6"}
|
||||
${ipcall cfg "ip route" "$LOCAL_ADDRESS" "localAddress"}
|
||||
${ipcall cfg "ip -6 route" "$LOCAL_ADDRESS6" "localAddress6"}
|
||||
fi
|
||||
${concatStringsSep "\n" (mapAttrsToList renderExtraVeth cfg . "extraVeths" or {})}
|
||||
fi
|
||||
|
||||
# Get the leader PID so that we can signal it in
|
||||
# preStop. We can't use machinectl there because D-Bus
|
||||
# might be shutting down. FIXME: in systemd 219 we can
|
||||
# just signal systemd-nspawn to do a clean shutdown.
|
||||
machinectl show "$INSTANCE" | sed 's/Leader=\(.*\)/\1/;t;d' > "/run/containers/$INSTANCE.pid"
|
||||
''
|
||||
);
|
||||
|
||||
system = config.nixpkgs.system;
|
||||
|
||||
|
@ -75,6 +250,63 @@ let
|
|||
|
||||
mkBindFlags = bs: concatMapStrings mkBindFlag (lib.attrValues bs);
|
||||
|
||||
networkOptions = {
|
||||
hostBridge = mkOption {
|
||||
type = types.nullOr types.string;
|
||||
default = null;
|
||||
example = "br0";
|
||||
description = ''
|
||||
Put the host-side of the veth-pair into the named bridge.
|
||||
Only one of hostAddress* or hostBridge can be given.
|
||||
'';
|
||||
};
|
||||
|
||||
hostAddress = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "10.231.136.1";
|
||||
description = ''
|
||||
The IPv4 address assigned to the host interface.
|
||||
(Not used when hostBridge is set.)
|
||||
'';
|
||||
};
|
||||
|
||||
hostAddress6 = mkOption {
|
||||
type = types.nullOr types.string;
|
||||
default = null;
|
||||
example = "fc00::1";
|
||||
description = ''
|
||||
The IPv6 address assigned to the host interface.
|
||||
(Not used when hostBridge is set.)
|
||||
'';
|
||||
};
|
||||
|
||||
localAddress = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "10.231.136.2";
|
||||
description = ''
|
||||
The IPv4 address assigned to the interface in the container.
|
||||
If a hostBridge is used, this should be given with netmask to access
|
||||
the whole network. Otherwise the default netmask is /32 and routing is
|
||||
set up from localAddress to hostAddress and back.
|
||||
'';
|
||||
};
|
||||
|
||||
localAddress6 = mkOption {
|
||||
type = types.nullOr types.string;
|
||||
default = null;
|
||||
example = "fc00::2";
|
||||
description = ''
|
||||
The IPv6 address assigned to the interface in the container.
|
||||
If a hostBridge is used, this should be given with netmask to access
|
||||
the whole network. Otherwise the default netmask is /128 and routing is
|
||||
set up from localAddress6 to hostAddress6 and back.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
@ -135,56 +367,6 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
hostBridge = mkOption {
|
||||
type = types.nullOr types.string;
|
||||
default = null;
|
||||
example = "br0";
|
||||
description = ''
|
||||
Put the host-side of the veth-pair into the named bridge.
|
||||
Only one of hostAddress* or hostBridge can be given.
|
||||
'';
|
||||
};
|
||||
|
||||
hostAddress = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "10.231.136.1";
|
||||
description = ''
|
||||
The IPv4 address assigned to the host interface.
|
||||
(Not used when hostBridge is set.)
|
||||
'';
|
||||
};
|
||||
|
||||
hostAddress6 = mkOption {
|
||||
type = types.nullOr types.string;
|
||||
default = null;
|
||||
example = "fc00::1";
|
||||
description = ''
|
||||
The IPv6 address assigned to the host interface.
|
||||
(Not used when hostBridge is set.)
|
||||
'';
|
||||
};
|
||||
|
||||
localAddress = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "10.231.136.2";
|
||||
description = ''
|
||||
The IPv4 address assigned to <literal>eth0</literal>
|
||||
in the container.
|
||||
'';
|
||||
};
|
||||
|
||||
localAddress6 = mkOption {
|
||||
type = types.nullOr types.string;
|
||||
default = null;
|
||||
example = "fc00::2";
|
||||
description = ''
|
||||
The IPv6 address assigned to <literal>eth0</literal>
|
||||
in the container.
|
||||
'';
|
||||
};
|
||||
|
||||
interfaces = mkOption {
|
||||
type = types.listOf types.string;
|
||||
default = [];
|
||||
|
@ -194,6 +376,15 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
extraVeths = mkOption {
|
||||
type = types.attrsOf types.optionSet;
|
||||
default = {};
|
||||
options = networkOptions;
|
||||
description = ''
|
||||
Extra veth-pairs to be created for the container
|
||||
'';
|
||||
};
|
||||
|
||||
autoStart = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
|
@ -216,7 +407,7 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
};
|
||||
} // networkOptions;
|
||||
|
||||
config = mkMerge
|
||||
[ (mkIf options.config.isDefined {
|
||||
|
@ -274,110 +465,11 @@ in
|
|||
environment.INSTANCE = "%i";
|
||||
environment.root = "/var/lib/containers/%i";
|
||||
|
||||
preStart =
|
||||
''
|
||||
# Clean up existing machined registration and interfaces.
|
||||
machinectl terminate "$INSTANCE" 2> /dev/null || true
|
||||
preStart = preStartScript {};
|
||||
|
||||
if [ "$PRIVATE_NETWORK" = 1 ]; then
|
||||
ip link del dev "ve-$INSTANCE" 2> /dev/null || true
|
||||
ip link del dev "vb-$INSTANCE" 2> /dev/null || true
|
||||
fi
|
||||
'';
|
||||
script = startScript {};
|
||||
|
||||
script =
|
||||
''
|
||||
mkdir -p -m 0755 "$root/etc" "$root/var/lib"
|
||||
mkdir -p -m 0700 "$root/var/lib/private" "$root/root" /run/containers
|
||||
if ! [ -e "$root/etc/os-release" ]; then
|
||||
touch "$root/etc/os-release"
|
||||
fi
|
||||
|
||||
if ! [ -e "$root/etc/machine-id" ]; then
|
||||
touch "$root/etc/machine-id"
|
||||
fi
|
||||
|
||||
mkdir -p -m 0755 \
|
||||
"/nix/var/nix/profiles/per-container/$INSTANCE" \
|
||||
"/nix/var/nix/gcroots/per-container/$INSTANCE"
|
||||
|
||||
cp --remove-destination /etc/resolv.conf "$root/etc/resolv.conf"
|
||||
|
||||
if [ "$PRIVATE_NETWORK" = 1 ]; then
|
||||
extraFlags+=" --network-veth"
|
||||
if [ -n "$HOST_BRIDGE" ]; then
|
||||
extraFlags+=" --network-bridge=$HOST_BRIDGE"
|
||||
fi
|
||||
fi
|
||||
|
||||
for iface in $INTERFACES; do
|
||||
extraFlags+=" --network-interface=$iface"
|
||||
done
|
||||
|
||||
for iface in $MACVLANS; do
|
||||
extraFlags+=" --network-macvlan=$iface"
|
||||
done
|
||||
|
||||
# If the host is 64-bit and the container is 32-bit, add a
|
||||
# --personality flag.
|
||||
${optionalString (config.nixpkgs.system == "x86_64-linux") ''
|
||||
if [ "$(< ''${SYSTEM_PATH:-/nix/var/nix/profiles/per-container/$INSTANCE/system}/system)" = i686-linux ]; then
|
||||
extraFlags+=" --personality=x86"
|
||||
fi
|
||||
''}
|
||||
|
||||
rm -f $root/var/lib/private/host-notify
|
||||
|
||||
# Run systemd-nspawn without startup notification (we'll
|
||||
# wait for the container systemd to signal readiness).
|
||||
EXIT_ON_REBOOT=1 NOTIFY_SOCKET= \
|
||||
exec ${config.systemd.package}/bin/systemd-nspawn \
|
||||
--keep-unit \
|
||||
-M "$INSTANCE" -D "$root" $extraFlags \
|
||||
$EXTRA_NSPAWN_FLAGS \
|
||||
--bind-ro=/nix/store \
|
||||
--bind-ro=/nix/var/nix/db \
|
||||
--bind-ro=/nix/var/nix/daemon-socket \
|
||||
--bind=/run/systemd/notify:/var/lib/private/host-notify \
|
||||
--bind="/nix/var/nix/profiles/per-container/$INSTANCE:/nix/var/nix/profiles" \
|
||||
--bind="/nix/var/nix/gcroots/per-container/$INSTANCE:/nix/var/nix/gcroots" \
|
||||
--setenv PRIVATE_NETWORK="$PRIVATE_NETWORK" \
|
||||
--setenv HOST_BRIDGE="$HOST_BRIDGE" \
|
||||
--setenv HOST_ADDRESS="$HOST_ADDRESS" \
|
||||
--setenv LOCAL_ADDRESS="$LOCAL_ADDRESS" \
|
||||
--setenv HOST_ADDRESS6="$HOST_ADDRESS6" \
|
||||
--setenv LOCAL_ADDRESS6="$LOCAL_ADDRESS6" \
|
||||
--setenv PATH="$PATH" \
|
||||
${containerInit} "''${SYSTEM_PATH:-/nix/var/nix/profiles/system}/init"
|
||||
'';
|
||||
|
||||
postStart =
|
||||
''
|
||||
if [ "$PRIVATE_NETWORK" = 1 ]; then
|
||||
if [ -z "$HOST_BRIDGE" ]; then
|
||||
ifaceHost=ve-$INSTANCE
|
||||
ip link set dev $ifaceHost up
|
||||
if [ -n "$HOST_ADDRESS" ]; then
|
||||
ip addr add $HOST_ADDRESS dev $ifaceHost
|
||||
fi
|
||||
if [ -n "$HOST_ADDRESS6" ]; then
|
||||
ip -6 addr add $HOST_ADDRESS6 dev $ifaceHost
|
||||
fi
|
||||
if [ -n "$LOCAL_ADDRESS" ]; then
|
||||
ip route add $LOCAL_ADDRESS dev $ifaceHost
|
||||
fi
|
||||
if [ -n "$LOCAL_ADDRESS6" ]; then
|
||||
ip -6 route add $LOCAL_ADDRESS6 dev $ifaceHost
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Get the leader PID so that we can signal it in
|
||||
# preStop. We can't use machinectl there because D-Bus
|
||||
# might be shutting down. FIXME: in systemd 219 we can
|
||||
# just signal systemd-nspawn to do a clean shutdown.
|
||||
machinectl show "$INSTANCE" | sed 's/Leader=\(.*\)/\1/;t;d' > "/run/containers/$INSTANCE.pid"
|
||||
'';
|
||||
postStart = postStartScript {};
|
||||
|
||||
preStop =
|
||||
''
|
||||
|
@ -404,8 +496,6 @@ in
|
|||
|
||||
Type = "notify";
|
||||
|
||||
NotifyAccess = "all";
|
||||
|
||||
# Note that on reboot, systemd-nspawn returns 133, so this
|
||||
# unit will be restarted. On poweroff, it returns 0, so the
|
||||
# unit won't be restarted.
|
||||
|
@ -421,6 +511,8 @@ in
|
|||
# after the timeout). So send an ignored signal.
|
||||
KillMode = "mixed";
|
||||
KillSignal = "WINCH";
|
||||
|
||||
DevicePolicy = "closed";
|
||||
};
|
||||
};
|
||||
in {
|
||||
|
@ -429,15 +521,20 @@ in
|
|||
[{ name = "container@"; value = unit; }]
|
||||
# declarative containers
|
||||
++ (mapAttrsToList (name: cfg: nameValuePair "container@${name}" (
|
||||
unit // {
|
||||
preStart = preStartScript cfg;
|
||||
script = startScript cfg;
|
||||
postStart = postStartScript cfg;
|
||||
} // (
|
||||
if cfg.autoStart then
|
||||
unit // {
|
||||
{
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "network.target" ];
|
||||
after = [ "network.target" ];
|
||||
restartTriggers = [ cfg.path ];
|
||||
reloadIfChanged = true;
|
||||
}
|
||||
else null
|
||||
else {})
|
||||
)) config.containers)
|
||||
));
|
||||
|
||||
|
@ -466,11 +563,11 @@ in
|
|||
LOCAL_ADDRESS6=${cfg.localAddress6}
|
||||
''}
|
||||
''}
|
||||
INTERFACES="${toString cfg.interfaces}"
|
||||
${optionalString cfg.autoStart ''
|
||||
AUTO_START=1
|
||||
''}
|
||||
EXTRA_NSPAWN_FLAGS="${mkBindFlags cfg.bindMounts}"
|
||||
INTERFACES="${toString cfg.interfaces}"
|
||||
${optionalString cfg.autoStart ''
|
||||
AUTO_START=1
|
||||
''}
|
||||
EXTRA_NSPAWN_FLAGS="${mkBindFlags cfg.bindMounts}"
|
||||
'';
|
||||
}) config.containers;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue