From bc830d71cd59f9b43daeccbe26c93675ae5e562b Mon Sep 17 00:00:00 2001 From: bergware Date: Thu, 6 Feb 2025 12:30:52 +0100 Subject: [PATCH] Wireless support : finetuning --- .../include/DockerClient.php | 45 ++++++++++--------- .../include/DockerContainers.php | 23 ++++++---- .../include/Helpers.php | 8 ++-- emhttp/plugins/dynamix/include/Wrappers.php | 36 ++++++++++++++- sbin/create_network_ini | 12 ++--- 5 files changed, 83 insertions(+), 41 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php index 6e1b9403a..26e1a0b15 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php @@ -1,6 +1,6 @@ "$docroot/state/plugins/dynamix.docker.manager/docker.json" ]; -// load network variables if needed. -$system = '/sys/class/net'; -$port = file_exists("$system/br0") ? 'br0' : (file_exists("$system/bond0") ? 'bond0' : 'eth0'); -$host = exec ("ip -br -4 addr show $port scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}'"); - -if (empty($host) && file_exists("$system/wlan0")) $host = exec ("ip -br -4 addr show wlan0 scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}'"); - -// get network drivers -$driver = DockerUtil::driver(); - -// determine active port name -$port = file_exists('/sys/class/net/br0') ? 'BR0' : (file_exists('/sys/class/net/bond0') ? 'BOND0' : 'ETH0'); - // Docker configuration file - guaranteed to exist $docker_cfgfile = '/boot/config/docker.cfg'; if (file_exists($docker_cfgfile)) { + $port = strtoupper(DockerUtil::port()); exec("grep -Pom2 '_SUBNET_|_{$port}(_[0-9]+)?=' $docker_cfgfile",$cfg); if (isset($cfg[0]) && $cfg[0]=='_SUBNET_' && empty($cfg[1])) { # interface has changed, update configuration @@ -279,9 +267,8 @@ class DockerTemplates { } private function getControlURL(&$ct, $myIP, $WebUI) { - global $host; $port = &$ct['Ports'][0]; - $myIP = $myIP ?: $this->getTemplateValue($ct['Image'],'MyIP') ?: (_var($ct,'NetworkMode')=='host'||_var($port,'NAT') ? $host : (_var($port,'IP') ?: DockerUtil::myIP($ct['Name']))); + $myIP = $myIP ?: $this->getTemplateValue($ct['Image'],'MyIP') ?: (_var($ct,'NetworkMode')=='host'||_var($port,'NAT') ? DockerUtils::host() : (_var($port,'IP') ?: DockerUtil::myIP($ct['Name']))); // Get the WebUI address from the templates as a fallback $WebUI = preg_replace("%\[IP\]%", $myIP, $WebUI ?? $this->getTemplateValue($ct['Image'], 'WebUI')); if (preg_match("%\[PORT:(\d+)\]%", $WebUI, $matches)) { @@ -305,9 +292,11 @@ class DockerTemplates { } public function getAllInfo($reload=false,$com=true,$communityApplications=false) { - global $driver, $dockerManPaths, $host; + global $dockerManPaths; $DockerClient = new DockerClient(); $DockerUpdate = new DockerUpdate(); + $driver = DockerUtil::driver(); + $host = DockerUtil::host(); //$DockerUpdate->verbose = $this->verbose; $info = DockerUtil::loadJSON($dockerManPaths['webui-info']); $autoStart = array_map('var_split', @file($dockerManPaths['autostart-file'],FILE_IGNORE_NEW_LINES) ?: []); @@ -959,7 +948,8 @@ class DockerClient { } public function getDockerContainers() { - global $driver, $host; + $driver = DockerUtil::driver(); + $host = DockerUtil::host(); // Return cached values if (is_array($this::$containersCache)) return $this::$containersCache; $this::$containersCache = []; @@ -1176,5 +1166,20 @@ class DockerUtil { public static function ctMap($ct, $type='Name') { return static::docker("inspect --format='{{.$type}}' $ct"); } + + public static function port() { + if (lan_port('br0')) return 'br0'; + if (lan_port('bond0')) return 'bond0'; + if (lan_port('eth0')) return 'eth0'; + if (lan_port('wlan0')) return 'wlan0'; + return ''; + } + + public static function host() { + $port = static::port(); + if (!$port) return ''; + $port = lan_port($port,true)==0 && lan_port('wlan0') ? 'wlan0' : $port; + return exec("ip -br -4 addr show $port scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}'"); + } } ?> diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php b/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php index 3b12a9507..8cc1d6670 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php @@ -1,6 +1,6 @@ getAllInfo(); $docker = []; @@ -144,23 +147,25 @@ foreach ($containers as $ct) { $ports_internal = []; $ports_external = []; if (isset($ct['Ports']['vlan'])) { - foreach ($ct['Ports']['vlan'] as $i) + foreach ($ct['Ports']['vlan'] as $i) { $ports_external[] = sprintf('%s', $i); + } $ports_internal[0] = sprintf('%s', 'all'); } foreach($ct['Networks'] as $netName => $netVals) { $networks[] = $netName; $network_ips[] = $running ? $netVals['IPAddress'] : null; - if (isset($ct['Networks']['host'])) { $ports_external[] = sprintf('%s', $netVals['IPAddress']); $ports_internal[0] = sprintf('%s', 'all'); - } else if (!isset($ct['Ports']['vlan']) || strpos($ct['NetworkMode'], 'container:') != 0) { + } elseif (!isset($ct['Ports']['vlan']) || strpos($ct['NetworkMode'],'container:')!==false) { foreach ($ct['Ports'] as $port) { - if (_var($port,'PublicPort') && _var($port,'Driver') == 'bridge') + if (_var($port,'PublicPort') && _var($port,'Driver') == 'bridge') { $ports_external[] = sprintf('%s:%s', $host, strtoupper(_var($port,'PublicPort'))); - if ((!isset($ct['Networks']['host'])) || (!isset($ct['Networks']['vlan']))) + } + if ((!isset($ct['Networks']['host'])) || (!isset($ct['Networks']['vlan']))) { $ports_internal[] = sprintf('%s:%s', _var($port,'PrivatePort'), strtoupper(_var($port,'Type'))); + } } } } @@ -246,7 +251,7 @@ foreach ($containers as $ct) { if (!empty($TS_version)) { if (!empty($TS_latest_version)) { if (version_compare($TS_version, $TS_latest_version, '<')) { - $TSinfo .= "
"._("Tailscale:")."v" . $TS_version . " ➔ v" . $TS_latest_version . " "._("available!")."
"; + $TSinfo .= "
"._("Tailscale:")."v".$TS_version." ➔ v".$TS_latest_version." "._("available!")."
"; } else { $TSinfo .= "
"._("Tailscale").":v".$TS_version."
"; } diff --git a/emhttp/plugins/dynamix.docker.manager/include/Helpers.php b/emhttp/plugins/dynamix.docker.manager/include/Helpers.php index 28dab85c6..706790bee 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/Helpers.php +++ b/emhttp/plugins/dynamix.docker.manager/include/Helpers.php @@ -1,6 +1,6 @@ getDockerContainers() as $ct) { $list = $port = []; diff --git a/emhttp/plugins/dynamix/include/Wrappers.php b/emhttp/plugins/dynamix/include/Wrappers.php index 37e4be227..36e5c4d63 100644 --- a/emhttp/plugins/dynamix/include/Wrappers.php +++ b/emhttp/plugins/dynamix/include/Wrappers.php @@ -1,6 +1,6 @@ =')) return $remote; } } + function _var(&$name, $key=null, $default='') { return is_null($key) ? ($name ?? $default) : ($name[$key] ?? $default); } + function celsius($temp) { return round(($temp-32)*5/9); } + function fahrenheit($temp) { return round(9/5*$temp)+32; } + function displayTemp($temp) { global $display; return (is_numeric($temp) && _var($display,'unit')=='F') ? fahrenheit($temp) : $temp; } + function get_value(&$name, $key, $default) { global $var; $value = $name[$key] ?? -1; return $value!==-1 ? $value : ($var[$key] ?? $default); } + function get_ctlr_options(&$type, &$disk) { if (!$type) return; $ports = []; @@ -106,12 +119,15 @@ function get_ctlr_options(&$type, &$disk) { if (isset($disk['smPort3'])) $ports[] = $disk['smPort3']; $type .= ($ports ? ','.implode($disk['smGlue'] ?? ',',$ports) : ''); } + function port_name($port) { return substr($port,-2)!='n1' ? $port : substr($port,0,-2); } + function exceed($value, $limit, $top=100) { return is_numeric($value) && $limit>0 ? ($value>$limit && $value<=$top) : false; } + function ipaddr($ethX='eth0', $prot=4) { global $$ethX; switch (_var($$ethX,'PROTOCOL:0')) { @@ -128,16 +144,20 @@ function ipaddr($ethX='eth0', $prot=4) { return _var($$ethX,'IPADDR:0'); } } + function no_tilde($name) { global $_tilde_ ,$_proxy_; return str_replace($_tilde_,$_proxy_,$name); } + function prefix($key) { return preg_replace('/\d+$/','',$key); } + function pool_name($key) { return preg_replace('/(\d+$|~.*$)/', '', $key); } + function native($name, $full=0) { global $_tilde_, $_arrow_; switch ($full) { @@ -145,11 +165,13 @@ function native($name, $full=0) { case 1: return strpos($name,$_tilde_)!==false ? "$_arrow_ ".explode($_tilde_,$name)[1] : $name; } } + function isSubpool($name) { global $subpools, $_tilde_; $subpool = my_explode($_tilde_,$name)[1]; return in_array($subpool,$subpools) ? $subpool : false; } + function get_nvme_info($device, $info) { switch ($info) { case 'temp': @@ -167,15 +189,18 @@ function get_nvme_info($device, $info) { return exec("smartctl -c /dev/$device 2>/dev/null | grep -Pom1 '^ *$state [+-] +\K[^W]+'"); } } + // convert strftime to date format function my_date($fmt, $time) { $legacy = ['%c' => 'D j M Y h:i A','%A' => 'l','%Y' => 'Y','%B' => 'F','%e' => 'j','%d' => 'd','%m' => 'm','%I' => 'h','%H' => 'H','%M' => 'i','%S' => 's','%p' => 'a','%R' => 'H:i', '%F' => 'Y-m-d', '%T' => 'H:i:s']; return date(strtr($fmt,$legacy), $time); } + // ensure params passed to logger are properly escaped function my_logger($message, $logger='webgui') { exec('logger -t '.escapeshellarg($logger).' -- '.escapeshellarg($message)); } + // Original PHP code by Chirp Internet: www.chirpinternet.eu // Please acknowledge use of this code by including this header. // https://www.the-art-of-web.com/php/http-get-contents/ @@ -226,6 +251,7 @@ function http_get_contents(string $url, array $opts = [], array &$getinfo = NULL curl_close($ch); return $out; } + /** * Detect network connectivity via Network Connectivity Status Indicator * @return bool @@ -235,4 +261,10 @@ function check_network_connectivity(): bool { $out = http_get_contents($url); return ($out=="Microsoft NCSI"); } + +function lan_port($port, $state=false) { + $system = '/sys/class/net'; + $exist = file_exists("$system/$port"); + return !$state ? $exist : ($exist ? file_get_contents("$system/$port/carrier") : false); +} ?> diff --git a/sbin/create_network_ini b/sbin/create_network_ini index fb5a1bd55..645aa1a37 100755 --- a/sbin/create_network_ini +++ b/sbin/create_network_ini @@ -2,8 +2,8 @@ # # script: create_network_ini # -# Copyright 2005-2023, Lime Technology -# Copyright 2012-2023, Bergware International. +# Copyright 2005-2025, Lime Technology +# Copyright 2012-2025, Bergware International. # # create initial network.ini file on system start # create system welcome message @@ -241,15 +241,15 @@ if [[ -z $interface || "eth0 br0 bond0 wlan0" =~ $interface ]]; then # find management interface [[ -e /sys/class/net/bond0 ]] && dev=bond0 || dev=eth0 [[ -e /sys/class/net/br0 ]] && dev=br0 - IPv4=$(ip -br -4 addr show $dev scope global | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') - IPv6=$(ip -br -6 addr show $dev scope global -temporary -deprecated | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') + IPv4=$(ip -br -4 addr show $dev scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}') + IPv6=$(ip -br -6 addr show $dev scope global -temporary -deprecated | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}') # show current IP assignment [[ -n $IPv4 ]] && echo " IPv4 address: $IPv4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue [[ -n $IPv6 ]] && echo " IPv6 address: $IPv6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue if [[ -e /sys/class/net/wlan0 ]]; then echo "Wireless network:" >>/etc/issue - IPv4=$(ip -br -4 addr show wlan0 scope global | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') - IPv6=$(ip -br -6 addr show wlan0 scope global -temporary -deprecated | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') + IPv4=$(ip -br -4 addr show wlan0 scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}') + IPv6=$(ip -br -6 addr show wlan0 scope global -temporary -deprecated | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}') [[ -n $IPv4 ]] && echo " IPv4 address: $IPv4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue [[ -n $IPv6 ]] && echo " IPv6 address: $IPv6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue fi