From: Michael Tremer Date: Sat, 20 May 2023 09:37:15 +0000 (+0000) Subject: monitoring: Refactor the whole thing X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2913e04e6c8029700ff051c9d258a743da5fb326;p=pbs.git monitoring: Refactor the whole thing This is now more of an opt-in which will give us more flexibility Signed-off-by: Michael Tremer --- diff --git a/src/buildservice/__init__.py b/src/buildservice/__init__.py index 8c7263b5..4ac4770b 100644 --- a/src/buildservice/__init__.py +++ b/src/buildservice/__init__.py @@ -66,24 +66,24 @@ class Backend(object): # Initialize the HTTP Client self.httpclient = httpclient.HTTPClient(self) - self.aws = aws.AWS(self) - self.builds = builds.Builds(self) - self.cache = cache.Cache(self) - self.jobs = jobs.Jobs(self) - self.builders = builders.Builders(self) - self.distros = distribution.Distributions(self) - self.events = events.Events(self) - self.keys = keys.Keys(self) - self.logstreams = logstreams.LogStreams(self) - self.messages = messages.Messages(self) - self.mirrors = mirrors.Mirrors(self) - self.packages = packages.Packages(self) - self.releasemonitoring = releasemonitoring.ReleaseMonitoring(self) - self.repos = repository.Repositories(self) - self.sessions = sessions.Sessions(self) - self.sources = sources.Sources(self) - self.uploads = uploads.Uploads(self) - self.users = users.Users(self) + self.aws = aws.AWS(self) + self.builds = builds.Builds(self) + self.cache = cache.Cache(self) + self.jobs = jobs.Jobs(self) + self.builders = builders.Builders(self) + self.distros = distribution.Distributions(self) + self.events = events.Events(self) + self.keys = keys.Keys(self) + self.logstreams = logstreams.LogStreams(self) + self.messages = messages.Messages(self) + self.mirrors = mirrors.Mirrors(self) + self.packages = packages.Packages(self) + self.monitorings = releasemonitoring.Monitorings(self) + self.repos = repository.Repositories(self) + self.sessions = sessions.Sessions(self) + self.sources = sources.Sources(self) + self.uploads = uploads.Uploads(self) + self.users = users.Users(self) # Open a connection to bugzilla. self.bugzilla = bugtracker.Bugzilla(self) diff --git a/src/buildservice/releasemonitoring.py b/src/buildservice/releasemonitoring.py index 1b1e0ba3..2ae838f2 100644 --- a/src/buildservice/releasemonitoring.py +++ b/src/buildservice/releasemonitoring.py @@ -18,6 +18,7 @@ # # ############################################################################### +import asyncio import json import logging import urllib.parse @@ -29,7 +30,32 @@ from .decorators import * # Setup logging log = logging.getLogger("pbs.releasemonitoring") -class ReleaseMonitoring(base.Object): +# Only send up to four simultaneous API requests +ratelimiter = asyncio.Semaphore(value=4) + +BUG_DESCRIPTION = """\ +A new version of %(name)s has been released: %(version)s\ +""" + +BUG_DESCRIPTION_WITH_BUILD = BUG_DESCRIPTION + """\n +XXX PUT STUFF ABOUT THE BUILD HERE +""" + +class ReleaseExistsError(Exception): + """ + Raised if a release already exists + """ + pass + + +class BuildExistsError(Exception): + """ + Raised if the build or a newer one already exists + """ + pass + + +class Monitorings(base.Object): baseurl = "https://release-monitoring.org" @property @@ -37,6 +63,8 @@ class ReleaseMonitoring(base.Object): return self.settings.get("release-monitoring-api-key") async def _request(self, method, url, data=None): + body = {} + # Authenticate to the API headers = { "Authorization" : "Token %s" % self.api_key, @@ -61,36 +89,65 @@ class ReleaseMonitoring(base.Object): # Decode JSON response if res.body: - return json.loads(res.body) + body = json.loads(res.body) - # Return an empty response - return {} + # Check if we have received an error + error = body.get("error") - # Packages + # Raise the error + if error: + raise RuntimeError(error) - def _get_package(self, query, *args): + return body + + def _get_monitoring(self, query, *args): res = self.db.get(query, *args) if res: - return Package(self.backend, id=res.id, data=res) + return Monitoring(self.backend, res.id, res) + + def _get_monitorings(self, query, *args): + res = self.db.query(query, *args) + + for row in res: + yield Monitoring(self.backend, row.id, row) - def get_package(self, distro, name): - return self._get_package(""" + def get_by_id(self, id): + return self._get_monitoring(""" SELECT * FROM - release_monitoring_packages + release_monitorings WHERE - deleted_at IS NULL - AND - distro = %s - AND - name = %s - """, distro, name, + id = %s + """, id, ) - def create_package(self, distro, name): - pass + async def create(self, distro, name, created_by, project_id, + follow="mainline", create_builds=True): + monitoring = self._get_monitoring(""" + INSERT INTO + release_monitorings + ( + distro_id, + name, + created_by, + project_id, + follow, + create_builds + ) + VALUES( + %s, %s, %s, %s, %s, %s + ) + RETURNING + * + """, distro, name, created_by, project_id, follow, + ) + + # Schedule the first check in the background + self.backend.run_task(monitoring.check) + + return monitoring async def search(self, name): """ @@ -107,31 +164,116 @@ class ReleaseMonitoring(base.Object): # Return all packages return [database.Row(item) for item in response.get("items")] + async def check(self, limit=None): + """ + Perform checks on monitorings + """ + # Fetch all monitorings that were never checked or checked longer than 24 hours ago + monitorings = self._get_monitorings(""" + SELECT + * + FROM + release_monitorings + WHERE + deleted_at IS NULL + AND + ( + last_check_at IS NULL + OR + last_check_at <= CURRENT_TIMESTAMP - INTERVAL '24 hours' + ) + ORDER BY + last_check_at ASC NULLS FIRST + LIMIT + %s + """, limit, + ) + + # Perform all checks concurrently + async with asyncio.TaskGroup() as tg: + for monitoring in monitorings: + tg.create_task(monitoring.check()) -class Package(base.DataObject): - table = "release_monitoring_packages" + +class Monitoring(base.DataObject): + table = "release_monitorings" + + def __str__(self): + return "%s - %s" % (self.distro, self.name) @property def distro(self): - return self.data.distro + """ + The distribution + """ + return self.backend.distros.get_by_id(self.data.distro_id) @property def name(self): + """ + The package name + """ return self.data.name + @property + def project_id(self): + return self.data.project_id + + @property + def follow(self): + return self.data.follow + + @property + def create_builds(self): + return self.data.create_builds + + # Check + + async def check(self): + # Wait until we are allowed to send an API request + async with ratelimiter: + log.info("Checking for new releases for %s" % self) + + # Fetch the current versions + versions = await self._fetch_versions() + + with self.db.transaction(): + try: + if self.follow == "mainline": + await self._follow_mainline(versions) + else: + raise ValueError("Cannot handle follow: %s" % self.follow) + + # If the release exists, do nothing + except ReleaseExistsError as e: + log.debug("Release %s already exists" % e) + + async def _fetch_versions(self): + """ + Fetches all versions for this project + """ + response = await self.backend.monitorings._request( + "GET", "/api/v2/versions/", { + "project_id" : self.project_id, + }, + ) + + # Parse the response as JSON and return it + return database.Row(response) + + async def _follow_mainline(self, versions): + """ + This will follow "mainline" i.e. the latest version + """ + return await self.create_release(versions.latest_version) + # Releases def _get_releases(self, query, *args): - res = self.db.query(query, *args) - - for row in res: - yield Release(self.backend, id=row.id, data=row) + return self.db.fetch_many(Release, query, *args, monitoring=self) def _get_release(self, query, *args): - res = self.db.get(query, *args) - - if res: - return Release(self.backend, id=res.id, data=res) + return self.db.fetch_one(Release, query, *args, monitoring=self) @property def latest_release(self): @@ -146,14 +288,14 @@ class Package(base.DataObject): WHERE deleted_at IS NULL AND - package_id = %s + monitoring_id = %s ORDER BY created_at DESC LIMIT 1 """, self.id, ) - @property + @lazy_property def releases(self): releases = self._get_releases(""" SELECT @@ -161,9 +303,7 @@ class Package(base.DataObject): FROM release_monitoring_releases WHERE - deleted_at IS NULL - AND - package_id = %s + monitoring_id = %s ORDER BY created_at DESC """, self.id, @@ -171,152 +311,170 @@ class Package(base.DataObject): return list(releases) - def _create_release(self, version): + def _release_exists(self, version): + """ + Returns True if this version already exists + """ + return version in [release.version for release in self.releases] + + async def create_release(self, version): """ Creates a new release for this package """ # XXX Do we need to check whether we are going backwards? + # Raise an error if the release already exists + if self._release_exists(version): + raise ReleaseExistsError(version) + + # Raise an error if we already have a newer build + elif self._build_exists(version): + raise BuildExistsError(version) + + log.info("%s: Creating new release %s" % (self, version)) + release = self._get_release(""" INSERT INTO release_monitoring_releases ( - package_id, + monitoring_id, version ) VALUES ( %s, %s ) - ON CONFLICT - (package_id, version) - WHERE - deleted_at IS NULL - DO - NOTHING RETURNING * """, self.id, version, ) + # Add the release to cache + self.releases.append(release) + + # Create a bug report + await release._create_bug() + + # Create a build + if self.data.create_builds: + await release._create_build() + # Return the release return release - # Update + # Builds - async def _fetch(self): + def _build_exists(self, version): """ - Fetches all sorts of information about a package + Returns True if a build with this version already exists """ - response = await self.backend.releasemonitoring._request( - "GET", "/api/v2/packages/", { - "distribution" : self.distro, - "name" : self.name, - }, - ) + # XXX needs to check if we already have a newer version - # Fetch all received items - items = response.get("items") + return version in [build.package.version for build in self.builds] - # Is the package known? - if not items: - # Automatically try to create the package - if await self._auto_create_package(): - return await self._fetch() + @property + def builds(self): + return self.distro.get_builds_by_name(self.name) - raise PackageNotFoundError(self.name) + @lazy_property + def latest_build(self): + builds = self.distro.get_builds_by_name(self.name, limit=1) - # Did we receive more than one item? - elif len(items) > 1: - raise RuntimeError("More than one item received for %s" % name) + for build in builds: + return build - for item in items: - return database.Row({ - "version" : item.get("version"), - "stable_version" : item.get("stable_version"), - }) - async def _auto_create_package(self): - """ - Tries to automatically create a package - """ - packages = await self.backend.releasemonitoring.search(self.name) +class Release(base.DataObject): + table = "release_monitoring_releases" - # Use the first exact match - for package in packages: - if not package.name == self.name: - continue + def __str__(self): + return "%s %s" % (self.monitoring.name, self.version) - print(package) + # Monitoring - # Automatically create a mapping - await self.update_mapping( - project_name=package.name, - project_ecosystem=package.ecosystem, - ) - - return True + @lazy_property + def monitoring(self): + return self.backend.monitorings.get_by_id(self.data.monitoring_id) - # We could not create a mapping - return False + # Version - async def update_mapping(self, project_name=None, project_ecosystem=None): - if project_name is None: - project_name = self.name + @property + def version(self): + return self.data.version - # Send request - await self.backend.releasemonitoring._request("POST", "/api/v2/packages/", - { - "distribution" : self.distro, - "package_name" : self.name, - "project_name" : project_name, - "project_ecosystem" : project_ecosystem, - }, - ) + # Bug - async def update(self): + async def _create_bug(self): """ - Update the information we have about this package + Creates a new bug report about this release """ - # Pull information from the API - package = await self._fetch() + args = { + # Product, Version & Component + "product" : self.monitoring.distro.bugzilla_product, + "version" : self.monitoring.distro.bugzilla_version, + "component" : self.monitoring.name, + + # Summary & Description + "summary" : "%s has been released" % self, + "description" : BUG_DESCRIPTION % \ + { + "name" : self.monitoring.name, + "version" : self.version + }, + + # Keywords + "keywords" : [ + # Mark this bug as created automatically + "Monitoring", + + # Mark this bug as a new release + "NewRelease", + ], + } - # Try to create a new release - release = self._create_release(package.stable_version) + # If we have a build, include it in the bug description + if self.build: + args |= { + "description" : BUG_DESCRIPTION_WITH_BUILD % \ + { + "name" : self.monitoring.name, + "version" : self.version + }, + } - # Return the new release - return release + # Create the bug + bug = await self.backend.bugzilla.create_bug(**args) + # Store the bug ID + self._set_attribute("bug_id", bug.id) -class Release(base.DataObject): - table = "release_monitoring_releases" + return bug - def __str__(self): - return self.version + # Build - # Version + def get_build(self): + if self.data.build_id: + return self.backend.builds.get_by_id(self.data.build_id) - @property - def version(self): - return self.data.version + def set_build(self, build): + if self.build: + raise AttributeError("Cannot reset build") - # Builds + self._set_attribute("build_id", build) - @lazy_property - def builds(self): - builds = self.backend.builds._get_builds(""" - SELECT - builds.* - FROM - release_monitoring_release_builds - LEFT JOIN - builds ON release_monitoring_release_builds.build_id = builds.id - WHERE - release_monitoring_release_builds.release_id = %s - AND - builds.deleted_at IS NULL - """, self.id, - ) + build = lazy_property(get_build, set_build) + + async def _create_build(self): + """ + Creates a build + """ + if self.build: + raise RuntimeError("Build already exists") + + # XXX since we cannot yet update any builds, we will simply clone the latest one + # to test the tooling + #print(self.monitoring.latest_build) - # Return builds by distribution - return { build.distro : build for build in builds } + # XXX does this need an owner? + #self.build = await self.monitoring.latest_build.create( + # repo=None, package=self.monitoring.latest_build.package) diff --git a/src/database.sql b/src/database.sql index 95b52c94..05942177 100644 --- a/src/database.sql +++ b/src/database.sql @@ -751,24 +751,24 @@ CREATE VIEW public.relation_sizes AS -- --- Name: release_monitoring_packages; Type: TABLE; Schema: public; Owner: - +-- Name: release_monitoring_releases; Type: TABLE; Schema: public; Owner: - -- -CREATE TABLE public.release_monitoring_packages ( +CREATE TABLE public.release_monitoring_releases ( id integer NOT NULL, - distro text NOT NULL, - name text NOT NULL, + monitoring_id integer NOT NULL, + version text NOT NULL, created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, - deleted_at timestamp without time zone, - auto_update boolean DEFAULT true NOT NULL + bug_id integer, + build_id integer ); -- --- Name: release_monitoring_packages_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- Name: release_monitoring_releases_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- -CREATE SEQUENCE public.release_monitoring_packages_id_seq +CREATE SEQUENCE public.release_monitoring_releases_id_seq AS integer START WITH 1 INCREMENT BY 1 @@ -778,42 +778,36 @@ CREATE SEQUENCE public.release_monitoring_packages_id_seq -- --- Name: release_monitoring_packages_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- Name: release_monitoring_releases_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- -ALTER SEQUENCE public.release_monitoring_packages_id_seq OWNED BY public.release_monitoring_packages.id; +ALTER SEQUENCE public.release_monitoring_releases_id_seq OWNED BY public.release_monitoring_releases.id; -- --- Name: release_monitoring_release_builds; Type: TABLE; Schema: public; Owner: - +-- Name: release_monitorings; Type: TABLE; Schema: public; Owner: - -- -CREATE TABLE public.release_monitoring_release_builds ( +CREATE TABLE public.release_monitorings ( id integer NOT NULL, - release_id integer NOT NULL, distro_id integer NOT NULL, - build_id integer NOT NULL -); - - --- --- Name: release_monitoring_releases; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.release_monitoring_releases ( - id integer NOT NULL, - package_id integer NOT NULL, - version text NOT NULL, + name text NOT NULL, created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, - deleted_at timestamp without time zone + created_by integer NOT NULL, + deleted_at timestamp without time zone, + deleted_by integer, + project_id integer NOT NULL, + follow text NOT NULL, + last_check_at timestamp without time zone, + create_builds boolean DEFAULT true NOT NULL ); -- --- Name: release_monitoring_releases_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- Name: release_monitorings_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- -CREATE SEQUENCE public.release_monitoring_releases_id_seq +CREATE SEQUENCE public.release_monitorings_id_seq AS integer START WITH 1 INCREMENT BY 1 @@ -823,10 +817,10 @@ CREATE SEQUENCE public.release_monitoring_releases_id_seq -- --- Name: release_monitoring_releases_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- Name: release_monitorings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - -- -ALTER SEQUENCE public.release_monitoring_releases_id_seq OWNED BY public.release_monitoring_releases.id; +ALTER SEQUENCE public.release_monitorings_id_seq OWNED BY public.release_monitorings.id; -- @@ -1246,17 +1240,17 @@ ALTER TABLE ONLY public.packages ALTER COLUMN id SET DEFAULT nextval('public.pac -- --- Name: release_monitoring_packages id; Type: DEFAULT; Schema: public; Owner: - +-- Name: release_monitoring_releases id; Type: DEFAULT; Schema: public; Owner: - -- -ALTER TABLE ONLY public.release_monitoring_packages ALTER COLUMN id SET DEFAULT nextval('public.release_monitoring_packages_id_seq'::regclass); +ALTER TABLE ONLY public.release_monitoring_releases ALTER COLUMN id SET DEFAULT nextval('public.release_monitoring_releases_id_seq'::regclass); -- --- Name: release_monitoring_releases id; Type: DEFAULT; Schema: public; Owner: - +-- Name: release_monitorings id; Type: DEFAULT; Schema: public; Owner: - -- -ALTER TABLE ONLY public.release_monitoring_releases ALTER COLUMN id SET DEFAULT nextval('public.release_monitoring_releases_id_seq'::regclass); +ALTER TABLE ONLY public.release_monitorings ALTER COLUMN id SET DEFAULT nextval('public.release_monitorings_id_seq'::regclass); -- @@ -1420,27 +1414,19 @@ ALTER TABLE ONLY public.packages -- --- Name: release_monitoring_packages release_monitoring_packages_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.release_monitoring_packages - ADD CONSTRAINT release_monitoring_packages_pkey PRIMARY KEY (id); - - --- --- Name: release_monitoring_release_builds release_monitoring_release_builds_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- Name: release_monitoring_releases release_monitoring_releases_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- -ALTER TABLE ONLY public.release_monitoring_release_builds - ADD CONSTRAINT release_monitoring_release_builds_pkey PRIMARY KEY (id); +ALTER TABLE ONLY public.release_monitoring_releases + ADD CONSTRAINT release_monitoring_releases_pkey PRIMARY KEY (id); -- --- Name: release_monitoring_releases release_monitoring_releases_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- Name: release_monitorings release_monitorings_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- -ALTER TABLE ONLY public.release_monitoring_releases - ADD CONSTRAINT release_monitoring_releases_pkey PRIMARY KEY (id); +ALTER TABLE ONLY public.release_monitorings + ADD CONSTRAINT release_monitorings_pkey PRIMARY KEY (id); -- @@ -1739,24 +1725,24 @@ CREATE INDEX packages_name ON public.packages USING btree (name); -- --- Name: release_monitoring_packages_unique; Type: INDEX; Schema: public; Owner: - +-- Name: release_monitoring_releases_search; Type: INDEX; Schema: public; Owner: - -- -CREATE UNIQUE INDEX release_monitoring_packages_unique ON public.release_monitoring_packages USING btree (distro, name) WHERE (deleted_at IS NULL); +CREATE INDEX release_monitoring_releases_search ON public.release_monitoring_releases USING btree (monitoring_id, created_at); -- --- Name: release_monitoring_release_builds_release_id; Type: INDEX; Schema: public; Owner: - +-- Name: release_monitoring_releases_unique; Type: INDEX; Schema: public; Owner: - -- -CREATE INDEX release_monitoring_release_builds_release_id ON public.release_monitoring_release_builds USING btree (release_id); +CREATE UNIQUE INDEX release_monitoring_releases_unique ON public.release_monitoring_releases USING btree (monitoring_id, version); -- --- Name: release_monitoring_releases_unique; Type: INDEX; Schema: public; Owner: - +-- Name: release_monitorings_unique; Type: INDEX; Schema: public; Owner: - -- -CREATE UNIQUE INDEX release_monitoring_releases_unique ON public.release_monitoring_releases USING btree (package_id, version) WHERE (deleted_at IS NULL); +CREATE UNIQUE INDEX release_monitorings_unique ON public.release_monitorings USING btree (distro_id, name) WHERE (deleted_at IS NULL); -- @@ -2139,35 +2125,35 @@ ALTER TABLE ONLY public.packages -- --- Name: release_monitoring_release_builds release_monitoring_release_builds_build_id; Type: FK CONSTRAINT; Schema: public; Owner: - +-- Name: release_monitoring_releases release_monitoring_releases_monitoring_id; Type: FK CONSTRAINT; Schema: public; Owner: - -- -ALTER TABLE ONLY public.release_monitoring_release_builds - ADD CONSTRAINT release_monitoring_release_builds_build_id FOREIGN KEY (build_id) REFERENCES public.builds(id); +ALTER TABLE ONLY public.release_monitoring_releases + ADD CONSTRAINT release_monitoring_releases_monitoring_id FOREIGN KEY (monitoring_id) REFERENCES public.release_monitorings(id); -- --- Name: release_monitoring_release_builds release_monitoring_release_builds_distro_id; Type: FK CONSTRAINT; Schema: public; Owner: - +-- Name: release_monitorings release_monitorings_created_by; Type: FK CONSTRAINT; Schema: public; Owner: - -- -ALTER TABLE ONLY public.release_monitoring_release_builds - ADD CONSTRAINT release_monitoring_release_builds_distro_id FOREIGN KEY (distro_id) REFERENCES public.distributions(id); +ALTER TABLE ONLY public.release_monitorings + ADD CONSTRAINT release_monitorings_created_by FOREIGN KEY (created_by) REFERENCES public.users(id); -- --- Name: release_monitoring_release_builds release_monitoring_release_builds_release_id; Type: FK CONSTRAINT; Schema: public; Owner: - +-- Name: release_monitorings release_monitorings_deleted_by; Type: FK CONSTRAINT; Schema: public; Owner: - -- -ALTER TABLE ONLY public.release_monitoring_release_builds - ADD CONSTRAINT release_monitoring_release_builds_release_id FOREIGN KEY (release_id) REFERENCES public.release_monitoring_releases(id); +ALTER TABLE ONLY public.release_monitorings + ADD CONSTRAINT release_monitorings_deleted_by FOREIGN KEY (deleted_by) REFERENCES public.users(id); -- --- Name: release_monitoring_releases release_monitoring_releases_package_id; Type: FK CONSTRAINT; Schema: public; Owner: - +-- Name: release_monitorings release_monitorings_distro_id; Type: FK CONSTRAINT; Schema: public; Owner: - -- -ALTER TABLE ONLY public.release_monitoring_releases - ADD CONSTRAINT release_monitoring_releases_package_id FOREIGN KEY (package_id) REFERENCES public.release_monitoring_packages(id); +ALTER TABLE ONLY public.release_monitorings + ADD CONSTRAINT release_monitorings_distro_id FOREIGN KEY (distro_id) REFERENCES public.distributions(id); -- diff --git a/src/scripts/pakfire-build-service b/src/scripts/pakfire-build-service index ed30120e..6d5f5fee 100644 --- a/src/scripts/pakfire-build-service +++ b/src/scripts/pakfire-build-service @@ -41,7 +41,7 @@ class Cli(object): "mirrors:check" : self._mirrors_check, # Release Monitoring - "releasemonitoring:update" : self._release_monitoring_update, + "releasemonitoring:check" : self._release_monitoring_check, # Repositories "repos:fetch-sources" : self.backend.repos.fetch_sources, @@ -174,26 +174,11 @@ class Cli(object): for repo in sorted(self.backend.repos): await repo.relaunch_pending_jobs() - async def _release_monitoring_update(self, *names): + async def _release_monitoring_check(self, *names): """ - Performs an update for the given package + Performs any outstanding checks """ - for name in names: - build = self.backend.builds.get_latest_by_name(name) - if not build: - log.error("Could not find package %s" % name) - continue - - with self.backend.db.transaction(): - # Show what we are working on - print(build.pkg) - - # Perform the update - release = await build.pkg.release_monitoring.update() - - # Show any new releases - if release: - print(" Found new release: %s" % release) + await self.backend.monitorings.check() async def _mirrors_check(self): """ diff --git a/src/web/__init__.py b/src/web/__init__.py index 351ff7b3..1cf391fb 100644 --- a/src/web/__init__.py +++ b/src/web/__init__.py @@ -225,6 +225,9 @@ class Application(tornado.web.Application): # Regularly check the mirrors self.backend.run_periodic_task(300, self.backend.mirrors.check) + # Regularly check for new releases + self.backend.run_periodic_task(300, self.backend.monitoring.check) + ## UI methods def extract_hostname(self, handler, url):