From: Michael Tremer Date: Mon, 9 Oct 2017 21:22:29 +0000 (+0100) Subject: Refactor jobs X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b92e0a0c238277dee208e66a4a7a322fb4fdb74;p=pbs.git Refactor jobs Signed-off-by: Michael Tremer --- diff --git a/src/buildservice/builds.py b/src/buildservice/builds.py index c5b6cc2e..a102f6e0 100644 --- a/src/buildservice/builds.py +++ b/src/buildservice/builds.py @@ -1341,12 +1341,34 @@ class Build(base.Object): class Jobs(base.Object): + def _get_job(self, query, *args): + res = self.db.get(query, *args) + + if res: + return Job(self.backend, res.id, data=res) + def _get_jobs(self, query, *args): res = self.db.query(query, *args) for row in res: yield Job(self.backend, row.id, data=row) + def create(self, build, arch, type="build"): + job = self._get_job("INSERT INTO jobs(uuid, type, build_id, arch, time_created) \ + VALUES(%s, %s, %s, %s, NOW()) RETURNING *", "%s" % uuid.uuid4(), type, build.id, arch) + job.log("created") + + # Set cache for Build object. + job.build = build + + # Jobs are by default in state "new" and wait for being checked + # for dependencies. Packages that do have no build dependencies + # can directly be forwarded to "pending" state. + if not job.pkg.requires: + job.state = "pending" + + return job + def get_by_id(self, id, data=None): return Job(self.pakfire, id, data) @@ -1516,62 +1538,42 @@ class Jobs(base.Object): return ret -class Job(base.Object): - def __init__(self, pakfire, id, data=None): - base.Object.__init__(self, pakfire) - - # The ID of this Job object. - self.id = id - - # Cache the data of this object. - self._data = data - self._build = None - self._builder = None - self._packages = None - self._logfiles = None +class Job(base.DataObject): + table = "jobs" def __str__(self): return "<%s id=%s %s>" % (self.__class__.__name__, self.id, self.name) - def __cmp__(self, other): - if self.type == "build" and other.type == "test": - return -1 - elif self.type == "test" and other.type == "build": - return 1 - - if self.build_id == other.build_id: - return cmp(self.arch, other.arch) + def __eq__(self, other): + if isinstance(other, self.__class__): + return self.id == other.id - ret = cmp(self.pkg, other.pkg) - - if not ret: - ret = cmp(self.time_created, other.time_created) + def __lt__(self, other): + if isinstance(other, self.__class__): + if (self.type, other.type) == ("build", "test"): + return True - return ret + if self.build == other.build: + return self.arch < other.arch # XXX needs to use the arch prio - @property - def distro(self): - assert self.build.distro - return self.build.distro + return self.time_created < other.time_created - @classmethod - def create(cls, pakfire, build, arch, type="build"): - id = pakfire.db.execute("INSERT INTO jobs(uuid, type, build_id, arch, time_created) \ - VALUES(%s, %s, %s, %s, NOW())", "%s" % uuid.uuid4(), type, build.id, arch) + def __iter__(self): + packages = self.backend.packages._get_packages("SELECT packages.* FROM jobs_packages \ + LEFT JOIN packages ON jobs_packages.pkg_id = packages.id \ + WHERE jobs_packages.job_id = %s ORDER BY packages.name", self.id) - job = Job(pakfire, id) - job.log("created") + return iter(packages) - # Set cache for Build object. - job._build = build + def __len__(self): + res = self.db.get("SELECT COUNT(*) AS len FROM jobs_packages \ + WHERE job_id = %s", self.id) - # Jobs are by default in state "new" and wait for being checked - # for dependencies. Packages that do have no build dependencies - # can directly be forwarded to "pending" state. - if not job.pkg.requires: - job.state = "pending" + return res.len - return job + @property + def distro(self): + return self.build.distro def delete(self): self.__delete_buildroots() @@ -1616,14 +1618,6 @@ class Job(base.Object): self.state = "new" self.log("reset", user=user) - @property - def data(self): - if self._data is None: - self._data = self.db.get("SELECT * FROM jobs WHERE id = %s", self.id) - assert self._data - - return self._data - ## Logging stuff def log(self, action, user=None, state=None, builder=None, test_job=None): @@ -1685,13 +1679,9 @@ class Job(base.Object): def build_id(self): return self.data.build_id - @property + @lazy_property def build(self): - if self._build is None: - self._build = self.pakfire.builds.get_by_id(self.build_id) - assert self._build - - return self._build + return self.pakfire.builds.get_by_id(self.build_id) @property def related_jobs(self): @@ -1796,19 +1786,9 @@ class Job(base.Object): if self._data: self._data["message"] = msg - @property - def builder_id(self): - return self.data.builder_id - def get_builder(self): - if not self.builder_id: - return - - if self._builder is None: - self._builder = builders.Builder(self.pakfire, self.builder_id) - assert self._builder - - return self._builder + if self.data.builder_id: + return self.backend.builders.get_by_id(self.data.builder_id) def set_builder(self, builder, user=None): self.db.execute("UPDATE jobs SET builder_id = %s WHERE id = %s", @@ -1824,16 +1804,12 @@ class Job(base.Object): if user: self.log("builder_assigned", builder=builder, user=user) - builder = property(get_builder, set_builder) + builder = lazy_property(get_builder, set_builder) @property def arch(self): return self.data.arch - @lazy_property - def _arch(self): - return self.backend.arches.get_by_name(self.arch) - @property def duration(self): if not self.time_started: @@ -1884,49 +1860,27 @@ class Job(base.Object): def tries(self): return self.data.tries - @property - def packages(self): - if self._packages is None: - self._packages = [] - - query = "SELECT pkg_id AS id FROM jobs_packages \ - JOIN packages ON packages.id = jobs_packages.pkg_id \ - WHERE jobs_packages.job_id = %s ORDER BY packages.name" - - for pkg in self.db.query(query, self.id): - pkg = packages.Package(self.pakfire, pkg.id) - pkg._job = self - - self._packages.append(pkg) - - return self._packages - def get_pkg_by_uuid(self, uuid): - pkg = self.db.get("SELECT packages.id FROM packages \ + pkg = self.backend.packages._get_package("SELECT packages.id FROM packages \ JOIN jobs_packages ON jobs_packages.pkg_id = packages.id \ WHERE jobs_packages.job_id = %s AND packages.uuid = %s", self.id, uuid) - if not pkg: - return - - pkg = packages.Package(self.pakfire, pkg.id) - pkg._job = self - - return pkg + if pkg: + pkg.job = self + return pkg - @property + @lazy_property def logfiles(self): - if self._logfiles is None: - self._logfiles = [] + logfiles = [] - for log in self.db.query("SELECT id FROM logfiles WHERE job_id = %s", self.id): - log = logs.LogFile(self.pakfire, log.id) - log._job = self + for log in self.db.query("SELECT id FROM logfiles WHERE job_id = %s", self.id): + log = logs.LogFile(self.pakfire, log.id) + log._job = self - self._logfiles.append(log) + logfiles.append(log) - return self._logfiles + return logfiles def add_file(self, filename): """ @@ -2004,11 +1958,7 @@ class Job(base.Object): return self.data.aborted_state def set_aborted_state(self, state): - self.db.execute("UPDATE jobs SET aborted_state = %s WHERE id = %s", - state, self.id) - - if self._data: - self._data["aborted_state"] = state + self._set_attribute("aborted_state", state) aborted_state = property(get_aborted_state, set_aborted_state) @@ -2198,24 +2148,6 @@ class Job(base.Object): return "\n\n".join(confs) - def used_by(self): - if not self.packages: - return [] - - conditions = [] - args = [] - - for pkg in self.packages: - conditions.append(" pkg_uuid = %s") - args.append(pkg.uuid) - - query = "SELECT DISTINCT job_id AS id FROM jobs_buildroots" - query += " WHERE %s" % " OR ".join(conditions) - - job_ids = self.db.query(query, *args) - - print job_ids - def resolvdep(self): config = pakfire.config.Config(files=["general.conf"]) config.parse(self.get_config()) diff --git a/src/buildservice/packages.py b/src/buildservice/packages.py index e2befe71..e2cc088f 100644 --- a/src/buildservice/packages.py +++ b/src/buildservice/packages.py @@ -17,6 +17,18 @@ from . import sources from .constants import * class Packages(base.Object): + def _get_package(self, query, *args): + res = self.db.get(query, *args) + + if res: + return Package(self.backend, res.id, data=res) + + def _get_packages(self, query, *args): + res = self.db.query(query, *args) + + for row in res: + yield Package(self.backend, row.id, data=row) + def get_all_names(self, public=None, user=None, states=None): query = "SELECT DISTINCT packages.name AS name, summary FROM packages \ JOIN builds ON builds.pkg_id = packages.id \ diff --git a/src/templates/jobs-detail.html b/src/templates/jobs-detail.html index ad79d818..3402c6ce 100644 --- a/src/templates/jobs-detail.html +++ b/src/templates/jobs-detail.html @@ -164,15 +164,15 @@ - {% if job.packages %} + {% if len(job) > 0 %}

{{ _("Package files") }} - ({{ len(job.packages) }}) + ({{ len(job) }})

- {% module PackagesTable(job, job.packages) %} + {% module PackagesTable(job, job) %} {% end %} {% if log %}