mirror of
https://github.com/openwrt/luci.git
synced 2026-05-31 02:21:50 +08:00
luci-app-dockerman: network aliases feature
Add network aliases to container view/create. Also init with ipv6 settings. Signed-off-by: Serhii Ivanov <icegood1980@gmail.com>
This commit is contained in:
+27
-5
@@ -308,6 +308,7 @@ return dm2.dv.extend({
|
||||
DNSNames: net?.DNSNames || '',
|
||||
IPv4Address: net?.IPAMConfig?.IPv4Address || net?.IPAddress || '',
|
||||
IPv6Address: net?.IPAMConfig?.IPv6Address || '',
|
||||
Aliases: net?.Aliases || '',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -582,6 +583,8 @@ return dm2.dv.extend({
|
||||
|
||||
o = ss.option(form.DummyValue, 'DNSNames', _('DNS Names'));
|
||||
|
||||
o = ss.option(form.DummyValue, 'Aliases', _('Aliases'));
|
||||
|
||||
ss.handleAdd = function(ev) {
|
||||
ev.preventDefault();
|
||||
view.executeNetworkAction('connect', null, null, this_container);
|
||||
@@ -1884,7 +1887,7 @@ return dm2.dv.extend({
|
||||
|
||||
const ip4Input = E('input', {
|
||||
'type': 'text',
|
||||
'id': 'network-ip',
|
||||
'id': 'network-ip4',
|
||||
'class': 'cbi-input-text',
|
||||
'placeholder': 'e.g., 172.18.0.5',
|
||||
'style': 'width:100%; margin-top:5px;'
|
||||
@@ -1892,18 +1895,29 @@ return dm2.dv.extend({
|
||||
|
||||
const ip6Input = E('input', {
|
||||
'type': 'text',
|
||||
'id': 'network-ip',
|
||||
'id': 'network-ip6',
|
||||
'class': 'cbi-input-text',
|
||||
'placeholder': 'e.g., 2001:db8:1::1',
|
||||
'style': 'width:100%; margin-top:5px;'
|
||||
});
|
||||
|
||||
const aliasesInput = E('input', {
|
||||
'type': 'text',
|
||||
'id': 'network-aliases',
|
||||
'class': 'cbi-input-text',
|
||||
'placeholder': 'e.g., database,db (comma-separated)',
|
||||
'style': 'width:100%; margin-top:5px;'
|
||||
});
|
||||
|
||||
const modalBody = E('div', { 'class': 'cbi-section' }, [
|
||||
E('p', {}, _('Select network to connect:')),
|
||||
networkSelect,
|
||||
E('label', { 'style': 'display:block; margin-top:10px;' }, _('IP Address (optional):')),
|
||||
E('label', { 'style': 'display:block; margin-top:10px;' }, _('IPv4 Address (optional):')),
|
||||
ip4Input,
|
||||
E('label', { 'style': 'display:block; margin-top:10px;' }, _('IPv6 Address (optional):')),
|
||||
ip6Input,
|
||||
E('label', { 'style': 'display:block; margin-top:10px;' }, _('Aliases (optional):')),
|
||||
aliasesInput,
|
||||
]);
|
||||
|
||||
ui.showModal(_('Connect Network'), [
|
||||
@@ -1919,7 +1933,9 @@ return dm2.dv.extend({
|
||||
'click': () => {
|
||||
const selectedNetwork = networkSelect.value;
|
||||
const ip4Address = ip4Input.value || '';
|
||||
// const ip6Address = ip6Input.value || '';
|
||||
const ip6Address = ip6Input.value || '';
|
||||
const aliasesRaw = aliasesInput.value || '';
|
||||
const aliases = aliasesRaw.split(',').map(a => a.trim()).filter(Boolean);
|
||||
|
||||
if (!selectedNetwork) {
|
||||
view.showNotification(_('Error'), [_('No network selected')], 5000, 'error');
|
||||
@@ -1929,7 +1945,13 @@ return dm2.dv.extend({
|
||||
ui.hideModal();
|
||||
|
||||
const body = { Container: this_container.Id };
|
||||
body.EndpointConfig = { IPAMConfig: { IPv4Address: ip4Address } }; //, IPv6Address: ip6Address || null
|
||||
body.EndpointConfig = {
|
||||
IPAMConfig: {
|
||||
IPv4Address: ip4Address || null,
|
||||
IPv6Address: ip6Address || null
|
||||
},
|
||||
Aliases: aliases.length > 0 ? aliases : null
|
||||
};
|
||||
|
||||
view.executeDockerAction(
|
||||
dm2.network_connect,
|
||||
|
||||
+22
-10
@@ -73,7 +73,8 @@ return dm2.dv.extend({
|
||||
const hostConfig = c.HostConfig || {};
|
||||
const resolvedImage = resolveImageId(c.Image) || resolveImageId(c.Config?.Image) || c.Image || c.Config?.Image || '';
|
||||
const builtInNetworks = new Set(['none', 'bridge', 'host']);
|
||||
const [netnames, nets] = Object.entries(c.NetworkSettings?.Networks || {});
|
||||
// Object.entries returns [[name, obj], ...] — pick the first network
|
||||
const [[firstName, firstNet] = []] = Object.entries(c.NetworkSettings?.Networks || {});
|
||||
|
||||
containerData.container = {
|
||||
name: c.Name?.substring(1) || '',
|
||||
@@ -82,20 +83,22 @@ return dm2.dv.extend({
|
||||
image: resolvedImage,
|
||||
privileged: hostConfig.Privileged ? 1 : 0,
|
||||
restart_policy: hostConfig.RestartPolicy?.Name || 'unless-stopped',
|
||||
network: (() => {
|
||||
return (netnames && (netnames.length > 0)) ? netnames[0] : '';
|
||||
network: firstName || '',
|
||||
network_aliases: (() => {
|
||||
if (!firstName || builtInNetworks.has(firstName)) return '';
|
||||
return (firstNet?.Aliases || []).join(', ');
|
||||
})(),
|
||||
ipv4: (() => {
|
||||
if (builtInNetworks.has(netnames[0])) return '';
|
||||
return (nets && (nets.length > 0)) ? nets[0]?.IPAddress || '' : '';
|
||||
if (!firstName || builtInNetworks.has(firstName)) return '';
|
||||
return firstNet?.IPAddress || '';
|
||||
})(),
|
||||
ipv6: (() => {
|
||||
if (builtInNetworks.has(netnames[0])) return '';
|
||||
return (nets && (nets.length > 0)) ? nets[0]?.GlobalIPv6Address || '' : '';
|
||||
if (!firstName || builtInNetworks.has(firstName)) return '';
|
||||
return firstNet?.GlobalIPv6Address || '';
|
||||
})(),
|
||||
ipv6_lla: (() => {
|
||||
if (builtInNetworks.has(netnames[0])) return '';
|
||||
return (nets && (nets.length > 0)) ? nets[0]?.LinkLocalIPv6Address || '' : '';
|
||||
if (!firstName || builtInNetworks.has(firstName)) return '';
|
||||
return firstNet?.LinkLocalIPv6Address || '';
|
||||
})(),
|
||||
link: hostConfig.Links || [],
|
||||
dns: hostConfig.Dns || [],
|
||||
@@ -272,6 +275,11 @@ return dm2.dv.extend({
|
||||
o.datatype = 'ip6ll';
|
||||
o.validate = not_with_a_docker_net;
|
||||
|
||||
o = s.option(form.Value, 'network_aliases', _('Network Aliases'));
|
||||
o.rmempty = true;
|
||||
o.placeholder = 'database,db (CSV)';
|
||||
o.validate = not_with_a_docker_net;
|
||||
|
||||
o = s.option(form.DynamicList, 'link', _('Links with other containers'));
|
||||
o.rmempty = true;
|
||||
o.placeholder='container_name:alias';
|
||||
@@ -762,6 +770,7 @@ return dm2.dv.extend({
|
||||
const name = get('name');
|
||||
// const pull = toBool(get('pull'));
|
||||
const network = get('network');
|
||||
const network_aliases = get('network_aliases');
|
||||
const publish = get('publish');
|
||||
const command = get('command');
|
||||
// const publish_all = toBool(get('publish_all'));
|
||||
@@ -829,7 +838,10 @@ return dm2.dv.extend({
|
||||
Sysctls: sysctl ? listToKv(sysctl) : undefined,
|
||||
},
|
||||
NetworkingConfig: {
|
||||
EndpointsConfig: { [network]: { IPAMConfig: { IPv4Address: get('ipv4') || null, IPv6Address: get('ipv6') || null } } },
|
||||
EndpointsConfig: { [network]: {
|
||||
IPAMConfig: { IPv4Address: get('ipv4') || null, IPv6Address: get('ipv6') || null },
|
||||
Aliases: network_aliases ? network_aliases.split(',').map(a => a.trim()).filter(Boolean) : null
|
||||
} },
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user