]> git.decadent.org.uk Git - dak.git/blobdiff - daklib/utils.py
Fix traceback when given suite is not recognized
[dak.git] / daklib / utils.py
index 707d3b85bd4564a8262b9b4e8f00ab8ad0ac2490..c144624a21b13b2872b455badccfd8279bb31efb 100755 (executable)
@@ -39,8 +39,12 @@ import re
 import email as modemail
 import subprocess
 
-from dbconn import DBConn, get_architecture, get_component, get_suite, get_override_type, Keyring
+from dbconn import DBConn, get_architecture, get_component, get_suite, \
+                   get_override_type, Keyring, session_wrapper, \
+                   get_active_keyring_paths, get_primary_keyring_path
+from sqlalchemy import desc
 from dak_exceptions import *
+from gpg import SignedFile
 from textutils import fix_maintainer
 from regexes import re_html_escaping, html_escaping, re_single_line_field, \
                     re_multi_line_field, re_srchasver, re_taint_free, \
@@ -111,7 +115,7 @@ def open_file(filename, mode='r'):
     try:
         f = open(filename, mode)
     except IOError:
-        raise CantOpenError, filename
+        raise CantOpenError(filename)
     return f
 
 ################################################################################
@@ -134,7 +138,7 @@ def our_raw_input(prompt=""):
 
 ################################################################################
 
-def extract_component_from_section(section):
+def extract_component_from_section(section, session=None):
     component = ""
 
     if section.find('/') != -1:
@@ -142,16 +146,25 @@ def extract_component_from_section(section):
 
     # Expand default component
     if component == "":
-        if Cnf.has_key("Component::%s" % section):
-            component = section
-        else:
+        comp = get_component(section, session)
+        if comp is None:
             component = "main"
+        else:
+            component = comp.component_name
 
     return (section, component)
 
 ################################################################################
 
-def parse_deb822(contents, signing_rules=0):
+def parse_deb822(armored_contents, signing_rules=0, keyrings=None, session=None):
+    require_signature = True
+    if keyrings == None:
+        keyrings = []
+        require_signature = False
+
+    signed_file = SignedFile(armored_contents, keyrings=keyrings, require_signature=require_signature)
+    contents = signed_file.contents
+
     error = ""
     changes = {}
 
@@ -159,7 +172,7 @@ def parse_deb822(contents, signing_rules=0):
     lines = contents.splitlines(True)
 
     if len(lines) == 0:
-        raise ParseChangesError, "[Empty changes file]"
+        raise ParseChangesError("[Empty changes file]")
 
     # Reindex by line number so we can easily verify the format of
     # .dsc files...
@@ -169,38 +182,16 @@ def parse_deb822(contents, signing_rules=0):
         index += 1
         indexed_lines[index] = line[:-1]
 
-    inside_signature = 0
-
     num_of_lines = len(indexed_lines.keys())
     index = 0
     first = -1
     while index < num_of_lines:
         index += 1
         line = indexed_lines[index]
-        if line == "":
-            if signing_rules == 1:
-                index += 1
-                if index > num_of_lines:
-                    raise InvalidDscError, index
-                line = indexed_lines[index]
-                if not line.startswith("-----BEGIN PGP SIGNATURE"):
-                    raise InvalidDscError, index
-                inside_signature = 0
-                break
-            else:
-                continue
-        if line.startswith("-----BEGIN PGP SIGNATURE"):
+        if line == "" and signing_rules == 1:
+            if index != num_of_lines:
+                raise InvalidDscError(index)
             break
-        if line.startswith("-----BEGIN PGP SIGNED MESSAGE"):
-            inside_signature = 1
-            if signing_rules == 1:
-                while index < num_of_lines and line != "":
-                    index += 1
-                    line = indexed_lines[index]
-            continue
-        # If we're not inside the signed data, don't process anything
-        if signing_rules >= 0 and not inside_signature:
-            continue
         slf = re_single_line_field.match(line)
         if slf:
             field = slf.groups()[0].lower()
@@ -213,7 +204,7 @@ def parse_deb822(contents, signing_rules=0):
         mlf = re_multi_line_field.match(line)
         if mlf:
             if first == -1:
-                raise ParseChangesError, "'%s'\n [Multi-line field continuing on from nothing?]" % (line)
+                raise ParseChangesError("'%s'\n [Multi-line field continuing on from nothing?]" % (line))
             if first == 1 and changes[field] != "":
                 changes[field] += '\n'
             first = 0
@@ -221,10 +212,7 @@ def parse_deb822(contents, signing_rules=0):
             continue
         error += line
 
-    if signing_rules == 1 and inside_signature:
-        raise InvalidDscError, index
-
-    changes["filecontents"] = "".join(lines)
+    changes["filecontents"] = armored_contents
 
     if changes.has_key("source"):
         # Strip the source version in brackets from the source field,
@@ -235,13 +223,13 @@ def parse_deb822(contents, signing_rules=0):
             changes["source-version"] = srcver.group(2)
 
     if error:
-        raise ParseChangesError, error
+        raise ParseChangesError(error)
 
     return changes
 
 ################################################################################
 
-def parse_changes(filename, signing_rules=0, dsc_file=0):
+def parse_changes(filename, signing_rules=0, dsc_file=0, keyrings=None):
     """
     Parses a changes file and returns a dictionary where each field is a
     key.  The mandatory first argument is the filename of the .changes
@@ -269,8 +257,8 @@ def parse_changes(filename, signing_rules=0, dsc_file=0):
     try:
         unicode(content, 'utf-8')
     except UnicodeError:
-        raise ChangesUnicodeError, "Changes file not proper utf-8"
-    changes = parse_deb822(content, signing_rules)
+        raise ChangesUnicodeError("Changes file not proper utf-8")
+    changes = parse_deb822(content, signing_rules, keyrings=keyrings)
 
 
     if not dsc_file:
@@ -284,7 +272,7 @@ def parse_changes(filename, signing_rules=0, dsc_file=0):
                 missingfields.append(keyword)
 
                 if len(missingfields):
-                    raise ParseChangesError, "Missing mandantory field(s) in changes file (policy 5.5): %s" % (missingfields)
+                    raise ParseChangesError("Missing mandantory field(s) in changes file (policy 5.5): %s" % (missingfields))
 
     return changes
 
@@ -362,7 +350,7 @@ def check_size(where, files):
     for f in files.keys():
         try:
             entry = os.stat(f)
-        except OSError, exc:
+        except OSError as exc:
             if exc.errno == 2:
                 # TODO: This happens when the file is in the pool.
                 continue
@@ -411,10 +399,10 @@ def check_dsc_files(dsc_filename, dsc=None, dsc_files=None):
         (r'orig.tar.gz',               ('orig_tar_gz', 'orig_tar')),
         (r'diff.gz',                   ('debian_diff',)),
         (r'tar.gz',                    ('native_tar_gz', 'native_tar')),
-        (r'debian\.tar\.(gz|bz2)',     ('debian_tar',)),
-        (r'orig\.tar\.(gz|bz2)',       ('orig_tar',)),
-        (r'tar\.(gz|bz2)',             ('native_tar',)),
-        (r'orig-.+\.tar\.(gz|bz2)',    ('more_orig_tar',)),
+        (r'debian\.tar\.(gz|bz2|xz)',  ('debian_tar',)),
+        (r'orig\.tar\.(gz|bz2|xz)',    ('orig_tar',)),
+        (r'tar\.(gz|bz2|xz)',          ('native_tar',)),
+        (r'orig-.+\.tar\.(gz|bz2|xz)', ('more_orig_tar',)),
     )
 
     for f in dsc_files.keys():
@@ -571,7 +559,7 @@ def build_file_list(changes, is_a_dsc=0, field="files", hashname="md5sum"):
             else:
                 (md5, size, name) = s
         except ValueError:
-            raise ParseChangesError, i
+            raise ParseChangesError(i)
 
         if section == "":
             section = "-"
@@ -699,14 +687,14 @@ def send_mail (message, filename=""):
                     os.unlink (filename);
                 return;
 
-        fd = os.open(filename, os.O_RDWR|os.O_EXCL, 0700);
+        fd = os.open(filename, os.O_RDWR|os.O_EXCL, 0o700);
         os.write (fd, message_raw.as_string(True));
         os.close (fd);
 
     # Invoke sendmail
     (result, output) = commands.getstatusoutput("%s < %s" % (Cnf["Dinstall::SendmailCommand"], filename))
     if (result != 0):
-        raise SendmailFailedError, output
+        raise SendmailFailedError(output)
 
     # Clean up any temporary files
     if message:
@@ -724,14 +712,14 @@ def poolify (source, component):
 
 ################################################################################
 
-def move (src, dest, overwrite = 0, perms = 0664):
+def move (src, dest, overwrite = 0, perms = 0o664):
     if os.path.exists(dest) and os.path.isdir(dest):
         dest_dir = dest
     else:
         dest_dir = os.path.dirname(dest)
     if not os.path.exists(dest_dir):
         umask = os.umask(00000)
-        os.makedirs(dest_dir, 02775)
+        os.makedirs(dest_dir, 0o2775)
         os.umask(umask)
     #print "Moving %s to %s..." % (src, dest)
     if os.path.exists(dest) and os.path.isdir(dest):
@@ -747,14 +735,14 @@ def move (src, dest, overwrite = 0, perms = 0664):
     os.chmod(dest, perms)
     os.unlink(src)
 
-def copy (src, dest, overwrite = 0, perms = 0664):
+def copy (src, dest, overwrite = 0, perms = 0o664):
     if os.path.exists(dest) and os.path.isdir(dest):
         dest_dir = dest
     else:
         dest_dir = os.path.dirname(dest)
     if not os.path.exists(dest_dir):
         umask = os.umask(00000)
-        os.makedirs(dest_dir, 02775)
+        os.makedirs(dest_dir, 0o2775)
         os.umask(umask)
     #print "Copying %s to %s..." % (src, dest)
     if os.path.exists(dest) and os.path.isdir(dest):
@@ -1034,8 +1022,8 @@ def parse_args(Options):
         suite_ids_list = []
         for suitename in split_args(Options["Suite"]):
             suite = get_suite(suitename, session=session)
-            if suite.suite_id is None:
-                warn("suite '%s' not recognised." % (suite.suite_name))
+            if not suite or suite.suite_id is None:
+                warn("suite '%s' not recognised." % (suite and suite.suite_name or suitename))
             else:
                 suite_ids_list.append(suite.suite_id)
         if suite_ids_list:
@@ -1265,7 +1253,7 @@ def retrieve_key (filename, keyserver=None, keyring=None):
     if not keyserver:
         keyserver = Cnf["Dinstall::KeyServer"]
     if not keyring:
-        keyring = Cnf.ValueList("Dinstall::GPGKeyring")[0]
+        keyring = get_primary_keyring_path()
 
     # Ensure the filename contains no shell meta-characters or other badness
     if not re_taint_free.match(filename):
@@ -1302,13 +1290,13 @@ def retrieve_key (filename, keyserver=None, keyring=None):
 
 def gpg_keyring_args(keyrings=None):
     if not keyrings:
-        keyrings = Cnf.ValueList("Dinstall::GPGKeyring")
+        keyrings = get_active_keyring_paths()
 
     return " ".join(["--keyring %s" % x for x in keyrings])
 
 ################################################################################
-
-def check_signature (sig_filename, data_filename="", keyrings=None, autofetch=None):
+@session_wrapper
+def check_signature (sig_filename, data_filename="", keyrings=None, autofetch=None, session=None):
     """
     Check the signature of a file and return the fingerprint if the
     signature is valid or 'None' if it's not.  The first argument is the
@@ -1336,7 +1324,7 @@ def check_signature (sig_filename, data_filename="", keyrings=None, autofetch=No
         return (None, rejects)
 
     if not keyrings:
-        keyrings = [ x.keyring_name for x in DBConn().session().query(Keyring).filter(Keyring.active == True).all() ]
+        keyrings = [ x.keyring_name for x in session.query(Keyring).filter(Keyring.active == True).all() ]
 
     # Autofetch the signing key if that's enabled
     if autofetch == None:
@@ -1561,7 +1549,7 @@ def get_changes_files(from_dir):
         # Much of the rest of p-u/p-a depends on being in the right place
         os.chdir(from_dir)
         changes_files = [x for x in os.listdir(from_dir) if x.endswith('.changes')]
-    except OSError, e:
+    except OSError as e:
         fubar("Failed to read list from directory %s (%s)" % (from_dir, e))
 
     return changes_files
@@ -1593,7 +1581,7 @@ def parse_wnpp_bug_file(file = "/srv/ftp-master.debian.org/scripts/masterfiles/w
     try:
         f = open(file)
         lines = f.readlines()
-    except IOError, e:
+    except IOError as e:
         print "Warning:  Couldn't open %s; don't know about WNPP bugs, so won't close any." % file
        lines = []
     wnpp = {}