/** * javascript/volumes.js * * Volumes panel: named-volume table + create/remove, backed by * ajax/volumes.php. Container-level bind mounts (e.g. appdata under * /mnt/user/appdata/...) are deliberately not shown here, since they * aren't a libpod-managed resource at all — see that file's header * comment. A named volume created here WITH a host path (v.hostPath) IS * still a real, listed podman volume, just backed by that path instead * of podman's own internal storage — see PodmanClient::createVolume(). */ (function () { 'use strict'; const P = window.Podman; let volumes = []; function rowHtml(v) { const pathCell = v.hostPath ? P.escapeHtml(v.hostPath) + ' bind' : P.escapeHtml(v.mountpoint); return '' + '' + '' + P.escapeHtml(v.name) + '' + '' + P.escapeHtml(v.driver) + '' + '' + pathCell + '' + '' + v.usedBy + '' + '' + ''; } function render() { const tbody = P.el('volumes-tbody'); tbody.innerHTML = volumes.length ? volumes.map(rowHtml).join('') : 'No named volumes.'; } function load() { const tbody = P.el('volumes-tbody'); tbody.innerHTML = P.loadingRow(5); return P.get('volumes', 'list').then(function (data) { volumes = data; render(); }).catch(function (err) { tbody.innerHTML = P.errorRow(5, err.message); }); } function init() { P.el('volumes-create-btn').addEventListener('click', function () { P.openFormModal({ title: 'New Volume', submitLabel: 'Create', fields: [ { name: 'name', label: 'Volume name', required: true, placeholder: 'my-volume' }, { name: 'path', label: 'Host path (optional)', placeholder: '/mnt/cache/appdata/my-volume', hint: 'Leave empty for a podman-managed volume. Set this to bind the volume ' + 'directly to an existing directory on disk (e.g. a cache pool path) instead.', }, ], onSubmit: function (values) { return P.post('volumes', 'create', { name: values.name, path: values.path || undefined }).then(load); }, }); }); P.el('volumes-tbody').addEventListener('click', function (e) { const btn = e.target.closest('button[data-action="remove"]'); if (!btn || btn.disabled) return; const name = btn.closest('tr').dataset.name; if (!confirm('Remove volume "' + name + '"? This deletes its data.')) return; btn.disabled = true; P.post('volumes', 'remove', { name: name }).then(load).catch(function (err) { alert('Remove failed: ' + err.message); btn.disabled = false; }); }); return load(); } P.registerPanel('volumes', { init: init, refresh: load }); })();