summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hscript/meta.cc44
-rw-r--r--hscript/meta.hh10
-rw-r--r--hscript/script.cc3
-rw-r--r--hscript/script_e.cc4
-rw-r--r--hscript/script_i.hh19
-rw-r--r--tests/fixtures/0229-svcenable-basic.installfile6
-rw-r--r--tests/fixtures/0230-svcenable-duplicate.installfile7
-rw-r--r--tests/fixtures/0231-svcenable-invalid.installfile6
-rw-r--r--tests/spec/simulator_spec.rb7
-rw-r--r--tests/spec/validator_spec.rb18
10 files changed, 124 insertions, 0 deletions
diff --git a/hscript/meta.cc b/hscript/meta.cc
index 9b0eb83..d43e58e 100644
--- a/hscript/meta.cc
+++ b/hscript/meta.cc
@@ -656,3 +656,47 @@ bool SigningKey::execute() const {
#endif /* HAS_INSTALL_ENV */
return true; /* LCOV_EXCL_LINE */
}
+
+Key *SvcEnable::parseFromData(const std::string &data, int lineno, int *errors,
+ int *, const Script *script) {
+ const static std::string valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890.-_";
+
+ if(data.find_first_not_of(valid_chars) != std::string::npos) {
+ if(errors) *errors += 1;
+ output_error("installfile:" + std::to_string(lineno),
+ "svcenable: invalid service name", data);
+ return nullptr;
+ }
+
+ return new SvcEnable(script, lineno, data);
+}
+
+bool SvcEnable::execute() const {
+ const std::string target = script->targetDirectory() +
+ "/etc/runlevels/default/" + _value;
+ const std::string initd = "/etc/init.d/" + _value;
+ output_info("installfile:" + std::to_string(line),
+ "svcenable: enabling service " + _value);
+
+ if(script->options().test(Simulate)) {
+ std::cout << "ln -s " << initd << " " << target << std::endl;
+ return true;
+ }
+
+#ifdef HAS_INSTALL_ENV
+ error_code ec;
+ if(!fs::exists(script->targetDirectory() + initd, ec)) {
+ output_warning("installfile:" + std::to_string(line),
+ "svcenable: service '" + _value + "' may be missing");
+ }
+
+ fs::create_symlink(initd, target, ec);
+ if(ec) {
+ output_error("installfile:" + std::to_string(line),
+ "svcenable: could not enable service " + _value,
+ ec.message());
+ return false;
+ }
+#endif /* HAS_INSTALL_ENV */
+ return true; /* LCOV_EXCL_LINE */
+}
diff --git a/hscript/meta.hh b/hscript/meta.hh
index 060054b..d522bdf 100644
--- a/hscript/meta.hh
+++ b/hscript/meta.hh
@@ -118,6 +118,16 @@ public:
bool execute() const override;
};
+class SvcEnable : public StringKey {
+private:
+ SvcEnable(const Script *_s, int _line, const std::string &_svc) :
+ StringKey(_s, _line, _svc) {}
+public:
+ static Key *parseFromData(const std::string &, int, int *, int *,
+ const Script *);
+ bool execute() const override;
+};
+
}
}
diff --git a/hscript/script.cc b/hscript/script.cc
index 626b9e8..5b261d2 100644
--- a/hscript/script.cc
+++ b/hscript/script.cc
@@ -48,6 +48,7 @@ const std::map<std::string, key_parse_fn> valid_keys = {
{"timezone", &Timezone::parseFromData},
{"repository", &Repository::parseFromData},
{"signingkey", &SigningKey::parseFromData},
+ {"svcenable", &SvcEnable::parseFromData},
{"netconfigtype", &NetConfigType::parseFromData},
{"netaddress", &NetAddress::parseFromData},
@@ -117,6 +118,8 @@ bool Script::ScriptPrivate::store_key(const std::string &key_name, Key *obj,
std::unique_ptr<SigningKey> key(dynamic_cast<SigningKey *>(obj));
this->repo_keys.push_back(std::move(key));
return true;
+ } else if(key_name == "svcenable") {
+ return store_svcenable(obj, lineno, errors, warnings, opts);
} else if(key_name == "username") {
return store_username(obj, lineno, errors, warnings, opts);
} else if(key_name == "useralias") {
diff --git a/hscript/script_e.cc b/hscript/script_e.cc
index a7bb6d2..829d672 100644
--- a/hscript/script_e.cc
+++ b/hscript/script_e.cc
@@ -653,6 +653,10 @@ bool Script::execute() const {
EXECUTE_OR_FAIL("timezone", internal->tzone)
+ for(const auto &svc : internal->svcs_enable) {
+ EXECUTE_OR_FAIL("svcenable", svc)
+ }
+
output_step_end("post-metadata");
return true;
}
diff --git a/hscript/script_i.hh b/hscript/script_i.hh
index a94a0d7..b91e60f 100644
--- a/hscript/script_i.hh
+++ b/hscript/script_i.hh
@@ -72,6 +72,9 @@ struct Script::ScriptPrivate {
/*! APK repository keys */
std::vector< std::unique_ptr<SigningKey> > repo_keys;
+ /*! Services to enable */
+ std::vector< std::unique_ptr<SvcEnable> > svcs_enable;
+
/*! User account information */
std::map< std::string, std::unique_ptr<UserDetail> > accounts;
@@ -232,6 +235,22 @@ struct Script::ScriptPrivate {
return true;
}
+ bool store_svcenable(Key *obj, int line, int *, int *warn, ScriptOptions) {
+ std::unique_ptr<SvcEnable> svc(dynamic_cast<SvcEnable *>(obj));
+ for(const auto &s : svcs_enable) {
+ if(s->value() == svc->value()) {
+ if(warn) *warn += 1;
+ output_warning("installfile:" + std::to_string(line),
+ "svcenable: service already enabled",
+ s->value());
+ return true;
+ }
+ }
+
+ svcs_enable.push_back(std::move(svc));
+ return true;
+ }
+
bool store_username(Key *obj, int line, int *errors, int *, ScriptOptions) {
if(accounts.size() >= 255) {
if(errors) *errors += 1;
diff --git a/tests/fixtures/0229-svcenable-basic.installfile b/tests/fixtures/0229-svcenable-basic.installfile
new file mode 100644
index 0000000..69e18d4
--- /dev/null
+++ b/tests/fixtures/0229-svcenable-basic.installfile
@@ -0,0 +1,6 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+svcenable sshd
diff --git a/tests/fixtures/0230-svcenable-duplicate.installfile b/tests/fixtures/0230-svcenable-duplicate.installfile
new file mode 100644
index 0000000..bbd3401
--- /dev/null
+++ b/tests/fixtures/0230-svcenable-duplicate.installfile
@@ -0,0 +1,7 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+svcenable sshd
+svcenable sshd
diff --git a/tests/fixtures/0231-svcenable-invalid.installfile b/tests/fixtures/0231-svcenable-invalid.installfile
new file mode 100644
index 0000000..f4fde97
--- /dev/null
+++ b/tests/fixtures/0231-svcenable-invalid.installfile
@@ -0,0 +1,6 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+svcenable ../hax/illegal
diff --git a/tests/spec/simulator_spec.rb b/tests/spec/simulator_spec.rb
index ab77782..2e63009 100644
--- a/tests/spec/simulator_spec.rb
+++ b/tests/spec/simulator_spec.rb
@@ -274,6 +274,13 @@ printf '%s\\t%s\\t%s\\t%s\\t0\\t0\\n' /dev/gwyn/source /usr/src auto noatime >>
expect(last_command_started.stdout).to include("cp /etc/apk/keys/packages@adelielinux.org.pub /target/etc/apk/keys/packages@adelielinux.org.pub")
end
end
+ context "simulating 'svcenable' execution" do
+ it "enables the service correctly" do
+ use_fixture '0229-svcenable-basic.installfile'
+ run_simulate
+ expect(last_command_started.stdout).to include("ln -s /etc/init.d/sshd /target/etc/runlevels/default/sshd")
+ end
+ end
context "simulating 'pkginstall' execution" do
# Runner.Execute.pkginstall.APKDB
it "initialises the APK database" do
diff --git a/tests/spec/validator_spec.rb b/tests/spec/validator_spec.rb
index 365a8f3..0bd3516 100644
--- a/tests/spec/validator_spec.rb
+++ b/tests/spec/validator_spec.rb
@@ -669,6 +669,24 @@ RSpec.describe 'HorizonScript validation', :type => :aruba do
expect(last_command_started).to have_output(/warning: .*pkginstall.*already/)
end
end
+ context "for 'svcenable' key" do
+ it "succeeds with a basic service" do
+ use_fixture '0229-svcenable-basic.installfile'
+ run_validate
+ expect(last_command_started).to have_output(PARSER_SUCCESS)
+ expect(last_command_started).to have_output(VALIDATOR_SUCCESS)
+ end
+ it "warns when a service is specified twice" do
+ use_fixture '0230-svcenable-duplicate.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/warning: .*svcenable.*already/)
+ end
+ it "fails when an invalid service name is specified" do
+ use_fixture '0231-svcenable-invalid.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*svcenable.*invalid/)
+ end
+ end
context "for 'diskid' key" do
it "succeeds with basic disk identification" do
use_fixture '0076-diskid-basic.installfile'