summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hscript/meta.cc58
-rw-r--r--hscript/meta.hh9
-rw-r--r--hscript/script.cc3
-rw-r--r--hscript/script_e.cc5
-rw-r--r--hscript/script_i.hh12
-rw-r--r--hscript/script_v.cc3
-rw-r--r--tests/fixtures/0223-arch-basic.installfile6
-rw-r--r--tests/fixtures/0224-arch-unknown.installfile6
-rw-r--r--tests/fixtures/0225-arch-invalid.installfile6
-rw-r--r--tests/spec/simulator_spec.rb7
-rw-r--r--tests/spec/validator_spec.rb18
11 files changed, 131 insertions, 2 deletions
diff --git a/hscript/meta.cc b/hscript/meta.cc
index b5309f3..f95e2ad 100644
--- a/hscript/meta.cc
+++ b/hscript/meta.cc
@@ -163,11 +163,65 @@ bool Hostname::execute(ScriptOptions opts) const {
}
+static std::set<std::string> valid_arches = {
+ "aarch64", "aarch64_be", "alpha", "armel", "armhf", "armv7",
+ "m68k", "mips", "mips64", "mipsel", "mips64el",
+ "pmmx", "ppc", "ppc64",
+ "riscv", "riscv64",
+ "s390x", "sparc", "sparc64",
+ "x86", "x86_64"
+};
+
+
+Key *Arch::parseFromData(const std::string &data, int lineno, int *errors,
+ int *warnings) {
+ if(data.find_first_not_of("abcdefghijklmnopqrstuvwyxz1234567890") !=
+ std::string::npos) {
+ if(errors) *errors += 1;
+ output_error("installfile:" + std::to_string(lineno),
+ "arch: expected CPU architecture name",
+ "'" + data + "' is not a valid CPU architecture name");
+ return nullptr;
+ }
+
+ if(valid_arches.find(data) == valid_arches.end()) {
+ if(warnings) *warnings += 1;
+ output_warning("installfile:" + std::to_string(lineno),
+ "arch: unknown CPU architecture '" + data + "'");
+ }
+
+ return new Arch(lineno, data);
+}
+
+bool Arch::execute(ScriptOptions opts) const {
+ output_info("installfile:" + std::to_string(line),
+ "arch: setting system CPU architecture to " + value());
+
+ if(opts.test(Simulate)) {
+ std::cout << "printf '" << this->value() << "\\" << "n'"
+ << " > /target/etc/apk/arch" << std::endl;
+ return true;
+ }
+
+#ifdef HAS_INSTALL_ENV
+ std::ofstream arch_f("/target/etc/apk/arch", std::ios_base::trunc);
+ if(!arch_f) {
+ output_error("installfile:" + std::to_string(line),
+ "arch: cannot write target CPU architecture information");
+ return false;
+ }
+
+ arch_f << this->value() << std::endl;
+#endif
+ return true;
+}
+
+
static std::regex valid_pkg("[0-9A-Za-z+_.-]*((>?<|[<>]?=|[~>])[0-9A-Za-z-_.]+)?");
-Key *PkgInstall::parseFromData(const std::string &data, int lineno, int *errors,
- int *warnings) {
+Key *PkgInstall::parseFromData(const std::string &data, int lineno,
+ int *errors, int *warnings) {
std::string next_pkg;
std::istringstream stream(data);
std::set<std::string> all_pkgs;
diff --git a/hscript/meta.hh b/hscript/meta.hh
index 547349d..8740f96 100644
--- a/hscript/meta.hh
+++ b/hscript/meta.hh
@@ -30,6 +30,15 @@ public:
bool execute(ScriptOptions) const override;
};
+class Arch : public StringKey {
+private:
+ Arch(int _line, const std::string &arch) :
+ StringKey(_line, arch) {}
+public:
+ static Key *parseFromData(const std::string &, int, int *, int *);
+ bool execute(ScriptOptions) const override;
+};
+
class PkgInstall : public Key {
private:
const std::set<std::string> _pkgs;
diff --git a/hscript/script.cc b/hscript/script.cc
index cb67fe6..10dfe6b 100644
--- a/hscript/script.cc
+++ b/hscript/script.cc
@@ -40,6 +40,7 @@ const std::map<std::string, key_parse_fn> valid_keys = {
{"pkginstall", &PkgInstall::parseFromData},
{"rootpw", &RootPassphrase::parseFromData},
+ {"arch", &Arch::parseFromData},
{"language", &Language::parseFromData},
{"keymap", &Keymap::parseFromData},
{"firmware", &Firmware::parseFromData},
@@ -92,6 +93,8 @@ bool Script::ScriptPrivate::store_key(const std::string &key_name, Key *obj,
return store_hostname(obj, lineno, errors, warnings, opts);
} else if(key_name == "pkginstall") {
return store_pkginstall(obj, lineno, errors, warnings, opts);
+ } else if(key_name == "arch") {
+ return store_arch(obj, lineno, errors, warnings, opts);
} else if(key_name == "rootpw") {
return store_rootpw(obj, lineno, errors, warnings, opts);
} else if(key_name == "language") {
diff --git a/hscript/script_e.cc b/hscript/script_e.cc
index f8c4ff6..2ae48d0 100644
--- a/hscript/script_e.cc
+++ b/hscript/script_e.cc
@@ -438,6 +438,11 @@ bool Script::execute() const {
}
#endif /* HAS_INSTALL_ENV */
+ /* REQ: Runner.Execute.pkginstall.arch */
+ if(internal->arch) {
+ EXECUTE_OR_FAIL("arch", internal->arch)
+ }
+
/* REQ: Runner.Execute.pkginstall */
output_info("internal", "installing packages to target");
std::ostringstream pkg_list;
diff --git a/hscript/script_i.hh b/hscript/script_i.hh
index cb7da13..9d854eb 100644
--- a/hscript/script_i.hh
+++ b/hscript/script_i.hh
@@ -46,6 +46,8 @@ struct Script::ScriptPrivate {
std::set<std::string> packages;
/*! The root shadow line. */
std::unique_ptr<RootPassphrase> rootpw;
+ /*! The system CPU architecture. */
+ std::unique_ptr<Arch> arch;
/*! The system language. */
std::unique_ptr<Language> lang;
/*! The system keymap. */
@@ -148,6 +150,16 @@ struct Script::ScriptPrivate {
return true;
}
+ bool store_arch(Key* obj, int line, int *errors, int *, ScriptOptions) {
+ if(arch) {
+ DUPLICATE_ERROR(arch, "arch", arch->value())
+ return false;
+ }
+ std::unique_ptr<Arch> a(dynamic_cast<Arch *>(obj));
+ arch = std::move(a);
+ return true;
+ }
+
bool store_rootpw(Key* obj, int line, int *errors, int *, ScriptOptions) {
if(rootpw) {
DUPLICATE_ERROR(rootpw, "rootpw", "an encrypted passphrase")
diff --git a/hscript/script_v.cc b/hscript/script_v.cc
index 7905cfa..ad40f72 100644
--- a/hscript/script_v.cc
+++ b/hscript/script_v.cc
@@ -259,6 +259,9 @@ bool Horizon::Script::validate() const {
/* REQ: Runner.Validate.rootpw */
if(!internal->rootpw->validate(opts)) failures++;
+ /* REQ: Runner.Validate.arch */
+ if(internal->arch && !internal->arch->validate(opts)) failures++;
+
/* REQ: Runner.Validate.language */
if(internal->lang && !internal->lang->validate(opts)) failures++;
diff --git a/tests/fixtures/0223-arch-basic.installfile b/tests/fixtures/0223-arch-basic.installfile
new file mode 100644
index 0000000..21c6e37
--- /dev/null
+++ b/tests/fixtures/0223-arch-basic.installfile
@@ -0,0 +1,6 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+arch ppc64
diff --git a/tests/fixtures/0224-arch-unknown.installfile b/tests/fixtures/0224-arch-unknown.installfile
new file mode 100644
index 0000000..cc457c1
--- /dev/null
+++ b/tests/fixtures/0224-arch-unknown.installfile
@@ -0,0 +1,6 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+arch hppa
diff --git a/tests/fixtures/0225-arch-invalid.installfile b/tests/fixtures/0225-arch-invalid.installfile
new file mode 100644
index 0000000..42adb08
--- /dev/null
+++ b/tests/fixtures/0225-arch-invalid.installfile
@@ -0,0 +1,6 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+mount /dev/sda1 /
+arch Intel x86_64
diff --git a/tests/spec/simulator_spec.rb b/tests/spec/simulator_spec.rb
index df2b2ae..67177c2 100644
--- a/tests/spec/simulator_spec.rb
+++ b/tests/spec/simulator_spec.rb
@@ -156,6 +156,13 @@ printf '%s\\t%s\\t%s\\t%s\\t0\\t0\\n' /dev/gwyn/source /usr/src auto noatime >>
expect(last_command_started.stderr).to include("set domain name 'we-sing-it-proudly.new-romantics.club'")
end
end
+ context "simulating 'arch' execution" do
+ it "sets the architecture properly" do
+ use_fixture '0223-arch-basic.installfile'
+ run_simulate
+ expect(last_command_started.stdout).to include("printf 'ppc64\\n' > /target/etc/apk/arch")
+ end
+ end
context "simulating 'repository' execution" do
it "outputs default repositories when none are specified" do
use_fixture '0001-basic.installfile'
diff --git a/tests/spec/validator_spec.rb b/tests/spec/validator_spec.rb
index eea3f2a..ba38563 100644
--- a/tests/spec/validator_spec.rb
+++ b/tests/spec/validator_spec.rb
@@ -203,6 +203,24 @@ RSpec.describe 'HorizonScript validation', :type => :aruba do
expect(last_command_started).to have_output(/error: .*language.*invalid/)
end
end
+ context "for 'arch' key" do
+ it "succeeds with valid architecture" do
+ use_fixture '0223-arch-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 on unrecognised architecture" do
+ use_fixture '0224-arch-unknown.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/warning: .*arch.*unknown CPU/)
+ end
+ it "fails on malformed architecture name" do
+ use_fixture '0225-arch-invalid.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*arch.*expected/)
+ end
+ end
context "for 'nameserver' key" do
it "succeeds with IPv4 and IPv6 addresses" do
use_fixture '0183-nameserver-basic.installfile'