luci2: implement initial backup / restore / flash view. Actual firmware flashing...
authorJo-Philipp Wich <jow@openwrt.org>
Wed, 2 Oct 2013 17:09:58 +0000 (17:09 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Wed, 2 Oct 2013 17:09:58 +0000 (17:09 +0000)
luci2/htdocs/luci2/luci2.js
luci2/htdocs/luci2/template/system.upgrade.htm [new file with mode: 0644]
luci2/htdocs/luci2/view/system.upgrade.js [new file with mode: 0644]

index dfd734b6c90e9d7f919ca3a343643d8e5a11ee80..02b0015a4f432ac6c966aaf67a589ae8a1f294ae 100644 (file)
@@ -1292,6 +1292,18 @@ function LuCI2()
                }),
 
 
+               testReset: _luci2.rpc.declare({
+                       object: 'luci2.system',
+                       method: 'reset_test',
+                       expect: { supported: false }
+               }),
+
+               startReset: _luci2.rpc.declare({
+                       object: 'luci2.system',
+                       method: 'reset_start'
+               }),
+
+
                performReboot: _luci2.rpc.declare({
                        object: 'luci2.system',
                        method: 'reboot'
diff --git a/luci2/htdocs/luci2/template/system.upgrade.htm b/luci2/htdocs/luci2/template/system.upgrade.htm
new file mode 100644 (file)
index 0000000..6541c22
--- /dev/null
@@ -0,0 +1,39 @@
+<div class="cbi-form" id="tabs" style="display:none">
+       <ul class="cbi-tabmenu">
+               <li><a href="#actions"><%:Actions%></a></li>
+               <li><a href="#config"><%:Configuration%></a></li>
+       </ul>
+
+       <div id="actions">
+               <h3><%:Backup / Restore%></h3>
+               <p><%:Click "Generate archive" to download a tar archive of the current configuration files. To reset the firmware to its initial state, click "Perform reset" (only possible with squashfs images).%></p>
+               <p>
+                       <form action="/cgi-bin/luci-backup" method="post" style="display:inline">
+                               <input type="hidden" name="sessionid" />
+                               <input class="cbi-button cbi-button-apply" type="button" id="btn_backup" value="<%:Generate archive%>" />
+                       </form>
+                       <input class="cbi-button cbi-button-reset" type="button" id="btn_reset" value="<%:Perform reset%>" />
+               </p>
+               <br />
+
+               <p><%:To restore configuration files, you can upload a previously generated backup archive here.%></p>
+               <p>
+                       <input class="cbi-button cbi-input-apply" type="button" id="btn_restore" value="<%:Upload archive...%>" />
+               </p>
+               <br />
+
+               <h3><%:Flash new firmware image%></h3>
+               <p><%:Upload a sysupgrade-compatible image here to replace the running firmware. Check "Keep settings" to retain the current configuration (requires an OpenWrt compatible firmware image).%></p>
+               <p>
+                       <input class="cbi-button cbi-input-apply" type="button" id="btn_flash" value="<%:Flash image...%>" />
+               </p>
+       </div>
+
+       <div id="config">
+               <textarea style="width:100%"></textarea>
+               <div class="cbi-page-actions">
+                       <input class="cbi-button cbi-button-save" type="button" id="btn_save" value="<%:Save%>" />
+                       <input class="cbi-button cbi-button-apply" type="button" id="btn_list" value="<%:Show current backup file list …%>" />
+               </div>
+       </div>
+</div>
diff --git a/luci2/htdocs/luci2/view/system.upgrade.js b/luci2/htdocs/luci2/view/system.upgrade.js
new file mode 100644 (file)
index 0000000..2df7f83
--- /dev/null
@@ -0,0 +1,234 @@
+L.ui.view.extend({
+       title: L.tr('Flash operations'),
+
+       handle_flash_upload: function() {
+               var self = this;
+               L.ui.upload(
+                       L.tr('Firmware upload'),
+                       L.tr('Select the sysupgrade image to flash and click "%s" to proceed.').format(L.tr('Ok')), {
+                               filename: '/tmp/firmware.bin',
+                               success: function(info) {
+                                       self.handle_flash_verify(info);
+                               }
+                       }
+               );
+       },
+
+       handle_flash_verify: function(info) {
+               var self = this;
+               L.system.testUpgrade().then(function(res) {
+                       if (res.code == 0)
+                       {
+                               L.ui.dialog(
+                                       L.tr('Verify firmware'), [
+                                               $('<p />').text(L.tr('The firmware image was uploaded completely. Please verify the checksum and file size below, then click "%s" to start the flash procedure.').format(L.tr('Ok'))),
+                                               $('<ul />')
+                                                       .append($('<li />')
+                                                               .append($('<strong />').text(L.tr('Checksum') + ': '))
+                                                               .append(info.checksum))
+                                                       .append($('<li />')
+                                                               .append($('<strong />').text(L.tr('Size') + ': '))
+                                                               .append('%1024mB'.format(info.size))),
+                                               $('<label />')
+                                                       .append($('<input />')
+                                                               .attr('type', 'checkbox')
+                                                               .prop('checked', true))
+                                                       .append(' ')
+                                                       .append(L.tr('Keep configuration when reflashing'))
+                                       ], {
+                                               style: 'confirm',
+                                               confirm: function() {
+                                                       //L.system.startUpgrade().then(function() {
+                                                       //      L.ui.reconnect();
+                                                       //});
+
+                                                       alert('Flash...');
+                                               }
+                                       }
+                               );
+                       }
+                       else
+                       {
+                               L.ui.dialog(
+                                       L.tr('Invalid image'), [
+                                               $('<p />').text(L.tr('Firmware image verification failed, the "sysupgrade" command responded with the message below:')),
+                                               $('<pre />')
+                                                       .addClass('alert-message')
+                                                       .text(res.stdout || res.stderr),
+                                               $('<p />').text(L.tr('Image verification failed with code %d.').format(res.code))
+                                       ], {
+                                               style: 'close',
+                                               close: function() {
+                                                       L.system.cleanUpgrade().then(function() {
+                                                               L.ui.dialog(false);
+                                                       });
+                                               }
+                                       }
+                               );
+                       }
+               });
+       },
+
+       handle_backup_upload: function() {
+               var self = this;
+               L.ui.upload(
+                       L.tr('Backup restore'),
+                       L.tr('Select the backup archive to restore and click "%s" to proceed.').format(L.tr('Ok')), {
+                               filename: '/tmp/backup.tar.gz',
+                               success: function(info) {
+                                       self.handle_backup_verify(info);
+                               }
+                       }
+               );
+       },
+
+       handle_backup_verify: function(info) {
+               var self = this;
+               L.ui.dialog(
+                       L.tr('Backup restore'), [
+                               $('<p />').text(L.tr('The backup archive was uploaded completely. Please verify the checksum and file size below, then click "%s" to restore the archive.').format(L.tr('Ok'))),
+                               $('<ul />')
+                                       .append($('<li />')
+                                               .append($('<strong />').text(L.tr('Checksum') + ': '))
+                                               .append(info.checksum))
+                                       .append($('<li />')
+                                               .append($('<strong />').text(L.tr('Size') + ': '))
+                                               .append('%1024mB'.format(info.size)))
+                       ], {
+                               style: 'confirm',
+                               confirm: function() {
+                                       self.handle_backup_restore();
+                               }
+                       }
+               );
+       },
+
+       handle_backup_restore: function() {
+               var self = this;
+               L.system.restoreBackup().then(function(res) {
+                       if (res.code == 0)
+                       {
+                               L.ui.dialog(
+                                       L.tr('Backup restore'), [
+                                               $('<p />').text(L.tr('The backup was successfully restored, it is advised to reboot the system now in order to apply all configuration changes.')),
+                                               $('<input />')
+                                                       .addClass('cbi-button')
+                                                       .attr('type', 'button')
+                                                       .attr('value', L.tr('Reboot system'))
+                                                       .click(function() { alert('Reboot...'); })
+                                       ], {
+                                               style: 'close',
+                                               close: function() {
+                                                       L.system.cleanBackup().then(function() {
+                                                               L.ui.dialog(false);
+                                                       });
+                                               }
+                                       }
+                               );
+                       }
+                       else
+                       {
+                               L.ui.dialog(
+                                       L.tr('Backup restore'), [
+                                               $('<p />').text(L.tr('Backup restoration failed, the "sysupgrade" command responded with the message below:')),
+                                               $('<pre />')
+                                                       .addClass('alert-message')
+                                                       .text(res.stdout || res.stderr),
+                                               $('<p />').text(L.tr('Backup restoration failed with code %d.').format(res.code))
+                                       ], {
+                                               style: 'close',
+                                               close: function() {
+                                                       L.system.cleanBackup().then(function() {
+                                                               L.ui.dialog(false);
+                                                       });
+                                               }
+                                       }
+                               );
+                       }
+               });
+       },
+
+       handle_backup_download: function() {
+               var form = $('#btn_backup').parent();
+
+               form.find('[name=sessionid]').val(L.globals.sid);
+               form.submit();
+       },
+
+       handle_reset: function() {
+               L.ui.dialog(L.tr('Really reset all changes?'), L.tr('This will reset the system to its initial configuration, all changes made since the initial flash will be lost!'), {
+                       style: 'confirm',
+                       confirm: function() {
+                               //L.system.startReset().then(function() {
+                               //      L.ui.reconnect();
+                               //});
+
+                               alert('Reset...');
+                       }
+               });
+       },
+
+       execute: function() {
+               var self = this;
+
+               L.system.testReset().then(function(reset_avail) {
+                       if (!reset_avail) {
+                               $('#btn_reset').prop('disabled', true);
+                       }
+
+                       if (!self.options.acls.backup) {
+                               $('#btn_restore, #btn_save, textarea').prop('disabled', true);
+                       }
+                       else {
+                               $('#btn_backup').click(function() { self.handle_backup_download(); });
+                               $('#btn_restore').click(function() { self.handle_backup_upload(); });
+                       }
+
+                       if (!self.options.acls.upgrade) {
+                               $('#btn_flash, #btn_reset').prop('disabled', true);
+                       }
+                       else {
+                               $('#btn_flash').click(function() { self.handle_flash_upload(); });
+                               $('#btn_reset').click(function() { self.handle_reset(); });
+                       }
+
+                       return L.system.getBackupConfig();
+               }).then(function(config) {
+                       $('textarea')
+                               .attr('rows', (config.match(/\n/g) || [ ]).length + 1)
+                               .val(config);
+
+                       $('#btn_save')
+                               .click(function() {
+                                       var data = ($('textarea').val() || '').replace(/\r/g, '').replace(/\n?$/, '\n');
+                                       L.ui.loading(true);
+                                       L.system.setBackupConfig(data).then(function() {
+                                               $('textarea')
+                                                       .attr('rows', (data.match(/\n/g) || [ ]).length + 1)
+                                                       .val(data);
+
+                                               L.ui.loading(false);
+                                       });
+                               });
+
+                       $('#btn_list')
+                               .click(function() {
+                                       L.ui.loading(true);
+                                       L.system.listBackup().then(function(list) {
+                                               L.ui.loading(false);
+                                               L.ui.dialog(
+                                                       L.tr('Backup file list'),
+                                                       $('<textarea />')
+                                                               .css('width', '100%')
+                                                               .attr('rows', list.length)
+                                                               .prop('readonly', true)
+                                                               .val(list.join('\n')),
+                                                       { style: 'close' }
+                                               );
+                                       });
+                               });
+               }).then(function() {
+                       $('#tabs').show().tabs();
+               });
+       }
+});