diff --git a/plugins/dynamix.docker.manager/DockerContainers.page b/plugins/dynamix.docker.manager/DockerContainers.page index 491275dcb..4bf68a658 100644 --- a/plugins/dynamix.docker.manager/DockerContainers.page +++ b/plugins/dynamix.docker.manager/DockerContainers.page @@ -4,8 +4,8 @@ Cond="(pgrep('dockerd')!==false)" Markdown="false" --- $("#DOCKER_APP_CONFIG_PATH").fileTreeAttach(); diff --git a/plugins/dynamix.docker.manager/include/CreateDocker.php b/plugins/dynamix.docker.manager/include/CreateDocker.php index be2b51695..faea486c2 100644 --- a/plugins/dynamix.docker.manager/include/CreateDocker.php +++ b/plugins/dynamix.docker.manager/include/CreateDocker.php @@ -1,6 +1,6 @@ ".print_r($m, true).""; }; +exec("docker network ls --filter driver='macvlan' --format='{{.Name}}'", $custom); +$subnet = ['bridge'=>'', 'host'=>'', 'none'=>'']; +foreach ($custom as $network) $subnet[$network] = exec("docker network inspect --format='{{range .IPAM.Config}}{{.Subnet}}{{end}}' $network"); + function stopContainer($name) { global $DockerClient; $waitID = mt_rand(); @@ -189,6 +193,7 @@ function postToXML($post, $setOwnership = false) { $xml->Repository = xml_encode(trim($post['contRepository'])); $xml->Registry = xml_encode(trim($post['contRegistry'])); $xml->Network = xml_encode($post['contNetwork']); + $xml->MyIP = xml_encode($post['contMyIP']); $xml->Privileged = (strtolower($post["contPrivileged"]) == 'on') ? 'true' : 'false'; $xml->Support = xml_encode($post['contSupport']); $xml->Overview = xml_encode($post['contOverview']); @@ -251,6 +256,7 @@ function xmlToVar($xml) { $out['Repository'] = xml_decode($xml->Repository); $out['Registry'] = xml_decode($xml->Registry); $out['Network'] = (isset($xml->Network)) ? xml_decode($xml->Network) : xml_decode($xml->Network['Default']); + $out['MyIP'] = isset($xml->MyIP) ? xml_decode($xml->MyIP) : ''; $out['Privileged'] = xml_decode($xml->Privileged); $out['Support'] = xml_decode($xml->Support); $out['Overview'] = stripslashes(xml_decode($xml->Overview)); @@ -362,6 +368,7 @@ function xmlToCommand($xml, $create_paths=false) { $cmdName = (strlen($xml['Name'])) ? '--name="'.$xml['Name'].'"' : ""; $cmdPrivileged = (strtolower($xml['Privileged']) == 'true') ? '--privileged="true"' : ""; $cmdNetwork = '--net="'.strtolower($xml['Network']).'"'; + $cmdMyIP = $xml['MyIP'] ? '--ip="'.$xml['MyIP'].'"' : ''; $Volumes = ['']; $Ports = ['']; $Variables = ['']; @@ -386,10 +393,10 @@ function xmlToCommand($xml, $create_paths=false) { } } elseif ($confType == 'port') { # Export ports as variable if Network is set to host - if (strtolower($xml['Network']) == 'host') { + if (preg_match('/^(host|eth[0-9]|br[0-9]|bond[0-9])/',strtolower($xml['Network']))) { $Variables[] = strtoupper(sprintf('"%s_PORT_%s"="%s"', $Mode, $containerConfig, $hostConfig)); # Export ports as port if Network is set to bridge - } elseif (strtolower($xml['Network']) == 'bridge') { + } elseif (strtolower($xml['Network'])== 'bridge') { $Ports[] = sprintf("%s:%s/%s", $hostConfig, $containerConfig, $Mode); # No export of ports if Network is set to none } @@ -399,9 +406,10 @@ function xmlToCommand($xml, $create_paths=false) { $Devices[] = '"'.$hostConfig.'"'; } } - $cmd = sprintf('/plugins/dynamix.docker.manager/scripts/docker create %s %s %s %s %s %s %s %s %s', + $cmd = sprintf('/plugins/dynamix.docker.manager/scripts/docker create %s %s %s %s %s %s %s %s %s %s', $cmdName, $cmdNetwork, + $cmdMyIP, $cmdPrivileged, implode(' -e ', $Variables), implode(' -p ', $Ports), @@ -1041,7 +1049,7 @@ $showAdditionalInfo = ''; } else { targetDiv.hide(); } - if (network==0 || network==1) { + if (network==0 || network==1 || network>2) { valueDiv.find('#dt2').text('Host Port:'); valueDiv.show(); } else { @@ -1355,13 +1363,20 @@ $showAdditionalInfo = ''; > Network Type: - + + + + + + + + Fixed IP address (optional): + + >
@@ -1519,6 +1534,20 @@ $showAdditionalInfo = ''; - + \ No newline at end of file diff --git a/plugins/dynamix/include/update.ethernet.php b/plugins/dynamix/include/update.ethernet.php index 5236a9af8..6360da801 100644 --- a/plugins/dynamix/include/update.ethernet.php +++ b/plugins/dynamix/include/update.ethernet.php @@ -1,6 +1,6 @@ \ No newline at end of file diff --git a/plugins/dynamix/scripts/netconfig b/plugins/dynamix/scripts/netconfig index cd446c03e..a4681d093 100755 --- a/plugins/dynamix/scripts/netconfig +++ b/plugins/dynamix/scripts/netconfig @@ -26,59 +26,63 @@ function ifname($name) { } return $name; } - -if ($run && file_exists($cfg)) { - $old = parse_ini_string(preg_replace('/^#/m',';',file_get_contents($cfg))); - if (isset($old['SYSNICS'])) { - // new syntax - $ifname = ifname($set); - } else { - // legacy syntax - if ($set=='eth0') $ifname = $old['BRIDGING']=='yes' ? ($old['BRNAME'] ?: 'br0') : ($old['BONDING']=='yes' ? ($old['BONDNAME'] ?: 'bond0') : $set); - } +function bond_nics(&$bond,$nic) { + $bond['BONDNICS'] = str_replace(',',' ',$bond['BONDNICS']); + return explode(' ',preg_replace("/$nic ?/","",$bond['BONDNICS'])); +} +function bridge_nics(&$bridge,$nic) { + $bridge['BRNICS'] = str_replace(',',' ',$bridge['BRNICS']); + return explode(' ',preg_replace("/$nic ?/","",$bridge['BRNICS'])); } // stop interface with existing (old) configuration // don't execute when only interface description has changed -if ($run) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$ifname}_stop")." >/dev/null"); - -if ($bonding = $ini['eth0']['BONDING']=='yes') { - $ini['eth0']['BONDNICS'] = str_replace(',',' ',$ini['eth0']['BONDNICS']); - $bond0 = explode(' ',trim(str_replace('eth0','',$ini['eth0']['BONDNICS']))); -// ensure additional NICs in bond are set free - if ($run && $set=='eth0') foreach ($bond0 as $nic) { - if (isset($old['SYSNICS'])) $nic = ifname($nic); - if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null"); +if ($run) { + $old = []; + if (file_exists($cfg)) { + $old = parse_ini_string(preg_replace('/^#/m',';',file_get_contents($cfg))); + if (isset($old['SYSNICS'])) { + // new syntax + $ifname = ifname($set); + } else { + // legacy syntax + if ($set=='eth0') $ifname = $old['BRIDGING']=='yes' ? ($old['BRNAME'] ?: 'br0') : ($old['BONDING']=='yes' ? ($old['BONDNAME'] ?: 'bond0') : $set); + } } -} - -if ($bridging = $ini['eth0']['BRIDGING']=='yes') { - $ini['eth0']['BRNICS'] = str_replace(',',' ',$ini['eth0']['BRNICS']); - $br0 = explode(' ',trim(str_replace('eth0','',$ini['eth0']['BRNICS']))); -// ensure additional NICs in bridge are set free - if ($run && $set=='eth0' && !$bonding) foreach ($br0 as $nic) { - if (isset($old['SYSNICS'])) $nic = ifname($nic); - if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null"); + exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$ifname}_stop")." >/dev/null"); + if ($ini[$set]['BONDING']=='yes') { + // release additional NICs in bond + foreach (bond_nics($ini[$set],$set) as $nic) { + if (isset($old['SYSNICS'])) $nic = ifname($nic); + if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null"); + } + } elseif ($ini[$set]['BRIDGING']=='yes') { + // release additional NICs in bridge + foreach (bridge_nics($ini[$set],$set) as $nic) { + if (isset($old['SYSNICS'])) $nic = ifname($nic); + if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null"); + } } } // create configuration file for all available interfaces $i = 0; $new = []; $new[] = "# Generated settings:"; foreach ($ini as $name => $port) { - if ($bonding && in_array($name,$bond0)) continue; - if ($bridging && in_array($name,$br0)) continue; - $bridge = $port['BRIDGING']=='yes'; + $bonding = $port['BONDING']=='yes'; + $bridging = $port['BRIDGING']=='yes'; + if ($bonding && in_array($name,bond_nics($port,$name))) continue; + if ($bridging && in_array($name,bridge_nics($port,$name))) continue; $trunk = $port['TYPE']=='trunk'; $j = 0; $x0 = 0; - $iface = $bridge ? $port['BRNAME'] : ($bonding && $name=='eth0' ? $port['BONDNAME'] : $name); + $iface = $bridging ? $port['BRNAME'] : ($bonding ? $port['BONDNAME'] : $name); $new[] = "IFNAME[$i]=\"$iface\""; if ($set==$name) $ifname = $iface; foreach ($port as $key => $val) { if (preg_match('/^(TYPE|BONDING$|BRIDGING)/',$key)) continue; if (!$bonding && preg_match('/^(BONDING_MODE|BONDING_MIIMON|BONDNICS|BONDNAME)/',$key)) continue; - if (!$bridge && preg_match('/^(BRSTP|BRFD|BRNICS|BRNAME)/',$key)) continue; + if (!$bridging && preg_match('/^(BRSTP|BRFD|BRNICS|BRNAME)/',$key)) continue; list($item,$x) = explode(':',$key,2); - if ($trunk && $x>0 && preg_match('/^(VLANID|USE_DHCP|IPADDR6?|NETMASK6?|GATEWAY6?|METRIC6?|PRIVACY6|DESCRIPTION|PROTOCOL)/',$key)) { + if ($trunk && $x>0 && preg_match('/^(VLANID|USE_DHCP|IPADDR6?|NETMASK6?|GATEWAY6?|METRIC|PRIVACY6|DESCRIPTION|PROTOCOL)/',$key)) { if ($x0 != $x) {$x0 = $x; $j++;} $vlan = ",$j]"; } else $vlan = ''; @@ -95,6 +99,7 @@ file_put_contents($cfg,implode("\r\n",$new)."\r\n"); // don't execute when only interface description has changed if ($run) { exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$ifname}_start")." >/dev/null"); + sleep(1); exec("/usr/local/sbin/create_network_ini >/dev/null"); } exit(0); diff --git a/plugins/dynamix/scripts/watchdog b/plugins/dynamix/scripts/watchdog new file mode 100755 index 000000000..cc22ceaa6 --- /dev/null +++ b/plugins/dynamix/scripts/watchdog @@ -0,0 +1,36 @@ +#!/bin/bash + +PREV= +while :; do + . /var/local/emhttp/var.ini + case $fsState in + Stopped) + DATA="Array Stopped" + ;; + Starting) + DATA="Array Starting" + ;; + *) + DATA="Array Started" + ;; + esac + if [[ $mdResync -gt 0 ]]; then + MODE= + if [[ $mdResyncAction =~ recon ]]; then + MODE='Parity-Sync / Data-Rebuild' + elif [[ $mdResyncAction =~ clear ]]; then + MODE='Clearing' + elif [[ $mdResyncAction == check ]]; then + MODE='Read-Check' + elif [[ $mdResyncAction =~ check ]]; then + MODE='Parity-Check' + fi + p=$((mdResyncPos*1000/mdResync)); w=${p:0:-1} + DATA="$DATA•$MODE ${w:-0}.${p: -1} %" + fi + if [[ $DATA != $PREV ]]; then + curl -s -X POST -d "$DATA" http://127.0.0.1/pub/watchdog?buffer_length=1 &>/dev/null + PREV=$DATA + fi + sleep 3 +done & diff --git a/plugins/dynamix/styles/default-black.css b/plugins/dynamix/styles/default-black.css index 7e7fe31df..18e4adf8f 100644 --- a/plugins/dynamix/styles/default-black.css +++ b/plugins/dynamix/styles/default-black.css @@ -1,5 +1,5 @@ html,body{font-family:arimo;font-size:12px;color:#808080;background-color:#000000;padding:0;margin:0;} -#template{min-width:1070px;max-width:1270px;margin:0 auto;} +#template{min-width:1080px;margin:0 10px;} img{border:0;text-decoration:none;vertical-align:middle;} p{text-align:justify;} p.centered{text-align:left;} @@ -36,7 +36,7 @@ select.slot{min-width:400px;max-width:400px;} input.narrow{width:132px;} input.trim{width:50px;} #header{height:90px;} -#header.image{background-size:1270px 90px; border-radius:5px;color:#D0D0D0;} +#header.image{background-size:100% 90px; border-radius:5px;color:#D0D0D0;} #header .logo{float:left;margin-top:20px;margin-left:20px;} #header .logo img{margin:0 0 2px 1px;} #header .logo a{color:#478406;font-size:18px;} @@ -156,13 +156,13 @@ table.share_status tbody tr.warn{color:#E68A00;background-color:#FEEFB3;} table.share_status.share tr td:last-child{width:4%;text-align:right;padding-right:10px;} table.share_status.fixed{border:1px solid #202020;} table.share_status.fixed thead tr>td+td{font-size:11px;} -table.share_status.fixed tr>td+td{width:38px;text-align:center;padding:0;} +table.share_status.fixed tr>td+td{min-width:30px;text-align:center;padding:0;} table.share_status.fixed tbody tr{border-bottom:1px #202020 dotted;} table.share_status.fixed tbody tr:nth-child(even){background-color:#000000;} table.share_status.fixed tbody tr td:nth-child(even){background-color:#0C0C0C;} table.share_status.table{margin-top:36px;} table.share_status.table tr>td{width:50%;} -table.share_status.dash{float:left;width:33%;margin-top:36px;margin-right:6px;border:1px solid #202020;} +table.share_status.dash{float:left;width:33%;margin-top:36px;border:1px solid #202020;} table.share_status.dash thead tr:last-child>td{font-weight:bold;border-bottom:1px solid #202020;} table.share_status.dash tbody td.blue{color:#3B5998;} table.share_status.dash.line {table-layout:fixed;} @@ -176,10 +176,10 @@ table.share_status.dash.line tr>td[colspan="4"]{width:100%;} table.share_status.dash.line tr>td:last-child{white-space:normal;} table.share_status.dash tr.h48{height:48px;} table.share_status.dash td:first-child{width:25%;} -table.share_status.m36{width:36%;margin-right:0;} +table.share_status.m36{width:36%;float:right;} table.share_status.m36 tr>td+td+td{width:14%;} table.share_status.m36 tr>td+td+td+td{width:8%;text-align:center;} -table.share_status.m0{width:30%;} +table.share_status.m0{width:30%;margin-left:0.5%;} table.share_status.m0 tr>td+td+td{width:12%;text-align:center;} [name=arrayOps]{margin-top:12px;} span.error{color:#F0000C;background-color:#FF9E9E;display:block;width:100%;} @@ -210,7 +210,7 @@ img.icon{margin:-3px 4px 0 0;} div.content{position:absolute;top:45px;left:0;width:100%;padding-bottom:30px;z-index:-1;clear:both;} div.content.shift{margin-top:-70px;} div.tabs{position:relative;margin:24px 0 0 0;} -div.tab{float:left;} +div.tab{float:left;margin:0 0 12px 0;} div.tab input[id^="tab"]{display:none;} div.tab [type=radio]+label:hover{background:#000000;color:#478406;cursor:pointer;} div.tab [type=radio]:checked+label{cursor:default;background:-webkit-radial-gradient(#303030,#505050);background:linear-gradient(#303030,#505050);color:#808080;} diff --git a/plugins/dynamix/styles/default-white.css b/plugins/dynamix/styles/default-white.css index b6871edbf..4f05fc1d2 100644 --- a/plugins/dynamix/styles/default-white.css +++ b/plugins/dynamix/styles/default-white.css @@ -1,5 +1,5 @@ html,body{font-family:arimo;font-size:12px;color:#303030;background-color:#FFFFFF;padding:0;margin:0;} -#template{min-width:1070px;max-width:1270px;margin:0 auto;} +#template{min-width:1080px;margin:0 10px;} img{border:0;text-decoration:none;vertical-align:middle;} p{text-align:justify;} p.centered{text-align:left;} @@ -35,7 +35,7 @@ select.slot{min-width:400px;max-width:400px;} input.narrow{width:132px;} input.trim{width:50px;} #header{height:90px;} -#header.image{background-size:1270px 90px; border-radius:5px;color:#202020;} +#header.image{background-size:100% 90px; border-radius:5px;color:#202020;} #header .logo{float:left;margin-top:20px;margin-left:20px;} #header .logo img{margin:0 0 2px 1px;} #header .logo a{color:#478406;font-size:18px;} @@ -154,13 +154,13 @@ table.share_status tbody tr.warn{color:#E68A00;background-color:#FEEFB3;} table.share_status.share tr td:last-child{width:4%;text-align:right;padding-right:10px;} table.share_status.fixed{border:1px solid #D0D0D0;} table.share_status.fixed thead tr>td+td{font-size:11px;} -table.share_status.fixed tr>td+td{width:38px;text-align:center;padding:0;} +table.share_status.fixed tr>td+td{min-width:30px;text-align:center;padding:0;} table.share_status.fixed tbody tr{border-bottom:1px #D0D0D0 dotted;} table.share_status.fixed tbody tr:nth-child(even){background-color:#FFFFFF;} table.share_status.fixed tbody tr td:nth-child(even){background-color:#F8F8F8;} table.share_status.table{margin-top:36px;} table.share_status.table tr>td{width:50%;} -table.share_status.dash{float:left;width:33%;margin-top:36px;margin-right:6px;border:1px solid #D0D0D0;} +table.share_status.dash{float:left;width:33%;margin-top:36px;border:1px solid #D0D0D0;} table.share_status.dash thead tr:last-child>td{font-weight:bold;border-bottom:1px solid #D0D0D0;} table.share_status.dash tbody td.blue{color:#3B5998;} table.share_status.dash.line {table-layout:fixed;} @@ -174,10 +174,10 @@ table.share_status.dash.line tr>td[colspan="4"]{width:100%;} table.share_status.dash.line tr>td:last-child{white-space:normal;} table.share_status.dash tr.h48{height:48px;} table.share_status.dash td:first-child{width:25%;} -table.share_status.m36{width:36%;margin-right:0;} +table.share_status.m36{width:36%;float:right;} table.share_status.m36 tr>td+td+td{width:14%;} table.share_status.m36 tr>td+td+td+td{width:8%;text-align:center;} -table.share_status.m0{width:30%;} +table.share_status.m0{width:30%;margin-left:0.5%;} table.share_status.m0 tr>td+td+td{width:12%;text-align:center;} [name=arrayOps]{margin-top:12px;} span.error{color:#F0000C;background-color:#FF9E9E;display:block;width:100%;} @@ -208,7 +208,7 @@ img.icon{margin:-3px 4px 0 0;} div.content{position:absolute;top:45px;left:0;width:100%;padding-bottom:30px;z-index:-1;clear:both;} div.content.shift{margin-top:-70px;} div.tabs{position:relative;margin:24px 0 0 0;} -div.tab{float:left;} +div.tab{float:left;margin:0 0 12px 0;} div.tab input[id^="tab"]{display:none;} div.tab [type=radio]+label:hover{background:#FFFFFF;color:#478406;cursor:pointer;} div.tab [type=radio]:checked+label{cursor:default;background:-webkit-radial-gradient(#F8F8F8,#E8E8E8);background:linear-gradient(#F8F8F8,#E8E8E8);color:#303030;}