Apache Mesos
uri_disk_profile.hpp
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef __RESOURCE_PROVIDER_URI_DISK_PROFILE_HPP__
18 #define __RESOURCE_PROVIDER_URI_DISK_PROFILE_HPP__
19 
20 #include <map>
21 #include <string>
22 #include <tuple>
23 
25 
26 #include <process/future.hpp>
27 #include <process/owned.hpp>
28 #include <process/process.hpp>
29 
30 #include <process/ssl/flags.hpp>
31 
32 #include <stout/duration.hpp>
33 #include <stout/error.hpp>
34 #include <stout/flags.hpp>
35 #include <stout/option.hpp>
36 #include <stout/path.hpp>
37 #include <stout/strings.hpp>
38 
39 #include <csi/spec.hpp>
40 
42 
43 namespace mesos {
44 namespace internal {
45 namespace profile {
46 
47 // Forward declaration.
48 class UriDiskProfileAdaptorProcess;
49 
50 struct Flags : public virtual flags::FlagsBase
51 {
53  {
54  add(&Flags::uri,
55  "uri",
56  None(),
57  "URI to a JSON object containing the disk profile mapping.\n"
58  "This module supports both HTTP(s) and file URIs\n."
59  "\n"
60  "The JSON object should consist of some top-level string keys\n"
61  "corresponding to the disk profile name. Each value should\n"
62  "contain a `VolumeCapability` under a 'volume_capabilities'\n"
63  "and a free-form string-string mapping under 'create_parameters'.\n"
64  "\n"
65  "The JSON is modeled after a protobuf found in\n"
66  "`src/csi/uri_disk_profile.proto`.\n"
67  "\n"
68  "For example:\n"
69  "{\n"
70  " \"profile_matrix\" : {\n"
71  " \"my-profile\" : {\n"
72  " \"volume_capabilities\" : {\n"
73  " \"block\" : {},\n"
74  " \"access_mode\" : { \"mode\" : \"SINGLE_NODE_WRITER\" }\n"
75  " },\n"
76  " \"create_parameters\" : {\n"
77  " \"mesos-does-not\" : \"interpret-these\",\n"
78  " \"type\" : \"raid5\",\n"
79  " \"stripes\" : \"3\",\n"
80  " \"stripesize\" : \"64\"\n"
81  " }\n"
82  " }\n"
83  " }\n"
84  "}",
85  static_cast<const Path*>(nullptr),
86  [](const Path& value) -> Option<Error> {
87  // For now, just check if the URI has a supported scheme.
88  //
89  // TODO(josephw): Once we have a proper URI class and parser,
90  // consider validating this URI more thoroughly.
91  if (strings::startsWith(value.string(), "http://")
92 #ifdef USE_SSL_SOCKET
93  || (process::network::openssl::flags().enabled &&
94  strings::startsWith(value.string(), "https://"))
95 #endif // USE_SSL_SOCKET
96  ) {
99 
100  if (url.isError()) {
101  return Error("Failed to parse URI: " + url.error());
102  }
103 
104  return None();
105  }
106 
107  // NOTE: The `Path` class will strip off the 'file://' prefix.
108  if (strings::contains(value.string(), "://")) {
109  return Error("--uri must use a supported scheme (file or http(s))");
110  }
111 
112  // We only allow absolute paths for file paths.
113  if (!value.absolute()) {
114  return Error("--uri to a file must be an absolute path");
115  }
116 
117  return None();
118  });
119 
121  "poll_interval",
122  "How long to wait between polling the specified `--uri`.\n"
123  "The time is checked each time the `translate` method is called.\n"
124  "If the given time has elapsed, then the URI is re-fetched."
125  "If not specified, the URI is only fetched once.",
126  [](const Option<Duration>& value) -> Option<Error> {
127  if (value.isSome() && value.get() <= Seconds(0)) {
128  return Error("--poll_interval must be non-negative");
129  }
130 
131  return None();
132  });
133 
135  "max_random_wait",
136  "How long at most to wait between discovering a new set of profiles\n"
137  "and notifying the callers of `watch`. The actual wait time is a\n"
138  "uniform random value between 0 and this value. If the `--uri` points\n"
139  "to a centralized location, it may be good to scale this number\n"
140  "according to the number of resource providers in the cluster.",
141  Seconds(0),
142  [](const Duration& value) -> Option<Error> {
143  if (value < Seconds(0)) {
144  return Error("--max_random_wait must be zero or greater");
145  }
146 
147  return None();
148  });
149  }
150 
151  // NOTE: We use the `Path` type here so that the stout flags parser
152  // does not attempt to read a file if given a `file://` prefixed value.
153  //
154  // TODO(josephw): Replace with a URI type when stout gets one.
156 
159 };
160 
161 
162 // The `UriDiskProfileAdaptor` is an example DiskProfile module that
163 // takes a URI as a module parameter and fetches that URI periodically.
164 // The fetched data is parsed into the required CSI protobufs
165 // (which also acts as validation).
166 //
167 // If there is an error during fetching, any previously fetched results
168 // will be used until fetching is successful.
169 //
170 // This module does not filter return results based on `CSIPluginInfo::type`
171 // and assumes that all fetched profiles are meant for all resource providers.
172 //
173 // See `Flags` above for more information.
175 {
176 public:
177  UriDiskProfileAdaptor(const Flags& _flags);
178 
179  virtual ~UriDiskProfileAdaptor();
180 
182  const std::string& profile,
183  const std::string& csiPluginInfoType) override;
184 
186  const hashset<std::string>& knownProfiles,
187  const std::string& csiPluginInfoType) override;
188 
189 protected:
192 };
193 
194 
196  public process::Process<UriDiskProfileAdaptorProcess>
197 {
198 public:
199  UriDiskProfileAdaptorProcess(const Flags& _flags);
200 
201  virtual void initialize() override;
202 
204  const std::string& profile,
205  const std::string& csiPluginInfoType);
206 
208  const hashset<std::string>& knownProfiles,
209  const std::string& csiPluginInfoType);
210 
211 private:
212  // Helpers for fetching the `--uri`.
213  // If `--poll_interval` is set, this method will dispatch to itself with
214  // a delay once the fetch is complete.
215  void poll();
216  void _poll(const Try<std::string>& fetched);
217 
218  // Helper that is called upon successfully polling and parsing the `--uri`.
219  // This method will check the following conditions before updating the state
220  // of the module:
221  // * All known profiles must be included in the updated set.
222  // * All properties of known profiles must match those in the updated set.
223  void notify(const resource_provider::DiskProfileMapping& parsed);
224 
225 private:
226  Flags flags;
227 
228  // The last fetched profile mapping.
229  // This module assumes that profiles can only be added and never removed.
230  // Once added, profiles cannot be changed either.
231  //
232  // TODO(josephw): Consider persisting this mapping across agent restarts.
233  std::map<std::string, DiskProfileAdaptor::ProfileInfo> data;
234 
235  // Convenience set of the keys in `data` above.
236  // This module does not filter based on `CSIPluginInfo::type`, so this
237  // is valid for all input to `watch(...)`.
238  hashset<std::string> profiles;
239 
240  // Will be satisfied whenever `data` is changed.
242 };
243 
244 } // namespace profile {
245 } // namespace internal {
246 } // namespace mesos {
247 
248 #endif // __RESOURCE_PROVIDER_URI_DISK_PROFILE_HPP__
Definition: uri_disk_profile.hpp:174
Definition: errorbase.hpp:35
static Try< URL > parse(const std::string &urlString)
virtual void initialize() override
Invoked when a process gets spawned.
Flags flags
Definition: uri_disk_profile.hpp:190
Definition: try.hpp:34
Definition: uri_disk_profile.hpp:50
virtual process::Future< hashset< std::string > > watch(const hashset< std::string > &knownProfiles, const std::string &csiPluginInfoType) override
Returns a future that will be satisifed iff the set of profiles known by the module differs from the ...
Definition: duration.hpp:32
bool isSome() const
Definition: option.hpp:115
Path uri
Definition: uri_disk_profile.hpp:155
bool contains(const std::string &s, const std::string &substr)
Definition: strings.hpp:406
Option< Duration > poll_interval
Definition: uri_disk_profile.hpp:157
Duration max_random_wait
Definition: uri_disk_profile.hpp:158
Represents a POSIX or Windows file system path and offers common path manipulations.
Definition: path.hpp:145
Definition: duration.hpp:259
Definition: flags.hpp:44
const T & get() const &
Definition: option.hpp:118
This module is used by Storage Resource Providers to translate the &quot;profile&quot; field of a Resource::Dis...
Definition: disk_profile.hpp:50
process::Owned< UriDiskProfileAdaptorProcess > process
Definition: uri_disk_profile.hpp:191
bool absolute() const
Definition: path.hpp:306
process::Future< hashset< std::string > > watch(const hashset< std::string > &knownProfiles, const std::string &csiPluginInfoType)
static Try error(const E &e)
Definition: try.hpp:42
process::Future< mesos::DiskProfileAdaptor::ProfileInfo > translate(const std::string &profile, const std::string &csiPluginInfoType)
Definition: uri_disk_profile.hpp:195
#define flags
Definition: decoder.hpp:18
Definition: none.hpp:27
bool isError() const
Definition: try.hpp:71
void add(T1 Flags::*t1, const Name &name, const Option< Name > &alias, const std::string &help, const T2 *t2, F validate)
Definition: flags.hpp:333
virtual process::Future< mesos::DiskProfileAdaptor::ProfileInfo > translate(const std::string &profile, const std::string &csiPluginInfoType) override
Called before a Storage Resource Provider makes an affected CSI request.
Definition: owned.hpp:35
bool startsWith(const std::string &s, const std::string &prefix)
Definition: strings.hpp:380
Definition: process.hpp:493
const std::string & string() const
Definition: path.hpp:317
Flags()
Definition: uri_disk_profile.hpp:52
Definition: future.hpp:57