diff --git a/plugins/dynamix.docker.manager/include/CreateDocker.php b/plugins/dynamix.docker.manager/include/CreateDocker.php index 5ca38354d..b23eabf5a 100644 --- a/plugins/dynamix.docker.manager/include/CreateDocker.php +++ b/plugins/dynamix.docker.manager/include/CreateDocker.php @@ -35,7 +35,47 @@ $subnet = ['bridge'=>'', 'host'=>'', 'none'=>'']; foreach ($custom as $network) $subnet[$network] = substr(DockerUtil::docker("network inspect --format='{{range .IPAM.Config}}{{.Subnet}}, {{end}}' $network"),0,-1); +exec('cat /sys/devices/system/cpu/*/topology/thread_siblings_list|sort -nu', $cpus); +function cpu_pinning() { + global $xml,$cpus; + $row1 = $row2 = []; + $vcpu = explode(',',$xml['CPUset'] ?? ''); + $total = count($cpus); + $loop = floor(($total-1)/22)+1; + for ($c = 0; $c < $loop; $c++) { + $row1[$c] = $row1[$c] = []; + $max = ($c == $loop-1 ? ($total%22?:22) : 22); + for ($n = 0; $n < $max; $n++) { + unset($cpu1,$cpu2); + list($cpu1, $cpu2) = preg_split('/[,-]/',$cpus[$c*22+$n]); + $row1[$c][] .="$cpu1"; + if ($cpu2) $row2[$c][] .= "$cpu2"; + } + } + //$title = implode('
',array_fill(0,$loop,'CPU:'.($cpu2 ? '
HT:':''))); + for ($c = 0; $c < $loop; $c++) { + if ($c) echo '
'; + echo "CPU:".implode($row1[$c]); + if ($row2[$c]) echo "
HT:".implode($row2[$c]); + } +/* + foreach ($cpus as $pair) { + unset($cpu1,$cpu2); + list($cpu1, $cpu2) = preg_split('/[,-]/',$pair); + $check1 = in_array($cpu1, $vcpu) ? ' checked':''; + $check2 = $cpu2 ? (in_array($cpu2, $vcpu) ? ' checked':''):''; + if ($cpu2) { + $row1[] = "$cpu1"; + $row2[] = "$cpu2"; + } else { + $row1[] = "$cpu1"; + } + } + echo "CPU:".implode($row1); + if ($row2) echo "
HT:".implode($row2); +*/ +} # ██████╗ ██████╗ ██████╗ ███████╗ # ██╔════╝██╔═══██╗██╔══██╗██╔════╝ @@ -251,6 +291,7 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t .switch-button-label.off{color:inherit;} .selectVariable{width:320px} .fa.button{color:maroon;font-size:24px;position:relative;top:4px;cursor:pointer} +span.cpu{display:inline-block;width:50px} @@ -524,6 +565,9 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t $(form).find('input[name="confTarget[]"]').each(function(){targets.push($(this));}); for (var i=0; i < types.length; i++) if (types[i]=='Port') $(targets[i]).val($(values[i]).val()); } + var vcpu = []; + $(form).find('input[id^="box"]').each(function(){if ($(this).prop('checked')) vcpu.push($('#'+$(this).prop('id').replace('box','cpu')).text());}); + form.contCPUset.value = vcpu.join(','); } function makeName(type) { @@ -664,6 +708,7 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t
+ doesContainerExist($templateName)): echo "\n"; endif; @@ -902,8 +947,6 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t @@ -920,6 +963,20 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t + + + + + + + + + + >

If you wish to append additional commands to your Docker container at run-time, you can specify them here.
- For example, if you wish to pin an application to live on a specific CPU core, you can enter "--cpuset=0" in this field. - Change 0 to the core # on your system (starting with 0). You can pin multiple cores by separation with a comma or a range of cores by separation with a dash. For all possible Docker run-time commands, see here: https://docs.docker.com/reference/run/

CPU Pinning:
+
+

Help text for CPU pinning.

+
+
Network Type: diff --git a/plugins/dynamix.docker.manager/include/DockerClient.php b/plugins/dynamix.docker.manager/include/DockerClient.php index b0962de31..cb087ca67 100644 --- a/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/plugins/dynamix.docker.manager/include/DockerClient.php @@ -269,6 +269,7 @@ class DockerTemplates { $tmp['running'] = $ct['Running']; $tmp['paused'] = $ct['Paused']; $tmp['autostart'] = in_array($name, $autoStart); + $tmp['cpuset'] = $ct['CPUset']; if (!is_file($tmp['icon']) || $reload) $tmp['icon'] = $this->getIcon($image); if ($ct['Running']) { $port = &$ct['Ports'][0]; @@ -725,6 +726,7 @@ class DockerClient { $c['Volumes'] = $info['HostConfig']['Binds']; $c['Created'] = $this->humanTiming($ct['Created']); $c['NetworkMode'] = $ct['HostConfig']['NetworkMode']; + $c['CPUset'] = $info['HostConfig']['CpusetCpus']; $c['BaseImage'] = $ct['Labels']['BASEIMAGE'] ?? false; $c['Ports'] = []; if ($driver[$c['NetworkMode']]=='bridge') { diff --git a/plugins/dynamix.docker.manager/include/Helpers.php b/plugins/dynamix.docker.manager/include/Helpers.php index 9af2577dc..388c6f245 100644 --- a/plugins/dynamix.docker.manager/include/Helpers.php +++ b/plugins/dynamix.docker.manager/include/Helpers.php @@ -29,6 +29,7 @@ function postToXML($post, $setOwnership=false) { $xml->Icon = xml_encode(trim($post['contIcon'])); $xml->ExtraParams = xml_encode($post['contExtraParams']); $xml->PostArgs = xml_encode($post['contPostArgs']); + $xml->CPUset = xml_encode($post['contCPUset']); $xml->DateInstalled = xml_encode(time()); $xml->DonateText = xml_encode($post['contDonateText']); $xml->DonateLink = xml_encode($post['contDonateLink']); @@ -104,6 +105,7 @@ function xmlToVar($xml) { $out['Icon'] = xml_decode($xml->Icon); $out['ExtraParams'] = xml_decode($xml->ExtraParams); $out['PostArgs'] = xml_decode($xml->PostArgs); + $out['CPUset'] = xml_decode($xml->CPUset); $out['DonateText'] = xml_decode($xml->DonateText); $out['DonateLink'] = xml_decode($xml->DonateLink); $out['Config'] = []; @@ -246,6 +248,7 @@ function xmlToCommand($xml, $create_paths=false) { $cmdPrivileged = strtolower($xml['Privileged'])=='true' ? '--privileged=true' : ''; $cmdNetwork = '--net='.escapeshellarg(strtolower($xml['Network'])); $cmdMyIP = $xml['MyIP'] ? '--ip='.escapeshellarg($xml['MyIP']) : ''; + $cmdCPUset = strlen($xml['CPUset']) ? '--cpuset-cpus='.escapeshellarg($xml['CPUset']) : ''; $Volumes = ['']; $Ports = ['']; $Variables = ['']; @@ -292,8 +295,8 @@ function xmlToCommand($xml, $create_paths=false) { } } - $cmd = sprintf($docroot.'/plugins/dynamix.docker.manager/scripts/docker create %s %s %s %s %s %s %s %s %s %s %s %s', - $cmdName, $cmdNetwork, $cmdMyIP, $cmdPrivileged, implode(' -e ', $Variables), implode(' -l ', $Labels), implode(' -p ', $Ports), implode(' -v ', $Volumes), implode(' --device=', $Devices), $xml['ExtraParams'], escapeshellarg($xml['Repository']), $xml['PostArgs']); + $cmd = sprintf($docroot.'/plugins/dynamix.docker.manager/scripts/docker create %s %s %s %s %s %s %s %s %s %s %s %s %s', + $cmdName, $cmdNetwork, $cmdMyIP, $cmdCPUset, $cmdPrivileged, implode(' -e ', $Variables), implode(' -l ', $Labels), implode(' -p ', $Ports), implode(' -v ', $Volumes), implode(' --device=', $Devices), $xml['ExtraParams'], escapeshellarg($xml['Repository']), $xml['PostArgs']); return [preg_replace('/\s+/', ' ', $cmd), $xml['Name'], $xml['Repository']]; } function stopContainer($name) {