Merge branch 'master' into staging

Conflicts:
	pkgs/development/libraries/fontconfig/default.nix
This commit is contained in:
Domen Kožar 2014-12-07 14:02:48 +01:00
commit 4aa3eec330
299 changed files with 22706 additions and 13278 deletions

View File

@ -115,6 +115,7 @@
nslqqq = "Nikita Mikhailov <nslqqq@gmail.com>"; nslqqq = "Nikita Mikhailov <nslqqq@gmail.com>";
ocharles = "Oliver Charles <ollie@ocharles.org.uk>"; ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
offline = "Jaka Hudoklin <jakahudoklin@gmail.com>"; offline = "Jaka Hudoklin <jakahudoklin@gmail.com>";
olcai = "Erik Timan <dev@timan.info>";
orbitz = "Malcolm Matalka <mmatalka@gmail.com>"; orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
page = "Carles Pagès <page@cubata.homelinux.net>"; page = "Carles Pagès <page@cubata.homelinux.net>";
pashev = "Igor Pashev <pashev.igor@gmail.com>"; pashev = "Igor Pashev <pashev.igor@gmail.com>";
@ -123,6 +124,7 @@
piotr = "Piotr Pietraszkiewicz <ppietrasa@gmail.com>"; piotr = "Piotr Pietraszkiewicz <ppietrasa@gmail.com>";
pkmx = "Chih-Mao Chen <pkmx.tw@gmail.com>"; pkmx = "Chih-Mao Chen <pkmx.tw@gmail.com>";
plcplc = "Philip Lykke Carlsen <plcplc@gmail.com>"; plcplc = "Philip Lykke Carlsen <plcplc@gmail.com>";
prikhi = "Pavan Rikhi <pavan.rikhi@gmail.com>";
pSub = "Pascal Wittmann <mail@pascal-wittmann.de>"; pSub = "Pascal Wittmann <mail@pascal-wittmann.de>";
puffnfresh = "Brian McKenna <brian@brianmckenna.org>"; puffnfresh = "Brian McKenna <brian@brianmckenna.org>";
qknight = "Joachim Schiele <js@lastlog.de>"; qknight = "Joachim Schiele <js@lastlog.de>";
@ -180,4 +182,5 @@
zef = "Zef Hemel <zef@zef.me>"; zef = "Zef Hemel <zef@zef.me>";
zimbatm = "zimbatm <zimbatm@zimbatm.com>"; zimbatm = "zimbatm <zimbatm@zimbatm.com>";
zoomulator = "Kim Simmons <zoomulator@gmail.com>"; zoomulator = "Kim Simmons <zoomulator@gmail.com>";
Gonzih = "Max Gonzih <gonzih@gmail.com>";
} }

View File

@ -39,6 +39,73 @@ in
''; '';
}; };
networking.proxy = {
default = lib.mkOption {
type = types.nullOr types.str;
default = null;
description = ''
This option specifies the default value for httpProxy, httpsProxy, ftpProxy and rsyncProxy.
'';
example = "http://127.0.0.1:3128";
};
httpProxy = lib.mkOption {
type = types.nullOr types.str;
default = cfg.proxy.default;
description = ''
This option specifies the http_proxy environment variable.
'';
example = "http://127.0.0.1:3128";
};
httpsProxy = lib.mkOption {
type = types.nullOr types.str;
default = cfg.proxy.default;
description = ''
This option specifies the https_proxy environment variable.
'';
example = "http://127.0.0.1:3128";
};
ftpProxy = lib.mkOption {
type = types.nullOr types.str;
default = cfg.proxy.default;
description = ''
This option specifies the ftp_proxy environment variable.
'';
example = "http://127.0.0.1:3128";
};
rsyncProxy = lib.mkOption {
type = types.nullOr types.str;
default = cfg.proxy.default;
description = ''
This option specifies the rsync_proxy environment variable.
'';
example = "http://127.0.0.1:3128";
};
noProxy = lib.mkOption {
type = types.nullOr types.str;
default = null;
description = ''
This option specifies the no_proxy environment variable.
If a default proxy is used and noProxy is null,
then noProxy will be set to 127.0.0.1,localhost.
'';
example = "127.0.0.1,localhost,.localdomain";
};
envVars = lib.mkOption {
type = types.attrs;
internal = true;
default = {};
description = ''
Environment variables used for the network proxy.
'';
};
};
}; };
config = { config = {
@ -84,13 +151,59 @@ in
dnsmasq_conf=/etc/dnsmasq-conf.conf dnsmasq_conf=/etc/dnsmasq-conf.conf
dnsmasq_resolv=/etc/dnsmasq-resolv.conf dnsmasq_resolv=/etc/dnsmasq-resolv.conf
''; '';
} // (optionalAttrs config.services.resolved.enable (
if dnsmasqResolve then {
"dnsmasq-resolv.conf".source = "/run/systemd/resolve/resolv.conf";
} else {
"resolv.conf".source = "/run/systemd/resolve/resolv.conf";
}
));
networking.proxy.envVars =
optionalAttrs (cfg.proxy.default != null) {
# other options already fallback to proxy.default
no_proxy = "127.0.0.1,localhost";
} // optionalAttrs (cfg.proxy.httpProxy != null) {
http_proxy = cfg.proxy.httpProxy;
} // optionalAttrs (cfg.proxy.httpsProxy != null) {
https_proxy = cfg.proxy.httpsProxy;
} // optionalAttrs (cfg.proxy.rsyncProxy != null) {
rsync_proxy = cfg.proxy.rsyncProxy;
} // optionalAttrs (cfg.proxy.ftpProxy != null) {
ftp_proxy = cfg.proxy.ftpProxy;
} // optionalAttrs (cfg.proxy.noProxy != null) {
no_proxy = cfg.proxy.noProxy;
}; };
# Install the proxy environment variables
environment.sessionVariables = cfg.proxy.envVars;
# The ip-up target is started when we have IP connectivity. So # The ip-up target is started when we have IP connectivity. So
# services that depend on IP connectivity (like ntpd) should be # services that depend on IP connectivity (like ntpd) should be
# pulled in by this target. # pulled in by this target.
systemd.targets.ip-up.description = "Services Requiring IP Connectivity"; systemd.targets.ip-up.description = "Services Requiring IP Connectivity";
# This is needed when /etc/resolv.conf is being overriden by networkd
# and other configurations. If the file is destroyed by an environment
# activation then it must be rebuilt so that applications which interface
# with /etc/resolv.conf directly don't break.
system.activationScripts.resolvconf = stringAfter [ "etc" "tmpfs" "var" ]
''
# Systemd resolved controls its own resolv.conf
rm -f /run/resolvconf/interfaces/systemd
${optionalString config.services.resolved.enable ''
rm -rf /run/resolvconf/interfaces
mkdir -p /run/resolvconf/interfaces
ln -s /run/systemd/resolve/resolv.conf /run/resolvconf/interfaces/systemd
''}
# Make sure resolv.conf is up to date if not managed by systemd
${optionalString (!config.services.resolved.enable) ''
${pkgs.openresolv}/bin/resolvconf -u
''}
'';
}; };
} }

View File

@ -12,7 +12,8 @@ with lib;
default = false; default = false;
type = types.bool; type = types.bool;
description = '' description = ''
Turn on this option if you want to enable all the firmware shipped with Debian/Ubuntu. Turn on this option if you want to enable all the firmware shipped with Debian/Ubuntu
and iwlwifi.
''; '';
}; };
@ -22,7 +23,11 @@ with lib;
###### implementation ###### implementation
config = mkIf config.hardware.enableAllFirmware { config = mkIf config.hardware.enableAllFirmware {
hardware.firmware = [ "${pkgs.firmwareLinuxNonfree}/lib/firmware" ]; hardware.firmware = [
"${pkgs.firmwareLinuxNonfree}/lib/firmware"
"${pkgs.iwlegacy}/lib/firmware"
"${pkgs.iwlwifi}/lib/firmware"
];
}; };
} }

View File

@ -30,7 +30,7 @@ with lib;
boot.kernelModules = [ "bbswitch" ]; boot.kernelModules = [ "bbswitch" ];
boot.extraModulePackages = [ kernel.bbswitch kernel.nvidia_x11 ]; boot.extraModulePackages = [ kernel.bbswitch kernel.nvidia_x11 ];
environment.systemPackages = [ pkgs.bumblebee ]; environment.systemPackages = [ pkgs.bumblebee pkgs.primus ];
systemd.services.bumblebeed = { systemd.services.bumblebeed = {
description = "Bumblebee Hybrid Graphics Switcher"; description = "Bumblebee Hybrid Graphics Switcher";

View File

@ -169,6 +169,9 @@
opentsdb = 159; opentsdb = 159;
scollector = 160; scollector = 160;
bosun = 161; bosun = 161;
kubernetes = 162;
peerflix = 163;
chronos = 164;
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
@ -209,6 +212,7 @@
privoxy = 32; privoxy = 32;
disnix = 33; disnix = 33;
osgi = 34; osgi = 34;
tor = 35;
ghostOne = 40; ghostOne = 40;
git = 41; git = 41;
fourstore = 42; fourstore = 42;
@ -302,6 +306,7 @@
liquidsoap = 155; liquidsoap = 155;
scollector = 156; scollector = 156;
bosun = 157; bosun = 157;
kubernetes = 158;
# When adding a gid, make sure it doesn't match an existing uid. And don't use gids above 399! # When adding a gid, make sure it doesn't match an existing uid. And don't use gids above 399!

View File

@ -292,6 +292,7 @@
./services/networking/znc.nix ./services/networking/znc.nix
./services/printing/cupsd.nix ./services/printing/cupsd.nix
./services/scheduling/atd.nix ./services/scheduling/atd.nix
./services/scheduling/chronos.nix
./services/scheduling/cron.nix ./services/scheduling/cron.nix
./services/scheduling/fcron.nix ./services/scheduling/fcron.nix
./services/search/elasticsearch.nix ./services/search/elasticsearch.nix
@ -301,7 +302,6 @@
./services/security/fprot.nix ./services/security/fprot.nix
./services/security/frandom.nix ./services/security/frandom.nix
./services/security/haveged.nix ./services/security/haveged.nix
./services/security/torify.nix
./services/security/tor.nix ./services/security/tor.nix
./services/security/torsocks.nix ./services/security/torsocks.nix
./services/system/dbus.nix ./services/system/dbus.nix
@ -309,6 +309,7 @@
./services/system/nscd.nix ./services/system/nscd.nix
./services/system/uptimed.nix ./services/system/uptimed.nix
./services/torrent/deluge.nix ./services/torrent/deluge.nix
./services/torrent/peerflix.nix
./services/torrent/transmission.nix ./services/torrent/transmission.nix
./services/ttys/agetty.nix ./services/ttys/agetty.nix
./services/ttys/gpm.nix ./services/ttys/gpm.nix
@ -357,6 +358,7 @@
./system/boot/loader/efi.nix ./system/boot/loader/efi.nix
./system/boot/loader/generations-dir/generations-dir.nix ./system/boot/loader/generations-dir/generations-dir.nix
./system/boot/loader/grub/grub.nix ./system/boot/loader/grub/grub.nix
./system/boot/loader/grub/ipxe.nix
./system/boot/loader/grub/memtest.nix ./system/boot/loader/grub/memtest.nix
./system/boot/loader/gummiboot/gummiboot.nix ./system/boot/loader/gummiboot/gummiboot.nix
./system/boot/loader/init-script/init-script.nix ./system/boot/loader/init-script/init-script.nix
@ -388,6 +390,8 @@
./tasks/kbd.nix ./tasks/kbd.nix
./tasks/lvm.nix ./tasks/lvm.nix
./tasks/network-interfaces.nix ./tasks/network-interfaces.nix
./tasks/network-interfaces-systemd.nix
./tasks/network-interfaces-scripted.nix
./tasks/scsi-link-power-management.nix ./tasks/scsi-link-power-management.nix
./tasks/swraid.nix ./tasks/swraid.nix
./tasks/trackpoint.nix ./tasks/trackpoint.nix
@ -395,6 +399,7 @@
./virtualisation/container-config.nix ./virtualisation/container-config.nix
./virtualisation/containers.nix ./virtualisation/containers.nix
./virtualisation/docker.nix ./virtualisation/docker.nix
./virtualisation/kubernetes.nix
./virtualisation/libvirtd.nix ./virtualisation/libvirtd.nix
./virtualisation/lxc.nix ./virtualisation/lxc.nix
#./virtualisation/nova.nix #./virtualisation/nova.nix

View File

@ -16,6 +16,22 @@ in
boot.extraModulePackages = [ virtualbox ]; boot.extraModulePackages = [ virtualbox ];
environment.systemPackages = [ virtualbox ]; environment.systemPackages = [ virtualbox ];
security.setuidOwners = let
mkVboxStub = program: {
inherit program;
owner = "root";
group = "vboxusers";
setuid = true;
};
in map mkVboxStub [
"VBoxBFE"
"VBoxBalloonCtrl"
"VBoxHeadless"
"VBoxManage"
"VBoxSDL"
"VirtualBox"
];
users.extraGroups.vboxusers.gid = config.ids.gids.vboxusers; users.extraGroups.vboxusers.gid = config.ids.gids.vboxusers;
services.udev.extraRules = services.udev.extraRules =

View File

@ -110,6 +110,9 @@ in zipModules ([]
# VirtualBox # VirtualBox
++ obsolete [ "services" "virtualbox" "enable" ] [ "services" "virtualboxGuest" "enable" ] ++ obsolete [ "services" "virtualbox" "enable" ] [ "services" "virtualboxGuest" "enable" ]
# proxy
++ obsolete [ "nix" "proxy" ] [ "networking" "proxy" "default" ]
# KDE # KDE
++ deprecated [ "kde" "extraPackages" ] [ "environment" "kdePackages" ] ++ deprecated [ "kde" "extraPackages" ] [ "environment" "kdePackages" ]
# ++ obsolete [ "environment" "kdePackages" ] [ "environment" "systemPackages" ] # !!! doesn't work! # ++ obsolete [ "environment" "kdePackages" ] [ "environment" "systemPackages" ] # !!! doesn't work!

View File

@ -16,6 +16,8 @@ with lib;
{ SSL_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt"; { SSL_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt";
# FIXME: unneeded - remove eventually. # FIXME: unneeded - remove eventually.
OPENSSL_X509_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt"; OPENSSL_X509_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt";
# FIXME: unneeded - remove eventually.
GIT_SSL_CAINFO = "/etc/ssl/certs/ca-bundle.crt";
}; };
}; };

View File

@ -109,6 +109,7 @@ in {
}; };
sqlalchemy_engine_url = mkOption { sqlalchemy_engine_url = mkOption {
default = "postgresql:///bacula";
example = '' example = ''
postgresql://bacula:bacula@localhost:5432/bacula postgresql://bacula:bacula@localhost:5432/bacula
mysql+mysqlconnector://<user>:<password>@<hostname>/<database>' mysql+mysqlconnector://<user>:<password>@<hostname>/<database>'

View File

@ -88,7 +88,7 @@ let
done done
${optionalString config.networking.usePredictableInterfaceNames '' ${optionalString config.networking.usePredictableInterfaceNames ''
cp ${./80-net-name-slot.rules} $out/80-net-name-slot.rules cp ${./80-net-setup-link.rules} $out/80-net-setup-link.rules
''} ''}
# If auto-configuration is disabled, then remove # If auto-configuration is disabled, then remove

View File

@ -84,7 +84,7 @@ in
startOn = "started network-interfaces"; startOn = "started network-interfaces";
stopOn = "stopping network-interfaces"; stopOn = "stopping network-interfaces";
path = [ pkgs.nfsUtils pkgs.sshfsFuse ]; path = [ pkgs.nfs-utils pkgs.sshfsFuse ];
preStop = preStop =
'' ''

View File

@ -86,11 +86,12 @@ in {
${pkgs.mesos}/bin/mesos-master \ ${pkgs.mesos}/bin/mesos-master \
--port=${toString cfg.port} \ --port=${toString cfg.port} \
--zk=${cfg.zk} \ --zk=${cfg.zk} \
${if cfg.quorum == 0 then "--registry=in_memory" else "--registry=replicated_log --quorum=${cfg.quorum}"} \ ${if cfg.quorum == 0 then "--registry=in_memory" else "--registry=replicated_log --quorum=${toString cfg.quorum}"} \
--work_dir=${cfg.workDir} \ --work_dir=${cfg.workDir} \
--logging_level=${cfg.logLevel} \ --logging_level=${cfg.logLevel} \
${toString cfg.extraCmdLineOptions} ${toString cfg.extraCmdLineOptions}
''; '';
Restart = "on-failure";
PermissionsStartOnly = true; PermissionsStartOnly = true;
}; };
preStart = '' preStart = ''

View File

@ -72,6 +72,7 @@ in {
description = "Mesos Slave"; description = "Mesos Slave";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" ]; after = [ "network-interfaces.target" ];
environment.MESOS_CONTAINERIZERS = "docker,mesos";
serviceConfig = { serviceConfig = {
ExecStart = '' ExecStart = ''
${pkgs.mesos}/bin/mesos-slave \ ${pkgs.mesos}/bin/mesos-slave \
@ -80,6 +81,7 @@ in {
${optionalString cfg.withHadoop "--hadoop-home=${pkgs.hadoop}"} \ ${optionalString cfg.withHadoop "--hadoop-home=${pkgs.hadoop}"} \
--work_dir=${cfg.workDir} \ --work_dir=${cfg.workDir} \
--logging_level=${cfg.logLevel} \ --logging_level=${cfg.logLevel} \
--docker=${pkgs.docker}/libexec/docker/docker \
${toString cfg.extraCmdLineOptions} ${toString cfg.extraCmdLineOptions}
''; '';
PermissionsStartOnly = true; PermissionsStartOnly = true;

View File

@ -193,17 +193,6 @@ in
''; '';
}; };
proxy = mkOption {
type = types.str;
default = "";
description = ''
This option specifies the proxy to use for fetchurl. The real effect
is just exporting http_proxy, https_proxy and ftp_proxy with that
value.
'';
example = "http://127.0.0.1:3128";
};
# Environment variables for running Nix. # Environment variables for running Nix.
envVars = mkOption { envVars = mkOption {
type = types.attrs; type = types.attrs;
@ -292,7 +281,9 @@ in
{ path = [ nix pkgs.openssl pkgs.utillinux pkgs.openssh ] { path = [ nix pkgs.openssl pkgs.utillinux pkgs.openssh ]
++ optionals cfg.distributedBuilds [ pkgs.gzip ]; ++ optionals cfg.distributedBuilds [ pkgs.gzip ];
environment = cfg.envVars // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-bundle.crt"; }; environment = cfg.envVars
// { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-bundle.crt"; }
// config.networking.proxy.envVars;
serviceConfig = serviceConfig =
{ Nice = cfg.daemonNiceLevel; { Nice = cfg.daemonNiceLevel;
@ -317,13 +308,6 @@ in
NIX_BUILD_HOOK = "${nix}/libexec/nix/build-remote.pl"; NIX_BUILD_HOOK = "${nix}/libexec/nix/build-remote.pl";
NIX_REMOTE_SYSTEMS = "/etc/nix/machines"; NIX_REMOTE_SYSTEMS = "/etc/nix/machines";
NIX_CURRENT_LOAD = "/run/nix/current-load"; NIX_CURRENT_LOAD = "/run/nix/current-load";
}
# !!! These should not be defined here, but in some general proxy configuration module!
// optionalAttrs (cfg.proxy != "") {
http_proxy = cfg.proxy;
https_proxy = cfg.proxy;
ftp_proxy = cfg.proxy;
}; };
# Set up the environment variables for running Nix. # Set up the environment variables for running Nix.

View File

@ -81,27 +81,26 @@ in
###### implementation ###### implementation
config = { config = mkMerge [
(mkIf cfgC.enable {
systemd.services."synergy-client" = { systemd.services."synergy-client" = {
enable = cfgC.enable;
after = [ "network.target" ]; after = [ "network.target" ];
description = "Synergy client"; description = "Synergy client";
wantedBy = optional cfgC.autoStart "multi-user.target"; wantedBy = [ "multi-user.target" ];
path = [ pkgs.synergy ]; path = [ pkgs.synergy ];
serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergyc -f ${optionalString (cfgC.screenName != "") "-n ${cfgC.screenName}"} ${cfgC.serverAddress}''; serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergyc -f ${optionalString (cfgC.screenName != "") "-n ${cfgC.screenName}"} ${cfgC.serverAddress}'';
}; };
})
(mkIf cfgS.enable {
systemd.services."synergy-server" = { systemd.services."synergy-server" = {
enable = cfgS.enable;
after = [ "network.target" ]; after = [ "network.target" ];
description = "Synergy server"; description = "Synergy server";
wantedBy = optional cfgS.autoStart "multi-user.target"; wantedBy = [ "multi-user.target" ];
path = [ pkgs.synergy ]; path = [ pkgs.synergy ];
serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} -f ${optionalString (cfgS.address != "") "-a ${cfgS.address}"} ${optionalString (cfgS.screenName != "") "-n ${cfgS.screenName}" }''; serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} -f ${optionalString (cfgS.address != "") "-a ${cfgS.address}"} ${optionalString (cfgS.screenName != "") "-n ${cfgS.screenName}" }'';
}; };
})
}; ];
} }

View File

@ -30,7 +30,6 @@ in {
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.bosun;
example = literalExample "pkgs.bosun"; example = literalExample "pkgs.bosun";
description = '' description = ''
bosun binary to use. bosun binary to use.
@ -94,8 +93,9 @@ in {
}; };
config = mkIf config.services.bosun.enable { config = mkIf cfg.enable {
services.bosun.package = mkDefault pkgs.bosun;
systemd.services.bosun = { systemd.services.bosun = {
description = "bosun metrics collector (part of Bosun)"; description = "bosun metrics collector (part of Bosun)";

View File

@ -86,7 +86,7 @@ in
boot.supportedFilesystems = [ "nfs" ]; # needed for statd and idmapd boot.supportedFilesystems = [ "nfs" ]; # needed for statd and idmapd
environment.systemPackages = [ pkgs.nfsUtils ]; environment.systemPackages = [ pkgs.nfs-utils ];
environment.etc = singleton environment.etc = singleton
{ source = exports; { source = exports;
@ -104,7 +104,7 @@ in
after = [ "rpcbind.service" "mountd.service" "idmapd.service" ]; after = [ "rpcbind.service" "mountd.service" "idmapd.service" ];
before = [ "statd.service" ]; before = [ "statd.service" ];
path = [ pkgs.nfsUtils ]; path = [ pkgs.nfs-utils ];
script = script =
'' ''
@ -131,7 +131,7 @@ in
requires = [ "rpcbind.service" ]; requires = [ "rpcbind.service" ];
after = [ "rpcbind.service" ]; after = [ "rpcbind.service" ];
path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; path = [ pkgs.nfs-utils pkgs.sysvtools pkgs.utillinux ];
preStart = preStart =
'' ''
@ -157,7 +157,7 @@ in
serviceConfig.Type = "forking"; serviceConfig.Type = "forking";
serviceConfig.ExecStart = '' serviceConfig.ExecStart = ''
@${pkgs.nfsUtils}/sbin/rpc.mountd rpc.mountd \ @${pkgs.nfs-utils}/sbin/rpc.mountd rpc.mountd \
${if cfg.mountdPort != null then "-p ${toString cfg.mountdPort}" else ""} ${if cfg.mountdPort != null then "-p ${toString cfg.mountdPort}" else ""}
''; '';
serviceConfig.Restart = "always"; serviceConfig.Restart = "always";

View File

@ -48,9 +48,10 @@ in
servers = mkOption { servers = mkOption {
default = [ default = [
"0.pool.ntp.org" "0.nixos.pool.ntp.org"
"1.pool.ntp.org" "1.nixos.pool.ntp.org"
"2.pool.ntp.org" "2.nixos.pool.ntp.org"
"3.nixos.pool.ntp.org"
]; ];
description = '' description = ''
The set of NTP servers from which to synchronise. The set of NTP servers from which to synchronise.
@ -99,8 +100,8 @@ in
jobs.chronyd = jobs.chronyd =
{ description = "chrony daemon"; { description = "chrony daemon";
wantedBy = [ "ip-up.target" ]; wantedBy = [ "multi-user.target" ];
partOf = [ "ip-up.target" ]; after = [ "network.target" ];
path = [ chrony ]; path = [ chrony ];

View File

@ -8,15 +8,29 @@ let
cfg = config.networking.dhcpcd; cfg = config.networking.dhcpcd;
interfaces = attrValues config.networking.interfaces;
enableDHCP = config.networking.useDHCP || any (i: i.useDHCP == true) interfaces;
# Don't start dhcpcd on explicitly configured interfaces or on # Don't start dhcpcd on explicitly configured interfaces or on
# interfaces that are part of a bridge, bond or sit device. # interfaces that are part of a bridge, bond or sit device.
ignoredInterfaces = ignoredInterfaces =
map (i: i.name) (filter (i: i.ip4 != [ ] || i.ipAddress != null) (attrValues config.networking.interfaces)) map (i: i.name) (filter (i: if i.useDHCP != null then !i.useDHCP else i.ip4 != [ ] || i.ipAddress != null) interfaces)
++ mapAttrsToList (i: _: i) config.networking.sits ++ mapAttrsToList (i: _: i) config.networking.sits
++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges)) ++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges))
++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bonds)) ++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bonds))
++ config.networking.dhcpcd.denyInterfaces; ++ config.networking.dhcpcd.denyInterfaces;
arrayAppendOrNull = a1: a2: if a1 == null && a2 == null then null
else if a1 == null then a2 else if a2 == null then a1
else a1 ++ a2;
# If dhcp is disabled but explicit interfaces are enabled,
# we need to provide dhcp just for those interfaces.
allowInterfaces = arrayAppendOrNull cfg.allowInterfaces
(if !config.networking.useDHCP && enableDHCP then
map (i: i.name) (filter (i: i.useDHCP == true) interfaces) else null);
# Config file adapted from the one that ships with dhcpcd. # Config file adapted from the one that ships with dhcpcd.
dhcpcdConf = pkgs.writeText "dhcpcd.conf" dhcpcdConf = pkgs.writeText "dhcpcd.conf"
'' ''
@ -41,7 +55,7 @@ let
denyinterfaces ${toString ignoredInterfaces} lo peth* vif* tap* tun* virbr* vnet* vboxnet* sit* denyinterfaces ${toString ignoredInterfaces} lo peth* vif* tap* tun* virbr* vnet* vboxnet* sit*
# Use the list of allowed interfaces if specified # Use the list of allowed interfaces if specified
${optionalString (cfg.allowInterfaces != null) "allowinterfaces ${toString cfg.allowInterfaces}"} ${optionalString (allowInterfaces != null) "allowinterfaces ${toString allowInterfaces}"}
${cfg.extraConfig} ${cfg.extraConfig}
''; '';
@ -132,7 +146,7 @@ in
###### implementation ###### implementation
config = mkIf config.networking.useDHCP { config = mkIf enableDHCP {
systemd.services.dhcpcd = systemd.services.dhcpcd =
{ description = "DHCP Client"; { description = "DHCP Client";

View File

@ -82,7 +82,7 @@ in
systemd.services.dnsmasq = { systemd.services.dnsmasq = {
description = "dnsmasq daemon"; description = "dnsmasq daemon";
after = [ "network.target" ]; after = [ "network.target" "systemd-resolved.conf" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ dnsmasq ]; path = [ dnsmasq ];
preStart = '' preStart = ''

View File

@ -458,8 +458,9 @@ in
systemd.services.firewall = { systemd.services.firewall = {
description = "Firewall"; description = "Firewall";
wantedBy = [ "network.target" ]; wantedBy = [ "network-pre.target" ];
after = [ "network-interfaces.target" "systemd-modules-load.service" ]; before = [ "network-pre.target" ];
after = [ "systemd-modules-load.service" ];
path = [ pkgs.iptables ]; path = [ pkgs.iptables ];

View File

@ -76,8 +76,7 @@ in
exec ${pkgs.gogoclient}/bin/gogoc -y -f /var/lib/gogoc/gogoc.conf exec ${pkgs.gogoclient}/bin/gogoc -y -f /var/lib/gogoc/gogoc.conf
''; '';
} // optionalAttrs cfg.autorun { } // optionalAttrs cfg.autorun {
wantedBy = [ "ip-up.target" ]; wantedBy = [ "multi-user.target" ];
partOf = [ "ip-up.target" ];
}; };
}; };

View File

@ -52,6 +52,7 @@ let
#!/bin/sh #!/bin/sh
if test "$2" = "up"; then if test "$2" = "up"; then
${config.systemd.package}/bin/systemctl start ip-up.target ${config.systemd.package}/bin/systemctl start ip-up.target
${config.systemd.package}/bin/systemctl start network-online.target
fi fi
''; '';

View File

@ -45,9 +45,10 @@ in
servers = mkOption { servers = mkOption {
default = [ default = [
"0.pool.ntp.org" "0.nixos.pool.ntp.org"
"1.pool.ntp.org" "1.nixos.pool.ntp.org"
"2.pool.ntp.org" "2.nixos.pool.ntp.org"
"3.nixos.pool.ntp.org"
]; ];
description = '' description = ''
The set of NTP servers from which to synchronise. The set of NTP servers from which to synchronise.
@ -76,8 +77,7 @@ in
jobs.ntpd = jobs.ntpd =
{ description = "NTP Daemon"; { description = "NTP Daemon";
wantedBy = [ "ip-up.target" ]; wantedBy = [ "multi-user.target" ];
partOf = [ "ip-up.target" ];
path = [ ntp ]; path = [ ntp ];

View File

@ -41,8 +41,7 @@ in
systemd.services.openntpd = { systemd.services.openntpd = {
description = "OpenNTP Server"; description = "OpenNTP Server";
wantedBy = [ "ip-up.target" ]; wantedBy = [ "multi-user.target" ];
partOf = [ "ip-up.target" ];
serviceConfig.ExecStart = "${package}/sbin/ntpd -d -f ${cfgFile}"; serviceConfig.ExecStart = "${package}/sbin/ntpd -d -f ${cfgFile}";
}; };
}; };

View File

@ -48,6 +48,7 @@ in
systemd.mounts = map ({ what, where }: { systemd.mounts = map ({ what, where }: {
bindsTo = [ "unifi.service" ]; bindsTo = [ "unifi.service" ];
partOf = [ "unifi.service" ]; partOf = [ "unifi.service" ];
unitConfig.RequiresMountsFor = stateDir;
options = "bind"; options = "bind";
what = what; what = what;
where = where; where = where;
@ -59,6 +60,7 @@ in
after = [ "network.target" ] ++ systemdMountPoints; after = [ "network.target" ] ++ systemdMountPoints;
partOf = systemdMountPoints; partOf = systemdMountPoints;
bindsTo = systemdMountPoints; bindsTo = systemdMountPoints;
unitConfig.RequiresMountsFor = stateDir;
preStart = '' preStart = ''
# Ensure privacy of state # Ensure privacy of state

View File

@ -0,0 +1,54 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.chronos;
in {
###### interface
options.services.chronos = {
enable = mkOption {
description = "Whether to enable graphite web frontend.";
default = false;
type = types.uniq types.bool;
};
httpPort = mkOption {
description = "Chronos listening port";
default = 8080;
type = types.int;
};
master = mkOption {
description = "Chronos mesos master zookeeper address";
default = "zk://${head cfg.zookeeperHosts}/mesos";
type = types.str;
};
zookeeperHosts = mkOption {
description = "Chronos mesos zookepper addresses";
default = [ "localhost:2181" ];
type = types.listOf types.str;
};
};
###### implementation
config = mkIf cfg.enable {
systemd.services.chronos = {
description = "Chronos Service";
wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" "zookeeper.service" ];
serviceConfig = {
ExecStart = "${pkgs.chronos}/bin/chronos --master ${cfg.master} --zk_hosts ${concatStringsSep "," cfg.zookeeperHosts} --http_port ${toString cfg.httpPort}";
User = "chronos";
};
};
users.extraUsers.chronos.uid = config.ids.uids.chronos;
};
}

View File

@ -3,120 +3,116 @@
with lib; with lib;
let let
inherit (pkgs) tor privoxy;
stateDir = "/var/lib/tor";
privoxyDir = stateDir+"/privoxy";
cfg = config.services.tor; cfg = config.services.tor;
torDirectory = "/var/lib/tor";
torUser = "tor"; opt = name: value: optionalString (value != null) "${name} ${value}";
optint = name: value: optionalString (value != 0) "${name} ${toString value}";
opt = name: value: if value != "" then "${name} ${value}" else ""; torRc = ''
optint = name: value: if value != 0 then "${name} ${toString value}" else ""; User tor
DataDirectory ${torDirectory}
${optint "ControlPort" cfg.controlPort}
''
# Client connection config
+ optionalString cfg.client.enable ''
SOCKSPort ${cfg.client.socksListenAddress}
${opt "SocksPolicy" cfg.client.socksPolicy}
''
# Relay config
+ optionalString cfg.relay.enable ''
ORPort ${cfg.relay.portSpec}
${opt "Nickname" cfg.relay.nickname}
${opt "ContactInfo" cfg.relay.contactInfo}
${optint "RelayBandwidthRate" cfg.relay.bandwidthRate}
${optint "RelayBandwidthBurst" cfg.relay.bandwidthBurst}
${opt "AccountingMax" cfg.relay.accountingMax}
${opt "AccountingStart" cfg.relay.accountingStart}
${if cfg.relay.isExit then
opt "ExitPolicy" cfg.relay.exitPolicy
else
"ExitPolicy reject *:*"}
${optionalString cfg.relay.isBridge ''
BridgeRelay 1
ServerTransportPlugin obfs2,obfs3 exec ${pkgs.pythonPackages.obfsproxy}/bin/obfsproxy managed
''}
''
+ cfg.extraConfig;
torRcFile = pkgs.writeText "torrc" torRc;
in in
{ {
###### interface
options = { options = {
services.tor = { services.tor = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable the Tor daemon. By default, the daemon is run without
relay, exit, bridge or client connectivity.
'';
};
config = mkOption { extraConfig = mkOption {
type = types.str;
default = ""; default = "";
description = '' description = ''
Extra configuration. Contents will be added verbatim to the Extra configuration. Contents will be added verbatim to the
configuration file. configuration file at the end.
'';
};
controlPort = mkOption {
type = types.int;
default = 0;
example = 9051;
description = ''
If set, Tor will accept connections on the specified port
and allow them to control the tor process.
''; '';
}; };
client = { client = {
enable = mkOption { enable = mkOption {
type = types.bool;
default = false; default = false;
description = '' description = ''
Whether to enable Tor daemon to route application connections. Whether to enable Tor daemon to route application
You might want to disable this if you plan running a dedicated Tor relay. connections. You might want to disable this if you plan
running a dedicated Tor relay.
''; '';
}; };
socksListenAddress = mkOption { socksListenAddress = mkOption {
type = types.str;
default = "127.0.0.1:9050"; default = "127.0.0.1:9050";
example = "192.168.0.1:9100"; example = "192.168.0.1:9100";
description = '' description = ''
Bind to this address to listen for connections from Socks-speaking Bind to this address to listen for connections from
applications. Socks-speaking applications.
'';
};
socksListenAddressFaster = mkOption {
default = "127.0.0.1:9063";
description = ''
Same as socksListenAddress but uses weaker circuit isolation to provide
performance suitable for a web browser.
''; '';
}; };
socksPolicy = mkOption { socksPolicy = mkOption {
default = ""; type = types.nullOr types.str;
default = null;
example = "accept 192.168.0.0/16, reject *"; example = "accept 192.168.0.0/16, reject *";
description = '' description = ''
Entry policies to allow/deny SOCKS requests based on IP address. Entry policies to allow/deny SOCKS requests based on IP
First entry that matches wins. If no SocksPolicy is set, we accept address. First entry that matches wins. If no SocksPolicy
all (and only) requests from SocksListenAddress. is set, we accept all (and only) requests from
SocksListenAddress.
''; '';
}; };
privoxy = {
enable = mkOption {
default = true;
description = ''
Whether to enable a special instance of privoxy dedicated to Tor.
To have anonymity, protocols need to be scrubbed of identifying
information.
Most people using Tor want to anonymize their web traffic, so by
default we enable an special instance of privoxy specifically for
Tor.
However, if you are only going to use Tor only for other kinds of
traffic then you can disable this option.
'';
};
listenAddress = mkOption {
default = "127.0.0.1:8118";
description = ''
Address that Tor's instance of privoxy is listening to.
*This does not configure the standard NixOS instance of privoxy.*
This is for Tor connections only!
See services.privoxy.listenAddress to configure the standard NixOS
instace of privoxy.
'';
};
config = mkOption {
default = "";
description = ''
Extra configuration for Tor's instance of privoxy. Contents will be
added verbatim to the configuration file.
*This does not configure the standard NixOS instance of privoxy.*
This is for Tor connections only!
See services.privoxy.extraConfig to configure the standard NixOS
instace of privoxy.
'';
};
};
}; };
relay = { relay = {
enable = mkOption { enable = mkOption {
type = types.bool;
default = false; default = false;
description = '' description = ''
Whether to enable relaying TOR traffic for others. Whether to enable relaying TOR traffic for others.
@ -126,16 +122,19 @@ in
}; };
isBridge = mkOption { isBridge = mkOption {
type = types.bool;
default = false; default = false;
description = '' description = ''
Bridge relays (or "bridges" ) are Tor relays that aren't listed in the Bridge relays (or "bridges") are Tor relays that aren't
main directory. Since there is no complete public list of them, even if an listed in the main directory. Since there is no complete
ISP is filtering connections to all the known Tor relays, they probably public list of them, even if an ISP is filtering
connections to all the known Tor relays, they probably
won't be able to block all the bridges. won't be able to block all the bridges.
A bridge relay can't be an exit relay. A bridge relay can't be an exit relay.
You need to set relay.enable to true for this option to take effect. You need to set relay.enable to true for this option to
take effect.
The bridge is set up with an obfuscated transport proxy. The bridge is set up with an obfuscated transport proxy.
@ -144,25 +143,72 @@ in
}; };
isExit = mkOption { isExit = mkOption {
type = types.bool;
default = false; default = false;
description = '' description = ''
An exit relay allows Tor users to access regular Internet services. An exit relay allows Tor users to access regular Internet
services.
Unlike running a non-exit relay, running an exit relay may expose Unlike running a non-exit relay, running an exit relay may
you to abuse complaints. See https://www.torproject.org/faq.html.en#ExitPolicies for more info. expose you to abuse complaints. See
https://www.torproject.org/faq.html.en#ExitPolicies for
more info.
You can specify which services Tor users may access via your exit relay using exitPolicy option. You can specify which services Tor users may access via
your exit relay using exitPolicy option.
''; '';
}; };
nickname = mkOption { nickname = mkOption {
type = types.str;
default = "anonymous"; default = "anonymous";
description = '' description = ''
A unique handle for your TOR relay. A unique handle for your TOR relay.
''; '';
}; };
contactInfo = mkOption {
type = types.nullOr types.str;
default = null;
example = "admin@relay.com";
description = ''
Contact information for the relay owner (e.g. a mail
address and GPG key ID).
'';
};
accountingMax = mkOption {
type = types.nullOr types.str;
default = null;
example = "450 GBytes";
description = ''
Specify maximum bandwidth allowed during an accounting
period. This allows you to limit overall tor bandwidth
over some time period. See the
<literal>AccountingMax</literal> option by looking at the
tor manual (<literal>man tor</literal>) for more.
Note this limit applies individually to upload and
download; if you specify <literal>"500 GBytes"</literal>
here, then you may transfer up to 1 TBytes of overall
bandwidth (500 GB upload, 500 GB download).
'';
};
accountingStart = mkOption {
type = types.nullOr types.str;
default = null;
example = "month 1 1:00";
description = ''
Specify length of an accounting period. This allows you to
limit overall tor bandwidth over some time period. See the
<literal>AccountingStart</literal> option by looking at
the tor manual (<literal>man tor</literal>) for more.
'';
};
bandwidthRate = mkOption { bandwidthRate = mkOption {
type = types.int;
default = 0; default = 0;
example = 100; example = 100;
description = '' description = ''
@ -172,6 +218,7 @@ in
}; };
bandwidthBurst = mkOption { bandwidthBurst = mkOption {
type = types.int;
default = cfg.relay.bandwidthRate; default = cfg.relay.bandwidthRate;
example = 200; example = 200;
description = '' description = ''
@ -181,143 +228,99 @@ in
''; '';
}; };
port = mkOption { portSpec = mkOption {
default = 9001; type = types.str;
example = "143";
description = '' description = ''
What port to advertise for Tor connections. What port to advertise for Tor connections. This corresponds
''; to the <literal>ORPort</literal> section in the Tor manual; see
}; <literal>man tor</literal> for more details.
listenAddress = mkOption { At a minimum, you should just specify the port for the
default = ""; relay to listen on; a common one like 143, 22, 80, or 443
example = "0.0.0.0:9090"; to help Tor users who may have very restrictive port-based
description = '' firewalls.
Set this if you need to listen on a port other than the one advertised
in relayPort (e.g. to advertise 443 but bind to 9090). You'll need to do
ipchains or other port forwsarding yourself to make this work.
''; '';
}; };
exitPolicy = mkOption { exitPolicy = mkOption {
default = ""; type = types.nullOr types.str;
default = null;
example = "accept *:6660-6667,reject *:*"; example = "accept *:6660-6667,reject *:*";
description = '' description = ''
A comma-separated list of exit policies. They're considered first A comma-separated list of exit policies. They're
to last, and the first match wins. If you want to _replace_ considered first to last, and the first match wins. If you
the default exit policy, end this with either a reject *:* or an want to _replace_ the default exit policy, end this with
accept *:*. Otherwise, you're _augmenting_ (prepending to) the either a reject *:* or an accept *:*. Otherwise, you're
default exit policy. Leave commented to just use the default, which is _augmenting_ (prepending to) the default exit
available in the man page or at https://www.torproject.org/documentation.html policy. Leave commented to just use the default, which is
available in the man page or at
https://www.torproject.org/documentation.html
Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses
for issues you might encounter if you use the default exit policy. for issues you might encounter if you use the default exit policy.
If certain IPs and ports are blocked externally, e.g. by your firewall, If certain IPs and ports are blocked externally, e.g. by
you should update your exit policy to reflect this -- otherwise Tor your firewall, you should update your exit policy to
users will be told that those destinations are down. reflect this -- otherwise Tor users will be told that
those destinations are down.
''; '';
}; };
};
};
}; };
}; config = mkIf cfg.enable {
};
###### implementation
config = mkIf (cfg.client.enable || cfg.relay.enable) {
assertions = singleton assertions = singleton
{ assertion = cfg.relay.enable -> !(cfg.relay.isBridge && cfg.relay.isExit); { message = "Can't be both an exit and a bridge relay at the same time";
message = "Can't be both an exit and a bridge relay at the same time"; assertion =
cfg.relay.enable -> !(cfg.relay.isBridge && cfg.relay.isExit);
}; };
users.extraUsers = singleton users.extraGroups.tor.gid = config.ids.gids.tor;
{ name = torUser; users.extraUsers.tor =
{ description = "Tor Daemon User";
createHome = true;
home = torDirectory;
group = "tor";
uid = config.ids.uids.tor; uid = config.ids.uids.tor;
description = "Tor daemon user";
home = stateDir;
}; };
jobs = { systemd.services.tor =
tor = { name = "tor"; { description = "Tor Daemon";
path = [ pkgs.tor ];
startOn = "started network-interfaces"; wantedBy = [ "multi-user.target" ];
stopOn = "stopping network-interfaces"; after = [ "network.target" ];
restartTriggers = [ torRcFile ];
preStart = '' # Translated from the upstream contrib/dist/tor.service.in
mkdir -m 0755 -p ${stateDir} serviceConfig =
chown ${torUser} ${stateDir} { Type = "simple";
''; ExecStartPre = "${pkgs.tor}/bin/tor -f ${torRcFile} --verify-config";
exec = "${tor}/bin/tor -f ${pkgs.writeText "torrc" cfg.config}"; ExecStart = "${pkgs.tor}/bin/tor -f ${torRcFile} --RunAsDaemon 0";
}; } ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
// optionalAttrs (cfg.client.privoxy.enable && cfg.client.enable) { KillSignal = "SIGINT";
torPrivoxy = { name = "tor-privoxy"; TimeoutSec = 30;
Restart = "on-failure";
startOn = "started network-interfaces"; LimitNOFILE = 32768;
stopOn = "stopping network-interfaces";
preStart = ''
mkdir -m 0755 -p ${privoxyDir}
chown ${torUser} ${privoxyDir}
'';
exec = "${privoxy}/sbin/privoxy --no-daemon --user ${torUser} ${pkgs.writeText "torPrivoxy.conf" cfg.client.privoxy.config}";
}; };
services.tor.config = ''
DataDirectory ${stateDir}
User ${torUser}
''
+ optionalString cfg.client.enable ''
SOCKSPort ${cfg.client.socksListenAddress} IsolateDestAddr
SOCKSPort ${cfg.client.socksListenAddressFaster}
${opt "SocksPolicy" cfg.client.socksPolicy}
''
+ optionalString cfg.relay.enable ''
ORPort ${toString cfg.relay.port}
${opt "ORListenAddress" cfg.relay.listenAddress }
${opt "Nickname" cfg.relay.nickname}
${optint "RelayBandwidthRate" cfg.relay.bandwidthRate}
${optint "RelayBandwidthBurst" cfg.relay.bandwidthBurst}
${if cfg.relay.isExit then opt "ExitPolicy" cfg.relay.exitPolicy else "ExitPolicy reject *:*"}
${if cfg.relay.isBridge then ''
BridgeRelay 1
ServerTransportPlugin obfs2,obfs3 exec ${pkgs.pythonPackages.obfsproxy}/bin/obfsproxy managed
'' else ""}
'';
services.tor.client.privoxy.config = ''
# Generally, this file goes in /etc/privoxy/config
#
# Tor listens as a SOCKS4a proxy here:
forward-socks4a / ${cfg.client.socksListenAddressFaster} .
confdir ${privoxy}/etc
logdir ${privoxyDir}
# actionsfile standard # Internal purpose, recommended
actionsfile default.action # Main actions file
actionsfile user.action # User customizations
filterfile default.filter
# Don't log interesting things, only startup messages, warnings and errors
logfile logfile
#jarfile jarfile
#debug 0 # show each GET/POST/CONNECT request
debug 4096 # Startup banner and warnings
debug 8192 # Errors - *we highly recommended enabling this*
user-manual ${privoxy}/doc/privoxy/user-manual
listen-address ${cfg.client.privoxy.listenAddress}
toggle 1
enable-remote-toggle 0
enable-edit-actions 0
enable-remote-http-toggle 0
buffer-limit 4096
# Extra config goes here
'';
# Hardening
# Note: DevicePolicy is set to 'closed', although the
# minimal permissions are really:
# DeviceAllow /dev/null rw
# DeviceAllow /dev/urandom r
# .. but we can't specify DeviceAllow multiple times. 'closed'
# is close enough.
PrivateTmp = "yes";
DevicePolicy = "closed";
InaccessibleDirectories = "/home";
ReadOnlyDirectories = "/";
ReadWriteDirectories = torDirectory;
NoNewPrivileges = "yes";
};
}; };
environment.systemPackages = [ pkgs.tor ];
};
} }

View File

@ -1,69 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.tor;
torify = pkgs.writeTextFile {
name = "torify";
text = ''
#!${pkgs.stdenv.shell}
TSOCKS_CONF_FILE=${pkgs.writeText "tsocks.conf" cfg.torify.config} LD_PRELOAD="${pkgs.tsocks}/lib/libtsocks.so $LD_PRELOAD" "$@"
'';
executable = true;
destination = "/bin/torify";
};
in
{
###### interface
options = {
services.tor.torify = {
enable = mkOption {
default = cfg.client.enable;
description = ''
Whether to build torify scipt to relay application traffic via TOR.
'';
};
server = mkOption {
default = "localhost:9050";
example = "192.168.0.20";
description = ''
IP address of TOR client to use.
'';
};
config = mkOption {
default = "";
description = ''
Extra configuration. Contents will be added verbatim to TSocks
configuration file.
'';
};
};
};
###### implementation
config = mkIf cfg.torify.enable {
environment.systemPackages = [ torify ]; # expose it to the users
services.tor.torify.config = ''
server = ${toString(head (splitString ":" cfg.torify.server))}
server_port = ${toString(tail (splitString ":" cfg.torify.server))}
local = 127.0.0.0/255.128.0.0
local = 127.128.0.0/255.192.0.0
'';
};
}

View File

@ -1,85 +1,100 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.services.tor.torsocks;
optionalNullStr = b: v: optionalString (b != null) v;
cfg = config.services.tor; configFile = ''
TorAddress ${toString (head (splitString ":" cfg.server))}
TorPort ${toString (tail (splitString ":" cfg.server))}
makeConfig = server: '' OnionAddrRange ${cfg.onionAddrRange}
server = ${toString(head (splitString ":" server))}
server_port = ${toString(tail (splitString ":" server))}
local = 127.0.0.0/255.128.0.0 ${optionalNullStr cfg.socks5Username
local = 127.128.0.0/255.192.0.0 "SOCKS5Username ${cfg.socks5Username}"}
local = 169.254.0.0/255.255.0.0 ${optionalNullStr cfg.socks5Password
local = 172.16.0.0/255.240.0.0 "SOCKS5Password ${cfg.socks5Password}"}
local = 192.168.0.0/255.255.0.0
${cfg.torsocks.config} AllowInbound ${if cfg.allowInbound then "1" else "0"}
''; '';
makeTorsocks = name: server: pkgs.writeTextFile {
name = name;
text = ''
#!${pkgs.stdenv.shell}
TORSOCKS_CONF_FILE=${pkgs.writeText "torsocks.conf" (makeConfig server)} LD_PRELOAD="${pkgs.torsocks}/lib/torsocks/libtorsocks.so $LD_PRELOAD" "$@"
'';
executable = true;
destination = "/bin/${name}";
};
torsocks = makeTorsocks "torsocks" cfg.torsocks.server;
torsocksFaster = makeTorsocks "torsocks-faster" cfg.torsocks.serverFaster;
in in
{ {
###### interface
options = { options = {
services.tor.torsocks = { services.tor.torsocks = {
enable = mkOption { enable = mkOption {
default = cfg.client.enable; type = types.bool;
default = false;
description = '' description = ''
Whether to build torsocks scipt to relay application traffic via TOR. Whether to build <literal>/etc/tor/torsocks.conf</literal>
containing the specified global torsocks configuration.
''; '';
}; };
server = mkOption { server = mkOption {
default = cfg.client.socksListenAddress; type = types.str;
example = "192.168.0.20:9050"; default = "127.0.0.1:9050";
example = "192.168.0.20:1234";
description = '' description = ''
IP address of TOR client to use. IP/Port of the Tor SOCKS server. Currently, hostnames are
NOT supported by torsocks.
''; '';
}; };
serverFaster = mkOption { onionAddrRange = mkOption {
default = cfg.client.socksListenAddressFaster; type = types.str;
example = "192.168.0.20:9063"; default = "127.42.42.0/24";
description = '' description = ''
IP address of TOR client to use for applications like web browsers which Tor hidden sites do not have real IP addresses. This
need less circuit isolation to achive satisfactory performance. specifies what range of IP addresses will be handed to the
application as "cookies" for .onion names. Of course, you
should pick a block of addresses which you aren't going to
ever need to actually connect to. This is similar to the
MapAddress feature of the main tor daemon.
''; '';
}; };
config = mkOption { socks5Username = mkOption {
default = ""; type = types.nullOr types.str;
default = null;
example = "bob";
description = '' description = ''
Extra configuration. Contents will be added verbatim to torsocks SOCKS5 username. The <literal>TORSOCKS_USERNAME</literal>
configuration file. environment variable overrides this option if it is set.
'';
};
socks5Password = mkOption {
type = types.nullOr types.str;
default = null;
example = "sekret";
description = ''
SOCKS5 password. The <literal>TORSOCKS_PASSWORD</literal>
environment variable overrides this option if it is set.
'';
};
allowInbound = mkOption {
type = types.bool;
default = false;
description = ''
Set Torsocks to accept inbound connections. If set to
<literal>true</literal>, listen() and accept() will be
allowed to be used with non localhost address.
''; '';
}; };
}; };
}; };
###### implementation config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.torsocks ];
config = mkIf cfg.torsocks.enable {
environment.systemPackages = [ torsocks torsocksFaster ]; # expose it to the users
};
environment.etc =
[ { source = pkgs.writeText "torsocks.conf" configFile;
target = "tor/torsocks.conf";
}
];
};
} }

View File

@ -0,0 +1,63 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.peerflix;
configFile = pkgs.writeText "peerflix-config.json" ''
{
"connections": 50,
"tmp": "${cfg.downloadDir}"
}
'';
in {
###### interface
options.services.peerflix = {
enable = mkOption {
description = "Whether to enable peerflix service.";
default = false;
type = types.uniq types.bool;
};
stateDir = mkOption {
description = "Peerflix state directory.";
default = "/var/lib/peerflix";
type = types.path;
};
downloadDir = mkOption {
description = "Peerflix temporary download directory.";
default = "${cfg.stateDir}/torrents";
type = types.path;
};
};
###### implementation
config = mkIf cfg.enable {
systemd.services.peerflix = {
description = "Peerflix Daemon";
wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" ];
environment.HOME = cfg.stateDir;
preStart = ''
mkdir -p "${cfg.stateDir}"/{torrents,.config/peerflix-server}
if [ "$(id -u)" = 0 ]; then chown -R peerflix "${cfg.stateDir}"; fi
ln -fs "${configFile}" "${cfg.stateDir}/.config/peerflix-server/config.json"
'';
serviceConfig = {
ExecStart = "${pkgs.nodePackages.peerflix-server}/bin/peerflix-server";
PermissionsStartOnly = true;
User = "peerflix";
};
};
users.extraUsers.peerflix.uid = config.ids.uids.peerflix;
};
}

View File

@ -341,8 +341,9 @@ addEntry("NixOS - Default", $defaultConfig);
$conf .= "$extraEntries\n" unless $extraEntriesBeforeNixOS; $conf .= "$extraEntries\n" unless $extraEntriesBeforeNixOS;
my $grubBootPath = $grubBoot->path;
# extraEntries could refer to @bootRoot@, which we have to substitute # extraEntries could refer to @bootRoot@, which we have to substitute
$conf =~ s/\@bootRoot\@/$grubBoot->path/g; $conf =~ s/\@bootRoot\@/$grubBootPath/g;
# Emit submenus for all system profiles. # Emit submenus for all system profiles.
sub addProfile { sub addProfile {

View File

@ -0,0 +1,64 @@
# This module adds a scripted iPXE entry to the GRUB boot menu.
{ config, lib, pkgs, ... }:
with lib;
let
scripts = builtins.attrNames config.boot.loader.grub.ipxe;
grubEntry = name:
''
menuentry "iPXE - ${name}" {
linux16 @bootRoot@/ipxe.lkrn
initrd16 @bootRoot@/${name}.ipxe
}
'';
scriptFile = name:
let
value = builtins.getAttr name config.boot.loader.grub.ipxe;
in
if builtins.typeOf value == "path" then value
else builtins.toFile "${name}.ipxe" value;
in
{
options =
{ boot.loader.grub.ipxe = mkOption {
type = types.attrsOf (types.either types.path types.str);
description =
''
Set of iPXE scripts available for
booting from the GRUB boot menu.
'';
default = { };
example = literalExample ''
{ demo = '''
#!ipxe
dhcp
chain http://boot.ipxe.org/demo/boot.php
''';
};
'';
};
};
config = mkIf (builtins.length scripts != 0) {
boot.loader.grub.extraEntries =
if config.boot.loader.grub.version == 2 then
toString (map grubEntry scripts)
else
throw "iPXE is not supported with GRUB 1.";
boot.loader.grub.extraFiles =
{ "ipxe.lkrn" = "${pkgs.ipxe}/ipxe.lkrn"; }
//
builtins.listToAttrs ( map
(name: { name = name+".ipxe"; value = scriptFile name; })
scripts
);
};
}

View File

@ -141,8 +141,6 @@ fi
# Use /etc/resolv.conf supplied by systemd-nspawn, if applicable. # Use /etc/resolv.conf supplied by systemd-nspawn, if applicable.
if [ -n "@useHostResolvConf@" -a -e /etc/resolv.conf ]; then if [ -n "@useHostResolvConf@" -a -e /etc/resolv.conf ]; then
cat /etc/resolv.conf | resolvconf -m 1000 -a host cat /etc/resolv.conf | resolvconf -m 1000 -a host
else
touch /etc/resolv.conf
fi fi

View File

@ -4,16 +4,185 @@ with lib;
let let
checkService = v: boolValues = [true false "yes" "no"];
let assertValueOneOf = name: values: attr:
let val = attr.${name}; assertValueOneOf = name: values: group: attr:
in optional (attr ? ${name} && !elem val values) "Systemd service field `${name}' cannot have value `${val}'."; optional (attr ? ${name} && !elem attr.${name} values)
checkType = assertValueOneOf "Type" ["simple" "forking" "oneshot" "dbus" "notify" "idle"]; "Systemd ${group} field `${name}' cannot have value `${attr.${name}}'.";
checkRestart = assertValueOneOf "Restart" ["no" "on-success" "on-failure" "on-abort" "always"];
errors = concatMap (c: c v) [checkType checkRestart]; assertHasField = name: group: attr:
in if errors == [] then true optional (!(attr ? ${name}))
"Systemd ${group} field `${name}' must exist.";
assertOnlyFields = fields: group: attr:
let badFields = filter (name: ! elem name fields) (attrNames attr); in
optional (badFields != [ ])
"Systemd ${group} has extra fields [${concatStringsSep " " badFields}].";
assertRange = name: min: max: group: attr:
optional (attr ? ${name} && !(min <= attr.${name} && max >= attr.${name}))
"Systemd ${group} field `${name}' is outside the range [${toString min},${toString max}]";
digits = map toString (range 0 9);
isByteFormat = s:
let
l = reverseList (stringToCharacters s);
suffix = head l;
nums = tail l;
in elem suffix (["K" "M" "G" "T"] ++ digits)
&& all (num: elem num digits) nums;
assertByteFormat = name: group: attr:
optional (attr ? ${name} && ! isByteFormat attr.${name})
"Systemd ${group} field `${name}' must be in byte format [0-9]+[KMGT].";
hexChars = stringToCharacters "0123456789abcdefABCDEF";
isMacAddress = s: stringLength s == 17
&& flip all (splitString ":" s) (bytes:
all (byte: elem byte hexChars) (stringToCharacters bytes)
);
assertMacAddress = name: group: attr:
optional (attr ? ${name} && ! isMacAddress attr.${name})
"Systemd ${group} field `${name}' must be a valid mac address.";
checkUnitConfig = group: checks: v:
let errors = concatMap (c: c group v) checks; in
if errors == [] then true
else builtins.trace (concatStringsSep "\n" errors) false; else builtins.trace (concatStringsSep "\n" errors) false;
checkService = checkUnitConfig "Service" [
(assertValueOneOf "Type" [
"simple" "forking" "oneshot" "dbus" "notify" "idle"
])
(assertValueOneOf "Restart" [
"no" "on-success" "on-failure" "on-abort" "always"
])
];
checkLink = checkUnitConfig "Link" [
(assertOnlyFields [
"Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "Name"
"MTUBytes" "BitsPerSecond" "Duplex" "WakeOnLan"
])
(assertValueOneOf "MACAddressPolicy" ["persistent" "random"])
(assertMacAddress "MACAddress")
(assertValueOneOf "NamePolicy" [
"kernel" "database" "onboard" "slot" "path" "mac"
])
(assertByteFormat "MTUBytes")
(assertByteFormat "BitsPerSecond")
(assertValueOneOf "Duplex" ["half" "full"])
(assertValueOneOf "WakeOnLan" ["phy" "magic" "off"])
];
checkNetdev = checkUnitConfig "Netdev" [
(assertOnlyFields [
"Description" "Name" "Kind" "MTUBytes" "MACAddress"
])
(assertHasField "Name")
(assertHasField "Kind")
(assertValueOneOf "Kind" [
"bridge" "bond" "vlan" "macvlan" "vxlan" "ipip"
"gre" "sit" "vti" "veth" "tun" "tap" "dummy"
])
(assertByteFormat "MTUBytes")
(assertMacAddress "MACAddress")
];
checkVlan = checkUnitConfig "VLAN" [
(assertOnlyFields ["Id"])
(assertRange "Id" 0 4094)
];
checkMacvlan = checkUnitConfig "MACVLAN" [
(assertOnlyFields ["Mode"])
(assertValueOneOf "Mode" ["private" "vepa" "bridge" "passthru"])
];
checkVxlan = checkUnitConfig "VXLAN" [
(assertOnlyFields ["Id" "Group" "TOS" "TTL" "MacLearning"])
(assertRange "TTL" 0 255)
(assertValueOneOf "MacLearning" boolValues)
];
checkTunnel = checkUnitConfig "Tunnel" [
(assertOnlyFields ["Local" "Remote" "TOS" "TTL" "DiscoverPathMTU"])
(assertRange "TTL" 0 255)
(assertValueOneOf "DiscoverPathMTU" boolValues)
];
checkPeer = checkUnitConfig "Peer" [
(assertOnlyFields ["Name" "MACAddress"])
(assertMacAddress "MACAddress")
];
tunTapChecks = [
(assertOnlyFields ["OneQueue" "MultiQueue" "PacketInfo" "User" "Group"])
(assertValueOneOf "OneQueue" boolValues)
(assertValueOneOf "MultiQueue" boolValues)
(assertValueOneOf "PacketInfo" boolValues)
];
checkTun = checkUnitConfig "Tun" tunTapChecks;
checkTap = checkUnitConfig "Tap" tunTapChecks;
checkBond = checkUnitConfig "Bond" [
(assertOnlyFields [
"Mode" "TransmitHashPolicy" "LACPTransmitRate" "MIIMonitorSec"
"UpDelaySec" "DownDelaySec"
])
(assertValueOneOf "Mode" [
"balance-rr" "active-backup" "balance-xor"
"broadcast" "802.3ad" "balance-tlb" "balance-alb"
])
(assertValueOneOf "TransmitHashPolicy" [
"layer2" "layer3+4" "layer2+3" "encap2+3" "802.3ad" "encap3+4"
])
(assertValueOneOf "LACPTransmitRate" ["slow" "fast"])
];
checkNetwork = checkUnitConfig "Network" [
(assertOnlyFields [
"Description" "DHCP" "DHCPServer" "IPv4LL" "IPv4LLRoute"
"LLMNR" "Domains" "Bridge" "Bond"
])
(assertValueOneOf "DHCP" ["both" "none" "v4" "v6"])
(assertValueOneOf "DHCPServer" boolValues)
(assertValueOneOf "IPv4LL" boolValues)
(assertValueOneOf "IPv4LLRoute" boolValues)
(assertValueOneOf "LLMNR" boolValues)
];
checkAddress = checkUnitConfig "Address" [
(assertOnlyFields ["Address" "Peer" "Broadcast" "Label"])
(assertHasField "Address")
];
checkRoute = checkUnitConfig "Route" [
(assertOnlyFields ["Gateway" "Destination" "Metric"])
(assertHasField "Gateway")
];
checkDhcp = checkUnitConfig "DHCP" [
(assertOnlyFields [
"UseDNS" "UseMTU" "SendHostname" "UseHostname" "UseDomains" "UseRoutes"
"CriticalConnections" "VendorClassIdentifier" "RequestBroadcast"
"RouteMetric"
])
(assertValueOneOf "UseDNS" boolValues)
(assertValueOneOf "UseMTU" boolValues)
(assertValueOneOf "SendHostname" boolValues)
(assertValueOneOf "UseHostname" boolValues)
(assertValueOneOf "UseDomains" boolValues)
(assertValueOneOf "UseRoutes" boolValues)
(assertValueOneOf "CriticalConnections" boolValues)
(assertValueOneOf "RequestBroadcast" boolValues)
];
unitOption = mkOptionType { unitOption = mkOptionType {
name = "systemd option"; name = "systemd option";
merge = loc: defs: merge = loc: defs:
@ -140,6 +309,15 @@ in rec {
''; '';
}; };
requisite = mkOption {
default = [];
type = types.listOf types.str;
description = ''
Similar to requires. However if the units listed are not started,
they will not be started and the transaction will fail.
'';
};
unitConfig = mkOption { unitConfig = mkOption {
default = {}; default = {};
example = { RequiresMountsFor = "/data"; }; example = { RequiresMountsFor = "/data"; };
@ -441,4 +619,345 @@ in rec {
targetOptions = commonUnitOptions; targetOptions = commonUnitOptions;
commonNetworkOptions = {
enable = mkOption {
default = true;
type = types.bool;
description = ''
If set to false, this unit will be a symlink to
/dev/null.
'';
};
matchConfig = mkOption {
default = {};
example = { Name = "eth0"; };
type = types.attrsOf unitOption;
description = ''
Each attribute in this set specifies an option in the
<literal>[Match]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.
'';
};
};
linkOptions = commonNetworkOptions // {
linkConfig = mkOption {
default = {};
example = { MACAddress = "00:ff:ee:aa:cc:dd"; };
type = types.addCheck (types.attrsOf unitOption) checkLink;
description = ''
Each attribute in this set specifies an option in the
<literal>[Link]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.link</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
};
netdevOptions = commonNetworkOptions // {
netdevConfig = mkOption {
default = {};
example = { Name = "mybridge"; Kind = "bridge"; };
type = types.addCheck (types.attrsOf unitOption) checkNetdev;
description = ''
Each attribute in this set specifies an option in the
<literal>[Netdev]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.netdev</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
vlanConfig = mkOption {
default = {};
example = { Id = "4"; };
type = types.addCheck (types.attrsOf unitOption) checkVlan;
description = ''
Each attribute in this set specifies an option in the
<literal>[VLAN]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.netdev</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
macvlanConfig = mkOption {
default = {};
example = { Mode = "private"; };
type = types.addCheck (types.attrsOf unitOption) checkMacvlan;
description = ''
Each attribute in this set specifies an option in the
<literal>[MACVLAN]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.netdev</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
vxlanConfig = mkOption {
default = {};
example = { Id = "4"; };
type = types.addCheck (types.attrsOf unitOption) checkVxlan;
description = ''
Each attribute in this set specifies an option in the
<literal>[VXLAN]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.netdev</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
tunnelConfig = mkOption {
default = {};
example = { Remote = "192.168.1.1"; };
type = types.addCheck (types.attrsOf unitOption) checkTunnel;
description = ''
Each attribute in this set specifies an option in the
<literal>[Tunnel]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.netdev</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
peerConfig = mkOption {
default = {};
example = { Name = "veth2"; };
type = types.addCheck (types.attrsOf unitOption) checkPeer;
description = ''
Each attribute in this set specifies an option in the
<literal>[Peer]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.netdev</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
tunConfig = mkOption {
default = {};
example = { User = "openvpn"; };
type = types.addCheck (types.attrsOf unitOption) checkTun;
description = ''
Each attribute in this set specifies an option in the
<literal>[Tun]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.netdev</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
tapConfig = mkOption {
default = {};
example = { User = "openvpn"; };
type = types.addCheck (types.attrsOf unitOption) checkTap;
description = ''
Each attribute in this set specifies an option in the
<literal>[Tap]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.netdev</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
bondConfig = mkOption {
default = {};
example = { Mode = "802.3ad"; };
type = types.addCheck (types.attrsOf unitOption) checkBond;
description = ''
Each attribute in this set specifies an option in the
<literal>[Bond]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.netdev</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
};
addressOptions = {
addressConfig = mkOption {
default = {};
example = { Address = "192.168.0.100/24"; };
type = types.addCheck (types.attrsOf unitOption) checkAddress;
description = ''
Each attribute in this set specifies an option in the
<literal>[Address]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
};
routeOptions = {
routeConfig = mkOption {
default = {};
example = { Gateway = "192.168.0.1"; };
type = types.addCheck (types.attrsOf unitOption) checkRoute;
description = ''
Each attribute in this set specifies an option in the
<literal>[Route]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
};
networkOptions = commonNetworkOptions // {
networkConfig = mkOption {
default = {};
example = { Description = "My Network"; };
type = types.addCheck (types.attrsOf unitOption) checkNetwork;
description = ''
Each attribute in this set specifies an option in the
<literal>[Network]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
dhcpConfig = mkOption {
default = {};
example = { UseDNS = true; UseRoutes = true; };
type = types.addCheck (types.attrsOf unitOption) checkDhcp;
description = ''
Each attribute in this set specifies an option in the
<literal>[DHCP]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
name = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
The name of the network interface to match against.
'';
};
DHCP = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Whether to enable DHCP on the interfaces matched.
'';
};
domains = mkOption {
type = types.nullOr (types.listOf types.str);
default = null;
description = ''
A list of domains to pass to the network config.
'';
};
address = mkOption {
default = [ ];
type = types.listOf types.str;
description = ''
A list of addresses to be added to the network section of the
unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
gateway = mkOption {
default = [ ];
type = types.listOf types.str;
description = ''
A list of gateways to be added to the network section of the
unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
dns = mkOption {
default = [ ];
type = types.listOf types.str;
description = ''
A list of dns servers to be added to the network section of the
unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
ntp = mkOption {
default = [ ];
type = types.listOf types.str;
description = ''
A list of ntp servers to be added to the network section of the
unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
vlan = mkOption {
default = [ ];
type = types.listOf types.str;
description = ''
A list of vlan interfaces to be added to the network section of the
unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
macvlan = mkOption {
default = [ ];
type = types.listOf types.str;
description = ''
A list of macvlan interfaces to be added to the network section of the
unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
vxlan = mkOption {
default = [ ];
type = types.listOf types.str;
description = ''
A list of vxlan interfaces to be added to the network section of the
unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
tunnel = mkOption {
default = [ ];
type = types.listOf types.str;
description = ''
A list of tunnel interfaces to be added to the network section of the
unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
addresses = mkOption {
default = [ ];
type = types.listOf types.optionSet;
options = [ addressOptions ];
description = ''
A list of address sections to be added to the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
routes = mkOption {
default = [ ];
type = types.listOf types.optionSet;
options = [ routeOptions ];
description = ''
A list of route sections to be added to the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
};
} }

View File

@ -36,6 +36,7 @@ let
"graphical.target" "graphical.target"
"multi-user.target" "multi-user.target"
"network.target" "network.target"
"network-pre.target"
"network-online.target" "network-online.target"
"nss-lookup.target" "nss-lookup.target"
"nss-user-lookup.target" "nss-user-lookup.target"
@ -96,6 +97,12 @@ let
"systemd-modules-load.service" "systemd-modules-load.service"
"kmod-static-nodes.service" "kmod-static-nodes.service"
# Networking
"systemd-networkd.service"
"systemd-networkd-wait-online.service"
"systemd-resolved.service"
"systemd-timesyncd.service"
# Filesystems. # Filesystems.
"systemd-fsck@.service" "systemd-fsck@.service"
"systemd-fsck-root.service" "systemd-fsck-root.service"
@ -212,6 +219,8 @@ let
{ PartOf = toString config.partOf; } { PartOf = toString config.partOf; }
// optionalAttrs (config.conflicts != []) // optionalAttrs (config.conflicts != [])
{ Conflicts = toString config.conflicts; } { Conflicts = toString config.conflicts; }
// optionalAttrs (config.requisite != [])
{ Requisite = toString config.requisite; }
// optionalAttrs (config.restartTriggers != []) // optionalAttrs (config.restartTriggers != [])
{ X-Restart-Triggers = toString config.restartTriggers; } { X-Restart-Triggers = toString config.restartTriggers; }
// optionalAttrs (config.description != "") { // optionalAttrs (config.description != "") {
@ -292,6 +301,19 @@ let
}; };
}; };
networkConfig = { name, config, ... }: {
config = {
matchConfig = optionalAttrs (config.name != null) {
Name = config.name;
};
networkConfig = optionalAttrs (config.DHCP != null) {
DHCP = config.DHCP;
} // optionalAttrs (config.domains != null) {
Domains = concatStringsSep " " config.domains;
};
};
};
toOption = x: toOption = x:
if x == true then "true" if x == true then "true"
else if x == false then "false" else if x == false then "false"
@ -384,6 +406,103 @@ let
''; '';
}; };
commonMatchText = def: ''
[Match]
${attrsToSection def.matchConfig}
'';
linkToUnit = name: def:
{ inherit (def) enable;
text = commonMatchText def +
''
[Link]
${attrsToSection def.linkConfig}
'';
};
netdevToUnit = name: def:
{ inherit (def) enable;
text = commonMatchText def +
''
[NetDev]
${attrsToSection def.netdevConfig}
${optionalString (def.vlanConfig != { }) ''
[VLAN]
${attrsToSection def.vlanConfig}
''}
${optionalString (def.macvlanConfig != { }) ''
[MACVLAN]
${attrsToSection def.macvlanConfig}
''}
${optionalString (def.vxlanConfig != { }) ''
[VXLAN]
${attrsToSection def.vxlanConfig}
''}
${optionalString (def.tunnelConfig != { }) ''
[Tunnel]
${attrsToSection def.tunnelConfig}
''}
${optionalString (def.peerConfig != { }) ''
[Peer]
${attrsToSection def.peerConfig}
''}
${optionalString (def.tunConfig != { }) ''
[Tun]
${attrsToSection def.tunConfig}
''}
${optionalString (def.tapConfig != { }) ''
[Tap]
${attrsToSection def.tapConfig}
''}
${optionalString (def.bondConfig != { }) ''
[Bond]
${attrsToSection def.bondConfig}
''}
'';
};
networkToUnit = name: def:
{ inherit (def) enable;
text = commonMatchText def +
''
[Network]
${attrsToSection def.networkConfig}
${concatStringsSep "\n" (map (s: "Address=${s}") def.address)}
${concatStringsSep "\n" (map (s: "Gateway=${s}") def.gateway)}
${concatStringsSep "\n" (map (s: "DNS=${s}") def.dns)}
${concatStringsSep "\n" (map (s: "NTP=${s}") def.ntp)}
${concatStringsSep "\n" (map (s: "VLAN=${s}") def.vlan)}
${concatStringsSep "\n" (map (s: "MACVLAN=${s}") def.macvlan)}
${concatStringsSep "\n" (map (s: "VXLAN=${s}") def.vxlan)}
${concatStringsSep "\n" (map (s: "Tunnel=${s}") def.tunnel)}
${optionalString (def.dhcpConfig != { }) ''
[DHCP]
${attrsToSection def.dhcpConfig}
''}
${flip concatMapStrings def.addresses (x: ''
[Address]
${attrsToSection x.addressConfig}
'')}
${flip concatMapStrings def.routes (x: ''
[Route]
${attrsToSection x.routeConfig}
'')}
'';
};
generateUnits = type: units: upstreamUnits: upstreamWants: generateUnits = type: units: upstreamUnits: upstreamWants:
pkgs.runCommand "${type}-units" { preferLocalBuild = true; } '' pkgs.runCommand "${type}-units" { preferLocalBuild = true; } ''
mkdir -p $out mkdir -p $out
@ -468,8 +587,9 @@ let
mkdir -p $out/getty.target.wants/ mkdir -p $out/getty.target.wants/
ln -s ../autovt@tty1.service $out/getty.target.wants/ ln -s ../autovt@tty1.service $out/getty.target.wants/
ln -s ../local-fs.target ../remote-fs.target ../network.target ../nss-lookup.target \ ln -s ../local-fs.target ../remote-fs.target ../network.target \
../nss-user-lookup.target ../swap.target $out/multi-user.target.wants/ ../nss-lookup.target ../nss-user-lookup.target ../swap.target \
$out/multi-user.target.wants/
''} ''}
''; # */ ''; # */
@ -562,6 +682,47 @@ in
''; '';
}; };
systemd.network.enable = mkOption {
default = false;
type = types.bool;
description = ''
Whether to enable networkd or not.
'';
};
systemd.network.links = mkOption {
default = {};
type = types.attrsOf types.optionSet;
options = [ linkOptions ];
description = "Definiton of systemd network links.";
};
systemd.network.netdevs = mkOption {
default = {};
type = types.attrsOf types.optionSet;
options = [ netdevOptions ];
description = "Definiton of systemd network devices.";
};
systemd.network.networks = mkOption {
default = {};
type = types.attrsOf types.optionSet;
options = [ networkOptions networkConfig ];
description = "Definiton of systemd networks.";
};
systemd.network.units = mkOption {
description = "Definition of networkd units.";
default = {};
type = types.attrsOf types.optionSet;
options = { name, config, ... }:
{ options = concreteUnitOptions;
config = {
unit = mkDefault (makeUnit name config);
};
};
};
systemd.defaultUnit = mkOption { systemd.defaultUnit = mkOption {
default = "multi-user.target"; default = "multi-user.target";
type = types.str; type = types.str;
@ -645,6 +806,22 @@ in
''; '';
}; };
services.resolved.enable = mkOption {
default = false;
type = types.bool;
description = ''
Enables the systemd dns resolver daemon.
'';
};
services.timesyncd.enable = mkOption {
default = false;
type = types.bool;
description = ''
Enables the systemd ntp client daemon.
'';
};
systemd.tmpfiles.rules = mkOption { systemd.tmpfiles.rules = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [];
@ -701,7 +878,7 @@ in
###### implementation ###### implementation
config = { config = mkMerge [ {
warnings = concatLists (mapAttrsToList (name: service: warnings = concatLists (mapAttrsToList (name: service:
optional (service.serviceConfig.Type or "" == "oneshot" && service.serviceConfig.Restart or "no" != "no") optional (service.serviceConfig.Type or "" == "oneshot" && service.serviceConfig.Restart or "no" != "no")
@ -714,6 +891,9 @@ in
environment.etc."systemd/system".source = environment.etc."systemd/system".source =
generateUnits "system" cfg.units upstreamSystemUnits upstreamSystemWants; generateUnits "system" cfg.units upstreamSystemUnits upstreamSystemWants;
environment.etc."systemd/network".source =
generateUnits "network" cfg.network.units [] [];
environment.etc."systemd/user".source = environment.etc."systemd/user".source =
generateUnits "user" cfg.user.units upstreamUserUnits []; generateUnits "user" cfg.user.units upstreamUserUnits [];
@ -766,6 +946,18 @@ in
unitConfig.X-StopOnReconfiguration = true; unitConfig.X-StopOnReconfiguration = true;
}; };
systemd.targets.network-online.after = [ "ip-up.target" ];
systemd.targets.network-pre = {
wantedBy = [ "network.target" ];
before = [ "network.target" ];
};
systemd.targets.remote-fs-pre = {
wantedBy = [ "remote-fs.target" ];
before = [ "remote-fs.target" ];
};
systemd.units = systemd.units =
mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets
// mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services
@ -779,6 +971,11 @@ in
(v: let n = escapeSystemdPath v.where; (v: let n = escapeSystemdPath v.where;
in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts); in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts);
systemd.network.units =
mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.network.links
// mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.network.netdevs
// mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.network.networks;
systemd.user.units = systemd.user.units =
mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.user.services mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.user.services
// mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.user.sockets; // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.user.sockets;
@ -800,6 +997,15 @@ in
users.extraUsers.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway; users.extraUsers.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway;
users.extraGroups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway; users.extraGroups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway;
users.extraUsers.systemd-network.uid = config.ids.uids.systemd-network;
users.extraGroups.systemd-network.gid = config.ids.gids.systemd-network;
users.extraUsers.systemd-resolve.uid = config.ids.uids.systemd-resolve;
users.extraGroups.systemd-resolve.gid = config.ids.gids.systemd-resolve;
users.extraUsers.systemd-timesync.uid = config.ids.uids.systemd-timesync;
users.extraGroups.systemd-timesync.gid = config.ids.gids.systemd-timesync;
# Generate timer units for all services that have a startAt value. # Generate timer units for all services that have a startAt value.
systemd.timers = systemd.timers =
mapAttrs (name: service: mapAttrs (name: service:
@ -833,5 +1039,57 @@ in
systemd.services.systemd-remount-fs.restartIfChanged = false; systemd.services.systemd-remount-fs.restartIfChanged = false;
systemd.services.systemd-journal-flush.restartIfChanged = false; systemd.services.systemd-journal-flush.restartIfChanged = false;
}; }
(mkIf config.systemd.network.enable {
systemd.services.systemd-networkd = {
wantedBy = [ "multi-user.target" ];
before = [ "network-interfaces.target" ];
restartTriggers = [ config.environment.etc."systemd/network".source ];
};
systemd.services.systemd-networkd-wait-online = {
before = [ "network-online.target" "ip-up.target" ];
wantedBy = [ "network-online.target" "ip-up.target" ];
};
systemd.services."systemd-network-wait-online@" = {
description = "Wait for Network Interface %I to be Configured";
conflicts = [ "shutdown.target" ];
requisite = [ "systemd-networkd.service" ];
after = [ "systemd-networkd.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "${config.systemd.package}/lib/systemd/systemd-networkd-wait-online -i %I";
};
};
services.resolved.enable = mkDefault true;
services.timesyncd.enable = mkDefault config.services.ntp.enable;
})
(mkIf config.services.resolved.enable {
systemd.services.systemd-resolved = {
wantedBy = [ "multi-user.target" ];
restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ];
};
environment.etc."systemd/resolved.conf".text = ''
[Resolve]
DNS=${concatStringsSep " " config.networking.nameservers}
'';
})
(mkIf config.services.timesyncd.enable {
systemd.services.systemd-timesyncd = {
wantedBy = [ "sysinit.target" ];
restartTriggers = [ config.environment.etc."systemd/timesyncd.conf".source ];
};
environment.etc."systemd/timesyncd.conf".text = ''
[Time]
NTP=${concatStringsSep " " config.services.ntp.servers}
'';
systemd.services.ntpd.enable = false;
})
];
} }

View File

@ -13,7 +13,7 @@ let
idmapdConfFile = pkgs.writeText "idmapd.conf" '' idmapdConfFile = pkgs.writeText "idmapd.conf" ''
[General] [General]
Pipefs-Directory = ${rpcMountpoint} Pipefs-Directory = ${rpcMountpoint}
${optionalString (config.networking.domain != "") ${optionalString (config.networking.domain != null)
"Domain = ${config.networking.domain}"} "Domain = ${config.networking.domain}"}
[Mapping] [Mapping]
@ -58,7 +58,7 @@ in
services.rpcbind.enable = true; services.rpcbind.enable = true;
system.fsPackages = [ pkgs.nfsUtils ]; system.fsPackages = [ pkgs.nfs-utils ];
boot.extraModprobeConfig = mkIf (cfg.lockdPort != null) '' boot.extraModprobeConfig = mkIf (cfg.lockdPort != null) ''
options lockd nlm_udpport=${toString cfg.lockdPort} nlm_tcpport=${toString cfg.lockdPort} options lockd nlm_udpport=${toString cfg.lockdPort} nlm_tcpport=${toString cfg.lockdPort}
@ -71,12 +71,12 @@ in
systemd.services.statd = systemd.services.statd =
{ description = "NFSv3 Network Status Monitor"; { description = "NFSv3 Network Status Monitor";
path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; path = [ pkgs.nfs-utils pkgs.sysvtools pkgs.utillinux ];
wantedBy = [ "network-online.target" "multi-user.target" ]; wantedBy = [ "remote-fs-pre.target" ];
before = [ "network-online.target" ]; before = [ "remote-fs-pre.target" ];
requires = [ "basic.target" "rpcbind.service" ]; requires = [ "basic.target" "rpcbind.service" ];
after = [ "basic.target" "rpcbind.service" "network.target" ]; after = [ "basic.target" "rpcbind.service" ];
unitConfig.DefaultDependencies = false; # don't stop during shutdown unitConfig.DefaultDependencies = false; # don't stop during shutdown
@ -89,7 +89,7 @@ in
serviceConfig.Type = "forking"; serviceConfig.Type = "forking";
serviceConfig.ExecStart = '' serviceConfig.ExecStart = ''
@${pkgs.nfsUtils}/sbin/rpc.statd rpc.statd --no-notify \ @${pkgs.nfs-utils}/sbin/rpc.statd rpc.statd --no-notify \
${if cfg.statdPort != null then "-p ${toString statdPort}" else ""} ${if cfg.statdPort != null then "-p ${toString statdPort}" else ""}
''; '';
serviceConfig.Restart = "always"; serviceConfig.Restart = "always";
@ -100,8 +100,8 @@ in
path = [ pkgs.sysvtools pkgs.utillinux ]; path = [ pkgs.sysvtools pkgs.utillinux ];
wantedBy = [ "network-online.target" "multi-user.target" ]; wantedBy = [ "remote-fs-pre.target" ];
before = [ "network-online.target" ]; before = [ "remote-fs-pre.target" ];
requires = [ "rpcbind.service" ]; requires = [ "rpcbind.service" ];
after = [ "rpcbind.service" ]; after = [ "rpcbind.service" ];
@ -117,7 +117,7 @@ in
''; '';
serviceConfig.Type = "forking"; serviceConfig.Type = "forking";
serviceConfig.ExecStart = "@${pkgs.nfsUtils}/sbin/rpc.idmapd rpc.idmapd -c ${idmapdConfFile}"; serviceConfig.ExecStart = "@${pkgs.nfs-utils}/sbin/rpc.idmapd rpc.idmapd -c ${idmapdConfFile}";
serviceConfig.Restart = "always"; serviceConfig.Restart = "always";
}; };

View File

@ -0,0 +1,342 @@
{ config, lib, pkgs, utils, ... }:
with lib;
with utils;
let
cfg = config.networking;
interfaces = attrValues cfg.interfaces;
hasVirtuals = any (i: i.virtual) interfaces;
# We must escape interfaces due to the systemd interpretation
subsystemDevice = interface:
"sys-subsystem-net-devices-${escapeSystemdPath interface}.device";
interfaceIps = i:
i.ip4 ++ optionals cfg.enableIPv6 i.ip6
++ optional (i.ipAddress != null) {
address = i.ipAddress;
prefixLength = i.prefixLength;
} ++ optional (cfg.enableIPv6 && i.ipv6Address != null) {
address = i.ipv6Address;
prefixLength = i.ipv6PrefixLength;
};
destroyBond = i: ''
while true; do
UPDATED=1
SLAVES=$(ip link | grep 'master ${i}' | awk -F: '{print $2}')
for I in $SLAVES; do
UPDATED=0
ip link set "$I" nomaster
done
[ "$UPDATED" -eq "1" ] && break
done
ip link set "${i}" down 2>/dev/null || true
ip link del "${i}" 2>/dev/null || true
'';
in
{
config = mkIf (!cfg.useNetworkd) {
systemd.services =
let
networkLocalCommands = {
after = [ "network-setup.service" ];
bindsTo = [ "network-setup.service" ];
};
networkSetup =
{ description = "Networking Setup";
after = [ "network-interfaces.target" "network-pre.target" ];
before = [ "network.target" ];
wantedBy = [ "network.target" ];
unitConfig.ConditionCapability = "CAP_NET_ADMIN";
path = [ pkgs.iproute ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
script =
''
# Set the static DNS configuration, if given.
${pkgs.openresolv}/sbin/resolvconf -m 1 -a static <<EOF
${optionalString (cfg.nameservers != [] && cfg.domain != null) ''
domain ${cfg.domain}
''}
${optionalString (cfg.search != []) ("search " + concatStringsSep " " cfg.search)}
${flip concatMapStrings cfg.nameservers (ns: ''
nameserver ${ns}
'')}
EOF
# Set the default gateway.
${optionalString (cfg.defaultGateway != null && cfg.defaultGateway != "") ''
# FIXME: get rid of "|| true" (necessary to make it idempotent).
ip route add default via "${cfg.defaultGateway}" ${
optionalString (cfg.defaultGatewayWindowSize != null)
"window ${cfg.defaultGatewayWindowSize}"} || true
''}
'';
};
# For each interface <foo>, create a job network-addresses-<foo>.service"
# that performs static address configuration. It has a "wants"
# dependency on <foo>.service, which is supposed to create
# the interface and need not exist (i.e. for hardware
# interfaces). It has a binds-to dependency on the actual
# network device, so it only gets started after the interface
# has appeared, and it's stopped when the interface
# disappears.
configureAddrs = i:
let
ips = interfaceIps i;
in
nameValuePair "network-addresses-${i.name}"
{ description = "Addresss configuration of ${i.name}";
wantedBy = [ "network-interfaces.target" ];
before = [ "network-interfaces.target" ];
bindsTo = [ (subsystemDevice i.name) ];
after = [ (subsystemDevice i.name) "network-pre.target" ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.iproute ];
script =
''
echo "bringing up interface..."
ip link set "${i.name}" up
restart_network_interfaces=false
'' + flip concatMapStrings (ips) (ip:
let
address = "${ip.address}/${toString ip.prefixLength}";
in
''
echo "checking ip ${address}..."
if out=$(ip addr add "${address}" dev "${i.name}" 2>&1); then
echo "added ip ${address}..."
restart_network_setup=true
elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then
echo "failed to add ${address}"
exit 1
fi
'')
+ optionalString (ips != [ ])
''
if [ "$restart_network_setup" = "true" ]; then
# Ensure that the default gateway remains set.
# (Flushing this interface may have removed it.)
${config.systemd.package}/bin/systemctl try-restart --no-block network-setup.service
fi
${config.systemd.package}/bin/systemctl start ip-up.target
'';
preStop =
''
echo "releasing configured ip's..."
'' + flip concatMapStrings (ips) (ip:
let
address = "${ip.address}/${toString ip.prefixLength}";
in
''
echo -n "Deleting ${address}..."
ip addr del "${address}" dev "${i.name}" >/dev/null 2>&1 || echo -n " Failed"
echo ""
'');
};
createTunDevice = i: nameValuePair "${i.name}-netdev"
{ description = "Virtual Network Interface ${i.name}";
requires = [ "dev-net-tun.device" ];
after = [ "dev-net-tun.device" "network-pre.target" ];
wantedBy = [ "network.target" (subsystemDevice i.name) ];
before = [ "network-interfaces.target" (subsystemDevice i.name) ];
path = [ pkgs.iproute ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
ip tuntap add dev "${i.name}" \
${optionalString (i.virtualType != null) "mode ${i.virtualType}"} \
user "${i.virtualOwner}"
'';
postStop = ''
ip link del ${i.name}
'';
};
createBridgeDevice = n: v: nameValuePair "${n}-netdev"
(let
deps = map subsystemDevice v.interfaces;
in
{ description = "Bridge Interface ${n}";
wantedBy = [ "network.target" (subsystemDevice n) ];
bindsTo = deps;
after = [ "network-pre.target" ] ++ deps
++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces;
before = [ "network-interfaces.target" (subsystemDevice n) ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.iproute ];
script = ''
# Remove Dead Interfaces
echo "Removing old bridge ${n}..."
ip link show "${n}" >/dev/null 2>&1 && ip link del "${n}"
echo "Adding bridge ${n}..."
ip link add name "${n}" type bridge
# Enslave child interfaces
${flip concatMapStrings v.interfaces (i: ''
ip link set "${i}" master "${n}"
ip link set "${i}" up
'')}
ip link set "${n}" up
'';
postStop = ''
ip link set "${n}" down || true
ip link del "${n}" || true
'';
});
createBondDevice = n: v: nameValuePair "${n}-netdev"
(let
deps = map subsystemDevice v.interfaces;
in
{ description = "Bond Interface ${n}";
wantedBy = [ "network.target" (subsystemDevice n) ];
bindsTo = deps;
after = [ "network-pre.target" ] ++ deps
++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces;
before = [ "network-interfaces.target" (subsystemDevice n) ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.iproute pkgs.gawk ];
script = ''
echo "Destroying old bond ${n}..."
${destroyBond n}
echo "Creating new bond ${n}..."
ip link add name "${n}" type bond \
${optionalString (v.mode != null) "mode ${toString v.mode}"} \
${optionalString (v.miimon != null) "miimon ${toString v.miimon}"} \
${optionalString (v.xmit_hash_policy != null) "xmit_hash_policy ${toString v.xmit_hash_policy}"} \
${optionalString (v.lacp_rate != null) "lacp_rate ${toString v.lacp_rate}"}
# !!! There must be a better way to wait for the interface
while [ ! -d "/sys/class/net/${n}" ]; do sleep 0.1; done;
# Bring up the bond and enslave the specified interfaces
ip link set "${n}" up
${flip concatMapStrings v.interfaces (i: ''
ip link set "${i}" down
ip link set "${i}" master "${n}"
'')}
'';
postStop = destroyBond n;
});
createMacvlanDevice = n: v: nameValuePair "${n}-netdev"
(let
deps = [ (subsystemDevice v.interface) ];
in
{ description = "Vlan Interface ${n}";
wantedBy = [ "network.target" (subsystemDevice n) ];
bindsTo = deps;
after = [ "network-pre.target" ] ++ deps;
before = [ "network-interfaces.target" (subsystemDevice n) ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.iproute ];
script = ''
# Remove Dead Interfaces
ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
ip link add link "${v.interface}" name "${n}" type macvlan \
${optionalString (v.mode != null) "mode ${v.mode}"}
ip link set "${n}" up
'';
postStop = ''
ip link delete "${n}"
'';
});
createSitDevice = n: v: nameValuePair "${n}-netdev"
(let
deps = optional (v.dev != null) (subsystemDevice v.dev);
in
{ description = "6-to-4 Tunnel Interface ${n}";
wantedBy = [ "network.target" (subsystemDevice n) ];
bindsTo = deps;
after = [ "network-pre.target" ] ++ deps;
before = [ "network-interfaces.target" (subsystemDevice n) ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.iproute ];
script = ''
# Remove Dead Interfaces
ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
ip link add name "${n}" type sit \
${optionalString (v.remote != null) "remote \"${v.remote}\""} \
${optionalString (v.local != null) "local \"${v.local}\""} \
${optionalString (v.ttl != null) "ttl ${toString v.ttl}"} \
${optionalString (v.dev != null) "dev \"${v.dev}\""}
ip link set "${n}" up
'';
postStop = ''
ip link delete "${n}"
'';
});
createVlanDevice = n: v: nameValuePair "${n}-netdev"
(let
deps = [ (subsystemDevice v.interface) ];
in
{ description = "Vlan Interface ${n}";
wantedBy = [ "network.target" (subsystemDevice n) ];
bindsTo = deps;
after = [ "network-pre.target" ] ++ deps;
before = [ "network-interfaces.target" (subsystemDevice n) ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.iproute ];
script = ''
# Remove Dead Interfaces
ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
ip link add link "${v.interface}" name "${n}" type vlan id "${toString v.id}"
ip link set "${n}" up
'';
postStop = ''
ip link delete "${n}"
'';
});
in listToAttrs (
map configureAddrs interfaces ++
map createTunDevice (filter (i: i.virtual) interfaces))
// mapAttrs' createBridgeDevice cfg.bridges
// mapAttrs' createBondDevice cfg.bonds
// mapAttrs' createMacvlanDevice cfg.macvlans
// mapAttrs' createSitDevice cfg.sits
// mapAttrs' createVlanDevice cfg.vlans
// {
"network-setup" = networkSetup;
"network-local-commands" = networkLocalCommands;
};
services.udev.extraRules =
''
KERNEL=="tun", TAG+="systemd"
'';
};
}

View File

@ -0,0 +1,174 @@
{ config, lib, pkgs, utils, ... }:
with lib;
with utils;
let
cfg = config.networking;
interfaces = attrValues cfg.interfaces;
interfaceIps = i:
i.ip4 ++ optionals cfg.enableIPv6 i.ip6
++ optional (i.ipAddress != null) {
address = i.ipAddress;
prefixLength = i.prefixLength;
} ++ optional (cfg.enableIPv6 && i.ipv6Address != null) {
address = i.ipv6Address;
prefixLength = i.ipv6PrefixLength;
};
dhcpStr = useDHCP: if useDHCP == true || useDHCP == null then "both" else "none";
slaves =
concatLists (map (bond: bond.interfaces) (attrValues cfg.bonds))
++ concatLists (map (bridge: bridge.interfaces) (attrValues cfg.bridges))
++ map (sit: sit.dev) (attrValues cfg.sits)
++ map (vlan: vlan.interface) (attrValues cfg.vlans);
in
{
config = mkIf cfg.useNetworkd {
assertions = [ {
assertion = cfg.defaultGatewayWindowSize == null;
message = "networking.defaultGatewayWindowSize is not supported by networkd.";
} ];
systemd.services.dhcpcd.enable = mkDefault false;
systemd.services.network-local-commands = {
after = [ "systemd-networkd.service" ];
bindsTo = [ "systemd-networkd.service" ];
};
systemd.network =
let
domains = cfg.search ++ (optional (cfg.domain != null) cfg.domain);
genericNetwork = override: {
DHCP = override (dhcpStr cfg.useDHCP);
} // optionalAttrs (cfg.defaultGateway != null) {
gateway = override [ cfg.defaultGateway ];
} // optionalAttrs (domains != [ ]) {
domains = override domains;
};
in mkMerge [ {
enable = true;
networks."99-main" = genericNetwork mkDefault;
}
(mkMerge (flip map interfaces (i: {
netdevs = mkIf i.virtual (
let
devType = if i.virtualType != null then i.virtualType
else (if hasPrefix "tun" i.name then "tun" else "tap");
in {
"40-${i.name}" = {
netdevConfig = {
Name = i.name;
Kind = devType;
};
"${devType}Config" = optionalAttrs (i.virtualOwner != null) {
User = i.virtualOwner;
};
};
});
networks."40-${i.name}" = mkMerge [ (genericNetwork mkDefault) {
name = mkDefault i.name;
DHCP = mkForce (dhcpStr
(if i.useDHCP != null then i.useDHCP else cfg.useDHCP && interfaceIps i == [ ]));
address = flip map (interfaceIps i)
(ip: "${ip.address}/${toString ip.prefixLength}");
} ];
})))
(mkMerge (flip mapAttrsToList cfg.bridges (name: bridge: {
netdevs."40-${name}" = {
netdevConfig = {
Name = name;
Kind = "bridge";
};
};
networks = listToAttrs (flip map bridge.interfaces (bi:
nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) {
DHCP = mkOverride 0 (dhcpStr false);
networkConfig.Bridge = name;
} ])));
})))
(mkMerge (flip mapAttrsToList cfg.bonds (name: bond: {
netdevs."40-${name}" = {
netdevConfig = {
Name = name;
Kind = "bond";
};
bondConfig =
(optionalAttrs (bond.lacp_rate != null) {
LACPTransmitRate = bond.lacp_rate;
}) // (optionalAttrs (bond.miimon != null) {
MIIMonitorSec = bond.miimon;
}) // (optionalAttrs (bond.mode != null) {
Mode = bond.mode;
}) // (optionalAttrs (bond.xmit_hash_policy != null) {
TransmitHashPolicy = bond.xmit_hash_policy;
});
};
networks = listToAttrs (flip map bond.interfaces (bi:
nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) {
DHCP = mkOverride 0 (dhcpStr false);
networkConfig.Bond = name;
} ])));
})))
(mkMerge (flip mapAttrsToList cfg.macvlans (name: macvlan: {
netdevs."40-${name}" = {
netdevConfig = {
Name = name;
Kind = "macvlan";
};
macvlanConfig = optionalAttrs (macvlan.mode != null) { Mode = macvlan.mode; };
};
networks."40-${macvlan.interface}" = (mkMerge [ (genericNetwork (mkOverride 999)) {
macvlan = [ name ];
} ]);
})))
(mkMerge (flip mapAttrsToList cfg.sits (name: sit: {
netdevs."40-${name}" = {
netdevConfig = {
Name = name;
Kind = "sit";
};
tunnelConfig =
(optionalAttrs (sit.remote != null) {
Remote = sit.remote;
}) // (optionalAttrs (sit.local != null) {
Local = sit.local;
}) // (optionalAttrs (sit.ttl != null) {
TTL = sit.ttl;
});
};
networks = mkIf (sit.dev != null) {
"40-${sit.dev}" = (mkMerge [ (genericNetwork (mkOverride 999)) {
tunnel = [ name ];
} ]);
};
})))
(mkMerge (flip mapAttrsToList cfg.vlans (name: vlan: {
netdevs."40-${name}" = {
netdevConfig = {
Name = name;
Kind = "vlan";
};
vlanConfig.Id = vlan.id;
};
networks."40-${vlan.interface}" = (mkMerge [ (genericNetwork (mkOverride 999)) {
vlan = [ name ];
} ]);
})))
];
# We need to prefill the slaved devices with networking options
# This forces the network interface creator to initialize slaves.
networking.interfaces = listToAttrs (map (i: nameValuePair i { }) slaves);
};
}

View File

@ -11,6 +11,11 @@ let
hasSits = cfg.sits != { }; hasSits = cfg.sits != { };
hasBonds = cfg.bonds != { }; hasBonds = cfg.bonds != { };
slaves = concatMap (i: i.interfaces) (attrValues cfg.bonds)
++ concatMap (i: i.interfaces) (attrValues cfg.bridges);
slaveIfs = map (i: cfg.interfaces.${i}) (filter (i: cfg.interfaces ? ${i}) slaves);
# We must escape interfaces due to the systemd interpretation # We must escape interfaces due to the systemd interpretation
subsystemDevice = interface: subsystemDevice = interface:
"sys-subsystem-net-devices-${escapeSystemdPath interface}.device"; "sys-subsystem-net-devices-${escapeSystemdPath interface}.device";
@ -45,6 +50,16 @@ let
description = "Name of the interface."; description = "Name of the interface.";
}; };
useDHCP = mkOption {
type = types.nullOr types.bool;
default = null;
description = ''
Whether this interface should be configured with dhcp.
Null implies the old behavior which depends on whether ip addresses
are specified or not.
'';
};
ip4 = mkOption { ip4 = mkOption {
default = [ ]; default = [ ];
example = [ example = [
@ -203,6 +218,7 @@ in
networking.hostName = mkOption { networking.hostName = mkOption {
default = "nixos"; default = "nixos";
type = types.str;
description = '' description = ''
The name of the machine. Leave it empty if you want to obtain The name of the machine. Leave it empty if you want to obtain
it from a DHCP server (if using DHCP). it from a DHCP server (if using DHCP).
@ -225,14 +241,16 @@ in
networking.enableIPv6 = mkOption { networking.enableIPv6 = mkOption {
default = true; default = true;
type = types.bool;
description = '' description = ''
Whether to enable support for IPv6. Whether to enable support for IPv6.
''; '';
}; };
networking.defaultGateway = mkOption { networking.defaultGateway = mkOption {
default = ""; default = null;
example = "131.211.84.1"; example = "131.211.84.1";
type = types.nullOr types.str;
description = '' description = ''
The default gateway. It can be left empty if it is auto-detected through DHCP. The default gateway. It can be left empty if it is auto-detected through DHCP.
''; '';
@ -266,8 +284,9 @@ in
}; };
networking.domain = mkOption { networking.domain = mkOption {
default = ""; default = null;
example = "home"; example = "home";
type = types.nullOr types.str;
description = '' description = ''
The domain. It can be left empty if it is auto-detected through DHCP. The domain. It can be left empty if it is auto-detected through DHCP.
''; '';
@ -414,6 +433,37 @@ in
}; };
}; };
networking.macvlans = mkOption {
type = types.attrsOf types.optionSet;
default = { };
example = {
wan = {
interface = "enp2s0";
mode = "vepa";
};
};
description = ''
This option allows you to define macvlan interfaces which should
be automatically created.
'';
options = {
interface = mkOption {
example = "enp4s0";
type = types.string;
description = "The interface the macvlan will transmit packets through.";
};
mode = mkOption {
default = null;
type = types.nullOr types.str;
example = "vepa";
description = "The mode of the macvlan device.";
};
};
};
networking.sits = mkOption { networking.sits = mkOption {
type = types.attrsOf types.optionSet; type = types.attrsOf types.optionSet;
default = { }; default = { };
@ -523,6 +573,16 @@ in
''; '';
}; };
networking.useNetworkd = mkOption {
default = false;
type = types.bool;
description = ''
Whether we should use networkd as the network configuration backend or
the legacy script based system. Note that this option is experimental,
enable at your own risk.
'';
};
}; };
@ -534,6 +594,9 @@ in
(flip map interfaces (i: { (flip map interfaces (i: {
assertion = i.subnetMask == null; assertion = i.subnetMask == null;
message = "The networking.interfaces.${i.name}.subnetMask option is defunct. Use prefixLength instead."; message = "The networking.interfaces.${i.name}.subnetMask option is defunct. Use prefixLength instead.";
})) ++ (flip map slaveIfs (i: {
assertion = i.ip4 == [ ] && i.ipAddress == null && i.ip6 == [ ] && i.ipv6Address == null;
message = "The networking.interfaces.${i.name} must not have any defined ips when it is a slave.";
})) ++ [ })) ++ [
{ {
assertion = cfg.hostId == null || (stringLength cfg.hostId == 8 && isHexString cfg.hostId); assertion = cfg.hostId == null || (stringLength cfg.hostId == 8 && isHexString cfg.hostId);
@ -552,345 +615,18 @@ in
# from being created. # from being created.
optionalString hasBonds "options bonding max_bonds=0"; optionalString hasBonds "options bonding max_bonds=0";
environment.systemPackages = boot.kernel.sysctl = {
[ pkgs.host "net.net.ipv4.conf.all.promote_secondaries" = true;
pkgs.iproute "net.ipv6.conf.all.disable_ipv6" = mkDefault (!cfg.enableIPv6);
pkgs.iputils "net.ipv6.conf.default.disable_ipv6" = mkDefault (!cfg.enableIPv6);
pkgs.nettools "net.ipv4.conf.all_forwarding" = mkDefault (any (i: i.proxyARP) interfaces);
pkgs.wirelesstools "net.ipv6.conf.all.forwarding" = mkDefault (any (i: i.proxyARP) interfaces);
pkgs.iw } // listToAttrs (concatLists (flip map (filter (i: i.proxyARP) interfaces)
pkgs.rfkill (i: flip map [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true))
pkgs.openresolv ));
]
++ optional (cfg.bridges != {}) pkgs.bridge_utils
++ optional hasVirtuals pkgs.tunctl
++ optional cfg.enableIPv6 pkgs.ndisc6;
security.setuidPrograms = [ "ping" "ping6" ]; security.setuidPrograms = [ "ping" "ping6" ];
systemd.targets."network-interfaces" =
{ description = "All Network Interfaces";
wantedBy = [ "network.target" ];
unitConfig.X-StopOnReconfiguration = true;
};
systemd.services =
let
networkSetup =
{ description = "Networking Setup";
after = [ "network-interfaces.target" ];
before = [ "network.target" ];
wantedBy = [ "network.target" ];
unitConfig.ConditionCapability = "CAP_NET_ADMIN";
path = [ pkgs.iproute ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
script =
''
# Set the static DNS configuration, if given.
${pkgs.openresolv}/sbin/resolvconf -m 1 -a static <<EOF
${optionalString (cfg.nameservers != [] && cfg.domain != "") ''
domain ${cfg.domain}
''}
${optionalString (cfg.search != []) ("search " + concatStringsSep " " cfg.search)}
${flip concatMapStrings cfg.nameservers (ns: ''
nameserver ${ns}
'')}
EOF
# Disable or enable IPv6.
${optionalString (!config.boot.isContainer) ''
if [ -e /proc/sys/net/ipv6/conf/all/disable_ipv6 ]; then
echo ${if cfg.enableIPv6 then "0" else "1"} > /proc/sys/net/ipv6/conf/all/disable_ipv6
fi
''}
# Set the default gateway.
${optionalString (cfg.defaultGateway != "") ''
# FIXME: get rid of "|| true" (necessary to make it idempotent).
ip route add default via "${cfg.defaultGateway}" ${
optionalString (cfg.defaultGatewayWindowSize != null)
"window ${cfg.defaultGatewayWindowSize}"} || true
''}
# Turn on forwarding if any interface has enabled proxy_arp.
${optionalString (any (i: i.proxyARP) interfaces) ''
echo 1 > /proc/sys/net/ipv4/ip_forward
''}
# Run any user-specified commands.
${cfg.localCommands}
'';
};
# For each interface <foo>, create a job <foo>-cfg.service"
# that performs static configuration. It has a "wants"
# dependency on <foo>.service, which is supposed to create
# the interface and need not exist (i.e. for hardware
# interfaces). It has a binds-to dependency on the actual
# network device, so it only gets started after the interface
# has appeared, and it's stopped when the interface
# disappears.
configureInterface = i:
let
ips = i.ip4 ++ optionals cfg.enableIPv6 i.ip6
++ optional (i.ipAddress != null) {
address = i.ipAddress;
prefixLength = i.prefixLength;
} ++ optional (cfg.enableIPv6 && i.ipv6Address != null) {
address = i.ipv6Address;
prefixLength = i.ipv6PrefixLength;
};
in
nameValuePair "${i.name}-cfg"
{ description = "Configuration of ${i.name}";
wantedBy = [ "network-interfaces.target" ];
bindsTo = [ (subsystemDevice i.name) ];
after = [ (subsystemDevice i.name) ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.iproute pkgs.gawk ];
script =
''
echo "bringing up interface..."
ip link set "${i.name}" up
''
+ optionalString (i.macAddress != null)
''
echo "setting MAC address to ${i.macAddress}..."
ip link set "${i.name}" address "${i.macAddress}"
''
+ optionalString (i.mtu != null)
''
echo "setting MTU to ${toString i.mtu}..."
ip link set "${i.name}" mtu "${toString i.mtu}"
''
# Ip Setup
+
''
curIps=$(ip -o a show dev "${i.name}" | awk '{print $4}')
# Only do an add if it's necessary. This is
# useful when the Nix store is accessed via this
# interface (e.g. in a QEMU VM test).
''
+ flip concatMapStrings (ips) (ip:
let
address = "${ip.address}/${toString ip.prefixLength}";
in
''
echo "checking ip ${address}..."
if ! echo "$curIps" | grep "${address}" >/dev/null 2>&1; then
if out=$(ip addr add "${address}" dev "${i.name}" 2>&1); then
echo "added ip ${address}..."
restart_network_setup=true
elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then
echo "failed to add ${address}"
exit 1
fi
fi
'')
+ optionalString (ips != [ ])
''
if [ restart_network_setup = true ]; then
# Ensure that the default gateway remains set.
# (Flushing this interface may have removed it.)
${config.systemd.package}/bin/systemctl try-restart --no-block network-setup.service
fi
${config.systemd.package}/bin/systemctl start ip-up.target
''
+ optionalString i.proxyARP
''
echo 1 > /proc/sys/net/ipv4/conf/${i.name}/proxy_arp
''
+ optionalString (i.proxyARP && cfg.enableIPv6)
''
echo 1 > /proc/sys/net/ipv6/conf/${i.name}/proxy_ndp
'';
preStop =
''
echo "releasing configured ip's..."
''
+ flip concatMapStrings (ips) (ip:
let
address = "${ip.address}/${toString ip.prefixLength}";
in
''
echo -n "Deleting ${address}..."
ip addr del "${address}" dev "${i.name}" >/dev/null 2>&1 || echo -n " Failed"
echo ""
'');
};
createTunDevice = i: nameValuePair "${i.name}-netdev"
{ description = "Virtual Network Interface ${i.name}";
requires = [ "dev-net-tun.device" ];
after = [ "dev-net-tun.device" ];
wantedBy = [ "network.target" (subsystemDevice i.name) ];
path = [ pkgs.iproute ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
ip tuntap add dev "${i.name}" \
${optionalString (i.virtualType != null) "mode ${i.virtualType}"} \
user "${i.virtualOwner}"
'';
postStop = ''
ip link del ${i.name}
'';
};
createBridgeDevice = n: v: nameValuePair "${n}-netdev"
(let
deps = map subsystemDevice v.interfaces;
in
{ description = "Bridge Interface ${n}";
wantedBy = [ "network.target" (subsystemDevice n) ];
bindsTo = deps;
after = deps;
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.bridge_utils pkgs.iproute ];
script =
''
# Remove Dead Interfaces
ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
brctl addbr "${n}"
# Set bridge's hello time to 0 to avoid startup delays.
brctl setfd "${n}" 0
${flip concatMapStrings v.interfaces (i: ''
brctl addif "${n}" "${i}"
ip link set "${i}" up
ip addr flush dev "${i}"
echo "bringing up network device ${n}..."
ip link set "${n}" up
'')}
# !!! Should delete (brctl delif) any interfaces that
# no longer belong to the bridge.
'';
postStop =
''
ip link set "${n}" down
brctl delbr "${n}"
'';
});
createBondDevice = n: v: nameValuePair "${n}-netdev"
(let
deps = map subsystemDevice v.interfaces;
in
{ description = "Bond Interface ${n}";
wantedBy = [ "network.target" (subsystemDevice n) ];
bindsTo = deps;
after = deps;
before = [ "${n}-cfg.service" ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.ifenslave pkgs.iproute ];
script = ''
ip link add name "${n}" type bond
# !!! There must be a better way to wait for the interface
while [ ! -d /sys/class/net/${n} ]; do sleep 0.1; done;
# Ensure the link is down so that we can set options
ip link set "${n}" down
# Set the miimon and mode options
${optionalString (v.miimon != null)
"echo \"${toString v.miimon}\" >/sys/class/net/${n}/bonding/miimon"}
${optionalString (v.mode != null)
"echo \"${v.mode}\" >/sys/class/net/${n}/bonding/mode"}
${optionalString (v.lacp_rate != null)
"echo \"${v.lacp_rate}\" >/sys/class/net/${n}/bonding/lacp_rate"}
${optionalString (v.xmit_hash_policy != null)
"echo \"${v.xmit_hash_policy}\" >/sys/class/net/${n}/bonding/xmit_hash_policy"}
# Bring up the bond and enslave the specified interfaces
ip link set "${n}" up
${flip concatMapStrings v.interfaces (i: ''
ifenslave "${n}" "${i}"
'')}
'';
postStop = ''
${flip concatMapStrings v.interfaces (i: ''
ifenslave -d "${n}" "${i}" >/dev/null 2>&1 || true
'')}
ip link set "${n}" down >/dev/null 2>&1 || true
ip link del "${n}" >/dev/null 2>&1 || true
'';
});
createSitDevice = n: v: nameValuePair "${n}-netdev"
(let
deps = optional (v.dev != null) (subsystemDevice v.dev);
in
{ description = "6-to-4 Tunnel Interface ${n}";
wantedBy = [ "network.target" (subsystemDevice n) ];
bindsTo = deps;
after = deps;
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.iproute ];
script = ''
# Remove Dead Interfaces
ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
ip link add name "${n}" type sit \
${optionalString (v.remote != null) "remote \"${v.remote}\""} \
${optionalString (v.local != null) "local \"${v.local}\""} \
${optionalString (v.ttl != null) "ttl ${toString v.ttl}"} \
${optionalString (v.dev != null) "dev \"${v.dev}\""}
ip link set "${n}" up
'';
postStop = ''
ip link delete "${n}"
'';
});
createVlanDevice = n: v: nameValuePair "${n}-netdev"
(let
deps = [ (subsystemDevice v.interface) ];
in
{ description = "Vlan Interface ${n}";
wantedBy = [ "network.target" (subsystemDevice n) ];
bindsTo = deps;
after = deps;
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.iproute ];
script = ''
# Remove Dead Interfaces
ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
ip link add link "${v.interface}" name "${n}" type vlan id "${toString v.id}"
ip link set "${n}" up
'';
postStop = ''
ip link delete "${n}"
'';
});
in listToAttrs (
map configureInterface interfaces ++
map createTunDevice (filter (i: i.virtual) interfaces))
// mapAttrs' createBridgeDevice cfg.bridges
// mapAttrs' createBondDevice cfg.bonds
// mapAttrs' createSitDevice cfg.sits
// mapAttrs' createVlanDevice cfg.vlans
// { "network-setup" = networkSetup; };
# Set the host and domain names in the activation script. Don't # Set the host and domain names in the activation script. Don't
# clear it if it's not configured in the NixOS configuration, # clear it if it's not configured in the NixOS configuration,
# since it may have been set by dhcpcd in the meantime. # since it may have been set by dhcpcd in the meantime.
@ -899,7 +635,7 @@ in
hostname "${cfg.hostName}" hostname "${cfg.hostName}"
''; '';
system.activationScripts.domain = system.activationScripts.domain =
optionalString (cfg.domain != "") '' optionalString (cfg.domain != null) ''
domainname "${cfg.domain}" domainname "${cfg.domain}"
''; '';
@ -918,11 +654,63 @@ in
} }
]; ];
services.udev.extraRules = environment.systemPackages =
'' [ pkgs.host
KERNEL=="tun", TAG+="systemd" pkgs.iproute
''; pkgs.iputils
pkgs.nettools
pkgs.wirelesstools
pkgs.iw
pkgs.rfkill
pkgs.openresolv
];
systemd.targets."network-interfaces" =
{ description = "All Network Interfaces";
wantedBy = [ "network.target" ];
before = [ "network.target" ];
after = [ "network-pre.target" ];
unitConfig.X-StopOnReconfiguration = true;
};
systemd.services = {
network-local-commands = {
description = "Extra networking commands.";
before = [ "network.target" ];
wantedBy = [ "network.target" ];
after = [ "network-pre.target" ];
unitConfig.ConditionCapability = "CAP_NET_ADMIN";
path = [ pkgs.iproute ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
script = ''
# Run any user-specified commands.
${cfg.localCommands}
'';
};
} // (listToAttrs (flip map interfaces (i:
nameValuePair "network-link-${i.name}"
{ description = "Link configuration of ${i.name}";
wantedBy = [ "network-interfaces.target" ];
before = [ "network-interfaces.target" ];
bindsTo = [ (subsystemDevice i.name) ];
after = [ (subsystemDevice i.name) "network-pre.target" ];
path = [ pkgs.iproute ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script =
''
echo "Configuring link..."
'' + optionalString (i.macAddress != null) ''
echo "setting MAC address to ${i.macAddress}..."
ip link set "${i.name}" address "${i.macAddress}"
'' + optionalString (i.mtu != null) ''
echo "setting MTU to ${toString i.mtu}..."
ip link set "${i.name}" mtu "${toString i.mtu}"
'';
})));
}; };
} }

View File

@ -7,8 +7,8 @@ with lib;
let let
cfg = config.virtualisation.docker; cfg = config.virtualisation.docker;
pro = config.nix.proxy; pro = config.networking.proxy.default;
proxy_env = optionalAttrs (pro != "") { Environment = "\"http_proxy=${pro}\""; }; proxy_env = optionalAttrs (pro != null) { Environment = "\"http_proxy=${pro}\""; };
in in
@ -103,6 +103,12 @@ in
LimitNPROC = 1048576; LimitNPROC = 1048576;
} // proxy_env; } // proxy_env;
postStart = ''
while ! [ -e /var/run/docker.sock ]; do
sleep 0.1
done
'';
# Presumably some containers are running we don't want to interrupt # Presumably some containers are running we don't want to interrupt
restartIfChanged = false; restartIfChanged = false;
}; };

View File

@ -0,0 +1,462 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.virtualisation.kubernetes;
in {
###### interface
options.virtualisation.kubernetes = {
package = mkOption {
description = "Kubernetes package to use.";
type = types.package;
};
verbose = mkOption {
description = "Kubernetes enable verbose mode for debugging";
default = false;
type = types.bool;
};
etcdServers = mkOption {
description = "Kubernetes list of etcd servers to watch.";
default = [ "127.0.0.1:4001" ];
type = types.listOf types.str;
};
roles = mkOption {
description = ''
Kubernetes role that this machine should take.
Master role will enable etcd, apiserver, scheduler and controller manager
services. Node role will enable etcd, docker, kubelet and proxy services.
'';
default = [];
type = types.listOf (types.enum ["master" "node"]);
};
dataDir = mkOption {
description = "Kubernetes root directory for managing kubelet files.";
default = "/var/lib/kubernetes";
type = types.path;
};
apiserver = {
enable = mkOption {
description = "Whether to enable kubernetes apiserver.";
default = false;
type = types.bool;
};
address = mkOption {
description = "Kubernetes apiserver listening address.";
default = "127.0.0.1";
type = types.str;
};
publicAddress = mkOption {
description = ''
Kubernetes apiserver public listening address used for read only and
secure port.
'';
default = cfg.apiserver.address;
type = types.str;
};
port = mkOption {
description = "Kubernets apiserver listening port.";
default = 8080;
type = types.int;
};
readOnlyPort = mkOption {
description = "Kubernets apiserver read-only port.";
default = 7080;
type = types.int;
};
securePort = mkOption {
description = "Kubernetes apiserver secure port.";
default = 6443;
type = types.int;
};
tlsCertFile = mkOption {
description = "Kubernetes apiserver certificate file.";
default = "";
type = types.str;
};
tlsPrivateKeyFile = mkOption {
description = "Kubernetes apiserver private key file.";
default = "";
type = types.str;
};
tokenAuth = mkOption {
description = ''
Kubernetes apiserver token authentication file. See
<link xlink:href="https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/authentication.md"/>
'';
default = {};
example = literalExample ''
{
alice = "abc123";
bob = "xyz987";
}
'';
type = types.attrsOf types.str;
};
authorizationMode = mkOption {
description = ''
Kubernetes apiserver authorization mode (AlwaysAllow/AlwaysDeny/ABAC). See
<link xlink:href="https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/authorization.md"/>
'';
default = "AlwaysAllow";
type = types.enum ["AlwaysAllow" "AlwaysDeny" "ABAC"];
};
authorizationPolicy = mkOption {
description = ''
Kubernetes apiserver authorization policy file. See
<link xlink:href="https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/authorization.md"/>
'';
default = [];
example = literalExample ''
[
{user = "admin";}
{user = "scheduler"; readonly = true; kind= "pods";}
{user = "scheduler"; kind = "bindings";}
{user = "kubelet"; readonly = true; kind = "bindings";}
{user = "kubelet"; kind = "events";}
{user= "alice"; ns = "projectCaribou";}
{user = "bob"; readonly = true; ns = "projectCaribou";}
]
'';
type = types.listOf types.attrs;
};
allowPrivileged = mkOption {
description = "Whether to allow privileged containers on kubernetes.";
default = false;
type = types.bool;
};
portalNet = mkOption {
description = "Kubernetes CIDR notation IP range from which to assign portal IPs";
default = "10.10.10.10/16";
type = types.str;
};
extraOpts = mkOption {
description = "Kubernetes apiserver extra command line options.";
default = "";
type = types.str;
};
};
scheduler = {
enable = mkOption {
description = "Whether to enable kubernetes scheduler.";
default = false;
type = types.bool;
};
address = mkOption {
description = "Kubernetes scheduler listening address.";
default = "127.0.0.1";
type = types.str;
};
port = mkOption {
description = "Kubernets scheduler listening port.";
default = 10251;
type = types.int;
};
master = mkOption {
description = "Kubernetes apiserver address";
default = "${cfg.apiserver.address}:${toString cfg.apiserver.port}";
type = types.str;
};
extraOpts = mkOption {
description = "Kubernetes scheduler extra command line options.";
default = "";
type = types.str;
};
};
controllerManager = {
enable = mkOption {
description = "Whether to enable kubernetes controller manager.";
default = false;
type = types.bool;
};
address = mkOption {
description = "Kubernetes controller manager listening address.";
default = "127.0.0.1";
type = types.str;
};
port = mkOption {
description = "Kubernets controller manager listening port.";
default = 10252;
type = types.int;
};
master = mkOption {
description = "Kubernetes apiserver address";
default = "${cfg.apiserver.address}:${toString cfg.apiserver.port}";
type = types.str;
};
machines = mkOption {
description = "Kubernetes apiserver list of machines to schedule to schedule onto";
default = [];
type = types.listOf types.str;
};
extraOpts = mkOption {
description = "Kubernetes scheduler extra command line options.";
default = "";
type = types.str;
};
};
kubelet = {
enable = mkOption {
description = "Whether to enable kubernetes kubelet.";
default = false;
type = types.bool;
};
address = mkOption {
description = "Kubernetes kubelet info server listening address.";
default = "0.0.0.0";
type = types.str;
};
port = mkOption {
description = "Kubernets kubelet info server listening port.";
default = 10250;
type = types.int;
};
hostname = mkOption {
description = "Kubernetes kubelet hostname override";
default = config.networking.hostName;
type = types.str;
};
allowPrivileged = mkOption {
description = "Whether to allow kubernetes containers to request privileged mode.";
default = false;
type = types.bool;
};
extraOpts = mkOption {
description = "Kubernetes kubelet extra command line options.";
default = "";
type = types.str;
};
};
proxy = {
enable = mkOption {
description = "Whether to enable kubernetes proxy.";
default = false;
type = types.bool;
};
address = mkOption {
description = "Kubernetes proxy listening address.";
default = "0.0.0.0";
type = types.str;
};
extraOpts = mkOption {
description = "Kubernetes proxy extra command line options.";
default = "";
type = types.str;
};
};
};
###### implementation
config = mkMerge [
(mkIf cfg.apiserver.enable {
systemd.services.kubernetes-apiserver = {
description = "Kubernetes Api Server";
wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" "etcd.service" ];
serviceConfig = {
ExecStart = let
authorizationPolicyFile =
pkgs.writeText "kubernetes-policy"
(builtins.toJSON cfg.apiserver.authorizationPolicy);
tokenAuthFile =
pkgs.writeText "kubernetes-auth"
(concatImapStringsSep "\n" (i: v: v + "," + (toString i))
(mapAttrsToList (name: token: token + "," + name) cfg.apiserver.tokenAuth));
in ''${cfg.package}/bin/kube-apiserver \
-etcd_servers=${concatMapStringsSep "," (f: "http://${f}") cfg.etcdServers} \
-address=${cfg.apiserver.address} \
-port=${toString cfg.apiserver.port} \
-read_only_port=${toString cfg.apiserver.readOnlyPort} \
-public_address_override=${cfg.apiserver.publicAddress} \
-allow_privileged=${if cfg.apiserver.allowPrivileged then "true" else "false"} \
${optionalString (cfg.apiserver.tlsCertFile!="")
"-tls_cert_file=${cfg.apiserver.tlsCertFile}"} \
${optionalString (cfg.apiserver.tlsPrivateKeyFile!="")
"-tls_private_key_file=${cfg.apiserver.tlsPrivateKeyFile}"} \
${optionalString (cfg.apiserver.tokenAuth!=[])
"-token_auth_file=${tokenAuthFile}"} \
-authorization_mode=${cfg.apiserver.authorizationMode} \
${optionalString (cfg.apiserver.authorizationMode == "ABAC")
"-authorization_policy_file=${authorizationPolicyFile}"} \
${optionalString (cfg.apiserver.tlsCertFile!="" && cfg.apiserver.tlsCertFile!="")
"-secure_port=${toString cfg.apiserver.securePort}"} \
-portal_net=${cfg.apiserver.portalNet} \
-logtostderr=true \
${optionalString cfg.verbose "-v=6 -log_flush_frequency=1s"} \
${cfg.apiserver.extraOpts}
'';
User = "kubernetes";
};
postStart = ''
until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.apiserver.address}:${toString cfg.apiserver.port}/'; do
sleep 1;
done
'';
};
})
(mkIf cfg.scheduler.enable {
systemd.services.kubernetes-scheduler = {
description = "Kubernetes Scheduler Service";
wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" "kubernetes-apiserver.service" ];
serviceConfig = {
ExecStart = ''${cfg.package}/bin/kube-scheduler \
-address=${cfg.scheduler.address} \
-port=${toString cfg.scheduler.port} \
-master=${cfg.scheduler.master} \
-logtostderr=true \
${optionalString cfg.verbose "-v=6 -log_flush_frequency=1s"} \
${cfg.scheduler.extraOpts}
'';
User = "kubernetes";
};
};
})
(mkIf cfg.controllerManager.enable {
systemd.services.kubernetes-controller-manager = {
description = "Kubernetes Controller Manager Service";
wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" "kubernetes-apiserver.service" ];
serviceConfig = {
ExecStart = ''${cfg.package}/bin/kube-controller-manager \
-address=${cfg.controllerManager.address} \
-port=${toString cfg.controllerManager.port} \
-master=${cfg.controllerManager.master} \
${optionalString (cfg.controllerManager.machines != [])
"-machines=${concatStringsSep "," cfg.controllerManager.machines}"} \
-logtostderr=true \
${optionalString cfg.verbose "-v=6 -log_flush_frequency=1s"} \
${cfg.controllerManager.extraOpts}
'';
User = "kubernetes";
};
};
})
(mkIf cfg.kubelet.enable {
systemd.services.kubernetes-kubelet = {
description = "Kubernetes Kubelet Service";
wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" "etcd.service" "docker.service" ];
serviceConfig = {
ExecStart = ''${cfg.package}/bin/kubelet \
-etcd_servers=${concatMapStringsSep "," (f: "http://${f}") cfg.etcdServers} \
-address=${cfg.kubelet.address} \
-port=${toString cfg.kubelet.port} \
-hostname_override=${cfg.kubelet.hostname} \
-allow_privileged=${if cfg.kubelet.allowPrivileged then "true" else "false"} \
-root_dir=${cfg.dataDir} \
-logtostderr=true \
${optionalString cfg.verbose "-v=6 -log_flush_frequency=1s"} \
${cfg.kubelet.extraOpts}
'';
User = "kubernetes";
PermissionsStartOnly = true;
WorkingDirectory = cfg.dataDir;
};
};
})
(mkIf cfg.proxy.enable {
systemd.services.kubernetes-proxy = {
description = "Kubernetes Proxy Service";
wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" "etcd.service" ];
serviceConfig = {
ExecStart = ''${cfg.package}/bin/kube-proxy \
-etcd_servers=${concatMapStringsSep "," (s: "http://${s}") cfg.etcdServers} \
-bind_address=${cfg.proxy.address} \
-logtostderr=true \
${optionalString cfg.verbose "-v=6 -log_flush_frequency=1s"} \
${cfg.proxy.extraOpts}
'';
};
};
})
(mkIf (any (el: el == "master") cfg.roles) {
virtualisation.kubernetes.apiserver.enable = mkDefault true;
virtualisation.kubernetes.scheduler.enable = mkDefault true;
virtualisation.kubernetes.controllerManager.enable = mkDefault true;
})
(mkIf (any (el: el == "node") cfg.roles) {
virtualisation.docker.enable = mkDefault true;
virtualisation.kubernetes.kubelet.enable = mkDefault true;
virtualisation.kubernetes.proxy.enable = mkDefault true;
})
(mkIf (any (el: el == "node" || el == "master") cfg.roles) {
services.etcd.enable = mkDefault true;
})
(mkIf (
cfg.apiserver.enable ||
cfg.scheduler.enable ||
cfg.controllerManager.enable ||
cfg.kubelet.enable ||
cfg.proxy.enable
) {
virtualisation.kubernetes.package = mkDefault pkgs.kubernetes;
environment.systemPackages = [ cfg.package ];
users.extraUsers = singleton {
name = "kubernetes";
uid = config.ids.uids.kubernetes;
description = "Kubernetes user";
extraGroups = [ "docker" ];
group = "kubernetes";
home = cfg.dataDir;
createHome = true;
};
users.extraGroups.kubernetes.gid = config.ids.gids.kubernetes;
})
];
}

View File

@ -66,6 +66,14 @@ in rec {
(all nixos.tests.misc) (all nixos.tests.misc)
(all nixos.tests.nat.firewall) (all nixos.tests.nat.firewall)
(all nixos.tests.nat.standalone) (all nixos.tests.nat.standalone)
(all nixos.tests.networking.scripted.static)
(all nixos.tests.networking.scripted.dhcpSimple)
(all nixos.tests.networking.scripted.dhcpOneIf)
(all nixos.tests.networking.scripted.bond)
(all nixos.tests.networking.scripted.bridge)
(all nixos.tests.networking.scripted.macvlan)
(all nixos.tests.networking.scripted.sit)
(all nixos.tests.networking.scripted.vlan)
(all nixos.tests.nfs3) (all nixos.tests.nfs3)
(all nixos.tests.openssh) (all nixos.tests.openssh)
(all nixos.tests.printing) (all nixos.tests.printing)

View File

@ -239,8 +239,9 @@ in rec {
tests.chromium = callTest tests/chromium.nix {}; tests.chromium = callTest tests/chromium.nix {};
tests.cjdns = callTest tests/cjdns.nix {}; tests.cjdns = callTest tests/cjdns.nix {};
tests.containers = callTest tests/containers.nix {}; tests.containers = callTest tests/containers.nix {};
tests.dockerRegistry = callTest tests/docker-registry.nix {}; tests.docker = scrubDrv (import tests/docker.nix { system = "x86_64-linux"; });
tests.etcd = callTest tests/etcd.nix {}; tests.dockerRegistry = scrubDrv (import tests/docker-registry.nix { system = "x86_64-linux"; });
tests.etcd = scrubDrv (import tests/etcd.nix { system = "x86_64-linux"; });
tests.firefox = callTest tests/firefox.nix {}; tests.firefox = callTest tests/firefox.nix {};
tests.firewall = callTest tests/firewall.nix {}; tests.firewall = callTest tests/firewall.nix {};
tests.gnome3 = callTest tests/gnome3.nix {}; tests.gnome3 = callTest tests/gnome3.nix {};
@ -258,6 +259,7 @@ in rec {
tests.ipv6 = callTest tests/ipv6.nix {}; tests.ipv6 = callTest tests/ipv6.nix {};
tests.jenkins = callTest tests/jenkins.nix {}; tests.jenkins = callTest tests/jenkins.nix {};
tests.kde4 = callTest tests/kde4.nix {}; tests.kde4 = callTest tests/kde4.nix {};
tests.kubernetes = scrubDrv (import tests/kubernetes.nix { system = "x86_64-linux"; });
tests.latestKernel.login = callTest tests/login.nix { latestKernel = true; }; tests.latestKernel.login = callTest tests/login.nix { latestKernel = true; };
tests.login = callTest tests/login.nix {}; tests.login = callTest tests/login.nix {};
#tests.logstash = callTest tests/logstash.nix {}; #tests.logstash = callTest tests/logstash.nix {};
@ -268,9 +270,28 @@ in rec {
tests.mysqlReplication = callTest tests/mysql-replication.nix {}; tests.mysqlReplication = callTest tests/mysql-replication.nix {};
tests.nat.firewall = callTest tests/nat.nix { withFirewall = true; }; tests.nat.firewall = callTest tests/nat.nix { withFirewall = true; };
tests.nat.standalone = callTest tests/nat.nix { withFirewall = false; }; tests.nat.standalone = callTest tests/nat.nix { withFirewall = false; };
tests.networking.networkd.static = callTest tests/networking.nix { networkd = true; test = "static"; };
tests.networking.networkd.dhcpSimple = callTest tests/networking.nix { networkd = true; test = "dhcpSimple"; };
tests.networking.networkd.dhcpOneIf = callTest tests/networking.nix { networkd = true; test = "dhcpOneIf"; };
tests.networking.networkd.bond = callTest tests/networking.nix { networkd = true; test = "bond"; };
tests.networking.networkd.bridge = callTest tests/networking.nix { networkd = true; test = "bridge"; };
tests.networking.networkd.macvlan = callTest tests/networking.nix { networkd = true; test = "macvlan"; };
tests.networking.networkd.sit = callTest tests/networking.nix { networkd = true; test = "sit"; };
tests.networking.networkd.vlan = callTest tests/networking.nix { networkd = true; test = "vlan"; };
tests.networking.scripted.static = callTest tests/networking.nix { networkd = false; test = "static"; };
tests.networking.scripted.dhcpSimple = callTest tests/networking.nix { networkd = false; test = "dhcpSimple"; };
tests.networking.scripted.dhcpOneIf = callTest tests/networking.nix { networkd = false; test = "dhcpOneIf"; };
tests.networking.scripted.bond = callTest tests/networking.nix { networkd = false; test = "bond"; };
tests.networking.scripted.bridge = callTest tests/networking.nix { networkd = false; test = "bridge"; };
tests.networking.scripted.macvlan = callTest tests/networking.nix { networkd = false; test = "macvlan"; };
tests.networking.scripted.sit = callTest tests/networking.nix { networkd = false; test = "sit"; };
tests.networking.scripted.vlan = callTest tests/networking.nix { networkd = false; test = "vlan"; };
# TODO: put in networking.nix after the test becomes more complete
tests.networkingProxy = callTest tests/networking-proxy.nix {};
tests.nfs3 = callTest tests/nfs.nix { version = 3; }; tests.nfs3 = callTest tests/nfs.nix { version = 3; };
tests.nsd = callTest tests/nsd.nix {}; tests.nsd = callTest tests/nsd.nix {};
tests.openssh = callTest tests/openssh.nix {}; tests.openssh = callTest tests/openssh.nix {};
tests.peerflix = callTest tests/peerflix.nix {};
tests.printing = callTest tests/printing.nix {}; tests.printing = callTest tests/printing.nix {};
tests.proxy = callTest tests/proxy.nix {}; tests.proxy = callTest tests/proxy.nix {};
tests.quake3 = callTest tests/quake3.nix {}; tests.quake3 = callTest tests/quake3.nix {};

24
nixos/tests/docker.nix Normal file
View File

@ -0,0 +1,24 @@
# This test runs docker and checks if simple container starts
import ./make-test.nix {
name = "docker";
nodes = {
docker =
{ config, pkgs, ... }:
{
virtualisation.docker.enable = true;
};
};
testScript = ''
startAll;
$docker->waitForUnit("docker.service");
$docker->succeed("tar cv --files-from /dev/null | docker import - scratch");
$docker->succeed("docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratch /bin/sleep 10");
$docker->succeed("docker ps | grep sleeping");
$docker->succeed("docker stop sleeping");
'';
}

View File

@ -38,7 +38,7 @@ let
makeConfig = { testChannel, grubVersion, grubDevice, grubIdentifier makeConfig = { testChannel, grubVersion, grubDevice, grubIdentifier
, readOnly ? true, forceGrubReinstallCount ? 0 }: , readOnly ? true, forceGrubReinstallCount ? 0 }:
pkgs.writeText "configuration.nix" '' pkgs.writeText "configuration.nix" ''
{ config, pkgs, modulesPath, ... }: { config, lib, pkgs, modulesPath, ... }:
{ imports = { imports =
[ ./hardware-configuration.nix [ ./hardware-configuration.nix
@ -58,6 +58,8 @@ let
${optionalString (!readOnly) "nix.readOnlyStore = false;"} ${optionalString (!readOnly) "nix.readOnlyStore = false;"}
swapDevices = lib.mkOverride 0 [ ];
environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ]; environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ];
} }
''; '';
@ -66,7 +68,7 @@ let
# Configuration of a web server that simulates the Nixpkgs channel # Configuration of a web server that simulates the Nixpkgs channel
# distribution server. # distribution server.
webserver = webserver =
{ config, pkgs, ... }: { config, lib, pkgs, ... }:
{ services.httpd.enable = true; { services.httpd.enable = true;
services.httpd.adminAddr = "foo@example.org"; services.httpd.adminAddr = "foo@example.org";

View File

@ -41,8 +41,7 @@ import ./make-test.nix ({ pkgs, ... }: {
]; ];
}; };
testScript = testScript = ''
''
$machine->waitUntilSucceeds("pgrep plasma-desktop"); $machine->waitUntilSucceeds("pgrep plasma-desktop");
$machine->waitForWindow(qr/plasma-desktop/); $machine->waitForWindow(qr/plasma-desktop/);

178
nixos/tests/kubernetes.nix Normal file
View File

@ -0,0 +1,178 @@
# This test runs two node kubernetes cluster and checks if simple redis pod works
import ./make-test.nix rec {
name = "kubernetes";
redisMaster = builtins.toFile "redis-master-pod.yaml" ''
id: redis-master-pod
kind: Pod
apiVersion: v1beta1
desiredState:
manifest:
version: v1beta1
id: redis-master-pod
containers:
- name: master
image: master:5000/scratch
cpu: 100
ports:
- name: redis-server
containerPort: 6379
hostPort: 6379
volumeMounts:
- name: nix-store
mountPath: /nix/store
readOnly: true
volumeMounts:
- name: system-profile
mountPath: /bin
readOnly: true
command:
- /bin/redis-server
volumes:
- name: nix-store
source:
hostDir:
path: /nix/store
- name: system-profile
source:
hostDir:
path: /run/current-system/sw/bin
labels:
name: redis
role: master
'';
nodes = {
master =
{ config, pkgs, lib, nodes, ... }:
{
virtualisation.memorySize = 512;
virtualisation.kubernetes = {
roles = ["master" "node"];
controllerManager.machines = ["master" "node"];
kubelet.extraOpts = "-network_container_image=master:5000/pause";
apiserver.address = "0.0.0.0";
verbose = true;
};
virtualisation.docker.extraOptions = "--iptables=false --ip-masq=false -b cbr0 --insecure-registry master:5000";
services.etcd = {
listenPeerUrls = ["http://0.0.0.0:7001"];
initialAdvertisePeerUrls = ["http://master:7001"];
initialCluster = ["master=http://master:7001" "node=http://node:7001"];
};
services.dockerRegistry.enable = true;
services.dockerRegistry.host = "0.0.0.0";
services.dockerRegistry.port = 5000;
virtualisation.vlans = [ 1 2 ];
networking.bridges = {
cbr0.interfaces = [ "eth2" ];
};
networking.interfaces = {
cbr0 = {
ipAddress = "10.10.0.1";
prefixLength = 24;
};
eth2.ip4 = lib.mkOverride 0 [ ];
};
networking.localCommands = ''
ip route add 10.10.0.0/16 dev cbr0
ip route flush cache
'';
networking.extraHosts = "127.0.0.1 master";
networking.firewall.enable = false;
#networking.firewall.allowedTCPPorts = [ 4001 7001 ];
environment.systemPackages = [ pkgs.redis ];
};
node =
{ config, pkgs, lib, nodes, ... }:
{
virtualisation.kubernetes = {
roles = ["node"];
kubelet.extraOpts = "-network_container_image=master:5000/pause";
verbose = true;
};
virtualisation.docker.extraOptions = "--iptables=false --ip-masq=false -b cbr0 --insecure-registry master:5000";
services.etcd = {
listenPeerUrls = ["http://0.0.0.0:7001"];
initialAdvertisePeerUrls = ["http://node:7001"];
initialCluster = ["master=http://master:7001" "node=http://node:7001"];
};
virtualisation.vlans = [ 1 2 ];
networking.bridges = {
cbr0.interfaces = [ "eth2" ];
};
networking.interfaces = {
cbr0 = {
ipAddress = "10.10.1.1";
prefixLength = 24;
};
eth2.ip4 = lib.mkOverride 0 [ ];
};
networking.localCommands = ''
ip route add 10.10.0.0/16 dev cbr0
ip route flush cache
'';
networking.extraHosts = "127.0.0.1 node";
networking.firewall.enable = false;
#networking.firewall.allowedTCPPorts = [ 4001 7001 ];
environment.systemPackages = [ pkgs.redis ];
};
client =
{ config, pkgs, nodes, ... }:
{
virtualisation.docker.enable = true;
virtualisation.docker.extraOptions = "--insecure-registry master:5000";
environment.systemPackages = [ pkgs.kubernetes ];
environment.etc."test/redis-master-pod.yaml".source = redisMaster;
environment.etc."test/pause".source = "${pkgs.kubernetes}/bin/kube-pause";
environment.etc."test/Dockerfile".source = pkgs.writeText "Dockerfile" ''
FROM scratch
ADD pause /
ENTRYPOINT ["/pause"]
'';
};
};
testScript = ''
startAll;
$master->waitForUnit("kubernetes-apiserver.service");
$master->waitForUnit("kubernetes-scheduler.service");
$master->waitForUnit("kubernetes-controller-manager.service");
$master->waitForUnit("kubernetes-kubelet.service");
$master->waitForUnit("kubernetes-proxy.service");
$node->waitForUnit("kubernetes-kubelet.service");
$node->waitForUnit("kubernetes-proxy.service");
$master->waitUntilSucceeds("kubecfg list minions | grep master");
$master->waitUntilSucceeds("kubecfg list minions | grep node");
$client->waitForUnit("docker.service");
$client->succeed("tar cv --files-from /dev/null | docker import - scratch");
$client->succeed("docker tag scratch master:5000/scratch");
$master->waitForUnit("docker-registry.service");
$client->succeed("docker push master:5000/scratch");
$client->succeed("mkdir -p /root/pause");
$client->succeed("cp /etc/test/pause /root/pause/");
$client->succeed("cp /etc/test/Dockerfile /root/pause/");
$client->succeed("cd /root/pause && docker build -t master:5000/pause .");
$client->succeed("docker push master:5000/pause");
subtest "simple pod", sub {
$client->succeed("kubectl create -f ${redisMaster} -s http://master:8080");
$client->waitUntilSucceeds("kubectl get pods -s http://master:8080 | grep redis-master | grep -i running");
}
'';
}

View File

@ -0,0 +1,109 @@
# Test whether `networking.proxy' work as expected.
# TODO: use a real proxy node and put this test into networking.nix
# TODO: test whether nix tools work as expected behind a proxy
let default-config = {
imports = [ ./common/user-account.nix ];
services.xserver.enable = false;
virtualisation.memorySize = 128;
};
in import ./make-test.nix {
name = "networking-proxy";
nodes = {
# no proxy
machine =
{ config, pkgs, ... }:
default-config;
# proxy default
machine2 =
{ config, pkgs, ... }:
default-config // {
networking.proxy.default = "http://user:pass@host:port";
};
# specific proxy options
machine3 =
{ config, pkgs, ... }:
default-config //
{
networking.proxy = {
# useless because overriden by the next options
default = "http://user:pass@host:port";
# advanced proxy setup
httpProxy = "123-http://user:pass@http-host:port";
httpsProxy = "456-http://user:pass@https-host:port";
rsyncProxy = "789-http://user:pass@rsync-host:port";
ftpProxy = "101112-http://user:pass@ftp-host:port";
noProxy = "131415-127.0.0.1,localhost,.localdomain";
};
};
# mix default + proxy options
machine4 =
{ config, pkgs, ... }:
default-config // {
networking.proxy = {
# open for all *_proxy env var
default = "000-http://user:pass@default-host:port";
# except for those 2
rsyncProxy = "123-http://user:pass@http-host:port";
noProxy = "131415-127.0.0.1,localhost,.localdomain";
};
};
};
testScript =
''
startAll;
# no proxy at all
print $machine->execute("env | grep -i proxy");
print $machine->execute("su - alice -c 'env | grep -i proxy'");
$machine->mustFail("env | grep -i proxy");
$machine->mustFail("su - alice -c 'env | grep -i proxy'");
# Use a default proxy option
print $machine2->execute("env | grep -i proxy");
print $machine2->execute("su - alice -c 'env | grep -i proxy'");
$machine2->mustSucceed("env | grep -i proxy");
$machine2->mustSucceed("su - alice -c 'env | grep -i proxy'");
# explicitly set each proxy option
print $machine3->execute("env | grep -i proxy");
print $machine3->execute("su - alice -c 'env | grep -i proxy'");
$machine3->mustSucceed("env | grep -i http_proxy | grep 123");
$machine3->mustSucceed("env | grep -i https_proxy | grep 456");
$machine3->mustSucceed("env | grep -i rsync_proxy | grep 789");
$machine3->mustSucceed("env | grep -i ftp_proxy | grep 101112");
$machine3->mustSucceed("env | grep -i no_proxy | grep 131415");
$machine3->mustSucceed("su - alice -c 'env | grep -i http_proxy | grep 123'");
$machine3->mustSucceed("su - alice -c 'env | grep -i https_proxy | grep 456'");
$machine3->mustSucceed("su - alice -c 'env | grep -i rsync_proxy | grep 789'");
$machine3->mustSucceed("su - alice -c 'env | grep -i ftp_proxy | grep 101112'");
$machine3->mustSucceed("su - alice -c 'env | grep -i no_proxy | grep 131415'");
# set default proxy option + some other specifics
print $machine4->execute("env | grep -i proxy");
print $machine4->execute("su - alice -c 'env | grep -i proxy'");
$machine4->mustSucceed("env | grep -i http_proxy | grep 000");
$machine4->mustSucceed("env | grep -i https_proxy | grep 000");
$machine4->mustSucceed("env | grep -i rsync_proxy | grep 123");
$machine4->mustSucceed("env | grep -i ftp_proxy | grep 000");
$machine4->mustSucceed("env | grep -i no_proxy | grep 131415");
$machine4->mustSucceed("su - alice -c 'env | grep -i http_proxy | grep 000'");
$machine4->mustSucceed("su - alice -c 'env | grep -i https_proxy | grep 000'");
$machine4->mustSucceed("su - alice -c 'env | grep -i rsync_proxy | grep 123'");
$machine4->mustSucceed("su - alice -c 'env | grep -i ftp_proxy | grep 000'");
$machine4->mustSucceed("su - alice -c 'env | grep -i no_proxy | grep 131415'");
'';
}

381
nixos/tests/networking.nix Normal file
View File

@ -0,0 +1,381 @@
import ./make-test.nix ({ networkd, test, ... }:
let
router = { config, pkgs, ... }:
with pkgs.lib;
let
vlanIfs = range 1 (length config.virtualisation.vlans);
in {
virtualisation.vlans = [ 1 2 3 ];
networking = {
useDHCP = false;
useNetworkd = networkd;
firewall.allowPing = true;
interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n:
nameValuePair "eth${toString n}" {
ipAddress = "192.168.${toString n}.1";
prefixLength = 24;
})));
};
services.dhcpd = {
enable = true;
interfaces = map (n: "eth${toString n}") vlanIfs;
extraConfig = ''
option subnet-mask 255.255.255.0;
'' + flip concatMapStrings vlanIfs (n: ''
subnet 192.168.${toString n}.0 netmask 255.255.255.0 {
option broadcast-address 192.168.${toString n}.255;
option routers 192.168.${toString n}.1;
range 192.168.${toString n}.2 192.168.${toString n}.254;
}
'');
};
};
testCases = {
static = {
name = "Static";
nodes.router = router;
nodes.client = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
defaultGateway = "192.168.1.1";
interfaces.eth1.ip4 = mkOverride 0 [
{ address = "192.168.1.2"; prefixLength = 24; }
{ address = "192.168.1.3"; prefixLength = 32; }
{ address = "192.168.1.10"; prefixLength = 32; }
];
interfaces.eth2.ip4 = mkOverride 0 [
{ address = "192.168.2.2"; prefixLength = 24; }
];
};
};
testScript = { nodes, ... }:
''
startAll;
$client->waitForUnit("network-interfaces.target");
$client->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Make sure dhcpcd is not started
$client->fail("systemctl status dhcpcd.service");
# Test vlan 1
$client->succeed("ping -c 1 192.168.1.1");
$client->succeed("ping -c 1 192.168.1.2");
$client->succeed("ping -c 1 192.168.1.3");
$client->succeed("ping -c 1 192.168.1.10");
$router->succeed("ping -c 1 192.168.1.1");
$router->succeed("ping -c 1 192.168.1.2");
$router->succeed("ping -c 1 192.168.1.3");
$router->succeed("ping -c 1 192.168.1.10");
# Test vlan 2
$client->succeed("ping -c 1 192.168.2.1");
$client->succeed("ping -c 1 192.168.2.2");
$router->succeed("ping -c 1 192.168.2.1");
$router->succeed("ping -c 1 192.168.2.2");
# Test default gateway
$router->succeed("ping -c 1 192.168.3.1");
$client->succeed("ping -c 1 192.168.3.1");
'';
};
dhcpSimple = {
name = "SimpleDHCP";
nodes.router = router;
nodes.client = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = true;
interfaces.eth1.ip4 = mkOverride 0 [ ];
interfaces.eth2.ip4 = mkOverride 0 [ ];
};
};
testScript = { nodes, ... }:
''
startAll;
$client->waitForUnit("network-interfaces.target");
$client->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Wait until we have an ip address on each interface
$client->succeed("while ! ip addr show dev eth1 | grep '192.168.1'; do true; done");
$client->succeed("while ! ip addr show dev eth2 | grep '192.168.2'; do true; done");
# Test vlan 1
$client->succeed("ping -c 1 192.168.1.1");
$client->succeed("ping -c 1 192.168.1.2");
$router->succeed("ping -c 1 192.168.1.1");
$router->succeed("ping -c 1 192.168.1.2");
# Test vlan 2
$client->succeed("ping -c 1 192.168.2.1");
$client->succeed("ping -c 1 192.168.2.2");
$router->succeed("ping -c 1 192.168.2.1");
$router->succeed("ping -c 1 192.168.2.2");
'';
};
dhcpOneIf = {
name = "OneInterfaceDHCP";
nodes.router = router;
nodes.client = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
interfaces.eth1 = {
ip4 = mkOverride 0 [ ];
useDHCP = true;
};
interfaces.eth2.ip4 = mkOverride 0 [ ];
};
};
testScript = { nodes, ... }:
''
startAll;
$client->waitForUnit("network-interfaces.target");
$client->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Wait until we have an ip address on each interface
$client->succeed("while ! ip addr show dev eth1 | grep '192.168.1'; do true; done");
# Test vlan 1
$client->succeed("ping -c 1 192.168.1.1");
$client->succeed("ping -c 1 192.168.1.2");
$router->succeed("ping -c 1 192.168.1.1");
$router->succeed("ping -c 1 192.168.1.2");
# Test vlan 2
$client->succeed("ping -c 1 192.168.2.1");
$client->fail("ping -c 1 192.168.2.2");
$router->succeed("ping -c 1 192.168.2.1");
$router->fail("ping -c 1 192.168.2.2");
'';
};
bond = let
node = address: { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
bonds.bond = {
mode = "balance-rr";
interfaces = [ "eth1" "eth2" ];
};
interfaces.eth1.ip4 = mkOverride 0 [ ];
interfaces.eth2.ip4 = mkOverride 0 [ ];
interfaces.bond.ip4 = mkOverride 0
[ { inherit address; prefixLength = 30; } ];
};
};
in {
name = "Bond";
nodes.client1 = node "192.168.1.1";
nodes.client2 = node "192.168.1.2";
testScript = { nodes, ... }:
''
startAll;
$client1->waitForUnit("network-interfaces.target");
$client1->waitForUnit("network.target");
$client2->waitForUnit("network-interfaces.target");
$client2->waitForUnit("network.target");
# Test bonding
$client1->succeed("ping -c 2 192.168.1.1");
$client1->succeed("ping -c 2 192.168.1.2");
$client2->succeed("ping -c 2 192.168.1.1");
$client2->succeed("ping -c 2 192.168.1.2");
'';
};
bridge = let
node = { address, vlan }: { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ vlan ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
interfaces.eth1.ip4 = mkOverride 0
[ { inherit address; prefixLength = 24; } ];
};
};
in {
name = "Bridge";
nodes.client1 = node { address = "192.168.1.2"; vlan = 1; };
nodes.client2 = node { address = "192.168.1.3"; vlan = 2; };
nodes.router = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
bridges.bridge.interfaces = [ "eth1" "eth2" ];
interfaces.eth1.ip4 = mkOverride 0 [ ];
interfaces.eth2.ip4 = mkOverride 0 [ ];
interfaces.bridge.ip4 = mkOverride 0
[ { address = "192.168.1.1"; prefixLength = 24; } ];
};
};
testScript = { nodes, ... }:
''
startAll;
$client1->waitForUnit("network-interfaces.target");
$client1->waitForUnit("network.target");
$client2->waitForUnit("network-interfaces.target");
$client2->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Test bridging
$client1->succeed("ping -c 1 192.168.1.1");
$client1->succeed("ping -c 1 192.168.1.2");
$client1->succeed("ping -c 1 192.168.1.3");
$client2->succeed("ping -c 1 192.168.1.1");
$client2->succeed("ping -c 1 192.168.1.2");
$client2->succeed("ping -c 1 192.168.1.3");
$router->succeed("ping -c 1 192.168.1.1");
$router->succeed("ping -c 1 192.168.1.2");
$router->succeed("ping -c 1 192.168.1.3");
'';
};
macvlan = {
name = "MACVLAN";
nodes.router = router;
nodes.client = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = true;
macvlans.macvlan.interface = "eth1";
interfaces.eth1.ip4 = mkOverride 0 [ ];
};
};
testScript = { nodes, ... }:
''
startAll;
$client->waitForUnit("network-interfaces.target");
$client->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Wait until we have an ip address on each interface
$client->succeed("while ! ip addr show dev eth1 | grep '192.168.1'; do true; done");
$client->succeed("while ! ip addr show dev macvlan | grep '192.168.1'; do true; done");
# Test macvlan
$client->succeed("ping -c 1 192.168.1.1");
$client->succeed("ping -c 1 192.168.1.2");
$client->succeed("ping -c 1 192.168.1.3");
$router->succeed("ping -c 1 192.168.1.1");
$router->succeed("ping -c 1 192.168.1.2");
$router->succeed("ping -c 1 192.168.1.3");
'';
};
sit = let
node = { address4, remote, address6 }: { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = networkd;
firewall.enable = false;
useDHCP = false;
sits.sit = {
inherit remote;
local = address4;
dev = "eth1";
};
interfaces.eth1.ip4 = mkOverride 0
[ { address = address4; prefixLength = 24; } ];
interfaces.sit.ip6 = mkOverride 0
[ { address = address6; prefixLength = 64; } ];
};
};
in {
name = "Sit";
nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; };
nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; };
testScript = { nodes, ... }:
''
startAll;
$client1->waitForUnit("network-interfaces.target");
$client1->waitForUnit("network.target");
$client2->waitForUnit("network-interfaces.target");
$client2->waitForUnit("network.target");
$client1->succeed("ip addr >&2");
$client2->succeed("ip addr >&2");
# Test ipv6
$client1->succeed("ping6 -c 1 fc00::1");
$client1->succeed("ping6 -c 1 fc00::2");
$client2->succeed("ping6 -c 1 fc00::1");
$client2->succeed("ping6 -c 1 fc00::2");
'';
};
vlan = let
node = address: { config, pkgs, ... }: with pkgs.lib; {
#virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
vlans.vlan = {
id = 1;
interface = "eth0";
};
interfaces.eth0.ip4 = mkOverride 0 [ ];
interfaces.eth1.ip4 = mkOverride 0 [ ];
interfaces.vlan.ip4 = mkOverride 0
[ { inherit address; prefixLength = 24; } ];
};
};
in {
name = "vlan";
nodes.client1 = node "192.168.1.1";
nodes.client2 = node "192.168.1.2";
testScript = { nodes, ... }:
''
startAll;
$client1->waitForUnit("network-interfaces.target");
$client1->waitForUnit("network.target");
$client2->waitForUnit("network-interfaces.target");
$client2->waitForUnit("network.target");
# Test vlan is setup
$client1->succeed("ip addr show dev vlan >&2");
$client2->succeed("ip addr show dev vlan >&2");
'';
};
};
case = testCases.${test};
in case // {
name = "${case.name}-Networking-${if networkd then "Networkd" else "Scripted"}";
})

View File

@ -38,7 +38,8 @@ in
testScript = testScript =
'' ''
$server->waitForUnit("nfsd"); $server->waitForUnit("nfsd");
$server->waitForUnit("network.target"); $server->succeed("systemctl start network-online.target");
$server->waitForUnit("network-online.target");
startAll; startAll;

21
nixos/tests/peerflix.nix Normal file
View File

@ -0,0 +1,21 @@
# This test runs peerflix and checks if peerflix starts
import ./make-test.nix {
name = "peerflix";
nodes = {
peerflix =
{ config, pkgs, ... }:
{
services.peerflix.enable = true;
};
};
testScript = ''
startAll;
$peerflix->waitForUnit("peerflix.service");
$peerflix->waitUntilSucceeds("curl localhost:9000");
'';
}

View File

@ -5,11 +5,11 @@
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "easytag-${version}"; name = "easytag-${version}";
version = "2.3.1"; version = "2.3.2";
src = fetchurl { src = fetchurl {
url = "mirror://gnome/sources/easytag/2.3/${name}.tar.xz"; url = "mirror://gnome/sources/easytag/2.3/${name}.tar.xz";
sha256 = "19cdx4hma4nl38m1zrc3mq9cjg6knw970abk5anhg7cvpc1371s7"; sha256 = "0bj3sj4yzlnhan38j84acs7qv27fl3xy4rdrfq6dnpz4q6qccm84";
}; };
preFixup = '' preFixup = ''

View File

@ -17,7 +17,7 @@ stdenv.mkDerivation rec {
src = if stdenv.system == "x86_64-linux" src = if stdenv.system == "x86_64-linux"
then fetchurl { then fetchurl {
url = "http://dl.google.com/linux/musicmanager/deb/pool/main/g/google-musicmanager-beta/google-musicmanager-${version}_amd64.deb"; url = "http://dl.google.com/linux/musicmanager/deb/pool/main/g/google-musicmanager-beta/google-musicmanager-${version}_amd64.deb";
sha256 = "0efdce3970e2cf83eb7d8f6021f987a1517a41823784ada8e51f1649f8a49342"; sha256 = "10nr7qlrn5af4g0l6n4xzximmhc216vhzgpy7cpxs662zpli3v1a";
} }
else fetchurl { else fetchurl {
url = "http://dl.google.com/linux/musicmanager/deb/pool/main/g/google-musicmanager-beta/google-musicmanager-${version}_i386.deb"; url = "http://dl.google.com/linux/musicmanager/deb/pool/main/g/google-musicmanager-beta/google-musicmanager-${version}_i386.deb";

View File

@ -4,11 +4,11 @@
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "guitarix-${version}"; name = "guitarix-${version}";
version = "0.32.0"; version = "0.32.1";
src = fetchurl { src = fetchurl {
url = "mirror://sourceforge/guitarix/guitarix2-${version}.tar.bz2"; url = "mirror://sourceforge/guitarix/guitarix2-${version}.tar.bz2";
sha256 = "06qxydcba1ga1l19kyqy0mk141mv6pa4wbkyh75xbwhyr65bwkc4"; sha256 = "1sl7ca1lj0wchh3xq7qw3zqrbyyh4r8cwljb9i3yplpsn90d1i3k";
}; };
buildInputs = [ buildInputs = [

View File

@ -0,0 +1,47 @@
{ stdenv, fetchurl, pkgconfig
, lv2, mesa, gtk2, cairo, pango, fftw }:
let
version = "0.8.1";
name = "meters.lv2-${version}";
# robtk submodule is pegged to this version
robtkVersion = "0.3.0";
robtkName = "robtk-${robtkVersion}";
src = fetchurl {
name = "${name}.tar.gz";
url = "https://github.com/x42/meters.lv2/archive/v${version}.tar.gz";
sha256 = "142dg0j34mv5b0agajj2x1n9kgsmkfh08n1cjzk0j8n4xk2wb6ri";
};
robtkSrc = fetchurl {
name = "${robtkName}.tar.gz";
url = "https://github.com/x42/robtk/archive/v${robtkVersion}.tar.gz";
sha256 = "1ny89i2sgga56k7fxskp9y8sb7pfhp6wgw5mni842p19z6q7h8rq";
};
in
stdenv.mkDerivation {
inherit name;
buildInputs = [ pkgconfig lv2 mesa gtk2 cairo pango fftw ];
srcs = [ src robtkSrc ];
sourceRoot = name;
postUnpack = "mv ${robtkName}/* ${name}/robtk"; # */
postPatch = "sed -i 's/fftw3f/fftw3/' Makefile";
preConfigure = "makeFlagsArray=( PREFIX=$out )";
meter_VERSION = version;
meta = with stdenv.lib;
{ description = "Collection of audio level meters with GUI in LV2 plugin format";
homepage = http://x42.github.io/meters.lv2/;
maintainers = with maintainers; [ emery ];
license = licenses.gpl2;
platforms = platforms.linux;
};
}

View File

@ -0,0 +1,23 @@
{ stdenv, fetchurl, pythonPackages, mopidy }:
pythonPackages.buildPythonPackage rec {
name = "mopidy-mopify-${version}";
version = "0.1.6";
src = fetchurl {
url = "https://github.com/dirkgroenen/mopidy-mopify/archive/${version}.tar.gz";
sha256 = "3581de6b0b42d2ece63bc153dcdba0594fbbeaacf695f2cd1e5d199670d83775";
};
propagatedBuildInputs = [ mopidy ];
doCheck = false;
meta = with stdenv.lib; {
homepage = https://github.com/dirkgroenen/mopidy-mopify;
description = "A mopidy webclient based on the Spotify webbased interface.";
license = licenses.gpl3;
maintainers = [ maintainers.Gonzih ];
};
}

View File

@ -28,11 +28,11 @@
# handle that. # handle that.
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "qmmp-0.7.6"; name = "qmmp-0.8.2";
src = fetchurl { src = fetchurl {
url = "http://qmmp.ylsoftware.com/files/${name}.tar.bz2"; url = "http://qmmp.ylsoftware.com/files/${name}.tar.bz2";
sha256 = "1hq08ii06lyfg516jrvxdfcjj509gvglvdlsr96aqi1fh8v4k5p9"; sha256 = "1vwjy3bv1gj6k5kqkhw2q7aspashw6x4lxccl28iydjfzk7d7cd4";
}; };
buildInputs = buildInputs =

View File

@ -0,0 +1,23 @@
{ stdenv, fetchurl, alsaLib, python, SDL }:
stdenv.mkDerivation rec {
version = "20120105";
name = "schismtracker-${version}";
src = fetchurl {
url = "http://schismtracker.org/dl/${name}.tar.bz2";
sha256 = "1ny7wv2wxm1av299wvpskall6438wjjpadphmqc7c0h6d0zg5kii";
};
configureFlags = "--enable-dependency-tracking";
buildInputs = [ alsaLib python SDL ];
meta = {
description = "Music tracker application, free reimplementation of Impulse Tracker";
homepage = "http://schismtracker.org/";
license = stdenv.lib.licenses.gpl2;
platforms = [ "x86_64-linux" "i686-linux" ];
maintainers = [ stdenv.lib.maintainers.ftrvxmtrx ];
};
}

View File

@ -8,12 +8,11 @@
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "sonic-visualiser-${version}"; name = "sonic-visualiser-${version}";
version = "2.3"; version = "2.4.1";
src = fetchurl { src = fetchurl {
url = "http://code.soundsoftware.ac.uk/attachments/download/1185/${name}.tar.gz";
url = "http://code.soundsoftware.ac.uk/attachments/download/918/${name}.tar.gz"; sha256 = "06nlha70kgrby16nyhngrv5q846xagnxdinv608v7ga7vpywwmyb";
sha256 = "1f06w2rin4r2mbi00bg3nmqdi2xdy9vq4jcmfanxzj3ld66ik40c";
}; };
buildInputs = buildInputs =

View File

@ -1,20 +1,20 @@
{ stdenv, fetchurl, alsaLib, boost, cairo, cmake, fftwSinglePrec, fltk { stdenv, fetchurl, alsaLib, boost, cairo, cmake, fftwSinglePrec, fltk
, jack2, libsndfile, mesa, minixml, pkgconfig, zlib, xorg , jack2, libsndfile, lv2, mesa, minixml, pkgconfig, zlib, xorg
}: }:
assert stdenv ? glibc; assert stdenv ? glibc;
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "yoshimi-${version}"; name = "yoshimi-${version}";
version = "1.2.5"; version = "1.3.0";
src = fetchurl { src = fetchurl {
url = "mirror://sourceforge/yoshimi/${name}.tar.bz2"; url = "mirror://sourceforge/yoshimi/${name}.tar.bz2";
sha256 = "0lixrxv0wds3p50kmy9k166qhavdjkhlxs432s248hk43k7n6c1h"; sha256 = "1zxblcl6ffwwzxh3d17hw1mp398b73wk5bsagdmx5gph038gdh7y";
}; };
buildInputs = [ buildInputs = [
alsaLib boost cairo fftwSinglePrec fltk jack2 libsndfile mesa alsaLib boost cairo fftwSinglePrec fltk jack2 libsndfile lv2 mesa
minixml zlib xorg.libpthreadstubs minixml zlib xorg.libpthreadstubs
]; ];

View File

@ -179,6 +179,7 @@ let
buildPycharm = { name, version, build, src, license, description }: buildPycharm = { name, version, build, src, license, description }:
(mkIdeaProduct rec { (mkIdeaProduct rec {
inherit name version build src; inherit name version build src;
patchSnappy = false;
product = "PyCharm"; product = "PyCharm";
meta = with stdenv.lib; { meta = with stdenv.lib; {
homepage = "https://www.jetbrains.com/pycharm/"; homepage = "https://www.jetbrains.com/pycharm/";
@ -270,25 +271,25 @@ in
pycharm-community = buildPycharm rec { pycharm-community = buildPycharm rec {
name = "pycharm-community-${version}"; name = "pycharm-community-${version}";
version = "3.4.1"; version = "4.0.1";
build = "135.1057"; build = "139.574";
description = "PyCharm 3.4 Community Edition"; description = "PyCharm 4.0 Community Edition";
license = stdenv.lib.licenses.asl20; license = stdenv.lib.licenses.asl20;
src = fetchurl { src = fetchurl {
url = "http://download.jetbrains.com/python/${name}.tar.gz"; url = "http://download.jetbrains.com/python/${name}.tar.gz";
sha256 = "96427b1e842e7c09141ec4d3ede627c5ca7d821c0d6c98169b56a34f9035ef64"; sha256 = "0jh0sxi5dpgpw7ga018fby7zvb4i9k49vwl8422lfcrgckdz9nv2";
}; };
}; };
pycharm-professional = buildPycharm rec { pycharm-professional = buildPycharm rec {
name = "pycharm-professional-${version}"; name = "pycharm-professional-${version}";
version = "3.4.1"; version = "4.0.1";
build = "135.1057"; build = "139.574";
description = "PyCharm 3.4 Professional Edition"; description = "PyCharm 4.0 Professional Edition";
license = stdenv.lib.licenses.unfree; license = stdenv.lib.licenses.unfree;
src = fetchurl { src = fetchurl {
url = "http://download.jetbrains.com/python/${name}.tar.gz"; url = "http://download.jetbrains.com/python/${name}.tar.gz";
sha256 = "e4f85f3248e8985ac9f8c326543f979b47ba1d7ac6b128a2cf2b3eb8ec545d2b"; sha256 = "04yjhg6vi2kz00sy8zg4wkz26ai90vbp0cnd850ynsab0jsy24w4";
}; };
}; };

View File

@ -5,8 +5,8 @@ stdenv.mkDerivation {
src = fetchgit { src = fetchgit {
url = "https://github.com/muennich/sxiv.git"; url = "https://github.com/muennich/sxiv.git";
rev = "54af451b4a81b5b1072f27de0981a2d39cabc2d6"; rev = "6216bf6c2d42be63025d29550831d9f4447f4066";
sha256 = "1b0fb6bd8d36af4c7f1160fcc12b5b7382546c7da35b4924d259f7efaa4c97d0"; sha256 = "e25e19cf073cc2621656e50d2c31cc59cc0fc200716f96c765374568a26977f1";
}; };
postUnpack = '' postUnpack = ''

View File

@ -1,6 +1,6 @@
{ fetchurl, stdenv, pkgconfig { fetchurl, stdenv, pkgconfig
, openssl, db48, boost, zlib, miniupnpc, qt4, qrencode, glib, protobuf , openssl, db48, boost, zlib, miniupnpc, qt4, qrencode, glib, protobuf
, utillinux, autogen, autoconf, autobuild, automake, db }: , utillinux, autogen, autoconf, autobuild, automake, autoreconfHook, db }:
with stdenv.lib; with stdenv.lib;
@ -8,7 +8,7 @@ let
buildAltcoin = makeOverridable ({walletName, gui ? true, ...}@a: buildAltcoin = makeOverridable ({walletName, gui ? true, ...}@a:
stdenv.mkDerivation ({ stdenv.mkDerivation ({
name = "${walletName}${toString (optional (!gui) "d")}-${a.version}"; name = "${walletName}${toString (optional (!gui) "d")}-${a.version}";
buildInputs = [ openssl db48 boost zlib miniupnpc ] buildInputs = [ pkgconfig openssl db48 boost zlib miniupnpc ]
++ optionals gui [ qt4 qrencode ] ++ a.extraBuildInputs or []; ++ optionals gui [ qt4 qrencode ] ++ a.extraBuildInputs or [];
configurePhase = optional gui "qmake"; configurePhase = optional gui "qmake";
@ -27,7 +27,7 @@ let
meta = { meta = {
platforms = platforms.unix; platforms = platforms.unix;
license = license.mit; license = license.mit;
maintainers = [ maintainers.offline ]; maintainers = [ maintainers.offline ] ++ a.extraMaintainers;
}; };
} // a) } // a)
); );
@ -35,31 +35,6 @@ let
in rec { in rec {
inherit buildAltcoin; inherit buildAltcoin;
litecoin = buildAltcoin rec {
walletName = "litecoin";
version = "0.8.5.3-rc3";
src = fetchurl {
url = "https://github.com/litecoin-project/litecoin/archive/v${version}.tar.gz";
sha256 = "1z4a7bm3z9kd7n0s38kln31z8shsd32d5d5v3br5p0jlnr5g3lk7";
};
meta = {
description = "A lite version of Bitcoin using scrypt as a proof-of-work algorithm";
longDescription= ''
Litecoin is a peer-to-peer Internet currency that enables instant payments
to anyone in the world. It is based on the Bitcoin protocol but differs
from Bitcoin in that it can be efficiently mined with consumer-grade hardware.
Litecoin provides faster transaction confirmations (2.5 minutes on average)
and uses a memory-hard, scrypt-based mining proof-of-work algorithm to target
the regular computers and GPUs most people already have.
The Litecoin network is scheduled to produce 84 million currency units.
'';
homepage = https://litecoin.org/;
};
};
litecoind = litecoin.override { gui = false; };
namecoin = buildAltcoin rec { namecoin = buildAltcoin rec {
walletName = "namecoin"; walletName = "namecoin";
version = "0.3.51.00"; version = "0.3.51.00";
@ -80,4 +55,28 @@ in rec {
}; };
}; };
darkcoin = buildAltcoin rec {
walletName = "darkcoin";
version = "0.9.13.15";
src = fetchurl {
url = "https://github.com/darkcoin/darkcoin/archive/v${version}.tar.gz";
sha256 = "1kly2y3g4dr1jwwf81smqvc7k662x6rvg4ggmxva1yaifb67bgjb";
};
extraBuildInputs = [ glib ];
meta = {
description = "A decentralized key/value registration and transfer system";
longDescription = ''
Darkcoin (DRK) is an open sourced, privacy-centric digital
currency. It allows you keep your finances private as you make
transactions, similar to cash.
'';
homepage = http://darkcoin.io;
extraMaintainers = [ maintainers.AndersonTorres ];
};
};
darkcoind = darkcoin.override { gui = false; };
} }

View File

@ -0,0 +1,60 @@
{ stdenv, fetchurl, pkgconfig
, openssl, db48, boost, zlib, miniupnpc, qt4, qrencode, glib, protobuf
, utillinux, autogen, autoreconfHook }:
with stdenv.lib;
let
mkAutoreconfCoin =
{ name, version, withGui, src, meta }:
stdenv.mkDerivation {
inherit src meta;
name = name + (toString (optional (!withGui) "d")) + "-" + version;
buildInputs = [ autogen autoreconfHook pkgconfig openssl
boost zlib miniupnpc db48 glib utillinux protobuf ]
++ optionals withGui [ qt4 qrencode protobuf ];
configureFlags = [ "--with-boost-libdir=${boost.lib}/lib" ] ++ optionals withGui [ "--with-gui=qt4" ];
};
mkLitecoin = { withGui }:
mkAutoreconfCoin rec {
name = "litecoin";
version = "0.9.3-preview5";
inherit withGui;
src = fetchurl {
url = "https://github.com/litecoin-project/litecoin/archive/v${version}.tar.gz";
sha256 = "0nnfz4s2g28jb5fqy6cabsryp3h2amzlyslr6g6k8r1vmzvx5ym6";
};
meta = with stdenv.lib; {
description = "A lite version of Bitcoin using scrypt as a proof-of-work algorithm";
longDescription= ''
Litecoin is a peer-to-peer Internet currency that enables instant payments
to anyone in the world. It is based on the Bitcoin protocol but differs
from Bitcoin in that it can be efficiently mined with consumer-grade hardware.
Litecoin provides faster transaction confirmations (2.5 minutes on average)
and uses a memory-hard, scrypt-based mining proof-of-work algorithm to target
the regular computers and GPUs most people already have.
The Litecoin network is scheduled to produce 84 million currency units.
'';
homepage = https://litecoin.org/;
platforms = platforms.unix;
license = licenses.mit;
maintainers = [ maintainers.offline maintainers.AndersonTorres ];
};
};
in {
litecoin = mkLitecoin { withGui = true; };
litecoind = mkLitecoin { withGui = false; };
}

View File

@ -19,7 +19,7 @@ stdenv.mkDerivation rec {
# http://sourceforge.net/projects/eaglemode/forums/forum/808824/topic/5115261 # http://sourceforge.net/projects/eaglemode/forums/forum/808824/topic/5115261
buildPhase = '' buildPhase = ''
export NIX_LDFLAGS="$NIX_LDFLAGS -lXxf86vm -lXext" export NIX_LDFLAGS="$NIX_LDFLAGS -lXxf86vm -lXext"
yes y | perl make.pl build perl make.pl build
''; '';
dontPatchELF = true; dontPatchELF = true;

View File

@ -1,7 +1,7 @@
{ stdenv, fetchgit, autoconf, automake, pkgconfig, libxml2 }: { stdenv, fetchgit, autoconf, automake, pkgconfig, libxml2 }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "evtest-1.31"; name = "evtest-1.32";
preConfigure = "autoreconf -iv"; preConfigure = "autoreconf -iv";
@ -9,8 +9,8 @@ stdenv.mkDerivation rec {
src = fetchgit { src = fetchgit {
url = "git://anongit.freedesktop.org/evtest"; url = "git://anongit.freedesktop.org/evtest";
rev = "871371806017301373b8b0e5b7e8f168ce1ea13f"; rev = "refs/tags/evtest-1.32";
sha256 = "1hxldlldlrb9lnnybn839a97fpqd1cixbmci2wzgr0rzhjbwhcgp"; sha256 = "150lb7d2gnkcqgfw1hcnb8lcvdb52fpig9j9qxjizp6irhlw2a31";
}; };
meta = with stdenv.lib; { meta = with stdenv.lib; {

View File

@ -7,12 +7,12 @@ assert pythonSupport -> python != null && swig != null;
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "gnuradio-osmosdr-${version}"; name = "gnuradio-osmosdr-${version}";
version = "0.1.0"; version = "0.1.4";
src = fetchgit { src = fetchgit {
url = "git://git.osmocom.org/gr-osmosdr"; url = "git://git.osmocom.org/gr-osmosdr";
rev = "refs/tags/v${version}"; rev = "refs/tags/v${version}";
sha256 = "112zfvnr6fjvhdc06ihi2sb0dp441qy7jq8rvr81nbyv3r8jspj4"; sha256 = "0vyzr4fhkblf2v3d7m0ch5hws4c493jw3ydl4y6b2dfbfzchhsz8";
}; };
buildInputs = [ buildInputs = [

View File

@ -23,11 +23,11 @@
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "gnuradio-${version}"; name = "gnuradio-${version}";
version = "3.7.5"; version = "3.7.5.1";
src = fetchurl { src = fetchurl {
url = "http://gnuradio.org/releases/gnuradio/${name}.tar.gz"; url = "http://gnuradio.org/releases/gnuradio/${name}.tar.gz";
sha256 = "0hv2nyz2hp1mjinin2q7jimh9mr81rjqvghqmaglz8w70qcn4zs6"; sha256 = "0gg4i8s1z5pcfk8d7n7baxv3lx2cjcizimvbziraj27lcbvpmwar";
}; };
buildInputs = [ buildInputs = [

View File

@ -8,11 +8,11 @@ assert pulseaudioSupport -> pulseaudio != null;
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "gqrx-${version}"; name = "gqrx-${version}";
version = "2.2.0"; version = "2.3.0";
src = fetchurl { src = fetchurl {
url = "mirror://sourceforge/project/gqrx/${version}/${name}-src.tar.gz"; url = "mirror://sourceforge/project/gqrx/${version}/${name}.tar.xz";
sha256 = "15ncx2shh43skph7sj3jvmkls9cbbbysld49c8xd23fhdsxanj9x"; sha256 = "0fyfkdd2ailg54ppv1y2fy2c692jmlmsyl1lxr20lyn6bvd9gpyn";
}; };
buildInputs = [ buildInputs = [
@ -21,6 +21,14 @@ stdenv.mkDerivation rec {
configurePhase = ''qmake PREFIX="$out"''; configurePhase = ''qmake PREFIX="$out"'';
postInstall = ''
mkdir -p "$out/share/applications"
mkdir -p "$out/share/icons"
cp gqrx.desktop "$out/share/applications/"
cp icons/gqrx.svg "$out/share/icons/"
'';
meta = with stdenv.lib; { meta = with stdenv.lib; {
description = "Software defined radio (SDR) receiver"; description = "Software defined radio (SDR) receiver";
longDescription = '' longDescription = ''

View File

@ -0,0 +1,57 @@
{ stdenv, fetchurl, gtk3, pythonPackages, python, pycairo, pygobject3, intltool,
pango, gsettings_desktop_schemas }:
pythonPackages.buildPythonPackage rec {
version = "4.1.1";
name = "gramps-${version}";
namePrefix = "";
buildInputs = [ intltool gtk3 ];
# Currently broken
doCheck = false;
src = fetchurl {
url = "mirror://sourceforge/gramps/Stable/${version}/${name}.tar.gz";
sha256 = "0jdps7yx2mlma1hdj64wssvnqd824xdvw0bmn2dnal5fn3h7h060";
};
pythonPath = [ pygobject3 pango pycairo pythonPackages.bsddb ];
# Same installPhase as in buildPythonPackage but without --old-and-unmanageble
# install flag.
installPhase = ''
runHook preInstall
mkdir -p "$out/lib/${python.libPrefix}/site-packages"
export PYTHONPATH="$out/lib/${python.libPrefix}/site-packages:$PYTHONPATH"
${python}/bin/${python.executable} setup.py install \
--install-lib=$out/lib/${python.libPrefix}/site-packages \
--prefix="$out"
eapth="$out/lib/${python.libPrefix}"/site-packages/easy-install.pth
if [ -e "$eapth" ]; then
# move colliding easy_install.pth to specifically named one
mv "$eapth" $(dirname "$eapth")/${name}.pth
fi
rm -f "$out/lib/${python.libPrefix}"/site-packages/site.py*
runHook postInstall
'';
# gobjectIntrospection package, wrap accordingly
preFixup = ''
wrapProgram $out/bin/gramps \
--prefix GI_TYPELIB_PATH : "$GI_TYPELIB_PATH" \
--prefix XDG_DATA_DIRS : "$GSETTINGS_SCHEMAS_PATH:$out/share"
'';
meta = with stdenv.lib; {
description = "Genealogy software";
homepage = http://gramps-project.org;
license = licenses.gpl2;
};
}

View File

@ -1,75 +1,41 @@
{ stdenv, fetchgit, ocaml, mupdf, lablgl, mesa { stdenv, makeWrapper, fetchgit, pkgconfig, ninja, ocaml, findlib, mupdf, lablgl
, libX11, libXext, gtk3, freetype, zlib, openjpeg , gtk3, openjpeg, jbig2dec, mujs }:
, jbig2dec, libjpeg, ncurses }:
stdenv.mkDerivation { let ocamlVersion = (builtins.parseDrvName (ocaml.name)).version;
name = "llpp-2014-05-26"; in stdenv.mkDerivation rec {
name = "llpp-2014-11-29";
src = fetchgit { src = fetchgit {
url = "git://repo.or.cz/llpp.git"; url = "git://repo.or.cz/llpp.git";
rev = "902143de64d86b5714b3a59d2cc7085083b87249"; rev = "481c8398b2c5dc4589738f5f80104ed75b9c73ff";
sha256 = "038xl4gbvm57na2lz1fw36sf43zaxq407zi2d53985vc33677j9s"; sha256 = "13zi5mzpd9j4mmm68m3zkv49xgkhswhqvmp4bbyi0psmhxak8y5l";
}; };
buildInputs = [ ocaml mupdf lablgl mesa libX11 libXext gtk3 buildInputs = [ pkgconfig ninja makeWrapper ocaml findlib mupdf lablgl
freetype jbig2dec libjpeg openjpeg zlib ncurses ]; gtk3 jbig2dec openjpeg mujs ];
# The build phase was extracted from buildall.sh, because that script configurePhase = ''
# fetched the dependencies on its own. sh configure.sh -O -F ${mupdf}
buildPhase = '' sed -i 's;-lopenjpeg;-lopenjp2;g' .config
ccopt="-O" sed -i 's;$builddir/link\.so;link.so;g' build.ninja
ccopt="$ccopt -I ${jbig2dec}/include"
ccopt="$ccopt -I ${libjpeg}/include"
ccopt="$ccopt -I ${freetype}/include/freetype2"
ccopt="$ccopt -I ${openjpeg}/include"
ccopt="$ccopt -I ${zlib}/include"
ccopt="$ccopt -I ${mupdf}/include"
ccopt="$ccopt -include ft2build.h"
ccopt="$ccopt -D_GNU_SOURCE"
cclib="$cclib -lmupdf"
cclib="$cclib -lz -ljpeg -lopenjp2 -ljbig2dec -lfreetype -lpthread"
cclib="$cclib -lX11"
cclib="$cclib -lfreetype"
comp=ocamlc.opt
cmsuf=cmo
sh mkhelp.sh keystoml.ml KEYS > help.ml
$comp -c -o link.o -ccopt "$ccopt" link.c
$comp -c -o help.$cmsuf help.ml
$comp -c -o utils.$cmsuf utils.ml
$comp -c -o wsi.cmi wsi.mli
$comp -c -o wsi.$cmsuf wsi.ml
$comp -c -o parser.$cmsuf parser.ml
$comp -c -o main.$cmsuf -I ${lablgl}/lib/ocaml/4.01.0/site-lib/lablgl main.ml
$comp -custom -o llpp \
-I ${lablgl}/lib/ocaml/4.01.0/site-lib/lablgl \
str.cma unix.cma lablgl.cma \
link.o \
-cclib "$cclib" \
help.cmo \
utils.cmo \
parser.cmo \
wsi.cmo \
main.cmo
''; '';
# Binary fails with 'No bytecode file specified.' if stripped. buildPhase = "${ninja}/bin/ninja";
dontStrip = true;
installPhase = '' installPhase = ''
install -d $out/bin install -d $out/bin $out/lib
install llpp llppac $out/bin install build/llpp $out/bin
install link.so $out/lib
wrapProgram $out/bin/llpp \
--prefix CAML_LD_LIBRARY_PATH ":" "${lablgl}/lib/ocaml/${ocamlVersion}/site-lib/lablgl" \
--prefix CAML_LD_LIBRARY_PATH ":" "$out/lib"
''; '';
meta = { meta = with stdenv.lib; {
homepage = http://repo.or.cz/w/llpp.git; homepage = http://repo.or.cz/w/llpp.git;
description = "A MuPDF based PDF pager written in OCaml"; description = "A MuPDF based PDF pager written in OCaml";
platforms = stdenv.lib.platforms.linux; platforms = platforms.linux;
maintainers = [ stdenv.lib.maintainers.pSub ]; maintainers = with maintainers; [ pSub ];
license = "GPL"; license = licenses.gpl3;
}; };
} }

View File

@ -0,0 +1,44 @@
{ stdenv, lib, fetchurl, dpkg, patchelf, qt4, libXtst, libXext, libX11, makeWrapper, libXScrnSaver }:
let
src =
if stdenv.system == "i686-linux" then fetchurl {
name = "rescuetime-installer.deb";
url = "https://www.rescuetime.com/installers/rescuetime_current_i386.deb";
sha256 = "03dj0ivavxlcvx7dv7y6zllwqkclfyxkfax691zv2qclmk5gf8wz";
} else fetchurl {
name = "rescuetime-installer.deb";
url = "https://www.rescuetime.com/installers/rescuetime_current_amd64.deb";
sha256 = "11by4lkij1ryv8h3mz55hj3ssrikl697rs5b7mlg3g058gr2v3wl";
};
in
stdenv.mkDerivation {
name = "rescuetime-2.8.6.1015";
inherit src;
buildInputs = [ dpkg makeWrapper ];
unpackPhase = ''
mkdir pkg
dpkg-deb -x $src pkg
sourceRoot=pkg
'';
installPhase = ''
mkdir -p $out/bin
cp usr/bin/rescuetime $out/bin
${patchelf}/bin/patchelf \
--interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" \
$out/bin/rescuetime
wrapProgram $out/bin/rescuetime \
--prefix LD_PRELOAD : ${qt4}/lib/libQtGui.so.4:${qt4}/lib/libQtCore.so.4:${libXtst}/lib/libXtst.so.6:${libXext}/lib/libXext.so.6:${libX11}/lib/libX11.so.6:${libXScrnSaver}/lib/libXss.so.1
'';
meta = with lib; {
description = "Helps you understand your daily habits so you can focus and be more productive";
homepage = "https://www.rescuetime.com";
maintainers = with maintainers; [ cstrahan ];
license = licenses.unfree;
platforms = [ "i686-linux" "x86_64-linux" ];
};
}

View File

@ -0,0 +1,30 @@
{stdenv, fetchhg}:
let
s =
rec {
baseName = "slmenu";
version = "hg-${date}";
date = "2012-02-01";
name = "${baseName}-${version}";
url = "https://bitbucket.org/rafaelgg/slmenu/";
rev = "7e74fa5db73e8b018da48d50dbbaf11cb5c62d13";
sha256 = "0zb7mm8344d3xmvrl62psazcabfk75pp083jqkmywdsrikgjagv6";
};
buildInputs = [
];
in
stdenv.mkDerivation {
inherit (s) name version;
inherit buildInputs;
src = fetchhg {
inherit (s) url sha256;
};
makeFlags = ''PREFIX=$(out)'';
meta = {
inherit (s) version;
description = ''A console dmenu-like tool'';
license = stdenv.lib.licenses.mit;
maintainers = [stdenv.lib.maintainers.raskin];
platforms = stdenv.lib.platforms.linux;
};
}

View File

@ -5,15 +5,15 @@ let
else if stdenv.system == "i686-linux" then "i386" else if stdenv.system == "i686-linux" then "i386"
else throw "Bittorrent Sync for: ${stdenv.system} not supported!"; else throw "Bittorrent Sync for: ${stdenv.system} not supported!";
sha256 = if stdenv.system == "x86_64-linux" then "c4b100bbf8cda0334e20793e02bf400d15266cb9d089917bd2b6b9d49dd37d19" sha256 = if stdenv.system == "x86_64-linux" then "0hiapq24y02pm7zi0jvqj4jxwdn5k74yxq9n1jpv8jmgir3iwznn"
else if stdenv.system == "i686-linux" then "5760471fcea396efd158758aa350b1c48a9d0633765a5e3b059baf8aeab615fa" else if stdenv.system == "i686-linux" then "0jv3zg0jhdzsc56kkpylwihvhsz73gsl2i2pjmqk3r3x4gwjk8xx"
else throw "Bittorrent Sync for: ${stdenv.system} not supported!"; else throw "Bittorrent Sync for: ${stdenv.system} not supported!";
libPath = stdenv.lib.makeLibraryPath [ stdenv.gcc.libc ]; libPath = stdenv.lib.makeLibraryPath [ stdenv.gcc.libc ];
in in
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "btsync-${version}"; name = "btsync-${version}";
version = "1.4.93"; version = "1.4.103";
src = fetchurl { src = fetchurl {
url = "http://syncapp.bittorrent.com/${version}/btsync_${arch}-${version}.tar.gz"; url = "http://syncapp.bittorrent.com/${version}/btsync_${arch}-${version}.tar.gz";

View File

@ -35,7 +35,7 @@ mkChromiumDerivation (base: rec {
meta = { meta = {
description = "An open source web browser from Google"; description = "An open source web browser from Google";
homepage = http://www.chromium.org/; homepage = http://www.chromium.org/;
maintainers = with maintainers; [ goibhniu chaoflow aszlig wizeman ]; maintainers = with maintainers; [ goibhniu chaoflow aszlig ];
license = licenses.bsd3; license = licenses.bsd3;
platforms = platforms.linux; platforms = platforms.linux;
}; };

View File

@ -4,189 +4,185 @@
# ruby generate_source.rb > source.nix # ruby generate_source.rb > source.nix
{ {
version = "33.1"; version = "34.0.5";
sources = [ sources = [
{ locale = "ach"; arch = "linux-i686"; sha1 = "f6ecc5e1d1470a4d79d0f680f3a194857674c5a1"; } { locale = "ach"; arch = "linux-i686"; sha1 = "2122f58004eec918c2a6f30e6d8a35fcee793f8d"; }
{ locale = "ach"; arch = "linux-x86_64"; sha1 = "d28450930e53f168c11e7e0c4e7df46c20d50882"; } { locale = "ach"; arch = "linux-x86_64"; sha1 = "c304799de726df6c6c99aa4d7b2cc2ae552b92c1"; }
{ locale = "af"; arch = "linux-i686"; sha1 = "2865493140bd8838e7981749f9fe7a734fa59745"; } { locale = "af"; arch = "linux-i686"; sha1 = "1e367d63ab86049ba4f3f4121fd3a9531a9cd00f"; }
{ locale = "af"; arch = "linux-x86_64"; sha1 = "8f94c2be8ba8e496ff917f78206ab9a9294e4de1"; } { locale = "af"; arch = "linux-x86_64"; sha1 = "1e2d3e17bed3aac9e53493f25d1e9a22a70f2710"; }
{ locale = "an"; arch = "linux-i686"; sha1 = "3f6ecaab216f91759a39e255571edaf9b48d4733"; } { locale = "an"; arch = "linux-i686"; sha1 = "cba77e9401b2ce16030cc46e7083c0a87c244165"; }
{ locale = "an"; arch = "linux-x86_64"; sha1 = "ae0fce83ae2aa416dc3acda327dec98f2c7c0b98"; } { locale = "an"; arch = "linux-x86_64"; sha1 = "adc7bb9a86596332c37a3cab118942c4953ec7e9"; }
{ locale = "ar"; arch = "linux-i686"; sha1 = "aeaed8574b13046d1afb129ad9d3cc0ee22b2bff"; } { locale = "ar"; arch = "linux-i686"; sha1 = "59a85dcbc756752ff2ba07ffb12fecf10beb2bf9"; }
{ locale = "ar"; arch = "linux-x86_64"; sha1 = "997495abb13611591ce9ab5ea81cc65dd7ee579a"; } { locale = "ar"; arch = "linux-x86_64"; sha1 = "0c9b4c4ef3d39e3e44885359e1a85e03c47b57e3"; }
{ locale = "as"; arch = "linux-i686"; sha1 = "84193f01192c8341905a0f8d2e7b3d198c39e113"; } { locale = "as"; arch = "linux-i686"; sha1 = "69633541cad0a8fbf1798d4b47047adc2ac23cf3"; }
{ locale = "as"; arch = "linux-x86_64"; sha1 = "f7e9278e9d4b0d3b45f453a16b5840bb84598ccc"; } { locale = "as"; arch = "linux-x86_64"; sha1 = "b628ace403803425ab5f8e485f1107ace00e36a4"; }
{ locale = "ast"; arch = "linux-i686"; sha1 = "e52fb5a1e813e1d91ec7562bd7e94632f661c5a4"; } { locale = "ast"; arch = "linux-i686"; sha1 = "adefb5324db5cb21ed46c2edee4b476e451d39d5"; }
{ locale = "ast"; arch = "linux-x86_64"; sha1 = "89f13d927c9d8596899ed09f8c9f7d97c26d78f5"; } { locale = "ast"; arch = "linux-x86_64"; sha1 = "734cbe739065246084cc452ca60e79248b3abada"; }
{ locale = "az"; arch = "linux-i686"; sha1 = "bc0972e18db99f9d6fdbe100dd09d62bb2c3afbd"; } { locale = "az"; arch = "linux-i686"; sha1 = "12a7a57784563982df4fa9c7da1e0ff830afe81f"; }
{ locale = "az"; arch = "linux-x86_64"; sha1 = "4552aa92a799086b7f79178eb8d846a84e77e094"; } { locale = "az"; arch = "linux-x86_64"; sha1 = "b8713205b616a81cea2675e477ef29db576f1ab0"; }
{ locale = "be"; arch = "linux-i686"; sha1 = "4c2577170f9df45a313c6728076cc35504f7ad80"; } { locale = "be"; arch = "linux-i686"; sha1 = "cb60c04c2abab2ad59d6e19a08a425744f0135a9"; }
{ locale = "be"; arch = "linux-x86_64"; sha1 = "dea774633ab5c1ab5c74380984253b0597d53d2c"; } { locale = "be"; arch = "linux-x86_64"; sha1 = "b1bd0faf18a2f1cb7617d7c1946d586ec7db2fd1"; }
{ locale = "bg"; arch = "linux-i686"; sha1 = "5f770c719895ddec1a8c27bda298361341b2e924"; } { locale = "bg"; arch = "linux-i686"; sha1 = "c260de634b14ed00a2396f09871fa726c5b24d09"; }
{ locale = "bg"; arch = "linux-x86_64"; sha1 = "5581f70176eb35cf01d5ebb368741130420b505e"; } { locale = "bg"; arch = "linux-x86_64"; sha1 = "0a723d9d1b5abadb8250b9be5e6af8b7615231c4"; }
{ locale = "bn-BD"; arch = "linux-i686"; sha1 = "f0853164e4d1497be6dcffd6dd365eaf56b6582b"; } { locale = "bn-BD"; arch = "linux-i686"; sha1 = "292e7f58b2ca6b603949cc22965de0e568811dfb"; }
{ locale = "bn-BD"; arch = "linux-x86_64"; sha1 = "0ccb11141eb9c339cfe652aee6e902ed0cd700e4"; } { locale = "bn-BD"; arch = "linux-x86_64"; sha1 = "c6f8afcd2e2269c5092dce8779e6068fd2e09540"; }
{ locale = "bn-IN"; arch = "linux-i686"; sha1 = "36448e2198e3650f0e5a107af3ae10dbdc8273ce"; } { locale = "bn-IN"; arch = "linux-i686"; sha1 = "3d93fbcb16a6161740cdee5c91fb2b9e6d5de77a"; }
{ locale = "bn-IN"; arch = "linux-x86_64"; sha1 = "804668a7692b378f6686ea56dae3b9e047bce4a1"; } { locale = "bn-IN"; arch = "linux-x86_64"; sha1 = "570cb383c4dcd09f90a02aa6898504295cad25e6"; }
{ locale = "br"; arch = "linux-i686"; sha1 = "396a845931ee25c79baaa2147c94b7eea6c8505f"; } { locale = "br"; arch = "linux-i686"; sha1 = "92fb316eae04d94320dd623d22d7b8c2a76018f6"; }
{ locale = "br"; arch = "linux-x86_64"; sha1 = "87d9567073d22f09abe6c45a044fd3b4ee4d925b"; } { locale = "br"; arch = "linux-x86_64"; sha1 = "a7410ed0ec67ae9746f652177664c292b727fdfc"; }
{ locale = "bs"; arch = "linux-i686"; sha1 = "e3263e2215862dad2268686242a2374e460d1868"; } { locale = "bs"; arch = "linux-i686"; sha1 = "7f08e9920875f59b6df051acc68d1bb508615396"; }
{ locale = "bs"; arch = "linux-x86_64"; sha1 = "714597790f46b03289a4a91e20f797c82672f849"; } { locale = "bs"; arch = "linux-x86_64"; sha1 = "654d90383abc26272d017b914627516b3aa33147"; }
{ locale = "ca"; arch = "linux-i686"; sha1 = "0dfc5d9abcac90e5ab254bb72ae20d987ff206f3"; } { locale = "ca"; arch = "linux-i686"; sha1 = "645133ed542917fa32518279b375cf9dc4149dd7"; }
{ locale = "ca"; arch = "linux-x86_64"; sha1 = "2eac6e7cb6eae8ca0714dd219eb08b3f7d846191"; } { locale = "ca"; arch = "linux-x86_64"; sha1 = "3eaff9df7e51971f9c1e37028430f0159ddcda9c"; }
{ locale = "cs"; arch = "linux-i686"; sha1 = "505764e55d673a282d38c3bca7db4ac29325ead1"; } { locale = "cs"; arch = "linux-i686"; sha1 = "4b283d1393fe06c80f412848b146295519e1957d"; }
{ locale = "cs"; arch = "linux-x86_64"; sha1 = "bd32e999d5c61b20bb3a5983032227ff2a7d6d84"; } { locale = "cs"; arch = "linux-x86_64"; sha1 = "5830a2bc46234d1adac6127fd470223ff750f5e7"; }
{ locale = "csb"; arch = "linux-i686"; sha1 = "ae5065363647da475901fb7cc156a4ecdecc528b"; } { locale = "csb"; arch = "linux-i686"; sha1 = "36c7bd7ccafdd5225d6f6dcde6928e4ca9aff603"; }
{ locale = "csb"; arch = "linux-x86_64"; sha1 = "df0de3d7e5b2aa84e37097b5f65168d732bfd3de"; } { locale = "csb"; arch = "linux-x86_64"; sha1 = "e5070bc33436df13e68e9ce63f091b1f60a96b5d"; }
{ locale = "cy"; arch = "linux-i686"; sha1 = "3e1e7991983277f4c07486d1f2896e2a192d5f85"; } { locale = "cy"; arch = "linux-i686"; sha1 = "7f6e35e997082406036864fb1cfc4bfd9380d156"; }
{ locale = "cy"; arch = "linux-x86_64"; sha1 = "20232e85c69830eb08b4387f69e3d26637b3d06c"; } { locale = "cy"; arch = "linux-x86_64"; sha1 = "2c2ac492181ccdf10ae88c6cf1ec14a9d81c6019"; }
{ locale = "da"; arch = "linux-i686"; sha1 = "1a3a3913876fe8eea20b4b6d33b939b9e531fd34"; } { locale = "da"; arch = "linux-i686"; sha1 = "cf2be147f015d40d0eecc1f00326856b06acdedd"; }
{ locale = "da"; arch = "linux-x86_64"; sha1 = "f89864c28eb750655fb212d77569fcfdfbd38ee9"; } { locale = "da"; arch = "linux-x86_64"; sha1 = "01804683989d0731826d7dda67d6d7a46fb8de48"; }
{ locale = "de"; arch = "linux-i686"; sha1 = "da97ff54467b5d0cad8142158e01514a1e75f457"; } { locale = "de"; arch = "linux-i686"; sha1 = "be8909ee0a9cf86869479c9173ea20f27d6e841a"; }
{ locale = "de"; arch = "linux-x86_64"; sha1 = "988c4cd52388368d21cfb1e6002c28f3e8fb57b1"; } { locale = "de"; arch = "linux-x86_64"; sha1 = "377f54230cbe9d8dfd6242043fc8e9e43e392688"; }
{ locale = "dsb"; arch = "linux-i686"; sha1 = "0997a81282c73a8faf8a784a296bbe9102c823bd"; } { locale = "dsb"; arch = "linux-i686"; sha1 = "d50f0fca6b2036aca565a694bf70112121acc009"; }
{ locale = "dsb"; arch = "linux-x86_64"; sha1 = "d6573147c354d29f0ba928888916882aafb92268"; } { locale = "dsb"; arch = "linux-x86_64"; sha1 = "f532c3ac7f45682aa916f5cde32c5921a83fe9cf"; }
{ locale = "el"; arch = "linux-i686"; sha1 = "df53cedb977f9f1cff6b43351fa19801c51e53d9"; } { locale = "el"; arch = "linux-i686"; sha1 = "2cf025815a5b9d7c1b7f353a592b700377797ff2"; }
{ locale = "el"; arch = "linux-x86_64"; sha1 = "e124b8586af6fb23371c006be0fbe3525dafc8a9"; } { locale = "el"; arch = "linux-x86_64"; sha1 = "2a3c3b79072d6196cfcd00d4ffe546415e5c3c2b"; }
{ locale = "en-GB"; arch = "linux-i686"; sha1 = "738a7335b42e4d324bb3c8411666c3d64e481f85"; } { locale = "en-GB"; arch = "linux-i686"; sha1 = "c638ac1b0f94d7afdf52b580108d9d9f0fbb4642"; }
{ locale = "en-GB"; arch = "linux-x86_64"; sha1 = "788abe682ac80e08739edf0fabfd4f160eee44da"; } { locale = "en-GB"; arch = "linux-x86_64"; sha1 = "3a89c58a1a391268de63de380f379cf47956873c"; }
{ locale = "en-US"; arch = "linux-i686"; sha1 = "9aeaab7265640c4dfdde57b0ef7eebac26c1d1ec"; } { locale = "en-US"; arch = "linux-i686"; sha1 = "9f83d949c426b798268a038c1173bad1efb8076f"; }
{ locale = "en-US"; arch = "linux-x86_64"; sha1 = "e4bdb638b0a4c90ecb664a9b64351a31ad237ee5"; } { locale = "en-US"; arch = "linux-x86_64"; sha1 = "e9f99d0fd1fadd62ba44606f0fe67cc829b64da3"; }
{ locale = "en-ZA"; arch = "linux-i686"; sha1 = "381749003d0755cec8dbf29cd1d4ebfa806576f8"; } { locale = "en-ZA"; arch = "linux-i686"; sha1 = "a84f15bb02673c849721290858de31ca9697448f"; }
{ locale = "en-ZA"; arch = "linux-x86_64"; sha1 = "518c307bb0b23592ff711943594ea76ffdf0d0c3"; } { locale = "en-ZA"; arch = "linux-x86_64"; sha1 = "28984e2a5d91f27247eb40db48f3055a24e77f3c"; }
{ locale = "eo"; arch = "linux-i686"; sha1 = "f570024c9c665b36bd8646f44b2b27ff7021f590"; } { locale = "eo"; arch = "linux-i686"; sha1 = "9951a09c2132d468ff1b8c647af195ddb3ecb050"; }
{ locale = "eo"; arch = "linux-x86_64"; sha1 = "fb777076f2a2a7d911a381a0561c02701dd54878"; } { locale = "eo"; arch = "linux-x86_64"; sha1 = "ec90facdeced4b969547a8193dc9f196a13a5c0c"; }
{ locale = "es-AR"; arch = "linux-i686"; sha1 = "20cac134a4312d5cee8ad1f144b2c44108e96b8e"; } { locale = "es-AR"; arch = "linux-i686"; sha1 = "a4df107f065e950fe2702871fb10d1d7ddc704dc"; }
{ locale = "es-AR"; arch = "linux-x86_64"; sha1 = "d4757bfb61d84d6d3e4b484377f1037b1ff2728c"; } { locale = "es-AR"; arch = "linux-x86_64"; sha1 = "6cd0464702921be32a70eb5b68be45f5f6a65ff4"; }
{ locale = "es-CL"; arch = "linux-i686"; sha1 = "0416114a667fbc9144186d9a74ce2cf3e09944cc"; } { locale = "es-CL"; arch = "linux-i686"; sha1 = "21325f12a6ed59c471a86a8273efd76fdc9dc3bd"; }
{ locale = "es-CL"; arch = "linux-x86_64"; sha1 = "73eeff57047143e8d4217bb22a3831555f87341f"; } { locale = "es-CL"; arch = "linux-x86_64"; sha1 = "b6660728d8ac2ba89a9bb522a8fd7552c7b0fd84"; }
{ locale = "es-ES"; arch = "linux-i686"; sha1 = "66d8288cb4af4d4e8584dcebefc14d9aaf46f4bc"; } { locale = "es-ES"; arch = "linux-i686"; sha1 = "00b2c86d3f7f6431760e2bdf6228090b46703b21"; }
{ locale = "es-ES"; arch = "linux-x86_64"; sha1 = "d0830ffc8634ab47033b932dcac51e7d042c4f19"; } { locale = "es-ES"; arch = "linux-x86_64"; sha1 = "d75ee1d75eb8c1d7f43fd082575cdb9d5657a719"; }
{ locale = "es-MX"; arch = "linux-i686"; sha1 = "592df3f8ee6e6a6fc56991a7b1e9f55a1ea1b8e8"; } { locale = "es-MX"; arch = "linux-i686"; sha1 = "6e7d188ae57eeb457a5af93cef77a3e0fd3e4138"; }
{ locale = "es-MX"; arch = "linux-x86_64"; sha1 = "cf0d2afac587dbb4f640ea672ea01190f2425905"; } { locale = "es-MX"; arch = "linux-x86_64"; sha1 = "905ae336894a4d7efdfd5890c43579fcbc4f63e6"; }
{ locale = "et"; arch = "linux-i686"; sha1 = "441a5dbb69fe61e28e06ec3ed29f34d067ec2ade"; } { locale = "et"; arch = "linux-i686"; sha1 = "49f5495d4fe4166f46f3d2cc784b0adadad40973"; }
{ locale = "et"; arch = "linux-x86_64"; sha1 = "633b25f83507b61829a934385766628c8764544e"; } { locale = "et"; arch = "linux-x86_64"; sha1 = "80706f89b23dd019718888c2308596ec63c0cd6c"; }
{ locale = "eu"; arch = "linux-i686"; sha1 = "f8f6ddf346afb5bb0420ab092463d61e5e6abfe7"; } { locale = "eu"; arch = "linux-i686"; sha1 = "2531d3d157aee3c20616fd94606668cc78ce71f5"; }
{ locale = "eu"; arch = "linux-x86_64"; sha1 = "cc7cfc43d8e6db5ac08f846e81a416e5a75b37b6"; } { locale = "eu"; arch = "linux-x86_64"; sha1 = "6c84eab337a4b43d604f34e7ea2b563500a52f37"; }
{ locale = "fa"; arch = "linux-i686"; sha1 = "796ee1d052e97372a870f113390ef25f26047203"; } { locale = "fa"; arch = "linux-i686"; sha1 = "61fe70954eca24f1d7fa8908f6cfaab1b4abfad2"; }
{ locale = "fa"; arch = "linux-x86_64"; sha1 = "3810bd3727a7de7474070e329ddeabfb98f4aeee"; } { locale = "fa"; arch = "linux-x86_64"; sha1 = "f43b28a2b0af9ba18da35c69824370cec628d056"; }
{ locale = "ff"; arch = "linux-i686"; sha1 = "436b6732f58bb6a128c6e3027358089bca0d753e"; } { locale = "ff"; arch = "linux-i686"; sha1 = "2c1f4c5a2f3639328af873e59afd6c6a479f69ae"; }
{ locale = "ff"; arch = "linux-x86_64"; sha1 = "ed7e3e1a90d31e40cd47645474246adba30eaa1d"; } { locale = "ff"; arch = "linux-x86_64"; sha1 = "8737e7d4263e66fafbf372568587173e58816f6a"; }
{ locale = "fi"; arch = "linux-i686"; sha1 = "1d7909cbfe55f6234b6789addae5c9a2dbcf1e49"; } { locale = "fi"; arch = "linux-i686"; sha1 = "3a5b5171449e3629b0e22d08a9bf9a5bb0428a19"; }
{ locale = "fi"; arch = "linux-x86_64"; sha1 = "d7734ee040a5ff56aa6d7149d6d5a78541f533fb"; } { locale = "fi"; arch = "linux-x86_64"; sha1 = "1c901117715d8ac9d869bd79d7ffda778562b4bd"; }
{ locale = "fr"; arch = "linux-i686"; sha1 = "a8614ef406ed6d4ce7f64f14335b5c4a13fd1ee2"; } { locale = "fr"; arch = "linux-i686"; sha1 = "3962280160df7f786cc26275025976df9c267174"; }
{ locale = "fr"; arch = "linux-x86_64"; sha1 = "98d5e3476784ee4d759b7995e2ff936910a1b213"; } { locale = "fr"; arch = "linux-x86_64"; sha1 = "cc2f1f433b88b5f73e5c7e4683d85e5275720734"; }
{ locale = "fy-NL"; arch = "linux-i686"; sha1 = "3c7a1c5e1fb9e0f2320a33771bde1cbd774eb6bf"; } { locale = "fy-NL"; arch = "linux-i686"; sha1 = "ed2b578e76aa9e56a85d3a02a3d9d6d25e07d624"; }
{ locale = "fy-NL"; arch = "linux-x86_64"; sha1 = "10178c5fc56dd8f510f80748767e7e5961bac6ff"; } { locale = "fy-NL"; arch = "linux-x86_64"; sha1 = "110741b45050dbc896424a6e9cf32b9f8555d657"; }
{ locale = "ga-IE"; arch = "linux-i686"; sha1 = "235c5016eb77c9369ee10e51514961a6986f3c78"; } { locale = "ga-IE"; arch = "linux-i686"; sha1 = "32fa55c45a7fbd57a7823135e87c288d463440ee"; }
{ locale = "ga-IE"; arch = "linux-x86_64"; sha1 = "023c3aafa794faa30cc25576e411f2482cc83131"; } { locale = "ga-IE"; arch = "linux-x86_64"; sha1 = "4d0c00130026b892cfc259d8ffb6c57338e8398d"; }
{ locale = "gd"; arch = "linux-i686"; sha1 = "e86c734f2afb872f407f78e867735ecda7ceb622"; } { locale = "gd"; arch = "linux-i686"; sha1 = "2fbafdbe1218eb34ec48a5d92904c0bd07b23690"; }
{ locale = "gd"; arch = "linux-x86_64"; sha1 = "29b695a5c8291f23b22871dcec4d6e66f918e21c"; } { locale = "gd"; arch = "linux-x86_64"; sha1 = "90810697ad8206eced9e4c4330c9242c4f3baafa"; }
{ locale = "gl"; arch = "linux-i686"; sha1 = "c13ac4e21e70e5d3bcf0b2149bfc3e6090c383ce"; } { locale = "gl"; arch = "linux-i686"; sha1 = "2be76249fc1afde7ed156beb5df2d2eef50a485e"; }
{ locale = "gl"; arch = "linux-x86_64"; sha1 = "70116ba4463b6937382dc9c7c8da465f5aa78c07"; } { locale = "gl"; arch = "linux-x86_64"; sha1 = "d400c5692a767b14dabce47303aa195bc17af3c5"; }
{ locale = "gu-IN"; arch = "linux-i686"; sha1 = "7b687b19b72543d411c9eeb4055015c4e4ebaa4b"; } { locale = "gu-IN"; arch = "linux-i686"; sha1 = "15704df5ff619aa6818521904d557eea65165206"; }
{ locale = "gu-IN"; arch = "linux-x86_64"; sha1 = "d2cc38aafa2311808d92f1c927b6b6fd86c35d59"; } { locale = "gu-IN"; arch = "linux-x86_64"; sha1 = "c19923c4e9d5ae89bf9f1aa441b9f92d6f2fd02c"; }
{ locale = "he"; arch = "linux-i686"; sha1 = "24027663a19be1d27379167585936591ffe01650"; } { locale = "he"; arch = "linux-i686"; sha1 = "39694a4f966ad488ff77592dc490302449104df3"; }
{ locale = "he"; arch = "linux-x86_64"; sha1 = "0ab9ec52df1e0debad953b2c658c16396a7c336d"; } { locale = "he"; arch = "linux-x86_64"; sha1 = "deb058d0798eadc5fe3920996421d86d446ca82e"; }
{ locale = "hi-IN"; arch = "linux-i686"; sha1 = "d72b91be0e392a853d3b894f2809bb16d4ed77f5"; } { locale = "hi-IN"; arch = "linux-i686"; sha1 = "8d28e60f8920001184dc20cc1f381f9474c9a6fd"; }
{ locale = "hi-IN"; arch = "linux-x86_64"; sha1 = "560a3562b66a46f7b5c235e5f0c9a37518dc60f4"; } { locale = "hi-IN"; arch = "linux-x86_64"; sha1 = "3e9c18fc995fc013d3bd8bc87f8accc951599e79"; }
{ locale = "hr"; arch = "linux-i686"; sha1 = "319c19a36f1d9f087f59470cb14ad0b9429cb751"; } { locale = "hr"; arch = "linux-i686"; sha1 = "6ced9bd6614b921600cca7520c8698f265087a31"; }
{ locale = "hr"; arch = "linux-x86_64"; sha1 = "2c98ac830fb0eff611cb82690d068dc61fa6fb21"; } { locale = "hr"; arch = "linux-x86_64"; sha1 = "8ef625b32212c387a367b8059c4d0bf62d5814da"; }
{ locale = "hsb"; arch = "linux-i686"; sha1 = "f8b2f8a85b7e5d8d4c551f0e64340cfe491695c4"; } { locale = "hsb"; arch = "linux-i686"; sha1 = "49ecea386737f963db43f8c13c8d7e9b036523f3"; }
{ locale = "hsb"; arch = "linux-x86_64"; sha1 = "5b6533ac4222a3e18c3d4ba74e0aa459bfa413d1"; } { locale = "hsb"; arch = "linux-x86_64"; sha1 = "7aba537cb8ffc7b7106dba4b378024c5a0356652"; }
{ locale = "hu"; arch = "linux-i686"; sha1 = "93308746df2c99182d2919fece807b47db688b3d"; } { locale = "hu"; arch = "linux-i686"; sha1 = "1d406c76c8846b4ec81e62a958d662b582f75357"; }
{ locale = "hu"; arch = "linux-x86_64"; sha1 = "9fd5cd46a04bed5b8fb079aeb59050664c5d93e0"; } { locale = "hu"; arch = "linux-x86_64"; sha1 = "4f582fd196573f5ab1c93dc6652a2e86617a0be7"; }
{ locale = "hy-AM"; arch = "linux-i686"; sha1 = "d889d18ccef0c7c25dc2e1fc71b9eaa6aaeb4229"; } { locale = "hy-AM"; arch = "linux-i686"; sha1 = "d71daf124c8a16d4bd1d9d17df47cf10d5a5137c"; }
{ locale = "hy-AM"; arch = "linux-x86_64"; sha1 = "2ef01a1c2f01825d80d6a0846d59ff6ad77e90e1"; } { locale = "hy-AM"; arch = "linux-x86_64"; sha1 = "b8f124244441a6ce474860731452760e92e575c4"; }
{ locale = "id"; arch = "linux-i686"; sha1 = "1c5cb9d1d4b20b2060a8fd07d2851067a4b71d6a"; } { locale = "id"; arch = "linux-i686"; sha1 = "8e4c0ec82aaeee6fdcf7541f6fd0bab8811ec5ae"; }
{ locale = "id"; arch = "linux-x86_64"; sha1 = "82c871d7554fe8411d8f6fccf5e3c7f0d7798885"; } { locale = "id"; arch = "linux-x86_64"; sha1 = "3b6a5ff08f1c7f81c0da50fa7d2ed17e7d7da645"; }
{ locale = "is"; arch = "linux-i686"; sha1 = "1e697fa5802915b826e29ea73805b7101a32312c"; } { locale = "is"; arch = "linux-i686"; sha1 = "0aa678cd3b58706ac7d9a36399abcc3a8f05a894"; }
{ locale = "is"; arch = "linux-x86_64"; sha1 = "44b0d19bc285462f305abf8137aefd9477715e8f"; } { locale = "is"; arch = "linux-x86_64"; sha1 = "e2a815e45fd6c20b37085aea0b2fe6e23848fde7"; }
{ locale = "it"; arch = "linux-i686"; sha1 = "16e00713bd355373c676e05a032933d9c210ba87"; } { locale = "it"; arch = "linux-i686"; sha1 = "8213e082043b61872df49709732d0f209956f858"; }
{ locale = "it"; arch = "linux-x86_64"; sha1 = "c32e8d9e9dde6c61092e4b72a3192f50e70bcfa9"; } { locale = "it"; arch = "linux-x86_64"; sha1 = "f411672ad5fb62ddc6cc2f9e89fea611de0d6356"; }
{ locale = "ja"; arch = "linux-i686"; sha1 = "d2d4d0a2c32769ae9fb6d27dfb71e52f146824c3"; } { locale = "ja"; arch = "linux-i686"; sha1 = "a540dd09786c0701a1ec22adbd1a19d6cbf0eb60"; }
{ locale = "ja"; arch = "linux-x86_64"; sha1 = "271d50bcf97440e61bf7b952a48fe3992c40faf0"; } { locale = "ja"; arch = "linux-x86_64"; sha1 = "decfa3a81bd81c0d04c62d1ff70858bcbfe505c2"; }
{ locale = "kk"; arch = "linux-i686"; sha1 = "bc1e2c28b01b7bffde01d88e6aa6aec1a8868f3d"; } { locale = "kk"; arch = "linux-i686"; sha1 = "bfda7cdf57eafd6248bd5f32cf6ba84a3a05f202"; }
{ locale = "kk"; arch = "linux-x86_64"; sha1 = "94a66d608cec6de58fb8d72b116395c77198494d"; } { locale = "kk"; arch = "linux-x86_64"; sha1 = "6a12ec04401251b9382a8b8b927f4684f7268971"; }
{ locale = "km"; arch = "linux-i686"; sha1 = "99fdf2ae88c34db6fe9234d236caffeb50cbb843"; } { locale = "km"; arch = "linux-i686"; sha1 = "06dc00c095690aa1eabd87d3dd425d3481349a09"; }
{ locale = "km"; arch = "linux-x86_64"; sha1 = "78645872859dc627c5d12e6aa86aef6e3528b3d9"; } { locale = "km"; arch = "linux-x86_64"; sha1 = "901e1755688474d888ebcc524ca6912280fa5c11"; }
{ locale = "kn"; arch = "linux-i686"; sha1 = "ef5dcee189c685ee5b71a76cb19138e65f22a0be"; } { locale = "kn"; arch = "linux-i686"; sha1 = "ccc86b5b46f3444f0a09b8d70ba804a9245e55f4"; }
{ locale = "kn"; arch = "linux-x86_64"; sha1 = "87b064a5ce23ffd1397b8a480e6a158b1de4cd67"; } { locale = "kn"; arch = "linux-x86_64"; sha1 = "b84394b314bd99a0bf856e0330d537f14dc624f1"; }
{ locale = "ko"; arch = "linux-i686"; sha1 = "95e6290a38025af724c34272f8e2a4d531e4f06a"; } { locale = "ko"; arch = "linux-i686"; sha1 = "3e3d97975c5c67db99785ccca608ad170e870523"; }
{ locale = "ko"; arch = "linux-x86_64"; sha1 = "e989184dfda401f19a895275519f729597a27e97"; } { locale = "ko"; arch = "linux-x86_64"; sha1 = "1575641404e5b6239745eeae202ddbb5b8ede6d0"; }
{ locale = "ku"; arch = "linux-i686"; sha1 = "c1004b96937b848d9e1e53f9fe4a8507d218572d"; } { locale = "lij"; arch = "linux-i686"; sha1 = "4abdf303280a82ededf5cb2a8433f169a4d2959a"; }
{ locale = "ku"; arch = "linux-x86_64"; sha1 = "a4e61d630ab6ce54a06ff1a90c7df3b76b235181"; } { locale = "lij"; arch = "linux-x86_64"; sha1 = "974f1c26ee02e3eb20daf8cb7a991e83dbeb8c60"; }
{ locale = "lij"; arch = "linux-i686"; sha1 = "be5da1e0d17c7b51da616c082932d8190a33a74e"; } { locale = "lt"; arch = "linux-i686"; sha1 = "18cdb106a6866bb1ce33c3712011602e2503799e"; }
{ locale = "lij"; arch = "linux-x86_64"; sha1 = "35e29b7825124dd5c68d02e7c1a15e9cdefaec22"; } { locale = "lt"; arch = "linux-x86_64"; sha1 = "fbf52dab19307bf8f8b7d84e32d7bcddfcb4693b"; }
{ locale = "lt"; arch = "linux-i686"; sha1 = "c09c5cf5f25eac88f90f4aeb48495f688d78d80d"; } { locale = "lv"; arch = "linux-i686"; sha1 = "a383ddf03d269575eee7b7fe44ae334aa8d648e9"; }
{ locale = "lt"; arch = "linux-x86_64"; sha1 = "7f4f6511d9cf4b70e34b37c823c12bd13409a7e8"; } { locale = "lv"; arch = "linux-x86_64"; sha1 = "91f4b3cfbd5651e0227e2d9c40cbc1eda94e3413"; }
{ locale = "lv"; arch = "linux-i686"; sha1 = "7fc81c00badbbd877a67d5e1998f16560dd41f3e"; } { locale = "mai"; arch = "linux-i686"; sha1 = "62318920bdcb6aa26fb31e2b80e861eeef0f4da6"; }
{ locale = "lv"; arch = "linux-x86_64"; sha1 = "5edb8fac36c755db3e3270a0cf4320970696ff4c"; } { locale = "mai"; arch = "linux-x86_64"; sha1 = "1811f361ed1b6d2864f0e7cc3950668ba8633288"; }
{ locale = "mai"; arch = "linux-i686"; sha1 = "4d49ecb2e195c9c65382155128ff02d857937703"; } { locale = "mk"; arch = "linux-i686"; sha1 = "9b2f802e0543719a3fa13027b283af062278466e"; }
{ locale = "mai"; arch = "linux-x86_64"; sha1 = "96d0dac8116f20972469e527757d17cf7c22792b"; } { locale = "mk"; arch = "linux-x86_64"; sha1 = "5b22cb28cfd1390dce8534674fcecb201f431ebd"; }
{ locale = "mk"; arch = "linux-i686"; sha1 = "b72b07ab4d69430d62fb9c497c047f2987636ea1"; } { locale = "ml"; arch = "linux-i686"; sha1 = "25862ddddd1d9f7ddcbff8780a39ab2609fdff74"; }
{ locale = "mk"; arch = "linux-x86_64"; sha1 = "441918ac58ff166851921bf1566e7dda24ce2377"; } { locale = "ml"; arch = "linux-x86_64"; sha1 = "eb5fa58184b6bd10434c5371834eaf2ee343bb6e"; }
{ locale = "ml"; arch = "linux-i686"; sha1 = "b7947f50a0618ba9b8fb5fa9f1adff13dbfc0147"; } { locale = "mr"; arch = "linux-i686"; sha1 = "b4dc26f1d52da326046173765832c8e06eb27adb"; }
{ locale = "ml"; arch = "linux-x86_64"; sha1 = "3c98db55a6b9c707957786cc40a03d69e9b4e619"; } { locale = "mr"; arch = "linux-x86_64"; sha1 = "d8e5968afee45607b2874845f2782add083f3d0a"; }
{ locale = "mr"; arch = "linux-i686"; sha1 = "f1e5109a2fe72d1c7d8a32f83918064d607efa1a"; } { locale = "ms"; arch = "linux-i686"; sha1 = "fce3550b0e03cf6c78d55f1e89afe27bea3ed0fa"; }
{ locale = "mr"; arch = "linux-x86_64"; sha1 = "820f056eb3413fc0e1979f192e9542db0c9e0e79"; } { locale = "ms"; arch = "linux-x86_64"; sha1 = "7bc8f231ac82827d9095ce896cb16f60c92b1053"; }
{ locale = "ms"; arch = "linux-i686"; sha1 = "6a9f01f286fbe0b63f6c171f0171f2883fa5b474"; } { locale = "nb-NO"; arch = "linux-i686"; sha1 = "7d077713f9cf02833fa9e3ef69a5dac11d88f59e"; }
{ locale = "ms"; arch = "linux-x86_64"; sha1 = "f8cccf1c87845947693c631fd60300d1a5ec7436"; } { locale = "nb-NO"; arch = "linux-x86_64"; sha1 = "642851c8ead7a0e673d9d8d0329a551cd9282337"; }
{ locale = "nb-NO"; arch = "linux-i686"; sha1 = "2dbe61442b310777b427d27159ee767d82a4b254"; } { locale = "nl"; arch = "linux-i686"; sha1 = "f0cd799d98840d8ca7825caac582035761347a94"; }
{ locale = "nb-NO"; arch = "linux-x86_64"; sha1 = "b7a437552fc540966478832bf89a85dc81b16766"; } { locale = "nl"; arch = "linux-x86_64"; sha1 = "beaa7e385b655c82999dc38eb39af31e7e9de69a"; }
{ locale = "nl"; arch = "linux-i686"; sha1 = "36f65d56954e59bd758b4a1c09abec85872eb140"; } { locale = "nn-NO"; arch = "linux-i686"; sha1 = "04ed2d080ef687b0504f3d42bea97b2e56876795"; }
{ locale = "nl"; arch = "linux-x86_64"; sha1 = "0c1ed8b52afdd3d15f163fc8899e14caeb0a4497"; } { locale = "nn-NO"; arch = "linux-x86_64"; sha1 = "857fbeef81cf00def5eaaa02effb1731eac15a1f"; }
{ locale = "nn-NO"; arch = "linux-i686"; sha1 = "729144a52c95cbcb2665da00e953cbdb269c0665"; } { locale = "or"; arch = "linux-i686"; sha1 = "a208556246b7574d5e71eec8a56d8a2ab3c43767"; }
{ locale = "nn-NO"; arch = "linux-x86_64"; sha1 = "5298026198b8d6c7eb0b816ca29bbd26f0f65907"; } { locale = "or"; arch = "linux-x86_64"; sha1 = "f7b223bfe82d2ab7a0f2dba0b93e682ef5c833e3"; }
{ locale = "or"; arch = "linux-i686"; sha1 = "33aaf77833a3c3a504559c399a270061a582ffbb"; } { locale = "pa-IN"; arch = "linux-i686"; sha1 = "b67c2aa36065ece0526a280cbe33adcb38a20843"; }
{ locale = "or"; arch = "linux-x86_64"; sha1 = "a2dca791375b174d0f888ce56555fe21e5b2eaf4"; } { locale = "pa-IN"; arch = "linux-x86_64"; sha1 = "73aef7a4e318625d18cade40090ec112667de295"; }
{ locale = "pa-IN"; arch = "linux-i686"; sha1 = "3670a8492dde8b19e1f5fba10d54eabd003183e1"; } { locale = "pl"; arch = "linux-i686"; sha1 = "3446a41365fb0852684d0808d1fa85ddabcf0958"; }
{ locale = "pa-IN"; arch = "linux-x86_64"; sha1 = "376576536d6a7d373ec5c453e107f63261819cf1"; } { locale = "pl"; arch = "linux-x86_64"; sha1 = "0c1b1f1279e1639e71acdccaa4a687bf26aca19f"; }
{ locale = "pl"; arch = "linux-i686"; sha1 = "53af2036a170d77f828e80d455edf6cddf826cfb"; } { locale = "pt-BR"; arch = "linux-i686"; sha1 = "a3ec0b02796f67a798bbb895cf926f9bd7ccbe8d"; }
{ locale = "pl"; arch = "linux-x86_64"; sha1 = "01e04cf2530c1b51bd9e8ee5114ac9ba5317e0e4"; } { locale = "pt-BR"; arch = "linux-x86_64"; sha1 = "e3b74fcb0ec26c440acedfe282a3ef0902a10d2b"; }
{ locale = "pt-BR"; arch = "linux-i686"; sha1 = "0fec2a4ea90ecb6d7e09041d45a4b0647c37ebe0"; } { locale = "pt-PT"; arch = "linux-i686"; sha1 = "0b942ec4a8fee50595a7b34e76636bfa83d2dfc0"; }
{ locale = "pt-BR"; arch = "linux-x86_64"; sha1 = "f7f1dd1f7d78b3647cb77f282b87a3d7224ec567"; } { locale = "pt-PT"; arch = "linux-x86_64"; sha1 = "d20698edd8193185342c2487433af4ea39fb6a3a"; }
{ locale = "pt-PT"; arch = "linux-i686"; sha1 = "cf46849b5fbd06b51c468f2dc6dab3eb9e8ffde1"; } { locale = "rm"; arch = "linux-i686"; sha1 = "442b8ac786b05e655b415a76427cca7ee0aa1abf"; }
{ locale = "pt-PT"; arch = "linux-x86_64"; sha1 = "e6bae39233b0c3735fb122b9e56ac4e82d435749"; } { locale = "rm"; arch = "linux-x86_64"; sha1 = "250cb2a8e3fe869ae150de97b15e6d8f8fd30da3"; }
{ locale = "rm"; arch = "linux-i686"; sha1 = "41ed6d9c3816647069b0416d1b7edda97fe1abff"; } { locale = "ro"; arch = "linux-i686"; sha1 = "3a796ab446e77064ad3a094464c54d578b5ca910"; }
{ locale = "rm"; arch = "linux-x86_64"; sha1 = "36a83ca4594ba79a3b01ee21a5cfde45b13b323e"; } { locale = "ro"; arch = "linux-x86_64"; sha1 = "a512c2bd2cdd21f108ff1f77a747c606f28f8621"; }
{ locale = "ro"; arch = "linux-i686"; sha1 = "d70284aea6297688eb25835a482d9ca349eac313"; } { locale = "ru"; arch = "linux-i686"; sha1 = "2a907a348dd1f61e2ee8b6027e2085ee2e7e71bf"; }
{ locale = "ro"; arch = "linux-x86_64"; sha1 = "78079d94b0ad83e6cd687433c335b7e0012c8cb8"; } { locale = "ru"; arch = "linux-x86_64"; sha1 = "228cad14512e25a445c1a5a92262ddf8fbb2f5c5"; }
{ locale = "ru"; arch = "linux-i686"; sha1 = "354fb775dbddfe9f87e78982e7456f20d01476bb"; } { locale = "si"; arch = "linux-i686"; sha1 = "69ad63bfa75e1279bdcfe3d4127d83bb49b134b4"; }
{ locale = "ru"; arch = "linux-x86_64"; sha1 = "30a29bb1cbf967fb24e5bbc6abefcdf074b316cc"; } { locale = "si"; arch = "linux-x86_64"; sha1 = "851e02e6ab551af88f41655cb3fe15883e536a62"; }
{ locale = "si"; arch = "linux-i686"; sha1 = "b20089f3f2ef670426a29e409426a9cd3569090a"; } { locale = "sk"; arch = "linux-i686"; sha1 = "56c439e0dca6d75aa218e995187d10c0f88d3390"; }
{ locale = "si"; arch = "linux-x86_64"; sha1 = "bee5b374f0ca41a858e9b61fe0b43a56bf303180"; } { locale = "sk"; arch = "linux-x86_64"; sha1 = "43b69972b4e785069eba3ca7db1d8563f5ea76d8"; }
{ locale = "sk"; arch = "linux-i686"; sha1 = "6c9d83b2cef140bdf513c7226854fc991d087785"; } { locale = "sl"; arch = "linux-i686"; sha1 = "64bad6a92fa3eb1c98e2ce038e4fafdddb699690"; }
{ locale = "sk"; arch = "linux-x86_64"; sha1 = "57595905385b6b7e77eee34f54a40562d041169d"; } { locale = "sl"; arch = "linux-x86_64"; sha1 = "ace07b787362d893be563c9d59ec7e616f3a1d11"; }
{ locale = "sl"; arch = "linux-i686"; sha1 = "63b3edf9aec8a6beabdf1a4b4a9fb0fb835345fc"; } { locale = "son"; arch = "linux-i686"; sha1 = "6a027929d81d9c36f62d0f092d4d7f1451713077"; }
{ locale = "sl"; arch = "linux-x86_64"; sha1 = "3afafa985ee73cfe378e39881665d2242a6943c9"; } { locale = "son"; arch = "linux-x86_64"; sha1 = "ebb4fd0f3dcabefd3d5e19a67d3e0e02a70918fa"; }
{ locale = "son"; arch = "linux-i686"; sha1 = "e6b6b56ebee586bb10511d197b11d93aefae6316"; } { locale = "sq"; arch = "linux-i686"; sha1 = "3048cc7c6837dbad7c654b37b44ee1c3a588633c"; }
{ locale = "son"; arch = "linux-x86_64"; sha1 = "f95cb4b571fa389df4e182632b12216699cc9f0a"; } { locale = "sq"; arch = "linux-x86_64"; sha1 = "d4ef1a51d0bf973fe4bfc614f8878f021ec46f5b"; }
{ locale = "sq"; arch = "linux-i686"; sha1 = "18dfa5b40bd31a0d23884f6e9af357b0be01c4b2"; } { locale = "sr"; arch = "linux-i686"; sha1 = "d10e7c6619d2a2879eaab9d8c3a1a7f7458f60bb"; }
{ locale = "sq"; arch = "linux-x86_64"; sha1 = "f9d026e9d5a85eaad008d65b736ae8c63cb5064d"; } { locale = "sr"; arch = "linux-x86_64"; sha1 = "5b140de3d590ea84f91165396b7e154acc247172"; }
{ locale = "sr"; arch = "linux-i686"; sha1 = "a5ed16491244d9ab6237546e241335005572c1c0"; } { locale = "sv-SE"; arch = "linux-i686"; sha1 = "57efc1f16710acd31a6db186673995f0713dba6f"; }
{ locale = "sr"; arch = "linux-x86_64"; sha1 = "2ed29dec3a28949b93f82d0652a38a5539fb2304"; } { locale = "sv-SE"; arch = "linux-x86_64"; sha1 = "d65d51b861eb62a5cdc99491f3c91dbb02638511"; }
{ locale = "sv-SE"; arch = "linux-i686"; sha1 = "594eae45b36645a47b12d9579826789e3255b275"; } { locale = "ta"; arch = "linux-i686"; sha1 = "aead4b55accc679c8fd49a099d12de95410bc480"; }
{ locale = "sv-SE"; arch = "linux-x86_64"; sha1 = "0cec1133910c8ae87878ca56fd63b610651f99ca"; } { locale = "ta"; arch = "linux-x86_64"; sha1 = "fcca6081e4fa248f86d77bc8d7aad658e82ef4c7"; }
{ locale = "ta"; arch = "linux-i686"; sha1 = "86da5bfa06e670359b831226822db6a40a7ec7c3"; } { locale = "te"; arch = "linux-i686"; sha1 = "dbcdd1cc740d82f075c71bb6e3d087312ab7700d"; }
{ locale = "ta"; arch = "linux-x86_64"; sha1 = "86b3749d396a7be3628face4bf7ed7278b98c5ab"; } { locale = "te"; arch = "linux-x86_64"; sha1 = "901df9c92377dec49e66b17c7efd5a3d8f8ea5d5"; }
{ locale = "te"; arch = "linux-i686"; sha1 = "7020a27e9173b52a54c8e442e8e2ffc60a888e2c"; } { locale = "th"; arch = "linux-i686"; sha1 = "a150db665c6a1e5ceb3d6a27896431890b5631c5"; }
{ locale = "te"; arch = "linux-x86_64"; sha1 = "417ea3e749a9f7309b11d50f99bd5c1b916a0c77"; } { locale = "th"; arch = "linux-x86_64"; sha1 = "144489c6c53d1fdc32a42d2ebb6905946369c70a"; }
{ locale = "th"; arch = "linux-i686"; sha1 = "539293f4f6183ec2941fa83705f7c91bf5e65776"; } { locale = "tr"; arch = "linux-i686"; sha1 = "ccfc01ef15ee5345a2f0e07b1c4bcf8ac4459554"; }
{ locale = "th"; arch = "linux-x86_64"; sha1 = "362d3c39936725437d63576f2c8ee6deaf9429ea"; } { locale = "tr"; arch = "linux-x86_64"; sha1 = "563862e9a8b355b12c3dca36fc4d8c219707820a"; }
{ locale = "tr"; arch = "linux-i686"; sha1 = "eb0d205cf6eac45a8405d072b89856293d4cb63e"; } { locale = "uk"; arch = "linux-i686"; sha1 = "9885b14de8ca7d1a25adec103e245dc6d54c226d"; }
{ locale = "tr"; arch = "linux-x86_64"; sha1 = "84c19d6ec3446ecbe03f0751822501d3628699a8"; } { locale = "uk"; arch = "linux-x86_64"; sha1 = "8d9d3e4a14d0288dc6d82cb652752712e0e4b577"; }
{ locale = "uk"; arch = "linux-i686"; sha1 = "5ef72696a4180c91483f406627ea040bede2f30c"; } { locale = "vi"; arch = "linux-i686"; sha1 = "a70b8c7d9a7bbda992faf8f3762e55412b12a08d"; }
{ locale = "uk"; arch = "linux-x86_64"; sha1 = "9de7bcc3ff254234e1844860c3bc907317c02ae6"; } { locale = "vi"; arch = "linux-x86_64"; sha1 = "17661185644f68902eb946a3cd179c77f9681881"; }
{ locale = "vi"; arch = "linux-i686"; sha1 = "3338130b87e4dd9ee7b8e7120dd158065a772290"; } { locale = "xh"; arch = "linux-i686"; sha1 = "1f1c9a8c1a614e5855d7303d808e661e54536de9"; }
{ locale = "vi"; arch = "linux-x86_64"; sha1 = "53ebf9890f9b4ccdc786fa65dcae739fae7b8f7c"; } { locale = "xh"; arch = "linux-x86_64"; sha1 = "17490957c9f3064ea5ea35562c0d669a557ea1ae"; }
{ locale = "xh"; arch = "linux-i686"; sha1 = "83ae4b1f84c64733d196b9bec58ab1468b126577"; } { locale = "zh-CN"; arch = "linux-i686"; sha1 = "5140d26ab69f0645ae512d8a9d277ae6efc7dc45"; }
{ locale = "xh"; arch = "linux-x86_64"; sha1 = "da5b9dca0277dd2be1027251c96f7524e0204f2f"; } { locale = "zh-CN"; arch = "linux-x86_64"; sha1 = "cc09fcde7062e5bac4952b239354152855b8c52a"; }
{ locale = "zh-CN"; arch = "linux-i686"; sha1 = "bc3e12000156a886e00a64bf536c5b2c35bb727d"; } { locale = "zh-TW"; arch = "linux-i686"; sha1 = "e923cb157faa256852ead1aef8e1c5e420e4fb27"; }
{ locale = "zh-CN"; arch = "linux-x86_64"; sha1 = "1ac45fd506eb1d5bb92a86ee3a9686e8c93b5c9e"; } { locale = "zh-TW"; arch = "linux-x86_64"; sha1 = "d801a229474eaee5229137f2e69629abdf60e36b"; }
{ locale = "zh-TW"; arch = "linux-i686"; sha1 = "5377236c138066df6f67083ae8ed348c6d611a81"; }
{ locale = "zh-TW"; arch = "linux-x86_64"; sha1 = "8733a47e10d1bd025507c09a443acf80dd614643"; }
{ locale = "zu"; arch = "linux-i686"; sha1 = "a653e724fe28431b2b5ca5f2553654da4ffa526f"; }
{ locale = "zu"; arch = "linux-x86_64"; sha1 = "81c967fc251d77a38de24519dba0f4465326fcd8"; }
]; ];
} }

View File

@ -15,14 +15,14 @@
assert stdenv.gcc ? libc && stdenv.gcc.libc != null; assert stdenv.gcc ? libc && stdenv.gcc.libc != null;
let version = "33.1.1"; in let version = "34.0.5"; in
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "firefox-${version}"; name = "firefox-${version}";
src = fetchurl { src = fetchurl {
url = "http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/${version}/source/firefox-${version}.source.tar.bz2"; url = "http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/${version}/source/firefox-${version}.source.tar.bz2";
sha1 = "1e9e3176e7d221c4f2ce479f37ee7c432236a0ec"; sha1 = "33654d38268d1d1f71105f48bbe97cf720f47be2";
}; };
buildInputs = buildInputs =
@ -97,7 +97,7 @@ stdenv.mkDerivation rec {
meta = { meta = {
description = "Web browser"; description = "Web browser";
homepage = http://www.mozilla.com/en-US/firefox/; homepage = http://www.mozilla.com/en-US/firefox/;
maintainers = with lib.maintainers; [ eelco wizeman ]; maintainers = with lib.maintainers; [ eelco ];
platforms = lib.platforms.linux; platforms = lib.platforms.linux;
}; };

View File

@ -90,7 +90,6 @@ stdenv.mkDerivation {
meta = { meta = {
description = "Adobe Flash Player browser plugin"; description = "Adobe Flash Player browser plugin";
homepage = http://www.adobe.com/products/flashplayer/; homepage = http://www.adobe.com/products/flashplayer/;
maintainers = with stdenv.lib.maintainers; [ wizeman ];
license = stdenv.lib.licenses.unfree; license = stdenv.lib.licenses.unfree;
}; };
} }

View File

@ -0,0 +1,18 @@
{stdenv, curl}:
stdenv.mkDerivation {
name = "chronos-maven-deps";
builder = ./fetch-chronos-deps.sh;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
outputHash = "0mm2sb1p5zz6b0z2s4zhdlix6fafydsxmqjy8zbkwzw4f6lazzyl";
buildInputs = [ curl ];
# We borrow these environment variables from the caller to allow
# easy proxy configuration. This is impure, but a fixed-output
# derivation like fetchurl is allowed to do so since its result is
# by definition pure.
impureEnvVars = ["http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy"];
}

View File

@ -0,0 +1,38 @@
{ stdenv, lib, makeWrapper, fetchgit, curl, jdk, maven, nodejs, mesos }:
stdenv.mkDerivation rec {
name = "chronos-${version}";
version = "286b2ccb8e4695f8e413406ceca85b60d3a87e22";
src = fetchgit {
url = "https://github.com/airbnb/chronos";
rev = version;
sha256 = "6c463c30530dc82276d30087e7ab08d6964b884232c0a93f691cef9fa1ff2651";
};
buildInputs = [ makeWrapper curl jdk maven nodejs mesos ];
mavenRepo = import ./chronos-deps.nix { inherit stdenv curl; };
buildPhase = ''
ln -s $mavenRepo .m2
mvn package -Dmaven.repo.local=$(pwd)/.m2
'';
installPhase = ''
mkdir -p $out/{bin,libexec/chronos}
cp target/chronos*.jar $out/libexec/chronos/${name}.jar
makeWrapper ${jdk.jre}/bin/java $out/bin/chronos \
--add-flags "-Xmx384m -Xms384m -cp $out/libexec/chronos/${name}.jar com.airbnb.scheduler.Main" \
--prefix "MESOS_NATIVE_LIBRARY" : "$MESOS_NATIVE_LIBRARY"
'';
meta = with lib; {
homepage = https://github.com/airbnb/chronos;
license = licenses.asl20;
description = "Fault tolerant job scheduler for Mesos which handles dependencies and ISO8601 based schedules";
maintainers = with maintainers; [ offline ];
platforms = with platforms; unix;
};
}

File diff suppressed because it is too large Load Diff

View File

@ -2,22 +2,25 @@
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "kubernetes-${version}"; name = "kubernetes-${version}";
version = "v0.5.2"; version = "v0.5.4";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "GoogleCloudPlatform"; owner = "GoogleCloudPlatform";
repo = "kubernetes"; repo = "kubernetes";
rev = version; rev = version;
sha256 = "0nrm59v43jx0cskpd294q946053cfw3y2cgs53ji35dnhgj6fl6w"; sha256 = "1pipcqpjz9zsi4kfsbdvbbbia642l4xg50pznjw5v061c5xk7vnk";
}; };
buildInputs = [ makeWrapper which go iptables rsync ]; buildInputs = [ makeWrapper which go iptables rsync ];
preBuild = "patchShebangs ./hack"; preBuild = "patchShebangs ./hack";
postBuild = ''go build --ldflags '-extldflags "-static" -s' build/pause/pause.go'';
installPhase = '' installPhase = ''
mkdir -p "$out/bin" mkdir -p "$out/bin"
cp _output/local/go/bin/* "$out/bin/" cp _output/local/go/bin/* "$out/bin/"
cp pause $out/bin/kube-pause
''; '';
preFixup = '' preFixup = ''
@ -29,6 +32,6 @@ stdenv.mkDerivation rec {
license = licenses.asl20; license = licenses.asl20;
homepage = https://github.com/GoogleCloudPlatform; homepage = https://github.com/GoogleCloudPlatform;
maintainers = with maintainers; [offline]; maintainers = with maintainers; [offline];
platforms = with platforms; linux; platforms = [ "x86_64-linux" ];
}; };
} }

View File

@ -1,80 +0,0 @@
diff --git a/configure.ac b/configure.ac
index 1ebd196..a49d7d4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -463,11 +463,6 @@ __EOF__
fi
# Determine linker flags for Java if not set.
- if test "$OS_NAME" = "darwin"; then
- dir="$JAVA_HOME/jre/lib/server"
- JAVA_TEST_LDFLAGS="-framework JavaVM"
- JAVA_JVM_LIBRARY=$dir/libjvm.dylib
- elif test "$OS_NAME" = "linux"; then
for arch in amd64 i386; do
dir="$JAVA_HOME/jre/lib/$arch/server"
if test -e "$dir"; then
@@ -477,7 +472,6 @@ __EOF__
break;
fi
done
- fi
if test -z "$JAVA_TEST_LDFLAGS"; then
AC_MSG_ERROR([failed to determine linker flags for using Java \
@@ -488,26 +482,6 @@ __EOF__
# flags as necessary (provided JAVA_CPPFLAGS was not set).
AC_MSG_CHECKING([whether or not we can build with JNI])
if test -z "$JAVA_CPPFLAGS"; then
- if test "$OS_NAME" = "darwin"; then
- while true; do # Loop until sucessful (via break) or exhausted options.
- m4_foreach([java_cppflags],
- [["-I$JAVA_HOME/include -I$JAVA_HOME/include/$OS_NAME"],
- ["-I/System/Library/Frameworks/JavaVM.framework/Headers"]],
- [JAVA_CPPFLAGS=java_cppflags
- TRY_LINK_JNI([break])])
- # Exhausted options.
- AC_MSG_ERROR([failed to build with JNI
- -------------------------------------------------------------------
- It appears we were unable to compile against the JNI. This is most
- likely due to one of the following issues:
- 1. You do not have a JDK installed on your system.
- 2. All JDKs installed on your system have deprecated JNI headers.
- It is advised to install OpenJDK on your system, as the JDK that
- ships with OS X has deprecated JNI headers.
- -------------------------------------------------------------------
- ])
- done
- else
while true; do # Loop until sucessful (via break) or exhausted options.
m4_foreach([java_cppflags],
[["-I$JAVA_HOME/include -I$JAVA_HOME/include/$OS_NAME"]],
@@ -516,7 +490,6 @@ __EOF__
# Exhausted options.
AC_MSG_ERROR([failed to build with JNI])
done
- fi
else
TRY_LINK_JNI([], [AC_MSG_ERROR([failed to build with JNI])])
fi
@@ -760,20 +733,6 @@ libcurl is required for mesos to build.
if test "x$with_cxx11" = "xyes"; then
AX_CXX_COMPILE_STDCXX_11([noext], [mandatory])
- case "$host_os" in
- darwin* )
- # If we're using clang, we need to pass -stdlib=libc++ too.
- if test "x$CLANG" = "xyes"; then
- CXXFLAGS="$CXXFLAGS -stdlib=libc++"
- fi
-
- # GTEST on OSX needs its own tr1 tuple.
- # TODO(dhamon): Update to gmock 1.7 and pass GTEST_LANG_CXX11 when in
- # c++11 mode.
- CXXFLAGS="$CXXFLAGS -DGTEST_USE_OWN_TR1_TUPLE=1"
- ;;
- esac
-
# Also pass the flags to 3rdparty libraries.
CONFIGURE_ARGS="$CONFIGURE_ARGS CXXFLAGS='$CXXFLAGS'"
fi

View File

@ -1,9 +1,10 @@
{ stdenv, lib, makeWrapper, fetchurl, fetchzip, curl, sasl, openssh, autoconf { stdenv, lib, makeWrapper, fetchurl, curl, sasl, openssh, autoconf
, automake, libtool, unzip, gnutar, jdk, maven, python, wrapPython , automake, libtool, unzip, gnutar, jdk, maven, python, wrapPython
, setuptools, distutils-cfg, boto, pythonProtobuf , setuptools, distutils-cfg, boto, pythonProtobuf, apr, subversion
, leveldb, glog
}: }:
let version = "0.19.1"; let version = "0.21.0";
in stdenv.mkDerivation { in stdenv.mkDerivation {
dontDisableStatic = true; dontDisableStatic = true;
@ -11,14 +12,13 @@ in stdenv.mkDerivation {
src = fetchurl { src = fetchurl {
url = "http://www.apache.org/dist/mesos/${version}/mesos-${version}.tar.gz"; url = "http://www.apache.org/dist/mesos/${version}/mesos-${version}.tar.gz";
sha256 = "12li5xqfcw3124qg3h2cji3yhrc7gbx91lj45zfliicwgjkbmyf1"; sha256 = "01ap8blrb046w26zf3i4r7vvnnhjsbfi20vz5yinmncqbzjjyx6i";
}; };
patches = [ ./darwin.patch ];
buildInputs = [ buildInputs = [
makeWrapper autoconf automake libtool curl sasl jdk maven makeWrapper autoconf automake libtool curl sasl jdk maven
python wrapPython boto distutils-cfg setuptools python wrapPython boto distutils-cfg setuptools leveldb
subversion apr glog
]; ];
propagatedBuildInputs = [ propagatedBuildInputs = [
@ -41,11 +41,11 @@ in stdenv.mkDerivation {
configureFlags = [ configureFlags = [
"--sbindir=\${out}/bin" "--sbindir=\${out}/bin"
"--with-python-headers=${python}/include" "--with-apr=${apr}"
"--with-webui" "--with-svn=${subversion}"
"--with-java-home=${jdk}" "--with-leveldb=${leveldb}"
"--with-java-headers=${jdk}/include" "--with-glog=${glog}"
"--with-included-zookeeper" "--disable-python-dependency-install"
]; ];
postInstall = '' postInstall = ''
@ -101,7 +101,7 @@ in stdenv.mkDerivation {
homepage = "http://mesos.apache.org"; homepage = "http://mesos.apache.org";
license = licenses.asl20; license = licenses.asl20;
description = "A cluster manager that provides efficient resource isolation and sharing across distributed applications, or frameworks"; description = "A cluster manager that provides efficient resource isolation and sharing across distributed applications, or frameworks";
maintainers = with maintainers; [ cstrahan ]; maintainers = with maintainers; [ cstrahan offline ];
platforms = with platforms; linux; platforms = with platforms; linux;
}; };
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,128 +1,46 @@
{ stdenv, fetchurl, jre, bash, simpleBuildTool, python27Packages }: { stdenv, fetchurl, makeWrapper, jre, pythonPackages
, mesosSupport ? true, mesos
}:
with stdenv.lib;
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "spark-${version}"; name = "spark-${version}";
version = "0.9.1"; version = "1.1.1";
src = fetchurl { src = fetchurl {
url = "http://d3kbcqa49mib13.cloudfront.net/${name}-bin-cdh4.tgz"; url = "http://d3kbcqa49mib13.cloudfront.net/${name}-bin-cdh4.tgz";
sha256 = "1k3954srx3km3ckmfi6wn8rldrljxc039g0pf5m3azgkmaz0gld5"; sha256 = "1k0lw8aq5is3gnsrm8q24s0knga6kb3c9xsca20g11fy8b0y4nvk";
}; };
unpackPhase = ''tar zxf $src''; buildInputs = [ makeWrapper jre pythonPackages.python pythonPackages.numpy ]
++ optional mesosSupport [ mesos ];
untarDir = "${name}-bin-cdh4"; untarDir = "${name}-bin-cdh4";
installPhase = '' installPhase = ''
set -x mkdir -p $out/{lib/${untarDir}/conf,bin}
mkdir -p $out/lib $out/bin mv * $out/lib/${untarDir}
mv ${untarDir} $out/lib
cat > $out/bin/spark-class <<EOF cat > $out/lib/${untarDir}/conf/spark-env.sh <<- EOF
#!${bash}/bin/bash export JAVA_HOME="${jre}"
export JAVA_HOME=${jre} export SPARK_HOME="$out/lib/${untarDir}"
export SPARK_HOME=$out/lib/${untarDir} export PYSPARK_PYTHON="${pythonPackages.python}/bin/${pythonPackages.python.executable}"
export PYTHONPATH="\$PYTHONPATH:$PYTHONPATH"
if [ -z "\$1" ]; then ${optionalString mesosSupport
echo "Usage: spark-class <class> [<args>]" >&2 ''export MESOS_NATIVE_LIBRARY="$MESOS_NATIVE_LIBRARY"''}
exit 1
fi
export SPARK_MEM=\''${SPARK_MEM:-1024m}
JAVA_OPTS=""
JAVA_OPTS="\$JAVA_OPTS -Djava.library.path=\"\$SPARK_LIBRARY_PATH\""
JAVA_OPTS="\$JAVA_OPTS -Xms\$SPARK_MEM -Xmx\$SPARK_MEM"
export JAVA_OPTS
CLASSPATH=\`$out/lib/${untarDir}/bin/compute-classpath.sh\`
export CLASSPATH
exec ${jre}/bin/java -cp "\$CLASSPATH" \$JAVA_OPTS "\$@"
EOF EOF
chmod +x $out/bin/spark-class
cat > $out/bin/spark-shell <<EOF for n in $(find $out/lib/${untarDir}/bin -type f ! -name "*.*"); do
#!${bash}/bin/bash makeWrapper "$n" "$out/bin/$(basename $n)"
set -o posix
export JAVA_HOME=${jre}
export SPARK_HOME=$out/lib/${untarDir}
for o in "\$@"; do
if [ "\$1" = "-c" -o "\$1" = "--cores" ]; then
shift
if [ -n "\$1" ]; then
OPTIONS="-Dspark.cores.max=\$1"
shift
fi
fi
done done
exit_status=127
saved_stty=""
function restoreSttySettings() {
stty \$saved_stty
saved_stty=""
}
function onExit() {
if [[ "\$saved_stty" != "" ]]; then
restoreSttySettings
fi
exit \$exit_status
}
trap onExit INT
saved_stty=\$(stty -g 2>/dev/null)
if [[ ! \$? ]]; then
saved_stty=""
fi
$out/bin/spark-class \$OPTIONS org.apache.spark.repl.Main "\$@"
exit_status=\$?
onExit
EOF
chmod +x $out/bin/spark-shell
cat > $out/bin/pyspark <<EOF
#!${bash}/bin/bash
export JAVA_HOME=${jre}
export SPARK_HOME=$out/lib/${untarDir}
export PYTHONPATH=$out/lib/${untarDir}/python:\$PYTHONPATH
export OLD_PYTHONSTARTUP=\$PYTHONSTARTUP
export PYTHONSTARTUP=$out/lib/${untarDir}/python/pyspark/shell.py
export SPARK_MEM=\''${SPARK_MEM:-1024m}
exec ${python27Packages.ipythonLight}/bin/ipython \$@
EOF
chmod +x $out/bin/pyspark
cat > $out/bin/spark-upload-scala <<EOF
#!${bash}/bin/bash
export JAVA_HOME=${jre}
export SPARK_HOME=$out/lib/${untarDir}
export SPARK_MEM=\''${SPARK_MEM:-1024m}
CLASS=\$1; shift
exec ${simpleBuildTool}/bin/sbt package "run-main \$CLASS \$@"
EOF
chmod +x $out/bin/spark-upload-scala
cat > $out/bin/spark-upload-python <<EOF
#!${bash}/bin/bash
exec $out/bin/pyspark \$@
EOF
chmod +x $out/bin/spark-upload-python
''; '';
phases = "unpackPhase installPhase";
meta = { meta = {
description = "Lightning-fast cluster computing"; description = "Lightning-fast cluster computing";
homepage = "http://spark.apache.org"; homepage = "http://spark.apache.org";
license = stdenv.lib.licenses.asl20; license = stdenv.lib.licenses.asl20;
platforms = stdenv.lib.platforms.all; platforms = stdenv.lib.platforms.all;
maintainers = [ stdenv.lib.maintainers.thoughtpolice ]; maintainers = with maintainers; [ thoughtpolice offline ];
repositories.git = git://git.apache.org/spark.git; repositories.git = git://git.apache.org/spark.git;
}; };
} }

View File

@ -5,7 +5,7 @@
let let
version = "2.2.1163"; version = "2.2.1287";
rpath = stdenv.lib.makeSearchPath "lib" [ rpath = stdenv.lib.makeSearchPath "lib" [
stdenv.glibc stdenv.glibc
@ -47,12 +47,12 @@ let
if stdenv.system == "x86_64-linux" then if stdenv.system == "x86_64-linux" then
fetchurl { fetchurl {
url = "http://downloads.hipchat.com/linux/arch/x86_64/hipchat-${version}-x86_64.pkg.tar.xz"; url = "http://downloads.hipchat.com/linux/arch/x86_64/hipchat-${version}-x86_64.pkg.tar.xz";
sha256 = "0yafin8qfnv9kj61z9vxza42r7fv8b9j04qs50masbly0jg5xsg8"; sha256 = "170izy3v18rgriz84h4gyf9354jvjrsbkgg53czq9l0scyz8x55b";
} }
else if stdenv.system == "i686-linux" then else if stdenv.system == "i686-linux" then
fetchurl { fetchurl {
url = "http://downloads.hipchat.com/linux/arch/i686/hipchat-${version}-i686.pkg.tar.xz"; url = "http://downloads.hipchat.com/linux/arch/i686/hipchat-${version}-i686.pkg.tar.xz";
sha256 = "1a0yvrnp41s53wpqv2jxsb3gd4vb49nfh89m6nwbw4qd85i5lfsp"; sha256 = "150q7pxg5vs14is5qf36yfsf7r70g49q9xr1d1rknmc5m4qa5rc5";
} }
else else
throw "HipChat is not supported on ${stdenv.system}"; throw "HipChat is not supported on ${stdenv.system}";
@ -75,8 +75,6 @@ stdenv.mkDerivation {
mv opt/HipChat/lib/ $d mv opt/HipChat/lib/ $d
mv usr/share $out mv usr/share $out
patchShebangs $out/bin
for file in $(find $d -type f); do for file in $(find $d -type f); do
patchelf --set-interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" $file || true patchelf --set-interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" $file || true
patchelf --set-rpath ${rpath}:\$ORIGIN $file || true patchelf --set-rpath ${rpath}:\$ORIGIN $file || true

View File

@ -1,16 +1,18 @@
{ stdenv, fetchurl, libtoxcore, pidgin, autoconf, automake, libtool, libsodium } : { stdenv, fetchFromGitHub, libtoxcore, pidgin, autoconf, automake, libtool
, libsodium } :
let let
version = "17a3fd9199"; version = "dd181722ea";
date = "20131012"; date = "20141202";
in in
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "tox-prpl-${date}-${version}"; name = "tox-prpl-${date}-${version}";
src = fetchurl { src = fetchFromGitHub {
url = "https://github.com/jin-eld/tox-prpl/tarball/${version}"; owner = "jin-eld";
name = "${name}.tar.gz"; repo = "tox-prpl";
sha256 = "0sz5wkyfwmhaj652xpsxq4p252cmmfa1vy6mp3jfyn145c758v9n"; rev = "${version}";
sha256 = "0wzyvg11h4ym28zqd24p35lza3siwm2519ga0yhk98rv458zks0v";
}; };
NIX_LDFLAGS = "-lssp -lsodium"; NIX_LDFLAGS = "-lssp -lsodium";

View File

@ -0,0 +1,21 @@
{ stdenv, fetchurl, pidgin } :
stdenv.mkDerivation rec {
name = "pidgin-window-merge-${version}";
version = "0.3";
src = fetchurl {
url = "https://github.com/downloads/dm0-/window_merge/window_merge-${version}.tar.gz";
sha256 = "0cb5rvi7jqvm345g9mlm4wpq0240kcybv81jpw5wlx7hz0lwi478";
};
buildInputs = [ pidgin ];
meta = with stdenv.lib; {
homepage = https://github.com/dm0-/window_merge;
description = "Pidgin plugin that merges the Buddy List window with a conversation window";
license = licenses.gpl3;
platforms = platforms.linux;
maintainers = with maintainers; [ jgeerds ];
};
}

View File

@ -1,29 +1,30 @@
{ stdenv, fetchFromGitHub, pkgconfig, libtoxcore, qt5, openal, opencv }: { stdenv, fetchFromGitHub, pkgconfig, libtoxcore, qt5, openalSoft, opencv
, libsodium }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "qtox-dev-20140918"; name = "qtox-dev-20141201";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "tux3"; owner = "tux3";
repo = "qTox"; repo = "qTox";
rev = "f06ec65bca"; rev = "qtox-windows-1417469442.11";
sha256 = "0r7qc444bgsxawyya5nw3xk1c50b90307lcwazs8mn35h4snr97m"; sha256 = "02nxj0w5qbgc79n8mgyqldk1yadf4p8pysn79f7fvi8fxq4j0j5n";
}; };
buildInputs = [ pkgconfig libtoxcore qt5 openal opencv ]; buildInputs = [ pkgconfig libtoxcore qt5 openalSoft opencv libsodium ];
configurePhase = "qmake"; configurePhase = "qmake";
installPhase = '' installPhase = ''
ensureDir $out/bin mkdir -p $out/bin
cp qtox $out/bin cp qtox $out/bin
''; '';
meta = with stdenv.lib; { meta = with stdenv.lib; {
description = "QT Tox client"; description = "QT Tox client";
license = licenses.gpl3; license = licenses.gpl3;
maintainers = with stdenv.lib.maintainers; [ viric ]; maintainers = with maintainers; [ viric jgeerds ];
platforms = stdenv.lib.platforms.all; platforms = platforms.all;
}; };
} }

View File

@ -1,17 +1,17 @@
{ stdenv, fetchurl, autoconf, libtool, automake, libsodium, ncurses { stdenv, fetchFromGitHub, autoconf, libtool, automake, libsodium, ncurses
, libtoxcore, openal, libvpx, freealut, libconfig, pkgconfig }: , libtoxcore, openal, libvpx, freealut, libconfig, pkgconfig }:
let stdenv.mkDerivation rec {
version = "0.5.1"; name = "toxic-dev-20141130";
in stdenv.mkDerivation rec {
name = "toxic-${version}";
src = fetchurl { src = fetchFromGitHub {
url = "https://github.com/Tox/toxic/archive/v${version}.tar.gz"; owner = "Tox";
sha256 = "0zzfgwm17a4xcy9l0ll2pksp45mz6f4s3isdrgjpw1xibv9xnzcm"; repo = "toxic";
rev = "4acfe84171";
sha256 = "1yqglh9fm75zph4fzf3z4gwmamngypwpvb7shpqgakdg8ybq0a8s";
}; };
makeFlags = [ "-Cbuild" "VERSION=${version}" "PREFIX=$(out)" ]; makeFlags = [ "-Cbuild" "PREFIX=$(out)" ];
installFlags = [ "PREFIX=$(out)" ]; installFlags = [ "PREFIX=$(out)" ];
buildInputs = [ buildInputs = [
@ -21,10 +21,10 @@ in stdenv.mkDerivation rec {
openal libvpx freealut openal libvpx freealut
]; ];
meta = { meta = with stdenv.lib; {
description = "Reference CLI for Tox"; description = "Reference CLI for Tox";
license = stdenv.lib.licenses.gpl3Plus; license = licenses.gpl3Plus;
maintainers = with stdenv.lib.maintainers; [ viric ]; maintainers = with maintainers; [ viric jgeerds ];
platforms = stdenv.lib.platforms.all; platforms = platforms.all;
}; };
} }

View File

@ -3,13 +3,13 @@
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "utox-dev-20140921"; name = "utox-dev-20141130";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "notsecure"; owner = "notsecure";
repo = "uTox"; repo = "uTox";
rev = "c0afc95cf3"; rev = "38b0a2014f";
sha256 = "0a6i0c9crj6b27alm8q0fcfj8q425khg5305sp57r7pj505l4d1f"; sha256 = "00g9fsp83yjq6dfim3hfpag0ny9w5kydghycfj3ic8qaljp47y8a";
}; };
buildInputs = [ pkgconfig libtoxcore dbus libvpx libX11 openal freetype buildInputs = [ pkgconfig libtoxcore dbus libvpx libX11 openal freetype
@ -22,7 +22,7 @@ stdenv.mkDerivation rec {
meta = with stdenv.lib; { meta = with stdenv.lib; {
description = "Lightweight Tox client"; description = "Lightweight Tox client";
license = licenses.gpl3; license = licenses.gpl3;
maintainers = with stdenv.lib.maintainers; [ iElectric ]; maintainers = with maintainers; [ iElectric jgeerds ];
platforms = stdenv.lib.platforms.all; platforms = platforms.all;
}; };
} }

View File

@ -29,7 +29,7 @@
with stdenv.lib; with stdenv.lib;
let version = "3.10.1"; in let version = "3.11.1"; in
stdenv.mkDerivation { stdenv.mkDerivation {
name = "claws-mail-${version}"; name = "claws-mail-${version}";
@ -43,22 +43,17 @@ stdenv.mkDerivation {
src = fetchurl { src = fetchurl {
url = "http://downloads.sourceforge.net/project/claws-mail/Claws%20Mail/${version}/claws-mail-${version}.tar.bz2"; url = "http://downloads.sourceforge.net/project/claws-mail/Claws%20Mail/${version}/claws-mail-${version}.tar.bz2";
sha256 = "634d35dee311a288fb8fcba36d26987afdcd5485730cf67d00554110f414178e"; sha256 = "0w13xzri9d3165qsxf1dig1f0gxn3ib4lysfc9pgi4zpyzd0zgrw";
}; };
buildInputs = buildInputs =
[ dbus dbus_glib gtk gnutls libetpan perl pkgconfig python ] [ curl dbus dbus_glib gtk gnutls libetpan perl pkgconfig python ]
++ optional enableSpellcheck enchant ++ optional enableSpellcheck enchant
++ optionals (enablePgp || enablePluginSmime) [ gnupg gpgme ] ++ optionals (enablePgp || enablePluginSmime) [ gnupg gpgme ]
++ optional enablePluginArchive libarchive ++ optional enablePluginArchive libarchive
++ optional enablePluginNotificationSounds libcanberra ++ optional enablePluginNotificationSounds libcanberra
++ optional enablePluginNotificationDialogs libnotify ++ optional enablePluginNotificationDialogs libnotify
++ optional enablePluginFancy libsoup ++ optional enablePluginFancy libsoup
++ optional
(enablePluginFancy || enablePluginRavatar || enablePluginRssyl
|| enablePluginSpamassassin || enablePluginSpamReport
|| enablePluginVcalendar)
curl
++ optional enablePluginRssyl libxml2 ++ optional enablePluginRssyl libxml2
++ optional enableNetworkManager networkmanager ++ optional enableNetworkManager networkmanager
++ optional enableLdap openldap ++ optional enableLdap openldap

View File

@ -4,117 +4,117 @@
# ruby generate_source.rb > source.nix # ruby generate_source.rb > source.nix
{ {
version = "31.2.0"; version = "31.3.0";
sources = [ sources = [
{ locale = "ar"; arch = "linux-i686"; sha1 = "d56d0a2590e04fca857f5083be846b8de73a138c"; } { locale = "ar"; arch = "linux-i686"; sha1 = "2579ce59d7c26bdd345732d6ab164fbf6e531b0a"; }
{ locale = "ar"; arch = "linux-x86_64"; sha1 = "8e6f0280225e71859cedf72307e12179e71b2bca"; } { locale = "ar"; arch = "linux-x86_64"; sha1 = "55b912f4424b06972cc9d3b14cab3eaa75abdff0"; }
{ locale = "ast"; arch = "linux-i686"; sha1 = "ca2544e5b09b065df8763e8c803856a3313c12b7"; } { locale = "ast"; arch = "linux-i686"; sha1 = "101de138543ae46b667cc9800e45d30a59c31ea0"; }
{ locale = "ast"; arch = "linux-x86_64"; sha1 = "71487e868e4a2a87fc2f1550c3c6959016cf4de4"; } { locale = "ast"; arch = "linux-x86_64"; sha1 = "0e290b8222ec3085d2848eb219fa2a950ab38f96"; }
{ locale = "be"; arch = "linux-i686"; sha1 = "1620d97545765499b37eb05d04bf6d9ee1470544"; } { locale = "be"; arch = "linux-i686"; sha1 = "80db08139076f5e2810edd931af353bc3c9f6326"; }
{ locale = "be"; arch = "linux-x86_64"; sha1 = "1aebaef6d0e05c6e8ca0d7673b5ab7d9123305ed"; } { locale = "be"; arch = "linux-x86_64"; sha1 = "0569479306e0e5fbaa9b87d9f547eec875cdc673"; }
{ locale = "bg"; arch = "linux-i686"; sha1 = "af62f41d3abb604ea4c9bd7ef297eaa28f65e00c"; } { locale = "bg"; arch = "linux-i686"; sha1 = "072900fc768486d525fa89ef4a289b3135ec7d1e"; }
{ locale = "bg"; arch = "linux-x86_64"; sha1 = "d67bba94639d967e65328fb989696e4e461a0bd3"; } { locale = "bg"; arch = "linux-x86_64"; sha1 = "b99da8534a06e89380b8a9c62e7ac848995cd648"; }
{ locale = "bn-BD"; arch = "linux-i686"; sha1 = "7d7180ab9fdb0694ea93842f79411038f576c3a9"; } { locale = "bn-BD"; arch = "linux-i686"; sha1 = "89303e18aa4bc22b1cb91f4d990eb2e3896336e9"; }
{ locale = "bn-BD"; arch = "linux-x86_64"; sha1 = "4794ee971d932272ac809e2cdf432de5f38e0073"; } { locale = "bn-BD"; arch = "linux-x86_64"; sha1 = "142a507fd977c81e18580acea9dc3e60fb6e6cca"; }
{ locale = "br"; arch = "linux-i686"; sha1 = "533b40426ca2ad796ffe8ce45051701c27c179be"; } { locale = "br"; arch = "linux-i686"; sha1 = "987b861d55d333d552e22fd6ce4d5d8fa3031e95"; }
{ locale = "br"; arch = "linux-x86_64"; sha1 = "921b1d5a09a3ee282dead4762176eade35a18270"; } { locale = "br"; arch = "linux-x86_64"; sha1 = "8c088d8f374e4cab6477ed5e071861d3875513fb"; }
{ locale = "ca"; arch = "linux-i686"; sha1 = "01858a6bd869dd5060899af428924c3e5d700ee6"; } { locale = "ca"; arch = "linux-i686"; sha1 = "0517ffca37a556548a9b8ded4d7084df0ad70d53"; }
{ locale = "ca"; arch = "linux-x86_64"; sha1 = "1d64573818675c956b4b61b5501b1c2420dfd894"; } { locale = "ca"; arch = "linux-x86_64"; sha1 = "a617ae22a924d458ed633e5728f44838d0b42c64"; }
{ locale = "cs"; arch = "linux-i686"; sha1 = "582dacac45ba886232cc0e9b2757996af1c61fd6"; } { locale = "cs"; arch = "linux-i686"; sha1 = "9ae7115dfc0c11528ec276d62925815f93f49dd0"; }
{ locale = "cs"; arch = "linux-x86_64"; sha1 = "6dc0aa493e90c1c24b2cb3c323a4778413371486"; } { locale = "cs"; arch = "linux-x86_64"; sha1 = "2155ef2017e5411a9279b66142306f5d5b9b2b0d"; }
{ locale = "da"; arch = "linux-i686"; sha1 = "c64e7c50015d4cd633695f98715b6082f23bfb5f"; } { locale = "da"; arch = "linux-i686"; sha1 = "dfb5ee11a096128f53cebe016156e34aa762a5be"; }
{ locale = "da"; arch = "linux-x86_64"; sha1 = "10bc1b1758a1cc53fb9503d8ae02c92e640bfb13"; } { locale = "da"; arch = "linux-x86_64"; sha1 = "8549835e2c3a120aea39c274d7cb1c7f54035649"; }
{ locale = "de"; arch = "linux-i686"; sha1 = "69be28626ef89fba20b568cc026786c82a6a3dd6"; } { locale = "de"; arch = "linux-i686"; sha1 = "3032a8b87835781d919cab8862057a2612a52af3"; }
{ locale = "de"; arch = "linux-x86_64"; sha1 = "4d43592b2b28241c3e95c089f52b5adfb6c60d80"; } { locale = "de"; arch = "linux-x86_64"; sha1 = "6a9a99636cbfbff3950c5f31681ed2aefbb170b9"; }
{ locale = "el"; arch = "linux-i686"; sha1 = "881a8a8021ee63ed0d62c594bee464532b2d63f9"; } { locale = "el"; arch = "linux-i686"; sha1 = "33bd8a4a7cdaab9937a7880f17c27177a667f1f5"; }
{ locale = "el"; arch = "linux-x86_64"; sha1 = "53a30b91a9391e673537ba23ab194573bb40535f"; } { locale = "el"; arch = "linux-x86_64"; sha1 = "e32d2382a8322cb65ed3b2b4d634cc818bf94d58"; }
{ locale = "en-GB"; arch = "linux-i686"; sha1 = "acc98d20faccfcbaaff944957b334598faf73351"; } { locale = "en-GB"; arch = "linux-i686"; sha1 = "2e85dcaa7450e2cd605ab41849693c6eb94aa4b8"; }
{ locale = "en-GB"; arch = "linux-x86_64"; sha1 = "01ba64dc0228f17c3afc86559a541bc1fd71646a"; } { locale = "en-GB"; arch = "linux-x86_64"; sha1 = "5a229b46fca9bfe736254bc9a65259c5722dac37"; }
{ locale = "en-US"; arch = "linux-i686"; sha1 = "fb035b98358fd697e31162f639a5f01d1f43490b"; } { locale = "en-US"; arch = "linux-i686"; sha1 = "40d0e9a5530812d2ffc471f9c1e9c64ec39bc3aa"; }
{ locale = "en-US"; arch = "linux-x86_64"; sha1 = "26be2c2f908054dc3c8b3d53bfe3a840aae56428"; } { locale = "en-US"; arch = "linux-x86_64"; sha1 = "5dc64b9a0fa7e4df1ed232b56478d52986c3b4ad"; }
{ locale = "es-AR"; arch = "linux-i686"; sha1 = "10049cd0188485a6ab61519402fa74d62e9cab2b"; } { locale = "es-AR"; arch = "linux-i686"; sha1 = "5b3cec2e5ddfd9a12eadc5ac270aba85acfe0051"; }
{ locale = "es-AR"; arch = "linux-x86_64"; sha1 = "f579cd0579ff249dc100658cc0e7e6677a28976d"; } { locale = "es-AR"; arch = "linux-x86_64"; sha1 = "bceb273367d49b927f5de022009fdd27b707d4eb"; }
{ locale = "es-ES"; arch = "linux-i686"; sha1 = "fb9174c60d66141fdf568c92259b02579e70e9fe"; } { locale = "es-ES"; arch = "linux-i686"; sha1 = "9911086185272ac2a5c6ee9b36170f1a7352b5a4"; }
{ locale = "es-ES"; arch = "linux-x86_64"; sha1 = "8f0f216d81badf5bffd976c0472d9f1318672e48"; } { locale = "es-ES"; arch = "linux-x86_64"; sha1 = "df164ccdb2ec8ac50c663fe5771a63cb51b991a8"; }
{ locale = "et"; arch = "linux-i686"; sha1 = "052477b4febfb97d446976d81453289850a61aa3"; } { locale = "et"; arch = "linux-i686"; sha1 = "1e98b4c19dc16e52a65e66a0b518626924a098b1"; }
{ locale = "et"; arch = "linux-x86_64"; sha1 = "6a6341649624e9932714d32d750501e71dbb3106"; } { locale = "et"; arch = "linux-x86_64"; sha1 = "2153b56a7336fdba78797025ebba8deb0c5796ed"; }
{ locale = "eu"; arch = "linux-i686"; sha1 = "effe11b4ab62a11c110e0edfd9b46c5c8f259133"; } { locale = "eu"; arch = "linux-i686"; sha1 = "864ae993a8e87b09ba2ebfa5d12a8cc9b36c9c27"; }
{ locale = "eu"; arch = "linux-x86_64"; sha1 = "5152d64bf47f7b92a1e33b42ba1b48596f7069d8"; } { locale = "eu"; arch = "linux-x86_64"; sha1 = "ad4a01b18e2c9d38d048f9ee28a19c00dd1dc122"; }
{ locale = "fi"; arch = "linux-i686"; sha1 = "6b3019504e9a97db8eae5a35c2b963ebdca144ed"; } { locale = "fi"; arch = "linux-i686"; sha1 = "d2ebe588dda618a29de4af0fbadbdd1daddd059c"; }
{ locale = "fi"; arch = "linux-x86_64"; sha1 = "a44a93c9c727ecb64f6f83a3fa6c66fc0f1a1153"; } { locale = "fi"; arch = "linux-x86_64"; sha1 = "3c5eb0bb4dec968678c812eda5d723b50ca2f150"; }
{ locale = "fr"; arch = "linux-i686"; sha1 = "31c96279136afe886465eae51b6f32d3f13e53bb"; } { locale = "fr"; arch = "linux-i686"; sha1 = "c71f67ab5942cb49add9a044d6eeb69523f416c9"; }
{ locale = "fr"; arch = "linux-x86_64"; sha1 = "c2923291007f5480d2913d6093b38233939f089a"; } { locale = "fr"; arch = "linux-x86_64"; sha1 = "60c5a7037de5439ffebc39980c87e5e1065e2d8c"; }
{ locale = "fy-NL"; arch = "linux-i686"; sha1 = "00425ba7a789dca73ad5cb3a65bc08040f1a8d2f"; } { locale = "fy-NL"; arch = "linux-i686"; sha1 = "09d4f2786ede2aff43250d4ed8f151f73c1cb983"; }
{ locale = "fy-NL"; arch = "linux-x86_64"; sha1 = "a462db5d04e8ad7c3840912b8445041391d01973"; } { locale = "fy-NL"; arch = "linux-x86_64"; sha1 = "839bea8234ccc71f9402487f022a3fcee13da341"; }
{ locale = "ga-IE"; arch = "linux-i686"; sha1 = "2158427e0f838e958d40a1d3b6a4e50127ac00ea"; } { locale = "ga-IE"; arch = "linux-i686"; sha1 = "07635c04802c1023a9c6ec6d66c2d9ed9c210800"; }
{ locale = "ga-IE"; arch = "linux-x86_64"; sha1 = "2390c016ee8b52cf927e4f9cb74b20d65fe06de3"; } { locale = "ga-IE"; arch = "linux-x86_64"; sha1 = "ff584fe726ca1be184c453d2eec250577d7747b4"; }
{ locale = "gd"; arch = "linux-i686"; sha1 = "d7e2675b58ff68bff21fb9d0ce0643073df4e491"; } { locale = "gd"; arch = "linux-i686"; sha1 = "3cbb34e8eba1ad0db2f25b51390b6b66efbdbd6b"; }
{ locale = "gd"; arch = "linux-x86_64"; sha1 = "ba01c8483e05a4b612443c8172737d901f665666"; } { locale = "gd"; arch = "linux-x86_64"; sha1 = "78703fbf8e9c7cf4db1522baaea837450972f568"; }
{ locale = "gl"; arch = "linux-i686"; sha1 = "9e2895f43b978304e42ec714b01857f494cea265"; } { locale = "gl"; arch = "linux-i686"; sha1 = "1aab34a16224d84c958aa65f4a0e8100a96003f4"; }
{ locale = "gl"; arch = "linux-x86_64"; sha1 = "c1cf1ee118b1133f8df6314a2aa8e83be14b4d5b"; } { locale = "gl"; arch = "linux-x86_64"; sha1 = "a8beb35a764b040a1d495e8e34623a884c1911c8"; }
{ locale = "he"; arch = "linux-i686"; sha1 = "a0a872333657bccb342a086a576f273fd34a2d21"; } { locale = "he"; arch = "linux-i686"; sha1 = "73fe49520af05bb79e20c202836fce347466c957"; }
{ locale = "he"; arch = "linux-x86_64"; sha1 = "6ceb775435b2ed0a14f11c096b595361baf6282d"; } { locale = "he"; arch = "linux-x86_64"; sha1 = "1780d0a0f342fc6c64e9365a548c13770f9d02f3"; }
{ locale = "hr"; arch = "linux-i686"; sha1 = "8975da24b95de228584cd5c8ab8c6d174f0fcd60"; } { locale = "hr"; arch = "linux-i686"; sha1 = "f2c570b88fe3368fa30a53f42357a02b610acb36"; }
{ locale = "hr"; arch = "linux-x86_64"; sha1 = "23467c23408408c878afe00244bf4779b1eead03"; } { locale = "hr"; arch = "linux-x86_64"; sha1 = "b3bb417879fd039222062f2df8f64811c1472cd6"; }
{ locale = "hu"; arch = "linux-i686"; sha1 = "690b220b01a1bcd683409fca76d50a507e09241e"; } { locale = "hu"; arch = "linux-i686"; sha1 = "3369f82671a7e56ca24161ac2a1dd7cd0ae9ba85"; }
{ locale = "hu"; arch = "linux-x86_64"; sha1 = "99ff74aab54f05295199edcb0e06b0fc68bff234"; } { locale = "hu"; arch = "linux-x86_64"; sha1 = "996b00fb13c2cfd826597eb817bdf8098b523f1b"; }
{ locale = "hy-AM"; arch = "linux-i686"; sha1 = "ed490aa96fce3e61c61ea60f7353edc06fffb5ce"; } { locale = "hy-AM"; arch = "linux-i686"; sha1 = "c805817f9463d74bb73cad273d91c15d04ef1786"; }
{ locale = "hy-AM"; arch = "linux-x86_64"; sha1 = "f907190eedbcca43e830f632416a0cfd4df9c77e"; } { locale = "hy-AM"; arch = "linux-x86_64"; sha1 = "20abe54c61fa4760a507da630c1b919cfe36cf6a"; }
{ locale = "id"; arch = "linux-i686"; sha1 = "3e328a1dd6c29f38913171aae8939f636eb9c845"; } { locale = "id"; arch = "linux-i686"; sha1 = "76e1659be7d8fbfcd2a6b0bcefdc3988d59e81fa"; }
{ locale = "id"; arch = "linux-x86_64"; sha1 = "ed074968abf7fb207c747c88a21d1f5834228445"; } { locale = "id"; arch = "linux-x86_64"; sha1 = "cff15be3455dcf7ed714e8e69d34dc2ad016b60f"; }
{ locale = "is"; arch = "linux-i686"; sha1 = "2da9b0ade06b20c19a90eb192c85e17ed96487b1"; } { locale = "is"; arch = "linux-i686"; sha1 = "be8238cddd980bbd7de2a21541b260fd6689a8d7"; }
{ locale = "is"; arch = "linux-x86_64"; sha1 = "7eefd8c52f95ed4c011ec1b95b4b7b1237801cdd"; } { locale = "is"; arch = "linux-x86_64"; sha1 = "1fcabd1b1b43ac25f7f5d2eca896ba7d5ea82102"; }
{ locale = "it"; arch = "linux-i686"; sha1 = "c46a316fe393dd2353802e488a31b55699ee8d62"; } { locale = "it"; arch = "linux-i686"; sha1 = "df18fd291ffbb80323dfd823aa04692bcf6f251f"; }
{ locale = "it"; arch = "linux-x86_64"; sha1 = "3e13de5f40f71455a1bf2e562c0ea07833ed28a6"; } { locale = "it"; arch = "linux-x86_64"; sha1 = "196fae349e7b06029e9738a12fb78f24ca691598"; }
{ locale = "ja"; arch = "linux-i686"; sha1 = "1a3e904090d6786f23b88cd91afa2f34fc732c70"; } { locale = "ja"; arch = "linux-i686"; sha1 = "a888ba62981b73d96ba39892a3372b36f0ffb2b3"; }
{ locale = "ja"; arch = "linux-x86_64"; sha1 = "8b8259bb4cbd30bc0e7aff95585d3f29e9bdd566"; } { locale = "ja"; arch = "linux-x86_64"; sha1 = "00e2be4b037a37429ee708d49c82af5ffafe8ca1"; }
{ locale = "ko"; arch = "linux-i686"; sha1 = "af8db8f0a4329babec9ede706ce36e0f5dcc714e"; } { locale = "ko"; arch = "linux-i686"; sha1 = "634ea25e7246ff1c23a0d57bdf928372ca867cd6"; }
{ locale = "ko"; arch = "linux-x86_64"; sha1 = "0397e824b2f2158b0862fe2ac7d192bc8c2c0a8b"; } { locale = "ko"; arch = "linux-x86_64"; sha1 = "cfa4acb0970ab87f44e3bbfe46717d1664c63e99"; }
{ locale = "lt"; arch = "linux-i686"; sha1 = "b53dae618889ef676053154517b69c05f0051ffe"; } { locale = "lt"; arch = "linux-i686"; sha1 = "50d2764febdfb206c704cc0eb14e0679e42dffc3"; }
{ locale = "lt"; arch = "linux-x86_64"; sha1 = "cb82a5027aecb830197b764c86452a008da5f55f"; } { locale = "lt"; arch = "linux-x86_64"; sha1 = "1a975a34ddcb0637957def46bd6cc3785a9630df"; }
{ locale = "nb-NO"; arch = "linux-i686"; sha1 = "7cca3934255d4f73f35fff9ef90e0c2ea48e856b"; } { locale = "nb-NO"; arch = "linux-i686"; sha1 = "c0cf3563e2322724447d1c6730a7d4674c9bad7a"; }
{ locale = "nb-NO"; arch = "linux-x86_64"; sha1 = "4b86d7723efd32be9722012e17ca0d49560fe22a"; } { locale = "nb-NO"; arch = "linux-x86_64"; sha1 = "0c7267858bf95345dc09f9b03b56283e3198f8a4"; }
{ locale = "nl"; arch = "linux-i686"; sha1 = "dc7430d675f88aa0f7e4b78fa93572305ed97222"; } { locale = "nl"; arch = "linux-i686"; sha1 = "8c8db046ca1f21c11d00914613010836e0c5aefc"; }
{ locale = "nl"; arch = "linux-x86_64"; sha1 = "e9e9f7ed4308d496bb6490ac252f236bcd659bda"; } { locale = "nl"; arch = "linux-x86_64"; sha1 = "acd50182d4e1f255ef70bf3d7dfc9ef963535def"; }
{ locale = "nn-NO"; arch = "linux-i686"; sha1 = "5a5f40de1986de090a59205446ce5918910c2ae1"; } { locale = "nn-NO"; arch = "linux-i686"; sha1 = "ca1728b39e052bd9975d2b2ec8cffa6290098316"; }
{ locale = "nn-NO"; arch = "linux-x86_64"; sha1 = "649eea7ff3be8b2d8cb0fa9df623e8f38117132d"; } { locale = "nn-NO"; arch = "linux-x86_64"; sha1 = "05a3bed8b8c0ccea66ceef02184f4ecd95e141f8"; }
{ locale = "pa-IN"; arch = "linux-i686"; sha1 = "5255472c604dd97b44433ab76c34d4e6c1e44d17"; } { locale = "pa-IN"; arch = "linux-i686"; sha1 = "e0aa8fca5e1df6adf5b5bf41d9c8f2a195e5b598"; }
{ locale = "pa-IN"; arch = "linux-x86_64"; sha1 = "8a1e3a0ec2400a43b41856fb111e86392d29a1fe"; } { locale = "pa-IN"; arch = "linux-x86_64"; sha1 = "fd4f63140ffc56095c7b66a3ff560409a43ad018"; }
{ locale = "pl"; arch = "linux-i686"; sha1 = "b279dbd5bfe1e45ac65891b6632461c8f76ac9b0"; } { locale = "pl"; arch = "linux-i686"; sha1 = "9dc57337681fd57c5eb51240463e25543385d23d"; }
{ locale = "pl"; arch = "linux-x86_64"; sha1 = "46b827110e9bb188075fa58088b2bec1a2762609"; } { locale = "pl"; arch = "linux-x86_64"; sha1 = "2c27721db5b96a8d488ce7a74e3ebf350f71f76a"; }
{ locale = "pt-BR"; arch = "linux-i686"; sha1 = "f2bcec6668773a907368d9d04cc3fb018992637c"; } { locale = "pt-BR"; arch = "linux-i686"; sha1 = "c4d3e3f02375533bfb734155327832b4bcddbbe5"; }
{ locale = "pt-BR"; arch = "linux-x86_64"; sha1 = "f91868c8678862da540e7e7ba9fc1ae1756de0db"; } { locale = "pt-BR"; arch = "linux-x86_64"; sha1 = "81d1cfacaf3f6a2830af0fceda7ac463867afa90"; }
{ locale = "pt-PT"; arch = "linux-i686"; sha1 = "4f62468a76e73b98f85bc13c48ad0e9c62cded36"; } { locale = "pt-PT"; arch = "linux-i686"; sha1 = "f59639147c77344d7fbe49c8c3320ec382ce261c"; }
{ locale = "pt-PT"; arch = "linux-x86_64"; sha1 = "a3647ab9b35f22e6ca6b0f943321f40c4376659f"; } { locale = "pt-PT"; arch = "linux-x86_64"; sha1 = "76d04ef5ac5ce644c04621adcc08059f4d509cdd"; }
{ locale = "rm"; arch = "linux-i686"; sha1 = "fb0af4d895b50cbb20fa049c83c0f47f8cf494d4"; } { locale = "rm"; arch = "linux-i686"; sha1 = "a9d4485e9740572e1c5b8579a171c381797c3f97"; }
{ locale = "rm"; arch = "linux-x86_64"; sha1 = "49501a9a00349a2db0be269831b76021f5a4d116"; } { locale = "rm"; arch = "linux-x86_64"; sha1 = "9d699390b577ec97842e75118ee6f0579c386fe0"; }
{ locale = "ro"; arch = "linux-i686"; sha1 = "4b03ae9f43f6b1c473fe170fae4141a1aa2898d5"; } { locale = "ro"; arch = "linux-i686"; sha1 = "e03991f23cd9da6e5f14e37a4f84faee64f529b1"; }
{ locale = "ro"; arch = "linux-x86_64"; sha1 = "0e0dc3b8836696b5453cef65c343b77c42df0e7a"; } { locale = "ro"; arch = "linux-x86_64"; sha1 = "7137b302ed8c1079ed8f7efa2eaaeaeeb900cc28"; }
{ locale = "ru"; arch = "linux-i686"; sha1 = "35c31b019b2c97f534f8ca33dcfb00503c712704"; } { locale = "ru"; arch = "linux-i686"; sha1 = "7cc98ffeebf3f450c5f29b177eca3e127184c89d"; }
{ locale = "ru"; arch = "linux-x86_64"; sha1 = "814eb4985e17a88af793e1e9dd657fd9b9a32822"; } { locale = "ru"; arch = "linux-x86_64"; sha1 = "c087c970e9456d60265f7f9f6be83100b3990ef9"; }
{ locale = "si"; arch = "linux-i686"; sha1 = "f700ffb1ce581fc19f4abbaa9139d4be904bace4"; } { locale = "si"; arch = "linux-i686"; sha1 = "4197c63d5669be0cd6856d17883f5dbb9690438f"; }
{ locale = "si"; arch = "linux-x86_64"; sha1 = "bd772880dac1bee8208dbf6a3e1a244af2d884aa"; } { locale = "si"; arch = "linux-x86_64"; sha1 = "753e858aba8212d86ce9a6855dfaa2223d2ce3bd"; }
{ locale = "sk"; arch = "linux-i686"; sha1 = "6ff95241e3feab5c003a0dc9020ab089d0286f0e"; } { locale = "sk"; arch = "linux-i686"; sha1 = "64ca38cce9a99b7cf281faf0c53e5b646cb8e7f7"; }
{ locale = "sk"; arch = "linux-x86_64"; sha1 = "7dfb864346fd853d83d910d98e1e530f049372d6"; } { locale = "sk"; arch = "linux-x86_64"; sha1 = "78e10824e31d2aee74d852d7b657dd3239cfbaa2"; }
{ locale = "sl"; arch = "linux-i686"; sha1 = "f9f824a578f77c13a8e39c9c5e756de8e05255cb"; } { locale = "sl"; arch = "linux-i686"; sha1 = "6d38031ef73b82a11193fe2333ba7bfc31e0da49"; }
{ locale = "sl"; arch = "linux-x86_64"; sha1 = "32e1e3983f0ea5e972f82d3c0f4663386f8da991"; } { locale = "sl"; arch = "linux-x86_64"; sha1 = "c1ba73354f662da9f541978b5611acc41ee60356"; }
{ locale = "sq"; arch = "linux-i686"; sha1 = "5b04196a291058c7c68485a245d73d01a2adfc27"; } { locale = "sq"; arch = "linux-i686"; sha1 = "3bc7482b81a754abc01e4c1face0aa4e65aa3ea6"; }
{ locale = "sq"; arch = "linux-x86_64"; sha1 = "1860030149e4568e8b24922dbed0673bc72aa7a2"; } { locale = "sq"; arch = "linux-x86_64"; sha1 = "2463ac4d17d95c41e5bfebf31c3127e3404caa02"; }
{ locale = "sr"; arch = "linux-i686"; sha1 = "c88e8d47f4078cb06600c4b6128b3d7a62239608"; } { locale = "sr"; arch = "linux-i686"; sha1 = "28f762f06a526f93b9a3ff3bd5a52a1bd4c6b314"; }
{ locale = "sr"; arch = "linux-x86_64"; sha1 = "195c76ce3b8cbc4d8a6cfb015116bbf57ffbed7e"; } { locale = "sr"; arch = "linux-x86_64"; sha1 = "69bbca2b8cea57a76cb3791029f0d55da8383594"; }
{ locale = "sv-SE"; arch = "linux-i686"; sha1 = "d19cfcfce1118693c0dee00dc8dbdc657932e817"; } { locale = "sv-SE"; arch = "linux-i686"; sha1 = "ddbfd64533c198deeb3e56cb137af3707cc22912"; }
{ locale = "sv-SE"; arch = "linux-x86_64"; sha1 = "92a1bd6764eef68e537c45c77b893da55ba910bc"; } { locale = "sv-SE"; arch = "linux-x86_64"; sha1 = "992b3a896d619393a829b0b404f6c69bc6d11263"; }
{ locale = "ta-LK"; arch = "linux-i686"; sha1 = "4bf45f785006cf30305d11aedf00d0038995e7e2"; } { locale = "ta-LK"; arch = "linux-i686"; sha1 = "dcc7382a20d316eabd500c9d7cfaa84b9e406d43"; }
{ locale = "ta-LK"; arch = "linux-x86_64"; sha1 = "30be2773e6922e6abc4af33cca35964425059fca"; } { locale = "ta-LK"; arch = "linux-x86_64"; sha1 = "4202e74f6cb4e7bb22ae08a5e28d02cac8dd4861"; }
{ locale = "tr"; arch = "linux-i686"; sha1 = "3a7de4dbed32a7d7b0faa20246f2ffc07ab31b44"; } { locale = "tr"; arch = "linux-i686"; sha1 = "1cb9db5a71df0990758a93728d1cccc229797aaa"; }
{ locale = "tr"; arch = "linux-x86_64"; sha1 = "d64aea1cdf318d08321681f70ff22d7f80ae9e4e"; } { locale = "tr"; arch = "linux-x86_64"; sha1 = "8406829869881ed3228f44531c32106f51ef8671"; }
{ locale = "uk"; arch = "linux-i686"; sha1 = "48d3a17e0b24c55e1fe3b73b019365e38653b187"; } { locale = "uk"; arch = "linux-i686"; sha1 = "e9d259c9872336d96e854208d08d0d09aeb98f47"; }
{ locale = "uk"; arch = "linux-x86_64"; sha1 = "ba89e2038eac2e8ad34ac4296feda8c62f170143"; } { locale = "uk"; arch = "linux-x86_64"; sha1 = "3a65b5a21c2310dcb243abbf1cfdc7ec097a6018"; }
{ locale = "vi"; arch = "linux-i686"; sha1 = "06ebf22992bc3890df6fae5955bb9791b9bb1339"; } { locale = "vi"; arch = "linux-i686"; sha1 = "60070b3d0488aa80aa331cfb0ea1f37301d074d4"; }
{ locale = "vi"; arch = "linux-x86_64"; sha1 = "3e5d8b660e799eeeb37bb5b0fbf86d4d44fa31ba"; } { locale = "vi"; arch = "linux-x86_64"; sha1 = "ffe662b33db700fe795972a08320370592de365b"; }
{ locale = "zh-CN"; arch = "linux-i686"; sha1 = "5a697d19c7890f600697dea64aa5ecff8ef0e5a1"; } { locale = "zh-CN"; arch = "linux-i686"; sha1 = "9722b296495a4ac01bb80952df97a1f1a92eed27"; }
{ locale = "zh-CN"; arch = "linux-x86_64"; sha1 = "3226435da70e0aae98eaee1fb1c9a87af7167403"; } { locale = "zh-CN"; arch = "linux-x86_64"; sha1 = "014e0cd18afceeb662d7c2e9f4541e7a4ef0260a"; }
{ locale = "zh-TW"; arch = "linux-i686"; sha1 = "53a2c162f9186dca91cc35f5298285f4f9da7a55"; } { locale = "zh-TW"; arch = "linux-i686"; sha1 = "f5174db5a7852d27bdfcca4b57fdf5ffd5294680"; }
{ locale = "zh-TW"; arch = "linux-x86_64"; sha1 = "12cdf96a7cc3ea40cd9542d8a7d16827116e65d7"; } { locale = "zh-TW"; arch = "linux-x86_64"; sha1 = "0014eea1f648f9ddcf977f56f7a82044b41c136e"; }
]; ];
} }

View File

@ -8,7 +8,7 @@ stdenv.mkDerivation rec {
src = fetchurl { src = fetchurl {
url = "http://dl.frostwire.com/frostwire/${version}/frostwire-${version}.x86_64.tar.gz"; url = "http://dl.frostwire.com/frostwire/${version}/frostwire-${version}.x86_64.tar.gz";
sha256 = "73d6e3db9971becf1c5b7faf12b62fa3ac0a243ac06b8b4eada9118f56990177"; sha256 = "16rpfh235jj75vm4rx6qqw25ax3rk2p21l6lippbm0pi13lp2pdh";
}; };
inherit jre; inherit jre;

View File

@ -10,7 +10,7 @@ assert withQt -> !withGtk && qt4 != null;
with stdenv.lib; with stdenv.lib;
let let
version = "1.12.1"; version = "1.12.2";
variant = if withGtk then "gtk" else if withQt then "qt" else "cli"; variant = if withGtk then "gtk" else if withQt then "qt" else "cli";
in in
@ -19,7 +19,7 @@ stdenv.mkDerivation {
src = fetchurl { src = fetchurl {
url = "http://www.wireshark.org/download/src/wireshark-${version}.tar.bz2"; url = "http://www.wireshark.org/download/src/wireshark-${version}.tar.bz2";
sha256 = "0jsqpr4s5smadvlm881l8fkhhw384ak3apkq4wxr05gc2va6pcl2"; sha256 = "14pjkl1r0lcnhrs8994dmrnpmpr4gn3xjkd8wcn694m512s1dbih";
}; };
buildInputs = [ buildInputs = [

View File

@ -3,11 +3,11 @@
}: }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "gnumeric-1.12.12"; name = "gnumeric-1.12.18";
src = fetchurl { src = fetchurl {
url = "mirror://gnome/sources/gnumeric/1.12/${name}.tar.xz"; url = "mirror://gnome/sources/gnumeric/1.12/${name}.tar.xz";
sha256 = "096i9x6b4i6x24vc4lsxx8fg2n2pjs2jb6x3bkg3ppa2c60w1jq0"; sha256 = "402224f858cfa4e91503ab1be0491fa3322713dabe56b6eae171def8b736d9e9";
}; };
preConfigure = ''sed -i 's/\(SUBDIRS.*\) doc/\1/' Makefile.in''; # fails when installing docs preConfigure = ''sed -i 's/\(SUBDIRS.*\) doc/\1/' Makefile.in''; # fails when installing docs

Some files were not shown because too many files have changed in this diff Show More