Skip to content

Commit e28532d

Browse files
authored
Merge pull request #1523 from saba8814/feat/add-scheduler-support
Add support for ietf-schedule
2 parents 19c820f + 797c5c0 commit e28532d

29 files changed

Lines changed: 1767 additions & 32 deletions
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
if [ -s /run/os-update ]; then
2+
printf '\n\033[1;33m *** %s ***\033[0m\n\n' "$(cat /run/os-update)"
3+
fi
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
f /run/os-update 0666 admin admin
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/bin/sh
2+
# Check for available software updates and notify on login if one exists.
3+
# Called by the scheduler.
4+
5+
NOTIFY_FILE=/run/os-update
6+
TAG=os-update
7+
8+
# Source os-release for VERSION and IMAGE_ID
9+
if [ ! -f /etc/os-release ]; then
10+
logger -t "$TAG" "ERROR: /etc/os-release not found"
11+
exit 1
12+
fi
13+
. /etc/os-release
14+
15+
# Dev/dirty builds have no comparable semver — always show the latest release
16+
IS_RELEASE=true
17+
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+'; then
18+
IS_RELEASE=false
19+
fi
20+
21+
# Read configured update-url from running config, fall back to upstream
22+
UPDATE_URL=$(copy running-config \
23+
-x '/ietf-system:system/infix-system:software/check-update/update-url' \
24+
2>/dev/null \
25+
| jq -r '.. | objects | ."update-url"? // empty')
26+
UPDATE_URL=${UPDATE_URL:-"https://github.com/kernelkit/infix"}
27+
28+
# Derive API URL from the configured update URL.
29+
# Default (github.com): https://github.com/org/repo → https://api.github.com/repos/org/repo
30+
REPO=$(echo "$UPDATE_URL" | sed 's|https://github.com/||; s|/*$||')
31+
API_URL="https://api.github.com/repos/${REPO}/releases/latest"
32+
33+
LATEST_TAG=$(curl -sSL --max-time 10 "$API_URL" 2>/dev/null \
34+
| jq -r '.tag_name // empty')
35+
if [ -z "$LATEST_TAG" ]; then
36+
logger -p daemon.info -t "$TAG" "Update check skipped: could not reach ${API_URL}"
37+
exit 0
38+
fi
39+
LATEST=${LATEST_TAG#v}
40+
41+
# Compare: is $1 strictly newer than $2?
42+
newer() {
43+
[ "$1" = "$2" ] && return 1
44+
[ "$(printf '%s\n%s' "$1" "$2" | sort -V | tail -1)" = "$1" ]
45+
}
46+
47+
if [ "$IS_RELEASE" = false ] || newer "$LATEST" "$VERSION"; then
48+
RELEASE_URL="${UPDATE_URL}/releases/${LATEST_TAG}"
49+
MSG="Software update available: ${LATEST_TAG}, running ${VERSION} (see ${RELEASE_URL})"
50+
logger -t "$TAG" "$MSG"
51+
printf '%s\n' "$MSG" > "$NOTIFY_FILE"
52+
else
53+
logger -p daemon.debug -t "$TAG" "No update available (current: $VERSION, latest: $LATEST)"
54+
printf '' > "$NOTIFY_FILE"
55+
fi

doc/ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ All notable changes to the project are documented in this file.
2323
clients onto the faster 5/6 GHz band
2424
- Add `legacy-rates` option to re-enable 802.11b rates on 2.4 GHz for
2525
old IoT devices (disabled by default)
26+
- Add system scheduling based on ietf-schedule (RFC 9922), using the
27+
iCalendar recurrence grouping pruned to cron-expressible rules. Schedules
28+
are reusable time-specs; features (`scheduled-reboot`,
29+
`software/check-update`) trigger off them via a schedule reference
2630

2731
### Fixes
2832

package/confd/confd.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ else
3636
CONFD_CONF_OPTS += --disable-gps
3737
endif
3838
define CONFD_INSTALL_EXTRA
39-
for fn in confd.conf resolvconf.conf; do \
39+
for fn in confd.conf crond.conf resolvconf.conf; do \
4040
cp $(CONFD_PKGDIR)/$$fn $(FINIT_D)/available/; \
4141
ln -sf ../available/$$fn $(FINIT_D)/enabled/$$fn; \
4242
done

package/confd/crond.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Cron daemon for infix-schedule
2+
service [2345] crond -f -- Cron daemon

src/confd/src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ confd_plugin_la_SOURCES = \
5050
if-wireguard.c \
5151
keystore.c \
5252
system.c \
53+
schedule.c \
5354
ntp.c \
5455
ptp.c \
5556
syslog.c \

src/confd/src/core.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,10 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod
621621
if ((rc = system_change(session, config, diff, event, confd)))
622622
goto free_diff;
623623

624+
/* infix-schedule */
625+
if ((rc = schedule_change(session, config, diff, event, confd)))
626+
goto free_diff;
627+
624628
/* infix-containers */
625629
#ifdef CONTAINERS
626630
if ((rc = containers_change(session, config, diff, event, confd)))
@@ -794,6 +798,11 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv)
794798
ERROR("Failed to subscribe to ietf-hardware");
795799
goto err;
796800
}
801+
rc = subscribe_model("infix-schedule", &confd, 0);
802+
if (rc) {
803+
ERROR("Failed to subscribe to infix-schedule");
804+
goto err;
805+
}
797806
rc = subscribe_model("infix-firewall", &confd, 0);
798807
if (rc) {
799808
ERROR("Failed to subscribe to infix-firewall");

src/confd/src/core.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,17 @@ int system_rpc_init (struct confd *confd);
215215
int hostnamefmt (struct confd *confd, const char *fmt, char *hostnm, size_t hostlen, char *domain, size_t domlen);
216216
int system_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
217217

218+
/* schedule.c */
219+
/* A feature registers cron consumer to run a command on a schedule. */
220+
struct cron_consumer {
221+
const char *path; /* xpath of the container holding the schedule-ref leaf */
222+
const char *sched_leaf; /* name of the schedule-ref leaf within 'path' */
223+
const char *enabled_leaf; /* boolean leaf in 'path' that gates the job; NULL = active whenever a schedule is referenced */
224+
const char *command; /* what crond runs on each occurrence */
225+
};
226+
int schedule_consumer_register(const struct cron_consumer *consumer);
227+
int schedule_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
228+
218229
/* containers.c */
219230
#ifdef CONTAINERS
220231
int containers_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);

0 commit comments

Comments
 (0)