Fix version output when missing.
[plcapi.git] / plc.d / db
1 #!/bin/bash
2 # $Id$
3 # $URL$
4 #
5 # priority: 900
6 #
7 # Bootstrap the database
8 #
9 # Mark Huang <mlhuang@cs.princeton.edu>
10 # Copyright (C) 2006 The Trustees of Princeton University
11 #
12
13 # Source function library and configuration
14 . /etc/plc.d/functions
15 . /etc/planetlab/plc_config
16
17 # Be verbose
18 set -x
19
20 # Export so that we do not have to specify -p to psql invocations
21 export PGPORT=$PLC_DB_PORT
22
23 # Install extensions
24 function extend_db()
25 {
26     shopt -s nullglob
27     for file in /usr/share/plc_api/extensions/*-up*; do
28         script=${file##*/}
29         name=${script%-up*}
30         extension=${script##*.}
31         version=$(psql -U $PLC_DB_USER --quiet --tuples-only --no-align -c \
32                   "SELECT version FROM plc_db_extensions WHERE name='$name' LIMIT 1" \
33                   $PLC_DB_NAME 2>/dev/null | awk 'BEGIN { ver=0 } /^[0-9]+$/ { ver=$1 } END { print ver }')
34         if [ $version -eq 0 ]; then
35             if [ "$extension" = "sql" ] ; then
36                 dialog " - $script (dbdumped)"
37                 dump_planetlab_db "before-$script"
38                 psql -U $PLC_DB_USER -f $file $PLC_DB_NAME
39             elif [ -x $file ] ; then
40                 dialog " - $script (dbdumped)"
41                 dump_planetlab_db "before-$script"
42                 $file
43             else
44                 dialog "\nWarning: extension $file not executable"
45             fi
46             check
47         fi
48         for file in /usr/share/plc_api/extensions/$name/migrations/[0-9]*-up-*; do
49             script=${file##*/}
50             index=${script%-up-*}
51             extension=${script##*.}
52             if [ $index -gt $version ] ; then
53                 if [ "$extension" = "sql" ] ; then
54                     dialog " - $script (dbdumped)"
55                     dump_planetlab_db "before-$script"
56                     psql -U $PLC_DB_USER -f $file $PLC_DB_NAME
57                 elif [ -x $file ] ; then
58                     dialog " - $script (dbdumped)"
59                     dump_planetlab_db "before-$script"
60                     $file
61                 else
62                     dialog "\nWarning: migration $file not executable"
63                 fi
64                 check
65             fi
66         done
67     done
68 }
69
70 # Updates the database by applying all migration scripts in
71 # /usr/share/plc_api/migrations/N-up-*, where N is greater than the
72 # current subversion. At least one of the migration scripts with the
73 # same N must update plc_db_version.subversion.
74 function migrate_db()
75 {
76     subversion=$(psql -U $PLC_DB_USER --quiet --tuples-only --no-align -c \
77                  "SELECT subversion FROM plc_db_version LIMIT 1" \
78                  $PLC_DB_NAME 2>/dev/null || echo 0)
79     shopt -s nullglob
80     for file in /usr/share/plc_api/migrations/[0-9]*-up-* ; do
81         script=$(basename $file)
82         index=${script%-up*}
83         extension=${script##*.}
84         if [ $index -gt $subversion ] ; then
85             if [ "$extension" = "sql" ] ; then
86                 dialog " - $script (dbdumped)"
87                 dump_planetlab_db "before-$script"
88                 psql -U $PLC_DB_USER -f $file $PLC_DB_NAME
89             elif [ -x $file ] ; then
90                 dialog " - $script (dbdumped)"
91                 dump_planetlab_db "before-$script"
92                 $file
93             else
94                 dialog "\nWarning: migration $file not executable"
95             fi
96             check
97         fi
98     done
99 }
100
101 function checkpoint_planetlab_db()
102 {
103     dumpfile=$1
104     pg_dump -U $PLC_DB_USER $PLC_DB_NAME > $dumpfile
105     check
106 }
107
108 function restore_planetlab_db()
109 {
110     dumpfile=$1
111     if [ -n "$dumpfile" ] ; then 
112         [ -f "$dumpfile" ] && psql -a -U $PLC_DB_USER $PLC_DB_NAME < $dumpfile
113         check
114     fi
115 }
116
117 # use a single date of this script invocation for the dump_*_db functions.
118 DATE=$(date +"%Y-%m-%d-%H-%M-%S")
119
120 # Dumps the database - optional argument to specify filename suffix
121 function dump_planetlab_db()
122 {
123     if [ -n "$1" ] ; then suffix="-$1" ; else suffix="" ; fi
124     dumpfile=/var/lib/pgsql/backups/$(date +"${PLC_DB_NAME}.${DATE}${suffix}.sql")
125     checkpoint_planetlab_db $dumpfile
126 }
127
128 function restore_drupal_db()
129 {
130     dumpfile=$1
131     if [ -n "$dumpfile" ] ; then 
132         [ -f "$dumpfile" ] && psql -a -U $PLC_DB_USER drupal < $1
133         check
134     fi
135 }
136
137 function checkpoint_drupal_db()
138 {
139     dumpfile=$1
140     pg_dump -U $PLC_DB_USER drupal > $dumpfile
141     check
142 }
143
144 function dump_drupal_db()
145 {
146     dumpfile=/var/lib/pgsql/backups/$(date +"drupal.${DATE}.sql")
147     checkpoint_drupal_db $dumpfile
148     check
149 }
150
151 # Clean up old backups
152 function clean_dumps()
153 {
154     find /var/lib/pgsql/backups '(' -name "$PLC_DB_NAME.*.sql" -o -name "drupal.*.sql" ')' -a -atime +15 | xargs rm -f
155     check
156 }
157
158 [ $PLC_DB_ENABLED -ne 1 ] && exit 0
159 case "$1" in
160     start)
161         MESSAGE=$"Bootstrapping the database"
162         dialog "$MESSAGE"
163
164         # Apply schema updates
165         migrate_db
166         extend_db
167
168         # Update the maintenance account username. This can't be
169         # done through the api-config script since it uses the
170         # maintenance account to access the API. The maintenance
171         # account should be person_id 1 since it is created by the
172         # DB schema itself.
173         psql -U $PLC_DB_USER -c "UPDATE persons SET email='$PLC_API_MAINTENANCE_USER' WHERE person_id=1" $PLC_DB_NAME
174
175         # Update the Drupal site_name variable
176         # also turn off drupal native user registration
177         psql -U $PLC_DB_USER drupal <<EOF
178 DELETE FROM variable WHERE name = 'site_name';
179 INSERT INTO variable (name, value) VALUES ('site_name', 's:${#PLC_NAME}:"$PLC_NAME";');
180 DELETE FROM variable WHERE name = 'user_register';
181 INSERT INTO variable (name, value) VALUES ('user_register', 's:1:"0";');
182 DELETE FROM cache;
183 EOF
184
185         # Bootstrap the DB
186         db-config
187         check
188
189         result "$MESSAGE"
190         ;;
191
192     migrate)
193         MESSAGE=$"Migrating the database"
194         dialog "$MESSAGE"
195
196         migrate_db
197         result "$MESSAGE"
198         ;;
199
200     dump)
201         MESSAGE=$"Dumping the databases in /var/lib/pgsql/backups"
202         dialog "$MESSAGE"
203
204         dump_planetlab_db
205         dump_drupal_db
206         result "$MESSAGE"
207         ;;
208
209     checkpoint)
210         MESSAGE=$"Checkpointing the databases"
211         checkpoint_planetlab_db $2
212         checkpoint_drupal_db $3
213         ;;
214
215     restore)
216         MESSAGE=$"Restoring the databases from checkpoint files"
217         restore_planetlab_db $2
218         restore_drupal_db $3
219         ;;
220
221     clean-dump)
222         MESSAGE=$"Cleaning old database dumps"
223         dialog "$MESSAGE"
224
225         clean_dumps
226         result "$MESSAGE"
227         ;;
228
229     stop)
230         MESSAGE="Ignoring request to stop myplc databases"
231         dialog "$MESSAGE"
232         result ""
233         ;;
234
235     *)
236         echo "Usage: $0 [start|migrate|dump|checkpoint|restore|clean-dump|stop]"
237         exit 1
238         ;;
239 esac
240
241 exit $ERRORS