{"id":396,"sha1":"0058552ddecfe60df75c3f71f9908ba963bfa1b0","playbook":{"id":4,"items":{"plays":104,"tasks":1377,"results":1365,"hosts":2,"files":504,"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-openstack.yml"]},"labels":[{"id":1,"name":"check:False"},{"id":2,"name":"tags:all"}],"started":"2025-12-08T13:39:52.478534Z","ended":"2025-12-08T14:14:54.510371Z","duration":"00:35:02.031837","name":null,"ansible_version":"2.18.6","client_version":"1.7.4","python_version":"3.12.3","server_version":"1.7.4","status":"failed","path":"/home/zuul/src/opendev.org/openstack/openstack-ansible/playbooks/setup-openstack.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: Slurp up the constraints file for later re-deployment\n  delegate_to: \"{{ venv_build_host }}\"\n  ansible.builtin.slurp:\n    src: \"{{ _venv_build_requirements_prefix }}-constraints.txt\"\n  register: _constraints_file_slurp\n  when: venv_wheel_build_enable | bool\n\n# TODO(odyssey4me):\n# Set a fact for the selective inclusion of the build package list.\n# Perhaps do this if the distro/architecture of the target host differs\n# from the build host.\n\n# NOTE(jrosser) remove the use: parameter when https://github.com/ansible/ansible/issues/82598 is fixed\n- name: Install distro packages for venv build\n  ansible.builtin.package:\n    name: >-\n      {{\n        (venv_wheel_build_enable | bool) | ternary(\n          venv_install_base_distro_package_list | union(venv_install_distro_package_list),\n          (\n            venv_build_base_distro_package_list |\n            union(venv_build_distro_package_list) |\n            union(venv_install_base_distro_package_list) |\n            union(venv_install_distro_package_list)\n          )\n        )\n      }}\n    state: \"{{ venv_distro_package_state }}\"\n    update_cache: \"{{ (ansible_facts['pkg_mgr'] == 'apt') | ternary('yes', omit) }}\"\n    cache_valid_time: \"{{ (ansible_facts['pkg_mgr'] == 'apt') | ternary(venv_distro_cache_valid_time, omit) }}\"\n    use: \"{{ ansible_facts['pkg_mgr'] }}\"\n  when:\n    - ((venv_build_base_distro_package_list | union(venv_build_distro_package_list)) | length > 0) or\n      ((venv_install_base_distro_package_list | union(venv_install_distro_package_list)) | length > 0)\n  register: _install_distro_packages\n  until: _install_distro_packages is success\n  retries: 5\n  delay: 2\n\n- name: Ensure a fresh venv_install_destination_path if venv_rebuild is enabled\n  ansible.builtin.file:\n    path: \"{{ venv_install_destination_path }}\"\n    state: absent\n  when:\n    - venv_rebuild | bool\n\n- name: Create the venv_install_destination_path parent directory\n  ansible.builtin.file:\n    path: \"{{ venv_install_destination_path }}\"\n    state: directory\n    mode: \"0755\"\n\n# Note(jrosser)\n# If the constraints file from the wheel build has been previously collected\n# then we must remove any git+... requirements from the input packages list\n# and replace them with the package name. The slurped constraints file will\n# contain the built version in the form foo=1.2.3dev4, and the requirements\n# file must just specify 'foo'.\n- name: Create the requirements file contents\n  ansible.builtin.set_fact:\n    _venv_install_pip_packages: |\n      {% if (venv_wheel_build_enable | bool) and\n            (_constraints_file_slurp is defined) and\n            (_constraints_file_slurp.content is defined) %}\n      {% set _newlist = [] %}\n      {%    for item in _venv_pip_packages  %}\n      {% set _x = _newlist.append(item.split('egg=')[-1]) %}\n      {%    endfor %}\n      {{ _newlist }}\n      {% else %}\n      {{ _venv_pip_packages }}\n      {% endif %}\n\n# Note(odyssey4me):\n# This requirements file is not used for anything except to determine\n# if requirements have changed. This helps reduce the execution time\n# of the role and to make the role execution idempotent. If not for\n# the conditional when installing the packages, any git constraints\n# would result in the package for that constraint always being\n# reinstalled.\n- name: Build requirement and constraint files for the venv\n  ansible.builtin.copy:\n    dest: \"{{ item.dest }}\"\n    content: \"{{ item.content }}\"\n    mode: \"0644\"\n  loop:\n    - dest: \"{{ venv_install_destination_path }}/requirements.txt\"\n      content: |-\n        {% for item in _venv_install_pip_packages | select() %}\n        {{ item }}\n        {% endfor %}\n    - dest: \"{{ venv_install_destination_path }}/global-constraints.txt\"\n      content: |-\n        {% for item in venv_build_global_constraints | select() %}\n        {{ item }}\n        {% endfor %}\n    - dest: \"{{ venv_install_destination_path }}/constraints.txt\"\n      content: |-\n        {%- if (venv_wheel_build_enable | bool) and\n              (_constraints_file_slurp is defined) and\n              (_constraints_file_slurp.content is defined) %}\n        {{ _constraints_file_slurp.content | b64decode }}\n        {%- else %}\n        {%   for item in venv_build_constraints | select() %}\n        {{ item }}\n        {%   endfor %}\n        {%- endif %}\n  loop_control:\n    label: \"{{ item.dest }}\"\n  register: _requirement_constraints_file\n\n- name: Upgrade pip/setuptools/wheel to the versions we want\n  ansible.builtin.pip:\n    name:\n      - \"{{ venv_install_tool }}\"\n      - setuptools\n      - wheel\n    state: \"{{ venv_pip_package_state }}\"\n    virtualenv: \"{{ venv_install_destination_path }}\"\n    virtualenv_command: \"{{ venv_python_executable }} -m venv\"\n    extra_args: >-\n      --constraint {{ venv_install_destination_path }}/global-constraints.txt\n      --constraint {{ venv_install_destination_path }}/constraints.txt\n      --log /var/log/python_venv_build.log\n      {{ venv_default_pip_install_args }}\n      {{ venv_pip_install_args }}\n  environment: \"{{ venv_pip_install_env | combine(_pip_upgrade_noconf) }}\"\n  vars:\n    _pip_upgrade_noconf:\n      PIP_CONFIG_FILE: \"{{ (venv_pip_upgrade_noconf | bool) | ternary('/dev/null', '') }}\"\n  register: _update_virtualenv_packages\n  until: _update_virtualenv_packages is success\n  retries: 5\n  delay: 2\n  notify:\n    - venv changed\n\n- name: Install python packages into the venv\n  block:\n    - name: Install python packages into the venv (pip)\n      ansible.builtin.pip:\n        name: \"{{ _venv_install_pip_packages }}\"\n        state: \"{{ venv_pip_package_state }}\"\n        executable: \"{{ venv_install_destination_path }}/bin/pip\"\n        extra_args: >-\n          --constraint {{ venv_install_destination_path }}/global-constraints.txt\n          --constraint {{ venv_install_destination_path }}/constraints.txt\n          --pre\n          --log /var/log/python_venv_build.log\n          {{ venv_default_pip_install_args }}\n          {{ venv_pip_install_args }}\n      environment: \"{{ venv_pip_install_env }}\"\n      when:\n        - _requirement_constraints_file.results | selectattr('changed') | length > 0\n        - venv_install_tool == 'pip'\n      register: _install_venv_pip_packages\n      until: _install_venv_pip_packages is success\n      retries: 5\n      delay: 2\n      notify:\n        - venv changed\n\n    - name: Install python packages into the venv (uv)\n      ansible.builtin.command: >-\n        {{ venv_install_destination_path }}/bin/uv pip\n          {{ (venv_pip_package_state == 'absent') | ternary('uninstall', 'install') }}\n          {% if venv_pip_package_state == 'latest' %}--upgrade{% endif %}\n          {% if venv_pip_package_state == 'forcereinstall' %}--reinstall{% endif %}\n          --python {{ venv_install_destination_path }}/bin/{{ venv_python_executable }}\n          --constraint {{ venv_install_destination_path }}/global-constraints.txt\n          --constraint {{ venv_install_destination_path }}/constraints.txt\n          --prerelease if-necessary-or-explicit\n          {{ venv_default_pip_install_args }}\n          {{ venv_pip_install_args }}\n          {{ _venv_install_pip_packages | join(' ') }}\n      changed_when:\n        - _install_venv_uv_packages.stderr_lines | select('match', '^(Installed|Uninstalled) \\d* packages in \\d*') | length > 0\n      environment: \"{{ venv_pip_install_env }}\"\n      when:\n        - _requirement_constraints_file.results | selectattr('changed') | length > 0\n        - venv_install_tool == 'uv'\n      register: _install_venv_uv_packages\n      until: _install_venv_uv_packages is success\n      retries: 5\n      delay: 2\n      notify:\n        - venv changed\n  rescue:\n    - name: Remove venv requirements/constraints files due to install failure\n      ansible.builtin.file:\n        path: \"{{ item }}\"\n        state: absent\n      with_items:\n        - \"{{ venv_install_destination_path }}/constraints.txt\"\n        - \"{{ venv_install_destination_path }}/global-constraints.txt\"\n        - \"{{ venv_install_destination_path }}/requirements.txt\"\n    - name: Show venv install failure message\n      ansible.builtin.fail:\n        msg: >\n          The python packages have failed to install, please check the log file\n          located at /var/log/python_venv_build.log for more information.\n\n- name: Add symlinks from distribution python packages\n  ansible.builtin.include_tasks: python_venv_install_symlink.yml\n  args:\n    apply:\n      tags:\n        - install\n  when:\n    - venv_packages_to_symlink | length > 0\n","created":"2025-12-08T13:39:54.201376Z","updated":"2025-12-08T13:39:54.201403Z","path":"/home/zuul/src/opendev.org/openstack/ansible-role-python_venv_build/tasks/python_venv_install.yml"}