summaryrefslogtreecommitdiffstats
path: root/node-admin/scripts/config-server.sh
blob: 60b05d4b3cd96101b2b9e8f40ab0ab44e7cb2aa1 (plain) (blame)
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
#!/bin/bash
# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

set -e

source "${0%/*}/common.sh"

declare CONTAINER_ROOT_DIR="$APPLICATION_STORAGE_ROOT/$CONFIG_SERVER_CONTAINER_NAME"

function Usage {
    UsageHelper "$@" <<EOF
Usage: $SCRIPT_NAME <command> [--wait]
Manage the Config Server

Commands:
  start     Start the Config Server in a Docker container
  stop      Remove the Config Server container
  restart   Stop, then start

Options:
  --hv-env <env>
            Start the config server with the given hosted Vespa environment
            name. Must be one of prod, dev, test, staging, etc. Default is
            $DEFAULT_HOSTED_VESPA_ENVIRONMENT.
  --hv-region <region>
            Start the config server with the given hosted Vespa region name.
            Default is $DEFAULT_HOSTED_VESPA_REGION.
  --wait true
            Make start wait until the Config Server is healthy
EOF
}

function Stop {
    # Prime sudo
    sudo true

    echo -n "Removing $CONFIG_SERVER_CONTAINER_NAME container... "
    docker rm -f "$CONFIG_SERVER_CONTAINER_NAME" &>/dev/null || true
    echo done

    if [ -d "$CONTAINER_ROOT_DIR" ]
    then
        # Double-check we're not 'rm -rf' something unexpected!
        if ! [[ "$CONTAINER_ROOT_DIR" =~ ^/home/docker/container-storage/ ]]
        then
            Fail "DANGEROUS: Almost removed '$CONTAINER_ROOT_DIR'..."
        fi

        echo -n "Removing container dir $CONTAINER_ROOT_DIR... "
        sudo rm -rf "$CONTAINER_ROOT_DIR"
        # The next two statements will prune empty parent directories.
        sudo mkdir "$CONTAINER_ROOT_DIR"
        sudo rmdir --ignore-fail-on-non-empty -p "$CONTAINER_ROOT_DIR"
        echo done
    fi
}

function Start {
    # Prime sudo
    sudo true

    local wait="${OPTION_WAIT:-true}"
    case "$wait" in
        true|false) : ;;
        *) Usage "--wait should only be set to true or false" ;;
    esac

    local region="${OPTION_HV_REGION:-$DEFAULT_HOSTED_VESPA_REGION}"
    local environment="${OPTION_HV_ENV:-$DEFAULT_HOSTED_VESPA_ENVIRONMENT}"

    echo -n "Creating container dir $CONTAINER_ROOT_DIR... "
    local shared_dir_on_localhost="$APPLICATION_STORAGE_ROOT/$CONFIG_SERVER_CONTAINER_NAME/$ROOT_DIR_SHARED_WITH_HOST"
    sudo mkdir -p "$shared_dir_on_localhost"
    sudo chmod a+wt "$shared_dir_on_localhost"
    echo done

    # Start config server
    echo -n "Making $CONFIG_SERVER_CONTAINER_NAME container... "
    local config_server_container_id
    config_server_container_id=$(\
        docker run \
               --detach \
               --cap-add=NET_ADMIN \
               --net=none \
               --hostname "$CONFIG_SERVER_HOSTNAME" \
               --name "$CONFIG_SERVER_CONTAINER_NAME" \
               --volume "/etc/hosts:/etc/hosts" \
               --volume "$shared_dir_on_localhost:/$ROOT_DIR_SHARED_WITH_HOST" \
               --env "HOSTED_VESPA_REGION=$region" \
               --env "HOSTED_VESPA_ENVIRONMENT=$environment" \
               --env "CONFIG_SERVER_HOSTNAME=$CONFIG_SERVER_HOSTNAME" \
               --env "HOST_BRIDGE_IP=$HOST_BRIDGE_IP" \
               --entrypoint /usr/local/bin/start-config-server.sh \
               "$DOCKER_IMAGE")
    echo done

    echo -n "Verifying that $CONFIG_SERVER_CONTAINER_NAME container is running... "
    local config_server_container_pid
    config_server_container_pid=$(docker inspect -f '{{.State.Pid}}' "$CONFIG_SERVER_CONTAINER_NAME")

    echo -n "(pid $config_server_container_pid) "

    # TODO: Use .State.Status instead (only supported from version 1.9).
    local config_server_container_running
    config_server_container_running=$(docker inspect -f '{{.State.Running}}' "$CONFIG_SERVER_CONTAINER_NAME")

    if [ "$config_server_container_pid" == 0 -o "$config_server_container_running" != true ]
    then
        echo "failed"
        Fail "The Config Server is not running anymore, consider looking" \
             "at the logs with 'docker logs $CONFIG_SERVER_CONTAINER_NAME'"
    fi
    echo "done"

    echo -n "Setting up the $CONFIG_SERVER_CONTAINER_NAME container network of type $NETWORK_TYPE... "
    if ! script_out=$(sudo ./configure-container-networking.py --"$NETWORK_TYPE" "$config_server_container_pid" "$CONFIG_SERVER_IP" 2>&1); then
        echo "failed"
        echo "$script_out"
        exit
    fi
    echo "done"

    if [ "$wait" == true ]
    then
        # Wait for config server to come up
        echo -n "Waiting for healthy Config Server (~30s)"
        local url="http://$CONFIG_SERVER_HOSTNAME:19071/state/v1/health"
        while ! curl --silent --fail --max-time 1 "$url" >/dev/null
        do
            echo -n .
            sleep 2
        done
        echo " done"
    fi
}

# Makes it easier to access scripts in the same 'scripts' directory
cd "$SCRIPT_DIR"

Main "$@"