From 6209b9c9f77af5f7ca0618a44bfd0b5955d7d678 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Tue, 23 Jun 2020 20:07:41 -0500 Subject: hscript: Implement runlevel support in svcenable key --- hscript/meta.cc | 27 ++++++++++++++++------ hscript/meta.hh | 12 ++++++++-- hscript/script_i.hh | 4 ++-- tests/fixtures/0239-svcenable-runlevel.installfile | 7 ++++++ tests/fixtures/0240-bootloader-invalid.installfile | 7 ++++++ tests/spec/simulator_spec.rb | 7 +++++- tests/spec/validator_spec.rb | 6 +++++ 7 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 tests/fixtures/0239-svcenable-runlevel.installfile create mode 100644 tests/fixtures/0240-bootloader-invalid.installfile diff --git a/hscript/meta.cc b/hscript/meta.cc index 15734c5..0ad4ea5 100644 --- a/hscript/meta.cc +++ b/hscript/meta.cc @@ -623,21 +623,34 @@ Key *SvcEnable::parseFromData(const std::string &data, const ScriptLocation &pos, int *errors, int *, const Script *script) { const static std::string valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890.-_"; + std::string::size_type space = data.find_first_of(' ');; + std::string svc, runlevel{"default"}; - if(data.find_first_not_of(valid_chars) != std::string::npos) { + if(space != std::string::npos) { + svc = data.substr(0, space); + runlevel = data.substr(space + 1); + } else { + svc = data; + } + + if(svc.find_first_not_of(valid_chars) != std::string::npos) { if(errors) *errors += 1; output_error(pos, "svcenable: invalid service name", data); return nullptr; } - return new SvcEnable(script, pos, data); + return new SvcEnable(script, pos, svc, runlevel); +} + +bool SvcEnable::validate() const { + return true; /* validation occurs during parsing */ } bool SvcEnable::execute() const { const std::string target = script->targetDirectory() + - "/etc/runlevels/default/" + _value; - const std::string initd = "/etc/init.d/" + _value; - output_info(pos, "svcenable: enabling service " + _value); + "/etc/runlevels/" + _runlevel + "/" + _svc; + const std::string initd = "/etc/init.d/" + _svc; + output_info(pos, "svcenable: enabling service " + _svc); if(script->options().test(Simulate)) { std::cout << "ln -s " << initd << " " << target << std::endl; @@ -647,12 +660,12 @@ bool SvcEnable::execute() const { #ifdef HAS_INSTALL_ENV error_code ec; if(!fs::exists(script->targetDirectory() + initd, ec)) { - output_warning(pos, "svcenable: missing service", _value); + output_warning(pos, "svcenable: missing service", _svc); } fs::create_symlink(initd, target, ec); if(ec) { - output_error(pos, "svcenable: could not enable service " + _value, + output_error(pos, "svcenable: could not enable service " + _svc, ec.message()); return false; } diff --git a/hscript/meta.hh b/hscript/meta.hh index 912cabf..8d56abb 100644 --- a/hscript/meta.hh +++ b/hscript/meta.hh @@ -118,13 +118,21 @@ public: bool execute() const override; }; -class SvcEnable : public StringKey { +class SvcEnable : public Key { private: + const std::string _svc; + const std::string _runlevel; + SvcEnable(const Script *_s, const ScriptLocation &_pos, - const std::string &_svc) : StringKey(_s, _pos, _svc) {} + const std::string &_sv, const std::string &_r) : Key(_s, _pos), + _svc(_sv), _runlevel(_r) {} public: static Key *parseFromData(const std::string &, const ScriptLocation &, int *, int *, const Script *); + + const std::string service() const { return this->_svc; } + const std::string runlevel() const { return this->_runlevel; } + bool validate() const override; bool execute() const override; }; diff --git a/hscript/script_i.hh b/hscript/script_i.hh index b223608..abe56ec 100644 --- a/hscript/script_i.hh +++ b/hscript/script_i.hh @@ -257,10 +257,10 @@ struct Script::ScriptPrivate { const ScriptOptions &) { std::unique_ptr svc(dynamic_cast(obj)); for(const auto &s : svcs_enable) { - if(s->value() == svc->value()) { + if(s->service() == svc->service()) { if(warn) *warn += 1; output_warning(pos, "svcenable: service already enabled", - s->value()); + s->service()); return true; } } diff --git a/tests/fixtures/0239-svcenable-runlevel.installfile b/tests/fixtures/0239-svcenable-runlevel.installfile new file mode 100644 index 0000000..b1b35b6 --- /dev/null +++ b/tests/fixtures/0239-svcenable-runlevel.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 udev boot diff --git a/tests/fixtures/0240-bootloader-invalid.installfile b/tests/fixtures/0240-bootloader-invalid.installfile new file mode 100644 index 0000000..210fe7f --- /dev/null +++ b/tests/fixtures/0240-bootloader-invalid.installfile @@ -0,0 +1,7 @@ +network false +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +mount /dev/sda1 / +arch ppc64 +bootloader grub-efi diff --git a/tests/spec/simulator_spec.rb b/tests/spec/simulator_spec.rb index 161fd12..bded726 100644 --- a/tests/spec/simulator_spec.rb +++ b/tests/spec/simulator_spec.rb @@ -32,7 +32,7 @@ RSpec.describe 'HorizonScript Simulator', :type => :aruba do end end it "handles validation failures correctly" do - use_fixture '0024-numeric-hostname.installfile' + use_fixture '0240-bootloader-invalid.installfile' run_simulate expect(last_command_started.stderr).to include("Script failed. Stop.") end @@ -280,6 +280,11 @@ printf '%s\\t%s\\t%s\\t%s\\t0\\t0\\n' /dev/gwyn/source /usr/src auto noatime >> run_simulate expect(last_command_started.stdout).to include("ln -s /etc/init.d/sshd /target/etc/runlevels/default/sshd") end + it "handles runlevels correctly" do + use_fixture '0239-svcenable-runlevel.installfile' + run_simulate + expect(last_command_started.stdout).to include("ln -s /etc/init.d/udev /target/etc/runlevels/boot/udev") + end end context "simulating 'pkginstall' execution" do # Runner.Execute.pkginstall.APKDB diff --git a/tests/spec/validator_spec.rb b/tests/spec/validator_spec.rb index a5e11e6..8fb6c95 100644 --- a/tests/spec/validator_spec.rb +++ b/tests/spec/validator_spec.rb @@ -687,6 +687,12 @@ RSpec.describe 'HorizonScript validation', :type => :aruba do run_validate expect(last_command_started).to have_output(/error: .*svcenable.*invalid/) end + it "succeeds with a runlevel specified" do + use_fixture '0239-svcenable-runlevel.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end end context "for 'diskid' key" do it "succeeds with basic disk identification" do -- cgit v1.2.3-60-g2f50