diff --git a/ansible/disable-selinux.yml b/ansible/disable-selinux.yml deleted file mode 100644 index 3ce1706c6..000000000 --- a/ansible/disable-selinux.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: Disable SELinux and reboot if required - hosts: seed:overcloud:infra-vms - tags: - - disable-selinux - roles: - - role: disable-selinux - disable_selinux_reboot_timeout: "{{ 600 if ansible_facts.virtualization_role == 'host' else 300 }}" - when: ansible_facts.os_family == 'RedHat' diff --git a/ansible/docker-devicemapper.yml b/ansible/docker-devicemapper.yml index 70ead14a4..2a7b30275 100644 --- a/ansible/docker-devicemapper.yml +++ b/ansible/docker-devicemapper.yml @@ -5,6 +5,18 @@ - docker - docker-devicemapper tasks: + - name: Warn about deprecation of devicemapper Docker storage driver + fail: + msg: > + Support for using the devicemapper Docker storage driver is + deprecated in Kayobe and will be removed in the Caracal 16.0.0 + release. To keep using devicemapper in the current release, ensure + that the version of Docker Engine installed is below 25.0.0. + # NOTE(priteau): We want this to print a nice big red warning and not to + # fail the run. + ignore_errors: yes + when: docker_storage_driver == 'devicemapper' + - name: Check for existing Docker configuration using devicemapper block: - name: Query Docker daemon for storage driver diff --git a/ansible/group_vars/all/apt b/ansible/group_vars/all/apt index 46d26de18..6e2867151 100644 --- a/ansible/group_vars/all/apt +++ b/ansible/group_vars/all/apt @@ -45,3 +45,12 @@ apt_repositories: [] # when replacing the distribution repositories via apt_repositories. # Default is false. apt_disable_sources_list: false + +# List of Apt auth configurations. Each item is a dict with the following keys: +# * machine: 'machine' entry in the auth file +# * login: 'login' entry in the auth file +# * password: 'password' entry in the auth file +# * filename: Name of a file in /etc/apt/auth.conf.d in which to store +# the auth configuration. The extension should be ``.conf``. +# Default is an empty list. +apt_auth: [] diff --git a/ansible/group_vars/all/bifrost b/ansible/group_vars/all/bifrost index d780cfb10..788dddd12 100644 --- a/ansible/group_vars/all/bifrost +++ b/ansible/group_vars/all/bifrost @@ -99,7 +99,7 @@ kolla_bifrost_inspector_port_addition: "{{ inspector_add_ports }}" kolla_bifrost_inspector_extra_kernel_options: "{{ inspector_extra_kernel_options }}" # List of introspection rules for Bifrost's Ironic Inspector service. -kolla_bifrost_inspector_rules: "{{ inspector_rules }}" +kolla_bifrost_inspector_rules: "{{ inspector_rules + [inspector_rule_legacy_deploy_kernel] }}" # Ironic inspector IPMI username to set. kolla_bifrost_inspector_ipmi_username: "{{ ipmi_username }}" @@ -117,6 +117,9 @@ kolla_bifrost_inspector_deploy_kernel: "http://{{ provision_oc_net_name | net_ip # Ironic inspector deployment ramdisk location. kolla_bifrost_inspector_deploy_ramdisk: "http://{{ provision_oc_net_name | net_ip }}:8080/ipa.initramfs" +# Ironic inspector legacy deployment kernel location. +kolla_bifrost_inspector_legacy_deploy_kernel: "http://{{ provision_oc_net_name | net_ip }}:8080/ipa.vmlinuz" + # Timeout of hardware inspection on overcloud nodes, in seconds. Default is # {{ inspector_inspection_timeout }}. kolla_bifrost_inspection_timeout: "{{ inspector_inspection_timeout }}" diff --git a/ansible/group_vars/all/infra-vms b/ansible/group_vars/all/infra-vms index da4d6e537..0cdcbbd1c 100644 --- a/ansible/group_vars/all/infra-vms +++ b/ansible/group_vars/all/infra-vms @@ -48,7 +48,7 @@ infra_vm_root_format: qcow2 # or # https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2 # when os_distribution is "rocky" and os_release is "9" -# "https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20220913.0.x86_64.qcow2" +# "https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2" # otherwise. infra_vm_root_image: >- {%- if os_distribution == 'ubuntu' %} @@ -58,7 +58,7 @@ infra_vm_root_image: >- {%- elif os_distribution == 'rocky' and os_release == '9' %} https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2 {%- else -%} - https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20220913.0.x86_64.qcow2 + https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2 {%- endif %} # Capacity of the infra VM data volume. diff --git a/ansible/group_vars/all/inspector b/ansible/group_vars/all/inspector index a84a98a49..61bc01236 100644 --- a/ansible/group_vars/all/inspector +++ b/ansible/group_vars/all/inspector @@ -119,6 +119,18 @@ inspector_rule_deploy_kernel: path: "driver_info/deploy_kernel" value: "{{ inspector_rule_var_deploy_kernel }}" +# Ironic inspector rule to update deployment kernel from legacy location. +inspector_rule_legacy_deploy_kernel: + description: "Update deploy kernel from legacy" + conditions: + - field: "node://driver_info.deploy_kernel" + op: "eq" + value: "{{ inspector_rule_var_legacy_deploy_kernel }}" + actions: + - action: "set-attribute" + path: "driver_info/deploy_kernel" + value: "{{ inspector_rule_var_deploy_kernel }}" + # Deployment ramdisk referenced by inspector rule. inspector_rule_var_deploy_ramdisk: diff --git a/ansible/group_vars/all/ipa b/ansible/group_vars/all/ipa index 5969c28f2..eb9862073 100644 --- a/ansible/group_vars/all/ipa +++ b/ansible/group_vars/all/ipa @@ -47,7 +47,7 @@ ipa_build_dib_elements: > ipa_build_dib_env_default: # TODO(mgoddard): Use {{ os_release }} here when we use os_distribution # above. - DIB_RELEASE: "8-stream" + DIB_RELEASE: "9-stream" DIB_REPOLOCATION_ironic_python_agent: "{{ ipa_build_source_url }}" DIB_REPOREF_ironic_python_agent: "{{ ipa_build_source_version }}" DIB_REPOREF_requirements: "{{ openstack_branch }}" diff --git a/ansible/group_vars/all/kolla b/ansible/group_vars/all/kolla index 6e823f1c2..99467d0b6 100644 --- a/ansible/group_vars/all/kolla +++ b/ansible/group_vars/all/kolla @@ -203,11 +203,11 @@ overcloud_container_image_regex_map: enabled: "{{ kolla_enable_multipathd | bool }}" - regex: ^murano enabled: "{{ kolla_enable_murano | bool }}" - - regex: neutron-server + - regex: "neutron-\\(server\\|metadata-agent\\)" enabled: "{{ kolla_enable_neutron | bool }}" # Neutron SFC agent not currently supported on CentOS binary builds. - - regex: "neutron-\\(dhcp\\|l3\\|metadata\\|linuxbridge\\|openvswitch\\)-agent" - enabled: "{{ kolla_enable_neutron | bool }}" + - regex: "neutron-\\(dhcp\\|l3\\|linuxbridge\\|openvswitch\\)-agent" + enabled: "{{ kolla_build_neutron_ovs | default(kolla_enable_neutron | bool and not kolla_enable_ovn | bool) }}" - regex: neutron-mlnx-agent enabled: "{{ kolla_enable_neutron_mlnx | bool }}" - regex: neutron-sriov-agent @@ -627,9 +627,15 @@ kolla_ansible_default_custom_passwords: >- if compute_libvirt_enabled | bool and compute_libvirt_enable_sasl | bool else {}) }} +# Dictionary containing extra custom passwords to add or override in the Kolla +# passwords file. +kolla_ansible_extra_custom_passwords: {} + # Dictionary containing custom passwords to add or override in the Kolla # passwords file. -kolla_ansible_custom_passwords: "{{ kolla_ansible_default_custom_passwords }}" +kolla_ansible_custom_passwords: >- + {{ kolla_ansible_default_custom_passwords | + combine(kolla_ansible_extra_custom_passwords) }} ############################################################################### # OpenStack API addresses. @@ -666,7 +672,7 @@ kolla_external_tls_cert: # Path to a CA certificate file to use for the OS_CACERT environment variable # in public-openrc.sh file when TLS is enabled, instead of Kolla-Ansible's # default. -kolla_external_fqdn_cacert: +kolla_public_openrc_cacert: "{{ kolla_external_fqdn_cacert | default }}" # Internal API certificate bundle. # @@ -679,7 +685,7 @@ kolla_internal_tls_cert: # Path to a CA certificate file to use for the OS_CACERT environment variable # in admin-openrc.sh file when TLS is enabled, instead of Kolla-Ansible's # default. -kolla_internal_fqdn_cacert: +kolla_admin_openrc_cacert: "{{ kolla_internal_fqdn_cacert | default }}" ############################################################################### # Proxy configuration diff --git a/ansible/group_vars/all/overcloud-dib b/ansible/group_vars/all/overcloud-dib index ca0e470c9..05bc0c0be 100644 --- a/ansible/group_vars/all/overcloud-dib +++ b/ansible/group_vars/all/overcloud-dib @@ -42,7 +42,7 @@ overcloud_dib_os_release: "{{ os_release }}" overcloud_dib_elements_default: - "{{ overcloud_dib_os_element }}" - "cloud-init-datasources" - - "{% if overcloud_dib_os_element in ['centos', 'rocky'] %}disable-selinux{% endif %}" + - "{% if os_distribution in ['centos', 'rocky'] %}disable-selinux{% endif %}" - "enable-serial-console" - "vm" diff --git a/ansible/group_vars/all/seed b/ansible/group_vars/all/seed index f1524a2e0..7ec3d4536 100644 --- a/ansible/group_vars/all/seed +++ b/ansible/group_vars/all/seed @@ -123,6 +123,10 @@ seed_users: "{{ users_default }}" # seed_containers: {} +# Whether to attempt a basic authentication login to a registry when +# deploying seed containers +seed_deploy_containers_registry_attempt_login: "{{ kolla_docker_registry_username is truthy and kolla_docker_registry_password is truthy }}" + ############################################################################### # Seed node firewalld configuration. diff --git a/ansible/group_vars/all/seed-vm b/ansible/group_vars/all/seed-vm index 6e5d3395c..81f5b6500 100644 --- a/ansible/group_vars/all/seed-vm +++ b/ansible/group_vars/all/seed-vm @@ -48,7 +48,7 @@ seed_vm_root_format: qcow2 # or # https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2 # when os_distribution is "rocky" and os_release is "9" -# "https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20220913.0.x86_64.qcow2" +# "https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2" # otherwise. seed_vm_root_image: >- {%- if os_distribution == 'ubuntu' %} @@ -58,7 +58,7 @@ seed_vm_root_image: >- {%- elif os_distribution == 'rocky' and os_release == '9' %} https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2 {%- else -%} - https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20220913.0.x86_64.qcow2 + https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2 {%- endif %} # Capacity of the seed VM data volume. diff --git a/ansible/group_vars/monitoring/firewall b/ansible/group_vars/monitoring/firewall index a1b151527..41c3c411b 100644 --- a/ansible/group_vars/monitoring/firewall +++ b/ansible/group_vars/monitoring/firewall @@ -19,7 +19,7 @@ firewalld_zones: > firewalld_default_zone: >- {{ controller_firewalld_default_zone if inventory_hostname in groups['controllers'] else - monitoring_firewalld_default_zone }}" + monitoring_firewalld_default_zone }} # A list of firewall rules to apply. Each item is a dict containing arguments # to pass to the firewalld module. Arguments are omitted if not provided, with @@ -30,4 +30,4 @@ firewalld_default_zone: >- firewalld_rules: > {{ controller_firewalld_rules if inventory_hostname in groups['controllers'] else - monitoring_firewalld_rules }}" + monitoring_firewalld_rules }} diff --git a/ansible/group_vars/seed/docker-registry b/ansible/group_vars/seed/docker-registry new file mode 100644 index 000000000..f439501ec --- /dev/null +++ b/ansible/group_vars/seed/docker-registry @@ -0,0 +1,7 @@ +--- +############################################################################### +# Seed node docker regsitry configuration. + +# Whether to attempt a basic authentication login to a registry when +# deploying seed containers +deploy_containers_registry_attempt_login: "{{ seed_deploy_containers_registry_attempt_login }}" diff --git a/ansible/infra-vm-host-configure.yml b/ansible/infra-vm-host-configure.yml index ce7b25c8e..e175757e5 100644 --- a/ansible/infra-vm-host-configure.yml +++ b/ansible/infra-vm-host-configure.yml @@ -9,7 +9,7 @@ - import_playbook: "wipe-disks.yml" - import_playbook: "users.yml" - import_playbook: "dev-tools.yml" -- import_playbook: "disable-selinux.yml" +- import_playbook: "selinux.yml" - import_playbook: "network.yml" - import_playbook: "firewall.yml" - import_playbook: "tuned.yml" diff --git a/ansible/kayobe-ansible-user.yml b/ansible/kayobe-ansible-user.yml index 6d081baf6..4568ab01a 100644 --- a/ansible/kayobe-ansible-user.yml +++ b/ansible/kayobe-ansible-user.yml @@ -13,20 +13,15 @@ - kayobe-ansible-user tasks: - name: Check whether the host is accessible via SSH - local_action: - module: command ssh -o BatchMode=yes -p {{ ssh_port }} {{ ssh_user }}@{{ ssh_host }} hostname - failed_when: false + raw: hostname + ignore_unreachable: true changed_when: false check_mode: no register: ssh_result - vars: - ssh_user: "{{ ansible_user }}" - ssh_host: "{{ ansible_host | default(inventory_hostname) }}" - ssh_port: "{{ ansible_ssh_port | default('22') }}" - name: Group hosts requiring kayobe user bootstrapping group_by: - key: kayobe_user_bootstrap_required_{{ ssh_result.rc != 0 }} + key: kayobe_user_bootstrap_required_{{ ssh_result.unreachable | default(false) }} changed_when: false - name: Display a message when bootstrapping is required @@ -34,7 +29,7 @@ msg: > Cannot access host via SSH using Kayobe Ansible user account - attempting bootstrap - when: ssh_result.rc != 0 + when: ssh_result.unreachable | default(false) - name: Ensure python is installed hosts: kayobe_user_bootstrap_required_True diff --git a/ansible/kolla-ansible.yml b/ansible/kolla-ansible.yml index 2469c0847..7f1d34025 100644 --- a/ansible/kolla-ansible.yml +++ b/ansible/kolla-ansible.yml @@ -93,20 +93,12 @@ - "{{ kayobe_config_path }}" kolla_overcloud_inventory_search_paths: "{{ kolla_overcloud_inventory_search_paths_static + kayobe_env_search_paths }}" kolla_ansible_certificates_path: "{{ kayobe_env_config_path }}/kolla/certificates" - # NOTE: This differs from the default SELinux mode in kolla ansible, - # which is permissive. The justification for using this mode is twofold: - # 1. it avoids filling up the audit log - # 2. it avoids an issue seen when using diskimage-builder in the bifrost - # container. - # We could look at making the SELinux mode configurable in future. - kolla_selinux_state: disabled kolla_inspector_dhcp_pool_start: "{{ inspection_net_name | net_inspection_allocation_pool_start }}" kolla_inspector_dhcp_pool_end: "{{ inspection_net_name | net_inspection_allocation_pool_end }}" kolla_inspector_netmask: "{{ inspection_net_name | net_mask }}" kolla_inspector_default_gateway: "{{ inspection_net_name | net_inspection_gateway or inspection_net_name | net_gateway }}" kolla_inspector_extra_kernel_options: "{{ inspector_extra_kernel_options }}" kolla_libvirt_tls: "{{ compute_libvirt_enable_tls | bool }}" - kolla_enable_host_ntp: false docker_daemon_mtu: "{{ public_net_name | net_mtu | default }}" kolla_globals_paths_static: - "{{ kayobe_config_path }}" diff --git a/ansible/kolla-bifrost-hostvars.yml b/ansible/kolla-bifrost-hostvars.yml index e43bcd7e6..a916c6f88 100644 --- a/ansible/kolla-bifrost-hostvars.yml +++ b/ansible/kolla-bifrost-hostvars.yml @@ -19,10 +19,10 @@ ipv4_interface_mac: "{% raw %}{{ extra.pxe_interface_mac | default }}{% endraw %}" ipv4_address: "{{ admin_oc_net_name | net_ip }}" ipv4_subnet_mask: "{{ admin_oc_net_name | net_mask }}" - # If the admin network does not have a gateway defined, use the - # seed as a gateway to allow external access until other networks have - # been configured. - ipv4_gateway: "{{ admin_oc_net_name | net_gateway or admin_oc_net_name | net_ip(seed_host) }}" + # If the admin network does not have a gateway defined and seed SNAT is + # enabled, use the seed as a gateway to allow external access until other + # networks have been configured. Otherwise, do not set any gateway. + ipv4_gateway: "{{ (admin_oc_net_name | net_gateway) or (admin_oc_net_name | net_ip(seed_host) if seed_enable_snat | bool) }}" ipv4_nameserver: "{{ resolv_nameservers }}" network_mtu: "{{ admin_oc_net_name | net_mtu or '1500' }}" vlan_id: "{{ '' if admin_oc_net_name == provision_oc_net_name else (admin_oc_net_name | net_vlan) }}" diff --git a/ansible/kolla-openstack.yml b/ansible/kolla-openstack.yml index 740faf5f8..3ab83923d 100644 --- a/ansible/kolla-openstack.yml +++ b/ansible/kolla-openstack.yml @@ -94,6 +94,7 @@ switch_type_to_device_type: arista: netmiko_arista_eos dellos9: netmiko_dell_force10 + dellos10: netmiko_dell_os10 dell-powerconnect: netmiko_dell_powerconnect junos: netmiko_juniper openvswitch: netmiko_ovs_linux diff --git a/ansible/overcloud-host-configure.yml b/ansible/overcloud-host-configure.yml index 31587891b..d43c711e9 100644 --- a/ansible/overcloud-host-configure.yml +++ b/ansible/overcloud-host-configure.yml @@ -9,7 +9,7 @@ - import_playbook: "wipe-disks.yml" - import_playbook: "users.yml" - import_playbook: "dev-tools.yml" -- import_playbook: "disable-selinux.yml" +- import_playbook: "selinux.yml" - import_playbook: "network.yml" - import_playbook: "firewall.yml" - import_playbook: "tuned.yml" diff --git a/ansible/roles/apt/defaults/main.yml b/ansible/roles/apt/defaults/main.yml index f818381d7..d604ca86c 100644 --- a/ansible/roles/apt/defaults/main.yml +++ b/ansible/roles/apt/defaults/main.yml @@ -48,3 +48,12 @@ apt_repositories: [] # when replacing the distribution repositories via apt_repositories. # Default is false. apt_disable_sources_list: false + +# List of Apt auth configurations. Each item is a dict with the following keys: +# * machine: 'machine' entry in the auth file +# * login: 'login' entry in the auth file +# * password: 'password' entry in the auth file +# * filename: Name of a file in /etc/apt/auth.conf.d in which to store +# the auth configuration. The extension should be ``.conf``. +# Default is an empty list. +apt_auth: [] diff --git a/ansible/roles/apt/files/auth_schema.json b/ansible/roles/apt/files/auth_schema.json new file mode 100644 index 000000000..977350822 --- /dev/null +++ b/ansible/roles/apt/files/auth_schema.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "List of Apt auth configurations", + "type": "array", + "items": { + "description": "Apt auth configuration", + "type": "object", + "required": ["machine", "login", "password", "filename"], + "properties": { + "machine": { + "type": "string", + "minLength": 1 + }, + "login": { + "type": "string", + "minLength": 1 + }, + "password": { + "type": "string", + "minLength": 1 + }, + "filename": { + "type": "string", + "minLength": 1 + } + } + } +} diff --git a/ansible/roles/apt/tasks/auth.yml b/ansible/roles/apt/tasks/auth.yml new file mode 100644 index 000000000..9718ebfc1 --- /dev/null +++ b/ansible/roles/apt/tasks/auth.yml @@ -0,0 +1,32 @@ +--- +- name: Validate Apt auth config + ansible.utils.validate: + criteria: "{{ lookup('ansible.builtin.file', 'auth_schema.json') }}" + data: "{{ apt_auth }}" + +- name: Ensure the Apt auth.conf.d directory exists + ansible.builtin.file: + path: "/etc/apt/auth.conf.d" + state: directory + owner: root + group: root + mode: 0755 + become: true + +- name: Configure Apt auth files + ansible.builtin.template: + src: "auth.conf.j2" + dest: "/etc/apt/auth.conf.d/{{ auth.filename }}" + owner: root + group: root + mode: 0600 + become: true + # apt_auth contains sensitive data, so iterate over indices to avoid exposing + # them in Ansible output. + loop: "{{ apt_auth | map(attribute='filename') }}" + loop_control: + index_var: auth_index + vars: + auth: "{{ apt_auth[auth_index] }}" + notify: + - Update apt cache diff --git a/ansible/roles/apt/tasks/keys.yml b/ansible/roles/apt/tasks/keys.yml index 4c1cda1e0..4b04e824b 100644 --- a/ansible/roles/apt/tasks/keys.yml +++ b/ansible/roles/apt/tasks/keys.yml @@ -17,3 +17,7 @@ mode: 0644 loop: "{{ apt_keys }}" become: true + register: result + until: result is successful + retries: 3 + delay: 5 diff --git a/ansible/roles/apt/tasks/main.yml b/ansible/roles/apt/tasks/main.yml index b4cb8f636..7bdf2cf01 100644 --- a/ansible/roles/apt/tasks/main.yml +++ b/ansible/roles/apt/tasks/main.yml @@ -6,3 +6,5 @@ - import_tasks: keys.yml - import_tasks: repos.yml + +- import_tasks: auth.yml diff --git a/ansible/roles/apt/templates/auth.conf.j2 b/ansible/roles/apt/templates/auth.conf.j2 new file mode 100644 index 000000000..a5abd10ae --- /dev/null +++ b/ansible/roles/apt/templates/auth.conf.j2 @@ -0,0 +1,5 @@ +# {{ ansible_managed }} + +machine {{ auth.machine }} +login {{ auth.login }} +password {{ auth.password }} diff --git a/ansible/roles/dell-switch-bmp/tasks/main.yml b/ansible/roles/dell-switch-bmp/tasks/main.yml index cc7e65894..c02a5a8bc 100644 --- a/ansible/roles/dell-switch-bmp/tasks/main.yml +++ b/ansible/roles/dell-switch-bmp/tasks/main.yml @@ -20,3 +20,7 @@ notify: - Copy Dell switch BMP images become: True + register: result + until: result is successful + retries: 3 + delay: 5 diff --git a/ansible/roles/deploy-containers/defaults/main.yml b/ansible/roles/deploy-containers/defaults/main.yml index 84c77a7e4..9130164e9 100644 --- a/ansible/roles/deploy-containers/defaults/main.yml +++ b/ansible/roles/deploy-containers/defaults/main.yml @@ -11,3 +11,5 @@ deploy_containers_defaults: restart_policy: "unless-stopped" deploy_containers_docker_api_timeout: 120 + +deploy_containers_registry_attempt_login: "{{ kolla_docker_registry_username is truthy and kolla_docker_registry_password is truthy }}" diff --git a/ansible/roles/deploy-containers/tasks/main.yml b/ansible/roles/deploy-containers/tasks/main.yml index c1ec533a3..a16e6d8d7 100644 --- a/ansible/roles/deploy-containers/tasks/main.yml +++ b/ansible/roles/deploy-containers/tasks/main.yml @@ -6,8 +6,7 @@ password: "{{ kolla_docker_registry_password }}" reauthorize: yes when: - - kolla_docker_registry_username is truthy - - kolla_docker_registry_password is truthy + - deploy_containers_registry_attempt_login | bool - name: Deploy containers (loop) include_tasks: deploy.yml diff --git a/ansible/roles/disable-selinux/tasks/main.yml b/ansible/roles/disable-selinux/tasks/main.yml deleted file mode 100644 index 5b777452b..000000000 --- a/ansible/roles/disable-selinux/tasks/main.yml +++ /dev/null @@ -1,40 +0,0 @@ ---- -- name: Ensure required packages are installed - package: - name: python3-libselinux - state: present - cache_valid_time: "{{ apt_cache_valid_time if ansible_facts.os_family == 'Debian' else omit }}" - update_cache: "{{ True if ansible_facts.os_family == 'Debian' else omit }}" - become: True - -- name: Check if SELinux configuration file exists - stat: - path: /etc/selinux/config - register: stat_result - -- name: Ensure SELinux is disabled - selinux: - state: disabled - register: selinux_result - become: True - when: stat_result.stat.exists - -- block: - - name: Set a fact to determine whether we are running locally - set_fact: - is_local: "{{ lookup('pipe', 'hostname') in [ansible_facts.hostname, ansible_facts.nodename] }}" - - - name: Reboot the system to apply SELinux changes (local) - command: shutdown -r now "Applying SELinux changes" - become: True - when: is_local | bool - - - name: Reboot the machine to apply SELinux - reboot: - reboot_timeout: "{{ disable_selinux_reboot_timeout }}" - msg: Applying SELinux changes - become: true - when: not is_local | bool - when: - - disable_selinux_do_reboot | bool - - selinux_result is changed diff --git a/ansible/roles/dnf/tasks/custom-repo.yml b/ansible/roles/dnf/tasks/custom-repo.yml index 759594ecf..a20018e92 100644 --- a/ansible/roles/dnf/tasks/custom-repo.yml +++ b/ansible/roles/dnf/tasks/custom-repo.yml @@ -16,12 +16,14 @@ metalink: "{{ item.value.metalink | default(omit)}}" mirrorlist: "{{ item.value.mirrorlist | default(omit)}}" mirrorlist_expire: "{{ item.value.mirrorlist_expire | default(omit)}}" + password: "{{ item.value.password | default(omit) }}" priority: "{{ item.value.priority | default(omit)}}" proxy: "{{ item.value.proxy | default(omit)}}" proxy_password: "{{ item.value.proxy_password | default(omit)}}" proxy_username: "{{ item.value.proxy_username | default(omit)}}" repo_gpgcheck: "{{ item.value.repo_gpgcheck | default(omit)}}" sslverify: "{{ item.value.sslverify | default(omit)}}" + username: "{{ item.value.username | default(omit) }}" state: "{{ item.value.state | default(omit)}}" with_dict: "{{ dnf_custom_repos }}" register: register_dnf_command diff --git a/ansible/roles/image-download/tasks/main.yml b/ansible/roles/image-download/tasks/main.yml index ce591a491..4dbcfcc48 100644 --- a/ansible/roles/image-download/tasks/main.yml +++ b/ansible/roles/image-download/tasks/main.yml @@ -18,6 +18,9 @@ url: "{{ image_download_checksum_url }}" return_content: true register: expected_checksum + until: expected_checksum is successful + retries: 3 + delay: 5 when: - image_download_checksum_url is not none - image_download_checksum_url != "" @@ -35,6 +38,10 @@ # Always download the image if we have no checksum to compare with. force: "{{ expected_checksum is skipped }}" backup: true + register: result + until: result is successful + retries: 3 + delay: 5 when: - image_download_url is not none - image_download_url != "" diff --git a/ansible/roles/kolla-ansible/defaults/main.yml b/ansible/roles/kolla-ansible/defaults/main.yml index 4f7a114d8..82f03eef4 100644 --- a/ansible/roles/kolla-ansible/defaults/main.yml +++ b/ansible/roles/kolla-ansible/defaults/main.yml @@ -169,8 +169,8 @@ kolla_enable_tls_external: kolla_enable_tls_internal: kolla_external_fqdn_cert: kolla_internal_fqdn_cert: -kolla_external_fqdn_cacert: -kolla_internal_fqdn_cacert: +kolla_public_openrc_cacert: +kolla_admin_openrc_cacert: ############################# # Ironic options @@ -282,18 +282,6 @@ kolla_ansible_custom_passwords: {} kolla_external_tls_cert: kolla_internal_tls_cert: -############################################################################### -# SELinux - -# Desired SELinux state. -kolla_selinux_state: - -############################################################################### -# NTP - -# Whether to enable the NTP daemon. -kolla_enable_host_ntp: - ############################################################################### # Docker configuration. diff --git a/ansible/roles/kolla-ansible/templates/kolla/globals.yml b/ansible/roles/kolla-ansible/templates/kolla/globals.yml index 507854caa..317316a3b 100644 --- a/ansible/roles/kolla-ansible/templates/kolla/globals.yml +++ b/ansible/roles/kolla-ansible/templates/kolla/globals.yml @@ -207,8 +207,7 @@ kolla_external_fqdn_cert: "{{ kolla_external_fqdn_cert }}" {% if kolla_internal_tls_cert is not none and kolla_internal_tls_cert | length > 0 %} kolla_internal_fqdn_cert: "{{ kolla_internal_fqdn_cert }}" {% endif %} -kolla_external_fqdn_cacert: "{{ kolla_external_fqdn_cacert }}" -kolla_internal_fqdn_cacert: "{{ kolla_internal_fqdn_cacert }}" +kolla_admin_openrc_cacert: "{{ kolla_admin_openrc_cacert }}" ################ # Region options @@ -551,13 +550,9 @@ grafana_admin_username: "{{ grafana_local_admin_user_name }}" # Bootstrap-servers - Host Configuration ######################################### -{% if kolla_selinux_state is not none %} -selinux_state: {{ kolla_selinux_state }} -{% endif %} - -{% if kolla_enable_host_ntp is not none %} -enable_host_ntp: {{ kolla_enable_host_ntp | bool }} -{% endif %} +# Kayobe performs configuration of SELinux, so there is no need for Kolla +# Ansible to repeat this. +change_selinux: false # Kayobe performs creation of the Kolla Ansible user account, so there is no # need for Kolla Ansible to repeat this. diff --git a/ansible/roles/kolla-ansible/templates/overcloud-services.j2 b/ansible/roles/kolla-ansible/templates/overcloud-services.j2 index 4a43b2dd5..da09f19f7 100644 --- a/ansible/roles/kolla-ansible/templates/overcloud-services.j2 +++ b/ansible/roles/kolla-ansible/templates/overcloud-services.j2 @@ -520,6 +520,7 @@ monitoring [prometheus-elasticsearch-exporter:children] elasticsearch +opensearch [prometheus-blackbox-exporter:children] monitoring diff --git a/ansible/roles/kolla-ansible/tests/test-extras.yml b/ansible/roles/kolla-ansible/tests/test-extras.yml index 527c39f37..39e3452bd 100644 --- a/ansible/roles/kolla-ansible/tests/test-extras.yml +++ b/ansible/roles/kolla-ansible/tests/test-extras.yml @@ -136,6 +136,7 @@ kolla_internal_fqdn_cert: "{{ temp_path }}/etc/kolla/certificates/internal.pem" kolla_internal_tls_cert: | bogus internal certificate + kolla_admin_openrc_cacert: "{{ temp_path }}/etc/kolla/certificates/ca/foo.crt" kolla_openstack_logging_debug: True grafana_local_admin_user_name: "grafana-admin" kolla_inspector_dhcp_pool_start: "1.2.3.4" @@ -261,6 +262,7 @@ kolla_external_fqdn_cert: "{{ temp_path }}/etc/kolla/certificates/external.pem" kolla_enable_tls_internal: True kolla_internal_fqdn_cert: "{{ temp_path }}/etc/kolla/certificates/internal.pem" + kolla_admin_openrc_cacert: "{{ temp_path }}/etc/kolla/certificates/ca/foo.crt" openstack_logging_debug: True grafana_admin_username: "grafana-admin" ironic_dnsmasq_dhcp_range: "1.2.3.4,1.2.3.5,255.255.255.0" diff --git a/ansible/roles/kolla-ansible/vars/Debian.yml b/ansible/roles/kolla-ansible/vars/Debian.yml index b9b871a4d..bb03e7b9c 100644 --- a/ansible/roles/kolla-ansible/vars/Debian.yml +++ b/ansible/roles/kolla-ansible/vars/Debian.yml @@ -2,6 +2,7 @@ # List of packages to install. kolla_ansible_package_dependencies: - gcc + - git - libffi-dev - libssl-dev - python3-dev diff --git a/ansible/roles/kolla-ansible/vars/RedHat.yml b/ansible/roles/kolla-ansible/vars/RedHat.yml index 6568ed9d1..499084905 100644 --- a/ansible/roles/kolla-ansible/vars/RedHat.yml +++ b/ansible/roles/kolla-ansible/vars/RedHat.yml @@ -2,6 +2,7 @@ # List of packages to install. kolla_ansible_package_dependencies: - gcc + - git - libffi-devel - openssl-devel - python3-devel diff --git a/ansible/roles/kolla-ansible/vars/main.yml b/ansible/roles/kolla-ansible/vars/main.yml index a6a524940..958d77e33 100644 --- a/ansible/roles/kolla-ansible/vars/main.yml +++ b/ansible/roles/kolla-ansible/vars/main.yml @@ -113,6 +113,7 @@ kolla_feature_flags: - gnocchi - gnocchi_statsd - grafana + - grafana_external - hacluster - haproxy - haproxy_memcached @@ -152,6 +153,7 @@ kolla_feature_flags: - keystone_federation - keystone_horizon_policy_file - kibana + - kibana_external - kuryr - loadbalancer - magnum @@ -164,6 +166,8 @@ kolla_feature_flags: - mariabackup - mariadb - masakari + - masakari_hostmonitor + - masakari_instancemonitor - memcached - mistral - monasca @@ -206,6 +210,7 @@ kolla_feature_flags: - placement - prometheus - prometheus_alertmanager + - prometheus_alertmanager_external - prometheus_blackbox_exporter - prometheus_cadvisor - prometheus_ceph_mgr_exporter @@ -215,6 +220,7 @@ kolla_feature_flags: - prometheus_haproxy_exporter - prometheus_libvirt_exporter - prometheus_memcached_exporter + - prometheus_msteams - prometheus_mysqld_exporter - prometheus_node_exporter - prometheus_openstack_exporter diff --git a/ansible/roles/kolla-bifrost/tasks/main.yml b/ansible/roles/kolla-bifrost/tasks/main.yml index ab8f1417b..ad5b6b40d 100644 --- a/ansible/roles/kolla-bifrost/tasks/main.yml +++ b/ansible/roles/kolla-bifrost/tasks/main.yml @@ -1,4 +1,12 @@ --- +- name: Check if inspection allocation is defined + assert: + that: + - kolla_bifrost_dhcp_pool_start | length > 0 + - kolla_bifrost_dhcp_pool_end | length > 0 + - kolla_bifrost_dhcp_pool_mask | length > 0 + fail_msg: "Inspection allocation pool for provisioning network is not properly defined" + - name: Ensure the Kolla Bifrost configuration directories exist file: path: "{{ kolla_node_custom_config_path }}/bifrost" diff --git a/ansible/roles/kolla/vars/Debian.yml b/ansible/roles/kolla/vars/Debian.yml index 3d7bff90c..7f65900c6 100644 --- a/ansible/roles/kolla/vars/Debian.yml +++ b/ansible/roles/kolla/vars/Debian.yml @@ -2,6 +2,7 @@ # List of packages to install. kolla_package_dependencies: - gcc + - git - libffi-dev - libssl-dev - python3-dev diff --git a/ansible/roles/kolla/vars/RedHat.yml b/ansible/roles/kolla/vars/RedHat.yml index dc2dbb32b..397acf767 100644 --- a/ansible/roles/kolla/vars/RedHat.yml +++ b/ansible/roles/kolla/vars/RedHat.yml @@ -2,6 +2,7 @@ # List of packages to install. kolla_package_dependencies: - gcc + - git - libffi-devel - openssl-devel - python3-devel diff --git a/ansible/roles/network-redhat/tasks/main.yml b/ansible/roles/network-redhat/tasks/main.yml index 24d5b4e92..b749ab479 100644 --- a/ansible/roles/network-redhat/tasks/main.yml +++ b/ansible/roles/network-redhat/tasks/main.yml @@ -17,6 +17,31 @@ when: resolv_is_managed | bool become: True +- name: Ensure NetworkManager DNS config is present only if required + become: true + community.general.ini_file: + path: /etc/NetworkManager/NetworkManager.conf + section: main + option: "{{ item.option }}" + value: "{{ item.value }}" + state: "{{ 'present' if resolv_is_managed | bool else 'absent'}}" + loop: + - option: dns + value: none + - option: rc-manager + value: unmanaged + when: + - ansible_facts.os_family == "RedHat" and ansible_facts.distribution_major_version == "9" + register: dns_config_task + +- name: Reload NetworkManager with DNS config + become: true + systemd: + name: NetworkManager + state: reloaded + daemon_reload: yes + when: dns_config_task is changed + - name: Configure network interfaces (RedHat) import_role: name: MichaelRigart.interfaces @@ -25,7 +50,7 @@ interfaces_ether_interfaces: > {{ network_interfaces | net_select_ethers | - map('net_interface_obj') | + map('net_interface_obj', names=network_interfaces) | list }} interfaces_bridge_interfaces: > {{ network_interfaces | diff --git a/ansible/roles/public-openrc/templates/public-openrc.sh.j2 b/ansible/roles/public-openrc/templates/public-openrc.sh.j2 index d0356e800..1c2dd179c 100644 --- a/ansible/roles/public-openrc/templates/public-openrc.sh.j2 +++ b/ansible/roles/public-openrc/templates/public-openrc.sh.j2 @@ -11,8 +11,8 @@ export OS_ENDPOINT_TYPE=publicURL export OS_MANILA_ENDPOINT_TYPE=publicURL {% elif "export OS_MISTRAL_ENDPOINT_TYPE" in line %} export OS_MISTRAL_ENDPOINT_TYPE=publicURL -{% elif "export OS_CACERT" in line and kolla_external_fqdn_cacert is not none %} -export OS_CACERT={{ kolla_external_fqdn_cacert }} +{% elif "export OS_CACERT" in line and kolla_public_openrc_cacert is not none %} +export OS_CACERT={{ kolla_public_openrc_cacert }} {% else %} {{ line }} {% endif %} diff --git a/ansible/roles/disable-selinux/defaults/main.yml b/ansible/roles/selinux/defaults/main.yml similarity index 50% rename from ansible/roles/disable-selinux/defaults/main.yml rename to ansible/roles/selinux/defaults/main.yml index 23fd5cd33..b58a0da96 100644 --- a/ansible/roles/disable-selinux/defaults/main.yml +++ b/ansible/roles/selinux/defaults/main.yml @@ -1,7 +1,14 @@ --- +# Target SELinux policy +selinux_policy: targeted + +# Target SELinux state +selinux_state: disabled + # Whether to reboot to apply SELinux config changes. disable_selinux_do_reboot: true +selinux_do_reboot: "{{ disable_selinux_do_reboot }}" # Number of seconds to wait for hosts to become accessible via SSH after being # rebooted. -disable_selinux_reboot_timeout: +selinux_reboot_timeout: diff --git a/ansible/roles/selinux/tasks/main.yml b/ansible/roles/selinux/tasks/main.yml new file mode 100644 index 000000000..54f699303 --- /dev/null +++ b/ansible/roles/selinux/tasks/main.yml @@ -0,0 +1,54 @@ +--- +- name: Ensure required packages are installed + package: + name: python3-libselinux + state: present + cache_valid_time: "{{ apt_cache_valid_time if ansible_facts.os_family == 'Debian' else omit }}" + update_cache: "{{ True if ansible_facts.os_family == 'Debian' else omit }}" + become: True + +- name: Check if SELinux configuration file exists + stat: + path: /etc/selinux/config + register: stat_result + +- name: Ensure desired SELinux state + selinux: + policy: "{{ selinux_policy }}" + state: "{{ selinux_state }}" + register: selinux_result + become: True + when: stat_result.stat.exists + +- block: + - name: Abort SELinux configuration because reboot is disabled + fail: + msg: > + SELinux state change requires a reboot, but selinux_do_reboot is + false. Please run again with selinux_do_reboot set to true to reboot. + when: + - not selinux_do_reboot | bool + + - block: + - name: Set a fact to determine whether we are running locally + set_fact: + is_local: "{{ lookup('pipe', 'hostname') in [ansible_facts.hostname, ansible_facts.nodename] }}" + + - name: Reboot the system to apply SELinux changes (local) + command: shutdown -r now "Applying SELinux changes" + become: True + when: + - is_local | bool + + - name: Reboot the machine to apply SELinux + reboot: + reboot_timeout: "{{ selinux_reboot_timeout }}" + msg: Applying SELinux changes + become: true + when: + - not is_local | bool + when: + - selinux_do_reboot | bool + when: + - stat_result.stat.exists + - selinux_result.reboot_required diff --git a/ansible/roles/veth/defaults/main.yml b/ansible/roles/veth/defaults/main.yml index e72b74341..2754b0d0a 100644 --- a/ansible/roles/veth/defaults/main.yml +++ b/ansible/roles/veth/defaults/main.yml @@ -1,3 +1,5 @@ --- +interfaces_use_networkmanager: "{{ ansible_facts.distribution_major_version | int >= 9 }}" + # List of virtual interfaces to configure. veth_interfaces: [] diff --git a/ansible/roles/veth/tasks/RedHat.yml b/ansible/roles/veth/tasks/RedHat.yml index 8315c8269..6b9c48760 100644 --- a/ansible/roles/veth/tasks/RedHat.yml +++ b/ansible/roles/veth/tasks/RedHat.yml @@ -1,6 +1,6 @@ --- - include_tasks: network-scripts.yml - when: ansible_facts.distribution_major_version | int < 9 + when: not interfaces_use_networkmanager - include_tasks: network-manager.yml - when: ansible_facts.distribution_major_version | int >= 9 + when: interfaces_use_networkmanager diff --git a/ansible/seed-host-configure.yml b/ansible/seed-host-configure.yml index 4a89f4f09..b41344eae 100644 --- a/ansible/seed-host-configure.yml +++ b/ansible/seed-host-configure.yml @@ -9,7 +9,7 @@ - import_playbook: "wipe-disks.yml" - import_playbook: "users.yml" - import_playbook: "dev-tools.yml" -- import_playbook: "disable-selinux.yml" +- import_playbook: "selinux.yml" - import_playbook: "network.yml" - import_playbook: "firewall.yml" - import_playbook: "tuned.yml" diff --git a/ansible/seed-introspection-rules.yml b/ansible/seed-introspection-rules.yml index f59655af6..21b31aeee 100644 --- a/ansible/seed-introspection-rules.yml +++ b/ansible/seed-introspection-rules.yml @@ -17,3 +17,4 @@ inspector_rule_var_lldp_switch_port_interface: "{{ kolla_bifrost_inspector_lldp_switch_port_interface }}" inspector_rule_var_deploy_kernel: "{{ kolla_bifrost_inspector_deploy_kernel }}" inspector_rule_var_deploy_ramdisk: "{{ kolla_bifrost_inspector_deploy_ramdisk }}" + inspector_rule_var_legacy_deploy_kernel: "{{ kolla_bifrost_inspector_legacy_deploy_kernel }}" diff --git a/ansible/selinux.yml b/ansible/selinux.yml new file mode 100644 index 000000000..3ffb2e45e --- /dev/null +++ b/ansible/selinux.yml @@ -0,0 +1,9 @@ +--- +- name: Configure SELinux state and reboot if required + hosts: seed:overcloud:infra-vms + tags: + - selinux + roles: + - role: selinux + selinux_reboot_timeout: "{{ disable_selinux_reboot_timeout | default(600 if ansible_facts.virtualization_role == 'host' else 300) }}" + when: ansible_facts.os_family == 'RedHat' diff --git a/dev/functions b/dev/functions index fe353e510..e51fdffec 100644 --- a/dev/functions +++ b/dev/functions @@ -232,18 +232,23 @@ function upgrade_kayobe_venv { # Deployment function is_deploy_image_built_locally { - ipa_build_images=$(kayobe configuration dump --host controllers[0] --var-name ipa_build_images) - [[ $ipa_build_images =~ ^true$ ]] + ipa_build_images=$(kayobe configuration dump --host localhost --var-name ipa_build_images) + to_bool "$ipa_build_images" } function is_ironic_enabled { - ironic_enabled=$(kayobe configuration dump --host controllers[0] --var-name kolla_enable_ironic) - [[ $ironic_enabled =~ ^true$ ]] + ironic_enabled=$(kayobe configuration dump --host localhost --var-name kolla_enable_ironic) + to_bool "$ironic_enabled" } function is_overcloud_host_image_built_by_dib { - overcloud_dib_build_host_images=$(kayobe configuration dump --host controllers[0] --var-name overcloud_dib_build_host_images) - [[ $overcloud_dib_build_host_images =~ ^true$ ]] + overcloud_dib_build_host_images=$(kayobe configuration dump --host localhost --var-name overcloud_dib_build_host_images) + to_bool "$overcloud_dib_build_host_images" +} + +function is_cinder_enabled { + flag="$(run_kayobe configuration dump --host localhost --var-name kolla_enable_cinder)" + to_bool "$flag" } function environment_setup { @@ -862,11 +867,6 @@ function to_bool { fi } -function is_cinder_enabled { - flag="$(run_kayobe configuration dump --host controllers[0] --var-name kolla_enable_cinder)" - to_bool "$flag" -} - function configure_iptables { # NOTE(wszumski): adapted from the ironic devstack plugin, see: # https://github.com/openstack/ironic/blob/36e87dc5b472d79470b783fbba9ce396e3cbb96e/devstack/lib/ironic#L2132 diff --git a/doc/source/configuration/reference/hosts.rst b/doc/source/configuration/reference/hosts.rst index 0140979d6..9d2e1e030 100644 --- a/doc/source/configuration/reference/hosts.rst +++ b/doc/source/configuration/reference/hosts.rst @@ -442,6 +442,39 @@ that is signed by the key. components: all signed_by: example-key.asc +Apt auth configuration +---------------------- + +Some repositories may require authentication using HTTP basic auth. Apt +supports specifying credentials in URLs in ``sources.list`` files, but these +files must be world-readable. A more secure setup involves writing credentials +to `auth.conf +`__ +files which can have more restrictive permissions. + +Auth configuration is defined by the ``apt_auth`` variable. The format is a +list, with each item mapping to a dict/map with the following items: + +* ``machine``: ``machine`` entry in the auth file +* ``login``: ``machine`` entry in the auth file +* ``password``: ``machine`` entry in the auth file +* ``filename``: Name of a file in ``/etc/apt/auth.conf.d`` in which to store + the auth configuration. The extension should be ``.conf``. + +The default value of ``apt_auth`` is an empty list. + +In the following example, credentials are provided for package repositories at +apt.example.com. + +.. code-block:: yaml + :caption: ``apt.yml`` + + apt_auth: + - machine: apt.example.com + login: my-username + password: my-password + filename: example.conf + Development tools ================= *tags:* @@ -479,15 +512,16 @@ package is added to all ``overcloud`` hosts: SELinux ======= *tags:* - | ``disable-selinux`` + | ``selinux`` .. note:: SELinux applies to CentOS and Rocky systems only. -SELinux is not supported by Kolla Ansible currently, so it is disabled by -Kayobe. If necessary, Kayobe will reboot systems in order to apply a change to +SELinux is not supported by Kolla Ansible currently, so it is set to permissive +by Kayobe. If necessary, it can be configured to disabled by setting +``selinux_state`` to ``disabled``. Kayobe will reboot systems when required for the SELinux configuration. The timeout for waiting for systems to reboot is -``disable_selinux_reboot_timeout``. Alternatively, the reboot may be avoided by -setting ``disable_selinux_do_reboot`` to ``false``. +``selinux_reboot_timeout``. Alternatively, the reboot may be avoided by setting +``selinux_do_reboot`` to ``false``. Network Configuration ===================== diff --git a/doc/source/configuration/reference/kolla-ansible.rst b/doc/source/configuration/reference/kolla-ansible.rst index 97c0a108b..f8c387ce1 100644 --- a/doc/source/configuration/reference/kolla-ansible.rst +++ b/doc/source/configuration/reference/kolla-ansible.rst @@ -268,10 +268,6 @@ The following variables affect TLS encryption of the public API. A TLS certificate bundle to use for the public API endpoints, if ``kolla_enable_tls_external`` is ``true``. Note that this should be formatted as a literal style block scalar. -``kolla_external_fqdn_cacert`` - Path to a CA certificate file to use for the ``OS_CACERT`` environment - variable in openrc files when TLS is enabled, instead of Kolla Ansible's - default. The following variables affect TLS encryption of the internal API. Currently this requires all Kolla images to be built with the API's root CA trusted. @@ -282,10 +278,18 @@ this requires all Kolla images to be built with the API's root CA trusted. A TLS certificate bundle to use for the internal API endpoints, if ``kolla_enable_tls_internal`` is ``true``. Note that this should be formatted as a literal style block scalar. -``kolla_internal_fqdn_cacert`` + +The following variables affect the generated ``admin-openrc.sh`` and +``public-openrc.sh`` environment files. + +``kolla_public_openrc_cacert`` + Path to a CA certificate file to use for the ``OS_CACERT`` environment + variable in the ``public-openrc.sh`` file when TLS is enabled, instead of + ``kolla_admin_openrc_cacert``. +``kolla_admin_openrc_cacert`` Path to a CA certificate file to use for the ``OS_CACERT`` environment - variable in openrc files when TLS is enabled, instead of Kolla Ansible's - default. + variable in the ``admin-openrc.sh`` and ``public-openrc.sh`` files when TLS + is enabled, instead of Kolla Ansible's default. Example: enabling TLS for the public API ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -302,7 +306,7 @@ Here is an example: -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- - kolla_external_fqdn_cacert: /path/to/ca/certificate/bundle + kolla_admin_openrc_cacert: /path/to/ca/certificate/bundle Example: enabling TLS for the internal API ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -319,7 +323,7 @@ Here is an example: -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- - kolla_internal_fqdn_cacert: /path/to/ca/certificate/bundle + kolla_admin_openrc_cacert: /path/to/ca/certificate/bundle Other certificates ------------------ @@ -592,27 +596,35 @@ variable, if present. The file is generated to ``$KAYOBE_CONFIG_PATH/kolla/passwords.yml``, and should be stored along with other Kayobe configuration files. This file should not be manually modified. -``kolla_ansible_custom_passwords`` - Dictionary containing custom passwords to add or override in the Kolla - passwords file. Default is ``{{ kolla_ansible_default_custom_passwords - }}``, which contains SSH keys for use by Kolla Ansible and Bifrost. - Configuring Custom Passwords ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In order to write additional passwords to ``passwords.yml``, set the kayobe -variable ``kolla_ansible_custom_passwords`` in -``$KAYOBE_CONFIG_PATH/kolla.yml``. +The following variables are used to configure custom passwords: + +* ``kolla_ansible_default_custom_passwords``: Dictionary containing default + custom passwords, required by Kolla Ansible. Contains SSH keys authorized by + kolla user on Kolla hosts, SSH keys authorized in hosts deployed by Bifrost, + Docker Registry password and compute libVirt custom passwords. +* ``kolla_ansible_extra_custom_passwords``: Dictionary containing extra custom + passwords to add or override in the Kolla passwords file. Default is an empty + dictionary. +* ``kolla_ansible_custom_passwords``: Dictionary containing custom passwords to + add or override in the Kolla passwords file. Default is the combination of + the ``kolla_ansible_default_custom_passwords`` and + ``kolla_ansible_extra_custom_passwords``. + +In this example we add our own ``my_custom_password`` and override +``keystone_admin_password``: .. code-block:: yaml :caption: ``$KAYOBE_CONFIG_PATH/kolla.yml`` --- - # Dictionary containing custom passwords to add or override in the Kolla - # passwords file. - kolla_ansible_custom_passwords: > - {{ kolla_ansible_default_custom_passwords | - combine({'my_custom_password': 'correcthorsebatterystaple'}) }} + # Dictionary containing extra custom passwords to add or override in the + # Kolla passwords file. + kolla_ansible_extra_custom_passwords: + my_custom_password: 'correcthorsebatterystaple' + keystone_admin_password: 'superduperstrongpassword' Control Plane Services ====================== diff --git a/doc/source/configuration/reference/seed-custom-containers.rst b/doc/source/configuration/reference/seed-custom-containers.rst index 4d4ef8e11..5b3e03cdd 100644 --- a/doc/source/configuration/reference/seed-custom-containers.rst +++ b/doc/source/configuration/reference/seed-custom-containers.rst @@ -60,3 +60,26 @@ List of Kayobe applied defaults to required docker_container variables: .. literalinclude:: ../../../../ansible/roles/deploy-containers/defaults/main.yml :language: yaml + +Docker registry +=============== + +Seed containers can be pulled from a docker registry deployed on the seed, +since the docker registry deployment step precedes the custom container +deployment step. + +It is also possible to deploy a custom containerised docker registry as a +custom seed container. In this case, basic authentication login attempts can be +disabled by setting + +.. code-block:: yaml + :caption: ``seed.yml`` + + seed_deploy_containers_registry_attempt_login: false + +Without this setting, the login will fail because the registry has not yet been +deployed. + +More information on deploying a docker registry can be found :ref:`here +`. + diff --git a/doc/source/configuration/scenarios/all-in-one/overcloud.rst b/doc/source/configuration/scenarios/all-in-one/overcloud.rst index 5e3b68eca..2992877ab 100644 --- a/doc/source/configuration/scenarios/all-in-one/overcloud.rst +++ b/doc/source/configuration/scenarios/all-in-one/overcloud.rst @@ -230,16 +230,16 @@ seen in MAAS): controller_bootstrap_user: "cloud-user" -By default, on systems with SELinux enabled, Kayobe will disable SELinux and -reboot the system to apply the change. In a test or development environment -this can be a bit disruptive, particularly when using ephemeral network -configuration. To avoid rebooting the system after disabling SELinux, set -``disable_selinux_do_reboot`` to ``false`` in ``etc/kayobe/globals.yml``. +By default, on systems with SELinux disabled, Kayobe will put SELinux in +permissive mode and reboot the system to apply the change. In a test or +development environment this can be a bit disruptive, particularly when using +ephemeral network configuration. To avoid rebooting the system after enabling +SELinux, set ``selinux_do_reboot`` to ``false`` in ``etc/kayobe/globals.yml``. .. code-block:: yaml :caption: ``etc/kayobe/globals.yml`` - disable_selinux_do_reboot: false + selinux_do_reboot: false In a development environment, we may wish to tune some Kolla Ansible variables. Using QEMU as the virtualisation type will be necessary if KVM is not diff --git a/doc/source/contributor/automated.rst b/doc/source/contributor/automated.rst index c0e7cc657..4383f0556 100644 --- a/doc/source/contributor/automated.rst +++ b/doc/source/contributor/automated.rst @@ -81,6 +81,30 @@ This can be added using the following commands:: sudo ip l set eth1 up sudo ip l set eth1 master breth1 +Configuration +------------- + +Enable TLS +^^^^^^^^^^ + +Apply the following configuration if you wish to enable TLS for the OpenStack +API: + +Set the following option in ``config/src/kayobe-config/etc/kayobe/kolla.yml``: + +.. code-block:: yaml + + kolla_enable_tls_internal: "yes" + +Set the following options in +``config/src/kayobe-config/etc/kayobe/kolla/globals.yml``: + +.. code-block:: yaml + + kolla_copy_ca_into_containers: "yes" + openstack_cacert: "{% if os_distribution == 'ubuntu' %}/etc/ssl/certs/ca-certificates.crt{% else %}/etc/pki/tls/certs/ca-bundle.crt{% endif %}" + kolla_admin_openrc_cacert: "{% if os_distribution == 'ubuntu' %}/etc/ssl/certs/ca-certificates.crt{% else %}/etc/pki/tls/certs/ca-bundle.crt{% endif %}" + Usage ----- @@ -101,6 +125,10 @@ its dependencies in a Python virtual environment:: changes will not been seen until you reinstall the package. To do this you can run ``./dev/install.sh``. +If you are using TLS and wish to generate self-signed certificates:: + + export KAYOBE_OVERCLOUD_GENERATE_CERTIFICATES=1 + Run the ``dev/overcloud-deploy.sh`` script to deploy the OpenStack control plane:: diff --git a/doc/source/deployment.rst b/doc/source/deployment.rst index fc70b587d..91cd967fd 100644 --- a/doc/source/deployment.rst +++ b/doc/source/deployment.rst @@ -534,6 +534,12 @@ image name regular expressions:: (kayobe) $ kayobe overcloud container image build ironic- nova-api +When your environment uses OVN, OVS images will not be built. If you want to +build all Neutron images at the same time, extra variable ``kolla_build_neutron_ovs`` +needs to be set to ``true``:: + + (kayobe) $ kayobe overcloud container image build -e kolla_build_neutron_ovs=true + In order to push images to a registry after they are built, add the ``--push`` argument. diff --git a/doc/source/installation.rst b/doc/source/installation.rst index fcb260016..a3082e9ae 100644 --- a/doc/source/installation.rst +++ b/doc/source/installation.rst @@ -160,7 +160,7 @@ Editable source installation ---------------------------- From Kayobe 5.0.0 onwards it is possible to create an `editable install -`__ +`__ of Kayobe. In an editable install, any changes to the Kayobe source tree will immediately be visible when running any Kayobe commands. To create an editable install, add the ``-e`` flag:: diff --git a/etc/kayobe/apt.yml b/etc/kayobe/apt.yml index 34bfdd2ef..b43ca9c08 100644 --- a/etc/kayobe/apt.yml +++ b/etc/kayobe/apt.yml @@ -46,6 +46,17 @@ # Default is false. #apt_disable_sources_list: +# List of Apt auth configurations. Each item is a dict with the following keys: +# * machine: 'machine' entry in the auth file +# * login: 'login' entry in the auth file +# * password: 'password' entry in the auth file +# * filename: Name of a file in which to store the auth configuration. The +# extension should be '.conf'. +# * filename: Name of a file in /etc/apt/auth.conf.d in which to store +# the auth configuration. The extension should be ``.conf``. +# Default is an empty list. +#apt_auth: + ############################################################################### # Dummy variable to allow Ansible to accept this file. workaround_ansible_issue_8743: yes diff --git a/etc/kayobe/bifrost.yml b/etc/kayobe/bifrost.yml index a9eba19dd..d15d18613 100644 --- a/etc/kayobe/bifrost.yml +++ b/etc/kayobe/bifrost.yml @@ -116,6 +116,9 @@ # Ironic inspector deployment ramdisk location. #kolla_bifrost_inspector_deploy_ramdisk: +# Ironic inspector legacy deployment kernel location. +#kolla_bifrost_inspector_legacy_deploy_kernel: + # Timeout of hardware inspection on overcloud nodes, in seconds. Default is # {{ inspector_inspection_timeout }}. #kolla_bifrost_inspection_timeout: diff --git a/etc/kayobe/infra-vms.yml b/etc/kayobe/infra-vms.yml index c6efae735..069c0877c 100644 --- a/etc/kayobe/infra-vms.yml +++ b/etc/kayobe/infra-vms.yml @@ -37,7 +37,7 @@ # or # https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2 # when os_distribution is "rocky" and os_release is "9" -# "https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20220913.0.x86_64.qcow2" +# "https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2" # otherwise. #infra_vm_root_image: diff --git a/etc/kayobe/kolla.yml b/etc/kayobe/kolla.yml index 6c4dc7f28..dc52eb253 100644 --- a/etc/kayobe/kolla.yml +++ b/etc/kayobe/kolla.yml @@ -299,6 +299,7 @@ #kolla_enable_gnocchi: #kolla_enable_gnocchi_statsd: #kolla_enable_grafana: +#kolla_enable_grafana_external: #kolla_enable_hacluster: #kolla_enable_haproxy: #kolla_enable_haproxy_memcached: @@ -338,6 +339,7 @@ #kolla_enable_keystone_federation: #kolla_enable_keystone_horizon_policy_file: #kolla_enable_kibana: +#kolla_enable_kibana_external: #kolla_enable_kuryr: #kolla_enable_loadbalancer: #kolla_enable_magnum: @@ -350,6 +352,8 @@ #kolla_enable_mariabackup: #kolla_enable_mariadb: #kolla_enable_masakari: +#kolla_enable_masakari_hostmonitor: +#kolla_enable_masakari_instancemonitor: #kolla_enable_memcached: #kolla_enable_mistral: #kolla_enable_monasca: @@ -392,6 +396,7 @@ #kolla_enable_placement: #kolla_enable_prometheus: #kolla_enable_prometheus_alertmanager: +#kolla_enable_prometheus_alertmanager_external: #kolla_enable_prometheus_blackbox_exporter: #kolla_enable_prometheus_cadvisor: #kolla_enable_prometheus_ceph_mgr_exporter: @@ -401,6 +406,7 @@ #kolla_enable_prometheus_haproxy_exporter: #kolla_enable_prometheus_libvirt_exporter: #kolla_enable_prometheus_memcached_exporter: +#kolla_enable_prometheus_msteams: #kolla_enable_prometheus_mysqld_exporter: #kolla_enable_prometheus_node_exporter: #kolla_enable_prometheus_openstack_exporter: @@ -507,6 +513,10 @@ # Kolla passwords file. #kolla_ansible_default_custom_passwords: +# Dictionary containing extra custom passwords to add or override in the Kolla +# passwords file. +#kolla_ansible_extra_custom_passwords: + # Dictionary containing custom passwords to add or override in the Kolla # passwords file. #kolla_ansible_custom_passwords: @@ -546,7 +556,7 @@ # Path to a CA certificate file to use for the OS_CACERT environment variable # in public-openrc.sh file when TLS is enabled, instead of Kolla-Ansible's # default. -#kolla_external_fqdn_cacert: +#kolla_public_openrc_cacert: # Internal API certificate bundle. # @@ -559,7 +569,7 @@ # Path to a CA certificate file to use for the OS_CACERT environment variable # in admin-openrc.sh file when TLS is enabled, instead of Kolla-Ansible's # default. -#kolla_internal_fqdn_cacert: +#kolla_admin_openrc_cacert: ############################################################################### # Proxy configuration diff --git a/etc/kayobe/seed-vm.yml b/etc/kayobe/seed-vm.yml index 5209b1b38..24122b033 100644 --- a/etc/kayobe/seed-vm.yml +++ b/etc/kayobe/seed-vm.yml @@ -31,7 +31,7 @@ # or # https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2 # when os_distribution is "rocky" and os_release is "9" -# "https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20220913.0.x86_64.qcow2" +# "https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2" # otherwise. #seed_vm_root_image: diff --git a/etc/kayobe/seed.yml b/etc/kayobe/seed.yml index f7cacab42..bc86fa627 100644 --- a/etc/kayobe/seed.yml +++ b/etc/kayobe/seed.yml @@ -106,6 +106,10 @@ # #seed_containers: +# Whether to attempt a basic authentication login to a registry when +# deploying seed containers +#seed_deploy_containers_registry_attempt_login: + ############################################################################### # Seed node firewalld configuration. diff --git a/kayobe/ansible.py b/kayobe/ansible.py index e73d25bfb..0b7579eef 100644 --- a/kayobe/ansible.py +++ b/kayobe/ansible.py @@ -21,6 +21,8 @@ import sys import tempfile +from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode + from kayobe import exception from kayobe import utils from kayobe import vault @@ -261,6 +263,18 @@ def run_playbook(parsed_args, playbook, *args, **kwargs): return run_playbooks(parsed_args, [playbook], *args, **kwargs) +def _sanitise_hostvar(var): + """Sanitise a host variable.""" + if isinstance(var, AnsibleVaultEncryptedUnicode): + return "******" + # Recursively sanitise dicts and lists. + if isinstance(var, dict): + return {k: _sanitise_hostvar(v) for k, v in var.items()} + if isinstance(var, list): + return [_sanitise_hostvar(v) for v in var] + return var + + def config_dump(parsed_args, host=None, hosts=None, var_name=None, facts=None, extra_vars=None, tags=None, verbose_level=None): dump_dir = tempfile.mkdtemp() @@ -286,7 +300,8 @@ def config_dump(parsed_args, host=None, hosts=None, var_name=None, LOG.debug("Found dump file %s", path) inventory_hostname, ext = os.path.splitext(path) if ext == ".yml": - hvars = utils.read_yaml_file(os.path.join(dump_dir, path)) + dump_file = os.path.join(dump_dir, path) + hvars = utils.read_config_dump_yaml_file(dump_file) if host: return hvars else: @@ -294,7 +309,7 @@ def config_dump(parsed_args, host=None, hosts=None, var_name=None, else: LOG.warning("Unexpected extension on config dump file %s", path) - return hostvars + return {k: _sanitise_hostvar(v) for k, v in hostvars.items()} finally: shutil.rmtree(dump_dir) diff --git a/kayobe/cli/commands.py b/kayobe/cli/commands.py index 0898dd11a..ffb2f02c2 100644 --- a/kayobe/cli/commands.py +++ b/kayobe/cli/commands.py @@ -105,15 +105,15 @@ def generate_kolla_ansible_config(self, parsed_args, install=False, tags = None if install else "config" playbooks = _build_playbook_list("kolla-ansible") self.run_kayobe_playbooks(parsed_args, playbooks, tags=tags, - ignore_limit=True) + ignore_limit=True, check=False) if service_config: playbooks = _build_playbook_list("kolla-openstack") self.run_kayobe_playbooks(parsed_args, playbooks, - ignore_limit=True) + ignore_limit=True, check=False) if bifrost_config: playbooks = _build_playbook_list("kolla-bifrost") self.run_kayobe_playbooks(parsed_args, playbooks, - ignore_limit=True) + ignore_limit=True, check=False) class KollaAnsibleMixin(object): @@ -254,7 +254,7 @@ def take_action(self, parsed_args): ka_tags = "install" playbooks = _build_playbook_list("kolla-ansible") self.run_kayobe_playbooks(parsed_args, playbooks, tags=ka_tags, - ignore_limit=True) + ignore_limit=True, check=False) if passwords_exist: # If we are bootstrapping a control host for an existing @@ -289,7 +289,7 @@ def take_action(self, parsed_args): self.run_kayobe_playbooks(parsed_args, playbooks, ignore_limit=True) playbooks = _build_playbook_list("kolla-ansible") self.run_kayobe_playbooks(parsed_args, playbooks, tags="install", - ignore_limit=True) + ignore_limit=True, check=False) class ConfigurationDump(KayobeAnsibleMixin, VaultMixin, Command): @@ -571,7 +571,7 @@ class SeedHostConfigure(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin, * Optionally, create a virtualenv for remote target hosts. * Optionally, wipe unmounted disk partitions (--wipe-disks). * Configure user accounts, group associations, and authorised SSH keys. - * Disable SELinux. + * Configure SELinux. * Configure the host's network interfaces. * Configure a firewall. * Configure tuned profile. @@ -878,7 +878,7 @@ class InfraVMHostConfigure(KayobeAnsibleMixin, VaultMixin, * Optionally, create a virtualenv for remote target hosts. * Optionally, wipe unmounted disk partitions (--wipe-disks). * Configure user accounts, group associations, and authorised SSH keys. - * Disable SELinux. + * Configure SELinux. * Configure the host's network interfaces. * Configure a firewall. * Configure tuned profile. @@ -1092,7 +1092,8 @@ class OvercloudDeprovision(KayobeAnsibleMixin, VaultMixin, Command): def take_action(self, parsed_args): self.app.LOG.debug("Deprovisioning overcloud") - playbooks = _build_playbook_list("overcloud-deprovision") + playbooks = _build_playbook_list("kolla-bifrost-hostvars", + "overcloud-deprovision") self.run_kayobe_playbooks(parsed_args, playbooks) @@ -1125,7 +1126,7 @@ class OvercloudHostConfigure(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin, * Optionally, create a virtualenv for remote target hosts. * Optionally, wipe unmounted disk partitions (--wipe-disks). * Configure user accounts, group associations, and authorised SSH keys. - * Disable SELinux. + * Configure SELinux. * Configure the host's network interfaces. * Configure a firewall. * Configure tuned profile. diff --git a/kayobe/plugins/filter/networks.py b/kayobe/plugins/filter/networks.py index 9af4b9dd9..58dbaf9e0 100644 --- a/kayobe/plugins/filter/networks.py +++ b/kayobe/plugins/filter/networks.py @@ -380,7 +380,7 @@ def _validate_rules(rules): @jinja2.pass_context -def net_interface_obj(context, name, inventory_hostname=None): +def net_interface_obj(context, name, inventory_hostname=None, names=None): """Return a dict representation of a network interface. The returned dict is compatible with the interfaces_ether_interfaces @@ -400,6 +400,27 @@ def net_interface_obj(context, name, inventory_hostname=None): netmask = None vlan = net_vlan(context, name, inventory_hostname) mtu = net_mtu(context, name, inventory_hostname) + + # NOTE(priteau): do not pass MTU for VLAN interfaces on bridges when it is + # identical to the parent bridge, to work around a NetworkManager bug. + if names is not None and net_is_vlan_interface(context, name, + inventory_hostname): + # Make a mapping of bridge interfaces and their MTUs + bridge_mtus = {} + for bridge in net_select_bridges(context, names, inventory_hostname): + bridge_interface = net_interface(context, bridge, + inventory_hostname) + bridge_mtus[bridge_interface] = net_mtu(context, bridge, + inventory_hostname) + + # Get parent and check for its MTU if it is a bridge + parent_or_device = get_vlan_parent( + context, name, device, vlan, inventory_hostname) + if parent_or_device in bridge_mtus: + parent_mtu = bridge_mtus[parent_or_device] + if mtu == parent_mtu: + mtu = None + routes = net_routes(context, name, inventory_hostname) if routes: routes = [_route_obj(route) for route in routes] diff --git a/kayobe/tests/unit/cli/test_commands.py b/kayobe/tests/unit/cli/test_commands.py index 87da04a9b..acf5f4cbc 100644 --- a/kayobe/tests/unit/cli/test_commands.py +++ b/kayobe/tests/unit/cli/test_commands.py @@ -60,7 +60,8 @@ def test_control_host_bootstrap(self, mock_run, mock_passwords, mock.ANY, [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="install", - ignore_limit=True + ignore_limit=True, + check=False, ), ] self.assertEqual(expected_calls, mock_run.call_args_list) @@ -93,7 +94,8 @@ def test_control_host_bootstrap_with_passwords( mock.ANY, [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags=None, - ignore_limit=True + ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -138,7 +140,8 @@ def test_control_host_upgrade(self, mock_run, mock_prune, mock.ANY, [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="install", - ignore_limit=True + ignore_limit=True, + check=False, ), ] self.assertEqual(expected_calls, mock_run.call_args_list) @@ -509,6 +512,7 @@ def test_seed_host_configure(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="config", ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -569,6 +573,7 @@ def test_seed_host_configure_wipe_disks(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="config", ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -872,11 +877,13 @@ def test_seed_service_deploy(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="config", ignore_limit=True, + check=False, ), mock.call( mock.ANY, [utils.get_data_files_path("ansible", "kolla-bifrost.yml")], ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -922,11 +929,13 @@ def test_seed_service_upgrade(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="config", ignore_limit=True, + check=False, ), mock.call( mock.ANY, [utils.get_data_files_path("ansible", "kolla-bifrost.yml")], ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -1181,6 +1190,7 @@ def test_overcloud_inventory_discover(self, mock_run_one, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="config", ignore_limit=True, + check=False, ), ] self.assertEqual(expected_calls, mock_run.call_args_list) @@ -1245,6 +1255,8 @@ def test_overcloud_deprovision(self, mock_run): mock.call( mock.ANY, [ + utils.get_data_files_path( + "ansible", "kolla-bifrost-hostvars.yml"), utils.get_data_files_path( "ansible", "overcloud-deprovision.yml"), ], @@ -1277,6 +1289,7 @@ def test_overcloud_facts_gather(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="config", ignore_limit=True, + check=False, ), ] self.assertEqual(expected_calls, mock_run.call_args_list) @@ -1320,6 +1333,7 @@ def test_overcloud_host_configure(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="config", ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -1376,6 +1390,7 @@ def test_overcloud_host_configure_wipe_disks(self, mock_kolla_run, [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="config", ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -1542,6 +1557,7 @@ def test_overcloud_database_backup(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="config", ignore_limit=True, + check=False, ), ] self.assertEqual(expected_calls, mock_run.call_args_list) @@ -1573,6 +1589,7 @@ def test_overcloud_database_backup_incremental(self, mock_kolla_run, [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="config", ignore_limit=True, + check=False, ), ] self.assertEqual(expected_calls, mock_run.call_args_list) @@ -1603,6 +1620,7 @@ def test_overcloud_database_recover(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="config", ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -1611,6 +1629,7 @@ def test_overcloud_database_recover(self, mock_kolla_run, mock_run): "kolla-openstack.yml"), ], ignore_limit=True, + check=False, ), ] self.assertEqual(expected_calls, mock_run.call_args_list) @@ -1642,6 +1661,7 @@ def test_overcloud_database_recover_force_host(self, mock_kolla_run, [utils.get_data_files_path("ansible", "kolla-ansible.yml")], tags="config", ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -1650,6 +1670,7 @@ def test_overcloud_database_recover_force_host(self, mock_kolla_run, "kolla-openstack.yml"), ], ignore_limit=True, + check=False, ), ] self.assertEqual(expected_calls, mock_run.call_args_list) @@ -1703,6 +1724,7 @@ def test_overcloud_service_deploy(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], ignore_limit=True, tags="config", + check=False, ), mock.call( mock.ANY, @@ -1711,6 +1733,7 @@ def test_overcloud_service_deploy(self, mock_kolla_run, mock_run): "kolla-openstack.yml"), ], ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -1768,6 +1791,7 @@ def test_overcloud_service_deploy_containers(self, mock_kolla_run, [utils.get_data_files_path("ansible", "kolla-ansible.yml")], ignore_limit=True, tags="config", + check=False, ), mock.call( mock.ANY, @@ -1776,6 +1800,7 @@ def test_overcloud_service_deploy_containers(self, mock_kolla_run, "kolla-openstack.yml"), ], ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -1821,6 +1846,7 @@ def test_overcloud_service_prechecks(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], ignore_limit=True, tags="config", + check=False, ), mock.call( mock.ANY, @@ -1829,6 +1855,7 @@ def test_overcloud_service_prechecks(self, mock_kolla_run, mock_run): "kolla-openstack.yml"), ], ignore_limit=True, + check=False, ), ] self.assertEqual(expected_calls, mock_run.call_args_list) @@ -1859,6 +1886,7 @@ def test_overcloud_service_reconfigure(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], ignore_limit=True, tags="config", + check=False, ), mock.call( mock.ANY, @@ -1867,6 +1895,7 @@ def test_overcloud_service_reconfigure(self, mock_kolla_run, mock_run): "kolla-openstack.yml"), ], ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -1923,6 +1952,7 @@ def test_overcloud_service_stop(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], ignore_limit=True, tags="config", + check=False, ), mock.call( mock.ANY, @@ -1931,6 +1961,7 @@ def test_overcloud_service_stop(self, mock_kolla_run, mock_run): "kolla-openstack.yml"), ], ignore_limit=True, + check=False, ), mock.call( mock.ANY, @@ -1987,6 +2018,7 @@ def test_overcloud_service_upgrade(self, mock_kolla_run, mock_run): [utils.get_data_files_path("ansible", "kolla-ansible.yml")], ignore_limit=True, tags=None, + check=False, ), mock.call( mock.ANY, @@ -1995,6 +2027,7 @@ def test_overcloud_service_upgrade(self, mock_kolla_run, mock_run): "kolla-openstack.yml"), ], ignore_limit=True, + check=False, ), mock.call( mock.ANY, diff --git a/kayobe/tests/unit/test_ansible.py b/kayobe/tests/unit/test_ansible.py index 54ccb4cf0..3d07eda91 100644 --- a/kayobe/tests/unit/test_ansible.py +++ b/kayobe/tests/unit/test_ansible.py @@ -450,7 +450,7 @@ def test_run_playbooks_failure(self, mock_validate, mock_vars, mock_run): ansible.run_playbooks, parsed_args, ["command"]) @mock.patch.object(shutil, 'rmtree') - @mock.patch.object(utils, 'read_yaml_file') + @mock.patch.object(utils, 'read_config_dump_yaml_file') @mock.patch.object(os, 'listdir') @mock.patch.object(ansible, 'run_playbook') @mock.patch.object(tempfile, 'mkdtemp') @@ -488,6 +488,70 @@ def test_config_dump(self, mock_mkdtemp, mock_run, mock_listdir, mock_read, mock.call(os.path.join(dump_dir, "host2.yml")), ]) + @mock.patch.object(shutil, 'rmtree') + @mock.patch.object(utils, 'read_file') + @mock.patch.object(os, 'listdir') + @mock.patch.object(ansible, 'run_playbook') + @mock.patch.object(tempfile, 'mkdtemp') + def test_config_dump_vaulted(self, mock_mkdtemp, mock_run, mock_listdir, + mock_read, mock_rmtree): + parser = argparse.ArgumentParser() + parsed_args = parser.parse_args([]) + dump_dir = "/path/to/dump" + mock_mkdtemp.return_value = dump_dir + mock_listdir.return_value = ["host1.yml", "host2.yml"] + config = """--- +key1: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 633230623736383232323862393364323037343430393530316636363961626361393133646437 + 643438663261356433656365646138666133383032376532310a63323432306431303437623637 + 346236316161343635636230613838316566383933313338636237616338326439616536316639 + 6334343462333062363334300a3930313762313463613537626531313230303731343365643766 + 666436333037 +key2: value2 +key3: + - !vault | + $ANSIBLE_VAULT;1.1;AES256 + 633230623736383232323862393364323037343430393530316636363961626361393133646437 + 643438663261356433656365646138666133383032376532310a63323432306431303437623637 + 346236316161343635636230613838316566383933313338636237616338326439616536316639 + 6334343462333062363334300a3930313762313463613537626531313230303731343365643766 + 666436333037 +""" + config_nested = """--- +key1: + key2: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 633230623736383232323862393364323037343430393530316636363961626361393133646437 + 643438663261356433656365646138666133383032376532310a63323432306431303437623637 + 346236316161343635636230613838316566383933313338636237616338326439616536316639 + 6334343462333062363334300a3930313762313463613537626531313230303731343365643766 + 666436333037 +""" + mock_read.side_effect = [config, config_nested] + result = ansible.config_dump(parsed_args) + expected_result = { + "host1": {"key1": "******", "key2": "value2", "key3": ["******"]}, + "host2": {"key1": {"key2": "******"}}, + } + self.assertEqual(result, expected_result) + dump_config_path = utils.get_data_files_path( + "ansible", "dump-config.yml") + mock_run.assert_called_once_with(parsed_args, + dump_config_path, + extra_vars={ + "dump_path": dump_dir, + }, + check_output=True, tags=None, + verbose_level=None, check=False, + list_tasks=False, diff=False) + mock_rmtree.assert_called_once_with(dump_dir) + mock_listdir.assert_any_call(dump_dir) + mock_read.assert_has_calls([ + mock.call(os.path.join(dump_dir, "host1.yml")), + mock.call(os.path.join(dump_dir, "host2.yml")), + ]) + @mock.patch.object(utils, 'galaxy_role_install', autospec=True) @mock.patch.object(utils, 'is_readable_file', autospec=True) @mock.patch.object(os, 'makedirs', autospec=True) diff --git a/kayobe/tests/unit/test_utils.py b/kayobe/tests/unit/test_utils.py index 38b382e0e..962017624 100644 --- a/kayobe/tests/unit/test_utils.py +++ b/kayobe/tests/unit/test_utils.py @@ -17,6 +17,7 @@ import unittest from unittest import mock +from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode import yaml from kayobe import exception @@ -125,6 +126,59 @@ def test_read_yaml_file_not_yaml(self, mock_read): mock_read.return_value = "[1{!" self.assertRaises(SystemExit, utils.read_yaml_file, "/path/to/file") + @mock.patch.object(utils, "read_file") + def test_read_config_dump_yaml_file(self, mock_read): + config = """--- +key1: value1 +key2: value2 +""" + mock_read.return_value = config + result = utils.read_config_dump_yaml_file("/path/to/file") + self.assertEqual(result, {"key1": "value1", "key2": "value2"}) + mock_read.assert_called_once_with("/path/to/file") + + @mock.patch.object(utils, "read_file") + def test_read_config_dump_yaml_file_vaulted(self, mock_read): + config = """--- +key1: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 633230623736383232323862393364323037343430393530316636363961626361393133646437 + 643438663261356433656365646138666133383032376532310a63323432306431303437623637 + 346236316161343635636230613838316566383933313338636237616338326439616536316639 + 6334343462333062363334300a3930313762313463613537626531313230303731343365643766 + 666436333037 +key2: value2 +key3: + - !vault | + $ANSIBLE_VAULT;1.1;AES256 + 633230623736383232323862393364323037343430393530316636363961626361393133646437 + 643438663261356433656365646138666133383032376532310a63323432306431303437623637 + 346236316161343635636230613838316566383933313338636237616338326439616536316639 + 6334343462333062363334300a3930313762313463613537626531313230303731343365643766 + 666436333037 +""" + mock_read.return_value = config + result = utils.read_config_dump_yaml_file("/path/to/file") + # Can't read the value without an encryption key, so just check type. + self.assertTrue(isinstance(result["key1"], + AnsibleVaultEncryptedUnicode)) + self.assertEqual(result["key2"], "value2") + self.assertTrue(isinstance(result["key3"][0], + AnsibleVaultEncryptedUnicode)) + mock_read.assert_called_once_with("/path/to/file") + + @mock.patch.object(utils, "read_file") + def test_read_config_dump_yaml_file_open_failure(self, mock_read): + mock_read.side_effect = IOError + self.assertRaises(SystemExit, utils.read_config_dump_yaml_file, + "/path/to/file") + + @mock.patch.object(utils, "read_file") + def test_read_config_dump_yaml_file_not_yaml(self, mock_read): + mock_read.return_value = "[1{!" + self.assertRaises(SystemExit, utils.read_config_dump_yaml_file, + "/path/to/file") + @mock.patch.object(subprocess, "check_call") def test_run_command(self, mock_call): output = utils.run_command(["command", "to", "run"]) diff --git a/kayobe/utils.py b/kayobe/utils.py index adb3fbd85..2ddd8cb05 100644 --- a/kayobe/utils.py +++ b/kayobe/utils.py @@ -16,12 +16,18 @@ from collections import defaultdict import glob import graphlib +try: + from importlib.metadata import Distribution +except ImportError: # for Python<3.8 + from importlib_metadata import Distribution +import json import logging import os import shutil import subprocess import sys +from ansible.parsing.yaml.loader import AnsibleLoader import yaml from kayobe import exception @@ -50,10 +56,30 @@ def _detect_install_prefix(path): return prefix_path +def _get_direct_url(dist): + direct_url = os.path.join(dist._path, 'direct_url.json') + if os.path.isfile(direct_url): + with open(direct_url, 'r') as f: + direct_url_content = json.loads(f.readline().strip()) + url = direct_url_content['url'] + prefix = 'file://' + if url.startswith(prefix): + return url[len(prefix):] + + return None + + def _get_base_path(): override = os.environ.get("KAYOBE_DATA_FILES_PATH") if override: return os.path.join(override) + + kayobe_dist = list(Distribution.discover(name="kayobe")) + if kayobe_dist: + direct_url = _get_direct_url(kayobe_dist[0]) + if direct_url: + return direct_url + egg_glob = os.path.join( sys.prefix, 'lib*', 'python*', '*-packages', 'kayobe.egg-link' ) @@ -68,7 +94,7 @@ def _get_base_path(): return os.path.join(prefix, "share", "kayobe") # Assume uninstalled - return os.path.join(os.path.realpath(__file__), "..") + return os.path.join(os.path.dirname(os.path.realpath(__file__)), "..") def galaxy_role_install(role_file, roles_path, force=False): @@ -131,11 +157,28 @@ def read_yaml_file(path): try: content = read_file(path) except IOError as e: - print("Failed to open config dump file %s: %s" % + print("Failed to open YAML file %s: %s" % (path, repr(e))) sys.exit(1) try: return yaml.safe_load(content) + except yaml.YAMLError as e: + print("Failed to decode YAML file %s: %s" % + (path, repr(e))) + sys.exit(1) + + +def read_config_dump_yaml_file(path): + """Read and decode a configuration dump YAML file.""" + try: + content = read_file(path) + except IOError as e: + print("Failed to open config dump file %s: %s" % + (path, repr(e))) + sys.exit(1) + try: + # AnsibleLoader supports loading vault encrypted variables. + return AnsibleLoader(content).get_single_data() except yaml.YAMLError as e: print("Failed to decode config dump YAML file %s: %s" % (path, repr(e))) diff --git a/playbooks/kayobe-infra-vm-base/overrides.yml.j2 b/playbooks/kayobe-infra-vm-base/overrides.yml.j2 index 1a72eb8f6..061d7589c 100644 --- a/playbooks/kayobe-infra-vm-base/overrides.yml.j2 +++ b/playbooks/kayobe-infra-vm-base/overrides.yml.j2 @@ -1,8 +1,4 @@ --- -# NOTE(mgoddard): Don't reboot after disabling SELinux during CI testing, as -# Ansible is run directly on the controller. -disable_selinux_do_reboot: false - # Use the OpenStack infra's Dockerhub mirror. docker_registry_mirrors: - "http://{{ zuul_site_mirror_fqdn }}:8082/" diff --git a/playbooks/kayobe-overcloud-base/overrides.yml.j2 b/playbooks/kayobe-overcloud-base/overrides.yml.j2 index 67ec1a737..af12ef61e 100644 --- a/playbooks/kayobe-overcloud-base/overrides.yml.j2 +++ b/playbooks/kayobe-overcloud-base/overrides.yml.j2 @@ -1,12 +1,4 @@ --- -{% if ansible_facts.distribution_release == "jammy" %} -os_release: "jammy" -{% endif %} - -# NOTE(mgoddard): Don't reboot after disabling SELinux during CI testing, as -# Ansible is run directly on the controller. -disable_selinux_do_reboot: false - # Use the OpenStack infra's Dockerhub mirror. docker_registry_mirrors: - "http://{{ zuul_site_mirror_fqdn }}:8082/" diff --git a/playbooks/kayobe-overcloud-host-configure-base/globals.yml.j2 b/playbooks/kayobe-overcloud-host-configure-base/globals.yml.j2 new file mode 100644 index 000000000..feff57d91 --- /dev/null +++ b/playbooks/kayobe-overcloud-host-configure-base/globals.yml.j2 @@ -0,0 +1,8 @@ +--- +# Pin Docker package to latest 24.x release before devicemapper was removed +{% if ansible_facts.distribution_release == "jammy" %} +docker_apt_package: "docker-ce=5:24.0.8-1~ubuntu.22.04~jammy" +{% else %} +docker_apt_package: "docker-ce=5:24.0.8-1~ubuntu.20.04~focal" +{% endif %} +docker_yum_package: "docker-ce-24*" diff --git a/playbooks/kayobe-overcloud-host-configure-base/overrides.yml.j2 b/playbooks/kayobe-overcloud-host-configure-base/overrides.yml.j2 index 6c7258195..6269f900f 100644 --- a/playbooks/kayobe-overcloud-host-configure-base/overrides.yml.j2 +++ b/playbooks/kayobe-overcloud-host-configure-base/overrides.yml.j2 @@ -149,6 +149,11 @@ apt_repositories: components: contrib signed_by: td-agent.asc apt_disable_sources_list: true +apt_auth: + - machine: https://apt.example.com + login: foo + password: bar + filename: test.conf {% endif %} {% if ansible_facts.os_family == 'RedHat' %} diff --git a/playbooks/kayobe-overcloud-host-configure-base/pre.yml b/playbooks/kayobe-overcloud-host-configure-base/pre.yml index 60f81d549..4651d04e7 100644 --- a/playbooks/kayobe-overcloud-host-configure-base/pre.yml +++ b/playbooks/kayobe-overcloud-host-configure-base/pre.yml @@ -25,6 +25,11 @@ src: overrides.yml.j2 dest: "{{ kayobe_config_src_dir }}/etc/kayobe/zzz-overrides.yml" + - name: Ensure kolla-ansible globals.yml override config file exists + template: + src: globals.yml.j2 + dest: "{{ kayobe_config_src_dir }}/etc/kayobe/kolla/globals.yml" + # NOTE(mgoddard): Create two loopback devices backed by files. These will # be added to a software RAID volume, then added to an LVM volume group. - name: Ensure a docker storage backing file exists diff --git a/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py b/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py index eeb37b9ab..dcc5d6bd6 100644 --- a/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py +++ b/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py @@ -219,6 +219,16 @@ def test_apt_custom_package_repository_is_available(host): assert host.package("td-agent").is_installed +@pytest.mark.skipif(not _is_apt(), reason="Apt only supported on Ubuntu") +def test_apt_auth(host): + apt_auth = host.file("/etc/apt/apt.auth.d/test.conf") + assert apt_auth.exists + auth_lines = apt_auth.content_string.split() + assert "machine https://apt.example.com" in auth_lines + assert "login foo" in auth_lines + assert "password bar" in auth_lines + + @pytest.mark.parametrize('repo', ["appstream", "baseos", "extras", "epel"]) @pytest.mark.skipif(not _is_dnf_mirror(), reason="DNF OpenDev mirror only for CentOS 8") def test_dnf_local_package_mirrors(host, repo): diff --git a/playbooks/kayobe-overcloud-upgrade-base/overrides.yml.j2 b/playbooks/kayobe-overcloud-upgrade-base/overrides.yml.j2 index 5972bdfd6..a4dd3a892 100644 --- a/playbooks/kayobe-overcloud-upgrade-base/overrides.yml.j2 +++ b/playbooks/kayobe-overcloud-upgrade-base/overrides.yml.j2 @@ -1,6 +1,8 @@ --- # NOTE(mgoddard): Don't reboot after disabling SELinux during CI testing, as # Ansible is run directly on the controller. +# TODO(priteau): This is needed for the deployment of the previous release. +# Remove when previous_release is zed. disable_selinux_do_reboot: false # Use the OpenStack infra's Dockerhub mirror. diff --git a/playbooks/kayobe-seed-base/overrides.yml.j2 b/playbooks/kayobe-seed-base/overrides.yml.j2 index e3be9f7d6..817d20a94 100644 --- a/playbooks/kayobe-seed-base/overrides.yml.j2 +++ b/playbooks/kayobe-seed-base/overrides.yml.j2 @@ -1,12 +1,4 @@ --- -{% if ansible_facts.distribution_release == "jammy" %} -os_release: "jammy" -{% endif %} - -# NOTE(mgoddard): Don't reboot after disabling SELinux during CI testing, as -# Ansible is run directly on the controller. -disable_selinux_do_reboot: false - # Use the OpenStack infra's Dockerhub mirror. docker_registry_mirrors: - "http://{{ zuul_site_mirror_fqdn }}:8082/" diff --git a/playbooks/kayobe-seed-upgrade-base/overrides.yml.j2 b/playbooks/kayobe-seed-upgrade-base/overrides.yml.j2 index 4c9a94716..f378daad7 100644 --- a/playbooks/kayobe-seed-upgrade-base/overrides.yml.j2 +++ b/playbooks/kayobe-seed-upgrade-base/overrides.yml.j2 @@ -1,6 +1,8 @@ --- # NOTE(mgoddard): Don't reboot after disabling SELinux during CI testing, as # Ansible is run directly on the controller. +# TODO(priteau): This is needed for the deployment of the previous release. +# Remove when previous_release is zed. disable_selinux_do_reboot: false # Use the OpenStack infra's Dockerhub mirror. diff --git a/playbooks/kayobe-seed-vm-base/overrides.yml.j2 b/playbooks/kayobe-seed-vm-base/overrides.yml.j2 index 9c5462c73..108efb74f 100644 --- a/playbooks/kayobe-seed-vm-base/overrides.yml.j2 +++ b/playbooks/kayobe-seed-vm-base/overrides.yml.j2 @@ -1,8 +1,4 @@ --- -# NOTE(mgoddard): Don't reboot after disabling SELinux during CI testing, as -# Ansible is run directly on the controller. -disable_selinux_do_reboot: false - # Use the OpenStack infra's Dockerhub mirror. docker_registry_mirrors: - "http://{{ zuul_site_mirror_fqdn }}:8082/" diff --git a/releasenotes/notes/add_option_to_build_OVS_images_while_using_OVN-48471bbaebc953be.yaml b/releasenotes/notes/add_option_to_build_OVS_images_while_using_OVN-48471bbaebc953be.yaml new file mode 100644 index 000000000..5f03bfb91 --- /dev/null +++ b/releasenotes/notes/add_option_to_build_OVS_images_while_using_OVN-48471bbaebc953be.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Adds a new variable ``kolla_build_neutron_ovs`` which gives users to have + option to build OVS container images while the system is using OVN. + This is useful when an user wants to build all container images at the + same time. diff --git a/releasenotes/notes/apt-auth-97d0291600836dec.yaml b/releasenotes/notes/apt-auth-97d0291600836dec.yaml new file mode 100644 index 000000000..6da3d2e39 --- /dev/null +++ b/releasenotes/notes/apt-auth-97d0291600836dec.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Adds support for auth configuration for Apt respositories and proxies using + ``auth.conf`` files. diff --git a/releasenotes/notes/bifrost-host-vars-deprovision-525c450cf20f7f71.yaml b/releasenotes/notes/bifrost-host-vars-deprovision-525c450cf20f7f71.yaml new file mode 100644 index 000000000..6d229fb5f --- /dev/null +++ b/releasenotes/notes/bifrost-host-vars-deprovision-525c450cf20f7f71.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fixes failure to run ``kayobe overcloud deprovision`` after Bifrost is + redeployed. + `LP#2038889 `__ diff --git a/releasenotes/notes/check-mode-local-config-3f8a4ba231a32c1f.yaml b/releasenotes/notes/check-mode-local-config-3f8a4ba231a32c1f.yaml new file mode 100644 index 000000000..fba1aa222 --- /dev/null +++ b/releasenotes/notes/check-mode-local-config-3f8a4ba231a32c1f.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixes an issue where local configuration generation would be skipped when + running in check mode. This would lead to Kolla Ansible checking with stale + configuration. See `story 2010526 + `__ for details. diff --git a/releasenotes/notes/config-dump-vault-edc615e475f234ac.yaml b/releasenotes/notes/config-dump-vault-edc615e475f234ac.yaml new file mode 100644 index 000000000..f8e6a2fc7 --- /dev/null +++ b/releasenotes/notes/config-dump-vault-edc615e475f234ac.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixes an issue where ``kayobe configuration dump`` would fail when + variables are encrypted using Ansible Vault. Encrypted variables are now + sanitised in the dump output. `LP#2031390 + `__ diff --git a/releasenotes/notes/configdrive-gateway-62366f613e6eaac9.yaml b/releasenotes/notes/configdrive-gateway-62366f613e6eaac9.yaml new file mode 100644 index 000000000..f43684f03 --- /dev/null +++ b/releasenotes/notes/configdrive-gateway-62366f613e6eaac9.yaml @@ -0,0 +1,14 @@ +--- +upgrade: + - | + If the admin network does not have a gateway defined and + ``seed_enable_snat`` is ``false``, which is the default, overcloud hosts + will not have a default gateway immediately after provisioning anymore. A + default gateway on another network can still be applied during the host + configuration step. +fixes: + - | + Fixes slow fact gathering in some environments by not configuring the seed + host as the initial default gateway for overcloud hosts when + ``seed_enable_snat`` is ``false``, which is the default. + `LP#2039461 `__ diff --git a/releasenotes/notes/dellos10-support-ngs-24ba50803b4bf528.yaml b/releasenotes/notes/dellos10-support-ngs-24ba50803b4bf528.yaml new file mode 100644 index 000000000..a659fb322 --- /dev/null +++ b/releasenotes/notes/dellos10-support-ngs-24ba50803b4bf528.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Adds support for using DellOS 10 switches with Networking Generic Switch. diff --git a/releasenotes/notes/deprecate-docker-devicemapper-234447328a24094f.yaml b/releasenotes/notes/deprecate-docker-devicemapper-234447328a24094f.yaml new file mode 100644 index 000000000..fa8ca3ea4 --- /dev/null +++ b/releasenotes/notes/deprecate-docker-devicemapper-234447328a24094f.yaml @@ -0,0 +1,8 @@ +--- +deprecations: + - | + Support for the ``devicemapper`` Docker storage driver is deprecated + following its removal from Docker Engine 25.0. Support will be fully + removed in the Caracal 16.0.0 release. Operators using ``devicemapper`` + should ensure that a compatible version of Docker Engine is installed (i.e. + release 24.x or below). diff --git a/releasenotes/notes/deprecate-fqdn-cacert-301d5a26ed7107ab.yaml b/releasenotes/notes/deprecate-fqdn-cacert-301d5a26ed7107ab.yaml new file mode 100644 index 000000000..d892cac43 --- /dev/null +++ b/releasenotes/notes/deprecate-fqdn-cacert-301d5a26ed7107ab.yaml @@ -0,0 +1,13 @@ +--- +deprecates: + - | + Renames ``kolla_external_fqdn_cacert`` to ``kolla_public_openrc_cacert`` + and ``kolla_internal_fqdn_cacert`` to ``kolla_admin_openrc_cacert``. This + matches the Kolla Ansible variable name and better reflects their purpose. + The old variable names are still supported until the end of the deprecation + period (2024.2 "D" series release or later). +fixes: + - | + Fixes an issue where the Kolla Ansible variable + ``kolla_admin_openrc_cacert`` was not set to the value of + ``kolla_internal_fqdn_cacert``. diff --git a/releasenotes/notes/disable-kolla-selinux-71f76e63776e0aed.yaml b/releasenotes/notes/disable-kolla-selinux-71f76e63776e0aed.yaml new file mode 100644 index 000000000..b6adcd28e --- /dev/null +++ b/releasenotes/notes/disable-kolla-selinux-71f76e63776e0aed.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Disables configuration of SELinux by Kolla Ansible, which could revert + configuration set by Kayobe. diff --git a/releasenotes/notes/disable-selinux-overcloud-dib-rocky-7c381912c3dfbc09.yaml b/releasenotes/notes/disable-selinux-overcloud-dib-rocky-7c381912c3dfbc09.yaml new file mode 100644 index 000000000..24b3bf78a --- /dev/null +++ b/releasenotes/notes/disable-selinux-overcloud-dib-rocky-7c381912c3dfbc09.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Adds missing ``disable-selinux`` element when building Rocky Linux + overcloud host disk images. diff --git a/releasenotes/notes/dnf-credentials-afc3bf7940cb6e99.yaml b/releasenotes/notes/dnf-credentials-afc3bf7940cb6e99.yaml new file mode 100644 index 000000000..50e2f94be --- /dev/null +++ b/releasenotes/notes/dnf-credentials-afc3bf7940cb6e99.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Adds support for specifying credentials (username and password) for custom + DNF repositories. diff --git a/releasenotes/notes/editable-install-data-file-path-743b7a85a5f5db6d.yaml b/releasenotes/notes/editable-install-data-file-path-743b7a85a5f5db6d.yaml new file mode 100644 index 000000000..dac75efa8 --- /dev/null +++ b/releasenotes/notes/editable-install-data-file-path-743b7a85a5f5db6d.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixes detection of data file path when using editable installations with a + recent pip. diff --git a/releasenotes/notes/fix-bifrost-gateway-b4bc8a0396dfa935.yaml b/releasenotes/notes/fix-bifrost-gateway-b4bc8a0396dfa935.yaml new file mode 100644 index 000000000..b2075e90a --- /dev/null +++ b/releasenotes/notes/fix-bifrost-gateway-b4bc8a0396dfa935.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fixes gateway assignment when seed SNAT is disabled. In this circumstance + Bifrost was generating ConfigDrive data with the default gateway unset even + when one is available on the admin network. diff --git a/releasenotes/notes/fix-ipa-eventlet-issues-82941ff32f31f2cb.yaml b/releasenotes/notes/fix-ipa-eventlet-issues-82941ff32f31f2cb.yaml new file mode 100644 index 000000000..1a8c39176 --- /dev/null +++ b/releasenotes/notes/fix-ipa-eventlet-issues-82941ff32f31f2cb.yaml @@ -0,0 +1,8 @@ +--- +upgrade: + - | + Ironic Python Agent images are now built using CentOS Stream 9 by default. +fixes: + - | + Fixes issues with TLS and eventlet affecting Ironic Python Agent. IPA + images should be rebuilt for affected deployments. diff --git a/releasenotes/notes/fix-resolv-conf-management-141788e64d0e82a0.yaml b/releasenotes/notes/fix-resolv-conf-management-141788e64d0e82a0.yaml new file mode 100644 index 000000000..102af06b2 --- /dev/null +++ b/releasenotes/notes/fix-resolv-conf-management-141788e64d0e82a0.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fixes a bug where NetworkManager would overwrite resolv.conf when + ``resolv_is_managed`` is set to ``True``. + `LP#2044537 `__ diff --git a/releasenotes/notes/honor-ssh-args-for-bootstrap-ba894df14ba58167.yaml b/releasenotes/notes/honor-ssh-args-for-bootstrap-ba894df14ba58167.yaml new file mode 100644 index 000000000..434408642 --- /dev/null +++ b/releasenotes/notes/honor-ssh-args-for-bootstrap-ba894df14ba58167.yaml @@ -0,0 +1,13 @@ +--- +fixes: + - | + When determining whether or not a host needs bootstrapping, we attempt to + connect to the host using ``ansible_user``, if the login fails, we then + assume that the host needs bootstrapping. In previous releases we used a + manually crafted ``ssh`` command. This did not respect any customisations + to the SSH arguments made through Ansible configuration. We now use the raw + module so that these customisations are used when connecting to the host. + One possible use case is to configure a jump host between the control host + and the target hosts. If bootstrapping was needed, hosts will now show as + unreachable in the summary stats at the end of the run. This can safely be + ignored. diff --git a/releasenotes/notes/kolla-passwords-overrides-065fd6bb8eb9689d.yaml b/releasenotes/notes/kolla-passwords-overrides-065fd6bb8eb9689d.yaml new file mode 100644 index 000000000..e66f05799 --- /dev/null +++ b/releasenotes/notes/kolla-passwords-overrides-065fd6bb8eb9689d.yaml @@ -0,0 +1,14 @@ +--- +fixes: + - | + Fixes an issue when user forgot to combine + ``kolla_ansible_custom_passwords``, + ``kolla_ansible_default_custom_passwords`` and own dictionary with custom + passwords in configuration files. Now + ``kolla_ansible_extra_custom_passwords`` should provide only user custom + passwords to add or override in ``kolla/passwords.yml``. +upgrade: + - | + Introduces a new variable ``kolla_ansible_extra_custom_passwords`` to avoid + the need to combine ``kolla_ansible_default_custom_passwords`` and + ``kolla_ansible_custom_passwords`` when adding or overriding passwords. diff --git a/releasenotes/notes/nm-bridge-vlan-mtu-workaround-71d48d582b5e23d6.yaml b/releasenotes/notes/nm-bridge-vlan-mtu-workaround-71d48d582b5e23d6.yaml new file mode 100644 index 000000000..e1568eb7a --- /dev/null +++ b/releasenotes/notes/nm-bridge-vlan-mtu-workaround-71d48d582b5e23d6.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Adds a workaround to avoid NetworkManager setting the MTU of bridge VLAN + interfaces to an incorrect value. + `LP#2039947 `__ diff --git a/releasenotes/notes/prometheus-elasticsearch-exporter-opensearch-cb7791220be58055.yaml b/releasenotes/notes/prometheus-elasticsearch-exporter-opensearch-cb7791220be58055.yaml new file mode 100644 index 000000000..f7834d304 --- /dev/null +++ b/releasenotes/notes/prometheus-elasticsearch-exporter-opensearch-cb7791220be58055.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Deploys ``prometheus-elasticsearch-exporter`` on hosts of the + ``opensearch`` group, resolving failures to connect to OpenSearch when the + ``elasticsearch`` and ``opensearch`` groups are different. diff --git a/releasenotes/notes/remove-network-manager-cloud-init-config-315c0eb846b72c93.yaml b/releasenotes/notes/remove-network-manager-cloud-init-config-315c0eb846b72c93.yaml new file mode 100644 index 000000000..23667afbf --- /dev/null +++ b/releasenotes/notes/remove-network-manager-cloud-init-config-315c0eb846b72c93.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixes conflicts between NetworkManager nmconnection files generated by + ``cloud-init`` and those generated by Kayobe by upgrading the + ``MichaelRigart.interfaces`` role to version 1.14.4. + `LP#2039975 `__ diff --git a/releasenotes/notes/rename-disable-selinux-9053ff36792066bc.yaml b/releasenotes/notes/rename-disable-selinux-9053ff36792066bc.yaml new file mode 100644 index 000000000..3bd5c7c92 --- /dev/null +++ b/releasenotes/notes/rename-disable-selinux-9053ff36792066bc.yaml @@ -0,0 +1,17 @@ +--- +features: + - | + Adds functionality to configure desired SELinux state (in addition to + disabling SELinux previously). +upgrade: + - | + The ``disable-selinux`` role has been renamed to ``selinux`` and so have + been the related variables. If you set one of them, adapt your + configuration: + + * ``disable_selinux_do_reboot`` becomes ``selinux_do_reboot`` + * ``disable_selinux_reboot_timeout`` becomes ``selinux_reboot_timeout`` + - | + Kayobe still sets SELinux to ``disabled`` by default, unlike in the Zed + 13.0.0 release. Operators may want to set ``selinux_state`` to + ``permissive`` to avoid another reboot in the Zed upgrade. diff --git a/releasenotes/notes/skip-kolla-docker-registry-login-f5b0ba858a35ea39.yaml b/releasenotes/notes/skip-kolla-docker-registry-login-f5b0ba858a35ea39.yaml new file mode 100644 index 000000000..7d61e6f9d --- /dev/null +++ b/releasenotes/notes/skip-kolla-docker-registry-login-f5b0ba858a35ea39.yaml @@ -0,0 +1,9 @@ +--- +features: + - | + Attempts to log in to the kolla docker registry can be skipped by setting + ``deploy_containers_registry_attempt_login`` to false. + + This is required for deployments using a non-standard registry + deployed on the seed during the deploy-container step, since it takes + place after the registry login attempt. diff --git a/releasenotes/notes/update-centos-cloud-image-latest-b967c585a23d1615.yaml b/releasenotes/notes/update-centos-cloud-image-latest-b967c585a23d1615.yaml new file mode 100644 index 000000000..60315e74c --- /dev/null +++ b/releasenotes/notes/update-centos-cloud-image-latest-b967c585a23d1615.yaml @@ -0,0 +1,5 @@ +--- +update: + - | + Updates base CentOS Stream 8 cloud image to + CentOS-Stream-GenericCloud-8-latest.x86_64. diff --git a/releasenotes/notes/update-deploy-kernel-6943f3ad3cb82c51.yaml b/releasenotes/notes/update-deploy-kernel-6943f3ad3cb82c51.yaml new file mode 100644 index 000000000..c098aec70 --- /dev/null +++ b/releasenotes/notes/update-deploy-kernel-6943f3ad3cb82c51.yaml @@ -0,0 +1,20 @@ +--- +upgrade: + - | + Adds an introspection rule to update the location of the deployment kernel + registered in existing Ironic nodes. Nodes discovered on a deployment + running the Train release or earlier may still be using the ``ipa.vmlinuz`` + kernel, which stays unchanged when deployment images get updated. If only + default introspection rules are in use, existing nodes may be updated from + the Bifrost container with the following command: + + ``OS_CLOUD=bifrost baremetal introspection reprocess $NODE_UUID_OR_NAME`` + + If non-default rules are used, reprocessing may revert any customisation + done by the operator. In this case, a more cautious approach is to update + the deployment kernel location manually: + + ``OS_CLOUD=bifrost baremetal node set --driver-info deploy_kernel= $NODE_UUID_OR_NAME`` + + If the ``kolla_bifrost_inspector_rules`` list is customised, the rule + ``inspector_rule_legacy_deploy_kernel`` should be added to it. diff --git a/requirements.txt b/requirements.txt index 017ea202a..59ab53f75 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,3 +13,4 @@ wcmatch>=8.2,<=9.0 # MIT ansible-cached-lookup<=2.0.0 # MIT # NOTE(wszusmki): Remove this when min python>=3.9 graphlib-backport<2.0.0 # PSF +jsonschema<5 # MIT diff --git a/requirements.yml b/requirements.yml index c892a3f1e..fb80c5ccc 100644 --- a/requirements.yml +++ b/requirements.yml @@ -19,8 +19,8 @@ roles: - src: jriguera.configdrive # There are no versioned releases of this role. version: 29871bf3279ef95fc8f7339b9abd13f869980750 - - name: MichaelRigart.interfaces - version: v1.14.1 + - src: MichaelRigart.interfaces + version: v1.14.4 - src: mrlesmithjr.chrony version: v0.1.4 - src: mrlesmithjr.manage_lvm diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml index fa3d6b482..fdf0035de 100644 --- a/zuul.d/project.yaml +++ b/zuul.d/project.yaml @@ -17,24 +17,20 @@ - kayobe-overcloud-rocky9 - kayobe-overcloud-ubuntu-focal - kayobe-overcloud-ubuntu-jammy - #- kayobe-overcloud-host-configure-centos8s - #- kayobe-overcloud-host-configure-centos9s - #- kayobe-overcloud-host-configure-rocky8 - #- kayobe-overcloud-host-configure-rocky9 - #- kayobe-overcloud-host-configure-ubuntu-focal - #- kayobe-overcloud-host-configure-ubuntu-jammy + - kayobe-overcloud-host-configure-centos8s + - kayobe-overcloud-host-configure-centos9s + - kayobe-overcloud-host-configure-rocky8 + - kayobe-overcloud-host-configure-rocky9 + - kayobe-overcloud-host-configure-ubuntu-focal + - kayobe-overcloud-host-configure-ubuntu-jammy - kayobe-overcloud-tls-centos8s - kayobe-overcloud-tls-rocky9 - - kayobe-overcloud-upgrade-centos8s - # - kayobe-overcloud-upgrade-ubuntu-focal Note(mattcrees): Job temporarily disabled until fix is merged, see: https://review.opendev.org/c/openstack/kolla/+/885857 - kayobe-seed-centos8s - kayobe-seed-rocky8 - kayobe-seed-rocky9 - kayobe-seed-ubuntu-focal - kayobe-seed-ubuntu-jammy - - kayobe-seed-upgrade-centos8s - - kayobe-seed-upgrade-ubuntu-focal - - kayobe-seed-vm-centos8sD + - kayobe-seed-vm-centos8s - kayobe-seed-vm-rocky8 - kayobe-seed-vm-rocky9 - kayobe-seed-vm-ubuntu-focal @@ -56,22 +52,18 @@ - kayobe-overcloud-rocky9 - kayobe-overcloud-ubuntu-focal - kayobe-overcloud-ubuntu-jammy - #- kayobe-overcloud-host-configure-centos8s - #- kayobe-overcloud-host-configure-rocky8 - #- kayobe-overcloud-host-configure-rocky9 - #- kayobe-overcloud-host-configure-ubuntu-focal - #- kayobe-overcloud-host-configure-ubuntu-jammy + - kayobe-overcloud-host-configure-centos8s + - kayobe-overcloud-host-configure-rocky8 + - kayobe-overcloud-host-configure-rocky9 + - kayobe-overcloud-host-configure-ubuntu-focal + - kayobe-overcloud-host-configure-ubuntu-jammy - kayobe-overcloud-tls-centos8s - kayobe-overcloud-tls-rocky9 - - kayobe-overcloud-upgrade-centos8s - # - kayobe-overcloud-upgrade-ubuntu-focal Note(mattcrees): Job temporarily disabled until fix is merged, see: https://review.opendev.org/c/openstack/kolla/+/885857 - kayobe-seed-centos8s - kayobe-seed-rocky8 - kayobe-seed-rocky9 - kayobe-seed-ubuntu-focal - kayobe-seed-ubuntu-jammy - - kayobe-seed-upgrade-centos8s - - kayobe-seed-upgrade-ubuntu-focal - kayobe-seed-vm-centos8s - kayobe-seed-vm-rocky8 - kayobe-seed-vm-rocky9