#!/bin/bash
# Default Values
#set -x
source /usr/share/ceph-tools/_ct-common

help_msg () {
    printf """
usage: $0 [-h] $CT_HELP_DESCR ...

Description         Emptying an OSD server

Optional
$CT_HELP_MSG

Example
  $0 $CT_HELP_EXAMPLE
"""
}

osd_noexist(){
  ret=$(ceph osd crush dump |jq '.devices[] | select(.id=='${1}')'|wc -l)
  return $ret
}

check_balancer(){
  # Test balancer status
  [ "$(ceph balancer status | jq .active)" == "true" ]
}

check_flag(){
  # Test flag
  # Param 1: flag to test
  [ "$(ceph -s | grep flags | grep ${1} | wc -l)" -eq "1" ]
}

check_osd_down(){
  # Test if OSD down
  # Param 1: osdid
  [ "$(ceph osd tree -f json| jq '.nodes[]|select(.id=='${1}').status')" == "\"down\"" ]
}

check_osd_out(){
  # Test if OSD out
  # Param 1: osdid
  [ "$(ceph osd tree -f json| jq '.nodes[]|select(.id=='${1}').reweight')" -eq "0" ]
}

check_osd_config(){
  # Test if OSD config
  # Param 1: key to test
  # Param 2: value to test
  [ "$(ct-osd-config -g ${1} 2>/dev/null | head -1 | awk '{print $3}')" == "\"${2}\"" ]
}

check_osd_purged(){
  # Test if OSD out
  # Param 1: osdid
  HOST=$(hostname -s)
  [ "$(ceph osd crush ls $HOST | grep -e"^osd.${1}$" |wc -l)" -eq "0" ]
}

check_osd_disabled(){
  # Test if OSD service is disable
  # Param 1: osdid
  systemctl is-enabled ceph-osd@${1}.service 2>&1 >/dev/null
}

check_osd_zapped(){
  # Test if OSD service is zapped
  # Param 1: osdid
  ! ceph-volume lvm list | grep " osd id"| grep $i
}

ct_help $@
shift $?
# Beginning of operations

ceph balancer off
while check_balancer; do sleep 1;done

ceph osd set noin
while ! check_flag "noin"; do sleep 1; done
ceph osd set noout
while ! check_flag "noout"; do sleep 1; done

OSDLIST=$(ceph osd tree-from $(hostname -s) | sed '1,2d' | awk '{print $1}')
for i in $OSDLIST ;do
  ct_healthy_wait
  echo "Set osd.${i} DOWN"
  systemctl stop ceph-osd@${i}.service
  while ! check_osd_down $i; do sleep 2; done
  ceph osd out $i
  while ! check_osd_out $i; do sleep 2; done
  ct-upmap-remapped | sh 2> /dev/null
done


ct_healthy_wait
echo "Set balancer On"
ceph balancer on
while ! check_balancer; do sleep 1; done

ct_healthy_wait

OSDLIST=$(ceph osd tree-from $(hostname -s)| sed '1,2d' |  awk '{print $1}')
for i in $OSDLIST; do
  echo "Disable ceph-osd@${i}.service"
  systemctl disable ceph-osd@${i}.service >/dev/null
  while ! check_osd_disabled ${i}; do sleep 2; done
done

for i in $(ls /etc/systemd/system/ceph-osd@*.service); do 
  rm -f /etc/systemd/system/$i 2>/dev/null
  while [ -f /etc/systemd/system/$i ]; do sleep 1; done
  rm -rf /etc/systemd/system/$i.service.d 2>/dev/null
  while [ -d /etc/systemd/system/$i.service.d ]; do sleep 1; done
done

ceph osd set norebalance
while ! check_flag "norebalance"; do sleep 1; done

ceph balancer off
while check_balancer; do sleep 1; done

_CT_MAX_BACKFILLS_INIT=$(ct-osd-config -g osd_max_backfills 2>/dev/null | head -1 | awk '{print $3}'|xargs)

ct-osd-config -s osd_max_backfills 1 > /dev/null
sleep 10
check_osd_config osd_max_backfills 1 || ct_logger "osd_max_backfills not set to 1"

for i in $OSDLIST; do
  echo "Set Destroy and purge osd.${i}"
  ceph osd destroy $i --yes-i-really-mean-it
  sleep 2
  ceph osd purge $i --yes-i-really-mean-it
  sleep 2
  check_osd_purged ${i} || ct_notify "OSD.${i} not Purged"
done

sleep 10

echo "Remapped"
for i in {1..3}; do
  ct_cr=$(ct_get_current_remapped)
  if [[ "$ct_cr" -eq "0" ]]; then
    break
  fi
  ct-upmap-remapped | sh 2> /dev/null
  sleep 10
done

ceph osd unset norebalance
while check_flag "norebalance"; do sleep 1; done

ct_healthy_wait 0

for i in $OSDLIST;do
  echo Zap OSD.${i}
  ceph-volume lvm zap --destroy --osd-id $i
  while ! check_osd_zapped; do sleep 2; done
done

ceph balancer on
while ! check_balancer; do sleep 1; done

ct-osd-config -s osd_max_backfills  $_CT_MAX_BACKFILLS_INIT
sleep 10
check_osd_config osd_max_backfills $_CT_MAX_BACKFILLS_INIT || ct_logger "osd_max_backfills not set to ${_CT_MAX_BACKFILLS_INIT}"

ceph osd unset noin
while check_flag "noin"; do sleep 1; done
ceph osd unset noout
while check_flag "noout"; do sleep 1; done

ct_on_exit 0
