Apache Mesos
v1_volume_manager_process.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 __CSI_V1_VOLUME_MANAGER_PROCESS_HPP__
18 #define __CSI_V1_VOLUME_MANAGER_PROCESS_HPP__
19 
20 #include <string>
21 #include <vector>
22 
23 #include <google/protobuf/map.h>
24 
25 #include <mesos/mesos.hpp>
26 
28 
29 #include <process/future.hpp>
30 #include <process/grpc.hpp>
31 #include <process/http.hpp>
32 #include <process/loop.hpp>
33 #include <process/owned.hpp>
34 #include <process/process.hpp>
35 #include <process/sequence.hpp>
36 
37 #include <stout/bytes.hpp>
38 #include <stout/duration.hpp>
39 #include <stout/error.hpp>
40 #include <stout/hashmap.hpp>
41 #include <stout/hashset.hpp>
42 #include <stout/nothing.hpp>
43 #include <stout/option.hpp>
44 #include <stout/try.hpp>
45 
46 #include "csi/metrics.hpp"
47 #include "csi/service_manager.hpp"
48 #include "csi/state.hpp"
49 #include "csi/v1_client.hpp"
50 #include "csi/v1_utils.hpp"
52 #include "csi/volume_manager.hpp"
53 
54 namespace mesos {
55 namespace csi {
56 namespace v1 {
57 
58 class VolumeManagerProcess : public process::Process<VolumeManagerProcess>
59 {
60 public:
61  explicit VolumeManagerProcess(
62  const std::string& _rootDir,
63  const CSIPluginInfo& _info,
64  const hashset<Service> _services,
65  const process::grpc::client::Runtime& _runtime,
66  ServiceManager* _serviceManager,
67  Metrics* _metrics,
68  SecretResolver* _secretResolver);
69 
71 
73 
75  const CSIVolume::VolumeCapability& capability,
76  const google::protobuf::Map<std::string, std::string>& parameters);
77 
79  const std::string& name,
80  const Bytes& capacity,
81  const CSIVolume::VolumeCapability& capability,
82  const google::protobuf::Map<std::string, std::string>& parameters);
83 
85  const VolumeInfo& volumeInfo,
86  const CSIVolume::VolumeCapability& capability,
87  const google::protobuf::Map<std::string, std::string>& parameters);
88 
89  process::Future<bool> deleteVolume(const std::string& volumeId);
90 
91  process::Future<Nothing> attachVolume(const std::string& volumeId);
92 
93  process::Future<Nothing> detachVolume(const std::string& volumeId);
94 
96  const std::string& volumeId,
97  const Option<state::VolumeState>& volumeState = None());
98 
99  process::Future<Nothing> unpublishVolume(const std::string& volumeId);
100 
101  // Wrapper functions to make CSI calls and update RPC metrics. Made public for
102  // testing purpose.
103  //
104  // The call is made asynchronously and thus no guarantee is provided on the
105  // order in which calls are sent. Callers need to either ensure to not have
106  // multiple conflicting calls in flight, or treat results idempotently.
107  //
108  // NOTE: We currently ensure this by 1) resource locking to forbid concurrent
109  // calls on the same volume, and 2) no profile update while there are ongoing
110  // `CREATE_DISK` or `DESTROY_DISK` operations.
111  template <typename Request, typename Response>
113  const Service& service,
114  process::Future<RPCResult<Response>> (Client::*rpc)(Request),
115  const Request& request,
116  bool retry = false);
117 
118  template <typename Request, typename Response>
120  const std::string& endpoint,
121  process::Future<RPCResult<Response>> (Client::*rpc)(Request),
122  const Request& request);
123 
124  template <typename Response>
126  const RPCResult<Response>& result, const Option<Duration>& backoff);
127 
128 private:
129  process::Future<Nothing> prepareServices();
130 
131  process::Future<bool> _deleteVolume(const std::string& volumeId);
132  process::Future<bool> __deleteVolume(const std::string& volumeId);
133 
134  // The following methods are used to manage volume lifecycles. Transient
135  // states are omitted.
136  //
137  // +------------+
138  // + + + | CREATED | ^
139  // | | | +---+----^---+ |
140  // _attachVolume | | | | | | _detachVolume
141  // | | | +---v----+---+ |
142  // v + + | NODE_READY | + ^
143  // | | +---+----^---+ | |
144  // __publishVolume | | | | | | _unpublishVolume
145  // | | +---v----+---+ | |
146  // v + | VOL_READY | + + ^
147  // | +---+----^---+ | | |
148  // _publishVolume | | | | | | __unpublishVolume
149  // | +---v----+---+ | | |
150  // V | PUBLISHED | + + +
151  // +------------+
152 
153  // Transition a volume to `NODE_READY` state from any state above.
154  process::Future<Nothing> _attachVolume(const std::string& volumeId);
155 
156  // Transition a volume to `CREATED` state from any state below.
157  process::Future<Nothing> _detachVolume(const std::string& volumeId);
158 
159  // Transition a volume to `PUBLISHED` state from any state above.
160  process::Future<Nothing> _publishVolume(const std::string& volumeId);
161 
162  // Transition a volume to `VOL_READY` state from any state above.
163  process::Future<Nothing> __publishVolume(const std::string& volumeId);
164 
165  // Transition a volume to `NODE_READY` state from any state below.
166  process::Future<Nothing> _unpublishVolume(const std::string& volumeId);
167 
168  // Transition a volume to `VOL_READY` state from any state below.
169  process::Future<Nothing> __unpublishVolume(const std::string& volumeId);
170 
171  void checkpointVolumeState(const std::string& volumeId);
172 
173  void garbageCollectMountPath(const std::string& volumeId);
174 
175  // Removes the metadata associated with a particular volume both
176  // from memory and from disk.
177  void removeVolume(const std::string& volumeId);
178 
179  // If the volume manager was initialized with a non-null secret resolver, this
180  // helper function will resolve any secrets in the provided map.
181  // Returns a map containing the resolved secrets.
183  resolveSecrets(
184  const google::protobuf::Map<std::string, Secret>& secrets);
185 
186  const std::string rootDir;
187  const CSIPluginInfo info;
188  const hashset<Service> services;
189 
191  ServiceManager* serviceManager;
192  Metrics* metrics;
193  SecretResolver* secretResolver;
194  const std::string mountRootDir;
195 
196  Option<std::string> bootId;
197  Option<PluginCapabilities> pluginCapabilities;
198  Option<ControllerCapabilities> controllerCapabilities;
199  Option<NodeCapabilities> nodeCapabilities;
200  Option<std::string> nodeId;
201 
202  struct VolumeData
203  {
204  VolumeData(state::VolumeState&& _state)
205  : state(_state), sequence(new process::Sequence("csi-volume-sequence")) {}
206 
207  state::VolumeState state;
208 
209  // We call all CSI operations on the same volume in a sequence to ensure
210  // that they are processed in a sequential order.
212  };
213 
215 };
216 
217 } // namespace v1 {
218 } // namespace csi {
219 } // namespace mesos {
220 
221 #endif // __CSI_V1_VOLUME_MANAGER_PROCESS_HPP__
Definition: option.hpp:29
process::Future< Nothing > detachVolume(const std::string &volumeId)
Future< Response > request(const Request &request, bool streamedResponse=false)
Asynchronously sends an HTTP request to the process and returns the HTTP response once the entire res...
process::Future< Option< Error > > validateVolume(const VolumeInfo &volumeInfo, const CSIVolume::VolumeCapability &capability, const google::protobuf::Map< std::string, std::string > &parameters)
Definition: check.hpp:33
process::Future< Nothing > unpublishVolume(const std::string &volumeId)
process::Future< RPCResult< Response > > _call(const std::string &endpoint, process::Future< RPCResult< Response >>(Client::*rpc)(Request), const Request &request)
Definition: volume_manager.hpp:48
process::Future< Bytes > getCapacity(const CSIVolume::VolumeCapability &capability, const google::protobuf::Map< std::string, std::string > &parameters)
process::Future< process::ControlFlow< Response > > __call(const RPCResult< Response > &result, const Option< Duration > &backoff)
Definition: metrics.hpp:28
Definition: v0.hpp:49
VolumeManagerProcess(const std::string &_rootDir, const CSIPluginInfo &_info, const hashset< Service > _services, const process::grpc::client::Runtime &_runtime, ServiceManager *_serviceManager, Metrics *_metrics, SecretResolver *_secretResolver)
Definition: sequence.hpp:33
Definition: v1_client.hpp:35
process::Future< VolumeInfo > createVolume(const std::string &name, const Bytes &capacity, const CSIVolume::VolumeCapability &capability, const google::protobuf::Map< std::string, std::string > &parameters)
process::Future< Nothing > recover()
A copyable interface to manage an internal runtime process for asynchronous gRPC calls.
Definition: grpc.hpp:157
Definition: agent.hpp:25
process::Future< bool > deleteVolume(const std::string &volumeId)
process::Future< Response > call(const Service &service, process::Future< RPCResult< Response >>(Client::*rpc)(Request), const Request &request, bool retry=false)
Definition: none.hpp:27
process::Future< Nothing > attachVolume(const std::string &volumeId)
CSIPluginContainerInfo::Service Service
Definition: service_manager.hpp:38
process::Future< Nothing > publishVolume(const std::string &volumeId, const Option< state::VolumeState > &volumeState=None())
Definition: v1_volume_manager_process.hpp:58
Definition: resolver.hpp:34
Definition: bytes.hpp:30
Definition: process.hpp:505
Definition: service_manager.hpp:51
constexpr const char * name
Definition: shell.hpp:41
process::Future< std::vector< VolumeInfo > > listVolumes()