diff --git a/srl-blue-merle/usr/libexec/blue-merle b/srl-blue-merle/usr/libexec/blue-merle
new file mode 100755
index 0000000..a758ac5
--- /dev/null
+++ b/srl-blue-merle/usr/libexec/blue-merle
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo Hello, World!
diff --git a/srl-blue-merle/usr/share/luci/menu.d/luci-app-opkg2.json b/srl-blue-merle/usr/share/luci/menu.d/luci-app-opkg2.json
index b4d2d79..bc5db82 100644
--- a/srl-blue-merle/usr/share/luci/menu.d/luci-app-opkg2.json
+++ b/srl-blue-merle/usr/share/luci/menu.d/luci-app-opkg2.json
@@ -1,13 +1,13 @@
{
- "admin/system/opkg2": {
- "title": "Software",
+ "admin/network/blue-merle": {
+ "title": "Blue Merle",
"order": 30,
"action": {
"type": "view",
"path": "opkg2"
},
"depends": {
- "acl": [ "luci-app-opkg2" ]
+ "acl": [ "luci-app-blue-merle" ]
}
}
}
diff --git a/srl-blue-merle/usr/share/rpcd/acl.d/luci-app-blue-merle.json b/srl-blue-merle/usr/share/rpcd/acl.d/luci-app-blue-merle.json
new file mode 100644
index 0000000..8e9ff2c
--- /dev/null
+++ b/srl-blue-merle/usr/share/rpcd/acl.d/luci-app-blue-merle.json
@@ -0,0 +1,26 @@
+{
+ "luci-app-blue-merle": {
+ "description": "Grant access to opkg management",
+ "read": {
+ "cgi-io": [ "exec" ],
+ "file": {
+ "/usr/libexec/blue-merle": [ "exec" ],
+ "/usr/libexec/blue-merle shred": [ "exec" ],
+ "/usr/libexec/blue-merle *": [ "exec" ],
+ "/etc/opkg.conf": [ "read" ],
+ "/etc/opkg/*.conf": [ "read" ]
+ },
+ "ubus": {
+ "luci": [ "getMountPoints" ]
+ }
+ },
+ "write": {
+ "file": {
+ "/usr/libexec/blue-merle": [ "exec" ],
+ "/usr/libexec/blue-merle shred": [ "exec" ],
+ "/usr/libexec/blue-merle *": [ "exec" ],
+ "/tmp/upload.ipk": [ "write" ]
+ }
+ }
+ }
+}
diff --git a/srl-blue-merle/usr/share/rpcd/acl.d/luci-app-opkg2.json b/srl-blue-merle/usr/share/rpcd/acl.d/luci-app-opkg2.json
deleted file mode 100644
index 1ed3aa0..0000000
--- a/srl-blue-merle/usr/share/rpcd/acl.d/luci-app-opkg2.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "luci-app-opkg2": {
- "description": "Grant access to opkg management",
- "read": {
- "cgi-io": [ "exec" ],
- "file": {
- "/usr/libexec/opkg-list installed": [ "exec" ],
- "/usr/libexec/opkg-list available": [ "exec" ],
- "/usr/libexec/opkg-call list-installed": [ "exec" ],
- "/usr/libexec/opkg-call list-available": [ "exec" ],
- "/etc/opkg.conf": [ "read" ],
- "/etc/opkg/*.conf": [ "read" ]
- },
- "ubus": {
- "luci": [ "getMountPoints" ]
- }
- },
- "write": {
- "file": {
- "/usr/libexec/opkg-call install *": [ "exec" ],
- "/usr/libexec/opkg-call remove *": [ "exec" ],
- "/usr/libexec/opkg-call update *": [ "exec" ],
- "/etc/opkg.conf": [ "write" ],
- "/etc/opkg/*.conf": [ "write" ],
- "/tmp/upload.ipk": [ "write" ]
- }
- }
- }
-}
diff --git a/srl-blue-merle/www/luci-static/resources/view/opkg2.js b/srl-blue-merle/www/luci-static/resources/view/opkg2.js
index 72a444c..f167a7e 100644
--- a/srl-blue-merle/www/luci-static/resources/view/opkg2.js
+++ b/srl-blue-merle/www/luci-static/resources/view/opkg2.js
@@ -199,140 +199,6 @@ function parseList(s, dest)
}
}
-function display(pattern)
-{
- var src = packages[currentDisplayMode === 'updates' ? 'installed' : currentDisplayMode],
- table = document.querySelector('#packages'),
- pagers = document.querySelectorAll('.controls > .pager'),
- i18n_filter = null;
-
- currentDisplayRows.length = 0;
-
- if (typeof(pattern) === 'string' && pattern.length > 0)
- pattern = new RegExp(pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'ig');
-
- switch (document.querySelector('input[name="filter_i18n"]:checked').value) {
- case 'all':
- i18n_filter = /^luci-i18n-/;
- break;
-
- case 'lang':
- i18n_filter = new RegExp('^luci-i18n-(base-.+|.+-(' + languages.join('|') + '))$');
- break;
- }
-
- for (var name in src.pkgs) {
- var pkg = src.pkgs[name],
- desc = pkg.description || '',
- altsize = null;
-
- if (!pkg.size && packages.available.pkgs[name])
- altsize = packages.available.pkgs[name].size;
-
- if (!desc && packages.available.pkgs[name])
- desc = packages.available.pkgs[name].description || '';
-
- desc = desc.split(/\n/);
- desc = desc[0].trim() + (desc.length > 1 ? '…' : '');
-
- if ((pattern instanceof RegExp) &&
- !name.match(pattern) && !desc.match(pattern))
- continue;
-
- if (name.indexOf('luci-i18n-') === 0 && (!(i18n_filter instanceof RegExp) || !name.match(i18n_filter)))
- continue;
-
- var btn, ver;
-
- if (currentDisplayMode === 'updates') {
- var avail = packages.available.pkgs[name],
- inst = packages.installed.pkgs[name];
-
- if (!inst || !inst.installed)
- continue;
-
- if (!avail || compareVersion(avail.version, pkg.version) <= 0)
- continue;
-
- ver = '%s » %s'.format(
- truncateVersion(pkg.version || '-'),
- truncateVersion(avail.version || '-'));
-
- btn = E('div', {
- 'class': 'btn cbi-button-positive',
- 'data-package': name,
- 'click': handleInstall
- }, _('Upgrade…'));
- }
- else if (currentDisplayMode === 'installed') {
- if (!pkg.installed)
- continue;
-
- ver = truncateVersion(pkg.version || '-');
- btn = E('div', {
- 'class': 'btn cbi-button-negative',
- 'data-package': name,
- 'click': handleRemove
- }, _('Remove…'));
- }
- else {
- var inst = packages.installed.pkgs[name];
-
- ver = truncateVersion(pkg.version || '-');
-
- if (!inst || !inst.installed)
- btn = E('div', {
- 'class': 'btn cbi-button-action',
- 'data-package': name,
- 'click': handleInstall
- }, _('Install…'));
- else if (inst.installed && inst.version != pkg.version)
- btn = E('div', {
- 'class': 'btn cbi-button-positive',
- 'data-package': name,
- 'click': handleInstall
- }, _('Upgrade…'));
- else
- btn = E('div', {
- 'class': 'btn cbi-button-neutral',
- 'disabled': 'disabled'
- }, _('Installed'));
- }
-
- name = '%h'.format(name);
- desc = '%h'.format(desc || '-');
-
- if (pattern) {
- name = name.replace(pattern, '$&');
- desc = desc.replace(pattern, '$&');
- }
-
- currentDisplayRows.push([
- name,
- ver,
- pkg.size ? '%1024mB'.format(pkg.size)
- : (altsize ? '~%1024mB'.format(altsize) : '-'),
- desc,
- btn
- ]);
- }
-
- currentDisplayRows.sort(function(a, b) {
- if (a[0] < b[0])
- return -1;
- else if (a[0] > b[0])
- return 1;
- else
- return 0;
- });
-
- for (var i = 0; i < pagers.length; i++) {
- pagers[i].parentNode.style.display = '';
- pagers[i].setAttribute('data-offset', 100);
- }
-
- handlePage({ target: pagers[0].querySelector('.prev') });
-}
function handlePage(ev)
{
@@ -852,9 +718,48 @@ function handleConfig(ev)
{
var conf = {};
- ui.showModal(_('OPKG Configuration'), [
- E('p', { 'class': 'spinning' }, _('Loading configuration data…'))
- ]);
+ var cmd = "/usr/libexec/blue-merle";
+ var dlg = ui.showModal(_('Executing blue merle'), [
+ E('p', { 'class': 'spinning' },
+ _('Waiting for the %h command to complete…').format(cmd))
+ ]);
+
+ var argv = []; //["shred"];
+ fs.exec_direct('/usr/libexec/blue-merle', argv, 'json').then(function(res) {
+
+ if (res.stdout)
+ dlg.appendChild(E('pre', [ res.stdout ]));
+
+ if (res.stderr) {
+ dlg.appendChild(E('h5', _('Errors')));
+ dlg.appendChild(E('pre', { 'class': 'errors' }, [ res.stderr ]));
+ }
+
+ if (res.code !== 0)
+ dlg.appendChild(E('p', _('The opkg %h command failed with code %d
.').format(cmd, (res.code & 0xff) || -1)));
+
+ dlg.appendChild(E('div', { 'class': 'right' },
+ E('div', {
+ 'class': 'btn',
+ 'click': L.bind(function(res) {
+ if (ui.menu && ui.menu.flushCache)
+ ui.menu.flushCache();
+
+ ui.hideModal();
+ updateLists();
+
+ if (res.code !== 0)
+ rejectFn(new Error(res.stderr || 'opkg error %d'.format(res.code)));
+ else
+ resolveFn(res);
+ }, this, res)
+ }, _('Dismiss'))));
+ }).catch(function(err) {
+ ui.addNotification(null, E('p', _('Unable to execute opkg %s command: %s').format(cmd, err)));
+ ui.hideModal();
+ });
+
+
fs.list('/etc/opkg').then(function(partials) {
var files = [ '/etc/opkg.conf' ];
@@ -914,7 +819,7 @@ function handleConfig(ev)
}, _('Save')),
]));
- ui.showModal(_('OPKG Configuration'), body);
+ //ui.showModal(_('OPKG Configuration'), body);
});
}