From b625fc41f069cd9ad099b43fbbab0beecd40d58d Mon Sep 17 00:00:00 2001 From: Dmitriy Rabotyagov Date: Tue, 12 Aug 2025 12:52:23 +0200 Subject: [PATCH] Add relevant releases tooling into the repo This patch adds refactored releasing tooling from [1] to the "mainlined" repository for general usage. [1] https://github.com/noonedeadpunk/osa_cli_releases/tree/standalone Change-Id: I486de0edfa6f07b960069ec99f60effefd157f11 Signed-off-by: Dmitriy Rabotyagov --- doc/source/contributors/periodic-work.rst | 24 +- inventory/openstack_inventory.json | 4449 +++++++++++++++++ osa_toolkit/releasing.py | 657 +++ setup.cfg | 8 +- test-requirements.txt | 3 + tests/fixtures/ansible-role-requirements.yml | 196 + tests/fixtures/global-requirements-pins.txt | 16 + tests/fixtures/repo_packages/gnocchi.yml | 38 + .../repo_packages/openstack_services.yml | 294 ++ tests/test_releases.py | 116 + tox.ini | 1 + 11 files changed, 5788 insertions(+), 14 deletions(-) create mode 100644 inventory/openstack_inventory.json create mode 100644 osa_toolkit/releasing.py create mode 100644 tests/fixtures/ansible-role-requirements.yml create mode 100644 tests/fixtures/global-requirements-pins.txt create mode 100644 tests/fixtures/repo_packages/gnocchi.yml create mode 100644 tests/fixtures/repo_packages/openstack_services.yml create mode 100644 tests/test_releases.py diff --git a/doc/source/contributors/periodic-work.rst b/doc/source/contributors/periodic-work.rst index 1fa628b136..058574e452 100644 --- a/doc/source/contributors/periodic-work.rst +++ b/doc/source/contributors/periodic-work.rst @@ -22,26 +22,24 @@ necessary for releasing into the openstack-ansible code tree. This allowed the tooling for releasing to be more flexible, and lighter, over time. -Now, all the functions are separated, and included into a branch -independent tooling, `osa_cli_releases`. +All the functions are separated, and included as an extra console +script ``openstack-ansible-releases``. -.. _osa_cli_releases: https://github.com/noonedeadpunk/osa_cli_releases - -You can install the latest version of this tooling by running: +By default, dependencies for the script are not installed to minimize amount +of them for regular users. +To ensure all required dependencies are installed for the script, you can run: .. parsed-literal:: - pip3 install -e git+https://github.com/noonedeadpunk/osa-cli.git#egg=openstack_ansible_cli - pip3 install -e git+https://github.com/noonedeadpunk/osa_cli_releases.git#egg=osa_cli_releases + pip3 install -e git+https://opendev.org/openstack/openstack-ansible#egg=openstack-ansible[releases] -This tooling can then be called using ``osa releases``. Each subcommand contains help by default. Updating upstream SHAs ---------------------- The dependencies for OpenStack-Ansible are updated -through the use of ``osa releases bump_upstream_shas``. This script +through the use of ``openstack-ansible-releases bump_upstream_shas``. This script updates the project's pinned SHAs, located in the ``inventory/group_vars//source_git.yml`` file, based on their ``_git_track_branch`` value. @@ -51,7 +49,7 @@ Updating OpenStack-Ansible roles -------------------------------- Updating the roles to their latest version per branch is done through -``osa releases bump_roles``. +``openstack-ansible-releases bump_roles``. This can do multiple things: @@ -61,13 +59,13 @@ This can do multiple things: * Unfreeze of master. Master doesn't get frozen, unless explicitly asked for it for release -milestones, using the command ``osa releases freeze_roles_for_milestone`` +milestones, using the command ``openstack-ansible-releases freeze_roles_for_milestone`` Updating required collections ----------------------------- Updating collections to their latest version is done through -``osa releases bump_collections``. +``openstack-ansible-releases bump_collections``. Please note, that only collections with type `git` are supported. Ones, that are installed from Ansible Galaxy should be bumped manually. @@ -77,7 +75,7 @@ Check current pins status ------------------------- You can check the current PyPI pins that are used in openstack-ansible -repository by running ``osa releases check_pins``. This will display +repository by running ``openstack-ansible-releases check_pins``. This will display a table, showing the current pin in OSA, and what is available upstream on PyPI. diff --git a/inventory/openstack_inventory.json b/inventory/openstack_inventory.json new file mode 100644 index 0000000000..05ae874e0b --- /dev/null +++ b/inventory/openstack_inventory.json @@ -0,0 +1,4449 @@ +{ + "_meta": { + "hostvars": { + "aio1": { + "ansible_host": "172.29.236.100", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "manila_share", + "container_name": "aio1", + "container_networks": { + "dbaas_address": { + "bridge": "br-dbaas", + "netmask": "255.255.252.0", + "type": "veth" + }, + "eth11_address": { + "bridge": "br-vlan", + "netmask": null, + "type": "veth" + }, + "eth12_address": { + "bridge": "br-vlan", + "netmask": null, + "type": "veth" + }, + "lbaas_address": { + "bridge": "br-lbaas", + "netmask": "255.255.252.0", + "type": "veth" + }, + "management_address": { + "address": "172.29.236.100", + "bridge": "br-mgmt", + "netmask": "255.255.252.0", + "type": "veth" + }, + "storage_address": { + "bridge": "br-storage", + "netmask": "255.255.252.0", + "type": "veth" + }, + "tunnel_address": { + "bridge": "br-vxlan", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "container_types": "aio1-host_containers", + "is_metal": true, + "management_address": "172.29.236.100", + "physical_host": "aio1", + "physical_host_group": "manila-data_hosts", + "properties": { + "is_metal": true + }, + "swift_vars": { + "region": 1, + "zone": 0 + } + }, + "aio1-adjutant-container-751a40c3": { + "ansible_host": "172.29.239.131", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "adjutant_api", + "container_name": "aio1-adjutant-container-751a40c3", + "container_networks": { + "management_address": { + "address": "172.29.239.131", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.239.131", + "physical_host": "aio1", + "physical_host_group": "registration_hosts", + "properties": {} + }, + "aio1-aodh-container-f622c67b": { + "ansible_host": "172.29.237.38", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "aodh_api", + "container_name": "aio1-aodh-container-f622c67b", + "container_networks": { + "management_address": { + "address": "172.29.237.38", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.237.38", + "physical_host": "aio1", + "physical_host_group": "metering-alarm_hosts", + "properties": {} + }, + "aio1-barbican-container-b2ce9f16": { + "ansible_host": "172.29.238.64", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "barbican_api", + "container_name": "aio1-barbican-container-b2ce9f16", + "container_networks": { + "management_address": { + "address": "172.29.238.64", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.238.64", + "physical_host": "aio1", + "physical_host_group": "key-manager_hosts", + "properties": {} + }, + "aio1-blazar-container-fd7d6250": { + "ansible_host": "172.29.238.112", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "blazar_api", + "container_name": "aio1-blazar-container-fd7d6250", + "container_networks": { + "management_address": { + "address": "172.29.238.112", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.238.112", + "physical_host": "aio1", + "physical_host_group": "reservation_hosts", + "properties": {} + }, + "aio1-ceilometer-central-container-030b124d": { + "ansible_host": "172.29.237.135", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "ceilometer_agent_central", + "container_name": "aio1-ceilometer-central-container-030b124d", + "container_networks": { + "management_address": { + "address": "172.29.237.135", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.237.135", + "physical_host": "aio1", + "physical_host_group": "metering-infra_hosts", + "properties": {} + }, + "aio1-ceph-mon-container-c1e520d8": { + "ansible_host": "172.29.239.67", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "ceph-mon", + "container_name": "aio1-ceph-mon-container-c1e520d8", + "container_networks": { + "management_address": { + "address": "172.29.239.67", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.239.67", + "physical_host": "aio1", + "physical_host_group": "ceph-mon_hosts", + "properties": {} + }, + "aio1-ceph-rgw-container-bdfd57cb": { + "ansible_host": "172.29.237.40", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "ceph-rgw", + "container_name": "aio1-ceph-rgw-container-bdfd57cb", + "container_networks": { + "management_address": { + "address": "172.29.237.40", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.237.40", + "physical_host": "aio1", + "physical_host_group": "ceph-rgw_hosts", + "properties": {} + }, + "aio1-cinder-api-container-77dc1e8a": { + "ansible_host": "172.29.239.171", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "cinder_api", + "container_name": "aio1-cinder-api-container-77dc1e8a", + "container_networks": { + "management_address": { + "address": "172.29.239.171", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + }, + "storage_address": { + "address": "172.29.246.14", + "bridge": "br-storage", + "interface": "eth2", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.239.171", + "physical_host": "aio1", + "physical_host_group": "storage-infra_hosts", + "properties": {} + }, + "aio1-cloudkitty-container-4d02f934": { + "ansible_host": "172.29.236.136", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "cloudkitty_api", + "container_name": "aio1-cloudkitty-container-4d02f934", + "container_networks": { + "management_address": { + "address": "172.29.236.136", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.236.136", + "physical_host": "aio1", + "physical_host_group": "rating_hosts", + "properties": {} + }, + "aio1-designate-container-92050663": { + "ansible_host": "172.29.239.11", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "designate_api", + "container_name": "aio1-designate-container-92050663", + "container_networks": { + "management_address": { + "address": "172.29.239.11", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.239.11", + "physical_host": "aio1", + "physical_host_group": "dnsaas_hosts", + "properties": {} + }, + "aio1-galera-container-4e7eea46": { + "ansible_host": "172.29.238.8", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "galera", + "container_name": "aio1-galera-container-4e7eea46", + "container_networks": { + "management_address": { + "address": "172.29.238.8", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.238.8", + "physical_host": "aio1", + "physical_host_group": "shared-infra_hosts", + "properties": {} + }, + "aio1-glance-container-1f06087a": { + "ansible_host": "172.29.237.43", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "glance_api", + "container_name": "aio1-glance-container-1f06087a", + "container_networks": { + "management_address": { + "address": "172.29.237.43", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + }, + "storage_address": { + "address": "172.29.246.7", + "bridge": "br-storage", + "interface": "eth2", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.237.43", + "physical_host": "aio1", + "physical_host_group": "image_hosts", + "properties": { + "container_fs_size": "12G" + } + }, + "aio1-gnocchi-container-c246ede9": { + "ansible_host": "172.29.238.213", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "gnocchi_api", + "container_name": "aio1-gnocchi-container-c246ede9", + "container_networks": { + "management_address": { + "address": "172.29.238.213", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.238.213", + "physical_host": "aio1", + "physical_host_group": "metrics_hosts", + "properties": {} + }, + "aio1-heat-api-container-4da31a7f": { + "ansible_host": "172.29.237.134", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "heat_api_cfn", + "container_name": "aio1-heat-api-container-4da31a7f", + "container_networks": { + "management_address": { + "address": "172.29.237.134", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.237.134", + "physical_host": "aio1", + "physical_host_group": "orchestration_hosts", + "properties": {} + }, + "aio1-horizon-container-e7e5967b": { + "ansible_host": "172.29.239.69", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "horizon", + "container_name": "aio1-horizon-container-e7e5967b", + "container_networks": { + "management_address": { + "address": "172.29.239.69", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.239.69", + "physical_host": "aio1", + "physical_host_group": "dashboard_hosts", + "properties": {} + }, + "aio1-ironic-api-container-4e4df96c": { + "ansible_host": "172.29.239.148", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "ironic_api", + "container_name": "aio1-ironic-api-container-4e4df96c", + "container_networks": { + "management_address": { + "address": "172.29.239.148", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.239.148", + "physical_host": "aio1", + "physical_host_group": "ironic-infra_hosts", + "properties": {} + }, + "aio1-ironic-compute-container-f6982d53": { + "ansible_host": "172.29.239.200", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "ironic_compute", + "container_name": "aio1-ironic-compute-container-f6982d53", + "container_networks": { + "management_address": { + "address": "172.29.239.200", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + }, + "storage_address": { + "address": "172.29.245.151", + "bridge": "br-storage", + "interface": "eth2", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.239.200", + "physical_host": "aio1", + "physical_host_group": "ironic-compute_hosts", + "properties": { + "is_metal": false + } + }, + "aio1-ironic-inspector-container-39692aa1": { + "ansible_host": "172.29.237.207", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "ironic_inspector", + "container_name": "aio1-ironic-inspector-container-39692aa1", + "container_networks": { + "bmaas_address": { + "address": "172.29.229.21", + "bridge": "br-bmaas", + "interface": "eth15", + "netmask": "255.255.252.0", + "type": "veth" + }, + "management_address": { + "address": "172.29.237.207", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.237.207", + "physical_host": "aio1", + "physical_host_group": "ironic-inspector_hosts", + "properties": {} + }, + "aio1-keystone-container-653a0714": { + "ansible_host": "172.29.237.25", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "keystone", + "container_name": "aio1-keystone-container-653a0714", + "container_networks": { + "management_address": { + "address": "172.29.237.25", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.237.25", + "physical_host": "aio1", + "physical_host_group": "identity_hosts", + "properties": {} + }, + "aio1-magnum-container-ba67787b": { + "ansible_host": "172.29.238.145", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "magnum", + "container_name": "aio1-magnum-container-ba67787b", + "container_networks": { + "management_address": { + "address": "172.29.238.145", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.238.145", + "physical_host": "aio1", + "physical_host_group": "magnum-infra_hosts", + "properties": {} + }, + "aio1-manila-container-98c9874a": { + "ansible_host": "172.29.237.6", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "manila_api", + "container_name": "aio1-manila-container-98c9874a", + "container_networks": { + "management_address": { + "address": "172.29.237.6", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.237.6", + "physical_host": "aio1", + "physical_host_group": "manila-infra_hosts", + "properties": {} + }, + "aio1-masakari-api-container-dd1eac12": { + "ansible_host": "172.29.238.237", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "masakari_engine", + "container_name": "aio1-masakari-api-container-dd1eac12", + "container_networks": { + "management_address": { + "address": "172.29.238.237", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.238.237", + "physical_host": "aio1", + "physical_host_group": "masakari-infra_hosts", + "properties": {} + }, + "aio1-memcached-container-aab1b554": { + "ansible_host": "172.29.238.196", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "memcached", + "container_name": "aio1-memcached-container-aab1b554", + "container_networks": { + "management_address": { + "address": "172.29.238.196", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.238.196", + "physical_host": "aio1", + "physical_host_group": "shared-infra_hosts", + "properties": {} + }, + "aio1-mistral-container-435cbc6d": { + "ansible_host": "172.29.239.74", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "mistral_api", + "container_name": "aio1-mistral-container-435cbc6d", + "container_networks": { + "management_address": { + "address": "172.29.239.74", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.239.74", + "physical_host": "aio1", + "physical_host_group": "mistral-infra_hosts", + "properties": {} + }, + "aio1-neutron-server-container-93961a30": { + "ansible_host": "172.29.238.173", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "neutron_server", + "container_name": "aio1-neutron-server-container-93961a30", + "container_networks": { + "management_address": { + "address": "172.29.238.173", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.238.173", + "physical_host": "aio1", + "physical_host_group": "network_hosts", + "properties": {} + }, + "aio1-nova-api-container-3bdc2ad4": { + "ansible_host": "172.29.236.203", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "nova_api_metadata", + "container_name": "aio1-nova-api-container-3bdc2ad4", + "container_networks": { + "management_address": { + "address": "172.29.236.203", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.236.203", + "physical_host": "aio1", + "physical_host_group": "compute-infra_hosts", + "properties": {} + }, + "aio1-octavia-server-container-df2452cf": { + "ansible_host": "172.29.238.166", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "octavia-api", + "container_name": "aio1-octavia-server-container-df2452cf", + "container_networks": { + "lbaas_address": { + "address": "172.29.232.14", + "bridge": "br-lbaas", + "interface": "eth14", + "netmask": "255.255.252.0", + "type": "veth" + }, + "management_address": { + "address": "172.29.238.166", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.238.166", + "physical_host": "aio1", + "physical_host_group": "octavia-infra_hosts", + "properties": {} + }, + "aio1-placement-container-36b96d32": { + "ansible_host": "172.29.238.54", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "placement_api", + "container_name": "aio1-placement-container-36b96d32", + "container_networks": { + "management_address": { + "address": "172.29.238.54", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.238.54", + "physical_host": "aio1", + "physical_host_group": "placement-infra_hosts", + "properties": {} + }, + "aio1-rabbit-mq-container-19accdb7": { + "ansible_host": "172.29.239.27", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "rabbitmq", + "container_name": "aio1-rabbit-mq-container-19accdb7", + "container_networks": { + "dbaas_address": { + "address": "172.29.252.16", + "bridge": "br-dbaas", + "interface": "eth13", + "netmask": "255.255.252.0", + "type": "veth" + }, + "management_address": { + "address": "172.29.239.27", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.239.27", + "physical_host": "aio1", + "physical_host_group": "shared-infra_hosts", + "properties": {} + }, + "aio1-repo-container-8e09a94e": { + "ansible_host": "172.29.236.75", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "pkg_repo", + "container_name": "aio1-repo-container-8e09a94e", + "container_networks": { + "management_address": { + "address": "172.29.236.75", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.236.75", + "physical_host": "aio1", + "physical_host_group": "repo-infra_hosts", + "properties": {} + }, + "aio1-skyline-container-653d6c73": { + "ansible_host": "172.29.238.52", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "skyline", + "container_name": "aio1-skyline-container-653d6c73", + "container_networks": { + "management_address": { + "address": "172.29.238.52", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.238.52", + "physical_host": "aio1", + "physical_host_group": "skyline_dashboard_hosts", + "properties": {} + }, + "aio1-swift-proxy-container-8ad906fc": { + "ansible_host": "172.29.237.186", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "swift_proxy", + "container_name": "aio1-swift-proxy-container-8ad906fc", + "container_networks": { + "management_address": { + "address": "172.29.237.186", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + }, + "storage_address": { + "address": "172.29.246.137", + "bridge": "br-storage", + "interface": "eth2", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.237.186", + "physical_host": "aio1", + "physical_host_group": "swift-proxy_hosts", + "properties": {}, + "swift_proxy_vars": { + "read_affinity": "r1=100", + "write_affinity": "r1", + "write_affinity_node_count": "1 * replicas" + }, + "swift_vars": { + "region": 1, + "zone": 0 + } + }, + "aio1-tacker-container-bcf92543": { + "ansible_host": "172.29.238.16", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "tacker_server", + "container_name": "aio1-tacker-container-bcf92543", + "container_networks": { + "management_address": { + "address": "172.29.238.16", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.238.16", + "physical_host": "aio1", + "physical_host_group": "mano_hosts", + "properties": {} + }, + "aio1-trove-api-container-e91426a3": { + "ansible_host": "172.29.239.210", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "trove_api", + "container_name": "aio1-trove-api-container-e91426a3", + "container_networks": { + "management_address": { + "address": "172.29.239.210", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.239.210", + "physical_host": "aio1", + "physical_host_group": "trove-infra_hosts", + "properties": {} + }, + "aio1-unbound-container-d00a4227": { + "ansible_host": "172.29.236.168", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "unbound", + "container_name": "aio1-unbound-container-d00a4227", + "container_networks": { + "management_address": { + "address": "172.29.236.168", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.236.168", + "physical_host": "aio1", + "physical_host_group": "unbound_hosts", + "properties": {} + }, + "aio1-utility-container-f4c87fa8": { + "ansible_host": "172.29.239.191", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "utility", + "container_name": "aio1-utility-container-f4c87fa8", + "container_networks": { + "management_address": { + "address": "172.29.239.191", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.239.191", + "physical_host": "aio1", + "physical_host_group": "shared-infra_hosts", + "properties": {} + }, + "aio1-zun-api-container-a405a8e0": { + "ansible_host": "172.29.239.164", + "cinder_qos_specs": [ + { + "cinder_volume_types": [ + "low-iops" + ], + "name": "low-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 75, + "write_iops_sec": 75 + } + }, + { + "cinder_volume_types": [ + "high-iops" + ], + "name": "high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 150, + "write_iops_sec": 150 + } + }, + { + "cinder_volume_types": [ + "ultra-high-iops" + ], + "name": "ultra-high-iops", + "options": { + "consumer": "front-end", + "read_iops_sec": 300, + "write_iops_sec": 300 + } + } + ], + "component": "zun_api", + "container_name": "aio1-zun-api-container-a405a8e0", + "container_networks": { + "management_address": { + "address": "172.29.239.164", + "bridge": "br-mgmt", + "interface": "eth1", + "netmask": "255.255.252.0", + "type": "veth" + } + }, + "container_tech": "lxc", + "management_address": "172.29.239.164", + "physical_host": "aio1", + "physical_host_group": "zun-infra_hosts", + "properties": {} + } + } + }, + "adjutant_all": { + "children": [ + "adjutant_api" + ], + "hosts": [] + }, + "adjutant_api": { + "children": [], + "hosts": [ + "aio1-adjutant-container-751a40c3" + ] + }, + "adjutant_container": { + "hosts": [ + "aio1-adjutant-container-751a40c3" + ] + }, + "aio1-host_containers": { + "hosts": [ + "aio1-zun-api-container-a405a8e0", + "aio1-mistral-container-435cbc6d", + "aio1-cloudkitty-container-4d02f934", + "aio1-barbican-container-b2ce9f16", + "aio1-masakari-api-container-dd1eac12", + "aio1-magnum-container-ba67787b", + "aio1-unbound-container-d00a4227", + "aio1-designate-container-92050663", + "aio1-heat-api-container-4da31a7f", + "aio1-galera-container-4e7eea46", + "aio1-utility-container-f4c87fa8", + "aio1-swift-proxy-container-8ad906fc", + "aio1-blazar-container-fd7d6250", + "aio1-skyline-container-653d6c73", + "aio1-neutron-server-container-93961a30", + "aio1-nova-api-container-3bdc2ad4", + "aio1-ceph-mon-container-c1e520d8", + "aio1-ceph-rgw-container-bdfd57cb", + "aio1-ironic-api-container-4e4df96c", + "aio1-ironic-compute-container-f6982d53", + "aio1-ironic-inspector-container-39692aa1", + "aio1-octavia-server-container-df2452cf", + "aio1-rabbit-mq-container-19accdb7", + "aio1-glance-container-1f06087a", + "aio1-ceilometer-central-container-030b124d", + "aio1-memcached-container-aab1b554", + "aio1-keystone-container-653a0714", + "aio1-repo-container-8e09a94e", + "aio1-cinder-api-container-77dc1e8a", + "aio1-trove-api-container-e91426a3", + "aio1-aodh-container-f622c67b", + "aio1-horizon-container-e7e5967b", + "aio1-placement-container-36b96d32", + "aio1-tacker-container-bcf92543", + "aio1-gnocchi-container-c246ede9", + "aio1-adjutant-container-751a40c3", + "aio1-manila-container-98c9874a" + ] + }, + "all": { + "vars": { + "container_cidr": "172.29.236.0/22", + "external_lb_vip_address": "{{ bootstrap_host_public_address }}", + "internal_lb_vip_address": "172.29.236.101", + "management_bridge": "br-mgmt", + "provider_networks": [ + { + "network": { + "container_bridge": "br-mgmt", + "container_interface": "eth1", + "container_type": "veth", + "group_binds": [ + "all_containers", + "hosts" + ], + "ip_from_q": "management", + "is_management_address": true, + "type": "raw" + } + }, + { + "network": { + "container_bridge": "br-vxlan", + "container_interface": "eth10", + "container_type": "veth", + "group_binds": [ + "neutron_openvswitch_agent" + ], + "ip_from_q": "tunnel", + "net_name": "vxlan", + "range": "1:1000", + "type": "vxlan" + } + }, + { + "network": { + "container_bridge": "br-dbaas", + "container_interface": "eth13", + "container_type": "veth", + "group_binds": [ + "neutron_openvswitch_agent", + "rabbitmq" + ], + "host_bind_override": "eth13", + "ip_from_q": "dbaas", + "net_name": "dbaas-mgmt", + "type": "flat" + } + }, + { + "network": { + "container_bridge": "br-lbaas", + "container_interface": "eth14", + "container_type": "veth", + "group_binds": [ + "neutron_openvswitch_agent", + "octavia-worker", + "octavia-housekeeping", + "octavia-health-manager" + ], + "host_bind_override": "eth14", + "ip_from_q": "lbaas", + "net_name": "lbaas", + "type": "flat" + } + }, + { + "network": { + "container_bridge": "br-bmaas", + "container_interface": "eth15", + "container_type": "veth", + "group_binds": [ + "ironic_inspector" + ], + "host_bind_override": "eth15", + "ip_from_q": "bmaas", + "net_name": "bmaas", + "type": "flat" + } + }, + { + "network": { + "container_bridge": "br-vlan", + "container_interface": "eth12", + "container_type": "veth", + "group_binds": [ + "neutron_openvswitch_agent" + ], + "host_bind_override": "eth12", + "net_name": "physnet1", + "type": "flat" + } + }, + { + "network": { + "container_bridge": "br-vlan", + "container_interface": "eth11", + "container_type": "veth", + "group_binds": [ + "neutron_openvswitch_agent" + ], + "net_name": "physnet2", + "range": "101:200,301:400", + "type": "vlan" + } + }, + { + "network": { + "container_bridge": "br-storage", + "container_interface": "eth2", + "container_type": "veth", + "group_binds": [ + "glance_api", + "cinder_api", + "cinder_volume", + "manila_share", + "nova_compute", + "swift_proxy" + ], + "ip_from_q": "storage", + "type": "raw" + } + } + ] + } + }, + "all_containers": { + "children": [ + "zun-compute_containers", + "zun-infra_containers", + "mistral-infra_containers", + "rating_containers", + "key-manager_containers", + "masakari-monitor_containers", + "masakari-infra_containers", + "magnum-infra_containers", + "unbound_containers", + "dnsaas_containers", + "orchestration_containers", + "database_containers", + "operator_containers", + "swift_containers", + "swift-proxy_containers", + "reservation_containers", + "skyline_dashboard_containers", + "network_containers", + "network-agent_containers", + "network-infra_containers", + "network-gateway_containers", + "network-northd_containers", + "compute-infra_containers", + "compute_containers", + "kvm-compute_containers", + "qemu-compute_containers", + "ceph-mon_containers", + "ceph-osd_containers", + "ceph-rgw_containers", + "ceph-mds_containers", + "ceph-nfs_containers", + "ironic-infra_containers", + "ironic-compute_containers", + "ironic-inspector_containers", + "octavia-infra_containers", + "mq_containers", + "image_containers", + "metering-compute_containers", + "metering-infra_containers", + "memcaching_containers", + "os-infra_containers", + "identity_containers", + "repo-infra_containers", + "storage-infra_containers", + "storage_containers", + "coordination_containers", + "trove-infra_containers", + "metering-alarm_containers", + "load_balancer_containers", + "haproxy_containers", + "dashboard_containers", + "placement-infra_containers", + "mano_containers", + "metrics_containers", + "registration_containers", + "shared-infra_containers", + "manila-data_containers", + "manila-infra_containers" + ], + "hosts": [] + }, + "aodh_alarm_evaluator": { + "children": [], + "hosts": [ + "aio1-aodh-container-f622c67b" + ] + }, + "aodh_alarm_notifier": { + "children": [], + "hosts": [ + "aio1-aodh-container-f622c67b" + ] + }, + "aodh_all": { + "children": [ + "aodh_api", + "aodh_listener", + "aodh_alarm_evaluator", + "aodh_alarm_notifier" + ], + "hosts": [] + }, + "aodh_api": { + "children": [], + "hosts": [ + "aio1-aodh-container-f622c67b" + ] + }, + "aodh_container": { + "hosts": [ + "aio1-aodh-container-f622c67b" + ] + }, + "aodh_listener": { + "children": [], + "hosts": [ + "aio1-aodh-container-f622c67b" + ] + }, + "barbican_all": { + "children": [ + "barbican_api" + ], + "hosts": [] + }, + "barbican_api": { + "children": [], + "hosts": [ + "aio1-barbican-container-b2ce9f16" + ] + }, + "barbican_container": { + "hosts": [ + "aio1-barbican-container-b2ce9f16" + ] + }, + "blazar_all": { + "children": [ + "blazar_api", + "blazar_manager" + ], + "hosts": [] + }, + "blazar_api": { + "children": [], + "hosts": [ + "aio1-blazar-container-fd7d6250" + ] + }, + "blazar_container": { + "hosts": [ + "aio1-blazar-container-fd7d6250" + ] + }, + "blazar_manager": { + "children": [], + "hosts": [ + "aio1-blazar-container-fd7d6250" + ] + }, + "ceilometer_agent_central": { + "children": [], + "hosts": [ + "aio1-ceilometer-central-container-030b124d" + ] + }, + "ceilometer_agent_compute": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "ceilometer_agent_notification": { + "children": [], + "hosts": [ + "aio1-ceilometer-central-container-030b124d" + ] + }, + "ceilometer_all": { + "children": [ + "ceilometer_agent_compute", + "ceilometer_agent_central", + "ceilometer_agent_notification" + ], + "hosts": [] + }, + "ceilometer_central_container": { + "hosts": [ + "aio1-ceilometer-central-container-030b124d" + ] + }, + "ceph-mds": { + "children": [], + "hosts": [] + }, + "ceph-mds_container": { + "hosts": [] + }, + "ceph-mds_containers": { + "children": [ + "ceph-mds_container" + ], + "hosts": [] + }, + "ceph-mds_hosts": { + "children": [], + "hosts": [] + }, + "ceph-mon": { + "children": [], + "hosts": [ + "aio1-ceph-mon-container-c1e520d8" + ] + }, + "ceph-mon_all": { + "hosts": [ + "aio1", + "aio1-ceph-mon-container-c1e520d8" + ] + }, + "ceph-mon_container": { + "hosts": [ + "aio1-ceph-mon-container-c1e520d8" + ] + }, + "ceph-mon_containers": { + "children": [ + "ceph-mon_container" + ], + "hosts": [] + }, + "ceph-mon_hosts": { + "hosts": [ + "aio1" + ] + }, + "ceph-nfs": { + "children": [], + "hosts": [] + }, + "ceph-nfs_container": { + "hosts": [] + }, + "ceph-nfs_containers": { + "children": [ + "ceph-nfs_container" + ], + "hosts": [] + }, + "ceph-nfs_hosts": { + "children": [], + "hosts": [] + }, + "ceph-osd": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "ceph-osd_all": { + "hosts": [ + "aio1" + ] + }, + "ceph-osd_container": { + "hosts": [] + }, + "ceph-osd_containers": { + "children": [ + "ceph-osd_container" + ], + "hosts": [] + }, + "ceph-osd_hosts": { + "hosts": [ + "aio1" + ] + }, + "ceph-rgw": { + "children": [], + "hosts": [ + "aio1-ceph-rgw-container-bdfd57cb" + ] + }, + "ceph-rgw_all": { + "hosts": [ + "aio1", + "aio1-ceph-rgw-container-bdfd57cb" + ] + }, + "ceph-rgw_container": { + "hosts": [ + "aio1-ceph-rgw-container-bdfd57cb" + ] + }, + "ceph-rgw_containers": { + "children": [ + "ceph-rgw_container" + ], + "hosts": [] + }, + "ceph-rgw_hosts": { + "hosts": [ + "aio1" + ] + }, + "ceph_all": { + "children": [ + "ceph-mon", + "ceph-osd", + "ceph-rgw", + "ceph-mds", + "ceph-nfs" + ], + "hosts": [] + }, + "cinder_all": { + "children": [ + "cinder_api", + "cinder_scheduler", + "cinder_volume", + "cinder_backup" + ], + "hosts": [] + }, + "cinder_api": { + "children": [], + "hosts": [ + "aio1-cinder-api-container-77dc1e8a" + ] + }, + "cinder_api_container": { + "hosts": [ + "aio1-cinder-api-container-77dc1e8a" + ] + }, + "cinder_backup": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "cinder_scheduler": { + "children": [], + "hosts": [ + "aio1-cinder-api-container-77dc1e8a" + ] + }, + "cinder_volume": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "cinder_volumes_container": { + "hosts": [] + }, + "cloudkitty_all": { + "children": [ + "cloudkitty_api", + "cloudkitty_engine" + ], + "hosts": [] + }, + "cloudkitty_api": { + "children": [], + "hosts": [ + "aio1-cloudkitty-container-4d02f934" + ] + }, + "cloudkitty_container": { + "hosts": [ + "aio1-cloudkitty-container-4d02f934" + ] + }, + "cloudkitty_engine": { + "children": [], + "hosts": [ + "aio1-cloudkitty-container-4d02f934" + ] + }, + "compute-infra_all": { + "hosts": [ + "aio1", + "aio1-nova-api-container-3bdc2ad4" + ] + }, + "compute-infra_containers": { + "children": [ + "nova_api_container" + ], + "hosts": [] + }, + "compute-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "compute_all": { + "hosts": [ + "aio1" + ] + }, + "compute_containers": { + "children": [ + "nova_compute_container" + ], + "hosts": [] + }, + "compute_hosts": { + "hosts": [ + "aio1" + ] + }, + "coordination_containers": { + "children": [ + "zookeeper_container" + ], + "hosts": [] + }, + "coordination_hosts": { + "children": [], + "hosts": [] + }, + "dashboard_all": { + "hosts": [ + "aio1", + "aio1-horizon-container-e7e5967b" + ] + }, + "dashboard_containers": { + "children": [ + "horizon_container" + ], + "hosts": [] + }, + "dashboard_hosts": { + "hosts": [ + "aio1" + ] + }, + "database_containers": { + "children": [ + "galera_container" + ], + "hosts": [] + }, + "database_hosts": { + "children": [], + "hosts": [] + }, + "designate_all": { + "children": [ + "designate_api", + "designate_central", + "designate_mdns", + "designate_worker", + "designate_producer", + "designate_sink" + ], + "hosts": [] + }, + "designate_api": { + "children": [], + "hosts": [ + "aio1-designate-container-92050663" + ] + }, + "designate_central": { + "children": [], + "hosts": [ + "aio1-designate-container-92050663" + ] + }, + "designate_container": { + "hosts": [ + "aio1-designate-container-92050663" + ] + }, + "designate_mdns": { + "children": [], + "hosts": [ + "aio1-designate-container-92050663" + ] + }, + "designate_producer": { + "children": [], + "hosts": [ + "aio1-designate-container-92050663" + ] + }, + "designate_sink": { + "children": [], + "hosts": [ + "aio1-designate-container-92050663" + ] + }, + "designate_worker": { + "children": [], + "hosts": [ + "aio1-designate-container-92050663" + ] + }, + "dnsaas_all": { + "hosts": [ + "aio1", + "aio1-designate-container-92050663" + ] + }, + "dnsaas_containers": { + "children": [ + "designate_container" + ], + "hosts": [] + }, + "dnsaas_hosts": { + "hosts": [ + "aio1" + ] + }, + "galera": { + "children": [], + "hosts": [ + "aio1-galera-container-4e7eea46" + ] + }, + "galera_all": { + "children": [ + "galera" + ], + "hosts": [] + }, + "galera_container": { + "hosts": [ + "aio1-galera-container-4e7eea46" + ] + }, + "glance_all": { + "children": [ + "glance_api" + ], + "hosts": [] + }, + "glance_api": { + "children": [], + "hosts": [ + "aio1-glance-container-1f06087a" + ] + }, + "glance_container": { + "hosts": [ + "aio1-glance-container-1f06087a" + ] + }, + "gnocchi_all": { + "children": [ + "gnocchi_api", + "gnocchi_metricd" + ], + "hosts": [] + }, + "gnocchi_api": { + "children": [], + "hosts": [ + "aio1-gnocchi-container-c246ede9" + ] + }, + "gnocchi_container": { + "hosts": [ + "aio1-gnocchi-container-c246ede9" + ] + }, + "gnocchi_metricd": { + "children": [], + "hosts": [ + "aio1-gnocchi-container-c246ede9" + ] + }, + "haproxy": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "haproxy_all": { + "children": [ + "haproxy" + ], + "hosts": [] + }, + "haproxy_container": { + "hosts": [] + }, + "haproxy_containers": { + "children": [ + "haproxy_container" + ], + "hosts": [] + }, + "haproxy_hosts": { + "children": [], + "hosts": [] + }, + "heat_all": { + "children": [ + "heat_api", + "heat_api_cfn", + "heat_engine" + ], + "hosts": [] + }, + "heat_api": { + "children": [], + "hosts": [ + "aio1-heat-api-container-4da31a7f" + ] + }, + "heat_api_cfn": { + "children": [], + "hosts": [ + "aio1-heat-api-container-4da31a7f" + ] + }, + "heat_api_container": { + "hosts": [ + "aio1-heat-api-container-4da31a7f" + ] + }, + "heat_engine": { + "children": [], + "hosts": [ + "aio1-heat-api-container-4da31a7f" + ] + }, + "horizon": { + "children": [], + "hosts": [ + "aio1-horizon-container-e7e5967b" + ] + }, + "horizon_all": { + "children": [ + "horizon" + ], + "hosts": [] + }, + "horizon_container": { + "hosts": [ + "aio1-horizon-container-e7e5967b" + ] + }, + "hosts": { + "children": [ + "zun-compute_hosts", + "zun-infra_hosts", + "mistral-infra_hosts", + "rating_hosts", + "key-manager_hosts", + "masakari-monitor_hosts", + "masakari-infra_hosts", + "magnum-infra_hosts", + "unbound_hosts", + "dnsaas_hosts", + "orchestration_hosts", + "database_hosts", + "operator_hosts", + "swift_hosts", + "swift-proxy_hosts", + "reservation_hosts", + "skyline_dashboard_hosts", + "network_hosts", + "network-agent_hosts", + "network-infra_hosts", + "network-gateway_hosts", + "network-northd_hosts", + "compute-infra_hosts", + "compute_hosts", + "kvm-compute_hosts", + "qemu-compute_hosts", + "ceph-mon_hosts", + "ceph-osd_hosts", + "ceph-rgw_hosts", + "ceph-mds_hosts", + "ceph-nfs_hosts", + "ironic-infra_hosts", + "ironic-compute_hosts", + "ironic-inspector_hosts", + "octavia-infra_hosts", + "mq_hosts", + "image_hosts", + "metering-compute_hosts", + "metering-infra_hosts", + "memcaching_hosts", + "os-infra_hosts", + "identity_hosts", + "repo-infra_hosts", + "storage-infra_hosts", + "storage_hosts", + "coordination_hosts", + "trove-infra_hosts", + "metering-alarm_hosts", + "load_balancer_hosts", + "haproxy_hosts", + "dashboard_hosts", + "placement-infra_hosts", + "mano_hosts", + "metrics_hosts", + "registration_hosts", + "shared-infra_hosts", + "manila-data_hosts", + "manila-infra_hosts" + ], + "hosts": [] + }, + "identity_all": { + "hosts": [ + "aio1", + "aio1-keystone-container-653a0714" + ] + }, + "identity_containers": { + "children": [ + "keystone_container" + ], + "hosts": [] + }, + "identity_hosts": { + "hosts": [ + "aio1" + ] + }, + "image_all": { + "hosts": [ + "aio1", + "aio1-glance-container-1f06087a" + ] + }, + "image_containers": { + "children": [ + "glance_container" + ], + "hosts": [] + }, + "image_hosts": { + "hosts": [ + "aio1" + ] + }, + "ironic-compute_all": { + "hosts": [ + "aio1", + "aio1-ironic-compute-container-f6982d53" + ] + }, + "ironic-compute_containers": { + "children": [ + "ironic_compute_container" + ], + "hosts": [] + }, + "ironic-compute_hosts": { + "hosts": [ + "aio1" + ] + }, + "ironic-infra_all": { + "hosts": [ + "aio1", + "aio1-ironic-api-container-4e4df96c" + ] + }, + "ironic-infra_containers": { + "children": [ + "ironic_api_container" + ], + "hosts": [] + }, + "ironic-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "ironic-inspector_all": { + "hosts": [ + "aio1", + "aio1-ironic-inspector-container-39692aa1" + ] + }, + "ironic-inspector_containers": { + "children": [ + "ironic_inspector_container" + ], + "hosts": [] + }, + "ironic-inspector_hosts": { + "hosts": [ + "aio1" + ] + }, + "ironic_all": { + "children": [ + "ironic_api", + "ironic_conductor", + "ironic_inspector", + "ironic_console" + ], + "hosts": [] + }, + "ironic_api": { + "children": [], + "hosts": [ + "aio1-ironic-api-container-4e4df96c" + ] + }, + "ironic_api_container": { + "hosts": [ + "aio1-ironic-api-container-4e4df96c" + ] + }, + "ironic_compute": { + "children": [], + "hosts": [ + "aio1-ironic-compute-container-f6982d53" + ] + }, + "ironic_compute_container": { + "hosts": [ + "aio1-ironic-compute-container-f6982d53" + ] + }, + "ironic_conductor": { + "children": [], + "hosts": [ + "aio1-ironic-api-container-4e4df96c" + ] + }, + "ironic_console": { + "children": [], + "hosts": [ + "aio1-ironic-compute-container-f6982d53" + ] + }, + "ironic_inspector": { + "children": [], + "hosts": [ + "aio1-ironic-inspector-container-39692aa1" + ] + }, + "ironic_inspector_container": { + "hosts": [ + "aio1-ironic-inspector-container-39692aa1" + ] + }, + "ironic_neutron_agent": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "key-manager_all": { + "hosts": [ + "aio1", + "aio1-barbican-container-b2ce9f16" + ] + }, + "key-manager_containers": { + "children": [ + "barbican_container" + ], + "hosts": [] + }, + "key-manager_hosts": { + "hosts": [ + "aio1" + ] + }, + "keystone": { + "children": [], + "hosts": [ + "aio1-keystone-container-653a0714" + ] + }, + "keystone_all": { + "children": [ + "keystone" + ], + "hosts": [] + }, + "keystone_container": { + "hosts": [ + "aio1-keystone-container-653a0714" + ] + }, + "kvm-compute_containers": { + "children": [ + "nova_compute_container" + ], + "hosts": [] + }, + "kvm-compute_hosts": { + "children": [], + "hosts": [] + }, + "load_balancer_all": { + "hosts": [ + "aio1" + ] + }, + "load_balancer_containers": { + "children": [ + "haproxy_container" + ], + "hosts": [] + }, + "load_balancer_hosts": { + "hosts": [ + "aio1" + ] + }, + "lxc_hosts": { + "hosts": [ + "aio1" + ] + }, + "magnum": { + "children": [], + "hosts": [ + "aio1-magnum-container-ba67787b" + ] + }, + "magnum-infra_all": { + "hosts": [ + "aio1", + "aio1-magnum-container-ba67787b" + ] + }, + "magnum-infra_containers": { + "children": [ + "magnum_container" + ], + "hosts": [] + }, + "magnum-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "magnum_all": { + "children": [ + "magnum" + ], + "hosts": [] + }, + "magnum_container": { + "hosts": [ + "aio1-magnum-container-ba67787b" + ] + }, + "manila-data_all": { + "hosts": [ + "aio1" + ] + }, + "manila-data_containers": { + "children": [ + "manila_data_container" + ], + "hosts": [] + }, + "manila-data_hosts": { + "hosts": [ + "aio1" + ] + }, + "manila-infra_all": { + "hosts": [ + "aio1", + "aio1-manila-container-98c9874a" + ] + }, + "manila-infra_containers": { + "children": [ + "manila_container" + ], + "hosts": [] + }, + "manila-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "manila_all": { + "children": [ + "manila_api", + "manila_scheduler", + "manila_data", + "manila_share" + ], + "hosts": [] + }, + "manila_api": { + "children": [], + "hosts": [ + "aio1-manila-container-98c9874a" + ] + }, + "manila_container": { + "hosts": [ + "aio1-manila-container-98c9874a" + ] + }, + "manila_data": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "manila_data_container": { + "hosts": [] + }, + "manila_scheduler": { + "children": [], + "hosts": [ + "aio1-manila-container-98c9874a" + ] + }, + "manila_share": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "mano_all": { + "hosts": [ + "aio1", + "aio1-tacker-container-bcf92543" + ] + }, + "mano_containers": { + "children": [ + "tacker_container" + ], + "hosts": [] + }, + "mano_hosts": { + "hosts": [ + "aio1" + ] + }, + "masakari-infra_all": { + "hosts": [ + "aio1", + "aio1-masakari-api-container-dd1eac12" + ] + }, + "masakari-infra_containers": { + "children": [ + "masakari_api_container" + ], + "hosts": [] + }, + "masakari-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "masakari-monitor_all": { + "hosts": [ + "aio1" + ] + }, + "masakari-monitor_containers": { + "children": [ + "masakari_monitors_container" + ], + "hosts": [] + }, + "masakari-monitor_hosts": { + "hosts": [ + "aio1" + ] + }, + "masakari_all": { + "children": [ + "masakari_engine", + "masakari_api", + "masakari_monitor" + ], + "hosts": [] + }, + "masakari_api": { + "children": [], + "hosts": [ + "aio1-masakari-api-container-dd1eac12" + ] + }, + "masakari_api_container": { + "hosts": [ + "aio1-masakari-api-container-dd1eac12" + ] + }, + "masakari_engine": { + "children": [], + "hosts": [ + "aio1-masakari-api-container-dd1eac12" + ] + }, + "masakari_monitor": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "masakari_monitors_container": { + "hosts": [] + }, + "memcached": { + "children": [], + "hosts": [ + "aio1-memcached-container-aab1b554" + ] + }, + "memcached_all": { + "children": [ + "memcached" + ], + "hosts": [] + }, + "memcached_container": { + "hosts": [ + "aio1-memcached-container-aab1b554" + ] + }, + "memcaching_containers": { + "children": [ + "memcached_container" + ], + "hosts": [] + }, + "memcaching_hosts": { + "children": [], + "hosts": [] + }, + "metering-alarm_all": { + "hosts": [ + "aio1", + "aio1-aodh-container-f622c67b" + ] + }, + "metering-alarm_containers": { + "children": [ + "aodh_container" + ], + "hosts": [] + }, + "metering-alarm_hosts": { + "hosts": [ + "aio1" + ] + }, + "metering-compute_all": { + "hosts": [ + "aio1" + ] + }, + "metering-compute_container": { + "hosts": [] + }, + "metering-compute_containers": { + "children": [ + "metering-compute_container" + ], + "hosts": [] + }, + "metering-compute_hosts": { + "hosts": [ + "aio1" + ] + }, + "metering-infra_all": { + "hosts": [ + "aio1", + "aio1-ceilometer-central-container-030b124d" + ] + }, + "metering-infra_containers": { + "children": [ + "ceilometer_central_container" + ], + "hosts": [] + }, + "metering-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "metrics_all": { + "hosts": [ + "aio1", + "aio1-gnocchi-container-c246ede9" + ] + }, + "metrics_containers": { + "children": [ + "gnocchi_container" + ], + "hosts": [] + }, + "metrics_hosts": { + "hosts": [ + "aio1" + ] + }, + "mistral-infra_all": { + "hosts": [ + "aio1", + "aio1-mistral-container-435cbc6d" + ] + }, + "mistral-infra_containers": { + "children": [ + "mistral_container" + ], + "hosts": [] + }, + "mistral-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "mistral_all": { + "children": [ + "mistral_api", + "mistral_engine", + "mistral_executor", + "mistral_notifier" + ], + "hosts": [] + }, + "mistral_api": { + "children": [], + "hosts": [ + "aio1-mistral-container-435cbc6d" + ] + }, + "mistral_container": { + "hosts": [ + "aio1-mistral-container-435cbc6d" + ] + }, + "mistral_engine": { + "children": [], + "hosts": [ + "aio1-mistral-container-435cbc6d" + ] + }, + "mistral_executor": { + "children": [], + "hosts": [ + "aio1-mistral-container-435cbc6d" + ] + }, + "mistral_notifier": { + "children": [], + "hosts": [ + "aio1-mistral-container-435cbc6d" + ] + }, + "mq_containers": { + "children": [ + "rabbit_mq_container" + ], + "hosts": [] + }, + "mq_hosts": { + "children": [], + "hosts": [] + }, + "network-agent_containers": { + "children": [ + "neutron_agents_container" + ], + "hosts": [] + }, + "network-agent_hosts": { + "children": [], + "hosts": [] + }, + "network-gateway_containers": { + "children": [ + "neutron_ovn_gateway_container" + ], + "hosts": [] + }, + "network-gateway_hosts": { + "children": [], + "hosts": [] + }, + "network-infra_containers": { + "children": [ + "neutron_server_container" + ], + "hosts": [] + }, + "network-infra_hosts": { + "children": [], + "hosts": [] + }, + "network-northd_containers": { + "children": [ + "neutron_ovn_northd_container" + ], + "hosts": [] + }, + "network-northd_hosts": { + "children": [], + "hosts": [] + }, + "network_all": { + "hosts": [ + "aio1", + "aio1-neutron-server-container-93961a30" + ] + }, + "network_containers": { + "children": [ + "neutron_agents_container", + "neutron_server_container" + ], + "hosts": [] + }, + "network_hosts": { + "hosts": [ + "aio1" + ] + }, + "neutron_agent": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "neutron_agents_container": { + "hosts": [] + }, + "neutron_all": { + "children": [ + "ironic_neutron_agent", + "neutron_agent", + "neutron_dhcp_agent", + "neutron_openvswitch_agent", + "neutron_metering_agent", + "neutron_l3_agent", + "neutron_bgp_dragent", + "neutron_metadata_agent", + "neutron_sriov_nic_agent", + "neutron_server", + "neutron_ovn_controller", + "neutron_ovn_gateway", + "neutron_ovn_northd" + ], + "hosts": [] + }, + "neutron_bgp_dragent": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "neutron_dhcp_agent": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "neutron_l3_agent": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "neutron_metadata_agent": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "neutron_metering_agent": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "neutron_openvswitch_agent": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "neutron_ovn_controller": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "neutron_ovn_gateway": { + "children": [], + "hosts": [] + }, + "neutron_ovn_gateway_container": { + "hosts": [] + }, + "neutron_ovn_northd": { + "children": [], + "hosts": [] + }, + "neutron_ovn_northd_container": { + "hosts": [] + }, + "neutron_server": { + "children": [], + "hosts": [ + "aio1-neutron-server-container-93961a30" + ] + }, + "neutron_server_container": { + "hosts": [ + "aio1-neutron-server-container-93961a30" + ] + }, + "neutron_sriov_nic_agent": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "nova_all": { + "children": [ + "nova_api_metadata", + "nova_api_os_compute", + "nova_compute", + "nova_conductor", + "nova_scheduler", + "nova_console", + "ironic_compute" + ], + "hosts": [] + }, + "nova_api_container": { + "hosts": [ + "aio1-nova-api-container-3bdc2ad4" + ] + }, + "nova_api_metadata": { + "children": [], + "hosts": [ + "aio1-nova-api-container-3bdc2ad4" + ] + }, + "nova_api_os_compute": { + "children": [], + "hosts": [ + "aio1-nova-api-container-3bdc2ad4" + ] + }, + "nova_compute": { + "children": [], + "hosts": [ + "aio1", + "aio1-ironic-compute-container-f6982d53" + ] + }, + "nova_compute_container": { + "hosts": [] + }, + "nova_conductor": { + "children": [], + "hosts": [ + "aio1-nova-api-container-3bdc2ad4" + ] + }, + "nova_console": { + "children": [], + "hosts": [ + "aio1-nova-api-container-3bdc2ad4" + ] + }, + "nova_scheduler": { + "children": [], + "hosts": [ + "aio1-nova-api-container-3bdc2ad4" + ] + }, + "octavia-api": { + "children": [], + "hosts": [ + "aio1-octavia-server-container-df2452cf" + ] + }, + "octavia-health-manager": { + "children": [], + "hosts": [ + "aio1-octavia-server-container-df2452cf" + ] + }, + "octavia-housekeeping": { + "children": [], + "hosts": [ + "aio1-octavia-server-container-df2452cf" + ] + }, + "octavia-infra_all": { + "hosts": [ + "aio1", + "aio1-octavia-server-container-df2452cf" + ] + }, + "octavia-infra_containers": { + "children": [ + "octavia_server_container" + ], + "hosts": [] + }, + "octavia-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "octavia-worker": { + "children": [], + "hosts": [ + "aio1-octavia-server-container-df2452cf" + ] + }, + "octavia_all": { + "children": [ + "octavia-api", + "octavia-worker", + "octavia-housekeeping", + "octavia-health-manager" + ], + "hosts": [] + }, + "octavia_server_container": { + "hosts": [ + "aio1-octavia-server-container-df2452cf" + ] + }, + "operator_containers": { + "children": [ + "utility_container" + ], + "hosts": [] + }, + "operator_hosts": { + "children": [], + "hosts": [] + }, + "orchestration_all": { + "hosts": [ + "aio1", + "aio1-heat-api-container-4da31a7f" + ] + }, + "orchestration_containers": { + "children": [ + "heat_api_container" + ], + "hosts": [] + }, + "orchestration_hosts": { + "hosts": [ + "aio1" + ] + }, + "os-infra_containers": { + "children": [ + "heat_api_container", + "nova_api_container", + "glance_container", + "horizon_container", + "placement_container" + ], + "hosts": [] + }, + "os-infra_hosts": { + "children": [], + "hosts": [] + }, + "pkg_repo": { + "children": [], + "hosts": [ + "aio1-repo-container-8e09a94e" + ] + }, + "placement-infra_all": { + "hosts": [ + "aio1", + "aio1-placement-container-36b96d32" + ] + }, + "placement-infra_containers": { + "children": [ + "placement_container" + ], + "hosts": [] + }, + "placement-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "placement_all": { + "children": [ + "placement_api" + ], + "hosts": [] + }, + "placement_api": { + "children": [], + "hosts": [ + "aio1-placement-container-36b96d32" + ] + }, + "placement_container": { + "hosts": [ + "aio1-placement-container-36b96d32" + ] + }, + "qemu-compute_containers": { + "children": [ + "nova_compute_container" + ], + "hosts": [] + }, + "qemu-compute_hosts": { + "children": [], + "hosts": [] + }, + "rabbit_mq_container": { + "hosts": [ + "aio1-rabbit-mq-container-19accdb7" + ] + }, + "rabbitmq": { + "children": [], + "hosts": [ + "aio1-rabbit-mq-container-19accdb7" + ] + }, + "rabbitmq_all": { + "children": [ + "rabbitmq" + ], + "hosts": [] + }, + "rating_all": { + "hosts": [ + "aio1", + "aio1-cloudkitty-container-4d02f934" + ] + }, + "rating_containers": { + "children": [ + "cloudkitty_container" + ], + "hosts": [] + }, + "rating_hosts": { + "hosts": [ + "aio1" + ] + }, + "registration_all": { + "hosts": [ + "aio1", + "aio1-adjutant-container-751a40c3" + ] + }, + "registration_containers": { + "children": [ + "adjutant_container" + ], + "hosts": [] + }, + "registration_hosts": { + "hosts": [ + "aio1" + ] + }, + "remote": { + "children": [ + "swift-remote_hosts" + ], + "hosts": [] + }, + "remote_containers": { + "children": [ + "swift-remote_containers" + ], + "hosts": [] + }, + "repo-infra_all": { + "hosts": [ + "aio1", + "aio1-repo-container-8e09a94e" + ] + }, + "repo-infra_containers": { + "children": [ + "repo_container" + ], + "hosts": [] + }, + "repo-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "repo_all": { + "children": [ + "pkg_repo" + ], + "hosts": [] + }, + "repo_container": { + "hosts": [ + "aio1-repo-container-8e09a94e" + ] + }, + "reservation_all": { + "hosts": [ + "aio1", + "aio1-blazar-container-fd7d6250" + ] + }, + "reservation_containers": { + "children": [ + "blazar_container" + ], + "hosts": [] + }, + "reservation_hosts": { + "hosts": [ + "aio1" + ] + }, + "shared-infra_all": { + "hosts": [ + "aio1", + "aio1-galera-container-4e7eea46", + "aio1-utility-container-f4c87fa8", + "aio1-rabbit-mq-container-19accdb7", + "aio1-memcached-container-aab1b554" + ] + }, + "shared-infra_containers": { + "children": [ + "galera_container", + "utility_container", + "rabbit_mq_container", + "memcached_container" + ], + "hosts": [] + }, + "shared-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "skyline": { + "children": [], + "hosts": [ + "aio1-skyline-container-653d6c73" + ] + }, + "skyline_all": { + "children": [ + "skyline" + ], + "hosts": [] + }, + "skyline_container": { + "hosts": [ + "aio1-skyline-container-653d6c73" + ] + }, + "skyline_dashboard_all": { + "hosts": [ + "aio1", + "aio1-skyline-container-653d6c73" + ] + }, + "skyline_dashboard_containers": { + "children": [ + "skyline_container" + ], + "hosts": [] + }, + "skyline_dashboard_hosts": { + "hosts": [ + "aio1" + ] + }, + "storage-infra_all": { + "hosts": [ + "aio1", + "aio1-cinder-api-container-77dc1e8a" + ] + }, + "storage-infra_containers": { + "children": [ + "cinder_api_container" + ], + "hosts": [] + }, + "storage-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "storage_all": { + "hosts": [ + "aio1" + ] + }, + "storage_containers": { + "children": [ + "cinder_volumes_container" + ], + "hosts": [] + }, + "storage_hosts": { + "hosts": [ + "aio1" + ] + }, + "swift-proxy_all": { + "hosts": [ + "aio1", + "aio1-swift-proxy-container-8ad906fc" + ] + }, + "swift-proxy_containers": { + "children": [ + "swift_proxy_container" + ], + "hosts": [] + }, + "swift-proxy_hosts": { + "hosts": [ + "aio1" + ] + }, + "swift-remote_containers": { + "children": [ + "swift_remote_container" + ], + "hosts": [] + }, + "swift-remote_hosts": { + "children": [], + "hosts": [] + }, + "swift_acc": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "swift_acc_container": { + "hosts": [] + }, + "swift_all": { + "children": [ + "swift_proxy", + "swift_acc", + "swift_obj", + "swift_cont" + ], + "hosts": [ + "aio1" + ] + }, + "swift_cont": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "swift_cont_container": { + "hosts": [] + }, + "swift_containers": { + "children": [ + "swift_acc_container", + "swift_obj_container", + "swift_cont_container" + ], + "hosts": [] + }, + "swift_hosts": { + "hosts": [ + "aio1" + ] + }, + "swift_obj": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "swift_obj_container": { + "hosts": [] + }, + "swift_proxy": { + "children": [], + "hosts": [ + "aio1-swift-proxy-container-8ad906fc" + ] + }, + "swift_proxy_container": { + "hosts": [ + "aio1-swift-proxy-container-8ad906fc" + ] + }, + "swift_remote": { + "children": [], + "hosts": [] + }, + "swift_remote_all": { + "children": [ + "swift_remote" + ], + "hosts": [] + }, + "swift_remote_container": { + "hosts": [] + }, + "tacker_all": { + "children": [ + "tacker_server" + ], + "hosts": [] + }, + "tacker_container": { + "hosts": [ + "aio1-tacker-container-bcf92543" + ] + }, + "tacker_server": { + "children": [], + "hosts": [ + "aio1-tacker-container-bcf92543" + ] + }, + "trove-infra_all": { + "hosts": [ + "aio1", + "aio1-trove-api-container-e91426a3" + ] + }, + "trove-infra_containers": { + "children": [ + "trove_api_container" + ], + "hosts": [] + }, + "trove-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "trove_all": { + "children": [ + "trove_api", + "trove_conductor", + "trove_taskmanager" + ], + "hosts": [] + }, + "trove_api": { + "children": [], + "hosts": [ + "aio1-trove-api-container-e91426a3" + ] + }, + "trove_api_container": { + "hosts": [ + "aio1-trove-api-container-e91426a3" + ] + }, + "trove_conductor": { + "children": [], + "hosts": [ + "aio1-trove-api-container-e91426a3" + ] + }, + "trove_taskmanager": { + "children": [], + "hosts": [ + "aio1-trove-api-container-e91426a3" + ] + }, + "unbound": { + "children": [], + "hosts": [ + "aio1-unbound-container-d00a4227" + ] + }, + "unbound_all": { + "children": [ + "unbound" + ], + "hosts": [ + "aio1", + "aio1-unbound-container-d00a4227" + ] + }, + "unbound_container": { + "hosts": [ + "aio1-unbound-container-d00a4227" + ] + }, + "unbound_containers": { + "children": [ + "unbound_container" + ], + "hosts": [] + }, + "unbound_hosts": { + "hosts": [ + "aio1" + ] + }, + "utility": { + "children": [], + "hosts": [ + "aio1-utility-container-f4c87fa8" + ] + }, + "utility_all": { + "children": [ + "utility" + ], + "hosts": [] + }, + "utility_container": { + "hosts": [ + "aio1-utility-container-f4c87fa8" + ] + }, + "zookeeper": { + "children": [], + "hosts": [] + }, + "zookeeper_all": { + "children": [ + "zookeeper" + ], + "hosts": [] + }, + "zookeeper_container": { + "hosts": [] + }, + "zun-compute_all": { + "hosts": [ + "aio1" + ] + }, + "zun-compute_containers": { + "children": [ + "zun_compute_container" + ], + "hosts": [] + }, + "zun-compute_hosts": { + "hosts": [ + "aio1" + ] + }, + "zun-infra_all": { + "hosts": [ + "aio1", + "aio1-zun-api-container-a405a8e0" + ] + }, + "zun-infra_containers": { + "children": [ + "zun_api_container" + ], + "hosts": [] + }, + "zun-infra_hosts": { + "hosts": [ + "aio1" + ] + }, + "zun_all": { + "children": [ + "zun_api", + "zun_compute" + ], + "hosts": [] + }, + "zun_api": { + "children": [], + "hosts": [ + "aio1-zun-api-container-a405a8e0" + ] + }, + "zun_api_container": { + "hosts": [ + "aio1-zun-api-container-a405a8e0" + ] + }, + "zun_compute": { + "children": [], + "hosts": [ + "aio1" + ] + }, + "zun_compute_container": { + "hosts": [] + } +} \ No newline at end of file diff --git a/osa_toolkit/releasing.py b/osa_toolkit/releasing.py new file mode 100644 index 0000000000..b4db04048e --- /dev/null +++ b/osa_toolkit/releasing.py @@ -0,0 +1,657 @@ +import argparse +import glob +import json +import os +import re +import shutil +import subprocess +import tempfile +import urllib.request +from datetime import datetime, timedelta + +try: + from git import Repo + from jinja2 import Template as j2_template + from packaging import requirements as pyrequirements + from packaging import version + from prettytable import PrettyTable # prettytable + from ruamel.yaml import YAML # ruamel.yaml +except ImportError as err: + raise SystemExit( + 'Required dependencies are missing for this script! ' + 'Please, make sure that OpenStack-Ansible is installed with ' + '`releases` extras.\n' + 'Check docs for more details: https://docs.openstack.org/openstack-ansible/latest/contributors/periodic-work.html#osa-cli-tooling \n\n' + f'Error: {err}' + ) + +BASE_URI_MAPPING = { + 'openstack_opendev_base_url': 'https://opendev.org', + 'openstack_github_base_url': 'https://github.com', + } + + +def _update_head_date(data): + """Parse data and update date of last bump in it + :param data: String to parse for + :returns: string with current date instead of old one + """ + return re.sub( + r'### HEAD as of [0-9.]{10} ###', + "### HEAD as of {:%d.%m.%Y} ###".format(datetime.now()), + data) + + +def parse_args(): + parser = argparse.ArgumentParser( + description="Tooling for releasing OpenStack-Ansible" + ) + subparsers = parser.add_subparsers(help='subcommand help') + + # check_pins + check_pins_parser = subparsers.add_parser( + 'check_pins', + help='Sha used for fetching the upper constraints file in requirements' + ) + check_pins_parser.add_argument( + "--requirements_sha", + help="Sha used for fetching the upper constraints file in requirements", + ) + check_pins_parser.add_argument( + "--file", + help="path to global requirements pin file", + default="global-requirement-pins.txt", + ) + check_pins_parser.set_defaults(func=analyse_global_requirement_pins) + + # bump_upstream_shas + bump_upstream_shas_parser = subparsers.add_parser( + 'bump_upstream_shas', + help='Bump SHAs of OpenStack services' + ) + + bump_upstream_shas_parser.add_argument( + "--path", + action='append', + help="glob expressions for finding files that contain SHAs", + default=["playbooks/defaults/repo_packages/*.yml", + "inventory/group_vars/*all/*_git.yml"], + ) + bump_upstream_shas_parser.set_defaults(func=bump_ushas) + + # bump_collections + bump_collections_parser = subparsers.add_parser( + 'bump_collections', + help='Bump version of Ansible collections' + ) + bump_collections_parser.add_argument( + "--file", + help="path to ansible-collection-requirements.yml file", + default="ansible-collection-requirements.yml", + ) + bump_collections_parser.set_defaults(func=bump_acr) + + # bump_roles + bump_roles_parser = subparsers.add_parser( + 'bump_roles', + help='Bump roles SHA and copies releases notes from the openstack roles.' + ) + bump_roles_parser.add_argument( + "--file", + help="path to ansible-role-requirements.yml file", + default="ansible-role-requirements.yml", + ) + bump_roles_parser.set_defaults(func=bump_arr) + + # freeze_roles_for_milestone + freeze_roles_parser = subparsers.add_parser( + 'freeze_roles_for_milestone', + help='Freeze all roles shas for milestone releases and copy release notes' + ) + freeze_roles_parser.add_argument( + "--file", + help="path to ansible-role-requirements.yml file", + default="ansible-role-requirements.yml", + ) + freeze_roles_parser.set_defaults(func=freeze_arr) + + # unfreeze_roles_from_milestone + unfreeze_roles_parser = subparsers.add_parser( + 'unfreeze_roles_from_milestone', + help=' Unfreeze all roles shas after milestone release' + ) + unfreeze_roles_parser.add_argument( + "--file", + help="path to ansible-role-requirements.yml file", + default="ansible-role-requirements.yml", + ) + freeze_roles_parser.set_defaults(func=unfreeze_arr) + + return parser.parse_args() + + +def analyse_global_requirement_pins(args): + """Check a package list file for updates on PyPI or on upper constraints""" + + with open(args.file, "r") as global_req_file: + pins = { + pin.name: pin.specifier + for pin in parse_requirements(global_req_file.read()) + } + + latest_versions = get_pypi_versions(pins.keys()) + + if not args.requirements_sha: + sha = discover_requirements_sha() + else: + sha = args.requirements_sha + + url = f"https://raw.githubusercontent.com/openstack/requirements/{sha}/upper-constraints.txt" + with urllib.request.urlopen(url) as response: + constraints_versions = { + pin.name: pin.specifier for pin in parse_requirements(response.read().decode('utf-8')) + } + + print_requirements_state(pins, latest_versions, constraints_versions) + + +def parse_requirements(requirements): + """Parse requirement file contents into name, constraints specs, and extra data + :param pin: Complete string containing a requirement + :returns: A detailed requirement, each requirement being a tuple containing: + - package 'name' (string) + - package 'specs' (list of tuples) + - package 'extras' (list) + """ + for req in requirements.split('\n'): + if re.match(r'^#\s*\w.*', req): + continue + try: + yield pyrequirements.Requirement(req) + except pyrequirements.InvalidRequirement: + continue + + +def get_pypi_versions(pins): + """ Display package metadata on PyPI + :param pins: this is a list of packages to check on PyPI + :returns: dict whose keys are package names and value is latest package version) + """ + versions = {} + for pkgname in pins: + versions[pkgname] = get_pypi_version(pkgname) + return versions + + +def get_pypi_version(name): + """ Return latest version of a package on PyPI + :param name: This is the project name on PyPI + :returns: String containing latest version of package + """ + with urllib.request.urlopen(f"https://pypi.org/pypi/{name}/json") as url: + data = json.load(url) + return data["info"]["version"] + + +def discover_requirements_sha( + path="inventory/group_vars/all/source_git.yml" +): + """ Finds in openstack-ansible repos the current SHA for the requirements repo + :param path: Location of the YAML file containing requirements_git_install_branch + :returns: String containing the SHA of the requirements repo. + """ + yaml = YAML() # use ruamel.yaml to keep comments + with open(path, "r") as os_repos_yaml: + repos = yaml.load(os_repos_yaml) + return repos["requirements_git_install_branch"] + + +def print_requirements_state(pins, latest_versions, constraints_versions): + """ Shows current status of global-requirement-pins.txt + :param pins: A dict containing requirements of the current global-requirement-pins file + :param latest_versions: A dict containing the latest version of each requirement in pypi + :param constraints_version: A dict containing the current version of all constraints from requirements repo + :returns: Nothing + """ + table = PrettyTable( + ["Package", "Current Version Spec", "Latest version on PyPI", "Constrained to"] + ) + for pkgname in pins.keys(): + table.add_row( + [ + pkgname, + pins[pkgname], + latest_versions[pkgname], + constraints_versions.get(pkgname, "None"), + ] + ) + print(table) + + +def bump_upstream_repos_shas(path): + """ Processes all the yaml files in the path by updating their upstream repos shas + :param path: String containing the location of the yaml files to update + :returns: None + """ + filelist = find_yaml_files(path) + for filename in filelist: + print("Working on %s" % filename) + bump_upstream_repos_sha_file(filename) + + +def find_yaml_files(paths): + """ Lists all the files in a provided paths + :param paths: Folder location + :returns: List of files matching the glob + """ + found_files = [ + file + for path in paths + for file in glob.glob(path) + ] + return found_files + + +def bump_upstream_repos_sha_file(filename): + yaml = YAML() # use ruamel.yaml to keep comments + yaml.preserve_quotes = True + with open(filename, "r") as ossyml: + yml_data = ossyml.read() + repofiledata = yaml.load(_update_head_date(yml_data)) + + repos = build_repos_dict(repofiledata) + changed = False + for project, projectdata in repos.items(): + # a _git_track_branch string of "None" means no tracking, which means + # do not update (as there is no branch to track) + project_url = j2_template(projectdata["url"]).render(BASE_URI_MAPPING) + if projectdata["trackbranch"] != "None": + print( + "Bumping project %s on its %s branch" + % (project_url, projectdata["trackbranch"]) + ) + sha = get_sha_from_ref(project_url, projectdata["trackbranch"]) + if repofiledata[project + "_git_install_branch"] != sha: + repofiledata[project + "_git_install_branch"] = sha + changed = True + else: + print( + "Skipping project %s branch %s" + % (project_url, projectdata["trackbranch"]) + ) + + if changed: + with open(filename, "w") as fw: + # Temporarily revert the explicit start to add --- into first line + yaml.explicit_start = True + yaml.dump(repofiledata, fw) + yaml.explicit_start = False + + +# def parse_repos_info(filename): +# """ Take a file consisting of ordered entries +# *_git_repo, followed by *_git_install_branch, with a comment the branch to track, +# returns information about each repos. +# :param filename: String containing path to file to analyse +# :returns: YAMLMap object, an ordered dict keeping the comments. +# """ +# yaml = YAML() # use ruamel.yaml to keep comments +# with open(filename,'r') as ossyml: +# y = yaml.load(ossyml) +# return y + + +def build_repos_dict(repofiledict): + """ Returns a structured dict of repos data + :param repofiledict: + :returns: Dict of repos, whose values are dicts containing shas and branches. + """ + repos = dict() + reponames = [ + key.replace("_git_repo", "") + for key in repofiledict.keys() + if key.endswith("_git_repo") + ] + for reponame in reponames: + repos[reponame] = { + "url": repofiledict[reponame + "_git_repo"], + "sha": repofiledict[reponame + "_git_install_branch"], + "trackbranch": repofiledict[reponame + "_git_track_branch"], + } + return repos + + +def get_sha_from_ref(repo_url, reference): + """ Returns the sha corresponding to the reference for a repo + :param repo_url: location of the git repository + :param reference: reference of the branch + :returns: utf-8 encoded string of the SHA found by the git command + """ + # Using subprocess instead of convoluted git libraries. + # Any rc != 0 will be throwing an exception, so we don't have to care + out = subprocess.check_output( + ["git", "ls-remote", "--exit-code", repo_url, reference] + ) + # out is a b'' type string always finishing up with a newline + # construct list of (ref,sha) + refs = [ + (line.split(b"\t")[1], line.split(b"\t")[0]) + for line in out.split(b"\n") + if line != b"" and b"^{}" not in line + ] + if len(refs) > 1: + raise ValueError( + "More than one ref for reference %s, please be more explicit %s" + % (reference, refs) + ) + return refs[0][1].decode("utf-8") + + +def freeze_ansible_role_requirements_file(filename=""): + """ Freezes a-r-r for master""" + update_ansible_role_requirements_file( + filename, milestone_freeze=True + ) + + +def unfreeze_ansible_role_requirements_file(filename=""): + """ Freezes a-r-r for master""" + update_ansible_role_requirements_file( + filename, milestone_unfreeze=True + ) + + +def update_ansible_role_requirements_file( + filename="", milestone_freeze=False, milestone_unfreeze=False +): + """ Updates the SHA of each of the ansible roles based on branch given in argument + Do not do anything on master except if milestone_freeze. + In that case, freeze by using the branch present in version. + Else, stable branches only get openstack roles bumped. + Copies all the release notes of the roles at the same time. + """ + + openstack_roles, external_roles, all_roles = sort_roles(filename) + + clone_root_path = tempfile.mkdtemp() + + for role in all_roles: + trackbranch = role.get("trackbranch") + if not trackbranch or trackbranch.lower() == "none": + print( + "Skipping role %s branch" % role["name"] + ) + continue + + copyreleasenotes = False + + shallow_since = role.get("shallow_since") + + # We don't want to copy config_template renos even if it's an openstack + # role, as it's not branched the same way. + if role in openstack_roles and (not role["src"].endswith("config_template")): + copyreleasenotes = True + + # Freeze sha by checking its trackbranch value + # Do not freeze sha if trackbranch is None + if trackbranch: + try: + role_repo = clone_role( + role["src"], clone_root_path, branch=trackbranch, depth="1" + ) + if milestone_unfreeze: + print(f"Unfreeze {trackbranch} role") + role["version"] = trackbranch + # Do nothing when trackbranch and version are same and not freezing + elif trackbranch == role.get("version") and not milestone_freeze: + print("Version and trackbranch equal, skipping...") + pass + # Freeze or Bump + else: + role_head = role_repo.head.object + role["version"] = str(role_head) + print(f"Bumped role {role['name']} to sha {role['version']}") + + if shallow_since: + head_timestamp = role_head.committed_datetime + head_datetime = head_timestamp - timedelta(days=1) + role["shallow_since"] = head_datetime.strftime('%Y-%m-%d') + + # Copy the release notes `Also handle the release notes + # If frozen, no need to copy release notes. + if copyreleasenotes: + print("Copying %s's release notes" % role["name"]) + copy_role_releasenotes(role_repo.working_dir, "./") + finally: + shutil.rmtree(role_repo.working_dir) + + shutil.rmtree(clone_root_path) + print("Overwriting ansible-role-requirements") + with open(filename, "w") as arryml: + yaml = YAML() # use ruamel.yaml to keep comments that could appear + yaml.explicit_start = True + yaml.dump(all_roles, arryml) + yaml.explicit_start = False + + +def update_ansible_collection_requirements(filename=''): + clone_root_path = tempfile.mkdtemp() + yaml = YAML() # use ruamel.yaml to keep comments + with open(filename, "r") as arryml: + yaml_data = arryml.read() + + all_requirements = yaml.load(_update_head_date(yaml_data)) + all_collections = all_requirements.get('collections') + + for collection in all_collections: + collection_type = collection.get('type') + if collection_type == 'git' and collection["version"] != 'master': + collection_repo = clone_role( + collection["source"], clone_root_path + ) + collection_tags = collection_repo.tags + collection_versions = list() + for tag in collection_tags: + try: + collection_versions.append(version.parse(tag.name)) + except version.InvalidVersion: + continue + collection['version'] = str(max(collection_versions)) + + all_requirements['collections'] = all_collections + print("Overwriting ansible-collection-requirements") + with open(filename, "w") as arryml: + yaml = YAML() # use ruamel.yaml to keep comments that could appear + yaml.explicit_start = True + yaml.dump(all_requirements, arryml) + yaml.explicit_start = False + + +def sort_roles(ansible_role_requirements_file): + """ Separate the openstack roles from the external roles + :param ansible_role_requirements_file: Path to the a-r-r file + :returns: 3-tuple: (list of openstack roles, list of external roles, list of all roles) + """ + yaml = YAML() # use ruamel.yaml to keep comments + with open(ansible_role_requirements_file, "r") as arryml: + yaml_data = arryml.read() + all_roles = yaml.load(_update_head_date(yaml_data)) + external_roles = [] + openstack_roles = [] + for role in all_roles: + if role["src"].startswith("https://git.openstack.org/") or ( + role["src"].startswith("https://opendev.org/openstack/") + ): + openstack_roles.append(role) + else: + external_roles.append(role) + return openstack_roles, external_roles, all_roles + + +def clone_role(url, clone_root_path, branch=None, clone_folder=None, depth=None): + """ Git clone + :param url: Source of the git repo + :param branch: Branch of the git repo + :param clone_root_path: The main folder in which the repo will be cloned. + :param clone_folder: The relative folder name of the git clone to the clone_root_path + :param depth(str): The git shallow clone depth + :returns: dulwich repository object + """ + gitargs = {} + + if depth and depth.isdigit(): + gitargs.update({"depth": depth, "no-single-branch": True}) + + if branch: + gitargs.update({"branch": branch}) + + if not clone_folder: + clone_folder = url.split("/")[-1] + dirpath = os.path.join(clone_root_path, clone_folder) + + print(f'Clonning {url} to {dirpath}') + repo = Repo.clone_from(url, dirpath, **gitargs) + return repo + + +def copy_role_releasenotes(src_path, dest_path): + """ Copy release notes from src to dest + """ + renos = glob.glob("{}/releasenotes/notes/*.yaml".format(src_path)) + for reno in renos: + subprocess.call( + ["rsync", "-aq", reno, "{}/releasenotes/notes/".format(dest_path)] + ) + + +def find_release_number(): + """ Find a release version amongst usual OSA files + :returns: version (str), filename containing version (string) + """ + yaml = YAML() # use ruamel.yaml to keep comments + oa_version_files = [ + "inventory/group_vars/all/all.yml", + "group_vars/all/all.yml", + "playbooks/inventory/group_vars/all.yml", + ] + for filename in oa_version_files: + try: + with open(filename, "r") as vf: + version = yaml.load(vf)["openstack_release"] + found_file = filename + break + except FileNotFoundError: + pass + else: + raise FileNotFoundError("No file found matching the list of files") + return version, found_file + + +def next_release_number(current_version, releasetype): + version = current_version.split(".") + if releasetype in ("milestone", "rc"): + return increment_milestone_version(version, releasetype) + else: + increment = {"bugfix": (0, 0, 1), "feature": (0, 1, 0)}[releasetype] + return increment_version(version, increment) + + +# THis is taken from releases repo +def increment_version(old_version, increment): + """Compute the new version based on the previous value. + :param old_version: Parts of the version string for the last + release. + :type old_version: list(str) + :param increment: Which positions to increment. + :type increment: tuple(int) + """ + new_version_parts = [] + clear = False + for cur, inc in zip(old_version, increment): + if clear: + new_version_parts.append("0") + else: + new_version_parts.append(str(int(cur) + inc)) + if inc: + clear = True + return new_version_parts + + +# THis is taken from releases repo +def increment_milestone_version(old_version, release_type): + """Increment a version using the rules for milestone projects. + :param old_version: Parts of the version string for the last + release. + :type old_version: list(str) + :param release_type: Either ``'milestone'`` or ``'rc'``. + :type release_type: str + """ + if release_type == "milestone": + if "b" in old_version[-1]: + # Not the first milestone + new_version_parts = old_version[:-1] + next_milestone = int(old_version[-1][2:]) + 1 + new_version_parts.append("0b{}".format(next_milestone)) + else: + new_version_parts = increment_version(old_version, (1, 0, 0)) + new_version_parts.append("0b1") + elif release_type == "rc": + new_version_parts = old_version[:-1] + if "b" in old_version[-1]: + # First RC + new_version_parts.append("0rc1") + else: + next_rc = int(old_version[-1][3:]) + 1 + new_version_parts.append("0rc{}".format(next_rc)) + else: + raise ValueError("Unknown release type {!r}".format(release_type)) + return new_version_parts + + +def bump_ushas(args): + """ Bump upstream projects SHAs. + :param path: String containing the path of the YAML files formatted for updates + """ + + bump_upstream_repos_shas(args.path) + + +def bump_acr(args): + """ Bump collection versions. + """ + + update_ansible_collection_requirements(filename=args.file) + + +def bump_arr(args): + """ Bump roles SHA and copies releases notes from the openstack roles. + Also bumps roles from external sources when the branch to bump is master. + """ + + update_ansible_role_requirements_file(filename=args.file) + + +def freeze_arr(args): + """ Freeze all roles shas for milestone releases. + Bump roles SHA and copies releases notes from the openstack roles. + Also freezes roles from external sources. + """ + + freeze_ansible_role_requirements_file(filename=args.file) + + +def unfreeze_arr(args): + """ Unfreeze all roles shas for milestone releases. + Also unfreezes roles from external sources. + """ + + unfreeze_ansible_role_requirements_file(filename=args.file) + + +def main(): + args = parse_args() + args.func(args) + + +if __name__ == "__main__": + main() diff --git a/setup.cfg b/setup.cfg index 4b40ab923f..5547a8c702 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,7 +26,13 @@ universal = 1 [files] packages = osa_toolkit -[entry_points] +[options.extras_require] +releases = + ruamel.yaml + Jinja2 + +[options.entry_points] console_scripts = openstack-ansible-inventory = osa_toolkit.generate:main openstack-ansible-inventory-manage = osa_toolkit.manage:main + openstack-ansible-releases = osa_toolkit.releasing:main [releases] diff --git a/test-requirements.txt b/test-requirements.txt index 3978982738..03930b3ea7 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -20,3 +20,6 @@ jmespath>=1.0.0 # MIT molecule==24.12.0 # MIT molecule-plugins[docker]==23.6.0 # MIT setuptools>75.0.0 # MIT + +# Requirements for releases script +ruamel.yaml>=0.18 # MIT diff --git a/tests/fixtures/ansible-role-requirements.yml b/tests/fixtures/ansible-role-requirements.yml new file mode 100644 index 0000000000..f48e6037f5 --- /dev/null +++ b/tests/fixtures/ansible-role-requirements.yml @@ -0,0 +1,196 @@ +- name: ansible-hardening + scm: git + src: https://git.openstack.org/openstack/ansible-hardening + version: ac92973e1393cedf336ed4e295005c08c1a083e0 +- name: apt_package_pinning + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-apt_package_pinning + version: 36b1161e8e76a76681bac089396a9e89056524d9 +- name: pip_install + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-pip_install + version: 4f82d736d3546275bad1041ea832b8d599f84fd1 +- name: galera_client + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-galera_client + version: a657d2289d9974335e18a5769b784e1860ede32b +- name: galera_server + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-galera_server + version: 94859aa149c659db66f240c0f292b92399f92171 +- name: ceph_client + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-ceph_client + version: 20c2776760627a343c7ac717b226ac410cf998cb +- name: haproxy_server + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-haproxy_server + version: 57508dde05b3908a160fd6fcd40a6a69f96e90c6 +- name: keepalived + scm: git + src: https://github.com/evrardjp/ansible-keepalived + version: 2b4a1f36c29b06b832bc4e6d112ca5559a98fd4a +- name: lxc_container_create + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-lxc_container_create + version: 3ff8b4c604be5794827941381a399ea3d0110bf2 +- name: lxc_hosts + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-lxc_hosts + version: b9fad5c1dafa27ef2585bed170119d0f8623bea4 +- name: memcached_server + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-memcached_server + version: 82e376f2e9547f35ebfaafad88abce74b9392b73 +- name: openstack_hosts + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-openstack_hosts + version: 40c1e84c87e75cdcbf5b3603a907eb04c3fa452f +- name: os_keystone + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_keystone + version: faae9f6696c03c0fbb4782eb5303885e96ec8aa7 +- name: openstack_openrc + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-openstack_openrc + version: f29df23e4a121c067769bbed17b8ca67612de8d4 +- name: os_aodh + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_aodh + version: 312e94e000132444ca01878a4f24d9d2ad0fe725 +- name: os_barbican + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_barbican + version: f3db3d834e9c1718e77cd73ff6b75a54b359d87a +- name: os_ceilometer + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_ceilometer + version: b9a235c748f6fbaca74c33baf89da2cccf04a7c4 +- name: os_cinder + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_cinder + version: 94902df33aa8d55f9b655bc35da168b096eb374f +- name: os_designate + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_designate + version: 3d4280b8b82a6492ac4bfea835119442e804a55e +- name: os_glance + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_glance + version: 971403b6d99161329d2f1ac71e416c566a9cce6e +- name: os_gnocchi + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_gnocchi + version: 5e0d08213ca0e0a2a31dfbaa75b6243e3aa9b99b +- name: os_heat + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_heat + version: d60077fba13ef8d199810d9a030acf416d9e10cb +- name: os_horizon + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_horizon + version: 0654b3847f7e74f817dfb64a9ac9a5b0ee3f3bb9 +- name: os_ironic + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_ironic + version: 1508e3731a69f7ef37aa2e7a1a2ee13290babee5 +- name: os_magnum + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_magnum + version: 8631188013df183b119767c1b1958561cee47711 +- name: os_molteniron + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_molteniron + version: f4ebd7ef37c8f9e8b46f591c9de6cf0888df1135 +- name: os_neutron + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_neutron + version: 39d00bbc0d546e6e74c3183b2d401947572f1d44 +- name: os_nova + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_nova + version: d0cc02fc82af1d6230ddcf8eb35f90671f40528a +- name: os_octavia + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_octavia + version: bffc1f6a8db60a168b9097df4ddc7ce3c5376331 +- name: os_rally + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_rally + version: 6baad96a484172794ffe7c7c637cd3562bcc061a +- name: os_sahara + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_sahara + version: ff06e20db8810215ef0e16327c8f8672a64e8aba +- name: os_swift + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_swift + version: ec76b8e2b4e90d889704073a038665bb44fdbc8d +- name: os_tacker + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_tacker + version: 7f990f3f4be4e150bb9447afbab96eeac88ed05c +- name: os_tempest + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_tempest + version: 5cfbdc3def0473ab3560a68cd4f0ffb8cca7a4e6 +- name: os_trove + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-os_trove + version: e74e708fb4cce962b2bded6e1882a0f882a19ef0 +- name: plugins + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-plugins + version: 335e9413b07760240a2d7ed9961e4754482cb60c +- name: rabbitmq_server + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-rabbitmq_server + version: ce90c91857de4a840e5db655a3a42b5de0482ede +- name: repo_build + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-repo_build + version: 64577cd93a5e5e2c37be61e07fa4f39a7a87c2ca +- name: repo_server + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-repo_server + version: 1bc95198290e8d563e9ca6137e40b5d15edcce25 +- name: rsyslog_client + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-rsyslog_client + version: 88bcc41d9d122ba9ad1b1a428b3238b1b27ecb1f +- name: rsyslog_server + scm: git + src: https://git.openstack.org/openstack/openstack-ansible-rsyslog_server + version: 45cf265fca25a5a5ae6435d8aa91aabcb160ce7b +- name: sshd + scm: git + src: https://github.com/willshersystems/ansible-sshd + version: 537b9b2bc2fd7f23301222098344727f8161993c +- name: bird + scm: git + src: https://github.com/logan2211/ansible-bird + version: 21d7d8de5af9e73c0853d3434a4b3d3f8dd39a70 +- name: etcd + scm: git + src: https://github.com/logan2211/ansible-etcd + version: '1.3' +- name: unbound + scm: git + src: https://github.com/logan2211/ansible-unbound + version: '1.6' +- name: resolvconf + scm: git + src: https://github.com/logan2211/ansible-resolvconf + version: '1.4' +- name: ceph-ansible + scm: git + src: https://github.com/ceph/ceph-ansible + version: 0be60456ce98d11ca6acf73d7f7a76c4f9dc5309 +- name: opendaylight + scm: git + src: https://github.com/opendaylight/integration-packaging-ansible-opendaylight + version: 4aabce0605ef0f51eef4d6564cc7d779630706c5 +- name: haproxy_endpoints + scm: git + src: https://github.com/logan2211/ansible-haproxy-endpoints + version: 49901861b16b8afaa9bccdbc649ac956610ff22b diff --git a/tests/fixtures/global-requirements-pins.txt b/tests/fixtures/global-requirements-pins.txt new file mode 100644 index 0000000000..feb747f123 --- /dev/null +++ b/tests/fixtures/global-requirements-pins.txt @@ -0,0 +1,16 @@ +# This file should only be used to set python package pins that are +# not present in OpenStack's upper-constraints. Any pins present in +# this file will override any requirements set in *requirements.txt, +# upper-constraints and any roles/vars. +# +# Use this file with caution! +# +### +### These are pinned to ensure exactly the same behaviour forever! ### +### These pins are updated through the sources-branch-updater script ### +### +# Bumping pip to version 10 fails in tempest when trying to install +# packages with an empty list. +pip==19.2 +setuptools==40.0.0 +wheel==0.31.1 diff --git a/tests/fixtures/repo_packages/gnocchi.yml b/tests/fixtures/repo_packages/gnocchi.yml new file mode 100644 index 0000000000..afad26332a --- /dev/null +++ b/tests/fixtures/repo_packages/gnocchi.yml @@ -0,0 +1,38 @@ +--- +# Copyright 2016, Rackspace US, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +## NOTICE on items in this file: +## * If you use anything in the *._git_install_branch field that is not a TAG +## make sure to leave an in-line comment as to "why". + +## For the sake of anyone else editing this file: +## * If you add services to this file please do so in alphabetical order. +## * Every entry should be name spaced with the name of the client followed by an "_" +## * All items with this file should be separated by `name_` note that the name of the +## package should be one long name with no additional `_` separating it. + + +### Before this is shipped all of these services should have a tag set as the branch, +### or have a comment / reason attached to them as to why a tag can not work. + + +## Gnocchi service +## This service has a different stable branch strategy to the rest of OpenStack. +## The SHA is recorded here to make the SHA updating easier. +gnocchi_git_repo: https://github.com/gnocchixyz/gnocchi +gnocchi_git_install_branch: 711e51f706dcc5bc97ad14ddc8108e501befee23 # HEAD of "stable/4.3" as of 17.08.2018 +gnocchi_git_project_group: gnocchi_all +gnocchi_git_track_branch: "stable/4.3" diff --git a/tests/fixtures/repo_packages/openstack_services.yml b/tests/fixtures/repo_packages/openstack_services.yml new file mode 100644 index 0000000000..f302526dc8 --- /dev/null +++ b/tests/fixtures/repo_packages/openstack_services.yml @@ -0,0 +1,294 @@ +--- +# Copyright 2014, Rackspace US, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +## NOTICE on items in this file: +## * If you use anything in the *._git_install_branch field that is not a TAG +## make sure to leave an in-line comment as to "why". + +## For the sake of anyone else editing this file: +## * If you add services to this file please do so in alphabetical order. +## * Every entry should be name spaced with the name of the client followed by an "_" +## * All items with this file should be separated by `name_` note that the name of the +## package should be one long name with no additional `_` separating it. + + +### Before this is shipped all of these services should have a tag set as the branch, +### or have a comment / reason attached to them as to why a tag can not work. + + +## Global Requirements +requirements_git_repo: https://git.openstack.org/openstack/requirements +requirements_git_install_branch: 4425ce22fda513fb7a20e77f28685004296731d0 # HEAD of "master" as of 08.08.2018 +requirements_git_track_branch: master + + +## Aodh service +aodh_git_repo: https://git.openstack.org/openstack/aodh +aodh_git_install_branch: d7dc751a7922fc0a5ea08ec80e3acb2db4b6979e # HEAD of "master" as of 08.08.2018 +aodh_git_project_group: aodh_all +aodh_git_track_branch: master + + +## Barbican service +barbican_git_repo: https://git.openstack.org/openstack/barbican +barbican_git_install_branch: 08ca2287dd845011d940a722f6418c3b73c6c7ae # HEAD of "master" as of 08.08.2018 +barbican_git_project_group: barbican_all +barbican_git_track_branch: master + + +## Ceilometer service +ceilometer_git_repo: https://git.openstack.org/openstack/ceilometer +ceilometer_git_install_branch: 413f9a3261c2b247395c36eef938b53ff8279214 # HEAD of "master" as of 08.08.2018 +ceilometer_git_project_group: ceilometer_all +ceilometer_git_track_branch: master + + +## Cinder service +cinder_git_repo: https://git.openstack.org/openstack/cinder +cinder_git_install_branch: a27d0eb32afc32d745de6a3aafb905ea6151813c # HEAD of "master" as of 08.08.2018 +cinder_git_project_group: cinder_all +cinder_git_track_branch: master + + +## Designate service +designate_git_repo: https://git.openstack.org/openstack/designate +designate_git_install_branch: 6daedf125c6126bd1c32a377fded9d7b46a2b4e9 # HEAD of "master" as of 08.08.2018 +designate_git_project_group: designate_all +designate_git_track_branch: master + + +## Horizon Designate dashboard plugin +designate_dashboard_git_repo: https://git.openstack.org/openstack/designate-dashboard +designate_dashboard_git_install_branch: e41d74a03d46d678c3e86bf98703bcc16dff71f6 # HEAD of "master" as of 08.08.2018 +designate_dashboard_git_project_group: horizon_all +designate_dashboard_git_track_branch: master + + +## Dragonflow service +dragonflow_git_repo: https://git.openstack.org/openstack/dragonflow +dragonflow_git_install_branch: 0f05fc13d7bd26097d16c634c5ddeb63f9bfaecd # HEAD of "master" as of 08.08.2018 +dragonflow_git_project_group: neutron_all +dragonflow_git_track_branch: master + + +## Glance service +glance_git_repo: https://git.openstack.org/openstack/glance +glance_git_install_branch: bfa25c5e5c05399506404e66d53b0d61eaa06ab7 # HEAD of "master" as of 08.08.2018 +glance_git_project_group: glance_all +glance_git_track_branch: master + + +## Heat service +heat_git_repo: https://git.openstack.org/openstack/heat +heat_git_install_branch: 8ca06cfeafc94e739947cf89affa4db57b6bf3c9 # HEAD of "master" as of 08.08.2018 +heat_git_project_group: heat_all +heat_git_track_branch: master + +## Horizon Heat dashboard plugin +heat_dashboard_git_repo: https://git.openstack.org/openstack/heat-dashboard +heat_dashboard_git_install_branch: df563384901294ac118c45a1e92734f67b6593d8 # HEAD of "master" as of 08.08.2018 +heat_dashboard_git_project_group: horizon_all +heat_dashboard_git_track_branch: master + +## Horizon service +horizon_git_repo: https://git.openstack.org/openstack/horizon +horizon_git_install_branch: a4443f4be7a7e38ce052080ed157337bc778c18d # HEAD of "master" as of 08.08.2018 +horizon_git_project_group: horizon_all +horizon_git_track_branch: master + +## Horizon Ironic dashboard plugin +ironic_dashboard_git_repo: https://git.openstack.org/openstack/ironic-ui +ironic_dashboard_git_install_branch: 36840aaa0da8053d2e4032c060a6a45af224572b # HEAD of "master" as of 08.08.2018 +ironic_dashboard_git_project_group: horizon_all +ironic_dashboard_git_track_branch: master + +## Horizon Magnum dashboard plugin +magnum_dashboard_git_repo: https://git.openstack.org/openstack/magnum-ui +magnum_dashboard_git_install_branch: dcf62a6e80fd3733b530cb76218b2ec5c3532cb6 # HEAD of "master" as of 08.08.2018 +magnum_dashboard_git_project_group: horizon_all +magnum_dashboard_git_track_branch: master + +## Horizon LBaaS dashboard plugin +neutron_lbaas_dashboard_git_repo: https://git.openstack.org/openstack/neutron-lbaas-dashboard +neutron_lbaas_dashboard_git_install_branch: dde6dfb2eba8eb2f1d9cd61986032b512330b281 # HEAD of "master" as of 08.08.2018 +neutron_lbaas_dashboard_git_project_group: horizon_all +neutron_lbaas_dashboard_git_track_branch: master + +## Horizon FWaaS dashboard plugin +neutron_fwaas_dashboard_git_repo: https://git.openstack.org//openstack/neutron-fwaas-dashboard +neutron_fwaas_dashboard_git_install_branch: 5ece747e15896cf998e3787aa07f547fa39e3e44 # HEAD of "master" as of 08.08.2018 +neutron_fwaas_dashboard_git_project_group: horizon_all +neutron_fwaas_dashboard_git_track_branch: master + +## Horizon Sahara dashboard plugin +sahara_dashboard_git_repo: https://git.openstack.org/openstack/sahara-dashboard +sahara_dashboard_git_install_branch: 4585a9d004427f52e34f0cd89374e8ba1cba2dff # HEAD of "master" as of 08.08.2018 +sahara_dashboard_git_project_group: horizon_all +sahara_dashboard_git_track_branch: master + + +## Keystone service +keystone_git_repo: https://git.openstack.org/openstack/keystone +keystone_git_install_branch: a2b510c17638d31d2983317a4261f9dc27507d24 # HEAD of "master" as of 08.08.2018 +keystone_git_project_group: keystone_all +keystone_git_track_branch: master + + +## Neutron service +neutron_git_repo: https://git.openstack.org/openstack/neutron +neutron_git_install_branch: 06f1aa6629d3e54c04ab06ca2808479f5ed9f186 # HEAD of "master" as of 08.08.2018 +neutron_git_project_group: neutron_all +neutron_git_track_branch: master + +neutron_lbaas_git_repo: https://git.openstack.org/openstack/neutron-lbaas +neutron_lbaas_git_install_branch: e4a9d3c1dfb06482f90699e60b98a94481af5f75 # HEAD of "master" as of 08.08.2018 +neutron_lbaas_git_project_group: neutron_all +neutron_lbaas_git_track_branch: master + +neutron_vpnaas_git_repo: https://git.openstack.org/openstack/neutron-vpnaas +neutron_vpnaas_git_install_branch: da4fff7e7aa756cd8280e8dd14fb8cccc5777277 # HEAD of "master" as of 08.08.2018 +neutron_vpnaas_git_project_group: neutron_all +neutron_vpnaas_git_track_branch: master + +neutron_fwaas_git_repo: https://git.openstack.org/openstack/neutron-fwaas +neutron_fwaas_git_install_branch: d61bd2961c5117f22d227a910b7a20e65322bb82 # HEAD of "master" as of 08.08.2018 +neutron_fwaas_git_project_group: neutron_all +neutron_fwaas_git_track_branch: master + +neutron_dynamic_routing_git_repo: https://git.openstack.org/openstack/neutron-dynamic-routing +neutron_dynamic_routing_git_install_branch: ac63f126c6bd0ab12d6cd80077023c3e5c264e98 # HEAD of "master" as of 08.08.2018 +neutron_dynamic_routing_git_project_group: neutron_all +neutron_dynamic_routing_git_track_branch: master + +networking_calico_git_repo: https://git.openstack.org/openstack/networking-calico +networking_calico_git_install_branch: 5d852f653552f2332dce48aa425ee842b5b684ad # HEAD of "master" as of 08.08.2018 +networking_calico_git_project_group: neutron_all +networking_calico_git_track_branch: master + +# ODL is frozen until further notice due to +# https://github.com/openstack/networking-odl/commit/391c1d89ef2b8133d3aafbe7612c7908be106e73#diff-b4ef698db8ca845e5845c4618278f29a +networking_odl_git_repo: https://git.openstack.org/openstack/networking-odl +networking_odl_git_install_branch: 53ff740b2a78626d5b077278997bdcec6b1b0892 # FROZEN HEAD of "master" as of 31.03.2018 +networking_odl_git_project_group: neutron_all +networking_odl_git_track_branch: None + +# BGPVPN is frozen until further notice due to +# https://github.com/openstack/networking-bgpvpn/commit/e9a0ea199b47f76f69545e04bdb4db44869c388b#diff-b4ef698db8ca845e5845c4618278f29a +networking_bgpvpn_git_repo: https://git.openstack.org/openstack/networking-bgpvpn +networking_bgpvpn_git_install_branch: 3b93ddacd390d92fb144e5660324d4da064ad9a4 # FROZEN HEAD of "master" as of 31.03.2018 +networking_bgpvpn_git_project_group: neutron_all +networking_bgpvpn_git_track_branch: None + +networking_sfc_git_repo: https://git.openstack.org/openstack/networking-sfc +networking_sfc_git_install_branch: 4c38303620c8a3f38d7261a64ce8532979bf7560 # HEAD of "master" as of 08.08.2018 +networking_sfc_git_project_group: neutron_all +networking_sfc_git_track_branch: master + + +## Nova service +nova_git_repo: https://git.openstack.org/openstack/nova +nova_git_install_branch: c52c2caf97a90de8770e9296d553e0e4a65ac946 # HEAD of "master" as of 08.08.2018 +nova_git_project_group: nova_all +nova_git_track_branch: master + + +## PowerVM Virt Driver +nova_powervm_git_repo: https://git.openstack.org/openstack/nova-powervm +nova_powervm_git_install_branch: 9b518d8c9986249a06e3f5dc1450b66283af91f1 # HEAD of "master" as of 08.08.2018 +nova_powervm_git_project_group: nova_all +nova_powervm_git_track_branch: master + + +## LXD Virt Driver +nova_lxd_git_repo: https://git.openstack.org/openstack/nova-lxd +nova_lxd_git_install_branch: bc8d540c95b3209321658000fd74b0e5065a7ee2 # HEAD of "master" as of 08.08.2018 +nova_lxd_git_project_group: nova_all +nova_lxd_git_track_branch: master + + +## Sahara service +sahara_git_repo: https://git.openstack.org/openstack/sahara +sahara_git_install_branch: 2c6232c9ad37079020ac72a29a54ab794cc80500 # HEAD of "master" as of 08.08.2018 +sahara_git_project_group: sahara_all +sahara_git_track_branch: master + + +## Swift service +swift_git_repo: https://git.openstack.org/openstack/swift +swift_git_install_branch: 7f7482c096d6c587c64a75e207842ab4dee6e8dd # HEAD of "master" as of 08.08.2018 +swift_git_project_group: swift_all +swift_git_track_branch: master + + +## Swift3 middleware +swift_swift3_git_repo: https://git.openstack.org/openstack/swift3 +swift_swift3_git_install_branch: 90db5d1510b2a770387961e7bf0fbeae8101ba45 # HEAD of "master" as of 08.08.2018 +swift_swift3_git_project_group: swift_all +swift_swift3_git_track_branch: master + + +## Ironic service +ironic_git_repo: https://git.openstack.org/openstack/ironic +ironic_git_install_branch: 89f68e70e06e24b100d93e751e2a3e8cb8dd9b61 # HEAD of "master" as of 08.08.2018 +ironic_git_project_group: ironic_all +ironic_git_track_branch: master + + +## Magnum service +magnum_git_repo: https://git.openstack.org/openstack/magnum +magnum_git_install_branch: 97b34e67508a69d800239087d0131c6ea128e790 # HEAD of "master" as of 08.08.2018 +magnum_git_project_group: magnum_all +magnum_git_track_branch: master + + +## Trove service +trove_git_repo: https://git.openstack.org/openstack/trove +trove_git_install_branch: 5f2462f0ea4ec2d084db102dbad35bf97eca1135 # HEAD of "master" as of 08.08.2018 +trove_git_project_group: trove_all +trove_git_track_branch: master + +## Horizon Trove dashboard plugin +trove_dashboard_git_repo: https://git.openstack.org/openstack/trove-dashboard +trove_dashboard_git_install_branch: 9b7f3d9561ce47f370642a3d169fce6469203148 # HEAD of "master" as of 08.08.2018 +trove_dashboard_git_project_group: horizon_all +trove_dashboard_git_track_branch: master + + +## Octavia service +octavia_git_repo: https://git.openstack.org/openstack/octavia +octavia_git_install_branch: a166c89b643c1bdaf3f36004fede25eb7a1c26f5 # HEAD of "master" as of 08.08.2018 +octavia_git_project_group: octavia_all +octavia_git_track_branch: master + + +## Tacker service +tacker_git_repo: https://git.openstack.org/openstack/tacker +tacker_git_install_branch: 5987ad8c56a61e3a6d8fcf37a2557926c585de41 # HEAD of "master" as of 08.08.2018 +tacker_git_project_group: tacker_all +tacker_git_track_branch: master + +## Congress service +congress_git_repo: https://git.openstack.org/openstack/congress +congress_git_install_branch: 502f40a7d24dd2603bc9e026edc685a956a52e15 # HEAD of "master" as of 08.08.2018 +congress_git_project_group: congress_all +congress_git_track_branch: master + +## Horizon Octavia dashboard plugin +octavia_dashboard_git_repo: https://git.openstack.org/openstack/octavia-dashboard +octavia_dashboard_git_install_branch: 4f7a5591ae8dd61b25af7f746f20d8f058aa991c # HEAD of "master" as of 08.08.2018 +octavia_dashboard_git_project_group: horizon_all +octavia_dashboard_git_track_branch: master + diff --git a/tests/test_releases.py b/tests/test_releases.py new file mode 100644 index 0000000000..9b586ab8ec --- /dev/null +++ b/tests/test_releases.py @@ -0,0 +1,116 @@ +import io +import unittest +from unittest.mock import patch +from osa_toolkit import releasing +from prettytable import PrettyTable +from ruamel.yaml import YAML +from packaging import requirements + +class TestReleasing(unittest.TestCase): + """ + Test suite for the 'releasing' module + """ + + def test_parse_requirements(self): + """ + Tests the `parse_requirements` function. + """ + req = list(releasing.parse_requirements("pip==18.0"))[0] + self.assertEqual(req.name, "pip") + self.assertEqual(req.specifier, requirements.SpecifierSet("==18.0")) + self.assertEqual(req.extras, set()) + + def test_discover_requirements_sha(self): + """ + Tests the `discover_requirements_sha` function. + """ + expected_sha = "4425ce22fda513fb7a20e77f28685004296731d0" + actual_sha = releasing.discover_requirements_sha( + path="tests/fixtures/repo_packages/openstack_services.yml" + ) + self.assertEqual(actual_sha, expected_sha) + + def test_print_requirements_state_not_in_uc(self): + """ + Tests `print_requirements_state` when a package is not in the + upper constraints. This test uses a context manager to capture + stdout, which is the equivalent of the `capsys` pytest fixture. + """ + pins = {"pip": "==18.0"} + latest_versions = {"pip": "18.0"} + constraints_versions = {} + + # Capture the output of the function + with patch('sys.stdout', new=io.StringIO()) as fake_stdout: + releasing.print_requirements_state(pins, latest_versions, constraints_versions) + captured_output = fake_stdout.getvalue() + + # Generate the expected output string for comparison + reftable = PrettyTable( + ["Package", "Current Version Spec", "Latest version on PyPI", "Constrained to"] + ) + reftable.add_row(["pip", "==18.0", "18.0", "None"]) + expected_output = str(reftable) + "\n" # PrettyTable adds a newline + + self.assertEqual(captured_output, expected_output) + + def test_print_requirements_state_in_uc(self): + """ + Tests `print_requirements_state` when a package is in the + upper constraints. + """ + pins = {"pip": "==18.0"} + latest_versions = {"pip": "18.0"} + constraints_versions = {"pip": "==30.3.0"} + + with patch('sys.stdout', new=io.StringIO()) as fake_stdout: + releasing.print_requirements_state(pins, latest_versions, constraints_versions) + captured_output = fake_stdout.getvalue() + + reftable = PrettyTable( + ["Package", "Current Version Spec", "Latest version on PyPI", "Constrained to"] + ) + reftable.add_row(["pip", "==18.0", "18.0", "==30.3.0"]) + expected_output = str(reftable) + "\n" + + self.assertEqual(captured_output, expected_output) + + def test_find_yaml_files(self): + """ + Tests the `find_yaml_files` function. + """ + self.assertEqual(len(releasing.find_yaml_files(["tests/fixtures/repo_packages/*.yaml"])), 0) + self.assertEqual(len(releasing.find_yaml_files(["tests/fixtures/notexistingfolder/"])), 0) + self.assertEqual( + len(releasing.find_yaml_files([ + "tests/fixtures/notexistingfolder/", + "tests/fixtures/repo_packages/*" + ])), 2 + ) + self.assertEqual(len(releasing.find_yaml_files(["tests/fixtures/repo_packages/*"])), 2) + + def test_build_repos_dict(self): + """ + Tests the `build_repos_dict` function. + """ + yaml = YAML() + with open("tests/fixtures/repo_packages/gnocchi.yml", "r") as fd: + repofiledata = yaml.load(fd) + repos = releasing.build_repos_dict(repofiledata) + + self.assertEqual(repos["gnocchi"]["url"], "https://github.com/gnocchixyz/gnocchi") + self.assertEqual(repos["gnocchi"]["sha"], "711e51f706dcc5bc97ad14ddc8108e501befee23") + self.assertEqual(repos["gnocchi"]["trackbranch"], "stable/4.3") + + def test_get_sha_from_ref(self): + """ + Tests the `get_sha_from_ref` function. + """ + sha = releasing.get_sha_from_ref( + "https://github.com/openstack/openstack-ansible.git", "newton-eol" + ) + self.assertEqual(sha, "bf565c6ae34bb4343b4d6b486bd9b514de370b0a") + + +if __name__ == '__main__': + unittest.main() diff --git a/tox.ini b/tox.ini index 13a4e5131f..c67226df2a 100644 --- a/tox.ini +++ b/tox.ini @@ -130,6 +130,7 @@ commands = coverage run -a {toxinidir}/tests/test_dictutils.py coverage run -a {toxinidir}/tests/test_ip.py coverage run -a {toxinidir}/tests/test_filesystem.py + coverage run -a {toxinidir}/tests/test_releases.py coverage report --show-missing --include={toxinidir}/inventory/*,{toxinidir}/osa_toolkit/* [testenv:py3-inventory]