You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2017/12/20 03:41:45 UTC
[1/2] mesos git commit: Moved files related to volume profiles into
`resource_provider/storage`.
Repository: mesos
Updated Branches:
refs/heads/master a3febec7e -> 5f40f3d40
Moved files related to volume profiles into `resource_provider/storage`.
Review: https://reviews.apache.org/r/64727/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/835d2a2c
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/835d2a2c
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/835d2a2c
Branch: refs/heads/master
Commit: 835d2a2c483c72c389c5d38edefd05584af73e0f
Parents: a3febec
Author: Chun-Hung Hsiao <ch...@mesosphere.io>
Authored: Tue Dec 19 19:21:07 2017 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Tue Dec 19 19:35:18 2017 -0800
----------------------------------------------------------------------
include/mesos/module/volume_profile.hpp | 2 +-
.../storage/volume_profile.hpp | 144 +++++++++
.../mesos/resource_provider/volume_profile.hpp | 144 ---------
src/Makefile.am | 22 +-
src/resource_provider/storage/provider.cpp | 2 +-
.../storage/uri_volume_profile.cpp | 321 +++++++++++++++++++
.../storage/uri_volume_profile.hpp | 248 ++++++++++++++
.../storage/volume_profile.cpp | 131 ++++++++
.../storage/volume_profile.proto | 43 +++
.../storage/volume_profile_utils.cpp | 121 +++++++
.../storage/volume_profile_utils.hpp | 48 +++
src/resource_provider/uri_volume_profile.cpp | 321 -------------------
src/resource_provider/uri_volume_profile.hpp | 248 --------------
src/resource_provider/volume_profile.cpp | 131 --------
src/resource_provider/volume_profile.proto | 43 ---
src/resource_provider/volume_profile_utils.cpp | 121 -------
src/resource_provider/volume_profile_utils.hpp | 48 ---
src/slave/slave.cpp | 2 +-
src/tests/volume_profile_tests.cpp | 6 +-
19 files changed, 1073 insertions(+), 1073 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/include/mesos/module/volume_profile.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/module/volume_profile.hpp b/include/mesos/module/volume_profile.hpp
index 0c6cb95..bb95b32 100644
--- a/include/mesos/module/volume_profile.hpp
+++ b/include/mesos/module/volume_profile.hpp
@@ -20,7 +20,7 @@
#include <mesos/mesos.hpp>
#include <mesos/module.hpp>
-#include <mesos/resource_provider/volume_profile.hpp>
+#include <mesos/resource_provider/storage/volume_profile.hpp>
namespace mesos {
namespace modules {
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/include/mesos/resource_provider/storage/volume_profile.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/resource_provider/storage/volume_profile.hpp b/include/mesos/resource_provider/storage/volume_profile.hpp
new file mode 100644
index 0000000..7141a14
--- /dev/null
+++ b/include/mesos/resource_provider/storage/volume_profile.hpp
@@ -0,0 +1,144 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef __MESOS_RESOURCE_PROVIDER_VOLUME_PROFILE_HPP__
+#define __MESOS_RESOURCE_PROVIDER_VOLUME_PROFILE_HPP__
+
+#include <memory>
+#include <string>
+#include <tuple>
+
+#include <process/future.hpp>
+
+#include <stout/hashset.hpp>
+#include <stout/none.hpp>
+#include <stout/nothing.hpp>
+
+#include <csi/spec.hpp>
+
+namespace mesos {
+
+/**
+ * This module is used by Storage Resource Providers to translate the
+ * "profile" field of a `Resource::DiskInfo::Source` into fields that a
+ * Container Storage Interface (CSI) plugin can potentially
+ * understand. This affects the following CSI requests:
+ * * ControllerPublishVolumeRequest
+ * * CreateVolumeRequest
+ * * GetCapacityRequest
+ * * NodePublishVolumeRequest
+ * * ValidateVolumeCapabilitiesRequest
+ *
+ * This module is not intended to interact with any CSI plugins directly.
+ *
+ * Documentation for each of the CSI requests can be found at:
+ * https://github.com/container-storage-interface/spec/
+ */
+class VolumeProfileAdaptor
+{
+public:
+ struct ProfileInfo
+ {
+ /**
+ * Corresponds to the `volume_capability` or `volume_capabilities`
+ * fields of the affected CSI requests listed in the module description.
+ *
+ * NOTE: Some CSI requests take a list of `VolumeCapability` objects.
+ * However, because there is no existing way to choose between a list
+ * of `VolumeCapability` objects, the module will only allow a single
+ * `VolumeCapability`.
+ */
+ csi::VolumeCapability capability;
+
+ /**
+ * Free-form key-value pairs which should be passed into the body
+ * of a `CreateVolumeRequest`. Neither Mesos nor this module is expected
+ * to act upon these values (except copying them into the request).
+ */
+ google::protobuf::Map<std::string, std::string> parameters;
+ };
+
+ /**
+ * Factory method used to create a VolumeProfileAdaptor instance.
+ * If the `name` parameter is provided, the module is instantiated
+ * using the `ModuleManager`. Otherwise, a "default" volume profile
+ * adaptor instance (defined in `src/resource_provider/volume_profile.cpp`)
+ * is returned.
+ *
+ * NOTE: The lifecycle of the returned object is delegated to the caller.
+ */
+ static Try<VolumeProfileAdaptor*> create(
+ const Option<std::string>& name = None());
+
+ /**
+ * Global methods for setting and getting a VolumeProfileAdaptor instance.
+ *
+ * The agent (or test) is expected to create and set the adaptor instance
+ * and manage the pointer (this method will only keep a weak pointer).
+ * Each component that needs to use the VolumeProfileAdaptor, such as the
+ * Storage Local Resource Provider, should call `getAdaptor`.
+ */
+ static void setAdaptor(const std::shared_ptr<VolumeProfileAdaptor>& adaptor);
+ static std::shared_ptr<VolumeProfileAdaptor> getAdaptor();
+
+ virtual ~VolumeProfileAdaptor() {}
+
+ /**
+ * Called before a Storage Resource Provider makes an affected CSI request.
+ * The caller is responsible for copying the returned values into the request
+ * object.
+ *
+ * This method is expected to return a Failure if a matching "profile"
+ * cannot be found or retrieved. The caller should not proceed with
+ * any of the affected CSI requests if this method returns a failure.
+ *
+ * The `csiPluginInfoType` parameter is the `CSIPluginInfo::type` field
+ * found inside `ResourceProviderInfo::storage`. This module may choose to
+ * filter results based on the type of CSI plugin.
+ *
+ * NOTE: This module assumes that profiles are immutable after creation.
+ * Changing the `VolumeCapability` or Parameters of a profile after creation
+ * may result in undefined behavior from the SLRP or CSI plugins.
+ */
+ virtual process::Future<ProfileInfo> translate(
+ const std::string& profile,
+ const std::string& csiPluginInfoType) = 0;
+
+ /**
+ * Returns a future that will be satisifed iff the set of profiles known
+ * by the module differs from the `knownProfiles` parameter.
+ *
+ * The `csiPluginInfoType` parameter is the `CSIPluginInfo::type` field
+ * found inside `ResourceProviderInfo::storage`. This module may choose to
+ * filter results based on the type of CSI plugin.
+ *
+ * NOTE: It is highly recommended for the module to insert a random delay
+ * between discovering a different set of profiles and satisfying this
+ * future, because the SLRP is expected to update the set of offered
+ * resources based on this future. Adding a random delay may prevent
+ * a thundering herd of resource updates to the Mesos master.
+ */
+ virtual process::Future<hashset<std::string>> watch(
+ const hashset<std::string>& knownProfiles,
+ const std::string& csiPluginInfoType) = 0;
+
+protected:
+ VolumeProfileAdaptor() {}
+};
+
+} // namespace mesos {
+
+#endif // __MESOS_RESOURCE_PROVIDER_VOLUME_PROFILE_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/include/mesos/resource_provider/volume_profile.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/resource_provider/volume_profile.hpp b/include/mesos/resource_provider/volume_profile.hpp
deleted file mode 100644
index 7141a14..0000000
--- a/include/mesos/resource_provider/volume_profile.hpp
+++ /dev/null
@@ -1,144 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef __MESOS_RESOURCE_PROVIDER_VOLUME_PROFILE_HPP__
-#define __MESOS_RESOURCE_PROVIDER_VOLUME_PROFILE_HPP__
-
-#include <memory>
-#include <string>
-#include <tuple>
-
-#include <process/future.hpp>
-
-#include <stout/hashset.hpp>
-#include <stout/none.hpp>
-#include <stout/nothing.hpp>
-
-#include <csi/spec.hpp>
-
-namespace mesos {
-
-/**
- * This module is used by Storage Resource Providers to translate the
- * "profile" field of a `Resource::DiskInfo::Source` into fields that a
- * Container Storage Interface (CSI) plugin can potentially
- * understand. This affects the following CSI requests:
- * * ControllerPublishVolumeRequest
- * * CreateVolumeRequest
- * * GetCapacityRequest
- * * NodePublishVolumeRequest
- * * ValidateVolumeCapabilitiesRequest
- *
- * This module is not intended to interact with any CSI plugins directly.
- *
- * Documentation for each of the CSI requests can be found at:
- * https://github.com/container-storage-interface/spec/
- */
-class VolumeProfileAdaptor
-{
-public:
- struct ProfileInfo
- {
- /**
- * Corresponds to the `volume_capability` or `volume_capabilities`
- * fields of the affected CSI requests listed in the module description.
- *
- * NOTE: Some CSI requests take a list of `VolumeCapability` objects.
- * However, because there is no existing way to choose between a list
- * of `VolumeCapability` objects, the module will only allow a single
- * `VolumeCapability`.
- */
- csi::VolumeCapability capability;
-
- /**
- * Free-form key-value pairs which should be passed into the body
- * of a `CreateVolumeRequest`. Neither Mesos nor this module is expected
- * to act upon these values (except copying them into the request).
- */
- google::protobuf::Map<std::string, std::string> parameters;
- };
-
- /**
- * Factory method used to create a VolumeProfileAdaptor instance.
- * If the `name` parameter is provided, the module is instantiated
- * using the `ModuleManager`. Otherwise, a "default" volume profile
- * adaptor instance (defined in `src/resource_provider/volume_profile.cpp`)
- * is returned.
- *
- * NOTE: The lifecycle of the returned object is delegated to the caller.
- */
- static Try<VolumeProfileAdaptor*> create(
- const Option<std::string>& name = None());
-
- /**
- * Global methods for setting and getting a VolumeProfileAdaptor instance.
- *
- * The agent (or test) is expected to create and set the adaptor instance
- * and manage the pointer (this method will only keep a weak pointer).
- * Each component that needs to use the VolumeProfileAdaptor, such as the
- * Storage Local Resource Provider, should call `getAdaptor`.
- */
- static void setAdaptor(const std::shared_ptr<VolumeProfileAdaptor>& adaptor);
- static std::shared_ptr<VolumeProfileAdaptor> getAdaptor();
-
- virtual ~VolumeProfileAdaptor() {}
-
- /**
- * Called before a Storage Resource Provider makes an affected CSI request.
- * The caller is responsible for copying the returned values into the request
- * object.
- *
- * This method is expected to return a Failure if a matching "profile"
- * cannot be found or retrieved. The caller should not proceed with
- * any of the affected CSI requests if this method returns a failure.
- *
- * The `csiPluginInfoType` parameter is the `CSIPluginInfo::type` field
- * found inside `ResourceProviderInfo::storage`. This module may choose to
- * filter results based on the type of CSI plugin.
- *
- * NOTE: This module assumes that profiles are immutable after creation.
- * Changing the `VolumeCapability` or Parameters of a profile after creation
- * may result in undefined behavior from the SLRP or CSI plugins.
- */
- virtual process::Future<ProfileInfo> translate(
- const std::string& profile,
- const std::string& csiPluginInfoType) = 0;
-
- /**
- * Returns a future that will be satisifed iff the set of profiles known
- * by the module differs from the `knownProfiles` parameter.
- *
- * The `csiPluginInfoType` parameter is the `CSIPluginInfo::type` field
- * found inside `ResourceProviderInfo::storage`. This module may choose to
- * filter results based on the type of CSI plugin.
- *
- * NOTE: It is highly recommended for the module to insert a random delay
- * between discovering a different set of profiles and satisfying this
- * future, because the SLRP is expected to update the set of offered
- * resources based on this future. Adding a random delay may prevent
- * a thundering herd of resource updates to the Mesos master.
- */
- virtual process::Future<hashset<std::string>> watch(
- const hashset<std::string>& knownProfiles,
- const std::string& csiPluginInfoType) = 0;
-
-protected:
- VolumeProfileAdaptor() {}
-};
-
-} // namespace mesos {
-
-#endif // __MESOS_RESOURCE_PROVIDER_VOLUME_PROFILE_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 33677df..5c6f180 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -383,8 +383,8 @@ CXX_PROTOS += \
if ENABLE_GRPC
CXX_PROTOS += \
- resource_provider/volume_profile.pb.cc \
- resource_provider/volume_profile.pb.h
+ resource_provider/storage/volume_profile.pb.cc \
+ resource_provider/storage/volume_profile.pb.h
CXX_CSI_PROTOS = \
../include/csi/csi.grpc.pb.cc \
@@ -781,7 +781,7 @@ resourceprovider_HEADERS = \
if ENABLE_GRPC
resourceprovider_HEADERS += \
- $(top_srcdir)/include/mesos/resource_provider/volume_profile.hpp
+ $(top_srcdir)/include/mesos/resource_provider/storage/volume_profile.hpp
endif
nodist_resourceprovider_HEADERS = \
@@ -1472,10 +1472,10 @@ endif
if ENABLE_GRPC
libmesos_no_3rdparty_la_SOURCES += \
- resource_provider/volume_profile.cpp \
- resource_provider/volume_profile.proto \
- resource_provider/volume_profile_utils.cpp \
- resource_provider/volume_profile_utils.hpp
+ resource_provider/storage/volume_profile.cpp \
+ resource_provider/storage/volume_profile.proto \
+ resource_provider/storage/volume_profile_utils.cpp \
+ resource_provider/storage/volume_profile_utils.hpp
if OS_LINUX
libmesos_no_3rdparty_la_SOURCES += \
@@ -2345,10 +2345,10 @@ libload_qos_controller_la_LDFLAGS = $(MESOS_MODULE_LDFLAGS)
if ENABLE_GRPC
pkgmodule_LTLIBRARIES += liburi_volume_profile.la
liburi_volume_profile_la_SOURCES = \
- resource_provider/uri_volume_profile.cpp \
- resource_provider/uri_volume_profile.hpp \
- resource_provider/volume_profile.ph.h \
- resource_provider/volume_profile_utils.hpp
+ resource_provider/storage/uri_volume_profile.cpp \
+ resource_provider/storage/uri_volume_profile.hpp \
+ resource_provider/storage/volume_profile.ph.h \
+ resource_provider/storage/volume_profile_utils.hpp
liburi_volume_profile_la_CPPFLAGS = $(MESOS_CPPFLAGS)
liburi_volume_profile_la_LDFLAGS = $(MESOS_MODULE_LDFLAGS)
endif
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/storage/provider.cpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/storage/provider.cpp b/src/resource_provider/storage/provider.cpp
index 6fd82ba..833d929 100644
--- a/src/resource_provider/storage/provider.cpp
+++ b/src/resource_provider/storage/provider.cpp
@@ -37,7 +37,7 @@
#include <mesos/type_utils.hpp>
#include <mesos/resource_provider/resource_provider.hpp>
-#include <mesos/resource_provider/volume_profile.hpp>
+#include <mesos/resource_provider/storage/volume_profile.hpp>
#include <mesos/v1/resource_provider.hpp>
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/storage/uri_volume_profile.cpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/storage/uri_volume_profile.cpp b/src/resource_provider/storage/uri_volume_profile.cpp
new file mode 100644
index 0000000..4431ad1
--- /dev/null
+++ b/src/resource_provider/storage/uri_volume_profile.cpp
@@ -0,0 +1,321 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "resource_provider/storage/uri_volume_profile.hpp"
+
+#include <map>
+#include <string>
+#include <tuple>
+
+#include <mesos/mesos.hpp>
+
+#include <mesos/module/volume_profile.hpp>
+
+#include <mesos/resource_provider/storage/volume_profile.hpp>
+
+#include <process/defer.hpp>
+#include <process/delay.hpp>
+#include <process/dispatch.hpp>
+#include <process/future.hpp>
+#include <process/owned.hpp>
+#include <process/socket.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/error.hpp>
+#include <stout/json.hpp>
+#include <stout/option.hpp>
+#include <stout/protobuf.hpp>
+#include <stout/result.hpp>
+#include <stout/strings.hpp>
+
+#include <csi/spec.hpp>
+#include <csi/utils.hpp>
+
+#include "resource_provider/storage/volume_profile_utils.hpp"
+
+using namespace mesos;
+using namespace process;
+
+using std::map;
+using std::string;
+using std::tuple;
+
+using google::protobuf::Map;
+
+using mesos::resource_provider::VolumeProfileMapping;
+
+namespace mesos {
+namespace internal {
+namespace profile {
+
+bool operator==(
+ const Map<string, string>& left,
+ const Map<string, string>& right) {
+ if (left.size() != right.size()) {
+ return false;
+ }
+
+ typename Map<string, string>::const_iterator iterator = left.begin();
+ while (iterator != left.end()) {
+ if (right.count(iterator->first) != 1) {
+ return false;
+ }
+
+ if (iterator->second != right.at(iterator->first)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+UriVolumeProfileAdaptor::UriVolumeProfileAdaptor(const Flags& _flags)
+ : flags(_flags),
+ process(new UriVolumeProfileAdaptorProcess(flags))
+{
+ spawn(process.get());
+}
+
+
+UriVolumeProfileAdaptor::~UriVolumeProfileAdaptor()
+{
+ terminate(process.get());
+ wait(process.get());
+}
+
+
+Future<VolumeProfileAdaptor::ProfileInfo> UriVolumeProfileAdaptor::translate(
+ const string& profile,
+ const std::string& csiPluginInfoType)
+{
+ return dispatch(
+ process.get(),
+ &UriVolumeProfileAdaptorProcess::translate,
+ profile,
+ csiPluginInfoType);
+}
+
+
+Future<hashset<string>> UriVolumeProfileAdaptor::watch(
+ const hashset<string>& knownProfiles,
+ const std::string& csiPluginInfoType)
+{
+ return dispatch(
+ process.get(),
+ &UriVolumeProfileAdaptorProcess::watch,
+ knownProfiles,
+ csiPluginInfoType);
+}
+
+
+UriVolumeProfileAdaptorProcess::UriVolumeProfileAdaptorProcess(
+ const Flags& _flags)
+ : ProcessBase(ID::generate("uri-volume-profile")),
+ flags(_flags),
+ watchPromise(new Promise<hashset<string>>()) {}
+
+
+void UriVolumeProfileAdaptorProcess::initialize()
+{
+ poll();
+}
+
+
+Future<VolumeProfileAdaptor::ProfileInfo>
+ UriVolumeProfileAdaptorProcess::translate(
+ const string& profile,
+ const std::string& csiPluginInfoType)
+{
+ if (data.count(profile) != 1) {
+ return Failure("Profile '" + profile + "' not found");
+ }
+
+ return data.at(profile);
+}
+
+
+Future<hashset<string>> UriVolumeProfileAdaptorProcess::watch(
+ const hashset<string>& knownProfiles,
+ const std::string& csiPluginInfoType)
+{
+ if (profiles != knownProfiles) {
+ return profiles;
+ }
+
+ return watchPromise->future();
+}
+
+
+void UriVolumeProfileAdaptorProcess::poll()
+{
+ // NOTE: The flags do not allow relative paths, so this is guaranteed to
+ // be either 'http://' or 'https://'.
+ if (strings::startsWith(flags.uri, "http")) {
+ // NOTE: We already validated that this URI is parsable in the flags.
+ Try<http::URL> url = http::URL::parse(flags.uri.string());
+ CHECK_SOME(url);
+
+ http::get(url.get())
+ .onAny(defer(self(), [=](const Future<http::Response>& future) {
+ if (future.isReady()) {
+ // NOTE: We don't check the HTTP status code because we don't know
+ // what potential codes are considered successful.
+ _poll(future->body);
+ } else if (future.isFailed()) {
+ _poll(Error(future.failure()));
+ } else {
+ _poll(Error("Future discarded or abandoned"));
+ }
+ }));
+ } else {
+ _poll(os::read(flags.uri.string()));
+ }
+}
+
+
+void UriVolumeProfileAdaptorProcess::_poll(const Try<string>& fetched)
+{
+ if (fetched.isSome()) {
+ Try<VolumeProfileMapping> parsed = parseVolumeProfileMapping(fetched.get());
+
+ if (parsed.isSome()) {
+ notify(parsed.get());
+ } else {
+ LOG(ERROR) << "Failed to parse result: " << parsed.error();
+ }
+ } else {
+ LOG(WARNING) << "Failed to poll URI: " << fetched.error();
+ }
+
+ // TODO(josephw): Do we want to retry if polling fails and no polling
+ // interval is set? Or perhaps we should exit in that case?
+ if (flags.poll_interval.isSome()) {
+ delay(flags.poll_interval.get(), self(), &Self::poll);
+ }
+}
+
+
+void UriVolumeProfileAdaptorProcess::notify(
+ const VolumeProfileMapping& parsed)
+{
+ bool hasErrors = false;
+
+ foreachkey (const string& profile, data) {
+ if (parsed.profile_matrix().count(profile) != 1) {
+ hasErrors = true;
+
+ LOG(WARNING)
+ << "Fetched profile mapping does not contain profile '" << profile
+ << "'. The fetched mapping will be ignored entirely";
+ continue;
+ }
+
+ bool matchingCapability =
+ data.at(profile).capability ==
+ parsed.profile_matrix().at(profile).volume_capabilities();
+
+ bool matchingParameters =
+ data.at(profile).parameters ==
+ parsed.profile_matrix().at(profile).create_parameters();
+
+ if (!matchingCapability || !matchingParameters) {
+ hasErrors = true;
+
+ LOG(WARNING)
+ << "Fetched profile mapping for profile '" << profile << "'"
+ << " does not match earlier data."
+ << " The fetched mapping will be ignored entirely";
+ }
+ }
+
+ // When encountering a data conflict, this module assumes there is a
+ // problem upstream (i.e. in the `--uri`). It is up to the operator
+ // to notice and resolve this.
+ if (hasErrors) {
+ return;
+ }
+
+ // Profiles can only be added, so if the parsed data is the same size,
+ // nothing has changed and no notifications need to be sent.
+ if (parsed.profile_matrix().size() <= data.size()) {
+ return;
+ }
+
+ // The fetched mapping satisfies our invariants.
+
+ // Save the protobuf as a map we can expose through the module interface.
+ // And update the convenience set of profile names.
+ profiles.clear();
+ auto iterator = parsed.profile_matrix().begin();
+ while (iterator != parsed.profile_matrix().end()) {
+ data[iterator->first] = {
+ iterator->second.volume_capabilities(),
+ iterator->second.create_parameters()
+ };
+
+ profiles.insert(iterator->first);
+ iterator++;
+ }
+
+ // Notify any watchers and then prepare a new promise for the next
+ // iteration of polling.
+ //
+ // TODO(josephw): Delay this based on the `--max_random_wait` option.
+ watchPromise->set(profiles);
+ watchPromise.reset(new Promise<hashset<string>>());
+
+ LOG(INFO)
+ << "Updated volume profile mapping to " << profiles.size()
+ << " total profiles";
+}
+
+} // namespace profile {
+} // namespace internal {
+} // namespace mesos {
+
+
+mesos::modules::Module<VolumeProfileAdaptor>
+org_apache_mesos_UriVolumeProfileAdaptor(
+ MESOS_MODULE_API_VERSION,
+ MESOS_VERSION,
+ "Apache Mesos",
+ "modules@mesos.apache.org",
+ "URI Volume Profile Adaptor module.",
+ nullptr,
+ [](const Parameters& parameters) -> VolumeProfileAdaptor* {
+ // Convert `parameters` into a map.
+ map<string, string> values;
+ foreach (const Parameter& parameter, parameters.parameter()) {
+ values[parameter.key()] = parameter.value();
+ }
+
+ // Load and validate flags from the map.
+ mesos::internal::profile::Flags flags;
+ Try<flags::Warnings> load = flags.load(values);
+
+ if (load.isError()) {
+ LOG(ERROR) << "Failed to parse parameters: " << load.error();
+ return nullptr;
+ }
+
+ // Log any flag warnings.
+ foreach (const flags::Warning& warning, load->warnings) {
+ LOG(WARNING) << warning.message;
+ }
+
+ return new mesos::internal::profile::UriVolumeProfileAdaptor(flags);
+ });
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/storage/uri_volume_profile.hpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/storage/uri_volume_profile.hpp b/src/resource_provider/storage/uri_volume_profile.hpp
new file mode 100644
index 0000000..a58758c
--- /dev/null
+++ b/src/resource_provider/storage/uri_volume_profile.hpp
@@ -0,0 +1,248 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef __RESOURCE_PROVIDER_URI_VOLUME_PROFILE_HPP__
+#define __RESOURCE_PROVIDER_URI_VOLUME_PROFILE_HPP__
+
+#include <map>
+#include <string>
+#include <tuple>
+
+#include <mesos/resource_provider/storage/volume_profile.hpp>
+
+#include <process/future.hpp>
+#include <process/owned.hpp>
+#include <process/process.hpp>
+
+#include <process/ssl/flags.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/error.hpp>
+#include <stout/flags.hpp>
+#include <stout/option.hpp>
+#include <stout/path.hpp>
+#include <stout/strings.hpp>
+
+#include <csi/spec.hpp>
+
+#include "resource_provider/storage/volume_profile_utils.hpp"
+
+namespace mesos {
+namespace internal {
+namespace profile {
+
+// Forward declaration.
+class UriVolumeProfileAdaptorProcess;
+
+struct Flags : public virtual flags::FlagsBase
+{
+ Flags()
+ {
+ add(&Flags::uri,
+ "uri",
+ None(),
+ "URI to a JSON object containing the volume profile mapping.\n"
+ "This module supports both HTTP(s) and file URIs\n."
+ "\n"
+ "The JSON object should consist of some top-level string keys\n"
+ "corresponding to the volume profile name. Each value should\n"
+ "contain a `VolumeCapability` under a 'volume_capabilities'\n"
+ "and a free-form string-string mapping under 'create_parameters'.\n"
+ "\n"
+ "The JSON is modeled after a protobuf found in\n"
+ "`src/csi/uri_volume_profile.proto`.\n"
+ "\n"
+ "For example:\n"
+ "{\n"
+ " \"profile_matrix\" : {\n"
+ " \"my-profile\" : {\n"
+ " \"volume_capabilities\" : {\n"
+ " \"block\" : {},\n"
+ " \"access_mode\" : { \"mode\" : \"SINGLE_NODE_WRITER\" }\n"
+ " },\n"
+ " \"create_parameters\" : {\n"
+ " \"mesos-does-not\" : \"interpret-these\",\n"
+ " \"type\" : \"raid5\",\n"
+ " \"stripes\" : \"3\",\n"
+ " \"stripesize\" : \"64\"\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ "}",
+ static_cast<const Path*>(nullptr),
+ [](const Path& value) -> Option<Error> {
+ // For now, just check if the URI has a supported scheme.
+ //
+ // TODO(josephw): Once we have a proper URI class and parser,
+ // consider validating this URI more thoroughly.
+ if (strings::startsWith(value.string(), "http://")
+#ifdef USE_SSL_SOCKET
+ || (process::network::openssl::flags().enabled &&
+ strings::startsWith(value.string(), "https://"))
+#endif // USE_SSL_SOCKET
+ ) {
+ Try<process::http::URL> url =
+ process::http::URL::parse(value.string());
+
+ if (url.isError()) {
+ return Error("Failed to parse URI: " + url.error());
+ }
+
+ return None();
+ }
+
+ // NOTE: The `Path` class will strip off the 'file://' prefix.
+ if (strings::contains(value.string(), "://")) {
+ return Error("--uri must use a supported scheme (file or http(s))");
+ }
+
+ // We only allow absolute paths for file paths.
+ if (!value.absolute()) {
+ return Error("--uri to a file must be an absolute path");
+ }
+
+ return None();
+ });
+
+ add(&Flags::poll_interval,
+ "poll_interval",
+ "How long to wait between polling the specified `--uri`.\n"
+ "The time is checked each time the `translate` method is called.\n"
+ "If the given time has elapsed, then the URI is re-fetched."
+ "If not specified, the URI is only fetched once.",
+ [](const Option<Duration>& value) -> Option<Error> {
+ if (value.isSome() && value.get() <= Seconds(0)) {
+ return Error("--poll_interval must be non-negative");
+ }
+
+ return None();
+ });
+
+ add(&Flags::max_random_wait,
+ "max_random_wait",
+ "How long at most to wait between discovering a new set of profiles\n"
+ "and notifying the callers of `watch`. The actual wait time is a\n"
+ "uniform random value between 0 and this value. If the `--uri` points\n"
+ "to a centralized location, it may be good to scale this number\n"
+ "according to the number of resource providers in the cluster.",
+ Seconds(0),
+ [](const Duration& value) -> Option<Error> {
+ if (value < Seconds(0)) {
+ return Error("--max_random_wait must be zero or greater");
+ }
+
+ return None();
+ });
+ }
+
+ // NOTE: We use the `Path` type here so that the stout flags parser
+ // does not attempt to read a file if given a `file://` prefixed value.
+ //
+ // TODO(josephw): Replace with a URI type when stout gets one.
+ Path uri;
+
+ Option<Duration> poll_interval;
+ Duration max_random_wait;
+};
+
+
+// The `UriVolumeProfileAdaptor` is an example VolumeProfile module that
+// takes a URI as a module parameter and fetches that URI periodically.
+// The fetched data is parsed into the required CSI protobufs
+// (which also acts as validation).
+//
+// If there is an error during fetching, any previously fetched results
+// will be used until fetching is successful.
+//
+// This module does not filter return results based on `CSIPluginInfo::type`
+// and assumes that all fetched profiles are meant for all resource providers.
+//
+// See `Flags` above for more information.
+class UriVolumeProfileAdaptor : public mesos::VolumeProfileAdaptor
+{
+public:
+ UriVolumeProfileAdaptor(const Flags& _flags);
+
+ virtual ~UriVolumeProfileAdaptor();
+
+ virtual process::Future<mesos::VolumeProfileAdaptor::ProfileInfo> translate(
+ const std::string& profile,
+ const std::string& csiPluginInfoType) override;
+
+ virtual process::Future<hashset<std::string>> watch(
+ const hashset<std::string>& knownProfiles,
+ const std::string& csiPluginInfoType) override;
+
+protected:
+ Flags flags;
+ process::Owned<UriVolumeProfileAdaptorProcess> process;
+};
+
+
+class UriVolumeProfileAdaptorProcess :
+ public process::Process<UriVolumeProfileAdaptorProcess>
+{
+public:
+ UriVolumeProfileAdaptorProcess(const Flags& _flags);
+
+ virtual void initialize() override;
+
+ process::Future<mesos::VolumeProfileAdaptor::ProfileInfo> translate(
+ const std::string& profile,
+ const std::string& csiPluginInfoType);
+
+ process::Future<hashset<std::string>> watch(
+ const hashset<std::string>& knownProfiles,
+ const std::string& csiPluginInfoType);
+
+private:
+ // Helpers for fetching the `--uri`.
+ // If `--poll_interval` is set, this method will dispatch to itself with
+ // a delay once the fetch is complete.
+ void poll();
+ void _poll(const Try<std::string>& fetched);
+
+ // Helper that is called upon successfully polling and parsing the `--uri`.
+ // This method will check the following conditions before updating the state
+ // of the module:
+ // * All known profiles must be included in the updated set.
+ // * All properties of known profiles must match those in the updated set.
+ void notify(const resource_provider::VolumeProfileMapping& parsed);
+
+private:
+ Flags flags;
+
+ // The last fetched profile mapping.
+ // This module assumes that profiles can only be added and never removed.
+ // Once added, profiles cannot be changed either.
+ //
+ // TODO(josephw): Consider persisting this mapping across agent restarts.
+ std::map<std::string, VolumeProfileAdaptor::ProfileInfo> data;
+
+ // Convenience set of the keys in `data` above.
+ // This module does not filter based on `CSIPluginInfo::type`, so this
+ // is valid for all input to `watch(...)`.
+ hashset<std::string> profiles;
+
+ // Will be satisfied whenever `data` is changed.
+ process::Owned<process::Promise<hashset<std::string>>> watchPromise;
+};
+
+} // namespace profile {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __RESOURCE_PROVIDER_URI_VOLUME_PROFILE_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/storage/volume_profile.cpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/storage/volume_profile.cpp b/src/resource_provider/storage/volume_profile.cpp
new file mode 100644
index 0000000..336220d
--- /dev/null
+++ b/src/resource_provider/storage/volume_profile.cpp
@@ -0,0 +1,131 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string>
+
+#include <mesos/mesos.hpp>
+
+#include <mesos/module/volume_profile.hpp>
+
+#include <mesos/resource_provider/storage/volume_profile.hpp>
+
+#include <process/future.hpp>
+
+#include <stout/hashset.hpp>
+
+#include <csi/spec.hpp>
+
+#include "module/manager.hpp"
+
+using std::string;
+using std::tuple;
+
+using process::Failure;
+using process::Future;
+
+using google::protobuf::Map;
+
+namespace mesos {
+namespace internal {
+
+// The default implementation does nothing and always returns a Failure
+// whenever called.
+class DefaultVolumeProfileAdaptor : public VolumeProfileAdaptor
+{
+public:
+ DefaultVolumeProfileAdaptor() {}
+
+ ~DefaultVolumeProfileAdaptor() {}
+
+ virtual Future<VolumeProfileAdaptor::ProfileInfo> translate(
+ const string& profile,
+ const string& csiPluginInfoType) override
+ {
+ return Failure("By default, volume profiles are not supported");
+ }
+
+ virtual Future<hashset<string>> watch(
+ const hashset<string>& knownProfiles,
+ const string& csiPluginInfoType) override
+ {
+ // If the input set of profiles is empty, that means the caller is in sync
+ // with this module. Hence, we return a future that will never be satisified
+ // because this module will never return a non-empty set of profiles.
+ if (knownProfiles.empty()) {
+ return Future<hashset<string>>();
+ }
+
+ return hashset<string>::EMPTY;
+ }
+};
+
+} // namespace internal {
+
+
+Try<VolumeProfileAdaptor*> VolumeProfileAdaptor::create(
+ const Option<string>& moduleName)
+{
+ if (moduleName.isNone()) {
+ LOG(INFO) << "Creating default volume profile adaptor module";
+ return new internal::DefaultVolumeProfileAdaptor();
+ }
+
+ LOG(INFO)
+ << "Creating volume profile adaptor module '" << moduleName.get() << "'";
+
+ Try<VolumeProfileAdaptor*> result =
+ modules::ModuleManager::create<VolumeProfileAdaptor>(moduleName.get());
+
+ if (result.isError()) {
+ return Error(
+ "Failed to initialize volume profile adaptor module: "
+ + result.error());
+ }
+
+ return result;
+}
+
+
+// NOTE: This is a pointer because we avoid using non-POD types
+// as global variables.
+//
+// NOTE: This is a `weak_ptr` because the ownership of the module should
+// belong to the caller of the `create` method above. This will, for example,
+// allow tests to instantiate an Agent and subsequently destruct the Agent
+// without leaving a module behind in a global variable.
+static std::weak_ptr<VolumeProfileAdaptor>* currentAdaptor = nullptr;
+
+
+void VolumeProfileAdaptor::setAdaptor(
+ const std::shared_ptr<VolumeProfileAdaptor>& adaptor)
+{
+ if (currentAdaptor != nullptr) {
+ delete currentAdaptor;
+ }
+
+ currentAdaptor = new std::weak_ptr<VolumeProfileAdaptor>(adaptor);
+}
+
+
+std::shared_ptr<VolumeProfileAdaptor> VolumeProfileAdaptor::getAdaptor()
+{
+ // This method should never be called before `setAdaptor` has been called.
+ CHECK_NOTNULL(currentAdaptor);
+
+ return currentAdaptor->lock();
+}
+
+} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/storage/volume_profile.proto
----------------------------------------------------------------------
diff --git a/src/resource_provider/storage/volume_profile.proto b/src/resource_provider/storage/volume_profile.proto
new file mode 100644
index 0000000..c0628ec
--- /dev/null
+++ b/src/resource_provider/storage/volume_profile.proto
@@ -0,0 +1,43 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+import "csi.proto";
+
+package mesos.resource_provider;
+
+
+message VolumeProfileMapping {
+ message CSIManifest {
+ // Capabilities used for creating, publishing, and validating volumes.
+ // This field is REQUIRED.
+ //
+ // NOTE: The name of this field is plural because some CSI requests
+ // support multiple capabilities. However, Mesos currently does not
+ // support this.
+ .csi.VolumeCapability volume_capabilities = 1;
+
+ // Parameters passed to the CSI CreateVolume RPC.
+ // This field is OPTIONAL.
+ map<string, string> create_parameters = 2;
+ }
+
+ // Each map entry associates a profile name (type string) with the CSI
+ // capabilities and parameters used to make specific CSI requests.
+ // This field is OPTIONAL.
+ map<string, CSIManifest> profile_matrix = 1;
+}
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/storage/volume_profile_utils.cpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/storage/volume_profile_utils.cpp b/src/resource_provider/storage/volume_profile_utils.cpp
new file mode 100644
index 0000000..3d04558
--- /dev/null
+++ b/src/resource_provider/storage/volume_profile_utils.cpp
@@ -0,0 +1,121 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "resource_provider/storage/volume_profile_utils.hpp"
+
+#include <google/protobuf/util/json_util.h>
+
+#include <stout/bytes.hpp>
+#include <stout/foreach.hpp>
+
+using std::string;
+
+using mesos::resource_provider::VolumeProfileMapping;
+
+namespace mesos{
+namespace internal {
+namespace profile {
+
+Try<VolumeProfileMapping> parseVolumeProfileMapping(
+ const string& data)
+{
+ // Use Google's JSON utility function to parse the JSON string.
+ VolumeProfileMapping output;
+ google::protobuf::util::JsonParseOptions options;
+ options.ignore_unknown_fields = true;
+
+ google::protobuf::util::Status status =
+ google::protobuf::util::JsonStringToMessage(data, &output, options);
+
+ if (!status.ok()) {
+ return Error(
+ "Failed to parse VolumeProfileMapping message: "
+ + status.ToString());
+ }
+
+ Option<Error> validation = validate(output);
+ if (validation.isSome()) {
+ return Error(
+ "Fetched profile mapping failed validation with: " + validation->message);
+ }
+
+ return output;
+}
+
+
+Option<Error> validate(const VolumeProfileMapping& mapping)
+{
+ auto iterator = mapping.profile_matrix().begin();
+ while (iterator != mapping.profile_matrix().end()) {
+ if (!iterator->second.has_volume_capabilities()) {
+ return Error(
+ "Profile '" + iterator->first + "' is missing the required field "
+ + "'volume_capabilities");
+ }
+
+ Option<Error> capabilities =
+ validate(iterator->second.volume_capabilities());
+
+ if (capabilities.isSome()) {
+ return Error(
+ "Profile '" + iterator->first + "' VolumeCapabilities are invalid: "
+ + capabilities->message);
+ }
+
+ // NOTE: The `create_parameters` field is optional and needs no further
+ // validation after parsing.
+
+ iterator++;
+ }
+
+ return None();
+}
+
+
+// TODO(chhsiao): Move this to CSI validation implementation file.
+Option<Error> validate(const csi::VolumeCapability& capability)
+{
+ if (capability.has_mount()) {
+ // The total size of this repeated field may not exceed 4 KB.
+ //
+ // TODO(josephw): The specification does not state how this maximum
+ // size is calculated. So this check is conservative and does not
+ // include padding or array separators in the size calculation.
+ size_t size = 0;
+ foreach (const string& flag, capability.mount().mount_flags()) {
+ size += flag.size();
+ }
+
+ if (Bytes(size) > Kilobytes(4)) {
+ return Error("Size of 'mount_flags' may not exceed 4 KB");
+ }
+ }
+
+ if (!capability.has_access_mode()) {
+ return Error("'access_mode' is a required field");
+ }
+
+ if (capability.access_mode().mode() ==
+ csi::VolumeCapability::AccessMode::UNKNOWN) {
+ return Error("'access_mode.mode' is unknown or not set");
+ }
+
+ return None();
+}
+
+} // namespace profile {
+} // namespace internal {
+} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/storage/volume_profile_utils.hpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/storage/volume_profile_utils.hpp b/src/resource_provider/storage/volume_profile_utils.hpp
new file mode 100644
index 0000000..29bdf44
--- /dev/null
+++ b/src/resource_provider/storage/volume_profile_utils.hpp
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef __RESOURCE_PROVIDER_URI_VOLUME_PROFILE_UTILS_HPP__
+#define __RESOURCE_PROVIDER_URI_VOLUME_PROFILE_UTILS_HPP__
+
+#include <stout/option.hpp>
+#include <stout/try.hpp>
+
+// ONLY USEFUL AFTER RUNNING PROTOC.
+#include "resource_provider/volume_profile.pb.h"
+
+namespace mesos {
+namespace internal {
+namespace profile {
+
+// Helper for parsing a string as the expected data format.
+Try<resource_provider::VolumeProfileMapping> parseVolumeProfileMapping(
+ const std::string& data);
+
+
+// Checks the fields inside a `VolumeProfileMapping` according to the
+// comments above the protobuf.
+Option<Error> validate(const resource_provider::VolumeProfileMapping& mapping);
+
+
+// Checks the fields inside a `VolumeCapability` according to the
+// comments above the protobuf.
+Option<Error> validate(const csi::VolumeCapability& capability);
+
+} // namespace profile {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __RESOURCE_PROVIDER_URI_VOLUME_PROFILE_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/uri_volume_profile.cpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/uri_volume_profile.cpp b/src/resource_provider/uri_volume_profile.cpp
deleted file mode 100644
index 9c5bcb9..0000000
--- a/src/resource_provider/uri_volume_profile.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "resource_provider/uri_volume_profile.hpp"
-
-#include <map>
-#include <string>
-#include <tuple>
-
-#include <mesos/mesos.hpp>
-
-#include <mesos/module/volume_profile.hpp>
-
-#include <mesos/resource_provider/volume_profile.hpp>
-
-#include <process/defer.hpp>
-#include <process/delay.hpp>
-#include <process/dispatch.hpp>
-#include <process/future.hpp>
-#include <process/owned.hpp>
-#include <process/socket.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/error.hpp>
-#include <stout/json.hpp>
-#include <stout/option.hpp>
-#include <stout/protobuf.hpp>
-#include <stout/result.hpp>
-#include <stout/strings.hpp>
-
-#include <csi/spec.hpp>
-#include <csi/utils.hpp>
-
-#include "resource_provider/volume_profile_utils.hpp"
-
-using namespace mesos;
-using namespace process;
-
-using std::map;
-using std::string;
-using std::tuple;
-
-using google::protobuf::Map;
-
-using mesos::resource_provider::VolumeProfileMapping;
-
-namespace mesos {
-namespace internal {
-namespace profile {
-
-bool operator==(
- const Map<string, string>& left,
- const Map<string, string>& right) {
- if (left.size() != right.size()) {
- return false;
- }
-
- typename Map<string, string>::const_iterator iterator = left.begin();
- while (iterator != left.end()) {
- if (right.count(iterator->first) != 1) {
- return false;
- }
-
- if (iterator->second != right.at(iterator->first)) {
- return false;
- }
- }
-
- return true;
-}
-
-
-UriVolumeProfileAdaptor::UriVolumeProfileAdaptor(const Flags& _flags)
- : flags(_flags),
- process(new UriVolumeProfileAdaptorProcess(flags))
-{
- spawn(process.get());
-}
-
-
-UriVolumeProfileAdaptor::~UriVolumeProfileAdaptor()
-{
- terminate(process.get());
- wait(process.get());
-}
-
-
-Future<VolumeProfileAdaptor::ProfileInfo> UriVolumeProfileAdaptor::translate(
- const string& profile,
- const std::string& csiPluginInfoType)
-{
- return dispatch(
- process.get(),
- &UriVolumeProfileAdaptorProcess::translate,
- profile,
- csiPluginInfoType);
-}
-
-
-Future<hashset<string>> UriVolumeProfileAdaptor::watch(
- const hashset<string>& knownProfiles,
- const std::string& csiPluginInfoType)
-{
- return dispatch(
- process.get(),
- &UriVolumeProfileAdaptorProcess::watch,
- knownProfiles,
- csiPluginInfoType);
-}
-
-
-UriVolumeProfileAdaptorProcess::UriVolumeProfileAdaptorProcess(
- const Flags& _flags)
- : ProcessBase(ID::generate("uri-volume-profile")),
- flags(_flags),
- watchPromise(new Promise<hashset<string>>()) {}
-
-
-void UriVolumeProfileAdaptorProcess::initialize()
-{
- poll();
-}
-
-
-Future<VolumeProfileAdaptor::ProfileInfo>
- UriVolumeProfileAdaptorProcess::translate(
- const string& profile,
- const std::string& csiPluginInfoType)
-{
- if (data.count(profile) != 1) {
- return Failure("Profile '" + profile + "' not found");
- }
-
- return data.at(profile);
-}
-
-
-Future<hashset<string>> UriVolumeProfileAdaptorProcess::watch(
- const hashset<string>& knownProfiles,
- const std::string& csiPluginInfoType)
-{
- if (profiles != knownProfiles) {
- return profiles;
- }
-
- return watchPromise->future();
-}
-
-
-void UriVolumeProfileAdaptorProcess::poll()
-{
- // NOTE: The flags do not allow relative paths, so this is guaranteed to
- // be either 'http://' or 'https://'.
- if (strings::startsWith(flags.uri, "http")) {
- // NOTE: We already validated that this URI is parsable in the flags.
- Try<http::URL> url = http::URL::parse(flags.uri.string());
- CHECK_SOME(url);
-
- http::get(url.get())
- .onAny(defer(self(), [=](const Future<http::Response>& future) {
- if (future.isReady()) {
- // NOTE: We don't check the HTTP status code because we don't know
- // what potential codes are considered successful.
- _poll(future->body);
- } else if (future.isFailed()) {
- _poll(Error(future.failure()));
- } else {
- _poll(Error("Future discarded or abandoned"));
- }
- }));
- } else {
- _poll(os::read(flags.uri.string()));
- }
-}
-
-
-void UriVolumeProfileAdaptorProcess::_poll(const Try<string>& fetched)
-{
- if (fetched.isSome()) {
- Try<VolumeProfileMapping> parsed = parseVolumeProfileMapping(fetched.get());
-
- if (parsed.isSome()) {
- notify(parsed.get());
- } else {
- LOG(ERROR) << "Failed to parse result: " << parsed.error();
- }
- } else {
- LOG(WARNING) << "Failed to poll URI: " << fetched.error();
- }
-
- // TODO(josephw): Do we want to retry if polling fails and no polling
- // interval is set? Or perhaps we should exit in that case?
- if (flags.poll_interval.isSome()) {
- delay(flags.poll_interval.get(), self(), &Self::poll);
- }
-}
-
-
-void UriVolumeProfileAdaptorProcess::notify(
- const VolumeProfileMapping& parsed)
-{
- bool hasErrors = false;
-
- foreachkey (const string& profile, data) {
- if (parsed.profile_matrix().count(profile) != 1) {
- hasErrors = true;
-
- LOG(WARNING)
- << "Fetched profile mapping does not contain profile '" << profile
- << "'. The fetched mapping will be ignored entirely";
- continue;
- }
-
- bool matchingCapability =
- data.at(profile).capability ==
- parsed.profile_matrix().at(profile).volume_capabilities();
-
- bool matchingParameters =
- data.at(profile).parameters ==
- parsed.profile_matrix().at(profile).create_parameters();
-
- if (!matchingCapability || !matchingParameters) {
- hasErrors = true;
-
- LOG(WARNING)
- << "Fetched profile mapping for profile '" << profile << "'"
- << " does not match earlier data."
- << " The fetched mapping will be ignored entirely";
- }
- }
-
- // When encountering a data conflict, this module assumes there is a
- // problem upstream (i.e. in the `--uri`). It is up to the operator
- // to notice and resolve this.
- if (hasErrors) {
- return;
- }
-
- // Profiles can only be added, so if the parsed data is the same size,
- // nothing has changed and no notifications need to be sent.
- if (parsed.profile_matrix().size() <= data.size()) {
- return;
- }
-
- // The fetched mapping satisfies our invariants.
-
- // Save the protobuf as a map we can expose through the module interface.
- // And update the convenience set of profile names.
- profiles.clear();
- auto iterator = parsed.profile_matrix().begin();
- while (iterator != parsed.profile_matrix().end()) {
- data[iterator->first] = {
- iterator->second.volume_capabilities(),
- iterator->second.create_parameters()
- };
-
- profiles.insert(iterator->first);
- iterator++;
- }
-
- // Notify any watchers and then prepare a new promise for the next
- // iteration of polling.
- //
- // TODO(josephw): Delay this based on the `--max_random_wait` option.
- watchPromise->set(profiles);
- watchPromise.reset(new Promise<hashset<string>>());
-
- LOG(INFO)
- << "Updated volume profile mapping to " << profiles.size()
- << " total profiles";
-}
-
-} // namespace profile {
-} // namespace internal {
-} // namespace mesos {
-
-
-mesos::modules::Module<VolumeProfileAdaptor>
-org_apache_mesos_UriVolumeProfileAdaptor(
- MESOS_MODULE_API_VERSION,
- MESOS_VERSION,
- "Apache Mesos",
- "modules@mesos.apache.org",
- "URI Volume Profile Adaptor module.",
- nullptr,
- [](const Parameters& parameters) -> VolumeProfileAdaptor* {
- // Convert `parameters` into a map.
- map<string, string> values;
- foreach (const Parameter& parameter, parameters.parameter()) {
- values[parameter.key()] = parameter.value();
- }
-
- // Load and validate flags from the map.
- mesos::internal::profile::Flags flags;
- Try<flags::Warnings> load = flags.load(values);
-
- if (load.isError()) {
- LOG(ERROR) << "Failed to parse parameters: " << load.error();
- return nullptr;
- }
-
- // Log any flag warnings.
- foreach (const flags::Warning& warning, load->warnings) {
- LOG(WARNING) << warning.message;
- }
-
- return new mesos::internal::profile::UriVolumeProfileAdaptor(flags);
- });
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/uri_volume_profile.hpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/uri_volume_profile.hpp b/src/resource_provider/uri_volume_profile.hpp
deleted file mode 100644
index 11c1727..0000000
--- a/src/resource_provider/uri_volume_profile.hpp
+++ /dev/null
@@ -1,248 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef __RESOURCE_PROVIDER_URI_VOLUME_PROFILE_HPP__
-#define __RESOURCE_PROVIDER_URI_VOLUME_PROFILE_HPP__
-
-#include <map>
-#include <string>
-#include <tuple>
-
-#include <mesos/resource_provider/volume_profile.hpp>
-
-#include <process/future.hpp>
-#include <process/owned.hpp>
-#include <process/process.hpp>
-
-#include <process/ssl/flags.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/error.hpp>
-#include <stout/flags.hpp>
-#include <stout/option.hpp>
-#include <stout/path.hpp>
-#include <stout/strings.hpp>
-
-#include <csi/spec.hpp>
-
-#include "resource_provider/volume_profile_utils.hpp"
-
-namespace mesos {
-namespace internal {
-namespace profile {
-
-// Forward declaration.
-class UriVolumeProfileAdaptorProcess;
-
-struct Flags : public virtual flags::FlagsBase
-{
- Flags()
- {
- add(&Flags::uri,
- "uri",
- None(),
- "URI to a JSON object containing the volume profile mapping.\n"
- "This module supports both HTTP(s) and file URIs\n."
- "\n"
- "The JSON object should consist of some top-level string keys\n"
- "corresponding to the volume profile name. Each value should\n"
- "contain a `VolumeCapability` under a 'volume_capabilities'\n"
- "and a free-form string-string mapping under 'create_parameters'.\n"
- "\n"
- "The JSON is modeled after a protobuf found in\n"
- "`src/csi/uri_volume_profile.proto`.\n"
- "\n"
- "For example:\n"
- "{\n"
- " \"profile_matrix\" : {\n"
- " \"my-profile\" : {\n"
- " \"volume_capabilities\" : {\n"
- " \"block\" : {},\n"
- " \"access_mode\" : { \"mode\" : \"SINGLE_NODE_WRITER\" }\n"
- " },\n"
- " \"create_parameters\" : {\n"
- " \"mesos-does-not\" : \"interpret-these\",\n"
- " \"type\" : \"raid5\",\n"
- " \"stripes\" : \"3\",\n"
- " \"stripesize\" : \"64\"\n"
- " }\n"
- " }\n"
- " }\n"
- "}",
- static_cast<const Path*>(nullptr),
- [](const Path& value) -> Option<Error> {
- // For now, just check if the URI has a supported scheme.
- //
- // TODO(josephw): Once we have a proper URI class and parser,
- // consider validating this URI more thoroughly.
- if (strings::startsWith(value.string(), "http://")
-#ifdef USE_SSL_SOCKET
- || (process::network::openssl::flags().enabled &&
- strings::startsWith(value.string(), "https://"))
-#endif // USE_SSL_SOCKET
- ) {
- Try<process::http::URL> url =
- process::http::URL::parse(value.string());
-
- if (url.isError()) {
- return Error("Failed to parse URI: " + url.error());
- }
-
- return None();
- }
-
- // NOTE: The `Path` class will strip off the 'file://' prefix.
- if (strings::contains(value.string(), "://")) {
- return Error("--uri must use a supported scheme (file or http(s))");
- }
-
- // We only allow absolute paths for file paths.
- if (!value.absolute()) {
- return Error("--uri to a file must be an absolute path");
- }
-
- return None();
- });
-
- add(&Flags::poll_interval,
- "poll_interval",
- "How long to wait between polling the specified `--uri`.\n"
- "The time is checked each time the `translate` method is called.\n"
- "If the given time has elapsed, then the URI is re-fetched."
- "If not specified, the URI is only fetched once.",
- [](const Option<Duration>& value) -> Option<Error> {
- if (value.isSome() && value.get() <= Seconds(0)) {
- return Error("--poll_interval must be non-negative");
- }
-
- return None();
- });
-
- add(&Flags::max_random_wait,
- "max_random_wait",
- "How long at most to wait between discovering a new set of profiles\n"
- "and notifying the callers of `watch`. The actual wait time is a\n"
- "uniform random value between 0 and this value. If the `--uri` points\n"
- "to a centralized location, it may be good to scale this number\n"
- "according to the number of resource providers in the cluster.",
- Seconds(0),
- [](const Duration& value) -> Option<Error> {
- if (value < Seconds(0)) {
- return Error("--max_random_wait must be zero or greater");
- }
-
- return None();
- });
- }
-
- // NOTE: We use the `Path` type here so that the stout flags parser
- // does not attempt to read a file if given a `file://` prefixed value.
- //
- // TODO(josephw): Replace with a URI type when stout gets one.
- Path uri;
-
- Option<Duration> poll_interval;
- Duration max_random_wait;
-};
-
-
-// The `UriVolumeProfileAdaptor` is an example VolumeProfile module that
-// takes a URI as a module parameter and fetches that URI periodically.
-// The fetched data is parsed into the required CSI protobufs
-// (which also acts as validation).
-//
-// If there is an error during fetching, any previously fetched results
-// will be used until fetching is successful.
-//
-// This module does not filter return results based on `CSIPluginInfo::type`
-// and assumes that all fetched profiles are meant for all resource providers.
-//
-// See `Flags` above for more information.
-class UriVolumeProfileAdaptor : public mesos::VolumeProfileAdaptor
-{
-public:
- UriVolumeProfileAdaptor(const Flags& _flags);
-
- virtual ~UriVolumeProfileAdaptor();
-
- virtual process::Future<mesos::VolumeProfileAdaptor::ProfileInfo> translate(
- const std::string& profile,
- const std::string& csiPluginInfoType) override;
-
- virtual process::Future<hashset<std::string>> watch(
- const hashset<std::string>& knownProfiles,
- const std::string& csiPluginInfoType) override;
-
-protected:
- Flags flags;
- process::Owned<UriVolumeProfileAdaptorProcess> process;
-};
-
-
-class UriVolumeProfileAdaptorProcess :
- public process::Process<UriVolumeProfileAdaptorProcess>
-{
-public:
- UriVolumeProfileAdaptorProcess(const Flags& _flags);
-
- virtual void initialize() override;
-
- process::Future<mesos::VolumeProfileAdaptor::ProfileInfo> translate(
- const std::string& profile,
- const std::string& csiPluginInfoType);
-
- process::Future<hashset<std::string>> watch(
- const hashset<std::string>& knownProfiles,
- const std::string& csiPluginInfoType);
-
-private:
- // Helpers for fetching the `--uri`.
- // If `--poll_interval` is set, this method will dispatch to itself with
- // a delay once the fetch is complete.
- void poll();
- void _poll(const Try<std::string>& fetched);
-
- // Helper that is called upon successfully polling and parsing the `--uri`.
- // This method will check the following conditions before updating the state
- // of the module:
- // * All known profiles must be included in the updated set.
- // * All properties of known profiles must match those in the updated set.
- void notify(const resource_provider::VolumeProfileMapping& parsed);
-
-private:
- Flags flags;
-
- // The last fetched profile mapping.
- // This module assumes that profiles can only be added and never removed.
- // Once added, profiles cannot be changed either.
- //
- // TODO(josephw): Consider persisting this mapping across agent restarts.
- std::map<std::string, VolumeProfileAdaptor::ProfileInfo> data;
-
- // Convenience set of the keys in `data` above.
- // This module does not filter based on `CSIPluginInfo::type`, so this
- // is valid for all input to `watch(...)`.
- hashset<std::string> profiles;
-
- // Will be satisfied whenever `data` is changed.
- process::Owned<process::Promise<hashset<std::string>>> watchPromise;
-};
-
-} // namespace profile {
-} // namespace internal {
-} // namespace mesos {
-
-#endif // __RESOURCE_PROVIDER_URI_VOLUME_PROFILE_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/volume_profile.cpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/volume_profile.cpp b/src/resource_provider/volume_profile.cpp
deleted file mode 100644
index 2b83703..0000000
--- a/src/resource_provider/volume_profile.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <string>
-
-#include <mesos/mesos.hpp>
-
-#include <mesos/module/volume_profile.hpp>
-
-#include <mesos/resource_provider/volume_profile.hpp>
-
-#include <process/future.hpp>
-
-#include <stout/hashset.hpp>
-
-#include <csi/spec.hpp>
-
-#include "module/manager.hpp"
-
-using std::string;
-using std::tuple;
-
-using process::Failure;
-using process::Future;
-
-using google::protobuf::Map;
-
-namespace mesos {
-namespace internal {
-
-// The default implementation does nothing and always returns a Failure
-// whenever called.
-class DefaultVolumeProfileAdaptor : public VolumeProfileAdaptor
-{
-public:
- DefaultVolumeProfileAdaptor() {}
-
- ~DefaultVolumeProfileAdaptor() {}
-
- virtual Future<VolumeProfileAdaptor::ProfileInfo> translate(
- const string& profile,
- const string& csiPluginInfoType) override
- {
- return Failure("By default, volume profiles are not supported");
- }
-
- virtual Future<hashset<string>> watch(
- const hashset<string>& knownProfiles,
- const string& csiPluginInfoType) override
- {
- // If the input set of profiles is empty, that means the caller is in sync
- // with this module. Hence, we return a future that will never be satisified
- // because this module will never return a non-empty set of profiles.
- if (knownProfiles.empty()) {
- return Future<hashset<string>>();
- }
-
- return hashset<string>::EMPTY;
- }
-};
-
-} // namespace internal {
-
-
-Try<VolumeProfileAdaptor*> VolumeProfileAdaptor::create(
- const Option<string>& moduleName)
-{
- if (moduleName.isNone()) {
- LOG(INFO) << "Creating default volume profile adaptor module";
- return new internal::DefaultVolumeProfileAdaptor();
- }
-
- LOG(INFO)
- << "Creating volume profile adaptor module '" << moduleName.get() << "'";
-
- Try<VolumeProfileAdaptor*> result =
- modules::ModuleManager::create<VolumeProfileAdaptor>(moduleName.get());
-
- if (result.isError()) {
- return Error(
- "Failed to initialize volume profile adaptor module: "
- + result.error());
- }
-
- return result;
-}
-
-
-// NOTE: This is a pointer because we avoid using non-POD types
-// as global variables.
-//
-// NOTE: This is a `weak_ptr` because the ownership of the module should
-// belong to the caller of the `create` method above. This will, for example,
-// allow tests to instantiate an Agent and subsequently destruct the Agent
-// without leaving a module behind in a global variable.
-static std::weak_ptr<VolumeProfileAdaptor>* currentAdaptor = nullptr;
-
-
-void VolumeProfileAdaptor::setAdaptor(
- const std::shared_ptr<VolumeProfileAdaptor>& adaptor)
-{
- if (currentAdaptor != nullptr) {
- delete currentAdaptor;
- }
-
- currentAdaptor = new std::weak_ptr<VolumeProfileAdaptor>(adaptor);
-}
-
-
-std::shared_ptr<VolumeProfileAdaptor> VolumeProfileAdaptor::getAdaptor()
-{
- // This method should never be called before `setAdaptor` has been called.
- CHECK_NOTNULL(currentAdaptor);
-
- return currentAdaptor->lock();
-}
-
-} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/volume_profile.proto
----------------------------------------------------------------------
diff --git a/src/resource_provider/volume_profile.proto b/src/resource_provider/volume_profile.proto
deleted file mode 100644
index c0628ec..0000000
--- a/src/resource_provider/volume_profile.proto
+++ /dev/null
@@ -1,43 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-syntax = "proto3";
-
-import "csi.proto";
-
-package mesos.resource_provider;
-
-
-message VolumeProfileMapping {
- message CSIManifest {
- // Capabilities used for creating, publishing, and validating volumes.
- // This field is REQUIRED.
- //
- // NOTE: The name of this field is plural because some CSI requests
- // support multiple capabilities. However, Mesos currently does not
- // support this.
- .csi.VolumeCapability volume_capabilities = 1;
-
- // Parameters passed to the CSI CreateVolume RPC.
- // This field is OPTIONAL.
- map<string, string> create_parameters = 2;
- }
-
- // Each map entry associates a profile name (type string) with the CSI
- // capabilities and parameters used to make specific CSI requests.
- // This field is OPTIONAL.
- map<string, CSIManifest> profile_matrix = 1;
-}
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/volume_profile_utils.cpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/volume_profile_utils.cpp b/src/resource_provider/volume_profile_utils.cpp
deleted file mode 100644
index ec8b1f4..0000000
--- a/src/resource_provider/volume_profile_utils.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "resource_provider/volume_profile_utils.hpp"
-
-#include <google/protobuf/util/json_util.h>
-
-#include <stout/bytes.hpp>
-#include <stout/foreach.hpp>
-
-using std::string;
-
-using mesos::resource_provider::VolumeProfileMapping;
-
-namespace mesos{
-namespace internal {
-namespace profile {
-
-Try<VolumeProfileMapping> parseVolumeProfileMapping(
- const string& data)
-{
- // Use Google's JSON utility function to parse the JSON string.
- VolumeProfileMapping output;
- google::protobuf::util::JsonParseOptions options;
- options.ignore_unknown_fields = true;
-
- google::protobuf::util::Status status =
- google::protobuf::util::JsonStringToMessage(data, &output, options);
-
- if (!status.ok()) {
- return Error(
- "Failed to parse VolumeProfileMapping message: "
- + status.ToString());
- }
-
- Option<Error> validation = validate(output);
- if (validation.isSome()) {
- return Error(
- "Fetched profile mapping failed validation with: " + validation->message);
- }
-
- return output;
-}
-
-
-Option<Error> validate(const VolumeProfileMapping& mapping)
-{
- auto iterator = mapping.profile_matrix().begin();
- while (iterator != mapping.profile_matrix().end()) {
- if (!iterator->second.has_volume_capabilities()) {
- return Error(
- "Profile '" + iterator->first + "' is missing the required field "
- + "'volume_capabilities");
- }
-
- Option<Error> capabilities =
- validate(iterator->second.volume_capabilities());
-
- if (capabilities.isSome()) {
- return Error(
- "Profile '" + iterator->first + "' VolumeCapabilities are invalid: "
- + capabilities->message);
- }
-
- // NOTE: The `create_parameters` field is optional and needs no further
- // validation after parsing.
-
- iterator++;
- }
-
- return None();
-}
-
-
-// TODO(chhsiao): Move this to CSI validation implementation file.
-Option<Error> validate(const csi::VolumeCapability& capability)
-{
- if (capability.has_mount()) {
- // The total size of this repeated field may not exceed 4 KB.
- //
- // TODO(josephw): The specification does not state how this maximum
- // size is calculated. So this check is conservative and does not
- // include padding or array separators in the size calculation.
- size_t size = 0;
- foreach (const string& flag, capability.mount().mount_flags()) {
- size += flag.size();
- }
-
- if (Bytes(size) > Kilobytes(4)) {
- return Error("Size of 'mount_flags' may not exceed 4 KB");
- }
- }
-
- if (!capability.has_access_mode()) {
- return Error("'access_mode' is a required field");
- }
-
- if (capability.access_mode().mode() ==
- csi::VolumeCapability::AccessMode::UNKNOWN) {
- return Error("'access_mode.mode' is unknown or not set");
- }
-
- return None();
-}
-
-} // namespace profile {
-} // namespace internal {
-} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/resource_provider/volume_profile_utils.hpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/volume_profile_utils.hpp b/src/resource_provider/volume_profile_utils.hpp
deleted file mode 100644
index 29bdf44..0000000
--- a/src/resource_provider/volume_profile_utils.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef __RESOURCE_PROVIDER_URI_VOLUME_PROFILE_UTILS_HPP__
-#define __RESOURCE_PROVIDER_URI_VOLUME_PROFILE_UTILS_HPP__
-
-#include <stout/option.hpp>
-#include <stout/try.hpp>
-
-// ONLY USEFUL AFTER RUNNING PROTOC.
-#include "resource_provider/volume_profile.pb.h"
-
-namespace mesos {
-namespace internal {
-namespace profile {
-
-// Helper for parsing a string as the expected data format.
-Try<resource_provider::VolumeProfileMapping> parseVolumeProfileMapping(
- const std::string& data);
-
-
-// Checks the fields inside a `VolumeProfileMapping` according to the
-// comments above the protobuf.
-Option<Error> validate(const resource_provider::VolumeProfileMapping& mapping);
-
-
-// Checks the fields inside a `VolumeCapability` according to the
-// comments above the protobuf.
-Option<Error> validate(const csi::VolumeCapability& capability);
-
-} // namespace profile {
-} // namespace internal {
-} // namespace mesos {
-
-#endif // __RESOURCE_PROVIDER_URI_VOLUME_PROFILE_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index 55dea08..264705f 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -37,7 +37,7 @@
#include <mesos/module/authenticatee.hpp>
#ifdef ENABLE_GRPC
-#include <mesos/resource_provider/volume_profile.hpp>
+#include <mesos/resource_provider/storage/volume_profile.hpp>
#endif
#include <process/after.hpp>
http://git-wip-us.apache.org/repos/asf/mesos/blob/835d2a2c/src/tests/volume_profile_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/volume_profile_tests.cpp b/src/tests/volume_profile_tests.cpp
index 2f5018f..6ed81c9 100644
--- a/src/tests/volume_profile_tests.cpp
+++ b/src/tests/volume_profile_tests.cpp
@@ -21,7 +21,7 @@
#include <mesos/module/volume_profile.hpp>
-#include <mesos/resource_provider/volume_profile.hpp>
+#include <mesos/resource_provider/storage/volume_profile.hpp>
#include <process/clock.hpp>
#include <process/future.hpp>
@@ -40,8 +40,8 @@
#include "module/manager.hpp"
-#include "resource_provider/uri_volume_profile.hpp"
-#include "resource_provider/volume_profile_utils.hpp"
+#include "resource_provider/storage/uri_volume_profile.hpp"
+#include "resource_provider/storage/volume_profile_utils.hpp"
#include "tests/flags.hpp"
#include "tests/mesos.hpp"
[2/2] mesos git commit: Made volume secret isolator not standalone
container aware.
Posted by ji...@apache.org.
Made volume secret isolator not standalone container aware.
We'll revisit this later.
Review: https://reviews.apache.org/r/64742
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5f40f3d4
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5f40f3d4
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5f40f3d4
Branch: refs/heads/master
Commit: 5f40f3d401bbdd7e324113214c286a26faf67540
Parents: 835d2a2
Author: Jie Yu <yu...@gmail.com>
Authored: Tue Dec 19 19:35:49 2017 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Tue Dec 19 19:36:28 2017 -0800
----------------------------------------------------------------------
src/slave/containerizer/mesos/isolators/volume/secret.cpp | 6 ------
src/slave/containerizer/mesos/isolators/volume/secret.hpp | 1 -
2 files changed, 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/5f40f3d4/src/slave/containerizer/mesos/isolators/volume/secret.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/volume/secret.cpp b/src/slave/containerizer/mesos/isolators/volume/secret.cpp
index e754a1b..8071e4e 100644
--- a/src/slave/containerizer/mesos/isolators/volume/secret.cpp
+++ b/src/slave/containerizer/mesos/isolators/volume/secret.cpp
@@ -99,12 +99,6 @@ bool VolumeSecretIsolatorProcess::supportsNesting()
}
-bool VolumeSecretIsolatorProcess::supportsStandalone()
-{
- return true;
-}
-
-
Future<Option<ContainerLaunchInfo>> VolumeSecretIsolatorProcess::prepare(
const ContainerID& containerId,
const ContainerConfig& containerConfig)
http://git-wip-us.apache.org/repos/asf/mesos/blob/5f40f3d4/src/slave/containerizer/mesos/isolators/volume/secret.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/volume/secret.hpp b/src/slave/containerizer/mesos/isolators/volume/secret.hpp
index 4515777..2680345 100644
--- a/src/slave/containerizer/mesos/isolators/volume/secret.hpp
+++ b/src/slave/containerizer/mesos/isolators/volume/secret.hpp
@@ -46,7 +46,6 @@ public:
virtual ~VolumeSecretIsolatorProcess() {}
virtual bool supportsNesting();
- virtual bool supportsStandalone();
virtual process::Future<Option<mesos::slave::ContainerLaunchInfo>> prepare(
const ContainerID& containerId,