1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
#!/usr/bin/env bash
# "To provide additional docker-compose args, set the COMPOSE var. Ex:
# COMPOSE="-f FILE_PATH_HERE"
set -o errexit
set -o pipefail
set -o nounset
set -o xtrace
ERROR() {
echo -e "\e[101m\e[97m[ERROR]\e[49m\e[39m" "$@"
}
WARNING() {
echo -e "\e[101m\e[97m[WARNING]\e[49m\e[39m" "$@"
}
INFO() {
echo -e "\e[104m\e[97m[INFO]\e[49m\e[39m" "$@"
}
exists() {
type "$1" > /dev/null 2>&1
}
# Change directory to the source directory of this script. Taken from:
# https://stackoverflow.com/a/246128/3858681
pushd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
HELP=0
INIT_ONLY=0
COMPOSE=${COMPOSE:-""}
SUBNET=${SUBNET:-"172.19.0.0/24"}
PROXY_SUBNET=${PROXY_SUBNET:-"172.19.1.0/24"}
NODES=${NODES:-5}
RUN_AS_DAEMON=0
INCLUDE_PROXY_NODES=0
POSITIONAL=()
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-h|--help)
HELP=1
shift # past argument
;;
--init-only)
INIT_ONLY=1
shift # past argument
;;
--compose)
COMPOSE="-f $2"
shift # past argument
shift # past value
;;
--subnet)
SUBNET="$2"
shift # past argument
shift # past value
;;
-n|--nodes)
NODES="$2"
shift # past argument
shift # past value
;;
-d|--daemon)
INFO "Running docker-compose as daemon"
RUN_AS_DAEMON=1
shift # past argument
;;
--ssh-proxy)
INFO "Include SSH proxy nodes"
INCLUDE_PROXY_NODES=1
shift # past argument
;;
--proxy-subnet)
PROXY_SUBNET="$2"
shift # past argument
shift # past value
;;
*)
POSITIONAL+=("$1")
ERROR "unknown option $1"
shift # past argument
;;
esac
done
# comment because ERROR:
# ./up.sh: line 79: POSITIONAL[@]: unbound variable]
# set -- "${POSITIONAL[@]}" # restore positional parameters
if [ "${HELP}" -eq 1 ]; then
echo "Usage: $0 [OPTION]"
echo " --help Display this message"
echo " --init-only Initializes ssh-keys, but does not call docker-compose"
echo " --daemon Runs docker-compose in the background"
echo " --compose PATH Path to an additional docker-compose yml config."
echo " --subnet SUBNET Subnet in 24 bit netmask"
echo " --nodes NODES Start how much nodes"
echo " --ssh-proxy Start with ssh proxy nodes"
echo " --proxy-subnet PROXY_SUBNET Proxy subnet in 24 bit netmask"
echo "To provide multiple additional docker-compose args, set the COMPOSE var directly, with the -f flag. Ex: COMPOSE=\"-f FILE_PATH_HERE -f ANOTHER_PATH\" ./up.sh'"
exit 0
fi
exists ssh-keygen || { ERROR "Please install ssh-keygen (apt-get install openssh-client)"; exit 1; }
exists perl || { ERROR "Please install perl (apt-get install perl)"; exit 1; }
# Generate SSH keys for the control node
if [ ! -f ./secret/node.env ]; then
INFO "Generating key pair"
mkdir -p secret
ssh-keygen -t rsa -N "" -f ./secret/id_rsa
INFO "Generating ./secret/control.env"
{ echo "# generated by tiup-cluster/docker/up.sh, parsed by tiup-cluster/docker/control/bashrc";
echo "# NOTE: newline is expressed as ↩";
echo "SSH_PRIVATE_KEY=$(perl -p -e "s/\n/↩/g" < ./secret/id_rsa)";
echo "SSH_PUBLIC_KEY=$(cat ./secret/id_rsa.pub)"; } >> ./secret/control.env
INFO "Generating ./secret/node.env"
{ echo "# generated by tiup-cluster/docker/up.sh, parsed by the \"tutum/debian\" docker image entrypoint script";
echo "ROOT_PASS=root";
echo "AUTHORIZED_KEYS=$(cat ./secret/id_rsa.pub)"; } >> ./secret/node.env
else
INFO "No need to generate key pair"
fi
# Make sure folders referenced in control Dockerfile exist and don't contain leftover files
rm -rf ./control/tiup-cluster
mkdir -p ./control/tiup-cluster/tiup-cluster
if [ "${INIT_ONLY}" -eq 1 ]; then
exit 0
fi
if [ "${SUBNET##*/}" -ne 24 ]; then
ERROR "Only subnet mask of 24 bits are currently supported"
exit 1
fi
if [ "$NODES" -gt "64" ]; then
ERROR "At most 64 nodes is supported"
exit 1
fi
exists python ||
{ ERROR "Please install python (https://www.python.org/downloads/)";
exit 1; }
exists docker ||
{ ERROR "Please install docker (https://docs.docker.com/engine/installation/)";
exit 1; }
exists pip ||
{ ERROR "Please install pip (https://docs.docker.com/engine/installation/)";
exit 1; }
pip3 install -U jinja2
exist_network=$(docker network ls | awk '{if($2 == "tiops") print $1}')
if [[ "$exist_network" == "" ]]; then
docker network create --gateway "${SUBNET%.*}.1" --subnet "${SUBNET}" tiops
else
echo "Skip create tiup-cluster network"
SUBNET=$(docker network inspect -f "{{range .IPAM.Config}}{{.Subnet}}{{end}}" tiops)
fi
if [[ "${SUBNET##*/}" -ne 24 ]]; then
ERROR "Only subnet mask of 24 bits are currently supported"
exit 1
fi
ipprefix=${SUBNET%.*}
ssh_proxy="False"
proxy_prefix=""
if [[ "${INCLUDE_PROXY_NODES}" -eq 1 ]]; then
ssh_proxy="True"
exist_network=$(docker network ls | awk '{if($2 == "tiproxy") print $1}')
if [[ "$exist_network" == "" ]]; then
docker network create --gateway "${PROXY_SUBNET%.*}.1" --subnet "${PROXY_SUBNET}" tiproxy
else
echo "Skip create tiup-cluster proxy network"
SUBNET=$(docker network inspect -f "{{range .IPAM.Config}}{{.Subnet}}{{end}}" tiproxy)
fi
if [[ "${PROXY_SUBNET##*/}" -ne 24 ]]; then
ERROR "Only proxy-subnet mask of 24 bits are currently supported"
exit 1
fi
proxy_prefix=${PROXY_SUBNET%.*}
fi
python -c "from jinja2 import Template; print(Template(open('docker-compose.yml.tpl').read()).render(nodes=$NODES, ipprefix='$ipprefix', ssh_proxy=$ssh_proxy, proxy_prefix='$proxy_prefix'))" > docker-compose.yml
sed "s/__IPPREFIX__/$ipprefix/g" docker-compose.dm.yml.tpl > docker-compose.dm.yml
sed -i '/TIUP_TEST_IP_PREFIX/d' ./secret/control.env
echo "TIUP_TEST_IP_PREFIX=$ipprefix" >> ./secret/control.env
INFO "Running \`docker-compose build\`"
cp -a ${TIUP_CLUSTER_ROOT}/* ./control/ || true
docker compose -f docker-compose.yml ${COMPOSE} build
INFO "Running \`docker-compose up\`"
if [ "${RUN_AS_DAEMON}" -eq 1 ]; then
# shellcheck disable=SC2086
docker compose -f docker-compose.yml ${COMPOSE} up -d
INFO "All containers started, run \`docker ps\` to view"
else
INFO "Please run \`docker exec -it tiup-cluster-control bash\` in another terminal to proceed"
# shellcheck disable=SC2086
docker compose -f docker-compose.yml ${COMPOSE} up
fi
popd
|