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 <list>
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/try.hpp>
34 
35 #include <process/future.hpp>
36 #include <process/owned.hpp>
37 #include <process/rwlock.hpp>
38 
41 
42 #include "slave/flags.hpp"
43 
45 
47 
48 namespace mesos {
49 namespace internal {
50 namespace slave {
51 
52 // Forward declaration.
53 class Backend;
54 class ProvisionerProcess;
55 class Store;
56 
57 // Provision info struct includes root filesystem for the container
58 // with specified image, all image manifests that include runtime
59 // configurations from the image will be passed to Mesos Containerizer.
61 {
62  std::string rootfs;
63 
64  // Docker v1 image manifest.
66 
67  // Appc image manifest.
69 };
70 
71 
73 {
74 public:
75  // Create the provisioner based on the specified flags.
77  const Flags& flags,
78  SecretResolver* secretResolver = nullptr);
79 
80  // Available only for testing.
82 
83  // NOTE: Made 'virtual' for mocking and testing.
84  virtual ~Provisioner();
85 
86  // Recover root filesystems for containers from the known
87  // containers (forked by the launcher) detected by the
88  // launcher. This function is also responsible for cleaning
89  // up any intermediate artifacts (e.g. directories) to not
90  // leak anything.
92  const hashset<ContainerID>& knownContainerIds) const;
93 
94  // Provision a root filesystem for the container using the specified
95  // image and return the absolute path to the root filesystem.
97  const ContainerID& containerId,
98  const Image& image) const;
99 
100  // Destroy a previously provisioned root filesystem. Assumes that
101  // all references (e.g., mounts, open files) to the provisioned
102  // filesystem have been removed. Return false if there is no
103  // provisioned root filesystem for the given container.
104  virtual process::Future<bool> destroy(const ContainerID& containerId) const;
105 
106  // Prune images in different stores. Image references in excludedImages
107  // will be passed to stores and retained in a best effort fashion.
108  // All layer paths used by active containers will not be pruned.
110  const std::vector<Image>& excludedImages) const;
111 
112 protected:
113  Provisioner() {} // For creating mock object.
114 
115 private:
116  Provisioner(const Provisioner&) = delete; // Not copyable.
117  Provisioner& operator=(const Provisioner&) = delete; // Not assignable.
118 
120 };
121 
122 
123 // Expose this class for testing only.
124 class ProvisionerProcess : public process::Process<ProvisionerProcess>
125 {
126 public:
128  const std::string& rootDir,
129  const std::string& defaultBackend,
130  const hashmap<Image::Type, process::Owned<Store>>& stores,
131  const hashmap<std::string, process::Owned<Backend>>& backends);
132 
134  const hashset<ContainerID>& knownContainerIds);
135 
137  const ContainerID& containerId,
138  const Image& image);
139 
140  process::Future<bool> destroy(const ContainerID& containerId);
141 
143  const std::vector<Image>& excludedImages);
144 
145 private:
147  const ContainerID& containerId,
148  const Image& image,
149  const std::string& backend,
150  const ImageInfo& imageInfo);
151 
152  process::Future<bool> _destroy(
153  const ContainerID& containerId,
154  const std::list<process::Future<bool>>& destroys);
155 
156  process::Future<bool> __destroy(const ContainerID& containerId);
157 
158  // Absolute path to the provisioner root directory. It can be
159  // derived from '--work_dir' but we keep a separate copy here
160  // because we converted it into an absolute path so managed rootfs
161  // paths match the ones in 'mountinfo' (important if mount-based
162  // backends are used).
163  const std::string rootDir;
164 
165  // The default provisioner backend, using the following logic:
166  // 1. Use `--image_provisioner_backend` if it is set.
167  // 2. Use overlayfs backend if it exists.
168  // 3. Use aufs backend if the overlayfs does not exist.
169  // 4. Use copy backend of both overlayfs and aufs do not exist.
170  const std::string defaultBackend;
171 
174 
175  struct Info
176  {
177  // Mappings: backend -> {rootfsId, ...}
179 
180  // TODO(zhitao): Remove Option after the deprecation cycle
181  // started in 1.5.
183 
184  process::Promise<bool> termination;
185 
186  // The container status in provisioner.
187  bool destroying = false;
188  };
189 
191 
192  struct Metrics
193  {
194  Metrics();
195  ~Metrics();
196 
197  process::metrics::Counter remove_container_errors;
198  } metrics;
199 
200  // This `ReadWriteLock` instance is used to protect the critical
201  // section, which includes store directory and provision directory.
202  // Because `provision` and `destroy` are scoped by `containerId`,
203  // they are not expected to touch the same critical section
204  // simultaneously, so any `provision` and `destroy` can happen concurrently.
205  // This is guaranteed by Mesos containerizer, e.g., a `destroy` will always
206  // wait for a container's `provision` to finish, then do the cleanup.
207  //
208  // On the other hand, `pruneImages` needs to know all active layers from all
209  // containers, therefore it must be exclusive to other `provision`, `destroy`
210  // and `pruneImages` so that we do not prune image layers which is used by an
211  // active `provision` or `destroy`.
212  process::ReadWriteLock rwLock;
213 };
214 
215 } // namespace slave {
216 } // namespace internal {
217 } // namespace mesos {
218 
219 #endif // __PROVISIONER_HPP__
virtual process::Future< bool > destroy(const ContainerID &containerId) const
Definition: try.hpp:34
Provisioner()
Definition: provisioner.hpp:113
process::Future< Nothing > recover(const hashset< ContainerID > &knownContainerIds)
Definition: flags.hpp:39
static Try< process::Owned< Provisioner > > create(const Flags &flags, SecretResolver *secretResolver=nullptr)
Option<::docker::spec::v1::ImageManifest > dockerManifest
Definition: provisioner.hpp:65
Definition: counter.hpp:26
Definition: store.hpp:45
Definition: hashmap.hpp:38
Option<::appc::spec::ImageManifest > appcManifest
Definition: provisioner.hpp:68
std::string rootfs
Definition: provisioner.hpp:62
process::Future< ProvisionInfo > provision(const ContainerID &containerId, const Image &image)
Definition: provisioner.hpp:124
ProvisionerProcess(const std::string &rootDir, const std::string &defaultBackend, const hashmap< Image::Type, process::Owned< Store >> &stores, const hashmap< std::string, process::Owned< Backend >> &backends)
Try< std::vector< Entry > > list(const std::string &hierarchy, const std::string &cgroup)
process::Future< bool > destroy(const ContainerID &containerId)
virtual process::Future< ProvisionInfo > provision(const ContainerID &containerId, const Image &image) const
#define flags
Definition: decoder.hpp:18
Definition: provisioner.hpp:60
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
Type
Definition: capabilities.hpp:79
virtual process::Future< Nothing > recover(const hashset< ContainerID > &knownContainerIds) const
ReadWriteLock is a lock that allows concurrent reads and exclusive writes.
Definition: rwlock.hpp:36
JSON::Object Metrics()
Definition: resolver.hpp:34
process::Future< Nothing > pruneImages(const std::vector< Image > &excludedImages)
Definition: owned.hpp:35
virtual process::Future< Nothing > pruneImages(const std::vector< Image > &excludedImages) const
Definition: process.hpp:493
Definition: provisioner.hpp:72