{"id":157,"sha1":"0e7baceccdbbfbf903757e64aaa9fdc3742611d2","playbook":{"id":2,"items":{"plays":18,"tasks":603,"results":2357,"hosts":15,"files":157,"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":4,"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-14T10:04:43.190296Z","ended":"2025-12-14T10:14:53.851603Z","duration":"00:10:10.661307","name":null,"ansible_version":"2.18.6","client_version":"1.7.4","python_version":"3.13.5","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 2014, 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# CONTAINER SETUP AND CONFIG\n- name: Write default container config\n  ansible.builtin.lineinfile:\n    dest: \"/var/lib/lxc/{{ inventory_hostname }}/config\"\n    line: \"{{ item.split('=', 1)[0] }} = {{ item.split('=', 1)[1] }}\"\n    backup: \"true\"\n  with_items: \"{{ lxc_container_default_config_list | union(lxc_container_config_list) }}\"\n  delegate_to: \"{{ physical_host }}\"\n  register: default_configuration_container\n  notify:\n    - Lxc container restart\n\n- name: Ensure containers have required auto mounts\n  ansible.builtin.lineinfile:\n    dest: \"/var/lib/lxc/{{ inventory_hostname }}/config\"\n    line: \"lxc.mount.auto = {{ lxc_container_mount_auto | join(' ') }}\"\n    regexp: \"^lxc.mount.auto =\"\n    backup: \"true\"\n  delegate_to: \"{{ physical_host }}\"\n\n- name: Ensure bind mount host directories exists\n  ansible.builtin.file:\n    path: \"{{ item['host_directory'] }}\"\n    state: \"directory\"\n    mode: \"0755\"\n  with_items: \"{{ lxc_container_default_bind_mounts | union(_lxc_container_bind_mounts) | union(lxc_container_bind_mounts) }}\"\n  delegate_to: \"{{ physical_host }}\"\n\n- name: Add bind mount configuration to container\n  ansible.builtin.lineinfile:\n    dest: \"/var/lib/lxc/{{ inventory_hostname }}/config\"\n    line: \"lxc.mount.entry = {{ item['host_directory'] }} {{ item['container_directory'].lstrip('/') }} none bind,create=dir 0 0\"\n    backup: \"true\"\n  with_items: \"{{ lxc_container_default_bind_mounts | union(_lxc_container_bind_mounts) | union(lxc_container_bind_mounts) }}\"\n  delegate_to: \"{{ physical_host }}\"\n  register: bind_configuration_container\n  notify:\n    - Lxc container restart\n\n- name: Create and start the container\n  community.general.lxc_container:\n    name: \"{{ inventory_hostname }}\"\n    state: started\n  delegate_to: \"{{ physical_host }}\"\n\n- name: Gather container facts\n  ansible.builtin.setup:\n    gather_subset: \"!all\"\n\n- name: Drop container setup script\n  ansible.builtin.template:\n    src: \"container-setup.sh.j2\"\n    dest: \"/opt/container-setup.sh\"\n    owner: \"root\"\n    group: \"root\"\n    mode: \"0755\"\n\n- name: Drop container first run script\n  ansible.builtin.template:\n    src: \"container-first-run.sh.j2\"\n    dest: \"/var/lib/lxc/{{ inventory_hostname }}/container-first-run.sh\"\n    owner: \"root\"\n    group: \"root\"\n    mode: \"0755\"\n  delegate_to: \"{{ physical_host }}\"\n\n- name: Execute first script\n  ansible.builtin.command: \"/var/lib/lxc/{{ inventory_hostname }}/container-first-run.sh\"\n  args:\n    creates: \"/var/lib/lxc/{{ inventory_hostname }}/setup.complete\"\n  register: container_extra_commands\n  until: container_extra_commands is success\n  retries: 5\n  delay: 2\n  delegate_to: \"{{ physical_host }}\"\n# CONTAINER SETUP AND CONFIG\n\n# VETH AND CONNECTIVITY SETTINGS\n- name: Create container mac script\n  ansible.builtin.template:\n    src: container_mac_generation.sh.j2\n    dest: \"/var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}_mac_generation.sh\"\n    mode: \"0755\"\n  delegate_to: \"{{ physical_host }}\"\n  with_dict: \"{{ lxc_container_networks_combined }}\"\n\n# TODO(noondeadpunk): Remove that in X cycle\n- name: Cleanup old mac scripts\n  ansible.builtin.file:\n    path: \"/openstack/{{ inventory_hostname }}/{{ item.value.interface }}_mac_generation.sh\"\n    state: absent\n  delegate_to: \"{{ physical_host }}\"\n  with_dict: \"{{ lxc_container_networks_combined }}\"\n\n- name: Set define static mac address from an existing interface\n  ansible.builtin.command: \"/var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}_mac_generation.sh\"\n  args:\n    creates: \"/var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr\"\n  delegate_to: \"{{ physical_host }}\"\n  with_dict: \"{{ lxc_container_networks_combined }}\"\n\n- name: Gather hardware addresses to be used as facts\n  ansible.builtin.slurp:\n    src: \"/var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr\"\n  changed_when: false\n  register: macs\n  with_dict: \"{{ lxc_container_networks_combined }}\"\n  delegate_to: \"{{ physical_host }}\"\n\n# NOTE(cloudnull): To dynamically set the mac address \"facts\" Ansible line\n#                  format is being used\n- name: Set fixed hardware address fact\n  ansible.builtin.set_fact: \"{{ item.item.value.interface }}_mac_address={{ item.content | b64decode }}\" # noqa: no-free-form\n  with_items:\n    - \"{{ macs.results }}\"\n\n# NOTE(andymccr): We need an index for the interfaces in LXC >= 3 converting\n#                 to a list and using with_indexed_items for this purpose.\n- name: LXC host config for container networks\n  ansible.builtin.template:\n    src: \"container-interface.ini.j2\"\n    dest: \"/var/lib/lxc/{{ inventory_hostname }}/{{ item.1.interface }}.ini\"\n    owner: \"root\"\n    group: \"root\"\n    mode: \"0644\"\n  with_indexed_items: \"{{ (lxc_container_networks_combined.values() | list) | sort(attribute='interface') }}\"\n  register: network_config\n  delegate_to: \"{{ physical_host }}\"\n\n- name: Container network includes\n  ansible.builtin.lineinfile:\n    dest: \"/var/lib/lxc/{{ inventory_hostname }}/config\"\n    line: \"lxc.include = /var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.ini\"\n    backup: \"true\"\n  with_dict: \"{{ lxc_container_networks_combined }}\"\n  when: item.value.interface is defined\n  register: network_includes\n  delegate_to: \"{{ physical_host }}\"\n\n- name: Create wiring script\n  ansible.builtin.copy:\n    src: \"lxc-veth-wiring.sh\"\n    dest: \"/var/lib/lxc/{{ inventory_hostname }}/lxc-veth-wiring.sh\"\n    owner: \"root\"\n    group: \"root\"\n    mode: \"0755\"\n  delegate_to: \"{{ physical_host }}\"\n\n# Adds post-down and pre-start hooks\n- name: Drop veth cleanup script\n  ansible.builtin.template:\n    src: \"veth-cleanup.sh.j2\"\n    dest: \"/var/lib/lxc/{{ inventory_hostname }}/veth-cleanup.sh\"\n    owner: \"root\"\n    group: \"root\"\n    mode: \"0755\"\n  delegate_to: \"{{ physical_host }}\"\n\n- name: Defines a pre, post, and haltsignal configs\n  ansible.builtin.lineinfile:\n    dest: \"/var/lib/lxc/{{ inventory_hostname }}/config\"\n    line: \"{{ item }}\"\n    backup: \"true\"\n  with_items:\n    - \"lxc.hook.pre-start = /var/lib/lxc/{{ inventory_hostname }}/veth-cleanup.sh\"\n    - \"lxc.hook.post-stop = /var/lib/lxc/{{ inventory_hostname }}/veth-cleanup.sh\"\n    - \"lxc.signal.halt = SIGRTMIN+4\"\n  delegate_to: \"{{ physical_host }}\"\n\n- name: Run veth wiring\n  ansible.builtin.set_fact:\n    lxc_container_veth_wiring: true\n  when:\n    - ((not lxc_container_veth_wiring | bool) and\n       ((network_config is changed) and (network_includes is changed))) and\n      not ((default_configuration_container is changed) or\n           (bind_configuration_container is changed))\n\n- name: Run container veth wiring script\n  ansible.builtin.command: >-\n    /var/lib/lxc/{{ inventory_hostname }}/lxc-veth-wiring.sh\n    \"{{ inventory_hostname }}\"\n    \"{{ lxc_container_network_veth_pair[-15:] }}\"\n    \"{{ item.value.interface }}\"\n    \"{{ item.value.bridge }}\"\n    \"{{ item.value.bridge_type | default('linux_bridge') }}\"\n  register: wiring_script\n  with_dict: \"{{ lxc_container_networks_combined }}\"\n  when:\n    - lxc_container_veth_wiring | bool\n    - item.value.interface is defined\n    - item.value.type is not defined or item.value.type == 'veth'\n  failed_when: wiring_script.rc not in [3, 0]\n  changed_when: wiring_script.rc == 3\n  delegate_to: \"{{ physical_host }}\"\n\n- name: Including lxc_container_network tasks\n  ansible.builtin.include_tasks: \"lxc_container_network.yml\"\n# VETH AND CONNECTIVITY SETTINGS\n\n# SYSTEMD SERVICES\n- name: Run the systemd-service role\n  ansible.builtin.import_role:\n    name: systemd_service\n  vars:\n    systemd_service_enabled: true\n    systemd_slice_name: lxc-system\n    systemd_services: \"{{ _lxc_container_systemd_services }}\"\n# SYSTEMD SERVICES\n\n# ENVIRONMENT AND HOSTNAME SETTINGS\n- name: Add global_environment_variables to environment file\n  ansible.builtin.blockinfile:\n    dest: \"/etc/environment\"\n    state: present\n    marker: \"# {mark} Managed by OpenStack-Ansible\"\n    insertbefore: EOF\n    block: \"{{ lookup('template', 'environment.j2') }}\"\n  remote_user: root\n\n- name: Create localhost config\n  ansible.builtin.lineinfile:\n    dest: \"/etc/hosts\"\n    regexp: \"^127.0.0.1\"\n    line: \"127.0.0.1 localhost\"\n    owner: \"root\"\n    group: \"root\"\n    mode: \"0644\"\n  remote_user: root\n\n- name: Set hostnamectl name\n  ansible.builtin.command: \"/usr/bin/hostnamectl --static --pretty --transient set-hostname {{ intended_hostname }}\"\n  changed_when: false\n  vars:\n    intended_hostname: \"{{ inventory_hostname | replace('_', '-') | quote }}\"\n  when: ansible_facts['hostname'] != intended_hostname\n\n- name: Generate machine-id\n  ansible.builtin.command: \"systemd-machine-id-setup\"\n  args:\n    creates: \"/etc/machine-id\"\n  register: machine_id\n  notify:\n    - Lxc container restart\n\n- name: Ensure the dbus directory exists\n  ansible.builtin.file:\n    path: \"/var/lib/dbus\"\n    state: \"directory\"\n    mode: \"0755\"\n\n- name: Create dbus machine-id\n  ansible.builtin.copy:\n    src: \"/etc/machine-id\"\n    dest: \"/var/lib/dbus/machine-id\"\n    mode: \"0444\"\n    remote_src: \"yes\"\n  remote_user: root\n\n- name: Link container journal to host\n  block:\n    - name: Retrieve the machine-id\n      ansible.builtin.slurp:\n        src: /etc/machine-id\n      register: machine_id\n\n    - name: Set bind mount for journal linking\n      ansible.builtin.set_fact:\n        lxc_container_journal_path: \"/var/log/journal/{{ (machine_id.content | b64decode).strip() }}\"\n\n    - name: Ensure journal directory exists\n      ansible.builtin.file:\n        path: \"{{ lxc_container_journal_path }}\"\n        state: \"directory\"\n        group: \"systemd-journal\"\n        owner: \"root\"\n        mode: \"02755\"\n      delegate_to: \"{{ item }}\"\n      with_items:\n        - \"{{ physical_host }}\"\n        - \"{{ inventory_hostname }}\"\n\n    - name: Add bind mount configuration to container\n      ansible.builtin.lineinfile:\n        dest: \"/var/lib/lxc/{{ inventory_hostname }}/config\"\n        line: \"lxc.mount.entry = {{ lxc_container_journal_path }} {{ lxc_container_journal_path.lstrip('/') }} none bind,create=dir 0 0\"\n        backup: \"true\"\n      delegate_to: \"{{ physical_host }}\"\n  when:\n    - lxc_container_journal_link | bool\n# ENVIRONMENT AND HOSTNAME SETTINGS\n\n# SET CONTAINER FACTS\n- name: Allow the usage of local facts\n  ansible.builtin.file:\n    path: /etc/ansible/facts.d/\n    state: directory\n    mode: \"0755\"\n  tags:\n    - always\n\n- name: Record the container variant deployed\n  community.general.ini_file:\n    dest: \"/etc/ansible/facts.d/openstack_ansible.fact\"\n    section: lxc\n    option: variant\n    value: \"{{ properties['lxc_container_variant'] | default(lxc_container_variant) }}\"\n    mode: \"0644\"\n  tags:\n    - always\n# SET CONTAINER FACTS\n","created":"2025-12-14T10:09:49.640020Z","updated":"2025-12-14T10:09:49.640032Z","path":"/home/zuul/src/opendev.org/openstack/openstack-ansible-lxc_container_create/tasks/lxc_container_config.yml"}