mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-29 17:42:41 +00:00 
			
		
		
		
	ucentral-state: add unified state management
Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
		| @@ -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/ | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
| @@ -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 | ||||
| } | ||||
| @@ -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 | ||||
| 	} | ||||
| } | ||||
| @@ -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 | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
							
								
								
									
										28
									
								
								feeds/ucentral/ucentral-state/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								feeds/ucentral/ucentral-state/Makefile
									
									
									
									
									
										Normal 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)) | ||||
							
								
								
									
										32
									
								
								feeds/ucentral/ucentral-state/files/ucentral-pstore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								feeds/ucentral/ucentral-state/files/ucentral-pstore
									
									
									
									
									
										Normal 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'); | ||||
							
								
								
									
										172
									
								
								feeds/ucentral/ucentral-state/files/ucentral-state
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										172
									
								
								feeds/ucentral/ucentral-state/files/ucentral-state
									
									
									
									
									
										Executable 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(); | ||||
							
								
								
									
										18
									
								
								feeds/ucentral/ucentral-state/files/ucentral-state.init
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								feeds/ucentral/ucentral-state/files/ucentral-state.init
									
									
									
									
									
										Normal 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 "$@" | ||||
| } | ||||
							
								
								
									
										56
									
								
								patches/0061-ucentral-state-OpenWrt-integration.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								patches/0061-ucentral-state-OpenWrt-integration.patch
									
									
									
									
									
										Normal 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 | ||||
|  | ||||
| @@ -43,6 +43,7 @@ packages: | ||||
|   - ucentral-dataplane | ||||
|   - ucentral-event | ||||
|   - ucentral-schema | ||||
|   - ucentral-state | ||||
|   - ucentral-tools | ||||
|   - udhcprelay | ||||
|   - ugps | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 John Crispin
					John Crispin