forked from openstack-archive/ec2-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinstall.sh
executable file
·336 lines (295 loc) · 10.3 KB
/
install.sh
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#!/bin/bash -e
#Parameters to configure
SERVICE_USERNAME=ec2api
SERVICE_PASSWORD=ec2api
SERVICE_TENANT=service
# this domain name will be used for project and user
SERVICE_DOMAIN_NAME=Default
EC2API_PORT=8788
CONNECTION="mysql://ec2api:[email protected]/ec2api?charset=utf8"
LOG_DIR=/var/log/ec2api
CONF_DIR=/etc/ec2api
NOVA_CONF=/etc/nova/nova.conf
SIGNING_DIR=/var/cache/ec2api
CONF_FILE=$CONF_DIR/ec2api.conf
APIPASTE_FILE=$CONF_DIR/api-paste.ini
AUTH_CACHE_DIR=${AUTH_CACHE_DIR:-/var/cache/ec2api}
CACHE_BACKEND='oslo_cache.dict'
#Check for environment
if [[ -z "$OS_AUTH_URL" || -z "$OS_USERNAME" || -z "$OS_PASSWORD" ]]; then
echo "Please set OS_AUTH_URL, OS_USERNAME, OS_PASSWORD"
exit 1
fi
if [[ -z "$OS_TENANT_NAME" && -z "$OS_PROJECT_NAME" ]]; then
echo "Please set OS_TENANT_NAME or OS_PROJECT_NAME"
exit 1
fi
#### utilities functions merged from devstack to check required parameter is not empty
# Prints line number and "message" in error format
# err $LINENO "message"
function err() {
local exitcode=$?
errXTRACE=$(set +o | grep xtrace)
set +o xtrace
local msg="[ERROR] ${BASH_SOURCE[2]}:$1 $2"
echo $msg 1>&2;
if [[ -n ${SCREEN_LOGDIR} ]]; then
echo $msg >> "${SCREEN_LOGDIR}/error.log"
fi
$errXTRACE
return $exitcode
}
# Prints backtrace info
# filename:lineno:function
function backtrace {
local level=$1
local deep=$((${#BASH_SOURCE[@]} - 1))
echo "[Call Trace]"
while [ $level -le $deep ]; do
echo "${BASH_SOURCE[$deep]}:${BASH_LINENO[$deep-1]}:${FUNCNAME[$deep-1]}"
deep=$((deep - 1))
done
}
# Prints line number and "message" then exits
# die $LINENO "message"
function die() {
local exitcode=$?
set +o xtrace
local line=$1; shift
if [ $exitcode == 0 ]; then
exitcode=1
fi
backtrace 2
err $line "$*"
exit $exitcode
}
# Checks an environment variable is not set or has length 0 OR if the
# exit code is non-zero and prints "message" and exits
# NOTE: env-var is the variable name without a '$'
# die_if_not_set $LINENO env-var "message"
function die_if_not_set() {
local exitcode=$?
FXTRACE=$(set +o | grep xtrace)
set +o xtrace
local line=$1; shift
local evar=$1; shift
if ! is_set $evar || [ $exitcode != 0 ]; then
die $line "$*"
fi
$FXTRACE
}
# Test if the named environment variable is set and not zero length
# is_set env-var
function is_set() {
local var=\$"$1"
eval "[ -n \"$var\" ]" # For ex.: sh -c "[ -n \"$var\" ]" would be better, but several exercises depends on this
}
#######################################
get_data() {
local match_column=$(($1 + 1))
local regex="$2"
local output_column=$(($3 + 1))
shift 3
output=$("$@" | \
awk -F'|' \
"! /^\+/ && \$${match_column} ~ \"^ *${regex} *\$\" \
{ print \$${output_column} }")
echo "$output"
}
get_id () {
get_data 1 id 2 "$@"
}
get_user() {
local username=$1
local user_id=$(openstack user show $username -f value -c id 2>/dev/null)
if [ -n "$user_id" ]; then
echo "Found existing $username user" >&2
echo $user_id
else
echo "Creating $username user..." >&2
openstack user create -f value -c id \
$username \
--password "$SERVICE_PASSWORD" \
--project $SERVICE_TENANT \
--email [email protected]
fi
}
add_role() {
local user_id=$1
local tenant=$2
local role_id=$3
local username=$4
user_roles=$(openstack user role list -f value -c ID \
$user_id \
--project $tenant 2>/dev/null)
die_if_not_set $LINENO user_roles "Fail to get user_roles for tenant($tenant) and user_id($user_id)"
existing_role=$(echo "$user_roles" | grep $role_id || true)
if [ -n "$existing_role" ]
then
echo "User $username already has role $role_id" >&2
return
fi
openstack role add $role_id \
--user $user_id \
--project $tenant
}
# Determines if the given option is present in the INI file
# ini_has_option config-file section option
function ini_has_option() {
local file=$1
local section=$2
local option=$3
local line
line=$(sudo sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
[ -n "$line" ]
}
# Set an option in an INI file
# iniset config-file section option value
function iniset() {
local file=$1
local section=$2
local option=$3
local value=$4
if ! sudo grep -q "^\[$section\]" "$file"; then
# Add section at the end
sudo bash -c "echo -e \"\n[$section]\" >>\"$file\""
fi
if ! ini_has_option "$file" "$section" "$option"; then
# Add it
sudo sed -i -e "/^\[$section\]/ a\\
$option = $value
" "$file"
else
# Replace it
sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ s|^\($option[ \t]*=[ \t]*\).*$|\1$value|" "$file"
fi
}
# Get an option from an INI file
# iniget config-file section option
function iniget() {
local file=$1
local section=$2
local option=$3
local line
line=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
echo ${line#*=}
}
# Copy an option from Nova INI file or from environment if it's set
function copynovaopt() {
local option_name=$1
local option_group=$2
local env_var
local option
env_var=${option_name^^}
if [ ${!env_var+x} ]; then
option=${!env_var}
elif ini_has_option "$NOVA_CONF" $option_group $option_name; then
option=$(iniget $NOVA_CONF $option_group $option_name)
else
return 0
fi
iniset $CONF_FILE $option_group $option_name $option
}
if [[ -n $(openstack catalog show network) ]]; then
VPC_SUPPORT="True"
DISABLE_EC2_CLASSIC="True"
else
VPC_SUPPORT="False"
DISABLE_EC2_CLASSIC="False"
fi
if [[ "$VPC_SUPPORT" == "True" && -z "$EXTERNAL_NETWORK" ]]; then
declare -a newtron_output
readarray -s 3 -t newtron_output < <(openstack network list --external)
if ((${#newtron_output[@]} < 2)); then
reason="No external network is declared in Neutron."
elif ((${#newtron_output[@]} > 2)); then
reason="More than one external networks are declared in Neutron."
else
EXTERNAL_NETWORK=$(echo $newtron_output | awk -F '|' '{ print $3 }')
fi
die_if_not_set $LINENO EXTERNAL_NETWORK "$reason. Please set EXTERNAL_NETWORK environment variable to the external network dedicated to EC2 elastic IP operations"
fi
#create keystone user with admin privileges
ADMIN_ROLE=$(openstack role show admin -c id -f value)
die_if_not_set $LINENO ADMIN_ROLE "Fail to get ADMIN_ROLE by 'openstack role show' "
SERVICE_TENANT_ID=$(openstack project show service -c id -f value)
die_if_not_set $LINENO SERVICE_TENANT_ID "Fail to get service tenant 'openstack project show' "
echo ADMIN_ROLE $ADMIN_ROLE
echo SERVICE_TENANT $SERVICE_TENANT
SERVICE_USERID=$(get_user $SERVICE_USERNAME)
die_if_not_set $LINENO SERVICE_USERID "Fail to get user for $SERVICE_USERNAME"
echo SERVICE_USERID $SERVICE_USERID
add_role $SERVICE_USERID $SERVICE_TENANT $ADMIN_ROLE $SERVICE_USERNAME
#create log dir
echo Creating log dir
sudo install -d $LOG_DIR --owner=$USER
#copy conf files (do not override it)
echo Creating configs
sudo mkdir -p /etc/ec2api > /dev/null
if [ ! -s $CONF_FILE ]; then
sudo touch $CONF_FILE
fi
if [ ! -s $APIPASTE_FILE ]; then
sudo cp etc/ec2api/api-paste.ini $APIPASTE_FILE
fi
#update default config with some values
OS_AUTH_URL_WO_PATH=`echo $OS_AUTH_URL | cut -f 1-3 -d /`
iniset $CONF_FILE DEFAULT ec2api_listen_port "$EC2API_PORT"
iniset $CONF_FILE DEFAULT ec2_port "$EC2API_PORT"
iniset $CONF_FILE DEFAULT api_paste_config $APIPASTE_FILE
iniset $CONF_FILE DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s] %(instance)s%(message)s"
iniset $CONF_FILE DEFAULT log_dir "$LOG_DIR"
iniset $CONF_FILE DEFAULT verbose True
iniset $CONF_FILE DEFAULT keystone_ec2_tokens_url "$OS_AUTH_URL_WO_PATH/v3/ec2tokens"
iniset $CONF_FILE database connection "$CONNECTION"
iniset $CONF_FILE DEFAULT disable_ec2_classic "$DISABLE_EC2_CLASSIC"
iniset $CONF_FILE DEFAULT external_network "$EXTERNAL_NETWORK"
GROUP_AUTHTOKEN="keystone_authtoken"
iniset $CONF_FILE $GROUP_AUTHTOKEN signing_dir "$AUTH_CACHE_DIR"
iniset $CONF_FILE $GROUP_AUTHTOKEN auth_uri "$OS_AUTH_URL"
iniset $CONF_FILE $GROUP_AUTHTOKEN auth_url "$OS_AUTH_URL"
iniset $CONF_FILE $GROUP_AUTHTOKEN username $SERVICE_USERNAME
iniset $CONF_FILE $GROUP_AUTHTOKEN password $SERVICE_PASSWORD
iniset $CONF_FILE $GROUP_AUTHTOKEN project_name $SERVICE_TENANT
iniset $CONF_FILE $GROUP_AUTHTOKEN project_domain_name $SERVICE_DOMAIN_NAME
iniset $CONF_FILE $GROUP_AUTHTOKEN user_domain_name $SERVICE_DOMAIN_NAME
iniset $CONF_FILE $GROUP_AUTHTOKEN auth_type password
GROUP_CACHE="cache"
iniset $CONF_FILE $GROUP_CACHE enabled True
iniset $CONF_FILE $GROUP_CACHE backend "$CACHE_BACKEND"
if [[ -f "$NOVA_CONF" ]]; then
# NOTE(ft): use swift instead internal s3 server if enabled
if [[ -n $(openstack catalog show object-store 2>/dev/null) ]] &&
[[ -n $(openstack catalog show s3 2>/dev/null) ]]; then
copynovaopt s3_host DEFAULT
copynovaopt s3_port DEFAULT
copynovaopt s3_affix_tenant DEFAULT
copynovaopt s3_use_ssl DEFAULT
fi
copynovaopt cert_topic DEFAULT
copynovaopt rabbit_hosts oslo_messaging_rabbit
copynovaopt rabbit_password oslo_messaging_rabbit
copynovaopt rabbit_userid oslo_messaging_rabbit
# TODO(ft): it's necessary to support other available messaging implementations
nova_state_path=$(iniget $NOVA_CONF DEFAULT state_path)
root_state_path=$(dirname $nova_state_path)
iniset $CONF_FILE DEFAULT state_path ${root_state_path}/ec2api
fi
#init cache dir
echo Creating signing dir
sudo mkdir -p $AUTH_CACHE_DIR
sudo chown $USER $AUTH_CACHE_DIR
sudo rm -f $AUTH_CACHE_DIR/*
#install it
echo Installing package
if [[ -z "$VIRTUAL_ENV" ]]; then
SUDO_PREFIX="sudo"
if ! command -v pip >/dev/null; then
sudo apt-get install python-pip
fi
fi
$SUDO_PREFIX pip install -e ./
$SUDO_PREFIX rm -rf build ec2_api.egg-info
#recreate database
echo Setuping database
$SUDO_PREFIX tools/db/ec2api-db-setup deb