一、环境
ansible + podman + quadlet + systemd
二、替换问题
1. podman 使用官方的二进制文件,启动 podman.service 的时候报错缺少选项 service
2. 如果环境变量中包含 "\n"/空白,变量解析会有问题
- 代码示例:
# defaults/main.yml
web_auth_container_default_env:
AA: "{{ web_auth_aa | string }}"
BB: "{{ web_auth_bb | string }}"
web_auth_aa: "sdfsdf\nsdfsd\nsdfs\n"
web_auth_bb: "aa aa aa"
# tasks/deploy.yml
- name: Apply web_auth podman compose started
register: "configure_quadlet"
containers.podman.podman_container:
capabilities: '{{ web_auth_container_capabilities }}'
cpus: '{{ web_auth_container_resources_cpus }}'
env: '{{ web_auth_container_env }}'
hostname: '{{ web_auth_container_hostname }}'
image: '{{ web_auth_container_image_full }}'
labels: '{{ web_auth_container_labels }}'
memory: '{{ web_auth_container_resources_memory }}'
name: '{{ web_auth_container_name }}'
network_mode: '{{ web_auth_container_network_mode }}'
pull: '{{ web_auth_container_pull }}'
recreate: '{{ web_auth_container_recreate }}'
state: quadlet
volumes: '{{ web_auth_container_volumes }}'
quadlet_options: "{{ container_quadlet_options }}"
tags: generate-quadlet
when:
- container_deploy_type | default('docker') == 'podman_compose'
- name: "Start {{ web_auth_container_name }} podman container with systemd"
containers.podman.systemd_service:
name: "{{ web_auth_container_name }}"
state: "{{ 'restarted' if (configure_quadlet is changed) else 'started' }}"
daemon_reload: true
tags: generate-quadlet
- 示例导致的问题
- 第一个问题:如果变量中包含换行符,最终写入 systemd 的时候会有多行,会报错 systemd 单元文件格式有问题
- 第二个问题:如果变量中包含空白字符,最终变量的值为第一段非空白字符(如果变量值以空白开头,最终变量值为空),上面示例中BB的值为 "aa",而不是预期的 "aa aa aa"
3. podman 启动一个容器,如果挂载的文件宿主机上不存在不会新建
- docker 会新建为目录
4. 配置 env_file 参数,如果文件中的变量值包含引号,引号也会当成值得一部分
- 代码示例:
# /root/.env
AA="aa"
# defaults/main.yml
web_auth_env_files: '/root/.env'
# tasks/deploy.yml
- name: Apply web_auth podman compose started
register: "configure_quadlet"
containers.podman.podman_container:
capabilities: '{{ web_auth_container_capabilities }}'
cpus: '{{ web_auth_container_resources_cpus }}'
env: '{{ web_auth_container_env }}'
env_file: '{{ web_auth_env_files }}'
hostname: '{{ web_auth_container_hostname }}'
image: '{{ web_auth_container_image_full }}'
labels: '{{ web_auth_container_labels }}'
memory: '{{ web_auth_container_resources_memory }}'
name: '{{ web_auth_container_name }}'
network_mode: '{{ web_auth_container_network_mode }}'
pull: '{{ web_auth_container_pull }}'
recreate: '{{ web_auth_container_recreate }}'
state: quadlet
volumes: '{{ web_auth_container_volumes }}'
quadlet_options: "{{ container_quadlet_options }}"
tags: generate-quadlet
when:
- container_deploy_type | default('docker') == 'podman_compose'
- name: "Start {{ web_auth_container_name }} podman container with systemd"
containers.podman.systemd_service:
name: "{{ web_auth_container_name }}"
state: "{{ 'restarted' if (configure_quadlet is changed) else 'started' }}"
daemon_reload: true
tags: generate-quadlet
- 示例导致的问题:
- 预期中AA的值应该为 aa,但实际为 "aa"
- 示例场景:有的变量中包含换行符,需要使用引号
三、变量解析问题处理
- 原文件链接
- 原文件代码:
def create_quadlet_content(self) -> str:
"""
Construct the quadlet content as a string.
"""
custom_user_options = self.custom_params.get("quadlet_options")
custom_text = "\n" + "\n".join(custom_user_options) if custom_user_options else ""
return f"[{self.section}]\n" + "\n".join(
f"{key}={value}" for key, value in self.dict_params
) + custom_text + "\n"
- 调整之后的代码:
def create_quadlet_content(self) -> str:
"""
Construct the quadlet content as a string.
"""
custom_user_options = self.custom_params.get("quadlet_options")
with open("/tmp/quadlet_presence.json", "w", encoding="utf-8") as f:
json.dump(self.dict_params, f, ensure_ascii=False, indent=2)
custom_text = "\n" + "\n".join(custom_user_options) if custom_user_options else ""
# return f"[{self.section}]\n" + "\n".join(
# f"{key}={value}" for key, value in self.dict_params
# ) + custom_text + "\n"
header = f"[{self.section}]\n"
# 键值对转为字符串行
param_lines = []
for key, value in self.dict_params:
if key == 'Environment' and isinstance(value, str):
value = value.replace("\n", "\\n")
if key == 'Environment' and isinstance(value, str) and ' ' in value.strip():
sub_key, sub_value = value.split("=", 1)
if not (sub_value.strip().startswith('"') and sub_value.strip().endswith('"')):
param_lines.append(f'{key}={sub_key}="{sub_value}"')
else:
param_lines.append(f'{key}={value}')
else:
param_lines.append(f'{key}={value}')
params_str = "\n".join(param_lines)
# 拼接最终结果
result = header + params_str + custom_text + "\n"
return result
Ansible+Podman部署替换及变量解析问题
511

被折叠的 条评论
为什么被折叠?



