softwarecontainer  0.18.0-739e8d7 2017-05-04
softwarecontainer::SoftwareContainer Class Reference

An abstraction of concrete container implementations. More...

#include <softwarecontainer.h>

Inheritance diagram for softwarecontainer::SoftwareContainer:
[legend]
Collaboration diagram for softwarecontainer::SoftwareContainer:
[legend]

Public Member Functions

 LOG_DECLARE_CLASS_CONTEXT ("PCL","SoftwareContainer library")
 
 SoftwareContainer (const ContainerID id, std::unique_ptr< const SoftwareContainerConfig > config)
 Creates a new SoftwareContainer instance. More...
 
bool startGateways (const GatewayConfiguration &configs)
 Starts the Gateways by setting the gateway configurations and activating the configured gateway. More...
 
std::shared_ptr< FunctionJobcreateFunctionJob (const std::function< int()> fun)
 Create a job that can run a function in a container. More...
 
std::shared_ptr< CommandJobcreateCommandJob (const std::string &command)
 Create a job that can run a command in a container. More...
 
void shutdown ()
 Shut down the container. More...
 
void shutdown (unsigned int timeout)
 Shot down the container with an explicit timeout. More...
 
void suspend ()
 Suspend the container. More...
 
void resume ()
 Resume a suspended container. More...
 
bool bindMount (const std::string &pathOnHost, const std::string &pathInContainer, bool readonly=true)
 Should only be called on containers in state 'READY'. More...
 
ObservableProperty< ContainerState > & getContainerState ()
 Get the state of this container instance. More...
 
bool previouslyConfigured ()
 Indicates if gateways have been configured previously. More...
 

Private Member Functions

bool bindMount (const std::string &src, const std::string &dst, const std::string &tmpContainerRoot, bool readOnly, bool writeBufferEnabled=false)
 bindMount Bind mount a src directory to another position dst. More...
 
bool tmpfsMount (const std::string dst, const int maxSize)
 tmpfsMount Mount a tmpfs in the dst path and limit size of the tmpfs to maxSize More...
 
bool writeToFile (const std::string &path, const std::string &content)
 
void markFileForDeletion (const std::string &path)
 
bool overlayMount (const std::string &lower, const std::string &upper, const std::string &work, const std::string &dst)
 overlayMount Mount a directory with an overlay on top of it. More...
 
bool syncOverlayMount (const std::string &lower, const std::string &upper)
 syncOverlayMount Copy the directory structure from upper layer to the lower layer More...
 
bool createSharedMountPoint (const std::string &path)
 createSharedMountPoint Make the mount point shared, ie new mount points created in one bind mount will also be created in the other mount point. More...
 
bool pathInList (const std::string path)
 checks whether given path is already added to clean up handlers or not More...
 

Private Attributes

std::vector< std::unique_ptr< CleanUpHandler > > m_cleanupHandlers
 m_cleanupHandlers A vector of cleanupHandlers added during the lifetime of the FileToolKitWithUndo that will be run from the destructor. More...
 
std::vector< std::unique_ptr< CreateDir > > m_createDirList
 m_createDirList A vector of CreateDir classes. More...
 

Detailed Description

An abstraction of concrete container implementations.

SoftwareContainer (SC) can be in various states. Some method calls are only valid when SC is in a particular state.

States:

  • READY
  • SUSPENDED
  • TERMINATED
  • INVALID

When SC is in state 'READY', all relevant gateways are added and the underlying container implementation is created and initialized. In this state, the following methods are allowed to be called:

When SC is in state 'SUSPENDED', the following method calls are allowed to be called:

  • shutdown() - successful call triggers a transition to TERMINATED
  • resume() - successful call triggers a transition to READY

When SC is in state 'INVALID', something has gone wrong in the underlying container implementation and the container should be considered to be in a broken state from which it cannot recover.

The following methods are allowed to be called in every state:

If a call is made when SC is in an inappropriate state, the InvalidOperationError exception is thrown. This error does not mean that the intended operation was erroneous, since the operation can't even be performed in the current state.

It is an error to call a method on a state which would be the result of the operation, e.g. calling suspend on a suspended container is an invalid operation. The reason for this is that the interface should be clear that there can't be any side effects or other changes when making a call which is redundant.

Definition at line 165 of file softwarecontainer.h.

Constructor & Destructor Documentation

softwarecontainer::SoftwareContainer::SoftwareContainer ( const ContainerID  id,
std::unique_ptr< const SoftwareContainerConfig config 
)

Creates a new SoftwareContainer instance.

On successful creation, the state will be 'READY'.

Parameters
idThe containerID to use.
configAn object holding all needed settings for the container
Exceptions
SoftwareContainerErrorIf unable to set up the needed directories or network settings for this container, or if anything goes wrong when creating and initializing the underlying container implementation.

Definition at line 58 of file softwarecontainer.cpp.

References softwarecontainer::FileToolkitWithUndo::tmpfsMount().

59  :
60  m_containerID(id),
61  m_config(std::move(config)),
62  m_previouslyConfigured(false)
63 {
64  m_containerRoot = buildPath(m_config->sharedMountsDir(), "SC-" + std::to_string(id));
65  m_tmpfsSize = 100485760;
66  checkContainerRoot(m_containerRoot);
67  if (m_config->writeBufferEnabled()) {
68  if (m_config->temporaryFileSystemWriteBufferEnableds()) {
69  m_tmpfsSize = m_config->temporaryFileSystemSize();
70  }
71  tmpfsMount(m_containerRoot, m_tmpfsSize);
72  }
73 
74 #ifdef ENABLE_NETWORKGATEWAY
75  checkNetworkSettings();
76 #endif // ENABLE_NETWORKGATEWAY
77 
78  m_container = std::shared_ptr<ContainerAbstractInterface>(
79  new Container("SC-" + std::to_string(id),
80  m_config->containerConfigPath(),
81  m_containerRoot,
82  m_config->writeBufferEnabled(),
83  m_config->containerShutdownTimeout()));
84 
85  if(!init()) {
86  throw SoftwareContainerError("Could not initialize SoftwareContainer, container ID: "
87  + std::to_string(id));
88  }
89 
90  m_containerState.setValueNotify(ContainerState::READY);
91 }
bool tmpfsMount(const std::string dst, const int maxSize)
tmpfsMount Mount a tmpfs in the dst path and limit size of the tmpfs to maxSize

Here is the call graph for this function:

Member Function Documentation

bool softwarecontainer::SoftwareContainer::startGateways ( const GatewayConfiguration configs)
virtual

Starts the Gateways by setting the gateway configurations and activating the configured gateway.

This should only be called on containers in state 'READY'

Returns
true If configuration and activation was successful
false If configuration or activation encountered a non-fatal error
Exceptions
GatewayErrorIf configuration or activation of any gateway encountered a fatal error.
InvalidOperationErrorIf called when state is not 'READY'
InvalidContainerErrorIf the container is in state 'INVALID'

Implements softwarecontainer::SoftwareContainerAbstractInterface.

Definition at line 174 of file softwarecontainer.cpp.

175 {
176  assertValidState();
177 
178  if (m_containerState != ContainerState::READY) {
179  std::string message = "Invalid to start gateways on non ready container " +
180  std::string(m_container->id());
181  log_error() << message;
182  throw InvalidOperationError(message);
183  }
184 
185  if (!configureGateways(gwConfig)) {
186  log_error() << "Could not configure Gateways";
187  return false;
188  }
189 
190  if (!activateGateways()) {
191  log_error() << "Could not activate Gateways";
192  return false;
193  }
194 
195  // Keep track of if user has called this method at least once
196  m_previouslyConfigured = true;
197 
198  return true;
199 }
std::shared_ptr< FunctionJob > softwarecontainer::SoftwareContainer::createFunctionJob ( const std::function< int()>  fun)

Create a job that can run a function in a container.

This should only be called on containers in state 'READY'

Exceptions
InvalidOperationErrorIf called when state is not 'READY'
InvalidContainerErrorIf the container is in state 'INVALID'

Definition at line 391 of file softwarecontainer.cpp.

392 {
393  assertValidState();
394 
395  if (m_containerState != ContainerState::READY) {
396  std::string message = "Invalid to execute code in non ready container " +
397  std::string(m_container->id());
398  log_error() << message;
399  throw InvalidOperationError(message);
400  }
401 
402  return std::make_shared<FunctionJob>(m_container, fun);
403 }
std::shared_ptr< CommandJob > softwarecontainer::SoftwareContainer::createCommandJob ( const std::string &  command)
virtual

Create a job that can run a command in a container.

This should only be called on containers in state 'READY'

Exceptions
InvalidOperationErrorIf called when state is not 'READY'
InvalidContainerErrorIf the container is in state 'INVALID'

Implements softwarecontainer::SoftwareContainerAbstractInterface.

Definition at line 405 of file softwarecontainer.cpp.

406 {
407  assertValidState();
408 
409  if (m_containerState != ContainerState::READY) {
410  std::string message = "Invalid to execute code in non ready container " +
411  std::string(m_container->id());
412  log_error() << message;
413  throw InvalidOperationError(message);
414  }
415 
416  return std::make_shared<CommandJob>(m_container, command);
417 }
void softwarecontainer::SoftwareContainer::shutdown ( )

Shut down the container.

A successful call to this method triggers a transition to state 'TERMINATED'.

This shoud only be called on containers in state 'READY' or 'SUSPENDED'

If the operation is not successful, the container state will be set to 'INVALID'. This means that this container instance should be considered broken.

Exceptions
ContainerErrorIf operation was unsucessful InvalidOperationError If called when state is not 'READY' or 'SUSPENDED'
InvalidContainerErrorIf the container is in state 'INVALID'

Definition at line 277 of file softwarecontainer.cpp.

278 {
279  return shutdown(m_config->containerShutdownTimeout());
280 }
void shutdown()
Shut down the container.
void softwarecontainer::SoftwareContainer::shutdown ( unsigned int  timeout)
virtual

Shot down the container with an explicit timeout.

Same as the shutdown() method, but the value passed will override any timeout value in the main configuration.

Parameters
timeoutSeconds to use for timeout

Implements softwarecontainer::SoftwareContainerAbstractInterface.

Definition at line 282 of file softwarecontainer.cpp.

283 {
284  assertValidState();
285 
286  log_debug() << "shutdown called";
287 
288  if (m_containerState != ContainerState::READY
289  && m_containerState != ContainerState::SUSPENDED)
290  {
291  std::string message = "Invalid to shut down container which is not ready or suspended " +
292  std::string(m_container->id());
293  log_error() << message;
294  throw InvalidOperationError(message);
295  }
296 
297  if(!shutdownGateways()) {
298  log_error() << "Could not shut down all gateways cleanly, check the log";
299  }
300 
301  if(!m_container->destroy(timeout)) {
302  std::string message = "Could not destroy the container during shutdown " +
303  std::string(m_container->id());
304  log_error() << message;
305  m_containerState.setValueNotify(ContainerState::INVALID);
306  throw ContainerError(message);
307  }
308 
309  m_containerState.setValueNotify(ContainerState::TERMINATED);
310 }
void softwarecontainer::SoftwareContainer::suspend ( )
virtual

Suspend the container.

This suspends any execution inside the container until resume is called. A successful call to this method triggers a transition to state 'SUSPENDED'.

If the operation is not successful, the container state will be set to 'INVALID'. This means that this container instance should be considered broken.

Exceptions
ContainerErrorIf operation was unsuccessful
InvalidOperationErrorIf called when state is not 'READY'
InvalidContainerErrorIf the container is in state 'INVALID'

Implements softwarecontainer::SoftwareContainerAbstractInterface.

Definition at line 312 of file softwarecontainer.cpp.

313 {
314  assertValidState();
315 
316  std::string id = std::string(m_container->id());
317 
318  if (m_containerState != ContainerState::READY) {
319  std::string message = "Invalid to suspend non ready container " + id;
320  log_error() << message;
321  throw InvalidOperationError(message);
322  }
323 
324  if (!m_container->suspend()) {
325  std::string message = "Failed to suspend container " + id;
326  log_error() << message;
327  m_containerState.setValueNotify(ContainerState::INVALID);
328  throw ContainerError(message);
329  }
330 
331  log_debug() << "Suspended container " << id;
332  m_containerState.setValueNotify(ContainerState::SUSPENDED);
333 }
void softwarecontainer::SoftwareContainer::resume ( )
virtual

Resume a suspended container.

This resumes execution of a container that was suspended. A successful call to this method will trigger a transition to state 'READY'.

If the operation is not successful, the container state will be set to 'INVALID'. This means that this container instance should be considered broken.

Exceptions
ContainerErrorIf operation was unsucessful
InvalidOperationErrorIf called when state is not 'SUSPENDED'
InvalidContainerErrorIf the container is in state 'INVALID'

Implements softwarecontainer::SoftwareContainerAbstractInterface.

Definition at line 335 of file softwarecontainer.cpp.

336 {
337  assertValidState();
338  std::string id = std::string(m_container->id());
339 
340  if (m_containerState != ContainerState::SUSPENDED) {
341  std::string message = "Invalid to resume non suspended container " + id;
342  log_error() << message;
343  throw InvalidOperationError(message);
344  }
345 
346  if (!m_container->resume()) {
347  std::string message = "Failed to resume container " + id;
348  log_error() << message;
349  m_containerState.setValueNotify(ContainerState::INVALID);
350  throw ContainerError(message);
351  }
352 
353  log_debug() << "Resumed container " << id;
354  m_containerState.setValueNotify(ContainerState::READY);
355 }
bool softwarecontainer::SoftwareContainer::bindMount ( const std::string &  pathOnHost,
const std::string &  pathInContainer,
bool  readonly = true 
)
virtual

Should only be called on containers in state 'READY'.

Exceptions
InvalidOperationErrorIf called when state is not 'READY'
InvalidContainerErrorIf the container is in state 'INVALID'

Implements softwarecontainer::SoftwareContainerAbstractInterface.

Definition at line 419 of file softwarecontainer.cpp.

422 {
423  assertValidState();
424 
425  std::string id = std::string(m_container->id());
426 
427  if (m_containerState != ContainerState::READY) {
428  std::string message = "Invalid to bind mount in non ready container " + id;
429  log_error() << message;
430  throw InvalidOperationError(message);
431  }
432 
433  return m_container->bindMountInContainer(pathOnHost, pathInContainer, readonly);
434 }
ObservableProperty< ContainerState > & softwarecontainer::SoftwareContainer::getContainerState ( )

Get the state of this container instance.

Returns
ContainerState representing the current state

Definition at line 386 of file softwarecontainer.cpp.

387 {
388  return m_containerState;
389 }
bool softwarecontainer::SoftwareContainer::previouslyConfigured ( )
virtual

Indicates if gateways have been configured previously.

The user should use this method to check if startGateways have been called previously.

TODO: This should be removed when quick-launch is implemented

Returns
true if startGateways has been called previously, false if not

Implements softwarecontainer::SoftwareContainerAbstractInterface.

Definition at line 445 of file softwarecontainer.cpp.

References softwarecontainer::isDirectory(), softwarecontainer::isDirectoryEmpty(), and softwarecontainer::FileToolkitWithUndo::m_createDirList.

446 {
447  return m_previouslyConfigured;
448 }

Here is the call graph for this function:


The documentation for this class was generated from the following files: