summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hscript/network.cc17
-rw-r--r--hscript/script_e.cc70
-rw-r--r--hscript/script_v.cc11
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) {