#!/bin/bash
# Copyright (c) 2018-2025 m-privacy GmbH
# ao
#
# Last change: 03/Jul/2025, ao

if test -z "$1"
then
	echo "Use: $0 [--nomon|--onlymon] target-hostname node-nr [osd-part [publicnet]]"
	echo "E.g. $0 ceph2 2 /dev/sda4 192.168.111."
	echo "(defaults)"
	echo 'Target node must have private net reachable'
	echo "--nomon: do not create monitor on target"
	echo "--onlymon: only create monitor on target"
	exit 0
fi

CREATEMON=true
ONLYMON=false
if test "$1" = "--nomon"
then
	CREATEMON=false
	shift
elif test "$1" = "--onlymon"
then
	ONLYMON=true
	shift
fi

TARGETHOST="$1"
NODENR="$2"
PART="$3"
test -z "$PART" && PART=/dev/sda4
PUBLIC="$4"
if test -z "$PUBLIC"
then
	PUBLIC="192.168.111."
fi
TARGETIP="$PUBLIC$NODENR"

RED="\033[31;01m"
BLUE="\033[34;01m"
GREEN="\033[32;01m"
MAGENTA="\033[35;01m"
RESET="\033[00m"

if ! ping -c 2 -q "$TARGETIP" > /dev/null
then
	echo "$TARGETIP is unreachable"
	exit $LINENO
fi
echo -e "${MAGENTA}o--> scp $HOME/.ssh/id_ed25519.pub $HOME/.ssh/id_ed25519 $HOME/.ssh/authorized_keys2 root@$TARGETIP:.ssh/${RESET}"
scp -o StrictHostKeyChecking=no "$HOME/.ssh/id_ed25519.pub" "$HOME/.ssh/id_ed25519" "$HOME/.ssh/authorized_keys2" "root@$TARGETIP:.ssh/" || exit $LINENO
echo -e "${MAGENTA}o--> partition check${RESET}"
if ! ssh "root@$TARGETIP" "fdisk -l" | grep -q "$PART"
then
	echo "No partition $PART found on $TARGETIP"
	exit $LINENO
fi
echo ""
echo "Extend cephfs cluster on this system $HOSTNAME to $TARGETHOST/$TARGETIP"
echo -n "OSD bluestore data stored on $PART"
if test "$CREATEMON" = "false"
then
	echo -n ", monitor NOT created"
elif test "$ONLYMON" = "true"
then
	echo -n ", only monitor created"
fi
echo ""
echo "Press return to continue or CTRL-C to exit."
read dummy

if ! host "$TARGETHOST" &>/dev/null
then
	echo "$TARGETIP $TARGETHOST" >>/etc/hosts
fi
echo -e "${MAGENTA}o--> ssh root@$TARGETIP pkill ceph-*${RESET}"
ssh "root@$TARGETIP" "pkill ceph-mon"
ssh "root@$TARGETIP" "pkill ceph-mgr"
ssh "root@$TARGETIP" "pkill ceph-mds"
ssh "root@$TARGETIP" "pkill ceph-osd"
if ssh "root@$TARGETIP" "mount"|grep -q "$PART"
then
	while ssh "root@$TARGETIP" "pgrep ceph-osd >/dev/null"
	do
		sleep 1
	done
	echo -e "${MAGENTA}o--> ssh root@$TARGETIP umount $PART${RESET}"
	ssh "root@$TARGETIP" "umount \"$PART\"" || exit $LINENO
fi
echo -e "${MAGENTA}o--> ssh root@$TARGETIP rm -rf /var/lib/ceph/*/* /etc/ceph/ceph.*.keyring${RESET}"
ssh "root@$TARGETIP" "rm -rf /var/lib/ceph/*/* /etc/ceph/ceph.*.keyring"
echo -e "${MAGENTA}o--> ssh root@$TARGETIP dpkg-reconfigure ceph-common${RESET}"
ssh "root@$TARGETIP" "dpkg-reconfigure ceph-common"

cd /etc/ceph || exit $LINENO
if test "$CREATEMON" = "true"
then
	echo -e "${MAGENTA}o--> ceph-deploy --overwrite-conf mon create $TARGETHOST${RESET}"
	ceph-deploy --overwrite-conf mon create $TARGETHOST || exit $LINENO
fi
echo -e "${MAGENTA}o--> ceph-deploy mgr create $TARGETHOST${RESET}"
ceph-deploy mgr create $TARGETHOST || exit $LINENO
if test "$ONLYMON" != "true"
then
	VGROUP="$(ssh root@$TARGETIP vgscan 2>/dev/null|grep Found|cut -d \" -f 2)"
	if test -n "$VGROUP"
	then
		echo -e "${MAGENTA}o--> ssh root@$TARGETIP vgremove -f "$VGROUP" "$PART"${RESET}"
		ssh "root@$TARGETIP" vgremove -f "$VGROUP" "$PART"
	fi
	echo -e "${MAGENTA}o--> ceph-deploy osd create "$TARGETHOST" --bluestore --data "$PART"${RESET}"
	ceph-deploy osd create "$TARGETHOST" --bluestore --data "$PART" || exit $LINENO
fi
echo -e "${MAGENTA}o--> ceph-deploy admin $TARGETHOST${RESET}"
ceph-deploy admin $TARGETHOST || exit $LINENO
if test "$ONLYMON" != "true"
then
	echo -e "${MAGENTA}o--> ceph-deploy mds create $TARGETHOST${RESET}"
	ceph-deploy mds create $TARGETHOST || exit $LINENO
fi
ssh "root@$TARGETIP" "chmod +r /etc/ceph/ceph.client.admin.keyring" || exit $LINENO
echo -e "${MAGENTA}o--> scp /etc/ceph/ceph.client.tgpro.keyring root@$TARGETIP:/etc/ceph/${RESET}"
scp /etc/ceph/ceph.client.tgpro.keyring "root@$TARGETIP:/etc/ceph/"
if test -e /etc/ceph/ceph.client.rbd.keyring
then
	echo -e "${MAGENTA}o--> scp /etc/ceph/ceph.client.rbd.keyring root@$TARGETIP:/etc/ceph/${RESET}"
	scp /etc/ceph/ceph.client.rbd.keyring "root@$TARGETIP:/etc/ceph/"
fi
if test -e /etc/ceph/ceph.client.crash.keyring
then
	echo -e "${MAGENTA}o--> scp /etc/ceph/ceph.client.crash.keyring root@$TARGETIP:/etc/ceph/${RESET}"
	scp /etc/ceph/ceph.client.crash.keyring "root@$TARGETIP:/etc/ceph/"
	ssh "root@$TARGETIP" "if ! grep -q 'client.crash' /etc/ceph/ceph.conf ; then echo -e '\n[client.crash]\nkeyring = /etc/ceph/ceph.client.crash.keyring' >> /etc/ceph/ceph.conf ; fi" || exit $LINENO
fi
if test "$ONLYMON" != "true"
then
	OSDHDD=$(ceph osd tree 2>/dev/null|grep hdd|tr -s ' '|cut -d ' ' -f 5)
	if test -n "$OSDHDD"
	then
		for i in $OSDHDD
		do
			echo -e "${MAGENTA}o--> ceph osd crush set-device-class ssd $i${RESET}"
			ceph osd crush rm-device-class $i
			ceph osd crush set-device-class ssd $i
		done
	fi
fi
if test "$CREATEMON" = "true"
then
	ceph-deploy --overwrite-conf admin $TARGETHOST
fi
echo -e "${MAGENTA}o--> ceph health${RESET}"
ssh "root@$TARGETIP" "ceph health"
echo -e "${MAGENTA}o--> Ready.${RESET}"
if test "$ONLYMON" != "true"
then
	if test "$CREATEMON" = "true"
	then
		echo "Please add the new monitor $TARGETIP to /etc/ceph/ceph.conf"
		echo "on all nodes."
	fi
	echo "Please adjust pool size and min_size values, if needed,"
	echo "Check: ceph osd pool get cephfs_[meta]data [min_]size"
	echo "Set:   ceph osd pool set cephfs_[meta]data [min_]size N"
	echo "Check: ceph osd pool get .mgr [min_]size"
	echo "Set:   ceph osd pool set .mgr [min_]size N"
fi
