...
 
Commits (3)
......@@ -631,7 +631,7 @@ repository https://mirrors.servercentral.com/adelie/1.0/user
</formalpara>
<formalpara id="svcenable.format">
<title>Format</title>
<para>The <literal>svcenable</literal> key is a string value which contains the name of a OpenRC service. The service file must be installed as part of a <literal>pkginstall</literal> key. <literal>svcenable</literal> may appear any number of times in a HorizonScript.</para>
<para>The <literal>svcenable</literal> key is a space-separate list which contains the name of a OpenRC service and an optional runlevel specification. The service file must be installed as part of a <literal>pkginstall</literal> key. <literal>svcenable</literal> may appear any number of times in a HorizonScript. If the runlevel is not specified, the <literal>default</literal> runlevel will be used.</para>
</formalpara>
<formalpara id="svcenable.examples">
<title>Examples</title>
......@@ -643,6 +643,14 @@ svcenable sshd
</programlisting>
<para>This configures the target computer to start the SSH daemon during system boot.</para>
</example>
<example>
<title>The <literal>svcenable</literal> Key &mdash; Start udev on Boot</title>
<programlisting>
svcenable udev boot
svcenable udev-trigger boot
</programlisting>
<para>This configures the target computer to start the <literal>udev</literal> and <literal>udev-trigger</literal> services during early boot, in the <literal>boot</literal> runlevel.</para>
</example>
<example>
<title>The <literal>svcenable</literal> Key &mdash; Typical Desktop</title>
<programlisting>
......
......@@ -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;
}
......
......@@ -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;
};
......
......@@ -257,10 +257,10 @@ struct Script::ScriptPrivate {
const ScriptOptions &) {
std::unique_ptr<SvcEnable> svc(dynamic_cast<SvcEnable *>(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;
}
}
......
network true
network false
hostname 123lonelycorgi.street
pkginstall adelie-base
rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
......
network false
hostname test.machine
pkginstall adelie-base
rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
mount /dev/sda1 /
svcenable sshd
svcenable udev boot
network false
hostname test.machine
pkginstall adelie-base
rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
mount /dev/sda1 /
arch ppc64
bootloader grub-efi
......@@ -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
......
......@@ -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
......