├── AUTHORS ├── LICENSE ├── README.md └── run.bash /AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of tsuru-now authors for copyright purposes. 2 | 3 | Álvaro Justen (@turicas) 4 | Andrews Medina 5 | Bram Borggreve 6 | Cezar Sa Espinola 7 | Francisco Souza 8 | Gabriel Mazetto 9 | Henrique Pereira 10 | Jonas Kac 11 | Joubert RedRat 12 | Paulo Sousa 13 | Philip Tzou 14 | Robson Roberto Souza Peixoto 15 | Sam Milledge 16 | Tarsis Azevedo 17 | Thiago Rodrigues 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, tsuru-now authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the Globo.com nor the names of its contributors 12 | may be used to endorse or promote products derived from this software without 13 | specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # INSTALL 2 | 3 | `now` script is *deprecated*. The current recommended method to install tsuru for test or development is [tsuru installer](https://docs.tsuru.io/stable/installing/using-tsuru-installer.html). 4 | 5 | # Tsuru Now 6 | 7 | Yet another script to install tsuru and its dependencies on Ubuntu or Debian distros. 8 | 9 | These are some goals for this project: 10 | 11 | * It should run without interaction and deliver a working environment; 12 | * It shouldn't be a problem to run the script multiple times on the same machine; 13 | * It should work on existing machines that might already have some components installed; 14 | * It should allow parameters to install a single role: 15 | * API node 16 | * Docker node 17 | * Load balancer node 18 | * A web UI to automatically run it on EC2 instances 19 | 20 | Note: This scripts works only on Debian or Ubuntu distros, isn't supported to run on CentOS/RHEL. 21 | 22 | ## Running 23 | 24 | Running the command below should already create a working tsuru environment: 25 | 26 | ``` 27 | curl -sL https://raw.githubusercontent.com/tsuru/now/master/run.bash | bash 28 | ``` 29 | 30 | ## Advanced Usage 31 | 32 | With Tsuru Now, you can build your own tsuru cluster easily. 33 | 34 | ### Building a cluster server 35 | 36 | ``` 37 | curl -sL https://raw.githubusercontent.com/tsuru/now/master/run.bash | bash -s -- --template server 38 | ``` 39 | 40 | 41 | ### Building a client connected to the server 42 | 43 | Assume the IP address of the cluster server is 10.42.42.1 44 | 45 | ``` 46 | curl -sL https://raw.githubusercontent.com/tsuru/now/master/run.bash | bash -s -- --template client --private-ip 10.42.42.1 47 | ``` 48 | 49 | 50 | ### Building a docker node controlled by the server 51 | 52 | Assume the IP address of the cluster server is 10.42.42.1 53 | 54 | ``` 55 | curl -sL https://raw.githubusercontent.com/tsuru/now/master/run.bash | bash -s -- --template dockerfarm --private-ip 10.42.42.1 56 | ``` 57 | -------------------------------------------------------------------------------- /run.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ue 2 | 3 | # Copyright 2017 tsuru-now authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | set -eu 8 | 9 | release="" 10 | codename="" 11 | host_ip="" 12 | private_ip="" 13 | host_name="" 14 | set_interface="" 15 | is_debug="" 16 | docker_node="" 17 | set_interface="" 18 | install_func=install_all 19 | pool="theonepool" 20 | mongohost="127.0.0.1" 21 | mongoport="27017" 22 | dockerhost="127.0.0.1" 23 | dockerport="2375" 24 | registryhost="" 25 | registryport="5000" 26 | adminuser="admin@example.com" 27 | adminpassword="admin123" 28 | install_tsuru_source=0 29 | tsuru_package_source="stable" 30 | hook_url=https://raw.githubusercontent.com/tsuru/tsuru/master/misc/git-hooks/pre-receive 31 | hook_name=pre-receive 32 | git_envs=(A=B) 33 | ext_repository="" 34 | export DEBIAN_FRONTEND=noninteractive 35 | 36 | declare -A DISTMAP=( 37 | [wheezy]=wheezy-backports 38 | [precise]=precise 39 | [saucy]=saucy 40 | [trusty]=trusty 41 | [utopic]=utopic 42 | ) 43 | 44 | TSURU_CONF=$(cat <&2 100 | } 101 | 102 | function running_port { 103 | local appname=$1 104 | running_addr "${appname}" | sed "s/.*://" 105 | } 106 | 107 | function running_addr { 108 | local appname=$1 109 | for _ in {1..30}; do 110 | sleep 0.5 111 | local addr=$(sudo netstat -tnlp | grep "${appname}" | tr -s " " | cut -d' ' -f 4 | sort | head -n1) 112 | if [[ $addr != "" ]]; then 113 | echo "${addr}" 114 | break 115 | fi 116 | echo "Waiting for ${appname}..." 1>&2 117 | done 118 | } 119 | 120 | function installed_version { 121 | local cmdid=${1-} 122 | local minversion=${2-} 123 | local version=${3-} 124 | local max_version=$(echo -e "${minversion}min\n$version" | sort -V | tail -n 1) 125 | local install_var=$(eval echo $`echo '{force_install_'`${cmdid}`echo '-}'`) 126 | if [[ $install_var != "1" && $max_version != "${minversion}min" ]]; then 127 | echo "${max_version}" 128 | fi 129 | } 130 | 131 | function get_inet_addr() { 132 | # Return IP address based on ifconfig's output 133 | /sbin/ifconfig | grep -A1 $1 2> /dev/null | grep "inet addr" | tail -n1 | \ 134 | sed "s/[^:]*:\([0-9.]*\).*/\1/" 135 | } 136 | 137 | function public_ip { 138 | # Try to take the public IP using AWS EC2's metadata API: 139 | local ip=$(curl -s -L -m2 -f http://169.254.169.254/latest/meta-data/public-ipv4 || true) 140 | 141 | # Try to use DigitalOcean's metadata API as fallback: 142 | if [[ "$ip" == "" || "$ip" == "not found" ]]; then 143 | ip=$(curl -s -L -m2 -f http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address || true) 144 | fi 145 | 146 | # Try via ifconfig 147 | if [[ "$ip" == "" || "$ip" == "not found" ]]; then 148 | ip=$(get_inet_addr eth) 149 | fi 150 | if [[ "$ip" == "" || "$ip" == "not found" ]]; then 151 | ip=$(get_inet_addr ens) 152 | fi 153 | if [[ "$ip" == "" || "$ip" == "not found" ]]; then 154 | ip=$(get_inet_addr venet0) 155 | fi 156 | if [[ "$ip" == "" || "$ip" == "not found" ]]; then 157 | ip=$(get_inet_addr wlan) 158 | fi 159 | 160 | # Try to access an external API to discover public IP 161 | if [[ "$ip" == "" || "$ip" == "not found" ]]; then 162 | ip=$(curl -s -L -m2 'https://api.ipify.org' || true) 163 | fi 164 | 165 | # Damn, it! 166 | if [[ "$ip" == "" || "$ip" == "not found" ]]; then 167 | error "Couldn't find a suitable public IP. Try using --host-ip option." 168 | exit 1 169 | fi 170 | 171 | echo "${ip}" 172 | } 173 | 174 | function local_ip { 175 | # Try to take the public IP using AWS EC2's metadata API: 176 | local ip=$(curl -s -L -m2 -f http://169.254.169.254/latest/meta-data/local-ipv4 || true) 177 | 178 | # Try to use DigitalOcean's metadata API as fallback: 179 | if [[ "$ip" == "" || "$ip" == "not found" ]]; then 180 | ip=$(curl -s -L -m2 -f http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address || true) 181 | fi 182 | 183 | if [[ "$ip" == "not found" ]]; then 184 | ip="" 185 | fi 186 | 187 | echo "${ip}" 188 | } 189 | 190 | function set_host { 191 | if [[ "$host_ip" && "$set_interface" ]]; then 192 | sudo ifconfig lo:0 $host_ip netmask 255.255.255.255 up 193 | fi 194 | if [[ $host_ip == "" ]]; then 195 | host_ip=$(public_ip) 196 | fi 197 | if [[ $host_ip == "127.0.0.1" ]]; then 198 | echo "Couldn't find suitable host_ip, please run with --host-ip " 199 | exit 1 200 | fi 201 | echo "Chosen host ip: $host_ip. You can override with --host-ip " 202 | 203 | if [[ $host_name == "" ]]; then 204 | host_name="$host_ip.nip.io" 205 | fi 206 | echo "$host_ip $host_name" | sudo tee -a /etc/hosts 207 | echo "Chosen host name: $host_name. You can override with --host-name " 208 | } 209 | 210 | function set_local_host { 211 | if [[ $private_ip == "" ]]; then 212 | private_ip=$(local_ip) 213 | fi 214 | if [[ $private_ip == "" ]]; then 215 | private_ip=$(public_ip) 216 | fi 217 | if [[ $private_ip == "127.0.0.1" ]]; then 218 | echo "Couldn't find suitable local_ip, please run with --host-ip " 219 | exit 1 220 | fi 221 | } 222 | 223 | function check_support { 224 | which apt-get > /dev/null 225 | if [ $? -ne 0 ]; then 226 | error "Error: apt-get should be available on the system" 227 | exit 1 228 | fi 229 | distid=$(lsb_release -is) 230 | release=$(lsb_release -rs) 231 | codename=$(lsb_release -cs) 232 | if [[ $distid == "Debian" && $(echo $release | awk '{printf("%d", $1)}') -lt 8 ]]; then 233 | error "Error: This script requires Debian release >= 8" 234 | fi 235 | echo "Detect ${distid} ${release} (${codename}), supported system" 236 | } 237 | 238 | function install_basic_deps { 239 | local tsuru_package_source=$1 240 | echo "Updating apt-get and installing basic dependencies (this could take a while)..." 241 | if [[ $distid == "Ubuntu" ]]; then 242 | sudo perl -i -pe 's/^# *(.+)(trusty|trusty-updates|trusty-security) multiverse$/$1$2 multiverse/gi' /etc/apt/sources.list 243 | fi 244 | sudo apt-get update 245 | sudo apt-get install linux-image-extra-$(uname -r) -qqy 246 | sudo apt-get install jq screen curl mercurial git bzr \ 247 | software-properties-common apt-transport-https -y 248 | if [[ $ext_repository ]]; then 249 | curl -sS ${ext_repository}/public.key | sudo apt-key add - 250 | echo "deb ${ext_repository} ${DISTMAP[$codename]} main contrib" | sudo tee /etc/apt/sources.list.d/tsuru-deb.list 251 | echo "deb-src ${ext_repository} ${DISTMAP[$codename]} main contrib" | sudo tee -a /etc/apt/sources.list.d/tsuru-deb.list 252 | else 253 | curl -s https://packagecloud.io/install/repositories/tsuru/${tsuru_package_source}/script.deb.sh | sudo bash 254 | fi 255 | sudo apt-get update 256 | } 257 | 258 | function install_docker { 259 | if [[ ${registryhost} == "" ]]; then 260 | registryhost=${dockerhost} 261 | fi 262 | local version=$(docker -v | awk -F '[ ,]+' '{ print $3 }') 263 | local iversion=$(installed_version docker 0.20.0 "${version}") 264 | if [[ $iversion != "" ]]; then 265 | echo "Skipping docker installation, version installed: $iversion" 266 | else 267 | echo "Installing docker..." 268 | curl -sSL https://get.docker.com/ | sudo sh 269 | fi 270 | if [[ `which systemctl` != "" ]] && [[ `systemctl is-system-running` != "offline" ]]; then 271 | sudo -E sh -c "mkdir -p /etc/systemd/system/docker.service.d" 272 | sudo -E sh -c "echo '[Service]\nExecStart=\nExecStart=/usr/bin/dockerd \$DOCKER_OPTS -H tcp://127.0.0.1:${dockerport} -H unix:///var/run/docker.sock --insecure-registry=${registryhost}:${registryport}' > /etc/systemd/system/docker.service.d/tsuru.conf" 273 | sudo systemctl daemon-reload 274 | else 275 | local opts=$(bash -c 'source /etc/default/docker && echo $DOCKER_OPTS') 276 | if [[ ! $opts =~ :// ]]; then 277 | echo "Changing /etc/default/docker to listen on tcp://127.0.0.1:${dockerport}..." 278 | echo "DOCKER_OPTS=\"\$DOCKER_OPTS -H tcp://127.0.0.1:${dockerport} -H unix:///var/run/docker.sock --insecure-registry=${registryhost}:${registryport}\"" | sudo tee -a /etc/default/docker > /dev/null 279 | fi 280 | fi 281 | sudo service docker stop 1>&2 2>/dev/null || true 282 | sudo service docker start 283 | sleep 5 284 | dockerport=$(running_port docker) 285 | if [[ $dockerport == "" ]]; then 286 | echo "Error: Couldn't find docker port, please check /var/log/upstart/docker.log for more information" 287 | echo "/var/log/upstart/docker.log contents:" 288 | cat /var/log/upstart/docker.log 289 | exit 1 290 | fi 291 | echo "docker found running at $dockerhost:$dockerport" 292 | local home_host=$(bash -ic 'source ~/.bashrc && echo $DOCKER_HOST') 293 | if [[ $home_host != "tcp://$dockerhost:$dockerport" ]]; then 294 | echo "Adding DOCKER_HOST to ~/.bashrc" 295 | echo -e "export DOCKER_HOST=tcp://$dockerhost:$dockerport" | tee -a ~/.bashrc > /dev/null 296 | fi 297 | export DOCKER_HOST=tcp://$dockerhost:$dockerport 298 | docker_node="$docker_node $dockerhost:$dockerport" 299 | } 300 | 301 | function install_docker_registry { 302 | echo "Installing docker-registry..." 303 | sudo mkdir -p /var/lib/registry 304 | docker rm -f registry || true 305 | docker run -d -p ${registryport}:${registryport} -e REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/var/lib/registry -v /var/lib/registry:/var/lib/registry --restart=always --name registry registry:2 306 | } 307 | 308 | function install_mongo { 309 | docker rm -f mongodb || true 310 | docker run -d -p 27017:27017 --net=host --restart=always --name mongodb mongo 311 | } 312 | 313 | function install_redis { 314 | docker rm -f redis || true 315 | docker run -d -p 6379:6379 --restart=always --name redis redis 316 | } 317 | 318 | function install_planb { 319 | docker rm -f tsuru_planb || true 320 | docker run -d --net=host --restart=always --name tsuru_planb tsuru/planb:v1 --listen ":80" 321 | } 322 | 323 | function install_gandalf { 324 | sudo apt-get install gandalf-server -y 325 | local hook_dir=/home/git/bare-template/hooks 326 | sudo mkdir -p $hook_dir 327 | sudo curl -sSL ${hook_url} -o ${hook_dir}/${hook_name} 328 | sudo chmod +x ${hook_dir}/${hook_name} 329 | sudo chown -R git:git /home/git/bare-template 330 | sudo sed "s/^\(host: \).*$/\1${host_name}/" /etc/gandalf.conf -i 331 | sudo sed "s/^#\(\s*template: \).*$/\1\/home\/git\/bare-template/" /etc/gandalf.conf -i 332 | sudo service gandalf-server stop 1>&2 2>/dev/null || true 333 | sudo service gandalf-server start 334 | sleep 5 335 | local gandalfaddr=$(running_addr gandalf) 336 | if [[ $gandalfaddr == "" ]]; then 337 | echo "Error: Couldn't find gandalf addr, please check /var/log/upstart/gandalf-server.log for more information" 338 | echo "/var/log/upstart/gandalf-server.log contents:" 339 | cat /var/log/upstart/gandalf-server.log 340 | exit 1 341 | fi 342 | echo "gandalf found running at $gandalfaddr" 343 | } 344 | 345 | function install_go { 346 | local version=$(go version 2>/dev/null | sed -e 's/go version[^0-9]*\([0-9.]*\).*/\1/') 347 | local iversion=$(installed_version go 1.1.0 "${version}") 348 | if [[ $iversion != "" ]]; then 349 | echo "Skipping go installation, version installed: $iversion" 350 | else 351 | echo "Installing go..." 352 | sudo apt-add-repository ppa:gophers/archive -y 353 | sudo apt-get update 354 | sudo apt-get install golang-1.8 -y 355 | echo -e "export PATH=$PATH:/usr/lib/go-1.8/bin" | tee -a ~/.bashrc > /dev/null 356 | export PATH=$PATH:/usr/lib/go-1.8/bin 357 | fi 358 | if [[ ${GOPATH-} == "" ]]; then 359 | export GOPATH=$HOME/go 360 | fi 361 | mkdir -p $GOPATH 362 | local bash_gopath=$(bash -ic 'unset GOPATH; source ~/.bashrc && echo $GOPATH') 363 | if [[ $bash_gopath != $GOPATH ]]; then 364 | echo "Adding GOPATH=$GOPATH to ~/.bashrc" 365 | echo -e "export GOPATH=$GOPATH" | tee -a ~/.bashrc > /dev/null 366 | fi 367 | } 368 | 369 | function install_test_deps { 370 | echo "Installing test dependencies..." 371 | sudo apt-get -y install xmlsec1 libsasl2-dev 372 | } 373 | 374 | function config_tsuru_pre { 375 | sudo mkdir -p /etc/tsuru 376 | echo "$TSURU_CONF" | sudo tee /etc/tsuru/tsuru.conf > /dev/null 377 | sudo sed -i.old -e "s/{{{HOST_IP}}}/${host_ip}/g" /etc/tsuru/tsuru.conf 378 | sudo sed -i.old -e "s/{{{PRIVATE_IP}}}/${dockerhost}/g" /etc/tsuru/tsuru.conf 379 | sudo sed -i.old -e "s/{{{REGISTRY_HOST}}}/${registryhost}/g" /etc/tsuru/tsuru.conf 380 | sudo sed -i.old -e "s/{{{HOST_NAME}}}/${host_name}/g" /etc/tsuru/tsuru.conf 381 | sudo sed -i.old -e "s/{{{MONGO_HOST}}}/${mongohost}/g" /etc/tsuru/tsuru.conf 382 | sudo sed -i.old -e "s/{{{MONGO_PORT}}}/${mongoport}/g" /etc/tsuru/tsuru.conf 383 | if [[ -e /etc/default/tsuru-server ]]; then 384 | sudo sed -i.old -e 's/=no/=yes/' /etc/default/tsuru-server 385 | fi 386 | } 387 | 388 | function config_tsuru_post { 389 | tsuru target-remove default 390 | tsuru target-add default "${private_ip}:8080" || true 391 | tsuru target-set default 392 | } 393 | 394 | function create_initial_user { 395 | echo "Creating initial admin user..." 396 | yes $adminpassword | tsurud root-user-create $adminuser || true 397 | yes $adminpassword | tsuru login $adminuser 398 | tsuru team-create admin || true 399 | } 400 | 401 | function enable_initial_user { 402 | mkdir -p ~/.ssh 403 | if ! grep -Pzo "Host ${private_ip}\s+StrictHostKeyChecking no" ~/.ssh/config >/dev/null; then 404 | echo -e "Host ${private_ip}\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config 405 | fi 406 | if ! grep -Pzo "Host ${private_ip}\s+StrictHostKeyChecking no" ~/.ssh/config >/dev/null; then 407 | echo -e "Host ${private_ip}\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config 408 | fi 409 | if [[ ! -e ~/.ssh/id_rsa ]]; then 410 | yes | ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa > /dev/null 411 | fi 412 | tsuru key-add -f rsa ~/.ssh/id_rsa.pub || true 413 | } 414 | 415 | function add_default_roles { 416 | tsuru role-add team-create global || true 417 | tsuru role-permission-add team-create role.update team.create || true 418 | 419 | tsuru role-add team-member team || true 420 | tsuru role-permission-add team-member app service-instance team || true 421 | 422 | tsuru role-default-add --team-create team-member || true 423 | tsuru role-default-add --user-create team-create || true 424 | } 425 | 426 | function add_as_docker_node { 427 | echo "Adding docker node to pool..." 428 | tsuru pool-add $pool -p -d 2>/dev/null || tsuru pool-add $pool 2>/dev/null || true 429 | amount=0 430 | for node in $docker_node; do 431 | tsuru node-add --register address="http://${node}" pool=$pool 2>/dev/null || true 432 | amount=$((amount+1)) 433 | done 434 | set +e 435 | status=1 436 | while [ $status != 0 ]; do 437 | tsuru node-list | grep "| http://" | grep ready | wc -l | grep -q "${amount}$" 438 | status=$? 439 | done 440 | set -e 441 | } 442 | 443 | function install_platform { 444 | echo "Installing platform container..." 445 | local has_plat=$((tsuru platform-list | grep "${1}"$) || true) 446 | if [[ ${has_plat} == "" ]]; then 447 | tsuru platform-add ${1} -i "tsuru/${1}" 448 | fi 449 | } 450 | 451 | function install_dashboard { 452 | echo "Installing tsuru-dashboard..." 453 | tsuru app-create tsuru-dashboard python -o $pool -t admin || true 454 | pushd ~/ 455 | if [[ ! -d ~/tsuru-dashboard ]]; then 456 | git clone https://github.com/tsuru/tsuru-dashboard 457 | fi 458 | pushd tsuru-dashboard 459 | git remote add tsuru "git@${private_ip}:tsuru-dashboard.git" || true 460 | git reset --hard 461 | git clean -dfx 462 | git pull 463 | git push tsuru master 464 | popd 465 | popd 466 | } 467 | 468 | function install_tsuru_pkg { 469 | echo "Installing Tsuru from deb package..." 470 | sudo apt-get install tsuru-server tsuru-client -y 471 | 472 | sudo service tsurud stop >/dev/null 2>&1 || true 473 | config_tsuru_pre 474 | sudo service tsurud start 475 | 476 | sleep 5 477 | } 478 | 479 | function install_tsuru_client { 480 | echo "Installing Tsuru client from deb package..." 481 | sudo apt-get install tsuru-client -qqy 482 | } 483 | 484 | function install_tsuru_src { 485 | echo "Installing Tsuru from source (this could take some minutes)..." 486 | if [[ -e ${GOPATH}/src/github.com/tsuru/tsuru ]]; then 487 | pushd "${GOPATH}/src/github.com/tsuru/tsuru" 488 | git reset --hard && git clean -dfx && git pull 489 | popd 490 | else 491 | mkdir -p "${GOPATH}/src/github.com/tsuru/tsuru" 492 | pushd "${GOPATH}/src/github.com/tsuru/tsuru" 493 | git clone https://github.com/tsuru/tsuru . 494 | popd 495 | fi 496 | go get github.com/tsuru/tsuru/cmd/tsurud 497 | go get github.com/tsuru/tsuru-client/tsuru 498 | sudo cp $(echo "${GOPATH}" | awk -F ':' '{print $1}')/bin/{tsurud,tsuru} /usr/local/bin 499 | 500 | screen -X -S api quit || true 501 | screen -S api -d -m tsurud api --config=/etc/tsuru/tsuru.conf 502 | 503 | local tsurudaddr=$(running_addr tsurud) 504 | if [[ $tsurudaddr == "" ]]; then 505 | echo "Error: Couldn't find tsurud addr, please check /var/log/syslog for more information" 506 | exit 1 507 | fi 508 | echo "tsurud api found running at $tsurudaddr" 509 | } 510 | 511 | function config_git_key { 512 | local tsuru_token=$(bash -ic 'source ~git/.bash_profile && echo $TSURU_TOKEN') 513 | if [[ $tsuru_token == "" ]]; then 514 | echo "Adding tsurud token to ~git/.bash_profile" 515 | local token=$(tsurud token || tsr token) 516 | echo "export TSURU_TOKEN=$token" | sudo tee -a ~git/.bash_profile > /dev/null 517 | fi 518 | local tsuru_host=$(bash -ic 'source ~git/.bash_profile && echo $TSURU_HOST') 519 | if [[ $tsuru_host != "$private_ip:8080" ]]; then 520 | echo "Adding tsurud host to ~git/.bash_profile" 521 | echo "export TSURU_HOST=$private_ip:8080" | sudo tee -a ~git/.bash_profile > /dev/null 522 | fi 523 | sudo chown -R git:git ~git/.bash_profile 524 | } 525 | 526 | function add_git_envs { 527 | if [[ "${#git_envs[@]}" -gt 1 ]]; then 528 | echo "Serializing provided env vars to ~git/.bash_profile" 529 | echo export ${git_envs[@]:1} | sudo tee -a ~git/.bash_profile > /dev/null 530 | fi 531 | } 532 | 533 | function banner_ansii { 534 | echo -e ' \x1B[38;2;37;184;108mo. \x1B[0m' 535 | echo -e ' _ \x1B[38;2;37;184;108m:8o. .:: \x1B[0m' 536 | echo -e ' | |_ ___ _ _ _ __ _ _ \x1B[38;2;37;184;108m.888o .o: . \x1B[0m' 537 | echo -e ' | __/ __| | | | \047__| | | | \x1B[38;2;37;184;108mO888O: .oO: \x1B[0m' 538 | echo -e ' | |_\__ \ |_| | | | |_| | \x1B[38;2;37;184;108mO88888O. :O8O. \x1B[0m' 539 | echo -e ' \__|___/\__,_|_| \__,_| \x1B[38;2;37;184;108mO8888888OoOo \x1B[0m' 540 | echo -e ' \x1B[38;2;37;184;108m.O88888888o: \x1B[0m' 541 | } 542 | 543 | function install_all { 544 | check_support 545 | install_basic_deps ${tsuru_package_source-"stable"} 546 | set_local_host 547 | set_host 548 | install_docker 549 | if [[ "${registryhost}" == "${dockerhost}" ]]; then 550 | install_docker_registry 551 | fi 552 | install_redis 553 | install_mongo 554 | install_planb 555 | install_gandalf 556 | if [[ ${install_tsuru_source-} == "1" ]]; then 557 | config_tsuru_pre 558 | install_go 559 | install_tsuru_src 560 | install_test_deps 561 | else 562 | install_tsuru_pkg 563 | fi 564 | config_tsuru_post 565 | config_git_key 566 | add_git_envs 567 | create_initial_user 568 | enable_initial_user 569 | add_default_roles 570 | add_as_docker_node 571 | install_platform python 572 | install_platform static 573 | if [[ ${without_dashboard-} != "1" ]]; then 574 | install_dashboard 575 | fi 576 | 577 | echo '######################## DONE! ########################' 578 | echo 579 | banner_ansii 580 | echo 581 | echo "Some information about your tsuru installation:" 582 | echo 583 | echo "Admin user: ${adminuser}" 584 | echo "Admin password: ${adminpassword} (PLEASE CHANGE RUNNING: tsuru change-password)" 585 | echo "Target address: http://$host_ip:8080" 586 | if [[ ${without_dashboard-} != "1" ]]; then 587 | local cont_id=$(docker ps | grep tsuru-dashboard | cut -d ' ' -f 1) 588 | local dashboard_port=$(docker inspect $cont_id | grep HostPort | head -n1 | sed "s/[^0-9]//g") 589 | echo "Dashboard address: http://$host_ip:$dashboard_port" 590 | echo 591 | echo "You should run \`source ~/.bashrc\` on your current terminal." 592 | echo 593 | echo "Installed apps:" 594 | sleep 1 595 | tsuru app-list 596 | fi 597 | } 598 | 599 | function install_server { 600 | check_support 601 | install_basic_deps ${tsuru_package_source-"stable"} 602 | set_local_host 603 | set_host 604 | install_docker 605 | if [[ "${registryhost}" == "${dockerhost}" ]]; then 606 | install_docker_registry 607 | fi 608 | install_redis 609 | install_mongo 610 | install_planb 611 | install_gandalf 612 | install_tsuru_pkg 613 | config_tsuru_post 614 | config_git_key 615 | add_git_envs 616 | create_initial_user 617 | enable_initial_user 618 | add_default_roles 619 | add_as_docker_node 620 | install_platform python 621 | 622 | echo '######################## DONE! ########################' 623 | echo 624 | banner_ansii 625 | echo 626 | echo "Some information about your tsuru installation:" 627 | echo 628 | echo "Admin user: ${adminuser}" 629 | echo "Admin password: ${adminpassword} (PLEASE CHANGE RUNNING: tsuru change-password)" 630 | echo "Target address: $host_ip:8080" 631 | } 632 | 633 | function install_client { 634 | check_support 635 | install_basic_deps ${tsuru_package_source-"stable"} 636 | set_local_host 637 | set_host 638 | install_tsuru_client 639 | config_tsuru_post 640 | enable_initial_user 641 | add_default_roles 642 | if [[ ${without_dashboard-} != "1" ]]; then 643 | install_dashboard 644 | fi 645 | 646 | echo '######################## DONE! ########################' 647 | echo 648 | banner_ansii 649 | echo 650 | echo "Some information about your tsuru installation:" 651 | echo 652 | echo "Admin user: ${adminuser}" 653 | echo "Admin password: ${adminpassword} (PLEASE CHANGE RUNNING: tsuru change-password)" 654 | echo "Target address: $host_ip:8080" 655 | if [[ ${without_dashboard-} != "1" ]]; then 656 | local cont_id=$(docker ps | grep tsuru-dashboard | cut -d ' ' -f 1) 657 | local dashboard_port=$(docker inspect $cont_id | grep HostPort | head -n1 | sed "s/[^0-9]//g") 658 | echo "Dashboard address: $host_ip:$dashboard_port" 659 | echo 660 | echo "You should run \`source ~/.bashrc\` on your current terminal." 661 | echo 662 | echo "Installed apps:" 663 | sleep 1 664 | tsuru app-list 665 | echo "Make sure that both ports 8080/tcp and 80/tcp are accessible remotely." 666 | fi 667 | } 668 | 669 | function install_dockerfarm { 670 | check_support 671 | install_basic_deps ${tsuru_package_source-"stable"} 672 | set_local_host 673 | set_host 674 | dockerhost=$(local_ip) 675 | if [[ $dockerhost == "" ]]; then 676 | dockerhost=$(public_ip) 677 | fi 678 | install_docker 679 | install_tsuru_client 680 | config_tsuru_post 681 | enable_initial_user 682 | add_default_roles 683 | add_as_docker_node 684 | } 685 | 686 | function install_exportvars { 687 | declare -p 688 | } 689 | 690 | function show_help { 691 | PROGRAM_NAME=$(basename $0) 692 | echo -e "Usage: $PROGRAM_NAME [options] 693 | 694 | Options: 695 | 696 | -n, --host-name [name] Set the VM's hostname 697 | -i, --host-ip [name] Set the VM's IP 698 | -pi, --private-ip [name] Set the VM's private IP 699 | -c, --tsuru-from-source Install tsuru from master source code (default: stable packages) 700 | -p, --tsuru-pkg-stable Install tsuru from stable packages 701 | -N, --tsuru-pkg-nightly Install tsuru from nightly build packages (default: stable packages) 702 | -f, --force-install [pkg] Force installation of named package 703 | -g, --gopath [path] prepend new path to env var GOPATH 704 | -u, --hook-url [url] Git hook URL 705 | -o, --hook-name [name] Git hook name 706 | -e, --env [key] [value] Set environment variable for git user in the VM 707 | -r, --ext-repository [repo] Set the external repository URL produced by tsuru/tsuru-deb 708 | -d, --docker-only Only install docker (default: docker, dashboard) 709 | -w, --without-dashboard Install without dashboard (default: with dashboard) 710 | -I, --set-interface The IP provided by --host-ip is not really allocated to this VM, 711 | use ifconfig to set up an interface so it can be reached 712 | -D, --docker-node [node1] [node2] ... 713 | Add extra docker nodes to tsuru server for building clusters 714 | -t, --template [name] Install template, name options: 715 | - all: install all packages (default) 716 | - dockerfarm: install docker only 717 | - server: install mongo, planb, gandalf, archiver, tsuru-server 718 | and their dependencies 719 | - client: install tsuru-client and their dependencies 720 | -v, --verbose Print debug messages 721 | -P, --docker-pool [name] Add docker to destination pool of tsuru (default: theonepool) 722 | -R, --registryhost Set the docker registry IP 723 | -sd, --systemd Set systemd as init system 724 | -h, --help This help screen 725 | " 726 | } 727 | 728 | while [ "${1-}" != "" ]; do 729 | case $1 in 730 | "-v" | "--verbose") 731 | set -x 732 | is_debug=1 733 | ;; 734 | "-P" | "--docker-pool") 735 | shift 736 | pool=$1 737 | ;; 738 | "-I" | "--set-interface") 739 | set_interface="y" 740 | ;; 741 | "-D" | "--docker-node") 742 | while [ "${2-}" != "" ]; do 743 | shift 744 | [[ ${1:0:1} != "-" ]] || break 745 | docker_node="$docker_node $1" 746 | done 747 | ;; 748 | "-t" | "--template") 749 | shift 750 | install_func=install_$1 751 | ;; 752 | "-n" | "--host-name") 753 | shift 754 | host_name=$1 755 | ;; 756 | "-i" | "--host-ip") 757 | shift 758 | host_ip=$1 759 | ;; 760 | "-pi" | "--private-ip") 761 | shift 762 | private_ip=$1 763 | ;; 764 | "-c" | "--tsuru-from-source") 765 | install_tsuru_source=1 766 | ;; 767 | "-p" | "--tsuru-pkg-stable") 768 | tsuru_package_source="stable" 769 | install_tsuru_pkg=1 770 | ;; 771 | "-f" | "--force-install") 772 | shift 773 | declare "force_install_$1=1" 774 | ;; 775 | "-g" | "--gopath") 776 | shift 777 | mkdir -p $1 778 | if [[ -v GOPATH ]]; then 779 | export GOPATH=$1:$GOPATH 780 | else 781 | export GOPATH=$1 782 | fi 783 | ;; 784 | "-u" | "--hook-url") 785 | shift 786 | hook_url=$1 787 | ;; 788 | "-o" | "--hook-name") 789 | shift 790 | hook_name=$1 791 | ;; 792 | "-e" | "--env") 793 | shift 794 | git_envs=("${git_envs[@]}" "$1=\"$2\"") 795 | shift 796 | ;; 797 | "-r" | "--ext-repository") 798 | shift 799 | ext_repository=$1 800 | ;; 801 | "-d" | "--docker-only") 802 | install_func=install_docker 803 | ;; 804 | "-w" | "--without-dashboard") 805 | without_dashboard=1 806 | ;; 807 | "-R" | "--registryhost") 808 | shift 809 | registryhost=$1 810 | ;; 811 | * | "-h" | "--help") 812 | show_help 813 | exit 814 | ;; 815 | 816 | esac 817 | shift 818 | done 819 | 820 | $install_func 821 | --------------------------------------------------------------------------------