This is an automated email from the ASF dual-hosted git repository.

bennoe pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 8a9eb868ff3979df1cb68ebf56cb451b411e06a9
Author: Benno Evers <[email protected]>
AuthorDate: Thu Jan 9 15:48:48 2020 +0100

    Added systemd support to domain socket agent flag.
    
    Added the ability to specify a unix domain socket
    as `systemd:<identifier>` for the `--domain_socket_location`
    agent flag.
    
    This will instruct the agent to expect the domain socket
    being passed by systemd with the specified name.
    
    Review: https://reviews.apache.org/r/71977
---
 src/slave/flags.cpp | 10 +++++----
 src/slave/main.cpp  | 62 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 63 insertions(+), 9 deletions(-)

diff --git a/src/slave/flags.cpp b/src/slave/flags.cpp
index 8c6c2ce..7653c39 100644
--- a/src/slave/flags.cpp
+++ b/src/slave/flags.cpp
@@ -988,10 +988,12 @@ mesos::internal::slave::Flags::Flags()
   add(&Flags::domain_socket_location,
       "domain_socket_location",
       "Location on the host filesystem of the domain socket used for\n"
-      "communication with executors.\n This flag will be ignored unless\n"
-      "the '--http_executor_domain_sockets' flag is also set to true.\n"
-      "Total path length must be less than 108 characters.\n"
-      "Will be set to <runtime_dir>/agent.sock by default.",
+      "communication with executors.\n Alternatively, this can be set to"
+      "'systemd:<identifier>' to use the domain socket with the given\n"
+      "identifier, which is expected to be passed by systemd.\n"
+      "This flag will be ignored unless the '--http_executor_domain_sockets'\n"
+      "flag is also set to true. Total path length must be less than 108\n"
+      "characters.\n Will be set to <runtime_dir>/agent.sock by default.",
       [](const Option<string>& location) -> Option<Error> {
         if (location.isSome() &&
             location->size() >= common::DOMAIN_SOCKET_MAX_PATH_LENGTH) {
diff --git a/src/slave/main.cpp b/src/slave/main.cpp
index 7bce6d2..9e40743 100644
--- a/src/slave/main.cpp
+++ b/src/slave/main.cpp
@@ -33,6 +33,7 @@
 
 #include <mesos/slave/resource_estimator.hpp>
 
+#include <process/network.hpp>
 #include <process/owned.hpp>
 #include <process/process.hpp>
 
@@ -41,10 +42,13 @@
 #include <stout/hashset.hpp>
 #include <stout/nothing.hpp>
 #include <stout/os.hpp>
+#include <stout/strings.hpp>
 
 #include <stout/os/permissions.hpp>
 
 #ifdef __linux__
+#include <linux/systemd.hpp>
+
 #include <stout/proc.hpp>
 #endif // __linux__
 
@@ -632,16 +636,64 @@ int main(int argc, char** argv)
     // been set by the user or automatically during startup.
     CHECK_SOME(flags.domain_socket_location);
 
-    LOG(INFO) << "Creating domain socket at " << *flags.domain_socket_location;
-    Try<Socket> socket =
-      common::createDomainSocket(*flags.domain_socket_location);
+    if (strings::startsWith(*flags.domain_socket_location, "systemd:")) {
+      LOG(INFO) << "Expecting domain socket to be passed by systemd";
 
-    if (socket.isError()) {
+      // Chop off `systemd:` prefix.
+      std::string name = flags.domain_socket_location->substr(8);
+#ifdef __linux__
+      Try<std::vector<int>> socketFds =
+        systemd::socket_activation::listenFdsWithName(name);
+#else
+      Try<std::vector<int>> socketFds; // Dummy to avoid compile errors.
       EXIT(EXIT_FAILURE)
+        << "Systemd socket passing is only supported on linux.";
+#endif
+
+      if (socketFds.isError()) {
+        EXIT(EXIT_FAILURE)
+          << "Could not get passed file descriptors from systemd: "
+          << socketFds.error();
+      }
+
+      if (socketFds->size() != 1u) {
+        EXIT(EXIT_FAILURE)
+          << "Expected exactly one socket with name " << name
+          << ", got " << socketFds->size() << " instead.";
+      }
+
+      int sockfd = socketFds->at(0);
+
+      // Don't use SSLSocketImpl for unix domain sockets.
+      Try<Socket> socket = Socket::create(
+          sockfd, process::network::internal::SocketImpl::Kind::POLL);
+
+      if (socket.isError()) {
+        EXIT(EXIT_FAILURE)
           << "Failed to create domain socket: " << socket.error();
+      }
+
+      executorSocket = socket.get();
+
+      // Adjust socket location to point to the *path*, not the systemd
+      // identifier.
+      auto addr = process::network::convert<process::network::unix::Address>(
+          process::network::address(sockfd).get()).get();
+
+      flags.domain_socket_location = addr.path();
+    } else {
+      Try<Socket> socket =
+        common::createDomainSocket(*flags.domain_socket_location);
+
+      if (socket.isError()) {
+        EXIT(EXIT_FAILURE)
+          << "Failed to create domain socket: " << socket.error();
+      }
+
+      executorSocket = socket.get();
     }
 
-    executorSocket = socket.get();
+    LOG(INFO) << "Using domain socket at " << *flags.domain_socket_location;
   }
 
   Slave* slave = new Slave(

Reply via email to