luci-app-attendedsysupgrade: support revision checks
SNAPSHOTS are not real releases and therefore the app always offers an upgrade, even if running the latest build. To prevent that all SNAPSHOTS now check for the running revision and if a newer one is available. Also do a bunch of refactoring based on JavaScript I learned over the last week. Signed-off-by: Paul Spooren <mail@aparcar.org>
This commit is contained in:
parent
ab2f8b8b04
commit
f799d550b6
1 changed files with 349 additions and 319 deletions
|
@ -33,6 +33,26 @@ function get_branch(version) {
|
|||
return version.replace("-SNAPSHOT", "").split(".").slice(0, 2).join(".");
|
||||
}
|
||||
|
||||
function get_revision_count(revision) {
|
||||
return parseInt(revision.substring(1).split("-")[0])
|
||||
}
|
||||
|
||||
function error_api_connect(response) {
|
||||
console.log(response)
|
||||
ui.showModal(_('Error connecting to upgrade server'), [
|
||||
E('p', {}, _(`Could not reach API at "${response.url}. Please try again later.`)),
|
||||
E('pre', {}, response.responseText),
|
||||
E('div', {
|
||||
'class': 'right'
|
||||
}, [
|
||||
E('div', {
|
||||
'class': 'btn',
|
||||
'click': ui.hideModal
|
||||
}, _('Close'))
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
function install_sysupgrade(url, keep, sha256) {
|
||||
displayStatus("notice spinning", E('p', _('Downloading firmware from server to browser')));
|
||||
request.get(url, {
|
||||
|
@ -49,7 +69,7 @@ function install_sysupgrade(url, keep, sha256) {
|
|||
form_data.append("filedata", response.blob());
|
||||
|
||||
displayStatus("notice spinning", E('p', _('Uploading firmware from browser to device')));
|
||||
request.get(L.env.cgi_base + "/cgi-upload", {
|
||||
request.get(`${L.env.cgi_base}/cgi-upload`, {
|
||||
method: 'PUT',
|
||||
content: form_data
|
||||
})
|
||||
|
@ -82,9 +102,9 @@ function request_sysupgrade(server_url, data) {
|
|||
var res, req;
|
||||
|
||||
if (data.request_hash) {
|
||||
req = request.get(server_url + "/api/build/" + data.request_hash)
|
||||
req = request.get(`${server_url}/api/v1/build/${data.request_hash}`)
|
||||
} else {
|
||||
req = request.post(server_url + "/api/build", {
|
||||
req = request.post(`${server_url}/api/v1/build`, {
|
||||
profile: data.board_name,
|
||||
target: data.target,
|
||||
version: data.version,
|
||||
|
@ -96,7 +116,7 @@ function request_sysupgrade(server_url, data) {
|
|||
req.then(response => {
|
||||
switch (response.status) {
|
||||
case 200:
|
||||
var res = response.json()
|
||||
res = response.json()
|
||||
var image;
|
||||
for (image of res.images) {
|
||||
if (image.type == "sysupgrade") {
|
||||
|
@ -104,7 +124,7 @@ function request_sysupgrade(server_url, data) {
|
|||
}
|
||||
}
|
||||
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', {
|
||||
type: 'checkbox'
|
||||
|
@ -112,7 +132,7 @@ function request_sysupgrade(server_url, data) {
|
|||
keep.checked = true;
|
||||
|
||||
var fields = [
|
||||
_('Version'), res.version_number + ' ' + res.version_code,
|
||||
_('Version'), `${res.version_number} ${res.version_code}`,
|
||||
_('File'), E('a', {
|
||||
'href': sysupgrade_url
|
||||
}, image.name),
|
||||
|
@ -220,41 +240,68 @@ function request_sysupgrade(server_url, data) {
|
|||
});
|
||||
}
|
||||
|
||||
function check_sysupgrade(server_url, current_version, target, board_name, packages) {
|
||||
displayStatus("notice spinning", E('p', _('Searching for an available sysupgrade')));
|
||||
var current_branch = get_branch(current_version);
|
||||
async function check_sysupgrade(server_url, system_board, packages) {
|
||||
var {
|
||||
board_name
|
||||
} = system_board;
|
||||
var {
|
||||
target,
|
||||
version,
|
||||
revision
|
||||
} = system_board.release;
|
||||
var current_branch = get_branch(version);
|
||||
var advanced_mode = uci.get_first('attendedsysupgrade', 'client', 'advanced_mode') || 0;
|
||||
var candidates = [];
|
||||
var response;
|
||||
|
||||
request.get(server_url + "/json/latest.json", {
|
||||
timeout: 8000
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
if (current_version == "SNAPSHOT") {
|
||||
candidates.push("SNAPSHOT");
|
||||
displayStatus("notice spinning", E('p', _(`Searching for an available sysupgrade of ${version} - ${revision}`)));
|
||||
|
||||
if (version.endsWith("SNAPSHOT")) {
|
||||
response = await request.get(`${server_url}/api/v1/revision/${version}/${target}`)
|
||||
if (!response.ok) {
|
||||
error_api_connect(response);
|
||||
return;
|
||||
}
|
||||
|
||||
const remote_revision = response.json().revision;
|
||||
|
||||
if (get_revision_count(revision) < get_revision_count(remote_revision)) {
|
||||
candidates.push(version);
|
||||
}
|
||||
} else {
|
||||
for (let version of response["latest"]) {
|
||||
var branch = get_branch(version);
|
||||
response = await request.get(`${server_url}/api/overview`, {
|
||||
timeout: 8000
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
error_api_connect(response);
|
||||
return;
|
||||
}
|
||||
|
||||
const latest = response.json().latest
|
||||
|
||||
for (let remote_version of latest) {
|
||||
var remote_branch = get_branch(remote_version);
|
||||
|
||||
// already latest version installed
|
||||
if (current_version == version) {
|
||||
if (version == remote_version) {
|
||||
break;
|
||||
}
|
||||
|
||||
// skip branch upgrades outside the advanced mode
|
||||
if (current_branch != branch && advanced_mode == 0) {
|
||||
if (current_branch != remote_branch && advanced_mode == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
candidates.unshift(version);
|
||||
candidates.unshift(remote_version);
|
||||
|
||||
// don't offer branches older than the current
|
||||
if (current_branch == branch) {
|
||||
if (current_branch == remote_branch) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (candidates.length) {
|
||||
var m, s, o;
|
||||
|
||||
|
@ -309,7 +356,7 @@ function check_sysupgrade(server_url, current_version, target, board_name, packa
|
|||
});
|
||||
} else {
|
||||
ui.showModal(_('No upgrade available'), [
|
||||
E('p', {}, _("The device runs the latest firmware version")),
|
||||
E('p', {}, _(`The device runs the latest firmware version ${version} - ${revision}`)),
|
||||
E('div', {
|
||||
'class': 'right'
|
||||
}, [
|
||||
|
@ -320,21 +367,6 @@ function check_sysupgrade(server_url, current_version, target, board_name, packa
|
|||
])
|
||||
]);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
ui.showModal(_('Error connecting to upgrade server'), [
|
||||
E('p', {}, _('Could not reach API at "%s". Please try again later.'.format(server_url))),
|
||||
E('pre', {}, error),
|
||||
E('div', {
|
||||
'class': 'right'
|
||||
}, [
|
||||
E('div', {
|
||||
'class': 'btn',
|
||||
'click': ui.hideModal
|
||||
}, _('Close'))
|
||||
])
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
function displayStatus(type, content) {
|
||||
|
@ -361,9 +393,7 @@ return view.extend({
|
|||
},
|
||||
render: function(res) {
|
||||
var packages = res[0].packages;
|
||||
var current_version = res[1].release.version;
|
||||
var target = res[1].release.target;
|
||||
var board_name = res[1].board_name;
|
||||
var system_board = res[1];
|
||||
var auto_search = uci.get_first('attendedsysupgrade', 'client', 'auto_search') || 1;
|
||||
var server_url = uci.get_first('attendedsysupgrade', 'server', 'url');
|
||||
|
||||
|
@ -374,13 +404,13 @@ return view.extend({
|
|||
];
|
||||
|
||||
if (auto_search == 1) {
|
||||
check_sysupgrade(server_url, current_version, target, board_name, packages)
|
||||
check_sysupgrade(server_url, system_board, packages)
|
||||
}
|
||||
|
||||
view.push(E('p', {
|
||||
'class': 'btn cbi-button-positive',
|
||||
'click': function() {
|
||||
check_sysupgrade(server_url, current_version, target, board_name, packages)
|
||||
check_sysupgrade(server_url, system_board, packages)
|
||||
}
|
||||
}, _('Search for sysupgrade')));
|
||||
|
||||
|
|
Loading…
Reference in a new issue