docker_container_copy_into: add mode_parse option (#1074)

* Add mode_parse option.

* Make yamllint config strict.

* Lint.
This commit is contained in:
Felix Fontein 2025-04-28 20:46:11 +02:00 committed by GitHub
parent 424b39fe36
commit ad989c1942
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 431 additions and 100 deletions

View File

@ -45,9 +45,9 @@ rules:
braces:
min-spaces-inside: 0
max-spaces-inside: 1
#octal-values:
# forbid-implicit-octal: true
# forbid-explicit-octal: true
octal-values:
forbid-implicit-octal: true
forbid-explicit-octal: true
comments:
min-spaces-from-content: 1
comments-indentation: false

View File

@ -46,9 +46,9 @@ rules:
braces:
min-spaces-inside: 0
max-spaces-inside: 1
#octal-values:
# forbid-implicit-octal: true
# forbid-explicit-octal: true
octal-values:
forbid-implicit-octal: true
forbid-explicit-octal: true
comments:
min-spaces-from-content: 1
comments-indentation: false

View File

@ -0,0 +1,2 @@
minor_changes:
- "docker_container_copy_into - add ``mode_parse`` parameter which determines how ``mode`` is parsed (https://github.com/ansible-collections/community.docker/pull/1074)."

View File

@ -95,8 +95,26 @@ options:
description:
- The file mode to use when writing the file to disk.
- Will use the file's mode from the source system if this option is not provided.
- Note that if you provide an octal number as a string, Ansible will parse it as a B(decimal) number.
type: int
- This option is parsed depending on how O(mode_parse) is set.
type: raw
mode_parse:
description:
- Determines how to parse the O(mode) parameter.
type: str
choices:
legacy:
- Parses the value of O(mode) as an integer.
- Note that if you provide an octal number as a string to O(mode), it will be parsed as a B(decimal) number.
If you provide an octal integer directly, though, it will work as expected.
- This has been the default behavior of the module since it was added to community.docker.
modern:
- Parses the value of O(mode) as an octal string, or takes the integer value if an integer has been provided.
- This is how M(ansible.builtin.copy) treats its O(ansible.builtin.copy#module:mode) option.
octal_string_only:
- Rejects everything that is not a string that can be parsed as an octal number.
- Use this value to ensure that no accidental conversion to integers happen.
default: legacy
version_added: 4.6.0
force:
description:
- If set to V(true), force writing the file (without performing any idempotency checks).
@ -134,7 +152,8 @@ EXAMPLES = r"""
container_path: /bin/runme
owner_id: 0 # root
group_id: 0 # root
mode: 0755 # readable and executable by all users, writable by root
mode: "0755" # readable and executable by all users, writable by root
mode_parse: modern # ensure that strings passed for 'mode' are passed as octal numbers
"""
RETURN = r"""
@ -153,6 +172,8 @@ import stat
import traceback
from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.module_utils.common.validation import check_type_int
from ansible.module_utils.six import integer_types, string_types
from ansible_collections.community.docker.plugins.module_utils._api.errors import APIError, DockerException, NotFound
@ -761,6 +782,20 @@ def copy_content_into_container(client, container, content, container_path, foll
client.module.exit_json(**result)
def parse_modern(mode):
if isinstance(mode, string_types):
return int(to_native(mode), 8)
if isinstance(mode, integer_types):
return mode
raise TypeError('must be an octal string or an integer, got {mode!r}'.format(mode=mode))
def parse_octal_string_only(mode):
if isinstance(mode, string_types):
return int(to_native(mode), 8)
raise TypeError('must be an octal string, got {mode!r}'.format(mode=mode))
def main():
argument_spec = dict(
container=dict(type='str', required=True),
@ -770,7 +805,8 @@ def main():
local_follow=dict(type='bool', default=True),
owner_id=dict(type='int'),
group_id=dict(type='int'),
mode=dict(type='int'),
mode=dict(type='raw'),
mode_parse=dict(type='str', choices=['legacy', 'modern', 'octal_string_only'], default='legacy'),
force=dict(type='bool'),
content=dict(type='str', no_log=True),
content_is_b64=dict(type='bool', default=False),
@ -802,6 +838,20 @@ def main():
content = client.module.params['content']
max_file_size_for_diff = client.module.params['_max_file_size_for_diff'] or 1
if mode is not None:
mode_parse = client.module.params['mode_parse']
try:
if mode_parse == 'legacy':
mode = check_type_int(mode)
elif mode_parse == 'modern':
mode = parse_modern(mode)
elif mode_parse == 'octal_string_only':
mode = parse_octal_string_only(mode)
except (TypeError, ValueError) as e:
client.fail("Error while parsing 'mode': {error}".format(error=e))
if mode < 0:
client.fail("'mode' must not be negative; got {mode}".format(mode=mode))
if content is not None:
if client.module.params['content_is_b64']:
try:

View File

@ -56,7 +56,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: false
register: result_1
@ -67,7 +68,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: true
register: result_1_diff
@ -78,7 +80,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
register: result_2
- name: Copy content (idempotent, check mode)
@ -87,7 +90,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: false
register: result_3
@ -98,7 +102,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: true
register: result_3_diff
@ -109,7 +114,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
register: result_4
- name: Copy content (idempotent, check mode, base 64)
@ -118,7 +124,8 @@
content: "{{ 'Content 1\n' | b64encode }}"
content_is_b64: true
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: false
register: result_3b64
@ -129,7 +136,8 @@
content: "{{ 'Content 1\n' | b64encode }}"
content_is_b64: true
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: true
register: result_3b64_diff
@ -140,7 +148,8 @@
content: "{{ 'Content 1\n' | b64encode }}"
content_is_b64: true
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
register: result_4b64
- name: Dump file
@ -161,7 +170,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
force: true
check_mode: true
diff: false
@ -173,7 +183,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
force: true
check_mode: true
diff: true
@ -185,7 +196,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
force: true
register: result_7
@ -207,7 +219,8 @@
content: |
Some other content
container_path: '/file'
mode: 0777
mode: "0777"
mode_parse: modern
owner_id: 123
group_id: 321
force: false
@ -221,7 +234,8 @@
content: |
Some other content
container_path: '/file'
mode: 0777
mode: "0777"
mode_parse: modern
owner_id: 123
group_id: 321
force: false
@ -235,7 +249,8 @@
content: |
Some other content
container_path: '/file'
mode: 0777
mode: "0777"
mode_parse: modern
owner_id: 123
group_id: 321
force: false
@ -253,6 +268,117 @@
chdir: /root
register: result_11
- name: Copy content (octal mode, mode_parse=modern)
docker_container_copy_into:
container: '{{ cname }}'
content: |
Content 1
container_path: '/file'
# yamllint disable
mode: 0770
# yamllint enable
mode_parse: modern
owner_id: 0
group_id: 0
register: result_12
- name: Dump file
docker_container_exec:
container: '{{ cname }}'
argv:
- /bin/sh
- "-c"
- >-
cat /file | base64;
stat -c '%s %a %F %u %g %N' /file > /dev/stderr
chdir: /root
register: result_13
- name: Copy content (octal mode, mode_parse=legacy)
docker_container_copy_into:
container: '{{ cname }}'
content: |
Content 1
container_path: '/file'
# yamllint disable
mode: 0707
# yamllint enable
mode_parse: legacy
owner_id: 0
group_id: 0
register: result_14
- name: Dump file
docker_container_exec:
container: '{{ cname }}'
argv:
- /bin/sh
- "-c"
- >-
cat /file | base64;
stat -c '%s %a %F %u %g %N' /file > /dev/stderr
chdir: /root
register: result_15
- name: Copy content (string mode, mode_parse=legacy)
docker_container_copy_into:
container: '{{ cname }}'
content: |
Content 1
container_path: '/file'
mode: "420"
mode_parse: legacy
owner_id: 0
group_id: 0
register: result_16
- name: Dump file
docker_container_exec:
container: '{{ cname }}'
argv:
- /bin/sh
- "-c"
- >-
cat /file | base64;
stat -c '%s %a %F %u %g %N' /file > /dev/stderr
chdir: /root
register: result_17
- name: Copy content (string mode, mode_parse=octal_string_only)
docker_container_copy_into:
container: '{{ cname }}'
content: |
Content 1
container_path: '/file'
mode: "0600"
mode_parse: octal_string_only
owner_id: 0
group_id: 0
register: result_18
- name: Dump file
docker_container_exec:
container: '{{ cname }}'
argv:
- /bin/sh
- "-c"
- >-
cat /file | base64;
stat -c '%s %a %F %u %g %N' /file > /dev/stderr
chdir: /root
register: result_19
- name: Restore state for next tasks
docker_container_copy_into:
container: '{{ cname }}'
content: |
Content 1
container_path: '/file'
mode: "0644"
mode_parse: octal_string_only
owner_id: 0
group_id: 0
- name: Check results
assert:
that:
@ -302,6 +428,18 @@
- result_10 is not changed
- result_11.stdout | b64decode == 'Content 1\n'
- result_11.stderr == '10 644 regular file 0 0 /file'
- result_12 is changed
- result_13.stdout | b64decode == 'Content 1\n'
- result_13.stderr == '10 770 regular file 0 0 /file'
- result_14 is changed
- result_15.stdout | b64decode == 'Content 1\n'
- result_15.stderr == '10 707 regular file 0 0 /file'
- result_16 is changed
- result_17.stdout | b64decode == 'Content 1\n'
- result_17.stderr == '10 644 regular file 0 0 /file'
- result_18 is changed
- result_19.stdout | b64decode == 'Content 1\n'
- result_19.stderr == '10 600 regular file 0 0 /file'
######################### Follow link - idempotence
@ -323,7 +461,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: true
check_mode: true
diff: false
@ -335,7 +474,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: true
check_mode: true
diff: true
@ -347,7 +487,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: true
register: result_2
@ -370,7 +511,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: true
force: true
check_mode: true
@ -383,7 +525,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: true
force: true
check_mode: true
@ -396,7 +539,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: true
force: true
register: result_5
@ -454,7 +598,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: false
check_mode: true
diff: false
@ -466,7 +611,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: false
check_mode: true
diff: true
@ -478,7 +624,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: false
register: result_2
@ -488,7 +635,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: false
register: result_3
@ -499,7 +647,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: true
register: result_3_diff
@ -510,7 +659,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
register: result_4
- name: Dump file
@ -531,7 +681,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
force: true
check_mode: true
diff: false
@ -543,7 +694,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
force: true
check_mode: true
diff: true
@ -555,7 +707,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
force: true
register: result_7
@ -615,7 +768,8 @@
content: |
Content 1
container_path: '/dir'
mode: 0644
mode: "0644"
mode_parse: modern
follow: false
check_mode: true
diff: false
@ -627,7 +781,8 @@
content: |
Content 1
container_path: '/dir'
mode: 0644
mode: "0644"
mode_parse: modern
follow: false
check_mode: true
diff: true
@ -639,7 +794,8 @@
content: |
Content 1
container_path: '/dir'
mode: 0644
mode: "0644"
mode_parse: modern
follow: false
register: result_2
@ -649,7 +805,8 @@
content: |
Content 1
container_path: '/dir'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: false
register: result_3
@ -660,7 +817,8 @@
content: |
Content 1
container_path: '/dir'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: true
register: result_3_diff
@ -671,7 +829,8 @@
content: |
Content 1
container_path: '/dir'
mode: 0644
mode: "0644"
mode_parse: modern
register: result_4
- name: Dump file
@ -719,7 +878,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: false
register: result_1
@ -731,7 +891,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: true
register: result_1_diff
@ -743,7 +904,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
register: result_2
- name: Dump file
@ -781,7 +943,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: false
register: result_1
@ -793,7 +956,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: true
register: result_1_diff
@ -805,7 +969,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
register: result_2
- name: Copy content (idempotent, check mode)
@ -815,7 +980,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: false
register: result_3
@ -827,7 +993,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: true
register: result_3_diff
@ -839,7 +1006,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
register: result_4
- name: Dump file
@ -885,7 +1053,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -899,7 +1068,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -913,7 +1083,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_2
@ -925,7 +1096,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -939,7 +1111,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -953,7 +1126,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_4
@ -977,7 +1151,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 13
group_id: 13
check_mode: true
@ -991,7 +1166,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 13
group_id: 13
check_mode: true
@ -1005,7 +1181,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 13
group_id: 13
register: result_7
@ -1068,7 +1245,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -1081,7 +1259,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -1094,7 +1273,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_2
@ -1105,7 +1285,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -1118,7 +1299,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -1131,7 +1313,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_4
@ -1142,7 +1325,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
register: result_5
ignore_errors: true

View File

@ -34,7 +34,7 @@
dest: '{{ remote_tmp_dir }}/file_1'
content: |
Content 1
mode: 0644
mode: "0644"
- name: Create file 2
copy:
@ -42,7 +42,7 @@
content: |-
Content 2
Extra line
mode: 0644
mode: "0644"
- name: Create link 1
file:
@ -50,7 +50,7 @@
state: link
src: file_1
follow: false
mode: 0644
mode: "0644"
- name: Create link 2
file:
@ -59,7 +59,7 @@
src: dead
force: true
follow: false
mode: 0644
mode: "0644"
################################################################################################
# Do tests
@ -173,7 +173,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0777
mode: "0777"
mode_parse: modern
owner_id: 123
group_id: 321
force: false
@ -186,7 +187,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0777
mode: "0777"
mode_parse: modern
owner_id: 123
group_id: 321
force: false
@ -199,7 +201,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0777
mode: "0777"
mode_parse: modern
owner_id: 123
group_id: 321
force: false
@ -684,7 +687,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: false
register: result_1
@ -694,7 +698,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: true
register: result_1_diff
@ -704,7 +709,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
register: result_2
- name: Copy file (idempotent, check mode)
@ -712,7 +718,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: false
register: result_3
@ -722,7 +729,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: true
register: result_3_diff
@ -732,7 +740,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
register: result_4
- name: Dump file
@ -776,7 +785,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -788,7 +798,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -800,7 +811,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_2
@ -810,7 +822,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -822,7 +835,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -834,7 +848,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_4
@ -856,7 +871,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 13
group_id: 13
check_mode: true
@ -868,7 +884,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 13
group_id: 13
check_mode: true
@ -880,7 +897,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 13
group_id: 13
register: result_7
@ -942,7 +960,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -954,7 +973,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -966,7 +986,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_2
@ -976,7 +997,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -988,7 +1010,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@ -1000,7 +1023,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_4
@ -1010,7 +1034,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
register: result_5
ignore_errors: true

View File

@ -2,5 +2,6 @@
plugins/inventory/docker_containers.py yamllint:unparsable-with-libyaml
plugins/inventory/docker_machine.py yamllint:unparsable-with-libyaml
plugins/inventory/docker_swarm.py yamllint:unparsable-with-libyaml
plugins/modules/docker_container_copy_into.py validate-modules:invalid-documentation
plugins/modules/docker_container_copy_into.py validate-modules:undocumented-parameter # _max_file_size_for_diff is used by the action plugin
plugins/modules/docker_image_build.py validate-modules:invalid-documentation

View File

@ -1,5 +1,6 @@
plugins/inventory/docker_containers.py yamllint:unparsable-with-libyaml
plugins/inventory/docker_machine.py yamllint:unparsable-with-libyaml
plugins/inventory/docker_swarm.py yamllint:unparsable-with-libyaml
plugins/modules/docker_container_copy_into.py validate-modules:invalid-documentation
plugins/modules/docker_container_copy_into.py validate-modules:undocumented-parameter # _max_file_size_for_diff is used by the action plugin
plugins/modules/docker_image_build.py validate-modules:invalid-documentation

View File

@ -0,0 +1,68 @@
# Copyright 2025 Felix Fontein <felix@fontein.de>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import pytest
from ansible_collections.community.docker.plugins.modules.docker_container_copy_into import parse_modern, parse_octal_string_only
@pytest.mark.parametrize("input, expected", [
('0777', 0o777),
('777', 0o777),
('0o777', 0o777),
('0755', 0o755),
('755', 0o755),
('0o755', 0o755),
('0644', 0o644),
('644', 0o644),
('0o644', 0o644),
(' 0644 ', 0o644),
(' 644 ', 0o644),
(' 0o644 ', 0o644),
('-1', -1),
])
def test_parse_string(input, expected):
assert parse_modern(input) == expected
assert parse_octal_string_only(input) == expected
@pytest.mark.parametrize("input", [
0o777,
0o755,
0o644,
12345,
123456789012345678901234567890123456789012345678901234567890,
])
def test_parse_int(input):
assert parse_modern(input) == input
with pytest.raises(TypeError, match="^must be an octal string, got {value}L?$".format(value=input)):
parse_octal_string_only(input)
@pytest.mark.parametrize("input", [
1.0,
755.5,
[],
{},
])
def test_parse_bad_type(input):
with pytest.raises(TypeError, match="^must be an octal string or an integer, got "):
parse_modern(input)
with pytest.raises(TypeError, match="^must be an octal string, got "):
parse_octal_string_only(input)
@pytest.mark.parametrize("input", [
"foo",
"8",
"9",
])
def test_parse_bad_value(input):
with pytest.raises(ValueError):
parse_modern(input)
with pytest.raises(ValueError):
parse_octal_string_only(input)