luci-app-attendedsysupgrade: use correct linter settings

The previous settings would use spaces which messed up things since LuCI
uses tabs everywhere.

Also removed a stray console.log

Signed-off-by: Paul Spooren <mail@aparcar.org>
This commit is contained in:
Paul Spooren 2021-08-31 09:22:13 -10:00
parent f092eec6b6
commit 641bfe3967
2 changed files with 377 additions and 346 deletions

View file

@ -7,28 +7,27 @@ return view.extend({
var m, s, o; var m, s, o;
m = new form.Map('attendedsysupgrade', _('Attended Sysupgrade'), m = new form.Map('attendedsysupgrade', _('Attended Sysupgrade'),
_('Attendedsysupgrade Configuration.') _('Attendedsysupgrade Configuration.'));
);
s = m.section(form.TypedSection, 'server', _('Server')); s = m.section(form.TypedSection, 'server', _('Server'));
s.anonymous = true; s.anonymous = true;
s.option(form.Value, 'url', _('Address'), s.option(form.Value, 'url', _('Address'),
_('Address of the sysupgrade server')); _('Address of the sysupgrade server'));
s = m.section(form.TypedSection, 'client', _('Client')); s = m.section(form.TypedSection, 'client', _('Client'));
s.anonymous = true; s.anonymous = true;
o = s.option(form.Flag, 'auto_search', _('Search on opening'), o = s.option(form.Flag, 'auto_search', _('Search on opening'),
_('Search for new sysupgrades on opening the tab')); _('Search for new sysupgrades on opening the tab'));
o.default = '1'; o.default = '1';
o.rmempty = false; o.rmempty = false;
o = s.option(form.Flag, 'advanced_mode', _('Advanced Mode'), o = s.option(form.Flag, 'advanced_mode', _('Advanced Mode'),
_('Show advanced options like packge list modification')); _('Show advanced options like packge list modification'));
o.default = '0'; o.default = '0';
o.rmempty = false; o.rmempty = false;
return m.render(); return m.render();
} },
}); });

View file

@ -9,412 +9,444 @@
'require dom'; 'require dom';
var callPackagelist = rpc.declare({ var callPackagelist = rpc.declare({
object: 'rpc-sys', object: 'rpc-sys',
method: 'packagelist', method: 'packagelist',
}); });
var callSystemBoard = rpc.declare({ var callSystemBoard = rpc.declare({
object: 'system', object: 'system',
method: 'board' method: 'board',
}); });
var callUpgradeStart = rpc.declare({ var callUpgradeStart = rpc.declare({
object: 'rpc-sys', object: 'rpc-sys',
method: 'upgrade_start', method: 'upgrade_start',
params: ["keep"] params: [ 'keep' ],
}); });
function get_branch(version) { function get_branch(version) {
// determine branch of a version // determine branch of a version
// SNAPSHOT -> SNAPSHOT // SNAPSHOT -> SNAPSHOT
// 21.02-SNAPSHOT -> 21.02 // 21.02-SNAPSHOT -> 21.02
// 21.02.0-rc1 -> 21.02 // 21.02.0-rc1 -> 21.02
// 19.07.8 -> 19.07 // 19.07.8 -> 19.07
return version.replace("-SNAPSHOT", "").split(".").slice(0, 2).join("."); return version.replace('-SNAPSHOT', '').split('.').slice(0, 2).join('.');
} }
function get_revision_count(revision) { function get_revision_count(revision) {
return parseInt(revision.substring(1).split("-")[0]) return parseInt(revision.substring(1).split('-')[0]);
} }
function error_api_connect(response) { function error_api_connect(response) {
console.log(response) ui.showModal(_('Error connecting to upgrade server'), [
ui.showModal(_('Error connecting to upgrade server'), [ E('p', {},
E('p', {}, _(`Could not reach API at "${response.url}. Please try again later.`)), _('Could not reach API at "%s". Please try again later.')
E('pre', {}, response.responseText), .format(response.url)),
E('div', { E('pre', {}, response.responseText),
'class': 'right' E('div', {
}, [ class: 'right',
E('div', { },
'class': 'btn', [
'click': ui.hideModal E('div', {
}, _('Close')) class: 'btn',
]) click: ui.hideModal,
]); },
_('Close')),
]),
]);
} }
function install_sysupgrade(url, keep, sha256) { function install_sysupgrade(url, keep, sha256) {
displayStatus("notice spinning", E('p', _('Downloading firmware from server to browser'))); displayStatus('notice spinning',
request.get(url, { E('p', _('Downloading firmware from server to browser')));
headers: { request
'Content-Type': 'application/x-www-form-urlencoded' .get(url, {
}, headers: {
responseType: 'blob' 'Content-Type': 'application/x-www-form-urlencoded',
}) },
.then(response => { responseType: 'blob',
var form_data = new FormData(); })
form_data.append("sessionid", rpc.getSessionID()); .then((response) => {
form_data.append("filename", "/tmp/firmware.bin"); var form_data = new FormData();
form_data.append("filemode", 600); form_data.append('sessionid', rpc.getSessionID());
form_data.append("filedata", response.blob()); form_data.append('filename', '/tmp/firmware.bin');
form_data.append('filemode', 600);
form_data.append('filedata', response.blob());
displayStatus("notice spinning", E('p', _('Uploading firmware from browser to device'))); displayStatus('notice spinning',
request.get(`${L.env.cgi_base}/cgi-upload`, { E('p', _('Uploading firmware from browser to device')));
method: 'PUT', request
content: form_data .get(`${L.env.cgi_base}/cgi-upload`, {
}) method: 'PUT',
.then(response => response.json()) content: form_data,
.then(response => { })
if (response.sha256sum != sha256) { .then((response) => response.json())
displayStatus("warning", [ .then((response) => {
E('b', _('Wrong checksum')), if (response.sha256sum != sha256) {
E('p', _('Error during download of firmware. Please try again')), displayStatus('warning', [
E('div', { E('b', _('Wrong checksum')),
'class': 'btn', E('p',
'click': ui.hideModal _('Error during download of firmware. Please try again')),
}, _('Close')) E('div', {
]); class: 'btn',
} else { click: ui.hideModal,
displayStatus('warning spinning', E('p', _('Installing the sysupgrade. Do not unpower device!'))); },
L.resolveDefault(callUpgradeStart(keep), {}).then(response => { _('Close')),
if (keep) { ]);
ui.awaitReconnect(window.location.host); } else {
} else { displayStatus(
ui.awaitReconnect('192.168.1.1', 'openwrt.lan'); 'warning spinning',
} E('p',
}); _('Installing the sysupgrade. Do not unpower device!')));
} L.resolveDefault(callUpgradeStart(keep), {})
}); .then((response) => {
}); if (keep) {
ui.awaitReconnect(window.location.host);
} else {
ui.awaitReconnect('192.168.1.1', 'openwrt.lan');
}
});
}
});
});
} }
function request_sysupgrade(server_url, data) { function request_sysupgrade(server_url, data) {
var res, req; var res, req;
if (data.request_hash) { if (data.request_hash) {
req = request.get(`${server_url}/api/v1/build/${data.request_hash}`) req = request.get(`${server_url}/api/v1/build/${data.request_hash}`);
} else { } else {
req = request.post(`${server_url}/api/v1/build`, { req = request.post(`${server_url}/api/v1/build`, {
profile: data.board_name, profile: data.board_name,
target: data.target, target: data.target,
version: data.version, version: data.version,
packages: data.packages, packages: data.packages,
diff_packages: true, diff_packages: true,
}) });
} }
req.then(response => { req.then((response) => {
switch (response.status) { switch (response.status) {
case 200: case 200:
res = response.json() res = response.json();
var image; var image;
for (image of res.images) { for (image of res.images) {
if (image.type == "sysupgrade") { if (image.type == 'sysupgrade') {
break; break;
} }
} }
if (image.name != undefined) { if (image.name != undefined) {
var sysupgrade_url = `${server_url}/store/${res.bin_dir}/${image.name}`; var sysupgrade_url = `${server_url}/store/${res.bin_dir}/${image.name}`;
var keep = E('input', { var keep = E('input', {
type: 'checkbox' type: 'checkbox',
}) });
keep.checked = true; keep.checked = true;
var fields = [ var fields = [
_('Version'), `${res.version_number} ${res.version_code}`, _('Version'),
_('File'), E('a', { `${res.version_number} ${res.version_code}`,
'href': sysupgrade_url _('File'),
}, image.name), E('a', {
_('SHA256'), image.sha256, href: sysupgrade_url,
_('Build Date'), res.build_at, },
_('Target'), res.target, image.name),
]; _('SHA256'),
image.sha256,
_('Build Date'),
res.build_at,
_('Target'),
res.target,
];
var table = E('div', { var table = E('div', {
'class': 'table' class: 'table',
}); });
for (var i = 0; i < fields.length; i += 2) { for (var i = 0; i < fields.length; i += 2) {
table.appendChild(E('div', { table.appendChild(E('tr', {
'class': 'tr' class: 'tr',
}, [ },
E('div', { [
'class': 'td left', E('td', {
'width': '33%' class: 'td left',
}, [fields[i]]), width: '33%',
E('div', { },
'class': 'td left' [ fields[i] ]),
}, [(fields[i + 1] != null) ? fields[i + 1] : '?']) E('td', {
])); class: 'td left',
} },
[ fields[i + 1] ]),
]));
}
var modal_body = [ var modal_body = [
table, table,
E('p', {}, E('label', { E('p', {class: 'mt-2'},
'class': 'btn' E('label', {
}, [ class: 'btn',
keep, ' ', _('Keep settings and retain the current configuration') },
])), [
E('div', { keep, ' ',
'class': 'right' _('Keep settings and retain the current configuration')
}, [ ])),
E('div', { E('div', {
'class': 'btn', class: 'right',
'click': ui.hideModal },
}, _('Cancel')), [
' ', E('div', {
E('div', { class: 'btn',
'class': 'btn cbi-button-action', click: ui.hideModal,
'click': function() { },
install_sysupgrade(sysupgrade_url, keep.checked, image.sha256) _('Cancel')),
} ' ',
}, _('Install Sysupgrade')) E('div', {
]) class: 'btn cbi-button-action',
] click: function() {
install_sysupgrade(sysupgrade_url, keep.checked,
image.sha256);
},
},
_('Install Sysupgrade')),
]),
];
ui.showModal(_('Successfully created sysupgrade image'), modal_body); ui.showModal(_('Successfully created sysupgrade image'), modal_body);
} }
break; break;
case 202: case 202:
res = response.json() res = response.json();
data.request_hash = res.request_hash; data.request_hash = res.request_hash;
if ("queue_position" in res) if ('queue_position' in res)
displayStatus("notice spinning", E('p', _('Request in build queue position %d'.format(res.queue_position)))); displayStatus('notice spinning',
else E('p', _('Request in build queue position %s')
displayStatus("notice spinning", E('p', _('Building firmware sysupgrade image'))); .format(res.queue_position)));
else
displayStatus('notice spinning',
E('p', _('Building firmware sysupgrade image')));
setTimeout(function() { setTimeout(function() { request_sysupgrade(server_url, data); }, 5000);
request_sysupgrade(server_url, data); break;
}, 5000); case 400: // bad request
break; case 422: // bad package
case 400: // bad request case 500: // build failed
case 422: // bad package res = response.json();
case 500: // build failed var body = [
res = response.json() E('p', {}, res.detail),
var body = [ E('p', {}, _('Please report the error message and request')),
E('p', {}, res.detail), E('b', {}, _('Request to server:')),
E('p', {}, _("Please report the error message and request")), E('pre', {}, JSON.stringify(data, null, 4)),
E('b', {}, _("Request to server:")), ];
E('pre', {}, JSON.stringify(data, null, 4)),
] if (res.stdout) {
body.push(E('b', {}, 'STDOUT:'));
body.push(E('pre', {}, res.stdout));
}
if (res.stdout) { if (res.stderr) {
body.push(E('b', {}, "STDOUT:")) body.push(E('b', {}, 'STDERR:'));
body.push(E('pre', {}, res.stdout)) body.push(E('pre', {}, res.stderr));
}
} body = body.concat([
E('div', {
if (res.stderr) { class: 'right',
body.push(E('b', {}, "STDERR:")) },
body.push(E('pre', {}, res.stderr)) [
E('div', {
} class: 'btn',
click: ui.hideModal,
body = body.concat([ },
E('div', { _('Close')),
'class': 'right' ]),
}, [ ]);
E('div', { ui.showModal(_('Error building the sysupgrade'), body);
'class': 'btn', break;
'click': ui.hideModal }
}, _('Close')) });
])
]);
ui.showModal(_('Error building the sysupgrade'), body);
break;
}
});
} }
async function check_sysupgrade(server_url, system_board, packages) { async function check_sysupgrade(server_url, system_board, packages) {
var { var {board_name} = system_board;
board_name var {target, version, revision} = system_board.release;
} = system_board; var current_branch = get_branch(version);
var { var advanced_mode =
target, uci.get_first('attendedsysupgrade', 'client', 'advanced_mode') || 0;
version, var candidates = [];
revision var response;
} = system_board.release;
var current_branch = get_branch(version);
var advanced_mode = uci.get_first('attendedsysupgrade', 'client', 'advanced_mode') || 0;
var candidates = [];
var response;
displayStatus("notice spinning", E('p', _(`Searching for an available sysupgrade of ${version} - ${revision}`))); displayStatus('notice spinning',
E('p', _('Searching for an available sysupgrade of %s - %s')
.format(version, revision)));
if (version.endsWith("SNAPSHOT")) { if (version.endsWith('SNAPSHOT')) {
response = await request.get(`${server_url}/api/v1/revision/${version}/${target}`) response =
if (!response.ok) { await request.get(`${server_url}/api/v1/revision/${version}/${target}`);
error_api_connect(response); if (!response.ok) {
return; error_api_connect(response);
} return;
}
const remote_revision = response.json().revision; const remote_revision = response.json().revision;
if (get_revision_count(revision) < get_revision_count(remote_revision)) { if (get_revision_count(revision) < get_revision_count(remote_revision)) {
candidates.push(version); candidates.push(version);
} }
} else { } else {
response = await request.get(`${server_url}/api/overview`, { response = await request.get(`${server_url}/api/overview`, {
timeout: 8000 timeout: 8000,
}); });
if (!response.ok) { if (!response.ok) {
error_api_connect(response); error_api_connect(response);
return; return;
} }
const latest = response.json().latest const latest = response.json().latest;
for (let remote_version of latest) { for (let remote_version of latest) {
var remote_branch = get_branch(remote_version); var remote_branch = get_branch(remote_version);
// already latest version installed // already latest version installed
if (version == remote_version) { if (version == remote_version) {
break; break;
} }
// skip branch upgrades outside the advanced mode // skip branch upgrades outside the advanced mode
if (current_branch != remote_branch && advanced_mode == 0) { if (current_branch != remote_branch && advanced_mode == 0) {
continue; continue;
} }
candidates.unshift(remote_version); candidates.unshift(remote_version);
// don't offer branches older than the current // don't offer branches older than the current
if (current_branch == remote_branch) { if (current_branch == remote_branch) {
break; break;
} }
} }
} }
if (candidates.length) { if (candidates.length) {
var m, s, o; var m, s, o;
var mapdata = { var mapdata = {
request: { request: {
board_name: board_name, board_name: board_name,
target: target, target: target,
version: candidates[0], version: candidates[0],
packages: Object.keys(packages).sort(), packages: Object.keys(packages).sort(),
} },
} };
m = new form.JSONMap(mapdata, ''); m = new form.JSONMap(mapdata, '');
s = m.section(form.NamedSection, 'request', 'example', '', s = m.section(form.NamedSection, 'request', 'example', '',
'Use defaults for the safest update'); 'Use defaults for the safest update');
o = s.option(form.ListValue, 'version', 'Select firmware version'); o = s.option(form.ListValue, 'version', 'Select firmware version');
for (let candidate of candidates) { for (let candidate of candidates) {
o.value(candidate, candidate); o.value(candidate, candidate);
} }
if (advanced_mode == 1) { if (advanced_mode == 1) {
o = s.option(form.Value, 'board_name', 'Board Name / Profile'); o = s.option(form.Value, 'board_name', 'Board Name / Profile');
o = s.option(form.DynamicList, 'packages', 'Packages'); o = s.option(form.DynamicList, 'packages', 'Packages');
} }
m.render().then(function(form_rendered) {
m.render() ui.showModal(_('New upgrade available'), [
.then(function(form_rendered) { form_rendered,
ui.showModal(_('New upgrade available'), [ E('div', {
form_rendered, class: 'right',
E('div', { },
'class': 'right' [
}, [ E('div', {
E('div', { class: 'btn',
'class': 'btn', click: ui.hideModal,
'click': ui.hideModal },
}, _('Cancel')), _('Cancel')),
' ', ' ',
E('div', { E('div', {
'class': 'btn cbi-button-action', class: 'btn cbi-button-action',
'click': function() { click: function() {
m.save().then(foo => { m.save().then((foo) => {
request_sysupgrade( request_sysupgrade(server_url, mapdata.request);
server_url, mapdata.request });
) },
}); },
} _('Request Sysupgrade')),
}, _('Request Sysupgrade')) ]),
]) ]);
]); });
}); } else {
} else { ui.showModal(_('No upgrade available'), [
ui.showModal(_('No upgrade available'), [ E('p', {},
E('p', {}, _(`The device runs the latest firmware version ${version} - ${revision}`)), _('The device runs the latest firmware version %s - %s')
E('div', { .format(version, revision)),
'class': 'right' E('div', {
}, [ class: 'right',
E('div', { },
'class': 'btn', [
'click': ui.hideModal E('div', {
}, _('Close')) class: 'btn',
]) click: ui.hideModal,
]); },
} _('Close')),
]),
]);
}
} }
function displayStatus(type, content) { function displayStatus(type, content) {
if (type) { if (type) {
var message = ui.showModal('', ''); var message = ui.showModal('', '');
message.classList.add('alert-message'); message.classList.add('alert-message');
DOMTokenList.prototype.add.apply(message.classList, type.split(/\s+/)); DOMTokenList.prototype.add.apply(message.classList, type.split(/\s+/));
if (content) if (content)
dom.content(message, content); dom.content(message, content);
} else { } else {
ui.hideModal(); ui.hideModal();
} }
} }
return view.extend({ return view.extend({
load: function() { load: function() {
return Promise.all([ return Promise.all([
L.resolveDefault(callPackagelist(), {}), L.resolveDefault(callPackagelist(), {}),
L.resolveDefault(callSystemBoard(), {}), L.resolveDefault(callSystemBoard(), {}),
uci.load('attendedsysupgrade') uci.load('attendedsysupgrade'),
]); ]);
}, },
render: function(res) { render: function(res) {
var packages = res[0].packages; var packages = res[0].packages;
var system_board = res[1]; var system_board = res[1];
var auto_search = uci.get_first('attendedsysupgrade', 'client', 'auto_search') || 1; var auto_search =
var server_url = uci.get_first('attendedsysupgrade', 'server', 'url'); uci.get_first('attendedsysupgrade', 'client', 'auto_search') || 1;
var server_url = uci.get_first('attendedsysupgrade', 'server', 'url');
var view = [ var view = [
E('h2', _("Attended Sysupgrade")), E('h2', _('Attended Sysupgrade')),
E('p', _('The attended sysupgrade service allows to easily upgrade vanilla and custom firmware images.')), E('p',
E('p', _('This is done by building a new firmware on demand via an online service.')) _('The attended sysupgrade service allows to easily upgrade vanilla and custom firmware images.')),
]; E('p',
_('This is done by building a new firmware on demand via an online service.')),
];
if (auto_search == 1) { if (auto_search == 1) {
check_sysupgrade(server_url, system_board, packages) check_sysupgrade(server_url, system_board, packages);
} }
view.push(E('p', { view.push(E('p', {
'class': 'btn cbi-button-positive', class: 'btn cbi-button-positive',
'click': function() { click:
check_sysupgrade(server_url, system_board, packages) function() { check_sysupgrade(server_url, system_board, packages); },
} },
}, _('Search for sysupgrade'))); _('Search for sysupgrade')));
return view;
},
return view;
},
}); });