diff --git i/3rdparty/stout/include/stout/os/posix/fork.hpp w/3rdparty/stout/include/stout/os/posix/fork.hpp index a29967d..290b98b 100644 --- i/3rdparty/stout/include/stout/os/posix/fork.hpp +++ w/3rdparty/stout/include/stout/os/posix/fork.hpp @@ -369,7 +369,7 @@ private: if (exec.isSome()) { // Execute the command (via '/bin/sh -c command'). const char* command = exec.get().command.c_str(); - execlp("sh", "sh", "-c", command, (char*) nullptr); + execlp("@sh@", "sh", "-c", command, (char*) nullptr); EXIT(EXIT_FAILURE) << "Failed to execute '" << command << "': " << os::strerror(errno); } else if (wait.isSome()) { diff --git i/3rdparty/stout/include/stout/posix/os.hpp w/3rdparty/stout/include/stout/posix/os.hpp index 8511dfd..1e7be01 100644 --- i/3rdparty/stout/include/stout/posix/os.hpp +++ w/3rdparty/stout/include/stout/posix/os.hpp @@ -366,7 +366,7 @@ inline Try> pids(Option group, Option session) inline Try tar(const std::string& path, const std::string& archive) { Try tarOut = - os::shell("tar %s %s %s", "-czf", archive.c_str(), path.c_str()); + os::shell("@tar@ %s %s %s", "-czf", archive.c_str(), path.c_str()); if (tarOut.isError()) { return Error("Failed to archive " + path + ": " + tarOut.error()); diff --git i/src/Makefile.am w/src/Makefile.am index 68fff14..c572f92 100644 --- i/src/Makefile.am +++ w/src/Makefile.am @@ -1775,7 +1775,7 @@ if HAS_JAVA $(MESOS_JAR): $(MESOS_JAR_SOURCE) $(MESOS_JAR_GENERATED) java/mesos.pom @echo "Building mesos-$(PACKAGE_VERSION).jar ..." - @cd $(abs_top_builddir)/src/java && $(MVN) -B -f mesos.pom clean package + @cd $(abs_top_builddir)/src/java && $(MVN) -B -f mesos.pom -Dmaven.repo.local=@mavenRepo@ clean package # Convenience library for JNI bindings. # TODO(Charles Reiss): We really should be building the Java library diff --git i/src/cli/mesos-scp w/src/cli/mesos-scp index a71ab07..1043d1b 100755 --- i/src/cli/mesos-scp +++ w/src/cli/mesos-scp @@ -19,7 +19,8 @@ if sys.version_info < (2,6,0): def scp(host, src, dst): - cmd = 'scp -pr %s %s' % (src, host + ':' + dst) + cmd = '@scp@ -pr %s %s' % (src, host + ':' + dst) + try: process = subprocess.Popen( cmd, diff --git i/src/common/command_utils.cpp w/src/common/command_utils.cpp index c50be76..388cc53 100644 --- i/src/common/command_utils.cpp +++ w/src/common/command_utils.cpp @@ -142,7 +142,7 @@ Future tar( argv.emplace_back(input); - return launch("tar", argv) + return launch("@tar@", argv) .then([]() { return Nothing(); }); } @@ -164,7 +164,7 @@ Future untar( argv.emplace_back(directory.get()); } - return launch("tar", argv) + return launch("@tar@", argv) .then([]() { return Nothing(); }); } @@ -172,7 +172,7 @@ Future untar( Future sha512(const Path& input) { #ifdef __linux__ - const string cmd = "sha512sum"; + const string cmd = "@sha512sum@"; vector argv = { cmd, input // Input file to compute shasum. @@ -208,7 +208,7 @@ Future gzip(const Path& input) input }; - return launch("gzip", argv) + return launch("@gzip@", argv) .then([]() { return Nothing(); }); } @@ -221,7 +221,7 @@ Future decompress(const Path& input) input }; - return launch("gzip", argv) + return launch("@gzip@", argv) .then([]() { return Nothing(); }); } diff --git i/src/launcher/fetcher.cpp w/src/launcher/fetcher.cpp index 42980f5..3aebeed 100644 --- i/src/launcher/fetcher.cpp +++ w/src/launcher/fetcher.cpp @@ -80,17 +80,17 @@ static Try extract( strings::endsWith(sourcePath, ".tar.bz2") || strings::endsWith(sourcePath, ".txz") || strings::endsWith(sourcePath, ".tar.xz")) { - command = {"tar", "-C", destinationDirectory, "-xf", sourcePath}; + command = {"@tar@", "-C", destinationDirectory, "-xf", sourcePath}; } else if (strings::endsWith(sourcePath, ".gz")) { string pathWithoutExtension = sourcePath.substr(0, sourcePath.length() - 3); string filename = Path(pathWithoutExtension).basename(); string destinationPath = path::join(destinationDirectory, filename); - command = {"gunzip", "-d", "-c"}; + command = {"@gunzip@", "-d", "-c"}; in = Subprocess::PATH(sourcePath); out = Subprocess::PATH(destinationPath); } else if (strings::endsWith(sourcePath, ".zip")) { - command = {"unzip", "-o", "-d", destinationDirectory, sourcePath}; + command = {"@unzip@", "-o", "-d", destinationDirectory, sourcePath}; } else { return false; } @@ -193,7 +193,7 @@ static Try copyFile( const string& sourcePath, const string& destinationPath) { - int status = os::spawn("cp", {"cp", sourcePath, destinationPath}); + int status = os::spawn("cp", {"@cp@", sourcePath, destinationPath}); if (status == -1) { return ErrnoError("Failed to copy '" + sourcePath + "'"); diff --git i/src/linux/perf.cpp w/src/linux/perf.cpp index b301e25..356a2cf 100644 --- i/src/linux/perf.cpp +++ w/src/linux/perf.cpp @@ -128,7 +128,7 @@ private: // NOTE: The supervisor childhook places perf in its own process group // and will kill the perf process when the parent dies. Try _perf = subprocess( - "perf", + "@perf@", argv, Subprocess::PIPE(), Subprocess::PIPE(), diff --git i/src/linux/systemd.cpp w/src/linux/systemd.cpp index 6318f48..394d88d 100644 --- i/src/linux/systemd.cpp +++ w/src/linux/systemd.cpp @@ -196,13 +196,21 @@ bool exists() // This is static as the init system should not change while we are running. static const bool exists = []() -> bool { // (1) Test whether `/sbin/init` links to systemd. - const Result realpath = os::realpath("/sbin/init"); - if (realpath.isError() || realpath.isNone()) { - LOG(WARNING) << "Failed to test /sbin/init for systemd environment: " - << (realpath.isError() ? realpath.error() - : "does not exist"); - - return false; + // cstrahan(nixos): first assume we're on NixOS, then try non-NixOS + Result realpath = os::realpath("/run/current-system/systemd/lib/systemd/systemd"); + Result realpathNixOS = realpath; + if (realpathNixOS.isError() || realpathNixOS.isNone()) { + Result realpathNonNixOS = realpath = os::realpath("/sbin/init"); + if (realpathNonNixOS.isError() || realpathNonNixOS.isNone()) { + LOG(WARNING) << "Failed to test /run/current-system/systemd/lib/systemd/systemd for systemd environment: " + << (realpathNixOS.isError() ? realpathNixOS.error() + : "does not exist"); + LOG(WARNING) << "Failed to test /sbin/init for systemd environment: " + << (realpathNonNixOS.isError() ? realpathNonNixOS.error() + : "does not exist"); + + return false; + } } CHECK_SOME(realpath); @@ -278,6 +286,10 @@ Path hierarchy() Try daemonReload() { + // cstrahan(nixos): should we patch these `systemctl`s? + // probably don't want to hard-code a particular systemd store path here, + // but if we use /run/current-system/sw/bin/systemctl, + // we won't be able to support non-NixOS distros. Try daemonReload = os::shell("systemctl daemon-reload"); if (daemonReload.isError()) { return Error("Failed to reload systemd daemon: " + daemonReload.error()); diff --git i/src/python/cli/src/mesos/cli.py w/src/python/cli/src/mesos/cli.py index 4a9b558..c08a8b9 100644 --- i/src/python/cli/src/mesos/cli.py +++ w/src/python/cli/src/mesos/cli.py @@ -40,7 +40,7 @@ def resolve(master): import subprocess process = subprocess.Popen( - ['mesos-resolve', master], + ['@mesos-resolve@', master], stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, diff --git i/src/slave/containerizer/mesos/isolators/docker/volume/isolator.cpp w/src/slave/containerizer/mesos/isolators/docker/volume/isolator.cpp index 5b630c1..d63ad69 100644 --- i/src/slave/containerizer/mesos/isolators/docker/volume/isolator.cpp +++ w/src/slave/containerizer/mesos/isolators/docker/volume/isolator.cpp @@ -499,7 +499,7 @@ Future> DockerVolumeIsolatorProcess::_prepare( // unsafe arbitrary commands). CommandInfo* command = launchInfo.add_pre_exec_commands(); command->set_shell(false); - command->set_value("mount"); + command->set_value("@mount@"); command->add_arguments("mount"); command->add_arguments("-n"); command->add_arguments("--rbind"); diff --git i/src/slave/containerizer/mesos/isolators/filesystem/linux.cpp w/src/slave/containerizer/mesos/isolators/filesystem/linux.cpp index d7fe9a8..1361a4e 100644 --- i/src/slave/containerizer/mesos/isolators/filesystem/linux.cpp +++ w/src/slave/containerizer/mesos/isolators/filesystem/linux.cpp @@ -154,9 +154,9 @@ Try LinuxFilesystemIsolatorProcess::create(const Flags& flags) // here because 'create' will only be invoked during // initialization. Try mount = os::shell( - "mount --bind %s %s && " - "mount --make-private %s && " - "mount --make-shared %s", + "@mount@ --bind %s %s && " + "@mount@ --make-private %s && " + "@mount@ --make-shared %s", workDir->c_str(), workDir->c_str(), workDir->c_str(), @@ -175,8 +175,8 @@ Try LinuxFilesystemIsolatorProcess::create(const Flags& flags) LOG(INFO) << "Making '" << workDir.get() << "' a shared mount"; Try mount = os::shell( - "mount --make-private %s && " - "mount --make-shared %s", + "@mount@ --make-private %s && " + "@mount@ --make-shared %s", workDir->c_str(), workDir->c_str()); @@ -422,7 +422,7 @@ Try> LinuxFilesystemIsolatorProcess::getPreExecCommands( CommandInfo command; command.set_shell(false); - command.set_value("mount"); + command.set_value("@mount@"); command.add_arguments("mount"); command.add_arguments("-n"); command.add_arguments("--rbind"); @@ -610,7 +610,7 @@ Try> LinuxFilesystemIsolatorProcess::getPreExecCommands( // TODO(jieyu): Consider the mode in the volume. CommandInfo command; command.set_shell(false); - command.set_value("mount"); + command.set_value("@mount@"); command.add_arguments("mount"); command.add_arguments("-n"); command.add_arguments("--rbind"); diff --git i/src/slave/containerizer/mesos/isolators/filesystem/shared.cpp w/src/slave/containerizer/mesos/isolators/filesystem/shared.cpp index 927d95b..576dc63 100644 --- i/src/slave/containerizer/mesos/isolators/filesystem/shared.cpp +++ w/src/slave/containerizer/mesos/isolators/filesystem/shared.cpp @@ -208,7 +208,7 @@ Future> SharedFilesystemIsolatorProcess::prepare( } launchInfo.add_pre_exec_commands()->set_value( - "mount -n --bind " + hostPath + " " + volume.container_path()); + "@mount@ -n --bind " + hostPath + " " + volume.container_path()); } return launchInfo; diff --git i/src/slave/containerizer/mesos/isolators/gpu/isolator.cpp w/src/slave/containerizer/mesos/isolators/gpu/isolator.cpp index 25636b5..33ec315 100644 --- i/src/slave/containerizer/mesos/isolators/gpu/isolator.cpp +++ w/src/slave/containerizer/mesos/isolators/gpu/isolator.cpp @@ -401,7 +401,7 @@ Future> NvidiaGpuIsolatorProcess::_prepare( } launchInfo.add_pre_exec_commands()->set_value( - "mount --no-mtab --rbind --read-only " + + "@mount@ --no-mtab --rbind --read-only " + volume.HOST_PATH() + " " + target); } diff --git i/src/slave/containerizer/mesos/isolators/gpu/volume.cpp w/src/slave/containerizer/mesos/isolators/gpu/volume.cpp index 536a3c7..e2819dd 100644 --- i/src/slave/containerizer/mesos/isolators/gpu/volume.cpp +++ w/src/slave/containerizer/mesos/isolators/gpu/volume.cpp @@ -274,7 +274,7 @@ Try NvidiaVolume::create() string path = path::join(hostPath, "bin", binary); if (!os::exists(path)) { - string command = "which " + binary; + string command = "@which@ " + binary; Try which = os::shell(command); if (which.isSome()) { @@ -288,7 +288,7 @@ Try NvidiaVolume::create() : "No such file or directory")); } - command = "cp " + realpath.get() + " " + path; + command = "@cp@ " + realpath.get() + " " + path; Try cp = os::shell(command); if (cp.isError()) { return Error("Failed to os::shell '" + command + "': " + cp.error()); @@ -360,7 +360,7 @@ Try NvidiaVolume::create() Path(realpath.get()).basename()); if (!os::exists(libraryPath)) { - string command = "cp " + realpath.get() + " " + libraryPath; + string command = "@cp@ " + realpath.get() + " " + libraryPath; Try cp = os::shell(command); if (cp.isError()) { return Error("Failed to os::shell '" + command + "':" diff --git i/src/slave/containerizer/mesos/isolators/namespaces/pid.cpp w/src/slave/containerizer/mesos/isolators/namespaces/pid.cpp index 42bc2e1..2f9066e 100644 --- i/src/slave/containerizer/mesos/isolators/namespaces/pid.cpp +++ w/src/slave/containerizer/mesos/isolators/namespaces/pid.cpp @@ -131,7 +131,7 @@ Future> NamespacesPidIsolatorProcess::prepare( // // TOOD(jieyu): Consider unmount the existing /proc. launchInfo.add_pre_exec_commands()->set_value( - "mount -n -t proc proc /proc -o nosuid,noexec,nodev"); + "@mount@ -n -t proc proc /proc -o nosuid,noexec,nodev"); return launchInfo; } diff --git i/src/slave/containerizer/mesos/isolators/network/cni/cni.cpp w/src/slave/containerizer/mesos/isolators/network/cni/cni.cpp index fc68f04..267b040 100644 --- i/src/slave/containerizer/mesos/isolators/network/cni/cni.cpp +++ w/src/slave/containerizer/mesos/isolators/network/cni/cni.cpp @@ -205,9 +205,9 @@ Try NetworkCniIsolatorProcess::create(const Flags& flags) // here because 'create' will only be invoked during // initialization. Try mount = os::shell( - "mount --bind %s %s && " - "mount --make-private %s && " - "mount --make-shared %s", + "@mount@ --bind %s %s && " + "@mount@ --make-private %s && " + "@mount@ --make-shared %s", rootDir->c_str(), rootDir->c_str(), rootDir->c_str(), @@ -227,8 +227,8 @@ Try NetworkCniIsolatorProcess::create(const Flags& flags) LOG(INFO) << "Making '" << rootDir.get() << "' a shared mount"; Try mount = os::shell( - "mount --make-private %s && " - "mount --make-shared %s", + "@mount@ --make-private %s && " + "@mount@ --make-shared %s", rootDir->c_str(), rootDir->c_str()); diff --git i/src/slave/containerizer/mesos/isolators/network/cni/plugins/port_mapper/port_mapper.cpp w/src/slave/containerizer/mesos/isolators/network/cni/plugins/port_mapper/port_mapper.cpp index 43cf3e4..94bad8b 100644 --- i/src/slave/containerizer/mesos/isolators/network/cni/plugins/port_mapper/port_mapper.cpp +++ w/src/slave/containerizer/mesos/isolators/network/cni/plugins/port_mapper/port_mapper.cpp @@ -301,7 +301,7 @@ Try PortMapper::addPortMapping( # Check if the `chain` exists in the iptable. If it does not # exist go ahead and install the chain in the iptables NAT # table. - iptables -w -t nat --list %s + @iptables@ -w -t nat --list %s if [ $? -ne 0 ]; then # NOTE: When we create the chain, there is a possibility of a # race due to which a container launch can fail. This can @@ -315,25 +315,25 @@ Try PortMapper::addPortMapping( # since it can happen only when the chain is created the first # time and two commands for creation of the chain are executed # simultaneously. - (iptables -w -t nat -N %s || exit 1) + (@iptables@ -w -t nat -N %s || exit 1) # Once the chain has been installed add a rule in the PREROUTING # chain to jump to this chain for any packets that are # destined to a local address. - (iptables -w -t nat -A PREROUTING \ + (@iptables@ -w -t nat -A PREROUTING \ -m addrtype --dst-type LOCAL -j %s || exit 1) # For locally generated packets we need a rule in the OUTPUT # chain as well, since locally generated packets directly hit # the output CHAIN, bypassing PREROUTING. - (iptables -w -t nat -A OUTPUT \ + (@iptables@ -w -t nat -A OUTPUT \ ! -d 127.0.0.0/8 -m addrtype \ --dst-type LOCAL -j %s || exit 1) fi # Within the `chain` go ahead and install the DNAT rule, if it # does not exist. - (iptables -w -t nat -C %s || iptables -t nat -A %s))~", + (@iptables@ -w -t nat -C %s || @iptables@ -t nat -A %s))~", chain, chain, chain, @@ -360,7 +360,7 @@ Try PortMapper::delPortMapping() # The iptables command searches for the DNAT rules with tag # "container_id: ", and if it exists goes ahead # and deletes it. - iptables -w -t nat -S %s | sed "/%s/ s/-A/iptables -w -t nat -D/e")~", + @iptables@ -w -t nat -S %s | sed "/%s/ s/-A/@iptables@ -w -t nat -D/e")~", chain, getIptablesRuleTag()).get(); diff --git i/src/slave/containerizer/mesos/isolators/network/port_mapping.cpp w/src/slave/containerizer/mesos/isolators/network/port_mapping.cpp index 57d4ccd..68c9577 100644 --- i/src/slave/containerizer/mesos/isolators/network/port_mapping.cpp +++ w/src/slave/containerizer/mesos/isolators/network/port_mapping.cpp @@ -1394,19 +1394,19 @@ Try PortMappingIsolatorProcess::create(const Flags& flags) // Check the availability of a few Linux commands that we will use. // We use the blocking os::shell here because 'create' will only be // invoked during initialization. - Try checkCommandTc = os::shell("tc filter show"); + Try checkCommandTc = os::shell("@tc@ filter show"); if (checkCommandTc.isError()) { return Error("Check command 'tc' failed: " + checkCommandTc.error()); } // NOTE: loopback device always exists. - Try checkCommandEthtool = os::shell("ethtool -k lo"); + Try checkCommandEthtool = os::shell("@ethtool@ -k lo"); if (checkCommandEthtool.isError()) { return Error("Check command 'ethtool' failed: " + checkCommandEthtool.error()); } - Try checkCommandIp = os::shell("ip link show"); + Try checkCommandIp = os::shell("@ip@ link show"); if (checkCommandIp.isError()) { return Error("Check command 'ip' failed: " + checkCommandIp.error()); } @@ -1940,9 +1940,9 @@ Try PortMappingIsolatorProcess::create(const Flags& flags) // visible. It's OK to use the blocking os::shell here because // 'create' will only be invoked during initialization. Try mount = os::shell( - "mount --bind %s %s && " - "mount --make-slave %s && " - "mount --make-shared %s", + "@mount@ --bind %s %s && " + "@mount@ --make-slave %s && " + "@mount@ --make-shared %s", bindMountRoot->c_str(), bindMountRoot->c_str(), bindMountRoot->c_str(), @@ -1959,8 +1959,8 @@ Try PortMappingIsolatorProcess::create(const Flags& flags) // shared mount yet (possibly due to slave crash while preparing // the work directory mount). It's safe to re-do the following. Try mount = os::shell( - "mount --make-slave %s && " - "mount --make-shared %s", + "@mount@ --make-slave %s && " + "@mount@ --make-shared %s", bindMountRoot->c_str(), bindMountRoot->c_str()); @@ -1979,8 +1979,8 @@ Try PortMappingIsolatorProcess::create(const Flags& flags) // so that they are in different peer groups. if (entry.shared() == bindMountEntry->shared()) { Try mount = os::shell( - "mount --make-slave %s && " - "mount --make-shared %s", + "@mount@ --make-slave %s && " + "@mount@ --make-shared %s", bindMountRoot->c_str(), bindMountRoot->c_str()); @@ -3927,6 +3927,8 @@ Try PortMappingIsolatorProcess::removeHostIPFilters( // TODO(jieyu): Use the Subcommand abstraction to remove most of the // logic here. Completely remove this function once we can assume a // newer kernel where 'setns' works for mount namespaces. +// cstrahan(nixos): this is executed in the container, +// so we don't want to substitute paths here. string PortMappingIsolatorProcess::scripts(Info* info) { ostringstream script; @@ -3937,7 +3939,7 @@ string PortMappingIsolatorProcess::scripts(Info* info) // Mark the mount point PORT_MAPPING_BIND_MOUNT_ROOT() as slave // mount so that changes in the container will not be propagated to // the host. - script << "mount --make-rslave " << bindMountRoot << "\n"; + script << "@mount@ --make-rslave " << bindMountRoot << "\n"; // Disable IPv6 when IPv6 module is loaded as IPv6 packets won't be // forwarded anyway. @@ -3945,7 +3947,7 @@ string PortMappingIsolatorProcess::scripts(Info* info) << " echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6\n"; // Configure lo and eth0. - script << "ip link set " << lo << " address " << hostMAC + script << "@ip@ link set " << lo << " address " << hostMAC << " mtu " << hostEth0MTU << " up\n"; // NOTE: This is mostly a kernel issue: in veth_xmit() the kernel @@ -3954,12 +3956,12 @@ string PortMappingIsolatorProcess::scripts(Info* info) // when we receive a packet with a bad checksum. Disabling rx // checksum offloading ensures the TCP layer will checksum and drop // it. - script << "ethtool -K " << eth0 << " rx off\n"; - script << "ip link set " << eth0 << " address " << hostMAC << " up\n"; - script << "ip addr add " << hostIPNetwork << " dev " << eth0 << "\n"; + script << "@ethtool@ -K " << eth0 << " rx off\n"; + script << "@ip@ link set " << eth0 << " address " << hostMAC << " up\n"; + script << "@ip@ addr add " << hostIPNetwork << " dev " << eth0 << "\n"; // Set up the default gateway to match that of eth0. - script << "ip route add default via " << hostDefaultGateway << "\n"; + script << "@ip@ route add default via " << hostDefaultGateway << "\n"; // Restrict the ephemeral ports that can be used by the container. script << "echo " << info->ephemeralPorts.lower() << " " @@ -3988,19 +3990,19 @@ string PortMappingIsolatorProcess::scripts(Info* info) } // Set up filters on lo and eth0. - script << "tc qdisc add dev " << lo << " ingress\n"; - script << "tc qdisc add dev " << eth0 << " ingress\n"; + script << "@tc@ qdisc add dev " << lo << " ingress\n"; + script << "@tc@ qdisc add dev " << eth0 << " ingress\n"; // Allow talking between containers and from container to host. // TODO(chzhcn): Consider merging the following two filters. - script << "tc filter add dev " << lo << " parent " << ingress::HANDLE + script << "@tc@ filter add dev " << lo << " parent " << ingress::HANDLE << " protocol ip" << " prio " << Priority(IP_FILTER_PRIORITY, NORMAL).get() << " u32" << " flowid ffff:0" << " match ip dst " << hostIPNetwork.address() << " action mirred egress redirect dev " << eth0 << "\n"; - script << "tc filter add dev " << lo << " parent " << ingress::HANDLE + script << "@tc@ filter add dev " << lo << " parent " << ingress::HANDLE << " protocol ip" << " prio " << Priority(IP_FILTER_PRIORITY, NORMAL).get() << " u32" << " flowid ffff:0" @@ -4011,7 +4013,7 @@ string PortMappingIsolatorProcess::scripts(Info* info) foreach (const PortRange& range, getPortRanges(info->nonEphemeralPorts + info->ephemeralPorts)) { // Local traffic inside a container will not be redirected to eth0. - script << "tc filter add dev " << lo << " parent " << ingress::HANDLE + script << "@tc@ filter add dev " << lo << " parent " << ingress::HANDLE << " protocol ip" << " prio " << Priority(IP_FILTER_PRIORITY, HIGH).get() << " u32" << " flowid ffff:0" @@ -4020,7 +4022,7 @@ string PortMappingIsolatorProcess::scripts(Info* info) // Traffic going to host loopback IP and ports assigned to this // container will be redirected to lo. - script << "tc filter add dev " << eth0 << " parent " << ingress::HANDLE + script << "@tc@ filter add dev " << eth0 << " parent " << ingress::HANDLE << " protocol ip" << " prio " << Priority(IP_FILTER_PRIORITY, NORMAL).get() << " u32" << " flowid ffff:0" @@ -4032,14 +4034,14 @@ string PortMappingIsolatorProcess::scripts(Info* info) } // Do not forward the ICMP packet if the destination IP is self. - script << "tc filter add dev " << lo << " parent " << ingress::HANDLE + script << "@tc@ filter add dev " << lo << " parent " << ingress::HANDLE << " protocol ip" << " prio " << Priority(ICMP_FILTER_PRIORITY, NORMAL).get() << " u32" << " flowid ffff:0" << " match ip protocol 1 0xff" << " match ip dst " << hostIPNetwork.address() << "\n"; - script << "tc filter add dev " << lo << " parent " << ingress::HANDLE + script << "@tc@ filter add dev " << lo << " parent " << ingress::HANDLE << " protocol ip" << " prio " << Priority(ICMP_FILTER_PRIORITY, NORMAL).get() << " u32" << " flowid ffff:0" @@ -4048,9 +4050,9 @@ string PortMappingIsolatorProcess::scripts(Info* info) << net::IP::Network::LOOPBACK_V4().address() << "\n"; // Display the filters created on eth0 and lo. - script << "tc filter show dev " << eth0 + script << "@tc@ filter show dev " << eth0 << " parent " << ingress::HANDLE << "\n"; - script << "tc filter show dev " << lo + script << "@tc@ filter show dev " << lo << " parent " << ingress::HANDLE << "\n"; // If throughput limit for container egress traffic exists, use HTB @@ -4062,9 +4064,9 @@ string PortMappingIsolatorProcess::scripts(Info* info) // throughput. TBF requires other parameters such as 'burst' that // HTB already has default values for. if (egressRateLimitPerContainer.isSome()) { - script << "tc qdisc add dev " << eth0 << " root handle " + script << "@tc@ qdisc add dev " << eth0 << " root handle " << CONTAINER_TX_HTB_HANDLE << " htb default 1\n"; - script << "tc class add dev " << eth0 << " parent " + script << "@tc@ class add dev " << eth0 << " parent " << CONTAINER_TX_HTB_HANDLE << " classid " << CONTAINER_TX_HTB_CLASS_ID << " htb rate " << egressRateLimitPerContainer.get().bytes() * 8 << "bit\n"; @@ -4075,12 +4077,12 @@ string PortMappingIsolatorProcess::scripts(Info* info) // fq_codel, which has a larger buffer and better control on // buffer bloat. // TODO(cwang): Verity that fq_codel qdisc is available. - script << "tc qdisc add dev " << eth0 + script << "@tc@ qdisc add dev " << eth0 << " parent " << CONTAINER_TX_HTB_CLASS_ID << " fq_codel\n"; // Display the htb qdisc and class created on eth0. - script << "tc qdisc show dev " << eth0 << "\n"; - script << "tc class show dev " << eth0 << "\n"; + script << "@tc@ qdisc show dev " << eth0 << "\n"; + script << "@tc@ class show dev " << eth0 << "\n"; } return script.str(); diff --git i/src/slave/containerizer/mesos/isolators/posix/disk.cpp w/src/slave/containerizer/mesos/isolators/posix/disk.cpp index eb23025..db268ea 100644 --- i/src/slave/containerizer/mesos/isolators/posix/disk.cpp +++ w/src/slave/containerizer/mesos/isolators/posix/disk.cpp @@ -572,7 +572,7 @@ private: // NOTE: The supervisor childhook will watch the parent process and kill // the 'du' process in case that the parent die. Try s = subprocess( - "du", + "@du@", command, Subprocess::PATH(os::DEV_NULL), Subprocess::PIPE(), diff --git i/src/slave/containerizer/mesos/isolators/volume/image.cpp w/src/slave/containerizer/mesos/isolators/volume/image.cpp index 35966aa..b62fc86 100644 --- i/src/slave/containerizer/mesos/isolators/volume/image.cpp +++ w/src/slave/containerizer/mesos/isolators/volume/image.cpp @@ -231,7 +231,7 @@ Future> VolumeImageIsolatorProcess::_prepare( CommandInfo* command = launchInfo.add_pre_exec_commands(); command->set_shell(false); - command->set_value("mount"); + command->set_value("@mount@"); command->add_arguments("mount"); command->add_arguments("-n"); command->add_arguments("--rbind"); diff --git i/src/slave/containerizer/mesos/isolators/volume/sandbox_path.cpp w/src/slave/containerizer/mesos/isolators/volume/sandbox_path.cpp index b321b86..8ed3e78 100644 --- i/src/slave/containerizer/mesos/isolators/volume/sandbox_path.cpp +++ w/src/slave/containerizer/mesos/isolators/volume/sandbox_path.cpp @@ -265,7 +265,7 @@ Future> VolumeSandboxPathIsolatorProcess::prepare( CommandInfo* command = launchInfo.add_pre_exec_commands(); command->set_shell(false); - command->set_value("mount"); + command->set_value("@mount@"); command->add_arguments("mount"); command->add_arguments("-n"); command->add_arguments("--rbind"); diff --git i/src/slave/containerizer/mesos/provisioner/backends/copy.cpp w/src/slave/containerizer/mesos/provisioner/backends/copy.cpp index 69faa03..01a3ed6 100644 --- i/src/slave/containerizer/mesos/provisioner/backends/copy.cpp +++ w/src/slave/containerizer/mesos/provisioner/backends/copy.cpp @@ -266,7 +266,7 @@ Future CopyBackendProcess::_provision( #endif // __APPLE__ || __FreeBSD__ Try s = subprocess( - "cp", + "@cp@", args, Subprocess::PATH(os::DEV_NULL), Subprocess::PATH(os::DEV_NULL), @@ -313,7 +313,7 @@ Future CopyBackendProcess::destroy(const string& rootfs) vector argv{"rm", "-rf", rootfs}; Try s = subprocess( - "rm", + "@rm@", argv, Subprocess::PATH(os::DEV_NULL), Subprocess::FD(STDOUT_FILENO), diff --git i/src/uri/fetchers/copy.cpp w/src/uri/fetchers/copy.cpp index 17f69be..831b08a 100644 --- i/src/uri/fetchers/copy.cpp +++ w/src/uri/fetchers/copy.cpp @@ -97,8 +97,8 @@ Future CopyFetcherPlugin::fetch( VLOG(1) << "Copying '" << uri.path() << "' to '" << directory << "'"; #ifndef __WINDOWS__ - const char* copyCommand = "cp"; - const vector argv = {"cp", "-a", uri.path(), directory}; + const char* copyCommand = "@cp@"; + const vector argv = {"@cp@", "-a", uri.path(), directory}; #else // __WINDOWS__ const char* copyCommand = os::Shell::name; const vector argv = diff --git i/src/uri/fetchers/curl.cpp w/src/uri/fetchers/curl.cpp index f34daf2..6a50341 100644 --- i/src/uri/fetchers/curl.cpp +++ w/src/uri/fetchers/curl.cpp @@ -109,7 +109,7 @@ Future CurlFetcherPlugin::fetch( }; Try s = subprocess( - "curl", + "@curl@", argv, Subprocess::PATH(os::DEV_NULL), Subprocess::PIPE(), diff --git i/src/uri/fetchers/docker.cpp w/src/uri/fetchers/docker.cpp index 91db13b..82a7fc4 100644 --- i/src/uri/fetchers/docker.cpp +++ w/src/uri/fetchers/docker.cpp @@ -114,7 +114,7 @@ static Future curl( // TODO(jieyu): Kill the process if discard is called. Try s = subprocess( - "curl", + "@curl@", argv, Subprocess::PATH(os::DEV_NULL), Subprocess::PIPE(), @@ -229,7 +229,7 @@ static Future download( // TODO(jieyu): Kill the process if discard is called. Try s = subprocess( - "curl", + "@curl@", argv, Subprocess::PATH(os::DEV_NULL), Subprocess::PIPE(),