lxc: path support

Signed-off-by: Mathieu Le Marec - Pasquet <kiorky@cryptelium.net>
This commit is contained in:
Mathieu Le Marec - Pasquet 2015-05-20 13:34:02 +02:00
parent e7542e7a38
commit f50e6dafa8
5 changed files with 916 additions and 292 deletions

View File

@ -278,7 +278,11 @@ def list_nodes(conn=None, call=None):
hide = True hide = True
if not get_configured_provider(): if not get_configured_provider():
return return
lxclist = _salt('lxc.list', extra=True)
path = None
if profile and profile in profiles:
path = profiles[profile].get('path', None)
lxclist = _salt('lxc.list', extra=True, path=path)
nodes = {} nodes = {}
for state, lxcs in six.iteritems(lxclist): for state, lxcs in six.iteritems(lxclist):
for lxcc, linfos in six.iteritems(lxcs): for lxcc, linfos in six.iteritems(lxcs):
@ -295,10 +299,9 @@ def list_nodes(conn=None, call=None):
# do not also mask half configured nodes which are explicitly asked # do not also mask half configured nodes which are explicitly asked
# to be acted on, on the command line # to be acted on, on the command line
if ( if (
(call in ['full'] or not hide) (call in ['full'] or not hide) and (
and ( (lxcc in names and call in ['action']) or (
(lxcc in names and call in ['action']) call in ['full'])
or (call in ['full'])
) )
): ):
nodes[lxcc] = info nodes[lxcc] = info
@ -383,7 +386,7 @@ def destroy(vm_, call=None):
return return
ret = {'comment': '{0} was not found'.format(vm_), ret = {'comment': '{0} was not found'.format(vm_),
'result': False} 'result': False}
if _salt('lxc.info', vm_): if _salt('lxc.info', vm_, path=path):
salt.utils.cloud.fire_event( salt.utils.cloud.fire_event(
'event', 'event',
'destroying instance', 'destroying instance',
@ -391,7 +394,7 @@ def destroy(vm_, call=None):
{'name': vm_, 'instance_id': vm_}, {'name': vm_, 'instance_id': vm_},
transport=__opts__['transport'] transport=__opts__['transport']
) )
cret = _salt('lxc.destroy', vm_, stop=True) cret = _salt('lxc.destroy', vm_, stop=True, path=path)
ret['result'] = cret['result'] ret['result'] = cret['result']
if ret['result']: if ret['result']:
ret['comment'] = '{0} was destroyed'.format(vm_) ret['comment'] = '{0} was destroyed'.format(vm_)
@ -507,18 +510,21 @@ def get_configured_provider(vm_=None):
profs = __opts__['profiles'] profs = __opts__['profiles']
tgt = 'profile: {0}'.format(curprof) tgt = 'profile: {0}'.format(curprof)
if ( if (
curprof in profs curprof in profs and
and profs[curprof]['provider'] == __active_provider_name__ profs[curprof]['provider'] == __active_provider_name__
): ):
prov, cdriver = profs[curprof]['provider'].split(':') prov, cdriver = profs[curprof]['provider'].split(':')
tgt += ' provider: {0}'.format(prov) tgt += ' provider: {0}'.format(prov)
data = get_provider(prov) data = get_provider(prov)
matched = True matched = True
# fallback if we have only __active_provider_name__ # fallback if we have only __active_provider_name__
if ((__opts__.get('destroy', False) and not data) if (
or (not matched and __active_provider_name__)): (__opts__.get('destroy', False) and not data) or (
not matched and __active_provider_name__
)
):
data = __opts__.get('providers', data = __opts__.get('providers',
{}).get(dalias, {}).get(driver, {}) {}).get(dalias, {}).get(driver, {})
# in all cases, verify that the linked saltmaster is alive. # in all cases, verify that the linked saltmaster is alive.
if data: if data:
try: try:

View File

@ -13,6 +13,7 @@ common logic to be re-used for common actions.
# Import python libs # Import python libs
from __future__ import absolute_import from __future__ import absolute_import
import functools import functools
import copy
import logging import logging
import os import os
import pipes import pipes
@ -123,11 +124,18 @@ def run(name,
python_shell=True, python_shell=True,
output_loglevel='debug', output_loglevel='debug',
ignore_retcode=False, ignore_retcode=False,
path=None,
use_vt=False, use_vt=False,
keep_env=None): keep_env=None):
''' '''
Common logic for running shell commands in containers Common logic for running shell commands in containers
path
path to the container parent (for LXC only)
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
CLI Example: CLI Example:
.. code-block:: bash .. code-block:: bash
@ -158,6 +166,8 @@ def run(name,
if exec_driver == 'lxc-attach': if exec_driver == 'lxc-attach':
full_cmd = 'lxc-attach ' full_cmd = 'lxc-attach '
if path:
full_cmd += '-P {0} '.format(pipes.quote(path))
if keep_env is not True: if keep_env is not True:
full_cmd += '--clear-env ' full_cmd += '--clear-env '
if 'PATH' not in to_keep: if 'PATH' not in to_keep:
@ -262,12 +272,19 @@ def copy_to(name,
source, source,
dest, dest,
container_type=None, container_type=None,
path=None,
exec_driver=None, exec_driver=None,
overwrite=False, overwrite=False,
makedirs=False): makedirs=False):
''' '''
Common logic for copying files to containers Common logic for copying files to containers
path
path to the container parent (for LXC only)
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
CLI Example: CLI Example:
.. code-block:: bash .. code-block:: bash
@ -276,9 +293,27 @@ def copy_to(name,
''' '''
# Get the appropriate functions # Get the appropriate functions
state = __salt__['{0}.state'.format(container_type)] state = __salt__['{0}.state'.format(container_type)]
run_all = __salt__['{0}.run_all'.format(container_type)]
c_state = state(name) def run_all(*args, **akwargs):
akwargs = copy.deepcopy(akwargs)
if container_type in ['lxc'] and 'path' not in akwargs:
akwargs['path'] = path
return __salt__['{0}.run_all'.format(container_type)](
*args, **akwargs)
state_kwargs = {}
cmd_kwargs = {'ignore_retcode': True}
if container_type in ['lxc']:
cmd_kwargs['path'] = path
state_kwargs['path'] = path
def _state(name):
if state_kwargs:
return state(name, **state_kwargs)
else:
return state(name)
c_state = _state(name)
if c_state != 'running': if c_state != 'running':
raise CommandExecutionError( raise CommandExecutionError(
'Container \'{0}\' is not running'.format(name) 'Container \'{0}\' is not running'.format(name)
@ -302,7 +337,7 @@ def copy_to(name,
raise SaltInvocationError('Destination path must be absolute') raise SaltInvocationError('Destination path must be absolute')
if run_all(name, if run_all(name,
'test -d {0}'.format(pipes.quote(dest)), 'test -d {0}'.format(pipes.quote(dest)),
ignore_retcode=True)['retcode'] == 0: **cmd_kwargs)['retcode'] == 0:
# Destination is a directory, full path to dest file will include the # Destination is a directory, full path to dest file will include the
# basename of the source file. # basename of the source file.
dest = os.path.join(dest, source_name) dest = os.path.join(dest, source_name)
@ -313,10 +348,11 @@ def copy_to(name,
dest_dir, dest_name = os.path.split(dest) dest_dir, dest_name = os.path.split(dest)
if run_all(name, if run_all(name,
'test -d {0}'.format(pipes.quote(dest_dir)), 'test -d {0}'.format(pipes.quote(dest_dir)),
ignore_retcode=True)['retcode'] != 0: **cmd_kwargs)['retcode'] != 0:
if makedirs: if makedirs:
result = run_all(name, result = run_all(name,
'mkdir -p {0}'.format(pipes.quote(dest_dir))) 'mkdir -p {0}'.format(pipes.quote(dest_dir)),
**cmd_kwargs)
if result['retcode'] != 0: if result['retcode'] != 0:
error = ('Unable to create destination directory {0} in ' error = ('Unable to create destination directory {0} in '
'container \'{1}\''.format(dest_dir, name)) 'container \'{1}\''.format(dest_dir, name))
@ -330,7 +366,7 @@ def copy_to(name,
) )
if not overwrite and run_all(name, if not overwrite and run_all(name,
'test -e {0}'.format(pipes.quote(dest)), 'test -e {0}'.format(pipes.quote(dest)),
ignore_retcode=True)['retcode'] == 0: **cmd_kwargs)['retcode'] == 0:
raise CommandExecutionError( raise CommandExecutionError(
'Destination path {0} already exists. Use overwrite=True to ' 'Destination path {0} already exists. Use overwrite=True to '
'overwrite it'.format(dest) 'overwrite it'.format(dest)
@ -350,9 +386,12 @@ def copy_to(name,
# and passing it as stdin to run(). This will keep down memory # and passing it as stdin to run(). This will keep down memory
# usage for the minion and make the operation run quicker. # usage for the minion and make the operation run quicker.
if exec_driver == 'lxc-attach': if exec_driver == 'lxc-attach':
lxcattach = 'lxc-attach'
if path:
lxcattach += ' -P {0}'.format(pipes.quote(path))
copy_cmd = ( copy_cmd = (
'cat "{0}" | lxc-attach --clear-env --set-var {1} -n {2} -- ' 'cat "{0}" | {4} --clear-env --set-var {1} -n {2} -- '
'tee "{3}"'.format(local_file, PATH, name, dest) 'tee "{3}"'.format(local_file, PATH, name, dest, lxcattach)
) )
elif exec_driver == 'nsenter': elif exec_driver == 'nsenter':
pid = __salt__['{0}.pid'.format(container_type)](name) pid = __salt__['{0}.pid'.format(container_type)](name)

File diff suppressed because it is too large Load Diff

View File

@ -31,11 +31,17 @@ __func_alias__ = {
} }
def _do(name, fun): def _do(name, fun, path=None):
''' '''
Invoke a function in the lxc module with no args Invoke a function in the lxc module with no args
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
''' '''
host = find_guest(name, quiet=True) host = find_guest(name, quiet=True, path=path)
if not host: if not host:
return False return False
@ -44,6 +50,7 @@ def _do(name, fun):
host, host,
'lxc.{0}'.format(fun), 'lxc.{0}'.format(fun),
[name], [name],
kwarg={'path': path},
timeout=60) timeout=60)
data = next(cmd_ret) data = next(cmd_ret)
data = data.get(host, {}).get('ret', None) data = data.get(host, {}).get('ret', None)
@ -52,12 +59,18 @@ def _do(name, fun):
return data return data
def _do_names(names, fun): def _do_names(names, fun, path=None):
''' '''
Invoke a function in the lxc module with no args Invoke a function in the lxc module with no args
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
''' '''
ret = {} ret = {}
hosts = find_guests(names) hosts = find_guests(names, path=path)
if not hosts: if not hosts:
return False return False
@ -69,6 +82,7 @@ def _do_names(names, fun):
host, host,
'lxc.{0}'.format(fun), 'lxc.{0}'.format(fun),
[name], [name],
kwarg={'path': path},
timeout=60)) timeout=60))
for cmd in cmds: for cmd in cmds:
data = next(cmd) data = next(cmd)
@ -78,33 +92,51 @@ def _do_names(names, fun):
return ret return ret
def find_guest(name, quiet=False): def find_guest(name, quiet=False, path=None):
''' '''
Returns the host for a container. Returns the host for a container.
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
.. code-block:: bash .. code-block:: bash
salt-run lxc.find_guest name salt-run lxc.find_guest name
''' '''
if quiet: if quiet:
log.warn('\'quiet\' argument is being deprecated. Please migrate to --quiet') log.warn('\'quiet\' argument is being deprecated.'
for data in _list_iter(): ' Please migrate to --quiet')
for data in _list_iter(path=path):
host, l = next(six.iteritems(data)) host, l = next(six.iteritems(data))
for x in 'running', 'frozen', 'stopped': for x in 'running', 'frozen', 'stopped':
if name in l[x]: if name in l[x]:
if not quiet: if not quiet:
__jid_event__.fire_event({'data': host, 'outputter': 'lxc_find_host'}, 'progress') __jid_event__.fire_event(
{'data': host,
'outputter': 'lxc_find_host'},
'progress')
return host return host
return None return None
def find_guests(names): def find_guests(names, path=None):
''' '''
Return a dict of hosts and named guests Return a dict of hosts and named guests
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
''' '''
ret = {} ret = {}
names = names.split(',') names = names.split(',')
for data in _list_iter(): for data in _list_iter(path=path):
host, stat = next(six.iteritems(data)) host, stat = next(six.iteritems(data))
for state in stat: for state in stat:
for name in stat[state]: for name in stat[state]:
@ -139,6 +171,12 @@ def init(names, host=None, saltcloud_mode=False, quiet=False, **kwargs):
host host
Minion on which to initialize the container **(required)** Minion on which to initialize the container **(required)**
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
saltcloud_mode saltcloud_mode
init the container with the saltcloud opts format instead init the container with the saltcloud opts format instead
See lxc.init_interface module documentation See lxc.init_interface module documentation
@ -169,7 +207,7 @@ def init(names, host=None, saltcloud_mode=False, quiet=False, **kwargs):
network_profile network_profile
Network profile to use for the container Network profile to use for the container
.. versionadded:: 2015.5.0 .. versionadded:: 2015.5.2
nic nic
.. deprecated:: 2015.5.0 .. deprecated:: 2015.5.0
@ -194,8 +232,10 @@ def init(names, host=None, saltcloud_mode=False, quiet=False, **kwargs):
Optional config parameters. By default, the id is set to Optional config parameters. By default, the id is set to
the name of the container. the name of the container.
''' '''
path = kwargs.get('path', None)
if quiet: if quiet:
log.warn('\'quiet\' argument is being deprecated. Please migrate to --quiet') log.warn('\'quiet\' argument is being deprecated.'
' Please migrate to --quiet')
ret = {'comment': '', 'result': True} ret = {'comment': '', 'result': True}
if host is None: if host is None:
# TODO: Support selection of host based on available memory/cpu/etc. # TODO: Support selection of host based on available memory/cpu/etc.
@ -222,7 +262,7 @@ def init(names, host=None, saltcloud_mode=False, quiet=False, **kwargs):
return ret return ret
log.info('Searching for LXC Hosts') log.info('Searching for LXC Hosts')
data = __salt__['lxc.list'](host, quiet=True) data = __salt__['lxc.list'](host, quiet=True, path=path)
for host, containers in six.iteritems(data): for host, containers in six.iteritems(data):
for name in names: for name in names:
if name in sum(six.itervalues(containers), []): if name in sum(six.itervalues(containers), []):
@ -372,6 +412,12 @@ def cloud_init(names, host=None, quiet=False, **kwargs):
host host
Minion to start the container on. Required. Minion to start the container on. Required.
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
saltcloud_mode saltcloud_mode
init the container with the saltcloud opts format instead init the container with the saltcloud opts format instead
''' '''
@ -381,13 +427,21 @@ def cloud_init(names, host=None, quiet=False, **kwargs):
saltcloud_mode=True, quiet=quiet, **kwargs) saltcloud_mode=True, quiet=quiet, **kwargs)
def _list_iter(host=None): def _list_iter(host=None, path=None):
''' '''
Return a generator iterating over hosts Return a generator iterating over hosts
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
''' '''
tgt = host or '*' tgt = host or '*'
client = salt.client.get_local_client(__opts__['conf_file']) client = salt.client.get_local_client(__opts__['conf_file'])
for container_info in client.cmd_iter(tgt, 'lxc.list'): for container_info in client.cmd_iter(
tgt, 'lxc.list', kwarg={'path': path}
):
if not container_info: if not container_info:
continue continue
if not isinstance(container_info, dict): if not isinstance(container_info, dict):
@ -406,34 +460,47 @@ def _list_iter(host=None):
yield chunk yield chunk
def list_(host=None, quiet=False): def list_(host=None, quiet=False, path=None):
''' '''
List defined containers (running, stopped, and frozen) for the named List defined containers (running, stopped, and frozen) for the named
(or all) host(s). (or all) host(s).
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
.. code-block:: bash .. code-block:: bash
salt-run lxc.list [host=minion_id] salt-run lxc.list [host=minion_id]
''' '''
it = _list_iter(host) it = _list_iter(host, path=path)
ret = {} ret = {}
for chunk in it: for chunk in it:
ret.update(chunk) ret.update(chunk)
if not quiet: if not quiet:
__jid_event__.fire_event({'data': chunk, 'outputter': 'lxc_list'}, 'progress') __jid_event__.fire_event(
{'data': chunk, 'outputter': 'lxc_list'}, 'progress')
return ret return ret
def purge(name, delete_key=True, quiet=False): def purge(name, delete_key=True, quiet=False, path=None):
''' '''
Purge the named container and delete its minion key if present. Purge the named container and delete its minion key if present.
WARNING: Destroys all data associated with the container. WARNING: Destroys all data associated with the container.
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
.. code-block:: bash .. code-block:: bash
salt-run lxc.purge name salt-run lxc.purge name
''' '''
data = _do_names(name, 'destroy') data = _do_names(name, 'destroy', path=path)
if data is False: if data is False:
return data return data
@ -445,75 +512,111 @@ def purge(name, delete_key=True, quiet=False):
return return
if not quiet: if not quiet:
__jid_event__.fire_event({'data': data, 'outputter': 'lxc_purge'}, 'progress') __jid_event__.fire_event(
{'data': data, 'outputter': 'lxc_purge'}, 'progress')
return data return data
def start(name, quiet=False): def start(name, quiet=False, path=None):
''' '''
Start the named container. Start the named container.
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
.. code-block:: bash .. code-block:: bash
salt-run lxc.start name salt-run lxc.start name
''' '''
data = _do_names(name, 'start') data = _do_names(name, 'start', path=path)
if data and not quiet: if data and not quiet:
__jid_event__.fire_event({'data': data, 'outputter': 'lxc_start'}, 'progress') __jid_event__.fire_event(
{'data': data, 'outputter': 'lxc_start'}, 'progress')
return data return data
def stop(name, quiet=False): def stop(name, quiet=False, path=None):
''' '''
Stop the named container. Stop the named container.
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
.. code-block:: bash .. code-block:: bash
salt-run lxc.stop name salt-run lxc.stop name
''' '''
data = _do_names(name, 'stop') data = _do_names(name, 'stop', path=path)
if data and not quiet: if data and not quiet:
__jid_event__.fire_event({'data': data, 'outputter': 'lxc_force_off'}, 'progress') __jid_event__.fire_event(
{'data': data, 'outputter': 'lxc_force_off'}, 'progress')
return data return data
def freeze(name, quiet=False): def freeze(name, quiet=False, path=None):
''' '''
Freeze the named container Freeze the named container
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
.. code-block:: bash .. code-block:: bash
salt-run lxc.freeze name salt-run lxc.freeze name
''' '''
data = _do_names(name, 'freeze') data = _do_names(name, 'freeze')
if data and not quiet: if data and not quiet:
__jid_event__.fire_event({'data': data, 'outputter': 'lxc_pause'}, 'progress') __jid_event__.fire_event(
{'data': data, 'outputter': 'lxc_pause'}, 'progress')
return data return data
def unfreeze(name, quiet=False): def unfreeze(name, quiet=False, path=None):
''' '''
Unfreeze the named container Unfreeze the named container
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
.. code-block:: bash .. code-block:: bash
salt-run lxc.unfreeze name salt-run lxc.unfreeze name
''' '''
data = _do_names(name, 'unfreeze') data = _do_names(name, 'unfreeze', path=path)
if data and not quiet: if data and not quiet:
__jid_event__.fire_event({'data': data, 'outputter': 'lxc_resume'}, 'progress') __jid_event__.fire_event(
{'data': data, 'outputter': 'lxc_resume'}, 'progress')
return data return data
def info(name, quiet=False): def info(name, quiet=False, path=None):
''' '''
Returns information about a container. Returns information about a container.
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
.. code-block:: bash .. code-block:: bash
salt-run lxc.info name salt-run lxc.info name
''' '''
data = _do_names(name, 'info') data = _do_names(name, 'info', path=path)
if data and not quiet: if data and not quiet:
__jid_event__.fire_event({'data': data, 'outputter': 'lxc_info'}, 'progress') __jid_event__.fire_event(
{'data': data, 'outputter': 'lxc_info'}, 'progress')
return data return data

View File

@ -27,9 +27,11 @@ def present(name,
size=None, size=None,
backing=None, backing=None,
vgname=None, vgname=None,
lvname=None): lvname=None,
path=None):
''' '''
.. versionchanged:: 2015.5.0 .. versionchanged:: Beryllium
The :mod:`lxc.created <salt.states.lxc.created>` state has been renamed The :mod:`lxc.created <salt.states.lxc.created>` state has been renamed
to ``lxc.present``, and the :mod:`lxc.cloned <salt.states.lxc.cloned>` to ``lxc.present``, and the :mod:`lxc.cloned <salt.states.lxc.cloned>`
state has been merged into this state. state has been merged into this state.
@ -39,13 +41,20 @@ def present(name,
name name
The name of the container to be created The name of the container to be created
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
running : False running : False
* If ``True``, ensure that the container is running * If ``True``, ensure that the container is running
* If ``False``, ensure that the container is stopped * If ``False``, ensure that the container is stopped
* If ``None``, do nothing with regards to the running state of the * If ``None``, do nothing with regards to the running state of the
container container
.. versionadded:: 2015.5.0 .. versionadded:: Beryllium
clone_from clone_from
Create named container as a clone of the specified container Create named container as a clone of the specified container
@ -85,6 +94,7 @@ def present(name,
<salt.modules.lxc.images>` function. <salt.modules.lxc.images>` function.
options options
.. versionadded:: 2015.5.0 .. versionadded:: 2015.5.0
Template-specific options to pass to the lxc-create command. These Template-specific options to pass to the lxc-create command. These
@ -153,7 +163,7 @@ def present(name,
pass pass
# Sanity check(s) # Sanity check(s)
if clone_from and not __salt__['lxc.exists'](clone_from): if clone_from and not __salt__['lxc.exists'](clone_from, path=path):
ret['result'] = False ret['result'] = False
ret['comment'] = ('Clone source \'{0}\' does not exist' ret['comment'] = ('Clone source \'{0}\' does not exist'
.format(clone_from)) .format(clone_from))
@ -162,7 +172,7 @@ def present(name,
action = 'cloned from {0}'.format(clone_from) if clone_from else 'created' action = 'cloned from {0}'.format(clone_from) if clone_from else 'created'
state = {'old': __salt__['lxc.state'](name)} state = {'old': __salt__['lxc.state'](name, path=path)}
if __opts__['test']: if __opts__['test']:
if state['old'] is None: if state['old'] is None:
ret['comment'] = ( ret['comment'] = (
@ -213,6 +223,7 @@ def present(name,
network_profile=network_profile, network_profile=network_profile,
snapshot=snapshot, snapshot=snapshot,
size=size, size=size,
path=path,
backing=backing) backing=backing)
else: else:
result = __salt__['lxc.create']( result = __salt__['lxc.create'](
@ -227,6 +238,7 @@ def present(name,
size=size, size=size,
backing=backing, backing=backing,
vgname=vgname, vgname=vgname,
path=path,
lvname=lvname) lvname=lvname)
except (CommandExecutionError, SaltInvocationError) as exc: except (CommandExecutionError, SaltInvocationError) as exc:
ret['result'] = False ret['result'] = False
@ -245,7 +257,7 @@ def present(name,
# Don't do anything # Don't do anything
pass pass
elif running: elif running:
c_state = __salt__['lxc.state'](name) c_state = __salt__['lxc.state'](name, path=path)
if c_state == 'running': if c_state == 'running':
ret['comment'] += ' and is running' ret['comment'] += ' and is running'
else: else:
@ -253,7 +265,9 @@ def present(name,
try: try:
start_func = 'lxc.unfreeze' if c_state == 'frozen' \ start_func = 'lxc.unfreeze' if c_state == 'frozen' \
else 'lxc.start' else 'lxc.start'
state['new'] = __salt__[start_func](name)['state']['new'] state['new'] = __salt__[start_func](
name, path=path
)['state']['new']
if state['new'] != 'running': if state['new'] != 'running':
ret['result'] = False ret['result'] = False
ret['comment'] += error ret['comment'] += error
@ -273,14 +287,16 @@ def present(name,
) )
else: else:
c_state = __salt__['lxc.state'](name) c_state = __salt__['lxc.state'](name, path=path)
if c_state == 'stopped': if c_state == 'stopped':
if state['old'] is not None: if state['old'] is not None:
ret['comment'] += ' and is stopped' ret['comment'] += ' and is stopped'
else: else:
error = ', but it could not be stopped' error = ', but it could not be stopped'
try: try:
state['new'] = __salt__['lxc.stop'](name)['state']['new'] state['new'] = __salt__['lxc.stop'](
name, path=path
)['state']['new']
if state['new'] != 'stopped': if state['new'] != 'stopped':
ret['result'] = False ret['result'] = False
ret['comment'] += error ret['comment'] += error
@ -296,13 +312,13 @@ def present(name,
if 'new' not in state: if 'new' not in state:
# Make sure we know the final state of the container before we return # Make sure we know the final state of the container before we return
state['new'] = __salt__['lxc.state'](name) state['new'] = __salt__['lxc.state'](name, path=path)
if state['old'] != state['new']: if state['old'] != state['new']:
ret['changes']['state'] = state ret['changes']['state'] = state
return ret return ret
def absent(name, stop=False): def absent(name, stop=False, path=None):
''' '''
Ensure a container is not present, destroying it if present Ensure a container is not present, destroying it if present
@ -315,6 +331,13 @@ def absent(name, stop=False):
.. versionadded:: 2015.5.2 .. versionadded:: 2015.5.2
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
.. code-block:: yaml .. code-block:: yaml
web01: web01:
@ -325,7 +348,7 @@ def absent(name, stop=False):
'result': True, 'result': True,
'comment': 'Container \'{0}\' does not exist'.format(name)} 'comment': 'Container \'{0}\' does not exist'.format(name)}
if not __salt__['lxc.exists'](name): if not __salt__['lxc.exists'](name, path=path):
return ret return ret
if __opts__['test']: if __opts__['test']:
@ -334,7 +357,7 @@ def absent(name, stop=False):
return ret return ret
try: try:
result = __salt__['lxc.destroy'](name, stop=stop) result = __salt__['lxc.destroy'](name, stop=stop, path=path)
except (SaltInvocationError, CommandExecutionError) as exc: except (SaltInvocationError, CommandExecutionError) as exc:
ret['result'] = False ret['result'] = False
ret['comment'] = 'Failed to destroy container: {0}'.format(exc) ret['comment'] = 'Failed to destroy container: {0}'.format(exc)
@ -345,7 +368,7 @@ def absent(name, stop=False):
# Container state (running/frozen/stopped) # Container state (running/frozen/stopped)
def running(name, restart=False): def running(name, restart=False, path=None):
''' '''
.. versionchanged:: 2015.5.0 .. versionchanged:: 2015.5.0
The :mod:`lxc.started <salt.states.lxc.started>` state has been renamed The :mod:`lxc.started <salt.states.lxc.started>` state has been renamed
@ -363,6 +386,12 @@ def running(name, restart=False):
name name
The name of the container The name of the container
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
restart : False restart : False
Restart container if it is already running Restart container if it is already running
@ -380,7 +409,7 @@ def running(name, restart=False):
'comment': 'Container \'{0}\' is already running'.format(name), 'comment': 'Container \'{0}\' is already running'.format(name),
'changes': {}} 'changes': {}}
state = {'old': __salt__['lxc.state'](name)} state = {'old': __salt__['lxc.state'](name, path=path)}
if state['old'] is None: if state['old'] is None:
ret['result'] = False ret['result'] = False
ret['comment'] = 'Container \'{0}\' does not exist'.format(name) ret['comment'] = 'Container \'{0}\' does not exist'.format(name)
@ -410,16 +439,16 @@ def running(name, restart=False):
try: try:
if state['old'] == 'frozen' and not restart: if state['old'] == 'frozen' and not restart:
result = __salt__['lxc.unfreeze'](name) result = __salt__['lxc.unfreeze'](name, path=path)
else: else:
if restart: if restart:
result = __salt__['lxc.restart'](name) result = __salt__['lxc.restart'](name, path=path)
else: else:
result = __salt__['lxc.start'](name) result = __salt__['lxc.start'](name, path=path)
except (CommandExecutionError, SaltInvocationError) as exc: except (CommandExecutionError, SaltInvocationError) as exc:
ret['result'] = False ret['result'] = False
ret['comment'] = exc.strerror ret['comment'] = exc.strerror
state['new'] = __salt__['lxc.state'](name) state['new'] = __salt__['lxc.state'](name, path=path)
else: else:
state['new'] = result['state']['new'] state['new'] = result['state']['new']
if state['new'] != 'running': if state['new'] != 'running':
@ -439,7 +468,7 @@ def running(name, restart=False):
return ret return ret
def frozen(name, start=True): def frozen(name, start=True, path=None):
''' '''
.. versionadded:: 2015.5.0 .. versionadded:: 2015.5.0
@ -454,6 +483,13 @@ def frozen(name, start=True):
name name
The name of the container The name of the container
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
start : True start : True
Start container first, if necessary. If ``False``, then this state will Start container first, if necessary. If ``False``, then this state will
fail if the container is not running. fail if the container is not running.
@ -472,7 +508,7 @@ def frozen(name, start=True):
'comment': 'Container \'{0}\' is already frozen'.format(name), 'comment': 'Container \'{0}\' is already frozen'.format(name),
'changes': {}} 'changes': {}}
state = {'old': __salt__['lxc.state'](name)} state = {'old': __salt__['lxc.state'](name, path=path)}
if state['old'] is None: if state['old'] is None:
ret['result'] = False ret['result'] = False
ret['comment'] = 'Container \'{0}\' does not exist'.format(name) ret['comment'] = 'Container \'{0}\' does not exist'.format(name)
@ -495,11 +531,11 @@ def frozen(name, start=True):
return ret return ret
try: try:
result = __salt__['lxc.freeze'](name, start=start) result = __salt__['lxc.freeze'](name, start=start, path=path)
except (CommandExecutionError, SaltInvocationError) as exc: except (CommandExecutionError, SaltInvocationError) as exc:
ret['result'] = False ret['result'] = False
ret['comment'] = exc.strerror ret['comment'] = exc.strerror
state['new'] = __salt__['lxc.state'](name) state['new'] = __salt__['lxc.state'](name, path=path)
else: else:
state['new'] = result['state']['new'] state['new'] = result['state']['new']
if state['new'] != 'frozen': if state['new'] != 'frozen':
@ -519,7 +555,7 @@ def frozen(name, start=True):
return ret return ret
def stopped(name, kill=False): def stopped(name, kill=False, path=None):
''' '''
Ensure that a container is stopped Ensure that a container is stopped
@ -535,6 +571,12 @@ def stopped(name, kill=False):
name name
The name of the container The name of the container
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
kill : False kill : False
Do not wait for the container to stop, kill all tasks in the container. Do not wait for the container to stop, kill all tasks in the container.
Older LXC versions will stop containers like this irrespective of this Older LXC versions will stop containers like this irrespective of this
@ -552,7 +594,7 @@ def stopped(name, kill=False):
'comment': 'Container \'{0}\' is already stopped'.format(name), 'comment': 'Container \'{0}\' is already stopped'.format(name),
'changes': {}} 'changes': {}}
state = {'old': __salt__['lxc.state'](name)} state = {'old': __salt__['lxc.state'](name, path=path)}
if state['old'] is None: if state['old'] is None:
ret['result'] = False ret['result'] = False
ret['comment'] = 'Container \'{0}\' does not exist'.format(name) ret['comment'] = 'Container \'{0}\' does not exist'.format(name)
@ -572,11 +614,11 @@ def stopped(name, kill=False):
return ret return ret
try: try:
result = __salt__['lxc.stop'](name, kill=kill) result = __salt__['lxc.stop'](name, kill=kill, path=path)
except (CommandExecutionError, SaltInvocationError) as exc: except (CommandExecutionError, SaltInvocationError) as exc:
ret['result'] = False ret['result'] = False
ret['comment'] = exc.strerror ret['comment'] = exc.strerror
state['new'] = __salt__['lxc.state'](name) state['new'] = __salt__['lxc.state'](name, path=path)
else: else:
state['new'] = result['state']['new'] state['new'] = result['state']['new']
if state['new'] != 'stopped': if state['new'] != 'stopped':
@ -606,7 +648,7 @@ def created(name, **kwargs):
return present(name, **kwargs) return present(name, **kwargs)
def started(name, restart=False): def started(name, path=None, restart=False):
''' '''
.. deprecated:: 2015.5.0 .. deprecated:: 2015.5.0
Use :mod:`lxc.running <salt.states.lxc.running>` Use :mod:`lxc.running <salt.states.lxc.running>`
@ -616,7 +658,7 @@ def started(name, restart=False):
'The lxc.started state has been renamed to lxc.running, please use ' 'The lxc.started state has been renamed to lxc.running, please use '
'lxc.running' 'lxc.running'
) )
return running(name, restart=restart) return running(name, restart=restart, path=path)
def cloned(name, def cloned(name,
@ -624,6 +666,7 @@ def cloned(name,
snapshot=True, snapshot=True,
size=None, size=None,
vgname=None, vgname=None,
path=None,
profile=None): profile=None):
''' '''
.. deprecated:: 2015.5.0 .. deprecated:: 2015.5.0
@ -640,6 +683,7 @@ def cloned(name,
snapshot=snapshot, snapshot=snapshot,
size=size, size=size,
vgname=vgname, vgname=vgname,
path=path,
profile=profile) profile=profile)
@ -682,6 +726,13 @@ def edited_conf(name, lxc_conf=None, lxc_conf_unset=None):
Edit LXC configuration options Edit LXC configuration options
path
path to the container parent
default: /var/lib/lxc (system default)
.. versionadded:: Beryllium
.. code-block:: bash .. code-block:: bash
setconf: setconf: