{"id":117,"sha1":"dbb374990dd0eb2c7e421f06ab001ab76194abcb","playbook":{"id":2,"items":{"plays":18,"tasks":603,"results":2798,"hosts":18,"files":138,"records":0},"arguments":{"version":null,"verbosity":0,"private_key_file":null,"remote_user":null,"connection":"openstack.osa.ssh","timeout":null,"ssh_common_args":null,"sftp_extra_args":null,"scp_extra_args":null,"ssh_extra_args":null,"ask_pass":false,"connection_password_file":null,"force_handlers":true,"flush_cache":false,"become":false,"become_method":"sudo","become_user":null,"become_ask_pass":false,"become_password_file":null,"tags":["all"],"skip_tags":[],"check":false,"diff":false,"inventory":["/home/zuul/src/opendev.org/openstack/openstack-ansible/inventory/dynamic_inventory.py","/home/zuul/src/opendev.org/openstack/openstack-ansible/inventory/inventory.ini","/etc/openstack_deploy/inventory.ini"],"listhosts":false,"subset":null,"extra_vars":"Not saved by ARA as configured by 'ignored_arguments'","vault_ids":[],"ask_vault_pass":false,"vault_password_files":[],"forks":8,"module_path":null,"syntax":false,"listtasks":false,"listtags":false,"step":false,"start_at_task":null,"args":["setup-hosts.yml"]},"labels":[{"id":1,"name":"check:False"},{"id":2,"name":"tags:all"}],"started":"2025-12-15T09:38:00.537317Z","ended":"2025-12-15T09:55:23.220443Z","duration":"00:17:22.683126","name":null,"ansible_version":"2.18.6","client_version":"1.7.4","python_version":"3.12.3","server_version":"1.7.4","status":"completed","path":"/home/zuul/src/opendev.org/openstack/openstack-ansible/playbooks/setup-hosts.yml","controller":"aio1.openstack.local","user":"root"},"content":"---\n# Copyright 2018, Rackspace US, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n- name: Set mount facts\n  ansible.builtin.set_fact:\n    systemd_mount_suffix: \"{{ (item.type == 'swap') | ternary('swap', 'mount') }}\"\n    systemd_mount_item: \"{{ item.where | default(item.what) }}\"\n\n- name: Escape mount service file name\n  ansible.builtin.command: systemd-escape -p --suffix=\"{{ systemd_mount_suffix }}\" \"{{ systemd_mount_item }}\"\n  changed_when: false\n  register: mount_service_name_escaped\n  when: item.escape_name | default(true)\n\n- name: Define mount service name\n  ansible.builtin.set_fact:\n    mount_service_name: \"{{ mount_service_name_escaped.stdout | default([systemd_mount_item, systemd_mount_suffix] | join('.')) }}\"\n\n# NOTE(noonedeadpunk): with s3fs IO error would raise on attempt to change permissions.\n- name: Create mount target(s)\n  ansible.builtin.file:\n    path: \"{{ item.where }}\"\n    state: directory\n    owner: \"{{ item.owner | default(omit) }}\"\n    group: \"{{ item.group | default(omit) }}\"\n    mode: \"0755\"\n  failed_when: false\n  when:\n    - item.where is defined\n    - item.state | default('unknown') != 'absent'\n    - item.type != 'swap'\n  tags:\n    - systemd-mount\n\n- name: Place mount credentials when required\n  ansible.builtin.copy:\n    dest: \"/etc/passwd-{{ mount_service_name }}\"\n    content: \"{{ item.credentials }}\"\n    owner: \"root\"\n    group: \"root\"\n    mode: \"0600\"\n  when:\n    - item.type == \"fuse.s3fs\"\n    - \"'credentials' in item\"\n\n- name: Create systemd mount services(s)\n  openstack.config_template.config_template:\n    src: \"systemd-mount.j2\"\n    dest: \"/etc/systemd/system/{{ mount_service_name }}\"\n    owner: \"root\"\n    group: \"root\"\n    mode: \"{{ item.unit_mode | default('0644') }}\"\n    config_overrides: \"{{ item.config_overrides | default({}) }}\"\n    config_type: \"ini\"\n  when:\n    - item.state | default('unknown') != 'absent'\n    - (item.mount_overrides_only is not defined) or (item.mount_overrides_only is defined and not item.mount_overrides_only)\n  tags:\n    - systemd-mount\n\n- name: Provision mount overrides file\n  when:\n    - item.mount_overrides_only is defined\n    - item.mount_overrides_only | bool\n    - item.config_overrides | length > 0\n  tags:\n    - systemd-mount\n  block:\n    - name: Create overrides folder for mount\n      ansible.builtin.file:\n        path: \"/etc/systemd/system/{{ mount_service_name }}.d\"\n        owner: \"root\"\n        group: \"root\"\n        mode: \"0755\"\n        state: directory\n\n    - name: Create overrides file\n      openstack.config_template.config_template:\n        dest: \"/etc/systemd/system/{{ mount_service_name }}.d/overrides.conf\"\n        owner: \"root\"\n        group: \"root\"\n        mode: \"0644\"\n        config_overrides: \"{{ item.config_overrides | default({}) }}\"\n        config_type: \"ini\"\n\n- name: Load or Unload mount(s)\n  ansible.builtin.systemd:\n    daemon_reload: true\n    name: \"{{ mount_service_name }}\"\n    enabled: \"{{ item.enabled | default(true) }}\"\n  when:\n    - item.state | default('unknown') != 'absent'\n\n# NOTE(cloudnull): The systemd module is not used to start the\n#                  mount because we don't want to inavertently\n#                  \"restart\" a mount unnecessarily. To ensure\n#                  we're able to load new options without\n#                  requiring a mount restart the systemctl\n#                  command is used with the \"reload-or-restart\"\n#                  argument. Additionally this command escapes\n#                  the name of the mount. If this command fails\n#                  the task will be rescued and the regular\n#                  systemd module will be attempted before\n#                  failing the task run.\n- name: Set the state of the mount  # noqa: command-instead-of-module\n  ansible.builtin.command: \"systemctl {{ systemd_mount_states[item.state] }} {{ mount_service_name }}\"\n  changed_when: false\n  ignore_errors: true\n  register: set_mount_state_command\n  when:\n    - item.state is defined\n\n- name: Set the state of the mount (fallback)\n  ansible.builtin.systemd:\n    name: \"{{ mount_service_name }}\"\n    state: \"{{ item.state }}\"\n  when:\n    - set_mount_state_command is failed\n\n- name: Unload mount(s)\n  ansible.builtin.systemd:\n    daemon_reload: true\n    name: \"{{ mount_service_name }}\"\n    enabled: false\n    no_block: true\n  when:\n    - item.state | default('unknown') == 'absent'\n  notify: Remove mount\n","created":"2025-12-15T09:42:25.122733Z","updated":"2025-12-15T09:42:25.122762Z","path":"/home/zuul/src/opendev.org/openstack/ansible-role-systemd_mount/tasks/systemd_mounts.yml"}