setcap-wrapper: Merging with upstream master and resolving conflicts

This commit is contained in:
Parnell Springmeyer
2017-01-25 11:08:05 -08:00
4612 changed files with 200748 additions and 124553 deletions
@@ -94,7 +94,6 @@ let cfg = config.ec2; in
elif [ "$fsType" = ext3 ]; then
mp="/disk$diskNr"
diskNr=$((diskNr + 1))
echo "mounting $device on $mp..."
if mountFS "$device" "$mp" "" ext3; then
if [ -z "$diskForUnionfs" ]; then diskForUnionfs="$mp"; fi
fi
@@ -138,7 +137,7 @@ let cfg = config.ec2; in
# Allow root logins only using the SSH key that the user specified
# at instance creation time.
services.openssh.enable = true;
services.openssh.permitRootLogin = "without-password";
services.openssh.permitRootLogin = "prohibit-password";
# Force getting the hostname from EC2.
networking.hostName = mkDefault "";
+2 -1
View File
@@ -178,7 +178,8 @@ in
systemd.services.waagent = {
wantedBy = [ "multi-user.target" ];
after = [ "ip-up.target" "sshd.service" ];
after = [ "network-online.target" "sshd.service" ];
wants = [ "network-online.target" ];
path = [ pkgs.e2fsprogs ];
description = "Windows Azure Agent Service";
@@ -0,0 +1,3 @@
{
"16.03" = "https://nixos.blob.core.windows.net/images/nixos-image-16.03.847.8688c17-x86_64-linux.vhd";
}
@@ -24,7 +24,7 @@ with lib;
# Allow root logins only using the SSH key that the user specified
# at instance creation time, ping client connections to avoid timeouts
services.openssh.enable = true;
services.openssh.permitRootLogin = "without-password";
services.openssh.permitRootLogin = "prohibit-password";
services.openssh.extraConfig = ''
ClientAliveInterval 180
'';
@@ -20,7 +20,7 @@ in
postVM =
''
PATH=$PATH:${stdenv.lib.makeBinPath [ pkgs.gnutar pkgs.gzip ]}
PATH=$PATH:${lib.makeBinPath [ pkgs.gnutar pkgs.gzip ]}
pushd $out
${pkgs.qemu_kvm}/bin/qemu-img convert -c -O qcow2 $diskImageBase nixos.qcow2
rm $diskImageBase
@@ -103,7 +103,7 @@ in
# Allow root logins only using the SSH key that the user specified
# at instance creation time.
services.openssh.enable = true;
services.openssh.permitRootLogin = "without-password";
services.openssh.permitRootLogin = "prohibit-password";
# Force getting the hostname from Google Compute.
networking.hostName = mkDefault "";
@@ -116,8 +116,8 @@ in
wantedBy = [ "multi-user.target" "sshd.service" ];
before = [ "sshd.service" ];
wants = [ "ip-up.target" ];
after = [ "ip-up.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
path = [ pkgs.wget pkgs.iproute ];
+199 -102
View File
@@ -12,21 +12,21 @@ let
''
echo "Bringing ${name} up"
ip link set dev ${name} up
${optionalString (cfg . "localAddress" or null != null) ''
${optionalString (cfg.localAddress != null) ''
echo "Setting ip for ${name}"
ip addr add ${cfg . "localAddress"} dev ${name}
ip addr add ${cfg.localAddress} dev ${name}
''}
${optionalString (cfg . "localAddress6" or null != null) ''
${optionalString (cfg.localAddress6 != null) ''
echo "Setting ip6 for ${name}"
ip -6 addr add ${cfg . "localAddress6"} dev ${name}
ip -6 addr add ${cfg.localAddress6} dev ${name}
''}
${optionalString (cfg . "hostAddress" or null != null) ''
${optionalString (cfg.hostAddress != null) ''
echo "Setting route to host for ${name}"
ip route add ${cfg . "hostAddress"} dev ${name}
ip route add ${cfg.hostAddress} dev ${name}
''}
${optionalString (cfg . "hostAddress6" or null != null) ''
${optionalString (cfg.hostAddress6 != null) ''
echo "Setting route6 to host for ${name}"
ip -6 route add ${cfg . "hostAddress6"} dev ${name}
ip -6 route add ${cfg.hostAddress6} dev ${name}
''}
''
);
@@ -56,9 +56,7 @@ let
ip -6 route add default via $HOST_ADDRESS6
fi
${concatStringsSep "\n" (mapAttrsToList renderExtraVeth cfg . "extraVeths" or {})}
ip a
ip r
${concatStringsSep "\n" (mapAttrsToList renderExtraVeth cfg.extraVeths)}
fi
# Start the regular stage 1 script.
@@ -67,7 +65,8 @@ let
);
nspawnExtraVethArgs = (name: cfg: "--network-veth-extra=${name}");
startScript = (cfg:
startScript = cfg:
''
mkdir -p -m 0755 "$root/etc" "$root/var/lib"
mkdir -p -m 0700 "$root/var/lib/private" "$root/root" /run/containers
@@ -92,11 +91,7 @@ let
fi
fi
${if cfg . "extraVeths" or null != null then
''extraFlags+=" ${concatStringsSep " " (mapAttrsToList nspawnExtraVethArgs cfg . "extraVeths" or {})}"''
else
''# No extra veth pairs to create''
}
extraFlags+=" ${concatStringsSep " " (mapAttrsToList nspawnExtraVethArgs cfg.extraVeths)}"
for iface in $INTERFACES; do
extraFlags+=" --network-interface=$iface"
@@ -134,11 +129,16 @@ let
--setenv HOST_ADDRESS6="$HOST_ADDRESS6" \
--setenv LOCAL_ADDRESS6="$LOCAL_ADDRESS6" \
--setenv PATH="$PATH" \
${if cfg.additionalCapabilities != null && cfg.additionalCapabilities != [] then
''--capability="${concatStringsSep " " cfg.additionalCapabilities}"'' else ""
} \
${if cfg.tmpfs != null && cfg.tmpfs != [] then
''--tmpfs=${concatStringsSep " --tmpfs=" cfg.tmpfs}'' else ""
} \
${containerInit cfg} "''${SYSTEM_PATH:-/nix/var/nix/profiles/system}/init"
''
);
'';
preStartScript = (cfg:
preStartScript = cfg:
''
# Clean up existing machined registration and interfaces.
machinectl terminate "$INSTANCE" 2> /dev/null || true
@@ -151,45 +151,43 @@ let
${concatStringsSep "\n" (
mapAttrsToList (name: cfg:
''ip link del dev ${name} 2> /dev/null || true ''
) cfg . "extraVeths" or {}
) cfg.extraVeths
)}
''
);
'';
postStartScript = (cfg:
let
ipcall = (cfg: ipcmd: variable: attribute:
if cfg . attribute or null == null then
ipcall = cfg: ipcmd: variable: attribute:
if cfg.${attribute} == null then
''
if [ -n "${variable}" ]; then
${ipcmd} add ${variable} dev $ifaceHost
fi
''
else
''${ipcmd} add ${cfg . attribute} dev $ifaceHost''
);
renderExtraVeth = (name: cfg:
if cfg . "hostBridge" or null != null then
''${ipcmd} add ${cfg.${attribute}} dev $ifaceHost'';
renderExtraVeth = name: cfg:
if cfg.hostBridge != null then
''
# Add ${name} to bridge ${cfg.hostBridge}
ip link set dev ${name} master ${cfg.hostBridge} up
''
else
''
# Set IPs and routes for ${name}
${optionalString (cfg . "hostAddress" or null != null) ''
ip addr add ${cfg . "hostAddress"} dev ${name}
''}
${optionalString (cfg . "hostAddress6" or null != null) ''
ip -6 addr add ${cfg . "hostAddress6"} dev ${name}
''}
${optionalString (cfg . "localAddress" or null != null) ''
ip route add ${cfg . "localAddress"} dev ${name}
''}
${optionalString (cfg . "localAddress6" or null != null) ''
ip -6 route add ${cfg . "localAddress6"} dev ${name}
''}
''
);
# Set IPs and routes for ${name}
${optionalString (cfg.hostAddress != null) ''
ip addr add ${cfg.hostAddress} dev ${name}
''}
${optionalString (cfg.hostAddress6 != null) ''
ip -6 addr add ${cfg.hostAddress6} dev ${name}
''}
${optionalString (cfg.localAddress != null) ''
ip route add ${cfg.localAddress} dev ${name}
''}
${optionalString (cfg.localAddress6 != null) ''
ip -6 route add ${cfg.localAddress6} dev ${name}
''}
'';
in
''
if [ "$PRIVATE_NETWORK" = 1 ]; then
@@ -202,7 +200,7 @@ let
${ipcall cfg "ip route" "$LOCAL_ADDRESS" "localAddress"}
${ipcall cfg "ip -6 route" "$LOCAL_ADDRESS6" "localAddress6"}
fi
${concatStringsSep "\n" (mapAttrsToList renderExtraVeth cfg . "extraVeths" or {})}
${concatStringsSep "\n" (mapAttrsToList renderExtraVeth cfg.extraVeths)}
fi
# Get the leader PID so that we can signal it in
@@ -213,6 +211,41 @@ let
''
);
serviceDirectives = cfg: {
ExecReload = pkgs.writeScript "reload-container"
''
#! ${pkgs.stdenv.shell} -e
${pkgs.nixos-container}/bin/nixos-container run "$INSTANCE" -- \
bash --login -c "''${SYSTEM_PATH:-/nix/var/nix/profiles/system}/bin/switch-to-configuration test"
'';
SyslogIdentifier = "container %i";
EnvironmentFile = "-/etc/containers/%i.conf";
Type = "notify";
# Note that on reboot, systemd-nspawn returns 133, so this
# unit will be restarted. On poweroff, it returns 0, so the
# unit won't be restarted.
RestartForceExitStatus = "133";
SuccessExitStatus = "133";
Restart = "on-failure";
# Hack: we don't want to kill systemd-nspawn, since we call
# "machinectl poweroff" in preStop to shut down the
# container cleanly. But systemd requires sending a signal
# (at least if we want remaining processes to be killed
# after the timeout). So send an ignored signal.
KillMode = "mixed";
KillSignal = "WINCH";
DevicePolicy = "closed";
DeviceAllow = map (d: "${d.node} ${d.modifier}") cfg.allowedDevices;
};
system = config.nixpkgs.system;
bindMountOpts = { name, config, ... }: {
@@ -243,6 +276,27 @@ let
};
allowedDeviceOpts = { name, config, ... }: {
options = {
node = mkOption {
example = "/dev/net/tun";
type = types.str;
description = "Path to device node";
};
modifier = mkOption {
example = "rw";
type = types.str;
description = ''
Device node access modifier. Takes a combination
<literal>r</literal> (read), <literal>w</literal> (write), and
<literal>m</literal> (mknod). See the
<literal>systemd.resource-control(5)</literal> man page for more
information.'';
};
};
};
mkBindFlag = d:
let flagPrefix = if d.isReadOnly then " --bind-ro=" else " --bind=";
mountstr = if d.hostPath != null then "${d.hostPath}:${d.mountPoint}" else "${d.mountPoint}";
@@ -307,6 +361,18 @@ let
};
dummyConfig =
{
extraVeths = {};
additionalCapabilities = [];
allowedDevices = [];
hostAddress = null;
hostAddress6 = null;
localAddress = null;
localAddress6 = null;
tmpfs = null;
};
in
{
@@ -367,6 +433,26 @@ in
'';
};
additionalCapabilities = mkOption {
type = types.listOf types.str;
default = [];
example = [ "CAP_NET_ADMIN" "CAP_MKNOD" ];
description = ''
Grant additional capabilities to the container. See the
capabilities(7) and systemd-nspawn(1) man pages for more
information.
'';
};
enableTun = mkOption {
type = types.bool;
default = false;
description = ''
Allows the container to create and setup tunnel interfaces
by granting the <literal>NET_ADMIN</literal> capability and
enabling access to <literal>/dev/net/tun</literal>.
'';
};
privateNetwork = mkOption {
type = types.bool;
default = false;
@@ -390,10 +476,20 @@ in
'';
};
macvlans = mkOption {
type = types.listOf types.str;
default = [];
example = [ "eth1" "eth2" ];
description = ''
The list of host interfaces from which macvlans will be
created. For each interface specified, a macvlan interface
will be created and moved to the container.
'';
};
extraVeths = mkOption {
type = types.attrsOf types.optionSet;
type = with types; attrsOf (submodule { options = networkOptions; });
default = {};
options = networkOptions;
description = ''
Extra veth-pairs to be created for the container
'';
@@ -408,8 +504,7 @@ in
};
bindMounts = mkOption {
type = types.loaOf types.optionSet;
options = [ bindMountOpts ];
type = with types; loaOf (submodule bindMountOpts);
default = {};
example = { "/home" = { hostPath = "/home/alice";
isReadOnly = false; };
@@ -421,6 +516,27 @@ in
'';
};
allowedDevices = mkOption {
type = with types; listOf (submodule allowedDeviceOpts);
default = [];
example = [ { node = "/dev/net/tun"; modifier = "rw"; } ];
description = ''
A list of device nodes to which the containers has access to.
'';
};
tmpfs = mkOption {
type = types.listOf types.str;
default = [];
example = [ "/var" ];
description = ''
Mounts a set of tmpfs file systems into the container.
Multiple paths can be specified.
Valid items must conform to the --tmpfs argument
of systemd-nspawn. See systemd-nspawn(1) for details.
'';
};
} // networkOptions;
config = mkMerge
@@ -451,7 +567,7 @@ in
containers. Each container appears as a service
<literal>container-<replaceable>name</replaceable></literal>
on the host system, allowing it to be started and stopped via
<command>systemctl</command> .
<command>systemctl</command>.
'';
};
@@ -470,11 +586,11 @@ in
environment.INSTANCE = "%i";
environment.root = "/var/lib/containers/%i";
preStart = preStartScript {};
preStart = preStartScript dummyConfig;
script = startScript {};
script = startScript dummyConfig;
postStart = postStartScript {};
postStart = postStartScript dummyConfig;
preStop =
''
@@ -487,59 +603,39 @@ in
restartIfChanged = false;
serviceConfig = {
ExecReload = pkgs.writeScript "reload-container"
''
#! ${pkgs.stdenv.shell} -e
${pkgs.nixos-container}/bin/nixos-container run "$INSTANCE" -- \
bash --login -c "''${SYSTEM_PATH:-/nix/var/nix/profiles/system}/bin/switch-to-configuration test"
'';
SyslogIdentifier = "container %i";
EnvironmentFile = "-/etc/containers/%i.conf";
Type = "notify";
# Note that on reboot, systemd-nspawn returns 133, so this
# unit will be restarted. On poweroff, it returns 0, so the
# unit won't be restarted.
RestartForceExitStatus = "133";
SuccessExitStatus = "133";
Restart = "on-failure";
# Hack: we don't want to kill systemd-nspawn, since we call
# "machinectl poweroff" in preStop to shut down the
# container cleanly. But systemd requires sending a signal
# (at least if we want remaining processes to be killed
# after the timeout). So send an ignored signal.
KillMode = "mixed";
KillSignal = "WINCH";
DevicePolicy = "closed";
};
serviceConfig = serviceDirectives dummyConfig;
};
in {
systemd.services = listToAttrs (filter (x: x.value != null) (
# The generic container template used by imperative containers
[{ name = "container@"; value = unit; }]
# declarative containers
++ (mapAttrsToList (name: cfg: nameValuePair "container@${name}" (
unit // {
preStart = preStartScript cfg;
script = startScript cfg;
postStart = postStartScript cfg;
} // (
if cfg.autoStart then
{
wantedBy = [ "multi-user.target" ];
wants = [ "network.target" ];
after = [ "network.target" ];
restartTriggers = [ cfg.path ];
reloadIfChanged = true;
}
else {})
++ (mapAttrsToList (name: cfg: nameValuePair "container@${name}" (let
config = cfg // (
if cfg.enableTun then
{
allowedDevices = cfg.allowedDevices
++ [ { node = "/dev/net/tun"; modifier = "rw"; } ];
additionalCapabilities = cfg.additionalCapabilities
++ [ "CAP_NET_ADMIN" ];
}
else {});
in
unit // {
preStart = preStartScript config;
script = startScript config;
postStart = postStartScript config;
serviceConfig = serviceDirectives config;
} // (
if config.autoStart then
{
wantedBy = [ "multi-user.target" ];
wants = [ "network.target" ];
after = [ "network.target" ];
restartTriggers = [ config.path ];
reloadIfChanged = true;
}
else {})
)) config.containers)
));
@@ -569,6 +665,7 @@ in
''}
''}
INTERFACES="${toString cfg.interfaces}"
MACVLANS="${toString cfg.macvlans}"
${optionalString cfg.autoStart ''
AUTO_START=1
''}
@@ -579,10 +676,10 @@ in
# Generate /etc/hosts entries for the containers.
networking.extraHosts = concatStrings (mapAttrsToList (name: cfg: optionalString (cfg.localAddress != null)
''
${cfg.localAddress} ${name}.containers
${head (splitString "/" cfg.localAddress)} ${name}.containers
'') config.containers);
networking.dhcpcd.denyInterfaces = [ "ve-*" ];
networking.dhcpcd.denyInterfaces = [ "ve-*" "vb-*" ];
environment.systemPackages = [ pkgs.nixos-container ];
});
+70 -53
View File
@@ -28,25 +28,63 @@ in
<command>docker</command> command line tool.
'';
};
socketActivation =
listenOptions =
mkOption {
type = types.listOf types.str;
default = ["/var/run/docker.sock"];
description =
''
A list of unix and tcp docker should listen to. The format follows
ListenStream as described in systemd.socket(5).
'';
};
enableOnBoot =
mkOption {
type = types.bool;
default = true;
description =
''
This option enables docker with socket activation. I.e. docker will
start when first called by client.
When enabled dockerd is started on boot. This is required for
container, which are created with the
<literal>--restart=always</literal> flag, to work. If this option is
disabled, docker might be started on demand by socket activation.
'';
};
storageDriver =
liveRestore =
mkOption {
type = types.enum ["aufs" "btrfs" "devicemapper" "overlay" "zfs"];
default = "devicemapper";
type = types.bool;
default = true;
description =
''
This option determines which Docker storage driver to use.
Allow dockerd to be restarted without affecting running container.
This option is incompatible with docker swarm.
'';
};
storageDriver =
mkOption {
type = types.nullOr (types.enum ["aufs" "btrfs" "devicemapper" "overlay" "overlay2" "zfs"]);
default = null;
description =
''
This option determines which Docker storage driver to use. By default
it let's docker automatically choose preferred storage driver.
'';
};
logDriver =
mkOption {
type = types.enum ["none" "json-file" "syslog" "journald" "gelf" "fluentd" "awslogs" "splunk" "etwlogs" "gcplogs"];
default = "journald";
description =
''
This option determines which Docker log driver to use.
'';
};
extraOptions =
mkOption {
type = types.separatedString " ";
@@ -57,64 +95,43 @@ in
<command>docker</command> daemon.
'';
};
postStart =
mkOption {
type = types.lines;
default = ''
while ! [ -e /var/run/docker.sock ]; do
sleep 0.1
done
'';
description = ''
The postStart phase of the systemd service. You may need to
override this if you are passing in flags to docker which
don't cause the socket file to be created. This option is ignored
if socket activation is used.
'';
};
};
###### implementation
config = mkIf cfg.enable (mkMerge [
{ environment.systemPackages = [ pkgs.docker ];
config = mkIf cfg.enable (mkMerge [{
environment.systemPackages = [ pkgs.docker ];
users.extraGroups.docker.gid = config.ids.gids.docker;
systemd.packages = [ pkgs.docker ];
systemd.services.docker = {
description = "Docker Application Container Engine";
wantedBy = optional (!cfg.socketActivation) "multi-user.target";
after = [ "network.target" ] ++ (optional cfg.socketActivation "docker.socket") ;
requires = optional cfg.socketActivation "docker.socket";
wantedBy = optional cfg.enableOnBoot "multi-user.target";
serviceConfig = {
ExecStart = "${pkgs.docker}/bin/docker daemon --group=docker --storage-driver=${cfg.storageDriver} ${optionalString cfg.socketActivation "--host=fd://"} ${cfg.extraOptions}";
# I'm not sure if that limits aren't too high, but it's what
# goes in config bundled with docker itself
LimitNOFILE = 1048576;
LimitNPROC = 1048576;
ExecStart = [
""
''
${pkgs.docker}/bin/dockerd \
--group=docker \
--host=fd:// \
--log-driver=${cfg.logDriver} \
${optionalString (cfg.storageDriver != null) "--storage-driver=${cfg.storageDriver}"} \
${optionalString cfg.liveRestore "--live-restore" } \
${cfg.extraOptions}
''];
ExecReload=[
""
"${pkgs.procps}/bin/kill -s HUP $MAINPID"
];
} // proxy_env;
path = [ pkgs.kmod ] ++ (optional (cfg.storageDriver == "zfs") pkgs.zfs);
postStart = if cfg.socketActivation then "" else cfg.postStart;
# Presumably some containers are running we don't want to interrupt
restartIfChanged = false;
};
systemd.sockets.docker.socketConfig.ListenStream = cfg.listenOptions;
}
(mkIf cfg.socketActivation {
systemd.sockets.docker = {
description = "Docker Socket for the API";
wantedBy = [ "sockets.target" ];
socketConfig = {
ListenStream = "/var/run/docker.sock";
SocketMode = "0660";
SocketUser = "root";
SocketGroup = "docker";
};
};
})
]);
imports = [
(mkRemovedOptionModule ["virtualisation" "docker" "socketActivation"] "This option was removed in favor of starting docker at boot")
];
}
+50 -2
View File
@@ -1,4 +1,4 @@
{
let self = {
"14.04".ap-northeast-1.hvm-ebs = "ami-71c6f470";
"14.04".ap-northeast-1.pv-ebs = "ami-4dcbf84c";
"14.04".ap-northeast-1.pv-s3 = "ami-8fc4f68e";
@@ -134,4 +134,52 @@
"16.03".us-west-2.hvm-s3 = "ami-925c9ff2";
"16.03".us-west-2.pv-ebs = "ami-5e61a23e";
"16.03".us-west-2.pv-s3 = "ami-734c8f13";
}
# 16.09.666.3738950
"16.09".ap-northeast-1.hvm-ebs = "ami-35578954";
"16.09".ap-northeast-1.hvm-s3 = "ami-d6528cb7";
"16.09".ap-northeast-1.pv-ebs = "ami-07548a66";
"16.09".ap-northeast-1.pv-s3 = "ami-f1548a90";
"16.09".ap-northeast-2.hvm-ebs = "ami-d48753ba";
"16.09".ap-northeast-2.hvm-s3 = "ami-4c865222";
"16.09".ap-northeast-2.pv-ebs = "ami-ca8551a4";
"16.09".ap-northeast-2.pv-s3 = "ami-9c8551f2";
"16.09".ap-south-1.hvm-ebs = "ami-922450fd";
"16.09".ap-south-1.hvm-s3 = "ami-6d3a4e02";
"16.09".ap-south-1.pv-ebs = "ami-4d394d22";
"16.09".ap-south-1.pv-s3 = "ami-17384c78";
"16.09".ap-southeast-1.hvm-ebs = "ami-f824809b";
"16.09".ap-southeast-1.hvm-s3 = "ami-f924809a";
"16.09".ap-southeast-1.pv-ebs = "ami-af2480cc";
"16.09".ap-southeast-1.pv-s3 = "ami-5826823b";
"16.09".ap-southeast-2.hvm-ebs = "ami-40fecd23";
"16.09".ap-southeast-2.hvm-s3 = "ami-48fecd2b";
"16.09".ap-southeast-2.pv-ebs = "ami-dffecdbc";
"16.09".ap-southeast-2.pv-s3 = "ami-e0fccf83";
"16.09".eu-central-1.hvm-ebs = "ami-1d8b7472";
"16.09".eu-central-1.hvm-s3 = "ami-1c8b7473";
"16.09".eu-central-1.pv-ebs = "ami-8c8d72e3";
"16.09".eu-central-1.pv-s3 = "ami-3488775b";
"16.09".eu-west-1.hvm-ebs = "ami-15662766";
"16.09".eu-west-1.hvm-s3 = "ami-476b2a34";
"16.09".eu-west-1.pv-ebs = "ami-876928f4";
"16.09".eu-west-1.pv-s3 = "ami-70682903";
"16.09".sa-east-1.hvm-ebs = "ami-27bc2e4b";
"16.09".sa-east-1.hvm-s3 = "ami-e4b92b88";
"16.09".sa-east-1.pv-ebs = "ami-4dbe2c21";
"16.09".sa-east-1.pv-s3 = "ami-77fc6e1b";
"16.09".us-east-1.hvm-ebs = "ami-93347684";
"16.09".us-east-1.hvm-s3 = "ami-5e347649";
"16.09".us-east-1.pv-ebs = "ami-b0387aa7";
"16.09".us-east-1.pv-s3 = "ami-51357746";
"16.09".us-west-1.hvm-ebs = "ami-06337a66";
"16.09".us-west-1.hvm-s3 = "ami-76307916";
"16.09".us-west-1.pv-ebs = "ami-fd327b9d";
"16.09".us-west-1.pv-s3 = "ami-cc347dac";
"16.09".us-west-2.hvm-ebs = "ami-49fe2729";
"16.09".us-west-2.hvm-s3 = "ami-93fc25f3";
"16.09".us-west-2.pv-ebs = "ami-14fe2774";
"16.09".us-west-2.pv-s3 = "ami-74f12814";
latest = self."16.09";
}; in self
@@ -111,7 +111,7 @@ in
# Allow root logins only using the SSH key that the user specified
# at instance creation time.
services.openssh.enable = true;
services.openssh.permitRootLogin = "without-password";
services.openssh.permitRootLogin = "prohibit-password";
services.openssh.passwordAuthentication = mkDefault false;
# Force getting the hostname from Google Compute.
@@ -125,7 +125,7 @@ in
169.254.169.254 metadata.google.internal metadata
'';
services.ntp.servers = [ "metadata.google.internal" ];
networking.timeServers = [ "metadata.google.internal" ];
networking.usePredictableInterfaceNames = false;
@@ -134,8 +134,8 @@ in
wantedBy = [ "sshd.service" ];
before = [ "sshd.service" ];
after = [ "network-online.target" "ip-up.target" ];
wants = [ "network-online.target" "ip-up.target" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
script = let wget = "${pkgs.wget}/bin/wget --retry-connrefused -t 15 --waitretry=10 --header='Metadata-Flavor: Google'";
mktemp = "mktemp --tmpdir=/run"; in
@@ -24,7 +24,7 @@ with lib;
copy_bin_and_libs ${pkgs.gnused}/bin/sed
copy_bin_and_libs ${pkgs.utillinux}/sbin/sfdisk
copy_bin_and_libs ${pkgs.utillinux}/sbin/lsblk
cp -v ${pkgs.cloud-utils}/bin/growpart $out/bin/growpart
cp -v ${pkgs.cloud-utils}/bin/.growpart-wrapped $out/bin/growpart
ln -s sed $out/bin/gnused
'';
+1 -1
View File
@@ -123,7 +123,7 @@ in {
# config file. But this path can unfortunately be garbage collected
# while still being used by the virtual machine. So update the
# emulator path on each startup to something valid (re-scan $PATH).
for file in /etc/libvirt/qemu/*.xml /etc/libvirt/lxc/*.xml; do
for file in /var/lib/libvirt/qemu/*.xml /var/lib/libvirt/lxc/*.xml; do
test -f "$file" || continue
# get (old) emulator path from config file
emulator=$(grep "^[[:space:]]*<emulator>" "$file" | sed 's,^[[:space:]]*<emulator>\(.*\)</emulator>.*,\1,')
+2 -4
View File
@@ -62,19 +62,17 @@ in
</citerefentry>.
'';
};
};
###### implementation
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.lxc ];
environment.etc."lxc/lxc.conf".text = cfg.systemConfig;
environment.etc."lxc/lxc-usernet".text = cfg.usernetConfig;
environment.etc."lxc/default.conf".text = cfg.defaultConfig;
security.apparmor.packages = [ pkgs.lxc ];
security.apparmor.profiles = [ "${pkgs.lxc}/etc/apparmor.d/lxc-containers" ];
};
}
+49
View File
@@ -0,0 +1,49 @@
# LXC Configuration
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.virtualisation.lxc.lxcfs;
in {
meta.maintainers = [ maintainers.mic92 ];
###### interface
options.virtualisation.lxc.lxcfs = {
enable =
mkOption {
type = types.bool;
default = false;
description = ''
This enables LXCFS, a FUSE filesystem for LXC.
To use lxcfs in include the following configuration in your
container configuration:
<code>
virtualisation.lxc.defaultConfig = "lxc.include = ''${pkgs.lxcfs}/share/lxc/config/common.conf.d/00-lxcfs.conf";
</code>
'';
};
};
###### implementation
config = mkIf cfg.enable {
services.cgmanager.enable = true;
systemd.services.lxcfs = {
description = "FUSE filesystem for LXC";
wantedBy = [ "multi-user.target" ];
requires = [ "cgmanager.service" ];
after = [ "cgmanager.service" ];
before = [ "lxc.service" ];
restartIfChanged = false;
serviceConfig = {
ExecStartPre="${pkgs.coreutils}/bin/mkdir -p /var/lib/lxcfs";
ExecStart="${pkgs.lxcfs}/bin/lxcfs /var/lib/lxcfs";
ExecStopPost="-${pkgs.fuse}/bin/fusermount -u /var/lib/lxcfs";
KillMode="process";
Restart="on-failure";
};
};
};
}
+1 -1
View File
@@ -31,7 +31,7 @@ with lib;
# Allow root logins
services.openssh.enable = true;
services.openssh.permitRootLogin = "without-password";
services.openssh.permitRootLogin = "prohibit-password";
# Put /tmp and /var on /ephemeral0, which has a lot more space.
# Unfortunately we can't do this with the `fileSystems' option
@@ -0,0 +1,84 @@
{ lib }:
with lib;
rec {
# A shell script string helper to get the value of a secret at
# runtime.
getSecret = secretOption:
if secretOption.storage == "fromFile"
then ''$(cat ${secretOption.value})''
else ''${secretOption.value}'';
# A shell script string help to replace at runtime in a file the
# pattern of a secret by its value.
replaceSecret = secretOption: filename: ''
sed -i "s/${secretOption.pattern}/${getSecret secretOption}/g" ${filename}
'';
# This generates an option that can be used to declare secrets which
# can be stored in the nix store, or not. A pattern is written in
# the nix store to represent the secret. The pattern can
# then be overwritten with the value of the secret at runtime.
mkSecretOption = {name, description ? ""}:
mkOption {
description = description;
type = types.submodule ({
options = {
pattern = mkOption {
type = types.str;
default = "##${name}##";
description = "The pattern that represent the secret.";
};
storage = mkOption {
type = types.enum [ "fromNixStore" "fromFile" ];
description = ''
Choose the way the password is provisionned. If
fromNixStore is used, the value is the password and it is
written in the nix store. If fromFile is used, the value
is a path from where the password will be read at
runtime. This is generally used with <link
xlink:href="https://nixos.org/nixops/manual/#opt-deployment.keys">
deployment keys</link> of Nixops.
'';};
value = mkOption {
type = types.str;
description = ''
If the storage is fromNixStore, the value is the password itself,
otherwise it is a path to the file that contains the password.
'';
};
};});
};
databaseOption = name: {
host = mkOption {
type = types.str;
default = "localhost";
description = ''
Host of the database.
'';
};
name = mkOption {
type = types.str;
default = name;
description = ''
Name of the existing database.
'';
};
user = mkOption {
type = types.str;
default = name;
description = ''
The database user. The user must exist and has access to
the specified database.
'';
};
password = mkSecretOption {
name = name + "MysqlPassword";
description = "The database user's password";};
};
}
@@ -0,0 +1,245 @@
{ config, lib, pkgs, ... }:
with lib; with import ./common.nix {inherit lib;};
let
cfg = config.virtualisation.openstack.glance;
commonConf = ''
[database]
connection = "mysql://${cfg.database.user}:${cfg.database.password.pattern}@${cfg.database.host}/${cfg.database.name}"
notification_driver = noop
[keystone_authtoken]
auth_url = ${cfg.authUrl}
auth_plugin = password
project_name = service
project_domain_id = default
user_domain_id = default
username = ${cfg.serviceUsername}
password = ${cfg.servicePassword.pattern}
[glance_store]
default_store = file
filesystem_store_datadir = /var/lib/glance/images/
'';
glanceApiConfTpl = pkgs.writeText "glance-api.conf" ''
${commonConf}
[paste_deploy]
flavor = keystone
config_file = ${cfg.package}/etc/glance-api-paste.ini
'';
glanceRegistryConfTpl = pkgs.writeText "glance-registry.conf" ''
${commonConf}
[paste_deploy]
config_file = ${cfg.package}/etc/glance-registry-paste.ini
'';
glanceApiConf = "/var/lib/glance/glance-api.conf";
glanceRegistryConf = "/var/lib/glance/glance-registry.conf";
in {
options.virtualisation.openstack.glance = {
package = mkOption {
type = types.package;
default = pkgs.glance;
example = literalExample "pkgs.glance";
description = ''
Glance package to use.
'';
};
enable = mkOption {
default = false;
type = types.bool;
description = ''
This option enables Glance as a single-machine
installation. That is, all of Glance's components are
enabled on this machine. This is useful for evaluating and
experimenting with Glance. Note we are currently not
providing any configurations for a multi-node setup.
'';
};
authUrl = mkOption {
type = types.str;
default = http://localhost:5000;
description = ''
Complete public Identity (Keystone) API endpoint. Note this is
unversionned.
'';
};
serviceUsername = mkOption {
type = types.str;
default = "glance";
description = ''
The Glance service username. This user is created if bootstrap
is enable, otherwise it has to be manually created before
starting this service.
'';
};
servicePassword = mkSecretOption {
name = "glanceAdminPassword";
description = ''
The Glance service user's password.
'';
};
database = databaseOption "glance";
bootstrap = {
enable = mkOption {
default = false;
type = types.bool;
description = ''
Bootstrap the Glance service by creating the service tenant,
an admin account and a public endpoint. This option provides
a ready-to-use glance service. This is only done at the
first Glance execution by the systemd post start section.
The keystone admin account is used to create required
Keystone resource for the Glance service.
<note><para> This option is a helper for setting up
development or testing environments.</para></note>
'';
};
endpointPublic = mkOption {
type = types.str;
default = "http://localhost:9292";
description = ''
The public image endpoint. The link <link
xlink:href="http://docs.openstack.org/liberty/install-guide-rdo/keystone-services.html">
create endpoint</link> provides more informations
about that.
'';
};
keystoneAdminUsername = mkOption {
type = types.str;
default = "admin";
description = ''
The keystone admin user name used to create the Glance account.
'';
};
keystoneAdminPassword = mkSecretOption {
name = "keystoneAdminPassword";
description = ''
The keystone admin user's password.
'';
};
keystoneAdminTenant = mkOption {
type = types.str;
default = "admin";
description = ''
The keystone admin tenant used to create the Glance account.
'';
};
keystoneAuthUrl = mkOption {
type = types.str;
default = "http://localhost:5000/v2.0";
description = ''
The keystone auth url used to create the Glance account.
'';
};
};
};
config = mkIf cfg.enable {
users.extraUsers = [{
name = "glance";
group = "glance";
uid = config.ids.gids.glance;
}];
users.extraGroups = [{
name = "glance";
gid = config.ids.gids.glance;
}];
systemd.services.glance-registry = {
description = "OpenStack Glance Registry Daemon";
after = [ "network.target"];
path = [ pkgs.curl pkgs.pythonPackages.keystoneclient pkgs.gawk ];
wantedBy = [ "multi-user.target" ];
preStart = ''
mkdir -m 775 -p /var/lib/glance/{images,scrubber,image_cache}
chown glance:glance /var/lib/glance/{images,scrubber,image_cache}
# Secret file managment
cp ${glanceRegistryConfTpl} ${glanceRegistryConf};
chown glance:glance ${glanceRegistryConf};
chmod 640 ${glanceRegistryConf}
${replaceSecret cfg.database.password glanceRegistryConf}
${replaceSecret cfg.servicePassword glanceRegistryConf}
cp ${glanceApiConfTpl} ${glanceApiConf};
chown glance:glance ${glanceApiConf};
chmod 640 ${glanceApiConf}
${replaceSecret cfg.database.password glanceApiConf}
${replaceSecret cfg.servicePassword glanceApiConf}
# Initialise the database
${cfg.package}/bin/glance-manage --config-file=${glanceApiConf} --config-file=${glanceRegistryConf} db_sync
'';
postStart = ''
set -eu
export OS_AUTH_URL=${cfg.bootstrap.keystoneAuthUrl}
export OS_USERNAME=${cfg.bootstrap.keystoneAdminUsername}
export OS_PASSWORD=${getSecret cfg.bootstrap.keystoneAdminPassword}
export OS_TENANT_NAME=${cfg.bootstrap.keystoneAdminTenant}
# Wait until the keystone is available for use
count=0
while ! keystone user-get ${cfg.bootstrap.keystoneAdminUsername} > /dev/null
do
if [ $count -eq 30 ]
then
echo "Tried 30 times, giving up..."
exit 1
fi
echo "Keystone not yet started. Waiting for 1 second..."
count=$((count++))
sleep 1
done
# If the service glance doesn't exist, we consider glance is
# not initialized
if ! keystone service-get glance
then
keystone service-create --type image --name glance
ID=$(keystone service-get glance | awk '/ id / { print $4 }')
keystone endpoint-create --region RegionOne --service $ID --internalurl http://localhost:9292 --adminurl http://localhost:9292 --publicurl ${cfg.bootstrap.endpointPublic}
keystone user-create --name ${cfg.serviceUsername} --tenant service --pass ${getSecret cfg.servicePassword}
keystone user-role-add --tenant service --user ${cfg.serviceUsername} --role admin
fi
'';
serviceConfig = {
PermissionsStartOnly = true; # preStart must be run as root
TimeoutStartSec = "600"; # 10min for initial db migrations
User = "glance";
Group = "glance";
ExecStart = "${cfg.package}/bin/glance-registry --config-file=${glanceRegistryConf}";
};
};
systemd.services.glance-api = {
description = "OpenStack Glance API Daemon";
after = [ "glance-registry.service" "network.target"];
requires = [ "glance-registry.service" "network.target"];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
PermissionsStartOnly = true; # preStart must be run as root
User = "glance";
Group = "glance";
ExecStart = "${cfg.package}/bin/glance-api --config-file=${glanceApiConf}";
};
};
};
}
@@ -0,0 +1,220 @@
{ config, lib, pkgs, ... }:
with lib; with import ./common.nix {inherit lib;};
let
cfg = config.virtualisation.openstack.keystone;
keystoneConfTpl = pkgs.writeText "keystone.conf" ''
[DEFAULT]
admin_token = ${cfg.adminToken.pattern}
policy_file=${cfg.package}/etc/policy.json
[database]
connection = "mysql://${cfg.database.user}:${cfg.database.password.pattern}@${cfg.database.host}/${cfg.database.name}"
[paste_deploy]
config_file = ${cfg.package}/etc/keystone-paste.ini
${cfg.extraConfig}
'';
keystoneConf = "/var/lib/keystone/keystone.conf";
in {
options.virtualisation.openstack.keystone = {
package = mkOption {
type = types.package;
example = literalExample "pkgs.keystone";
description = ''
Keystone package to use.
'';
};
enable = mkOption {
default = false;
type = types.bool;
description = ''
Enable Keystone, the OpenStack Identity Service
'';
};
extraConfig = mkOption {
default = "";
type = types.lines;
description = ''
Additional text appended to <filename>keystone.conf</filename>,
the main Keystone configuration file.
'';
};
adminToken = mkSecretOption {
name = "adminToken";
description = ''
This is the admin token used to boostrap keystone,
ie. to provision first resources.
'';
};
bootstrap = {
enable = mkOption {
default = false;
type = types.bool;
description = ''
Bootstrap the Keystone service by creating the service
tenant, an admin account and a public endpoint. This options
provides a ready-to-use admin account. This is only done at
the first Keystone execution by the systemd post start.
Note this option is a helper for setting up development or
testing environments.
'';
};
endpointPublic = mkOption {
type = types.str;
default = "http://localhost:5000/v2.0";
description = ''
The public identity endpoint. The link <link
xlink:href="http://docs.openstack.org/liberty/install-guide-rdo/keystone-services.html">
create keystone endpoint</link> provides more informations
about that.
'';
};
adminUsername = mkOption {
type = types.str;
default = "admin";
description = ''
A keystone admin username.
'';
};
adminPassword = mkSecretOption {
name = "keystoneAdminPassword";
description = ''
The keystone admin user's password.
'';
};
adminTenant = mkOption {
type = types.str;
default = "admin";
description = ''
A keystone admin tenant name.
'';
};
};
database = {
host = mkOption {
type = types.str;
default = "localhost";
description = ''
Host of the database.
'';
};
name = mkOption {
type = types.str;
default = "keystone";
description = ''
Name of the existing database.
'';
};
user = mkOption {
type = types.str;
default = "keystone";
description = ''
The database user. The user must exist and has access to
the specified database.
'';
};
password = mkSecretOption {
name = "mysqlPassword";
description = "The database user's password";};
};
};
config = mkIf cfg.enable {
# Note: when changing the default, make it conditional on
# system.stateVersion to maintain compatibility with existing
# systems!
virtualisation.openstack.keystone.package = mkDefault pkgs.keystone;
users.extraUsers = [{
name = "keystone";
group = "keystone";
uid = config.ids.uids.keystone;
}];
users.extraGroups = [{
name = "keystone";
gid = config.ids.gids.keystone;
}];
systemd.services.keystone-all = {
description = "OpenStack Keystone Daemon";
after = [ "network.target"];
path = [ cfg.package pkgs.mysql pkgs.curl pkgs.pythonPackages.keystoneclient pkgs.gawk ];
wantedBy = [ "multi-user.target" ];
preStart = ''
mkdir -m 755 -p /var/lib/keystone
cp ${keystoneConfTpl} ${keystoneConf};
chown keystone:keystone ${keystoneConf};
chmod 640 ${keystoneConf}
${replaceSecret cfg.database.password keystoneConf}
${replaceSecret cfg.adminToken keystoneConf}
# Initialise the database
${cfg.package}/bin/keystone-manage --config-file=${keystoneConf} db_sync
# Set up the keystone's PKI infrastructure
${cfg.package}/bin/keystone-manage --config-file=${keystoneConf} pki_setup --keystone-user keystone --keystone-group keystone
'';
postStart = optionalString cfg.bootstrap.enable ''
set -eu
# Wait until the keystone is available for use
count=0
while ! curl --fail -s http://localhost:35357/v2.0 > /dev/null
do
if [ $count -eq 30 ]
then
echo "Tried 30 times, giving up..."
exit 1
fi
echo "Keystone not yet started. Waiting for 1 second..."
count=$((count++))
sleep 1
done
# We use the service token to create a first admin user
export OS_SERVICE_ENDPOINT=http://localhost:35357/v2.0
export OS_SERVICE_TOKEN=${getSecret cfg.adminToken}
# If the tenant service doesn't exist, we consider
# keystone is not initialized
if ! keystone tenant-get service
then
keystone tenant-create --name service
keystone tenant-create --name ${cfg.bootstrap.adminTenant}
keystone user-create --name ${cfg.bootstrap.adminUsername} --tenant ${cfg.bootstrap.adminTenant} --pass ${getSecret cfg.bootstrap.adminPassword}
keystone role-create --name admin
keystone role-create --name Member
keystone user-role-add --tenant ${cfg.bootstrap.adminTenant} --user ${cfg.bootstrap.adminUsername} --role admin
keystone service-create --type identity --name keystone
ID=$(keystone service-get keystone | awk '/ id / { print $4 }')
keystone endpoint-create --region RegionOne --service $ID --publicurl ${cfg.bootstrap.endpointPublic} --adminurl http://localhost:35357/v2.0 --internalurl http://localhost:5000/v2.0
fi
'';
serviceConfig = {
PermissionsStartOnly = true; # preStart must be run as root
TimeoutStartSec = "600"; # 10min for initial db migrations
User = "keystone";
Group = "keystone";
ExecStart = "${cfg.package}/bin/keystone-all --config-file=${keystoneConf}";
};
};
};
}
@@ -57,7 +57,7 @@ in
boot.kernelModules = [ "prl_tg" "prl_eth" "prl_fs" "prl_fs_freeze" "acpi_memhotplug" ];
services.ntp.enable = false;
services.timesyncd.enable = false;
systemd.services.prltoolsd = {
description = "Parallels Tools' service";
+21 -17
View File
@@ -13,6 +13,8 @@ with lib;
let
qemu = config.system.build.qemu or pkgs.qemu_test;
vmName =
if config.networking.hostName == ""
then "noname"
@@ -32,7 +34,7 @@ let
NIX_DISK_IMAGE=$(readlink -f ''${NIX_DISK_IMAGE:-${config.virtualisation.diskImage}})
if ! test -e "$NIX_DISK_IMAGE"; then
${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 "$NIX_DISK_IMAGE" \
${qemu}/bin/qemu-img create -f qcow2 "$NIX_DISK_IMAGE" \
${toString config.virtualisation.diskSize}M || exit 1
fi
@@ -47,7 +49,7 @@ let
${if cfg.useBootLoader then ''
# Create a writable copy/snapshot of the boot disk.
# A writable boot disk can be booted from automatically.
${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 -b ${bootDisk}/disk.img $TMPDIR/disk.img || exit 1
${qemu}/bin/qemu-img create -f qcow2 -b ${bootDisk}/disk.img $TMPDIR/disk.img || exit 1
${if cfg.useEFIBoot then ''
# VM needs a writable flash BIOS.
@@ -63,14 +65,14 @@ let
extraDisks=""
${flip concatMapStrings cfg.emptyDiskImages (size: ''
if ! test -e "empty$idx.qcow2"; then
${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 "empty$idx.qcow2" "${toString size}M"
${qemu}/bin/qemu-img create -f qcow2 "empty$idx.qcow2" "${toString size}M"
fi
extraDisks="$extraDisks -drive index=$idx,file=$(pwd)/empty$idx.qcow2,if=${cfg.qemu.diskInterface},werror=report"
idx=$((idx + 1))
'')}
# Start QEMU.
exec ${pkgs.qemu_kvm}/bin/qemu-kvm \
exec ${qemu}/bin/qemu-kvm \
-name ${vmName} \
-m ${toString config.virtualisation.memorySize} \
${optionalString (pkgs.stdenv.system == "x86_64-linux") "-cpu kvm64"} \
@@ -121,7 +123,7 @@ let
mkdir $out
diskImage=$out/disk.img
bootFlash=$out/bios.bin
${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 $diskImage "40M"
${qemu}/bin/qemu-img create -f qcow2 $diskImage "40M"
${if cfg.useEFIBoot then ''
cp ${pkgs.OVMF-CSM}/FV/OVMF.fd $bootFlash
chmod 0644 $bootFlash
@@ -272,11 +274,11 @@ in
virtualisation.writableStore =
mkOption {
default = false;
default = true; # FIXME
description =
''
If enabled, the Nix store in the VM is made writable by
layering a unionfs-fuse/tmpfs filesystem on top of the host's Nix
layering an overlay filesystem on top of the host's Nix
store.
'';
};
@@ -393,6 +395,13 @@ in
chmod 1777 $targetRoot/tmp
mkdir -p $targetRoot/boot
${optionalString cfg.writableStore ''
echo "mounting overlay filesystem on /nix/store..."
mkdir -p 0755 $targetRoot/nix/.rw-store/store $targetRoot/nix/.rw-store/work $targetRoot/nix/store
mount -t overlay overlay $targetRoot/nix/store \
-o lowerdir=$targetRoot/nix/.ro-store,upperdir=$targetRoot/nix/.rw-store/store,workdir=$targetRoot/nix/.rw-store/work || fail
''}
'';
# After booting, register the closure of the paths in
@@ -410,7 +419,8 @@ in
'';
boot.initrd.availableKernelModules =
optional (cfg.qemu.diskInterface == "scsi") "sym53c8xx";
optional cfg.writableStore "overlay"
++ optional (cfg.qemu.diskInterface == "scsi") "sym53c8xx";
virtualisation.bootDevice =
mkDefault (if cfg.qemu.diskInterface == "scsi" then "/dev/sda" else "/dev/vda");
@@ -430,13 +440,13 @@ in
${if cfg.writableStore then "/nix/.ro-store" else "/nix/store"} =
{ device = "store";
fsType = "9p";
options = [ "trans=virtio" "version=9p2000.L" "cache=loose" ];
options = [ "trans=virtio" "version=9p2000.L" "veryloose" ];
neededForBoot = true;
};
"/tmp/xchg" =
{ device = "xchg";
fsType = "9p";
options = [ "trans=virtio" "version=9p2000.L" "cache=loose" ];
options = [ "trans=virtio" "version=9p2000.L" "veryloose" ];
neededForBoot = true;
};
"/tmp/shared" =
@@ -445,12 +455,6 @@ in
options = [ "trans=virtio" "version=9p2000.L" ];
neededForBoot = true;
};
} // optionalAttrs cfg.writableStore
{ "/nix/store" =
{ fsType = "unionfs-fuse";
device = "unionfs";
options = [ "allow_other" "cow" "nonempty" "chroot=/mnt-root" "max_files=32768" "hide_meta_files" "dirs=/nix/.rw-store=rw:/nix/.ro-store=ro" ];
};
} // optionalAttrs (cfg.writableStore && cfg.writableStoreUseTmpfs)
{ "/nix/.rw-store" =
{ fsType = "tmpfs";
@@ -470,7 +474,7 @@ in
boot.initrd.luks.devices = mkVMOverride {};
# Don't run ntpd in the guest. It should get the correct time from KVM.
services.ntp.enable = false;
services.timesyncd.enable = false;
system.build.vm = pkgs.runCommand "nixos-vm" { preferLocalBuild = true; }
''
@@ -4,10 +4,15 @@ with lib;
let
cfg = config.virtualisation.virtualbox.host;
virtualbox = config.boot.kernelPackages.virtualbox.override {
virtualbox = pkgs.virtualbox.override {
inherit (cfg) enableHardening headless;
};
kernelModules = config.boot.kernelPackages.virtualbox.override {
inherit virtualbox;
};
in
{
@@ -60,7 +65,7 @@ in
config = mkIf cfg.enable (mkMerge [{
boot.kernelModules = [ "vboxdrv" "vboxnetadp" "vboxnetflt" ];
boot.extraModulePackages = [ virtualbox ];
boot.extraModulePackages = [ kernelModules ];
environment.systemPackages = [ virtualbox ];
security.permissionsWrappers.setuid = let
@@ -34,7 +34,7 @@ in {
postVM =
''
export HOME=$PWD
export PATH=${pkgs.linuxPackages.virtualbox}/bin:$PATH
export PATH=${pkgs.virtualbox}/bin:$PATH
echo "creating VirtualBox pass-through disk wrapper (no copying invovled)..."
VBoxManage internalcommands createrawvmdk -filename disk.vmdk -rawdisk $diskImage
@@ -5,6 +5,7 @@ with lib;
let
cfg = config.services.vmwareGuest;
open-vm-tools = pkgs.open-vm-tools;
xf86inputvmmouse = pkgs.xorg.xf86inputvmmouse;
in
{
options = {
@@ -29,18 +30,17 @@ in
services.xserver = {
videoDrivers = mkOverride 50 [ "vmware" ];
modules = [ xf86inputvmmouse ];
config = ''
Section "InputDevice"
Section "InputClass"
Identifier "VMMouse"
MatchDevicePath "/dev/input/event*"
MatchProduct "ImPS/2 Generic Wheel Mouse"
Driver "vmmouse"
EndSection
'';
serverLayoutSection = ''
InputDevice "VMMouse"
'';
displayManager.sessionCommands = ''
${open-vm-tools}/bin/vmware-user-suid-wrapper
'';
+9 -9
View File
@@ -324,18 +324,18 @@ in
domain-needed
dhcp-hostsfile=/var/run/xen/dnsmasq.etherfile
dhcp-authoritative
dhcp-range=$XEN_BRIDGE_IP_RANGE_START,$XEN_BRIDGE_IP_RANGE_END,$XEN_BRIDGE_NETWORK_ADDRESS
dhcp-range=$XEN_BRIDGE_IP_RANGE_START,$XEN_BRIDGE_IP_RANGE_END
dhcp-no-override
no-ping
dhcp-leasefile=/var/run/xen/dnsmasq.leasefile
EOF
# DHCP
${pkgs.iptables}/bin/iptables -I INPUT -i ${cfg.bridge.name} -p tcp -s $XEN_BRIDGE_NETWORK_ADDRESS/${toString cfg.bridge.prefixLength} --sport 68 --dport 67 -j ACCEPT
${pkgs.iptables}/bin/iptables -I INPUT -i ${cfg.bridge.name} -p udp -s $XEN_BRIDGE_NETWORK_ADDRESS/${toString cfg.bridge.prefixLength} --sport 68 --dport 67 -j ACCEPT
${pkgs.iptables}/bin/iptables -w -I INPUT -i ${cfg.bridge.name} -p tcp -s $XEN_BRIDGE_NETWORK_ADDRESS/${toString cfg.bridge.prefixLength} --sport 68 --dport 67 -j ACCEPT
${pkgs.iptables}/bin/iptables -w -I INPUT -i ${cfg.bridge.name} -p udp -s $XEN_BRIDGE_NETWORK_ADDRESS/${toString cfg.bridge.prefixLength} --sport 68 --dport 67 -j ACCEPT
# DNS
${pkgs.iptables}/bin/iptables -I INPUT -i ${cfg.bridge.name} -p tcp -d ${cfg.bridge.address} --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
${pkgs.iptables}/bin/iptables -I INPUT -i ${cfg.bridge.name} -p udp -d ${cfg.bridge.address} --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
${pkgs.iptables}/bin/iptables -w -I INPUT -i ${cfg.bridge.name} -p tcp -d ${cfg.bridge.address} --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
${pkgs.iptables}/bin/iptables -w -I INPUT -i ${cfg.bridge.name} -p udp -d ${cfg.bridge.address} --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
${pkgs.bridge-utils}/bin/brctl addbr ${cfg.bridge.name}
${pkgs.inetutils}/bin/ifconfig ${cfg.bridge.name} ${cfg.bridge.address}
@@ -347,11 +347,11 @@ in
${pkgs.bridge-utils}/bin/brctl delbr ${cfg.bridge.name}
# DNS
${pkgs.iptables}/bin/iptables -D INPUT -i ${cfg.bridge.name} -p udp -d ${cfg.bridge.address} --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
${pkgs.iptables}/bin/iptables -D INPUT -i ${cfg.bridge.name} -p tcp -d ${cfg.bridge.address} --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
${pkgs.iptables}/bin/iptables -w -D INPUT -i ${cfg.bridge.name} -p udp -d ${cfg.bridge.address} --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
${pkgs.iptables}/bin/iptables -w -D INPUT -i ${cfg.bridge.name} -p tcp -d ${cfg.bridge.address} --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
# DHCP
${pkgs.iptables}/bin/iptables -D INPUT -i ${cfg.bridge.name} -p udp --sport 68 --dport 67 -j ACCEPT
${pkgs.iptables}/bin/iptables -D INPUT -i ${cfg.bridge.name} -p tcp --sport 68 --dport 67 -j ACCEPT
${pkgs.iptables}/bin/iptables -w -D INPUT -i ${cfg.bridge.name} -p udp --sport 68 --dport 67 -j ACCEPT
${pkgs.iptables}/bin/iptables -w -D INPUT -i ${cfg.bridge.name} -p tcp --sport 68 --dport 67 -j ACCEPT
'';
};
+1 -1
View File
@@ -18,5 +18,5 @@
services.syslogd.tty = "hvc0";
# Don't run ntpd, since we should get the correct time from Dom0.
services.ntp.enable = false;
services.timesyncd.enable = false;
}