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