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

Public Member Functions

 SoftwareContainerAgent (Glib::RefPtr< Glib::MainContext > mainLoopContext, std::shared_ptr< Config > config, std::shared_ptr< SoftwareContainerFactory > factory, std::shared_ptr< ContainerUtilityInterface > utility)
 creates a new agent object and runs some initialization More...
 
std::vector< ContainerID > listContainers ()
 get a list of all containers More...
 
std::vector< std::string > listCapabilities ()
 List all capabilities that the user can set. More...
 
void deleteContainer (ContainerID containerID)
 delete container by ID More...
 
SoftwareContainerPtr getContainer (ContainerID containerID)
 Fetches a pointer to a SoftwareContainer matching an ID. More...
 
ContainerID createContainer (const std::string &config)
 Create a new container. More...
 
pid_t execute (ContainerID containerID, const std::string &cmdLine, const std::string &workingDirectory, const std::string &outputFile, const EnvironmentVariables &env, std::function< void(pid_t, int)> listener)
 Launch the given command in a the given container. More...
 
void shutdownContainer (ContainerID containerID)
 shuts down a container More...
 
void suspendContainer (ContainerID containerID)
 suspends execution of a container More...
 
void resumeContainer (ContainerID containerID)
 resumes execution of a container More...
 
void bindMount (const ContainerID containerID, const std::string &pathInHost, const std::string &pathInContainer, bool readOnly)
 Bind mount a folder into the container. More...
 
void setCapabilities (const ContainerID &containerID, const std::vector< std::string > &capabilities)
 Set capabilities for the container. More...
 

Detailed Description

Definition at line 82 of file softwarecontaineragent.h.

Constructor & Destructor Documentation

softwarecontainer::SoftwareContainerAgent::SoftwareContainerAgent ( Glib::RefPtr< Glib::MainContext >  mainLoopContext,
std::shared_ptr< Config config,
std::shared_ptr< SoftwareContainerFactory factory,
std::shared_ptr< ContainerUtilityInterface utility 
)

creates a new agent object and runs some initialization

This will check if the workspace is sound

The config is used to set various values in the agent, or for the agent to pass along to objects it creates.

Parameters
mainLoopContextA Glib::MainContext
configA general SoftwareContainer config
Exceptions
SoftwareContainerAgentErrorif initialization of the agent fails because of the Workspace initialization
ConfigStoreErrorif initialization of ConfigStore fails

Definition at line 32 of file softwarecontaineragent.cpp.

35  :
36  m_mainLoopContext(mainLoopContext),
37  m_config(config),
38  m_factory(factory),
39  m_containerUtility(utility)
40 {
41  m_containerIdPool.push_back(0);
42 
43  // Get all configs for the config object
44  int shutdownTimeout =
45  m_config->getIntValue(ConfigDefinition::SC_GROUP,
46  ConfigDefinition::SC_SHUTDOWN_TIMEOUT_KEY);
47  std::string sharedMountsDir =
48  m_config->getStringValue(ConfigDefinition::SC_GROUP,
49  ConfigDefinition::SC_SHARED_MOUNTS_DIR_KEY);
50  std::string lxcConfigPath =
51  m_config->getStringValue(ConfigDefinition::SC_GROUP,
52  ConfigDefinition::SC_LXC_CONFIG_PATH_KEY);
53 #ifdef ENABLE_NETWORKGATEWAY
54  // All of the below are network settings
55  bool createBridge = m_config->getBoolValue(ConfigDefinition::SC_GROUP,
56  ConfigDefinition::SC_CREATE_BRIDGE_KEY);
57  std::string bridgeDevice = m_config->getStringValue(ConfigDefinition::SC_GROUP,
58  ConfigDefinition::SC_BRIDGE_DEVICE_KEY);
59  std::string bridgeIp = m_config->getStringValue(ConfigDefinition::SC_GROUP,
60  ConfigDefinition::SC_BRIDGE_IP_KEY);
61  std::string bridgeNetmask = m_config->getStringValue(ConfigDefinition::SC_GROUP,
62  ConfigDefinition::SC_BRIDGE_NETMASK_KEY);
63  int bridgeNetmaskBits = m_config->getIntValue(ConfigDefinition::SC_GROUP,
64  ConfigDefinition::SC_BRIDGE_NETMASK_BITLENGTH_KEY);
65  std::string bridgeNetAddr = m_config->getStringValue(ConfigDefinition::SC_GROUP,
66  ConfigDefinition::SC_BRIDGE_NETADDR_KEY);
67 #endif // ENABLE_NETWORKGATEWAY
68 
69  // Get all configs for the config stores
70  std::string serviceManifestDir =
71  m_config->getStringValue(ConfigDefinition::SC_GROUP,
72  ConfigDefinition::SC_SERVICE_MANIFEST_DIR_KEY);
73  std::string defaultServiceManifestDir =
74  m_config->getStringValue(ConfigDefinition::SC_GROUP,
75  ConfigDefinition::SC_DEFAULT_SERVICE_MANIFEST_DIR_KEY);
76 
77  std::unique_ptr<ServiceManifestLoader> defaultLoader(new ServiceManifestFileLoader(defaultServiceManifestDir));
78  std::unique_ptr<ServiceManifestLoader> loader(new ServiceManifestFileLoader(serviceManifestDir));
79 
80  m_filteredConfigStore = std::make_shared<FilteredConfigStore>(std::move(loader));
81  m_defaultConfigStore = std::make_shared<DefaultConfigStore>(std::move(defaultLoader));
82 
83  m_containerUtility->removeOldContainers();
84  m_containerUtility->checkWorkspace();
85 
86  m_containerConfig = SoftwareContainerConfig(
87 #ifdef ENABLE_NETWORKGATEWAY
88  createBridge,
89  bridgeDevice,
90  bridgeIp,
91  bridgeNetmask,
92  bridgeNetmaskBits,
93  bridgeNetAddr,
94 #endif // ENABLE_NETWORKGATEWAY
95  lxcConfigPath,
96  sharedMountsDir,
97  shutdownTimeout);
98 
99 }

Member Function Documentation

std::vector< ContainerID > softwarecontainer::SoftwareContainerAgent::listContainers ( )

get a list of all containers

Returns
a vector of container IDs

Definition at line 131 of file softwarecontaineragent.cpp.

132 {
133  std::vector<ContainerID> containerIDs;
134  for (auto &cont : m_containers) {
135  containerIDs.push_back(cont.first);
136  }
137 
138  return containerIDs;
139 }
std::vector< std::string > softwarecontainer::SoftwareContainerAgent::listCapabilities ( )

List all capabilities that the user can set.

Capabilities are a mapping from a string to a set of gateway configurations. This method returns all capability names that can be used through setCapabilities.

Returns
a list of capabilities
Exceptions
SoftwareContainerErrorif not possible to create.

Definition at line 300 of file softwarecontaineragent.cpp.

301 {
302  return m_filteredConfigStore->IDs();
303 }
void softwarecontainer::SoftwareContainerAgent::deleteContainer ( ContainerID  containerID)

delete container by ID

Exceptions
SoftwareContainerErroron failure.

Definition at line 141 of file softwarecontaineragent.cpp.

Referenced by shutdownContainer().

142 {
143  assertContainerExists(containerID);
144 
145  m_containers.erase(containerID);
146  m_containerIdPool.push_back(containerID);
147 }

Here is the caller graph for this function:

SoftwareContainerAgent::SoftwareContainerPtr softwarecontainer::SoftwareContainerAgent::getContainer ( ContainerID  containerID)

Fetches a pointer to a SoftwareContainer matching an ID.

Parameters
containerIDthe ID for the container
Returns
Pointer to the matched container if there is such a container.
Exceptions
SoftwareContainerErroron failure.

Definition at line 149 of file softwarecontaineragent.cpp.

Referenced by bindMount(), execute(), resumeContainer(), shutdownContainer(), and suspendContainer().

150 {
151  assertContainerExists(containerID);
152  return m_containers[containerID];
153 }

Here is the caller graph for this function:

ContainerID softwarecontainer::SoftwareContainerAgent::createContainer ( const std::string &  config)

Create a new container.

Parameters
configcontainer-wide configuration string
areference to ContainerID
Returns
ContainerID for the newly created container
Exceptions
SoftwareContainerErrorif not possible to create.

Definition at line 168 of file softwarecontaineragent.cpp.

References softwarecontainer::ContainerOptionParser::parse().

169 {
170  profilepoint("createContainerStart");
171  profilefunction("createContainerFunction");
172 
173  // Set options for this container
174  std::unique_ptr<DynamicContainerOptions> options = m_optionParser.parse(config);
175  std::unique_ptr<SoftwareContainerConfig> containerConfig = options->toConfig(m_containerConfig);
176 
177  // Get an ID and create the container
178  ContainerID containerID = findSuitableId();
179  auto container = m_factory->createContainer(containerID, std::move(containerConfig));
180  log_debug() << "Created container with ID :" << containerID;
181 
182  m_containers[containerID] = container;
183  return containerID;
184 }
std::unique_ptr< DynamicContainerOptions > parse(const std::string &config)
Parse config needed for starting up the container in a correct manner.

Here is the call graph for this function:

pid_t softwarecontainer::SoftwareContainerAgent::execute ( ContainerID  containerID,
const std::string &  cmdLine,
const std::string &  workingDirectory,
const std::string &  outputFile,
const EnvironmentVariables &  env,
std::function< void(pid_t, int)>  listener 
)

Launch the given command in a the given container.

Parameters
containerIDthe id for the container
cmdLinethe command to run
workingDirectorythe working directory to use when running
outputFilewhere to log any output
envany environment variables to pass to the command
listenera function that runs when the process exits
Returns
process id of the given command

Definition at line 186 of file softwarecontaineragent.cpp.

References softwarecontainer::addProcessListener(), and getContainer().

192 {
193  profilefunction("executeFunction");
194  SoftwareContainerPtr container = getContainer(containerID);
195 
196  /*
197  * We want to always apply any default capabilities we have. The only way to configure
198  * the gateways from the agent is through setCapabilities - which sets the default caps also.
199  *
200  * If it has not been set previously, then we use a call without arguments to setCapabilities
201  * to set it up, since we then should get only the default ones.
202  */
203  if (!m_containers[containerID]->previouslyConfigured()) {
204  log_info() << "Container not configured yet, configuring with default capabilities, if any";
205  GatewayConfiguration gatewayConfigs = m_defaultConfigStore->configs();
206  if (!updateGatewayConfigs(containerID, gatewayConfigs)) {
207  std::string errorMessage("Could not set default capabilities on container " + std::to_string(containerID));
208  log_error() << errorMessage;
209  throw SoftwareContainerError(errorMessage);
210  }
211 
212  }
213 
214  // Set up a CommandJob for this run in the container
215  auto job = container->createCommandJob(cmdLine);
216  if (nullptr == job) {
217  std::string errorMessage("Could not create job instance for " + cmdLine);
218  log_error() << errorMessage;
219  throw SoftwareContainerAgentError(errorMessage);
220  }
221 
222  job->setOutputFile(outputFile);
223  job->setEnvironmentVariables(env);
224  job->setWorkingDirectory(workingDirectory);
225 
226  // Start it
227  if (!job->start()) {
228  std::string errorMessage("Could not start job");
229  log_error() << errorMessage;
230  throw SoftwareContainerError(errorMessage);
231  }
232 
233  // If things went well, do what we need when it exits
234  addProcessListener(m_connections, job->pid(), [listener](pid_t pid, int exitCode) {
235  listener(pid, exitCode);
236  }, m_mainLoopContext);
237 
238  profilepoint("executeEnd");
239 
240  return job->pid();
241 }
void addProcessListener(SignalConnectionsHandler &connections, pid_t pid, std::function< void(pid_t, int)> function, Glib::RefPtr< Glib::MainContext > context)
addProcessListener Adds a glib child watch for a process.
SoftwareContainerPtr getContainer(ContainerID containerID)
Fetches a pointer to a SoftwareContainer matching an ID.

Here is the call graph for this function:

void softwarecontainer::SoftwareContainerAgent::shutdownContainer ( ContainerID  containerID)

shuts down a container

Parameters
containerIDthe container to shut down
Exceptions
SoftwareContainerErroron failure.

Definition at line 243 of file softwarecontaineragent.cpp.

References deleteContainer(), and getContainer().

244 {
245  profilefunction("shutdownContainerFunction");
246 
247  SoftwareContainerPtr container = getContainer(containerID);
248 
249  int timeout = m_containerConfig.containerShutdownTimeout();
250  container->shutdown(timeout);
251 
252  try {
253  deleteContainer(containerID);
254  } catch (SoftwareContainerError &err) {
255  std::string errorMessage("Could not delete the container" + std::string(err.what()));
256  log_error() << errorMessage;
257  throw SoftwareContainerError(errorMessage);
258  }
259 }
SoftwareContainerPtr getContainer(ContainerID containerID)
Fetches a pointer to a SoftwareContainer matching an ID.
void deleteContainer(ContainerID containerID)
delete container by ID

Here is the call graph for this function:

void softwarecontainer::SoftwareContainerAgent::suspendContainer ( ContainerID  containerID)

suspends execution of a container

Parameters
containerIDthe container to suspend
Exceptions
SoftwareContainerErroron failure.

Definition at line 261 of file softwarecontaineragent.cpp.

References getContainer().

262 {
263  SoftwareContainerPtr container = getContainer(containerID);
264  container->suspend();
265 }
SoftwareContainerPtr getContainer(ContainerID containerID)
Fetches a pointer to a SoftwareContainer matching an ID.

Here is the call graph for this function:

void softwarecontainer::SoftwareContainerAgent::resumeContainer ( ContainerID  containerID)

resumes execution of a container

Parameters
containerIDthe container to resume
Exceptions
SoftwareContainerErroron failure.

Definition at line 267 of file softwarecontaineragent.cpp.

References getContainer().

268 {
269  SoftwareContainerPtr container = getContainer(containerID);
270  container->resume();
271 }
SoftwareContainerPtr getContainer(ContainerID containerID)
Fetches a pointer to a SoftwareContainer matching an ID.

Here is the call graph for this function:

void softwarecontainer::SoftwareContainerAgent::bindMount ( const ContainerID  containerID,
const std::string &  pathInHost,
const std::string &  pathInContainer,
bool  readOnly 
)

Bind mount a folder into the container.

Parameters
containerIDthe container to bind into
pathInHostpath to the folder in the host system
subPathInContainerpath (relative to a fixed start point) to use in the container
readOnlywhether or not to mount read-only
referenceto the full path of the mounted folder in the container
Exceptions
SoftwareContainerErroron failure.

Definition at line 273 of file softwarecontaineragent.cpp.

References getContainer().

277 {
278  profilefunction("bindMountFunction");
279  SoftwareContainerPtr container = getContainer(containerID);
280 
281  bool result = container->bindMount(pathInHost,
282  pathInContainer,
283  readOnly);
284  if (!result) {
285  std::string errorMessage("Unable to bind mount " + pathInHost + " to " + pathInContainer);
286  log_error() << errorMessage;
287  throw SoftwareContainerError(errorMessage);
288  }
289 }
SoftwareContainerPtr getContainer(ContainerID containerID)
Fetches a pointer to a SoftwareContainer matching an ID.

Here is the call graph for this function:

void softwarecontainer::SoftwareContainerAgent::setCapabilities ( const ContainerID &  containerID,
const std::vector< std::string > &  capabilities 
)

Set capabilities for the container.

Capabilities are a mapping from a string to a set of gateway configurations. Capabilities are translated into gateway configurations and then sent the same way as with startGateways

Parameters
containerIDthe container to use
capabilitiesthe capabilities
Exceptions
SoftwareContainerErroron failure.

Definition at line 305 of file softwarecontaineragent.cpp.

307 {
308  if (capabilities.empty()) {
309  log_warning() << "Got empty list of capabilities";
310  return;
311  }
312 
313  // Log a list of all caps that were provided
314  std::string caps = "";
315  for (const std::string &capName : capabilities) {
316  caps += " " + capName;
317  }
318  log_debug() << "Will attempt to set capabilities:" + caps;
319 
320  GatewayConfiguration gatewayConfigs = m_defaultConfigStore->configs();
321  GatewayConfiguration filteredConfigs = m_filteredConfigStore->configsByID(capabilities);
322 
323  // If we get an empty config the user passed a non existent cap name
324  if (filteredConfigs.empty()) {
325  std::string errorMessage("One or more capabilities were not found");
326  log_error() << errorMessage;
327  throw SoftwareContainerError(errorMessage);
328  }
329 
330  gatewayConfigs.append(filteredConfigs);
331 
332  // Update container gateway configuration
333  if (!updateGatewayConfigs(containerID, gatewayConfigs)) {
334  std::string errorMessage("Could not set gateway configuration for capability");
335  log_error() << errorMessage;
336  throw SoftwareContainerError(errorMessage);
337  }
338 }

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