Idempotency for LXC cloning

Previously, clone operations where the new container already exists were
reporting as failed. This commit modifies that behavior so that if the
new container exists, it returns the facts for that container instead of
failing.

To facilitate these changes, a _container_exists method was added which
returns True or False based on whether or not the container name is in
the output from self._list().

I also made a few fixes in the documentation by removing trailing spaces
and fixing a typo in the state on line 222.
This commit is contained in:
David Wittman 2014-09-25 12:31:31 -05:00
parent 1ec913f21a
commit 7032f4bb1e

40
rpc_deployment/library/lxc Executable file → Normal file
View File

@ -219,7 +219,7 @@ container_config_options:
- lxc: orig=test-container - lxc: orig=test-container
new=test-container-new new=test-container-new
command=clone command=clone
state=started state=running
# Destroy a container. # Destroy a container.
- lxc: name=test-container - lxc: name=test-container
@ -546,7 +546,7 @@ class LxcManagement(object):
rc, return_data, err = self._run_command(build_command) rc, return_data, err = self._run_command(build_command)
if rc not in self.rc: if rc not in self.rc:
msg = 'Failed to get container Information.' msg = 'Failed to get container Information'
self.failure(err, rc, msg) self.failure(err, rc, msg)
ip_count = 0 ip_count = 0
@ -561,6 +561,19 @@ class LxcManagement(object):
else: else:
return cstate return cstate
def _container_exists(self, name, variables_dict):
"""Return True or False based on whether or not the container exists
:param name: ``str`` name of the container
"""
containers = self._list(variables_dict=variables_dict)
for container in containers.splitlines():
if container == name:
return True
return False
@staticmethod @staticmethod
def _construct_command(build_list): def _construct_command(build_list):
"""Return a string from a command and build list. """Return a string from a command and build list.
@ -679,21 +692,19 @@ class LxcManagement(object):
name = variables_dict.pop('name') name = variables_dict.pop('name')
state = variables_dict.pop('state', 'running') state = variables_dict.pop('state', 'running')
containers = self._list(variables_dict=variables_dict) if self._container_exists(name, variables_dict):
for container in containers.splitlines():
if container == name:
container_info = self._get_container_info( container_info = self._get_container_info(
name=name, variables_dict=variables_dict name=name, variables_dict=variables_dict
) )
return self._lxc_facts(facts={name: container_info})
else: else:
created_container_info = self._create(name, state, variables_dict) container_info = self._create(name, state, variables_dict)
return self._lxc_facts(facts={name: created_container_info})
return self._lxc_facts(facts={name: container_info})
def _destroy(self, name): def _destroy(self, name):
"""Destroy an LXC container. """Destroy an LXC container.
:param name: ``str` Name of the container to destroy :param name: ``str`` Name of the container to destroy
""" """
build_command = [ build_command = [
self.module.get_bin_path('lxc-destroy', True), self.module.get_bin_path('lxc-destroy', True),
@ -720,9 +731,7 @@ class LxcManagement(object):
variables_dict = self._get_vars(variables, required=['name']) variables_dict = self._get_vars(variables, required=['name'])
name = variables_dict.pop('name') name = variables_dict.pop('name')
containers = self._list(variables_dict=variables_dict) if self._container_exists(name, variables_dict):
for container in containers.splitlines():
if container == name:
self._destroy(name=name) self._destroy(name=name)
def _local_clone(self, orig, new, variables_dict): def _local_clone(self, orig, new, variables_dict):
@ -788,6 +797,13 @@ class LxcManagement(object):
orig = variables_dict.pop('orig') orig = variables_dict.pop('orig')
new = variables_dict.pop('new') new = variables_dict.pop('new')
# Check to see if new container already exists
if self._container_exists(new, variables_dict):
new_container_info = self._get_container_info(
name=new, variables_dict=variables_dict
)
return self._lxc_facts(facts={new: new_container_info})
container_data = self._get_container_info( container_data = self._get_container_info(
name=orig, variables_dict=variables_dict name=orig, variables_dict=variables_dict
) )