heat_template_version: wallaby description: > OpenStack containerized Redis services parameters: ContainerRedisImage: description: image type: string tags: - role_specific ContainerRedisConfigImage: description: The container image to use for the redis config_volume type: string tags: - role_specific ClusterCommonTag: default: false description: When set to false, a pacemaker service is configured to use a floating tag for its container image name, e.g. 'REGISTRY/NAMESPACE/IMAGENAME:pcmklatest'. When set to true, the service uses a floating prefix as well, e.g. 'cluster.common.tag/IMAGENAME:pcmklatest'. type: boolean ClusterFullTag: default: true description: When set to true, the pacemaker service uses a fully constant tag for its container image name, e.g. 'cluster.common.tag/SERVICENAME:pcmklatest'. type: boolean EndpointMap: default: {} description: Mapping of service endpoint -> protocol. Typically set via parameter_defaults in the resource registry. type: json ServiceData: default: {} description: Dictionary packing service data type: json ServiceNetMap: default: {} description: Mapping of service_name -> network name. Typically set via parameter_defaults in the resource registry. Use parameter_merge_strategies to merge it with the defaults. type: json RoleName: default: '' description: Role name on which the service is applied type: string RoleParameters: default: {} description: Parameters specific to the role type: json ConfigDebug: default: false description: Whether to run config management (e.g. Puppet) in debug mode. type: boolean EnableInternalTLS: type: boolean default: false RedisIPv6: default: false description: Enable IPv6 in Redis type: boolean ContainerCli: type: string default: 'podman' description: CLI tool used to manage containers. constraints: - allowed_values: ['docker', 'podman'] DeployIdentifier: default: '' type: string description: > Setting this to a unique value will re-run any deployment tasks which perform configuration on a Heat stack-update. parameter_groups: - label: deprecated description: | The following parameters are deprecated and will be removed. They should not be relied on for new deployments. If you have concerns regarding deprecated parameters, please contact the TripleO development team on IRC or the OpenStack mailing list. parameters: - RedisIPv6 conditions: is_ipv6: equals: - {get_param: [ServiceData, net_ip_version_map, {get_param: [ServiceNetMap, RedisNetwork]}]} - 6 resources: ContainersCommon: type: ../containers-common.yaml RedisBase: type: ./redis-container-puppet.yaml properties: EndpointMap: {get_param: EndpointMap} ServiceData: {get_param: ServiceData} ServiceNetMap: {get_param: ServiceNetMap} RoleName: {get_param: RoleName} RoleParameters: {get_param: RoleParameters} RoleParametersValue: type: OS::Heat::Value properties: type: json value: map_replace: - map_replace: - ContainerRedisImage: ContainerRedisImage ContainerRedisConfigImage: ContainerRedisConfigImage - values: {get_param: [RoleParameters]} - values: ContainerRedisImage: {get_param: ContainerRedisImage} ContainerRedisConfigImage: {get_param: ContainerRedisConfigImage} outputs: role_data: description: Role data for the Redis API role. value: service_name: redis firewall_rules: '108 redis-bundle': dport: - 3124 - 6379 - 26379 config_settings: map_merge: - {get_attr: [RedisBase, role_data, config_settings]} - redis::service_manage: false redis::notify_service: false redis::managed_by_cluster_manager: true tripleo::profile::pacemaker::database::redis_bundle::redis_docker_image: &redis_image_pcmklatest if: - {get_param: ClusterFullTag} - "cluster.common.tag/redis:pcmklatest" - yaql: data: if: - {get_param: ClusterCommonTag} - yaql: data: {get_attr: [RoleParametersValue, value, ContainerRedisImage]} expression: concat("cluster.common.tag/", $.data.rightSplit(separator => "/", maxSplits => 1)[1]) - {get_attr: [RoleParametersValue, value, ContainerRedisImage]} expression: concat($.data.rightSplit(separator => ":", maxSplits => 1)[0], ":pcmklatest") tripleo::profile::pacemaker::database::redis_bundle::control_port: 3124 tripleo::profile::pacemaker::database::redis_bundle::container_backend: {get_param: ContainerCli} # starting from pcs-0.10.14-6 enforces validations but this doesn't work when running # outside the respective containers. we need to use --force to overcome this. tripleo::profile::pacemaker::database::redis_bundle::force_ocf: true tripleo::stunnel::manage_service: false tripleo::stunnel::foreground: 'yes' tripleo::profile::pacemaker::database::redis_bundle::tls_proxy_bind_ip: str_replace: template: "%{hiera('$NETWORK')}" params: $NETWORK: {get_param: [ServiceNetMap, RedisNetwork]} tripleo::profile::pacemaker::database::redis_bundle::tls_proxy_fqdn: str_replace: template: "%{hiera('fqdn_$NETWORK')}" params: $NETWORK: {get_param: [ServiceNetMap, RedisNetwork]} tripleo::profile::pacemaker::database::redis_bundle::tls_proxy_port: 6379 tripleo::profile::pacemaker::database::redis::tls_proxy_bind_ip: str_replace: template: "%{hiera('$NETWORK')}" params: $NETWORK: {get_param: [ServiceNetMap, RedisNetwork]} tripleo::profile::pacemaker::database::redis::tls_proxy_fqdn: str_replace: template: "%{hiera('fqdn_$NETWORK')}" params: $NETWORK: {get_param: [ServiceNetMap, RedisNetwork]} tripleo::profile::pacemaker::database::redis::tls_proxy_port: 6379 - if: - {get_param: EnableInternalTLS} - redis::extra_config_file: "/etc/redis-tls.conf" tripleo::profile::pacemaker::database::redis_bundle::extra_config_file: "/etc/redis-tls.conf" tripleo::profile::pacemaker::database::redis_bundle::tls_tunnel_base_port: 6660 tripleo::profile::pacemaker::database::redis_bundle::tls_tunnel_local_name: if: - is_ipv6 - '::1' - '127.0.0.1' service_config_settings: {get_attr: [RedisBase, role_data, service_config_settings]} # BEGIN DOCKER SETTINGS puppet_config: config_volume: 'redis' # NOTE: we need the exec tag to copy /etc/redis.conf.puppet to # /etc/redis.conf # https://github.com/arioch/puppet-redis/commit/1c004143223e660cbd433422ff8194508aab9763 puppet_tags: 'exec' step_config: | Exec <| title == 'systemd-reload-redis' |> { unless => 'true' } include tripleo::profile::pacemaker::database::redis_bundle config_image: &redis_config_image {get_attr: [RoleParametersValue, value, ContainerRedisConfigImage]} kolla_config: /var/lib/kolla/config_files/redis.json: command: /usr/sbin/pacemaker_remoted config_files: - dest: /etc/libqb/force-filesystem-sockets source: /dev/null owner: root perm: '0644' - source: "/var/lib/kolla/config_files/src/*" dest: "/" merge: true preserve_properties: true optional: true permissions: - path: /run/redis owner: redis:redis recurse: true - path: /var/lib/redis owner: redis:redis recurse: true - path: /var/log/redis owner: redis:redis recurse: true /var/lib/kolla/config_files/redis_tls_proxy.json: command: # Note: kolla doesn't process string arguments as expected, # so use a bash idiom to achieve the same result str_replace: template: bash -c $* -- eval /wait-port-and-run.sh $(hiera fqdn_$NETWORK) 6379 stunnel /etc/stunnel/stunnel.conf params: $NETWORK: {get_param: [ServiceNetMap, RedisNetwork]} config_files: - source: "/var/lib/kolla/config_files/src/*" dest: "/" merge: true preserve_properties: true - source: "/var/lib/kolla/config_files/src-tls/*" dest: "/" merge: true optional: true preserve_properties: true permissions: - path: /etc/pki/tls/certs/redis.crt owner: root:root perm: '0600' optional: true - path: /etc/pki/tls/private/redis.key owner: root:root perm: '0600' optional: true container_config_scripts: {get_attr: [ContainersCommon, container_config_scripts]} docker_config: step_1: if: - {get_param: EnableInternalTLS} - redis_tls_proxy: start_order: 0 image: {get_attr: [RoleParametersValue, value, ContainerRedisImage]} net: host user: root restart: always volumes: list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/kolla/config_files/redis_tls_proxy.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/config-data/puppet-generated/redis:/var/lib/kolla/config_files/src:ro - /etc/pki/tls/certs/redis.crt:/var/lib/kolla/config_files/src-tls/etc/pki/tls/certs/redis.crt:ro - /etc/pki/tls/private/redis.key:/var/lib/kolla/config_files/src-tls/etc/pki/tls/private/redis.key:ro - /var/lib/container-config-scripts/wait-port-and-run.sh:/wait-port-and-run.sh:ro environment: KOLLA_CONFIG_STRATEGY: COPY_ALWAYS metadata_settings: get_attr: [RedisBase, role_data, metadata_settings] external_deploy_tasks: {get_attr: [RedisBase, role_data, external_deploy_tasks]} host_prep_tasks: - name: create persistent directories file: path: "{{ item.path }}" state: directory setype: "{{ item.setype }}" mode: "{{ item.mode|default(omit) }}" with_items: - { 'path': /var/lib/redis, 'setype': container_file_t } - { 'path': /var/log/containers/redis, 'setype': container_file_t, 'mode': '0750' } - { 'path': /run/redis, 'setype': container_file_t } - name: ensure /run/redis is present upon reboot copy: dest: /etc/tmpfiles.d/run-redis.conf content: | d /run/redis 0755 root root - - deploy_steps_tasks: list_concat: - get_attr: [RedisBase, role_data, deploy_steps_tasks] - - name: Redis tag container image for pacemaker when: step|int == 1 import_role: name: tripleo_container_tag vars: container_image: {get_attr: [RoleParametersValue, value, ContainerRedisImage]} container_image_latest: *redis_image_pcmklatest - name: Redis HA Wrappers Step when: step|int == 2 block: &redis_puppet_bundle - name: Redis puppet bundle import_role: name: tripleo_ha_wrapper vars: tripleo_ha_wrapper_service_name: redis tripleo_ha_wrapper_resource_name: redis tripleo_ha_wrapper_bundle_name: redis-bundle tripleo_ha_wrapper_resource_state: Slave Master tripleo_ha_wrapper_puppet_config_volume: redis tripleo_ha_wrapper_puppet_execute: 'include ::tripleo::profile::base::pacemaker; include ::tripleo::profile::pacemaker::database::redis_bundle' tripleo_ha_wrapper_puppet_tags: 'pacemaker::resource::bundle,pacemaker::property,pacemaker::resource::ocf,pacemaker::constraint::order,pacemaker::constraint::colocation' tripleo_ha_wrapper_puppet_debug: {get_param: ConfigDebug} tripleo_ha_wrapper_config_suffix: .previous_run external_update_tasks: list_concat: - get_attr: [RedisBase, role_data, external_update_tasks] - - when: step|int == 1 tags: ha_image_update block: - block: &redis_container_image_facts - name: Get redis image from pacemaker become: true register: xmllint_pcmk_redis_image # retrieve info even when pacemaker is stopped shell: 'xmllint --xpath "string(//bundle[@id=''redis-bundle'']/podman/@image)" /var/lib/pacemaker/cib/cib.xml' - name: Get container redis image set_fact: # container image to use for deployment redis_image: {get_attr: [RoleParametersValue, value, ContainerRedisImage]} # pacemaker bundle image name to use for deployment redis_image_latest: *redis_image_pcmklatest # image currently configured in pacemaker bundle pcmk_redis_image: '{{xmllint_pcmk_redis_image.stdout}}' delegate_to: '{{ (groups["redis"] | difference(groups["excluded_overcloud"]))[0] }}' - name: redis temporary pacemaker container tag in case of image switch become: true import_role: name: tripleo_ha_image_update vars: tripleo_ha_image_update_node_names: '{{ groups["redis"] | difference(groups["excluded_overcloud"]) }}' tripleo_ha_image_update_bundle: redis-bundle tripleo_ha_image_update_new_image: '{{redis_image_latest}}' tripleo_ha_image_update_old_image: '{{pcmk_redis_image}}' when: - (pcmk_redis_image != "") - (pcmk_redis_image != redis_image_latest) update_tasks: - block: *redis_container_image_facts when: (step|int == 0 or step|int == 2) - name: Check for update of redis container image name when: step|int == 0 assert: that: pcmk_redis_image == redis_image_latest fail_msg: "redis image change detected, run overcloud external-update --tags ha_image_update first" - name: redis_pacemaker_puppet_tmpfile_cleanup when: step|int == 1 block: &redis_pacemaker_puppet_tmpfile_cleanup - name: Clean old tmpfile configuration file: path: /etc/tmpfiles.d/var-run-redis.conf state: absent - name: Tear-down non-HA redis container when: - step|int == 1 block: &redis_teardown_nonha - name: Remove non-HA redis container include_role: name: tripleo_container_rm vars: tripleo_container_cli: "{{ container_cli }}" tripleo_containers_to_rm: - redis - name: Redis fetch and retag container image for pacemaker when: step|int == 2 block: &redis_fetch_retag_container_tasks - name: Retag pcmklatest to latest redis image include_role: name: tripleo_container_tag vars: container_image: "{{redis_image}}" container_image_latest: "{{redis_image_latest}}" post_update_tasks: - name: Redis bundle post update when: step|int == 1 block: *redis_puppet_bundle vars: tripleo_ha_wrapper_minor_update: true upgrade_tasks: - name: redis_pacemaker_puppet_tmpfile_cleanup when: step|int == 1 block: *redis_pacemaker_puppet_tmpfile_cleanup - name: Tear-down non-HA redis container when: - step|int == 0 block: *redis_teardown_nonha - name: Prepare switch of redis image name when: - step|int == 0 block: - name: Get redis image id currently used by pacemaker shell: "pcs resource config redis-bundle | grep -Eo 'image=[^ ]+' | awk -F= '{print $2;}'" register: redis_image_current_res failed_when: false - name: Image facts for redis set_fact: redis_image_latest: *redis_image_pcmklatest redis_image_current: "{{redis_image_current_res.stdout}}" - name: Temporarily tag the current redis image id with the upgraded image name import_role: name: tripleo_container_tag vars: container_image: "{{redis_image_current}}" container_image_latest: "{{redis_image_latest}}" pull_image: false when: - redis_image_current != '' - redis_image_current != redis_image_latest # Steps are separate playbook runs and we need to keep state - name: Create redis retag statefile file: path: '/var/lib/tripleo/redis_needs_retag' state: touch when: - redis_image_current != '' - redis_image_current != redis_image_latest - name: Update redis-bundle pcs resource bundle for new container image when: - step|int == 1 block: - name: Set upgrade redis facts set_fact: is_redis_bootstrap_node: "{{redis_short_bootstrap_node_name|lower == ansible_facts['hostname']|lower}}" - name: Check for redis retag statefile stat: path: '/var/lib/tripleo/redis_needs_retag' register: redis_retag_state_file - name: Update redis-bundle pcs resource bundle for new container image when: - step|int == 1 - is_redis_bootstrap_node|bool - redis_retag_state_file.stat.exists|bool block: - name: Disable the redis cluster resource before container upgrade pacemaker_resource: resource: redis-bundle state: disable wait_for_resource: true register: output retries: 5 until: output.rc == 0 - name: Move redis logging to /var/log/containers block: - name: Check redis logging configuration in pacemaker command: cibadmin --query --xpath "//storage-mapping[@id='redis-log' and @source-dir='/var/log/containers/redis']" failed_when: false register: redis_logs_moved - name: Change redis logging configuration in pacemaker # rc == 6 means the configuration doesn't exist in the CIB when: redis_logs_moved.rc == 6 block: - name: Remove old bind mount for logging in the redis bundle command: pcs resource bundle update redis-bundle storage-map remove redis-log - name: Add a bind mount for logging in the redis bundle command: pcs resource bundle update redis-bundle storage-map add id=redis-log source-dir=/var/log/containers/redis target-dir=/var/log/redis options=rw - name: Update the redis bundle to use the new container image name command: "pcs resource bundle update redis-bundle container image={{redis_image_latest}}" - name: Enable the redis cluster resource pacemaker_resource: resource: redis-bundle state: enable wait_for_resource: true register: output retries: 5 until: output.rc == 0 - name: Check for redis retag statefile when: - step|int == 3 stat: path: '/var/lib/tripleo/redis_needs_retag' register: redis_retag_state_file - name: Retag redis-bundle container image when: - step|int == 3 - redis_retag_state_file.stat.exists|bool block: - name: Disable the redis cluster resource before container upgrade pacemaker_resource: resource: redis-bundle state: disable wait_for_resource: true register: output retries: 5 until: output.rc == 0 - name: Retag the pacemaker image if containerized block: - block: *redis_container_image_facts - block: *redis_fetch_retag_container_tasks - name: Enable the redis-bundle cluster resource pacemaker_resource: resource: redis-bundle state: enable wait_for_resource: true register: output retries: 5 until: output.rc == 0 - name: Remove redis retag statefile file: path: '/var/lib/tripleo/redis_needs_retag' state: absent