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
|
#! /bin/bash -e
#
# MaaS database control script. See main() at the bottom for usage.
#
# Most functions take as their first argument a database cluster's data
# directory. This is where the database's socket, pidfile, log, and data will
# reside.
#
# Some design choices for this module:
#
# * Everything is PostgreSQL on Ubuntu.
# * Each branch gets its own cluster. Kill & delete when done.
# * Databases run under the system user that creates them. No root required.
# * No global configuration apart from a basic PostgreSQL install.
# * Connections use Unix sockets. No TCP port hogging.
POSTGRES_VERSION=9.1
PGCTL="/usr/lib/postgresql/${POSTGRES_VERSION}/bin/pg_ctl"
# Figure out the full absolute data directory path for a given cluster, even
# if a relative path is given.
maasdb_locate() {
local DATADIR
DATADIR="$1"
if test -z "$1"
then
echo "Specify a data directory for the MaaS database cluster." >&2
return 1
fi
if ! echo "$DATADIR" | grep '^/'
then
echo "`pwd`/$DATADIR"
fi
}
# Create a database cluster.
maasdb_create_cluster() {
local DATADIR
DATADIR="`maasdb_locate "$1"`"
if ! test -d "$DATADIR/base"
then
mkdir -p -- "$DATADIR"
$PGCTL init -s -D "$DATADIR" -o '-E utf8 -A trust'
fi
}
# Start a database cluster.
maasdb_start_cluster() {
local DATADIR DISPOSABLE EXTRA_POSTGRES_OPTS
DATADIR="`maasdb_locate "$1"`"
# Pass "disposable" as the second argument if the data in this database
# is not important at all and you're willing to cut corners for speed.
DISPOSABLE="$2"
if test "$DISPOSABLE" = "disposable"
then
# -F -- don't bother fsync'ing.
EXTRA_POSTGRES_OPTS="-F"
else
EXTRA_POSTGRES_OPTS=""
fi
maasdb_create_cluster "$DATADIR"
if ! test -f "$DATADIR/postmaster.pid"
then
# pg_ctl options:
# -D <dir> -- data directory.
# -l <file> -- log file.
# -s -- no informational messages.
# -w -- wait until startup is complete.
# postgres options:
# -h <arg> -- host name; empty arg means Unix socket only.
# -k -- socket directory.
$PGCTL start \
-D "$DATADIR" -l "$DATADIR/backend.log" -s -w \
-o "-h '' -k '$DATADIR' $EXTRA_POSTGRES_OPTS"
fi
}
# Stop a database cluster.
maasdb_stop_cluster() {
local DATADIR
DATADIR="`maasdb_locate "$1"`"
if test -f "$DATADIR/postmaster.pid"
then
$PGCTL stop -W -m fast -D "$DATADIR"
fi
}
# Initialize a MaaS database.
maasdb_init_db() {
local DATADIR DISPOSABLE MARKER
DATADIR="`maasdb_locate "$1"`"
# Pass "disposable" as the second argument if the data in this database
# is not important at all and you're willing to cut corners for speed.
DISPOSABLE="$2"
maasdb_start_cluster "$DATADIR" "$DISPOSABLE"
MARKER="$DATADIR/maas-created"
if ! test -f "$MARKER"
then
createdb -h "$DATADIR" maas && touch "$MARKER"
fi
}
# Open a psql shell on a MaaS database.
maasdb_shell() {
local DATADIR
DATADIR="`maasdb_locate "$1"`"
maasdb_init_db "$DATADIR"
psql -h "$DATADIR" maas
}
# Execute a query on a MaaS database.
maasdb_query() {
local DATADIR QUERY
DATADIR="`maasdb_locate "$1"`"
QUERY="$2"
maasdb_init_db "$DATADIR"
psql -h "$DATADIR" maas -c "$QUERY"
}
# Delete an entire MaaS database and cluster. Use only with extreme care!
maasdb_delete_cluster() {
local DATADIR
DATADIR="`maasdb_locate "$1"`"
# Before deleting anything, does this at least look like a MaaS database
# cluster?
if test -d "$DATADIR/base"
then
maasdb_stop_cluster "$DATADIR"
rm -rf -- "$DATADIR"
fi
}
usage() {
cat <<EOF >&2
Usage: maasdb <command> <cluster-path>
Where <command> is one of:
start
stop
query
shell
delete-cluster
And <cluster-path> is the path to the MaaS development database cluster,
typically "./db"
EOF
}
unknown_command() {
echo >&2 "** Unknown command: $1 **"
echo
usage
exit 1
}
main() {
local COMMAND DATADIR
COMMAND="$1"
DATADIR="$2"
if ! shift 2
then
usage
exit 1
fi
case "$COMMAND" in
start) maasdb_init_db "$DATADIR" "$@" ;;
stop) maasdb_stop_cluster "$DATADIR" "$@" ;;
query) maasdb_query "$DATADIR" "$@" ;;
shell) maasdb_shell "$DATADIR" "$@" ;;
delete-cluster) maasdb_delete_cluster "$DATADIR" "$@" ;;
*) unknown_command "$COMMAND" ;;
esac
}
main "$@"
|