# Get a client using -v /home/tripleo-admin/ceph_config:/etc/ceph:z as input - name: Get ceph_cli ansible.builtin.include_tasks: ceph_cli.yaml vars: ceph_config_home: "{{ ceph_config_tmp_client_home }}" ceph_fsid: "{{ mon_dump.fsid }}" ceph_cluster: ceph - name: Migrate mon when: debug | default(true) ansible.builtin.debug: msg: "Migrate mon: {{ cur_mon }} to node: {{ target_node }}" - name: MON - Get current mon IP address from node_map override when: node_map is defined ansible.builtin.set_fact: mon_ipaddr: "{{ mon_ip | trim | ansible.utils.ipaddr }}" vars: mon_ip: |- {% for mon in node_map %} {% if mon.hostname == cur_mon %} {{ mon.ip }} {% endif %} {% endfor %} - name: MON - Check mons quorum become: true ansible.builtin.command: "{{ ceph_cli }} -s -f json" register: monmap until: (monmap.stdout | from_json | community.general.json_query('monmap.num_mons') | int) >= ((decomm_nodes |default([]) | length | int) | default(3)) retries: 100 delay: "{{ ceph_retry_delay }}" tags: - ceph_mon_quorum # Backup data - name: Backup data for client purposes when: cur_mon != client_node ansible.builtin.include_tasks: backup.yaml vars: host: "{{ cur_mon }}" tags: - ceph_backup # Before draining the current node, migrate the active mgr on a different # _admin host - name: Migrate Ceph mgr from the current node if required block: - name: MON - Get the current active mgr become: true ansible.builtin.command: "{{ ceph_cli }} mgr stat -f json" register: mgr - name: MON - Load mgr data ansible.builtin.set_fact: mgr: "{{ mgr.stdout | from_json }}" - name: Print active mgr when: debug | default(false) ansible.builtin.debug: msg: "Active mgr: {{ mgr.active_name }}" - name: Fail mgr if active in the current node ansible.builtin.include_tasks: fail_mgr.yaml when: - mgr.active_name | length > 0 - mgr.active_name | regex_search(cur_mon | split('.') | first) or mgr.active_name | regex_search(target_node | split('.') | first) # Drain and rm the cur_mon from the Ceph cluster - name: MON - Drain and rm --force the cur_mon host # when: cur_mon in decomm_nodes ansible.builtin.include_tasks: drain.yaml vars: host: "{{ cur_mon }}" tags: - ceph_drain - name: MON - Get current mon IP address when: - mon_ipaddr is not defined - discover_mons | bool | default(true) ansible.builtin.set_fact: mon_ipaddr: "{{ mon_ip | split(':') | first | ansible.utils.ipaddr }}" vars: mon_ip: |- {% for mon in mon_dump.mons %} {% if mon.name == cur_mon.split('.')[0] %} {{ mon.addr }} {% endif %} {% endfor %} - name: MON - Migrate the mon ip address from src to target node # if no mon addr, this variable is False and the whole block is skipped # because there's no network related action that should be performed when: - mon_ipaddr | default('') - ceph_keep_mon_ipaddr | default(false) ansible.builtin.include_tasks: network.yaml vars: src_node: "{{ cur_mon }}" dest_node: "{{ target_node }}" manual_migration: true - name: Redeploy MON when: ceph_keep_mon_ipaddr | default(false) become: true block: - name: Unmanage mons become: true ceph_mkspec: service_type: mon cluster: ceph apply: true label: "mon" render_path: "{{ ceph_spec_render_dir }}" unmanaged: true register: spc environment: CEPH_CONTAINER_IMAGE: "{{ ceph_container }}" CEPH_CONTAINER_BINARY: "{{ ceph_container_cli }}" CEPH_CONF: "{{ ceph_config_tmp_client_home }}" notify: restart mgr - name: Print the resulting spec when: debug | default(false) ansible.builtin.debug: msg: "{{ spc }}" # Check if a mon exists in the target node and remove it - name: MON - Get tmp mon ansible.builtin.command: "{{ ceph_cli }} orch ps --daemon_type mon --daemon_id {{ daemon_id }} -f json" register: psmon vars: daemon_id: "{{ target_node.split('.')[0] }}" - name: MON - Delete the running mon when: psmon.stdout | from_json | community.general.json_query('[*].daemon_name') | length > 0 ansible.builtin.command: "{{ ceph_cli }} orch daemon rm mon.{{ target_node.split('.')[0] }} --force" until: '"Removed" in rmmon.stdout' register: rmmon retries: 30 delay: "{{ ceph_retry_delay }}" loop_control: label: "MON - Get tmp mon" notify: restart mgr - name: MON - Wait for the current mon to be deleted ansible.builtin.pause: seconds: "{{ ceph_wait_mon_timeout }}" - name: MON - Redeploy mon on {{ target_node }} when: debug | default(false) ansible.builtin.debug: msg: "{{ ceph_cli }} orch daemon add mon {{ target_node }}:{{ mon_ipaddr }}" - name: MON - Redeploy mon on {{ target_node }} ansible.builtin.command: "{{ ceph_cli }} orch daemon add mon {{ target_node }}:{{ mon_ipaddr }}" notify: restart mgr - name: MON - Wait for the spec to be updated ansible.builtin.pause: seconds: "{{ ceph_wait_mon_timeout }}" - name: MON - Check mons quorum become: true ansible.builtin.command: "{{ ceph_cli }} -s -f json" register: monmap until: (monmap.stdout | from_json | community.general.json_query('monmap.num_mons') | int) >= ((decomm_nodes |default([]) | length | int) | default(3)) retries: 100 delay: "{{ ceph_retry_delay }}" tags: - ceph_mon_quorum # Post actions: refresh mgr data, reconfigure osds - name: MON - refresh cephadm info - fail ceph mgr and refresh osd config become: true block: - name: reconfig osds ansible.builtin.command: "{{ ceph_cli }} orch reconfig osd.default_drive_group " - name: force-fail ceph mgr ansible.builtin.include_tasks: fail_mgr.yaml - name: MON - Manage mons # root privileges required to run cephadm # and apply the new spec become: true ceph_mkspec: service_type: mon cluster: ceph apply: true label: "mon" render_path: "{{ ceph_spec_render_dir }}" unmanaged: false environment: CEPH_CONTAINER_IMAGE: "{{ ceph_container }}" CEPH_CONTAINER_BINARY: "{{ ceph_container_cli }}" CEPH_CONF: "{{ ceph_config_tmp_client_home }}" notify: restart mgr # Wait for the redeploy to finish before moving to the next stage - name: MON - wait daemons ansible.builtin.include_tasks: wait_daemons.yaml vars: daemon: mon daemon_id: "{{ target_node.split('.')[0] }}"