#!/bin/bash
# Copyright (c) 2022-2026 m-privacy GmbH
# ao
#
# Last change: 18/Aug/2026, ao

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

if test -z "$1" -o "$1" = "-h" -o "$1" = "help"
then
	echo "Use: $0 data_partition [public_net [cluster_net]]"
	echo "E.g. $0 /dev/sda4 192.168.111. 192.168.112."
	echo "Using a journal partition is no longer recommended."
	exit 0
fi

PART="$1"
test -z "$PART" && PART=/dev/sda4
PUBLIC="$2"
if test -z "$PUBLIC"
then
	PUBLIC="192.168.111."
fi
CLUSTER="$3"
if test -z "$CLUSTER"
then
	CLUSTER="$PUBLIC"
fi
MYIP=$(/sbin/ip addr show 2>/dev/null|grep "^    inet"|grep "${PUBLIC//./\\.}"|head -n 1|cut -d " " -f 6|cut -d / -f 1)
if test -z "$MYIP"
then
	echo "No interface has IP ${PUBLIC}X"
	exit $LINENO
fi
if test "$PUBLIC" != "$CLUSTER"
then
	MYIP2=$(/sbin/ip addr show 2>/dev/null|grep "^    inet"|grep "${CLUSTER//./\\.}"|head -n 1|cut -d " " -f 6|cut -d / -f 1)
	if test -z "$MYIP2"
	then
		echo "No interface has IP ${CLUSTER}X"
		exit $LINENO
	fi
fi
if ! fdisk -l|grep -q "$PART"
then
	echo "No partition $PART found"
	exit $LINENO
fi

MDSMEM=64
MEMSIZE=$(grep MemTotal: /proc/meminfo 2>/dev/null|tr -s " "|cut -d " " -f 2)
if test -n "$MEMSIZE"
then
	MAXMEMSIZE=$(($MEMSIZE/2097152))
	if test "$MDSMEM" -gt $MAXMEMSIZE
	then
		MDSMEM=$MAXMEMSIZE
	fi
else
	MDSMEM=4
fi

#MYIP2=$(/sbin/ip addr show 2>/dev/null|grep "^    inet"|grep "192\.168\.112\."|head -n 1|cut -d " " -f 6|cut -d / -f 1)
echo -e "\nCreate a one node cephfs cluster on this system $HOSTNAME"
echo -n "OSD bluestore data stored on $PART, MDS cache ${MDSMEM}G"
echo -e -n "\nPublic IP: $MYIP"
if test -n "$MYIP2"
then
	echo -n ", Cluster IP: $MYIP2"
else
	echo -n ", Cluster IP: $MYIP"
fi
mount|grep "^$PART on"
echo -e "\nPress return to continue or CTRL-C to exit."
read dummy
echo -e "${MAGENTA}o--> Starting${RESET}"

mkdir -p /var/lib/ceph/crash/posted

if ! test -f $HOME/.ssh/id_ed25519
then
	ssh-keygen -t ed25519 -N "" -C "Ceph Key" -f $HOME/.ssh/id_ed25519 || exit $LINENO
	cp -a $HOME/.ssh/id_ed25519.pub $HOME/.ssh/authorized_keys2 || exit $LINENO
	mkdir -p -m 0700 /var/lib/ceph/.ssh
	cp -a $HOME/.ssh/id_ed25519 /var/lib/ceph/.ssh/ || exit $LINENO
	cp -a $HOME/.ssh/id_ed25519.pub /var/lib/ceph/.ssh/authorized_keys2 || exit $LINENO
	chown -R ceph:ceph /var/lib/ceph/.ssh
fi
if ! rsbac_usershow ceph &>/dev/null
then
	dpkg-reconfigure ceph-common
fi
pkill ceph-mon
pkill ceph-mgr
pkill ceph-mds
pkill ceph-osd
if mount|grep -q "$PART"
then
	while pgrep ceph-osd >/dev/null
	do
		sleep 1
	done
	umount "$PART" || exit $LINENO
fi
rm -rf /var/lib/ceph/*/* /etc/ceph/ceph.*.keyring
cd /etc/ceph/ || exit $LINENO
#MYIP=$(/sbin/ip addr show 2>/dev/null|grep "^    inet"|grep "${PUBLIC//./\\.}"|head -n 1|cut -d " " -f 6|cut -d / -f 1)
test -n "$MYIP" || exit $LINENO
echo "My IP: $MYIP"
if ! grep -q "$MYIP" /etc/hosts
then
	{
		echo -e "$MYIP\t$(hostname -f)\t$HOSTNAME"
		grep -v "$HOSTNAME" /etc/hosts
	} > /etc/hosts.new
	mv /etc/hosts.new /etc/hosts
fi
ssh -oStrictHostKeyChecking=no "$HOSTNAME" /bin/true || exit $LINENO
echo -e "${MAGENTA}o--> ceph-deploy new $HOSTNAME${RESET}"
chown ceph:ceph /etc/ceph
ceph-deploy new $HOSTNAME || exit $LINENO
test -f /etc/ceph/ceph.conf || exit $LINENO
if test -n "$MYIP2"
then
	CLUSTERNET="${CLUSTER}0/24"
else
	CLUSTERNET="${PUBLIC}0/24"
fi
echo "cluster_network = $CLUSTERNET
public_network = ${PUBLIC}0/24
osd pool default size = 1
osd pool default min size = 1
osd pool default pg num = 32
osd pool default pgp num = 32
osd_pool_default_pg_autoscale_mode = on
mds cache size = ${MDSMEM}G" >> /etc/ceph/ceph.conf || exit $LINENO
echo -e "${MAGENTA}o--> ceph-deploy mon create-initial${RESET}"
ceph-deploy --overwrite-conf mon create-initial || exit $LINENO
echo -e "${MAGENTA}o--> ceph-deploy mgr create $HOSTNAME${RESET}"
ceph-deploy mgr create $HOSTNAME || exit $LINENO
echo -e "${MAGENTA}o--> chown ceph:ceph $PART${RESET}"
chown ceph:ceph $PART || exit $LINENO
VGROUP="$(vgscan 2>/dev/null|grep Found|cut -d \" -f 2)"
if test -n "$VGROUP"
then
	echo -e "${MAGENTA}o--> vgremove -f "$VGROUP" "$PART"${RESET}"
	vgremove -f "$VGROUP" "$PART"
fi
echo -e "${MAGENTA}o--> ceph-deploy osd create "$HOSTNAME" --bluestore --data "$PART"${RESET}"
ceph-deploy osd create "$HOSTNAME" --bluestore --data "$PART" || exit $LINENO
chown ceph:ceph $PART || exit $LINENO
echo -e "${MAGENTA}o--> ceph-deploy admin $HOSTNAME${RESET}"
ceph-deploy admin $HOSTNAME || exit $LINENO
echo -e "${MAGENTA}o--> ceph-deploy mds create $HOSTNAME${RESET}"
ceph-deploy mds create $HOSTNAME || exit $LINENO
chmod +r /etc/ceph/ceph.client.admin.keyring || exit $LINENO
echo -e "${MAGENTA}o--> ceph osd pool delete rbd rbd --yes-i-really-really-mean-it${RESET}"
ceph osd pool delete rbd rbd --yes-i-really-really-mean-it
echo -e "${MAGENTA}o--> ceph mgr module enable pg_autoscaler${RESET}"
ceph mgr module enable pg_autoscaler
echo -e "${MAGENTA}o--> ceph config set global osd_pool_default_pg_autoscale_mode on${RESET}"
ceph config set global osd_pool_default_pg_autoscale_mode on
echo -e "${MAGENTA}o--> ceph osd pool create cephfs_data 32${RESET}"
ceph osd pool create cephfs_data 32 || exit $LINENO
echo -e "${MAGENTA}o--> ceph osd pool set cephfs_data pg_num_min 16${RESET}"
ceph osd pool set cephfs_data pg_num_min 16
echo -e "${MAGENTA}o--> ceph osd pool create cephfs_metadata 16${RESET}"
ceph osd pool create cephfs_metadata 16 || exit $LINENO
echo -e "${MAGENTA}o--> ceph osd pool set cephfs_metadata pg_num_min 4${RESET}"
ceph osd pool set cephfs_metadata pg_num_min 4
echo -e "${MAGENTA}o--> ceph osd pool set cephfs_data pg_autoscale_mode on${RESET}"
ceph osd pool set cephfs_data pg_autoscale_mode on
echo -e "${MAGENTA}o--> ceph osd pool set cephfs_metadata pg_autoscale_mode on${RESET}"
ceph osd pool set cephfs_metadata pg_autoscale_mode on
echo -e "${MAGENTA}o--> ceph mgr module disable restful${RESET}"
ceph mgr module disable restful
echo -e "${MAGENTA}o--> ceph config set global device_failure_prediction_mode local${RESET}"
ceph config set global device_failure_prediction_mode local
echo -e "${MAGENTA}o--> ceph config set mgr mgr/crash/warn_recent_interval 0${RESET}"
ceph config set mgr mgr/crash/warn_recent_interval 0
echo -e "${MAGENTA}o--> ceph config set mon auth_allow_insecure_global_id_reclaim false${RESET}"
ceph config set mon auth_allow_insecure_global_id_reclaim false
echo -e "${MAGENTA}o--> ceph config set mon mon_data_avail_warn 10${RESET}"
ceph config set mon mon_data_avail_warn 10
echo -e "${MAGENTA}o--> ceph osd crush tunables optimal${RESET}"
ceph osd crush tunables optimal
echo -e "${MAGENTA}o--> ceph fs new cephfs cephfs_metadata cephfs_data${RESET}"
ceph fs new cephfs cephfs_metadata cephfs_data || exit $LINENO
echo -e "${MAGENTA}o--> ceph fs set cephfs session_autoclose 180${RESET}"
ceph fs set cephfs session_autoclose 180 || exit $LINENO
echo -e "${MAGENTA}o--> ceph fs set cephfs allow_standby_replay yes${RESET}"
ceph fs set cephfs allow_standby_replay yes || exit $LINENO
echo -e "${MAGENTA}o--> ceph config set mds mds_cache_memory_limit ${MDSMEM}G${RESET}"
ceph config set mds mds_cache_memory_limit ${MDSMEM}G || exit $LINENO
echo -e "${MAGENTA}o--> ceph config set global mon_cluster_log_level info${RESET}"
ceph config set global mon_cluster_log_level info
echo -e "${MAGENTA}o--> ceph config set mon debug_mon 0/0${RESET}"
ceph config set mon debug_mon 0/0

sleep 5
pgrep ceph-osd >/dev/null || /etc/init.d/ceph start osd
KEY=$(grep "key = " "/etc/ceph/ceph.client.admin.keyring" | cut -d " " -f 3)
echo -e "${MAGENTA}o--> mount -t ceph $HOSTNAME:/ /mnt/ -o name=admin,secret=\"$KEY\"${RESET}"
mount -t ceph "$MYIP:/" /mnt/ -o name=admin,secret="$KEY" || exit $LINENO
echo "mount -t ceph \"$MYIP:/\" /mnt/ -o name=admin,secret=\"$KEY\"" >> /root/.bash_history
echo -e "${MAGENTA}o--> mkdir -p /mnt/homeuser /mnt/backup${RESET}"
mkdir -p /mnt/homeuser /mnt/backup || exit $LINENO
echo -e "${MAGENTA}o--> chown 430:100 /mnt/backup${RESET}"
chown 430:100 /mnt/backup || exit $LINENO
chmod 700 /mnt/backup || exit $LINENO
echo -e "${MAGENTA}o--> umount /mnt/${RESET}"
umount /mnt/ || exit $LINENO
chown root:cephadm /etc/ceph/ceph.client.admin.keyring
chmod 640 /etc/ceph/ceph.client.admin.keyring
if ! ceph auth get client.tgpro &>/dev/null
then
	echo -e "${MAGENTA}o--> create Ceph user tgpro${RESET}"
	ceph auth get-or-create client.tgpro mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rw pool=cephfs_data' mds "allow rwps path=/homeuser, allow rwps path=/backup" -o /etc/ceph/ceph.client.tgpro.keyring
	chown root:cephadm /etc/ceph/ceph.client.tgpro.keyring
	chmod 640 /etc/ceph/ceph.client.tgpro.keyring
fi
if ! ceph auth get client.crash &>/dev/null
then
	echo -e "${MAGENTA}o--> create Ceph user crash${RESET}"
	ceph auth get-or-create client.crash mon 'profile crash' mgr 'profile crash' -o /etc/ceph/ceph.client.crash.keyring
	chown root:ceph /etc/ceph/ceph.client.crash.keyring
	chmod 640 /etc/ceph/ceph.client.crash.keyring
fi
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
mkdir -p /var/lib/ceph/crash/posted
chown ceph /var/lib/ceph/crash/posted
echo -e "${MAGENTA}o--> ceph osd pool autoscale-status${RESET}"
ceph osd pool autoscale-status
echo -e "${MAGENTA}o--> ceph config optimize${RESET}"
ceph config set osd bluestore_cache_size_hdd 3221225472
ceph config set osd bluestore_compression_max_blob_size_hdd 65536
ceph config set osd bluestore_compression_min_blob_size_hdd 8192
ceph config set osd bluestore_deferred_batch_ops_hdd 16
ceph config set osd bluestore_max_blob_size_hdd 65536
ceph config set osd bluestore_min_alloc_size_hdd 4096
ceph config set osd bluestore_prefer_deferred_size_hdd 0
ceph config set osd bluestore_throttle_cost_per_io_hdd 4000
ceph config set osd osd_delete_sleep_hdd 0
ceph config set osd osd_op_num_shards_hdd 8
ceph config set osd osd_op_num_threads_per_shard_hdd 2
ceph config set osd osd_recovery_max_active_hdd 10
ceph config set osd osd_recovery_sleep_hdd 0
ceph config set osd osd_snap_trim_sleep_hdd 0
ceph config set osd bdev_enable_discard true
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
echo -e "${MAGENTA}o--> ceph health${RESET}"
ceph health
echo -e "${MAGENTA}o--> Ready.${RESET}"
echo "CephFS credentials are in /etc/ceph/ceph.client.tgpro.keyring"
