Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions board/common/rootfs/etc/profile.d/update-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if [ -s /run/os-update ]; then
printf '\n\033[1;33m *** %s ***\033[0m\n\n' "$(cat /run/os-update)"
fi
1 change: 1 addition & 0 deletions board/common/rootfs/etc/tmpfiles.d/os-schedule.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f /run/os-update 0666 admin admin
55 changes: 55 additions & 0 deletions board/common/rootfs/usr/sbin/check-update
Comment thread
saba8814 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/sh
# Check for available software updates and notify on login if one exists.
# Called by the scheduler.

NOTIFY_FILE=/run/os-update
TAG=os-update

# Source os-release for VERSION and IMAGE_ID
if [ ! -f /etc/os-release ]; then
logger -t "$TAG" "ERROR: /etc/os-release not found"
exit 1
fi
. /etc/os-release

# Dev/dirty builds have no comparable semver — always show the latest release
IS_RELEASE=true
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+'; then
IS_RELEASE=false
fi

# Read configured update-url from running config, fall back to upstream
UPDATE_URL=$(copy running-config \
-x '/ietf-system:system/infix-system:software/check-update/update-url' \
2>/dev/null \
| jq -r '.. | objects | ."update-url"? // empty')
UPDATE_URL=${UPDATE_URL:-"https://github.com/kernelkit/infix"}

# Derive API URL from the configured update URL.
# Default (github.com): https://github.com/org/repo → https://api.github.com/repos/org/repo
REPO=$(echo "$UPDATE_URL" | sed 's|https://github.com/||; s|/*$||')
API_URL="https://api.github.com/repos/${REPO}/releases/latest"

LATEST_TAG=$(curl -sSL --max-time 10 "$API_URL" 2>/dev/null \
| jq -r '.tag_name // empty')
if [ -z "$LATEST_TAG" ]; then
logger -p daemon.info -t "$TAG" "Update check skipped: could not reach ${API_URL}"
exit 0
fi
LATEST=${LATEST_TAG#v}

# Compare: is $1 strictly newer than $2?
newer() {
[ "$1" = "$2" ] && return 1
[ "$(printf '%s\n%s' "$1" "$2" | sort -V | tail -1)" = "$1" ]
}

if [ "$IS_RELEASE" = false ] || newer "$LATEST" "$VERSION"; then
RELEASE_URL="${UPDATE_URL}/releases/${LATEST_TAG}"
MSG="Software update available: ${LATEST_TAG}, running ${VERSION} (see ${RELEASE_URL})"
logger -t "$TAG" "$MSG"
printf '%s\n' "$MSG" > "$NOTIFY_FILE"
else
logger -p daemon.debug -t "$TAG" "No update available (current: $VERSION, latest: $LATEST)"
printf '' > "$NOTIFY_FILE"
fi
4 changes: 4 additions & 0 deletions doc/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ All notable changes to the project are documented in this file.
clients onto the faster 5/6 GHz band
- Add `legacy-rates` option to re-enable 802.11b rates on 2.4 GHz for
old IoT devices (disabled by default)
- Add system scheduling based on ietf-schedule (RFC 9922), using the
iCalendar recurrence grouping pruned to cron-expressible rules. Schedules
are reusable time-specs; features (`scheduled-reboot`,
`software/check-update`) trigger off them via a schedule reference

### Fixes

Expand Down
2 changes: 1 addition & 1 deletion package/confd/confd.mk
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ else
CONFD_CONF_OPTS += --disable-gps
endif
define CONFD_INSTALL_EXTRA
for fn in confd.conf resolvconf.conf; do \
for fn in confd.conf crond.conf resolvconf.conf; do \
cp $(CONFD_PKGDIR)/$$fn $(FINIT_D)/available/; \
ln -sf ../available/$$fn $(FINIT_D)/enabled/$$fn; \
done
Expand Down
2 changes: 2 additions & 0 deletions package/confd/crond.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Cron daemon for infix-schedule
service [2345] crond -f -- Cron daemon
1 change: 1 addition & 0 deletions src/confd/src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ confd_plugin_la_SOURCES = \
if-wireguard.c \
keystore.c \
system.c \
schedule.c \
ntp.c \
ptp.c \
syslog.c \
Expand Down
9 changes: 9 additions & 0 deletions src/confd/src/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,10 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod
if ((rc = system_change(session, config, diff, event, confd)))
goto free_diff;

/* infix-schedule */
if ((rc = schedule_change(session, config, diff, event, confd)))
goto free_diff;

/* infix-containers */
#ifdef CONTAINERS
if ((rc = containers_change(session, config, diff, event, confd)))
Expand Down Expand Up @@ -794,6 +798,11 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv)
ERROR("Failed to subscribe to ietf-hardware");
goto err;
}
rc = subscribe_model("infix-schedule", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to infix-schedule");
goto err;
}
rc = subscribe_model("infix-firewall", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to infix-firewall");
Expand Down
11 changes: 11 additions & 0 deletions src/confd/src/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,17 @@ int system_rpc_init (struct confd *confd);
int hostnamefmt (struct confd *confd, const char *fmt, char *hostnm, size_t hostlen, char *domain, size_t domlen);
int system_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);

/* schedule.c */
/* A feature registers cron consumer to run a command on a schedule. */
struct cron_consumer {
const char *path; /* xpath of the container holding the schedule-ref leaf */
const char *sched_leaf; /* name of the schedule-ref leaf within 'path' */
const char *enabled_leaf; /* boolean leaf in 'path' that gates the job; NULL = active whenever a schedule is referenced */
const char *command; /* what crond runs on each occurrence */
};
int schedule_consumer_register(const struct cron_consumer *consumer);
int schedule_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);

/* containers.c */
#ifdef CONTAINERS
int containers_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
Expand Down
Loading