diff --git a/configs/aarch64_defconfig b/configs/aarch64_defconfig index 9dab65b3..2d37812b 100644 --- a/configs/aarch64_defconfig +++ b/configs/aarch64_defconfig @@ -166,6 +166,7 @@ BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y BR2_PACKAGE_HOST_PYTHON_YANGDOC=y BR2_DOWNLOAD_FORCE_CHECK_HASHES=y +BR2_PACKAGE_GETENT=y TRUSTED_KEYS=y TRUSTED_KEYS_DEVELOPMENT=y DISK_IMAGE_BOOT_BIN=y diff --git a/configs/aarch64_minimal_defconfig b/configs/aarch64_minimal_defconfig index 04d607ef..5877db15 100644 --- a/configs/aarch64_minimal_defconfig +++ b/configs/aarch64_minimal_defconfig @@ -139,6 +139,7 @@ BR2_PACKAGE_LIBINPUT=y BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y BR2_DOWNLOAD_FORCE_CHECK_HASHES=y +BR2_PACKAGE_GETENT=y DISK_IMAGE_BOOT_BIN=y TRUSTED_KEYS=y TRUSTED_KEYS_DEVELOPMENT=y diff --git a/configs/r2s_defconfig b/configs/r2s_defconfig index 711e9b9e..9dce92fe 100644 --- a/configs/r2s_defconfig +++ b/configs/r2s_defconfig @@ -203,6 +203,7 @@ BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y BR2_PACKAGE_HOST_PYTHON_YANGDOC=y BR2_DOWNLOAD_FORCE_CHECK_HASHES=y +BR2_PACKAGE_GETENT=y TRUSTED_KEYS=y TRUSTED_KEYS_DEVELOPMENT=y # GNS3_APPLIANCE is not set diff --git a/configs/riscv64_defconfig b/configs/riscv64_defconfig index b490f1e5..f89ce5f2 100644 --- a/configs/riscv64_defconfig +++ b/configs/riscv64_defconfig @@ -196,6 +196,7 @@ BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_HOST_PYTHON_YANGDOC=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y BR2_DOWNLOAD_FORCE_CHECK_HASHES=y +BR2_PACKAGE_GETENT=y TRUSTED_KEYS=y TRUSTED_KEYS_DEVELOPMENT=y # GNS3_APPLIANCE is not set diff --git a/configs/x86_64_defconfig b/configs/x86_64_defconfig index 976453fe..bb7e6f65 100644 --- a/configs/x86_64_defconfig +++ b/configs/x86_64_defconfig @@ -168,6 +168,7 @@ BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y BR2_PACKAGE_HOST_PYTHON_YANGDOC=y BR2_DOWNLOAD_FORCE_CHECK_HASHES=y +BR2_PACKAGE_GETENT=y TRUSTED_KEYS=y TRUSTED_KEYS_DEVELOPMENT=y GNS3_APPLIANCE_RAM=512 diff --git a/configs/x86_64_minimal_defconfig b/configs/x86_64_minimal_defconfig index 33e364be..b961a158 100644 --- a/configs/x86_64_minimal_defconfig +++ b/configs/x86_64_minimal_defconfig @@ -7,13 +7,14 @@ BR2_CCACHE=y BR2_CCACHE_DIR="${BR2_EXTERNAL_INFIX_PATH}/.ccache" BR2_ENABLE_DEBUG=y BR2_GLOBAL_PATCH_DIR="${BR2_EXTERNAL_INFIX_PATH}/patches" +BR2_DOWNLOAD_FORCE_CHECK_HASHES=y BR2_TARGET_GENERIC_HOSTNAME="ix" BR2_TARGET_GENERIC_ISSUE="Infix by KernelKit" BR2_INIT_FINIT=y BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt ${BR2_EXTERNAL_INFIX_PATH}/board/common/xattrs" -# BR2_TARGET_ENABLE_ROOT_LOGIN is not set BR2_ROOTFS_MERGED_USR=y +# BR2_TARGET_ENABLE_ROOT_LOGIN is not set BR2_SYSTEM_BIN_SH_BASH=y BR2_TARGET_GENERIC_GETTY_PORT="@console" BR2_TARGET_GENERIC_GETTY_TERM="xterm" @@ -50,10 +51,7 @@ BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y BR2_PACKAGE_PYTHON3=y -BR2_PACKAGE_LIBSSH_OPENSSL=y BR2_PACKAGE_LIBSSH2=y -BR2_PACKAGE_LIBSSH2_OPENSSL=y -BR2_PACKAGE_LIBXCRYPT=y BR2_PACKAGE_LIBOPENSSL_BIN=y BR2_PACKAGE_LIBCURL_CURL=y BR2_PACKAGE_LIBMNL=y @@ -83,6 +81,7 @@ BR2_PACKAGE_TCPDUMP=y BR2_PACKAGE_WHOIS=y BR2_PACKAGE_BASH_COMPLETION=y BR2_PACKAGE_SUDO=y +BR2_PACKAGE_GETENT=y BR2_PACKAGE_KMOD_TOOLS=y BR2_PACKAGE_PWGEN=y BR2_PACKAGE_RAUC=y @@ -123,7 +122,6 @@ BR2_PACKAGE_CONFD=y BR2_PACKAGE_CONFD_TEST_MODE=y BR2_PACKAGE_GENCERT=y BR2_PACKAGE_STATD=y -BR2_PACKAGE_SHOW=y BR2_PACKAGE_FACTORY=y BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y @@ -139,9 +137,9 @@ BR2_PACKAGE_KLISH_PLUGIN_INFIX=y BR2_PACKAGE_LOWDOWN=y BR2_PACKAGE_MCD=y BR2_PACKAGE_MDNS_ALIAS=y +BR2_PACKAGE_SHOW=y BR2_PACKAGE_ROUSETTE=y BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y -BR2_DOWNLOAD_FORCE_CHECK_HASHES=y TRUSTED_KEYS=y TRUSTED_KEYS_DEVELOPMENT=y GNS3_APPLIANCE_RAM=512 diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 0532797e..ccecd9d8 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -38,10 +38,6 @@ struct sr_change { sr_val_t *new; }; -static char *ver = NULL; -static char *rel = NULL; -static char *sys = NULL; -static char *os = NULL; static char *nm = NULL; static char *id = NULL; @@ -90,17 +86,9 @@ static void setvar(const char *line, const char *key, char **var) static void os_init(void) { - struct utsname uts; char line[80]; FILE *fp; - if (!uname(&uts)) { - os = strdup(uts.sysname); - ver = strdup(uts.release); - rel = strdup(uts.release); - sys = strdup(uts.machine); - } - fp = fopen("/etc/os-release", "r"); if (!fp) { fp = fopen("/usr/lib/os-release", "r"); @@ -110,36 +98,12 @@ static void os_init(void) while (fgets(line, sizeof(line), fp)) { line[strlen(line) - 1] = 0; /* drop \n */ - setvar(line, "NAME", &os); - setvar(line, "VERSION_ID", &ver); - setvar(line, "BUILD_ID", &rel); - setvar(line, "ARCHITECTURE", &sys); setvar(line, "DEFAULT_HOSTNAME", &nm); setvar(line, "ID", &id); } fclose(fp); } -static char *fmtime(time_t t, char *buf, size_t len) -{ - const char *isofmt = "%FT%T%z"; - struct tm tm; - size_t i, n; - - tzset(); - localtime_r(&t, &tm); - n = strftime(buf, len, isofmt, &tm); - i = n - 5; - if (buf[i] == '+' || buf[i] == '-') { - buf[i + 6] = buf[i + 5]; - buf[i + 5] = buf[i + 4]; - buf[i + 4] = buf[i + 3]; - buf[i + 3] = ':'; - } - - return buf; -} - static sr_error_t _sr_change_iter(sr_session_ctx_t *session, struct confd *confd, char *xpath, sr_error_t cb(sr_session_ctx_t *, struct confd *, struct sr_change *)) { @@ -165,71 +129,6 @@ static sr_error_t _sr_change_iter(sr_session_ctx_t *session, struct confd *confd return SR_ERR_OK; } -static int clock_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module, - const char *path, const char *request_path, uint32_t request_id, - struct lyd_node **parent, void *priv) -{ - static char boottime[64] = { 0 }; - const struct ly_ctx *ctx; - char curtime[64]; - time_t now, boot; - int rc; - - ctx = sr_acquire_context(sr_session_get_connection(session)); - - now = time(NULL); - if (!boottime[0]) { - struct sysinfo si; - - sysinfo(&si); - boot = now - si.uptime; - fmtime(boot, boottime, sizeof(boottime)); - } - fmtime(now, curtime, sizeof(curtime)); - - if ((rc = lydx_new_path(ctx, parent, CLOCK_PATH_, "boot-datetime", "%s", boottime))) - goto fail; - if ((rc = lydx_new_path(ctx, parent, CLOCK_PATH_, "current-datetime", "%s", curtime))) - goto fail; - - if (rc) { - fail: - ERROR("Failed building data tree, libyang error %d", rc); - rc = SR_ERR_INTERNAL; - } - - sr_release_context(sr_session_get_connection(session)); - return rc; -} - -static int platform_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module, - const char *path, const char *request_path, uint32_t request_id, - struct lyd_node **parent, void *priv) -{ - const struct ly_ctx *ctx; - int rc; - - ctx = sr_acquire_context(sr_session_get_connection(session)); - - if ((rc = lydx_new_path(ctx, parent, PLATFORM_PATH_, "os-name", "%s", os))) - goto fail; - if ((rc = lydx_new_path(ctx, parent, PLATFORM_PATH_, "os-release", "%s", rel))) - goto fail; - if ((rc = lydx_new_path(ctx, parent, PLATFORM_PATH_, "os-version", "%s", ver))) - goto fail; - if ((rc = lydx_new_path(ctx, parent, PLATFORM_PATH_, "machine", "%s", sys))) - goto fail; - - if (rc) { - fail: - ERROR("Failed building data tree, libyang error %d", rc); - rc = SR_ERR_INTERNAL; - } - - sr_release_context(sr_session_get_connection(session)); - return rc; -} - static int rpc_exec(sr_session_ctx_t *session, uint32_t sub_id, const char *path, const sr_val_t *input, const size_t input_cnt, sr_event_t event, unsigned request_id, @@ -1408,30 +1307,6 @@ static int change_auth(sr_session_ctx_t *session, uint32_t sub_id, const char *m return SR_ERR_OK; } -static int auth_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module, - const char *path, const char *request_path, uint32_t request_id, - struct lyd_node **parent, void *priv) -{ - const char *fmt = "/ietf-system:system/authentication/user[name='%s']/password"; - struct spwd *spwd; - - setspent(); - while ((spwd = getspent())) { - char xpath[256]; - - /* Skip any records that do not pass YANG validation */ - if (!spwd->sp_pwdp || spwd->sp_pwdp[0] == '0' || - spwd->sp_pwdp[0] == '*' || spwd->sp_pwdp[0] == '!') - continue; - - snprintf(xpath, sizeof(xpath), fmt, spwd->sp_namp); - lyd_new_path(*parent, NULL, xpath, spwd->sp_pwdp, 0, 0); - } - endspent(); - - return SR_ERR_OK; -} - static int change_nacm(sr_session_ctx_t *session, uint32_t sub_id, const char *module, const char *_, sr_event_t event, unsigned request_id, void *priv) { @@ -1773,23 +1648,6 @@ err: return SR_ERR_OK; } -static int hostname_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module, - const char *path, const char *request_path, uint32_t request_id, - struct lyd_node **parent, void *priv) -{ - char hostname[128]; - int rc; - - gethostname(hostname, sizeof(hostname)); - rc = lyd_new_path(*parent, NULL, path, hostname, 0, NULL); - if (rc) { - ERROR("Failed building data tree, libyang error %d", rc); - rc = SR_ERR_INTERNAL; - } - - return rc; -} - int ietf_system_init(struct confd *confd) { int rc; @@ -1797,12 +1655,10 @@ int ietf_system_init(struct confd *confd) os_init(); REGISTER_CHANGE(confd->session, "ietf-system", XPATH_AUTH_, 0, change_auth, confd, &confd->sub); - REGISTER_OPER(confd->session, "ietf-system", PASSWORD_PATH, auth_cb, confd, 0, &confd->sub); REGISTER_MONITOR(confd->session, "ietf-netconf-acm", "/ietf-netconf-acm:nacm//.", 0, change_nacm, confd, &confd->sub); REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/hostname", 0, change_hostname, confd, &confd->sub); - REGISTER_OPER(confd->session, "ietf-system", XPATH_BASE_"/hostname", hostname_cb, confd, 0, &confd->sub); REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/infix-system:motd", 0, change_motd, confd, &confd->sub); REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/infix-system:motd-banner", 0, change_motd_banner, confd, &confd->sub); REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/infix-system:text-editor", 0, change_editor, confd, &confd->sub); @@ -1810,9 +1666,6 @@ int ietf_system_init(struct confd *confd) REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/ntp", 0, change_ntp, confd, &confd->sub); REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/dns-resolver", 0, change_dns, confd, &confd->sub); - REGISTER_OPER(confd->session, "ietf-system", CLOCK_PATH_, clock_cb, NULL, 0, &confd->sub); - REGISTER_OPER(confd->session, "ietf-system", PLATFORM_PATH_, platform_cb, NULL, 0, &confd->sub); - REGISTER_RPC(confd->session, "/ietf-system:system-restart", rpc_exec, "reboot", &confd->sub); REGISTER_RPC(confd->session, "/ietf-system:system-shutdown", rpc_exec, "poweroff", &confd->sub); REGISTER_RPC(confd->session, "/ietf-system:set-current-datetime", rpc_set_datetime, NULL, &confd->sub); diff --git a/src/statd/python/yanger/ietf_system.py b/src/statd/python/yanger/ietf_system.py index 08b76be3..a66ca7b2 100644 --- a/src/statd/python/yanger/ietf_system.py +++ b/src/statd/python/yanger/ietf_system.py @@ -1,7 +1,7 @@ import subprocess import ipaddress -from .common import insert +from .common import insert,YangDate from .host import HOST def uboot_get_boot_order(): @@ -157,6 +157,24 @@ def add_software_slots(out, data): slots.append(new) out["slot"] = slots +def add_platform(out): + platform = {} + pmap = { + "NAME": "os-name", + "VERSION_ID": "os-version", + "BUILD_ID": "os-release", + "ARCHITECTURE": "machine" + } + + os_release = HOST.read("/etc/os-release") + for line in os_release.splitlines(): + key, value = line.split('=') + name = pmap.get(key) + if name: + platform[name] = value.strip("\"") + + insert(out, "platform", platform) + def add_software(out): software = {} try: @@ -171,31 +189,83 @@ def add_software(out): except subprocess.CalledProcessError: pass # Maybe an upgrade i progress, then rauc does not respond - installer_status = HOST.run_json(["rauc-installation-status"]) - installer = {} - if installer_status.get("operation"): - installer["operation"] = installer_status["operation"] - if "progress" in installer_status: - progress = {} + except FileNotFoundError: + pass - if installer_status["progress"].get("percentage"): - progress["percentage"] = int(installer_status["progress"]["percentage"]) - if installer_status["progress"].get("message"): - progress["message"] = installer_status["progress"]["message"] - installer["progress"] = progress - software["installer"] = installer + installer = {} + try: + installer_status = HOST.run_json(["rauc-installation-status"]) + if installer_status.get("operation"): + installer["operation"] = installer_status["operation"] + if "progress" in installer_status: + progress = {} + + if installer_status["progress"].get("percentage"): + progress["percentage"] = int(installer_status["progress"]["percentage"]) + if installer_status["progress"].get("message"): + progress["message"] = installer_status["progress"]["message"] + installer["progress"] = progress + software["installer"] = installer + except FileNotFoundError: + pass insert(out, "infix-system:software", software) +def add_hostname(out): + hostname = HOST.run(tuple(["hostname"])) + out["hostname"] = hostname.strip() + +def add_users(out): + shadow_output = HOST.run_multiline(["getent", "shadow"], []) + users = [] + + for line in shadow_output: + parts = line.split(':') + if len(parts) < 2: + continue + username = parts[0] + password_hash = parts[1] + + # Skip any records that do not pass YANG validation + if (not password_hash or + password_hash.startswith('0') or + password_hash.startswith('*') or + password_hash.startswith('!')): + continue + user = {} + user["name"] = username + user["password"] = password_hash + users.append(user) + + + insert(out, "authentication", "user", users) + +def add_clock(out): + clock = {} + clock_now=YangDate() + + uptime=HOST.read("/proc/uptime") + uptime = float(uptime.split()[0]) + + clock["boot-datetime"] = str(clock_now.from_seconds(uptime)) + clock["current-datetime"] = str(clock_now) + insert(out, "clock", clock) + def operational(): out = { + "ietf-system:system": { + }, "ietf-system:system-state": { } } out_state = out["ietf-system:system-state"] - + out_system = out["ietf-system:system"] + add_hostname(out_system) + add_users(out_system) add_software(out_state) add_ntp(out_state) add_dns(out_state) + add_clock(out_state) + add_platform(out_state) return out diff --git a/src/statd/statd.c b/src/statd/statd.c index 11e3aaec..8a1f14aa 100644 --- a/src/statd/statd.c +++ b/src/statd/statd.c @@ -38,7 +38,7 @@ #define XPATH_ROUTING_BASE "/ietf-routing:routing/control-plane-protocols/control-plane-protocol" #define XPATH_ROUTING_TABLE "/ietf-routing:routing/ribs" #define XPATH_HARDWARE_BASE "/ietf-hardware:hardware" -#define XPATH_SYSTEM_BASE "/ietf-system:system-state" +#define XPATH_SYSTEM_BASE "/ietf-system" #define XPATH_ROUTING_OSPF XPATH_ROUTING_BASE "/ospf" #define XPATH_CONTAIN_BASE "/infix-containers:containers" #define XPATH_DHCP_SERVER_BASE "/infix-dhcp-server:dhcp-server" @@ -344,7 +344,9 @@ static int subscribe_to_all(struct statd *statd) return SR_ERR_INTERNAL; if (subscribe(statd, "ietf-hardware", XPATH_HARDWARE_BASE, sr_generic_cb)) return SR_ERR_INTERNAL; - if (subscribe(statd, "ietf-system", XPATH_SYSTEM_BASE, sr_generic_cb)) + if (subscribe(statd, "ietf-system", XPATH_SYSTEM_BASE":system", sr_generic_cb)) + return SR_ERR_INTERNAL; + if (subscribe(statd, "ietf-system", XPATH_SYSTEM_BASE":system-state", sr_generic_cb)) return SR_ERR_INTERNAL; if (subscribe(statd, "ieee802-dot1ab-lldp", XPATH_LLDP_BASE, sr_generic_cb)) return SR_ERR_INTERNAL;