This is an automated email from the ASF dual-hosted git repository.
jpeach pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git
The following commit(s) were added to refs/heads/master by this push:
new 4708c2a Added filesystem operations to the `ContainerLaunchInfo`
message.
4708c2a is described below
commit 4708c2a368e12a89669135f47777d0dd05d9b0b2
Author: James Peach <[email protected]>
AuthorDate: Mon May 27 16:44:58 2019 -0700
Added filesystem operations to the `ContainerLaunchInfo` message.
The `filesystem/linux` isolator was using pre-exec commands
to set up Linux ABI symlinks, which is inefficient since it
ends spawning `ln(1)` a number of times. The fix adds a new
`ContainerFileOperation` message to the containerizer launch
information. The containerizer executes the requested file
operation after performing the container mounts.
Review: https://reviews.apache.org/r/70712/
---
include/mesos/slave/containerizer.proto | 29 +++++++++++++++++++++-
src/common/protobuf_utils.cpp | 15 +++++++++++
src/common/protobuf_utils.hpp | 5 ++++
.../mesos/isolators/cgroups/cgroups.cpp | 20 ++++++---------
.../mesos/isolators/filesystem/linux.cpp | 10 +++-----
src/slave/containerizer/mesos/launch.cpp | 28 +++++++++++++++++++++
6 files changed, 87 insertions(+), 20 deletions(-)
diff --git a/include/mesos/slave/containerizer.proto
b/include/mesos/slave/containerizer.proto
index e992448..b2e35cb 100644
--- a/include/mesos/slave/containerizer.proto
+++ b/include/mesos/slave/containerizer.proto
@@ -193,6 +193,29 @@ message ContainerMountInfo {
/**
+ * Describes a file operation to be applied to the container at
+ * launch time.
+ */
+message ContainerFileOperation {
+ enum Operation {
+ // Create a symlink that points to `source` at `target`.
+ SYMLINK = 1;
+ };
+
+ message Symlink {
+ optional string source = 1;
+ optional string target = 2;
+ }
+
+ optional Operation operation = 1;
+
+ oneof parameters {
+ Symlink symlink = 2;
+ }
+}
+
+
+/**
* Protobuf returned by Isolator::prepare(). The command is executed
* by the Launcher in the containerized context.
* Note: Currently, any URIs or Environment in the CommandInfo will be
@@ -202,7 +225,7 @@ message ContainerMountInfo {
message ContainerLaunchInfo {
// The additional preparation commands to execute before
// executing the command.
- repeated CommandInfo pre_exec_commands = 1;
+ repeated CommandInfo pre_exec_commands = 1 [deprecated=true];
// The environment set for the container.
optional Environment environment = 2;
@@ -248,6 +271,10 @@ message ContainerLaunchInfo {
// Paths are masked after all other mounts are made.
repeated string masked_paths = 21;
+ // The list of filesystem operations to perform after the container
+ // mounts, but before launching the container process.
+ repeated ContainerFileOperation file_operations = 22;
+
// (Linux only) The Seccomp profile for the container.
// The profile is used to configure syscall filtering via `libseccomp`.
optional seccomp.ContainerSeccompProfile seccomp_profile = 18;
diff --git a/src/common/protobuf_utils.cpp b/src/common/protobuf_utils.cpp
index 8b252cb..870859d 100644
--- a/src/common/protobuf_utils.cpp
+++ b/src/common/protobuf_utils.cpp
@@ -66,6 +66,7 @@ using google::protobuf::RepeatedPtrField;
using mesos::authorization::VIEW_ROLE;
+using mesos::slave::ContainerFileOperation;
using mesos::slave::ContainerLimitation;
using mesos::slave::ContainerMountInfo;
using mesos::slave::ContainerState;
@@ -1241,6 +1242,20 @@ ContainerMountInfo createContainerMount(
return mnt;
}
+
+mesos::slave::ContainerFileOperation containerSymlinkOperation(
+ const std::string& source,
+ const std::string& target)
+{
+ ContainerFileOperation op;
+
+ op.set_operation(ContainerFileOperation::SYMLINK);
+ op.mutable_symlink()->set_source(source);
+ op.mutable_symlink()->set_target(target);
+
+ return op;
+}
+
} // namespace slave {
namespace maintenance {
diff --git a/src/common/protobuf_utils.hpp b/src/common/protobuf_utils.hpp
index 273ae27..8aa9aff 100644
--- a/src/common/protobuf_utils.hpp
+++ b/src/common/protobuf_utils.hpp
@@ -414,6 +414,11 @@ mesos::slave::ContainerMountInfo createContainerMount(
const std::string& options,
unsigned long flags);
+
+mesos::slave::ContainerFileOperation containerSymlinkOperation(
+ const std::string& source,
+ const std::string& target);
+
} // namespace slave {
namespace maintenance {
diff --git a/src/slave/containerizer/mesos/isolators/cgroups/cgroups.cpp
b/src/slave/containerizer/mesos/isolators/cgroups/cgroups.cpp
index 8f94453..e7819d7 100644
--- a/src/slave/containerizer/mesos/isolators/cgroups/cgroups.cpp
+++ b/src/slave/containerizer/mesos/isolators/cgroups/cgroups.cpp
@@ -42,6 +42,8 @@
#include "slave/containerizer/mesos/isolators/cgroups/cgroups.hpp"
#include "slave/containerizer/mesos/isolators/cgroups/constants.hpp"
+using mesos::internal::protobuf::slave::containerSymlinkOperation;
+
using mesos::slave::ContainerConfig;
using mesos::slave::ContainerLaunchInfo;
using mesos::slave::ContainerLimitation;
@@ -565,18 +567,12 @@ Future<Option<ContainerLaunchInfo>>
CgroupsIsolatorProcess::__prepare(
foreach (const string& hierarchy, subsystems.keys()) {
if (subsystems.get(hierarchy).size() > 1) {
foreach (const Owned<Subsystem>& subsystem, subsystems.get(hierarchy)) {
- CommandInfo* command = launchInfo.add_pre_exec_commands();
- command->set_shell(false);
- command->set_value("ln");
- command->add_arguments("ln");
- command->add_arguments("-s");
- command->add_arguments(
- path::join("/sys/fs/cgroup", Path(hierarchy).basename()));
-
- command->add_arguments(path::join(
- containerConfig.rootfs(),
- "/sys/fs/cgroup",
- subsystem->name()));
+ *launchInfo.add_file_operations() = containerSymlinkOperation(
+ path::join("/sys/fs/cgroup", Path(hierarchy).basename()),
+ path::join(
+ containerConfig.rootfs(),
+ "/sys/fs/cgroup",
+ subsystem->name()));
}
}
}
diff --git a/src/slave/containerizer/mesos/isolators/filesystem/linux.cpp
b/src/slave/containerizer/mesos/isolators/filesystem/linux.cpp
index 190054c..3cfb6e9 100644
--- a/src/slave/containerizer/mesos/isolators/filesystem/linux.cpp
+++ b/src/slave/containerizer/mesos/isolators/filesystem/linux.cpp
@@ -61,6 +61,7 @@ using std::string;
using std::vector;
using mesos::internal::protobuf::slave::createContainerMount;
+using mesos::internal::protobuf::slave::containerSymlinkOperation;
using mesos::slave::ContainerClass;
using mesos::slave::ContainerConfig;
@@ -213,13 +214,8 @@ static Try<Nothing> makeStandardDevices(
};
foreach (const auto& symlink, symlinks) {
- CommandInfo* ln = launchInfo.add_pre_exec_commands();
- ln->set_shell(false);
- ln->set_value("ln");
- ln->add_arguments("ln");
- ln->add_arguments("-s");
- ln->add_arguments(symlink.first);
- ln->add_arguments(symlink.second);
+ *launchInfo.add_file_operations() =
+ containerSymlinkOperation(symlink.first, symlink.second);
}
// TODO(idownes): Set up console device.
diff --git a/src/slave/containerizer/mesos/launch.cpp
b/src/slave/containerizer/mesos/launch.cpp
index 5ddb4c7..0c482f4 100644
--- a/src/slave/containerizer/mesos/launch.cpp
+++ b/src/slave/containerizer/mesos/launch.cpp
@@ -33,6 +33,7 @@
#include <stout/adaptor.hpp>
#include <stout/foreach.hpp>
+#include <stout/fs.hpp>
#include <stout/option.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
@@ -94,6 +95,7 @@ using mesos::internal::capabilities::ProcessCapabilities;
using mesos::internal::seccomp::SeccompFilter;
#endif
+using mesos::slave::ContainerFileOperation;
using mesos::slave::ContainerLaunchInfo;
using mesos::slave::ContainerMountInfo;
@@ -472,6 +474,25 @@ static Try<Nothing> maskPath(const string& target)
}
+static Try<Nothing> executeFileOperation(const ContainerFileOperation& op)
+{
+ Try<Nothing> result = Nothing();
+
+ switch (op.operation()) {
+ case ContainerFileOperation::SYMLINK:
+ result = ::fs::symlink(op.symlink().source(), op.symlink().target());
+ if (result.isError()) {
+ return Error(
+ "Failed to link '" + op.symlink().source() + "' as '" +
+ op.symlink().target() + "': " + result.error());
+ }
+ break;
+ }
+
+ return result;
+}
+
+
static Try<Nothing> installResourceLimits(const RLimitInfo& limits)
{
#ifdef __WINDOWS__
@@ -768,6 +789,13 @@ int MesosContainerizerLaunch::execute()
mount = maskPath(target);
if (mount.isError()) {
cerr << "Failed to mask container paths: " << mount.error() << endl;
+ }
+ }
+
+ foreach (const ContainerFileOperation& op, launchInfo.file_operations()) {
+ Try<Nothing> result = executeFileOperation(op);
+ if (result.isError()) {
+ cerr << result.error() << endl;
exitWithStatus(EXIT_FAILURE);
}
}