mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Split config parameter to config, devices, profiles, source et al
This commit is contained in:
parent
776a748eb4
commit
a0bf88f60a
1 changed files with 83 additions and 49 deletions
|
@ -32,26 +32,43 @@ options:
|
||||||
description:
|
description:
|
||||||
- Name of a container.
|
- Name of a container.
|
||||||
required: true
|
required: true
|
||||||
|
architecture:
|
||||||
|
description:
|
||||||
|
- The archiecture for the container (e.g. "x86_64" or "i686").
|
||||||
|
See https://github.com/lxc/lxd/blob/master/doc/rest-api.md#post-1
|
||||||
|
required: false
|
||||||
config:
|
config:
|
||||||
description:
|
description:
|
||||||
- A config dictionary for creating a container.
|
- The config for the container (e.g. '{"limits.cpu": "2"}').
|
||||||
See https://github.com/lxc/lxd/blob/master/doc/rest-api.md#post-1
|
See https://github.com/lxc/lxd/blob/master/doc/rest-api.md#post-1
|
||||||
- Required when the container is not created yet and the state is
|
- If the container already exists and its "config" value in metadata
|
||||||
not absent.
|
obtained from
|
||||||
- If the container already exists and its metadata obtained from
|
|
||||||
GET /1.0/containers/<name>
|
GET /1.0/containers/<name>
|
||||||
https://github.com/lxc/lxd/blob/master/doc/rest-api.md#10containersname
|
https://github.com/lxc/lxd/blob/master/doc/rest-api.md#10containersname
|
||||||
are different, they this module tries to apply the configurations.
|
are different, they this module tries to apply the configurations.
|
||||||
The following keys in config will be compared and applied.
|
- The key starts with 'volatile.' are ignored for this comparison.
|
||||||
- architecture
|
|
||||||
- config
|
|
||||||
- The key starts with 'volatile.' are ignored for comparison.
|
|
||||||
- devices
|
|
||||||
- ephemeral
|
|
||||||
- profiles
|
|
||||||
- Not all config values are supported to apply the existing container.
|
- Not all config values are supported to apply the existing container.
|
||||||
Maybe you need to delete and recreate a container.
|
Maybe you need to delete and recreate a container.
|
||||||
required: false
|
required: false
|
||||||
|
devices:
|
||||||
|
description:
|
||||||
|
- The devices for the container
|
||||||
|
(e.g. '{ "rootfs": { "path": "/dev/kvm", "type": "unix-char" }').
|
||||||
|
See https://github.com/lxc/lxd/blob/master/doc/rest-api.md#post-1
|
||||||
|
required: false
|
||||||
|
ephemeral:
|
||||||
|
description:
|
||||||
|
- Whether or not the container is ephemeral (e.g. true or false).
|
||||||
|
See https://github.com/lxc/lxd/blob/master/doc/rest-api.md#post-1
|
||||||
|
required: false
|
||||||
|
source:
|
||||||
|
description:
|
||||||
|
- The source for the container
|
||||||
|
(e.g. '{ "type": "image", "mode": "pull",
|
||||||
|
"server": "https://images.linuxcontainers.org", "protocol": "lxd",
|
||||||
|
"alias": "ubuntu/xenial/amd64" }').
|
||||||
|
See https://github.com/lxc/lxd/blob/master/doc/rest-api.md#post-1
|
||||||
|
required: false
|
||||||
state:
|
state:
|
||||||
choices:
|
choices:
|
||||||
- started
|
- started
|
||||||
|
@ -113,14 +130,13 @@ EXAMPLES = """
|
||||||
lxd_container:
|
lxd_container:
|
||||||
name: mycontainer
|
name: mycontainer
|
||||||
state: started
|
state: started
|
||||||
config:
|
source:
|
||||||
source:
|
type: image
|
||||||
type: image
|
mode: pull
|
||||||
mode: pull
|
server: https://images.linuxcontainers.org
|
||||||
server: https://images.linuxcontainers.org
|
protocol: lxd
|
||||||
protocol: lxd
|
alias: "ubuntu/xenial/amd64"
|
||||||
alias: "ubuntu/xenial/amd64"
|
profiles: ["default"]
|
||||||
profiles: ["default"]
|
|
||||||
- name: Install python in the created container "mycontainer"
|
- name: Install python in the created container "mycontainer"
|
||||||
command: lxc exec mycontainer -- apt install -y python
|
command: lxc exec mycontainer -- apt install -y python
|
||||||
- name: Copy /etc/hosts in the created container "mycontainer" to localhost with name "mycontainer-hosts"
|
- name: Copy /etc/hosts in the created container "mycontainer" to localhost with name "mycontainer-hosts"
|
||||||
|
@ -144,14 +160,13 @@ EXAMPLES = """
|
||||||
lxd_container:
|
lxd_container:
|
||||||
name: mycontainer
|
name: mycontainer
|
||||||
state: stopped
|
state: stopped
|
||||||
config:
|
source:
|
||||||
source:
|
type: image
|
||||||
type: image
|
mode: pull
|
||||||
mode: pull
|
server: https://images.linuxcontainers.org
|
||||||
server: https://images.linuxcontainers.org
|
protocol: lxd
|
||||||
protocol: lxd
|
alias: "ubuntu/xenial/amd64"
|
||||||
alias: "ubuntu/xenial/amd64"
|
profiles: ["default"]
|
||||||
profiles: ["default"]
|
|
||||||
|
|
||||||
- hosts: localhost
|
- hosts: localhost
|
||||||
connection: local
|
connection: local
|
||||||
|
@ -160,14 +175,13 @@ EXAMPLES = """
|
||||||
lxd_container:
|
lxd_container:
|
||||||
name: mycontainer
|
name: mycontainer
|
||||||
state: restarted
|
state: restarted
|
||||||
config:
|
source:
|
||||||
source:
|
type: image
|
||||||
type: image
|
mode: pull
|
||||||
mode: pull
|
server: https://images.linuxcontainers.org
|
||||||
server: https://images.linuxcontainers.org
|
protocol: lxd
|
||||||
protocol: lxd
|
alias: "ubuntu/xenial/amd64"
|
||||||
alias: "ubuntu/xenial/amd64"
|
profiles: ["default"]
|
||||||
profiles: ["default"]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
RETURN="""
|
RETURN="""
|
||||||
|
@ -257,7 +271,13 @@ class LxdContainerManagement(object):
|
||||||
"""
|
"""
|
||||||
self.module = module
|
self.module = module
|
||||||
self.container_name = self.module.params['name']
|
self.container_name = self.module.params['name']
|
||||||
self.config = self.module.params.get('config', None)
|
|
||||||
|
self.container_config = {}
|
||||||
|
for attr in ['architecture', 'config', 'devices', 'ephemeral', 'profiles', 'source']:
|
||||||
|
param_val = self.module.params.get(attr, None)
|
||||||
|
if param_val is not None:
|
||||||
|
self.container_config[attr] = param_val
|
||||||
|
|
||||||
self.state = self.module.params['state']
|
self.state = self.module.params['state']
|
||||||
self.timeout = self.module.params['timeout']
|
self.timeout = self.module.params['timeout']
|
||||||
self.wait_for_ipv4_addresses = self.module.params['wait_for_ipv4_addresses']
|
self.wait_for_ipv4_addresses = self.module.params['wait_for_ipv4_addresses']
|
||||||
|
@ -296,13 +316,12 @@ class LxdContainerManagement(object):
|
||||||
def _operate_and_wait(self, method, path, body_json=None):
|
def _operate_and_wait(self, method, path, body_json=None):
|
||||||
resp_json = self._send_request(method, path, body_json=body_json)
|
resp_json = self._send_request(method, path, body_json=body_json)
|
||||||
if resp_json['type'] == 'async':
|
if resp_json['type'] == 'async':
|
||||||
path = '{0}/wait?timeout={1}'.format(resp_json['operation'], self.timeout)
|
url = '{0}/wait?timeout={1}'.format(resp_json['operation'], self.timeout)
|
||||||
resp_json = self._send_request('GET', path)
|
resp_json = self._send_request('GET', url)
|
||||||
if resp_json['metadata']['status'] != 'Success':
|
if resp_json['metadata']['status'] != 'Success':
|
||||||
url = self._path_to_url(path)
|
|
||||||
self.module.fail_json(
|
self.module.fail_json(
|
||||||
msg='error response for waiting opearation',
|
msg='error response for waiting opearation',
|
||||||
request={'method': method, 'url': url, 'json': body_json, 'timeout': self.timeout},
|
request={'method': method, 'url': url, 'timeout': self.timeout},
|
||||||
response={'json': resp_json},
|
response={'json': resp_json},
|
||||||
logs=self.logs
|
logs=self.logs
|
||||||
)
|
)
|
||||||
|
@ -333,10 +352,10 @@ class LxdContainerManagement(object):
|
||||||
return self._operate_and_wait('PUT', '/1.0/containers/{0}/state'.format(self.container_name), body_json=body_json)
|
return self._operate_and_wait('PUT', '/1.0/containers/{0}/state'.format(self.container_name), body_json=body_json)
|
||||||
|
|
||||||
def _create_container(self):
|
def _create_container(self):
|
||||||
config = self.config.copy()
|
config = self.container_config.copy()
|
||||||
config['name'] = self.container_name
|
config['name'] = self.container_name
|
||||||
self._operate_and_wait('POST', '/1.0/containers', config)
|
self._operate_and_wait('POST', '/1.0/containers', config)
|
||||||
self.actions.append('creat')
|
self.actions.append('create')
|
||||||
|
|
||||||
def _start_container(self):
|
def _start_container(self):
|
||||||
self._change_state('start')
|
self._change_state('start')
|
||||||
|
@ -453,13 +472,13 @@ class LxdContainerManagement(object):
|
||||||
self._freeze_container()
|
self._freeze_container()
|
||||||
|
|
||||||
def _needs_to_change_config(self, key):
|
def _needs_to_change_config(self, key):
|
||||||
if key not in self.config:
|
if key not in self.container_config:
|
||||||
return False
|
return False
|
||||||
if key == 'config':
|
if key == 'config':
|
||||||
old_configs = dict((k, v) for k, v in self.old_container_json['metadata'][key].items() if not k.startswith('volatile.'))
|
old_configs = dict((k, v) for k, v in self.old_container_json['metadata'][key].items() if not k.startswith('volatile.'))
|
||||||
else:
|
else:
|
||||||
old_configs = self.old_container_json['metadata'][key]
|
old_configs = self.old_container_json['metadata'][key]
|
||||||
return self.config[key] != old_configs
|
return self.container_config[key] != old_configs
|
||||||
|
|
||||||
def _needs_to_apply_configs(self):
|
def _needs_to_apply_configs(self):
|
||||||
return (
|
return (
|
||||||
|
@ -479,16 +498,16 @@ class LxdContainerManagement(object):
|
||||||
'profiles': old_metadata['profiles']
|
'profiles': old_metadata['profiles']
|
||||||
}
|
}
|
||||||
if self._needs_to_change_config('architecture'):
|
if self._needs_to_change_config('architecture'):
|
||||||
body_json['architecture'] = self.config['architecture']
|
body_json['architecture'] = self.container_config['architecture']
|
||||||
if self._needs_to_change_config('config'):
|
if self._needs_to_change_config('config'):
|
||||||
for k, v in self.config['config'].items():
|
for k, v in self.container_config['config'].items():
|
||||||
body_json['config'][k] = v
|
body_json['config'][k] = v
|
||||||
if self._needs_to_change_config('ephemeral'):
|
if self._needs_to_change_config('ephemeral'):
|
||||||
body_json['ephemeral'] = self.config['ephemeral']
|
body_json['ephemeral'] = self.container_config['ephemeral']
|
||||||
if self._needs_to_change_config('devices'):
|
if self._needs_to_change_config('devices'):
|
||||||
body_json['devices'] = self.config['devices']
|
body_json['devices'] = self.container_config['devices']
|
||||||
if self._needs_to_change_config('profiles'):
|
if self._needs_to_change_config('profiles'):
|
||||||
body_json['profiles'] = self.config['profiles']
|
body_json['profiles'] = self.container_config['profiles']
|
||||||
self._operate_and_wait('PUT', '/1.0/containers/{0}'.format(self.container_name), body_json=body_json)
|
self._operate_and_wait('PUT', '/1.0/containers/{0}'.format(self.container_name), body_json=body_json)
|
||||||
self.actions.append('apply_configs')
|
self.actions.append('apply_configs')
|
||||||
|
|
||||||
|
@ -522,9 +541,24 @@ def main():
|
||||||
type='str',
|
type='str',
|
||||||
required=True
|
required=True
|
||||||
),
|
),
|
||||||
|
architecture=dict(
|
||||||
|
type='str',
|
||||||
|
),
|
||||||
config=dict(
|
config=dict(
|
||||||
type='dict',
|
type='dict',
|
||||||
),
|
),
|
||||||
|
devices=dict(
|
||||||
|
type='dict',
|
||||||
|
),
|
||||||
|
ephemeral=dict(
|
||||||
|
type='bool',
|
||||||
|
),
|
||||||
|
profiles=dict(
|
||||||
|
type='list',
|
||||||
|
),
|
||||||
|
source=dict(
|
||||||
|
type='dict',
|
||||||
|
),
|
||||||
state=dict(
|
state=dict(
|
||||||
choices=LXD_ANSIBLE_STATES.keys(),
|
choices=LXD_ANSIBLE_STATES.keys(),
|
||||||
default='started'
|
default='started'
|
||||||
|
|
Loading…
Reference in a new issue