This repository has been archived by the owner on Aug 29, 2018. It is now read-only.
/
control
249 lines (212 loc) · 7.13 KB
/
control
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
#!/bin/bash
source $OPENSHIFT_CARTRIDGE_SDK_BASH
export STOPTIMEOUT=10
# Run mysql commands
function run_sql {
echo "$@" | /usr/bin/mysql -h $OPENSHIFT_MYSQL_DB_HOST -P $OPENSHIFT_MYSQL_DB_PORT -u $OPENSHIFT_MYSQL_DB_USERNAME --password="$OPENSHIFT_MYSQL_DB_PASSWORD" --skip-column-names
}
function is_running {
pidfile=$OPENSHIFT_MYSQL_DIR/pid/mysql.pid
if [ -f $pidfile ]; then
mysql_pid=`cat $pidfile 2> /dev/null`
myid=`id -u`
if `ps --pid $mysql_pid > /dev/null 2>&1` || `pgrep -x mysqld_safe -u $myid > /dev/null 2>&1`
then
return 0
fi
fi
return 1
}
# TODO: account for standalone scenario
# TODO: source user hooks?
# Start mysqld and block until it comes up.
function start {
if ! is_running; then
echo "Starting MySQL cartridge"
erb conf/my.cnf.erb.hidden > conf/my.cnf
/usr/bin/mysqld_safe --defaults-file=$OPENSHIFT_MYSQL_DIR/conf/my.cnf > /dev/null 2>&1 &
wait_for_mysqld_availability
else
echo "MySQL already running" 1>&2
fi
}
function wait_for_mysqld_availability {
test_select=${1:-false}
for i in {1..30}; do
if is_running; then
if $test_select; then
run_sql 'select 1' 2> /dev/null && return 0
else
return 0
fi
fi
sleep 1
done
return 1
}
function stop {
if is_running; then
pidfile=$OPENSHIFT_MYSQL_DIR/pid/mysql.pid
if [ -f $pidfile ]; then
echo "Stopping MySQL cartridge"
pid=$( /bin/cat $pidfile )
/bin/kill $pid
ret=$?
if [ $ret -eq 0 ]; then
TIMEOUT="$STOPTIMEOUT"
while [ $TIMEOUT -gt 0 ] && [ -f "$pidfile" ]
do
/bin/kill -0 "$pid" >/dev/null 2>&1 || break
sleep 1
let TIMEOUT=${TIMEOUT}-1
done
fi
else
if `pgrep -x mysqld_safe > /dev/null 2>&1`; then
echo "Warning: MySQL process exists without a pid file. Use force-stop to kill." 1>&2
else
echo "MySQL already stopped" 1>&2
fi
fi
fi
}
function status {
if is_running; then
client_result "MySQL is running"
else
client_result "MySQL is stopped"
fi
exit 0
}
function pre_snapshot {
start
# The following call is necessary due to race conditions that can arise if mysql
# is recovering from a force-stop
wait_for_mysqld_availability true
echo "$OPENSHIFT_MYSQL_DB_USERNAME" > $OPENSHIFT_DATA_DIR/mysql_db_username
echo "$OPENSHIFT_MYSQL_DB_HOST" > $OPENSHIFT_DATA_DIR/mysql_db_host
echo "$OPENSHIFT_APP_NAME" > $OPENSHIFT_DATA_DIR/mysql_db_dbname
dump_file=$OPENSHIFT_DATA_DIR/mysql_dump_snapshot.gz
local db_host=$OPENSHIFT_MYSQL_DB_HOST
local db_port=$OPENSHIFT_MYSQL_DB_PORT
{
/usr/bin/mysqldump --extended-insert --quick -h $db_host -P $db_port -u $OPENSHIFT_MYSQL_DB_USERNAME --password="$OPENSHIFT_MYSQL_DB_PASSWORD" --all-databases --events --triggers --routines --add-drop-table | /bin/gzip > $dump_file
} ||
{
warning "Couldn't not dump mysql! Continuing anyway"
/bin/rm -rf $OPENSHIFT_DATA_DIR/mysql_dump_snapshot.gz
}
stop
}
function post_snapshot {
true
}
function pre_restore {
cleanup_dump
}
function post_restore {
# Ensure a snapshot file exists
if [ -f $OPENSHIFT_DATA_DIR/mysql_dump_snapshot.gz ]; then
start
# Restore stashed variables and get current variables
OLD_IP=$(< $OPENSHIFT_DATA_DIR/mysql_db_host)
NEW_IP=$OPENSHIFT_MYSQL_DB_HOST
OLD_NAME=$(< $OPENSHIFT_DATA_DIR/mysql_db_dbname)
NEW_NAME=$OPENSHIFT_APP_NAME
if [ -s $OPENSHIFT_DATA_DIR/mysql_db_username ]; then
OLD_USER=$(< $OPENSHIFT_DATA_DIR/mysql_db_username)
else
OLD_USER="admin"
fi
NEW_USER=$OPENSHIFT_MYSQL_DB_USERNAME
# Drop and recreate current database
# Need to use backticks here to make sure name is properly escaped
run_sql "DROP DATABASE IF EXISTS \`$NEW_NAME\`;" || error "Could not drop existing database" 187
run_sql "CREATE DATABASE \`$NEW_NAME\`;" || error "Could not create database" 187
# Restore the old database verbatim, this will be using the old database name
# Pipe this command directly to mysql instead of using run_sql so that we don't have to create a massive string to hold the sql dump file
# TODO: Ideally this would pipe directly into run_sql, but I have yet to get it to work
{
(
echo "SET AUTOCOMMIT=0;"
echo "SET UNIQUE_CHECKS=0;"
echo "SET FOREIGN_KEY_CHECKS=0;"
/bin/zcat $OPENSHIFT_DATA_DIR/mysql_dump_snapshot.gz
echo "SET FOREIGN_KEY_CHECKS=1;"
echo "SET UNIQUE_CHECKS=1;"
echo "SET AUTOCOMMIT=1;"
echo "COMMIT;"
) | /usr/bin/mysql -h $OPENSHIFT_MYSQL_DB_HOST -P $OPENSHIFT_MYSQL_DB_PORT -u $OPENSHIFT_MYSQL_DB_USERNAME --password="$OPENSHIFT_MYSQL_DB_PASSWORD" --skip-column-names
} || error "Could not import MySQL Database" 187
# Grant permissions to the current user
run_sql "
GRANT ALL ON *.* TO '$NEW_USER'@'$NEW_IP' IDENTIFIED BY '$OPENSHIFT_MYSQL_DB_PASSWORD' WITH GRANT OPTION;
GRANT ALL ON *.* TO '$NEW_USER'@'localhost' IDENTIFIED BY '$OPENSHIFT_MYSQL_DB_PASSWORD' WITH GRANT OPTION;
" || error "Could not grant permissions for MySQL database" 187
# Only run the following if the username is different
if [ "${OLD_USER}" != "${NEW_USER}" ]
then
# Remove the user from any grants that it has
{
for host in $(run_sql "SELECT Host from mysql.user WHERE user.user='${OLD_USER}'")
do
run_sql "DROP USER \`$OLD_USER\`@'${host}';" || warning "Could not drop old user" 187
done
}
fi
# Refresh the privileges
run_sql "FLUSH PRIVILEGES;" || error "Could not flush privileges" 187
# Only run the following if the database name has changed
if [ "${OLD_NAME}" == "${NEW_NAME}" ]
then
warning "Old and new names are the same, no need to rename"
else
# Dump the old database and restore it into the new database
# This approach provides relational consistency and will work with tables, views, triggers, etc
# TODO: This may not work if the user created another database that has references to this database
{
/usr/bin/mysqldump -h $NEW_IP -P $OPENSHIFT_MYSQL_DB_PORT -u $NEW_USER --password="$OPENSHIFT_MYSQL_DB_PASSWORD" $OLD_NAME | \
mysql -h $NEW_IP -P $OPENSHIFT_MYSQL_DB_PORT -u $NEW_USER --password="$OPENSHIFT_MYSQL_DB_PASSWORD" $NEW_NAME
} || error "Could not rename database" 187
# Drop the old database now that the data has been preserved
run_sql "DROP DATABASE \`$OLD_NAME\`;" || error "Could not drop old database" 187
fi
cleanup_dump
else
echo "MySQL restore attempted but no dump found!" 1>&2
echo "$OPENSHIFT_DATA_DIR/mysql_dump_snapshot.gz does not exist" 1>&2
fi
}
function cleanup_dump {
rm -f $OPENSHIFT_DATA_DIR/mysql_dump_snapshot.gz
rm -f $OPENSHIFT_DATA_DIR/mysql_db_host
rm -f $OPENSHIFT_DATA_DIR/mysql_db_username
rm -f $OPENSHIFT_DATA_DIR/mysql_db_dbname
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
stop
start
;;
pre-snapshot)
pre_snapshot
;;
post-snapshot)
post_snapshot
;;
pre-restore)
pre_restore
;;
post-restore)
post_restore
;;
esac