mirror of
https://github.com/openwrt/luci.git
synced 2025-02-23 18:15:09 +00:00
Move classes required for Lua runtime support into a new `luci-lua-runtime` package. Also replace the `luci.http` and `luci.util` classes in `luci-lib-base` with stubbed versions interacting with the ucode based runtime environment. Finally merge `luci-base-ucode` into the remainders of `luci-base`. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
151 lines
3.2 KiB
Ucode
151 lines
3.2 KiB
Ucode
// Copyright 2022 Jo-Philipp Wich <jo@mein.io>
|
|
// Licensed to the public under the Apache License 2.0.
|
|
|
|
import { STATUS_NO_DATA, STATUS_PERMISSION_DENIED } from 'ubus';
|
|
|
|
let last_ubus_error;
|
|
|
|
const ubus_error_map = [
|
|
200, 'OK',
|
|
400, 'Invalid command',
|
|
400, 'Invalid argument',
|
|
404, 'Method not found',
|
|
404, 'Not found',
|
|
204, 'No data',
|
|
403, 'Permission denied',
|
|
504, 'Timeout',
|
|
500, 'Not supported',
|
|
500, 'Unknown error',
|
|
503, 'Connection failed',
|
|
500, 'Out of memory',
|
|
400, 'Parse error',
|
|
500, 'System error',
|
|
];
|
|
|
|
function ubus_call(object, method, args) {
|
|
ubus.error(); // clear previous error
|
|
|
|
let res = ubus.call(object, method, args);
|
|
|
|
last_ubus_error = ubus.error(true);
|
|
|
|
return res ?? !last_ubus_error;
|
|
}
|
|
|
|
function ubus_state_to_http(err) {
|
|
let code = ubus_error_map[(err << 1) + 0] ?? 200;
|
|
let msg = ubus_error_map[(err << 1) + 1] ?? 'OK';
|
|
|
|
http.status(code, msg);
|
|
|
|
if (code != 204) {
|
|
http.prepare_content('text/plain');
|
|
http.write(msg);
|
|
}
|
|
}
|
|
|
|
function uci_apply(rollback) {
|
|
if (rollback) {
|
|
const timeout = +(config?.apply?.rollback ?? 90) || 0;
|
|
const success = ubus_call('uci', 'apply', {
|
|
ubus_rpc_session: ctx.authsession,
|
|
timeout: max(timeout, 90),
|
|
rollback: true
|
|
});
|
|
|
|
if (success) {
|
|
const token = dispatcher.randomid(16);
|
|
|
|
ubus.call('session', 'set', {
|
|
ubus_rpc_session: '00000000000000000000000000000000',
|
|
values: {
|
|
rollback: {
|
|
token,
|
|
session: ctx.authsession,
|
|
timeout: time() + timeout
|
|
}
|
|
}
|
|
});
|
|
|
|
return token;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
else {
|
|
let changes = ubus_call('uci', 'changes', { ubus_rpc_session: ctx.authsession })?.changes;
|
|
|
|
for (let config in changes)
|
|
if (!ubus_call('uci', 'commit', { ubus_rpc_session: ctx.authsession, config }))
|
|
return false;
|
|
|
|
return ubus_call('uci', 'apply', {
|
|
ubus_rpc_session: ctx.authsession,
|
|
rollback: false
|
|
});
|
|
}
|
|
}
|
|
|
|
function uci_confirm(token) {
|
|
const data = ubus.call('session', 'get', {
|
|
ubus_rpc_session: '00000000000000000000000000000000',
|
|
keys: [ 'rollback' ]
|
|
})?.values?.rollback;
|
|
|
|
if (type(data?.token) != 'string' || type(data?.session) != 'string' ||
|
|
type(data?.timeout) != 'int' || data.timeout < time()) {
|
|
last_ubus_error = STATUS_NO_DATA;
|
|
|
|
return false;
|
|
}
|
|
|
|
if (token != data.token) {
|
|
last_ubus_error = STATUS_PERMISSION_DENIED;
|
|
|
|
return false;
|
|
}
|
|
|
|
if (!ubus_call('uci', 'confirm', { ubus_rpc_session: data.session }))
|
|
return false;
|
|
|
|
ubus_call('session', 'set', {
|
|
ubus_rpc_session: '00000000000000000000000000000000',
|
|
values: { rollback: {} }
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
return {
|
|
action_apply_rollback: function() {
|
|
const token = uci_apply(true);
|
|
|
|
if (token) {
|
|
http.prepare_content('application/json; charset=UTF-8');
|
|
http.write_json({ token });
|
|
}
|
|
else {
|
|
ubus_state_to_http(last_ubus_error);
|
|
}
|
|
},
|
|
|
|
action_apply_unchecked: function() {
|
|
uci_apply(false);
|
|
ubus_state_to_http(last_ubus_error);
|
|
},
|
|
|
|
action_confirm: function() {
|
|
uci_confirm(http.formvalue('token'));
|
|
ubus_state_to_http(last_ubus_error);
|
|
},
|
|
|
|
action_revert: function() {
|
|
for (let config in ubus_call('uci', 'changes', { ubus_rpc_session: ctx.authsession })?.changes)
|
|
if (!ubus_call('uci', 'revert', { ubus_rpc_session: ctx.authsession, config }))
|
|
break;
|
|
|
|
ubus_state_to_http(last_ubus_error);
|
|
}
|
|
};
|