mirror of
https://github.com/unraid/webgui.git
synced 2026-01-05 17:20:04 -06:00
Make bridge / macvtap selection per physical interface
This commit is contained in:
@@ -23,7 +23,8 @@ require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
$DockerClient = new DockerClient();
|
||||
exec("/etc/rc.d/rc.docker status >/dev/null",$dummy,$DockerStopped);
|
||||
|
||||
$bridge = file_exists('/sys/class/net/br0');
|
||||
exec("ls --indicator-style=none /sys/class/net|awk '/^br[0-9]+$/'",$nics);
|
||||
$bridge = count($nics)>0;
|
||||
|
||||
function strposX($s, $c, $n=1) {
|
||||
$p = 0;
|
||||
|
||||
@@ -661,12 +661,7 @@
|
||||
$netmodel = $nic['model'] ?: 'virtio-net';
|
||||
|
||||
$net_res =$this->libvirt_get_net_res($this->conn, $nic['network']);
|
||||
$bridge = file_exists('/sys/class/net/br0');
|
||||
if ($bridge) {
|
||||
exec("brctl show|grep -Po '^(vir)?br[0-9]+(\.[0-9]+)?'", $br);
|
||||
} else {
|
||||
exec("ip -br a|grep -Po '^(virbr|vhost)[0-9][^@ ]*'",$br);
|
||||
}
|
||||
exec("ip -br a|grep -Po '^((vir)?br|vhost)[0-9]+(\.[0-9]+)?'",$br);
|
||||
if ($nic["boot"] != NULL) $nicboot = "<boot order='".$nic["boot"]."'/>" ; else $nicboot = "" ;
|
||||
if ($net_res) {
|
||||
$netstr .= "<interface type='network'>
|
||||
@@ -676,7 +671,7 @@
|
||||
$nicboot
|
||||
</interface>";
|
||||
} elseif (in_array($nic['network'], $br)) {
|
||||
if ($bridge || $nic['network']=='virbr0') {
|
||||
if (preg_match('/^(vir)?br/',$nic['network'])) {
|
||||
$netstr .= "<interface type='bridge'>
|
||||
<mac address='{$nic['mac']}'/>
|
||||
<source bridge='" . htmlspecialchars($nic['network'], ENT_QUOTES | ENT_XML1) . "'/>
|
||||
|
||||
@@ -1066,11 +1066,7 @@ private static $encoding = 'UTF-8';
|
||||
function getValidNetworks() {
|
||||
global $lv;
|
||||
$arrValidNetworks = [];
|
||||
if (file_exists('/sys/class/net/br0')) {
|
||||
exec("brctl show|grep -Po '^(vir)?br[0-9]+(\.[0-9]+)?'", $arrBridges);
|
||||
} else {
|
||||
exec("ip -br a|grep -Po '^(virbr|vhost)[0-9][^@ ]*'",$arrBridges);
|
||||
}
|
||||
exec("ip -br a|grep -Po '^((vir)?br|vhost)[0-9]+(\.[0-9]+)?'",$arrBridges);
|
||||
if (!is_array($arrBridges)) {
|
||||
$arrBridges = [];
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ UNSHARE=/usr/bin/unshare
|
||||
SYSTEM=/sys/class/net
|
||||
CONF6=/proc/sys/net/ipv6/conf
|
||||
ACTIVE=$(ls --indicator-style=none $SYSTEM|awk '/^(bond|br|eth)[0-9]/' ORS=' ')
|
||||
NICS=$(ls --indicator-style=none $SYSTEM|awk '/^eth[0-9]+$/')
|
||||
|
||||
DOCKERD=dockerd
|
||||
DOCKER=/usr/bin/$DOCKERD
|
||||
@@ -33,11 +34,19 @@ TMP=/var/tmp/network.tmp
|
||||
|
||||
# Set defaults used by the docker daemon
|
||||
if [[ -f $DOCKER_CFG ]]; then
|
||||
if ! grep -qPm1 "_${PORT^^}(_[0-9]+)?=" $DOCKER_CFG; then
|
||||
# interface has changed, update configuration
|
||||
sed -ri "s/_(BR0|BOND0|ETH0)(_[0-9]+)?=/_${PORT^^}\2=/" $DOCKER_CFG
|
||||
sed -ri "s/(br0|bond0|eth0)(\.[0-9]+ )/$PORT\2/g" $DOCKER_CFG
|
||||
fi
|
||||
for NIC in $NICS; do
|
||||
if [[ -e $SYSTEM/${NIC/eth/br} ]]; then
|
||||
NIC=${NIC/eth/br}
|
||||
elif [[ -e $SYSTEM/${NIC/eth/bond} ]]; then
|
||||
NIC=${NIC/eth/bond}
|
||||
fi
|
||||
if ! grep -qPm1 "_${NIC^^}(_[0-9]+)?=" $DOCKER_CFG; then
|
||||
# interface has changed, update configuration
|
||||
X=${NIC//[^0-9]/}
|
||||
sed -ri "s/_(BR|BOND|ETH)$X(_[0-9]+)?=/_${NIC^^}\2=/" $DOCKER_CFG
|
||||
sed -ri "s/(br|bond|eth)$X(\.[0-9]+)? /$NIC\2 /g" $DOCKER_CFG
|
||||
fi
|
||||
done
|
||||
# Read (updated) unRAID docker configuration file
|
||||
. $DOCKER_CFG
|
||||
fi
|
||||
@@ -77,24 +86,6 @@ else
|
||||
[[ -e $SYSTEM/docker0 ]] && echo 1 > $CONF6/docker0/disable_ipv6
|
||||
fi
|
||||
|
||||
# user selection when bridge is enabled
|
||||
if [[ -z $DOCKER_NETWORK_TYPE ]]; then
|
||||
DETACH='ipvlan'
|
||||
ATTACH='macvlan'
|
||||
MODE='bridge'
|
||||
else
|
||||
DETACH='macvlan'
|
||||
ATTACH='ipvlan'
|
||||
MODE='l2 bridge'
|
||||
fi
|
||||
|
||||
# fixed selection when bridge is disabled
|
||||
if [[ $PORT != br0 ]]; then
|
||||
DETACH='ipvlan'
|
||||
ATTACH='macvlan'
|
||||
MODE='bridge'
|
||||
fi
|
||||
|
||||
export DOCKER_RAMDISK=true
|
||||
|
||||
# Get docker daemon PID (if existing)
|
||||
@@ -167,9 +158,29 @@ wipe() {
|
||||
echo ${wet[@]/$wet}
|
||||
}
|
||||
|
||||
# Network driver
|
||||
driver() {
|
||||
# user selection when bridge is enabled
|
||||
if [[ -z $DOCKER_NETWORK_TYPE ]]; then
|
||||
DETACH='ipvlan'
|
||||
ATTACH='macvlan'
|
||||
MODE='bridge'
|
||||
else
|
||||
DETACH='macvlan'
|
||||
ATTACH='ipvlan'
|
||||
MODE='l2 bridge'
|
||||
fi
|
||||
# fixed selection when bridge is disabled
|
||||
if [[ $1 != br ]]; then
|
||||
DETACH='ipvlan'
|
||||
ATTACH='macvlan'
|
||||
MODE='bridge'
|
||||
fi
|
||||
}
|
||||
|
||||
# Custom networks
|
||||
network(){
|
||||
docker network ls --filter driver="$1" --format='{{.Name}}' 2>/dev/null|tr '\n' ' '
|
||||
docker network ls --filter driver="$1" --format='{{.Name}}' 2>/dev/null|grep -P "^[a-z]+$2(\$|\.)"|tr '\n' ' '
|
||||
}
|
||||
|
||||
# Is container running?
|
||||
@@ -223,7 +234,7 @@ add_route(){
|
||||
# Add custom networks
|
||||
start_network(){
|
||||
# create list of possible custom networks
|
||||
EXCLUDE=; INCLUDE=$(ls --indicator-style=none $SYSTEM|awk '/^br[0-9]/' ORS=' ')
|
||||
EXCLUDE=; INCLUDE=$(ls --indicator-style=none $SYSTEM|awk '/^br[0-9]+/' ORS=' ')
|
||||
while IFS=$'\n' read -r NETWORK; do
|
||||
if [[ ${NETWORK:0:4} == bond ]]; then
|
||||
if [[ $INCLUDE =~ "${NETWORK/bond/br} " ]]; then
|
||||
@@ -239,7 +250,7 @@ start_network(){
|
||||
INCLUDE="${INCLUDE}${NETWORK} "
|
||||
fi
|
||||
fi
|
||||
done <<< $(ls --indicator-style=none $SYSTEM|grep -P '^(bond|eth)[0-9]')
|
||||
done <<< $(ls --indicator-style=none $SYSTEM|grep -P '^(bond|eth)[0-9]+')
|
||||
wait_daemon
|
||||
if ! is_docker_running; then return 1; fi
|
||||
# get container settings for custom networks to reconnect later
|
||||
@@ -286,18 +297,27 @@ start_network(){
|
||||
done
|
||||
done
|
||||
# detach custom networks
|
||||
for NETWORK in $(network $DETACH); do
|
||||
[[ $STOCK =~ ${NETWORK%%[0-9]*} || $DOCKER_USER_NETWORKS != preserve ]] && docker network rm $NETWORK >/dev/null
|
||||
done
|
||||
# get existing custom networks
|
||||
for NETWORK in $(network $ATTACH); do
|
||||
if [[ $STOCK =~ ${NETWORK%%[0-9]*} ]]; then
|
||||
[[ $EXCLUDE =~ "$NETWORK " || ! $ACTIVE =~ "$NETWORK " ]] && docker network rm $NETWORK >/dev/null
|
||||
else
|
||||
[[ $DOCKER_USER_NETWORKS != preserve ]] && docker network rm $NETWORK >/dev/null
|
||||
for NIC in $NICS; do
|
||||
if [[ -e $SYSTEM/${NIC/eth/br} ]]; then
|
||||
NIC=${NIC/eth/br}
|
||||
elif [[ -e $SYSTEM/${NIC/eth/bond} ]]; then
|
||||
NIC=${NIC/eth/bond}
|
||||
fi
|
||||
X=${NIC//[^0-9]/}
|
||||
driver ${NIC//[0-9]/}
|
||||
for NETWORK in $(network $DETACH $X); do
|
||||
[[ $STOCK =~ ${NETWORK%%[0-9]*} || $DOCKER_USER_NETWORKS != preserve ]] && docker network rm $NETWORK >/dev/null
|
||||
done
|
||||
# get existing custom networks
|
||||
for NETWORK in $(network $ATTACH $X); do
|
||||
if [[ $STOCK =~ ${NETWORK%%[0-9]*} ]]; then
|
||||
[[ $EXCLUDE =~ "$NETWORK " || ! $ACTIVE =~ "$NETWORK " ]] && docker network rm $NETWORK >/dev/null
|
||||
else
|
||||
[[ $DOCKER_USER_NETWORKS != preserve ]] && docker network rm $NETWORK >/dev/null
|
||||
fi
|
||||
done
|
||||
NETWORKS=$(network $ATTACH $X)
|
||||
done
|
||||
NETWORKS=$(network $ATTACH)
|
||||
# add or remove custom network
|
||||
for NETWORK in $INCLUDE; do
|
||||
if [[ ! $DOCKER_CUSTOM_NETWORKS =~ "$NETWORK " ]]; then
|
||||
@@ -428,7 +448,9 @@ start_network(){
|
||||
[[ -n $RANGE ]] && SERVER="--aux-address=server=${R4%/*}" || SERVER="--aux-address=server=${SHIM_HIGH%/*}"
|
||||
fi
|
||||
fi
|
||||
[[ ${NETWORK:0:2} == br ]] && VHOST=$NETWORK || VHOST=vhost${NETWORK//[^0-9.]/}
|
||||
TYPE=${NETWORK//[0-9.]/}
|
||||
driver $TYPE
|
||||
[[ $TYPE == br ]] && VHOST=$NETWORK || VHOST=vhost${NETWORK//[^0-9.]/}
|
||||
docker network create -d $ATTACH $SUBNET $GATEWAY $SERVER $RANGE $SUBNET6 $GATEWAY6 $SERVER6 $RANGE6 -o parent=$VHOST $NETWORK | xargs docker network inspect -f "created network $ATTACH {{.Name}} with subnets: {{range .IPAM.Config}}{{.Subnet}}; {{end}}" 2>/dev/null | logger -t $(basename $0)
|
||||
# connect containers to this new network
|
||||
for CONNECT in ${NETRESTORE[$NETWORK]}; do
|
||||
@@ -490,16 +512,24 @@ shim_network(){
|
||||
|
||||
# Remove custom networks
|
||||
stop_network(){
|
||||
for NETWORK in $(network $ATTACH); do
|
||||
[[ $STOCK =~ ${NETWORK%%[0-9]*} || $DOCKER_USER_NETWORKS != preserve ]] && docker network rm $NETWORK >/dev/null
|
||||
done
|
||||
for LINK in $(ls --indicator-style=none $SYSTEM|grep '^shim-'); do
|
||||
ip -4 addr flush dev $LINK
|
||||
ip -4 route flush dev $LINK
|
||||
ip -6 addr flush dev $LINK
|
||||
ip -6 route flush dev $LINK
|
||||
ip link set $LINK down
|
||||
ip link del $LINK
|
||||
for NIC in $NICS; do
|
||||
if [[ -e $SYSTEM/${NIC/eth/br} ]]; then
|
||||
NIC=${NIC/eth/br}
|
||||
elif [[ -e $SYSTEM/${NIC/eth/bond} ]]; then
|
||||
NIC=${NIC/eth/bond}
|
||||
fi
|
||||
X=${NIC//[^0-9]/}
|
||||
driver ${NIC//[0-9]/}
|
||||
for NETWORK in $(network $ATTACH $X); do
|
||||
[[ $STOCK =~ ${NETWORK%%[0-9]*} || $DOCKER_USER_NETWORKS != preserve ]] && docker network rm $NETWORK >/dev/null
|
||||
LINK=shim-$NETWORK
|
||||
if [[ -e $SYSTEM/$LINK ]]; then
|
||||
ip -4 addr flush dev $LINK
|
||||
ip -4 route flush dev $LINK
|
||||
ip link set $LINK down
|
||||
ip link del $LINK
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ if [ -f /boot/config/domain.cfg ]; then
|
||||
. /boot/config/domain.cfg
|
||||
fi
|
||||
|
||||
SYSTEM=/sys/class/net
|
||||
MODULES=${MODULES:-"vhost_net"}
|
||||
TIMEOUT=${TIMEOUT:-60}
|
||||
HOSTSHUTDOWN=${HOSTSHUTDOWN:-"shutdown"}
|
||||
@@ -159,7 +160,7 @@ waitstop() {
|
||||
}
|
||||
|
||||
start_libvirtd() {
|
||||
if [ -f $LIBVIRTD_PIDFILE ];then
|
||||
if [[ -f $LIBVIRTD_PIDFILE ]]; then
|
||||
echo "libvirt is already running..."
|
||||
exit 1
|
||||
fi
|
||||
@@ -171,14 +172,29 @@ start_libvirtd() {
|
||||
sed -ri "s/<vendor id='none'\/>/<vendor_id state='on' value='none'\/>/g" /etc/libvirt/qemu/*.xml &> /dev/null
|
||||
# remove <locked/> from xml because libvirt + virlogd + virlockd has an issue with locked
|
||||
sed -ri "s/<locked\/>//g" /etc/libvirt/qemu/*.xml &> /dev/null
|
||||
# update interface section of VM configuration files
|
||||
if [[ -e /sys/class/net/br0 ]]; then
|
||||
# link VM to bridge interface
|
||||
sed -ri "s/<interface type='direct'>/<interface type='bridge'>/;s/<source dev='vhost([0-9]+(\.[0-9]+)?)' mode='bridge'\/>/<source bridge='br\1'\/>/" /etc/libvirt/qemu/*.xml &> /dev/null
|
||||
else
|
||||
# link VM to macvtap interface
|
||||
sed -ri "s/<interface type='bridge'>/<interface type='direct'>/;s/<source bridge='br([0-9]+(\.[0-9]+)?)'\/>/<source dev='vhost\1' mode='bridge'\/>/" /etc/libvirt/qemu/*.xml &> /dev/null
|
||||
fi
|
||||
# update interface section((s) of VM configuration files
|
||||
for XML in /etc/libvirt/qemu/*.xml; do
|
||||
# get all interface sections
|
||||
ROW=($(grep -nhP '<interface type=' $XML|grep -Pom1 '^[0-9]+'))
|
||||
# get all source sections
|
||||
CAT=($(grep -nhP '<source (bridge|dev)=' $XML|awk '{print $1$3}'))
|
||||
for i in ${!ROW[@]}; do
|
||||
SOURCE=$(echo ${CAT[$i]}|grep -Pom1 '^[0-9]+')
|
||||
DEV=$(echo ${CAT[$i]}|grep -Pom1 "^.+='\K[^']+")
|
||||
if [[ ! -e $SYSTEM/$DEV ]]; then
|
||||
NAME=${DEV//[0-9.]/}
|
||||
if [[ $NAME == br ]]; then
|
||||
# change to macvtap
|
||||
sed -ri "${ROW[$i]} s/<interface type='bridge'>/<interface type='direct'>/" $XML &> /dev/null
|
||||
sed -ri "$SOURCE s/<source bridge='$DEV'\/>/<source dev='${DEV/$NAME/vhost}' mode='bridge'\/>/" $XML &> /dev/null
|
||||
else
|
||||
# change to bridge
|
||||
sed -ri "${ROW[$i]} s/<interface type='direct'>/<interface type='bridge'>/" $XML &> /dev/null
|
||||
sed -ri "$SOURCE s/<source dev='$DEV' mode='bridge'\/>/<source bridge='${DEV/$NAME/br}'\/>/" $XML &> /dev/null
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
# copy any new conf files we dont currently have
|
||||
cp -n /etc/libvirt-/*.conf /etc/libvirt &> /dev/null
|
||||
# ensure tpm-states path exists
|
||||
@@ -191,7 +207,7 @@ start_libvirtd() {
|
||||
}
|
||||
|
||||
stop_libvirtd() {
|
||||
if [ ! -f $LIBVIRTD_PIDFILE ];then
|
||||
if [[ ! -f $LIBVIRTD_PIDFILE ]]; then
|
||||
echo "libvirt is not running..."
|
||||
exit 2
|
||||
fi
|
||||
@@ -207,7 +223,7 @@ stop_libvirtd() {
|
||||
}
|
||||
|
||||
start_virtlogd() {
|
||||
if [ -f $VIRTLOGD_PIDFILE ];then
|
||||
if [[ -f $VIRTLOGD_PIDFILE ]]; then
|
||||
echo "virtlogd is already running..."
|
||||
exit 1
|
||||
fi
|
||||
@@ -217,7 +233,7 @@ start_virtlogd() {
|
||||
}
|
||||
|
||||
stop_virtlogd() {
|
||||
if [ ! -f $VIRTLOGD_PIDFILE ];then
|
||||
if [[ ! -f $VIRTLOGD_PIDFILE ]]; then
|
||||
echo "virtlogd is not running..."
|
||||
exit 2
|
||||
fi
|
||||
@@ -227,7 +243,7 @@ stop_virtlogd() {
|
||||
}
|
||||
|
||||
start_virtlockd() {
|
||||
if [ -f $VIRTLOCKD_PIDFILE ];then
|
||||
if [[ -f $VIRTLOCKD_PIDFILE ]]; then
|
||||
echo "virtlockd is already running..."
|
||||
exit 1
|
||||
fi
|
||||
@@ -237,7 +253,7 @@ start_virtlockd() {
|
||||
}
|
||||
|
||||
stop_virtlockd() {
|
||||
if [ ! -f $VIRTLOCKD_PIDFILE ];then
|
||||
if [[ ! -f $VIRTLOCKD_PIDFILE ]]; then
|
||||
echo "virtlockd is not running..."
|
||||
exit 2
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user