+ def autobuild_upload(self, changes, srcpath, session=None):
+ """
+ Update queue_build database table used for incoming autobuild support.
+
+ @type changes: Changes
+ @param changes: changes object for the upload to process
+
+ @type srcpath: string
+ @param srcpath: path for the queue file entries/link destinations
+
+ @type session: SQLAlchemy session
+ @param session: Optional SQLAlchemy session. If this is passed, the
+ caller is responsible for ensuring a transaction has begun and
+ committing the results or rolling back based on the result code. If
+ not passed, a commit will be performed at the end of the function,
+ otherwise the caller is responsible for commiting.
+
+ @rtype: NoneType or string
+ @return: None if the operation failed, a string describing the error if not
+ """
+
+ localcommit = False
+ if session is None:
+ session = DBConn().session()
+ localcommit = True
+
+ # TODO: Remove by moving queue config into the database
+ conf = Config()
+
+ for suitename in changes.changes["distribution"].keys():
+ # TODO: Move into database as:
+ # buildqueuedir TEXT DEFAULT NULL (i.e. NULL is no build)
+ # buildqueuecopy BOOLEAN NOT NULL DEFAULT FALSE (i.e. default is symlink)
+ # This also gets rid of the SecurityQueueBuild hack below
+ if suitename not in conf.ValueList("Dinstall::QueueBuildSuites"):
+ continue
+
+ # Find suite object
+ s = get_suite(suitename, session)
+ if s is None:
+ return "INTERNAL ERROR: Could not find suite %s" % suitename
+
+ # TODO: Get from database as above
+ dest_dir = conf["Dir::QueueBuild"]
+
+ # TODO: Move into database as above
+ if conf.FindB("Dinstall::SecurityQueueBuild"):
+ dest_dir = os.path.join(dest_dir, suitename)
+
+ for file_entry in changes.files.keys():
+ src = os.path.join(srcpath, file_entry)
+ dest = os.path.join(dest_dir, file_entry)
+
+ # TODO: Move into database as above
+ if Cnf.FindB("Dinstall::SecurityQueueBuild"):
+ # Copy it since the original won't be readable by www-data
+ utils.copy(src, dest)
+ else:
+ # Create a symlink to it
+ os.symlink(src, dest)
+
+ qb = QueueBuild()
+ qb.suite_id = s.suite_id
+ qb.queue_id = self.queue_id
+ qb.filename = dest
+ qb.in_queue = True
+
+ session.add(qb)
+
+ # If the .orig.tar.gz is in the pool, create a symlink to
+ # it (if one doesn't already exist)
+ if changes.orig_tar_id:
+ # Determine the .orig.tar.gz file name
+ for dsc_file in changes.dsc_files.keys():
+ if dsc_file.endswith(".orig.tar.gz"):
+ filename = dsc_file
+
+ dest = os.path.join(dest_dir, filename)
+
+ # If it doesn't exist, create a symlink
+ if not os.path.exists(dest):
+ q = session.execute("SELECT l.path, f.filename FROM location l, files f WHERE f.id = :id and f.location = l.id",
+ {'id': changes.orig_tar_id})
+ res = q.fetchone()
+ if not res:
+ return "[INTERNAL ERROR] Couldn't find id %s in files table." % (changes.orig_tar_id)
+
+ src = os.path.join(res[0], res[1])
+ os.symlink(src, dest)
+
+ # Add it to the list of packages for later processing by apt-ftparchive
+ qb = QueueBuild()
+ qb.suite_id = s.suite_id
+ qb.queue_id = self.queue_id
+ qb.filename = dest
+ qb.in_queue = True
+ session.add(qb)
+
+ # If it does, update things to ensure it's not removed prematurely
+ else:
+ qb = get_queue_build(dest, suite_id, session)
+ if qb is None:
+ qb.in_queue = True
+ qb.last_used = None
+ session.add(qb)
+
+ if localcommit:
+ session.commit()
+
+ return None
+