Repository: mesos
Updated Branches:
  refs/heads/master 74e09a82e -> e878c74fb


http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/slave/containerizer/linux_launcher.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/linux_launcher.cpp 
b/src/slave/containerizer/linux_launcher.cpp
index 1ce03e3..f3cc813 100644
--- a/src/slave/containerizer/linux_launcher.cpp
+++ b/src/slave/containerizer/linux_launcher.cpp
@@ -28,6 +28,7 @@
 #include <stout/abort.hpp>
 #include <stout/hashset.hpp>
 #include <stout/path.hpp>
+#include <stout/strings.hpp>
 
 #include "linux/cgroups.hpp"
 
@@ -57,6 +58,12 @@ LinuxLauncher::LinuxLauncher(
     hierarchy(_hierarchy) {}
 
 
+// An old glibc might not have this symbol.
+#ifndef CLONE_NEWNET
+#define CLONE_NEWNET 0x40000000
+#endif
+
+
 Try<Launcher*> LinuxLauncher::create(const Flags& flags)
 {
   Try<string> hierarchy = cgroups::prepare(
@@ -75,6 +82,15 @@ Try<Launcher*> LinuxLauncher::create(const Flags& flags)
   // to use.
   int namespaces = 0;
 
+#ifdef WITH_NETWORK_ISOLATOR
+  // The network port mapping isolator requires network (CLONE_NEWNET)
+  // and mount (CLONE_NEWNS) namespaces.
+  if (strings::contains(flags.isolation, "network/port_mapping")) {
+    namespaces |= CLONE_NEWNET;
+    namespaces |= CLONE_NEWNS;
+  }
+#endif
+
   return new LinuxLauncher(flags, namespaces, hierarchy.get());
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp 
b/src/slave/containerizer/mesos/containerizer.cpp
index 2fd121f..2c394e2 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -40,6 +40,9 @@
 #include "slave/containerizer/isolators/cgroups/mem.hpp"
 #include "slave/containerizer/isolators/cgroups/perf_event.hpp"
 #endif // __linux__
+#ifdef WITH_NETWORK_ISOLATOR
+#include "slave/containerizer/isolators/network/port_mapping.hpp"
+#endif
 
 #include "slave/containerizer/mesos/containerizer.hpp"
 #include "slave/containerizer/mesos/launch.hpp"
@@ -130,6 +133,9 @@ Try<MesosContainerizer*> MesosContainerizer::create(
   creators["cgroups/mem"] = &CgroupsMemIsolatorProcess::create;
   creators["cgroups/perf_event"] = &CgroupsPerfEventIsolatorProcess::create;
 #endif // __linux__
+#ifdef WITH_NETWORK_ISOLATOR
+  creators["network/port_mapping"] = &PortMappingIsolatorProcess::create;
+#endif
 
   vector<Owned<Isolator> > isolators;
 
@@ -148,8 +154,10 @@ Try<MesosContainerizer*> MesosContainerizer::create(
   }
 
 #ifdef __linux__
-  // Use cgroups on Linux if any cgroups isolators are used.
-  Try<Launcher*> launcher = strings::contains(isolation, "cgroups")
+  // Determine which launcher to use based on the isolation flag.
+  Try<Launcher*> launcher =
+    (strings::contains(isolation, "cgroups") ||
+     strings::contains(isolation, "network/port_mapping"))
     ? LinuxLauncher::create(flags)
     : PosixLauncher::create(flags);
 #else

http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/slave/flags.hpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.hpp b/src/slave/flags.hpp
index 3b8ba08..c6a970f 100644
--- a/src/slave/flags.hpp
+++ b/src/slave/flags.hpp
@@ -56,8 +56,10 @@ public:
 
     add(&Flags::isolation,
         "isolation",
-        "Isolation mechanisms to use, e.g., 'posix/cpu,posix/mem'\n"
-        "or 'cgroups/cpu,cgroups/mem' or 'external'.",
+        "Isolation mechanisms to use, e.g., 'posix/cpu,posix/mem', or\n"
+        "'cgroups/cpu,cgroups/mem', or network/port_mapping\n"
+        "(configure with flag: --with-network-isolator to enable),\n"
+        "or 'external'.",
         "posix/cpu,posix/mem");
 
     add(&Flags::default_role,
@@ -254,6 +256,34 @@ public:
         "default_container_image",
         "The default container image to use if not specified by a task,\n"
         "when using external containerizer");
+
+#ifdef WITH_NETWORK_ISOLATOR
+    add(&Flags::ephemeral_ports_per_container,
+        "ephemeral_ports_per_container",
+        "Number of ephemeral ports allocated to a container by the network\n"
+        "isolator. This number has to be a power of 2.\n",
+        DEFAULT_EPHEMERAL_PORTS_PER_CONTAINER);
+
+    add(&Flags::private_resources,
+        "private_resources",
+        "The resources that will be manged by the slave locally, and not\n"
+        "exposed to Mesos master and frameworks. It shares the same format\n"
+        "as the 'resources' flag. One example of such type of resources\n"
+        "is ephemeral ports when port mapping network isolator is enabled.\n"
+        "Use 'ports:[x-y]' to specify the ephemeral ports that will be\n"
+        "locally managed.\n");
+
+    add(&Flags::eth0_name,
+        "eth0_name",
+        "The name of the public network interface (e.g., eth0). If it is\n"
+        "not specified, the network isolator will try to guess it based\n"
+        "on the host default gateway.");
+
+    add(&Flags::lo_name,
+        "lo_name",
+        "The name of the loopback network interface (e.g., lo). If it is\n"
+        "not specified, the network isolator will try to guess it.");
+#endif // WITH_NETWORK_ISOLATOR
   }
 
   bool version;
@@ -291,6 +321,12 @@ public:
   Option<std::string> credential;
   Option<std::string> containerizer_path;
   Option<std::string> default_container_image;
+#ifdef WITH_NETWORK_ISOLATOR
+  uint16_t ephemeral_ports_per_container;
+  Option<std::string> private_resources;
+  Option<std::string> eth0_name;
+  Option<std::string> lo_name;
+#endif
 };
 
 } // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index 0cb98cd..24eb8fd 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -274,11 +274,24 @@ void Slave::initialize()
   CHECK_SOME(os::mkdir(flags.work_dir))
     << "Failed to create slave work directory '" << flags.work_dir << "'";
 
-  Try<Resources> _resources = Containerizer::resources(flags);
-  if (_resources.isError()) {
-    EXIT(1) << "Failed to determine slave resources: " << _resources.error();
+  Try<Resources> resources = Containerizer::resources(flags);
+  if (resources.isError()) {
+    EXIT(1) << "Failed to determine slave resources: " << resources.error();
   }
-  LOG(INFO) << "Slave resources: " << _resources.get();
+  LOG(INFO) << "Slave resources: " << resources.get();
+
+#ifdef WITH_NETWORK_ISOLATOR
+  // Resources that are not exposed to the frameworks, but managed by
+  // the slave privately.
+  Try<Resources> privateResources = Resources::parse(
+      flags.private_resources.get(""), flags.default_role);
+
+  if (privateResources.isError()) {
+    EXIT(1) << "Failed to determine slave private resources: "
+            << privateResources.error();
+  }
+  LOG(INFO) << "Slave private resources: " << privateResources.get();
+#endif
 
   if (flags.attributes.isSome()) {
     attributes = Attributes::parse(flags.attributes.get());
@@ -302,10 +315,14 @@ void Slave::initialize()
   // Initialize slave info.
   info.set_hostname(hostname);
   info.set_port(self().port);
-  info.mutable_resources()->CopyFrom(_resources.get());
+  info.mutable_resources()->CopyFrom(resources.get());
   info.mutable_attributes()->CopyFrom(attributes);
   info.set_checkpoint(flags.checkpoint);
 
+#ifdef WITH_NETWORK_ISOLATOR
+  info.mutable_private_resources()->CopyFrom(privateResources.get());
+#endif
+
   LOG(INFO) << "Slave hostname: " << info.hostname();
   LOG(INFO) << "Slave checkpoint: " << stringify(flags.checkpoint);
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/tests/environment.cpp
----------------------------------------------------------------------
diff --git a/src/tests/environment.cpp b/src/tests/environment.cpp
index e991d57..4aaf1a4 100644
--- a/src/tests/environment.cpp
+++ b/src/tests/environment.cpp
@@ -144,6 +144,14 @@ static bool enable(const ::testing::TestInfo& test)
     }
   }
 
+#ifdef WITH_NETWORK_ISOLATOR
+  // Currently, the network isolator does not support multiple slaves.
+  if (strings::contains(test.name(), "MultipleSlaves") &&
+      os::user().isSome() && os::user().get() == "root") {
+    return false;
+  }
+#endif
+
   return true;
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/tests/isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/isolator_tests.cpp b/src/tests/isolator_tests.cpp
index 5a141e3..6fef4e0 100644
--- a/src/tests/isolator_tests.cpp
+++ b/src/tests/isolator_tests.cpp
@@ -56,6 +56,7 @@
 #include "tests/utils.hpp"
 
 using namespace mesos;
+
 using namespace mesos::internal;
 using namespace mesos::internal::tests;
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/tests/mesos.cpp
----------------------------------------------------------------------
diff --git a/src/tests/mesos.cpp b/src/tests/mesos.cpp
index 216bd6f..6550673 100644
--- a/src/tests/mesos.cpp
+++ b/src/tests/mesos.cpp
@@ -33,6 +33,7 @@
 #include "linux/cgroups.hpp"
 #endif
 
+#include "slave/constants.hpp"
 #include "slave/containerizer/containerizer.hpp"
 
 #include "slave/containerizer/mesos/containerizer.hpp"
@@ -328,6 +329,13 @@ slave::Flags 
ContainerizerTest<slave::MesosContainerizer>::CreateSlaveFlags()
   flags.isolation = "posix/cpu,posix/mem";
 #endif
 
+#ifdef WITH_NETWORK_ISOLATOR
+  if (user.get() == "root") {
+    flags.isolation += ",network/port_mapping";
+    flags.private_resources = "ports:" + slave::DEFAULT_EPHEMERAL_PORTS;
+  }
+#endif
+
   return flags;
 }
 

Reply via email to