From efe16d2b85fd7efc546f840dd380f382f5865622 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Sat, 13 Jun 2020 17:58:58 -0500 Subject: hscript: Stub unfinished implementation of 'bootloader' key --- hscript/meta.cc | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++ hscript/meta.hh | 11 ++++++ hscript/script.cc | 5 +++ hscript/script_i.hh | 13 ++++++++ 4 files changed, 125 insertions(+) diff --git a/hscript/meta.cc b/hscript/meta.cc index c3308d2..75f4ca1 100644 --- a/hscript/meta.cc +++ b/hscript/meta.cc @@ -676,3 +676,99 @@ Key *Version::parseFromData(const std::string &data, bool Version::execute() const { return true; } + + +Key *Bootloader::parseFromData(const std::string &data, + const ScriptLocation &pos, int *errors, int *, + const Script *script) { + if(data.find_first_of(" ") != std::string::npos) { + if(errors) *errors += 1; + output_error(pos, "bootloader: invalid bootloader", data); + return nullptr; + } + + return new Bootloader(script, pos, data); +} + +const std::string my_arch(const Horizon::Script *script) { + const Key *arch_key = script->getOneValue("arch"); + if(arch_key != nullptr) { + const Arch *real_arch = dynamic_cast(arch_key); + return real_arch->value(); + } else { +# if defined(__powerpc64__) + return "ppc64"; +# elif defined(__powerpc__) + return "ppc"; +# elif defined(__aarch64__) + return "aarch64"; +# elif defined(__arm__) + return "armv7"; +# elif defined(__i386__) + return "pmmx"; +# elif defined(__x86_64__) + return "x86_64"; +# else +# error Unknown architecture. +# endif + } +} + +bool Bootloader::validate() const { + const std::string arch = my_arch(script); + + /* 'true' and 'false' are always valid. */ + if(_value == "true" || _value == "false") return true; + + if(arch == "ppc64") { + const static std::set valid_ppc64 = {"grub-ieee1275"}; + return valid_ppc64.find(this->value()) != valid_ppc64.end(); + } else if(arch == "ppc") { + const static std::set valid_ppc = {"grub-ieee1275", + "iquik"}; + return valid_ppc.find(this->value()) != valid_ppc.end(); + } else if(arch == "aarch64") { + const static std::set valid_arm64 = {"grub-efi"}; + return valid_arm64.find(this->value()) != valid_arm64.end(); + } else if(arch == "armv7") { + const static std::set valid_arm = {}; + return valid_arm.find(this->value()) != valid_arm.end(); + } else if(arch == "pmmx") { + const static std::set valid_pmmx = {"grub-bios", + "grub-efi"}; + return valid_pmmx.find(this->value()) != valid_pmmx.end(); + } else if(arch == "x86_64") { + const static std::set valid_x86 = {"grub-bios", + "grub-efi"}; + return valid_x86.find(this->value()) != valid_x86.end(); + } else { + output_error(pos, "bootloader: unknown architecture", arch); + return false; + } +} + +bool Bootloader::execute() const { + /* Nothing to do. */ + if(_value == "false") return true; + + const std::string arch = my_arch(script); + std::string method; + + if(_value == "true") { + if(arch == "ppc64" || arch == "ppc") { + method = "grub-ieee1275"; + } else if(arch == "aarch64") { + method = "grub-efi"; + } else if(arch == "x86_64" || arch == "pmmx") { + if(fs::exists("/sys/firmware/efi")) method = "grub-efi"; + else method = "grub-bios"; + } else { + output_error(pos, "bootloader: no default for architecture", arch); + return false; + } + } else { + method = _value; + } + + return false; +} diff --git a/hscript/meta.hh b/hscript/meta.hh index ab22f1f..912cabf 100644 --- a/hscript/meta.hh +++ b/hscript/meta.hh @@ -138,6 +138,17 @@ public: bool execute() const override; }; +class Bootloader : public StringKey { +private: + Bootloader(const Script *_s, const ScriptLocation &_p, + const std::string &_v) : StringKey(_s, _p, _v) {} +public: + static Key *parseFromData(const std::string &, const ScriptLocation &, + int *, int *, const Script *); + bool validate() const override; + bool execute() const override; +}; + } } diff --git a/hscript/script.cc b/hscript/script.cc index 8fc15f7..897d5d4 100644 --- a/hscript/script.cc +++ b/hscript/script.cc @@ -52,6 +52,7 @@ const std::map valid_keys = { {"signingkey", &SigningKey::parseFromData}, {"svcenable", &SvcEnable::parseFromData}, {"version", &Version::parseFromData}, + {"bootloader", &Bootloader::parseFromData}, {"netconfigtype", &NetConfigType::parseFromData}, {"netaddress", &NetAddress::parseFromData}, @@ -125,6 +126,8 @@ bool Script::ScriptPrivate::store_key(const std::string &key_name, Key *obj, return store_svcenable(obj, pos, errors, warnings, opts); } else if(key_name == "version") { return store_version(obj, pos, errors, warnings, opts); + } else if(key_name == "bootloader") { + return store_bootloader(obj, pos, errors, warnings, opts); } else if(key_name == "username") { return store_username(obj, pos, errors, warnings, opts); } else if(key_name == "useralias") { @@ -386,6 +389,8 @@ const Keys::Key *Script::getOneValue(std::string name) const { return this->internal->keymap.get(); } else if(name == "version") { return this->internal->version.get(); + } else if(name == "bootloader") { + return this->internal->boot.get(); } else if(name == "firmware") { #ifdef NON_LIBRE_FIRMWARE return this->internal->firmware.get(); diff --git a/hscript/script_i.hh b/hscript/script_i.hh index c6dbb54..b223608 100644 --- a/hscript/script_i.hh +++ b/hscript/script_i.hh @@ -63,6 +63,8 @@ struct Script::ScriptPrivate { std::unique_ptr tzone; /*! The version of Adélie to install. */ std::unique_ptr version; + /*! The desired bootloader configuration. */ + std::unique_ptr boot; /*! Network addressing configuration */ std::vector< std::unique_ptr > addresses; @@ -278,6 +280,17 @@ struct Script::ScriptPrivate { return true; } + bool store_bootloader(Key *obj, const ScriptLocation &pos, int *errors, + int *, const ScriptOptions &) { + if(boot) { + DUPLICATE_ERROR(boot, "bootloader", boot->value()) + return false; + } + std::unique_ptr b(dynamic_cast(obj)); + boot = std::move(b); + return true; + } + bool store_username(Key *obj, const ScriptLocation &pos, int *errors, int *, const ScriptOptions &) { if(accounts.size() >= 255) { -- cgit v1.2.3-60-g2f50