ucentral-state: add unified state management

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2023-09-11 08:35:25 +02:00
parent eef130b2fe
commit 5ff383df91
12 changed files with 309 additions and 84 deletions

View File

@@ -21,7 +21,7 @@ start_service() {
mkdir -p /tmp/ucentral/
ucode -l fs /usr/share/ucentral/pstore.uc
#ucode -l fs /usr/share/ucentral/pstore.uc
. /lib/functions.sh
cp /etc/config-shadow/ucentral /etc/config/

View File

@@ -1,14 +0,0 @@
#!/bin/sh /etc/rc.common
START=99
USE_PROCD=1
PROG=/usr/libexec/ucentral-wdt.sh
start_service() {
active=$(readlink /etc/ucentral/ucentral.active)
[ -n "$active" -a "$active" != "/etc/ucentral/ucentral.cfg.0000000001" ] && return 0
procd_open_instance
procd_set_param command "$PROG"
procd_close_instance
}

View File

@@ -1,27 +0,0 @@
#!/bin/sh /etc/rc.common
START=99
USE_PROCD=1
PROG=/usr/share/ucentral/health.uc
boot() {
# dummy stub to make sure health does not start before
# a config is applied
true
}
service_triggers() {
procd_add_reload_trigger ustats
}
start_service() {
. /lib/functions.sh
config_load 'ustats'
config_get interval 'health' 'interval' 120
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn 1 $interval 0
procd_close_instance
}

View File

@@ -1,23 +0,0 @@
#!/bin/sh /etc/rc.common
START=99
USE_PROCD=1
PROG=/usr/share/ucentral/state.uc
service_triggers() {
procd_add_reload_trigger ustats
}
start_service() {
. /lib/functions.sh
config_load 'ustats'
config_get interval 'stats' 'interval' 0
[ "$interval" -eq 0 ] || {
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn 1 $interval 0
procd_close_instance
}
}

View File

@@ -1,16 +0,0 @@
#!/bin/sh
sleep 60
[ -f /etc/ucentral/redirector.json ] || return 0
active=$(ubus call ucentral status | jsonfilter -e '@.active')
[ -n "$active" -a ! "$active" -eq 1 ] && {
logger ucentral-wdt: all good
exit 0
}
logger ucentral-wdt: restarting client
/etc/init.d/ucentral restart

View File

@@ -4,11 +4,9 @@ PKG_NAME:=ucentral-schema
PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-schema.git
PKG_MIRROR_HASH:=edb9bc0b8209226f585c724c88720eab2263c33eff6ebe2f2a5898896eb1fc11
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2022-05-29
PKG_SOURCE_VERSION:=e9529eab9cae27f170bdb440eb60d7a0a2588cea
PKG_SOURCE_VERSION:=357eaf3deb61836bc88c1862550c7cd3cdf08c7f
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
PKG_LICENSE:=BSD-3-Clause

View File

@@ -0,0 +1,28 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ucentral-state
PKG_RELEASE:=1
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
PKG_LICENSE:=BSD-3-Clause
include $(INCLUDE_DIR)/package.mk
define Package/ucentral-state
SECTION:=ucentral
CATEGORY:=uCentral
TITLE:=uCentral state monitoring daemon
endef
define Build/Compile
endef
define Package/ucentral-state/install
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/config
$(INSTALL_BIN) ./files/ucentral-state $(1)/usr/sbin/
$(INSTALL_BIN) ./files/ucentral-pstore $(1)/usr/sbin/
$(INSTALL_BIN) ./files/ucentral-state.init $(1)/etc/init.d/ucentral-state
endef
$(eval $(call BuildPackage,ucentral-state))

View File

@@ -0,0 +1,32 @@
#!/usr/bin/ucode
'use strict';
import * as fs from 'fs';
function move_to_json(src, dst) {
if (!fs.stat(src))
return 0;
let fd = fs.open(src, "r");
let line, lines = [];
while (line = fd.read("line")) {
line = trim(line);
try {
line = json(line);
} catch(c) {};
push(lines, line);
}
fd.close();
fs.unlink(src);
fd = fs.open(dst, "w");
let msg = {};
msg[fs.basename(dst)] = lines;
fd.write(msg);
fd.close();
print(lines);
}
move_to_json('/sys/fs/pstore/dmesg-ramoops-0', '/tmp/crashlog');
move_to_json('/sys/fs/pstore/console-ramoops-0', '/tmp/consolelog');
move_to_json('/sys/fs/pstore/pmsg-ramoops-0', '/tmp/pstore');
move_to_json('/sys/fs/pstore/pmsg-ramoops-0', '/tmp/pstore-state');

View File

@@ -0,0 +1,172 @@
#!/usr/bin/ucode
'use strict';
import * as libubus from 'ubus';
import * as libuci from 'uci';
import * as uloop from 'uloop';
import * as nl80211 from 'nl80211';
import * as rtnl from 'rtnl';
import * as fs from 'fs';
uloop.init();
let ubus = libubus.connect();
let uci = libuci.cursor();
let config;
let healthcheck;
healthcheck = {
run: function(delay) {
if (healthcheck.timer)
healthcheck.timer.cancel();
if (healthcheck.pid)
healthcheck.pid.delete();
printf('start healthcheck in ' + delay / 1000 + ' seconds\n');
healthcheck.delay = delay;
if (delay)
healthcheck.timer = uloop.timer(delay, healthcheck.spawn)
},
complete: function() {
printf('healtcheck completed\n');
healthcheck.run(healthcheck.delay);
},
spawn: function() {
printf('healtcheck execute\n');
healthcheck.pid = uloop.process('/usr/share/ucentral/health.uc', [], {}, healthcheck.complete);
},
};
let state;
state = {
run: function(delay) {
if (state.timer)
state.timer.cancel();
if (state.pid)
state.pid.delete();
printf('start state in ' + delay / 1000 + ' seconds\n');
state.delay = delay;
if (delay)
state.timer = uloop.timer(delay, state.spawn)
},
complete: function() {
printf('state completed\n');
state.run(state.delay);
},
spawn: function() {
printf('state execute\n');
state.pid = uloop.process('/usr/share/ucentral/state.uc', [], {}, state.complete);
},
};
function config_load() {
uci.load('ustats');
config = uci.get_all('ustats');
healthcheck.run((config?.health?.interval || 0) * 1000);
state.run((config?.stats?.interval || 0) * 1000);
}
function led_write(led, property, value) {
let path = '/sys/class/leds/' + led + '/' + property;
let current = trim(fs.readfile(path));
if (current == value)
return;
let file = fs.open(path, 'w');
if (!file)
return;
file.write(value);
file.close();
}
function led_find(alias) {
let path = fs.readfile('/proc/device-tree/aliases/' + alias);
if (!path)
return;
return trim(fs.readfile('/proc/device-tree/' + trim(path) + '/label'));
}
function factory_reset_timeout() {
let led = led_find('led-running');
if (led)
led_write(led, 'trigger', 'default-on');
}
let blink_timer;
function blink_timeout() {
if (!blink_timer)
return;
blink_timer.cancel();
blink_timer = null;
system('/etc/init.d/led turnon');
}
let state_handler = {
connect: function() {
let led = led_find('led-running');
if (!led)
return ubus.STATUS_INVALID_ARGUMENT;
led_write(led, 'trigger', 'heartbeat');
return 0;
},
online: function() {
let led = led_find('led-running');
if (!led)
return ubus.STATUS_INVALID_ARGUMENT;
led_write(led, 'trigger', 'default-on');
return 0;
},
'factory-reset': function() {
let led = led_find('led-running');
if (!led)
return ubus.STATUS_INVALID_ARGUMENT;
led_write(led, 'trigger', 'timer');
led_write(led, 'delay_on', '100');
led_write(led, 'delay_off', '100');
uloop.timer(6000, factory_reset_timeout);
return 0;
},
blink: function(args) {
system('/etc/init.d/led blink');
blink_timer = uloop.timer((args.duration || 10) * 1000, blink_timeout);
return 0;
},
};
let ubus_methods = {
set: {
call: function(req) {
if (!state_handler[req.args.state])
return ubus.STATUS_INVALID_ARGUMENT;
blink_timeout();
printf('set state -> ' + req.args.state + '\n');
return state_handler[req.args.state](req.args);
},
args: {
state:'',
duration: 0
}
},
reload: {
call: function(req) {
config_load();
return 0;
},
args: {
}
},
};
ubus.publish('state', ubus_methods);
config_load();
uloop.run();
uloop.done();

View File

@@ -0,0 +1,18 @@
#!/bin/sh /etc/rc.common
START=80
USE_PROCD=1
PROG=/usr/sbin/ucentral-state
start_service() {
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn 3600 1 0
procd_close_instance
}
boot() {
/usr/sbin/ucentral-pstore
start "$@"
}

View File

@@ -0,0 +1,56 @@
From d7dc13e260c94f3686576aa1d64159201683164d Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Mon, 11 Sep 2023 08:16:52 +0200
Subject: [PATCH] ucentral-state: OpenWrt integration
Signed-off-by: John Crispin <john@phrozen.org>
---
package/base-files/files/etc/diag.sh | 7 +++++++
package/base-files/files/etc/init.d/done | 2 +-
package/base-files/files/etc/rc.button/reset | 1 +
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/package/base-files/files/etc/diag.sh b/package/base-files/files/etc/diag.sh
index 37a8ec758e..27a3052ade 100644
--- a/package/base-files/files/etc/diag.sh
+++ b/package/base-files/files/etc/diag.sh
@@ -35,6 +35,13 @@ set_led_state() {
status_led="$upgrade"
status_led_blink_preinit_regular
;;
+ reboot)
+
+ ;;
+ connect)
+ status_led="$running"
+ status_led_set_heartbeat
+ ;;
done)
status_led_off
[ "$status_led" != "$running" ] && \
diff --git a/package/base-files/files/etc/init.d/done b/package/base-files/files/etc/init.d/done
index 32d6118df7..016df40dcc 100755
--- a/package/base-files/files/etc/init.d/done
+++ b/package/base-files/files/etc/init.d/done
@@ -13,5 +13,5 @@ boot() {
# set leds to normal state
. /etc/diag.sh
- set_state done
+ set_state connect
}
diff --git a/package/base-files/files/etc/rc.button/reset b/package/base-files/files/etc/rc.button/reset
index 2403122ad2..2f558fe035 100755
--- a/package/base-files/files/etc/rc.button/reset
+++ b/package/base-files/files/etc/rc.button/reset
@@ -6,6 +6,7 @@ OVERLAY="$( grep ' /overlay ' /proc/mounts )"
case "$ACTION" in
pressed)
+ ubus call state set '{"state": "factory-reset"}'
[ -z "$OVERLAY" ] && return 0
return 5
--
2.34.1

View File

@@ -43,6 +43,7 @@ packages:
- ucentral-dataplane
- ucentral-event
- ucentral-schema
- ucentral-state
- ucentral-tools
- udhcprelay
- ugps