Updated lxc module to remove the clone state

The clone state was removed in favor of making the module more
declarative. This change was done in response to review in PR #328
from @bcoca.

In the commit new examples were created on how this feature works.
This commit is contained in:
Kevin Carter 2015-05-13 21:20:05 -05:00
parent 9800126a6e
commit fd0c21df27

View file

@ -156,12 +156,12 @@ options:
- restarted
- absent
- frozen
- clone
description:
- Define the state of a container. If you use clone the container
will be stopped while the clone operation is happening and upon
completion of the clone the original container state will be
restored.
- Define the state of a container. If you clone a container using
`clone_name` the newly cloned container created in a stopped state.
The running container will be stopped while the clone operation is
happening and upon completion of the clone the original container
state will be restored.
required: false
default: started
container_config:
@ -225,6 +225,7 @@ EXAMPLES = """
- name: Create filesystem container
lxc_container:
name: test-container-config
backing_store: dir
container_log: true
template: ubuntu
state: started
@ -238,7 +239,7 @@ EXAMPLES = """
# Create an lvm container, run a complex command in it, add additional
# configuration to it, create an archive of it, and finally leave the container
# in a frozen state. The container archive will be compressed using bzip2
- name: Create an lvm container
- name: Create a frozen lvm container
lxc_container:
name: test-container-lvm
container_log: true
@ -263,14 +264,6 @@ EXAMPLES = """
- name: Debug info on container "test-container-lvm"
debug: var=lvm_container_info
- name: Get information on a given container.
lxc_container:
name: test-container-config
register: config_container_info
- name: debug info on container "test-container"
debug: var=config_container_info
- name: Run a command in a container and ensure its in a "stopped" state.
lxc_container:
name: test-container-started
@ -285,19 +278,19 @@ EXAMPLES = """
container_command: |
echo 'hello world.' | tee /opt/frozen
- name: Start a container.
- name: Start a container
lxc_container:
name: test-container-stopped
state: started
- name: Run a command in a container and then restart it.
- name: Run a command in a container and then restart it
lxc_container:
name: test-container-started
state: restarted
container_command: |
echo 'hello world.' | tee /opt/restarted
- name: Run a complex command within a "running" container.
- name: Run a complex command within a "running" container
lxc_container:
name: test-container-started
container_command: |
@ -317,7 +310,10 @@ EXAMPLES = """
archive: true
archive_path: /opt/archives
- name: Create an overlayfs container
# Create a container using overlayfs, create an archive of it, create a
# snapshot clone of the container and and finally leave the container
# in a frozen state. The container archive will be compressed using gzip.
- name: Create an overlayfs container archive and clone it
lxc_container:
name: test-container-overlayfs
container_log: true
@ -325,40 +321,42 @@ EXAMPLES = """
state: started
backing_store: overlayfs
template_options: --release trusty
- name: Clone a container
lxc_container:
name: test-container-overlayfs
clone_name: test-container-clone
state: clone
- name: Clone a container using snapshot.
lxc_container:
name: test-container-overlayfs
clone_name: test-container-overlayfs-clone
backing_store: overlayfs
clone_snapshot: true
state: clone
clone_name: test-container-overlayfs-clone-snapshot
archive: true
archive_compression: gzip
register: clone_container_info
- name: debug info on container "test-container"
debug: var=clone_container_info
- name: Clone a container using snapshot
lxc_container:
name: test-container-overlayfs-clone-snapshot
backing_store: overlayfs
clone_name: test-container-overlayfs-clone-snapshot2
clone_snapshot: true
- name: Create a new container and clone it
lxc_container:
name: test-container-new-overlayfs
clone_name: test-container-new-overlayfs-clone
backing_store: overlayfs
clone_snapshot: true
state: clone
name: test-container-new-archive
backing_store: dir
clone_name: test-container-new-archive-clone
- name: Create a new container, clone it, and archive
- name: Archive and clone a container then destroy it
lxc_container:
name: test-container-new-overlayfs
clone_name: test-container-new-overlayfs-clone
backing_store: overlayfs
clone_snapshot: true
state: clone
name: test-container-new-archive
state: absent
clone_name: test-container-new-archive-destroyed-clone
archive: true
archive_compression: gzip
- name: Destroy a container.
- name: Start a cloned container.
lxc_container:
name: test-container-new-archive-destroyed-clone
state: started
- name: Destroy a container
lxc_container:
name: "{{ item }}"
state: absent
@ -369,8 +367,12 @@ EXAMPLES = """
- test-container-lvm
- test-container-config
- test-container-overlayfs
- test-container-clone
- test-container-overlayfs-clone
- test-container-overlayfs-clone-snapshot
- test-container-overlayfs-clone-snapshot2
- test-container-new-archive
- test-container-new-archive-clone
- test-container-new-archive-destroyed-clone
"""
@ -518,18 +520,16 @@ def create_script(command):
f.close()
# Ensure the script is executable.
os.chmod(script_file, 0755)
os.chmod(script_file, 1755)
# Get temporary directory.
tempdir = tempfile.gettempdir()
# Output log file.
stdout = path.join(tempdir, 'lxc-attach-script.log')
stdout_file = open(stdout, 'ab')
stdout_file = open(path.join(tempdir, 'lxc-attach-script.log'), 'ab')
# Error log file.
stderr = path.join(tempdir, 'lxc-attach-script.err')
stderr_file = open(stderr, 'ab')
stderr_file = open(path.join(tempdir, 'lxc-attach-script.err'), 'ab')
# Execute the script command.
try:
@ -561,6 +561,7 @@ class LxcContainerManagement(object):
self.container_name = self.module.params['name']
self.container = self.get_container_bind()
self.archive_info = None
self.clone_info = None
def get_container_bind(self):
return lxc.Container(name=self.container_name)
@ -735,7 +736,7 @@ class LxcContainerManagement(object):
self._container_startup()
self.container.freeze()
def _clone(self, count=0):
def _container_create_clone(self):
"""Clone a new LXC container from an existing container.
This method will clone an existing container to a new container using
@ -751,66 +752,51 @@ class LxcContainerManagement(object):
state.
"""
self.check_count(count=count, method='clone')
if self._container_exists(container_name=self.container_name):
# Ensure that the state of the original container is stopped
container_state = self._get_state()
if container_state != 'stopped':
self.state_change = True
self.container.stop()
# Ensure that the state of the original container is stopped
container_state = self._get_state()
if container_state != 'stopped':
self.state_change = True
self.container.stop()
build_command = [
self.module.get_bin_path('lxc-clone', True),
]
build_command = [
self.module.get_bin_path('lxc-clone', True),
]
build_command = self._add_variables(
variables_dict=self._get_vars(
variables=LXC_COMMAND_MAP['clone']['variables']
),
build_command=build_command
)
build_command = self._add_variables(
variables_dict=self._get_vars(
variables=LXC_COMMAND_MAP['clone']['variables']
),
build_command=build_command
)
# Load logging for the instance when creating it.
if self.module.params.get('clone_snapshot') in BOOLEANS_TRUE:
build_command.append('--snapshot')
# Load logging for the instance when creating it.
if self.module.params.get('clone_snapshot') in BOOLEANS_TRUE:
build_command.append('--snapshot')
# Check for backing_store == overlayfs if so force the use of snapshot
# If overlay fs is used and snapshot is unset the clone command will
# fail with an unsupported type.
elif self.module.params.get('backing_store') == 'overlayfs':
build_command.append('--snapshot')
rc, return_data, err = self._run_command(build_command)
if rc != 0:
message = "Failed executing lxc-clone."
self.failure(
err=err, rc=rc, msg=message, command=' '.join(
build_command
)
rc, return_data, err = self._run_command(build_command)
if rc != 0:
message = "Failed executing lxc-clone."
self.failure(
err=err, rc=rc, msg=message, command=' '.join(
build_command
)
else:
self.state_change = True
# Restore the original state of the origin container if it was
# not in a stopped state.
if container_state == 'running':
self.container.start()
elif container_state == 'frozen':
self.container.start()
self.container.freeze()
# Change the container name context to the new cloned container
# This enforces that the state of the new cloned container will be
# "stopped".
self.state = 'stopped'
self.container_name = self.module.params['clone_name']
self.container = self.get_container_bind()
# Return data
self._execute_command()
# Perform any configuration updates
self._config()
# Check if the container needs to have an archive created.
self._check_archive()
)
else:
self._create()
count += 1
self._clone(count)
self.state_change = True
# Restore the original state of the origin container if it was
# not in a stopped state.
if container_state == 'running':
self.container.start()
elif container_state == 'frozen':
self.container.start()
self.container.freeze()
return True
def _create(self):
"""Create a new LXC container.
@ -965,6 +951,23 @@ class LxcContainerManagement(object):
'archive': self._container_create_tar()
}
def _check_clone(self):
"""Create a compressed archive of a container.
This will store archive_info in as self.archive_info
"""
clone_name = self.module.params.get('clone_name')
if clone_name:
if not self._container_exists(container_name=clone_name):
self.clone_info = {
'cloned': self._container_create_clone()
}
else:
self.clone_info = {
'cloned': False
}
def _destroyed(self, timeout=60):
"""Ensure a container is destroyed.
@ -979,6 +982,9 @@ class LxcContainerManagement(object):
# Check if the container needs to have an archive created.
self._check_archive()
# Check if the container is to be cloned
self._check_clone()
if self._get_state() != 'stopped':
self.state_change = True
self.container.stop()
@ -1028,6 +1034,9 @@ class LxcContainerManagement(object):
# Check if the container needs to have an archive created.
self._check_archive()
# Check if the container is to be cloned
self._check_clone()
else:
self._create()
count += 1
@ -1055,6 +1064,9 @@ class LxcContainerManagement(object):
# Check if the container needs to have an archive created.
self._check_archive()
# Check if the container is to be cloned
self._check_clone()
else:
self._create()
count += 1
@ -1082,6 +1094,9 @@ class LxcContainerManagement(object):
# Check if the container needs to have an archive created.
self._check_archive()
# Check if the container is to be cloned
self._check_clone()
else:
self._create()
count += 1
@ -1122,6 +1137,9 @@ class LxcContainerManagement(object):
# Check if the container needs to have an archive created.
self._check_archive()
# Check if the container is to be cloned
self._check_clone()
else:
self._create()
count += 1
@ -1581,6 +1599,9 @@ class LxcContainerManagement(object):
if self.archive_info:
outcome.update(self.archive_info)
if self.clone_info:
outcome.update(self.clone_info)
self.module.exit_json(
changed=self.state_change,
lxc_container=outcome