diff options
-rw-r--r-- | hscript/network.cc | 17 | ||||
-rw-r--r-- | hscript/script_e.cc | 70 | ||||
-rw-r--r-- | hscript/script_v.cc | 11 |
3 files changed, 96 insertions, 2 deletions
diff --git a/hscript/network.cc b/hscript/network.cc index f728aef..28e382b 100644 --- a/hscript/network.cc +++ b/hscript/network.cc @@ -348,8 +348,21 @@ Key *Nameserver::parseFromData(const std::string &data, int lineno, return new Nameserver(lineno, data); } -bool Nameserver::execute(ScriptOptions) const { - return false; +bool Nameserver::execute(ScriptOptions opts) const { + if(opts.test(Simulate)) { + std::cout << "printf 'nameserver %s\\" << "n' " << _value + << " >>/target/etc/resolv.conf" << std::endl; + return true; + } + + std::ofstream resolvconf("/target/etc/resolv.conf", std::ios_base::app); + if(!resolvconf) { + output_error("installfile:" + std::to_string(line), + "nameserver: couldn't write configuration to target"); + return false; + } + resolvconf << "nameserver " << _value << std::endl; + return true; } diff --git a/hscript/script_e.cc b/hscript/script_e.cc index a35b818..ef43bba 100644 --- a/hscript/script_e.cc +++ b/hscript/script_e.cc @@ -234,6 +234,7 @@ bool Script::execute() const { } } + bool dhcp = false; if(!internal->addresses.empty()) { fs::path netifrc_dir("/tmp/horizon/netifrc"); if(!fs::exists(netifrc_dir) && @@ -247,6 +248,7 @@ bool Script::execute() const { EXECUTE_FAILURE("netaddress"); /* "Soft" error. Not fatal. */ } + if(addr->type() == NetAddress::DHCP) dhcp = true; } std::ostringstream conf; @@ -288,6 +290,55 @@ bool Script::execute() const { } } + /* REQ: Runner.Execute.nameserver */ + if(!internal->nses.empty()) { + for(auto &ns : internal->nses) { + if(!ns->execute(opts)) { + EXECUTE_FAILURE("nameserver"); + return false; + } + } + + /* REQ: Runner.Execute.nameserver.FQDN */ + const std::string &hostname(internal->hostname->value()); + const std::string::size_type dot = hostname.find_first_of('.'); + if(dot != std::string::npos && hostname.size() > dot + 1) { + const std::string domain(hostname.substr(dot + 1)); + if(opts.test(Simulate)) { + std::cout << "printf 'domain " << domain << "\\" + << "n >>/target/etc/resolv.conf" << std::endl; + } else { + std::ofstream resolvconf("/target/etc/resolv.conf", + std::ios_base::app); + if(!resolvconf) { + output_error("internal", "failed to open resolv.conf"); + EXECUTE_FAILURE("nameserver"); + return false; + } + resolvconf << "domain " << domain << std::endl; + } + } + + if(dhcp) { + if(opts.test(Simulate)) { + std::cout << "mv /target/etc/resolv.conf " + << "/target/etc/resolv.conf.head" << std::endl; + } else { + if(fs::exists("/target/etc/resolv.conf", ec)) { + fs::rename("/target/etc/resolv.conf", + "/target/etc/resolv.conf.head", ec); + if(ec) { + output_error("internal", + "cannot save nameserver configuration", + ec.message()); + EXECUTE_FAILURE("nameserver"); + return false; + } + } + } + } + } + if(!internal->network->execute(opts)) { EXECUTE_FAILURE("network"); return false; @@ -304,6 +355,9 @@ bool Script::execute() const { } std::cout << "cp /target/etc/conf.d/net /etc/conf.d/net" << std::endl; + if(!internal->nses.empty()) { + std::cout << "cp /target/etc/resolv.conf* /etc/" << std::endl; + } } else { if(do_wpa) { fs::copy_file("/target/etc/wpa_supplicant/wpa_supplicant.conf", @@ -323,6 +377,22 @@ bool Script::execute() const { EXECUTE_FAILURE("network"); return false; } + if(!internal->nses.empty()) { + if(dhcp) { + fs::copy_file("/target/etc/resolv.conf.head", + "/etc/resolv.conf.head", ec); + } else { + fs::copy_file("/target/etc/resolv.conf", + "/etc/resolv.conf", ec); + } + + if(ec) { + output_error("internal", "cannot use DNS configuration " + "during installation", ec.message()); + EXECUTE_FAILURE("network"); + return false; + } + } } } output_step_end("net"); diff --git a/hscript/script_v.cc b/hscript/script_v.cc index a5b85dc..9453c62 100644 --- a/hscript/script_v.cc +++ b/hscript/script_v.cc @@ -13,6 +13,11 @@ #include <algorithm> #include <map> #include <memory> +#ifdef HAS_INSTALL_ENV +# include <resolv.h> /* MAXNS */ +#else +# define MAXNS 3 /* default */ +#endif #include <set> #include <string> #include <vector> @@ -212,6 +217,12 @@ bool Horizon::Script::validate() const { for(auto &ns : internal->nses) { if(!ns->validate(opts)) failures++; } + if(internal->nses.size() > MAXNS) { + output_warning("installfile:" + + to_string(internal->nses[MAXNS]->lineno()), + "nameserver: more nameservers are defined than usable", + to_string(MAXNS) + " nameservers are allowed"); + } /* REQ: Runner.Validate.network.netssid */ for(auto &ssid : internal->ssids) { |