blob: e6d71fd0f75086def6c8266184b2b125b356172e [file] [log] [blame]
Bogdan Caprita151ee8d2014-10-29 16:37:33 -07001#!/bin/bash
2#
3# Installs node manager on the local machine.
4#
5# Specifically:
6#
7# 1. Fetches the binaries required for a node manager installation from a few
8# possible sources.
9#
10# 2. Sets up the helper with setuid. The helper binary needs to be owned by
11# root and have the suid bit set, to enable the node manager to run binaries
12# under different system accounts than itself.
13#
14# 3. Runs the self-install command on the node manager.
15#
16# Usage:
17#
Bogdan Caprita99d45cc2014-10-30 10:16:25 -070018# # Gets binaries from local repository
Bogdan Caprita151ee8d2014-10-29 16:37:33 -070019# ./nminstall <install parent dir>
20#
21# # Gets binaries from local filesystem
22# ./nminstall <install parent dir> /path/to/binaries
23#
Bogdan Caprita7f85cfa2014-11-04 11:08:03 -080024# # Gets binaries from HTTP server
Bogdan Caprita151ee8d2014-10-29 16:37:33 -070025# ./nminstall <install parent dir> http://host/path
26
27set -e
28
29usage() {
30 echo "usage:"
31 echo "./nminstall <install parent dir> [<binary source>]"
32}
33
Bogdan Capritad1748462014-11-08 16:49:46 -080034readonly BIN_NAMES=(noded suidhelper agentd)
Bogdan Caprita151ee8d2014-10-29 16:37:33 -070035
Bogdan Caprita99d45cc2014-10-30 10:16:25 -070036###############################################################################
37# Copies one binary from source to destination.
38# Arguments:
39# name of the binary
40# source dir of binary
41# destination dir of binary
42# Returns:
43# None
44###############################################################################
45copy_binary() {
46 local -r BIN_NAME="$1"
47 local -r BIN_SRC_DIR="$2"
48 local -r BIN_DEST_DIR="$3"
49 local -r SOURCE="${BIN_SRC_DIR}/${BIN_NAME}"
50 if [[ -x "${SOURCE}" ]]; then
51 local -r DESTINATION="${BIN_DEST_DIR}/${BIN_NAME}"
52 cp "${SOURCE}" "${DESTINATION}"
53 chmod 700 "${DESTINATION}"
54 else
55 echo "couldn't find ${SOURCE}"
56 exit 1
57 fi
58}
59
60###############################################################################
Bogdan Caprita151ee8d2014-10-29 16:37:33 -070061# Fetches binaries needed by node manager installation.
62# Globals:
63# BIN_NAMES
64# VEYRON_ROOT
65# Arguments:
66# destination for binaries
67# source of binaries
68# Returns:
69# None
Bogdan Caprita99d45cc2014-10-30 10:16:25 -070070###############################################################################
Bogdan Caprita151ee8d2014-10-29 16:37:33 -070071get_binaries() {
72 local -r BIN_INSTALL="$1"
73 local -r BIN_SOURCE="$2"
74
75 local bin_names_str=""
Bogdan Caprita7f85cfa2014-11-04 11:08:03 -080076 for bin_name in "${BIN_NAMES[@]}"; do
Bogdan Caprita151ee8d2014-10-29 16:37:33 -070077 bin_names_str+=" ${bin_name}"
78 done
Bogdan Caprita7f85cfa2014-11-04 11:08:03 -080079
Bogdan Caprita151ee8d2014-10-29 16:37:33 -070080 # If source is not specified, try to look for it in the repository.
81 if [[ -z "${BIN_SOURCE}" ]]; then
82 if [[ -z "${VEYRON_ROOT}" ]]; then
83 echo 'ERROR: binary source not specified and no local repository available'
84 exit 1
85 fi
86 local -r REPO_BIN_DIR="${VEYRON_ROOT}/veyron/go/bin"
Bogdan Caprita99d45cc2014-10-30 10:16:25 -070087 echo "Fetching binaries:${bin_names_str} from build repository: ${REPO_BIN_DIR} ..."
Bogdan Caprita7f85cfa2014-11-04 11:08:03 -080088 for bin_name in "${BIN_NAMES[@]}"; do
Bogdan Caprita99d45cc2014-10-30 10:16:25 -070089 copy_binary "${bin_name}" "${REPO_BIN_DIR}" "${BIN_INSTALL}"
Bogdan Caprita151ee8d2014-10-29 16:37:33 -070090 done
Bogdan Caprita151ee8d2014-10-29 16:37:33 -070091 return
92 fi
93
Bogdan Caprita99d45cc2014-10-30 10:16:25 -070094 # If the source is specified as an existing local filesystem path,
95 # look for the binaries there.
96 if [[ -d "${BIN_SOURCE}" ]]; then
97 echo "Fetching binaries:${bin_names_str} locally from: ${BIN_SOURCE} ..."
Bogdan Caprita7f85cfa2014-11-04 11:08:03 -080098 for bin_name in "${BIN_NAMES[@]}"; do
Bogdan Caprita99d45cc2014-10-30 10:16:25 -070099 copy_binary "${bin_name}" "${BIN_SOURCE}" "${BIN_INSTALL}"
100 done
101 return
102 fi
103
Bogdan Caprita7f85cfa2014-11-04 11:08:03 -0800104 # If the source looks like a URL, use HTTP to fetch.
105 local -r URL_REGEXP='^(https?|ftp|file)://'
106 if [[ "${BIN_SOURCE}" =~ ${URL_REGEXP} ]]; then
107 echo "Fetching binaries:${bin_names_str} remotely from: ${BIN_SOURCE} ..."
108 for bin_name in "${BIN_NAMES[@]}"; do
109 local DEST="${BIN_INSTALL}/${bin_name}"
110 curl -f -o "${DEST}" "${BIN_SOURCE}/${bin_name}"
111 chmod 700 "${DEST}"
112 done
113 return
114 fi
115
Bogdan Caprita151ee8d2014-10-29 16:37:33 -0700116 echo 'ERROR: couldn'"'"'t fetch binaries.'
117 exit 1
118}
119
120main() {
121 local -r INSTALL_PARENT_DIR="$1"
122 if [[ -z "${INSTALL_PARENT_DIR}" ]]; then
123 echo 'No local install destination specified!'
124 usage
125 exit 1
126 fi
127
128 if [[ ! -d "${INSTALL_PARENT_DIR}" ]]; then
129 echo "${INSTALL_PARENT_DIR} is not a directory!"
130 exit 1
131 fi
132
133 local -r INSTALL_DIR="${INSTALL_PARENT_DIR}/node_manager"
134
135 # TODO(caprita): Check that the node manager is not already installed before
136 # proceeding. We should require an explicit uninstall to avoid wiping away
137 # the node manager accidentally.
138 sudo rm -rf "${INSTALL_DIR}"
139 mkdir -m 700 "${INSTALL_DIR}"
140
141 local -r BIN_INSTALL="${INSTALL_DIR}/bin"
142 mkdir -m 700 "${BIN_INSTALL}"
143
144 # Fetch the binaries.
145 local -r BIN_SOURCE="$2"
146 get_binaries "${BIN_INSTALL}" "${BIN_SOURCE}"
Bogdan Caprita7f85cfa2014-11-04 11:08:03 -0800147 for bin_name in "${BIN_NAMES[@]}"; do
148 local BINARY="${BIN_INSTALL}/${bin_name}"
149 if [[ ! -s "${BINARY}" ]]; then
150 echo "${BINARY} is empty."
151 exit 1
152 fi
153 done
Bogdan Caprita99d45cc2014-10-30 10:16:25 -0700154 echo "Binaries are in ${BIN_INSTALL}."
Bogdan Caprita151ee8d2014-10-29 16:37:33 -0700155
156 # Set up the suidhelper.
157 echo "Configuring suidhelper ..."
158 local -r SETUID_SCRIPT="${BIN_INSTALL}/suidhelper"
159 sudo bash -c "chown root:root \"${SETUID_SCRIPT}\"; chmod 4551 \"${SETUID_SCRIPT}\""
160 echo "Suidhelper configured."
161
162 # Tell the node manager to install itself.
163 local -r NM_ROOT="${INSTALL_DIR}/nmroot"
164 echo "Installing node manager under ${NM_ROOT} ..."
Bogdan Capritad1748462014-11-08 16:49:46 -0800165 local -r PUBLISH=$(hostname)
Bogdan Capritae20f8d42014-11-12 11:32:29 -0800166 VEYRON_NM_CURRENT="${INSTALL_DIR}/noded.curr" VEYRON_NM_ROOT="${NM_ROOT}" VEYRON_NM_HELPER="${SETUID_SCRIPT}" "${BIN_INSTALL}/noded" --install_self --name="${PUBLISH}"
Bogdan Caprita151ee8d2014-10-29 16:37:33 -0700167 echo "Node manager installed."
Bogdan Capritae20f8d42014-11-12 11:32:29 -0800168
169 local -r SECURITY_DIR="${INSTALL_DIR}/security"
170 mkdir -m 700 "${SECURITY_DIR}"
171 local -r PRINCIPAL_DIR="${SECURITY_DIR}/principal"
172 mkdir -m 700 "${PRINCIPAL_DIR}"
173 local -r AGENT_KEY_DIR="${SECURITY_DIR}/keys"
174 mkdir -m 700 "${AGENT_KEY_DIR}"
175
176 # Run node manager under the security agent.
177 echo
178 echo "Running:"
179 echo "VEYRON_CREDENTIALS=\"${PRINCIPAL_DIR}\" \"${BIN_INSTALL}/agentd\" --additional_principals=\"${AGENT_KEY_DIR}\" \"${INSTALL_DIR}/noded.curr\""
180 echo
181 # NOTE: If you update the command below, please also update the command echoed
182 # above to keep the two in sync.
183 VEYRON_CREDENTIALS="${PRINCIPAL_DIR}" "${BIN_INSTALL}/agentd" --additional_principals="${AGENT_KEY_DIR}" "${INSTALL_DIR}/noded.curr"
Bogdan Caprita151ee8d2014-10-29 16:37:33 -0700184}
185
186main "$@"