diff --git a/ansible/inventory/group_vars/all/ansible-control b/ansible/inventory/group_vars/all/ansible-control index 635024df0..073021253 100644 --- a/ansible/inventory/group_vars/all/ansible-control +++ b/ansible/inventory/group_vars/all/ansible-control @@ -105,6 +105,24 @@ ansible_control_tuned_active_builtin_profile: "throughput-performance" # singleplatform-eng.users role. ansible_control_users: "{{ users_default }}" +############################################################################### +# Ansible control host additional containers configuration + +# Dict of containers to deploy. +# Example: +# ansible_control_containers: +# squid: +# image: "docker.io/stackhpc/squid" +# pre: "{{ kayobe_env_config_path }}/containers/squid/pre.yml" +# post: "{{ kayobe_env_config_path }}/containers/squid/post.yml" +# tag: "3.5.20-1" +# +ansible_control_containers: {} + +# Whether to attempt a basic authentication login to a registry when +# deploying containers. +ansible_control_manage_containers_registry_attempt_login: "{{ kolla_docker_registry_username is truthy and kolla_docker_registry_password is truthy }}" + ############################################################################### # Ansible control host firewalld configuration. diff --git a/ansible/inventory/group_vars/all/controllers b/ansible/inventory/group_vars/all/controllers index f8be1616a..207cbd0d0 100644 --- a/ansible/inventory/group_vars/all/controllers +++ b/ansible/inventory/group_vars/all/controllers @@ -203,6 +203,24 @@ controller_tuned_active_builtin_profile: "throughput-performance" # singleplatform-eng.users role. controller_users: "{{ users_default }}" +############################################################################### +# Controller node additional containers configuration + +# Dict of containers to deploy. +# Example: +# controller_containers: +# squid: +# image: "docker.io/stackhpc/squid" +# pre: "{{ kayobe_env_config_path }}/containers/squid/pre.yml" +# post: "{{ kayobe_env_config_path }}/containers/squid/post.yml" +# tag: "3.5.20-1" +# +controller_containers: {} + +# Whether to attempt a basic authentication login to a registry when +# deploying controller containers +controller_manage_containers_registry_attempt_login: "{{ kolla_docker_registry_username is truthy and kolla_docker_registry_password is truthy }}" + ############################################################################### # Controller node firewalld configuration. diff --git a/ansible/inventory/group_vars/all/globals b/ansible/inventory/group_vars/all/globals index 54c562c87..715fe2758 100644 --- a/ansible/inventory/group_vars/all/globals +++ b/ansible/inventory/group_vars/all/globals @@ -55,6 +55,17 @@ kayobe_ansible_user: "stack" # is "rocky". os_distribution: "rocky" +# Mapping from OS distribution name to OS family. Supported keys are +# "centos", "rocky", and "ubuntu". +os_family_map: + centos: RedHat + rocky: RedHat + ubuntu: Debian + +# OS family. Valid options are "RedHat" and "Debian". Default depends on +# os_distribution. +os_family: "{{ os_family_map[os_distribution | lower] }}" + # OS release. Valid options are "10-stream" when os_distribution is "centos", # "10" when os_distribution is "rocky", or "noble" when os_distribution is # "ubuntu". @@ -66,6 +77,10 @@ os_release: >- ############################################################################### # Ansible configuration. +# String used as the header comment in files managed by Kayobe. Default is +# "Ansible managed". +kayobe_managed: "Ansible managed" + # Filter to apply to the setup module when gathering facts. Default is to not # specify a filter. kayobe_ansible_setup_filter: "{{ omit }}" diff --git a/ansible/inventory/group_vars/all/infra-vms b/ansible/inventory/group_vars/all/infra-vms index df0b8bcaa..f5643aab1 100644 --- a/ansible/inventory/group_vars/all/infra-vms +++ b/ansible/inventory/group_vars/all/infra-vms @@ -209,6 +209,24 @@ infra_vm_tuned_active_builtin_profile: "virtual-guest" # singleplatform-eng.users role. infra_vm_users: "{{ users_default }}" +############################################################################### +# Infrastructure VM node additional containers configuration + +# Dict of containers to deploy. +# Example: +# infra_vm_containers: +# squid: +# image: "docker.io/stackhpc/squid" +# pre: "{{ kayobe_env_config_path }}/containers/squid/pre.yml" +# post: "{{ kayobe_env_config_path }}/containers/squid/post.yml" +# tag: "3.5.20-1" +# +infra_vm_containers: {} + +# Whether to attempt a basic authentication login to a registry when +# deploying Infrastructure VM node containers +infra_vm_manage_containers_registry_attempt_login: "{{ kolla_docker_registry_username is truthy and kolla_docker_registry_password is truthy }}" + ############################################################################### # Infrastructure VM node firewalld configuration. diff --git a/ansible/inventory/group_vars/all/monitoring b/ansible/inventory/group_vars/all/monitoring index 61492f2b2..396548704 100644 --- a/ansible/inventory/group_vars/all/monitoring +++ b/ansible/inventory/group_vars/all/monitoring @@ -103,6 +103,24 @@ monitoring_tuned_active_builtin_profile: "throughput-performance" # singleplatform-eng.users role. monitoring_users: "{{ controller_users }}" +############################################################################### +# Monitoring node additional containers configuration + +# Dict of containers to deploy. +# Example: +# monitoring_containers: +# squid: +# image: "docker.io/stackhpc/squid" +# pre: "{{ kayobe_env_config_path }}/containers/squid/pre.yml" +# post: "{{ kayobe_env_config_path }}/containers/squid/post.yml" +# tag: "3.5.20-1" +# +monitoring_containers: {} + +# Whether to attempt a basic authentication login to a registry when +# deploying monitoring node containers +monitoring_manage_containers_registry_attempt_login: "{{ kolla_docker_registry_username is truthy and kolla_docker_registry_password is truthy }}" + ############################################################################### # Monitoring node firewalld configuration. diff --git a/ansible/inventory/group_vars/all/openstack b/ansible/inventory/group_vars/all/openstack index 430293d3f..a7a6e4312 100644 --- a/ansible/inventory/group_vars/all/openstack +++ b/ansible/inventory/group_vars/all/openstack @@ -2,10 +2,10 @@ ############################################################################### # OpenStack release configuration. -# Name of the current OpenStack release. Default is "master". -openstack_release: "master" +# Name of the current OpenStack release. Default is "2026.1". +openstack_release: "2026.1" -# Name of the current OpenStack branch. Default is "master". +# Name of the current OpenStack branch. Default is "stable/2026.1". openstack_branch: >- {% if openstack_release != 'master' %}stable/{% endif %}{{ openstack_release | lower }} diff --git a/ansible/inventory/group_vars/all/seed b/ansible/inventory/group_vars/all/seed index 22c0bc6d4..d5fac0d2a 100644 --- a/ansible/inventory/group_vars/all/seed +++ b/ansible/inventory/group_vars/all/seed @@ -133,7 +133,7 @@ seed_users: "{{ users_default }}" ############################################################################### # Seed node additional containers configuration -# Dict of container images to start +# Dict of containers to deploy. # Example: # seed_containers: # squid: @@ -144,10 +144,16 @@ seed_users: "{{ users_default }}" # seed_containers: {} -# Whether to attempt a basic authentication login to a registry when -# deploying seed containers +# (Deprecated) Whether to attempt a basic authentication login to a registry when +# deploying seed containers. +# TODO(mattcrees): remove seed_deploy_containers_registry_attempt_login in the +# Hibiscus cycle. seed_deploy_containers_registry_attempt_login: "{{ kolla_docker_registry_username is truthy and kolla_docker_registry_password is truthy }}" +# Whether to attempt a basic authentication login to a registry when +# deploying seed containers. +seed_manage_containers_registry_attempt_login: "{{ seed_deploy_containers_registry_attempt_login }}" + ############################################################################### # Seed node firewalld configuration. diff --git a/ansible/inventory/group_vars/all/storage b/ansible/inventory/group_vars/all/storage index 46ea4bc79..a15eafb0b 100644 --- a/ansible/inventory/group_vars/all/storage +++ b/ansible/inventory/group_vars/all/storage @@ -152,6 +152,24 @@ storage_tuned_active_builtin_profile: "throughput-performance" # singleplatform-eng.users role. storage_users: "{{ users_default }}" +############################################################################### +# Storage node additional containers configuration + +# Dict of containers to deploy. +# Example: +# storage_containers: +# squid: +# image: "docker.io/stackhpc/squid" +# pre: "{{ kayobe_env_config_path }}/containers/squid/pre.yml" +# post: "{{ kayobe_env_config_path }}/containers/squid/post.yml" +# tag: "3.5.20-1" +# +storage_containers: {} + +# Whether to attempt a basic authentication login to a registry when +# deploying storage containers +storage_manage_containers_registry_attempt_login: "{{ kolla_docker_registry_username is truthy and kolla_docker_registry_password is truthy }}" + ############################################################################### # Storage node firewalld configuration. diff --git a/ansible/inventory/group_vars/ansible-control/manage-containers b/ansible/inventory/group_vars/ansible-control/manage-containers new file mode 100644 index 000000000..71b0b66d2 --- /dev/null +++ b/ansible/inventory/group_vars/ansible-control/manage-containers @@ -0,0 +1,10 @@ +--- +############################################################################### +# Ansible control host custom containers configuration. + +# Dict of containers to deploy. +manage_custom_containers: "{{ ansible_control_containers }}" + +# Whether to attempt a basic authentication login to a registry when +# deploying Ansible control host containers +manage_containers_registry_attempt_login: "{{ ansible_control_manage_containers_registry_attempt_login }}" diff --git a/ansible/inventory/group_vars/controllers/manage-containers b/ansible/inventory/group_vars/controllers/manage-containers new file mode 100644 index 000000000..370a973a0 --- /dev/null +++ b/ansible/inventory/group_vars/controllers/manage-containers @@ -0,0 +1,10 @@ +--- +############################################################################### +# Controller node custom containers configuration. + +# Dict of containers to deploy. +manage_custom_containers: "{{ controller_containers }}" + +# Whether to attempt a basic authentication login to a registry when +# deploying controller node containers +manage_containers_registry_attempt_login: "{{ controller_manage_containers_registry_attempt_login }}" diff --git a/ansible/inventory/group_vars/infra-vms/manage-containers b/ansible/inventory/group_vars/infra-vms/manage-containers new file mode 100644 index 000000000..d034074f3 --- /dev/null +++ b/ansible/inventory/group_vars/infra-vms/manage-containers @@ -0,0 +1,10 @@ +--- +############################################################################### +# Infrastructure VM node custom containers configuration. + +# Dict of containers to deploy. +manage_custom_containers: "{{ infra_vm_containers }}" + +# Whether to attempt a basic authentication login to a registry when +# deploying infrastructure VM containers +manage_containers_registry_attempt_login: "{{ infra_vm_manage_containers_registry_attempt_login }}" diff --git a/ansible/inventory/group_vars/monitoring/manage-containers b/ansible/inventory/group_vars/monitoring/manage-containers new file mode 100644 index 000000000..d7b840983 --- /dev/null +++ b/ansible/inventory/group_vars/monitoring/manage-containers @@ -0,0 +1,10 @@ +--- +############################################################################### +# Monitoring node custom containers configuration. + +# Dict of containers to deploy. +manage_custom_containers: "{{ monitoring_containers }}" + +# Whether to attempt a basic authentication login to a registry when +# deploying monitoring node containers +manage_containers_registry_attempt_login: "{{ monitoring_manage_containers_registry_attempt_login }}" diff --git a/ansible/inventory/group_vars/seed/docker-registry b/ansible/inventory/group_vars/seed/manage-containers similarity index 52% rename from ansible/inventory/group_vars/seed/docker-registry rename to ansible/inventory/group_vars/seed/manage-containers index f439501ec..9fe2b3449 100644 --- a/ansible/inventory/group_vars/seed/docker-registry +++ b/ansible/inventory/group_vars/seed/manage-containers @@ -1,7 +1,10 @@ --- ############################################################################### -# Seed node docker regsitry configuration. +# Seed node custom containers configuration. + +# Dict of containers to deploy. +manage_custom_containers: "{{ seed_containers }}" # Whether to attempt a basic authentication login to a registry when # deploying seed containers -deploy_containers_registry_attempt_login: "{{ seed_deploy_containers_registry_attempt_login }}" +manage_containers_registry_attempt_login: "{{ seed_manage_containers_registry_attempt_login }}" diff --git a/ansible/inventory/group_vars/storage/manage-containers b/ansible/inventory/group_vars/storage/manage-containers new file mode 100644 index 000000000..ee563f756 --- /dev/null +++ b/ansible/inventory/group_vars/storage/manage-containers @@ -0,0 +1,10 @@ +--- +############################################################################### +# Storage node custom containers configuration. + +# Dict of containers to deploy. +manage_custom_containers: "{{ storage_containers }}" + +# Whether to attempt a basic authentication login to a registry when +# deploying storage node containers +manage_containers_registry_attempt_login: "{{ storage_manage_containers_registry_attempt_login }}" diff --git a/ansible/kayobe-target-venv.yml b/ansible/kayobe-target-venv.yml index 4d4ae092f..53005c86e 100644 --- a/ansible/kayobe-target-venv.yml +++ b/ansible/kayobe-target-venv.yml @@ -26,9 +26,7 @@ filter: "{{ kayobe_ansible_setup_filter }}" gather_subset: "{{ kayobe_ansible_setup_gather_subset }}" when: - #TODO(mattcrees): Enable this check once this bug is fixed: - # https://bugs.launchpad.net/kayobe/+bug/2144548 - # - ansible_facts is undefined or ansible_facts is falsy + - ansible_facts is undefined or ansible_facts is falsy - kayobe_virtualenv is defined register: gather_facts_result # Before any facts are gathered, ansible doesn't know about diff --git a/ansible/kolla-ansible.yml b/ansible/kolla-ansible.yml index 913331c4a..a02f96135 100644 --- a/ansible/kolla-ansible.yml +++ b/ansible/kolla-ansible.yml @@ -147,6 +147,11 @@ description: "Bifrost provisioning network" network: "{{ provision_oc_net_name }}" required: "{{ kolla_enable_bifrost | bool }}" + register: kolla_host_vars_result + + - name: Set Kolla Ansible host variable facts + set_fact: + args: "{{ kolla_host_vars_result.kolla_ansible_host_vars }}" - import_role: name: kolla-ansible-host-vars @@ -233,6 +238,11 @@ network: "{{ public_net_name }}" required: "{{ inventory_hostname in groups[controller_loadbalancer_group] }}" external_networks: "{{ ironic_networks + provider_networks }}" + register: kolla_host_vars_result + + - name: Set Kolla Ansible host variable facts + set_fact: + args: "{{ kolla_host_vars_result.kolla_ansible_host_vars }}" - import_role: name: kolla-ansible-host-vars diff --git a/ansible/manage-containers.yml b/ansible/manage-containers.yml new file mode 100644 index 000000000..054034039 --- /dev/null +++ b/ansible/manage-containers.yml @@ -0,0 +1,17 @@ +--- +- name: "Ensure defined container images are {{ kayobe_action | default('deploy') }}ed" + hosts: "{{ manage_containers_target_hosts | default('seed') }}" + tags: + # Kept for backward compatibility. + # TODO(mattcrees): Will be removed in the Hibiscus release. + - seed-deploy-containers + - seed-manage-containers + - manage-containers + tasks: + - import_role: + name: manage-containers + vars: + manage_containers_registry: "{{ kolla_docker_registry }}" + manage_containers_registry_username: "{{ kolla_docker_registry_username }}" + manage_containers_registry_password: "{{ kolla_docker_registry_password }}" + manage_containers_action: "{{ kayobe_action | default('deploy') }}" diff --git a/ansible/overcloud-extras.yml b/ansible/overcloud-extras.yml index 0a5d4fa4e..20af3f179 100644 --- a/ansible/overcloud-extras.yml +++ b/ansible/overcloud-extras.yml @@ -8,4 +8,5 @@ # action: One of deploy, destroy, pull, reconfigure, upgrade - import_playbook: docker-registry.yml +- import_playbook: manage-containers.yml - import_playbook: opensm.yml diff --git a/ansible/roles/apt/templates/auth.conf.j2 b/ansible/roles/apt/templates/auth.conf.j2 index a5abd10ae..128eb8070 100644 --- a/ansible/roles/apt/templates/auth.conf.j2 +++ b/ansible/roles/apt/templates/auth.conf.j2 @@ -1,4 +1,4 @@ -# {{ ansible_managed }} +# {{ kayobe_managed }} machine {{ auth.machine }} login {{ auth.login }} diff --git a/ansible/roles/apt/templates/kayobe.sources.j2 b/ansible/roles/apt/templates/kayobe.sources.j2 index bc99a19fe..83d83758f 100644 --- a/ansible/roles/apt/templates/kayobe.sources.j2 +++ b/ansible/roles/apt/templates/kayobe.sources.j2 @@ -1,4 +1,4 @@ -# {{ ansible_managed }} +# {{ kayobe_managed }} {% for repo in apt_repositories %} {% if reponame == repo.name | default('kayobe') %} diff --git a/ansible/roles/dell-switch-bmp/templates/dell-switch-bmp.conf.j2 b/ansible/roles/dell-switch-bmp/templates/dell-switch-bmp.conf.j2 index 068fe3bc2..4e36d22da 100644 --- a/ansible/roles/dell-switch-bmp/templates/dell-switch-bmp.conf.j2 +++ b/ansible/roles/dell-switch-bmp/templates/dell-switch-bmp.conf.j2 @@ -1,4 +1,4 @@ -# {{ ansible_managed }} +# {{ kayobe_managed }} # This file provides dnsmasq configuration for Dell Switches using Bare Metal # Provisioning (BMP). diff --git a/ansible/roles/docker-registry/defaults/main.yml b/ansible/roles/docker-registry/defaults/main.yml index 51e5ce4a2..5107b3a55 100644 --- a/ansible/roles/docker-registry/defaults/main.yml +++ b/ansible/roles/docker-registry/defaults/main.yml @@ -95,3 +95,7 @@ docker_registry_volumes: docker_registry_restart_policy: "unless-stopped" #docker_registry_restart_retries: + +# Owner and group for docker registry configuration files. +docker_registry_ansible_user_uid: "{{ ansible_user }}" +docker_registry_ansible_user_gid: "{{ ansible_user }}" diff --git a/ansible/roles/kolla-ansible/tasks/install.yml b/ansible/roles/kolla-ansible/tasks/install.yml index 3a77fcc06..9408c3793 100644 --- a/ansible/roles/kolla-ansible/tasks/install.yml +++ b/ansible/roles/kolla-ansible/tasks/install.yml @@ -147,12 +147,25 @@ virtualenv: "{{ kolla_ansible_venv }}" virtualenv_python: "{{ kolla_ansible_venv_python }}" +- name: Ensure core Ansible collections are installed + command: + cmd: >- + ansible-galaxy collection install --force + -r {{ kolla_ansible_core_requirements_yml }} + -p {{ kolla_ansible_venv }}/share/kolla-ansible/ansible/collections/ + environment: + # NOTE(wszumski): Ignore collections shipped with ansible, so that we can install + # newer versions. + ANSIBLE_COLLECTIONS_SCAN_SYS_PATH: "False" + # NOTE(wszumski): Don't use path configured for kayobe + ANSIBLE_COLLECTIONS_PATH: '' + when: not kolla_ansible_venv_ansible + - name: Ensure Ansible collections are installed command: cmd: >- ansible-galaxy collection install --force -r {{ kolla_ansible_requirements_yml }} - {% if not kolla_ansible_venv_ansible %}-r {{ kolla_ansible_core_requirements_yml }}{% endif %} -p {{ kolla_ansible_venv }}/share/kolla-ansible/ansible/collections/ environment: # NOTE(wszumski): Ignore collections shipped with ansible, so that we can install diff --git a/ansible/roles/kolla-ansible/templates/overcloud-components.j2 b/ansible/roles/kolla-ansible/templates/overcloud-components.j2 index 415c5c7d1..3eea3b95c 100644 --- a/ansible/roles/kolla-ansible/templates/overcloud-components.j2 +++ b/ansible/roles/kolla-ansible/templates/overcloud-components.j2 @@ -109,7 +109,6 @@ control [cyborg:children] control -compute [gnocchi:children] control diff --git a/ansible/roles/kolla-ansible/templates/overcloud-services.j2 b/ansible/roles/kolla-ansible/templates/overcloud-services.j2 index cd0a3cae5..4ac3d4b13 100644 --- a/ansible/roles/kolla-ansible/templates/overcloud-services.j2 +++ b/ansible/roles/kolla-ansible/templates/overcloud-services.j2 @@ -137,12 +137,26 @@ neutron cinder [cinder-backup:children] +cinder + +[cinder-backup-lvm:children] +storage + +[cinder-backup-multiple:children] +cinder storage [cinder-scheduler:children] cinder [cinder-volume:children] +cinder + +[cinder-volume-lvm:children] +storage + +[cinder-volume-multiple:children] +cinder storage # Cloudkitty diff --git a/ansible/roles/kolla-build/templates/template-override.j2.j2 b/ansible/roles/kolla-build/templates/template-override.j2.j2 index ac8957267..0b9991c7c 100644 --- a/ansible/roles/kolla-build/templates/template-override.j2.j2 +++ b/ansible/roles/kolla-build/templates/template-override.j2.j2 @@ -1,4 +1,4 @@ -# {{ ansible_managed }} +# {{ kayobe_managed }} {% raw %} {% extends parent_template %} diff --git a/ansible/roles/kolla-openstack/defaults/main.yml b/ansible/roles/kolla-openstack/defaults/main.yml index 0feb15251..b87b54566 100644 --- a/ansible/roles/kolla-openstack/defaults/main.yml +++ b/ansible/roles/kolla-openstack/defaults/main.yml @@ -148,6 +148,10 @@ kolla_openstack_custom_config_include_globs_default: glob: prometheus/** - enabled: '{{ kolla_enable_swift | bool }}' glob: swift/** + - enabled: '{{ kolla_enable_watcher | bool }}' + glob: watcher.conf + - enabled: '{{ kolla_enable_watcher | bool }}' + glob: watcher/** # Extra items to add to kolla_openstack_custom_config_include_globs_default # to produce kolla_openstack_custom_config_include_globs. @@ -795,3 +799,9 @@ kolla_enable_prometheus: false # Whether to enable swift. kolla_enable_swift: false + +############################################################################### +# Watcher configuration. + +# Whether to enable watcher +kolla_enable_watcher: false diff --git a/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml b/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml index 035a4cb09..6bd7da34d 100644 --- a/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml +++ b/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml @@ -137,6 +137,7 @@ provisioner: kolla_enable_prometheus: true kolla_enable_swift: true kolla_enable_telegraf: true + kolla_enable_watcher: true lint: name: ansible-lint scenario: diff --git a/ansible/roles/kolla-openstack/molecule/enable-everything/prepare.yml b/ansible/roles/kolla-openstack/molecule/enable-everything/prepare.yml index 4e945b3aa..913f3768e 100644 --- a/ansible/roles/kolla-openstack/molecule/enable-everything/prepare.yml +++ b/ansible/roles/kolla-openstack/molecule/enable-everything/prepare.yml @@ -40,6 +40,7 @@ - prometheus/prometheus.yml.d # Example of non-ini files that should be templated but not merged - fluentd/input/ + - watcher - name: Ensure extra INI configuration files exist copy: @@ -74,6 +75,7 @@ - nova.conf - octavia.conf - placement.conf + - watcher.conf - name: Ensure extra YAML configuration files exist copy: @@ -113,6 +115,10 @@ format1 /^(?\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}) \[(?\w+)\] (?.*)/ + - dest: watcher/policy.yaml + content: | + --- + "my_custom_rule": "role:custom_role" loop_control: label: "{{ item.dest }}" diff --git a/ansible/roles/kolla-openstack/molecule/enable-everything/tests/test_default.py b/ansible/roles/kolla-openstack/molecule/enable-everything/tests/test_default.py index 72d74d0b0..50c524459 100644 --- a/ansible/roles/kolla-openstack/molecule/enable-everything/tests/test_default.py +++ b/ansible/roles/kolla-openstack/molecule/enable-everything/tests/test_default.py @@ -78,6 +78,7 @@ def test_service_ini_file(host, path): 'nova.conf', 'octavia.conf', 'placement.conf', + 'watcher.conf', 'backup.my.cnf']) def test_service_ini_file_extra_confs(host, path): # Tests config added via extra config files @@ -92,7 +93,8 @@ def test_service_ini_file_extra_confs(host, path): 'ironic/ironic-agent.kernel', 'nova/nova-libvirt/cacert.pem', 'nova/nova-libvirt/clientcert.pem', - 'nova/nova-libvirt/clientkey.pem']) + 'nova/nova-libvirt/clientkey.pem', + 'watcher/policy.yaml']) def test_service_non_ini_file(host, path): # TODO(mgoddard): Check config file contents. path = os.path.join('/etc/kolla/config', path) diff --git a/ansible/roles/manage-containers/defaults/main.yml b/ansible/roles/manage-containers/defaults/main.yml index d98bb77df..e79c8ec75 100644 --- a/ansible/roles/manage-containers/defaults/main.yml +++ b/ansible/roles/manage-containers/defaults/main.yml @@ -2,6 +2,9 @@ # Action to perform: One of: "deploy", "destroy". manage_containers_action: "deploy" +#TODO(mattcrees): remove deploy_containers_defaults in Hibiscus cycle +manage_containers_defaults: "{{ deploy_containers_defaults }}" + deploy_containers_defaults: comparisons: image: strict @@ -13,6 +16,13 @@ deploy_containers_defaults: privileged: False restart_policy: "unless-stopped" -deploy_containers_docker_api_timeout: 120 +manage_custom_containers: [] + +#TODO(mattcrees): remove deploy_containers_docker_api_timeout in Hibiscus cycle. +manage_containers_docker_api_timeout: "{{ deploy_containers_docker_api_timeout | default(120) }}" + +manage_containers_registry: +manage_containers_registry_username: +manage_containers_registry_password: -deploy_containers_registry_attempt_login: "{{ kolla_docker_registry_username is truthy and kolla_docker_registry_password is truthy }}" +manage_containers_registry_attempt_login: "{{ manage_containers_registry_username is truthy and manage_containers_registry_password is truthy }}" diff --git a/ansible/roles/manage-containers/tasks/deploy-container.yml b/ansible/roles/manage-containers/tasks/deploy-container.yml index 2fb39ca90..c29912758 100644 --- a/ansible/roles/manage-containers/tasks/deploy-container.yml +++ b/ansible/roles/manage-containers/tasks/deploy-container.yml @@ -28,7 +28,7 @@ restart_policy: "{{ container_config.restart_policy | default(deploy_containers_defaults.restart_policy) }}" shm_size: "{{ container_config.shm_size | default(omit) }}" sysctls: "{{ container_config.sysctls | default(omit) }}" - timeout: "{{ deploy_containers_docker_api_timeout }}" + timeout: "{{ manage_containers_docker_api_timeout }}" ulimits: "{{ container_config.ulimits | default(omit) }}" user: "{{ container_config.user | default(omit) }}" volumes: "{{ container_config.volumes | default(omit) }}" diff --git a/ansible/roles/manage-containers/tasks/deploy.yml b/ansible/roles/manage-containers/tasks/deploy.yml index a735e9b26..5c9fdfb25 100644 --- a/ansible/roles/manage-containers/tasks/deploy.yml +++ b/ansible/roles/manage-containers/tasks/deploy.yml @@ -1,12 +1,12 @@ --- - name: Login to container registry kayobe_container_login: - registry_url: "{{ kolla_docker_registry or omit }}" - username: "{{ kolla_docker_registry_username }}" - password: "{{ kolla_docker_registry_password }}" + registry_url: "{{ manage_containers_registry or omit }}" + username: "{{ manage_containers_registry_username }}" + password: "{{ manage_containers_registry_password }}" reauthorize: yes when: - - deploy_containers_registry_attempt_login | bool + - manage_containers_registry_attempt_login | bool become: "{{ container_engine == 'podman' }}" - name: Deploy containers (loop) @@ -14,4 +14,4 @@ vars: container_name: "{{ item.key }}" container_config: "{{ item.value }}" - with_dict: "{{ seed_containers }}" + with_dict: "{{ manage_custom_containers }}" diff --git a/ansible/roles/manage-containers/tasks/destroy.yml b/ansible/roles/manage-containers/tasks/destroy.yml index 5059832fa..44613b308 100644 --- a/ansible/roles/manage-containers/tasks/destroy.yml +++ b/ansible/roles/manage-containers/tasks/destroy.yml @@ -4,4 +4,4 @@ vars: container_name: "{{ item.key }}" container_config: "{{ item.value }}" - with_dict: "{{ seed_containers }}" + with_dict: "{{ manage_custom_containers }}" diff --git a/ansible/roles/manage-containers/tasks/pull.yml b/ansible/roles/manage-containers/tasks/pull.yml new file mode 100644 index 000000000..c9f4b474c --- /dev/null +++ b/ansible/roles/manage-containers/tasks/pull.yml @@ -0,0 +1,9 @@ +--- +- name: Pull custom container images + kayobe_container_image: + name: "{{ item.value.image }}" + source: pull + state: present + with_dict: "{{ manage_custom_containers }}" + when: kayobe_action != 'destroy' + become: "{{ container_engine == 'podman' }}" diff --git a/ansible/roles/manage-containers/tasks/upgrade.yml b/ansible/roles/manage-containers/tasks/upgrade.yml new file mode 100644 index 000000000..f670a5b78 --- /dev/null +++ b/ansible/roles/manage-containers/tasks/upgrade.yml @@ -0,0 +1,2 @@ +--- +- include_tasks: deploy.yml diff --git a/ansible/roles/public-openrc/templates/public-openrc.sh.j2 b/ansible/roles/public-openrc/templates/public-openrc.sh.j2 index 49225fc60..e0c5e400b 100644 --- a/ansible/roles/public-openrc/templates/public-openrc.sh.j2 +++ b/ansible/roles/public-openrc/templates/public-openrc.sh.j2 @@ -1,4 +1,4 @@ -# {{ ansible_managed }} +# {{ kayobe_managed }} {% for line in (admin_openrc.content | b64decode).splitlines() %} {% if "export OS_AUTH_URL" in line %} diff --git a/ansible/roles/trust-store/defaults/main.yml b/ansible/roles/trust-store/defaults/main.yml index 37bd1755a..1d6c20a89 100644 --- a/ansible/roles/trust-store/defaults/main.yml +++ b/ansible/roles/trust-store/defaults/main.yml @@ -1,8 +1,9 @@ --- trust_store_ca_certificates: [] +trust_store_os_family: "{{ os_family | default(ansible_facts.os_family) | lower }}" trust_store_ca_path_debian: /usr/local/share/ca-certificates trust_store_ca_path_redhat: /etc/pki/ca-trust/source/anchors -trust_store_ca_path: "{{ lookup('vars', 'trust_store_ca_path_' ~ ansible_facts.os_family | lower) }}" +trust_store_ca_path: "{{ lookup('vars', 'trust_store_ca_path_' ~ trust_store_os_family) }}" trust_store_update_cmd_debian: update-ca-certificates trust_store_update_cmd_redhat: update-ca-trust -trust_store_update_cmd: "{{ lookup('vars', 'trust_store_update_cmd_' ~ ansible_facts.os_family | lower) }}" +trust_store_update_cmd: "{{ lookup('vars', 'trust_store_update_cmd_' ~ trust_store_os_family) }}" diff --git a/ansible/seed-manage-containers.yml b/ansible/seed-manage-containers.yml deleted file mode 100644 index 10cd6c0ab..000000000 --- a/ansible/seed-manage-containers.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -- name: "Ensure defined container images are {{ kayobe_action | default('deploy') }}ed on seed node" - hosts: seed - tags: - - seed-deploy-containers - - seed-manage-containers - vars: - manage_containers_action: "{{ kayobe_action | default('deploy') }}" - roles: - - role: manage-containers diff --git a/ansible/trust-store.yml b/ansible/trust-store.yml index 69596a809..af74ce74e 100644 --- a/ansible/trust-store.yml +++ b/ansible/trust-store.yml @@ -1,7 +1,7 @@ --- - name: Add custom CAs to system trust store hosts: seed-hypervisor:seed:overcloud:infra-vms:ansible-control - gather_facts: true + gather_facts: false max_fail_percentage: >- {{ trust_store_max_fail_percentage | default(host_configure_max_fail_percentage) | diff --git a/dev/functions b/dev/functions index b5de6ad71..547965730 100644 --- a/dev/functions +++ b/dev/functions @@ -66,6 +66,9 @@ function config_defaults { # Whether to use Kolla test images. export KAYOBE_USE_KOLLA_TEST_IMAGES=${KAYOBE_USE_KOLLA_TEST_IMAGES:-1} + # Whether to deploy a custom container. + export KAYOBE_DEPLOY_CUSTOM_CONTAINER=${KAYOBE_DEPLOY_CUSTOM_CONTAINER:-0} + # Additional arguments to pass to kayobe commands. export KAYOBE_EXTRA_ARGS=${KAYOBE_EXTRA_ARGS:-} @@ -337,6 +340,12 @@ function ansible_control_host_configure { echo "Configuring the Ansible control host" run_kayobe control host configure + + # Deploy a custom container on the Ansible control host. + if [[ ${KAYOBE_DEPLOY_CUSTOM_CONTAINER} = 1 ]]; then + echo "Deploying custom container" + run_kayobe control host service deploy + fi } function seed_hypervisor_deploy { diff --git a/doc/source/_extra/.htaccess b/doc/source/_extra/.htaccess index b78a9292c..5924e22c5 100644 --- a/doc/source/_extra/.htaccess +++ b/doc/source/_extra/.htaccess @@ -16,3 +16,7 @@ redirectmatch 301 ^/([^/]+/[^/]+)/configuration/seed-custom-containers.html$ /$1 # The following redirects were added when development/* was moved to # contributor/*. redirectmatch 301 ^/([^/]+/[^/]+)/development/([^/]+).html$ /$1/contributor/$2.html + +# The following redirect was added when the seed-custom-containers feature was +# generalised for other hosts. +redirectmatch 301 ^/([^/]+/[^/]+)/configuration/reference/seed-custom-containers.html$ /$1/configuration/reference/custom-containers.html diff --git a/doc/source/administration/seed.rst b/doc/source/administration/seed.rst index 0e2f8ba35..7664305a7 100644 --- a/doc/source/administration/seed.rst +++ b/doc/source/administration/seed.rst @@ -20,7 +20,7 @@ Destroying all services on the seed This step will destroy all containers, container images, and volumes that were deployed by Kayobe and Kolla. To destroy volumes and images associated with - :ref:`custom containers `, you must configure the + :ref:`custom containers `, you must configure the ``post_destroy`` and ``pre_destroy`` hooks to do the clean up manually as Kayobe will not automatically clean these up. It is generally only advised to run this command when you have no important data on the system. diff --git a/doc/source/configuration/reference/seed-custom-containers.rst b/doc/source/configuration/reference/custom-containers.rst similarity index 62% rename from doc/source/configuration/reference/seed-custom-containers.rst rename to doc/source/configuration/reference/custom-containers.rst index 70cc748ca..f0b7a7beb 100644 --- a/doc/source/configuration/reference/seed-custom-containers.rst +++ b/doc/source/configuration/reference/custom-containers.rst @@ -1,11 +1,12 @@ -.. _configuration-seed-custom-containers: +.. _configuration-custom-containers: -====================== -Seed custom containers -====================== +================= +Custom containers +================= This section covers configuration of the user-defined containers deployment -functionality that runs on the seed host. +functionality that runs on the seed, infrastructure VMs, overcloud and Ansible +control hosts. Configuration ============= @@ -70,7 +71,7 @@ Possible options for container deployment: volumes: For a detailed explanation of each option - please see `Ansible -docker_container `_ +docker_container `_ module page. List of Kayobe applied defaults to required docker_container variables: @@ -82,22 +83,47 @@ List of Kayobe applied defaults to required docker_container variables: Docker registry =============== -Seed containers can be pulled from a docker registry deployed on the seed, -since the docker registry deployment step precedes the custom container -deployment step. -It is also possible to deploy a custom containerised docker registry as a -custom seed container. In this case, basic authentication login attempts can be -disabled by setting +Custom containers can be pulled from a docker registry deployed on the seed. +This is possible since the docker registry deployment step precedes the custom +container deployment step. + +It is also possible to deploy a custom containerised docker registry as a custom +seed container. In this case, basic authentication login attempts can be +disabled by setting: .. code-block:: yaml - :caption: ``seed.yml`` + :caption: ``seed.yml`` + + seed_manage_containers_registry_attempt_login: false + +.. code-block:: yaml + :caption: ``infra-vms.yml`` + + infra_vm_manage_containers_registry_attempt_login: false + +.. code-block:: yaml + :caption: ``controllers.yml`` + + controller_manage_containers_registry_attempt_login: false - seed_deploy_containers_registry_attempt_login: false +.. code-block:: yaml + :caption: ``storage.yml`` + + storage_manage_containers_registry_attempt_login: false + +.. code-block:: yaml + :caption: ``monitoring.yml`` + + monitoring_manage_containers_registry_attempt_login: false + +.. code-block:: yaml + :caption: ``ansible-control.yml`` + + ansible_control_manage_containers_registry_attempt_login: false Without this setting, the login will fail because the registry has not yet been deployed. More information on deploying a docker registry can be found :ref:`here `. - diff --git a/doc/source/configuration/reference/index.rst b/doc/source/configuration/reference/index.rst index f88c1f03a..36e39a95e 100644 --- a/doc/source/configuration/reference/index.rst +++ b/doc/source/configuration/reference/index.rst @@ -21,7 +21,7 @@ options. overcloud-dib ironic-python-agent docker-registry - seed-custom-containers + custom-containers infra-vms vgpu nova-cells diff --git a/doc/source/configuration/reference/ironic-python-agent.rst b/doc/source/configuration/reference/ironic-python-agent.rst index 401fa2225..6492bb04e 100644 --- a/doc/source/configuration/reference/ironic-python-agent.rst +++ b/doc/source/configuration/reference/ironic-python-agent.rst @@ -34,6 +34,12 @@ image build``. ``ipa_build_images`` Whether to build IPA images from source. Default is ``False``. +``ipa_build_distro`` + Override the OS distribution used to build IPA images. Default is the host + distribution. +``ipa_build_release`` + Override the OS release used to build IPA images. Default is the host + release. ``ipa_build_source_url`` URL of IPA source repository. Default is https://opendev.org/openstack/ironic-python-agent @@ -43,15 +49,16 @@ image build``. URL of IPA builder source repository. Default is https://opendev.org/openstack/ironic-python-agent-builder ``ipa_builder_source_version`` - Version of IPA builder source repository. Default is ``master``. + Version of IPA builder source repository. Default is ``{{ openstack_branch }}``. ``ipa_build_dib_host_packages_extra`` List of additional build host packages to install. Default is ``[ 'zstd' ]``. ``ipa_build_dib_elements_default`` List of default Diskimage Builder (DIB) elements to use when building IPA - images. Default is ``["centos", "dynamic-login", "enable-serial-console", - "ironic-python-agent-ramdisk"]`` when ``os_distribution`` is ``"rocky"``, and - ``["ubuntu", "dynamic-login", "enable-serial-console", - "ironic-python-agent-ramdisk"]`` otherwise. + images. Default is ``["rocky-container", "dynamic-login", + "enable-serial-console", "ironic-python-agent-ramdisk", "baremetal"]`` when + ``ipa_build_distro`` is ``"rocky"``, and ``[ipa_build_distro, + "dynamic-login", "enable-serial-console", "ironic-python-agent-ramdisk", + "baremetal"]`` otherwise. ``ipa_build_dib_elements_extra`` List of additional Diskimage Builder (DIB) elements to use when building IPA images. Default is empty. @@ -61,14 +68,13 @@ image build``. ``ipa_build_dib_elements_extra``. ``ipa_build_dib_env_default`` Dictionary of default environment variables to provide to Diskimage Builder - (DIB) during IPA image build. Default is ``{"DIB_RELEASE": "9-stream", - "DIB_REPOLOCATION_ironic_python_agent": "{{ ipa_build_source_url }}", - "DIB_REPOREF_ironic_python_agent": "{{ ipa_build_source_version }}", - "DIB_REPOREF_requirements": "{{ ipa_build_source_version }}"}`` if - ``os_distribution`` is ``"rocky"`` else ``{"DIB_RELEASE": "{{ os_release - }}", "DIB_REPOLOCATION_ironic_python_agent": "{{ ipa_build_source_url }}", - "DIB_REPOREF_ironic_python_agent": "{{ ipa_build_source_version }}", - "DIB_REPOREF_requirements": "{{ ipa_build_source_version }}"}``. + (DIB) during IPA image build. Default is ``{"DIB_RELEASE": "{{ + ipa_build_release }}", "DIB_CONTAINERFILE_RUNTIME": "{{ container_engine + }}", "DIB_CONTAINERFILE_RUNTIME_ROOT": "{{ (container_engine == 'podman') | + int }}", "DIB_REPOLOCATION_ironic_python_agent": "{{ ipa_build_source_url + }}", "DIB_REPOREF_ironic_python_agent": "{{ ipa_build_source_version }}", + "DIB_REPOREF_requirements": "{{ ipa_build_source_version }}", + "DIB_IPA_COMPRESS_CMD": 'zstd -19'}`` ``ipa_build_dib_env_extra`` Dictionary of additional environment variables to provide to Diskimage Builder (DIB) during IPA image build. Default is empty. @@ -92,11 +98,15 @@ image build``. role for usage. Default is combination of ``ipa_build_dib_git_elements_default`` and ``ipa_build_dib_git_elements_extra``. ``ipa_build_dib_packages`` - List of DIB packages to install. Default is none. + List of DIB packages to install. Default is ``["python3-yaml"]`` when + ``ipa_build_distro`` is ``"rocky"``, otherwise none. ``ipa_build_upper_constraints_file`` Upper constraints file for installing packages in the virtual environment used for building IPA images. Default is ``{{ pip_upper_constraints_file }}``. +``ipa_build_dib_upper_constraints_file`` + Upper constraints file for installation of DIB to build IPA images. + Default is an empty string. Example: Building IPA images locally ------------------------------------ @@ -304,7 +314,7 @@ inspection. ``ipa_collectors_default`` and ``ipa_collectors_extra``. ``ipa_benchmarks_default`` List of default inspection benchmarks to run. Default is ``["cpu", "disk", - "ram"]``. + "mem"]``. ``ipa_benchmarks_extra`` List of extra inspection benchmarks to run. Default is none. ``ipa_benchmarks`` diff --git a/doc/source/configuration/reference/kolla-ansible.rst b/doc/source/configuration/reference/kolla-ansible.rst index aa748bc6c..ea2f6e85e 100644 --- a/doc/source/configuration/reference/kolla-ansible.rst +++ b/doc/source/configuration/reference/kolla-ansible.rst @@ -829,6 +829,8 @@ which files are supported. ``placement/*`` Extended Placement configuration. ``prometheus/*`` Prometheus configuration. ``swift/*`` Extended swift configuration. + ``watcher.conf`` Watcher configuration. + ``watcher/*`` Extended Watcher configuration. =============================== ======================================================= Configuring an OpenStack Component diff --git a/doc/source/configuration/reference/os-distribution.rst b/doc/source/configuration/reference/os-distribution.rst index 5f29d95ec..716f68777 100644 --- a/doc/source/configuration/reference/os-distribution.rst +++ b/doc/source/configuration/reference/os-distribution.rst @@ -20,6 +20,17 @@ is set to ``rocky`` it may be set to ``10``, and this is its default value. When ``os_distribution`` is set to ``ubuntu`` it may be set to ``noble``, and this is its default value. +The ``os_family_map`` variable in ``etc/kayobe/globals.yml`` maps +``os_distribution`` values to OS families. The default mapping is: + +* ``centos`` -> ``RedHat`` +* ``rocky`` -> ``RedHat`` +* ``ubuntu`` -> ``Debian`` + +The ``os_family`` variable in ``etc/kayobe/globals.yml`` defaults to +``{{ os_family_map[os_distribution | lower] }}``, and may be used by +configuration defaults that only need to distinguish between OS families. + These variables are used to set various defaults, including: * Bootstrap users diff --git a/doc/source/deployment.rst b/doc/source/deployment.rst index c6ec74b7f..eb75d2127 100644 --- a/doc/source/deployment.rst +++ b/doc/source/deployment.rst @@ -229,7 +229,7 @@ After this command has completed the seed services will be active. information about configuring Bifrost. :ref:`configuration-bifrost-overcloud-root-image` provides information on configuring the root disk image build process. See :ref:`here - ` for information about deploying + ` for information about deploying additional, custom services (containers) on a seed node. Building Deployment Images @@ -377,6 +377,11 @@ To trigger the hooks:: (kayobe) $ kayobe infra vm service deploy +.. seealso:: + + See :ref:`here ` for information about + deploying additional, custom services (containers) on infrastructure VMs. + Example ^^^^^^^ @@ -724,6 +729,9 @@ services running in Docker containers. Information on configuration of Kolla Ansible is available :ref:`here `. + See :ref:`here ` for information about + deploying additional, custom services (containers) on overcloud hosts. + Interacting with the Control Plane ---------------------------------- diff --git a/doc/test/redirect-tests.txt b/doc/test/redirect-tests.txt index 0387e3358..a84b8d26e 100644 --- a/doc/test/redirect-tests.txt +++ b/doc/test/redirect-tests.txt @@ -27,3 +27,6 @@ # Moved /kayobe/latest/development/*.html to /kayobe/latest/contributor/ /kayobe/latest/development/automated.html 301 /kayobe/latest/contributor/automated.html /kayobe/latest/development/index.html 301 /kayobe/latest/contributor/index.html + +# Moved /kayobe/latest/configuration/reference/seed-custom-containers.html to /kayobe/latest/configuration/reference/custom-containers.html +/kayobe/latest/configuration/reference/seed-custom-containers.html 301 /kayobe/latest/configuration/reference/custom-containers.html diff --git a/etc/kayobe/ansible-control.yml b/etc/kayobe/ansible-control.yml index 5232d4470..5c3ca32cf 100644 --- a/etc/kayobe/ansible-control.yml +++ b/etc/kayobe/ansible-control.yml @@ -90,6 +90,24 @@ # singleplatform-eng.users role. #ansible_control_users: +############################################################################### +# Ansible control host additional containers configuration + +# Dict of containers to deploy. +# Example: +# seed_containers: +# squid: +# image: "docker.io/stackhpc/squid" +# pre: "{{ kayobe_env_config_path }}/containers/squid/pre.yml" +# post: "{{ kayobe_env_config_path }}/containers/squid/post.yml" +# tag: "3.5.20-1" +# +#ansible_control_containers: + +# Whether to attempt a basic authentication login to a registry when +# deploying containers. +#ansible_control_manage_containers_registry_attempt_login: + ############################################################################### # Ansible control host firewalld configuration. diff --git a/etc/kayobe/controllers.yml b/etc/kayobe/controllers.yml index 7dd3199f2..2f9d3d181 100644 --- a/etc/kayobe/controllers.yml +++ b/etc/kayobe/controllers.yml @@ -164,6 +164,24 @@ # singleplatform-eng.users role. #controller_users: +############################################################################### +# Controller node additional containers configuration + +# Dict of containers to deploy. +# Example: +# controller_containers: +# squid: +# image: "stackhpc/squid:3.5.20-1" +# pre: "{{ kayobe_env_config_path }}/containers/squid/pre.yml" +# post: "{{ kayobe_env_config_path }}/containers/squid/post.yml" +# +#controller_containers: + + +# Whether to attempt a basic authentication login to a registry when +# deploying controller containers +#controller_manage_containers_registry_attempt_login: + ############################################################################### # Controller node firewalld configuration. diff --git a/etc/kayobe/globals.yml b/etc/kayobe/globals.yml index bcf9aca4e..c17ec7c27 100644 --- a/etc/kayobe/globals.yml +++ b/etc/kayobe/globals.yml @@ -48,6 +48,14 @@ # is "rocky". #os_distribution: +# Mapping from OS distribution name to OS family. Supported keys are +# "centos", "rocky", and "ubuntu". +#os_family_map: + +# OS family. Valid options are "RedHat" and "Debian". Default depends on +# os_distribution. +#os_family: + # OS release. Valid options are "10-stream" when os_distribution is "centos", # "10" when os_distribution is "rocky", or "noble" when os_distribution is # "ubuntu". @@ -56,6 +64,10 @@ ############################################################################### # Ansible configuration. +# String used as the header comment in files managed by Kayobe. Default is +# "Ansible managed". +#kayobe_managed: + # Filter to apply to the setup module when gathering facts. Default is to not # specify a filter. #kayobe_ansible_setup_filter: diff --git a/etc/kayobe/infra-vms.yml b/etc/kayobe/infra-vms.yml index 50362e59d..e8bc24ef0 100644 --- a/etc/kayobe/infra-vms.yml +++ b/etc/kayobe/infra-vms.yml @@ -167,6 +167,23 @@ # singleplatform-eng.users role. #infra_vm_users: +############################################################################### +# Infrastructure VM node additional containers configuration + +# Dict of containers to deploy. +# Example: +# infra_vm_containers: +# squid: +# image: "stackhpc/squid:3.5.20-1" +# pre: "{{ kayobe_env_config_path }}/containers/squid/pre.yml" +# post: "{{ kayobe_env_config_path }}/containers/squid/post.yml" +# +#infra_vm_containers: + +# Whether to attempt a basic authentication login to a registry when +# deploying controller containers +#infra_vm_manage_containers_registry_attempt_login: + ############################################################################### # Infrastructure VM node firewalld configuration. diff --git a/etc/kayobe/monitoring.yml b/etc/kayobe/monitoring.yml index 463b3090b..6045cb20b 100644 --- a/etc/kayobe/monitoring.yml +++ b/etc/kayobe/monitoring.yml @@ -96,6 +96,23 @@ # singleplatform-eng.users role. #monitoring_users: +############################################################################### +# Monitoring node additional containers configuration + +# Dict of containers to deploy. +# Example: +# monitoring_containers: +# squid: +# image: "stackhpc/squid:3.5.20-1" +# pre: "{{ kayobe_env_config_path }}/containers/squid/pre.yml" +# post: "{{ kayobe_env_config_path }}/containers/squid/post.yml" +# +#monitoring_containers: + +# Whether to attempt a basic authentication login to a registry when +# deploying monitoring containers +#monitoring_manage_containers_registry_attempt_login: + ############################################################################### # Monitoring node firewalld configuration. diff --git a/etc/kayobe/openstack.yml b/etc/kayobe/openstack.yml index 1acfd0756..688b6f4c0 100644 --- a/etc/kayobe/openstack.yml +++ b/etc/kayobe/openstack.yml @@ -2,10 +2,10 @@ ############################################################################### # OpenStack release configuration. -# Name of the current OpenStack release. Default is "master". +# Name of the current OpenStack release. Default is "2026.1". #openstack_release: -# Name of the current OpenStack branch. Default is "master". +# Name of the current OpenStack branch. Default is "stable/2026.1". #openstack_branch: ############################################################################### diff --git a/etc/kayobe/seed.yml b/etc/kayobe/seed.yml index 46f1cddc6..044682538 100644 --- a/etc/kayobe/seed.yml +++ b/etc/kayobe/seed.yml @@ -107,7 +107,7 @@ ############################################################################### # Seed node additional containers configuration -# Dict of container images to start +# Dict of containers to deploy. # Example: # seed_containers: # squid: @@ -119,8 +119,8 @@ #seed_containers: # Whether to attempt a basic authentication login to a registry when -# deploying seed containers -#seed_deploy_containers_registry_attempt_login: +# deploying seed containers. +#seed_manage_containers_registry_attempt_login: ############################################################################### # Seed node firewalld configuration. diff --git a/etc/kayobe/storage.yml b/etc/kayobe/storage.yml index 53376b4ef..320ffbb4b 100644 --- a/etc/kayobe/storage.yml +++ b/etc/kayobe/storage.yml @@ -126,6 +126,23 @@ # singleplatform-eng.users role. #storage_users: +############################################################################### +# Storage node additional containers configuration + +# Dict of containers to deploy. +# Example: +# storage_containers: +# squid: +# image: "stackhpc/squid:3.5.20-1" +# pre: "{{ kayobe_env_config_path }}/containers/squid/pre.yml" +# post: "{{ kayobe_env_config_path }}/containers/squid/post.yml" +# +#storage_containers: + +# Whether to attempt a basic authentication login to a registry when +# deploying storage containers +#storage_manage_containers_registry_attempt_login: + ############################################################################### # Storage node firewalld configuration. diff --git a/kayobe/cli/commands.py b/kayobe/cli/commands.py index 2660bd7ad..529d9b623 100644 --- a/kayobe/cli/commands.py +++ b/kayobe/cli/commands.py @@ -466,14 +466,48 @@ class ControlHostServiceDeploy(KayobeAnsibleMixin, VaultMixin, Command): """Deploy the Ansible control host services.""" def take_action(self, parsed_args): - self.app.LOG.debug("Running no-op control host service deploy") + self.app.LOG.debug("Deploying Ansible control host services") + playbooks = _build_playbook_list("manage-containers") + extra_vars = { + "kayobe_action": "deploy", + "manage_containers_target_hosts": "ansible-control", + } + self.run_kayobe_playbooks(parsed_args, playbooks, + limit="ansible-control", + extra_vars=extra_vars) class ControlHostServiceDestroy(KayobeAnsibleMixin, VaultMixin, Command): """Destroy the Ansible control host services.""" def take_action(self, parsed_args): - self.app.LOG.debug("Running no-op control host service destroy") + if not parsed_args.yes_i_really_really_mean_it: + self.app.LOG.error("This will permanently destroy all services " + "and data. Specify " + "--yes-i-really-really-mean-it to confirm that " + "you understand this.") + sys.exit(1) + self.app.LOG.debug("Destroying Ansible control host services") + + extra_vars = { + "kayobe_action": "destroy", + "manage_containers_target_hosts": "ansible-control", + } + playbooks = _build_playbook_list( + "manage-containers", + "docker-registry") + self.run_kayobe_playbooks(parsed_args, playbooks, + limit="ansible-control", + extra_vars=extra_vars) + + def get_parser(self, prog_name): + parser = super(ControlHostServiceDestroy, self).get_parser(prog_name) + group = parser.add_argument_group("Services") + group.add_argument("--yes-i-really-really-mean-it", + action='store_true', + help="confirm that you understand that this will " + "permanently destroy all services and data.") + return parser class ConfigurationDump(KayobeAnsibleMixin, VaultMixin, Command): @@ -883,11 +917,12 @@ class SeedServiceDeploy(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin, def take_action(self, parsed_args): self.app.LOG.debug("Deploying seed services") - self.handle_kolla_tags_limits_deprecation(parsed_args) - playbooks = _build_playbook_list( - "seed-manage-containers") - extra_vars = {"kayobe_action": "deploy"} - self.run_kayobe_playbooks(parsed_args, playbooks, + playbooks = _build_playbook_list("manage-containers") + extra_vars = { + "kayobe_action": "deploy", + "manage_containers_target_hosts": "seed", + } + self.run_kayobe_playbooks(parsed_args, playbooks, limit="seed", extra_vars=extra_vars) self.generate_kolla_ansible_config(parsed_args, service_config=False, bifrost_config=True) @@ -925,11 +960,14 @@ def take_action(self, parsed_args): self.run_kolla_ansible_seed(parsed_args, "destroy", extra_args=extra_args) - extra_vars = {"kayobe_action": "destroy"} + extra_vars = { + "kayobe_action": "destroy", + "manage_containers_target_hosts": "seed", + } playbooks = _build_playbook_list( - "seed-manage-containers", + "manage-containers", "docker-registry") - self.run_kayobe_playbooks(parsed_args, playbooks, + self.run_kayobe_playbooks(parsed_args, playbooks, limit="seed", extra_vars=extra_vars) def get_parser(self, prog_name): @@ -960,11 +998,12 @@ class SeedServiceUpgrade(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin, def take_action(self, parsed_args): self.app.LOG.debug("Upgrading seed services") - self.handle_kolla_tags_limits_deprecation(parsed_args) - playbooks = _build_playbook_list( - "seed-manage-containers") - extra_vars = {"kayobe_action": "deploy"} - self.run_kayobe_playbooks(parsed_args, playbooks, + playbooks = _build_playbook_list("manage-containers") + extra_vars = { + "kayobe_action": "deploy", + "manage_containers_target_hosts": "seed", + } + self.run_kayobe_playbooks(parsed_args, playbooks, limit="seed", extra_vars=extra_vars) self.generate_kolla_ansible_config(parsed_args, service_config=False, bifrost_config=True) @@ -1219,19 +1258,52 @@ class InfraVMServiceDeploy(KayobeAnsibleMixin, VaultMixin, """Run hooks for infra VM services.""" def take_action(self, parsed_args): - self.app.LOG.debug("Running no-op Infra VM service deploy") + self.app.LOG.debug("Running Infra VM service deploy") + playbooks = _build_playbook_list("manage-containers") + extra_vars = { + "kayobe_action": "deploy", + "manage_containers_target_hosts": "infra-vms", + } + self.run_kayobe_playbooks(parsed_args, playbooks, limit="infra-vms", + extra_vars=extra_vars) -class InfraVMServiceDestroy(KayobeAnsibleMixin, VaultMixin, - Command): +class InfraVMServiceDestroy(KayobeAnsibleMixin, + VaultMixin, Command): """Destroy the infra VM services. Permanently destroy the infra VM containers, container images, and container volumes. """ + def get_parser(self, prog_name): + parser = super(InfraVMServiceDestroy, self).get_parser(prog_name) + group = parser.add_argument_group("Services") + group.add_argument("--yes-i-really-really-mean-it", + action='store_true', + help="confirm that you understand that this will " + "permanently destroy all services and data.") + return parser + def take_action(self, parsed_args): - self.app.LOG.debug("Running no-op Infra VM service destroy") + if not parsed_args.yes_i_really_really_mean_it: + self.app.LOG.error("This will permanently destroy all services " + "and data. Specify " + "--yes-i-really-really-mean-it to confirm that " + "you understand this.") + sys.exit(1) + + self.app.LOG.debug("Destroying infra VM services") + + extra_vars = { + "kayobe_action": "destroy", + "manage_containers_target_hosts": "infra-vms", + } + playbooks = _build_playbook_list( + "manage-containers", + "docker-registry") + self.run_kayobe_playbooks(parsed_args, playbooks, limit="infra-vms", + extra_vars=extra_vars) class OvercloudInventoryDiscover(KayobeAnsibleMixin, VaultMixin, Command): @@ -1712,7 +1784,10 @@ def take_action(self, parsed_args): # Deploy kayobe extra services. playbooks = _build_playbook_list("overcloud-extras") - extra_vars = {"kayobe_action": "deploy"} + extra_vars = { + "kayobe_action": "deploy", + "manage_containers_target_hosts": "overcloud", + } self.run_kayobe_playbooks(parsed_args, playbooks, extra_vars=extra_vars, limit="overcloud") @@ -1771,7 +1846,10 @@ def take_action(self, parsed_args): # Deploy kayobe extra services. playbooks = _build_playbook_list("overcloud-extras") - extra_vars = {"kayobe_action": "deploy"} + extra_vars = { + "kayobe_action": "deploy", + "manage_containers_target_hosts": "overcloud", + } self.run_kayobe_playbooks(parsed_args, playbooks, extra_vars=extra_vars, limit="overcloud") @@ -1868,7 +1946,10 @@ def take_action(self, parsed_args): # Reconfigure kayobe extra services. playbooks = _build_playbook_list("overcloud-extras") - extra_vars = {"kayobe_action": "reconfigure"} + extra_vars = { + "kayobe_action": "reconfigure", + "manage_containers_target_hosts": "overcloud", + } self.run_kayobe_playbooks(parsed_args, playbooks, extra_vars=extra_vars, limit="overcloud") @@ -1923,7 +2004,10 @@ def take_action(self, parsed_args): # Stop kayobe extra services. playbooks = _build_playbook_list("overcloud-extras") - extra_vars = {"kayobe_action": "stop"} + extra_vars = { + "kayobe_action": "stop", + "manage_containers_target_hosts": "overcloud", + } self.run_kayobe_playbooks(parsed_args, playbooks, extra_vars=extra_vars, limit="overcloud") @@ -1975,7 +2059,10 @@ def take_action(self, parsed_args): # Upgrade kayobe extra services. playbooks = _build_playbook_list("overcloud-extras") - extra_vars = {"kayobe_action": "upgrade"} + extra_vars = { + "kayobe_action": "upgrade", + "manage_containers_target_hosts": "overcloud", + } self.run_kayobe_playbooks(parsed_args, playbooks, extra_vars=extra_vars, limit="overcloud") @@ -2026,7 +2113,10 @@ def take_action(self, parsed_args): # Destroy kayobe extra services. playbooks = _build_playbook_list("overcloud-extras") - extra_vars = {"kayobe_action": "destroy"} + extra_vars = { + "kayobe_action": "destroy", + "manage_containers_target_hosts": "overcloud", + } self.run_kayobe_playbooks(parsed_args, playbooks, extra_vars=extra_vars, limit="overcloud") @@ -2048,7 +2138,10 @@ def take_action(self, parsed_args): # Pull container images for kayobe extra services. playbooks = _build_playbook_list("overcloud-extras") - extra_vars = {"kayobe_action": "pull"} + extra_vars = { + "kayobe_action": "pull", + "manage_containers_target_hosts": "overcloud", + } self.run_kayobe_playbooks(parsed_args, playbooks, extra_vars=extra_vars, limit="overcloud") diff --git a/kayobe/plugins/action/kolla_ansible_host_vars.py b/kayobe/plugins/action/kolla_ansible_host_vars.py index 085e60004..229b71306 100644 --- a/kayobe/plugins/action/kolla_ansible_host_vars.py +++ b/kayobe/plugins/action/kolla_ansible_host_vars.py @@ -96,8 +96,7 @@ def _run(self, interfaces, external_networks): result['failed'] = True result['msg'] = "; ".join(errors) else: - result['ansible_facts'] = facts - result['_ansible_facts_cacheable'] = False + result['kolla_ansible_host_vars'] = facts return result def _get_interface_fact(self, net_name, required, description): diff --git a/kayobe/tests/unit/cli/test_commands.py b/kayobe/tests/unit/cli/test_commands.py index 694b08c81..171cf4678 100644 --- a/kayobe/tests/unit/cli/test_commands.py +++ b/kayobe/tests/unit/cli/test_commands.py @@ -916,8 +916,10 @@ def test_seed_service_deploy(self, mock_kolla_run, mock_run): expected_calls = [ mock.call( mock.ANY, - [utils.get_data_files_path("ansible", "seed-manage-containers.yml")], # noqa - extra_vars={'kayobe_action': 'deploy'} + [utils.get_data_files_path("ansible", "manage-containers.yml")], # noqa + limit="seed", + extra_vars={'kayobe_action': 'deploy', + 'manage_containers_target_hosts': 'seed'} ), mock.call( mock.ANY, @@ -942,7 +944,8 @@ def test_seed_service_deploy(self, mock_kolla_run, mock_run): utils.get_data_files_path( "ansible", "dell-switch-bmp.yml"), ], - extra_vars={'kayobe_action': 'deploy'} + extra_vars={'kayobe_action': 'deploy', + 'manage_containers_target_hosts': 'seed'} ), ] self.assertListEqual(expected_calls, mock_run.call_args_list) @@ -970,8 +973,10 @@ def test_seed_service_upgrade(self, mock_kolla_run, mock_run): expected_calls = [ mock.call( mock.ANY, - [utils.get_data_files_path("ansible", "seed-manage-containers.yml")], # noqa - extra_vars={'kayobe_action': 'deploy'} + [utils.get_data_files_path("ansible", "manage-containers.yml")], # noqa + limit="seed", + extra_vars={'kayobe_action': 'deploy', + 'manage_containers_target_hosts': 'seed'} ), mock.call( mock.ANY, @@ -1195,7 +1200,7 @@ def test_infra_vm_host_package_update_all(self, mock_run): self.assertListEqual(expected_calls, mock_run.call_args_list) @mock.patch.object(commands.KayobeAnsibleMixin, - "run_kayobe_playbook") + "run_kayobe_playbooks") def test_infra_vm_service_deploy(self, mock_run): command = commands.InfraVMServiceDeploy(TestApp(), []) parser = command.get_parser("test") @@ -1204,7 +1209,16 @@ def test_infra_vm_service_deploy(self, mock_run): result = command.run(parsed_args) self.assertEqual(0, result) - expected_calls = [] + expected_calls = [ + mock.call( + mock.ANY, + [utils.get_data_files_path( + "ansible", "manage-containers.yml")], + limit="infra-vms", + extra_vars={'kayobe_action': 'deploy', + 'manage_containers_target_hosts': 'infra-vms'} + ), + ] self.assertListEqual(expected_calls, mock_run.call_args_list) @mock.patch.object(commands.KayobeAnsibleMixin, @@ -1759,6 +1773,7 @@ def test_overcloud_service_deploy(self, mock_kolla_run, mock_run): limit="overcloud", extra_vars={ "kayobe_action": "deploy", + "manage_containers_target_hosts": "overcloud", }, ), mock.call( @@ -1827,6 +1842,7 @@ def test_overcloud_service_deploy_containers(self, mock_kolla_run, limit="overcloud", extra_vars={ "kayobe_action": "deploy", + "manage_containers_target_hosts": "overcloud", }, ), ] @@ -1924,6 +1940,7 @@ def test_overcloud_service_reconfigure(self, mock_kolla_run, mock_run): limit="overcloud", extra_vars={ "kayobe_action": "reconfigure", + "manage_containers_target_hosts": "overcloud", }, ), mock.call( @@ -1991,6 +2008,7 @@ def test_overcloud_service_stop(self, mock_kolla_run, mock_run): limit="overcloud", extra_vars={ "kayobe_action": "stop", + "manage_containers_target_hosts": "overcloud", }, ), ] @@ -2057,6 +2075,7 @@ def test_overcloud_service_upgrade(self, mock_kolla_run, mock_run): limit="overcloud", extra_vars={ "kayobe_action": "upgrade", + "manage_containers_target_hosts": "overcloud", } ), mock.call( diff --git a/kayobe/tests/unit/plugins/action/test_kolla_ansible_host_vars.py b/kayobe/tests/unit/plugins/action/test_kolla_ansible_host_vars.py index 480a5cf2a..dcd2f3cbd 100644 --- a/kayobe/tests/unit/plugins/action/test_kolla_ansible_host_vars.py +++ b/kayobe/tests/unit/plugins/action/test_kolla_ansible_host_vars.py @@ -96,8 +96,7 @@ def test__run_empty_args(self): result = module._run([], []) expected = { "changed": False, - "ansible_facts": {}, - "_ansible_facts_cacheable": False, + "kolla_ansible_host_vars": {}, } self.assertEqual(expected, result) @@ -112,10 +111,9 @@ def test__run_one_interface(self): result = module._run(interfaces, []) expected = { "changed": False, - "ansible_facts": { + "kolla_ansible_host_vars": { "kolla_foo_interface": "eth0", }, - "_ansible_facts_cacheable": False, } self.assertEqual(expected, result) @@ -135,11 +133,10 @@ def test__run_two_interfaces(self): result = module._run(interfaces, []) expected = { "changed": False, - "ansible_facts": { + "kolla_ansible_host_vars": { "kolla_foo_interface": "eth0", "kolla_bar_interface": "eth1", }, - "_ansible_facts_cacheable": False, } self.assertEqual(expected, result) @@ -171,8 +168,7 @@ def test__run_interface_not_mapped_not_required(self): result = module._run(interfaces, []) expected = { "changed": False, - "ansible_facts": {}, - "_ansible_facts_cacheable": False, + "kolla_ansible_host_vars": {}, } self.assertEqual(expected, result) @@ -208,8 +204,7 @@ def test__run_interface_no_interface_not_required(self): result = module._run(interfaces, []) expected = { "changed": False, - "ansible_facts": {}, - "_ansible_facts_cacheable": False, + "kolla_ansible_host_vars": {}, } self.assertEqual(expected, result) @@ -247,11 +242,10 @@ def test_run_external_networks_one(self): result = module._run([], external_networks) expected = { "changed": False, - "ansible_facts": { + "kolla_ansible_host_vars": { "kolla_neutron_bridge_names": "eth0-ovs", "kolla_neutron_external_interfaces": "eth0", }, - "_ansible_facts_cacheable": False, } self.assertEqual(expected, result) @@ -266,12 +260,11 @@ def test_run_external_networks_one_with_physnet(self): result = module._run([], external_networks) expected = { "changed": False, - "ansible_facts": { + "kolla_ansible_host_vars": { "kolla_neutron_bridge_names": "eth0-ovs", "kolla_neutron_external_interfaces": "eth0", "kolla_neutron_physical_networks": "custom1", }, - "_ansible_facts_cacheable": False, } self.assertEqual(expected, result) @@ -287,11 +280,10 @@ def test_run_external_networks_two(self): result = module._run([], external_networks) expected = { "changed": False, - "ansible_facts": { + "kolla_ansible_host_vars": { "kolla_neutron_bridge_names": "eth0-ovs,eth1-ovs", "kolla_neutron_external_interfaces": "eth0,eth1", }, - "_ansible_facts_cacheable": False, } self.assertEqual(expected, result) @@ -310,12 +302,11 @@ def test_run_external_networks_two_with_physnet(self): result = module._run([], external_networks) expected = { "changed": False, - "ansible_facts": { + "kolla_ansible_host_vars": { "kolla_neutron_bridge_names": "eth0-ovs,eth1-ovs", "kolla_neutron_external_interfaces": "eth0,eth1", "kolla_neutron_physical_networks": "custom1,custom2", }, - "_ansible_facts_cacheable": False, } self.assertEqual(expected, result) @@ -353,11 +344,10 @@ def test_run_external_networks_two_same_interface(self): result = module._run([], external_networks) expected = { "changed": False, - "ansible_facts": { + "kolla_ansible_host_vars": { "kolla_neutron_bridge_names": "eth0-ovs", "kolla_neutron_external_interfaces": "eth0", }, - "_ansible_facts_cacheable": False, } self.assertEqual(expected, result) @@ -376,12 +366,11 @@ def test_run_external_networks_two_same_interface_with_physnet(self): result = module._run([], external_networks) expected = { "changed": False, - "ansible_facts": { + "kolla_ansible_host_vars": { "kolla_neutron_bridge_names": "eth0-ovs", "kolla_neutron_external_interfaces": "eth0", "kolla_neutron_physical_networks": "custom1", }, - "_ansible_facts_cacheable": False, } self.assertEqual(expected, result) @@ -424,11 +413,10 @@ def test_run_external_networks_two_vlans(self): result = module._run([], external_networks) expected = { "changed": False, - "ansible_facts": { + "kolla_ansible_host_vars": { "kolla_neutron_bridge_names": "eth0-ovs", "kolla_neutron_external_interfaces": "eth0", }, - "_ansible_facts_cacheable": False, } self.assertEqual(expected, result) @@ -443,11 +431,10 @@ def test_run_external_networks_bridge(self): result = module._run([], external_networks) expected = { "changed": False, - "ansible_facts": { + "kolla_ansible_host_vars": { "kolla_neutron_bridge_names": "breth0-ovs", "kolla_neutron_external_interfaces": "p-breth0-ovs", }, - "_ansible_facts_cacheable": False, } self.assertEqual(expected, result) @@ -463,11 +450,10 @@ def test_run_external_networks_bridge_vlan(self): result = module._run([], external_networks) expected = { "changed": False, - "ansible_facts": { + "kolla_ansible_host_vars": { "kolla_neutron_bridge_names": "breth0-ovs", "kolla_neutron_external_interfaces": "p-breth0-ovs", }, - "_ansible_facts_cacheable": False, } self.assertEqual(expected, result) @@ -495,8 +481,7 @@ def test_run_external_networks_not_mapped_not_required(self): result = module._run([], external_networks) expected = { "changed": False, - "ansible_facts": {}, - "_ansible_facts_cacheable": False, + "kolla_ansible_host_vars": {}, } self.assertEqual(expected, result) @@ -528,8 +513,7 @@ def test_run_external_networks_no_interface_not_required(self): result = module._run([], external_networks) expected = { "changed": False, - "ansible_facts": {}, - "_ansible_facts_cacheable": False, + "kolla_ansible_host_vars": {}, } self.assertEqual(expected, result) diff --git a/kayobe/tests/unit/plugins/filter/test_nmstate.py b/kayobe/tests/unit/plugins/filter/test_nmstate.py index 91c5966c8..da1fef140 100644 --- a/kayobe/tests/unit/plugins/filter/test_nmstate.py +++ b/kayobe/tests/unit/plugins/filter/test_nmstate.py @@ -327,29 +327,6 @@ def test_ethtool_feature_aliases(self): } self.assertEqual(eth_iface["ethtool"]["feature"], expected_features) - def test_ethtool_combined_config(self): - """Test combined ring and feature configuration.""" - variables = { - "inventory_hostname": "test-host", - "test_interface": "eth0", - "test_ethtool_config": { - "ring": {"rx": 1024, "tx": 512}, - "feature": {"rx": True, "gso": False} - } - } - context = self._make_context(variables) - result = nmstate.nmstate_config(context, ["test"]) - - eth_iface = next(i for i in result["interfaces"] - - - if i["name"] == "eth0") - expected_ethtool = { - "ring": {"rx": 1024, "tx": 512}, - "feature": {"rx-checksum": True, "tx-generic-segmentation": False} - } - self.assertEqual(eth_iface["ethtool"], expected_ethtool) - def test_ethtool_invalid_feature(self): """Test error handling for unsupported features.""" variables = { @@ -472,28 +449,6 @@ def test_vlan_interface_invalid_name(self): if i["name"] == "eth0") self.assertEqual(eth_iface["type"], "ethernet") - def test_vlan_interface_parent_derivation(self): - """Test VLAN parent derivation from interface name.""" - variables = { - "inventory_hostname": "test-host", - "ansible_facts": {"os_family": "RedHat"}, - "vlan_interface": "bond0.42", - "vlan_vlan": 42, - } - context = self._make_context(variables) - result = nmstate.nmstate_config(context, ["vlan"]) - - vlan_iface = next( - i for i in result["interfaces"] - if i["name"] == "bond0.42") - self.assertEqual(vlan_iface["vlan"]["base-iface"], "bond0") - self.assertEqual(vlan_iface["vlan"]["id"], 42) - - bond_iface = next( - i for i in result["interfaces"] - if i["name"] == "bond0") - self.assertEqual(bond_iface["state"], "up") - def test_vlan_interface_qos_map_structured(self): context = self._make_context( { @@ -639,25 +594,6 @@ def test_defroute_true_static_ip(self): self.assertEqual(default_routes[0]["next-hop-address"], "10.0.0.254") - def test_defroute_unset_static_ip(self): - """Test defroute unset (None) adds default route for static IP.""" - variables = { - "inventory_hostname": "test-host", - "test_interface": "eth0", - "test_ips": {"test-host": "10.0.0.1"}, - "test_cidr": "10.0.0.1/24", - "test_gateway": "10.0.0.254", - } - context = self._make_context(variables) - result = nmstate.nmstate_config(context, ["test"]) - - default_routes = [ - r for r in result["routes"]["config"] - if r["destination"] == "0.0.0.0/0"] - self.assertEqual(len(default_routes), 1) - self.assertEqual(default_routes[0]["next-hop-address"], - "10.0.0.254") - def test_defroute_false_dhcp(self): """Test defroute=false disables auto-routes for DHCP.""" variables = { @@ -744,24 +680,6 @@ def test_ovs_patch_links(self): self.assertIn({"name": "eth1"}, bridge_ports) self.assertIn({"name": "p-br0-phy"}, bridge_ports) - def test_route_without_table(self): - """Test route without table-id omits the field.""" - variables = { - "inventory_hostname": "test-host", - "test_interface": "eth0", - "test_routes": [ - {"cidr": "10.0.0.0/24", "gateway": "192.168.1.1"} - ], - } - context = self._make_context(variables) - result = nmstate.nmstate_config(context, ["test"]) - - routes = result["routes"]["config"] - self.assertEqual(len(routes), 1) - self.assertEqual(routes[0]["destination"], "10.0.0.0/24") - self.assertEqual(routes[0]["next-hop-address"], "192.168.1.1") - self.assertNotIn("table-id", routes[0]) - def test_route_with_supported_attributes(self): """Test route maps supported nmstate attributes.""" variables = { @@ -785,6 +703,7 @@ def test_route_with_supported_attributes(self): self.assertEqual(routes[0]["metric"], 400) self.assertTrue(routes[0]["on-link"]) self.assertEqual(routes[0]["source"], "192.168.1.2") + self.assertNotIn("table-id", routes[0]) def test_route_with_supported_options(self): """Test documented route options map to nmstate attributes.""" diff --git a/playbooks/kayobe-ansible-control-host-configure-base/overrides.yml.j2 b/playbooks/kayobe-ansible-control-host-configure-base/overrides.yml.j2 index c643dcf6d..34a2faef7 100644 --- a/playbooks/kayobe-ansible-control-host-configure-base/overrides.yml.j2 +++ b/playbooks/kayobe-ansible-control-host-configure-base/overrides.yml.j2 @@ -265,3 +265,9 @@ ansible_control_fail2ban_enabled: true # Add a custom entry to /etc/hosts. custom_etc_hosts_entries: foo.example.com: 127.0.0.88 + +# Deploy a hello-world container. +ansible_control_containers: + hello-world: + image: docker.io/library/hello-world + tag: latest \ No newline at end of file diff --git a/playbooks/kayobe-ansible-control-host-configure-base/run.yml b/playbooks/kayobe-ansible-control-host-configure-base/run.yml index c439f9555..f2c50466e 100644 --- a/playbooks/kayobe-ansible-control-host-configure-base/run.yml +++ b/playbooks/kayobe-ansible-control-host-configure-base/run.yml @@ -2,6 +2,7 @@ - hosts: primary environment: KAYOBE_CONFIG_SOURCE_PATH: "{{ kayobe_config_src_dir }}" + KAYOBE_DEPLOY_CUSTOM_CONTAINER: "{{ deploy_custom_container | default(false) | ternary(1, 0) }}" tasks: - name: Prevent NetworkManager from managing default interface command: 'nmcli dev set {{ ansible_facts.default_ipv4.interface }} managed no' diff --git a/playbooks/kayobe-base/overrides.yml.j2 b/playbooks/kayobe-base/overrides.yml.j2 index 7ef429669..55ba472d1 100644 --- a/playbooks/kayobe-base/overrides.yml.j2 +++ b/playbooks/kayobe-base/overrides.yml.j2 @@ -1,3 +1,7 @@ --- # Test support for not escalating privileges kayobe_control_host_become: "{{ kayobe_control_host_become }}" + +# Disable external network connectivity check in CI. We see random failures +# pinging 8.8.8.8. +nc_skip_external_net: true diff --git a/playbooks/kayobe-overcloud-base/overrides.yml.j2 b/playbooks/kayobe-overcloud-base/overrides.yml.j2 index c08a83e5b..913b847e6 100644 --- a/playbooks/kayobe-overcloud-base/overrides.yml.j2 +++ b/playbooks/kayobe-overcloud-base/overrides.yml.j2 @@ -65,3 +65,9 @@ kolla_base_distro: "{% raw %}{{ 'rocky' if os_distribution == 'centos' else os_d # Support overriding container_engine container_engine: "{{ container_engine }}" + +# Deploy a hello-world container. +controller_containers: + hello-world: + image: docker.io/library/hello-world + tag: latest diff --git a/playbooks/kayobe-overcloud-base/run.yml b/playbooks/kayobe-overcloud-base/run.yml index 23ad0ba3d..0c7820d5c 100644 --- a/playbooks/kayobe-overcloud-base/run.yml +++ b/playbooks/kayobe-overcloud-base/run.yml @@ -4,6 +4,7 @@ KAYOBE_CONFIG_SOURCE_PATH: "{{ kayobe_config_src_dir }}" KAYOBE_OVERCLOUD_GENERATE_CERTIFICATES: "{{ tls_enabled | ternary(1, 0) }}" KAYOBE_VAULT_PASSWORD: 'test-password' + KAYOBE_DEPLOY_CUSTOM_CONTAINER: "{{ deploy_custom_container | default(false) | ternary(1, 0) }}" # TODO(mgoddard): Remove this when libvirt on host is used by default. TENKS_CONFIG_PATH: "dev/tenks-deploy-config-compute{% if tls_enabled %}-libvirt-on-host{% endif %}.yml" tasks: @@ -12,6 +13,12 @@ cmd: "{{ kayobe_src_dir }}/dev/overcloud-deploy.sh &> {{ logs_dir }}/ansible/overcloud-deploy" executable: /bin/bash + - name: Check that hello-world custom container was deployed + shell: + cmd: "sudo {{ container_engine | default('docker') }} ps -a | grep hello-world" + executable: /bin/bash + when: deploy_custom_container | default(false) + # Check that passwords are Vault encrypted. - name: View passwords.yml using Ansible Vault vars: @@ -64,7 +71,7 @@ # that aren't deployed in this scenario. cmd: > source {{ kayobe_src_dir }}/dev/environment-setup.sh && - kayobe network connectivity check --limit overcloud + KAYOBE_ENVIRONMENT=aio-network-connectivity kayobe network connectivity check --limit overcloud &> {{ logs_dir }}/ansible/network-connectivity-check executable: /bin/bash - name: Perform database backup diff --git a/releasenotes/notes/add-support-for-watcher-custom-config-files-01ebecc4feb232db.yaml b/releasenotes/notes/add-support-for-watcher-custom-config-files-01ebecc4feb232db.yaml new file mode 100644 index 000000000..2f8fa291a --- /dev/null +++ b/releasenotes/notes/add-support-for-watcher-custom-config-files-01ebecc4feb232db.yaml @@ -0,0 +1,4 @@ +--- +features: + - Adds support for custom Watcher configuration via ``watcher.conf`` and + ``watcher/*`` files. diff --git a/releasenotes/notes/ansible-broken-conditionals-deprecation-7a0713c08d8a0a3d.yaml b/releasenotes/notes/ansible-broken-conditionals-deprecation-7a0713c08d8a0a3d.yaml index 36a2b6765..b9cc46fc1 100644 --- a/releasenotes/notes/ansible-broken-conditionals-deprecation-7a0713c08d8a0a3d.yaml +++ b/releasenotes/notes/ansible-broken-conditionals-deprecation-7a0713c08d8a0a3d.yaml @@ -1,7 +1,7 @@ --- deprecations: - | - Kayobe currently ships with ``ANSIBLE_ALLOW_BROKEN_CONDITIONALS` enabled by + Kayobe currently ships with ``ANSIBLE_ALLOW_BROKEN_CONDITIONALS`` enabled by default. This will be removed in the 2026.2 cycle. Please check the Ansible output of any custom playbooks for deprecation warnings related to this setting and update the playbooks accordingly. You can set diff --git a/releasenotes/notes/deploy-more-containers-7799f9cfd98da4f3.yaml b/releasenotes/notes/deploy-more-containers-7799f9cfd98da4f3.yaml new file mode 100644 index 000000000..97e7e23e0 --- /dev/null +++ b/releasenotes/notes/deploy-more-containers-7799f9cfd98da4f3.yaml @@ -0,0 +1,21 @@ +--- +features: + - | + Extends the seed's "custom containers" feature to support deploying + containers on infrastructure VMs, overcloud and Ansible control hosts. +deprecations: + - | + The tags ``seed-deploy-containers`` and ``seed-manage-containers`` are + deprecated in favour of the more universal ``manage-containers``. They have + been kept for backward compatibility, but will be removed in the Hibiscus + release. + - | + The variable ``seed_deploy_containers_registry_attempt_login`` has + been renamed to ``seed_manage_containers_registry_attempt_login`` and the + deprecated variable will subsequently be removed in the Hibiscus release. + - | + The variables ``deploy_containers_registry_attempt_login`` and + ``deploy_containers_docker_api_timeout`` have been renamed to + ``manage_containers_registry_attempt_login`` and + ``manage_containers_docker_api_timeout`` respectively. The old variable + names are deprecated and will be removed in the Hibiscus release. diff --git a/requirements.yml b/requirements.yml index 352609203..6cdba6264 100644 --- a/requirements.yml +++ b/requirements.yml @@ -2,9 +2,9 @@ collections: - name: https://opendev.org/openstack/ansible-collection-kolla type: git - version: master + version: stable/2026.1 - name: community.docker - version: 5.1.0 + version: 5.2.0 - name: community.network version: 5.1.0 - name: dellemc.os6 @@ -31,9 +31,9 @@ roles: version: 2.0.2 - src: jriguera.configdrive # There are no versioned releases of this role. - version: c6da1f29d6c1d8d5e0f9f0d2dd2d4dfb1973e62d + version: ebf31eee91056a8fcc71a304ff50b014909cf4ca - src: MichaelRigart.interfaces - version: v1.16.1 + version: v1.17.0 - src: mrlesmithjr.chrony version: v0.2.0 - src: mrlesmithjr.manage_lvm @@ -51,7 +51,7 @@ roles: - src: stackhpc.libvirt-host version: v1.15.1 - src: stackhpc.libvirt-vm - version: v1.16.3 + version: v1.16.4 - src: stackhpc.luks version: 0.4.4 - src: stackhpc.os-ironic-state diff --git a/roles/kayobe-diagnostics/files/get_logs.sh b/roles/kayobe-diagnostics/files/get_logs.sh index 267563523..29d943514 100644 --- a/roles/kayobe-diagnostics/files/get_logs.sh +++ b/roles/kayobe-diagnostics/files/get_logs.sh @@ -41,11 +41,11 @@ copy_bifrost_logs() { } copy_logs() { - cp -rnL /var/log/kolla/* ${LOG_DIR}/kolla/ + cp -rL --update=none /var/log/kolla/* ${LOG_DIR}/kolla/ if [[ -d ${CONFIG_DIR} ]]; then - cp -rnL ${CONFIG_DIR}/etc/kayobe/* ${LOG_DIR}/kayobe_configs - cp -rnL ${CONFIG_DIR}/etc/kolla/* ${LOG_DIR}/kolla_configs - cp -rnL /etc/kolla/* ${LOG_DIR}/kolla_node_configs + cp -rL --update=none ${CONFIG_DIR}/etc/kayobe/* ${LOG_DIR}/kayobe_configs + cp -rL --update=none ${CONFIG_DIR}/etc/kolla/* ${LOG_DIR}/kolla_configs + cp -rL --update=none /etc/kolla/* ${LOG_DIR}/kolla_node_configs # Don't save the IPA images. rm ${LOG_DIR}/kayobe_configs/kolla/config/ironic/ironic-agent.{kernel,initramfs} rm ${LOG_DIR}/kolla_configs/config/ironic/ironic-agent.{kernel,initramfs} @@ -54,8 +54,8 @@ copy_logs() { fi if [[ -n ${PREVIOUS_CONFIG_DIR} ]] && [[ -d ${PREVIOUS_CONFIG_DIR} ]]; then mkdir -p ${LOG_DIR}/previous_{kayobe,kolla}_configs - cp -rnL ${PREVIOUS_CONFIG_DIR}/etc/kayobe/* ${LOG_DIR}/previous_kayobe_configs - cp -rnL ${PREVIOUS_CONFIG_DIR}/etc/kolla/* ${LOG_DIR}/previous_kolla_configs + cp -rL --update=none ${PREVIOUS_CONFIG_DIR}/etc/kayobe/* ${LOG_DIR}/previous_kayobe_configs + cp -rL --update=none ${PREVIOUS_CONFIG_DIR}/etc/kolla/* ${LOG_DIR}/previous_kolla_configs # NOTE: we can't save node configs in /etc/kolla for the pervious # release since they'll have been overwritten at this point. # Don't save the IPA images. @@ -64,10 +64,10 @@ copy_logs() { fi if [[ -d /opt/kayobe/etc/kolla ]]; then - cp -rnL /opt/kayobe/etc/kolla/* ${LOG_DIR}/kolla_build_configs/ + cp -rL --update=none /opt/kayobe/etc/kolla/* ${LOG_DIR}/kolla_build_configs/ fi - cp -rvnL /var/log/* ${LOG_DIR}/system_logs/ + cp -rvL --update=none /var/log/* ${LOG_DIR}/system_logs/ if [[ -x "$(command -v journalctl)" ]]; then journalctl --no-pager > ${LOG_DIR}/system_logs/syslog.txt diff --git a/tox.ini b/tox.ini index 86f549130..6f173d62d 100644 --- a/tox.ini +++ b/tox.ini @@ -19,7 +19,7 @@ setenv = OS_TEST_TIMEOUT=60 ANSIBLE_VERBOSITY=3 deps = - -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} + -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2026.1} -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt commands = stestr run {posargs} @@ -42,7 +42,7 @@ commands = [testenv:venv] deps = - -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} + -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2026.1} -r{toxinidir}/test-requirements.txt -r{toxinidir}/doc/requirements.txt commands = {posargs} @@ -60,7 +60,7 @@ commands = [testenv:molecule] deps = - -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} + -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2026.1} -r{toxinidir}/requirements.txt -r{toxinidir}/molecule-requirements.txt commands = @@ -130,7 +130,7 @@ commands = [testenv:docs] deps = - -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} + -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/2026.1} -r{toxinidir}/doc/requirements.txt commands = rm -rf doc/build/html diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml index 3157ef5dc..2b889a470 100644 --- a/zuul.d/jobs.yaml +++ b/zuul.d/jobs.yaml @@ -71,11 +71,19 @@ required-projects: # Include kayobe to ensure other projects can use this job. - name: openstack/ansible-collection-kolla + # TODO(wszumski): Remove when kayobe stable/2026.1 exists. + override-checkout: stable/2026.1 - name: openstack/kayobe - name: openstack/kayobe-config-dev - name: openstack/kolla + # TODO(wszumski): Remove when kayobe stable/2026.1 exists. + override-checkout: stable/2026.1 - name: openstack/kolla-ansible + # TODO(wszumski): Remove when kayobe stable/2026.1 exists. + override-checkout: stable/2026.1 - name: openstack/requirements + # TODO(wszumski): Remove when kayobe stable/2026.1 exists. + override-checkout: stable/2026.1 - name: openstack/tenks irrelevant-files: - ^\..+ @@ -135,11 +143,31 @@ name: kayobe-ansible-control-host-configure-rocky10 parent: kayobe-ansible-control-host-configure-base nodeset: kayobe-rocky10 + vars: + deploy_custom_container: true + +- job: + name: kayobe-ansible-control-host-configure-rocky10-podman + parent: kayobe-ansible-control-host-configure-base + nodeset: kayobe-rocky10 + vars: + deploy_custom_container: true + container_engine: podman - job: name: kayobe-ansible-control-host-configure-ubuntu-noble parent: kayobe-ansible-control-host-configure-base nodeset: kayobe-ubuntu-noble + vars: + deploy_custom_container: true + +- job: + name: kayobe-ansible-control-host-configure-ubuntu-noble-podman + parent: kayobe-ansible-control-host-configure-base + nodeset: kayobe-ubuntu-noble + vars: + deploy_custom_container: true + container_engine: podman - job: name: kayobe-overcloud-base @@ -348,6 +376,7 @@ vars: fail2ban_enabled: true ci_network_engine: nmstate + deploy_custom_container: true - job: name: kayobe-overcloud-host-configure-ubuntu-noble @@ -355,6 +384,7 @@ nodeset: kayobe-ubuntu-noble vars: fail2ban_enabled: true + deploy_custom_container: true - job: name: kayobe-seed-upgrade-base diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml index e2c6f3e44..6a8217146 100644 --- a/zuul.d/project.yaml +++ b/zuul.d/project.yaml @@ -16,7 +16,9 @@ - kayobe-tox-ansible - kayobe-tox-molecule - kayobe-ansible-control-host-configure-rocky10 + - kayobe-ansible-control-host-configure-rocky10-podman - kayobe-ansible-control-host-configure-ubuntu-noble + - kayobe-ansible-control-host-configure-ubuntu-noble-podman - kayobe-infra-vm-rocky10 - kayobe-infra-vm-ubuntu-noble - kayobe-overcloud-host-configure-rocky10