From a9ccd9bc7e22573c5c327d3f75722ebd3cca6a82 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Fri, 20 Oct 2023 05:20:11 -0500 Subject: hscript: Allow svcenable to create new runlevels This is going to be useful in general for some advanced use cases, but most importantly, it will allow us to define runlevels for live media. Ref: #346 --- devel/requirements/3b_runner.xml | 8 ++++++++ hscript/meta.cc | 12 ++++++++++-- hscript/script_e.cc | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/devel/requirements/3b_runner.xml b/devel/requirements/3b_runner.xml index a5080fe..b5e9848 100644 --- a/devel/requirements/3b_runner.xml +++ b/devel/requirements/3b_runner.xml @@ -820,6 +820,14 @@ Runner.Execute.timezone.Missing If the zoneinfo file for the specified timezone in the timezone key is missing in the target namespace, but present in the installation environment, the system shall copy the zoneinfo file from the installation environment to the /etc/localtime file in the target namespace. + + Runner.Execute.svcenable + The system shall configure the service manager in the target namespace to start services as specified in any specified svcenable keys. + + + Runner.Execute.svcenable.AddlRunlevels + If a runlevel not defined by the system service manager is specified in a svcenable key, it shall be interpreted to be a stacked runlevel atop the default runlevel and shall be configured as such in the target namespace. + Runner.Execute.bootloader If a bootloader key is specified in the HorizonScript, the system shall perform the requested bootloader configuration. diff --git a/hscript/meta.cc b/hscript/meta.cc index af72eaf..a12b874 100644 --- a/hscript/meta.cc +++ b/hscript/meta.cc @@ -652,12 +652,14 @@ bool SvcEnable::validate() const { /* LCOV_EXCL_STOP */ bool SvcEnable::execute() const { - const std::string target = script->targetDirectory() + - "/etc/runlevels/" + _runlevel + "/" + _svc; + const std::string target_rl = script->targetDirectory() + + "/etc/runlevels/" + _runlevel; + const std::string target = target_rl + "/" + _svc; const std::string initd = "/etc/init.d/" + _svc; output_info(pos, "svcenable: enabling service " + _svc); if(script->options().test(Simulate)) { + std::cout << "mkdir -p " << target_rl << std::endl; std::cout << "ln -s " << initd << " " << target << std::endl; return true; } @@ -667,6 +669,12 @@ bool SvcEnable::execute() const { if(!fs::exists(script->targetDirectory() + initd, ec)) { output_warning(pos, "svcenable: missing service", _svc); } + fs::create_directory(target_rl, ec); + if(ec && ec.value() != EEXIST) { + output_error(pos, "svcenable: could not create runlevel directory " + "/etc/runlevels/" + _runlevel, ec.message()); + return false; + } fs::create_symlink(initd, target, ec); if(ec && ec.value() != EEXIST) { diff --git a/hscript/script_e.cc b/hscript/script_e.cc index 3cdc78f..8f0f4b4 100644 --- a/hscript/script_e.cc +++ b/hscript/script_e.cc @@ -677,6 +677,25 @@ bool Script::execute() const { for(const auto &svc : internal->svcs_enable) { EXECUTE_OR_FAIL("svcenable", svc) } +#ifdef HAS_INSTALL_ENV + if(!opts.test(Simulate)) { + const std::set def_runlevels{ + "boot", "default", "empty", "nonetwork", "shutdown", "sysinit" + }; + const auto rl_dir{targ_etc + "/runlevels"}; + for(auto &&file : fs::directory_iterator(rl_dir)) { + const auto runlevel{file.path().filename().string()}; + if(def_runlevels.find(runlevel) == def_runlevels.end()) { + fs::create_symlink("../default", + rl_dir + "/" + runlevel + "/default", ec); + if(ec) { + output_error("internal", "could not stack runlevel " + + runlevel, ec.message()); + } + } + } + } +#endif if(internal->boot) { EXECUTE_OR_FAIL("bootloader", internal->boot) -- cgit v1.2.3-70-g09d2