diff --git a/ansible/inventory/group_vars/all/container-engine b/ansible/inventory/group_vars/all/container-engine index 29f7b3106..4e4982bdf 100644 --- a/ansible/inventory/group_vars/all/container-engine +++ b/ansible/inventory/group_vars/all/container-engine @@ -12,8 +12,9 @@ container_engine_volumes_path: "{{ podman_volumes_path if container_engine == 'p ############################################################################### # Docker configuration. -# Name of the docker storage driver. Default is 'overlay2'. -docker_storage_driver: overlay2 +# Name of the docker storage driver. Default is "", which defers to the +# Docker runtime default. +docker_storage_driver: "" # URL of docker registry docker_registry: diff --git a/ansible/inventory/group_vars/all/controllers b/ansible/inventory/group_vars/all/controllers index ead2f1104..a0cffca4b 100644 --- a/ansible/inventory/group_vars/all/controllers +++ b/ansible/inventory/group_vars/all/controllers @@ -44,7 +44,6 @@ controller_default_network_interfaces: > inspection_net_name, internal_net_name, storage_net_name, - swift_storage_net_name, cleaning_net_name] | select | unique | list }} # List of extra networks to which controller nodes are attached. diff --git a/ansible/inventory/group_vars/all/kolla b/ansible/inventory/group_vars/all/kolla index 6a104abf1..e21f89767 100644 --- a/ansible/inventory/group_vars/all/kolla +++ b/ansible/inventory/group_vars/all/kolla @@ -244,8 +244,6 @@ overcloud_container_image_regex_map: enabled: "{{ kolla_enable_redis | bool }}" - regex: ^skyline enabled: "{{ kolla_enable_skyline | bool }}" - - regex: ^swift - enabled: "{{ kolla_enable_swift | bool }}" - regex: ^tacker enabled: "{{ kolla_enable_tacker | bool }}" - regex: ^tgtd @@ -405,8 +403,6 @@ kolla_overcloud_inventory_pass_through_host_vars_default: - "kolla_api_interface" - "kolla_storage_interface" - "kolla_cluster_interface" - - "kolla_swift_storage_interface" - - "kolla_swift_replication_interface" - "kolla_provision_interface" - "kolla_inspector_dnsmasq_interface" - "kolla_dns_interface" @@ -437,8 +433,6 @@ kolla_overcloud_inventory_pass_through_host_vars_map_default: kolla_api_interface: "api_interface" kolla_storage_interface: "storage_interface" kolla_cluster_interface: "cluster_interface" - kolla_swift_storage_interface: "swift_storage_interface" - kolla_swift_replication_interface: "swift_replication_interface" kolla_provision_interface: "provision_interface" kolla_inspector_dnsmasq_interface: "ironic_dnsmasq_interface" kolla_dns_interface: "dns_interface" @@ -580,7 +574,6 @@ 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_trove: "no" kolla_enable_valkey: "no" diff --git a/ansible/inventory/group_vars/all/network b/ansible/inventory/group_vars/all/network index 61f1529cd..f5500bf91 100644 --- a/ansible/inventory/group_vars/all/network +++ b/ansible/inventory/group_vars/all/network @@ -1,12 +1,14 @@ --- +# Kayobe network configuration. + ############################################################################### # Network role to network name mappings. # Name of the network used for admin access to the overcloud admin_oc_net_name: "{{ provision_oc_net_name }}" -# Name of the network used by the overcloud hosts to manage the bare metal -# compute hosts via their out-of-band management controllers. +# Name of the network used by the seed to manage the bare metal overcloud +# hosts via their out-of-band management controllers. oob_oc_net_name: 'oob_oc_net' # Name of the network used by the seed to provision the bare metal overcloud @@ -43,12 +45,6 @@ storage_net_name: 'storage_net' # Name of the network used to carry storage management traffic. storage_mgmt_net_name: 'storage_mgmt_net' -# Name of the network used to carry swift storage data traffic. -swift_storage_net_name: "{{ storage_net_name }}" - -# Name of the network used to carry swift storage replication traffic. -swift_storage_replication_net_name: "{{ storage_mgmt_net_name }}" - # Name of the network used to perform hardware introspection on the bare metal # workload hosts. inspection_net_name: "{{ 'inspection_net' if kolla_enable_ironic | bool else None }}" @@ -58,7 +54,7 @@ inspection_net_name: "{{ 'inspection_net' if kolla_enable_ironic | bool else Non cleaning_net_name: "{{ provision_wl_net_name }}" ############################################################################### -# Network interface naming conventions. +# Network virtual patch link configuration. # Suffix for Open vSwitch bridge names. network_bridge_suffix_ovs: '-ovs' diff --git a/ansible/inventory/group_vars/all/storage b/ansible/inventory/group_vars/all/storage index df4a55d6e..fce656df8 100644 --- a/ansible/inventory/group_vars/all/storage +++ b/ansible/inventory/group_vars/all/storage @@ -13,11 +13,7 @@ storage_bootstrap_user: "{{ 'cloud-user' if os_distribution == 'centos' else os_ # List of networks to which storage nodes are attached. storage_network_interfaces: > {{ (storage_default_network_interfaces + - storage_extra_network_interfaces + - ([swift_storage_net_name] - if storage_needs_swift_network else []) + - ([swift_storage_replication_net_name] - if storage_needs_swift_replication_network else [])) | select | unique | list }} + storage_extra_network_interfaces) | select | unique | list }} # List of default networks to which storage nodes are attached. storage_default_network_interfaces: > @@ -29,15 +25,6 @@ storage_default_network_interfaces: > # List of extra networks to which storage nodes are attached. storage_extra_network_interfaces: [] -# Whether this host requires access to Swift networks. -storage_needs_swift_network: >- - {{ kolla_enable_swift | bool and - inventory_hostname in query('inventory_hostnames', swift_hosts) }} - -storage_needs_swift_replication_network: >- - {{ kolla_enable_swift | bool and - inventory_hostname in query('inventory_hostnames', swift_hosts) }} - ############################################################################### # Storage node BIOS configuration. diff --git a/ansible/inventory/group_vars/all/swift b/ansible/inventory/group_vars/all/swift deleted file mode 100644 index bd509434b..000000000 --- a/ansible/inventory/group_vars/all/swift +++ /dev/null @@ -1,67 +0,0 @@ ---- -############################################################################### -# OpenStack Swift configuration. - -# Short name of the kolla container image used to build rings. Default is the -# swift=object image. -swift_ring_build_image_name: swift-object - -# Full name of the kolla container image used to build rings. -swift_ring_build_image: "{{ kolla_docker_registry ~ '/' if kolla_docker_registry else '' }}{{ kolla_docker_namespace }}/{{ swift_ring_build_image_name }}:{{ openstack_release }}-{{ kolla_base_distro }}-{{ kolla_base_distro_version }}" - -# Ansible host pattern matching hosts on which Swift object storage services -# are deployed. The default is to use hosts in the 'storage' group. -swift_hosts: "storage" - -# Name of the host used to build Swift rings. Default is the first host of -# 'swift_hosts'. -swift_ring_build_host: "{{ query('inventory_hostnames', swift_hosts)[0] }}" - -# ID of the Swift region for this host. Default is 1. -swift_region: 1 - -# ID of the Swift zone. This can be set to different values for different hosts -# to place them in different zones. Default is 0. -swift_zone: 0 - -# Base-2 logarithm of the number of partitions. -# i.e. num_partitions=2^. Default is 10. -swift_part_power: 10 - -# Object replication count. Default is the smaller of the number of Swift -# hosts, or 3. -swift_replication_count: "{{ [query('inventory_hostnames', swift_hosts) | length, 3] | min }}" - -# Minimum time in hours between moving a given partition. Default is 1. -swift_min_part_hours: 1 - -# Ports on which Swift services listen. Default is: -# object: 6000 -# account: 6001 -# container: 6002 -swift_service_ports: - object: 6000 - account: 6001 - container: 6002 - -# List of block devices to use for Swift. Each item is a dict with the -# following items: -# - 'device': Block device path. Required. -# - 'fs_label': Name of the label used to create the file system on the device. -# Optional. Default is to use the basename of the device. -# - 'services': List of services that will use this block device. Optional. -# Default is 'swift_block_device_default_services'. Allowed items are -# 'account', 'container', and 'object'. -# - 'weight': Weight of the block device. Optional. Default is -# 'swift_block_device_default_weight'. -swift_block_devices: [] - -# Default weight to assign to block devices in the ring. Default is 100. -swift_block_device_default_weight: 100 - -# Default list of services to assign block devices to. Allowed items are -# 'account', 'container', and 'object'. Default value is all of these. -swift_block_device_default_services: - - account - - container - - object diff --git a/ansible/kolla-ansible.yml b/ansible/kolla-ansible.yml index 07514a63d..7542f1a79 100644 --- a/ansible/kolla-ansible.yml +++ b/ansible/kolla-ansible.yml @@ -204,14 +204,6 @@ description: "Cluster network" network: "{{ storage_mgmt_net_name }}" required: False - - var_name: "kolla_swift_storage_interface" - description: "Swift storage network" - network: "{{ swift_storage_net_name }}" - required: False - - var_name: "kolla_swift_replication_interface" - description: "Swift storage replication network" - network: "{{ swift_storage_replication_net_name }}" - required: False - var_name: "kolla_provision_interface" description: "Bare metal provisioning network" network: "{{ provision_wl_net_name }}" diff --git a/ansible/overcloud-etc-hosts-fixup.yml b/ansible/overcloud-etc-hosts-fixup.yml index aed231139..6c10a69fe 100644 --- a/ansible/overcloud-etc-hosts-fixup.yml +++ b/ansible/overcloud-etc-hosts-fixup.yml @@ -7,8 +7,19 @@ # which it is listening. As a workaround, we remove the stale entries from # /etc/hosts. See https://github.com/stackhpc/kayobe/issues/14. -- name: Ensure overcloud hosts' /etc/hosts does not contain incorrect IPs +- name: Collect hosts to map through to kolla-ansible hosts: overcloud + gather_facts: false + tags: + - etc-hosts-fixup + tasks: + - name: Group by kolla_overcloud_inventory_pass_through_enabled + ansible.builtin.group_by: + key: "kolla_mapped_overcloud_host_{{ kolla_overcloud_inventory_pass_through_enabled }}" + changed_when: false + +- name: Ensure overcloud hosts' /etc/hosts does not contain incorrect IPs + hosts: kolla_mapped_overcloud_host_True max_fail_percentage: >- {{ overcloud_etc_hosts_fixup_max_fail_percentage | default(kayobe_max_fail_percentage) | @@ -28,7 +39,7 @@ become: True - name: Ensure rabbitmq containers' /etc/hosts does not contain incorrect IPs - hosts: overcloud + hosts: kolla_mapped_overcloud_host_True max_fail_percentage: >- {{ overcloud_etc_hosts_fixup_max_fail_percentage | default(kayobe_max_fail_percentage) | diff --git a/ansible/overcloud-host-configure.yml b/ansible/overcloud-host-configure.yml index e485720b6..568899655 100644 --- a/ansible/overcloud-host-configure.yml +++ b/ansible/overcloud-host-configure.yml @@ -31,6 +31,5 @@ - import_playbook: "kolla-target-venv.yml" - import_playbook: "container-engine.yml" - import_playbook: "apparmor-libvirt.yml" -- import_playbook: "swift-block-devices.yml" - import_playbook: "compute-libvirt-host.yml" - import_playbook: "vgpu.yml" diff --git a/ansible/physical-network.yml b/ansible/physical-network.yml index 8891a62c5..9cdc4de6d 100644 --- a/ansible/physical-network.yml +++ b/ansible/physical-network.yml @@ -28,7 +28,9 @@ physical_network_display: False # List of supported values for the 'switch_type' variable. supported_switch_types: + - alliedware-plus - arista + - cisco-nxos - dellos6 - dellos9 - dellos10 @@ -109,6 +111,22 @@ debug: var: switch_interface_config +- name: Ensure AlliedWare Plus physical switches are configured + hosts: switches_of_type_alliedware-plus:&switches_in_display_mode_False + gather_facts: no + max_fail_percentage: >- + {{ physical_network_max_fail_percentage | + default(kayobe_max_fail_percentage) | + default(100) }} + roles: + - role: ssh-known-host + when: not switch_skip_keyscan | bool + + - role: alliedware-plus-switch + alliedware_plus_switch_config: "{{ switch_config }}" + alliedware_plus_switch_interface_config: "{{ switch_interface_config }}" + alliedware_plus_switch_save: "{{ switch_config_save }}" + - name: Ensure Arista physical switches are configured hosts: switches_of_type_arista:&switches_in_display_mode_False gather_facts: no @@ -126,6 +144,22 @@ arista_switch_config: "{{ switch_config }}" arista_switch_interface_config: "{{ switch_interface_config }}" +- name: Ensure Cisco NX-OS physical switches are configured + hosts: switches_of_type_cisco-nxos:&switches_in_display_mode_False + gather_facts: no + max_fail_percentage: >- + {{ physical_network_max_fail_percentage | + default(kayobe_max_fail_percentage) | + default(100) }} + roles: + - role: ssh-known-host + when: not switch_skip_keyscan | bool + + - role: cisco-nxos-switch + cisco_nxos_switch_config: "{{ switch_config }}" + cisco_nxos_switch_interface_config: "{{ switch_interface_config }}" + cisco_nxos_switch_save: "{{ switch_config_save }}" + - name: Ensure DellOS physical switches are configured hosts: switches_of_type_dellos6:switches_of_type_dellos9:switches_of_type_dellos10:&switches_in_display_mode_False gather_facts: no diff --git a/ansible/roles/alliedware-plus-switch/README.md b/ansible/roles/alliedware-plus-switch/README.md new file mode 100644 index 000000000..4b5290336 --- /dev/null +++ b/ansible/roles/alliedware-plus-switch/README.md @@ -0,0 +1,79 @@ +AlliedWare Plus Switch +====================== + +This role configures AlliedWare Plus switches using the +`alliedtelesis.awplus.awplus_config` Ansible module. It provides a fairly +minimal abstraction of the configuration interface provided by the +`awplus_config` module, allowing for application of arbitrary switch +configuration options. + +Requirements +------------ + +The switches should be configured to allow SSH access. + +The `alliedtelesis.awplus` Ansible collection must be installed. + +Role Variables +-------------- + +`alliedware_plus_switch_config` is a list of configuration lines to apply to +the switch, and defaults to an empty list. + +`alliedware_plus_switch_interface_config` contains interface configuration. It +is a dict mapping switch interface names to configuration dicts, and defaults +to an empty dict. Each dict may contain the following items: + +- `description` - an optional description to apply to the interface. +- `config` - a list of per-interface configuration commands. + +`alliedware_plus_switch_save` controls whether the running configuration is +saved to the startup configuration when they differ, including any previously +unsaved changes. Defaults to `false`. + +Dependencies +------------ + +None + +Example Playbook +---------------- + +The following playbook configures hosts in the `alliedware-plus-switches` +group. It assumes host variables for each switch holding the host and SSH +credentials. + + --- + - name: Ensure AlliedWare Plus switches are configured + hosts: alliedware-plus-switches + gather_facts: no + vars: + ansible_connection: ansible.netcommon.network_cli + ansible_network_os: alliedtelesis.awplus.awplus + roles: + - role: alliedware-plus-switch + alliedware_plus_switch_config: + - "vlan database" + - " vlan 1000,1001 state enable" + alliedware_plus_switch_interface_config: + port1.0.1: + description: server-1 + config: + - "no shutdown" + - "switchport" + - "switchport mode trunk" + - "switchport trunk native vlan 1000" + - "switchport trunk allowed vlan add 1001" + port1.0.2: + description: server-2 + config: + - "no shutdown" + - "switchport" + - "switchport mode trunk" + - "switchport trunk native vlan 1000" + - "switchport trunk allowed vlan add 1001" + +Author Information +------------------ + +- Pierre Riteau () diff --git a/ansible/roles/alliedware-plus-switch/defaults/main.yml b/ansible/roles/alliedware-plus-switch/defaults/main.yml new file mode 100644 index 000000000..3a1e6556c --- /dev/null +++ b/ansible/roles/alliedware-plus-switch/defaults/main.yml @@ -0,0 +1,11 @@ +--- +# List of configuration lines to apply to the switch. +alliedware_plus_switch_config: [] + +# Interface configuration. Dict mapping switch interface names to configuration +# dicts. Each dict contains an optional 'description' item and a 'config' item +# which should contain a list of per-interface configuration. +alliedware_plus_switch_interface_config: {} + +# Whether to save the configuration. +alliedware_plus_switch_save: false diff --git a/ansible/roles/alliedware-plus-switch/tasks/main.yml b/ansible/roles/alliedware-plus-switch/tasks/main.yml new file mode 100644 index 000000000..ceb0d434c --- /dev/null +++ b/ansible/roles/alliedware-plus-switch/tasks/main.yml @@ -0,0 +1,6 @@ +--- +- name: Ensure AlliedWare Plus switches are configured + alliedtelesis.awplus.awplus_config: + lines: "{{ lookup('template', 'alliedware-plus-config.j2') }}" + save_when: >- + {{ alliedware_plus_switch_save | bool | ternary('modified', 'never') }} diff --git a/ansible/roles/alliedware-plus-switch/templates/alliedware-plus-config.j2 b/ansible/roles/alliedware-plus-switch/templates/alliedware-plus-config.j2 new file mode 100644 index 000000000..e1138bb9e --- /dev/null +++ b/ansible/roles/alliedware-plus-switch/templates/alliedware-plus-config.j2 @@ -0,0 +1,15 @@ +#jinja2: trim_blocks: True,lstrip_blocks: True + +{% for line in alliedware_plus_switch_config %} +{{ line }} +{% endfor %} + +{% for interface, config in alliedware_plus_switch_interface_config.items() %} +interface {{ interface }} +{% if config.description is defined %} + description {{ config.description }} +{% endif %} +{% for line in config.config %} + {{ line }} +{% endfor %} +{% endfor %} diff --git a/ansible/roles/cisco-nxos-switch/README.md b/ansible/roles/cisco-nxos-switch/README.md new file mode 100644 index 000000000..e51f59cdd --- /dev/null +++ b/ansible/roles/cisco-nxos-switch/README.md @@ -0,0 +1,59 @@ +Cisco NX-OS Switch +================== + +This role configures Cisco NX-OS switches using the `cisco.nxos.nxos_config` +Ansible module. It allows global and per-interface configuration commands to +be applied to the switch. + +Requirements +------------ + +The switches should be configured to allow SSH access. + +The `cisco.nxos` Ansible collection must be installed. + +Role Variables +-------------- + +`cisco_nxos_switch_config` is a list of configuration lines to apply to the +switch, and defaults to an empty list. + +`cisco_nxos_switch_interface_config` is a dict mapping switch interface names +to configuration dicts, and defaults to an empty dict. Each dict contains: + +- `description` - an optional description to apply to the interface. +- `config` - a list of per-interface configuration commands. + +`cisco_nxos_switch_save` controls whether the running configuration is saved +to the startup configuration when they differ, including any previously unsaved +changes. Defaults to `false`. + +Dependencies +------------ + +None + +Example Playbook +---------------- + +The following playbook configures hosts in the `cisco-nxos-switches` group. +It assumes host variables for each switch holding the host and SSH credentials. +It enables LLDP and configures an Ethernet interface as a switchport. + + --- + - name: Ensure Cisco NX-OS switches are configured + hosts: cisco-nxos-switches + gather_facts: no + vars: + ansible_connection: ansible.netcommon.network_cli + ansible_network_os: cisco.nxos.nxos + roles: + - role: cisco-nxos-switch + cisco_nxos_switch_config: + - "feature lldp" + cisco_nxos_switch_interface_config: + Ethernet1/1: + description: server-1 + config: + - "switchport" + - "switchport mode access" diff --git a/ansible/roles/cisco-nxos-switch/defaults/main.yml b/ansible/roles/cisco-nxos-switch/defaults/main.yml new file mode 100644 index 000000000..8356cac5a --- /dev/null +++ b/ansible/roles/cisco-nxos-switch/defaults/main.yml @@ -0,0 +1,11 @@ +--- +# List of configuration lines to apply to the switch. +cisco_nxos_switch_config: [] + +# Interface configuration. Dict mapping switch interface names to configuration +# dicts. Each dict contains an optional 'description' item and a 'config' item +# which should contain a list of per-interface configuration. +cisco_nxos_switch_interface_config: {} + +# Whether to save the configuration. +cisco_nxos_switch_save: false diff --git a/ansible/roles/cisco-nxos-switch/tasks/main.yml b/ansible/roles/cisco-nxos-switch/tasks/main.yml new file mode 100644 index 000000000..beb5cd07b --- /dev/null +++ b/ansible/roles/cisco-nxos-switch/tasks/main.yml @@ -0,0 +1,6 @@ +--- +- name: Ensure Cisco NX-OS switches are configured + cisco.nxos.nxos_config: + content: "{{ lookup('template', 'cisco-nxos-config.j2') }}" + save_when: >- + {{ cisco_nxos_switch_save | bool | ternary('modified', 'never') }} diff --git a/ansible/roles/cisco-nxos-switch/templates/cisco-nxos-config.j2 b/ansible/roles/cisco-nxos-switch/templates/cisco-nxos-config.j2 new file mode 100644 index 000000000..d219991f9 --- /dev/null +++ b/ansible/roles/cisco-nxos-switch/templates/cisco-nxos-config.j2 @@ -0,0 +1,16 @@ +#jinja2: trim_blocks: True,lstrip_blocks: True + +{% for line in cisco_nxos_switch_config %} +{{ line }} +{% endfor %} + +{% for interface, config in cisco_nxos_switch_interface_config.items() %} +interface {{ interface }} +{% if config.description is defined %} + description {{ config.description }} +{% endif %} +{% for line in config.config %} + {{ line }} +{% endfor %} +! +{% endfor %} diff --git a/ansible/roles/dell-switch/handlers/main.yml b/ansible/roles/dell-switch/handlers/main.yml new file mode 100644 index 000000000..cb37f2201 --- /dev/null +++ b/ansible/roles/dell-switch/handlers/main.yml @@ -0,0 +1,15 @@ +--- +- name: Save DellOS6 running-config to startup-config + dellemc.os6.os6_config: # noqa fqcn[canonical] + save: true + when: dell_switch_save | bool + +- name: Save DellOS9 running-config to startup-config + dellemc.os9.os9_config: # noqa fqcn[canonical] + save: true + when: dell_switch_save | bool + +- name: Save DellOS10 running-config to startup-config + dellemc.os10.os10_config: # noqa fqcn[canonical] + save: true + when: dell_switch_save | bool diff --git a/ansible/roles/dell-switch/tasks/main.yml b/ansible/roles/dell-switch/tasks/main.yml index 2f7620ee8..c9f7aa86d 100644 --- a/ansible/roles/dell-switch/tasks/main.yml +++ b/ansible/roles/dell-switch/tasks/main.yml @@ -2,17 +2,17 @@ - name: Ensure DellOS6 switches are configured dellemc.os6.os6_config: # noqa fqcn[canonical] src: "../templates/dellos6-config.j2" - save: "{{ dell_switch_save | bool }}" + notify: Save DellOS6 running-config to startup-config when: dell_switch_type == 'dellos6' - name: Ensure DellOS9 switches are configured dellemc.os9.os9_config: # noqa fqcn[canonical] src: "../templates/dellos9-config.j2" - save: "{{ dell_switch_save | bool }}" + notify: Save DellOS9 running-config to startup-config when: dell_switch_type == 'dellos9' - name: Ensure DellOS10 switches are configured dellemc.os10.os10_config: # noqa fqcn[canonical] src: "../templates/dellos10-config.j2" - save: "{{ dell_switch_save | bool }}" + notify: Save DellOS10 running-config to startup-config when: dell_switch_type == 'dellos10' diff --git a/ansible/roles/dell-switch/templates/dellos10-config.j2 b/ansible/roles/dell-switch/templates/dellos10-config.j2 index 7904f89c6..1aa4b212d 100644 --- a/ansible/roles/dell-switch/templates/dellos10-config.j2 +++ b/ansible/roles/dell-switch/templates/dellos10-config.j2 @@ -4,13 +4,28 @@ {{ line }} {% endfor %} +{# Configure VLAN interfaces first as others might depend on them. #} + {% for interface, config in dell_switch_interface_config.items() %} +{% if 'vlan' in interface %} interface {{ interface }} {% if config.description is defined %} -description "{{ config.description }}" + description {{ ('"' ~ config.description ~ '"') if ' ' in config.description else config.description }} {% endif %} {% for line in config.config %} -{{ line }} + {{ line }} +{% endfor %} +{% endif %} +{% endfor %} + +{% for interface, config in dell_switch_interface_config.items() %} +{% if 'vlan' not in interface %} +interface {{ interface }} +{% if config.description is defined %} + description {{ ('"' ~ config.description ~ '"') if ' ' in config.description else config.description }} +{% endif %} +{% for line in config.config %} + {{ line }} {% endfor %} -exit +{% endif %} {% endfor %} diff --git a/ansible/roles/dell-switch/templates/dellos9-config.j2 b/ansible/roles/dell-switch/templates/dellos9-config.j2 index 6108e9a0d..422116269 100644 --- a/ansible/roles/dell-switch/templates/dellos9-config.j2 +++ b/ansible/roles/dell-switch/templates/dellos9-config.j2 @@ -10,14 +10,13 @@ {% for interface, config in dell_switch_interface_config.items() %} {% if 'vlan' not in interface %} - interface {{ interface }} +interface {{ interface }} {% if config.description is defined %} description "{{ config.description }}" {% endif %} {% for line in config.config %} {{ line }} {% endfor %} - exit {% endif %} {% endfor %} @@ -30,6 +29,5 @@ interface {{ interface }} {% for line in config.config %} {{ line }} {% endfor %} - exit {% endif %} {% endfor %} diff --git a/ansible/roles/firewalld/tasks/enabled.yml b/ansible/roles/firewalld/tasks/enabled.yml index 1ab86bcd6..4428c8b27 100644 --- a/ansible/roles/firewalld/tasks/enabled.yml +++ b/ansible/roles/firewalld/tasks/enabled.yml @@ -13,6 +13,23 @@ state: started become: true +# NOTE: The firewalld Ansible module decides whether to use online or offline +# (on-disk only) operations when it is imported, based on whether the firewalld +# D-Bus interface is available. Starting the service does not guarantee that +# the interface is ready yet, so if the first zone is created too early it is +# written to disk only and is not loaded into the running daemon. A subsequent +# attempt to assign an interface to that zone then fails with +# 'INVALID_ZONE'. Wait until firewalld can be queried before configuring it. +- name: Wait for firewalld to be ready + command: + cmd: firewall-cmd --state + register: firewalld_state + until: firewalld_state.rc == 0 + retries: 30 + delay: 1 + changed_when: false + become: true + - block: - name: Get firewalld current default zone command: diff --git a/ansible/roles/ipa-images/tasks/set-driver-info.yml b/ansible/roles/ipa-images/tasks/set-driver-info.yml index 6ddcbc89e..b416438f3 100644 --- a/ansible/roles/ipa-images/tasks/set-driver-info.yml +++ b/ansible/roles/ipa-images/tasks/set-driver-info.yml @@ -64,6 +64,6 @@ --driver-info deploy_ramdisk={{ ipa_images_ramdisk_uuid }} with_items: "{{ ipa_images_ironic_nodes }}" when: - item["driver_info"].deploy_kernel != ipa_images_kernel_uuid or - item["driver_info"].deploy_ramdisk != ipa_images_ramdisk_uuid + item["driver_info"].deploy_kernel | default("UNSET") != ipa_images_kernel_uuid or + item["driver_info"].deploy_ramdisk | default("UNSET") != ipa_images_ramdisk_uuid environment: "{{ ipa_images_ironic_openstack_auth_env }}" diff --git a/ansible/roles/kolla-ansible-host-vars/tests/test.yml b/ansible/roles/kolla-ansible-host-vars/tests/test.yml index 4ff5d56ef..d211e9424 100644 --- a/ansible/roles/kolla-ansible-host-vars/tests/test.yml +++ b/ansible/roles/kolla-ansible-host-vars/tests/test.yml @@ -20,8 +20,6 @@ kolla_provision_interface: "eth8" kolla_inspector_dnsmasq_interface: "eth9" kolla_tunnel_interface: "eth10" - kolla_swift_storage_interface: "eth13" - kolla_swift_replication_interface: "eth14" - name: Add a compute host to the inventory add_host: @@ -61,8 +59,6 @@ - "kolla_api_interface" - "kolla_storage_interface" - "kolla_cluster_interface" - - "kolla_swift_storage_interface" - - "kolla_swift_replication_interface" - "kolla_provision_interface" - "kolla_inspector_dnsmasq_interface" - "kolla_dns_interface" @@ -76,8 +72,6 @@ kolla_api_interface: "api_interface" kolla_storage_interface: "storage_interface" kolla_cluster_interface: "cluster_interface" - kolla_swift_storage_interface: "swift_storage_interface" - kolla_swift_replication_interface: "swift_replication_interface" kolla_provision_interface: "provision_interface" kolla_inspector_dnsmasq_interface: "ironic_dnsmasq_interface" kolla_dns_interface: "dns_interface" @@ -120,8 +114,6 @@ api_interface: "eth2" storage_interface: "eth3" cluster_interface: "eth4" - swift_storage_interface: "eth13" - swift_replication_interface: "eth14" provision_interface: "eth8" ironic_dnsmasq_interface: "eth9" dns_interface: "eth5" diff --git a/ansible/roles/kolla-ansible/defaults/main.yml b/ansible/roles/kolla-ansible/defaults/main.yml index ad5b08b89..a044b5d53 100644 --- a/ansible/roles/kolla-ansible/defaults/main.yml +++ b/ansible/roles/kolla-ansible/defaults/main.yml @@ -39,6 +39,17 @@ kolla_ansible_core_requirements_yml: "{{ kolla_ansible_venv }}/share/kolla-ansib # If None, custom collections are not installed. kolla_ansible_custom_requirements_paths: +# Path to the Ansible configuration file used when installing Ansible +# collections for Kolla Ansible. Kayobe supports a Kolla Ansible-specific +# configuration file at $KAYOBE_CONFIG_PATH/kolla/ansible.cfg, falling back +# to $KAYOBE_CONFIG_PATH/ansible.cfg. If neither exists, the value of the +# ANSIBLE_CONFIG environment variable is used. +kolla_ansible_ansible_config: >- + {%- set config_path = kayobe_config_path | default('/etc/kayobe') -%} + {%- set kolla_config = config_path ~ '/kolla/ansible.cfg' -%} + {%- set kayobe_config = config_path ~ '/ansible.cfg' -%} + {{ kolla_config if kolla_config is file else (kayobe_config if kayobe_config is file else lookup('env', 'ANSIBLE_CONFIG')) }} + # 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: @@ -243,7 +254,6 @@ kolla_openstack_logging_debug: #kolla_enable_neutron_agent_ha: #kolla_enable_neutron_vpnaas: #kolla_enable_prometheus: -#kolla_enable_swift: #kolla_enable_watcher: ####################### diff --git a/ansible/roles/kolla-ansible/tasks/install.yml b/ansible/roles/kolla-ansible/tasks/install.yml index a271b7bf4..4411b975b 100644 --- a/ansible/roles/kolla-ansible/tasks/install.yml +++ b/ansible/roles/kolla-ansible/tasks/install.yml @@ -128,6 +128,11 @@ ANSIBLE_COLLECTIONS_SCAN_SYS_PATH: "False" # NOTE(wszumski): Don't use path configured for kayobe ANSIBLE_COLLECTIONS_PATH: '' + # NOTE(wszumski): Set the Ansible configuration file explicitly. The + # ansible-galaxy subprocess does not reliably pick up a custom Galaxy + # server list otherwise, since it is run from a different working + # directory to the parent ansible-playbook. + ANSIBLE_CONFIG: "{{ kolla_ansible_ansible_config }}" when: not kolla_ansible_venv_ansible - name: Ensure Ansible collections are installed @@ -142,6 +147,9 @@ ANSIBLE_COLLECTIONS_SCAN_SYS_PATH: "False" # NOTE(wszumski): Don't use path configured for kayobe ANSIBLE_COLLECTIONS_PATH: '' + # NOTE(wszumski): Set the Ansible configuration file explicitly. See the + # comment on the core collections task above. + ANSIBLE_CONFIG: "{{ kolla_ansible_ansible_config }}" - name: Check for custom Ansible collections requirements files stat: @@ -165,6 +173,9 @@ ANSIBLE_COLLECTIONS_SCAN_SYS_PATH: "False" # NOTE(wszumski): Don't use path configured for kayobe ANSIBLE_COLLECTIONS_PATH: '' + # NOTE(wszumski): Set the Ansible configuration file explicitly. See the + # comment on the core collections task above. + ANSIBLE_CONFIG: "{{ kolla_ansible_ansible_config }}" 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 ce4dd1f76..ddd18b2b7 100644 --- a/ansible/roles/kolla-ansible/templates/kolla/globals.yml +++ b/ansible/roles/kolla-ansible/templates/kolla/globals.yml @@ -109,8 +109,6 @@ docker_registry_username: "{{ kolla_docker_registry_username }}" #api_address_family: "{% raw %}{{ network_address_family }}{% endraw %}" #storage_address_family: "{% raw %}{{ network_address_family }}{% endraw %}" #cluster_address_family: "{% raw %}{{ network_address_family }}{% endraw %}" -#swift_storage_address_family: "{% raw %}{{ storage_address_family }}{% endraw %}" -#swift_replication_address_family: "{% raw %}{{ swift_storage_address_family }}{% endraw %}" #migration_address_family: "{% raw %}{{ network_address_family }}{% endraw %}" #tunnel_address_family: "{% raw %}{{ network_address_family }}{% endraw %}" #octavia_network_address_family: "{% raw %}{{ api_address_family }}{% endraw %}" @@ -284,7 +282,6 @@ enable_{{ feature_flag }}: {{ hostvars[inventory_hostname]['kolla_enable_' ~ fea # Configure image backend. #glance_backend_ceph: "no" #glance_backend_file: "yes" -#glance_backend_swift: "no" #glance_backend_vmware: "no" #enable_glance_image_cache: "no" # Configure glance upgrade option. @@ -324,7 +321,7 @@ enable_{{ feature_flag }}: {{ hostvars[inventory_hostname]['kolla_enable_' ~ fea # Valid options are [ '', redis, etcd ] #cinder_coordination_backend: "{% raw %}{{ 'redis' if enable_redis|bool else 'etcd' if enable_etcd|bool else '' }}{% endraw %}" -# Valid options are [ nfs, swift, ceph ] +# Valid options are [ nfs, ceph, s3 ] #cinder_backup_driver: "ceph" #cinder_backup_share: "" #cinder_backup_mount_options_nfs: "" @@ -431,31 +428,6 @@ ironic_kernel_cmdline_extras: #hnas_evs_ip: #hnas_file_system_name: -################################ -# Swift - Object Storage Options -################################ -# Swift expects block devices to be available for storage. Two types of storage -# are supported: 1 - storage device with a special partition name and filesystem -# label, 2 - unpartitioned disk with a filesystem. The label of this filesystem -# is used to detect the disk which Swift will be using. - -# Swift support two matching modes, valid options are [ prefix, strict ] -#swift_devices_match_mode: "strict" - -# This parameter defines matching pattern: if "strict" mode was selected, -# for swift_devices_match_mode then swift_device_name should specify the name of -# the special swift partition for example: "KOLLA_SWIFT_DATA", if "prefix" mode was -# selected then swift_devices_name should specify a pattern which would match to -# filesystems' labels prepared for swift. -#swift_devices_name: "KOLLA_SWIFT_DATA" - -# Configure swift upgrade option, due to currently kolla support -# two upgrade ways for swift: legacy_upgrade and rolling_upgrade -# The variable "swift_enable_rolling_upgrade: yes" is meaning rolling_upgrade -# were enabled and opposite -# Rolling upgrade were enable by default -#swift_enable_rolling_upgrade: "yes" - ################################### # VMware - OpenStack VMware support ################################### diff --git a/ansible/roles/kolla-ansible/tests/test-extras.yml b/ansible/roles/kolla-ansible/tests/test-extras.yml index 6b10ae794..e3c8f784e 100644 --- a/ansible/roles/kolla-ansible/tests/test-extras.yml +++ b/ansible/roles/kolla-ansible/tests/test-extras.yml @@ -196,7 +196,6 @@ kolla_enable_osprofiler: True kolla_enable_prometheus: True kolla_enable_skyline: True - kolla_enable_swift: True kolla_enable_tacker: True kolla_enable_trove: True kolla_enable_watcher: True @@ -306,7 +305,6 @@ #enable_osprofiler: True #enable_prometheus: True #enable_skyline: True - #enable_swift: True #enable_tacker: True #enable_trove: True #enable_watcher: True @@ -334,8 +332,6 @@ - kolla_external_vip_interface - storage_interface - cluster_interface - - swift_storage_interface - - swift_replication_interface - provision_interface - ironic_dnsmasq_interface - dns_interface diff --git a/ansible/roles/kolla-openstack/defaults/main.yml b/ansible/roles/kolla-openstack/defaults/main.yml index b87b54566..3b63e766d 100644 --- a/ansible/roles/kolla-openstack/defaults/main.yml +++ b/ansible/roles/kolla-openstack/defaults/main.yml @@ -146,8 +146,6 @@ kolla_openstack_custom_config_include_globs_default: glob: placement/** - enabled: '{{ kolla_enable_prometheus | bool }}' glob: prometheus/** - - enabled: '{{ kolla_enable_swift | bool }}' - glob: swift/** - enabled: '{{ kolla_enable_watcher | bool }}' glob: watcher.conf - enabled: '{{ kolla_enable_watcher | bool }}' @@ -215,12 +213,6 @@ kolla_openstack_custom_config_rules_default: - glob: ironic/ironic-agent.kernel strategy: copy priority: 1000 - - glob: swift/*.builder - strategy: copy - priority: 1000 - - glob: swift/*.ring.gz - strategy: copy - priority: 1000 - glob: '**/*.pem' strategy: copy priority: 1000 @@ -608,13 +600,6 @@ kolla_inspector_ipa_ramdisk_path: # kolla_inspector_ipa_ramdisk_path is set. kolla_inspector_ipa_host: -# Whether to enable the Swift introspection data store. -kolla_inspector_enable_swift: - -# Dict of authentication parameters for accessing the Swift introspection data -# store. -kolla_inspector_swift_auth: {} - # Deprecated: # Free form extra configuration to append to ironic-inspector.conf. kolla_extra_inspector: @@ -794,12 +779,6 @@ kolla_extra_placement: # Whether to enable Prometheus. kolla_enable_prometheus: false -############################################################################### -# Swift configuration. - -# Whether to enable swift. -kolla_enable_swift: false - ############################################################################### # Watcher configuration. diff --git a/ansible/roles/kolla-openstack/molecule/default/tests/test_default.py b/ansible/roles/kolla-openstack/molecule/default/tests/test_default.py index 086841cfe..1c3e2f3d1 100644 --- a/ansible/roles/kolla-openstack/molecule/default/tests/test_default.py +++ b/ansible/roles/kolla-openstack/molecule/default/tests/test_default.py @@ -46,8 +46,7 @@ 'masakari', 'neutron', 'nova', - 'prometheus', - 'swift']) + 'prometheus']) def test_service_config_directory_absent(host, path): path = os.path.join('/etc/kolla/config', path) utils.test_path_absent(host, path) diff --git a/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml b/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml index 6bd7da34d..5b1e38736 100644 --- a/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml +++ b/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml @@ -135,7 +135,6 @@ provisioner: [extra-placement.conf] foo=bar kolla_enable_prometheus: true - kolla_enable_swift: true kolla_enable_telegraf: true kolla_enable_watcher: true lint: diff --git a/ansible/roles/swift-block-devices/defaults/main.yml b/ansible/roles/swift-block-devices/defaults/main.yml deleted file mode 100644 index 55c0f0562..000000000 --- a/ansible/roles/swift-block-devices/defaults/main.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -# Label used to create partitions. This is used by kolla-ansible to determine -# which disks to mount. -swift_block_devices_part_label: KOLLA_SWIFT_DATA - -# List of block devices to use for Swift. Each item is a dict with the -# following items: -# - 'device': Block device path. Required. -# - 'fs_label': Name of the label used to create the file system on the device. -# Optional. Default is to use the basename of the device. -swift_block_devices: [] diff --git a/ansible/roles/swift-block-devices/tasks/main.yml b/ansible/roles/swift-block-devices/tasks/main.yml deleted file mode 100644 index 1da9979fa..000000000 --- a/ansible/roles/swift-block-devices/tasks/main.yml +++ /dev/null @@ -1,73 +0,0 @@ ---- -- name: Fail if swift_block_devices is not in the expected format - fail: - msg: >- - Device {{ device_index }} in swift_block_devices is in an invalid format. - Items should be a dict, containing at least a 'device' field. - with_items: "{{ swift_block_devices }}" - when: item is not mapping or 'device' not in item - loop_control: - index_var: device_index - -- name: Ensure required packages are installed - package: - name: - - parted - - xfsprogs - 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 - when: swift_block_devices | length > 0 - -- name: Check the presence of a partition on the Swift block devices - become: True - parted: - device: "{{ item.device }}" - with_items: "{{ swift_block_devices }}" - loop_control: - label: "{{ item.device }}" - register: swift_disk_info - -- name: Fail if the Swift block devices have already a partition - fail: - msg: > - The physical disk {{ item.item.device }} already has a partition. - Ensure that each disk in 'swift_block_devices' does not have any - partitions. - with_items: "{{ swift_disk_info.results }}" - when: - - item.partitions | length > 0 - - item.partitions.0.name != swift_block_devices_part_label - loop_control: - label: "{{ item.item.device }}" - -- name: Ensure partitions exist for Swift block device - become: True - parted: - device: "{{ item.item.device }}" - number: 1 - label: gpt - name: "{{ swift_block_devices_part_label }}" - state: present - with_items: "{{ swift_disk_info.results }}" - when: item.partitions | length == 0 - loop_control: - label: "{{ item.item.device }}" - -- name: Ensure Swift XFS file systems exist - become: true - filesystem: - dev: "{{ partition_name }}" - force: true - fstype: xfs - opts: "-L {{ fs_label }}" - with_items: "{{ swift_disk_info.results }}" - when: item.partitions | length == 0 - loop_control: - label: "{{ device }}" - index_var: index - vars: - device: "{{ item.item.device }}" - partition_name: "{{ device }}{% if device.startswith('/dev/loop') %}p{% endif %}1" - fs_label: "{{ item.item.fs_label | default(device | basename) }}" diff --git a/ansible/roles/swift-block-devices/tests/main.yml b/ansible/roles/swift-block-devices/tests/main.yml deleted file mode 100644 index 853028045..000000000 --- a/ansible/roles/swift-block-devices/tests/main.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -- import_playbook: test-invalid-format.yml -- import_playbook: test-mount.yml -- import_playbook: test-bootstrapped.yml - -- hosts: localhost - connection: local - tasks: - - name: Fail if any tests failed - fail: - msg: > - Test failures: {{ test_failures }} - when: test_failures is defined diff --git a/ansible/roles/swift-block-devices/tests/test-bootstrapped.yml b/ansible/roles/swift-block-devices/tests/test-bootstrapped.yml deleted file mode 100644 index 577b19ab7..000000000 --- a/ansible/roles/swift-block-devices/tests/test-bootstrapped.yml +++ /dev/null @@ -1,69 +0,0 @@ ---- -# Test case with one device that has already been partitioned. - -- hosts: localhost - connection: local - tasks: - - name: Allocate a temporary file for a fake device - tempfile: - register: tempfile - - - name: Allocate a fake device file - command: fallocate -l 350M {{ tempfile.path }} - - - name: Find a free loopback device - command: losetup -f - register: loopback - become: true - - - name: Create a loopback device - command: losetup {{ loopback.stdout }} {{ tempfile.path }} - become: true - - - name: Add a partition - become: True - parted: - device: "{{ loopback.stdout }}" - number: 1 - label: gpt - name: KOLLA_SWIFT_DATA - state: present - - - block: - - name: Test the swift-block-devices role - include_role: - name: ../../swift-block-devices - vars: - swift_block_devices: - - device: "{{ loopback.stdout }}" - apt_cache_valid_time: 3600 - - - name: Get name of fake partition - parted: - device: "{{ loopback.stdout }}" - register: "disk_info" - become: True - - - name: Validate number of partition - assert: - that: disk_info.partitions | length == 1 - msg: > - Number of partitions is not correct. - - - name: Validate partition label is present - assert: - that: "disk_info.partitions.0.name == 'KOLLA_SWIFT_DATA'" - msg: > - Name of partition is not correct. - - always: - - name: Remove the fake file - file: - name: "{{ loopback.stdout }}" - state: absent - become: true - - rescue: - - name: Flag that a failure occurred - set_fact: - test_failures: "{{ test_failures | default(0) | int + 1 }}" diff --git a/ansible/roles/swift-block-devices/tests/test-invalid-format.yml b/ansible/roles/swift-block-devices/tests/test-invalid-format.yml deleted file mode 100644 index 22df7be5e..000000000 --- a/ansible/roles/swift-block-devices/tests/test-invalid-format.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- -# Test case with swift_block_devices in an invalid format. - -- hosts: localhost - connection: local - tasks: - - block: - - name: Test the swift-block-devices role - include_role: - name: ../../swift-block-devices - vars: - swift_block_devices: - - /dev/fake - apt_cache_valid_time: 3600 - - rescue: - - name: Flag that the error was raised - set_fact: - raised_error: true - - - name: Flag that a failure occurred - set_fact: - test_failures: "{{ test_failures | default(0) | int + 1 }}" - when: raised_error is not defined diff --git a/ansible/roles/swift-block-devices/tests/test-mount.yml b/ansible/roles/swift-block-devices/tests/test-mount.yml deleted file mode 100644 index 5489160d9..000000000 --- a/ansible/roles/swift-block-devices/tests/test-mount.yml +++ /dev/null @@ -1,61 +0,0 @@ ---- -# Test case with one device that has not yet been tagged by kayobe with the -# kolla-ansible bootstrap label. - -- hosts: localhost - connection: local - tasks: - - name: Allocate a temporary file for a fake device - tempfile: - register: tempfile - - - name: Allocate a fake device file - command: fallocate -l 350M {{ tempfile.path }} - - - name: Find a free loopback device - command: losetup -f - register: loopback - become: true - - - name: Create a loopback device - command: losetup {{ loopback.stdout }} {{ tempfile.path }} - become: true - - - block: - - name: Test the swift-block-devices role - include_role: - name: ../../swift-block-devices - vars: - swift_block_devices: - - device: "{{ loopback.stdout }}" - apt_cache_valid_time: 3600 - - - name: Get name of fake partition - parted: - device: "{{ loopback.stdout }}" - register: "disk_info" - become: True - - - name: Validate number of partition - assert: - that: disk_info.partitions | length == 1 - msg: > - Number of partitions is not correct. - - - name: Validate partition label is present - assert: - that: "disk_info.partitions.0.name == 'KOLLA_SWIFT_DATA'" - msg: > - Name of partition is not correct. - - always: - - name: Remove the fake file - file: - name: "{{ loopback.stdout }}" - state: absent - become: true - - rescue: - - name: Flag that a failure occurred - set_fact: - test_failures: "{{ test_failures | default(0) | int + 1 }}" diff --git a/ansible/roles/swift-rings/defaults/main.yml b/ansible/roles/swift-rings/defaults/main.yml deleted file mode 100644 index 32ae7dea4..000000000 --- a/ansible/roles/swift-rings/defaults/main.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- -# Host on which to build Swift rings. -swift_ring_build_host: - -# Path to Kayobe cnnfigutation for Swift. -swift_config_path: - -# Path in the container in which to build rings. -swift_container_build_path: /tmp/swift-rings - -# Path on the build host in which to store ring files temporarily. -swift_ring_build_path: /tmp/swift-rings - -# Docker image to use to build rings. -swift_ring_build_image: - -# Base-2 logarithm of the number of partitions. -# i.e. num_partitions=2^. -swift_part_power: - -# Object replication count. -swift_replication_count: - -# Minimum time in hours between moving a given partition. -swift_min_part_hours: - -# List of configuration items for each host. Each item is a dict containing the -# following fields: -# - host: hostname -# - region: Swift region -# - zone: Swift zone -# - ip: storage network IP address -# - ports: dict of ports for the storage network -# - replication_ip: replication network IP address -# - replication_ports: dict of ports for the replication network -# - block_devices: list of block devices to use for Swift. Each item is a dict with the -# following items: -# - 'device': Block device path. Required. -# - 'fs_label': Name of the label used to create the file system on the device. -# Optional. Default is to use the basename of the device. -# - 'services': List of services that will use this block device. Optional. -# Default is 'block_device_default_services' for this host. -# - 'weight': Weight of the block device. Optional. Default is -# 'block_device_default_weight' for this host. -# - 'block_device_default_services': default list of services to assign block -# devices on this host to. -# - 'block_device_default_weight': default weight to assign to block devices on -# this host. -swift_host_config: [] diff --git a/ansible/roles/swift-rings/files/swift-ring-builder.py b/ansible/roles/swift-rings/files/swift-ring-builder.py deleted file mode 100644 index 274bd2a07..000000000 --- a/ansible/roles/swift-rings/files/swift-ring-builder.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python3 - -""" -Script to build a Swift ring from a declarative YAML configuration. This has -been built via a script to avoid repeated 'docker exec' commands which could -take a long time. - -Usage: - -python swift-ring-builder.py - -Example: - -python swift-ring-builder.py /path/to/config.yml /path/to/builds object - -Example configuration format: - ---- -part_power: 10 -replication_count: 3 -min_part_hours: 1 -hosts: - - host: swift1 - region: 1 - zone: 1 - ip: 10.0.0.1 - port: 6001 - replication_ip: 10.1.0.1 - replication_port: 6001 - devices: - - device: /dev/sdb - weight: 100 - - device: /dev/sdc - weight: 100 -""" -import subprocess -import sys - -import yaml - - -class RingBuilder(object): - """Helper class for building Swift rings.""" - - def __init__(self, build_path, service_name): - self.build_path = build_path - self.service_name = service_name - - def get_base_command(self): - return [ - 'swift-ring-builder', - '%s/%s.builder' % (self.build_path, self.service_name), - ] - - def create(self, part_power, replication_count, min_part_hours): - cmd = self.get_base_command() - cmd += [ - 'create', - "{}".format(part_power), - "{}".format(replication_count), - "{}".format(min_part_hours), - ] - try: - subprocess.check_call(cmd) - except subprocess.CalledProcessError: - print("Failed to create %s ring" % self.service_name) - sys.exit(1) - - def add_device(self, host, device): - cmd = self.get_base_command() - cmd += [ - 'add', - '--region', "{}".format(host['region']), - '--zone', "{}".format(host['zone']), - '--ip', host['ip'], - '--port', "{}".format(host['port']), - '--replication-ip', host['replication_ip'], - '--replication-port', "{}".format(host['replication_port']), - '--device', device['device'], - '--weight', "{}".format(device['weight']), - ] - try: - subprocess.check_call(cmd) - except subprocess.CalledProcessError: - print("Failed to add device %s on host %s to %s ring" % - (host['host'], device['device'], self.service_name)) - sys.exit(1) - - def rebalance(self): - cmd = self.get_base_command() - cmd += [ - 'rebalance', - ] - try: - subprocess.check_call(cmd) - except subprocess.CalledProcessError: - print("Failed to rebalance %s ring" % self.service_name) - sys.exit(1) - - -def build_rings(config, build_path, service_name): - builder = RingBuilder(build_path, service_name) - builder.create(config['part_power'], config['replication_count'], - config['min_part_hours']) - for host in config['hosts']: - devices = host['devices'] - # If no devices are present for this host, this will be None. - if devices is None: - continue - for device in devices: - builder.add_device(host, device) - builder.rebalance() - - -def main(): - if len(sys.argv) != 4: - raise Exception("Usage: {0} " - "") - config_path = sys.argv[1] - build_path = sys.argv[2] - service_name = sys.argv[3] - with open(config_path) as f: - config = yaml.safe_load(f) - build_rings(config, build_path, service_name) - - -if __name__ == "__main__": - main() diff --git a/ansible/roles/swift-rings/tasks/main.yml b/ansible/roles/swift-rings/tasks/main.yml deleted file mode 100644 index aa6f5e6fb..000000000 --- a/ansible/roles/swift-rings/tasks/main.yml +++ /dev/null @@ -1,68 +0,0 @@ ---- -# We generate a configuration file and execute a python script in a container -# that builds a ring based on the config file contents. Doing it this way -# avoids a large task loop with docker container for each step, which would be -# quite slow. - -# Execute the following commands on the ring build host. -- block: - - name: Ensure Swift ring build directory exists - file: - path: "{{ swift_ring_build_path }}" - state: directory - - - name: Ensure Swift ring builder script exists - copy: - src: swift-ring-builder.py - dest: "{{ swift_ring_build_path }}" - register: copy_result - - - name: Ensure Swift ring builder configuration exists - template: - src: swift-ring.yml.j2 - dest: "{{ swift_ring_build_path }}/{{ service_name }}-ring.yml" - with_items: "{{ swift_service_names }}" - loop_control: - loop_var: service_name - - - name: Ensure Swift rings exist - kayobe_container: - cleanup: true - command: >- - python3 {{ swift_container_build_path }}/swift-ring-builder.py - {{ swift_container_build_path }}/{{ item }}-ring.yml - {{ swift_container_build_path }} - {{ item }} - detach: false - image: "{{ swift_ring_build_image }}" - name: "swift_{{ item }}_ring_builder" - user: "{{ copy_result.uid }}:{{ copy_result.gid }}" - volumes: - - "{{ swift_ring_build_path }}/:{{ swift_container_build_path }}/" - with_items: "{{ swift_service_names }}" - become: "{{ container_engine == 'podman' }}" - - - name: Ensure Swift ring files are copied - fetch: - src: "{{ swift_ring_build_path }}/{{ item[0] }}.{{ item[1] }}" - dest: "{{ swift_config_path }}/{{ item[0] }}.{{ item[1] }}" - flat: true - mode: 0644 - with_nested: - - "{{ swift_service_names }}" - - - ring.gz - - builder - become: true - - always: - - name: Remove Swift ring build directory from build host - file: - path: "{{ swift_ring_build_path }}" - state: absent - become: true - - delegate_to: "{{ swift_ring_build_host }}" - vars: - # NOTE: Without this, the seed's ansible_host variable will not be - # respected when using delegate_to. - ansible_host: "{{ hostvars[swift_ring_build_host].ansible_host | default(swift_ring_build_host) }}" diff --git a/ansible/roles/swift-rings/templates/swift-ring.yml.j2 b/ansible/roles/swift-rings/templates/swift-ring.yml.j2 deleted file mode 100644 index 08aecc646..000000000 --- a/ansible/roles/swift-rings/templates/swift-ring.yml.j2 +++ /dev/null @@ -1,21 +0,0 @@ ---- -part_power: {{ swift_part_power }} -replication_count: {{ swift_replication_count }} -min_part_hours: {{ swift_min_part_hours }} -hosts: -{% for host_config in swift_host_config %} - - host: {{ host_config.host }} - region: {{ host_config.region }} - zone: {{ host_config.zone }} - ip: {{ host_config.ip }} - port: {{ host_config.ports[service_name] }} - replication_ip: {{ host_config.replication_ip }} - replication_port: {{ host_config.replication_ports[service_name] }} - devices: -{% for device in host_config.block_devices %} -{% if service_name in (device.services | default(host_config.block_device_default_services)) %} - - device: {{ device.fs_label | default(device.device | basename) }} - weight: {{ device.weight | default(host_config.block_device_default_weight) }} -{% endif %} -{% endfor %} -{% endfor %} diff --git a/ansible/roles/swift-rings/vars/main.yml b/ansible/roles/swift-rings/vars/main.yml deleted file mode 100644 index c6b67fbc8..000000000 --- a/ansible/roles/swift-rings/vars/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -# List of names of Swift services. -swift_service_names: - - object - - account - - container diff --git a/ansible/swift-block-devices.yml b/ansible/swift-block-devices.yml deleted file mode 100644 index 306a13d1b..000000000 --- a/ansible/swift-block-devices.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: Ensure Swift block devices are prepared - hosts: "{{ swift_hosts }}" - max_fail_percentage: >- - {{ swift_block_devices_max_fail_percentage | - default(kayobe_max_fail_percentage) | - default(100) }} - vars: - swift_hosts: storage - tags: - - swift - - swift-block-devices - roles: - - role: swift-block-devices - when: kolla_enable_swift | bool diff --git a/ansible/swift-rings.yml b/ansible/swift-rings.yml deleted file mode 100644 index 56a17c9ac..000000000 --- a/ansible/swift-rings.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- -- name: Ensure swift ring files exist - hosts: localhost - tags: - - swift - - swift-rings - tasks: - - name: Initialise a fact about swift hosts - set_fact: - swift_host_config: [] - - - name: Update a fact about Swift hosts - set_fact: - swift_host_config: "{{ swift_host_config + [swift_host] }}" - vars: - swift_host: - host: "{{ host }}" - region: "{{ hostvars[host]['swift_region'] }}" - zone: "{{ hostvars[host]['swift_zone'] }}" - ip: "{{ swift_storage_net_name | net_ip(inventory_hostname=host) }}" - ports: "{{ hostvars[host]['swift_service_ports'] }}" - replication_ip: "{{ swift_storage_replication_net_name | net_ip(inventory_hostname=host) }}" - replication_ports: "{{ hostvars[host]['swift_service_ports'] }}" - block_devices: "{{ hostvars[host]['swift_block_devices'] }}" - block_device_default_services: "{{ hostvars[host]['swift_block_device_default_services'] }}" - block_device_default_weight: "{{ hostvars[host]['swift_block_device_default_weight'] }}" - with_inventory_hostnames: "{{ swift_hosts }}" - loop_control: - loop_var: host - - - include_role: - name: swift-rings - vars: - swift_config_path: "{{ kayobe_env_config_path }}/kolla/config/swift" - when: kolla_enable_swift | bool diff --git a/dev/dev-vagrant.yml b/dev/dev-vagrant.yml index de676b86b..241e21a0f 100644 --- a/dev/dev-vagrant.yml +++ b/dev/dev-vagrant.yml @@ -17,9 +17,6 @@ kayobe_ansible_user: vagrant # Set an interface name for LLDP discovery. inspector_lldp_switch_port_interface_default: eth0 -# Disable swift. -kolla_enable_swift: False - # Map all networks to the all-in-one network. oob_oc_net_name: aio provision_oc_net_name: aio diff --git a/dev/functions b/dev/functions index cd20e05e3..57c343654 100644 --- a/dev/functions +++ b/dev/functions @@ -1040,8 +1040,6 @@ function configure_iptables { # bridge, breth1. sudo iptables -A FORWARD -i breth1 -j ACCEPT || true - # agent ramdisk gets instance image from swift - sudo iptables -I INPUT -d $INTERNAL_VIP -p tcp --dport ${SWIFT_DEFAULT_BIND_PORT:-8080} -j ACCEPT || true sudo iptables -I INPUT -d $INTERNAL_VIP -p tcp --dport $GLANCE_SERVICE_PORT -j ACCEPT || true sudo iptables -I INPUT -d $HOST_IP -p tcp --dport $IRONIC_HTTP_PORT -j ACCEPT || true diff --git a/doc/source/configuration/reference/hosts.rst b/doc/source/configuration/reference/hosts.rst index 292934d9e..02364e142 100644 --- a/doc/source/configuration/reference/hosts.rst +++ b/doc/source/configuration/reference/hosts.rst @@ -1253,9 +1253,10 @@ insecure (HTTP) registry, set ``podman_registry_insecure`` to ``true``. Docker ------ -The ``docker_storage_driver`` variable sets the Docker storage driver, and by -default the ``overlay2`` driver is used. See :ref:`configuration-hosts-lvm` for -information about configuring LVM for Docker. +The ``docker_storage_driver`` variable sets the Docker storage driver. By +default it is unset, which defers to Docker's runtime default. See +:ref:`configuration-hosts-lvm` for information about configuring LVM for +Docker. If using an insecure (HTTP) registry, set ``docker_registry_insecure`` to ``true``. diff --git a/doc/source/configuration/reference/kolla-ansible.rst b/doc/source/configuration/reference/kolla-ansible.rst index ea2f6e85e..35f3f32a7 100644 --- a/doc/source/configuration/reference/kolla-ansible.rst +++ b/doc/source/configuration/reference/kolla-ansible.rst @@ -554,8 +554,6 @@ defined for a host, it is ignored. - "kolla_api_interface" - "kolla_storage_interface" - "kolla_cluster_interface" - - "kolla_swift_storage_interface" - - "kolla_swift_replication_interface" - "kolla_provision_interface" - "kolla_inspector_dnsmasq_interface" - "kolla_dns_interface" @@ -581,8 +579,6 @@ defined for a host, it is ignored. kolla_api_interface: "api_interface" kolla_storage_interface: "storage_interface" kolla_cluster_interface: "cluster_interface" - kolla_swift_storage_interface: "swift_storage_interface" - kolla_swift_replication_interface: "swift_replication_interface" kolla_provision_interface: "provision_interface" kolla_inspector_dnsmasq_interface: "ironic_dnsmasq_interface" kolla_dns_interface: "dns_interface" @@ -741,7 +737,7 @@ A common task is enabling a new OpenStack service. This may be done via the :caption: ``$KAYOBE_CONFIG_PATH/kolla.yml`` --- - kolla_enable_swift: true + kolla_enable_barbican: true Note that in some cases additional configuration may be required to successfully deploy a service - check the :kolla-ansible-doc:`Kolla Ansible @@ -828,7 +824,6 @@ which files are supported. ``placement.conf`` Placement configuration. ``placement/*`` Extended Placement configuration. ``prometheus/*`` Prometheus configuration. - ``swift/*`` Extended swift configuration. ``watcher.conf`` Watcher configuration. ``watcher/*`` Extended Watcher configuration. =============================== ======================================================= diff --git a/doc/source/configuration/reference/network.rst b/doc/source/configuration/reference/network.rst index 32d259557..27caeb72a 100644 --- a/doc/source/configuration/reference/network.rst +++ b/doc/source/configuration/reference/network.rst @@ -914,12 +914,6 @@ Storage network (``storage_net_name``) Name of the network used to carry storage data traffic. Storage management network (``storage_mgmt_net_name``) Name of the network used to carry storage management traffic. -Swift storage network (``swift_storage_net_name``) - Name of the network used to carry Swift storage data traffic. - Defaults to the storage network (``storage_net_name``). -Swift storage replication network (``swift_storage_replication_net_name``) - Name of the network used to carry storage management traffic. - Defaults to the storage management network (``storage_mgmt_net_name``) Workload inspection network (``inspection_net_name``) Name of the network used to perform hardware introspection on the bare metal workload hosts. @@ -956,8 +950,6 @@ To configure network roles in a system with two networks, ``example1`` and - example2 storage_net_name: example2 storage_mgmt_net_name: example2 - swift_storage_net_name: example2 - swift_replication_net_name: example2 inspection_net_name: example2 cleaning_net_name: example2 @@ -1323,9 +1315,6 @@ By default, the storage hosts are attached to the following networks: * storage network * storage management network -In addition, if Swift is enabled, they can also be attached to the Swift -management and replication networks. - Virtualised Compute Hosts ------------------------- diff --git a/doc/source/configuration/reference/physical-network.rst b/doc/source/configuration/reference/physical-network.rst index ff00a60c8..bfc2c1273 100644 --- a/doc/source/configuration/reference/physical-network.rst +++ b/doc/source/configuration/reference/physical-network.rst @@ -14,7 +14,9 @@ configure`` command. See :ref:`physical-network` for details. The following switch operating systems are currently supported: +* AlliedWare Plus * Arista EOS +* Cisco NX-OS * Cumulus Linux (via `Network Command Line Utility (NCLU) `__) * Cumulus Linux (via `NVIDIA User Experience command line utility (NVUE) @@ -196,6 +198,28 @@ hosts file on the Ansible control host will need to be populated manually. Device-specific Configuration Variables ======================================= +AlliedWare Plus +--------------- + +Configuration for these devices is applied using the ``alliedware-plus-switch`` +Ansible role in Kayobe. The role configures AlliedWare Plus switches using the +``alliedtelesis.awplus`` Ansible modules. + +``switch_type`` should be set to ``alliedware-plus``. + + +``switch_config_save`` may be set to ``true`` to save the running configuration +to the startup configuration when they differ, including any previously unsaved +changes. + +* ``ansible_host`` is the hostname or IP address. Optional. +* ``ansible_user`` is the SSH username. +* ``ansible_ssh_pass`` is the SSH password. +* ``ansible_connection`` should be ``ansible.netcommon.network_cli``. +* ``ansible_network_os`` should be ``alliedtelesis.awplus.awplus``. +* ``ansible_become`` should be ``true``. +* ``ansible_become_method`` should be ``enable``. + Arista EOS ---------- @@ -213,6 +237,44 @@ modules. * ``ansible_become`` should be ``true``. * ``ansible_become_method`` should be ``enable``. +Cisco NX-OS +----------- + +Configuration for these devices is applied using the ``cisco-nxos-switch`` +Ansible role in Kayobe. The role configures Cisco NX-OS switches using the +``cisco.nxos.nxos_config`` Ansible module. + +``switch_type`` should be set to ``cisco-nxos``. + +``switch_config_save`` may be set to ``true`` to save the running configuration +to the startup configuration when they differ, including any previously unsaved +changes. + +* ``ansible_host`` is the hostname or IP address. Optional. +* ``ansible_user`` is the SSH username. +* ``ansible_ssh_pass`` is the SSH password, if using password authentication. +* ``ansible_connection`` should be ``ansible.netcommon.network_cli``. +* ``ansible_network_os`` should be ``cisco.nxos.nxos``. + +The SSH user must have permission to configure the switch. + +For example, the following host variables enable LLDP and configure a +switchport: + +.. code-block:: yaml + + switch_type: cisco-nxos + ansible_connection: ansible.netcommon.network_cli + ansible_network_os: cisco.nxos.nxos + switch_config: + - "feature lldp" + switch_interface_config: + Ethernet1/1: + description: server-1 + config: + - "switchport" + - "switchport mode access" + Cumulus Linux (with NCLU) ------------------------- diff --git a/doc/source/configuration/scenarios/all-in-one/overcloud.rst b/doc/source/configuration/scenarios/all-in-one/overcloud.rst index 431b0d587..ed8b01bd8 100644 --- a/doc/source/configuration/scenarios/all-in-one/overcloud.rst +++ b/doc/source/configuration/scenarios/all-in-one/overcloud.rst @@ -152,12 +152,6 @@ the name of the default controller networks to ``aio``: #storage_mgmt_net_name: storage_mgmt_net_name: aio - # Name of the network used to carry swift storage data traffic. - #swift_storage_net_name: - - # Name of the network used to carry swift storage replication traffic. - #swift_storage_replication_net_name: - # Name of the network used to perform hardware introspection on the bare metal # workload hosts. #inspection_net_name: diff --git a/doc/source/deployment.rst b/doc/source/deployment.rst index f9d079291..aa7ce5947 100644 --- a/doc/source/deployment.rst +++ b/doc/source/deployment.rst @@ -726,18 +726,6 @@ rebuilding images, use the ``--force-rebuild`` argument. See :ref:`here ` for information on how to configure the IPA image build process. -Building Swift Rings --------------------- - -.. note:: - - This section can be skipped if Swift is not in use. - -Swift uses ring files to control placement of data across a cluster. These -files can be generated automatically using the following command:: - - (kayobe) $ kayobe overcloud swift rings generate - Deploying Containerised Services -------------------------------- diff --git a/etc/kayobe/container-engine.yml b/etc/kayobe/container-engine.yml index 48ea969b3..ffe1d4943 100644 --- a/etc/kayobe/container-engine.yml +++ b/etc/kayobe/container-engine.yml @@ -12,7 +12,8 @@ ############################################################################### # Docker configuration. -# Name of the docker storage driver. Default is 'overlay2'. +# Name of the docker storage driver. Default is "", which defers to the +# Docker runtime default. #docker_storage_driver: # URL of docker registry diff --git a/etc/kayobe/networks.yml b/etc/kayobe/networks.yml index a2b1093c5..a7fe9b77a 100644 --- a/etc/kayobe/networks.yml +++ b/etc/kayobe/networks.yml @@ -2,7 +2,7 @@ # Kayobe network configuration. ############################################################################### -# Network role to network mappings. +# Network role to network name mappings. # Name of the network used for admin access to the overcloud #admin_oc_net_name: @@ -42,12 +42,6 @@ # Name of the network used to carry storage management traffic. #storage_mgmt_net_name: -# Name of the network used to carry swift storage data traffic. -#swift_storage_net_name: - -# Name of the network used to carry swift storage replication traffic. -#swift_storage_replication_net_name: - # Name of the network used to perform hardware introspection on the bare metal # workload hosts. #inspection_net_name: @@ -111,6 +105,12 @@ # 'name' items. These tables will be added to /etc/iproute2/rt_tables. #network_route_tables: +############################################################################### +# Systemd-networkd configuration. + +# Prefix for systemd-networkd configuration file names. +#networkd_prefix: + ############################################################################### # Network connectivity check configuration. diff --git a/etc/kayobe/storage.yml b/etc/kayobe/storage.yml index b71b1a9f6..c4651f54f 100644 --- a/etc/kayobe/storage.yml +++ b/etc/kayobe/storage.yml @@ -19,11 +19,6 @@ # List of extra networks to which storage nodes are attached. #storage_extra_network_interfaces: -# Whether this host requires access to Swift networks. -#storage_needs_swift_network: - -#storage_needs_swift_replication_network: - ############################################################################### # Storage node BIOS configuration. diff --git a/etc/kayobe/swift.yml b/etc/kayobe/swift.yml deleted file mode 100644 index c8812b068..000000000 --- a/etc/kayobe/swift.yml +++ /dev/null @@ -1,65 +0,0 @@ ---- -############################################################################### -# OpenStack Swift configuration. - -# Short name of the kolla container image used to build rings. Default is the -# swift=object image. -#swift_ring_build_image_name: - -# Full name of the kolla container image used to build rings. -#swift_ring_build_image: - -# Ansible host pattern matching hosts on which Swift object storage services -# are deployed. The default is to use hosts in the 'storage' group. -#swift_hosts: - -# Name of the host used to build Swift rings. Default is the first host of -# 'swift_hosts'. -#swift_ring_build_host: - -# ID of the Swift region for this host. Default is 1. -#swift_region: - -# ID of the Swift zone. This can be set to different values for different hosts -# to place them in different zones. Default is 0. -#swift_zone: - -# Base-2 logarithm of the number of partitions. -# i.e. num_partitions=2^. Default is 10. -#swift_part_power: - -# Object replication count. Default is the smaller of the number of Swift -# hosts, or 3. -#swift_replication_count: - -# Minimum time in hours between moving a given partition. Default is 1. -#swift_min_part_hours: - -# Ports on which Swift services listen. Default is: -# object: 6000 -# account: 6001 -# container: 6002 -#swift_service_ports: - -# List of block devices to use for Swift. Each item is a dict with the -# following items: -# - 'device': Block device path. Required. -# - 'fs_label': Name of the label used to create the file system on the device. -# Optional. Default is to use the basename of the device. -# - 'services': List of services that will use this block device. Optional. -# Default is 'swift_block_device_default_services'. Allowed items are -# 'account', 'container', and 'object'. -# - 'weight': Weight of the block device. Optional. Default is -# 'swift_block_device_default_weight'. -#swift_block_devices: - -# Default weight to assign to block devices in the ring. Default is 100. -#swift_block_device_default_weight: - -# Default list of services to assign block devices to. Allowed items are -# 'account', 'container', and 'object'. Default value is all of these. -#swift_block_device_default_services: - -############################################################################### -# Dummy variable to allow Ansible to accept this file. -workaround_ansible_issue_8743: yes diff --git a/kayobe/ansible.py b/kayobe/ansible.py index 406076a47..bc411c35b 100644 --- a/kayobe/ansible.py +++ b/kayobe/ansible.py @@ -634,6 +634,24 @@ def config_dump(parsed_args, host=None, hosts=None, var_name=None, shutil.rmtree(dump_dir) +def _get_galaxy_environment(parsed_args): + """Return an environment dict for running ansible-galaxy commands. + + This ensures that a custom Ansible configuration file in the Kayobe + configuration path, if present, is used by ansible-galaxy. Without this, + galaxy server configuration such as a custom server list would be ignored + when installing roles and collections. + + :param parsed_args: Parsed command line arguments. + """ + env = os.environ.copy() + # If a custom Ansible configuration file exists, use it. + ansible_cfg_path = os.path.join(parsed_args.config_path, "ansible.cfg") + if utils.is_readable_file(ansible_cfg_path)["result"]: + env.setdefault("ANSIBLE_CONFIG", ansible_cfg_path) + return env + + def install_galaxy_roles(parsed_args, force=False): """Install Ansible Galaxy role dependencies. @@ -643,10 +661,12 @@ def install_galaxy_roles(parsed_args, force=False): :param parsed_args: Parsed command line arguments. :param force: Whether to force reinstallation of roles. """ + env = _get_galaxy_environment(parsed_args) LOG.info("Installing galaxy role dependencies from kayobe") requirements = utils.get_data_files_path("requirements.yml") roles_destination = utils.get_data_files_path('ansible', 'roles') - utils.galaxy_role_install(requirements, roles_destination, force=force) + utils.galaxy_role_install(requirements, roles_destination, force=force, + env=env) # Check for requirements in kayobe configuration. kc_reqs_path = os.path.join(parsed_args.config_path, @@ -669,7 +689,8 @@ def install_galaxy_roles(parsed_args, force=False): (parsed_args.config_path, str(e))) # Install roles from kayobe-config. - utils.galaxy_role_install(kc_reqs_path, kc_roles_path, force=force) + utils.galaxy_role_install(kc_reqs_path, kc_roles_path, force=force, + env=env) def install_galaxy_collections(parsed_args, force=False): @@ -681,12 +702,13 @@ def install_galaxy_collections(parsed_args, force=False): :param parsed_args: Parsed command line arguments. :param force: Whether to force reinstallation of roles. """ + env = _get_galaxy_environment(parsed_args) LOG.info("Installing galaxy collection dependencies from kayobe") requirements = utils.get_data_files_path("requirements.yml") collections_destination = utils.get_data_files_path('ansible', 'collections') utils.galaxy_collection_install(requirements, collections_destination, - force=force) + force=force, env=env) # Check for requirements in kayobe configuration. kc_reqs_path = os.path.join(parsed_args.config_path, @@ -711,7 +733,7 @@ def install_galaxy_collections(parsed_args, force=False): # Install collections from kayobe-config. utils.galaxy_collection_install(kc_reqs_path, kc_collections_path, - force=force) + force=force, env=env) def prune_galaxy_roles(parsed_args): diff --git a/kayobe/cli/commands.py b/kayobe/cli/commands.py index d6f4a9c47..49e0dccd4 100644 --- a/kayobe/cli/commands.py +++ b/kayobe/cli/commands.py @@ -2225,15 +2225,6 @@ def take_action(self, parsed_args): self.run_kayobe_playbooks(parsed_args, playbooks) -class OvercloudSwiftRingsGenerate(KayobeAnsibleMixin, VaultMixin, Command): - """Generate Swift rings.""" - - def take_action(self, parsed_args): - self.app.LOG.debug("Generating Swift rings") - playbooks = _build_playbook_list("swift-rings") - self.run_kayobe_playbooks(parsed_args, playbooks) - - class NetworkConnectivityCheck(KayobeAnsibleMixin, VaultMixin, Command): """Check network connectivity between hosts in the control plane. diff --git a/kayobe/tests/unit/cli/test_commands.py b/kayobe/tests/unit/cli/test_commands.py index 8cda090b0..a92c33cce 100644 --- a/kayobe/tests/unit/cli/test_commands.py +++ b/kayobe/tests/unit/cli/test_commands.py @@ -2410,26 +2410,6 @@ def test_overcloud_post_configure(self, mock_run): ] self.assertListEqual(expected_calls, mock_run.call_args_list) - @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_playbooks") - def test_overcloud_swift_rings_generate(self, mock_run): - command = commands.OvercloudSwiftRingsGenerate(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", "swift-rings.yml"), - ], - ), - ] - self.assertListEqual(expected_calls, mock_run.call_args_list) - @mock.patch.object(commands.KayobeAnsibleMixin, "run_kayobe_playbooks") def test_baremetal_compute_register(self, mock_run): diff --git a/kayobe/tests/unit/test_ansible.py b/kayobe/tests/unit/test_ansible.py index 9e7500b86..198f85fad 100644 --- a/kayobe/tests/unit/test_ansible.py +++ b/kayobe/tests/unit/test_ansible.py @@ -837,6 +837,47 @@ def test_config_dump_vaulted(self, mock_mkdtemp, mock_run, mock_listdir, mock.call(os.path.join(dump_dir, "host2.yml")), ]) + @mock.patch.object(utils, 'is_readable_file', autospec=True) + def test_get_galaxy_environment_ansible_cfg(self, mock_is_readable): + parser = argparse.ArgumentParser() + ansible.add_args(parser) + parsed_args = parser.parse_args([]) + mock_is_readable.return_value = {"result": True} + + with mock.patch.dict(os.environ, {}, clear=True): + env = ansible._get_galaxy_environment(parsed_args) + + self.assertEqual(env["ANSIBLE_CONFIG"], "/etc/kayobe/ansible.cfg") + mock_is_readable.assert_called_once_with("/etc/kayobe/ansible.cfg") + + @mock.patch.object(utils, 'is_readable_file', autospec=True) + def test_get_galaxy_environment_no_ansible_cfg(self, mock_is_readable): + parser = argparse.ArgumentParser() + ansible.add_args(parser) + parsed_args = parser.parse_args([]) + mock_is_readable.return_value = {"result": False} + + with mock.patch.dict(os.environ, {}, clear=True): + env = ansible._get_galaxy_environment(parsed_args) + + self.assertNotIn("ANSIBLE_CONFIG", env) + mock_is_readable.assert_called_once_with("/etc/kayobe/ansible.cfg") + + @mock.patch.object(utils, 'is_readable_file', autospec=True) + def test_get_galaxy_environment_existing_ansible_cfg( + self, mock_is_readable): + parser = argparse.ArgumentParser() + ansible.add_args(parser) + parsed_args = parser.parse_args([]) + mock_is_readable.return_value = {"result": True} + + with mock.patch.dict( + os.environ, {"ANSIBLE_CONFIG": "/path/to/ansible.cfg"}): + env = ansible._get_galaxy_environment(parsed_args) + + self.assertEqual(env["ANSIBLE_CONFIG"], "/path/to/ansible.cfg") + mock_is_readable.assert_called_once_with("/etc/kayobe/ansible.cfg") + @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) @@ -849,11 +890,14 @@ def test_install_galaxy_roles(self, mock_mkdirs, mock_is_readable, ansible.install_galaxy_roles(parsed_args) - mock_install.assert_called_once_with(utils.get_data_files_path( - "requirements.yml"), utils.get_data_files_path( - "ansible", "roles"), force=False) - mock_is_readable.assert_called_once_with( - "/etc/kayobe/ansible/requirements.yml") + mock_install.assert_called_once_with( + utils.get_data_files_path("requirements.yml"), + utils.get_data_files_path("ansible", "roles"), + force=False, env=mock.ANY) + mock_is_readable.assert_has_calls([ + mock.call("/etc/kayobe/ansible.cfg"), + mock.call("/etc/kayobe/ansible/requirements.yml"), + ]) self.assertFalse(mock_mkdirs.called) @mock.patch.object(utils, 'galaxy_role_install', autospec=True) @@ -871,12 +915,15 @@ def test_install_galaxy_roles_with_kayobe_config( expected_calls = [ mock.call(utils.get_data_files_path("requirements.yml"), utils.get_data_files_path("ansible", "roles"), - force=False), + force=False, env=mock.ANY), mock.call("/etc/kayobe/ansible/requirements.yml", - "/etc/kayobe/ansible/roles", force=False)] + "/etc/kayobe/ansible/roles", + force=False, env=mock.ANY)] self.assertListEqual(expected_calls, mock_install.call_args_list) - mock_is_readable.assert_called_once_with( - "/etc/kayobe/ansible/requirements.yml") + mock_is_readable.assert_has_calls([ + mock.call("/etc/kayobe/ansible.cfg"), + mock.call("/etc/kayobe/ansible/requirements.yml"), + ]) mock_mkdirs.assert_called_once_with("/etc/kayobe/ansible/roles") @mock.patch.object(utils, 'galaxy_role_install', autospec=True) @@ -894,12 +941,15 @@ def test_install_galaxy_roles_with_kayobe_config_forced( expected_calls = [ mock.call(utils.get_data_files_path("requirements.yml"), utils.get_data_files_path("ansible", "roles"), - force=True), + force=True, env=mock.ANY), mock.call("/etc/kayobe/ansible/requirements.yml", - "/etc/kayobe/ansible/roles", force=True)] + "/etc/kayobe/ansible/roles", + force=True, env=mock.ANY)] self.assertListEqual(expected_calls, mock_install.call_args_list) - mock_is_readable.assert_called_once_with( - "/etc/kayobe/ansible/requirements.yml") + mock_is_readable.assert_has_calls([ + mock.call("/etc/kayobe/ansible.cfg"), + mock.call("/etc/kayobe/ansible/requirements.yml"), + ]) mock_mkdirs.assert_called_once_with("/etc/kayobe/ansible/roles") @mock.patch.object(utils, 'galaxy_role_install', autospec=True) @@ -916,11 +966,14 @@ def test_install_galaxy_roles_with_kayobe_config_mkdirs_failure( self.assertRaises(exception.Error, ansible.install_galaxy_roles, parsed_args) - mock_install.assert_called_once_with(utils.get_data_files_path( - "requirements.yml"), utils.get_data_files_path("ansible", "roles"), - force=False) - mock_is_readable.assert_called_once_with( - "/etc/kayobe/ansible/requirements.yml") + mock_install.assert_called_once_with( + utils.get_data_files_path("requirements.yml"), + utils.get_data_files_path("ansible", "roles"), + force=False, env=mock.ANY) + mock_is_readable.assert_has_calls([ + mock.call("/etc/kayobe/ansible.cfg"), + mock.call("/etc/kayobe/ansible/requirements.yml"), + ]) mock_mkdirs.assert_called_once_with("/etc/kayobe/ansible/roles") @mock.patch.object(utils, 'galaxy_collection_install', autospec=True) @@ -935,11 +988,14 @@ def test_install_galaxy_collections(self, mock_mkdirs, mock_is_readable, ansible.install_galaxy_collections(parsed_args) - mock_install.assert_called_once_with(utils.get_data_files_path( - "requirements.yml"), utils.get_data_files_path( - "ansible", "collections"), force=False) - mock_is_readable.assert_called_once_with( - "/etc/kayobe/ansible/requirements.yml") + mock_install.assert_called_once_with( + utils.get_data_files_path("requirements.yml"), + utils.get_data_files_path("ansible", "collections"), + force=False, env=mock.ANY) + mock_is_readable.assert_has_calls([ + mock.call("/etc/kayobe/ansible.cfg"), + mock.call("/etc/kayobe/ansible/requirements.yml"), + ]) self.assertFalse(mock_mkdirs.called) @mock.patch.object(utils, 'galaxy_collection_install', autospec=True) @@ -957,12 +1013,15 @@ def test_install_galaxy_collections_with_kayobe_config( expected_calls = [ mock.call(utils.get_data_files_path("requirements.yml"), utils.get_data_files_path("ansible", "collections"), - force=False), + force=False, env=mock.ANY), mock.call("/etc/kayobe/ansible/requirements.yml", - "/etc/kayobe/ansible/collections", force=False)] + "/etc/kayobe/ansible/collections", + force=False, env=mock.ANY)] self.assertListEqual(expected_calls, mock_install.call_args_list) - mock_is_readable.assert_called_once_with( - "/etc/kayobe/ansible/requirements.yml") + mock_is_readable.assert_has_calls([ + mock.call("/etc/kayobe/ansible.cfg"), + mock.call("/etc/kayobe/ansible/requirements.yml"), + ]) mock_mkdirs.assert_called_once_with("/etc/kayobe/ansible/collections") @mock.patch.object(utils, 'galaxy_collection_install', autospec=True) @@ -980,12 +1039,15 @@ def test_install_galaxy_collections_with_kayobe_config_forced( expected_calls = [ mock.call(utils.get_data_files_path("requirements.yml"), utils.get_data_files_path("ansible", "collections"), - force=True), + force=True, env=mock.ANY), mock.call("/etc/kayobe/ansible/requirements.yml", - "/etc/kayobe/ansible/collections", force=True)] + "/etc/kayobe/ansible/collections", + force=True, env=mock.ANY)] self.assertListEqual(expected_calls, mock_install.call_args_list) - mock_is_readable.assert_called_once_with( - "/etc/kayobe/ansible/requirements.yml") + mock_is_readable.assert_has_calls([ + mock.call("/etc/kayobe/ansible.cfg"), + mock.call("/etc/kayobe/ansible/requirements.yml"), + ]) mock_mkdirs.assert_called_once_with("/etc/kayobe/ansible/collections") @mock.patch.object(utils, 'galaxy_collection_install', autospec=True) @@ -1004,9 +1066,12 @@ def test_install_galaxy_collections_with_kayobe_config_mkdirs_failure( mock_install.assert_called_once_with( utils.get_data_files_path("requirements.yml"), - utils.get_data_files_path("ansible", "collections"), force=False) - mock_is_readable.assert_called_once_with( - "/etc/kayobe/ansible/requirements.yml") + utils.get_data_files_path("ansible", "collections"), + force=False, env=mock.ANY) + mock_is_readable.assert_has_calls([ + mock.call("/etc/kayobe/ansible.cfg"), + mock.call("/etc/kayobe/ansible/requirements.yml"), + ]) mock_mkdirs.assert_called_once_with("/etc/kayobe/ansible/collections") @mock.patch.object(utils, 'galaxy_remove', autospec=True) diff --git a/kayobe/tests/unit/test_utils.py b/kayobe/tests/unit/test_utils.py index 736678e9f..fc9abc871 100644 --- a/kayobe/tests/unit/test_utils.py +++ b/kayobe/tests/unit/test_utils.py @@ -34,7 +34,18 @@ def test_galaxy_role_install(self, mock_run): utils.galaxy_role_install("/path/to/role/file", "/path/to/roles") mock_run.assert_called_once_with(["ansible-galaxy", "role", "install", "--roles-path", "/path/to/roles", - "--role-file", "/path/to/role/file"]) + "--role-file", "/path/to/role/file"], + env=None) + + @mock.patch.object(utils, "run_command") + def test_galaxy_role_install_env(self, mock_run): + env = {"ANSIBLE_CONFIG": "/etc/kayobe/ansible.cfg"} + utils.galaxy_role_install("/path/to/role/file", "/path/to/roles", + env=env) + mock_run.assert_called_once_with(["ansible-galaxy", "role", "install", + "--roles-path", "/path/to/roles", + "--role-file", "/path/to/role/file"], + env=env) @mock.patch.object(utils, "run_command") def test_galaxy_role_install_failure(self, mock_run): @@ -57,6 +68,24 @@ def test_galaxy_collection_install(self, mock_read, mock_run): "/path/to/collection/file"], env=env) + @mock.patch.object(utils, "run_command") + @mock.patch.object(utils, "read_yaml_file") + def test_galaxy_collection_install_env(self, mock_read, mock_run): + mock_read.return_value = {"collections": []} + env = {"ANSIBLE_CONFIG": "/etc/kayobe/ansible.cfg"} + utils.galaxy_collection_install("/path/to/collection/file", + "/path/to/collections", env=env) + expected_env = { + 'ANSIBLE_COLLECTIONS_SCAN_SYS_PATH': 'False', + 'ANSIBLE_CONFIG': '/etc/kayobe/ansible.cfg', + } + mock_run.assert_called_once_with(["ansible-galaxy", "collection", + "install", "--collections-path", + "/path/to/collections", + "--requirements-file", + "/path/to/collection/file"], + env=expected_env) + @mock.patch.object(utils, "run_command") @mock.patch.object(utils, "read_yaml_file") def test_galaxy_collection_install_failure(self, mock_read, mock_run): diff --git a/kayobe/utils.py b/kayobe/utils.py index 14cbf6637..248851658 100644 --- a/kayobe/utils.py +++ b/kayobe/utils.py @@ -102,15 +102,22 @@ def _get_base_path(): return os.path.join(os.path.dirname(os.path.realpath(__file__)), "..") -def galaxy_role_install(role_file, roles_path, force=False): - """Install Ansible roles via Ansible Galaxy.""" +def galaxy_role_install(role_file, roles_path, force=False, env=None): + """Install Ansible roles via Ansible Galaxy. + + :param role_file: Path to a file containing role requirements. + :param roles_path: Path to a directory in which to install roles. + :param force: Whether to force reinstallation of roles. + :param env: Optional environment dict to use when invoking + ansible-galaxy. If None, the current environment is inherited. + """ cmd = ["ansible-galaxy", "role", "install"] cmd += ["--roles-path", roles_path] cmd += ["--role-file", role_file] if force: cmd += ["--force"] try: - run_command(cmd) + run_command(cmd, env=env) except subprocess.CalledProcessError as e: LOG.error("Failed to install Ansible roles from %s via Ansible " "Galaxy: returncode %d", role_file, e.returncode) @@ -118,7 +125,17 @@ def galaxy_role_install(role_file, roles_path, force=False): def galaxy_collection_install(requirements_file, collections_path, - force=False): + force=False, env=None): + """Install Ansible collections via Ansible Galaxy. + + :param requirements_file: Path to a file containing collection + requirements. + :param collections_path: Path to a directory in which to install + collections. + :param force: Whether to force reinstallation of collections. + :param env: Optional environment dict to use when invoking + ansible-galaxy. If None, the current environment is inherited. + """ requirements = read_yaml_file(requirements_file) if not isinstance(requirements, dict): # Handle legacy role list format, which causes the command to fail. @@ -131,7 +148,7 @@ def galaxy_collection_install(requirements_file, collections_path, # kayobe requirements.yml. "ANSIBLE_COLLECTIONS_SCAN_SYS_PATH": "False", } - env = env_defaults | os.environ + env = env_defaults | (env if env is not None else os.environ) if force: cmd += ["--force"] try: diff --git a/playbooks/kayobe-base/pre.yml b/playbooks/kayobe-base/pre.yml index a8be2b19c..5168b990f 100644 --- a/playbooks/kayobe-base/pre.yml +++ b/playbooks/kayobe-base/pre.yml @@ -22,6 +22,17 @@ # https://github.com/ansible/ansible/issues/81777 pipelining = False retries = 3 + + [galaxy] + # Prefer the site's OpenDev Ansible Galaxy mirror, falling back to the + # public Galaxy server. + server_list = opendev, galaxy + + [galaxy_server.opendev] + url = https://{{ zuul_site_mirror_fqdn }}:4448/api/ + + [galaxy_server.galaxy] + url = https://galaxy.ansible.com/ ansible_cfg_kolla: | [defaults] # Ensure that facts are referenced via ansible_facts.. @@ -43,6 +54,17 @@ # https://github.com/ansible/ansible/issues/81777 pipelining = False retries = 3 + + [galaxy] + # Prefer the site's OpenDev Ansible Galaxy mirror, falling back to the + # public Galaxy server. + server_list = opendev, galaxy + + [galaxy_server.opendev] + url = https://{{ zuul_site_mirror_fqdn }}:4448/api/ + + [galaxy_server.galaxy] + url = https://galaxy.ansible.com/ roles: - role: kayobe-diagnostics kayobe_diagnostics_phase: "pre" diff --git a/playbooks/kayobe-overcloud-upgrade-base/run.yml b/playbooks/kayobe-overcloud-upgrade-base/run.yml index 318432e67..123d5686b 100644 --- a/playbooks/kayobe-overcloud-upgrade-base/run.yml +++ b/playbooks/kayobe-overcloud-upgrade-base/run.yml @@ -76,14 +76,12 @@ cmd: dev/overcloud-test-vm.sh &> {{ logs_dir }}/ansible/overcloud-test-vm-pre-upgrade chdir: "{{ previous_kayobe_src_dir }}" executable: /bin/bash - when: ansible_facts.os_family != 'Debian' - name: Perform testing of the baremetal machines in the overcloud prior to upgrade shell: cmd: dev/overcloud-test-baremetal.sh &> {{ logs_dir }}/ansible/overcloud-test-bm-pre-upgrade chdir: "{{ previous_kayobe_src_dir }}" executable: /bin/bash - when: ansible_facts.os_family != 'Debian' # Upgrade Kayobe, and use it to perform an upgrade of the control plane. diff --git a/playbooks/kayobe-tox/ansible-ci.cfg.j2 b/playbooks/kayobe-tox/ansible-ci.cfg.j2 new file mode 100644 index 000000000..5bfa402a3 --- /dev/null +++ b/playbooks/kayobe-tox/ansible-ci.cfg.j2 @@ -0,0 +1,14 @@ +# CI-only Ansible configuration. This file is intentionally not named +# ansible.cfg so that it is not auto-discovered by Ansible on a developer's +# machine. CI renders it from this template via a Zuul pre-run playbook, then +# points ANSIBLE_CONFIG at it for the tox jobs. +[galaxy] +# Prefer the site's OpenDev Ansible Galaxy mirror, falling back to the public +# Galaxy server. This speeds up and stabilises role/collection installs in CI. +server_list = opendev, galaxy + +[galaxy_server.opendev] +url = https://{{ zuul_site_mirror_fqdn }}:4448/api/ + +[galaxy_server.galaxy] +url = https://galaxy.ansible.com/ diff --git a/playbooks/kayobe-tox/pre.yml b/playbooks/kayobe-tox/pre.yml new file mode 100644 index 000000000..cb4b100ee --- /dev/null +++ b/playbooks/kayobe-tox/pre.yml @@ -0,0 +1,8 @@ +--- +- hosts: all + gather_facts: true + tasks: + - name: Render CI ansible.cfg using the site mirror + template: + src: ansible-ci.cfg.j2 + dest: "{{ ansible_env.PWD }}/ansible-ci.cfg" diff --git a/releasenotes/notes/add-cisco-nxos-switch-support-6ef2c747d24e5197.yaml b/releasenotes/notes/add-cisco-nxos-switch-support-6ef2c747d24e5197.yaml new file mode 100644 index 000000000..7886998b7 --- /dev/null +++ b/releasenotes/notes/add-cisco-nxos-switch-support-6ef2c747d24e5197.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Adds support for configuring Cisco NX-OS switches with + ``kayobe physical network configure``. Set ``switch_type`` to + ``cisco-nxos`` to use this support. diff --git a/releasenotes/notes/alliedware-plus-switch-75625ad2e5d61241.yaml b/releasenotes/notes/alliedware-plus-switch-75625ad2e5d61241.yaml new file mode 100644 index 000000000..1dd97cd60 --- /dev/null +++ b/releasenotes/notes/alliedware-plus-switch-75625ad2e5d61241.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Adds support for configuration of AlliedWare Plus switches. This is + integrated with the ``kayobe physical network configure`` command. diff --git a/releasenotes/notes/bug-2168529-b206bb5ace7090b3.yaml b/releasenotes/notes/bug-2168529-b206bb5ace7090b3.yaml new file mode 100644 index 000000000..d06aaa964 --- /dev/null +++ b/releasenotes/notes/bug-2168529-b206bb5ace7090b3.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fixes Dell OS10 switch config. Also makes sure that VLAN interfaces are + defined first as others might depend on them. + `LP#2168529 `__ diff --git a/releasenotes/notes/bug-2168538-2c528e265fe6ce6c.yaml b/releasenotes/notes/bug-2168538-2c528e265fe6ce6c.yaml new file mode 100644 index 000000000..78b8ca0f6 --- /dev/null +++ b/releasenotes/notes/bug-2168538-2c528e265fe6ce6c.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixes Dell switch configuration tasks always reporting as ``changed`` when + saving switch configuration was enabled. Switch configuration is now saved + only when changes have been made. + `LP#2168538 `__ diff --git a/releasenotes/notes/bug-2168557-2a1748c41ec3b28f.yaml b/releasenotes/notes/bug-2168557-2a1748c41ec3b28f.yaml new file mode 100644 index 000000000..230656d40 --- /dev/null +++ b/releasenotes/notes/bug-2168557-2a1748c41ec3b28f.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fixes regression causing DellOS10 switch config tasks to always change + description strings if there are not whitespace characters. + `LP#2168557 `__ diff --git a/releasenotes/notes/bug-2168744-d0872c5d71c4e76f.yaml b/releasenotes/notes/bug-2168744-d0872c5d71c4e76f.yaml new file mode 100644 index 000000000..710a55461 --- /dev/null +++ b/releasenotes/notes/bug-2168744-d0872c5d71c4e76f.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixes Dell OS9 switch config. + `LP#2168744 `__ diff --git a/releasenotes/notes/docker-storage-driver-runtime-default-271e86e7162984cb.yaml b/releasenotes/notes/docker-storage-driver-runtime-default-271e86e7162984cb.yaml new file mode 100644 index 000000000..814b32299 --- /dev/null +++ b/releasenotes/notes/docker-storage-driver-runtime-default-271e86e7162984cb.yaml @@ -0,0 +1,13 @@ +--- +upgrade: + - | + ``docker_storage_driver`` is now unset by default, which defers to the + Docker runtime default storage backend. + + On fresh installations of Docker Engine 29.0 and later, Docker uses the + containerd image store by default. On existing installations upgraded from + earlier Docker versions, Docker continues using the legacy graph drivers + (including ``overlay2``) until the containerd image store is explicitly + enabled. See the Docker `containerd image store + `__ documentation for + details. diff --git a/releasenotes/notes/firewalld-wait-ready-7a1c2d9e4f6b8a30.yaml b/releasenotes/notes/firewalld-wait-ready-7a1c2d9e4f6b8a30.yaml new file mode 100644 index 000000000..76b0bcba0 --- /dev/null +++ b/releasenotes/notes/firewalld-wait-ready-7a1c2d9e4f6b8a30.yaml @@ -0,0 +1,9 @@ +--- +fixes: + - | + Fixes a race when configuring firewalld that could cause host + configuration to fail with ``INVALID_ZONE`` for a zone that was created + while firewalld was still starting up. The firewalld role now waits until + the firewalld D-Bus interface is ready before creating zones, ensuring + that they are applied to the running daemon rather than only to the + on-disk configuration. diff --git a/releasenotes/notes/fix-etc-hosts-fixup-non-kolla-hosts-c42c9b50067d5155.yaml b/releasenotes/notes/fix-etc-hosts-fixup-non-kolla-hosts-c42c9b50067d5155.yaml new file mode 100644 index 000000000..e31ea7f49 --- /dev/null +++ b/releasenotes/notes/fix-etc-hosts-fixup-non-kolla-hosts-c42c9b50067d5155.yaml @@ -0,0 +1,9 @@ +--- +fixes: + - | + Fixes a bug where ``ansible/overcloud-etc-hosts-fixup.yml``, run as part + of ``kayobe overcloud host upgrade``, attempted to run on all overcloud + hosts, including those that are not mapped through to the generated + kolla-ansible inventory. It is now skipped on hosts that are not mapped + through to kolla-ansible. + `LP#2167869 `__ diff --git a/releasenotes/notes/galaxy-use-ansible-cfg-d34b1f4c3e1a2b7c.yaml b/releasenotes/notes/galaxy-use-ansible-cfg-d34b1f4c3e1a2b7c.yaml new file mode 100644 index 000000000..64997535a --- /dev/null +++ b/releasenotes/notes/galaxy-use-ansible-cfg-d34b1f4c3e1a2b7c.yaml @@ -0,0 +1,9 @@ +--- +fixes: + - | + Fixes installation of Ansible roles and collections during ``kayobe + control host bootstrap`` to respect a custom ``ansible.cfg`` in the Kayobe + configuration path. Previously the ``ansible-galaxy`` commands were run + without ``ANSIBLE_CONFIG`` set, so configuration such as a custom Galaxy + server list (``server_list``) was ignored and the default public Galaxy + server was used instead. diff --git a/releasenotes/notes/kolla-ansible-collections-use-ansible-cfg-6c1ba8a6e480fc8f.yaml b/releasenotes/notes/kolla-ansible-collections-use-ansible-cfg-6c1ba8a6e480fc8f.yaml new file mode 100644 index 000000000..5ab7cf4dc --- /dev/null +++ b/releasenotes/notes/kolla-ansible-collections-use-ansible-cfg-6c1ba8a6e480fc8f.yaml @@ -0,0 +1,9 @@ +--- +fixes: + - | + Fixes installation of Kolla Ansible collection dependencies during + ``kayobe control host bootstrap`` to respect a custom ``ansible.cfg`` in + the Kayobe configuration path. Previously the ``ansible-galaxy`` commands + run by the ``kolla-ansible`` role did not set ``ANSIBLE_CONFIG``, so + configuration such as a custom Galaxy server list (``server_list``) was + ignored and the default public Galaxy server was used instead. diff --git a/releasenotes/notes/remove-swift-support-7edf979aef2a1414.yaml b/releasenotes/notes/remove-swift-support-7edf979aef2a1414.yaml new file mode 100644 index 000000000..35cf2a17e --- /dev/null +++ b/releasenotes/notes/remove-swift-support-7edf979aef2a1414.yaml @@ -0,0 +1,7 @@ +--- +upgrade: + - | + Support for deploying Swift has been removed, following its removal from + Kolla Ansible. This includes the ``kayobe overcloud swift rings generate`` + command, the ``swift-rings`` and ``swift-block-devices`` roles, and the + associated ``swift`` inventory and configuration variables. diff --git a/releasenotes/notes/tolerate-missing-image-ids-2a6a46b7cb74fca5.yaml b/releasenotes/notes/tolerate-missing-image-ids-2a6a46b7cb74fca5.yaml new file mode 100644 index 000000000..793b25e1b --- /dev/null +++ b/releasenotes/notes/tolerate-missing-image-ids-2a6a46b7cb74fca5.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fixes deployment image updates failing when an Ironic node is missing + deployment image IDs. `LP#2165045 + `__ diff --git a/requirements.yml b/requirements.yml index 17ce80ed9..7bbbf9eec 100644 --- a/requirements.yml +++ b/requirements.yml @@ -1,10 +1,14 @@ --- collections: + - name: alliedtelesis.awplus + version: 1.3.0 - name: https://opendev.org/openstack/ansible-collection-kolla type: git version: master + - name: cisco.nxos + version: 13.0.0 - name: community.docker - version: 5.2.0 + version: 5.3.0 - name: community.network version: 5.1.0 - name: dellemc.enterprise_sonic diff --git a/roles/host-configure-test-harness/tests/test_host_configure.py b/roles/host-configure-test-harness/tests/test_host_configure.py index 5c03a28cd..a5f7a1be0 100644 --- a/roles/host-configure-test-harness/tests/test_host_configure.py +++ b/roles/host-configure-test-harness/tests/test_host_configure.py @@ -190,10 +190,20 @@ def test_cloud_init_is_disabled(host): assert host.file("/etc/cloud/cloud-init.disabled").exists -def test_docker_storage_driver_is_overlay2(host): +def test_docker_storage_driver_is_configured(host): with host.sudo("stack"): - info = host.check_output("docker info") - assert "overlay2" in info + driver_status_json = host.check_output( + "docker info --format '{{json .DriverStatus}}'") + + driver_status = json.loads(driver_status_json) + status_map = { + entry[0]: entry[1] + for entry in driver_status + if isinstance(entry, list) and len(entry) == 2 + } + + driver_type = status_map.get("driver-type", "") + assert driver_type.startswith("io.containerd.snapshotter.") @pytest.mark.parametrize('user', ['kolla', 'stack']) diff --git a/setup.cfg b/setup.cfg index f4094b93c..a96bf711e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -88,7 +88,6 @@ kayobe.cli= overcloud_service_reconfigure = kayobe.cli.commands:OvercloudServiceReconfigure overcloud_service_stop = kayobe.cli.commands:OvercloudServiceStop overcloud_service_upgrade = kayobe.cli.commands:OvercloudServiceUpgrade - overcloud_swift_rings_generate = kayobe.cli.commands:OvercloudSwiftRingsGenerate physical_network_configure = kayobe.cli.commands:PhysicalNetworkConfigure playbook_run = kayobe.cli.commands:PlaybookRun seed_container_image_build = kayobe.cli.commands:SeedContainerImageBuild @@ -213,8 +212,6 @@ kayobe.cli.overcloud_service_stop = hooks = kayobe.cli.commands:HookDispatcher kayobe.cli.overcloud_service_upgrade = hooks = kayobe.cli.commands:HookDispatcher -kayobe.cli.overcloud_swift_rings_generate = - hooks = kayobe.cli.commands:HookDispatcher kayobe.cli.overcloud_passwords_view = hooks = kayobe.cli.commands:HookDispatcher kayobe.cli.physical_network_configure = diff --git a/tox.ini b/tox.ini index 86f549130..582a843cd 100644 --- a/tox.ini +++ b/tox.ini @@ -6,6 +6,7 @@ envlist = py3,pep8 usedevelop = True passenv = HOME + ANSIBLE_CONFIG allowlist_externals = bash make diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml index 1ef9a2bd6..da3cb55a0 100644 --- a/zuul.d/jobs.yaml +++ b/zuul.d/jobs.yaml @@ -4,11 +4,17 @@ description: | Tox job that checks Ansible playbook syntax. parent: openstack-tox - pre-run: playbooks/kayobe-tox-ansible-syntax/pre.yml + pre-run: + - playbooks/kayobe-tox/pre.yml + - playbooks/kayobe-tox-ansible-syntax/pre.yml required-projects: - name: openstack/ansible-collection-kolla vars: tox_envlist: ansible-syntax + # Use the site's OpenDev Galaxy mirror for role/collection installs. + # A pre-run playbook renders ansible-ci.cfg from a template. + tox_environment: + ANSIBLE_CONFIG: "{{ ansible_env.PWD ~ '/ansible-ci.cfg' }}" ansible_collection_kolla_src_dir: "{{ ansible_env.PWD ~ '/' ~ zuul.projects['opendev.org/openstack/ansible-collection-kolla'].src_dir }}" kayobe_src_dir: "{{ ansible_env.PWD ~ '/' ~ zuul.projects['opendev.org/openstack/kayobe'].src_dir }}" irrelevant-files: @@ -27,9 +33,14 @@ description: | Tox job that runs native Ansible role tests. parent: openstack-tox-with-sudo + pre-run: playbooks/kayobe-tox/pre.yml timeout: 3600 vars: tox_envlist: ansible + # Use the site's OpenDev Galaxy mirror for role/collection installs. + # A pre-run playbook renders ansible-ci.cfg from a template. + tox_environment: + ANSIBLE_CONFIG: "{{ ansible_env.PWD ~ '/ansible-ci.cfg' }}" required-projects: - name: openstack/requirements irrelevant-files: @@ -48,12 +59,18 @@ description: | Tox job that runs molecule-based Ansible role tests. parent: openstack-tox-with-sudo - pre-run: playbooks/kayobe-tox-molecule/pre.yml + pre-run: + - playbooks/kayobe-tox/pre.yml + - playbooks/kayobe-tox-molecule/pre.yml timeout: 3600 required-projects: - openstack/requirements vars: tox_envlist: molecule + # Use the site's OpenDev Galaxy mirror for role/collection installs. + # A pre-run playbook renders ansible-ci.cfg from a template. + tox_environment: + ANSIBLE_CONFIG: "{{ ansible_env.PWD ~ '/ansible-ci.cfg' }}" irrelevant-files: - ^.*\.md$ - ^.*\.rst$ diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml index 70b618334..b10876f99 100644 --- a/zuul.d/project.yaml +++ b/zuul.d/project.yaml @@ -29,6 +29,7 @@ - kayobe-overcloud-ubuntu-noble - kayobe-overcloud-ubuntu-noble-podman - kayobe-overcloud-upgrade-rocky10 + - kayobe-overcloud-upgrade-ubuntu-noble - kayobe-seed-rocky10 - kayobe-seed-rocky10-podman - kayobe-seed-ubuntu-noble @@ -57,6 +58,7 @@ - kayobe-overcloud-ubuntu-noble - kayobe-overcloud-ubuntu-noble-podman - kayobe-overcloud-upgrade-rocky10 + - kayobe-overcloud-upgrade-ubuntu-noble - kayobe-seed-rocky10 - kayobe-seed-rocky10-podman - kayobe-seed-ubuntu-noble @@ -89,6 +91,3 @@ - kayobe-seed-vm-rocky10-q35 - kayobe-seed-vm-ubuntu-noble-cloud-image - kayobe-seed-vm-ubuntu-noble-q35 - periodic: - jobs: - - kayobe-overcloud-upgrade-ubuntu-noble