mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-26 18:53:01 +02:00
Compare commits
2
Commits
modem
...
user-scripts
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
257f1df1d5 | ||
|
|
8664c27096 |
@@ -22,6 +22,8 @@ All notable changes to the project are documented in this file.
|
|||||||
- Update documentation for use of VETH pairs in containers
|
- Update documentation for use of VETH pairs in containers
|
||||||
- Issue #454: create bridges in `factory-config` with IGMP/MLD snooping
|
- Issue #454: create bridges in `factory-config` with IGMP/MLD snooping
|
||||||
enabled by default
|
enabled by default
|
||||||
|
- Add support for optionally running user scripts from
|
||||||
|
`/cfg/user-scripts.d`
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Add missing LICENSE hash for factory reset tool
|
- Add missing LICENSE hash for factory reset tool
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
task [2] run-parts /cfg/user-scripts.d -- Running user startup scripts
|
||||||
@@ -226,7 +226,7 @@ sysrepoctl -s $SEARCH \
|
|||||||
-i infix-dhcp-client@2024-04-12.yang -g wheel -p 0660 \
|
-i infix-dhcp-client@2024-04-12.yang -g wheel -p 0660 \
|
||||||
-i infix-shell-type@2023-08-21.yang -g wheel -p 0660 \
|
-i infix-shell-type@2023-08-21.yang -g wheel -p 0660 \
|
||||||
-i infix-system@2024-04-12.yang -g wheel -p 0660 \
|
-i infix-system@2024-04-12.yang -g wheel -p 0660 \
|
||||||
-i infix-services@2024-04-08.yang -g wheel -p 0660 \
|
-i infix-services@2024-05-21.yang -g wheel -p 0660 \
|
||||||
-i ieee802-ethernet-interface@2019-06-21.yang -g wheel -p 0660 \
|
-i ieee802-ethernet-interface@2019-06-21.yang -g wheel -p 0660 \
|
||||||
-i infix-ethernet-interface@2024-02-27.yang -g wheel -p 0660 \
|
-i infix-ethernet-interface@2024-02-27.yang -g wheel -p 0660 \
|
||||||
-I "${INIT_DATA}"
|
-I "${INIT_DATA}"
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
SVC(web) \
|
SVC(web) \
|
||||||
SVC(ttyd) \
|
SVC(ttyd) \
|
||||||
SVC(netbrowse) \
|
SVC(netbrowse) \
|
||||||
|
SVC(userscripts) \
|
||||||
SVC(all) /* must be last entry */
|
SVC(all) /* must be last entry */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -52,7 +53,7 @@ struct mdns_svc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct srx_module_requirement reqs[] = {
|
static const struct srx_module_requirement reqs[] = {
|
||||||
{ .dir = YANG_PATH_, .name = "infix-services", .rev = "2024-04-08" },
|
{ .dir = YANG_PATH_, .name = "infix-services", .rev = "2024-05-21" },
|
||||||
{ .dir = YANG_PATH_, .name = "ieee802-dot1ab-lldp", .rev = "2022-03-15" },
|
{ .dir = YANG_PATH_, .name = "ieee802-dot1ab-lldp", .rev = "2022-03-15" },
|
||||||
{ .dir = YANG_PATH_, .name = "infix-lldp", .rev = "2023-08-23" },
|
{ .dir = YANG_PATH_, .name = "infix-lldp", .rev = "2023-08-23" },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
@@ -291,6 +292,21 @@ static int web_change(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
|
|||||||
return put(cfg, srv);
|
return put(cfg, srv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int userscripts_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||||
|
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||||
|
{
|
||||||
|
struct lyd_node *srv = NULL;
|
||||||
|
sr_data_t *cfg;
|
||||||
|
|
||||||
|
cfg = get(session, event, xpath, &srv, "user-scripts", NULL);
|
||||||
|
if (!cfg)
|
||||||
|
return SR_ERR_OK;
|
||||||
|
|
||||||
|
svc_enadis(lydx_is_enabled(srv, "enabled"), none, "user-scripts");
|
||||||
|
|
||||||
|
return put(cfg, srv);
|
||||||
|
}
|
||||||
|
|
||||||
int infix_services_init(struct confd *confd)
|
int infix_services_init(struct confd *confd)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
@@ -312,6 +328,8 @@ int infix_services_init(struct confd *confd)
|
|||||||
0, netbrowse_change, confd, &confd->sub);
|
0, netbrowse_change, confd, &confd->sub);
|
||||||
REGISTER_CHANGE(confd->session, "ieee802-dot1ab-lldp", "/ieee802-dot1ab-lldp:lldp",
|
REGISTER_CHANGE(confd->session, "ieee802-dot1ab-lldp", "/ieee802-dot1ab-lldp:lldp",
|
||||||
0, lldp_change, confd, &confd->sub);
|
0, lldp_change, confd, &confd->sub);
|
||||||
|
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:user-scripts",
|
||||||
|
0, userscripts_change, confd, &confd->sub);
|
||||||
|
|
||||||
return SR_ERR_OK;
|
return SR_ERR_OK;
|
||||||
fail:
|
fail:
|
||||||
|
|||||||
+17
@@ -7,6 +7,10 @@ module infix-services {
|
|||||||
contact "kernelkit@googlegroups.com";
|
contact "kernelkit@googlegroups.com";
|
||||||
description "Infix services, generic.";
|
description "Infix services, generic.";
|
||||||
|
|
||||||
|
revision 2024-05-21 {
|
||||||
|
description "Add support for user-scripts.";
|
||||||
|
reference "internal";
|
||||||
|
}
|
||||||
revision 2024-04-08 {
|
revision 2024-04-08 {
|
||||||
description "Initial support for web services.";
|
description "Initial support for web services.";
|
||||||
reference "internal";
|
reference "internal";
|
||||||
@@ -33,6 +37,19 @@ module infix-services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
container user-scripts {
|
||||||
|
description "Run scripts in /cfg/user-scripts.d on system startup
|
||||||
|
|
||||||
|
CAUTION! Anyone who can write to this directory will be able to
|
||||||
|
install a permanent backdoor on the system. This could include
|
||||||
|
a remote attacker with brief window of access.";
|
||||||
|
|
||||||
|
leaf enabled {
|
||||||
|
description "Enable or disable user script execution";
|
||||||
|
type boolean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
container web {
|
container web {
|
||||||
description "Web services";
|
description "Web services";
|
||||||
|
|
||||||
Executable
+63
@@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
|
||||||
|
import infamy
|
||||||
|
|
||||||
|
def attach(env):
|
||||||
|
return (env.attach("target", "mgmt"), env.attach("target", "mgmt", "ssh"))
|
||||||
|
|
||||||
|
with infamy.Test() as test:
|
||||||
|
with test.step("Initialize"):
|
||||||
|
env = infamy.Env(infamy.std_topology("1x1"))
|
||||||
|
target, tgtssh = attach(env)
|
||||||
|
|
||||||
|
cookie = "".join((random.choices(string.ascii_lowercase, k=16)))
|
||||||
|
script = f"/cfg/user-scripts.d/infamy-user-script-test.sh"
|
||||||
|
output = f"/tmp/{cookie}.cookie"
|
||||||
|
|
||||||
|
with test.step(f"Install {script}"):
|
||||||
|
tgtssh.runsh(f"""
|
||||||
|
set -e
|
||||||
|
|
||||||
|
mkdir -p $(dirname {script})
|
||||||
|
printf '#!/bin/sh\necho -n {cookie} >{output}\n' >{script}
|
||||||
|
chmod +x {script}
|
||||||
|
""")
|
||||||
|
|
||||||
|
with test.step("Enable user scripts and reboot"):
|
||||||
|
target.put_config_dict("infix-services", {
|
||||||
|
"user-scripts": {
|
||||||
|
"enabled": True
|
||||||
|
}
|
||||||
|
})
|
||||||
|
target.copy("running", "startup")
|
||||||
|
target.reboot()
|
||||||
|
infamy.util.wait_boot(target) or test.fail()
|
||||||
|
target, tgtssh = attach(env)
|
||||||
|
|
||||||
|
with test.step(f"Verify that {script} has run"):
|
||||||
|
cat = tgtssh.runsh(f"cat {output}").stdout
|
||||||
|
assert cat == cookie, f"Read back {repr(cat)}, expected {repr(cookie)}"
|
||||||
|
|
||||||
|
with test.step("Disable user scripts and reboot"):
|
||||||
|
target.put_config_dict("infix-services", {
|
||||||
|
"user-scripts": {
|
||||||
|
"enabled": False
|
||||||
|
}
|
||||||
|
})
|
||||||
|
target.copy("running", "startup")
|
||||||
|
target.reboot()
|
||||||
|
infamy.util.wait_boot(target) or test.fail()
|
||||||
|
target, tgtssh = attach(env)
|
||||||
|
|
||||||
|
with test.step(f"Verify that {script} has not run"):
|
||||||
|
exists = tgtssh.run(["test", "-f", f"{output}"]).returncode == 0
|
||||||
|
assert not exists, f"Unexpectedly found {output}"
|
||||||
|
|
||||||
|
with test.step(f"Remove {script}"):
|
||||||
|
tgtssh.runsh(f"rm {script}")
|
||||||
|
|
||||||
|
test.succeed()
|
||||||
Reference in New Issue
Block a user