containers / ansible-podman-collections

Repository for Ansible content that can include playbooks, roles, modules, and plugins for use with the Podman tool
GNU General Public License v3.0
274 stars 148 forks source link

podman_generate_systemd with default header recreates service file despite no config changes #557

Closed maciej-markowski closed 1 year ago

maciej-markowski commented 1 year ago

Is this a BUG REPORT or FEATURE REQUEST? (leave only one on its own line)

/kind bug

Description

containers.podman.podman_generate_systemd by default includes the header with date into systemd service file. If the task is run again, service file gets recreated, despite no config changes - only thing that changed is that current date is not the same as written in config file. It is an idempotency issue, as this task usually comes with follow up tasks / handlers that stops the container and run it as systemd service, while configuration was not changed and container is already running as systemd service. Steps to reproduce the issue:

  1. Run the task that creates service file

  2. Run the same task again.

Describe the results you received:

changed result with every run.

Describe the results you expected: changed result after first run, OK result with every next run without config changes.

Additional information you deem important (e.g. issue happens only occasionally):

workaround: set no_header: true. Solution: multiple. Get rid of the header as default, remove date from the header, compare only actual content of service file ignoring the header...

Version of the containers.podman collection: Either git commit if installed from git: git show --summary Or version from ansible-galaxy if installed from galaxy: ansible-galaxy collection list | grep containers.podman

containers.podman     1.10.1

Output of ansible --version:

ansible [core 2.14.2]
  config file = /vagrant/ansible/ansible.cfg
  configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/vagrant/.local/lib/python3.9/site-packages/ansible
  ansible collection location = /home/vagrant/.ansible/collections
  executable location = /home/vagrant/.local/bin/ansible
  python version = 3.9.13 (main, Nov  9 2022, 13:16:24) [GCC 8.5.0 20210514 (Red Hat 8.5.0-15)] (/usr/bin/python3)
  jinja version = 3.1.1
  libyaml = True

Output of podman version:

podman version 4.0.2

Output of podman info --debug:

host:
  arch: amd64
  buildahVersion: 1.24.6
  cgroupControllers: []
  cgroupManager: cgroupfs
  cgroupVersion: v1
  conmon:
    package: conmon-2.1.4-1.module+el8.7.0+16520+2db5507d.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.1.4, commit: 0a5e320a8e7296e3766ea94b93934276ee520d2a'
  cpus: 4
  distribution:
    distribution: '"rhel"'
    version: "8.5"
  eventLogger: file
  hostname: dws1
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
  kernel: 4.18.0-348.20.1.el8_5.x86_64
  linkmode: dynamic
  logDriver: k8s-file
  memFree: 1325920256
  memTotal: 16601169920
  networkBackend: cni
  ociRuntime:
    name: runc
    package: runc-1.1.4-1.module+el8.7.0+16520+2db5507d.x86_64
    path: /usr/bin/runc
    version: |-
      runc version 1.1.4
      spec: 1.0.2-dev
      go: go1.18.4
      libseccomp: 2.5.1
  os: linux
  remoteSocket:
    path: /run/user/1000/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_NET_RAW,CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: true
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: true
  serviceIsRemote: false
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns-1.1.8-2.module+el8.7.0+16520+2db5507d.x86_64
    version: |-
      slirp4netns version 1.1.8
      commit: d361001f495417b880f20329121e3aa431a8f90f
      libslirp: 4.4.0
      SLIRP_CONFIG_VERSION_MAX: 3
      libseccomp: 2.5.1
  swapFree: 4294963200
  swapTotal: 4294963200
  uptime: 3h 24m 56.34s (Approximately 0.12 days)
plugins:
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  - ipvlan
  volume:
  - local
registries:
  search:
  - registry.access.redhat.com
  - registry.redhat.io
  - docker.io
store:
  configFile: /home/vagrant/.config/containers/storage.conf
  containerStore:
    number: 0
    paused: 0
    running: 0
    stopped: 0
  graphDriverName: overlay
  graphOptions: {}
  graphRoot: /home/vagrant/.local/share/containers/storage
  graphStatus:
    Backing Filesystem: xfs
    Native Overlay Diff: "true"
    Supports d_type: "true"
    Using metacopy: "false"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 0
  runRoot: /run/user/1000/containers
  volumePath: /home/vagrant/.local/share/containers/storage/volumes
version:
  APIVersion: 4.0.2
  Built: 1675945378
  BuiltTime: Thu Feb  9 06:22:58 2023
  GitCommit: ""
  GoVersion: go1.18.9
  OsArch: linux/amd64
  Version: 4.0.2

Package info (e.g. output of rpm -q podman or apt list podman):

podman-4.0.2-9.module+el8.7.0+18128+0ba3165d.x86_64

Playbok you run with ansible (e.g. content of playbook.yaml):

    - name: Create podman systemd service
      containers.podman.podman_generate_systemd:
        name: "dummy"
        dest: "/etc/systemd/system"
        restart_policy: on-failure

Command line and output of ansible run with high verbosity

Please NOTE: if you submit a bug about idempotency, run the playbook with --diff option, like:

ansible-playbook -i inventory --diff -vv playbook.yml

TASK [Create podman systemd service] **************************************************************************************************************************************************************
task path: /vagrant/ansible/install_pulp.yml:55
Monday 27 February 2023  06:52:32 -0600 (0:00:07.678)       0:00:13.816 *******
changed: [localhost] => {
    "changed": true,
    "podman_command": "podman generate systemd --restart-policy=on-failure --name --format json dummy",
    "systemd_units": {
        "container-dummy": "# container-dummy.service\n# autogenerated by Podman 4.0.2\n# Mon Feb 27 06:52:33 CST 2023\n\n[Unit]\nDescription=Podman container-dummy.service\nDocumentation=man:podman-generate-systemd(1)\nWants=network-online.target\nAfter=network-online.target\nRequiresMountsFor=/run/containers/storage\n\n[Service]\nEnvironment=PODMAN_SYSTEMD_UNIT=%n\nRestart=on-failure\nTimeoutStopSec=70\nExecStart=/usr/bin/podman start dummy\nExecStop=/usr/bin/podman stop -t 10 dummy\nExecStopPost=/usr/bin/podman stop -t 10 dummy\nPIDFile=/run/containers/storage/overlay-containers/18b7e6ad6e018d9614827d83199c74413486e5a76ed06d1170262bf0de219548/userdata/conmon.pid\nType=forking\n\n[Install]\nWantedBy=default.target\n"
    }
}

Additional environment details (AWS, VirtualBox, physical, etc.):

sshnaidm commented 1 year ago

@CyberFox001 would like to look into?

CyberFox001 commented 1 year ago

@sshnaidm I can take look, but this week I'm very busy. I will try to find time.

CyberFox001 commented 1 year ago

Do we really want to make the Ansible module podman_generate_systemd idempotent as its name is an imperative action ?

This Ansible module was made to reflect the podman command podman generate systemd. Which is an imperative command. But maybe we need a podman_to_systemd_unit Ansible module who is made from the Ansible user point of view, more than from the podman commands point of view.

Since podman 4.4.0 we have the introduction of Quadlet, a new systemd-generator that easily writes and maintains systemd services using Podman. Maybe it's time to make a new Ansible module that use Quadlet with podman >= 4.4.0 and podman generate systemd command with podman <= 4.4.0.

It's just a thought, but I think we need to make a choice about it.

sshnaidm commented 1 year ago

Quadlet seems like a good option for future. Probably this time it's fine to set no-header as a default? I don't see much sense to have it. Either way we can implement comparison without taking header into account: https://github.com/containers/ansible-podman-collections/blob/7c06ddec3b51bab66d6733ce6d78a29681246a02/plugins/modules/podman_generate_systemd.py#L453-L461

sshnaidm commented 1 year ago

@maciej-markowski please test if #558 helps.

maciej-markowski commented 1 year ago

@sshnaidm tested. Works fine, thanks!