%PDF- %PDF-
Direktori : /proc/self/root/usr/lib/python2.7/site-packages/salt/states/ |
Current File : //proc/self/root/usr/lib/python2.7/site-packages/salt/states/lxd_image.py |
# -*- coding: utf-8 -*- ''' Manage LXD images. .. versionadded:: 2019.2.0 .. note: - `pylxd`_ version 2 is required to let this work, currently only available via pip. To install on Ubuntu: $ apt-get install libssl-dev python-pip $ pip install -U pylxd - you need lxd installed on the minion for the init() and version() methods. - for the config_get() and config_get() methods you need to have lxd-client installed. .. _: https://github.com/lxc/pylxd/blob/master/doc/source/installation.rst :maintainer: René Jochum <rene@jochums.at> :maturity: new :depends: python-pylxd :platform: Linux ''' # Import python libs from __future__ import absolute_import, print_function, unicode_literals # Import salt libs from salt.exceptions import CommandExecutionError from salt.exceptions import SaltInvocationError import salt.ext.six as six from salt.ext.six.moves import map __docformat__ = 'restructuredtext en' __virtualname__ = 'lxd_image' def __virtual__(): ''' Only load if the lxd module is available in __salt__ ''' return __virtualname__ if 'lxd.version' in __salt__ else False def present(name, source, aliases=None, public=None, auto_update=None, remote_addr=None, cert=None, key=None, verify_cert=True): ''' Ensure an image exists, copy it else from source name : An alias of the image, this is used to check if the image exists and it will be added as alias to the image on copy/create. source : Source dict. For an LXD to LXD copy: .. code-block: yaml source: type: lxd name: ubuntu/xenial/amd64 # This can also be a fingerprint. remote_addr: https://images.linuxcontainers.org:8443 cert: ~/.config/lxd/client.crt key: ~/.config/lxd/client.key verify_cert: False .. attention: For this kind of remote you also need to provide: - a https:// remote_addr - a cert and key - verify_cert From file: .. code-block: yaml source: type: file filename: salt://lxd/files/busybox.tar.xz saltenv: base From simplestreams: .. code-block: yaml source: type: simplestreams server: https://cloud-images.ubuntu.com/releases name: xenial/amd64 From an URL: .. code-block: yaml source: type: url url: https://dl.stgraber.org/lxd aliases : List of aliases to append, can be empty. public : Make this image public available on this instance? None on source_type LXD means copy source None on source_type file means False auto_update : Try to auto-update from the original source? None on source_type LXD means copy source source_type file does not have auto-update. remote_addr : An URL to a remote Server, you also have to give cert and key if you provide remote_addr! Examples: https://myserver.lan:8443 /var/lib/mysocket.sock cert : PEM Formatted SSL Zertifikate. Examples: ~/.config/lxc/client.crt key : PEM Formatted SSL Key. Examples: ~/.config/lxc/client.key verify_cert : True Wherever to verify the cert, this is by default True but in the most cases you want to set it off as LXD normaly uses self-signed certificates. ''' if aliases is None: aliases = [] # Create a copy of aliases, since we're modifying it here aliases = aliases[:] ret = { 'name': name, 'source': source, 'aliases': aliases, 'public': public, 'auto_update': auto_update, 'remote_addr': remote_addr, 'cert': cert, 'key': key, 'verify_cert': verify_cert, 'changes': {} } image = None try: image = __salt__['lxd.image_get_by_alias']( name, remote_addr, cert, key, verify_cert, _raw=True ) except CommandExecutionError as e: return _error(ret, six.text_type(e)) except SaltInvocationError as e: # Image not found pass if image is None: if __opts__['test']: # Test is on, just return that we would create the image msg = 'Would create the image "{0}"'.format(name) ret['changes'] = {'created': msg} return _unchanged(ret, msg) try: if source['type'] == 'lxd': image = __salt__['lxd.image_copy_lxd']( source['name'], src_remote_addr=source['remote_addr'], src_cert=source['cert'], src_key=source['key'], src_verify_cert=source.get('verify_cert', True), remote_addr=remote_addr, cert=cert, key=key, verify_cert=verify_cert, aliases=aliases, public=public, auto_update=auto_update, _raw=True ) if source['type'] == 'file': if 'saltenv' not in source: source['saltenv'] = __env__ image = __salt__['lxd.image_from_file']( source['filename'], remote_addr=remote_addr, cert=cert, key=key, verify_cert=verify_cert, aliases=aliases, public=False if public is None else public, saltenv=source['saltenv'], _raw=True ) if source['type'] == 'simplestreams': image = __salt__['lxd.image_from_simplestreams']( source['server'], source['name'], remote_addr=remote_addr, cert=cert, key=key, verify_cert=verify_cert, aliases=aliases, public=False if public is None else public, auto_update=False if auto_update is None else auto_update, _raw=True ) if source['type'] == 'url': image = __salt__['lxd.image_from_url']( source['url'], remote_addr=remote_addr, cert=cert, key=key, verify_cert=verify_cert, aliases=aliases, public=False if public is None else public, auto_update=False if auto_update is None else auto_update, _raw=True ) except CommandExecutionError as e: return _error(ret, six.text_type(e)) # Sync aliases if name not in aliases: aliases.append(name) old_aliases = set([six.text_type(a['name']) for a in image.aliases]) new_aliases = set(map(six.text_type, aliases)) alias_changes = [] # Removed aliases for k in old_aliases.difference(new_aliases): if not __opts__['test']: __salt__['lxd.image_alias_delete'](image, k) alias_changes.append('Removed alias "{0}"'.format(k)) else: alias_changes.append('Would remove alias "{0}"'.format(k)) # New aliases for k in new_aliases.difference(old_aliases): if not __opts__['test']: __salt__['lxd.image_alias_add'](image, k, '') alias_changes.append('Added alias "{0}"'.format(k)) else: alias_changes.append('Would add alias "{0}"'.format(k)) if alias_changes: ret['changes']['aliases'] = alias_changes # Set public if public is not None and image.public != public: if not __opts__['test']: ret['changes']['public'] = \ 'Setting the image public to {0!s}'.format(public) image.public = public __salt__['lxd.pylxd_save_object'](image) else: ret['changes']['public'] = \ 'Would set public to {0!s}'.format(public) if __opts__['test'] and ret['changes']: return _unchanged( ret, 'Would do {0} changes'.format(len(ret['changes'].keys())) ) return _success(ret, '{0} changes'.format(len(ret['changes'].keys()))) def absent(name, remote_addr=None, cert=None, key=None, verify_cert=True): ''' name : An alias or fingerprint of the image to check and delete. remote_addr : An URL to a remote Server, you also have to give cert and key if you provide remote_addr! Examples: https://myserver.lan:8443 /var/lib/mysocket.sock cert : PEM Formatted SSL Zertifikate. Examples: ~/.config/lxc/client.crt key : PEM Formatted SSL Key. Examples: ~/.config/lxc/client.key verify_cert : True Wherever to verify the cert, this is by default True but in the most cases you want to set it off as LXD normaly uses self-signed certificates. ''' ret = { 'name': name, 'remote_addr': remote_addr, 'cert': cert, 'key': key, 'verify_cert': verify_cert, 'changes': {} } image = None try: image = __salt__['lxd.image_get_by_alias']( name, remote_addr, cert, key, verify_cert, _raw=True ) except CommandExecutionError as e: return _error(ret, six.text_type(e)) except SaltInvocationError as e: try: image = __salt__['lxd.image_get']( name, remote_addr, cert, key, verify_cert, _raw=True ) except CommandExecutionError as e: return _error(ret, six.text_type(e)) except SaltInvocationError as e: return _success(ret, 'Image "{0}" not found.'.format(name)) if __opts__['test']: ret['changes'] = { 'removed': 'Image "{0}" would get deleted.'.format(name) } return _success(ret, ret['changes']['removed']) __salt__['lxd.image_delete']( image ) ret['changes'] = { 'removed': 'Image "{0}" has been deleted.'.format(name) } return _success(ret, ret['changes']['removed']) def _success(ret, success_msg): ret['result'] = True ret['comment'] = success_msg if 'changes' not in ret: ret['changes'] = {} return ret def _unchanged(ret, msg): ret['result'] = None ret['comment'] = msg if 'changes' not in ret: ret['changes'] = {} return ret def _error(ret, err_msg): ret['result'] = False ret['comment'] = err_msg if 'changes' not in ret: ret['changes'] = {} return ret