提交 4338314e 编写于 作者: M Mike O'Connor

Merge branch 'master' of https://ftp-master.debian.org/git/dak

...@@ -126,6 +126,14 @@ Import-Archive ...@@ -126,6 +126,14 @@ Import-Archive
ExportDir "/srv/ftp.debian.org/dak/import-archive-files/"; ExportDir "/srv/ftp.debian.org/dak/import-archive-files/";
}; };
Import-Keyring
{
/srv/ftp.debian.org/keyrings/debian-maintainers.gpg
{
Debian-Maintainer "true";
};
};
Reject-Proposed-Updates Reject-Proposed-Updates
{ {
StableRejector "the Stable Release Team"; StableRejector "the Stable Release Team";
......
...@@ -144,6 +144,8 @@ def init(): ...@@ -144,6 +144,8 @@ def init():
"Sync PostgreSQL users with passwd file"), "Sync PostgreSQL users with passwd file"),
("init-db", ("init-db",
"Update the database to match the conf file"), "Update the database to match the conf file"),
("update-db",
"Updates databae schema to latest revision"),
("init-dirs", ("init-dirs",
"Initial setup of the archive"), "Initial setup of the archive"),
("make-maintainers", ("make-maintainers",
......
#!/usr/bin/env python
# Debian Archive Kit Database Update Script
# Copyright (C) 2008 Michael Casadevall <mcasadevall@debian.org>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
################################################################################
# <tomv_w> really, if we want to screw ourselves, let's find a better way.
# <Ganneff> rm -rf /srv/ftp.debian.org
################################################################################
import psycopg2, time
################################################################################
def do_update(self):
print "Adding DM fields to database"
try:
c = self.db.cursor()
c.execute("ALTER TABLE source ADD COLUMN dm_upload_allowed BOOLEAN DEFAULT 'no' NOT NULL;")
c.execute("ALTER TABLE keyrings ADD COLUMN debian_maintainer BOOLEAN DEFAULT 'false' NOT NULL;")
print "Migrating DM data to source table. This might take some time ..."
c.execute("UPDATE source SET dm_upload_allowed = 't' WHERE id IN (SELECT source FROM src_uploaders);")
c.execute("UPDATE config SET value = '1' WHERE name = 'db_revision'")
print "Migrating DM uids to normal uids"
c.execute("SELECT uid FROM uid WHERE uid LIKE 'dm:%'")
rows = c.fetchall()
for r in rows:
uid = r[0]
c.execute("UPDATE uid SET uid = '%s' WHERE uid = '%s'" % (uid[3:], uid))
self.db.commit()
print "IMPORTANT: Set the debian_maintainer flag in the config file for keyrings that are DMs!"
print " Failure to do so will result in DM's having full upload abilities!"
print "REMINDER: Remember to run the updated byhand-dm crontab to update Debian Maintainer information"
print ""
print "Pausing for five seconds ..."
time.sleep (5)
except psycopg2.ProgrammingError, msg:
self.db.rollback()
print "FATAL: Unable to apply DM table update 1!"
print "Error Message: " + str(msg)
print "Database changes have been rolled back."
...@@ -222,6 +222,11 @@ def main(): ...@@ -222,6 +222,11 @@ def main():
keyringname = keyring_names[0] keyringname = keyring_names[0]
keyring = Keyring(keyringname) keyring = Keyring(keyringname)
is_dm = "false"
if Cnf.has_key("Import-Keyring::"+keyringname+"::Debian-Maintainer"):
projectB.query("UPDATE keyrings SET debian_maintainer = '%s' WHERE name = '%s'" % (Cnf["Import-Keyring::"+keyringname+"::Debian-Maintainer"], keyringname.split("/")[-1]))
is_dm = Cnf["Import-Keyring::"+keyringname+"::Debian-Maintainer"]
keyring_id = database.get_or_set_keyring_id( keyring_id = database.get_or_set_keyring_id(
keyringname.split("/")[-1]) keyringname.split("/")[-1])
...@@ -291,7 +296,12 @@ def main(): ...@@ -291,7 +296,12 @@ def main():
projectB.query("UPDATE fingerprint SET uid = %d WHERE id = %d" % (newuid, oldfid)) projectB.query("UPDATE fingerprint SET uid = %d WHERE id = %d" % (newuid, oldfid))
if oldkid != keyring_id: if oldkid != keyring_id:
projectB.query("UPDATE fingerprint SET keyring = %d WHERE id = %d" % (keyring_id, oldfid)) # Only change the keyring if it won't result in a loss of permissions
q = projectB.query("SELECT debian_maintainer FROM keyrings WHERE id = '%d'" % (keyring_id))
if is_dm == "false" and q.getresult()[0][0] == 'f':
projectB.query("UPDATE fingerprint SET keyring = %d WHERE id = %d" % (keyring_id, oldfid))
else:
print "Key %s exists in both DM and DD keyrings. Not demoting." % (f)
# All done! # All done!
......
...@@ -151,7 +151,7 @@ SELECT f.fingerprint, f.id, u.uid FROM fingerprint f, uid u WHERE f.uid = u.id ...@@ -151,7 +151,7 @@ SELECT f.fingerprint, f.id, u.uid FROM fingerprint f, uid u WHERE f.uid = u.id
print "Assigning %s to 0x%s." % (uid, fingerprint) print "Assigning %s to 0x%s." % (uid, fingerprint)
elif existing_uid == uid: elif existing_uid == uid:
pass pass
elif existing_uid[:3] == "dm:": elif '@' not in existing_ui:
q = projectB.query("UPDATE fingerprint SET uid = %s WHERE id = %s" % (uid_id, fingerprint_id)) q = projectB.query("UPDATE fingerprint SET uid = %s WHERE id = %s" % (uid_id, fingerprint_id))
print "Promoting DM %s to DD %s with keyid 0x%s." % (existing_uid, uid, fingerprint) print "Promoting DM %s to DD %s with keyid 0x%s." % (existing_uid, uid, fingerprint)
else: else:
......
...@@ -298,10 +298,14 @@ def install (): ...@@ -298,10 +298,14 @@ def install ():
filename = files[file]["pool name"] + file filename = files[file]["pool name"] + file
dsc_component = files[file]["component"] dsc_component = files[file]["component"]
dsc_location_id = files[file]["location id"] dsc_location_id = files[file]["location id"]
if dsc.has_key("dm-upload-allowed") and dsc["dm-upload-allowed"] == "yes":
dm_upload_allowed = "true"
else:
dm_upload_allowed = "false"
if not files[file].has_key("files id") or not files[file]["files id"]: if not files[file].has_key("files id") or not files[file]["files id"]:
files[file]["files id"] = database.set_files_id (filename, files[file]["size"], files[file]["md5sum"], files[file]["sha1sum"], files[file]["sha256sum"], dsc_location_id) files[file]["files id"] = database.set_files_id (filename, files[file]["size"], files[file]["md5sum"], files[file]["sha1sum"], files[file]["sha256sum"], dsc_location_id)
projectB.query("INSERT INTO source (source, version, maintainer, changedby, file, install_date, sig_fpr) VALUES ('%s', '%s', %d, %d, %d, '%s', %s)" projectB.query("INSERT INTO source (source, version, maintainer, changedby, file, install_date, sig_fpr, dm_upload_allowed) VALUES ('%s', '%s', %d, %d, %d, '%s', %s, %s)"
% (package, version, maintainer_id, changedby_id, files[file]["files id"], install_date, fingerprint_id)) % (package, version, maintainer_id, changedby_id, files[file]["files id"], install_date, fingerprint_id, dm_upload_allowed))
for suite in changes["distribution"].keys(): for suite in changes["distribution"].keys():
suite_id = database.get_suite_id(suite) suite_id = database.get_suite_id(suite)
...@@ -322,21 +326,20 @@ def install (): ...@@ -322,21 +326,20 @@ def install ():
projectB.query("INSERT INTO dsc_files (source, file) VALUES (currval('source_id_seq'), %d)" % (files_id)) projectB.query("INSERT INTO dsc_files (source, file) VALUES (currval('source_id_seq'), %d)" % (files_id))
# Add the src_uploaders to the DB # Add the src_uploaders to the DB
if dsc.get("dm-upload-allowed", "no") == "yes": uploader_ids = [maintainer_id]
uploader_ids = [maintainer_id] if dsc.has_key("uploaders"):
if dsc.has_key("uploaders"): for u in dsc["uploaders"].split(","):
for u in dsc["uploaders"].split(","): u = u.replace("'", "\\'")
u = u.replace("'", "\\'") u = u.strip()
u = u.strip() uploader_ids.append(
uploader_ids.append( database.get_or_set_maintainer_id(u))
database.get_or_set_maintainer_id(u)) added_ids = {}
added_ids = {} for u in uploader_ids:
for u in uploader_ids: if added_ids.has_key(u):
if added_ids.has_key(u): utils.warn("Already saw uploader %s for source %s" % (u, package))
utils.warn("Already saw uploader %s for source %s" % (u, package)) continue
continue added_ids[u]=1
added_ids[u]=1 projectB.query("INSERT INTO src_uploaders (source, maintainer) VALUES (currval('source_id_seq'), %d)" % (u))
projectB.query("INSERT INTO src_uploaders (source, maintainer) VALUES (currval('source_id_seq'), %d)" % (u))
# Add the .deb files to the DB # Add the .deb files to the DB
......
...@@ -997,7 +997,7 @@ def check_timestamps(): ...@@ -997,7 +997,7 @@ def check_timestamps():
################################################################################ ################################################################################
def lookup_uid_from_fingerprint(fpr): def lookup_uid_from_fingerprint(fpr):
q = Upload.projectB.query("SELECT u.uid, u.name FROM fingerprint f, uid u WHERE f.uid = u.id AND f.fingerprint = '%s'" % (fpr)) q = Upload.projectB.query("SELECT u.uid, u.name, k.debian_maintainer FROM fingerprint f JOIN keyrings k ON (f.keyring=k.id), uid u WHERE f.uid = u.id AND f.fingerprint = '%s'" % (fpr))
qs = q.getresult() qs = q.getresult()
if len(qs) == 0: if len(qs) == 0:
return (None, None) return (None, None)
...@@ -1007,7 +1007,7 @@ def lookup_uid_from_fingerprint(fpr): ...@@ -1007,7 +1007,7 @@ def lookup_uid_from_fingerprint(fpr):
def check_signed_by_key(): def check_signed_by_key():
"""Ensure the .changes is signed by an authorized uploader.""" """Ensure the .changes is signed by an authorized uploader."""
(uid, uid_name) = lookup_uid_from_fingerprint(changes["fingerprint"]) (uid, uid_name, is_dm) = lookup_uid_from_fingerprint(changes["fingerprint"])
if uid_name == None: if uid_name == None:
uid_name = "" uid_name = ""
...@@ -1017,8 +1017,8 @@ def check_signed_by_key(): ...@@ -1017,8 +1017,8 @@ def check_signed_by_key():
may_nmu, may_sponsor = 1, 1 may_nmu, may_sponsor = 1, 1
# XXX by default new dds don't have a fingerprint/uid in the db atm, # XXX by default new dds don't have a fingerprint/uid in the db atm,
# and can't get one in there if we don't allow nmu/sponsorship # and can't get one in there if we don't allow nmu/sponsorship
elif uid[:3] == "dm:": elif is_dm is "t":
uid_email = uid[3:] uid_email = uid
may_nmu, may_sponsor = 0, 0 may_nmu, may_sponsor = 0, 0
else: else:
uid_email = "%s@debian.org" % (uid) uid_email = "%s@debian.org" % (uid)
...@@ -1043,25 +1043,28 @@ def check_signed_by_key(): ...@@ -1043,25 +1043,28 @@ def check_signed_by_key():
if not sponsored and not may_nmu: if not sponsored and not may_nmu:
source_ids = [] source_ids = []
check_suites = changes["distribution"].keys() q = Upload.projectB.query("SELECT s.id, s.version FROM source s JOIN src_associations sa ON (s.id = sa.source) WHERE s.source = '%s' AND s.dm_upload_allowed = 'yes'" % (changes["source"]))
if "unstable" not in check_suites: check_suites.append("unstable")
for suite in check_suites: highest_sid, highest_version = None, None
suite_id = database.get_suite_id(suite)
q = Upload.projectB.query("SELECT s.id FROM source s JOIN src_associations sa ON (s.id = sa.source) WHERE s.source = '%s' AND sa.suite = %d" % (changes["source"], suite_id)) should_reject = True
for si in q.getresult(): for si in q.getresult():
if si[0] not in source_ids: source_ids.append(si[0]) if highest_version == None or apt_pkg.VersionCompare(si[1], highest_version) == 1:
highest_sid = si[0]
is_nmu = 1 highest_version = si[1]
for si in source_ids:
is_nmu = 1 if highest_sid == None:
q = Upload.projectB.query("SELECT m.name FROM maintainer m WHERE m.id IN (SELECT maintainer FROM src_uploaders WHERE src_uploaders.source = %s)" % (si)) reject("Source package %s does not have 'DM-Upload-Allowed: yes' in its most recent version" % changes["source"])
else:
q = Upload.projectB.query("SELECT m.name FROM maintainer m WHERE m.id IN (SELECT su.maintainer FROM src_uploaders su JOIN source s ON (s.id = su.source) WHERE su.source = %s)" % (highest_sid))
for m in q.getresult(): for m in q.getresult():
(rfc822, rfc2047, name, email) = utils.fix_maintainer(m[0]) (rfc822, rfc2047, name, email) = utils.fix_maintainer(m[0])
if email == uid_email or name == uid_name: if email == uid_email or name == uid_name:
is_nmu=0 should_reject=True
break break
if is_nmu:
reject("%s may not upload/NMU source package %s" % (uid, changes["source"])) if should_reject == True:
reject("%s is not in Maintainer or Uploaders of source package %s" % (uid, changes["source"]))
for b in changes["binary"].keys(): for b in changes["binary"].keys():
for suite in changes["distribution"].keys(): for suite in changes["distribution"].keys():
......
#!/usr/bin/env python
# Debian Archive Kit Database Update Script
# Copyright (C) 2008 Michael Casadevall <mcasadevall@debian.org>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
################################################################################
# <Ganneff> when do you have it written?
# <NCommander> Ganneff, after you make my debian account
# <Ganneff> blackmail wont work
# <NCommander> damn it
################################################################################
import psycopg2, sys, fcntl, os
import apt_pkg
import time
from daklib import database
from daklib import utils
################################################################################
Cnf = None
projectB = None
required_database_schema = 1
################################################################################
class UpdateDB:
def usage (self, exit_code=0):
print """Usage: dak update-db
Updates dak's database schema to the lastest version. You should disable crontabs while this is running
-h, --help show this help and exit."""
sys.exit(exit_code)
################################################################################
def update_db_to_zero(self):
# This function will attempt to update a pre-zero database schema to zero
# First, do the sure thing, and create the configuration table
try:
print "Creating configuration table ..."
c = self.db.cursor()
c.execute("""CREATE TABLE config (
id SERIAL PRIMARY KEY NOT NULL,
name TEXT UNIQUE NOT NULL,
value TEXT
);""")
c.execute("INSERT INTO config VALUES ( nextval('config_id_seq'), 'db_revision', '0')");
self.db.commit()
except psycopg2.ProgrammingError:
self.db.rollback()
print "Failed to create configuration table."
print "Can the projectB user CREATE TABLE?"
print ""
print "Aborting update."
sys.exit(-255)
################################################################################
def get_db_rev(self):
global projectB
# We keep database revision info the config table
# Try and access it
try:
c = self.db.cursor()
q = c.execute("SELECT value FROM config WHERE name = 'db_revision';");
return c.fetchone()[0]
except psycopg2.ProgrammingError:
# Whoops .. no config table ...
self.db.rollback()
print "No configuration table found, assuming dak database revision to be pre-zero"
return -1
################################################################################
def update_db(self):
# Ok, try and find the configuration table
print "Determining dak database revision ..."
try:
self.db = psycopg2.connect("dbname='" + Cnf["DB::Name"] + "' host='" + Cnf["DB::Host"] + "' port='" + str(Cnf["DB::Port"]) + "'")
except:
print "FATAL: Failed connect to database"
pass
database_revision = int(self.get_db_rev())
if database_revision == -1:
print "dak database schema predates update-db."
print ""
print "This script will attempt to upgrade it to the lastest, but may fail."
print "Please make sure you have a database backup handy. If you don't, press Ctrl-C now!"
print ""
print "Continuing in five seconds ..."
time.sleep(5)
print ""
print "Attempting to upgrade pre-zero database to zero"
self.update_db_to_zero()
database_revision = 0
print "dak database schema at " + str(database_revision)
print "dak version requires schema " + str(required_database_schema)
if database_revision == required_database_schema:
print "no updates required"
sys.exit(0)
for i in range (database_revision, required_database_schema):
print "updating databse schema from " + str(database_revision) + " to " + str(i+1)
dakdb = __import__("dakdb", globals(), locals(), ['update'+str(i+1)])
update_module = getattr(dakdb, "update"+str(i+1))
update_module.do_update(self)
database_revision += 1
################################################################################
def init (self):
global Cnf, projectB
Cnf = utils.get_conf()
arguments = [('h', "help", "Update-DB::Options::Help")]
for i in [ "help" ]:
if not Cnf.has_key("Update-DB::Options::%s" % (i)):
Cnf["Update-DB::Options::%s" % (i)] = ""
arguments = apt_pkg.ParseCommandLine(Cnf, arguments, sys.argv)
options = Cnf.SubTree("Update-DB::Options")
if options["Help"]:
usage()
elif arguments:
utils.warn("dak update-db takes no arguments.")
usage(exit_code=1)
self.update_db()
try:
lock_fd = os.open(Cnf["Dinstall::LockFile"], os.O_RDWR | os.O_CREAT)
fcntl.lockf(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError, e:
if errno.errorcode[e.errno] == 'EACCES' or errno.errorcode[e.errno] == 'EAGAIN':
utils.fubar("Couldn't obtain lock; assuming another 'dak process-unchecked' is already running.")
################################################################################
if __name__ == '__main__':
app = UpdateDB()
app.init()
def main():
app = UpdateDB()
app.init()
...@@ -41,7 +41,7 @@ echo "Authorised upload by $ID, copying into place" ...@@ -41,7 +41,7 @@ echo "Authorised upload by $ID, copying into place"
OUT=$(mktemp) OUT=$(mktemp)
cp "$BYHAND" "$DESTKR" cp "$BYHAND" "$DESTKR"
dak import-keyring --generate-users "dm:%s" "$DESTKR" >$OUT dak import-keyring -D --generate-users "%s" "$DESTKR" >$OUT
if [ -s "$OUT" ]; then if [ -s "$OUT" ]; then
/usr/sbin/sendmail -odq -oi -t <<EOF /usr/sbin/sendmail -odq -oi -t <<EOF
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册