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
,
81 version
: data
.version
,
82 packages
: data
.packages
,
87 req
.then(response
=> {
88 switch (response
.status
) {
90 var res
= response
.json()
93 for (image
of res
.images
) {
94 if (image
.type
== "sysupgrade") {
98 if (image
.name
!= undefined) {
99 var sysupgrade_url
= server_url
+ "/store/" + res
.bin_dir
+ "/" + image
.name
;
101 var keep
= E('input', {
107 _('Version'), res
.version_number
+ ' ' + res
.version_code
,
109 'href': sysupgrade_url
111 _('SHA256'), image
.sha256
,
112 _('Build Date'), res
.build_at
,
113 _('Target'), res
.target
,
116 var table
= E('div', {
120 for (var i
= 0; i
< fields
.length
; i
+= 2) {
121 table
.appendChild(E('div', {
130 }, [(fields
[i
+ 1] != null) ? fields
[i
+ 1] : '?'])
136 E('p', {}, E('label', {
139 keep
, ' ', _('Keep settings and retain the current configuration')
146 'click': ui
.hideModal
150 'class': 'btn cbi-button-action',
151 'click': function() {
152 install_sysupgrade(sysupgrade_url
, keep
.checked
, image
.sha256
)
154 }, _('Install Sysupgrade'))
158 ui
.showModal(_('Successfully created sysupgrade image'), modal_body
);
163 res
= response
.json()
164 data
.request_hash
= res
.request_hash
;
165 switch (res
.status
) {
167 displayStatus("notice spinning", E('p', _('Request in build queue')));
170 displayStatus("notice spinning", E('p', _('Building the sysupgrade image')));
173 setTimeout(function() {
174 request_sysupgrade(server_url
, data
);
177 case 400: // bad request
178 case 422: // bad package
179 case 500: // build failed
180 res
= response
.json()
182 E('p', {}, _(res
.message
)),
183 E('p', {}, _("Please report the error message and request")),
184 E('b', {}, _("Request to server:")),
185 E('pre', {}, JSON
.stringify(data
, null, 4)),
190 body
.push(E('b', {}, "STDOUT:"))
191 body
.push(E('pre', {}, res
.stdout
))
196 body
.push(E('b', {}, "STDERR:"))
197 body
.push(E('pre', {}, res
.stderr
))
207 'click': ui
.hideModal
211 ui
.showModal(_('Error building the sysupgrade'), body
);
217 function check_sysupgrade(server_url
, current_version
, target
, board_name
, packages
) {
218 displayStatus("notice spinning", E('p', _('Searching for an available sysupgrade')));
219 var current_branch
= current_version
.split(".").slice(0, 2).join(".");
220 var advanced_mode
= uci
.get_first('attendedsysupgrade', 'client', 'advanced_mode') || 0;
222 fetch(server_url
+ "/api/latest")
223 .then(response
=> response
.json())
225 if (current_version
== "SNAPSHOT") {
226 candidates
.push("SNAPSHOT");
228 for (let version
of response
["latest"]) {
229 var branch
= version
.split(".").slice(0, 2).join(".");
231 // already latest version installed
232 if (current_version
== version
) {
236 // skip branch upgrades outside the advanced mode
237 if (current_branch
!= branch
&& advanced_mode
== 0) {
241 candidates
.unshift(version
);
243 // don't offer branches older than the current
244 if (current_branch
== branch
) {
252 console
.log(candidates
);
256 board_name
: board_name
,
258 version
: candidates
[0],
259 packages
: Object
.keys(packages
).sort(),
263 m
= new form
.JSONMap(mapdata
, '');
265 s
= m
.section(form
.NamedSection
, 'request', 'example', '',
266 'Use defaults for the safest update');
267 o
= s
.option(form
.ListValue
, 'version', 'Select firmware version');
268 for (let candidate
of candidates
) {
269 o
.value(candidate
, candidate
);
272 if (advanced_mode
== 1) {
273 o
= s
.option(form
.Value
, 'board_name', 'Board Name / Profile');
274 o
= s
.option(form
.DynamicList
, 'packages', 'Packages');
279 .then(function(form_rendered
) {
280 ui
.showModal(_('New upgrade available'), [
287 'click': ui
.hideModal
291 'class': 'btn cbi-button-action',
292 'click': function() {
293 m
.save().then(foo
=> {
295 server_url
, mapdata
.request
299 }, _('Request Sysupgrade'))
304 ui
.showModal(_('No upgrade available'), [
305 E('p', {}, _("The device runs the latest firmware version")),
311 'click': ui
.hideModal
319 function displayStatus(type
, content
) {
321 var message
= ui
.showModal('', '');
323 message
.classList
.add('alert-message');
324 DOMTokenList
.prototype.add
.apply(message
.classList
, type
.split(/\s+/));
327 dom
.content(message
, content
);
336 L
.resolveDefault(callPackagelist(), {}),
337 L
.resolveDefault(callSystemBoard(), {}),
338 uci
.load('attendedsysupgrade')
341 render: function(res
) {
342 var packages
= res
[0].packages
;
343 var current_version
= res
[1].release
.version
;
344 var target
= res
[1].release
.target
;
345 var board_name
= res
[1].board_name
;
346 var auto_search
= uci
.get_first('attendedsysupgrade', 'client', 'auto_search') || 1;
347 var server_url
= uci
.get_first('attendedsysupgrade', 'server', 'url');
350 E('h2', _("Attended Sysupgrade")),
351 E('p', _('The attended sysupgrade service allows to easily upgrade vanilla and custom firmware images.')),
352 E('p', _('This is done by building a new firmware on demand via an online service.'))
355 if (auto_search
== 1) {
356 check_sysupgrade(server_url
, current_version
, target
, board_name
, packages
)
360 'class': 'btn cbi-button-positive',
361 'click': function() {
362 check_sysupgrade(server_url
, current_version
, target
, board_name
, packages
)
364 }, _('Search for sysupgrade')));