Commit 29386d3e authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Add vcluster-setup utility



This utility can be used to configure an environment for a virtual
cluster. It sets up entries in /etc/hosts, creates the necessary
directory structure, and generates helper scripts.

Documentation for virtual clusters will come in a later patch.
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarRené Nussbaumer <rn@google.com>
parent 39b8cd94
......@@ -93,6 +93,7 @@
# tools
/tools/kvm-ifup
/tools/ensure-dirs
/tools/vcluster-setup
# scripts
/scripts/gnt-backup
......
......@@ -160,6 +160,7 @@ CLEANFILES = \
$(man_MANS) \
$(manhtml) \
tools/kvm-ifup \
tools/vcluster-setup
stamp-directories \
stamp-srclinks \
$(nodist_pkgpython_PYTHON) \
......@@ -675,6 +676,9 @@ dist_tools_SCRIPTS = \
tools/xm-console-wrapper \
tools/master-ip-setup
nodist_tools_SCRIPTS = \
tools/vcluster-setup
pkglib_python_scripts = \
daemons/import-export \
tools/check-cert-expired
......@@ -716,6 +720,7 @@ EXTRA_DIST = \
$(pkglib_python_scripts) \
devel/upload.in \
tools/kvm-ifup.in \
tools/vcluster-setup.in \
$(docdot) \
$(docpng) \
$(docrst) \
......@@ -1052,6 +1057,10 @@ devel/upload: devel/upload.in $(REPLACE_VARS_SED)
sed -f $(REPLACE_VARS_SED) < $< > $@
chmod u+x $@
tools/vcluster-setup: tools/vcluster-setup.in $(REPLACE_VARS_SED)
sed -f $(REPLACE_VARS_SED) < $< > $@
chmod +x $@
daemons/%:: daemons/%.in $(REPLACE_VARS_SED)
sed -f $(REPLACE_VARS_SED) < $< > $@
chmod +x $@
......
#!/bin/bash
#
# Copyright (C) 2012 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
set -e -u -o pipefail
shopt -s extglob
readonly self=$(readlink -f $0)
readonly ensure_dirs=@PKGLIBDIR@/ensure-dirs
readonly action_shortcuts=( start stop restart status )
readonly default_nodecount=5
readonly default_instcount=10
readonly default_netprefix=192.0.2
readonly default_netdev=eth0
readonly cluster_name=cluster
# IP address space:
# Cluster: .1
# Nodes: .10-.99
# Instances: .100-.254
readonly first_node_ipaddr_octet=10
readonly first_inst_ipaddr_octet=100
readonly max_node_count=$((first_inst_ipaddr_octet - first_node_ipaddr_octet))
readonly max_instance_count=$((255 - first_inst_ipaddr_octet))
usage() {
echo "Usage: $0 [-c <number>] [-i <number>] [-p <prefix>] [-n <netdev>]"\
'<directory>'
echo
echo 'Options:'
echo " -c Number of virtual nodes (defaults to $default_nodecount)"
echo " -i Number of instances (defaults to $default_instcount)"
echo " -p IPv4 network prefix (defaults to $default_netprefix)"
echo ' -n Network device for virtual IP addresses (defaults to'\
"$default_netdev)"
}
# Variables for options
nodecount=$default_nodecount
instcount=$default_instcount
netprefix=$default_netprefix
netdev=$default_netdev
# Parse options
while getopts :hc:p:n:i: opt; do
case "$opt" in
h)
usage
exit 0
;;
c)
nodecount="$OPTARG"
if [[ "$nodecount" != +([0-9]) ]]; then
echo "Invalid node count number: $nodecount" >&2
exit 1
elif (( nodecount > max_node_count )); then
echo "Node count must be $max_node_count or lower" >&2
exit 1
fi
;;
i)
instcount="$OPTARG"
if [[ "$instcount" != +([0-9]) ]]; then
echo "Invalid instance count number: $instcount" >&2
exit 1
elif (( instcount > max_instance_count )); then
echo "Instance count must be $max_instance_count or lower" >&2
exit 1
fi
;;
p)
netprefix="$OPTARG"
if [[ "$netprefix" != +([0-9]).+([0-9]).+([0-9]) ]]; then
echo "Invalid network prefix: $netprefix" >&2
exit 1
fi
;;
n)
netdev="$OPTARG"
if ! ip link show $netdev >/dev/null; then
echo "Invalid network device: $netdev" >&2
exit 1
fi
;;
\?)
echo "Invalid option: -$OPTARG" >&2
usage >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument" >&2
usage >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
if [[ "$#" != 1 ]]; then
usage
exit 1
fi
readonly rootdir=$1; shift
if [[ ! -d "$rootdir" ]]; then
echo "Directory '$rootdir' does not exist!" >&2
exit 1
fi
if (( $nodecount < 1 )); then
echo "Must create at least one node, currently requested $nodecount" >&2
exit 1
fi
node_hostname() {
local -r number="$1"
echo "node$((number + 1))"
}
instance_hostname() {
local -r number="$1"
echo "instance$((number + 1))"
}
node_ipaddr() {
local -r number="$1"
echo "$netprefix.$((first_node_ipaddr_octet + number))"
}
instance_ipaddr() {
local -r number="$1"
echo "$netprefix.$((first_inst_ipaddr_octet + number))"
}
setup_node() {
local -r number="$1"
local -r nodedir=$rootdir/$(node_hostname $number)
echo "Setting up node '$(node_hostname $number)' ..." >&2
if [[ ! -d $nodedir ]]; then
mkdir $nodedir
fi
mkdir -p \
$nodedir/etc/default \
$nodedir/var/lock\
$nodedir/var/{lib,log,run}/ganeti
GANETI_HOSTNAME=$(node_hostname $number) \
GANETI_ROOTDIR=$nodedir \
$ensure_dirs
local -r daemon_args="-b $(node_ipaddr $number)"
cat > $nodedir/etc/default/ganeti <<EOF
# Default settings for virtual node $i
NODED_ARGS='--no-mlock $daemon_args'
MASTERD_ARGS=''
RAPI_ARGS='$daemon_args'
CONFD_ARGS='$daemon_args'
export GANETI_ROOTDIR='$nodedir'
export GANETI_HOSTNAME='$(node_hostname $number)'
EOF
cat > $nodedir/cmd <<EOF
#!/bin/bash
export GANETI_ROOTDIR='$nodedir'
export GANETI_HOSTNAME='$(node_hostname $number)'
bash -c "\$*"
EOF
chmod +x $nodedir/cmd
}
setup_all_nodes() {
for ((i=0; i < nodecount; ++i)); do
setup_node $i
done
}
setup_etc_hosts() {
echo 'Configuring /etc/hosts ...' >&2
(
set -e -u
local -r tmpfile=$(mktemp /etc/hosts.vcluster.XXXXX)
trap "rm -f $tmpfile" EXIT
{
egrep -v "^$netprefix.[[:digit:]]+[[:space:]]" /etc/hosts
echo "$netprefix.1 $cluster_name"
for ((i=0; i < nodecount; ++i)); do
echo "$(node_ipaddr $i) $(node_hostname $i)"
done
for ((i=0; i < instcount; ++i)); do
echo "$(instance_ipaddr $i) $(instance_hostname $i)"
done
} > $tmpfile && \
chmod 0644 $tmpfile && \
mv $tmpfile /etc/hosts && \
trap - EXIT
)
}
setup_network_interfaces() {
echo 'Configuring network ...' >&2
for ((i=0; i < nodecount; ++i)); do
local ipaddr="$(node_ipaddr $i)/32"
ip addr del "$ipaddr" dev "$netdev" || :
ip addr add "$ipaddr" dev "$netdev"
done
}
setup_scripts() {
echo 'Configuring helper scripts ...' >&2
for action in "${action_shortcuts[@]}"; do
{
echo '#!/bin/bash'
for ((i=0; i < nodecount; ++i)); do
local name=$(node_hostname $i)
echo "echo 'Action \"$action\" for virtual node \"$name\" ...'"
echo "$name/cmd /etc/init.d/ganeti $action"
done
} > $rootdir/$action-all
chmod +x $rootdir/$action-all
done
}
show_info() {
cat <<EOF
Virtual cluster setup is complete.
Root directory: $rootdir
Cluster name: $cluster_name
EOF
echo 'Nodes:' $(for ((i=0; i < nodecount; ++i)); do node_hostname $i; done)
cat <<EOF
Initialize cluster:
cd $rootdir && node1/cmd gnt-cluster init --no-etc-hosts $cluster_name
Change cluster settings:
cd $rootdir && node1/cmd gnt-cluster modify \\
--enabled-hypervisors=fake \\
--specs-disk-size=min=0 --specs-disk-count=min=0
Add node:
cd $rootdir && node1/cmd gnt-node add --no-ssh-key-check node2
EOF
}
setup_all_nodes
setup_etc_hosts
setup_network_interfaces
setup_scripts
show_info
exit 0
# vim: set sw=2 sts=2 et :
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment