containers: Add a hostbridge and ipv6 addresses

This allows the containers to have their interface in a bridge on the host.
Also this adds IPv6 addresses to the containers both with bridged and unbridged
network.
This commit is contained in:
Arnold Krille 2016-01-30 23:00:39 +01:00
parent 530f59979a
commit aa46904490

View File

@ -28,14 +28,23 @@ let
# Initialise the container side of the veth pair. # Initialise the container side of the veth pair.
if [ "$PRIVATE_NETWORK" = 1 ]; then if [ "$PRIVATE_NETWORK" = 1 ]; then
ip link set host0 name eth0 ip link set host0 name eth0
ip link set dev eth0 up ip link set dev eth0 up
if [ -n "$LOCAL_ADDRESS" ]; then
ip addr add $LOCAL_ADDRESS dev eth0
fi
if [ -n "$LOCAL_ADDRESS6" ]; then
ip -6 addr add $LOCAL_ADDRESS6 dev eth0
fi
if [ -n "$HOST_ADDRESS" ]; then if [ -n "$HOST_ADDRESS" ]; then
ip route add $HOST_ADDRESS dev eth0 ip route add $HOST_ADDRESS dev eth0
ip route add default via $HOST_ADDRESS ip route add default via $HOST_ADDRESS
fi fi
if [ -n "$LOCAL_ADDRESS" ]; then if [ -n "$HOST_ADDRESS6" ]; then
ip addr add $LOCAL_ADDRESS dev eth0 ip -6 route add $HOST_ADDRESS6 dev eth0
ip -6 route add default via $HOST_ADDRESS6
fi fi
fi fi
@ -142,12 +151,33 @@ in
''; '';
}; };
hostBridge = mkOption {
type = types.nullOr types.string;
default = null;
example = "br0";
description = ''
Put the host-side of the veth-pair into the named bridge.
Only one of hostAddress* or hostBridge can be given.
'';
};
hostAddress = mkOption { hostAddress = mkOption {
type = types.nullOr types.str; type = types.nullOr types.str;
default = null; default = null;
example = "10.231.136.1"; example = "10.231.136.1";
description = '' description = ''
The IPv4 address assigned to the host interface. The IPv4 address assigned to the host interface.
(Not used when hostBridge is set.)
'';
};
hostAddress6 = mkOption {
type = types.nullOr types.string;
default = null;
example = "fc00::1";
description = ''
The IPv6 address assigned to the host interface.
(Not used when hostBridge is set.)
''; '';
}; };
@ -161,6 +191,16 @@ in
''; '';
}; };
localAddress6 = mkOption {
type = types.nullOr types.string;
default = null;
example = "fc00::2";
description = ''
The IPv6 address assigned to <literal>eth0</literal>
in the container.
'';
};
interfaces = mkOption { interfaces = mkOption {
type = types.listOf types.string; type = types.listOf types.string;
default = []; default = [];
@ -257,11 +297,7 @@ in
if [ "$PRIVATE_NETWORK" = 1 ]; then if [ "$PRIVATE_NETWORK" = 1 ]; then
ip link del dev "ve-$INSTANCE" 2> /dev/null || true ip link del dev "ve-$INSTANCE" 2> /dev/null || true
fi ip link del dev "vb-$INSTANCE" 2> /dev/null || true
if [ "$PRIVATE_NETWORK" = 1 ]; then
ip link del dev "ve-$INSTANCE" 2> /dev/null || true
fi fi
''; '';
@ -281,6 +317,9 @@ in
if [ "$PRIVATE_NETWORK" = 1 ]; then if [ "$PRIVATE_NETWORK" = 1 ]; then
extraFlags+=" --network-veth" extraFlags+=" --network-veth"
if [ -n "$HOST_BRIDGE" ]; then
extraFlags+=" --network-bridge=$HOST_BRIDGE"
fi
fi fi
for iface in $INTERFACES; do for iface in $INTERFACES; do
@ -315,8 +354,11 @@ in
--bind="/nix/var/nix/profiles/per-container/$INSTANCE:/nix/var/nix/profiles" \ --bind="/nix/var/nix/profiles/per-container/$INSTANCE:/nix/var/nix/profiles" \
--bind="/nix/var/nix/gcroots/per-container/$INSTANCE:/nix/var/nix/gcroots" \ --bind="/nix/var/nix/gcroots/per-container/$INSTANCE:/nix/var/nix/gcroots" \
--setenv PRIVATE_NETWORK="$PRIVATE_NETWORK" \ --setenv PRIVATE_NETWORK="$PRIVATE_NETWORK" \
--setenv HOST_BRIDGE="$HOST_BRIDGE" \
--setenv HOST_ADDRESS="$HOST_ADDRESS" \ --setenv HOST_ADDRESS="$HOST_ADDRESS" \
--setenv LOCAL_ADDRESS="$LOCAL_ADDRESS" \ --setenv LOCAL_ADDRESS="$LOCAL_ADDRESS" \
--setenv HOST_ADDRESS6="$HOST_ADDRESS6" \
--setenv LOCAL_ADDRESS6="$LOCAL_ADDRESS6" \
--setenv PATH="$PATH" \ --setenv PATH="$PATH" \
${containerInit} "''${SYSTEM_PATH:-/nix/var/nix/profiles/system}/init" ${containerInit} "''${SYSTEM_PATH:-/nix/var/nix/profiles/system}/init"
''; '';
@ -324,13 +366,21 @@ in
postStart = postStart =
'' ''
if [ "$PRIVATE_NETWORK" = 1 ]; then if [ "$PRIVATE_NETWORK" = 1 ]; then
ifaceHost=ve-$INSTANCE if [ -z "$HOST_BRIDGE" ]; then
ip link set dev $ifaceHost up ifaceHost=ve-$INSTANCE
if [ -n "$HOST_ADDRESS" ]; then ip link set dev $ifaceHost up
ip addr add $HOST_ADDRESS dev $ifaceHost if [ -n "$HOST_ADDRESS" ]; then
fi ip addr add $HOST_ADDRESS dev $ifaceHost
if [ -n "$LOCAL_ADDRESS" ]; then fi
ip route add $LOCAL_ADDRESS dev $ifaceHost if [ -n "$HOST_ADDRESS6" ]; then
ip -6 addr add $HOST_ADDRESS6 dev $ifaceHost
fi
if [ -n "$LOCAL_ADDRESS" ]; then
ip route add $LOCAL_ADDRESS dev $ifaceHost
fi
if [ -n "$LOCAL_ADDRESS6" ]; then
ip -6 route add $LOCAL_ADDRESS6 dev $ifaceHost
fi
fi fi
fi fi
@ -353,6 +403,9 @@ in
restartIfChanged = false; restartIfChanged = false;
#reloadIfChanged = true; # FIXME #reloadIfChanged = true; # FIXME
wants = [ "netwprk.target" ];
after = [ "network.target" ];
serviceConfig = { serviceConfig = {
ExecReload = pkgs.writeScript "reload-container" ExecReload = pkgs.writeScript "reload-container"
'' ''
@ -396,12 +449,21 @@ in
SYSTEM_PATH=${cfg.path} SYSTEM_PATH=${cfg.path}
${optionalString cfg.privateNetwork '' ${optionalString cfg.privateNetwork ''
PRIVATE_NETWORK=1 PRIVATE_NETWORK=1
${optionalString (cfg.hostBridge != null) ''
HOST_BRIDGE=${cfg.hostBridge}
''}
${optionalString (cfg.hostAddress != null) '' ${optionalString (cfg.hostAddress != null) ''
HOST_ADDRESS=${cfg.hostAddress} HOST_ADDRESS=${cfg.hostAddress}
''} ''}
${optionalString (cfg.hostAddress6 != null) ''
HOST_ADDRESS6=${cfg.hostAddress6}
''}
${optionalString (cfg.localAddress != null) '' ${optionalString (cfg.localAddress != null) ''
LOCAL_ADDRESS=${cfg.localAddress} LOCAL_ADDRESS=${cfg.localAddress}
''} ''}
${optionalString (cfg.localAddress6 != null) ''
LOCAL_ADDRESS6=${cfg.localAddress6}
''}
''} ''}
INTERFACES="${toString cfg.interfaces}" INTERFACES="${toString cfg.interfaces}"
${optionalString cfg.autoStart '' ${optionalString cfg.autoStart ''