Skip to content

Instantly share code, notes, and snippets.

@ivotron
Last active August 9, 2017 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ivotron/62d19dbad88c802e804edfb58d542acb to your computer and use it in GitHub Desktop.
Save ivotron/62d19dbad88c802e804edfb58d542acb to your computer and use it in GitHub Desktop.
ceph demo without unwanted stuff
#!/bin/bash
set -e
export LC_ALL=C
# Global variables
: ${CLUSTER:=ceph}
: ${RGW_NAME:=$(hostname -s)}
: ${MON_NAME:=$(hostname -s)}
: ${MGR_NAME:=$(hostname -s)}
: ${MON_DATA_DIR:=/var/lib/ceph/mon/${CLUSTER}-${MON_NAME}}
: ${RGW_CIVETWEB_PORT:=80}
: ${NETWORK_AUTO_DETECT:=0}
: ${RESTAPI_IP:=0.0.0.0}
: ${RESTAPI_PORT:=5000}
: ${RESTAPI_BASE_URL:=/api/v0.1}
: ${RESTAPI_LOG_LEVEL:=warning}
: ${RESTAPI_LOG_FILE:=/var/log/ceph/ceph-restapi.log}
# Internal variables
MDS_KEYRING=/var/lib/ceph/mds/${CLUSTER}-0/keyring
OSD_KEYRING=/var/lib/ceph/osd/${CLUSTER}-0/keyring
ADMIN_KEYRING=/etc/ceph/${CLUSTER}.client.admin.keyring
MON_KEYRING=/etc/ceph/${CLUSTER}.mon.keyring
RGW_KEYRING=/var/lib/ceph/radosgw/${RGW_NAME}/keyring
CEPH_PATH_BASE=/var/lib/ceph
MONMAP=/etc/ceph/monmap-${CLUSTER}
MGR_KEYRING=/var/lib/ceph/mgr/${CLUSTER}-${MGR_NAME}/keyring
IPV4_REGEXP='[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
IPV4_NETWORK_REGEXP="$IPV4_REGEXP/[0-9]\{1,2\}"
CLI_OPTS="--cluster ${CLUSTER}"
DAEMON_OPTS="--cluster ${CLUSTER} --setuser ceph --setgroup ceph"
if [[ -n $DEBUG ]]; then
set -x
fi
#############
# FUNCTIONS #
#############
# Transform any set of strings to uppercase
function to_uppercase {
echo "${@^^}"
}
# Test if a command line tool is available
function is_available {
command -v $@ &>/dev/null
}
function flat_to_ipv6 {
# Get a flat input like fe800000000000000042acfffe110003 and output fe80::0042:acff:fe11:0003
# This input usually comes from the ipv6_route or if_inet6 files from /proc
# First, split the string in set of 4 bytes with ":" as separator
value=$(echo "$@" | sed -e 's/.\{4\}/&:/g' -e '$s/\:$//')
# Let's remove the useless 0000 and "::"
value=${value//0000/:};
while $(echo $value | grep -q ":::"); do
value=${value//::/:};
done
echo $value
}
function get_ip {
NIC=$1
# IPv4 is the default unless we specify it
IP_VERSION=${2:-4}
# We should avoid reporting any IPv6 "scope local" interface that would make the ceph bind() call to fail
if is_available ip; then
ip -$IP_VERSION -o a s $NIC | grep "scope global" | awk '{ sub ("/..", "", $4); print $4 }' || true
else
case "$IP_VERSION" in
6)
# We don't want local scope, so let's remove field 4 if not 00
ip=$(flat_to_ipv6 $(grep $NIC /proc/net/if_inet6 | awk '$4==00 {print $1}'))
# IPv6 IPs should be surrounded by brackets to let ceph-monmap being happy
echo "[$ip]"
;;
*)
grep -o "$IPV4_REGEXP" /proc/net/fib_trie | grep -vEw "^127|255$|0$" | head -1
;;
esac
fi
}
function get_network {
NIC=$1
# IPv4 is the default unless we specify it
IP_VERSION=${2:-4}
case "$IP_VERSION" in
6)
if is_available ip; then
ip -$IP_VERSION route show dev $NIC | grep proto | awk '{ print $1 }' | grep -v default | grep -vi ^fe80 || true
else
# We don't want the link local routes
line=$(grep $NIC /proc/1/task/1/net/ipv6_route | awk '$2==40' | grep -v ^fe80 || true)
base=$(echo $line | awk '{ print $1 }')
base=$(flat_to_ipv6 $base)
mask=$(echo $line | awk '{ print $2 }')
echo "$base/$((16#$mask))"
fi
;;
*)
if is_available ip; then
ip -$IP_VERSION route show dev $NIC | grep proto | awk '{ print $1 }' | grep -v default | grep "/" || true
else
grep -o "$IPV4_NETWORK_REGEXP" /proc/net/fib_trie | grep -vE "^127|^0" | head -1
fi
;;
esac
}
# Log arguments with timestamp
function log {
if [ -z "$*" ]; then
return 1
fi
TIMESTAMP=$(date '+%F %T')
echo "${TIMESTAMP} $0: $*"
return 0
}
function create_mandatory_directories {
# Let's create the bootstrap directories
for directory in osd mds rgw; do
mkdir -p /var/lib/ceph/bootstrap-$directory
done
# Let's create the ceph directories
for directory in mon osd mds radosgw tmp mgr; do
mkdir -p /var/lib/ceph/$directory
done
# Create socket directory
mkdir -p /var/run/ceph
# Adjust the owner of all those directories
#chown --verbose -R ceph. /var/run/ceph/ /var/lib/ceph/*
}
#######
# MON #
#######
function bootstrap_mon {
if [[ ${NETWORK_AUTO_DETECT} -eq 0 ]]; then
if [[ -z "$CEPH_PUBLIC_NETWORK" ]]; then
log "ERROR- CEPH_PUBLIC_NETWORK must be defined as the name of the network for the OSDs"
exit 1
fi
if [[ -z "$MON_IP" ]]; then
log "ERROR- MON_IP must be defined as the IP address of the monitor"
exit 1
fi
else
NIC_MORE_TRAFFIC=$(grep -vE "lo:|face|Inter" /proc/net/dev | sort -n -k 2 | tail -1 | awk '{ sub (":", "", $1); print $1 }')
IP_VERSION=4
if [ ${NETWORK_AUTO_DETECT} -gt 1 ]; then
MON_IP=$(get_ip ${NIC_MORE_TRAFFIC} ${NETWORK_AUTO_DETECT})
CEPH_PUBLIC_NETWORK=$(get_network ${NIC_MORE_TRAFFIC} ${NETWORK_AUTO_DETECT})
IP_VERSION=${NETWORK_AUTO_DETECT}
else # Means -eq 1
MON_IP="[$(get_ip ${NIC_MORE_TRAFFIC} 6)]"
CEPH_PUBLIC_NETWORK=$(get_network ${NIC_MORE_TRAFFIC} 6)
IP_VERSION=6
if [ -z "$MON_IP" ]; then
MON_IP=$(get_ip ${NIC_MORE_TRAFFIC})
CEPH_PUBLIC_NETWORK=$(get_network ${NIC_MORE_TRAFFIC})
IP_VERSION=4
fi
fi
fi
if [[ -z "$MON_IP" || -z "$CEPH_PUBLIC_NETWORK" ]]; then
log "ERROR- it looks like we have not been able to discover the network settings"
exit 1
fi
# bootstrap MON
if [ ! -e /etc/ceph/${CLUSTER}.conf ]; then
fsid=$(uuidgen)
cat <<ENDHERE >/etc/ceph/${CLUSTER}.conf
[global]
fsid = $fsid
mon initial members = ${MON_NAME}
mon host = ${MON_IP}
auth cluster required = cephx
auth service required = cephx
auth client required = cephx
osd crush chooseleaf type = 0
osd journal size = 100
osd pool default pg num = 8
osd pool default pgp num = 8
osd pool default size = 1
public network = ${CEPH_PUBLIC_NETWORK}
cluster network = ${CEPH_PUBLIC_NETWORK}
ENDHERE
# For ext4
if [ "$(findmnt -n -o FSTYPE -T /var/lib/ceph)" = "ext4" ]; then
cat <<ENDHERE >> /etc/ceph/${CLUSTER}.conf
osd max object name len = 256
osd max object namespace len = 64
ENDHERE
fi
# Generate administrator key
ceph-authtool $ADMIN_KEYRING --create-keyring --gen-key -n client.admin --set-uid=0 --cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow'
# Generate the mon. key
ceph-authtool $MON_KEYRING --create-keyring --gen-key -n mon. --cap mon 'allow *'
# Generate initial monitor map
monmaptool --create --add ${MON_NAME} ${MON_IP} --fsid ${fsid} $MONMAP
fi
# If we don't have a monitor keyring, this is a new monitor
if [ ! -e "$MON_DATA_DIR/keyring" ]; then
if [ ! -e $ADMIN_KEYRING ]; then
log "ERROR- $ADMIN_KEYRING must exist; get it from your existing mon"
exit 2
fi
if [ ! -e $MON_KEYRING ]; then
log "ERROR- $MON_KEYRING must exist. You can extract it from your current monitor by running 'ceph ${CLI_OPTS} auth get mon. -o /tmp/${CLUSTER}.mon.keyring'"
exit 3
fi
if [ ! -e $MONMAP ]; then
log "ERROR- $MONMAP must exist. You can extract it from your current monitor by running 'ceph ${CLI_OPTS} mon getmap -o /tmp/monmap-${CLUSTER}'"
exit 4
fi
# Import the client.admin keyring and the monitor keyring into a new, temporary one
ceph-authtool /tmp/${CLUSTER}.mon.keyring --create-keyring --import-keyring $ADMIN_KEYRING
ceph-authtool /tmp/${CLUSTER}.mon.keyring --import-keyring $MON_KEYRING
# Make the monitor directory
mkdir -p "$MON_DATA_DIR"
# Prepare the monitor daemon's directory with the map and keyring
#chown --verbose -R ceph. $CEPH_PATH_BASE/mon /tmp/${CLUSTER}.mon.keyring
ceph-mon ${CLI_OPTS} --mkfs -i ${MON_NAME} --monmap $MONMAP --keyring /tmp/${CLUSTER}.mon.keyring --mon-data "$MON_DATA_DIR"
# Clean up the temporary key
rm /tmp/${CLUSTER}.mon.keyring
fi
# start MON
#chown --verbose -R ceph. $CEPH_PATH_BASE/mon /etc/ceph/
ceph-mon ${DAEMON_OPTS} -i ${MON_NAME} --public-addr "${MON_IP}:6789"
# change replica size
ceph ${CLI_OPTS} osd pool set rbd size 1
}
#######
# OSD #
#######
function bootstrap_osd {
if [ ! -e $CEPH_PATH_BASE/osd/${CLUSTER}-0/keyring ]; then
# bootstrap OSD
mkdir -p $CEPH_PATH_BASE/osd/${CLUSTER}-0
ceph ${CLI_OPTS} osd create
#chown --verbose -R ceph. $CEPH_PATH_BASE/osd/${CLUSTER}-0
ceph-osd ${CLI_OPTS} -i 0 --mkfs --setuser ceph --setgroup ceph
ceph ${CLI_OPTS} auth get-or-create osd.0 osd 'allow *' mon 'allow profile osd' -o $OSD_KEYRING
ceph ${CLI_OPTS} osd crush add 0 1 root=default host=localhost
fi
# start OSD
#chown --verbose -R ceph. $CEPH_PATH_BASE/osd/${CLUSTER}-0
ceph-osd ${DAEMON_OPTS} -i 0
}
#######
# MDS #
#######
function bootstrap_mds {
if [ ! -e $MDS_KEYRING ]; then
# create ceph filesystem
ceph ${CLI_OPTS} osd pool create cephfs_data 8
ceph ${CLI_OPTS} osd pool create cephfs_metadata 8
ceph ${CLI_OPTS} fs new cephfs cephfs_metadata cephfs_data
# bootstrap MDS
mkdir -p $CEPH_PATH_BASE/mds/${CLUSTER}-0
ceph ${CLI_OPTS} auth get-or-create mds.0 mds 'allow' osd 'allow *' mon 'allow profile mds' -o $MDS_KEYRING
#chown --verbose -R ceph. $CEPH_PATH_BASE/mds/${CLUSTER}-0
fi
# start MDS
ceph-mds ${DAEMON_OPTS} -i 0
}
#######
# RGW #
#######
function bootstrap_rgw {
if [ ! -e $RGW_KEYRING ]; then
# bootstrap RGW
mkdir -p $CEPH_PATH_BASE/radosgw/${RGW_NAME}
ceph ${CLI_OPTS} auth get-or-create client.radosgw.gateway osd 'allow rwx' mon 'allow rw' -o $RGW_KEYRING
#chown --verbose -R ceph. $CEPH_PATH_BASE/radosgw/${RGW_NAME}
#configure rgw dns name
cat <<ENDHERE >>/etc/ceph/${CLUSTER}.conf
[client.radosgw.gateway]
rgw dns name = ${RGW_NAME}
ENDHERE
fi
# start RGW
radosgw ${DAEMON_OPTS} -n client.radosgw.gateway -k $RGW_KEYRING --rgw-socket-path="" --rgw-frontends="civetweb port=${RGW_CIVETWEB_PORT}"
}
function bootstrap_demo_user {
if [ -n "$CEPH_DEMO_UID" ] && [ -n "$CEPH_DEMO_ACCESS_KEY" ] && [ -n "$CEPH_DEMO_SECRET_KEY" ]; then
if [ -f /ceph-demo-user ]; then
log "Demo user already exists with credentials:"
cat /ceph-demo-user
else
log "Setting up a demo user..."
radosgw-admin ${CLI_OPTS} user create --uid=$CEPH_DEMO_UID --display-name="Ceph demo user" --access-key=$CEPH_DEMO_ACCESS_KEY --secret-key=$CEPH_DEMO_SECRET_KEY
sed -i s/AWS_ACCESS_KEY_PLACEHOLDER/$CEPH_DEMO_ACCESS_KEY/ /root/.s3cfg
sed -i s/AWS_SECRET_KEY_PLACEHOLDER/$CEPH_DEMO_SECRET_KEY/ /root/.s3cfg
echo "Access key: $CEPH_DEMO_ACCESS_KEY" > /ceph-demo-user
echo "Secret key: $CEPH_DEMO_SECRET_KEY" >> /ceph-demo-user
# Use rgw port
sed -i "s/host_base = localhost/host_base = ${RGW_NAME}:${RGW_CIVETWEB_PORT}/" /root/.s3cfg
sed -i "s/host_bucket = localhost/host_bucket = ${RGW_NAME}:${RGW_CIVETWEB_PORT}/" /root/.s3cfg
if [ -n "$CEPH_DEMO_BUCKET" ]; then
log "Creating bucket..."
log "Transforming your bucket name to uppercase."
log "It appears there is a bug in s3cmd 1.6.1 with lowercase bucket names."
s3cmd mb s3://$(to_uppercase $CEPH_DEMO_BUCKET)
fi
fi
fi
}
#######
# NFS #
#######
function bootstrap_nfs {
# Init RPC
rpcbind || return 0
rpc.statd -L || return 0
rpc.idmapd || return 0
# start ganesha
ganesha.nfsd -F ${GANESHA_OPTIONS} ${GANESHA_EPOCH}
}
#######
# API #
#######
function bootstrap_rest_api {
if [[ ! "$(egrep "\[client.restapi\]" /etc/ceph/${CLUSTER}.conf)" ]]; then
cat <<ENDHERE >>/etc/ceph/${CLUSTER}.conf
[client.restapi]
public addr = ${RESTAPI_IP}:${RESTAPI_PORT}
restapi base url = ${RESTAPI_BASE_URL}
restapi log level = ${RESTAPI_LOG_LEVEL}
log file = ${RESTAPI_LOG_FILE}
ENDHERE
fi
# start ceph-rest-api
ceph-rest-api ${CLI_OPTS} -c /etc/ceph/${CLUSTER}.conf -n client.admin &
}
##############
# RBD MIRROR #
##############
function bootstrap_rbd_mirror {
# start rbd-mirror
rbd-mirror ${DAEMON_OPTS}
}
#######
# MGR #
#######
function bootstrap_mgr {
mkdir -p $CEPH_PATH_BASE/mgr/${CLUSTER}-$MGR_NAME
ceph ${CLI_OPTS} auth get-or-create mgr.$MGR_NAME mon 'allow *' -o $MGR_KEYRING
#chown --verbose -R ceph. $CEPH_PATH_BASE/mgr
# start ceph-mgr
ceph-mgr ${DAEMON_OPTS} -i $MGR_NAME
}
#########
# WATCH #
#########
create_mandatory_directories
bootstrap_mon
bootstrap_osd
#bootstrap_mds
#bootstrap_rgw
#bootstrap_demo_user
#bootstrap_rest_api
# bootstrap_nfs is temporarily disabled due to broken package dependencies with nfs-ganesha"
# For more info see: https://github.com/ceph/ceph-docker/pull/564"
#bootstrap_nfs
#bootstrap_rbd_mirror
#bootstrap_mgr
log "SUCCESS"
exec ceph ${CLI_OPTS} -w
CEPH_NET=175.20.0.0/16
MON_IP=175.20.0.12
docker run -d \
--name=cephd \
--net cephnet \
--ip $MON_IP \
-v `pwd`/etcceph:/etc/ceph \
-v `pwd`/entrypoint.sh:/root/entrypoint.sh \
-e MON_IP=$MON_IP \
-e CEPH_PUBLIC_NETWORK=$CEPH_NET \
ceph/demo:tag-build-master-kraken-ubuntu-16.04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment