diff --git a/plugins/dynamix.docker.manager/DockerContainers.page b/plugins/dynamix.docker.manager/DockerContainers.page index 7efa73f88..124f89166 100644 --- a/plugins/dynamix.docker.manager/DockerContainers.page +++ b/plugins/dynamix.docker.manager/DockerContainers.page @@ -74,7 +74,7 @@ img.stopped{opacity:0.3;} $info = $DockerTemplates->getAllInfo(); $contextMenus = []; - $IP = $var["IPADDR"]; + $IP = $eth0["IPADDR:0"]; foreach ($all_containers as $ct) { $name = $ct["Name"]; $is_autostart = ($info[$name]['autostart']) ? 'true' : 'false'; diff --git a/plugins/dynamix.docker.manager/include/CreateDocker.php b/plugins/dynamix.docker.manager/include/CreateDocker.php index 02c5276a6..db49f9bd1 100644 --- a/plugins/dynamix.docker.manager/include/CreateDocker.php +++ b/plugins/dynamix.docker.manager/include/CreateDocker.php @@ -2,6 +2,8 @@ /* Copyright 2015, Lime Technology * Copyright 2015, Guilherme Jardim, Eric Schultz, Jon Panozzo. * + * Adaptations by Bergware International (May 2016) + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation. @@ -374,8 +376,10 @@ function xmlToCommand($xml, $create_paths=false) { # Export ports as variable if Network is set to host if (strtolower($xml['Network']) == 'host') { $Variables[] = strtoupper(sprintf('"%s_PORT_%s"="%s"', $Mode, $containerConfig, $hostConfig)); - } else { + # Export ports as port if Network is set to bridge + } elseif (strtolower($xml['Network']) == 'bridge') { $Ports[] = sprintf("%s:%s/%s", $hostConfig, $containerConfig, $Mode); + # No export of ports if Network is set to none } } elseif ($confType == "variable") { $Variables[] = sprintf('"%s"="%s"', $containerConfig, $hostConfig); @@ -421,6 +425,24 @@ function setXmlVal(&$xml, $value, $el, $attr = null, $pos = 0) { $xml = $dom->saveXML(); } +function getUsedPorts() { + global $dockerManPaths; + $docker = new DockerClient(); + $docker = $docker->getDockerContainers(); + if (!$docker) $docker = []; + $names = $ports = []; + foreach ($docker as $ct) $names[] = strtolower($ct['Name']); + foreach (glob($dockerManPaths['templates-user'].'/*.xml',GLOB_NOSORT) as $file) { + $name = strtolower(getXmlVal($file,'Name')); + if (!in_array($name,$names)) continue; + $list = []; $p = 0; + $list['Name'] = $name; + $list['Port'] = ''; + while ($port = getXmlVal($file,'HostPort',null,$p++)) $list['Port'] .= $port.' '; + $ports[] = $list; + } + return $ports; +} # ██████╗ ██████╗ ██████╗ ███████╗ # ██╔════╝██╔═══██╗██╔══██╗██╔════╝ @@ -633,10 +655,10 @@ if ($_GET['xmlTemplate']) { echo ""; } } +echo ""; $authoringMode = ($dockercfg["DOCKER_AUTHORING_MODE"] == "yes") ? true : false; $authoring = $authoringMode ? 'advanced' : 'noshow'; $showAdditionalInfo = ''; - ?> @@ -644,36 +666,15 @@ $showAdditionalInfo = ''; @@ -731,7 +726,7 @@ $showAdditionalInfo = ''; } $('#tab'+this_tab).bind({click:function(){$('#'+elementId).show();}}); for (var x=1; x<=last; x++) if(x != this_tab) $('#tab'+x).bind({click:function(){$('#'+elementId).hide();}}); - + $('.advanced-switch').switchButton({ labels_placement: "left", on_label: 'Advanced View', off_label: 'Basic View'}); $('.advanced-switch').change(function () { var status = $(this).is(':checked'); @@ -768,7 +763,7 @@ $showAdditionalInfo = ''; // Create config nodes using templateDisplayConfig function makeConfig(opts) { confNum += 1; - newConfig = $("#templateDisplayConfig").html(); + var newConfig = $("#templateDisplayConfig").html(); newConfig = newConfig.format(opts.Name, opts.Target, opts.Default, @@ -780,8 +775,10 @@ $showAdditionalInfo = ''; opts.Mask, opts.Value, opts.Buttons, - (opts.Required == "true") ? "required" : "" - ); + (opts.Required == "true") ? "required" : "", + opts.Reference, + opts.Label + ); newConfig = "
"+newConfig+"
"; newConfig = $($.parseHTML(newConfig)); value = newConfig.find("input[name='confValue[]']"); @@ -806,6 +803,15 @@ $showAdditionalInfo = ''; return newConfig.prop('outerHTML'); } + function makeUsedPorts(container,current) { + var html = []; + for (var i=0; i < container.length; i++) { + var highlight = container[i].Name.toLowerCase()==current.toLowerCase() ? "color:#F0000C" : ""; + html.push($("#templateUsedPorts").html().format(highlight,container[i].Name,container[i].Port)); + } + return html.join(''); + } + function getVal(el, name) { var el = $(el).find("*[name="+name+"]"); if (el.length) { @@ -818,6 +824,7 @@ $showAdditionalInfo = ''; function addConfigPopup() { var title = 'Add Configuration'; var popup = $( "#dialogAddConfig" ); + var network = $('select[name="contNetwork"]')[0].selectedIndex; // Load popup the popup with the template info popup.html($("#templatePopupConfig").html()); @@ -826,8 +833,8 @@ $showAdditionalInfo = ''; popup.find(".switch").switchButton({labels_placement:"right",on_label:'YES',off_label:'NO'}); popup.find(".switch-button-background").css("margin-top", "6px"); - // Load Mode field if needed - toggleMode(popup.find("*[name=Type]:first")); + // Load Mode field if needed and enable field + toggleMode(popup.find("*[name=Type]:first"),false); // Start Dialog section popup.dialog({ @@ -849,18 +856,21 @@ $showAdditionalInfo = ''; if ( ! Opts["Name"] ){ Opts["Name"] = makeName(Opts["Type"]); } - Opts.Description = (Opts.Description.length) ? Opts.Description : "Container "+Opts.Type+": "+Opts.Target; + var reference = "Container "+Opts.Type+": "+(Opts.Type != 'Port' || network==0 ? Opts.Target : 'N/A'); + Opts.Reference = reference.replace('Variable','Key'); if (Opts.Required == "true") { - Opts.Buttons = " "; - Opts.Buttons += ""; + Opts.Buttons = " "; + Opts.Buttons += ""; } else { - Opts.Buttons = " "; - Opts.Buttons += ""; + Opts.Buttons = " "; + Opts.Buttons += ""; } - Opts.Number = confNum; + Opts.Number = confNum; + Opts.Label = Opts.Type != 'Variable' ? 'Host '+Opts.Name : Opts.Name; newConf = makeConfig(Opts); $("#configLocation").append(newConf); reloadTriggers(); + $('input[name="contName"]').trigger('change'); // signal change }, Cancel: function() { $(this).dialog("close"); @@ -873,9 +883,10 @@ $showAdditionalInfo = ''; $(".ui-button-text").css('padding','0px 5px'); } - function editConfigPopup(num) { + function editConfigPopup(num,disabled) { var title = 'Edit Configuration'; var popup = $("#dialogAddConfig"); + var network = $('select[name="contNetwork"]')[0].selectedIndex; // Load popup the popup with the template info popup.html($("#templatePopupConfig").html()); @@ -894,7 +905,7 @@ $showAdditionalInfo = ''; // Load Mode field if needed var mode = config.find("input[name='confMode[]']").val(); - toggleMode(popup.find("*[name=Type]:first")); + toggleMode(popup.find("*[name=Type]:first"),disabled); popup.find("*[name=Mode]:first").val(mode); // Add switchButton to checkboxes @@ -917,15 +928,17 @@ $showAdditionalInfo = ''; ["Name","Target","Default","Mode","Description","Type","Display","Required","Mask","Value"].forEach(function(e){ Opts[e] = getVal(Element, e); }); - Opts.Description = (Opts.Description.length) ? Opts.Description : "Container "+Opts.Type+": "+Opts.Target; + var reference = "Container "+Opts.Type+": "+(Opts.Type != 'Port' || network==0 ? Opts.Target : 'N/A'); + Opts.Reference = reference.replace('Variable','Key'); if (Opts.Display == "always-hide" || Opts.Display == "advanced-hide") { - Opts.Buttons = " "; - Opts.Buttons += ""; + Opts.Buttons = " "; + Opts.Buttons += ""; } else { - Opts.Buttons = " "; - Opts.Buttons += ""; + Opts.Buttons = " "; + Opts.Buttons += ""; } - Opts.Number = num; + Opts.Number = num; + Opts.Label = Opts.Type != 'Variable' ? 'Host '+Opts.Name : Opts.Name; newConf = makeConfig(Opts); if (config.hasClass("config_"+Opts.Display)) { config.html(newConf); @@ -938,7 +951,8 @@ $showAdditionalInfo = ''; $("#configLocation").append(newConf); } } - reloadTriggers(); + reloadTriggers(); + $('input[name="contName"]').trigger('change'); // signal change }, Cancel: function() { $(this).dialog("close"); @@ -954,6 +968,17 @@ $showAdditionalInfo = ''; function removeConfig(num) { $('#ConfigNum' + num).fadeOut("fast", function() { $(this).remove(); }); + $('input[name="contName"]').trigger('change'); // signal change + } + + function prepareConfig(form) { + var types = [], values = [], targets = []; + if ($('select[name="contNetwork"]').val()=='host') { + $(form).find('input[name="confType[]"]').each(function(){types.push($(this).val());}); + $(form).find('input[name="confValue[]"]').each(function(){values.push($(this));}); + $(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()); + } } function makeName(type) { @@ -961,7 +986,7 @@ $showAdditionalInfo = ''; return type + " "+i; } - function toggleMode(el) { + function toggleMode(el,disabled) { var mode = $(el).parent().siblings('#Mode'); var valueDiv = $(el).parent().siblings('#Value'); var defaultDiv = $(el).parent().siblings('#Default'); @@ -969,6 +994,7 @@ $showAdditionalInfo = ''; var value = valueDiv.find('input[name=Value]'); var target = targetDiv.find('input[name=Target]'); + var network = $('select[name="contNetwork"]')[0].selectedIndex; value.unbind(); target.unbind(); @@ -978,21 +1004,42 @@ $showAdditionalInfo = ''; targetDiv.css('display', ''); mode.html(''); - var index = $(el)[0].selectedIndex; - if (index == 0) { - // Path - mode.html("
Mode
"); + $(el).prop('disabled',disabled); + switch ($(el)[0].selectedIndex) { + case 0: // Path + mode.html("
Access Mode:
"); value.bind("click", function(){openFileBrowser(this,$(this).val(), 'sh', true, false);}); - } else if (index == 1) { - // Port - mode.html("
Mode
"); + targetDiv.find('#dt1').text('Container Path:'); + valueDiv.find('#dt2').text('Host Path:'); + break; + case 1: // Port + mode.html("
Connection Type:
"); value.addClass("numbersOnly"); - target.addClass("numbersOnly"); - } else if (index == 3) { - // Device - targetDiv.css('display', 'none'); - defaultDiv.css('display', 'none'); + if (network==0) { + if (target.val()) target.prop('disabled',true); else target.addClass("numbersOnly"); + targetDiv.find('#dt1').text('Container Port:'); + targetDiv.show(); + } else { + targetDiv.hide(); + } + if (network==0 || network==1) { + valueDiv.find('#dt2').text('Host Port:'); + valueDiv.show(); + } else { + valueDiv.hide(); + mode.html(''); + } + break; + case 2: // Variable + targetDiv.find('#dt1').text('Key:'); + valueDiv.find('#dt2').text('Value:'); + break; + case 3: // Device + targetDiv.hide(); + defaultDiv.hide(); + valueDiv.find('#dt2').text('Value:'); value.bind("click", function(){openFileBrowser(this,$(this).val(), '', true, true);}); + break; } reloadTriggers(); } @@ -1066,8 +1113,8 @@ $showAdditionalInfo = '';
-
- + +
doesContainerExist($templateName)): echo "\n"; endif; else:?> @@ -1116,12 +1163,18 @@ $showAdditionalInfo = '';

Default templates
- When valid repositories are added to your Docker Repositories page, they will appear in a section on this drop down for you to choose (master categorized by author, then by application template). After selecting a default template, the page will populate with new information about the application in the Description field, and will typically provide instructions for how to setup the container. Select a default template when it is the first time you are configuring this application. + When valid repositories are added to your Docker Repositories page, they will appear in a section on this drop down for you to choose (master categorized by author, then by application template). + After selecting a default template, the page will populate with new information about the application in the Description field, and will typically provide instructions for how to setup the container. + Select a default template when it is the first time you are configuring this application.

User-defined templates
- Once you've added an application to your system through a Default template, the settings you specified are saved to your USB flash device to make it easy to rebuild your applications in the event an upgrade were to fail or if another issue occurred. To rebuild, simply select the previously loaded application from the User-defined list and all the settings for the container will appear populated from your previous setup. Clicking create will redownload the necessary files for the application and should restore you to a working state. To delete a User-defined template, select it from the list above and click the red X to the right of it. + Once you've added an application to your system through a Default template, + the settings you specified are saved to your USB flash device to make it easy to rebuild your applications in the event an upgrade were to fail or if another issue occurred. + To rebuild, simply select the previously loaded application from the User-defined list and all the settings for the container will appear populated from your previous setup. + Clicking create will redownload the necessary files for the application and should restore you to a working state. + To delete a User-defined template, select it from the list above and click the red X to the right of it.

@@ -1140,11 +1193,11 @@ $showAdditionalInfo = ''; - + - + > @@ -1260,7 +1314,8 @@ $showAdditionalInfo = ''; @@ -1271,7 +1326,10 @@ $showAdditionalInfo = ''; @@ -1288,48 +1346,57 @@ $showAdditionalInfo = ''; > > - - + + >
Overview:
Overview:
@@ -1160,7 +1213,8 @@ $showAdditionalInfo = '';
-

The repository for the application on the Docker Registry. Format of authorname/appname. Optionally you can add a : after appname and request a specific version for the container image.

+

The repository for the application on the Docker Registry. Format of authorname/appname. + Optionally you can add a : after appname and request a specific version for the container image.

-

When you click on an application icon from the Docker Containers page, the WebUI option will link to the path in this field. Use [IP} to identify the IP of your host and [PORT:####] replacing the #'s for your port.

+

When you click on an application icon from the Docker Containers page, the WebUI option will link to the path in this field. + Use [IP] to identify the IP of your host and [PORT:####] replacing the #'s for your port.

-

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/

+

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/

-

If the Bridge type is selected, the application’s network access will be restricted to only communicating on the ports specified in the port mappings section. If the Host type is selected, the application will be given access to communicate using any port on the host that isn’t already mapped to another in-use application/service. Generally speaking, it is recommended to leave this setting to its default value as specified per application template.

+

If the Bridge type is selected, the application’s network access will be restricted to only communicating on the ports specified in the port mappings section. + If the Host type is selected, the application will be given access to communicate using any port on the host that isn’t already mapped to another in-use application/service. + Generally speaking, it is recommended to leave this setting to its default value as specified per application template.

IMPORTANT NOTE: If adjusting port mappings, do not modify the settings for the Container port as only the Host port can be adjusted.

Privileged: - Privileged:
-

For containers that require the use of host-device access directly or need full exposure to host capabilities, this option will need to be selected. For more information, see this link: https://docs.docker.com/reference/run/#runtime-privilege-linux-capabilities-and-lxc-configuration

+

For containers that require the use of host-device access directly or need full exposure to host capabilities, this option will need to be selected. +
For more information, see this link: https://docs.docker.com/reference/run/#runtime-privilege-linux-capabilities-and-lxc-configuration

-
- +

+
- - + +
  Show advanced settings ... Show advanced settings ...
- - +
+
- - + + + +
  Add another Path, Port or Variable Show deployed host ports ...
+
+ + + +
Add another Path, Port or Variable

- +
- +
  - + - + - +
@@ -1345,11 +1412,11 @@ $showAdditionalInfo = ''; # ╚█████╔╝███████║ ██║ ███████╗██║ ╚═╝ ██║██║ ███████╗██║ ██║ ██║ ███████╗███████║ # ╚════╝ ╚══════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ ?> -