class Group(orm.SQLObject): #pylint: disable-msg=R0904 """ An ultra-simple group definition. """ class sqlmeta: #pylint: disable-msg=C0103,R0903 """ names like "Group", "Order" and "User" are reserved words in SQL so we set the name to something safe for SQL """ table = "tg_group" group_name = orm.col.UnicodeCol(length=16, alternateID=True, alternateMethodName="by_group_name") display_name = orm.col.UnicodeCol(length=255) created = orm.col.DateTimeCol(default=datetime.now) # collection of all users belonging to this group users = orm.RelatedJoin("User", intermediateTable="user_group", joinColumn="group_id", otherColumn="user_id") # collection of all permissions for this group permissions = orm.RelatedJoin("Permission", joinColumn="group_id", intermediateTable="group_permission", otherColumn="permission_id")
class Soname(sqlobject.SQLObject): class sqlmeta(myMeta): pass soname = sqlobject.StringCol(alternateID=True) needed_by = sqlobject.RelatedJoin('Filedata', otherColumn='filedata_id', joinColumn='soname_id', intermediateTable='dt_needed_list', addRemoveName='FileThatRequires') has_soname = sqlobject.RelatedJoin('Filedata', otherColumn='filedata_id', joinColumn='soname_id', intermediateTable='soname_list', addRemoveName='FileWithSoname')
class License(sqlobject.SQLObject): class sqlmeta(myMeta): pass license = sqlobject.StringCol(alternateID=True) license_type = sqlobject.StringCol() filesWith = sqlobject.RelatedJoin('License', otherColumn='filedata_id', joinColumn='license_id', intermediateTable='filedata_license', addRemoveName='FileWith')
class Permission(orm.SQLObject): #pylint: disable-msg=R0904 """ basic permission model """ permission_name = orm.col.UnicodeCol( length=16, alternateID=True, alternateMethodName="by_permission_name") description = orm.col.UnicodeCol(length=255) groups = orm.RelatedJoin("Group", intermediateTable="group_permission", joinColumn="permission_id", otherColumn="group_id")
class Filedata(sqlobject.SQLObject): class sqlmeta(myMeta): pass basename = sqlobject.StringCol() full_path = sqlobject.StringCol(alternateID=True) dt_needed = sqlobject.RelatedJoin('Soname', joinColumn='filedata_id', otherColumn='soname_id', intermediateTable='dt_needed_list', addRemoveName='DtNeeded') soname = sqlobject.RelatedJoin('Soname', joinColumn='filedata_id', otherColumn='soname_id', intermediateTable='soname_list', addRemoveName='Soname') license = sqlobject.RelatedJoin('License', joinColumn='filedata_id', otherColumn='license_id', intermediateTable='filedata_license', addRemoveName='License') tags = sqlobject.MultipleJoin('Tag')
class User(orm.SQLObject): #pylint: disable-msg=R0904 """ Reasonably basic User definition. Probably would want additional attributes. """ class sqlmeta: #pylint: disable-msg=C0103,R0903 """ names like "Group", "Order" and "User" are reserved words in SQL so we set the name to something safe for SQL """ table = "tg_user" user_name = orm.col.UnicodeCol(length=16, alternateID=True, alternateMethodName="by_user_name") email_address = orm.col.UnicodeCol(length=255, alternateID=True, alternateMethodName="by_email_address") display_name = orm.col.UnicodeCol(length=255) password = orm.col.UnicodeCol(length=40) created = orm.col.DateTimeCol(default=datetime.now) # groups this user belongs to groups = orm.RelatedJoin("Group", intermediateTable="user_group", joinColumn="user_id", otherColumn="group_id") def _get_permissions(self): """ return the permissions """ perms = set() for group in self.groups: perms = perms | set(group.permissions) return perms def _set_password(self, cleartext_password): "Runs cleartext_password through the hash algorithm before saving." password_hash = identity.encrypt_password(cleartext_password) self._SO_set_password(password_hash) #pylint: disable-msg=E1101 def set_password_raw(self, password): "Saves the password as-is to the database." self._SO_set_password(password) #pylint: disable-msg=E1101
class Job(threading.Thread, sqlobject.SQLObject): """Class implementing a build job""" status = sqlobject.IntCol(default=JobStatus.UNKNOWN) mailto = sqlobject.StringCol(default=None) package = sqlobject.ForeignKey('Package', cascade=True) dist = sqlobject.StringCol(default='sid') arch = sqlobject.StringCol(default='any') creation_date = sqlobject.DateTimeCol(default=sqlobject.DateTimeCol.now) status_changed = sqlobject.DateTimeCol(default=None) build_start = sqlobject.DateTimeCol(default=None) build_end = sqlobject.DateTimeCol(default=None) host = sqlobject.StringCol(default=None) deps = sqlobject.RelatedJoin('Job', joinColumn='joba', otherColumn='jobb') log = sqlobject.SingleJoin('Log') notify = None def __init__(self, *args, **kwargs): """Init job""" threading.Thread.__init__(self) sqlobject.SQLObject.__init__(self, *args, **kwargs) self.do_quit = threading.Event() self.status_lock = threading.Lock() def __setattr__(self, name, value): """Override setattr to log build status changes""" if name == "status": RebuilddLog.info("Job %s for %s_%s on %s/%s changed status from %s to %s"\ % (self.id, self.package.name, self.package.version, self.dist, self.arch, JobStatus.whatis(self.status), JobStatus.whatis(value))) self.status_changed = sqlobject.DateTimeCol.now() sqlobject.SQLObject.__setattr__(self, name, value) @property def logfile(self): """Compute and return logfile name""" build_log_file = "%s/%s_%s-%s-%s-%s.%s.log" % (RebuilddConfig().get('log', 'logs_dir'), self.package.name, self.package.version, self.dist, self.arch, self.creation_date.strftime("%Y%m%d-%H%M%S"), self.id) return build_log_file def preexec_child(self): """Start a new group process before executing child""" os.setsid() def get_source_cmd(self): """Return command used for grabing source for this distribution Substitutions are done in the command strings: $d => The distro's name $a => the target architecture $p => the package's name $v => the package's version $j => rebuildd job id """ try: args = { 'd': self.dist, 'a': self.arch, \ 'v': self.package.version, 'p': self.package.name, \ 'j': str(self.id) } t = Template(RebuilddConfig().get('build', 'source_cmd')) return t.safe_substitute(**args) except TypeError, error: RebuilddLog.error("get_source_cmd has invalid format: %s" % error) return None
class Package(threading.Thread, sqlobject.SQLObject): """ check package with pkgname, pkgver, reponame, action, hashsum action will be ['commit', 'release', 'candidate', 'rebuild', ...] """ pkgname = sqlobject.StringCol() pkgver = sqlobject.StringCol() reponame = sqlobject.StringCol(default="default") action = sqlobject.StringCol(default="commit") build_args = sqlobject.StringCol(default=None) hashsum = sqlobject.StringCol(default=None) expired = sqlobject.DateTimeCol(default=sqlobject.DateTimeCol.now) priority = sqlobject.StringCol(default=None) jobs = sqlobject.MultipleJoin('Job', joinColumn='package_id') triggered = sqlobject.IntCol(default=1) upload_status = sqlobject.IntCol(default=UploadStatus.UNKNOWN) status_changed = sqlobject.DateTimeCol(default=sqlobject.DateTimeCol.now) deps = sqlobject.RelatedJoin('Package', joinColumn='pkga', otherColumn='pkgb') notify = None def __init__(self, *args, **kwargs): sqlobject.SQLObject.__init__(self, *args, **kwargs) threading.Thread.__init__(self) self.do_quit = threading.Event() self.status_lock = status_lock def __setattr__(self, name, value): if name == "upload_status": self.status_changed = sqlobject.DateTimeCol.now() sqlobject.SQLObject.__setattr__(self, name, value) def dict(self): result = { "id": self.id, "pkgname": self.pkgname, "pkgver": self.pkgver, "reponame": self.reponame, "action": self.action, "hashsum": self.hashsum, "expired": try_strftime(self.expired, default='never'), "priority": self.priority, "triggered": self.triggered, "build_args": self.build_args.split('|') if self.build_args else [], "upload_status": UploadStatus.whatis(self.upload_status), "status_changed": try_strftime(self.status_changed) } return result @staticmethod def version_compare(a, b): if version.parse(a.pkgver) >= version.parse(b.pkgver): return True return False def giveup(self): self.upload_status = UploadStatus.UPLOAD_GIVEUP for job in self.jobs: if job.status == JobStatus.WAIT: job.status = JobStatus.GIVEUP def is_allowed_to_build(self): for dep in Package.selectBy(id=self)[0].deps: if Package.selectBy( id=dep)[0].upload_status != UploadStatus.UPLOAD_OK: if self.is_maybe_giveup(): self.giveup() return False return True def is_maybe_giveup(self): for dep in Package.selectBy(id=self)[0].deps: for job in Package.selectBy(id=dep)[0].jobs: if Job.selectBy(id=job)[0].status in JobFailedStatus: return True return False def add_dep(self, dep): for exist_dep in self.deps: if exist_dep.id == dep.id: return self.addPackage(dep) def add_deps(self, deps): for dep in deps: self.add_dep(dep)