diff options
author | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2020-05-24 20:35:14 -0500 |
---|---|---|
committer | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2020-05-24 20:35:14 -0500 |
commit | 9c9e400b68f9cfb2270434fb8a16cc0df906ab8b (patch) | |
tree | 051470d7c3d29401462e3563bca34b11e58af5c5 | |
parent | b9980223dd469f24359d969ab24c3694507897e5 (diff) | |
download | horizon-9c9e400b68f9cfb2270434fb8a16cc0df906ab8b.tar.gz horizon-9c9e400b68f9cfb2270434fb8a16cc0df906ab8b.tar.bz2 horizon-9c9e400b68f9cfb2270434fb8a16cc0df906ab8b.tar.xz horizon-9c9e400b68f9cfb2270434fb8a16cc0df906ab8b.zip |
hscript: Implement 'svcenable' key and tests
-rw-r--r-- | hscript/meta.cc | 44 | ||||
-rw-r--r-- | hscript/meta.hh | 10 | ||||
-rw-r--r-- | hscript/script.cc | 3 | ||||
-rw-r--r-- | hscript/script_e.cc | 4 | ||||
-rw-r--r-- | hscript/script_i.hh | 19 | ||||
-rw-r--r-- | tests/fixtures/0229-svcenable-basic.installfile | 6 | ||||
-rw-r--r-- | tests/fixtures/0230-svcenable-duplicate.installfile | 7 | ||||
-rw-r--r-- | tests/fixtures/0231-svcenable-invalid.installfile | 6 | ||||
-rw-r--r-- | tests/spec/simulator_spec.rb | 7 | ||||
-rw-r--r-- | tests/spec/validator_spec.rb | 18 |
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' |