aboutsummaryrefslogtreecommitdiff
path: root/ansible/module_utils
diff options
context:
space:
mode:
Diffstat (limited to 'ansible/module_utils')
-rw-r--r--ansible/module_utils/kolla_podman_worker.py92
1 files changed, 54 insertions, 38 deletions
diff --git a/ansible/module_utils/kolla_podman_worker.py b/ansible/module_utils/kolla_podman_worker.py
index 82653bb8d..a7644c351 100644
--- a/ansible/module_utils/kolla_podman_worker.py
+++ b/ansible/module_utils/kolla_podman_worker.py
@@ -192,6 +192,7 @@ class PodmanWorker(ContainerWorker):
)
if src == 'devpts':
mount_item = dict(
+ source=src,
target=dest,
type='devpts'
)
@@ -385,50 +386,65 @@ class PodmanWorker(ContainerWorker):
else:
return string
- raw_volumes, binds = self.generate_volumes()
- raw_vols, current_binds = self.generate_volumes(
- container_info['HostConfig'].get('Binds'))
-
- current_vols = [check_slash(vol) for vol in raw_vols if vol]
- volumes = [check_slash(vol) for vol in raw_volumes if vol]
+ # NOTE(blanson): Podman automatically appends default flags
+ # such as rprivate, nosuid, nodev, rbind to all mounts.
+ # For special paths like /proc, /run, /sys, and /var/run,
+ # noexec is also added by default. We remove these defaults
+ # because they do not reflect a meaningful difference
+ # between the requested and current container configuration.
+ # Additionally, if neither 'ro' nor 'rw' is specified,
+ # we implicitly assume 'rw' (Podman's default behavior).
+ def normalize_mode(path, mode):
+ default_flags = {'rprivate', 'nosuid', 'nodev', 'rbind'}
+ special_paths_noexec = {'/proc', '/run', '/sys', '/var/run'}
+
+ flags = set(mode.split(',')) if mode else set()
+ flags -= default_flags
+
+ if any(path.startswith(p) for p in special_paths_noexec):
+ flags.discard('noexec')
+ if not (flags & {'ro', 'rw'}):
+ flags.add('rw')
+ return flags
+
+ # NOTE(blanson): Convert a binds dict into a list of
+ # (src, dst, normalized_flags) tuples. Normalization ignores
+ # default Podman flags and noexec for special paths to allow
+ # consistent comparison.
+ def build_bind_list(binds_dict):
+ lst = []
+ for src, info in (binds_dict or {}).items():
+ src_path = check_slash(src)
+ dst_path = check_slash(info['bind'])
+ mode_flags = normalize_mode(
+ dst_path,
+ info['mode'],
+ )
+ lst.append((src_path, dst_path, mode_flags))
+ return lst
- if not volumes:
- volumes = list()
- if not current_vols:
- current_vols = list()
- if not current_binds:
- current_binds = list()
+ binds_input = container_info['HostConfig'].get('Binds')
+ raw_volumes, binds = self.generate_volumes()
+ raw_vols, current_binds = (
+ [], {}
+ ) if not binds_input else self.generate_volumes(binds_input)
- volumes.sort()
- current_vols.sort()
+ volumes = [check_slash(v) for v in raw_volumes or [] if v]
+ current_vols = [check_slash(v) for v in raw_vols or [] if v]
- if set(volumes).symmetric_difference(set(current_vols)):
+ if set(volumes) != set(current_vols):
return True
- new_binds = list()
- new_current_binds = list()
- if binds:
- for k, v in binds.items():
- k = check_slash(k)
- v['bind'] = check_slash(v['bind'])
- new_binds.append(
- "{}:{}:{}".format(k, v['bind'], v['mode']))
-
- if current_binds:
- for k, v in current_binds.items():
- k = check_slash(k)
- v['bind'] = check_slash(v['bind'])
- if 'ro' in v['mode']:
- v['mode'] = 'ro'
- else:
- v['mode'] = 'rw'
- new_current_binds.append(
- "{}:{}:{}".format(k, v['bind'], v['mode'][0:2]))
-
- new_binds.sort()
- new_current_binds.sort()
+ req_bind_list = [
+ (src, dst, frozenset(flags))
+ for src, dst, flags in build_bind_list(binds)
+ ]
+ cur_bind_list = [
+ (src, dst, frozenset(flags))
+ for src, dst, flags in build_bind_list(current_binds)
+ ]
- if set(new_binds).symmetric_difference(set(new_current_binds)):
+ if set(req_bind_list) != set(cur_bind_list):
return True
def compare_dimensions(self, container_info):