luci-app-dockerman: lint fixes

Signed-off-by: Paul Donald <newtwen+github@gmail.com>
This commit is contained in:
Paul Donald
2026-02-16 01:39:36 +01:00
parent 6d2eb7fa63
commit 4de7515207
10 changed files with 49 additions and 40 deletions

View File

@@ -78,7 +78,7 @@ const loadPromise = Promise.all([
));
if (dh) {
const isTcp6 = dh.startsWith('tcp6://');
// const isTcp6 = dh.startsWith('tcp6://');
const protocol = dh.includes(':2376') ? 'https://' : 'http://';
dockerHost = dh.replace(/^(tcp|inet)6?:\/\//, protocol);
@@ -125,7 +125,7 @@ function call_docker(method, path, options = {}) {
const host = dockerHost;
const onChunk = options.onChunk || null; // Optional callback for streaming NDJSON
const api_ver = uci.get('dockerd', 'globals', 'api_version') || '';
const api_ver_str = api_ver ? `/${version}` : '';
const api_ver_str = api_ver ? `/${api_ver}` : '';
if (!host) {
@@ -362,13 +362,13 @@ const core_methods = {
events: { args: { query: { 'since': '', 'until': `${Date.now()}`, 'filters': '' } }, call: (request) => call_docker('GET', '/events', { query: request?.query, onChunk: request?.onChunk }) },
};
/*
const exec_methods = {
start: { args: { id: '', body: '' }, call: (request) => call_docker('POST', `/exec/${request?.id}/start`, { payload: request?.body }) },
resize: { args: { id: '', query: { 'h': 0, 'w': 0 } }, call: (request) => call_docker('POST', `/exec/${request?.id}/resize`, { query: request?.query }) },
inspect: { args: { id: '' }, call: (request) => call_docker('GET', `/exec/${request?.id}/json`) },
};
*/
const container_methods = {
list: { args: { query: { 'all': false, 'limit': false, 'size': false, 'filters': '' } }, call: (request) => call_docker('GET', '/containers/json', { query: request?.query }) },

View File

@@ -1092,7 +1092,7 @@ const dv = view.extend({
// Track progressive response progress
let lastIndex = 0;
let title = _('Progress');
// let title = _('Progress');
xhr.onprogress = (upd) => {
const chunk = xhr.responseText.slice(lastIndex);
lastIndex = xhr.responseText.length;
@@ -1238,6 +1238,7 @@ const ansiToHtml = function(text) {
// These include cursor positioning, screen clearing, etc.
text = text
// Strip CSI sequences (cursor movement, screen clearing, etc.)
// eslint-disable-next-line no-control-regex
.replace(/\x1B\[[0-9;?]*[A-Za-z]/g, (match) => {
// Keep only SGR (Select Graphic Rendition) sequences ending in 'm'
if (match.endsWith('m')) {
@@ -1247,10 +1248,13 @@ const ansiToHtml = function(text) {
return '';
})
// Strip OSC sequences (window title, etc.)
// eslint-disable-next-line no-control-regex
.replace(/\x1B\][^\x07]*\x07/g, '')
// Strip other escape sequences
// eslint-disable-next-line no-control-regex
.replace(/\x1B[><=]/g, '')
// Strip bell character
// eslint-disable-next-line no-control-regex
.replace(/\x07/g, '');
// ANSI color codes mapping
@@ -1286,6 +1290,7 @@ const ansiToHtml = function(text) {
};
// Split by ANSI escape sequences and process
// eslint-disable-next-line no-control-regex
const ansiRegex = /\x1B\[([\d;]*)m/g;
let html = '';
let currentStyle = {};

View File

@@ -442,9 +442,9 @@ return dm2.dv.extend({
s.nodescriptions = true;
s.addremove = false;
let o, t, ss;
let o, ss;
t = s.tab('info', _('Info'));
s.tab('info', _('Info'));
o = s.taboption('info', form.Value, 'Name', _('Name'));
@@ -548,7 +548,7 @@ return dm2.dv.extend({
};
// NETWORKS TAB
t = s.tab('network', _('Networks'));
s.tab('network', _('Networks'));
o = s.taboption('network', form.SectionValue, '__net__', form.TableSection, 'nets', null);
ss = o.subsection;
@@ -596,7 +596,7 @@ return dm2.dv.extend({
t = s.tab('resources', _('Resources'));
s.tab('resources', _('Resources'));
o = s.taboption('resources', form.SectionValue, '__hcfg__', form.TypedSection, 'hostcfg', null);
ss = o.subsection;
@@ -692,7 +692,7 @@ return dm2.dv.extend({
};
// STATS TAB
t = s.tab('stats', _('Stats'));
s.tab('stats', _('Stats'));
function updateStats(stats_data) {
const status = view.getContainerStatus(this_container);
@@ -819,7 +819,7 @@ return dm2.dv.extend({
o.render = L.bind(() => { return updateStats(stats_data)}, this);
// PROCESS TAB
t = s.tab('ps', _('Processes'));
s.tab('ps', _('Processes'));
// Create custom table for processes using L.ui.Table
o = s.taboption('ps', form.DummyValue, '_ps_table', _('Running Processes'));
@@ -879,7 +879,7 @@ return dm2.dv.extend({
}, this);
// CHANGES TAB
t = s.tab('changes', _('Changes'));
s.tab('changes', _('Changes'));
// Create custom table for changes using L.ui.Table
o = s.taboption('changes', form.DummyValue, '_changes_table', _('Filesystem Changes'));
@@ -913,7 +913,7 @@ return dm2.dv.extend({
// FILE TAB
t = s.tab('file', _('File'));
s.tab('file', _('File'));
let fileDiv = null;
o = s.taboption('file', form.DummyValue, 'json', '_file');
@@ -962,7 +962,7 @@ return dm2.dv.extend({
// INSPECT TAB
t = s.tab('inspect', _('Inspect'));
s.tab('inspect', _('Inspect'));
let inspectDiv = null;
o = s.taboption('inspect', form.Button, 'json', _('Container Inspect'));
@@ -995,7 +995,7 @@ return dm2.dv.extend({
// TERMINAL TAB
t = s.tab('console', _('Console'));
s.tab('console', _('Console'));
o = s.taboption('console', form.DummyValue, 'console_controls', _('Console Connection'));
o.render = L.bind(() => {
@@ -1067,7 +1067,7 @@ return dm2.dv.extend({
}, this);
// WEBSOCKET TAB
t = s.tab('wsconsole', _('WebSocket'));
s.tab('wsconsole', _('WebSocket'));
dm2.js_api_ready.then(([apiAvailable, host]) => {
// Wait for JS API availability check to complete
@@ -1148,7 +1148,7 @@ return dm2.dv.extend({
});
// LOGS TAB
t = s.tab('logs', _('Logs'));
s.tab('logs', _('Logs'));
let logsDiv = null;
let logsLoaded = false;
@@ -1305,14 +1305,14 @@ return dm2.dv.extend({
if (!map)
return Promise.reject(new Error(_('Form is not ready yet.')));
const listToKv = view.listToKv;
// const listToKv = view.listToKv;
const get = (opt) => map.data.get('json', 'cont', opt);
const getn = (opt) => map.data.get('json', 'nets', opt);
// const getn = (opt) => map.data.get('json', 'nets', opt);
const gethc = (opt) => map.data.get('json', 'hostcfg', opt);
const toBool = (val) => (val === 1 || val === '1' || val === true);
const toInt = (val) => val ? Number.parseInt(val) : undefined;
const toFloat = (val) => val ? Number.parseFloat(val) : undefined;
// const toFloat = (val) => val ? Number.parseFloat(val) : undefined;
// First: update properties
map.parse()
@@ -1918,7 +1918,7 @@ return dm2.dv.extend({
'click': () => {
const selectedNetwork = networkSelect.value;
const ip4Address = ip4Input.value || '';
const ip6Address = ip6Input.value || '';
// const ip6Address = ip6Input.value || '';
if (!selectedNetwork) {
view.showNotification(_('Error'), [_('No network selected')], 5000, 'error');

View File

@@ -93,7 +93,7 @@ return dm2.dv.extend({
if (builtInNetworks.has(netnames[0])) return '';
return (nets && (nets.length > 0)) ? nets[0]?.GlobalIPv6Address || '' : '';
})(),
ipv6: (() => {
ipv6_lla: (() => {
if (builtInNetworks.has(netnames[0])) return '';
return (nets && (nets.length > 0)) ? nets[0]?.LinkLocalIPv6Address || '' : '';
})(),
@@ -754,11 +754,11 @@ return dm2.dv.extend({
.then(() => {
const get = (opt) => map.data.get('json', 'container', opt);
const name = get('name');
const pull = toBool(get('pull'));
// const pull = toBool(get('pull'));
const network = get('network');
const publish = get('publish');
const command = get('command');
const publish_all = toBool(get('publish_all'));
// const publish_all = toBool(get('publish_all'));
const device = get('device');
const tmpfs = get('tmpfs');
const sysctl = get('sysctl');
@@ -833,7 +833,12 @@ return dm2.dv.extend({
const volumeIds = new Set((view.volumes || []).map(v => v.Id));
const mounts = [];
for (const entry of volumeEntries) {
let [source, target, options] = (typeof entry === 'string' ? entry : '')?.split(':')?.map(e => e && e.trim() || '');
let e = typeof entry === 'string' ? entry : '';
let f = e.split(':')?.map(e => e && e.trim() || '');
let source = f[0];
let target = f[1];
let options = f[2];
if (!options) options = '';
// Validate source and target are not empty

View File

@@ -37,7 +37,7 @@ return dm2.dv.extend({
return Promise.all([
dm2.docker_events({ query: { since: `0`, until: `${now}` } }),
dm2.js_api_ready.then(([ok, host]) => this.js_api = ok),
dm2.js_api_ready.then(([ok, ]) => this.js_api = ok),
]);
},

View File

@@ -51,10 +51,10 @@ return dm2.dv.extend({
s.addremove = false;
s.nodescriptions = true;
let o, t, ss;
let o, ss;
// INFO TAB
t = s.tab('info', _('Info'));
s.tab('info', _('Info'));
o = s.taboption('info', form.DummyValue, 'Name', _('Network Name'));
o = s.taboption('info', form.DummyValue, 'Id', _('ID'));
@@ -93,7 +93,7 @@ return dm2.dv.extend({
o.cfgvalue = view.objectCfgValueTT;
// CONFIGS TAB
t = s.tab('detail', _('Detail'));
s.tab('detail', _('Detail'));
o = s.taboption('detail', form.DummyValue, 'Driver', _('IPAM Driver'));
@@ -131,7 +131,7 @@ return dm2.dv.extend({
// INSPECT TAB
t = s.tab('inspect', _('Inspect'));
s.tab('inspect', _('Inspect'));
o = s.taboption('inspect', form.SectionValue, '__ins__', form.NamedSection, '_inspect', null);
ss = o.subsection;

View File

@@ -20,7 +20,7 @@ return dm2.dv.extend({
]);
},
render([]) {
render() {
// stuff JSONMap with {network: {}} to prime it with a new empty entry
const m = new form.JSONMap({network: {}}, _('Docker - New Network'));

View File

@@ -204,7 +204,7 @@ return dm2.dv.extend({
getNetworksTable(networks, containers) {
const data = [];
for (const [i, net] of (networks || []).entries()) {
for (const [ , net] of (networks || []).entries()) {
const n = net.Name;
const _shortId = (net.Id || '').substring(0, 12);
const shortLink = E('a', {

View File

@@ -66,7 +66,7 @@ function getVolumesInUseByContainers(containers) {
return dm2.dv.extend({
load() {
const now = Math.floor(Date.now() / 1000);
// const now = Math.floor(Date.now() / 1000);
return Promise.all([
dm2.docker_version(),
@@ -234,21 +234,21 @@ return dm2.dv.extend({
m.readonly = true;
m.tabbed = false;
let s, o, v;
let s;
// Add Version and Environment tables
s = m.section(form.TableSection, 'vb', _('Version'));
s.anonymous = true;
o = s.option(form.DummyValue, 'entry', _('Name'));
o = s.option(form.DummyValue, 'value', _('Value'));
s.option(form.DummyValue, 'entry', _('Name'));
s.option(form.DummyValue, 'value', _('Value'));
s = m.section(form.TableSection, 'ib', _('Environment'));
s.anonymous = true;
s.filterrow = true;
o = s.option(form.DummyValue, 'entry', _('Entry'));
o = s.option(form.DummyValue, 'value', _('Value'));
s.option(form.DummyValue, 'entry', _('Entry'));
s.option(form.DummyValue, 'value', _('Value'));
// Render the form sections and append them
return m.render()

View File

@@ -278,8 +278,7 @@ return dm2.dv.extend({
getVolumesTable(volumes) {
const data = [];
for (const [i, vol] of (volumes?.Volumes || []).entries()) {
const n = vol.Name;
for (const [ , vol] of (volumes?.Volumes || []).entries()) {
const labels = vol?.Labels || {};
// Just push plain data objects without UCI metadata