From 2495654ac0b1d9a4002f8d385d10d2afec784dda Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Thu, 19 Dec 2019 17:14:27 -0600 Subject: hscript: Add 'arch' key implementation and related tests --- hscript/meta.cc | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++-- hscript/meta.hh | 9 +++++++++ hscript/script.cc | 3 +++ hscript/script_e.cc | 5 +++++ hscript/script_i.hh | 12 +++++++++++ hscript/script_v.cc | 3 +++ 6 files changed, 88 insertions(+), 2 deletions(-) (limited to 'hscript') 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 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 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 _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 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 packages; /*! The root shadow line. */ std::unique_ptr rootpw; + /*! The system CPU architecture. */ + std::unique_ptr arch; /*! The system language. */ std::unique_ptr 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 a(dynamic_cast(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++; -- cgit v1.2.3-70-g09d2