diff --git a/ansible/baremetal-compute-register.yml b/ansible/baremetal-compute-register.yml index 95b18f97e..2ce507e19 100644 --- a/ansible/baremetal-compute-register.yml +++ b/ansible/baremetal-compute-register.yml @@ -61,10 +61,10 @@ --name {{ inventory_hostname }} \ --driver {{ ironic_driver }} \ {% for key, value in ironic_driver_info.items() %} - --driver-info {{ key }}={{ value }} \ + --driver-info {{ (key ~ '=' ~ value) | quote }} \ {% endfor %} {% for key, value in ironic_properties.items() %} - --property {{ key }}={{ value }} \ + --property {{ (key ~ '=' ~ value) | quote }} \ {% endfor %} --resource-class {{ ironic_resource_class }} when: diff --git a/ansible/baremetal-compute-serial-console.yml b/ansible/baremetal-compute-serial-console.yml index cd987a485..a5e957000 100644 --- a/ansible/baremetal-compute-serial-console.yml +++ b/ansible/baremetal-compute-serial-console.yml @@ -83,18 +83,18 @@ - name: Set IPMI serial console terminal port vars: - name: "{{ node['name'] }}" - port: "{{ hostvars[controller_host].console_allocation_result.ports[name] }}" + node_name: "{{ node['name'] }}" + node_port: "{{ hostvars[controller_host].console_allocation_result.ports[node_name] }}" # NOTE: Without this, the controller's ansible_host variable will not # be respected when using delegate_to. ansible_host: "{{ hostvars[controller_host].ansible_host | default(controller_host) }}" command: > - {{ venv }}/bin/openstack baremetal node set {{ name }} --driver-info ipmi_terminal_port={{ port }} + {{ venv }}/bin/openstack baremetal node set {{ node_name }} --driver-info ipmi_terminal_port={{ node_port }} delegate_to: "{{ controller_host }}" environment: "{{ openstack_auth_env }}" when: >- node['driver_info'].ipmi_terminal_port is not defined or - node['driver_info'].ipmi_terminal_port | int != port | int + node['driver_info'].ipmi_terminal_port | int != node_port | int - name: Enable the IPMI socat serial console vars: diff --git a/ansible/container-engine.yml b/ansible/container-engine.yml index 7e6b30a23..0b2e6846b 100644 --- a/ansible/container-engine.yml +++ b/ansible/container-engine.yml @@ -15,7 +15,6 @@ name: docker vars: docker_daemon_mtu: "{{ public_net_name | net_mtu | default }}" - docker_configure_for_zun: "{{ kolla_enable_zun | bool }}" docker_http_proxy: "{{ kolla_http_proxy }}" docker_https_proxy: "{{ kolla_https_proxy }}" docker_no_proxy: "{{ kolla_no_proxy | select | join(',') }}" diff --git a/ansible/dell-switch-bmp.yml b/ansible/dell-switch-bmp.yml index 5e7ba991e..65c18f089 100644 --- a/ansible/dell-switch-bmp.yml +++ b/ansible/dell-switch-bmp.yml @@ -10,4 +10,4 @@ - role: dell-switch-bmp # This is the Nginx web server on the seed node. dell_switch_bmp_http_base_url: "http://{{ provision_oc_net_name | net_ip }}:8080" - when: dell_switch_bmp_images + when: dell_switch_bmp_images is truthy diff --git a/ansible/inventory/group_vars/all/bifrost b/ansible/inventory/group_vars/all/bifrost index f307c4118..e82688b5f 100644 --- a/ansible/inventory/group_vars/all/bifrost +++ b/ansible/inventory/group_vars/all/bifrost @@ -106,6 +106,11 @@ kolla_bifrost_inspector_keep_ports: "present" # kept to retain full node inspection capabilities. kolla_bifrost_inspector_extra_kernel_options: "{{ inspector_extra_kernel_options }}" +# Node driver to use for auto-discovered nodes. Default is +# {{ inspector_discovery_enroll_node_driver }}, defined in inspector.yml. Set +# to 'redfish' for modern BMC implementations. +kolla_bifrost_inspector_default_node_driver: "{{ inspector_discovery_enroll_node_driver }}" + # List of introspection rules for Bifrost's Ironic Inspector service. kolla_bifrost_inspector_rules: "{{ inspector_rules }}" diff --git a/ansible/inventory/group_vars/all/kolla b/ansible/inventory/group_vars/all/kolla index 0380ae27f..329929105 100644 --- a/ansible/inventory/group_vars/all/kolla +++ b/ansible/inventory/group_vars/all/kolla @@ -174,8 +174,6 @@ overcloud_container_image_regex_map: enabled: "{{ kolla_enable_heat | bool }}" - regex: ^horizon enabled: "{{ kolla_enable_horizon | bool }}" - - regex: ^influxdb - enabled: "{{ kolla_enable_influxdb | bool }}" - regex: ^ironic enabled: "{{ kolla_enable_ironic | bool }}" - regex: ironic-neutron-agent @@ -188,8 +186,6 @@ overcloud_container_image_regex_map: enabled: "{{ kolla_enable_keystone | bool }}" - regex: kolla-toolbox enabled: True - - regex: ^kuryr - enabled: "{{ kolla_enable_kuryr | bool }}" - regex: ^letsencrypt enabled: "{{ kolla_enable_letsencrypt | bool }}" - regex: ^magnum @@ -250,8 +246,6 @@ overcloud_container_image_regex_map: enabled: "{{ kolla_enable_swift | bool }}" - regex: ^tacker enabled: "{{ kolla_enable_tacker | bool }}" - - regex: ^telegraf - enabled: "{{ kolla_enable_telegraf | bool }}" - regex: ^tgtd enabled: "{{ kolla_enable_cinder | bool or kolla_enable_ironic | bool }}" - regex: ^trove @@ -260,8 +254,6 @@ overcloud_container_image_regex_map: enabled: "{{ kolla_enable_valkey | bool }}" - regex: ^watcher enabled: "{{ kolla_enable_watcher | bool }}" - - regex: ^zun - enabled: "{{ kolla_enable_zun | bool }}" # List of regular expressions matching names of container images to build for # overcloud hosts. @@ -558,13 +550,11 @@ kolla_enable_grafana: "no" kolla_enable_hacluster: "no" kolla_enable_heat: "{{ kolla_enable_openstack_core | bool }}" kolla_enable_horizon: "{{ kolla_enable_openstack_core | bool }}" -kolla_enable_influxdb: "{{ kolla_enable_cloudkitty | bool }}" kolla_enable_ironic: "no" kolla_enable_ironic_dnsmasq: "{{ kolla_enable_ironic | bool and kolla_inspector_enable_discovery | bool }}" kolla_enable_ironic_pxe_filter: "{{ kolla_enable_ironic | bool and kolla_inspector_enable_discovery | bool }}" kolla_enable_ironic_neutron_agent: "{{ kolla_enable_neutron | bool and kolla_enable_ironic | bool }}" kolla_enable_iscsid: "{{ kolla_enable_cinder | bool and kolla_enable_cinder_backend_iscsi | bool }}" -kolla_enable_kuryr: "no" kolla_enable_letsencrypt: "no" kolla_enable_magnum: "no" kolla_enable_manila: "no" @@ -583,19 +573,17 @@ kolla_enable_ovs_dpdk: "no" kolla_enable_opensearch: "{{ kolla_enable_central_logging | bool or kolla_enable_osprofiler | bool }}" kolla_enable_opensearch_dashboards: "{{ kolla_enable_opensearch | bool }}" kolla_enable_osprofiler: "no" -kolla_enable_placement: "{{ kolla_enable_nova | bool or kolla_enable_zun | bool }}" +kolla_enable_placement: "{{ kolla_enable_nova | bool }}" kolla_enable_prometheus: "no" kolla_enable_qdrouterd: "no" kolla_enable_redis: "no" kolla_enable_skyline: "no" kolla_enable_swift: "no" kolla_enable_tacker: "no" -kolla_enable_telegraf: "no" kolla_enable_trove: "no" kolla_enable_valkey: "no" kolla_enable_vitrage: "no" kolla_enable_watcher: "no" -kolla_enable_zun: "no" ############################################################################### # Kolla custom config generation. diff --git a/ansible/ip-allocation.yml b/ansible/ip-allocation.yml index 46c49b2a5..2f4ab78d6 100644 --- a/ansible/ip-allocation.yml +++ b/ansible/ip-allocation.yml @@ -32,7 +32,7 @@ when: - item | net_cidr != None - item | net_bootproto != 'dhcp' - - not item | net_no_ip | bool + - item | net_no_ip is falsy roles: - role: ip-allocation ip_allocation_filename: "{{ kayobe_env_config_path }}/network-allocation.yml" diff --git a/ansible/kolla-ansible.yml b/ansible/kolla-ansible.yml index 01abf815c..913331c4a 100644 --- a/ansible/kolla-ansible.yml +++ b/ansible/kolla-ansible.yml @@ -102,6 +102,10 @@ vars: kolla_ansible_control_host_become: "{{ kayobe_control_host_become | bool }}" kolla_ansible_install_epel: "{{ dnf_install_epel }}" + kolla_ansible_custom_requirements_search_paths_static: + - "{{ kayobe_config_path }}" + kolla_ansible_custom_requirements_search_paths: "{{ kolla_ansible_custom_requirements_search_paths_static + kayobe_env_search_paths | default([]) }}" + kolla_ansible_custom_requirements_paths: "{{ kolla_ansible_custom_requirements_search_paths | map('regex_replace', '$', '/kolla/requirements.yml') | list }}" kolla_external_fqdn_cert: "{{ kolla_config_path }}/certificates/haproxy.pem" kolla_internal_fqdn_cert: "{{ kolla_config_path }}/certificates/haproxy-internal.pem" kolla_ansible_passwords_path: "{{ kayobe_env_config_path }}/kolla/passwords.yml" diff --git a/ansible/network-connectivity.yml b/ansible/network-connectivity.yml index 327522c67..5fdbe2eab 100644 --- a/ansible/network-connectivity.yml +++ b/ansible/network-connectivity.yml @@ -51,8 +51,8 @@ ping {{ item | net_gateway }} -c1 -M do {% if mtu %} -s {{ mtu | int - icmp_overhead_bytes }}{% endif %} with_items: "{{ network_interfaces }}" when: - - item | net_ip - - item | net_gateway + - item | net_ip is truthy + - item | net_gateway is truthy changed_when: False vars: mtu: "{{ item | net_mtu }}" @@ -77,14 +77,14 @@ when: - remote_hosts | length > 0 - remote_ip | length > 0 - - item | net_ip + - item | net_ip is truthy changed_when: False vars: # Select other hosts targeted by this play which have this network # interface (item). remote_hosts: > {{ hostvars.values() | - selectattr('inventory_hostname', 'is_in', play_hosts) | + selectattr('inventory_hostname', 'is_in', ansible_play_batch) | selectattr('network_interfaces', 'defined') | selectattr('network_interfaces', 'issuperset', [item]) | rejectattr('inventory_hostname', 'equalto', inventory_hostname) | @@ -95,5 +95,5 @@ # in the command. Assumption was that this was being evaluated once # for the when clause and then again for the command. Bug? remote_host: "{{ remote_hosts | random(seed=ansible_facts.date_time.iso8601) if remote_hosts | length > 0 else '' }}" - remote_ip: "{{ lookup('cached', 'vars', item ~ '_ips', default={})[remote_host] | default('', true) }}" + remote_ip: "{{ lookup('vars', item ~ '_ips', default={})[remote_host] | default('', true) }}" mtu: "{{ item | net_mtu }}" diff --git a/ansible/overcloud-hardware-register.yml b/ansible/overcloud-hardware-register.yml new file mode 100644 index 000000000..13c9c812d --- /dev/null +++ b/ansible/overcloud-hardware-register.yml @@ -0,0 +1,61 @@ +--- +- name: Ensure overcloud hosts are registered in Bifrost + hosts: overcloud + gather_facts: false + vars: + seed_host: "{{ groups['seed'][0] }}" + # Try to reduce contention on Bifrost and resolve db lock errors + serial: 10 + tasks: + - name: Fail when no supported drivers are available + ansible.builtin.fail: + msg: This node uses an unsupported or undefined driver, only Redfish is supported. + when: + - ironic_driver | default ('') not in ['redfish'] + + - name: List baremetal nodes + command: > + {{ container_engine }} exec bifrost_deploy + bash -c ' + export OS_CLOUD=bifrost && + openstack baremetal node show {{ inventory_hostname }}' + register: node_show + failed_when: false + changed_when: false + delegate_to: "{{ seed_host }}" + vars: + ansible_host: "{{ hostvars[seed_host].ansible_host | default(seed_host) }}" + + - name: Create baremetal nodes + command: > + {{ container_engine }} exec bifrost_deploy + bash -c ' + export OS_CLOUD=bifrost && + openstack baremetal node create + --driver {{ ironic_driver }} + {% for key, value in ironic_driver_info.items() %} + --driver-info {{ (key ~ '=' ~ value) | quote }} + {% endfor %} + {% for key, value in ironic_properties.items() %} + --property {{ (key ~ '=' ~ value) | quote }} + {% endfor %} + --name {{ inventory_hostname }}' + delegate_to: "{{ seed_host }}" + vars: + ansible_host: "{{ hostvars[seed_host].ansible_host | default(seed_host) }}" + when: + - node_show.rc != 0 + + - name: Manage baremetal nodes + command: > + {{ container_engine }} exec bifrost_deploy + bash -c ' + export OS_CLOUD=bifrost && + openstack baremetal node manage + {{ inventory_hostname }} + --wait' + delegate_to: "{{ seed_host }}" + vars: + ansible_host: "{{ hostvars[seed_host].ansible_host | default(seed_host) }}" + when: + - node_show.rc != 0 diff --git a/ansible/roles/dnf/tasks/local-mirror.yml b/ansible/roles/dnf/tasks/local-mirror.yml index 3204ccbab..f7726b964 100644 --- a/ansible/roles/dnf/tasks/local-mirror.yml +++ b/ansible/roles/dnf/tasks/local-mirror.yml @@ -12,9 +12,10 @@ when: (role_path ~ '/templates/' ~ item ~ '.j2') is exists loop: - "{{ repo_file_prefix }}.repo" - - "{{ repo_file_prefix }}-extras.repo" - "{{ repo_file_prefix }}-addons.repo" - "{{ repo_file_prefix }}-devel.repo" + - "{{ repo_file_prefix }}-extras.repo" + - "{{ repo_file_prefix }}-security.repo" - name: Update cache dnf: diff --git a/ansible/roles/dnf/templates/rocky-security.repo.j2 b/ansible/roles/dnf/templates/rocky-security.repo.j2 new file mode 100644 index 000000000..fd4b304c3 --- /dev/null +++ b/ansible/roles/dnf/templates/rocky-security.repo.j2 @@ -0,0 +1,37 @@ +# rocky-security.repo +# +# The mirrorlist system uses the connecting IP address of the client and the +# update status of each mirror to pick current mirrors that are geographically +# close to the client. You should use this for Rocky updates unless you are +# manually picking other mirrors. +# +# If the mirrorlist does not work for you, you can try the commented out +# baseurl line instead. + +[security] +name=Rocky Linux $releasever - Security +#mirrorlist=https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=security-$releasever$rltype +baseurl=http://{{ dnf_rocky_mirror_host }}/{{ dnf_rocky_mirror_directory }}/$releasever/security/$basearch/os/ +gpgcheck=1 +enabled=0 +countme=1 +metadata_expire=6h +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-10 + +[security-debuginfo] +name=Rocky Linux $releasever - Security Debug +#mirrorlist=https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=security-$releasever-debug$rltype +baseurl=http://{{ dnf_rocky_mirror_host }}/{{ dnf_rocky_mirror_directory }}/$releasever/security/$basearch/debug/tree/ +gpgcheck=1 +enabled=0 +metadata_expire=6h +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-10 + +[security-source] +name=Rocky Linux $releasever - Security Source +#mirrorlist=https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=security-$releasever-source$rltype +baseurl=http://{{ dnf_rocky_mirror_host }}/{{ dnf_rocky_mirror_directory }}/$releasever/security/source/tree/ +gpgcheck=1 +enabled=0 +metadata_expire=6h +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-10 diff --git a/ansible/roles/etc-hosts/tasks/etc-hosts.yml b/ansible/roles/etc-hosts/tasks/etc-hosts.yml index 26ecd81d2..b90751ec2 100644 --- a/ansible/roles/etc-hosts/tasks/etc-hosts.yml +++ b/ansible/roles/etc-hosts/tasks/etc-hosts.yml @@ -30,6 +30,7 @@ regexp: "^127.0.1.1\\b.*\\s{{ ansible_facts.hostname }}\\b" state: absent become: True + when: inventory_hostname in etc_hosts_hosts - name: Generate /etc/hosts for all of the nodes blockinfile: diff --git a/ansible/roles/ipa-images/tasks/main.yml b/ansible/roles/ipa-images/tasks/main.yml index d1ddac12e..86a40202a 100644 --- a/ansible/roles/ipa-images/tasks/main.yml +++ b/ansible/roles/ipa-images/tasks/main.yml @@ -96,7 +96,7 @@ checksum: "{{ ipa_images_checksum.results[1].stat.checksum }}" glance_checksum: "{{ ipa_images_ramdisk.images[0].checksum | default }}" when: - - item.glance_checksum + - item.glance_checksum | default('') | length > 0 - item.checksum != item.glance_checksum environment: "{{ ipa_images_openstack_auth_env }}" diff --git a/ansible/roles/kolla-ansible/defaults/main.yml b/ansible/roles/kolla-ansible/defaults/main.yml index 6ab577683..0624d626e 100644 --- a/ansible/roles/kolla-ansible/defaults/main.yml +++ b/ansible/roles/kolla-ansible/defaults/main.yml @@ -34,6 +34,11 @@ kolla_ansible_requirements_yml: "{{ kolla_ansible_venv }}/share/kolla-ansible/re # Path to a an additional requirements.yml file for Ansible collections when using ansible-core. kolla_ansible_core_requirements_yml: "{{ kolla_ansible_venv }}/share/kolla-ansible/requirements-core.yml" +# List of optional paths to custom requirements.yml files for Ansible +# collections. Files that exist will be installed in order. +# If None, custom collections are not installed. +kolla_ansible_custom_requirements_paths: + # Virtualenv directory where Kolla-ansible's ansible modules will execute # remotely on the target nodes. If None, no virtualenv will be used. kolla_ansible_target_venv: @@ -228,9 +233,7 @@ kolla_openstack_logging_debug: #kolla_enable_grafana: #kolla_enable_heat: #kolla_enable_horizon: -#kolla_enable_influxdb: #kolla_enable_ironic: -#kolla_enable_kuryr: #kolla_enable_magnum: #kolla_enable_manila: #kolla_enable_mistral: @@ -241,7 +244,6 @@ kolla_openstack_logging_debug: #kolla_enable_neutron_vpnaas: #kolla_enable_prometheus: #kolla_enable_swift: -#kolla_enable_telegraf: #kolla_enable_watcher: ####################### diff --git a/ansible/roles/kolla-ansible/tasks/install.yml b/ansible/roles/kolla-ansible/tasks/install.yml index d328ed4f2..3a77fcc06 100644 --- a/ansible/roles/kolla-ansible/tasks/install.yml +++ b/ansible/roles/kolla-ansible/tasks/install.yml @@ -160,3 +160,29 @@ ANSIBLE_COLLECTIONS_SCAN_SYS_PATH: "False" # NOTE(wszumski): Don't use path configured for kayobe ANSIBLE_COLLECTIONS_PATH: '' + +- name: Check for custom Ansible collections requirements files + stat: + path: "{{ item }}" + get_checksum: False + mime: False + with_items: "{{ kolla_ansible_custom_requirements_paths }}" + register: kolla_ansible_custom_requirements_file + when: kolla_ansible_custom_requirements_paths is not none + +- name: Ensure custom Ansible collections are installed + command: + cmd: >- + ansible-galaxy collection install --force + -r {{ item.item }} + -p {{ kolla_ansible_venv }}/share/kolla-ansible/ansible/collections/ + with_items: "{{ kolla_ansible_custom_requirements_file.results }}" + environment: + # NOTE(wszumski): Ignore collections shipped with ansible, so that we can install + # newer versions. + ANSIBLE_COLLECTIONS_SCAN_SYS_PATH: "False" + # NOTE(wszumski): Don't use path configured for kayobe + ANSIBLE_COLLECTIONS_PATH: '' + when: + - kolla_ansible_custom_requirements_paths is not none + - item.stat.exists diff --git a/ansible/roles/kolla-ansible/templates/kolla/globals.yml b/ansible/roles/kolla-ansible/templates/kolla/globals.yml index 77135cd05..889ba5b49 100644 --- a/ansible/roles/kolla-ansible/templates/kolla/globals.yml +++ b/ansible/roles/kolla-ansible/templates/kolla/globals.yml @@ -74,8 +74,6 @@ docker_namespace: "{{ kolla_docker_namespace }}" docker_registry_username: "{{ kolla_docker_registry_username }}" {% endif %} -#docker_configure_for_zun: "no" - ################### # Messaging options ################### diff --git a/ansible/roles/kolla-ansible/templates/overcloud-components.j2 b/ansible/roles/kolla-ansible/templates/overcloud-components.j2 index f8c90e2cb..415c5c7d1 100644 --- a/ansible/roles/kolla-ansible/templates/overcloud-components.j2 +++ b/ansible/roles/kolla-ansible/templates/overcloud-components.j2 @@ -135,9 +135,6 @@ control [bifrost:children] deployment -[zun:children] -control - [skyline:children] control diff --git a/ansible/roles/kolla-ansible/templates/overcloud-services.j2 b/ansible/roles/kolla-ansible/templates/overcloud-services.j2 index b4d3bf049..cd0a3cae5 100644 --- a/ansible/roles/kolla-ansible/templates/overcloud-services.j2 +++ b/ansible/roles/kolla-ansible/templates/overcloud-services.j2 @@ -343,19 +343,6 @@ designate [placement-api:children] placement -# Zun -[zun-api:children] -zun - -[zun-wsproxy:children] -zun - -[zun-compute:children] -compute - -[zun-cni-daemon:children] -compute - # Skyline [skyline-apiserver:children] skyline diff --git a/ansible/roles/kolla-ansible/tests/test-extras.yml b/ansible/roles/kolla-ansible/tests/test-extras.yml index 607d7945e..83c3513ab 100644 --- a/ansible/roles/kolla-ansible/tests/test-extras.yml +++ b/ansible/roles/kolla-ansible/tests/test-extras.yml @@ -163,10 +163,8 @@ kolla_enable_haproxy: True kolla_enable_heat: True kolla_enable_horizon: True - kolla_enable_influxdb: True kolla_enable_ironic: True kolla_enable_ironic_neutron_agent: True - kolla_enable_kuryr: True kolla_enable_magnum: True kolla_enable_manila: True kolla_enable_manila_backend_generic: True @@ -189,10 +187,8 @@ kolla_enable_skyline: True kolla_enable_swift: True kolla_enable_tacker: True - kolla_enable_telegraf: True kolla_enable_trove: True kolla_enable_watcher: True - kolla_enable_zun: True kolla_globals_paths_extra: - "{{ tempfile_result.path ~ '/etc/kayobe/' }}" kolla_ansible_custom_passwords: @@ -278,10 +274,8 @@ #enable_haproxy: True #enable_heat: True #enable_horizon: True - #enable_influxdb: True #enable_ironic: True #enable_ironic_neutron_agent: True - #enable_kuryr: True #enable_magnum: True #enable_manila: True #enable_manila_backend_generic: True @@ -304,10 +298,8 @@ #enable_skyline: True #enable_swift: True #enable_tacker: True - #enable_telegraf: True #enable_trove: True #enable_watcher: True - #enable_zun: True extra-global-1: "extra-val-1" extra-global-2: "extra-val-2" diff --git a/ansible/roles/kolla-ansible/vars/main.yml b/ansible/roles/kolla-ansible/vars/main.yml index 6533227b0..d99259b49 100644 --- a/ansible/roles/kolla-ansible/vars/main.yml +++ b/ansible/roles/kolla-ansible/vars/main.yml @@ -137,8 +137,6 @@ kolla_feature_flags: - horizon_tacker - horizon_trove - horizon_watcher - - horizon_zun - - influxdb - ironic - ironic_dnsmasq - ironic_neutron_agent @@ -149,7 +147,6 @@ kolla_feature_flags: - keystone - keystone_federation - keystone_horizon_policy_file - - kuryr - letsencrypt - loadbalancer - magnum @@ -222,16 +219,16 @@ kolla_feature_flags: - prometheus_node_exporter - prometheus_openstack_exporter - prometheus_openstack_exporter_external + - prometheus_openstack_network_exporter - prometheus_proxysql_exporter - prometheus_rabbitmq_exporter - prometheus_server + - prometheus_valkey_exporter - proxysql - rabbitmq - skyline - tacker - - telegraf - trove - trove_singletenant - valkey - watcher - - zun diff --git a/ansible/roles/kolla-bifrost/defaults/main.yml b/ansible/roles/kolla-bifrost/defaults/main.yml index 2ab957d03..b86df4aa1 100644 --- a/ansible/roles/kolla-bifrost/defaults/main.yml +++ b/ansible/roles/kolla-bifrost/defaults/main.yml @@ -54,6 +54,10 @@ kolla_bifrost_inspector_keep_ports: # List of extra kernel parameters for the inspector default PXE configuration. kolla_bifrost_inspector_extra_kernel_options: +# Node driver to use for auto-discovered nodes. Default is unset, which uses +# Bifrost's default of 'ipmi'. +kolla_bifrost_inspector_default_node_driver: + # Whether to download the Ironic Python Agent (IPA) images. kolla_bifrost_download_ipa: true diff --git a/ansible/roles/kolla-bifrost/templates/kolla/config/bifrost/bifrost.yml b/ansible/roles/kolla-bifrost/templates/kolla/config/bifrost/bifrost.yml index 712bed6de..2da110ce7 100644 --- a/ansible/roles/kolla-bifrost/templates/kolla/config/bifrost/bifrost.yml +++ b/ansible/roles/kolla-bifrost/templates/kolla/config/bifrost/bifrost.yml @@ -49,6 +49,11 @@ inspector_keep_ports: "{{ kolla_bifrost_inspector_keep_ports }}" inspector_extra_kernel_options: "{{ kolla_bifrost_inspector_extra_kernel_options if kolla_bifrost_inspector_extra_kernel_options is string else kolla_bifrost_inspector_extra_kernel_options | join(' ') }}" {% endif %} +{% if kolla_bifrost_inspector_default_node_driver %} +# Node driver to use for auto-discovered nodes. +inspector_default_node_driver: "{{ kolla_bifrost_inspector_default_node_driver }}" +{% endif %} + # Whether to download Ironic Python Agent (IPA) images. download_ipa: "{{ kolla_bifrost_download_ipa }}" diff --git a/ansible/roles/kolla-openstack/defaults/main.yml b/ansible/roles/kolla-openstack/defaults/main.yml index 0fabde950..0feb15251 100644 --- a/ansible/roles/kolla-openstack/defaults/main.yml +++ b/ansible/roles/kolla-openstack/defaults/main.yml @@ -90,8 +90,6 @@ kolla_openstack_custom_config_include_globs_default: glob: heat/** - enabled: '{{ kolla_enable_horizon | bool }}' glob: horizon/** - - enabled: '{{ kolla_enable_influxdb | bool }}' - glob: influx* - enabled: '{{ kolla_enable_ironic | bool }}' glob: ironic.conf - enabled: '{{ kolla_enable_ironic | bool }}' @@ -150,8 +148,6 @@ kolla_openstack_custom_config_include_globs_default: glob: prometheus/** - enabled: '{{ kolla_enable_swift | bool }}' glob: swift/** - - enabled: '{{ kolla_enable_telegraf | bool }}' - glob: telegraf/** # Extra items to add to kolla_openstack_custom_config_include_globs_default # to produce kolla_openstack_custom_config_include_globs. @@ -249,9 +245,6 @@ kolla_openstack_custom_config_rules_default: - glob: "**/*httpd.conf" strategy: template priority: 1000 - - glob: "**/influxdb.conf" - strategy: template - priority: 1000 - glob: "**/keepalived.conf" strategy: template priority: 1000 @@ -264,10 +257,6 @@ kolla_openstack_custom_config_rules_default: - glob: "**/*wsgi*.conf" strategy: template priority: 1000 - # NOTE(wszumksi): Telegraf uses toml for its configuration files - - glob: telegraf/** - strategy: template - priority: 1000 # INI files - glob: "**/*.conf" strategy: "{{ kolla_openstack_custom_config_ini_merge_strategy_default }}" @@ -443,12 +432,6 @@ kolla_extra_heat: # Whether to enable Horizon. kolla_enable_horizon: false -############################################################################### -# InfluxDB configuration. - -# Whether to enable InfluxDB. -kolla_enable_influxdb: false - ############################################################################### # Ironic configuration. @@ -812,9 +795,3 @@ kolla_enable_prometheus: false # Whether to enable swift. kolla_enable_swift: false - -############################################################################### -# Telegraf configuration. - -# Whether to enable telegraf -kolla_enable_telegraf: true diff --git a/ansible/roles/network-nmstate/tasks/main.yml b/ansible/roles/network-nmstate/tasks/main.yml index 4bff2ed9d..3a3732ae3 100644 --- a/ansible/roles/network-nmstate/tasks/main.yml +++ b/ansible/roles/network-nmstate/tasks/main.yml @@ -109,8 +109,8 @@ | combine({ (item | net_interface): (item | net_zone) }) }} loop: "{{ network_interfaces | default([]) }}" when: - - item | net_zone - - item | net_interface + - item | net_zone is truthy + - item | net_interface is truthy - name: Build nmstate firewalld interface-zone items set_fact: diff --git a/dev/functions b/dev/functions index 64c335724..b5de6ad71 100644 --- a/dev/functions +++ b/dev/functions @@ -63,6 +63,9 @@ function config_defaults { # Whether to perform overcloud post configuration. export KAYOBE_OVERCLOUD_POST_CONFIGURE=${KAYOBE_OVERCLOUD_POST_CONFIGURE:-1} + # Whether to use Kolla test images. + export KAYOBE_USE_KOLLA_TEST_IMAGES=${KAYOBE_USE_KOLLA_TEST_IMAGES:-1} + # Additional arguments to pass to kayobe commands. export KAYOBE_EXTRA_ARGS=${KAYOBE_EXTRA_ARGS:-} @@ -91,6 +94,12 @@ function config_defaults { # Log directory in case of errors export LOGDIR=${LOGDIR:-} + + # Test with broken conditionals support disabled. We do not want to allow + # new upstream code to add broken conditionals, but want to continue to + # enable ANSIBLE_ALLOW_BROKEN_CONDITIONALS by default for a period of time + # so that users have a chance to update their playbooks. + export ANSIBLE_ALLOW_BROKEN_CONDITIONALS=${ANSIBLE_ALLOW_BROKEN_CONDITIONALS:-false} } function config_set { @@ -514,7 +523,7 @@ function overcloud_deploy { cp ${KOLLA_CONFIG_PATH:-/etc/kolla}/config/octavia/*.pem ${KAYOBE_CONFIG_PATH}/kolla/config/octavia/ fi echo "Deploying containerised overcloud services" - run_kayobe overcloud service deploy + run_kayobe overcloud service deploy $( ((KAYOBE_USE_KOLLA_TEST_IMAGES)) && echo "--use-test-images" ) fi if [[ ${KAYOBE_OVERCLOUD_POST_CONFIGURE} = 1 ]]; then @@ -566,7 +575,7 @@ function overcloud_upgrade { run_kayobe overcloud service configuration save --exclude 'ironic-agent.*' echo "Deploying containerised overcloud services" - run_kayobe overcloud service upgrade + run_kayobe overcloud service upgrade $( ((KAYOBE_USE_KOLLA_TEST_IMAGES)) && echo "--use-test-images" ) echo "Control plane upgrade complete" } diff --git a/doc/source/configuration/reference/bifrost.rst b/doc/source/configuration/reference/bifrost.rst index 62ab636be..c2acb5e35 100644 --- a/doc/source/configuration/reference/bifrost.rst +++ b/doc/source/configuration/reference/bifrost.rst @@ -279,6 +279,12 @@ The following options configure the Ironic Inspector service in the ``kolla_bifrost_inspector_keep_ports`` Which ports to keep after introspection. One of ``all``, ``present`` or ``added``. Default is ``present`` to align with Bifrost's defaults. +``kolla_bifrost_inspector_default_node_driver`` + Node driver to use for auto-discovered nodes. Default is + ``{{ inspector_discovery_enroll_node_driver }}``, defined in + ``${KAYOBE_CONFIG_PATH}/inspector.yml``. Set to ``redfish`` for modern BMC + implementations. Corresponds to ``[auto_discover] driver`` in + ``ironic.conf``. ``kolla_bifrost_inspector_extra_kernel_options`` List of extra kernel parameters for the inspector default PXE configuration. Default is ``{{ inspector_extra_kernel_options }}``, defined diff --git a/doc/source/configuration/reference/kolla-ansible.rst b/doc/source/configuration/reference/kolla-ansible.rst index eca5e7755..aa748bc6c 100644 --- a/doc/source/configuration/reference/kolla-ansible.rst +++ b/doc/source/configuration/reference/kolla-ansible.rst @@ -77,6 +77,46 @@ For example, to use the `hashi_vault Ansible lookup plugin kolla_ansible_venv_extra_requirements: - "hvac" +Custom Ansible Collections Requirements +--------------------------------------- + +Kayobe can install additional Ansible collections for Kolla Ansible from +custom requirements files. + +By default, Kayobe looks for ``kolla/requirements.yml`` in +``${KAYOBE_CONFIG_PATH}`` and each path in ``kayobe_env_search_paths``. + +Example custom collections requirements file: + +.. code-block:: yaml + :caption: ``$KAYOBE_CONFIG_PATH/kolla/requirements.yml`` + + --- + collections: + - name: git+https://git.example.com/myorg/ansible-collection-kolla-filters.git + type: git + version: main + +Any files that exist are installed in order with +``ansible-galaxy collection install`` after the default Kolla Ansible +collections are installed. Missing files are skipped. + +Use case: custom filter plugins in Kolla templates +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +One use case is shipping site-specific Jinja2 filter plugins in a private +Ansible collection, then using those filters in Kolla service configuration +templates under ``${KAYOBE_CONFIG_PATH}/kolla/config``. + +If a custom collection provides a filter named +``myorg.kolla_filters.to_backend_name``, reference the filter in a Kolla +custom template, for example: + +.. code-block:: jinja + :caption: ``$KAYOBE_CONFIG_PATH/kolla/config/haproxy/haproxy.cfg`` + + backend {{ inventory_hostname | myorg.kolla_filters.to_backend_name }} + Local environment ================= @@ -764,7 +804,6 @@ which files are supported. ``heat.conf`` Heat configuration. ``heat/*`` Extended heat configuration. ``horizon/*`` Extended horizon configuration. - ``influx*`` InfluxDB configuration. ``ironic.conf`` Ironic configuration. ``ironic/*`` Extended ironic configuration. ``keepalived/*`` Extended keepalived configuration. @@ -790,7 +829,6 @@ which files are supported. ``placement/*`` Extended Placement configuration. ``prometheus/*`` Prometheus configuration. ``swift/*`` Extended swift configuration. - ``telegraf/*`` Extended Telegraf configuration. =============================== ======================================================= Configuring an OpenStack Component diff --git a/doc/source/deployment.rst b/doc/source/deployment.rst index 5148700a8..c6ec74b7f 100644 --- a/doc/source/deployment.rst +++ b/doc/source/deployment.rst @@ -468,6 +468,52 @@ to add them to the Kayobe and Kolla-Ansible inventories:: naming Ironic nodes via switch port descriptions, Ironic Inspector and LLDP. +Registration +------------ + +This workflow acts as an alternative to enrolling nodes through discovery where +nodes can be registered in Bifrost via Kayobe given these nodes are defined in +the Kayobe inventory. + +A group_vars file for the `overcloud` group should be created which contains the Ironic +variables, this should be in ``etc/kayobe/inventory/group_vars/overcloud/ironic_vars`` or +in the environment you are using. + +.. code-block:: yaml + + ironic_driver: redfish + + ironic_driver_info: + redfish_system_id: "{{ ironic_redfish_system_id }}" + redfish_address: "{{ ironic_redfish_address }}" + redfish_username: "{{ ironic_redfish_username }}" + redfish_password: "{{ ironic_redfish_password }}" + redfish_verify_ca: "{{ ironic_redfish_verify_ca }}" + ipmi_address: "{{ ipmi_address }}" + + ironic_properties: + capabilities: "{{ ironic_capabilities }}" + + ironic_resource_class: "example_resouce_class" + ironic_redfish_system_id: "/redfish/v1/Systems/System.Embedded.1" + ironic_redfish_verify_ca: "{{ inspector_rule_var_redfish_verify_ca }}" + ironic_redfish_address: "{{ ipmi_address }}" + ironic_redfish_username: "{{ inspector_redfish_username }}" + ironic_redfish_password: "{{ inspector_redfish_password }}" + ironic_capabilities: "boot_option:local,boot_mode:uefi" + +It's essential that the Ironic username and password match the BMC username +and password for your nodes, if the username and password combination is +not the same for the entire group you will need to adjust your configuration +accordingly. The IPMI address should also match the BMC address for your node. +Once this has been completed you can begin enrolling the Ironic nodes:: + + (kayobe) $ kayobe overcloud hardware register + +Inspector is not used to discover nodes and no node inspection will take place on +enrollment, nodes will automatically be placed into ``manageable`` state. To inspect, +you should use ``kayobe overcloud hardware inspect`` following enrollment. + Saving Hardware Introspection Data ---------------------------------- diff --git a/etc/kayobe/bifrost.yml b/etc/kayobe/bifrost.yml index d65c9d27d..05625eee3 100644 --- a/etc/kayobe/bifrost.yml +++ b/etc/kayobe/bifrost.yml @@ -106,6 +106,11 @@ # kept to retain full node inspection capabilities. #kolla_bifrost_inspector_extra_kernel_options: +# Node driver to use for auto-discovered nodes. Default is +# {{ inspector_discovery_enroll_node_driver }}, defined in inspector.yml. Set +# to 'redfish' for modern BMC implementations. +#kolla_bifrost_inspector_default_node_driver: + # List of introspection rules for Bifrost's Ironic Inspector service. #kolla_bifrost_inspector_rules: diff --git a/etc/kayobe/kolla.yml b/etc/kayobe/kolla.yml index a89f2949d..c5993e8e4 100644 --- a/etc/kayobe/kolla.yml +++ b/etc/kayobe/kolla.yml @@ -349,8 +349,6 @@ #kolla_enable_horizon_tacker: #kolla_enable_horizon_trove: #kolla_enable_horizon_watcher: -#kolla_enable_horizon_zun: -#kolla_enable_influxdb: #kolla_enable_ironic: #kolla_enable_ironic_dnsmasq: #kolla_enable_ironic_neutron_agent: @@ -361,7 +359,6 @@ #kolla_enable_keystone: #kolla_enable_keystone_federation: #kolla_enable_keystone_horizon_policy_file: -#kolla_enable_kuryr: #kolla_enable_letsencrypt: #kolla_enable_loadbalancer: #kolla_enable_magnum: @@ -434,19 +431,19 @@ #kolla_enable_prometheus_node_exporter: #kolla_enable_prometheus_openstack_exporter: #kolla_enable_prometheus_openstack_exporter_external: +#kolla_enable_prometheus_openstack_network_exporter: #kolla_enable_prometheus_proxysql_exporter: #kolla_enable_prometheus_rabbitmq_exporter: #kolla_enable_prometheus_server: +#kolla_enable_prometheus_valkey_exporter: #kolla_enable_proxysql: #kolla_enable_rabbitmq: #kolla_enable_skyline: #kolla_enable_tacker: -#kolla_enable_telegraf: #kolla_enable_trove: #kolla_enable_trove_singletenant: #kolla_enable_valkey: #kolla_enable_watcher: -#kolla_enable_zun: ############################################################################### # Kolla custom config generation. diff --git a/kayobe/cli/commands.py b/kayobe/cli/commands.py index ee97c5d3b..2660bd7ad 100644 --- a/kayobe/cli/commands.py +++ b/kayobe/cli/commands.py @@ -1303,6 +1303,16 @@ def take_action(self, parsed_args): self.run_kayobe_playbooks(parsed_args, playbooks) +class OvercloudHardwareRegister(KayobeAnsibleMixin, VaultMixin, Command): + """Register overcloud hosts in Bifrost""" + + def take_action(self, parsed_args): + self.app.LOG.debug("Registering overcloud hosts in Bifrost") + playbooks = _build_playbook_list("kolla-bifrost-hostvars", + "overcloud-hardware-register") + self.run_kayobe_playbooks(parsed_args, playbooks) + + class OvercloudHardwareInspect(KayobeAnsibleMixin, VaultMixin, Command): """Inspect the overcloud hardware using ironic inspector. @@ -1557,6 +1567,9 @@ def get_parser(self, prog_name): "the remote node (required)") group.add_argument("--skip-prechecks", action='store_true', help="skip the kolla-ansible prechecks command") + group.add_argument("--use-test-images", action="store_true", + help="Allow use of test images " + "(i.e. quay.io/openstack.kolla)") return parser def take_action(self, parsed_args): @@ -1569,7 +1582,11 @@ def take_action(self, parsed_args): # Run kolla-ansible prechecks before deployment. if not parsed_args.skip_prechecks: - self.run_kolla_ansible_overcloud(parsed_args, "prechecks") + extra_vars = {} + if parsed_args.use_test_images: + extra_vars["kolla_test_images"] = "yes" + self.run_kolla_ansible_overcloud(parsed_args, "prechecks", + extra_vars=extra_vars) # Generate the configuration. extra_vars = {} @@ -1669,6 +1686,9 @@ def get_parser(self, prog_name): group = parser.add_argument_group("Service Deployment") group.add_argument("--skip-prechecks", action='store_true', help="skip the kolla-ansible prechecks command") + group.add_argument("--use-test-images", action="store_true", + help="Allow use of test images " + "(i.e. quay.io/openstack.kolla)") return parser def take_action(self, parsed_args): @@ -1681,7 +1701,11 @@ def take_action(self, parsed_args): # Run kolla-ansible prechecks before deployment. if not parsed_args.skip_prechecks: - self.run_kolla_ansible_overcloud(parsed_args, "prechecks") + extra_vars = {} + if parsed_args.use_test_images: + extra_vars["kolla_test_images"] = "yes" + self.run_kolla_ansible_overcloud(parsed_args, "prechecks", + extra_vars=extra_vars) # Perform the kolla-ansible deployment. self.run_kolla_ansible_overcloud(parsed_args, "deploy") @@ -1721,6 +1745,9 @@ def get_parser(self, prog_name): group = parser.add_argument_group("Service Deployment") group.add_argument("--skip-prechecks", action='store_true', help="skip the kolla-ansible prechecks command") + group.add_argument("--use-test-images", action="store_true", + help="Allow use of test images " + "(i.e. quay.io/openstack.kolla)") return parser def take_action(self, parsed_args): @@ -1733,7 +1760,11 @@ def take_action(self, parsed_args): # Run kolla-ansible prechecks before deployment. if not parsed_args.skip_prechecks: - self.run_kolla_ansible_overcloud(parsed_args, "prechecks") + extra_vars = {} + if parsed_args.use_test_images: + extra_vars["kolla_test_images"] = "yes" + self.run_kolla_ansible_overcloud(parsed_args, "prechecks", + extra_vars=extra_vars) # Perform the kolla-ansible deployment. self.run_kolla_ansible_overcloud(parsed_args, "manage-containers") @@ -1758,6 +1789,14 @@ class OvercloudServicePrechecks(KollaAnsibleMixin, KayobeAnsibleMixin, services. """ + def get_parser(self, prog_name): + parser = super(OvercloudServicePrechecks, self).get_parser(prog_name) + group = parser.add_argument_group("Service Prechecks") + group.add_argument("--use-test-images", action="store_true", + help="Allow use of test images " + "(i.e. quay.io/openstack.kolla)") + return parser + def take_action(self, parsed_args): self.app.LOG.debug("Running overcloud prechecks") @@ -1767,7 +1806,11 @@ def take_action(self, parsed_args): self.generate_kolla_ansible_config(parsed_args) # Run the kolla-ansible prechecks. - self.run_kolla_ansible_overcloud(parsed_args, "prechecks") + extra_vars = {} + if parsed_args.use_test_images: + extra_vars["kolla_test_images"] = "yes" + self.run_kolla_ansible_overcloud(parsed_args, "prechecks", + extra_vars=extra_vars) class OvercloudServicePasswordsView(KayobeAnsibleMixin, VaultMixin, Command): @@ -1799,6 +1842,9 @@ def get_parser(self, prog_name): group = parser.add_argument_group("Service Reconfiguration") group.add_argument("--skip-prechecks", action='store_true', help="skip the kolla-ansible prechecks command") + group.add_argument("--use-test-images", action="store_true", + help="Allow use of test images " + "(i.e. quay.io/openstack.kolla)") return parser def take_action(self, parsed_args): @@ -1811,7 +1857,11 @@ def take_action(self, parsed_args): # Run kolla-ansible prechecks before reconfiguration. if not parsed_args.skip_prechecks: - self.run_kolla_ansible_overcloud(parsed_args, "prechecks") + extra_vars = {} + if parsed_args.use_test_images: + extra_vars["kolla_test_images"] = "yes" + self.run_kolla_ansible_overcloud(parsed_args, "prechecks", + extra_vars=extra_vars) # Perform the kolla-ansible reconfiguration. self.run_kolla_ansible_overcloud(parsed_args, "reconfigure") @@ -1899,6 +1949,9 @@ def get_parser(self, prog_name): group = parser.add_argument_group("Service Upgrade") group.add_argument("--skip-prechecks", action='store_true', help="skip the kolla-ansible prechecks command") + group.add_argument("--use-test-images", action="store_true", + help="Allow use of test images " + "(i.e. quay.io/openstack.kolla)") return parser def take_action(self, parsed_args): @@ -1911,7 +1964,11 @@ def take_action(self, parsed_args): # Run kolla-ansible prechecks before upgrade. if not parsed_args.skip_prechecks: - self.run_kolla_ansible_overcloud(parsed_args, "prechecks") + extra_vars = {} + if parsed_args.use_test_images: + extra_vars["kolla_test_images"] = "yes" + self.run_kolla_ansible_overcloud(parsed_args, "prechecks", + extra_vars=extra_vars) # Perform the kolla-ansible upgrade. self.run_kolla_ansible_overcloud(parsed_args, "upgrade") diff --git a/kayobe/plugins/action/merge_configs.py b/kayobe/plugins/action/merge_configs.py index 605414bfc..0a93fbfe7 100644 --- a/kayobe/plugins/action/merge_configs.py +++ b/kayobe/plugins/action/merge_configs.py @@ -165,9 +165,9 @@ def read_config(self, source, config): os.path.join(self._loader._basedir, 'templates'), os.path.dirname(source), ] - self._templar.environment.loader.searchpath = searchpath - result = self._templar.template(template_data) + templar = self._templar.copy_with_new_env(searchpath=searchpath) + result = templar.template(template_data) fakefile = StringIO(result) config.parse(fakefile) fakefile.close() diff --git a/kayobe/plugins/action/merge_yaml.py b/kayobe/plugins/action/merge_yaml.py index 35d250371..c35b182b4 100644 --- a/kayobe/plugins/action/merge_yaml.py +++ b/kayobe/plugins/action/merge_yaml.py @@ -105,9 +105,9 @@ def read_config(self, source): os.path.join(self._loader._basedir, 'templates'), os.path.dirname(source), ] - self._templar.environment.loader.searchpath = searchpath - template_data = self._templar.template(template_data) + templar = self._templar.copy_with_new_env(searchpath=searchpath) + template_data = templar.template(template_data) result = yaml.safe_load(template_data) return result or {} @@ -119,7 +119,7 @@ def run(self, tmp=None, task_vars=None): # save template args. extra_vars = self._task.args.get('vars', list()) - old_vars = self._templar._available_variables + old_vars = self._templar.available_variables temp_vars = task_vars.copy() temp_vars.update(extra_vars) diff --git a/kayobe/tests/unit/cli/test_commands.py b/kayobe/tests/unit/cli/test_commands.py index a72d76ecd..694b08c81 100644 --- a/kayobe/tests/unit/cli/test_commands.py +++ b/kayobe/tests/unit/cli/test_commands.py @@ -1244,6 +1244,29 @@ def test_overcloud_inventory_discover(self, mock_run_one, mock_run): ] self.assertListEqual(expected_calls, mock_run.call_args_list) + @mock.patch.object(commands.KayobeAnsibleMixin, + "run_kayobe_playbooks") + def test_overcloud_hardware_register(self, mock_run): + command = commands.OvercloudHardwareRegister(TestApp(), []) + parser = command.get_parser("test") + parsed_args = parser.parse_args([]) + + result = command.run(parsed_args) + self.assertEqual(0, result) + + expected_calls = [ + mock.call( + mock.ANY, + [ + utils.get_data_files_path( + "ansible", "kolla-bifrost-hostvars.yml"), + utils.get_data_files_path( + "ansible", "overcloud-hardware-register.yml"), + ], + ), + ] + self.assertListEqual(expected_calls, mock_run.call_args_list) + @mock.patch.object(commands.KayobeAnsibleMixin, "run_kayobe_playbooks") def test_overcloud_hardware_inspect(self, mock_run): @@ -1752,6 +1775,7 @@ def test_overcloud_service_deploy(self, mock_kolla_run, mock_run): mock.call( mock.ANY, "prechecks", + extra_vars={} ), mock.call( mock.ANY, @@ -1812,6 +1836,7 @@ def test_overcloud_service_deploy_containers(self, mock_kolla_run, mock.call( mock.ANY, "prechecks", + extra_vars={} ), mock.call( mock.ANY, @@ -1856,6 +1881,7 @@ def test_overcloud_service_prechecks(self, mock_kolla_run, mock_run): mock.call( mock.ANY, "prechecks", + extra_vars={} ), ] self.assertListEqual(expected_calls, mock_kolla_run.call_args_list) @@ -1914,6 +1940,7 @@ def test_overcloud_service_reconfigure(self, mock_kolla_run, mock_run): mock.call( mock.ANY, "prechecks", + extra_vars={} ), mock.call( mock.ANY, @@ -2046,7 +2073,8 @@ def test_overcloud_service_upgrade(self, mock_kolla_run, mock_run): expected_calls = [ mock.call( mock.ANY, - "prechecks" + "prechecks", + extra_vars={} ), mock.call( mock.ANY, diff --git a/playbooks/kayobe-ansible-control-host-configure-base/overrides.yml.j2 b/playbooks/kayobe-ansible-control-host-configure-base/overrides.yml.j2 new file mode 100644 index 000000000..c643dcf6d --- /dev/null +++ b/playbooks/kayobe-ansible-control-host-configure-base/overrides.yml.j2 @@ -0,0 +1,267 @@ +--- +pip_upper_constraints_file: "/tmp/upper-constraints.txt" + +# Use the CI infra's PyPI mirror. +pip_local_mirror: true +pip_index_url: "http://{{ zuul_site_mirror_fqdn }}/pypi/simple" +pip_trusted_hosts: + - "{{ zuul_site_mirror_fqdn }}" + +# NOTE(mgoddard): CentOS 8 removes interfaces from their bridge during ifdown, +# and removes the bridge if there are no interfaces left. When Kayobe bounces +# veth links plugged into the bridge, it causes the bridge which has the IP we +# are using for SSH to be removed. Use a dummy interface. +aio_bridge_ports: + - dummy1 + +# The following configuration aims to test some of the 'host configure' +# command. +{% set host_configure_network_engine = ci_network_engine | default('default') %} + +# Additional users. +ansible_control_users: + - username: kayobe-test-user + name: Kayobe test user + password: kayobe-test-user-password + groups: + - stack + +# Exercise nmstate networking engine in CI host configure jobs where +# required packages are available. +{% if host_configure_network_engine == "nmstate" %} +network_engine: {{ host_configure_network_engine }} +{% endif %} + +# Additional network interfaces, testing a variety of interface configurations. +ansible_control_extra_network_interfaces: + - test_net_eth + - test_net_eth_vlan + - test_net_bridge + - test_net_bridge_vlan + - test_net_bond + - test_net_bond_vlan + - test_net_bridge_noip +{% if ansible_os_family == "Debian" %} + - test_net_systemd_vlan +{% endif %} + +# Custom IP routing tables. +network_route_tables: + - id: 2 + name: kayobe-test-route-table + +# dummy2: Dummy interface for testing. +test_net_eth_cidr: 192.168.34.0/24 +test_net_eth_routes: + - cidr: 192.168.40.0/24 + gateway: 192.168.34.254 +test_net_eth_interface: dummy2 + +# dummy2.42: VLAN subinterface of dummy2. +test_net_eth_vlan_cidr: 192.168.35.0/24 +test_net_eth_vlan_interface: "{% raw %}{{ test_net_eth_interface }}.{{ test_net_eth_vlan_vlan }}{% endraw %}" +test_net_eth_vlan_vlan: 42 +test_net_eth_vlan_routes: + - cidr: 192.168.40.0/24 + gateway: 192.168.35.254 + table: kayobe-test-route-table +test_net_eth_vlan_rules: +{% if ansible_facts.os_family == 'RedHat' and host_configure_network_engine == 'nmstate' %} + - from: 192.168.35.0/24 + table: kayobe-test-route-table + - to: 192.168.35.0/24 + table: kayobe-test-route-table +{% elif ansible_facts.os_family == 'RedHat' %} + - from 192.168.35.0/24 table 2 + - to: 192.168.35.0/24 + table: kayobe-test-route-table +{% else %} + - from: 192.168.35.0/24 + table: kayobe-test-route-table + - to: 192.168.35.0/24 + table: kayobe-test-route-table +{% endif %} +test_net_eth_vlan_zone: test-zone1 +{% if host_configure_network_engine == "nmstate" %} +test_net_eth_vlan_ingress_qos_map: + - from: 3 + to: 12 + - from: 7 + to: 254 +test_net_eth_vlan_egress_qos_map: + - from: 129 + to: 7 + - from: 130 + to: 6 +{% endif %} + +# br0: bridge with ports dummy3, dummy4. +test_net_bridge_cidr: 192.168.36.0/24 +test_net_bridge_interface: br0 +test_net_bridge_bridge_ports: [dummy3, dummy4] +test_net_bridge_bridge_stp: false +test_net_bridge_zone: test-zone2 + +# br0.43: VLAN subinterface of br0. +test_net_bridge_vlan_cidr: 192.168.37.0/24 +test_net_bridge_vlan_interface: "{% raw %}{{ test_net_bridge_interface }}.{{ test_net_bridge_vlan_vlan }}{% endraw %}" +test_net_bridge_vlan_vlan: 43 +test_net_bridge_vlan_zone: test-zone3 + +# bond0: bond with slaves dummy5, dummy6. +test_net_bond_cidr: 192.168.38.0/24 +test_net_bond_interface: bond0 +test_net_bond_bond_slaves: [dummy5, dummy6] +test_net_bond_bond_mode: balance-rr +test_net_bond_zone: test-zone3 + +# bond0.44: VLAN subinterface of bond0. +test_net_bond_vlan_cidr: 192.168.39.0/24 +test_net_bond_vlan_interface: "{% raw %}{{ test_net_bond_interface }}.{{ test_net_bond_vlan_vlan }}{% endraw %}" +test_net_bond_vlan_vlan: 44 +test_net_bond_vlan_zone: public + +# br1: Bridge interface without IP address. +test_net_bridge_noip_cidr: 192.168.40.0/24 +test_net_bridge_noip_interface: br1 +test_net_bridge_noip_bridge_ports: [dummy7] +test_net_bridge_noip_bridge_stp: true +test_net_bridge_noip_no_ip: true + +{% if ansible_os_family == "Debian" %} +# vlan45: VLAN interface of bond0 using systemd-networkd style +test_net_systemd_vlan_cidr: 192.168.41.0/24 +test_net_systemd_vlan_interface: "vlan{% raw %}{{ test_net_systemd_vlan_vlan }}{% endraw %}" +test_net_systemd_vlan_parent: "{% raw %}{{ test_net_bond_interface }}{% endraw %}" +test_net_systemd_vlan_vlan: 45 +test_net_systemd_vlan_zone: public +{% endif %} + +# Define a software RAID device consisting of two loopback devices. +ansible_control_mdadm_arrays: + - name: md0 + devices: + - /dev/loop0 + - /dev/loop1 + level: '1' + state: present + +# Layer LUKS encryption on top of the software RAID +ansible_control_luks_devices: + - name: loopback-crypt + device: /dev/md0 + +# Create an LVM volume group for Docker volumes. +ansible_control_lvm_groups: + - "{% raw %}{{ ansible_control_lvm_group_data }}{% endraw %}" + +# Provide a disk for use by LVM. Uses the LUKS encrypted device created above. +ansible_control_lvm_group_data_disks: + - /dev/mapper/loopback-crypt + +# Set a sysctl. +ansible_control_sysctl_parameters: + fs.mount-max: 99999 + +# Disable cloud-init. +disable_cloud_init: true + +# Set Honolulu time. +timezone: Pacific/Honolulu + +{% if ansible_facts.os_family == "Debian" %} +apt_config: + - content: | + Acquire::Retries 1; + filename: 99retries +apt_keys: + - url: https://packages.treasuredata.com/GPG-KEY-td-agent + filename: td-agent.asc +apt_repositories: + # Ubuntu noble repositories. + - url: "http://{{ zuul_site_mirror_fqdn }}/ubuntu/" + suites: noble noble-updates + components: main universe + - url: "http://{{ zuul_site_mirror_fqdn }}/ubuntu/" + suites: noble-security + components: main universe + # Treasuredata repository. + - url: https://packages.treasuredata.com/lts/5/ubuntu/noble + components: contrib + signed_by: td-agent.asc +apt_preferences: + - content: | + Package: fake-package + Pin: origin fake.repo.url + Pin-Priority: 1 + filename: 99fakepackage +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' %} +# Configure a custom DNF repository. +dnf_custom_repos: + fluent-package: + baseurl: https://fluentd.cdn.cncf.io/lts/6/redhat/$releasever/$basearch + gpgkey: https://fluentd.cdn.cncf.io/GPG-KEY-fluent-package + gpgcheck: yes +# The EPEL repository is missing from zuul images. Using local mirror makes +# sure it is defined. +dnf_use_local_mirror: true +# Install EPEL local mirror. +dnf_install_epel: true +# Enable DNF Automatic. +dnf_automatic_enabled: true +{% endif %} + +# Override the default NTP pool +chrony_ntp_servers: + - server: time.cloudflare.com + type: pool + options: + - option: maxsources + val: 2 + +# Force system clock synchronisation +ntp_force_sync: True + +# Enable firewalld +ansible_control_firewalld_enabled: true +ansible_control_firewalld_zones: + - zone: test-zone1 + - zone: test-zone2 + - zone: test-zone3 +ansible_control_firewalld_default_zone: +ansible_control_firewalld_rules: + - port: 8080/tcp + zone: test-zone1 + - service: http + zone: test-zone2 + - icmp_block: echo-request + zone: test-zone3 + - service: cockpit + state: disabled + zone: public + +# Configure a swap file. +ansible_control_swap: + - path: /swapfile + size_mb: 256 + +# Generate a password for libvirt SASL authentication. +compute_libvirt_sasl_password: "{% raw %}{{ lookup('password', '/tmp/libvirt-sasl-password') }}{% endraw %}" + +# Configure container engine. +ansible_control_container_engine_enabled: true + +# Test fail2ban configuration +ansible_control_fail2ban_enabled: true + +# Add a custom entry to /etc/hosts. +custom_etc_hosts_entries: + foo.example.com: 127.0.0.88 diff --git a/playbooks/kayobe-ansible-control-host-configure-base/pre.yml b/playbooks/kayobe-ansible-control-host-configure-base/pre.yml new file mode 100644 index 000000000..41690184f --- /dev/null +++ b/playbooks/kayobe-ansible-control-host-configure-base/pre.yml @@ -0,0 +1,62 @@ +--- +- hosts: primary + environment: + KAYOBE_CONFIG_SOURCE_PATH: "{{ kayobe_config_src_dir }}" + tasks: + - name: Ensure host-configure test harness dependencies are installed + include_role: + name: host-configure-test-harness + tasks_from: pre + + # NOTE(mgoddard): The kayobe dev config by default expects a bridge - + # breth1 - to exist with an IP address of 192.168.33.7. + - import_role: + name: kayobe-network-bootstrap + vars: + bridge_interface: breth1 + bridge_ip: 192.168.33.7 + bridge_prefix: 24 + bridge_port_interface: dummy1 + + # NOTE(mgoddard): Use the name zz-20-overrides.yml to ensure this takes + # precedence over the standard config files, but can control order with the + # priority (number after zz). + - name: Ensure kayobe-config override config file exists + template: + src: overrides.yml.j2 + dest: "{{ kayobe_config_src_dir }}/etc/kayobe/zz-20-overrides.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 + command: truncate -s 2G /tmp/docker-storage{{ item }} + loop: [0, 1] + + - name: Ensure the docker storage loopback device is created + command: losetup /dev/loop{{ item }} /tmp/docker-storage{{ item }} + become: true + loop: [0, 1] + + - name: Ensure dummy network interfaces exist + command: ip link add dummy{{ item }} type dummy + become: true + loop: "{{ range(2, 8) | list }}" + when: ansible_facts.os_family == 'Debian' + + - name: Ensure firewalld is unmasked + ansible.builtin.systemd_service: + name: firewalld + masked: false + become: true + + - name: Ensure kayobe is installed + shell: + cmd: dev/install.sh &> {{ logs_dir }}/ansible/install + chdir: "{{ kayobe_src_dir }}" + executable: /bin/bash + + - name: Configure the firewall + shell: + cmd: dev/configure-firewall.sh + chdir: "{{ kayobe_src_dir }}" + executable: /bin/bash diff --git a/playbooks/kayobe-ansible-control-host-configure-base/run.yml b/playbooks/kayobe-ansible-control-host-configure-base/run.yml new file mode 100644 index 000000000..c439f9555 --- /dev/null +++ b/playbooks/kayobe-ansible-control-host-configure-base/run.yml @@ -0,0 +1,22 @@ +--- +- hosts: primary + environment: + KAYOBE_CONFIG_SOURCE_PATH: "{{ kayobe_config_src_dir }}" + tasks: + - name: Prevent NetworkManager from managing default interface + command: 'nmcli dev set {{ ansible_facts.default_ipv4.interface }} managed no' + become: true + when: ansible_facts.os_family == 'RedHat' + + - name: Ensure Ansible control host is configured + shell: + cmd: "{{ kayobe_src_dir }}/dev/ansible-control-host-configure.sh &> {{ logs_dir }}/ansible/ansible-control-host-configure" + executable: /bin/bash + + - name: Run host-configure test harness + import_role: + name: host-configure-test-harness + tasks_from: run + environment: + FAIL2BAN_ENABLED: "{{ fail2ban_enabled | default(false) }}" + CI_NETWORK_ENGINE: "{{ ci_network_engine | default('default') }}" diff --git a/playbooks/kayobe-overcloud-base/run.yml b/playbooks/kayobe-overcloud-base/run.yml index e5c617bc8..23ad0ba3d 100644 --- a/playbooks/kayobe-overcloud-base/run.yml +++ b/playbooks/kayobe-overcloud-base/run.yml @@ -58,6 +58,15 @@ kayobe baremetal compute register &> {{ logs_dir }}/ansible/baremetal-compute-register executable: /bin/bash + - name: Run network connectivity check + shell: + # NOTE(wszumski): Limit to overcloud as we have hosts in our inventory + # that aren't deployed in this scenario. + cmd: > + source {{ kayobe_src_dir }}/dev/environment-setup.sh && + kayobe network connectivity check --limit overcloud + executable: /bin/bash + - name: Perform database backup shell: cmd: > diff --git a/playbooks/kayobe-overcloud-host-configure-base/pre.yml b/playbooks/kayobe-overcloud-host-configure-base/pre.yml index d564c45a8..424baf458 100644 --- a/playbooks/kayobe-overcloud-host-configure-base/pre.yml +++ b/playbooks/kayobe-overcloud-host-configure-base/pre.yml @@ -1,23 +1,10 @@ --- - hosts: primary - vars: - testinfra_venv: ~/testinfra-venv tasks: - - name: Ensure python3 and setuptools are installed - package: - name: - - python3 - - python3-setuptools - become: true - - - name: Ensure testinfra is installed - pip: - name: - - distro - - pytest-testinfra - - pytest-html - virtualenv: "{{ testinfra_venv }}" - virtualenv_command: python3 -m venv + - name: Ensure host-configure test harness dependencies are installed + include_role: + name: host-configure-test-harness + tasks_from: pre # NOTE(mgoddard): Use the name zz-30-overrides.yml to ensure this takes # precedence over the standard config files and zz-20-overrides.yml from diff --git a/playbooks/kayobe-overcloud-host-configure-base/run.yml b/playbooks/kayobe-overcloud-host-configure-base/run.yml index 1863cc753..3aa185a70 100644 --- a/playbooks/kayobe-overcloud-host-configure-base/run.yml +++ b/playbooks/kayobe-overcloud-host-configure-base/run.yml @@ -6,9 +6,6 @@ KAYOBE_OVERCLOUD_CONTAINER_IMAGE_PULL: 0 KAYOBE_OVERCLOUD_SERVICE_DEPLOY: 0 KAYOBE_OVERCLOUD_POST_CONFIGURE: 0 - vars: - testinfra_venv: ~/testinfra-venv - test_path: "{{ kayobe_src_dir }}/playbooks/kayobe-overcloud-host-configure-base/tests/" tasks: - name: Prevent NetworkManager from managing default interface command: 'nmcli dev set {{ ansible_facts.default_ipv4.interface }} managed no' @@ -20,20 +17,11 @@ cmd: "{{ kayobe_src_dir }}/dev/overcloud-deploy.sh &> {{ logs_dir }}/ansible/overcloud-deploy" executable: /bin/bash - - name: Return artifact to Zuul - zuul_return: - data: - zuul: - artifacts: - - name: "Unit Test Report" - url: "{{ inventory_hostname }}/test-results.html" - metadata: - type: unit_test_report - - - name: Run testinfra tests - command: "{{ testinfra_venv }}/bin/py.test {{ test_path }} --html={{ logs_dir }}/test-results.html --self-contained-html" + - name: Run host-configure test harness + import_role: + name: host-configure-test-harness + tasks_from: run environment: - SITE_MIRROR_FQDN: "{{ zuul_site_mirror_fqdn }}" FAIL2BAN_ENABLED: "{{ fail2ban_enabled | default(false) }}" CI_NETWORK_ENGINE: "{{ ci_network_engine | default('default') }}" diff --git a/releasenotes/notes/add-overcloud-hardware-register-command-cc68b9fbdf7c6c3a.yaml b/releasenotes/notes/add-overcloud-hardware-register-command-cc68b9fbdf7c6c3a.yaml new file mode 100644 index 000000000..b198cabb3 --- /dev/null +++ b/releasenotes/notes/add-overcloud-hardware-register-command-cc68b9fbdf7c6c3a.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Adds a new ``kayobe overcloud hardware register`` command to enroll + overcloud hosts in Bifrost based on nodes defined in the Kayobe + inventory. diff --git a/releasenotes/notes/adds-kolla-ansible-custom-requirements-0e914805f1708aec.yaml b/releasenotes/notes/adds-kolla-ansible-custom-requirements-0e914805f1708aec.yaml new file mode 100644 index 000000000..724982f36 --- /dev/null +++ b/releasenotes/notes/adds-kolla-ansible-custom-requirements-0e914805f1708aec.yaml @@ -0,0 +1,10 @@ +--- +features: + - | + Adds support for installing extra Kolla Ansible collections from + ``kolla/requirements.yml`` files discovered in + ``${KAYOBE_CONFIG_PATH}`` and ``kayobe_env_search_paths``. + This can be used to provide custom collections, including filter plugins + used by Kolla configuration templates. See :kayobe-doc:`Kayobe + documentation ` for more + details. diff --git a/releasenotes/notes/ansible-broken-conditionals-deprecation-7a0713c08d8a0a3d.yaml b/releasenotes/notes/ansible-broken-conditionals-deprecation-7a0713c08d8a0a3d.yaml new file mode 100644 index 000000000..36a2b6765 --- /dev/null +++ b/releasenotes/notes/ansible-broken-conditionals-deprecation-7a0713c08d8a0a3d.yaml @@ -0,0 +1,9 @@ +--- +deprecations: + - | + Kayobe currently ships with ``ANSIBLE_ALLOW_BROKEN_CONDITIONALS` enabled by + default. This will be removed in the 2026.2 cycle. Please check the Ansible + output of any custom playbooks for deprecation warnings related to this + setting and update the playbooks accordingly. You can set + ``ANSIBLE_ALLOW_BROKEN_CONDITIONALS=false`` in your shell environment to + surface these issues more explicitly. diff --git a/releasenotes/notes/bifrost-inspector-default-node-driver-a3f82c1d4e5b9078.yaml b/releasenotes/notes/bifrost-inspector-default-node-driver-a3f82c1d4e5b9078.yaml new file mode 100644 index 000000000..9fabcbca8 --- /dev/null +++ b/releasenotes/notes/bifrost-inspector-default-node-driver-a3f82c1d4e5b9078.yaml @@ -0,0 +1,11 @@ +--- +features: + - | + Adds support for configuring the Ironic auto-discovery node driver used + by Bifrost via the new ``kolla_bifrost_inspector_default_node_driver`` + variable. This corresponds to ``[auto_discover] driver`` in + ``ironic.conf``. The default is ``{{ inspector_discovery_enroll_node_driver }}``, + defined in ``inspector.yml``, which itself defaults to ``ipmi``. Set to + ``redfish`` for modern BMC implementations. + See `bug 2137417 `_ for + details. diff --git a/releasenotes/notes/fix-network-connectivity-ansible-2.19-26ba287e9adfd7f3.yaml b/releasenotes/notes/fix-network-connectivity-ansible-2.19-26ba287e9adfd7f3.yaml new file mode 100644 index 000000000..81d7ad1a9 --- /dev/null +++ b/releasenotes/notes/fix-network-connectivity-ansible-2.19-26ba287e9adfd7f3.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixes network connectivity check failing when using ansible>=2.19. See + `LP#2138614 `_. diff --git a/releasenotes/notes/kolla-use-test-images-b8f70f3748135f60.yaml b/releasenotes/notes/kolla-use-test-images-b8f70f3748135f60.yaml new file mode 100644 index 000000000..7e9369a82 --- /dev/null +++ b/releasenotes/notes/kolla-use-test-images-b8f70f3748135f60.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Adds the ``--use-test-images`` option to commands running kolla-ansible + prechecks to allow use of test images (i.e. ``quay.io/openstack.kolla``). diff --git a/releasenotes/notes/rocky-security-repo-9c40690280459f41.yaml b/releasenotes/notes/rocky-security-repo-9c40690280459f41.yaml new file mode 100644 index 000000000..cb02190fb --- /dev/null +++ b/releasenotes/notes/rocky-security-repo-9c40690280459f41.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Adds support for templating configuration for the new Rocky Linux security + repository. diff --git a/releasenotes/notes/sync-kolla-feature-flags-2026-1-f1c943a205c6e7a6.yaml b/releasenotes/notes/sync-kolla-feature-flags-2026-1-f1c943a205c6e7a6.yaml new file mode 100644 index 000000000..fd06a6e66 --- /dev/null +++ b/releasenotes/notes/sync-kolla-feature-flags-2026-1-f1c943a205c6e7a6.yaml @@ -0,0 +1,18 @@ +--- +upgrade: + - | + Synchronises Kayobe feature flags with Kolla Ansible 2026.1. The + following services have been removed and are no longer supported: + + - InfluxDB (``kolla_enable_influxdb``) + - Kuryr (``kolla_enable_kuryr``) + - Telegraf (``kolla_enable_telegraf``) + - Zun (``kolla_enable_zun``, ``kolla_enable_horizon_zun``) + + References to these services have been removed from the overcloud + container image regex map, the inventory defaults, the kolla-openstack + role custom config include globs and rules, and the operator example + configuration in ``etc/kayobe/kolla.yml``. + + The ``kolla_enable_placement`` default no longer depends on + ``kolla_enable_zun``; it now depends only on ``kolla_enable_nova``. diff --git a/requirements.yml b/requirements.yml index c7402326a..352609203 100644 --- a/requirements.yml +++ b/requirements.yml @@ -31,7 +31,7 @@ roles: version: 2.0.2 - src: jriguera.configdrive # There are no versioned releases of this role. - version: 17d9f7e76942012e9d09490ecb119066d16aad3d + version: c6da1f29d6c1d8d5e0f9f0d2dd2d4dfb1973e62d - src: MichaelRigart.interfaces version: v1.16.1 - src: mrlesmithjr.chrony @@ -49,7 +49,7 @@ roles: - src: stackhpc.drac-facts version: v1.0.1 - src: stackhpc.libvirt-host - version: v1.15.0 + version: v1.15.1 - src: stackhpc.libvirt-vm version: v1.16.3 - src: stackhpc.luks diff --git a/roles/host-configure-test-harness/defaults/main.yml b/roles/host-configure-test-harness/defaults/main.yml new file mode 100644 index 000000000..dc9e7c2cb --- /dev/null +++ b/roles/host-configure-test-harness/defaults/main.yml @@ -0,0 +1,5 @@ +--- +host_configure_testinfra_venv: ~/testinfra-venv +host_configure_test_path: "{{ kayobe_src_dir }}/roles/host-configure-test-harness/tests/" +host_configure_test_results_path: "{{ logs_dir }}/test-results.html" +host_configure_site_mirror_fqdn: "{{ zuul_site_mirror_fqdn }}" diff --git a/roles/host-configure-test-harness/tasks/pre.yml b/roles/host-configure-test-harness/tasks/pre.yml new file mode 100644 index 000000000..9a28a1f00 --- /dev/null +++ b/roles/host-configure-test-harness/tasks/pre.yml @@ -0,0 +1,16 @@ +--- +- name: Ensure python3 and setuptools are installed + package: + name: + - python3 + - python3-setuptools + become: true + +- name: Ensure testinfra is installed + pip: + name: + - distro + - pytest-testinfra + - pytest-html + virtualenv: "{{ host_configure_testinfra_venv }}" + virtualenv_command: python3 -m venv diff --git a/roles/host-configure-test-harness/tasks/run.yml b/roles/host-configure-test-harness/tasks/run.yml new file mode 100644 index 000000000..000864114 --- /dev/null +++ b/roles/host-configure-test-harness/tasks/run.yml @@ -0,0 +1,19 @@ +--- +- name: Return artifact to Zuul + zuul_return: + data: + zuul: + artifacts: + - name: "Unit Test Report" + url: "{{ inventory_hostname }}/test-results.html" + metadata: + type: unit_test_report + +- name: Run testinfra tests + command: >- + {{ host_configure_testinfra_venv }}/bin/py.test + {{ host_configure_test_path }} + --html={{ host_configure_test_results_path }} + --self-contained-html + environment: + SITE_MIRROR_FQDN: "{{ host_configure_site_mirror_fqdn }}" diff --git a/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py b/roles/host-configure-test-harness/tests/test_host_configure.py similarity index 96% rename from playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py rename to roles/host-configure-test-harness/tests/test_host_configure.py index 0f620472f..5c03a28cd 100644 --- a/playbooks/kayobe-overcloud-host-configure-base/tests/test_overcloud_host_configure.py +++ b/roles/host-configure-test-harness/tests/test_host_configure.py @@ -11,6 +11,11 @@ import pytest +def _is_ansible_control_host(host): + interface = host.interface('breth1') + return '192.168.33.7' in interface.addresses + + def _is_apt(): info = distro.id() return info == 'ubuntu' @@ -180,6 +185,8 @@ def test_sysctls(host): def test_cloud_init_is_disabled(host): + if _is_ansible_control_host(host): + pytest.skip("cloud-init not disabled on Ansible control host") assert host.file("/etc/cloud/cloud-init.disabled").exists @@ -191,12 +198,16 @@ def test_docker_storage_driver_is_overlay2(host): @pytest.mark.parametrize('user', ['kolla', 'stack']) def test_docker_image_download(host, user): + if _is_ansible_control_host(host) and user == 'kolla': + pytest.skip("User kolla not configured on Ansible control host") with host.sudo(user): host.check_output("docker pull quay.io/podman/hello") @pytest.mark.parametrize('user', ['kolla', 'stack']) def test_docker_container_run(host, user): + if _is_ansible_control_host(host) and user == 'kolla': + pytest.skip("User kolla not configured on Ansible control host") with host.sudo(user): host.check_output("docker run --rm quay.io/podman/hello") diff --git a/roles/kayobe-ci-prep/tasks/main.yml b/roles/kayobe-ci-prep/tasks/main.yml index b3b9c25ad..942a1988a 100644 --- a/roles/kayobe-ci-prep/tasks/main.yml +++ b/roles/kayobe-ci-prep/tasks/main.yml @@ -9,10 +9,20 @@ vars: configure_ephemeral_mountpoint: "{{ '/var/lib/containers' if container_engine | default('docker') == 'podman' else '/var/lib/docker' }}" +- name: Find YUM repo files + become: true + ansible.builtin.find: + paths: /etc/yum.repos.d + patterns: "*.repo" + file_type: file + register: repo_files + when: ansible_facts.distribution == "Rocky" + - name: Set Rocky Linux mirror to download.rockylinux.org become: true ansible.builtin.shell: - cmd: sed -i 's/mirrorlist/#mirrorlist/g; s/#baseurl/baseurl/g' /etc/yum.repos.d/rocky.repo + cmd: sed -i 's/mirrorlist/#mirrorlist/g; s/#baseurl/baseurl/g' {{ item }} + loop: "{{ repo_files.files | map(attribute='path') | list }}" when: ansible_facts.distribution == "Rocky" - block: diff --git a/setup.cfg b/setup.cfg index 7f385d1e4..f4094b93c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -67,6 +67,7 @@ kayobe.cli= overcloud_deprovision = kayobe.cli.commands:OvercloudDeprovision overcloud_facts_gather = kayobe.cli.commands:OvercloudFactsGather overcloud_hardware_inspect = kayobe.cli.commands:OvercloudHardwareInspect + overcloud_hardware_register = kayobe.cli.commands:OvercloudHardwareRegister overcloud_host_configure = kayobe.cli.commands:OvercloudHostConfigure overcloud_host_image_build = kayobe.cli.commands:OvercloudHostImageBuild overcloud_host_package_update = kayobe.cli.commands:OvercloudHostPackageUpdate @@ -172,6 +173,8 @@ kayobe.cli.overcloud_facts_gather = hooks = kayobe.cli.commands:HookDispatcher kayobe.cli.overcloud_hardware_inspect = hooks = kayobe.cli.commands:HookDispatcher +kayobe.cli.overcloud_hardware_register = + hooks = kayobe.cli.commands:HookDispatcher kayobe.cli.overcloud_host_configure = hooks = kayobe.cli.commands:HookDispatcher kayobe.cli.overcloud_host_image_build = diff --git a/tools/run-bashate.sh b/tools/run-bashate.sh index dd35ba737..78d7c5a1b 100755 --- a/tools/run-bashate.sh +++ b/tools/run-bashate.sh @@ -7,5 +7,6 @@ ROOT=$(readlink -fn $(dirname $0)/.. ) # https://bugs.launchpad.net/bash8/+bug/1895102 find $ROOT -not -wholename \*.tox/\* -and -not -wholename \*.test/\* \ -and -not -wholename \*.ansible/\* -and -not -wholename \*venv\* \ + -and -not -wholename \*/ansible/collections/\* \ -and -not -wholename \*/ansible/roles/\*.\*/\* \ -and -name \*.sh -print0 | xargs -0 bashate -v --ignore E006,E010 diff --git a/tox.ini b/tox.ini index d284e89ae..86f549130 100644 --- a/tox.ini +++ b/tox.ini @@ -38,7 +38,7 @@ commands = # directives. python3 {toxinidir}/tools/sphinx8 README.rst CONTRIBUTING.rst doc/source --ignore D001 yamllint etc/kayobe - bandit -r --severity-level=high ansible kayobe tools + bandit -r --severity-level=high -x ansible/collections ansible kayobe tools [testenv:venv] deps = diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml index ecd50c249..3157ef5dc 100644 --- a/zuul.d/jobs.yaml +++ b/zuul.d/jobs.yaml @@ -114,6 +114,33 @@ roles: - zuul: openstack/kolla +- job: + name: kayobe-ansible-control-host-configure-base + parent: kayobe-base + description: | + Base job for testing Ansible control host configuration. + + Configures the primary VM as an Ansible control host. + pre-run: playbooks/kayobe-ansible-control-host-configure-base/pre.yml + run: playbooks/kayobe-ansible-control-host-configure-base/run.yml + timeout: 7200 + +- job: + name: kayobe-ansible-control-host-configure-centos10s + parent: kayobe-ansible-control-host-configure-base + nodeset: kayobe-centos10s + voting: false + +- job: + name: kayobe-ansible-control-host-configure-rocky10 + parent: kayobe-ansible-control-host-configure-base + nodeset: kayobe-rocky10 + +- job: + name: kayobe-ansible-control-host-configure-ubuntu-noble + parent: kayobe-ansible-control-host-configure-base + nodeset: kayobe-ubuntu-noble + - job: name: kayobe-overcloud-base parent: kayobe-base diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml index 1e7975186..e2c6f3e44 100644 --- a/zuul.d/project.yaml +++ b/zuul.d/project.yaml @@ -15,6 +15,8 @@ - kayobe-tox-ansible-syntax - kayobe-tox-ansible - kayobe-tox-molecule + - kayobe-ansible-control-host-configure-rocky10 + - kayobe-ansible-control-host-configure-ubuntu-noble - kayobe-infra-vm-rocky10 - kayobe-infra-vm-ubuntu-noble - kayobe-overcloud-host-configure-rocky10 @@ -46,6 +48,8 @@ - kayobe-tox-ansible-syntax - kayobe-tox-ansible - kayobe-tox-molecule + - kayobe-ansible-control-host-configure-rocky10 + - kayobe-ansible-control-host-configure-ubuntu-noble - kayobe-infra-vm-rocky10 - kayobe-infra-vm-ubuntu-noble - kayobe-overcloud-host-configure-rocky10 @@ -72,6 +76,7 @@ experimental: jobs: + - kayobe-ansible-control-host-configure-centos10s - kayobe-infra-vm-centos10s - kayobe-infra-vm-centos10s-cloud-image - kayobe-infra-vm-rocky10-cloud-image