summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devel/requirements/3b_runner.xml8
-rw-r--r--hscript/meta.cc12
-rw-r--r--hscript/script_e.cc19
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 @@
<title>Runner.Execute.timezone.Missing</title>
<para>If the zoneinfo file for the specified timezone in the <literal>timezone</literal> 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 <literal>/etc/localtime</literal> file in the target namespace.</para>
</formalpara>
+ <formalpara id="Runner.Execute.svcenable">
+ <title>Runner.Execute.svcenable</title>
+ <para>The system shall configure the service manager in the target namespace to start services as specified in any specified <literal>svcenable</literal> keys.</para>
+ </formalpara>
+ <formalpara id="Runner.Execute.svcenable.AddlRunlevels">
+ <title>Runner.Execute.svcenable.AddlRunlevels</title>
+ <para>If a runlevel not defined by the system service manager is specified in a <literal>svcenable</literal> key, it shall be interpreted to be a stacked runlevel atop the default runlevel and shall be configured as such in the target namespace.</para>
+ </formalpara>
<formalpara id="Runner.Execute.bootloader">
<title>Runner.Execute.bootloader</title>
<para>If a <literal>bootloader</literal> key is specified in the HorizonScript, the system shall perform the requested bootloader configuration.</para>
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<std::string> 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)