"""module to process policy queue uploads"""
from .config import Config
-from .dbconn import BinaryMetadata, Component, MetadataKey, Override, OverrideType
+from .dbconn import BinaryMetadata, Component, MetadataKey, Override, OverrideType, Suite, get_mapped_component
from .fstransactions import FilesystemTransaction
from .regexes import re_file_changes, re_file_safe
+import daklib.utils as utils
import errno
import os
class UploadCopy(object):
"""export a policy queue upload
- This class can be used in a with-statements:
+ This class can be used in a with-statement::
with UploadCopy(...) as copy:
...
Doing so will provide a temporary copy of the upload in the directory
- given by the `directory` attribute. The copy will be removed on leaving
+ given by the C{directory} attribute. The copy will be removed on leaving
the with-block.
-
- Args:
- upload (daklib.dbconn.PolicyQueueUpload)
"""
def __init__(self, upload):
+ """initializer
+
+ @type upload: L{daklib.dbconn.PolicyQueueUpload}
+ @param upload: upload to handle
+ """
+
self.directory = None
self.upload = upload
- def export(self, directory, mode=None, symlink=True):
+ def export(self, directory, mode=None, symlink=True, ignore_existing=False):
"""export a copy of the upload
- Args:
- directory (str)
+ @type directory: str
+ @param directory: directory to export to
- Kwargs:
- mode (int): permissions to use for the copied files
- symlink (bool): use symlinks instead of copying the files (default: True)
+ @type mode: int
+ @param mode: permissions to use for the copied files
+
+ @type symlink: bool
+ @param symlink: use symlinks instead of copying the files
+
+ @type ignore_existing: bool
+ @param ignore_existing: ignore already existing files
"""
with FilesystemTransaction() as fs:
source = self.upload.source
for dsc_file in source.srcfiles:
f = dsc_file.poolfile
dst = os.path.join(directory, os.path.basename(f.filename))
- fs.copy(f.fullpath, dst, mode=mode, symlink=symlink)
+ if not os.path.exists(dst) or not ignore_existing:
+ fs.copy(f.fullpath, dst, mode=mode, symlink=symlink)
+
for binary in self.upload.binaries:
f = binary.poolfile
dst = os.path.join(directory, os.path.basename(f.filename))
- fs.copy(f.fullpath, dst, mode=mode, symlink=symlink)
+ if not os.path.exists(dst) or not ignore_existing:
+ fs.copy(f.fullpath, dst, mode=mode, symlink=symlink)
# copy byhand files
for byhand in self.upload.byhand:
src = os.path.join(queue.path, byhand.filename)
dst = os.path.join(directory, byhand.filename)
- fs.copy(src, dst, mode=mode, symlink=symlink)
+ if not os.path.exists(dst) or not ignore_existing:
+ fs.copy(src, dst, mode=mode, symlink=symlink)
# copy .changes
src = os.path.join(queue.path, self.upload.changes.changesname)
dst = os.path.join(directory, self.upload.changes.changesname)
- fs.copy(src, dst, mode=mode, symlink=symlink)
+ if not os.path.exists(dst) or not ignore_existing:
+ fs.copy(src, dst, mode=mode, symlink=symlink)
def __enter__(self):
assert self.directory is None
def __init__(self, upload, session):
"""initializer
- Args:
- upload (daklib.dbconn.PolicyQueueUpload): upload to process
- session: database session
+ @type upload: L{daklib.dbconn.PolicyQueueUpload}
+ @param upload: upload to process
+
+ @param session: database session
"""
self.upload = upload
self.session = session
def _source_override(self, component_name):
package = self.upload.source.source
suite = self._overridesuite
+ component = get_mapped_component(component_name, self.session)
query = self.session.query(Override).filter_by(package=package, suite=suite) \
.join(OverrideType).filter(OverrideType.overridetype == 'dsc') \
- .join(Component).filter(Component.component_name == component_name)
+ .filter(Override.component == component)
return query.first()
def _binary_override(self, binary, component_name):
package = binary.package
suite = self._overridesuite
overridetype = binary.binarytype
+ component = get_mapped_component(component_name, self.session)
query = self.session.query(Override).filter_by(package=package, suite=suite) \
.join(OverrideType).filter(OverrideType.overridetype == overridetype) \
- .join(Component).filter(Component.component_name == component_name)
+ .filter(Override.component == component)
return query.first()
def _binary_metadata(self, binary, key):
def reject(self, reason):
"""mark upload as rejected
- Args:
- reason (str): reason for the rejection
+ @type reason: str
+ @param reason: reason for the rejection
"""
+ cnf = Config()
+
fn1 = 'REJECT.{0}'.format(self._changes_prefix)
assert re_file_safe.match(fn1)
try:
fh = os.open(fn, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
os.write(fh, 'NOTOK\n')
+ os.write(fh, 'From: {0} <{1}>\n\n'.format(utils.whoami(), cnf['Dinstall::MyAdminAddress']))
os.write(fh, reason)
os.close(fh)
except OSError as e:
def get_action(self):
"""get current action
- Returns:
- string giving the current action, one of 'ACCEPT', 'ACCEPTED', 'REJECT'
+ @rtype: str
+ @return: string giving the current action, one of 'ACCEPT', 'ACCEPTED', 'REJECT'
"""
changes_prefix = self._changes_prefix
def missing_overrides(self, hints=None):
"""get missing override entries for the upload
- Kwargs:
- hints (list of dict): suggested hints for new overrides in the same
- format as the return value
-
- Returns:
- list of dicts with the following keys:
- package: package name
- priority: default priority (from upload)
- section: default section (from upload)
- component: default component (from upload)
- type: type of required override ('dsc', 'deb' or 'udeb')
- All values are strings.
+ @type hints: list of dict
+ @param hints: suggested hints for new overrides in the same format as
+ the return value
+
+ @return: list of dicts with the following keys:
+
+ - package: package name
+ - priority: default priority (from upload)
+ - section: default section (from upload)
+ - component: default component (from upload)
+ - type: type of required override ('dsc', 'deb' or 'udeb')
+
+ All values are strings.
"""
# TODO: use Package-List field
missing = []
if section.find('/') != -1:
component = section.split('/', 1)[0]
override = self._binary_override(binary, component)
- if override is None:
+ if override is None and not any(o['package'] == binary.package and o['type'] == binary.binarytype for o in missing):
hint = hints_map.get((binary.binarytype, binary.package))
if hint is not None:
missing.append(hint)