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(
