Commit 8a02c8b9 authored by jan.koester's avatar jan.koester
Browse files

test

parent 5e1f2c64
Loading
Loading
Loading
Loading
+4 −3
Changes for modules/containers/containers.cpp: 4 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *   list                  -> {containers, images, jobs, bridges} or
 *                            {unavailable} when containerd isn't there
 *       containers: [{name, image, state, pid, started, exitCode, restarts,
 *           error?, network, address?, autostart, restart, memory, tasks}]
 *           error?, network, address?, lease?, autostart, restart, memory, tasks}]
 *       images: [{image, id, digest, size, layers, created, pulled,
 *           architecture, entrypoint?, cmd?, workdir?, user?, env[], ports[],
 *           volumes[], usedBy[]}]
@@ -41,7 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *   create {container}    a container: name, image, entrypoint[], args[],
 *   update {name, container}   env[], user, workdir, hostname, boot,
 *                         autostart, restart, network, bridge, address,
 *                         gateway, dns[], binds[], tmpfs[], readOnly,
 *                         gateway, mac, dns[], binds[], tmpfs[], devices[], readOnly,
 *                         memoryMax, tasksMax, capabilities[],
 *                         dropCapabilities[] (update: name renames)
 *   delete {name}         (its files go in the background)
@@ -78,7 +78,7 @@ const std::set<std::string> Numbers = {"pid", "started", "exit_code", "restarts"
// repeated keys -> JSON list names
const std::vector<std::pair<std::string, std::string>> Lists = {
    {"entrypoint", "entrypoint"}, {"arg", "args"}, {"env", "env"}, {"dns", "dns"}, {"bind", "binds"},
    {"tmpfs", "tmpfs"}, {"capability", "capabilities"}, {"drop_capability", "dropCapabilities"},
    {"tmpfs", "tmpfs"}, {"device", "devices"}, {"capability", "capabilities"}, {"drop_capability", "dropCapabilities"},
    {"port", "ports"}, {"volume", "volumes"}, {"used_by", "usedBy"}};

std::string camel(const std::string &k) {
@@ -240,6 +240,7 @@ std::string settingsFields(json_object *c, Fields &f, bool create) {
    text("bridge", "bridge");
    text("address", "address");
    text("gateway", "gateway");
    text("mac", "mac");
    flag("readOnly", "read_only");
    number("memoryMax", "memory_max");
    number("tasksMax", "tasks_max");
+25 −6
Changes for www/modules/containers.js: 25 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -30,6 +30,12 @@
    'Host network (like nspawn without --private-network)': 'Netzwerk des Hosts (wie nspawn ohne --private-network)',
    'Only loopback': 'Nur Loopback', 'Own address in a bridge': 'Eigene Adresse in einer Bridge',
    'Bridge': 'Bridge', 'Address (CIDR)': 'Adresse (CIDR)', 'Gateway': 'Gateway', 'DNS servers': 'DNS-Server',
    'Address from DHCP': 'Adresse per DHCP', 'MAC address': 'MAC-Adresse',
    'default: made from the name (stays the same)': 'Vorgabe: aus dem Namen (bleibt gleich)',
    'Devices (one per line, e.g. /dev/dri for an Intel GPU)': 'Geräte (eines pro Zeile, z. B. /dev/dri für eine Intel-GPU)',
    'The container may use only these devices (and /dev/null & co.); its user gets their groups (render, video).':
      'Der Container darf nur diese Geräte benutzen (und /dev/null & Co.); sein Benutzer bekommt ihre Gruppen (render, video).',
    'DHCP: {0}': 'DHCP: {0}', 'DHCP': 'DHCP',
    'separated by blanks; empty: the host\'s': 'durch Leerzeichen getrennt; leer: die des Hosts',
    'No bridge yet: create one under Network.': 'Noch keine Bridge: unter Netzwerk anlegen.',
    'The image listens on {0}.': 'Das Image lauscht auf {0}.',
@@ -188,14 +194,21 @@
        const net = h('select', {name: 'network'},
          [['host', t('Host network (like nspawn without --private-network)')], ['none', t('Only loopback')],
           ['bridge', t('Own address in a bridge')]].map(([v, l]) => h('option', {value: v, selected: c.network === v}, l)));
        const dhcp = h('input', {type: 'checkbox', name: 'dhcp', checked: c.address === 'dhcp'});
        const staticBox = h('div', {class: 'row'},
          h('label', {}, t('Address (CIDR)'), h('input', {name: 'address', value: c.address === 'dhcp' ? '' : (c.address || ''), placeholder: '192.168.1.50/24'})),
          h('label', {}, t('Gateway'), h('input', {name: 'gateway', value: c.gateway || '', placeholder: '192.168.1.1'})));
        const bridgeBox = h('div', {},
          h('div', {class: 'row'},
            h('label', {}, t('Bridge'), h('select', {name: 'bridge'},
              bridges.map(b => h('option', {value: b, selected: b === c.bridge}, b)),
              c.bridge && !bridges.includes(c.bridge) ? h('option', {value: c.bridge, selected: true}, c.bridge) : null)),
            h('label', {}, t('Address (CIDR)'), h('input', {name: 'address', value: c.address || '', placeholder: '192.168.1.50/24'})),
            h('label', {}, t('Gateway'), h('input', {name: 'gateway', value: c.gateway || '', placeholder: '192.168.1.1'}))),
            h('label', {}, t('MAC address'), h('input', {name: 'mac', value: c.mac || '', placeholder: t('default: made from the name (stays the same)')}))),
          h('label', {class: 'check'}, dhcp, t('Address from DHCP')),
          staticBox,
          bridges.length ? null : h('p', {class: 'hint'}, t('No bridge yet: create one under Network.')));
        dhcp.addEventListener('change', () => { staticBox.hidden = dhcp.checked; });
        staticBox.hidden = dhcp.checked;
        const portsHint = h('p', {class: 'hint'});
        const volumesHint = h('p', {class: 'hint'});
        const entry = h('input', {name: 'entrypoint', value: joinWords(c.entrypoint), class: 'mono'});
@@ -246,6 +259,8 @@
              h('label', {}, t('Working directory'), workdir),
              h('label', {}, t('Host name'), h('input', {name: 'hostname', value: c.hostname || '', placeholder: c.name || ''}))),
            h('label', {}, t('tmpfs directories (one per line)'), area('tmpfs', c.tmpfs, 2)),
            h('label', {}, t('Devices (one per line, e.g. /dev/dri for an Intel GPU)'), area('devices', c.devices, 2)),
            h('p', {class: 'hint'}, t('The container may use only these devices (and /dev/null & co.); its user gets their groups (render, video).')),
            h('div', {class: 'row'},
              h('label', {}, t('Memory limit (MiB, 0: none)'),
                h('input', {name: 'memoryMax', type: 'number', min: 0, value: Math.round((c.memoryMax || 0) / 1048576)})),
@@ -264,9 +279,11 @@
        const mem = Number(d.memoryMax) || 0;
        const container = {
          name: d.name.trim(), image: d.image, autostart: d.autostart, restart: d.restart, network: d.network,
          bridge: d.network === 'bridge' ? (d.bridge || '') : '', address: d.network === 'bridge' ? d.address.trim() : '',
          gateway: d.network === 'bridge' ? d.gateway.trim() : '', dns: words(d.dns), args: words(d.args),
          entrypoint: words(d.entrypoint), env: lines(d.env), binds: lines(d.binds), tmpfs: lines(d.tmpfs),
          bridge: d.network === 'bridge' ? (d.bridge || '') : '',
          address: d.network !== 'bridge' ? '' : d.dhcp ? 'dhcp' : d.address.trim(),
          gateway: d.network === 'bridge' && !d.dhcp ? d.gateway.trim() : '', mac: d.network === 'bridge' ? d.mac.trim() : '',
          dns: words(d.dns), args: words(d.args),
          entrypoint: words(d.entrypoint), env: lines(d.env), binds: lines(d.binds), tmpfs: lines(d.tmpfs), devices: lines(d.devices),
          user: d.user.trim(), workdir: d.workdir.trim(), hostname: d.hostname.trim(),
          memoryMax: mem * 1048576, tasksMax: Number(d.tasksMax) || 0,
          capabilities: words(d.capabilities), dropCapabilities: words(d.dropCapabilities),
@@ -309,7 +326,9 @@
          {title: t('Name'), render: c => h('strong', {}, c.name)},
          {title: t('Image'), render: c => h('span', {class: 'mono'}, c.image || '')},
          {title: t('State'), render: stateCell},
          {title: t('Network'), render: c => c.network === 'bridge' ? h('span', {class: 'mono'}, c.address || t('bridge')) : t(c.network || '')},
          {title: t('Network'), render: c => c.network !== 'bridge' ? t(c.network || '')
            : c.address === 'dhcp' ? h('span', {class: 'mono'}, c.lease ? t('DHCP: {0}', c.lease) : t('DHCP'))
            : h('span', {class: 'mono'}, c.address || t('bridge'))},
          {title: t('Memory'), render: c => c.state === 'running' && c.memory ? mib(c.memory) : ''},
          {title: '', class: 'actions', render: c => {
            const up = c.state === 'running' || c.state === 'starting' || c.state === 'stopping';