Apache Mesos
provisioner.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 __PROVISIONER_HPP__
18 #define __PROVISIONER_HPP__
19 
20 #include <vector>
21 
22 #include <mesos/resources.hpp>
23 
24 #include <mesos/appc/spec.hpp>
25 
26 #include <mesos/docker/v1.hpp>
27 
29 
30 #include <mesos/slave/isolator.hpp> // For ContainerState.
31 
32 #include <stout/nothing.hpp>
33 #include <stout/path.hpp>
34 #include <stout/try.hpp>
35 
36 #include <process/future.hpp>
37 #include <process/owned.hpp>
38 #include <process/rwlock.hpp>
39 
42 
43 #include "slave/flags.hpp"
44 
46 
48 
49 namespace mesos {
50 namespace internal {
51 namespace slave {
52 
53 // Forward declaration.
54 class Backend;
55 class ProvisionerProcess;
56 class Store;
57 
58 // Provision info struct includes root filesystem for the container
59 // with specified image, all image manifests that include runtime
60 // configurations from the image will be passed to Mesos Containerizer.
62 {
63  std::string rootfs;
64 
65  // Ephemeral volumes are any additional paths the Provisioner backend
66  // may have created that should be counted towards the sandbox disk quota.
68 
69  // Docker v1 image manifest.
71 
72  // Appc image manifest.
74 };
75 
76 
78 {
79 public:
80  // Create the provisioner based on the specified flags.
82  const Flags& flags,
83  SecretResolver* secretResolver = nullptr);
84 
85  // This allows the backend to be mocked for testing.
87  const Flags& flags,
88  const std::string& rootDir,
89  const std::string& defaultBackend,
90  const hashmap<std::string, process::Owned<Backend>>& backends,
91  SecretResolver* secretResolver = nullptr);
92 
93  // Available only for testing.
95 
96  // NOTE: Made 'virtual' for mocking and testing.
97  virtual ~Provisioner();
98 
99  // Recover root filesystems for containers from the known
100  // containers (forked by the launcher) detected by the
101  // launcher. This function is also responsible for cleaning
102  // up any intermediate artifacts (e.g. directories) to not
103  // leak anything.
105  const hashset<ContainerID>& knownContainerIds) const;
106 
107  // Provision a root filesystem for the container using the specified
108  // image and return the absolute path to the root filesystem.
109  virtual process::Future<ProvisionInfo> provision(
110  const ContainerID& containerId,
111  const Image& image) const;
112 
113  // Destroy a previously provisioned root filesystem. Assumes that
114  // all references (e.g., mounts, open files) to the provisioned
115  // filesystem have been removed. Return false if there is no
116  // provisioned root filesystem for the given container.
117  virtual process::Future<bool> destroy(const ContainerID& containerId) const;
118 
119  // Prune images in different stores. Image references in excludedImages
120  // will be passed to stores and retained in a best effort fashion.
121  // All layer paths used by active containers will not be pruned.
122  virtual process::Future<Nothing> pruneImages(
123  const std::vector<Image>& excludedImages) const;
124 
125 protected:
126  Provisioner() {} // For creating mock object.
127 
128 private:
129  Provisioner(const Provisioner&) = delete; // Not copyable.
130  Provisioner& operator=(const Provisioner&) = delete; // Not assignable.
131 
133 };
134 
135 
136 // Expose this class for testing only.
137 class ProvisionerProcess : public process::Process<ProvisionerProcess>
138 {
139 public:
141  const std::string& rootDir,
142  const std::string& defaultBackend,
143  const hashmap<Image::Type, process::Owned<Store>>& stores,
144  const hashmap<std::string, process::Owned<Backend>>& backends);
145 
147  const hashset<ContainerID>& knownContainerIds);
148 
150  const ContainerID& containerId,
151  const Image& image);
152 
153  process::Future<bool> destroy(const ContainerID& containerId);
154 
155  process::Future<Nothing> pruneImages(
156  const std::vector<Image>& excludedImages);
157 
158 private:
160  const ContainerID& containerId,
161  const Image& image,
162  const std::string& backend,
163  const ImageInfo& imageInfo);
164 
165  process::Future<bool> _destroy(
166  const ContainerID& containerId,
167  const std::vector<process::Future<bool>>& destroys);
168 
169  void __destroy(
170  const ContainerID& containerId,
171  const process::Future<std::vector<process::Future<bool>>>& futures);
172 
173  // Absolute path to the provisioner root directory. It can be
174  // derived from '--work_dir' but we keep a separate copy here
175  // because we converted it into an absolute path so managed rootfs
176  // paths match the ones in 'mountinfo' (important if mount-based
177  // backends are used).
178  const std::string rootDir;
179 
180  // The default provisioner backend, using the following logic:
181  // 1. Use `--image_provisioner_backend` if it is set.
182  // 2. Use overlayfs backend if it exists.
183  // 3. Use aufs backend if the overlayfs does not exist.
184  // 4. Use copy backend of both overlayfs and aufs do not exist.
185  const std::string defaultBackend;
186 
189 
190  struct Info
191  {
192  // Mappings: backend -> {rootfsId, ...}
194 
195  // TODO(zhitao): Remove Option after the deprecation cycle
196  // started in 1.5.
198 
199  // We keep track of the future for 'backend->provision' so
200  // that destroy will only start calling 'backend->destroy'
201  // after 'backend->provision' has finished.
202  process::Future<ProvisionInfo> provisioning;
203 
204  process::Promise<bool> termination;
205 
206  // The container status in provisioner.
207  bool destroying = false;
208  };
209 
211 
212  struct Metrics
213  {
214  Metrics();
215  ~Metrics();
216 
217  process::metrics::Counter remove_container_errors;
218  } metrics;
219 
220  // This `ReadWriteLock` instance is used to protect the critical section which
221  // is the layers in the store directory (i.e. `--docker_store_dir`/layers/).
222  // Any `provision` and `destroy` can happen concurrently since they are not
223  // expected to touch the critical section simultaneously.
224  //
225  // On the other hand, `pruneImages` needs to know all active layers from all
226  // containers, therefore it must be exclusive to other `provision`, `destroy`
227  // and `pruneImages` so that we do not prune image layers which are used by an
228  // active `provision` or `destroy`.
229  process::ReadWriteLock rwLock;
230 };
231 
232 } // namespace slave {
233 } // namespace internal {
234 } // namespace mesos {
235 
236 #endif // __PROVISIONER_HPP__
Protocol< RecoverRequest, RecoverResponse > recover
Definition: option.hpp:29
Definition: check.hpp:33
Provisioner()
Definition: provisioner.hpp:126
Option< std::vector< Path > > ephemeralVolumes
Definition: provisioner.hpp:67
Definition: flags.hpp:39
Option<::docker::spec::v1::ImageManifest > dockerManifest
Definition: provisioner.hpp:70
Definition: counter.hpp:26
Definition: store.hpp:45
Definition: hashmap.hpp:38
Option<::appc::spec::ImageManifest > appcManifest
Definition: provisioner.hpp:73
Try< std::vector< Info > > infos(int familiy, int states)
std::string rootfs
Definition: provisioner.hpp:63
Definition: agent.hpp:25
Definition: provisioner.hpp:137
process::Future< Nothing > destroy(const std::string &hierarchy, const std::string &cgroup="/")
Result< Process > process(pid_t pid)
Definition: freebsd.hpp:30
Definition: provisioner.hpp:61
URI image(const std::string &repository, const std::string &reference, const std::string &registry, const Option< std::string > &scheme=None(), const Option< int > &port=None())
Definition: docker.hpp:30
Definition: attributes.hpp:24
Definition: executor.hpp:48
Type
Definition: capabilities.hpp:79
ReadWriteLock is a lock that allows concurrent reads and exclusive writes.
Definition: rwlock.hpp:36
JSON::Object Metrics()
Try< Nothing > create(const std::string &hierarchy, const std::string &cgroup, bool recursive=false)
Definition: resolver.hpp:34
Definition: owned.hpp:36
Definition: process.hpp:505
Definition: parse.hpp:33
PID< MetricsProcess > metrics
Definition: provisioner.hpp:77