3 """ Database Update Main Script
5 @contact: Debian FTP Master <ftpmaster@debian.org>
6 # Copyright (C) 2008 Michael Casadevall <mcasadevall@debian.org>
7 @license: GNU General Public License version 2 or later
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with this program; if not, write to the Free Software
22 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 ################################################################################
26 # <Ganneff> when do you have it written?
27 # <NCommander> Ganneff, after you make my debian account
28 # <Ganneff> blackmail wont work
29 # <NCommander> damn it
31 ################################################################################
41 from daklib import utils
42 from daklib.dak_exceptions import DBUpdateError
44 ################################################################################
47 required_database_schema = 15
49 ################################################################################
52 def usage (self, exit_code=0):
53 print """Usage: dak update-db
54 Updates dak's database schema to the lastest version. You should disable crontabs while this is running
56 -h, --help show this help and exit."""
60 ################################################################################
62 def update_db_to_zero(self):
63 """ This function will attempt to update a pre-zero database schema to zero """
65 # First, do the sure thing, and create the configuration table
67 print "Creating configuration table ..."
69 c.execute("""CREATE TABLE config (
70 id SERIAL PRIMARY KEY NOT NULL,
71 name TEXT UNIQUE NOT NULL,
74 c.execute("INSERT INTO config VALUES ( nextval('config_id_seq'), 'db_revision', '0')")
77 except psycopg2.ProgrammingError:
79 print "Failed to create configuration table."
80 print "Can the projectB user CREATE TABLE?"
82 print "Aborting update."
85 ################################################################################
88 # We keep database revision info the config table
93 q = c.execute("SELECT value FROM config WHERE name = 'db_revision';")
94 return c.fetchone()[0]
96 except psycopg2.ProgrammingError:
97 # Whoops .. no config table ...
99 print "No configuration table found, assuming dak database revision to be pre-zero"
102 ################################################################################
105 # Ok, try and find the configuration table
106 print "Determining dak database revision ..."
109 # Build a connect string
110 connect_str = "dbname=%s"% (Cnf["DB::Name"])
111 if Cnf["DB::Host"] != '': connect_str += " host=%s" % (Cnf["DB::Host"])
112 if Cnf["DB::Port"] != '-1': connect_str += " port=%d" % (int(Cnf["DB::Port"]))
114 self.db = psycopg2.connect(connect_str)
117 print "FATAL: Failed connect to database"
120 database_revision = int(self.get_db_rev())
122 if database_revision == -1:
123 print "dak database schema predates update-db."
125 print "This script will attempt to upgrade it to the lastest, but may fail."
126 print "Please make sure you have a database backup handy. If you don't, press Ctrl-C now!"
128 print "Continuing in five seconds ..."
131 print "Attempting to upgrade pre-zero database to zero"
133 self.update_db_to_zero()
134 database_revision = 0
136 print "dak database schema at " + str(database_revision)
137 print "dak version requires schema " + str(required_database_schema)
139 if database_revision == required_database_schema:
140 print "no updates required"
143 for i in range (database_revision, required_database_schema):
144 print "updating database schema from " + str(database_revision) + " to " + str(i+1)
146 dakdb = __import__("dakdb", globals(), locals(), ['update'+str(i+1)])
147 update_module = getattr(dakdb, "update"+str(i+1))
148 update_module.do_update(self)
149 except DBUpdateError, e:
150 # Seems the update did not work.
151 print "Was unable to update database schema from %s to %s." % (str(database_revision), str(i+1))
152 print "The error message received was %s" % (e)
153 utils.fubar("DB Schema upgrade failed")
154 database_revision += 1
156 ################################################################################
161 Cnf = utils.get_conf()
162 arguments = [('h', "help", "Update-DB::Options::Help")]
164 if not Cnf.has_key("Update-DB::Options::%s" % (i)):
165 Cnf["Update-DB::Options::%s" % (i)] = ""
167 arguments = apt_pkg.ParseCommandLine(Cnf, arguments, sys.argv)
169 options = Cnf.SubTree("Update-DB::Options")
173 utils.warn("dak update-db takes no arguments.")
174 self.usage(exit_code=1)
180 lock_fd = os.open(Cnf["Dinstall::LockFile"], os.O_RDWR | os.O_CREAT)
181 fcntl.lockf(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
183 if errno.errorcode[e.errno] == 'EACCES' or errno.errorcode[e.errno] == 'EAGAIN':
184 utils.fubar("Couldn't obtain lock; assuming another 'dak process-unchecked' is already running.")
187 ################################################################################
189 if __name__ == '__main__':