11 var callPackagelist = rpc.declare({
13 method: 'packagelist',
16 var callSystemBoard = rpc.declare({
21 var callUpgradeStart = rpc.declare({
23 method: 'upgrade_start',
27 function install_sysupgrade(url, keep, sha256) {
28 displayStatus("notice spinning", E('p', _('Downloading firmware from server to browser')));
31 'Content-Type': 'application/x-www-form-urlencoded'
36 var form_data = new FormData();
37 form_data.append("sessionid", rpc.getSessionID());
38 form_data.append("filename", "/tmp/firmware.bin");
39 form_data.append("filemode", 600);
40 form_data.append("filedata", response.blob());
42 displayStatus("notice spinning", E('p', _('Uploading firmware from browser to device')));
43 request.get(L.env.cgi_base + "/cgi-upload", {
47 .then(response => response.json())
49 if (response.sha256sum != sha256) {
50 displayStatus("warning", [
51 E('b', _('Wrong checksum')),
52 E('p', _('Error during download of firmware. Please try again')),
59 displayStatus('warning spinning', E('p', _('Installing the sysupgrade. Do not unpower device!')));
60 L.resolveDefault(callUpgradeStart(keep), {}).then(response => {
62 ui.awaitReconnect(window.location.host);
64 ui.awaitReconnect('192.168.1.1', 'openwrt.lan');
72 function request_sysupgrade(server_url, data) {
75 if (data.request_hash) {
76 req = request.get(server_url + "/api/build/" + data.request_hash)
78 req = request.post(server_url + "/api/build", {
79 profile: data.board_name,
80 version: data.version,
81 packages: data.packages,
86 req.then(response => {
87 switch (response.status) {
89 var res = response.json()
92 for (image of res.images) {
93 if (image.type == "sysupgrade") {
97 if (image.name != undefined) {
98 var sysupgrade_url = server_url + "/store/" + res.bin_dir + "/" + image.name;
100 var keep = E('input', {
106 _('Version'), res.version_number + ' ' + res.version_code,
108 'href': sysupgrade_url
110 _('SHA256'), image.sha256,
111 _('Build Date'), res.build_at,
112 _('Target'), res.target,
115 var table = E('div', {
119 for (var i = 0; i < fields.length; i += 2) {
120 table.appendChild(E('div', {
129 }, [(fields[i + 1] != null) ? fields[i + 1] : '?'])
135 E('p', {}, E('label', {
138 keep, ' ', _('Keep settings and retain the current configuration')
145 'click': ui.hideModal
149 'class': 'btn cbi-button-action',
150 'click': function() {
151 install_sysupgrade(sysupgrade_url, keep.checked, image.sha256)
153 }, _('Install Sysupgrade'))
157 ui.showModal(_('Successfully created sysupgrade image'), modal_body);
162 res = response.json()
163 data.request_hash = res.request_hash;
164 switch (res.status) {
166 displayStatus("notice spinning", E('p', _('Request in build queue')));
169 displayStatus("notice spinning", E('p', _('Building the sysupgrade image')));
172 setTimeout(function() {
173 request_sysupgrade(server_url, data);
176 case 400: // bad request
177 case 422: // bad package
178 case 500: // build failed
179 res = response.json()
181 E('p', {}, _(res.message)),
182 E('p', {}, _("Please report the error message and request")),
183 E('b', {}, _("Request to server:")),
184 E('pre', {}, JSON.stringify(data, null, 4)),
189 body.push(E('b', {}, "STDOUT:"))
190 body.push(E('pre', {}, res.stdout))
195 body.push(E('b', {}, "STDERR:"))
196 body.push(E('pre', {}, res.stderr))
206 'click': ui.hideModal
210 ui.showModal(_('Error building the sysupgrade'), body);
216 function check_sysupgrade(server_url, current_version, board_name, packages) {
217 displayStatus("notice spinning", E('p', _('Searching for an available sysupgrade')));
218 var current_branch = current_version.split(".").slice(0, 2).join(".");
220 fetch(server_url + "/api/latest")
221 .then(response => response.json())
223 if (current_version == "SNAPSHOT") {
224 candidates.push("SNAPSHOT");
226 for (let version of response["latest"]) {
227 var branch = version.split(".").slice(0, 2).join(".");
229 // already latest version installed
230 if (current_version == version) {
234 // warn user that a new major release would be installed
235 //if (current_branch != branch) {
236 // branch["warn_branch_jump"] = true;
239 candidates.unshift(version);
241 // don't offer branches older than the current
242 if (current_branch == branch) {
249 var advanced_mode = uci.get_first('attendedsysupgrade', 'client', 'advanced_mode') || 0;
251 console.log(candidates);
255 board_name: board_name,
256 version: candidates[0],
257 packages: Object.keys(packages).sort(),
261 m = new form.JSONMap(mapdata, '');
263 s = m.section(form.NamedSection, 'request', 'example', '',
264 'Use defaults for the safest update');
265 o = s.option(form.ListValue, 'version', 'Select firmware version');
266 for (let candidate of candidates) {
267 o.value(candidate, candidate);
270 if (advanced_mode == 1) {
271 o = s.option(form.Value, 'board_name', 'Board Name / Profile');
272 o = s.option(form.DynamicList, 'packages', 'Packages');
277 .then(function(form_rendered) {
278 ui.showModal(_('New upgrade available'), [
285 'click': ui.hideModal
289 'class': 'btn cbi-button-action',
290 'click': function() {
291 m.save().then(foo => {
293 server_url, mapdata.request
297 }, _('Request Sysupgrade'))
302 ui.showModal(_('No upgrade available'), [
303 E('p', {}, _("The device runs the latest firmware version")),
309 'click': ui.hideModal
317 function displayStatus(type, content) {
319 var message = ui.showModal('', '');
321 message.classList.add('alert-message');
322 DOMTokenList.prototype.add.apply(message.classList, type.split(/\s+/));
325 dom.content(message, content);
334 L.resolveDefault(callPackagelist(), {}),
335 L.resolveDefault(callSystemBoard(), {}),
336 uci.load('attendedsysupgrade')
339 render: function(res) {
340 var packages = res[0].packages;
341 var current_version = res[1].release.version;
342 var board_name = res[1].board_name;
343 var auto_search = uci.get_first('attendedsysupgrade', 'client', 'auto_search') || 1;
344 var server_url = uci.get_first('attendedsysupgrade', 'server', 'url');
347 E('h2', _("Attended Sysupgrade")),
348 E('p', _('The attended sysupgrade service allows to easily upgrade vanilla and custom firmware images.')),
349 E('p', _('This is done by building a new firmware on demand via an online service.'))
352 if (auto_search == 1) {
353 check_sysupgrade(server_url, current_version, board_name, packages)
357 'class': 'btn cbi-button-positive',
358 'click': function() {
359 check_sysupgrade(server_url, current_version, board_name, packages)
361 }, _('Search for sysupgrade')));