mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-06 03:14:12 +08:00
This commit is contained in:
1 parent
c7bafc635d
commit
c71da84035
264 files changed
+8169
-3944
No files matched your search
@@ -8,7 +8,6 @@ let status = require('status');
|
||||
let config = require('config');
|
||||
let refresh = require('refresh');
|
||||
let rules = require('rules');
|
||||
let license = require('license');
|
||||
let statistics = require('statistics');
|
||||
|
||||
return {
|
||||
@@ -66,17 +65,7 @@ return {
|
||||
refresh: true
|
||||
},
|
||||
call: rules.delete
|
||||
},
|
||||
|
||||
license_get: {
|
||||
call: license.get
|
||||
},
|
||||
|
||||
license_update: {
|
||||
args: {
|
||||
license_key: ''
|
||||
},
|
||||
call: license.update
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
@@ -12,7 +12,6 @@ let reload_uci = core.reload_uci;
|
||||
let cfg = core.cfg;
|
||||
let to_bool = core.to_bool;
|
||||
let to_int = core.to_int;
|
||||
let mask_secret = core.mask_secret;
|
||||
let api_error = core.api_error;
|
||||
let uci_commit_option = core.uci_commit_option;
|
||||
let bool_uci = core.bool_uci;
|
||||
@@ -46,10 +45,6 @@ function build_config() {
|
||||
version: CONFIG_SCHEMA_VERSION
|
||||
},
|
||||
values: values,
|
||||
license: {
|
||||
configured: !!cfg('license_key', ''),
|
||||
key_masked: mask_secret(cfg('license_key', ''))
|
||||
},
|
||||
device: {
|
||||
vendor: cfg('device_vendor', ''),
|
||||
model: cfg('device_model', ''),
|
||||
@@ -67,9 +62,6 @@ function validate_config_value(name, value) {
|
||||
return api_error('dedicated_method_required', 'Use set_enabled to change enabled state', name);
|
||||
}
|
||||
|
||||
if (name == 'license_key') {
|
||||
return api_error('dedicated_method_required', 'Use license_update to change the license key', name);
|
||||
}
|
||||
|
||||
return api_error('unknown_option', 'Unsupported SafeShield configuration option', name);
|
||||
}
|
||||
|
||||
@@ -149,20 +149,6 @@ function identity_cfg(name, def) {
|
||||
return (v == null) ? def : v;
|
||||
}
|
||||
|
||||
function mask_secret(v) {
|
||||
let s = sprintf('%s', v || '');
|
||||
let n = length(s);
|
||||
|
||||
if (n == 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (n <= 8) {
|
||||
return '********';
|
||||
}
|
||||
|
||||
return sprintf('%s...%s', substr(s, 0, 4), substr(s, n - 4));
|
||||
}
|
||||
|
||||
function api_error(code, message, field) {
|
||||
let error = {
|
||||
@@ -242,7 +228,6 @@ return {
|
||||
reload_uci: reload_uci,
|
||||
cfg: cfg,
|
||||
identity_cfg: identity_cfg,
|
||||
mask_secret: mask_secret,
|
||||
api_error: api_error,
|
||||
uci_commit_option: uci_commit_option,
|
||||
uci_delete_option: uci_delete_option,
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
let core = require('core');
|
||||
let runtime = require('runtime');
|
||||
|
||||
let reload_uci = core.reload_uci;
|
||||
let cfg = core.cfg;
|
||||
let trim = core.trim;
|
||||
let mask_secret = core.mask_secret;
|
||||
let api_error = core.api_error;
|
||||
let uci_commit_option = core.uci_commit_option;
|
||||
let uci_delete_option = core.uci_delete_option;
|
||||
let start_refresh_async = runtime.start_refresh_async;
|
||||
let reset_statistics_upload_state = runtime.reset_statistics_upload_state;
|
||||
|
||||
function license_get_call() {
|
||||
reload_uci();
|
||||
|
||||
let key = cfg('license_key', '');
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
license: {
|
||||
configured: !!key,
|
||||
key: key
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function license_update_call(request) {
|
||||
reload_uci();
|
||||
|
||||
if (request.args.license_key == null) {
|
||||
return api_error('missing_argument', 'license_key is required; use an empty string to clear it', 'license_key');
|
||||
}
|
||||
|
||||
let key = trim(request.args.license_key);
|
||||
|
||||
if (length(key) > 512 || match(key, /[\r\n]/)) {
|
||||
return api_error('invalid_license_key', 'license_key must be at most 512 characters and contain no line breaks', 'license_key');
|
||||
}
|
||||
|
||||
let current = cfg('license_key', '');
|
||||
|
||||
if (current == key) {
|
||||
return {
|
||||
ok: true,
|
||||
changed: false,
|
||||
license: {
|
||||
configured: !!key,
|
||||
key_masked: mask_secret(key)
|
||||
},
|
||||
refresh: {
|
||||
requested: false,
|
||||
accepted: false,
|
||||
reason: 'unchanged'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let saved = key == ''
|
||||
? uci_delete_option('license_key')
|
||||
: uci_commit_option('license_key', key);
|
||||
|
||||
if (!saved) {
|
||||
return api_error('uci_commit_failed', 'Failed to update the SafeShield license key');
|
||||
}
|
||||
|
||||
reset_statistics_upload_state();
|
||||
let refresh = start_refresh_async();
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
changed: true,
|
||||
license: {
|
||||
configured: !!key,
|
||||
key_masked: mask_secret(key)
|
||||
},
|
||||
refresh: {
|
||||
requested: true,
|
||||
accepted: refresh.accepted,
|
||||
reason: refresh.reason || ''
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
get: license_get_call,
|
||||
update: license_update_call
|
||||
};
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
let core = require('core');
|
||||
let fs = require('fs');
|
||||
let ubus = require('ubus').connect();
|
||||
|
||||
let PKG_NAME = core.PKG_NAME;
|
||||
let STATUS_FILE = core.STATUS_FILE;
|
||||
@@ -12,43 +11,72 @@ let to_bool = core.to_bool;
|
||||
let reload_uci = core.reload_uci;
|
||||
let cfg = core.cfg;
|
||||
|
||||
function service_running(name) {
|
||||
let r = ubus.call('service', 'list', { name: name });
|
||||
if (!r || !r[name] || !r[name].instances) {
|
||||
return false;
|
||||
// Do not call ubus synchronously from an rpcd handler. In particular,
|
||||
// service.list may require the same event loop currently serving the caller.
|
||||
// Use an independent ubus client with its built-in -t timeout (seconds).
|
||||
// BusyBox/OpenWrt installations do not necessarily provide coreutils timeout.
|
||||
// Only successful procd lookups are briefly reused. A failed lookup must not
|
||||
// poison subsequent requests or be mistaken for a stopped service.
|
||||
let service_cache = {};
|
||||
|
||||
function service_status(name, use_cache) {
|
||||
if (name != PKG_NAME && name != 'dnsmasq') {
|
||||
return { state: 'unknown', running: false, lookup_ok: false };
|
||||
}
|
||||
|
||||
for (let inst_name, inst in r[name].instances) {
|
||||
if (inst.running) {
|
||||
return true;
|
||||
let now = time();
|
||||
let cached = service_cache[name];
|
||||
if (use_cache && cached && cached.at == now) {
|
||||
return cached.value;
|
||||
}
|
||||
|
||||
let pipe = fs.popen(sprintf("ubus -t 2 call service list '{\"name\":\"%s\"}' 2>/dev/null", name), 'r');
|
||||
if (!pipe) {
|
||||
return { state: 'unknown', running: false, lookup_ok: false };
|
||||
}
|
||||
|
||||
let output = pipe.read('all');
|
||||
pipe.close();
|
||||
if (!output) {
|
||||
return { state: 'unknown', running: false, lookup_ok: false };
|
||||
}
|
||||
|
||||
let result = json(output);
|
||||
// procd returns an empty object when the named service is absent.
|
||||
// That is a valid stopped response, not a transport failure.
|
||||
if (type(result) != 'object') {
|
||||
return { state: 'unknown', running: false, lookup_ok: false };
|
||||
}
|
||||
|
||||
let instances = result[name] && result[name].instances;
|
||||
let running = false;
|
||||
if (type(instances) == 'object') {
|
||||
for (let instance_name, instance in instances) {
|
||||
if (instance && instance.running) {
|
||||
running = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
let value = { state: running ? 'running' : 'stopped', running: running, lookup_ok: true, instances: instances || {} };
|
||||
if (use_cache) {
|
||||
service_cache[name] = { at: now, value: value };
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function service_running(name) {
|
||||
return service_status(name, false).running;
|
||||
}
|
||||
|
||||
function service_instance_running(name, instance_name) {
|
||||
let r = ubus.call('service', 'list', { name: name });
|
||||
if (!r || !r[name] || !r[name].instances || !r[name].instances[instance_name]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!r[name].instances[instance_name].running;
|
||||
let state = service_status(name, false);
|
||||
return !!(state.instances && state.instances[instance_name] && state.instances[instance_name].running);
|
||||
}
|
||||
|
||||
function dnsmasq_running() {
|
||||
let r = ubus.call('service', 'list', { name: 'dnsmasq' });
|
||||
if (!r || !r.dnsmasq || !r.dnsmasq.instances) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let inst_name, inst in r.dnsmasq.instances) {
|
||||
if (inst.running) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return service_running('dnsmasq');
|
||||
}
|
||||
|
||||
function run_service_action(action, timeout_ms) {
|
||||
@@ -85,10 +113,11 @@ function start_refresh_async() {
|
||||
};
|
||||
}
|
||||
|
||||
if (!service_running(PKG_NAME)) {
|
||||
let service = service_status(PKG_NAME, false);
|
||||
if (!service.running) {
|
||||
return {
|
||||
accepted: false,
|
||||
reason: 'service_stopped'
|
||||
reason: service.lookup_ok ? 'service_stopped' : 'service_unavailable'
|
||||
};
|
||||
}
|
||||
|
||||
@@ -129,10 +158,11 @@ function start_local_apply_async() {
|
||||
};
|
||||
}
|
||||
|
||||
if (!service_running(PKG_NAME)) {
|
||||
let service = service_status(PKG_NAME, false);
|
||||
if (!service.running) {
|
||||
return {
|
||||
accepted: false,
|
||||
reason: 'service_stopped'
|
||||
reason: service.lookup_ok ? 'service_stopped' : 'service_unavailable'
|
||||
};
|
||||
}
|
||||
|
||||
@@ -155,6 +185,7 @@ function start_local_apply_async() {
|
||||
|
||||
return {
|
||||
service_running: service_running,
|
||||
service_status: service_status,
|
||||
service_instance_running: service_instance_running,
|
||||
dnsmasq_running: dnsmasq_running,
|
||||
run_service_action: run_service_action,
|
||||
|
||||
@@ -91,7 +91,8 @@ function build_statistics() {
|
||||
let snapshot_interval_s = to_int(cfg('statistics_snapshot_interval_s', '60'), 60);
|
||||
let data = read_json_file(STATISTICS_FILE, {});
|
||||
let totals = (type(data.totals) == 'object') ? data.totals : {};
|
||||
let collector_running = service_instance_running(PKG_NAME, 'statistics');
|
||||
let collector_service = runtime.service_status(PKG_NAME, true);
|
||||
let collector_running = !!(collector_service.instances && collector_service.instances.statistics && collector_service.instances.statistics.running);
|
||||
let effective_enabled = enabled && collector_running;
|
||||
let source = sanitize_source(data.source);
|
||||
if (!effective_enabled) {
|
||||
@@ -106,6 +107,8 @@ function build_statistics() {
|
||||
effective_enabled: effective_enabled,
|
||||
available: !!data.schema,
|
||||
collector_running: collector_running,
|
||||
collector_state: collector_service.lookup_ok ? (collector_running ? 'running' : 'stopped') : 'unknown',
|
||||
collector_lookup_ok: collector_service.lookup_ok,
|
||||
volatile: to_bool(data.volatile, true),
|
||||
storage: sprintf('%s', data.storage || 'tmpfs'),
|
||||
persistent: to_bool(data.persistent, false),
|
||||
|
||||
@@ -20,7 +20,6 @@ let file_size_kb = core.file_size_kb;
|
||||
let to_bool = core.to_bool;
|
||||
let to_optional_bool = core.to_optional_bool;
|
||||
let to_int = core.to_int;
|
||||
let mask_secret = core.mask_secret;
|
||||
let service_running = runtime.service_running;
|
||||
let dnsmasq_running = runtime.dnsmasq_running;
|
||||
|
||||
@@ -134,8 +133,6 @@ function build_status() {
|
||||
let refresh_interval_s = to_int(cfg('refresh_interval_s', '28800'), 28800);
|
||||
let boot_start_delay_s = to_int(cfg('boot_start_delay_s', '30'), 30);
|
||||
|
||||
let license_key = cfg('license_key', '');
|
||||
let license_configured = !!license_key;
|
||||
let apply_local_overrides = to_bool(cfg('apply_local_overrides', '1'), true);
|
||||
|
||||
let cfg_physical_fingerprint = identity_cfg('physical_fingerprint', '');
|
||||
@@ -186,8 +183,8 @@ function build_status() {
|
||||
let artifact_block_source_count = to_int(data.artifact_block_source_count || (artifact_download_url_present ? 1 : 0), 0);
|
||||
let artifact_allow_source_count = to_int(data.artifact_allow_source_count || 0, 0);
|
||||
|
||||
let license_plan = data.license_plan || '';
|
||||
let license_status = data.license_status || '';
|
||||
let entitlement_plan = data.entitlement_plan || '';
|
||||
let entitlement_status = data.entitlement_status || '';
|
||||
let physical_fingerprint = data.physical_fingerprint || cfg_physical_fingerprint || '';
|
||||
let fingerprint_version = to_int(data.fingerprint_version || cfg_fingerprint_version || 1, 1);
|
||||
let identity_provider = data.identity_provider || cfg_identity_provider || '';
|
||||
@@ -217,8 +214,10 @@ function build_status() {
|
||||
|
||||
let hub_source = build_api_source(data, enabled);
|
||||
let installed = blocklist_installed || file_exists(BLOCKLIST_FILE);
|
||||
let refreshd_running = service_running(PKG_NAME);
|
||||
let dns_running = dnsmasq_running();
|
||||
let refresh_service = runtime.service_status(PKG_NAME, true);
|
||||
let dns_service = runtime.service_status('dnsmasq', true);
|
||||
let refreshd_running = refresh_service.running;
|
||||
let dns_running = dns_service.running;
|
||||
|
||||
let generated_at = time();
|
||||
let next_refresh_in_s = 0;
|
||||
@@ -245,7 +244,11 @@ function build_status() {
|
||||
|
||||
runtime: {
|
||||
refreshd_running: refreshd_running,
|
||||
refreshd_state: refresh_service.state,
|
||||
refreshd_lookup_ok: refresh_service.lookup_ok,
|
||||
dnsmasq_running: dns_running,
|
||||
dnsmasq_state: dns_service.state,
|
||||
dnsmasq_lookup_ok: dns_service.lookup_ok,
|
||||
dnsmasq_version: dnsmasq_version,
|
||||
dnsmasq_min_version: dnsmasq_min_version,
|
||||
dns_runtime_ok: health_dns_runtime || dns_running,
|
||||
@@ -255,11 +258,9 @@ function build_status() {
|
||||
last_result: last_result,
|
||||
last_error_code: last_error_code
|
||||
},
|
||||
license: {
|
||||
configured: license_configured,
|
||||
key_masked: mask_secret(license_key),
|
||||
plan: license_plan,
|
||||
status: license_status
|
||||
entitlement: {
|
||||
plan: entitlement_plan,
|
||||
status: entitlement_status
|
||||
},
|
||||
|
||||
device: {
|
||||
|
||||
Reference in new issue
Block a user