Loading src/containers.cpp +7 −8 Changes for src/containers.cpp: 7 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -214,8 +214,8 @@ std::vector<std::string> hostNameservers() { return out; } // the container's /etc/resolv.conf (images expect that file) std::string resolvConf(const Settings &s) { // the container's name servers (its resolv.conf / resolv.yaml) std::vector<std::string> nameservers(const Settings &s) { std::vector<std::string> servers = s.dns; if (servers.empty()) for (auto &n : hostNameservers()) { Loading @@ -224,9 +224,7 @@ std::string resolvConf(const Settings &s) { servers.push_back(n); } if (servers.empty() && !s.gateway.empty()) servers.push_back(s.gateway); std::string out; for (auto &n : servers) out += "nameserver " + n + "\n"; return out; return servers; } std::string prepare(const Settings &s) { Loading @@ -236,9 +234,10 @@ std::string prepare(const Settings &s) { std::string host = s.hostname.empty() ? s.name : s.hostname; // with DHCP the supervisor writes the leased address in later std::string ip = s.network == "bridge" && !s.address.empty() && !isDhcp(s) ? s.address.substr(0, s.address.find('/')) : "127.0.1.1"; std::string hosts = "127.0.0.1\tlocalhost\n::1\tlocalhost ip6-localhost ip6-loopback\n" + ip + "\t" + host + "\n"; if (!writeFile(dir + "/hosts", hosts) || !writeFile(dir + "/hostname", host + "\n") || !writeFile(dir + "/resolv.conf", resolvConf(s))) std::vector<std::string> servers = nameservers(s); if (!writeFile(dir + "/hosts", hostsText(host, ip)) || !writeFile(dir + "/hostname", host + "\n") || !writeFile(dir + "/resolv.conf", resolvConfText(servers)) || !writeFile(dir + "/host.yaml", hostYaml(host, ip)) || !writeFile(dir + "/resolv.yaml", resolvYaml(servers))) return sysErr(dir, errno); return ""; } Loading src/runtime.cpp +56 −4 Changes for src/runtime.cpp: 56 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -145,6 +145,21 @@ struct Pid1 { if (fd >= 0) close(fd); } } // a FenrirOS image (os-release ID or ID_LIKE fenriros): its systempp // reads /etc/host.yaml and /etc/resolv.yaml, not hosts and resolv.conf static bool fenrirOs() { std::string text; if (!readFile("/etc/os-release", text) && !readFile("/usr/lib/os-release", text)) return false; for (auto &line : split(text, '\n')) { std::string l = trim(line); if (!startsWith(l, "ID=") && !startsWith(l, "ID_LIKE=")) continue; std::string v = l.substr(l.find('=') + 1); if (v.size() >= 2 && (v[0] == '"' || v[0] == '\'')) v = v.substr(1, v.size() - 2); for (auto &w : split(v, ' ')) if (w == "fenriros") return true; } return false; } void mountFs(const char *type, const std::string &where, unsigned long flags, const std::string &opts = "") { target(where, false); must(mount(type, where.c_str(), type, flags, opts.empty() ? nullptr : opts.c_str()) == 0, "mount " + where); Loading Loading @@ -234,6 +249,12 @@ struct Pid1 { binds.push_back({openTree(host, ro), where, !S_ISDIR(st.st_mode), ro}); }; for (const char *f : {"hosts", "hostname", "resolv.conf"}) source(l.dir + "/" + f, std::string("/etc/") + f, false); // systempp's: only mounted in a FenrirOS image, which is known // after pivoting (its os-release resolved inside the container) size_t yamlBinds = binds.size(); for (const char *f : {"host.yaml", "resolv.yaml"}) source(l.dir + "/" + f, std::string("/etc/") + f, false); std::vector<Bind> yaml(binds.begin() + yamlBinds, binds.end()); binds.resize(yamlBinds); for (auto &b : s.binds) { std::vector<std::string> p = split(b, ':'); bool ro = p.size() > 1 && p.back() == "ro"; Loading Loading @@ -274,6 +295,11 @@ struct Pid1 { symlink("/proc/self/fd/2", "/dev/stderr"); symlink("/proc/kcore", "/dev/core"); bool fenriros = fenrirOs(); for (auto &b : yaml) { if (fenriros) attach(b.fd, b.where, b.file); close(b.fd); } for (auto &b : binds) { attach(b.fd, b.where, b.file); close(b.fd); Loading Loading @@ -648,11 +674,11 @@ private: writeFile(statePath(s.name, ".lease"), "address=" + l.cidr() + "\ngateway=" + l.routerText() + "\ndns=" + join(l.dnsText(), " ") + "\nexpires=" + std::to_string((long long)(l.obtained + l.seconds)) + "\n"); rewrite(_l.dir + "/hosts", "127.0.0.1\tlocalhost\n::1\tlocalhost ip6-localhost ip6-loopback\n" + ip + "\t" + host + "\n"); rewrite(_l.dir + "/hosts", hostsText(host, ip)); rewrite(_l.dir + "/host.yaml", hostYaml(host, ip)); if (s.dns.empty() && !l.dns.empty()) { std::string r; for (auto &d : l.dnsText()) r += "nameserver " + d + "\n"; rewrite(_l.dir + "/resolv.conf", r); rewrite(_l.dir + "/resolv.conf", resolvConfText(l.dnsText())); rewrite(_l.dir + "/resolv.yaml", resolvYaml(l.dnsText())); } } Loading Loading @@ -776,6 +802,32 @@ int supervise(const Launch &l, int status) { } // namespace std::string hostsText(const std::string &host, const std::string &ip) { return "127.0.0.1\tlocalhost\n::1\tlocalhost ip6-localhost ip6-loopback\n" + ip + "\t" + host + "\n"; } // systempp's /etc/host.yaml (format: systempp src/linux/netdb.cpp) std::string hostYaml(const std::string &host, const std::string &ip) { auto entry = [](const std::string &addr, const std::string &name, const std::string &aliases) { return " - ip: \"" + addr + "\"\n name: " + name + "\n aliases: [" + aliases + "]\n"; }; return "hostname: " + host + "\nhosts:\n" + entry("127.0.0.1", "localhost", "") + entry("::1", "localhost", "ip6-localhost, ip6-loopback") + entry(ip, host, ""); } std::string resolvConfText(const std::vector<std::string> &servers) { std::string out; for (auto &n : servers) out += "nameserver " + n + "\n"; return out; } // systempp's /etc/resolv.yaml ("- nameserver: <address>") std::string resolvYaml(const std::vector<std::string> &servers) { std::string out; for (auto &n : servers) out += "- nameserver: \"" + n + "\"\n"; return out; } std::string hostVeth(const std::string &name) { std::string n = "veth" + name; if (n.size() <= 15 && n.find('.') == std::string::npos) return n; Loading src/runtime.h +12 −2 Changes for src/runtime.h: 12 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -42,8 +42,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * directory), pivots into it and then mounts, from inside -- so a symlink * in the image can't send a mount to the host -- /proc, /sys (read-only), * /dev (tmpfs with the usual nodes, devpts, /dev/shm, mqueue), the * container's /etc/hosts, /etc/hostname and /etc/resolv.conf, the bind * mounts and tmpfs of its settings. Kernel interfaces in /proc are made * container's /etc/hosts, /etc/hostname and /etc/resolv.conf (in a * FenrirOS image, os-release ID=fenriros, also systempp's /etc/host.yaml * and /etc/resolv.yaml, which it reads instead), the bind mounts and tmpfs * of its settings. Kernel interfaces in /proc are made * read-only or masked as Docker does. The capability bounding set is cut * to Docker's default (boot: nspawn's), plus/minus the settings. * Loading Loading @@ -80,6 +82,14 @@ pid_t launch(const Launch &l, int *status, std::string &err); std::string hostVeth(const std::string &name); std::string cgroupOf(const std::string &name); // the container's name files, written into its directory by prepare() and // (Address=dhcp) by the supervisor: hosts and resolv.conf for every image, // host.yaml and resolv.yaml (systempp's formats) for FenrirOS images std::string hostsText(const std::string &host, const std::string &ip); std::string hostYaml(const std::string &host, const std::string &ip); std::string resolvConfText(const std::vector<std::string> &servers); std::string resolvYaml(const std::vector<std::string> &servers); // a signal by name (TERM, SIGTERM) or number; 0 if unknown int signalNumber(const std::string &name); Loading Loading
src/containers.cpp +7 −8 Changes for src/containers.cpp: 7 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -214,8 +214,8 @@ std::vector<std::string> hostNameservers() { return out; } // the container's /etc/resolv.conf (images expect that file) std::string resolvConf(const Settings &s) { // the container's name servers (its resolv.conf / resolv.yaml) std::vector<std::string> nameservers(const Settings &s) { std::vector<std::string> servers = s.dns; if (servers.empty()) for (auto &n : hostNameservers()) { Loading @@ -224,9 +224,7 @@ std::string resolvConf(const Settings &s) { servers.push_back(n); } if (servers.empty() && !s.gateway.empty()) servers.push_back(s.gateway); std::string out; for (auto &n : servers) out += "nameserver " + n + "\n"; return out; return servers; } std::string prepare(const Settings &s) { Loading @@ -236,9 +234,10 @@ std::string prepare(const Settings &s) { std::string host = s.hostname.empty() ? s.name : s.hostname; // with DHCP the supervisor writes the leased address in later std::string ip = s.network == "bridge" && !s.address.empty() && !isDhcp(s) ? s.address.substr(0, s.address.find('/')) : "127.0.1.1"; std::string hosts = "127.0.0.1\tlocalhost\n::1\tlocalhost ip6-localhost ip6-loopback\n" + ip + "\t" + host + "\n"; if (!writeFile(dir + "/hosts", hosts) || !writeFile(dir + "/hostname", host + "\n") || !writeFile(dir + "/resolv.conf", resolvConf(s))) std::vector<std::string> servers = nameservers(s); if (!writeFile(dir + "/hosts", hostsText(host, ip)) || !writeFile(dir + "/hostname", host + "\n") || !writeFile(dir + "/resolv.conf", resolvConfText(servers)) || !writeFile(dir + "/host.yaml", hostYaml(host, ip)) || !writeFile(dir + "/resolv.yaml", resolvYaml(servers))) return sysErr(dir, errno); return ""; } Loading
src/runtime.cpp +56 −4 Changes for src/runtime.cpp: 56 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -145,6 +145,21 @@ struct Pid1 { if (fd >= 0) close(fd); } } // a FenrirOS image (os-release ID or ID_LIKE fenriros): its systempp // reads /etc/host.yaml and /etc/resolv.yaml, not hosts and resolv.conf static bool fenrirOs() { std::string text; if (!readFile("/etc/os-release", text) && !readFile("/usr/lib/os-release", text)) return false; for (auto &line : split(text, '\n')) { std::string l = trim(line); if (!startsWith(l, "ID=") && !startsWith(l, "ID_LIKE=")) continue; std::string v = l.substr(l.find('=') + 1); if (v.size() >= 2 && (v[0] == '"' || v[0] == '\'')) v = v.substr(1, v.size() - 2); for (auto &w : split(v, ' ')) if (w == "fenriros") return true; } return false; } void mountFs(const char *type, const std::string &where, unsigned long flags, const std::string &opts = "") { target(where, false); must(mount(type, where.c_str(), type, flags, opts.empty() ? nullptr : opts.c_str()) == 0, "mount " + where); Loading Loading @@ -234,6 +249,12 @@ struct Pid1 { binds.push_back({openTree(host, ro), where, !S_ISDIR(st.st_mode), ro}); }; for (const char *f : {"hosts", "hostname", "resolv.conf"}) source(l.dir + "/" + f, std::string("/etc/") + f, false); // systempp's: only mounted in a FenrirOS image, which is known // after pivoting (its os-release resolved inside the container) size_t yamlBinds = binds.size(); for (const char *f : {"host.yaml", "resolv.yaml"}) source(l.dir + "/" + f, std::string("/etc/") + f, false); std::vector<Bind> yaml(binds.begin() + yamlBinds, binds.end()); binds.resize(yamlBinds); for (auto &b : s.binds) { std::vector<std::string> p = split(b, ':'); bool ro = p.size() > 1 && p.back() == "ro"; Loading Loading @@ -274,6 +295,11 @@ struct Pid1 { symlink("/proc/self/fd/2", "/dev/stderr"); symlink("/proc/kcore", "/dev/core"); bool fenriros = fenrirOs(); for (auto &b : yaml) { if (fenriros) attach(b.fd, b.where, b.file); close(b.fd); } for (auto &b : binds) { attach(b.fd, b.where, b.file); close(b.fd); Loading Loading @@ -648,11 +674,11 @@ private: writeFile(statePath(s.name, ".lease"), "address=" + l.cidr() + "\ngateway=" + l.routerText() + "\ndns=" + join(l.dnsText(), " ") + "\nexpires=" + std::to_string((long long)(l.obtained + l.seconds)) + "\n"); rewrite(_l.dir + "/hosts", "127.0.0.1\tlocalhost\n::1\tlocalhost ip6-localhost ip6-loopback\n" + ip + "\t" + host + "\n"); rewrite(_l.dir + "/hosts", hostsText(host, ip)); rewrite(_l.dir + "/host.yaml", hostYaml(host, ip)); if (s.dns.empty() && !l.dns.empty()) { std::string r; for (auto &d : l.dnsText()) r += "nameserver " + d + "\n"; rewrite(_l.dir + "/resolv.conf", r); rewrite(_l.dir + "/resolv.conf", resolvConfText(l.dnsText())); rewrite(_l.dir + "/resolv.yaml", resolvYaml(l.dnsText())); } } Loading Loading @@ -776,6 +802,32 @@ int supervise(const Launch &l, int status) { } // namespace std::string hostsText(const std::string &host, const std::string &ip) { return "127.0.0.1\tlocalhost\n::1\tlocalhost ip6-localhost ip6-loopback\n" + ip + "\t" + host + "\n"; } // systempp's /etc/host.yaml (format: systempp src/linux/netdb.cpp) std::string hostYaml(const std::string &host, const std::string &ip) { auto entry = [](const std::string &addr, const std::string &name, const std::string &aliases) { return " - ip: \"" + addr + "\"\n name: " + name + "\n aliases: [" + aliases + "]\n"; }; return "hostname: " + host + "\nhosts:\n" + entry("127.0.0.1", "localhost", "") + entry("::1", "localhost", "ip6-localhost, ip6-loopback") + entry(ip, host, ""); } std::string resolvConfText(const std::vector<std::string> &servers) { std::string out; for (auto &n : servers) out += "nameserver " + n + "\n"; return out; } // systempp's /etc/resolv.yaml ("- nameserver: <address>") std::string resolvYaml(const std::vector<std::string> &servers) { std::string out; for (auto &n : servers) out += "- nameserver: \"" + n + "\"\n"; return out; } std::string hostVeth(const std::string &name) { std::string n = "veth" + name; if (n.size() <= 15 && n.find('.') == std::string::npos) return n; Loading
src/runtime.h +12 −2 Changes for src/runtime.h: 12 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -42,8 +42,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * directory), pivots into it and then mounts, from inside -- so a symlink * in the image can't send a mount to the host -- /proc, /sys (read-only), * /dev (tmpfs with the usual nodes, devpts, /dev/shm, mqueue), the * container's /etc/hosts, /etc/hostname and /etc/resolv.conf, the bind * mounts and tmpfs of its settings. Kernel interfaces in /proc are made * container's /etc/hosts, /etc/hostname and /etc/resolv.conf (in a * FenrirOS image, os-release ID=fenriros, also systempp's /etc/host.yaml * and /etc/resolv.yaml, which it reads instead), the bind mounts and tmpfs * of its settings. Kernel interfaces in /proc are made * read-only or masked as Docker does. The capability bounding set is cut * to Docker's default (boot: nspawn's), plus/minus the settings. * Loading Loading @@ -80,6 +82,14 @@ pid_t launch(const Launch &l, int *status, std::string &err); std::string hostVeth(const std::string &name); std::string cgroupOf(const std::string &name); // the container's name files, written into its directory by prepare() and // (Address=dhcp) by the supervisor: hosts and resolv.conf for every image, // host.yaml and resolv.yaml (systempp's formats) for FenrirOS images std::string hostsText(const std::string &host, const std::string &ip); std::string hostYaml(const std::string &host, const std::string &ip); std::string resolvConfText(const std::vector<std::string> &servers); std::string resolvYaml(const std::vector<std::string> &servers); // a signal by name (TERM, SIGTERM) or number; 0 if unknown int signalNumber(const std::string &name); Loading