mirror of
https://github.com/ansible-collections/community.docker.git
synced 2026-03-15 19:58:28 +00:00
Support labels and shm_size for image build. Allow to specify (swap) memory limits in other units than bytes. (#727)
This commit is contained in:
parent
74636e7f0e
commit
0812d0b495
3
changelogs/fragments/727-docker_image-build.yml
Normal file
3
changelogs/fragments/727-docker_image-build.yml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
minor_changes:
|
||||||
|
- "docker_image - allow to specify labels and ``/dev/shm`` size when building images (https://github.com/ansible-collections/community.docker/issues/726, https://github.com/ansible-collections/community.docker/pull/727)."
|
||||||
|
- "docker_image - allow to specify memory size and swap memory size in other units than bytes (https://github.com/ansible-collections/community.docker/pull/727)."
|
||||||
@ -156,7 +156,8 @@ options:
|
|||||||
type: float
|
type: float
|
||||||
cpuset_cpus:
|
cpuset_cpus:
|
||||||
description:
|
description:
|
||||||
- CPUs in which to allow execution V(1,3) or V(1-3).
|
- CPUs in which to allow execution.
|
||||||
|
- For example V(1,3) or V(1-3).
|
||||||
type: str
|
type: str
|
||||||
cpuset_mems:
|
cpuset_mems:
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -112,13 +112,21 @@ options:
|
|||||||
suboptions:
|
suboptions:
|
||||||
memory:
|
memory:
|
||||||
description:
|
description:
|
||||||
- Set memory limit for build.
|
- "Memory limit for build in format C(<number>[<unit>]). Number is a positive integer.
|
||||||
type: int
|
Unit can be V(B) (byte), V(K) (kibibyte, 1024B), V(M) (mebibyte), V(G) (gibibyte),
|
||||||
|
V(T) (tebibyte), or V(P) (pebibyte)."
|
||||||
|
- Omitting the unit defaults to bytes.
|
||||||
|
- Before community.docker 3.6.0, no units were allowed.
|
||||||
|
type: str
|
||||||
memswap:
|
memswap:
|
||||||
description:
|
description:
|
||||||
- Total memory (memory + swap).
|
- "Total memory limit (memory + swap) for build in format C(<number>[<unit>]), or
|
||||||
- Use V(-1) to disable swap.
|
the special values V(unlimited) or V(-1) for unlimited swap usage.
|
||||||
type: int
|
Number is a positive integer. Unit can be V(B) (byte), V(K) (kibibyte, 1024B),
|
||||||
|
V(M) (mebibyte), V(G) (gibibyte), V(T) (tebibyte), or V(P) (pebibyte)."
|
||||||
|
- Omitting the unit defaults to bytes.
|
||||||
|
- Before community.docker 3.6.0, no units were allowed, and neither was the special value V(unlimited).
|
||||||
|
type: str
|
||||||
cpushares:
|
cpushares:
|
||||||
description:
|
description:
|
||||||
- CPU shares (relative weight).
|
- CPU shares (relative weight).
|
||||||
@ -144,6 +152,19 @@ options:
|
|||||||
- Platform in the format C(os[/arch[/variant]]).
|
- Platform in the format C(os[/arch[/variant]]).
|
||||||
type: str
|
type: str
|
||||||
version_added: 1.1.0
|
version_added: 1.1.0
|
||||||
|
shm_size:
|
||||||
|
description:
|
||||||
|
- "Size of C(/dev/shm) in format C(<number>[<unit>]). Number is positive integer.
|
||||||
|
Unit can be V(B) (byte), V(K) (kibibyte, 1024B), V(M) (mebibyte), V(G) (gibibyte),
|
||||||
|
V(T) (tebibyte), or V(P) (pebibyte)."
|
||||||
|
- Omitting the unit defaults to bytes. If you omit the size entirely, Docker daemon uses V(64M).
|
||||||
|
type: str
|
||||||
|
version_added: 3.6.0
|
||||||
|
labels:
|
||||||
|
description:
|
||||||
|
- Dictionary of key value pairs.
|
||||||
|
type: dict
|
||||||
|
version_added: 3.6.0
|
||||||
archive_path:
|
archive_path:
|
||||||
description:
|
description:
|
||||||
- Use with O(state=present) to archive an image to a C(.tar) file.
|
- Use with O(state=present) to archive an image to a C(.tar) file.
|
||||||
@ -338,6 +359,7 @@ import os
|
|||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
|
from ansible.module_utils.common.text.formatters import human_to_bytes
|
||||||
|
|
||||||
from ansible_collections.community.docker.plugins.module_utils.common_api import (
|
from ansible_collections.community.docker.plugins.module_utils.common_api import (
|
||||||
AnsibleDockerClient,
|
AnsibleDockerClient,
|
||||||
@ -377,6 +399,17 @@ from ansible_collections.community.docker.plugins.module_utils._api.utils.utils
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def convert_to_bytes(value, module, name, unlimited_value=None):
|
||||||
|
if value is None:
|
||||||
|
return value
|
||||||
|
try:
|
||||||
|
if unlimited_value is not None and value in ('unlimited', str(unlimited_value)):
|
||||||
|
return unlimited_value
|
||||||
|
return human_to_bytes(value)
|
||||||
|
except ValueError as exc:
|
||||||
|
module.fail_json(msg='Failed to convert %s to bytes: %s' % (name, to_native(exc)))
|
||||||
|
|
||||||
|
|
||||||
class ImageManager(DockerBaseClass):
|
class ImageManager(DockerBaseClass):
|
||||||
|
|
||||||
def __init__(self, client, results):
|
def __init__(self, client, results):
|
||||||
@ -402,6 +435,12 @@ class ImageManager(DockerBaseClass):
|
|||||||
self.archive_path = parameters['archive_path']
|
self.archive_path = parameters['archive_path']
|
||||||
self.cache_from = build.get('cache_from')
|
self.cache_from = build.get('cache_from')
|
||||||
self.container_limits = build.get('container_limits')
|
self.container_limits = build.get('container_limits')
|
||||||
|
if self.container_limits and 'memory' in self.container_limits:
|
||||||
|
self.container_limits['memory'] = convert_to_bytes(
|
||||||
|
self.container_limits['memory'], self.client.module, 'build.container_limits.memory')
|
||||||
|
if self.container_limits and 'memswap' in self.container_limits:
|
||||||
|
self.container_limits['memswap'] = convert_to_bytes(
|
||||||
|
self.container_limits['memswap'], self.client.module, 'build.container_limits.memswap', unlimited_value=-1)
|
||||||
self.dockerfile = build.get('dockerfile')
|
self.dockerfile = build.get('dockerfile')
|
||||||
self.force_source = parameters['force_source']
|
self.force_source = parameters['force_source']
|
||||||
self.force_absent = parameters['force_absent']
|
self.force_absent = parameters['force_absent']
|
||||||
@ -424,6 +463,8 @@ class ImageManager(DockerBaseClass):
|
|||||||
self.buildargs = build.get('args')
|
self.buildargs = build.get('args')
|
||||||
self.build_platform = build.get('platform')
|
self.build_platform = build.get('platform')
|
||||||
self.use_config_proxy = build.get('use_config_proxy')
|
self.use_config_proxy = build.get('use_config_proxy')
|
||||||
|
self.shm_size = convert_to_bytes(build.get('shm_size'), self.client.module, 'build.shm_size')
|
||||||
|
self.labels = clean_dict_booleans_for_docker_api(build.get('labels'))
|
||||||
|
|
||||||
# If name contains a tag, it takes precedence over tag parameter.
|
# If name contains a tag, it takes precedence over tag parameter.
|
||||||
if not is_image_name_id(self.name):
|
if not is_image_name_id(self.name):
|
||||||
@ -825,6 +866,12 @@ class ImageManager(DockerBaseClass):
|
|||||||
if self.build_platform is not None:
|
if self.build_platform is not None:
|
||||||
params['platform'] = self.build_platform
|
params['platform'] = self.build_platform
|
||||||
|
|
||||||
|
if self.shm_size is not None:
|
||||||
|
params['shmsize'] = self.shm_size
|
||||||
|
|
||||||
|
if self.labels:
|
||||||
|
params['labels'] = json.dumps(self.labels)
|
||||||
|
|
||||||
if context is not None:
|
if context is not None:
|
||||||
headers['Content-Type'] = 'application/tar'
|
headers['Content-Type'] = 'application/tar'
|
||||||
|
|
||||||
@ -945,8 +992,8 @@ def main():
|
|||||||
build=dict(type='dict', options=dict(
|
build=dict(type='dict', options=dict(
|
||||||
cache_from=dict(type='list', elements='str'),
|
cache_from=dict(type='list', elements='str'),
|
||||||
container_limits=dict(type='dict', options=dict(
|
container_limits=dict(type='dict', options=dict(
|
||||||
memory=dict(type='int'),
|
memory=dict(type='str'),
|
||||||
memswap=dict(type='int'),
|
memswap=dict(type='str'),
|
||||||
cpushares=dict(type='int'),
|
cpushares=dict(type='int'),
|
||||||
cpusetcpus=dict(type='str'),
|
cpusetcpus=dict(type='str'),
|
||||||
)),
|
)),
|
||||||
@ -962,6 +1009,8 @@ def main():
|
|||||||
target=dict(type='str'),
|
target=dict(type='str'),
|
||||||
etc_hosts=dict(type='dict'),
|
etc_hosts=dict(type='dict'),
|
||||||
platform=dict(type='str'),
|
platform=dict(type='str'),
|
||||||
|
shm_size=dict(type='str'),
|
||||||
|
labels=dict(type='dict'),
|
||||||
)),
|
)),
|
||||||
archive_path=dict(type='path'),
|
archive_path=dict(type='path'),
|
||||||
force_source=dict(type='bool', default=False),
|
force_source=dict(type='bool', default=False),
|
||||||
|
|||||||
@ -117,7 +117,7 @@
|
|||||||
register: fail_3
|
register: fail_3
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
|
|
||||||
- name: buildargs
|
- name: Build image ID (must fail)
|
||||||
docker_image:
|
docker_image:
|
||||||
source: build
|
source: build
|
||||||
name: "{{ present_1.image.Id }}"
|
name: "{{ present_1.image.Id }}"
|
||||||
|
|||||||
@ -76,7 +76,7 @@
|
|||||||
build:
|
build:
|
||||||
path: "{{ remote_tmp_dir }}/files"
|
path: "{{ remote_tmp_dir }}/files"
|
||||||
container_limits:
|
container_limits:
|
||||||
memory: 4000
|
memory: 4KB
|
||||||
pull: false
|
pull: false
|
||||||
source: build
|
source: build
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
@ -88,8 +88,8 @@
|
|||||||
build:
|
build:
|
||||||
path: "{{ remote_tmp_dir }}/files"
|
path: "{{ remote_tmp_dir }}/files"
|
||||||
container_limits:
|
container_limits:
|
||||||
memory: 7000000
|
memory: 7MB
|
||||||
memswap: 8000000
|
memswap: 8MB
|
||||||
pull: false
|
pull: false
|
||||||
source: build
|
source: build
|
||||||
register: container_limits_2
|
register: container_limits_2
|
||||||
@ -444,3 +444,61 @@
|
|||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- path_1 is changed
|
- path_1 is changed
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
## build.shm_size ##################################################
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
- name: Build image with custom shm_size
|
||||||
|
docker_image:
|
||||||
|
name: "{{ iname }}"
|
||||||
|
build:
|
||||||
|
path: "{{ remote_tmp_dir }}/files"
|
||||||
|
dockerfile: "MyDockerfile"
|
||||||
|
pull: false
|
||||||
|
shm_size: 128MB
|
||||||
|
source: build
|
||||||
|
register: path_1
|
||||||
|
|
||||||
|
- name: cleanup
|
||||||
|
docker_image:
|
||||||
|
name: "{{ iname }}"
|
||||||
|
state: absent
|
||||||
|
force_absent: true
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- path_1 is changed
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
## build.labels ####################################################
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
- name: Build image with labels
|
||||||
|
docker_image:
|
||||||
|
name: "{{ iname }}"
|
||||||
|
build:
|
||||||
|
path: "{{ remote_tmp_dir }}/files"
|
||||||
|
dockerfile: "MyDockerfile"
|
||||||
|
pull: false
|
||||||
|
labels:
|
||||||
|
FOO: BAR
|
||||||
|
this is a label: this is the label's value
|
||||||
|
source: build
|
||||||
|
register: labels_1
|
||||||
|
|
||||||
|
- name: cleanup
|
||||||
|
docker_image:
|
||||||
|
name: "{{ iname }}"
|
||||||
|
state: absent
|
||||||
|
force_absent: true
|
||||||
|
|
||||||
|
- name: Show image information
|
||||||
|
debug:
|
||||||
|
var: labels_1.image
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- labels_1 is changed
|
||||||
|
- labels_1.image.Config.Labels.FOO == 'BAR'
|
||||||
|
- labels_1.image.Config.Labels["this is a label"] == "this is the label's value"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user