···
+
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:
// Execute the command (via '/bin/sh -c command').
···
<< "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<std::set<pid_t>> pids(Option<pid_t> group, Option<pid_t> session)
inline Try<Nothing> tar(const std::string& path, const std::string& archive)
Try<std::string> tarOut =
···
return Error("Failed to archive " + path + ": " + tarOut.error());
+
diff --git i/src/Makefile.am w/src/Makefile.am
+
index 68fff14..c572f92 100644
+
@@ -1775,7 +1775,7 @@ if HAS_JAVA
$(MESOS_JAR): $(MESOS_JAR_SOURCE) $(MESOS_JAR_GENERATED) java/mesos.pom
@echo "Building mesos-$(PACKAGE_VERSION).jar ..."
···
# 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):
···
process = subprocess.Popen(
+
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<Nothing> tar(
argv.emplace_back(input);
···
.then([]() { return Nothing(); });
+
@@ -164,7 +164,7 @@ Future<Nothing> untar(
argv.emplace_back(directory.get());
···
.then([]() { return Nothing(); });
+
@@ -172,7 +172,7 @@ Future<Nothing> untar(
Future<string> sha512(const Path& input)
···
input // Input file to compute shasum.
+
@@ -208,7 +208,7 @@ Future<Nothing> gzip(const Path& input)
···
.then([]() { return Nothing(); });
+
@@ -221,7 +221,7 @@ Future<Nothing> decompress(const Path& input)
···
.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<bool> 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};
+
@@ -193,7 +193,7 @@ static Try<string> copyFile(
const string& sourcePath,
const string& destinationPath)
+
- int status = os::spawn("cp", {"cp", sourcePath, destinationPath});
+
+ int status = os::spawn("cp", {"@cp@", sourcePath, destinationPath});
+
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<Subprocess> _perf = subprocess(
···
+
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 {
···
Try<string> 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):
···
+
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<Option<ContainerLaunchInfo>> DockerVolumeIsolatorProcess::_prepare(
// unsafe arbitrary commands).
CommandInfo* command = launchInfo.add_pre_exec_commands();
···
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<Isolator*> LinuxFilesystemIsolatorProcess::create(const Flags& flags)
// here because 'create' will only be invoked during
Try<string> mount = os::shell(
···
+
@@ -175,8 +175,8 @@ Try<Isolator*> LinuxFilesystemIsolatorProcess::create(const Flags& flags)
LOG(INFO) << "Making '" << workDir.get() << "' a shared mount";
Try<string> mount = os::shell(
···
+
@@ -422,7 +422,7 @@ Try<vector<CommandInfo>> LinuxFilesystemIsolatorProcess::getPreExecCommands(
command.set_shell(false);
···
command.add_arguments("mount");
command.add_arguments("-n");
command.add_arguments("--rbind");
+
@@ -610,7 +610,7 @@ Try<vector<CommandInfo>> LinuxFilesystemIsolatorProcess::getPreExecCommands(
// TODO(jieyu): Consider the mode in the volume.
command.set_shell(false);
···
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<Option<ContainerLaunchInfo>> SharedFilesystemIsolatorProcess::prepare(
launchInfo.add_pre_exec_commands()->set_value(
···
+
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<Option<ContainerLaunchInfo>> NvidiaGpuIsolatorProcess::_prepare(
launchInfo.add_pre_exec_commands()->set_value(
···
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> NvidiaVolume::create()
string path = path::join(hostPath, "bin", binary);
···
Try<string> which = os::shell(command);
+
@@ -288,7 +288,7 @@ Try<NvidiaVolume> NvidiaVolume::create()
: "No such file or directory"));
···
Try<string> cp = os::shell(command);
return Error("Failed to os::shell '" + command + "': " + cp.error());
+
@@ -360,7 +360,7 @@ Try<NvidiaVolume> NvidiaVolume::create()
Path(realpath.get()).basename());
if (!os::exists(libraryPath)) {
···
Try<string> cp = os::shell(command);
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<Option<ContainerLaunchInfo>> NamespacesPidIsolatorProcess::prepare(
// TOOD(jieyu): Consider unmount the existing /proc.
launchInfo.add_pre_exec_commands()->set_value(
···
+
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<Isolator*> NetworkCniIsolatorProcess::create(const Flags& flags)
// here because 'create' will only be invoked during
Try<string> mount = os::shell(
···
+
@@ -227,8 +227,8 @@ Try<Isolator*> NetworkCniIsolatorProcess::create(const Flags& flags)
LOG(INFO) << "Making '" << rootDir.get() << "' a shared mount";
Try<string> mount = os::shell(
···
+
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<Nothing> 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
···
# 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<Nothing> 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
···
+
@@ -360,7 +360,7 @@ Try<Nothing> PortMapper::delPortMapping()
# The iptables command searches for the DNAT rules with tag
# "container_id: <CNI_CONTAINERID>", and if it exists goes ahead
···
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<Isolator*> 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.
···
if (checkCommandIp.isError()) {
return Error("Check command 'ip' failed: " + checkCommandIp.error());
+
@@ -1940,9 +1940,9 @@ Try<Isolator*> 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<string> mount = os::shell(
···
+
@@ -1959,8 +1959,8 @@ Try<Isolator*> 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<string> mount = os::shell(
···
+
@@ -1979,8 +1979,8 @@ Try<Isolator*> PortMappingIsolatorProcess::create(const Flags& flags)
// so that they are in different peer groups.
if (entry.shared() == bindMountEntry->shared()) {
Try<string> mount = os::shell(
···
+
@@ -3927,6 +3927,8 @@ Try<Nothing> 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.
···
string PortMappingIsolatorProcess::scripts(Info* info)
+
@@ -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
···
// Disable IPv6 when IPv6 module is loaded as IPv6 packets won't be
+
@@ -3945,7 +3947,7 @@ string PortMappingIsolatorProcess::scripts(Info* info)
<< " echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6\n";
// Configure lo and eth0.
···
<< " 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
···
// 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.
···
<< " prio " << Priority(IP_FILTER_PRIORITY, NORMAL).get() << " u32"
+
@@ -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.
···
<< " prio " << Priority(IP_FILTER_PRIORITY, HIGH).get() << " u32"
+
@@ -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.
···
<< " prio " << Priority(IP_FILTER_PRIORITY, NORMAL).get() << " u32"
+
@@ -4032,14 +4034,14 @@ string PortMappingIsolatorProcess::scripts(Info* info)
// Do not forward the ICMP packet if the destination IP is self.
···
<< " prio " << Priority(ICMP_FILTER_PRIORITY, NORMAL).get() << " u32"
+
@@ -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
···
<< " 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()) {
···
<< 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
// TODO(cwang): Verity that fq_codel qdisc is available.
···
+
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<Subprocess> s = subprocess(
+
Subprocess::PATH(os::DEV_NULL),
+
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<Option<ContainerLaunchInfo>> VolumeImageIsolatorProcess::_prepare(
CommandInfo* command = launchInfo.add_pre_exec_commands();
command->set_shell(false);
···
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<Option<ContainerLaunchInfo>> VolumeSandboxPathIsolatorProcess::prepare(
CommandInfo* command = launchInfo.add_pre_exec_commands();
command->set_shell(false);
···
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<Nothing> CopyBackendProcess::_provision(
#endif // __APPLE__ || __FreeBSD__
Try<Subprocess> s = subprocess(
+
Subprocess::PATH(os::DEV_NULL),
+
Subprocess::PATH(os::DEV_NULL),
+
@@ -313,7 +313,7 @@ Future<bool> CopyBackendProcess::destroy(const string& rootfs)
vector<string> argv{"rm", "-rf", rootfs};
Try<Subprocess> s = subprocess(
+
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<Nothing> CopyFetcherPlugin::fetch(
+
VLOG(1) << "Copying '" << uri.path() << "' to '" << directory << "'";
+
- const char* copyCommand = "cp";
+
- const vector<string> argv = {"cp", "-a", uri.path(), directory};
+
+ const char* copyCommand = "@cp@";
+
+ const vector<string> argv = {"@cp@", "-a", uri.path(), directory};
+
const char* copyCommand = os::Shell::name;
+
const vector<string> 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<Nothing> CurlFetcherPlugin::fetch(
Try<Subprocess> s = subprocess(
+
Subprocess::PATH(os::DEV_NULL),
+
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<http::Response> curl(
// TODO(jieyu): Kill the process if discard is called.
···
+
Subprocess::PATH(os::DEV_NULL),
+
@@ -229,7 +229,7 @@ static Future<int> download(
// TODO(jieyu): Kill the process if discard is called.
Try<Subprocess> s = subprocess(
+
Subprocess::PATH(os::DEV_NULL),