]> git.ipfire.org Git - people/ms/pakfire.git/commitdiff
Merge branch 'master' of ssh://people.ipfire.org/pub/git/pakfire
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 23 Oct 2022 17:33:43 +0000 (17:33 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 23 Oct 2022 17:33:43 +0000 (17:33 +0000)
Makefile.am
src/pakfire/client.py [deleted file]
src/pakfire/hub.py
src/scripts/pakfire-client.in

index 0f26c83fa230a58e6e71a732a3ef28190b1df694..42ca63c758859b2f32befcf57e8f2c888423a843 100644 (file)
@@ -124,7 +124,6 @@ CLEANFILES += \
 pakfire_PYTHON = \
        src/pakfire/__init__.py \
        src/pakfire/__version__.py \
-       src/pakfire/client.py \
        src/pakfire/config.py \
        src/pakfire/constants.py \
        src/pakfire/daemon.py \
diff --git a/src/pakfire/client.py b/src/pakfire/client.py
deleted file mode 100644 (file)
index 9eb4764..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-#!/usr/bin/python3
-###############################################################################
-#                                                                             #
-# Pakfire - The IPFire package management system                              #
-# Copyright (C) 2013 Pakfire development team                                 #
-#                                                                             #
-# This program is free software: you can redistribute it and/or modify        #
-# it under the terms of the GNU General Public License as published by        #
-# the Free Software Foundation, either version 3 of the License, or           #
-# (at your option) any later version.                                         #
-#                                                                             #
-# This program is distributed in the hope that it will be useful,             #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
-# GNU General Public License for more details.                                #
-#                                                                             #
-# You should have received a copy of the GNU General Public License           #
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
-#                                                                             #
-###############################################################################
-
-import logging
-
-from . import config
-from . import hub
-
-from .constants import *
-from .i18n import _
-
-log = logging.getLogger("pakfire.client")
-log.propagate = 1
-
-class Client(object):
-       def __init__(self, config_file="client.conf"):
-               # Read configuration
-               self.config = config.Config(config_file)
-
-               # Create connection to the hub
-               self.hub = self.connect_to_hub()
-
-       def connect_to_hub(self):
-               huburl = self.config.get("client", "server", PAKFIRE_HUB)
-
-               # keytab
-               keytab = self.config.get("client", "keytab")
-
-               # Create a connection to the hub
-               return hub.Hub(huburl, keytab=keytab)
-
-       async def check_connection(self):
-               """
-                       Tests the connection to the hub
-               """
-               return await self.hub.test()
-
-       # Builds
-
-       async def build(self, *args, **kwargs):
-               return await self.hub.build(*args, **kwargs)
-
-       def get_build(self, build_id):
-               return Build(self, build_id)
-
-       # Jobs
-
-       def get_job(self, job_id):
-               return Job(self, job_id)
-
-       # Uploads
-
-       def upload(self, *args, **kwargs):
-               return self.hub.upload(*args, **kwargs)
-
-
-class _ClientObject(object):
-       def __init__(self, client, id):
-               self.client = client
-
-               # UUID of the build
-               self.id = id
-
-               self._data = None
-               self._cache = {}
-
-       def __repr__(self):
-               return "<%s %s>" % (self.__class__.__name__, self.id)
-
-       def __eq__(self, other):
-               return self.id == other.id
-
-       @property
-       def data(self):
-               if self._data is None:
-                       self._data = self._load()
-
-               return self._data
-
-       def refresh(self):
-               self._data = self._load()
-
-       def _load(self):
-               """
-                       Loads information about this object from the hub
-               """
-               raise NotImplementedError
-
-
-class Build(_ClientObject):
-       def _load(self):
-               """
-                       Loads information about this build from the hub
-               """
-               return self.client.hub.get_build(self.id)
-
-       @property
-       def jobs(self):
-               jobs = []
-
-               for job in self.data.get("jobs"):
-                       try:
-                               j = self._cache[job]
-                       except KeyError:
-                               j = Job(self.client, job)
-
-                       jobs.append(j)
-
-               return sorted(jobs)
-
-       @property
-       def type(self):
-               """
-                       The type of this build (release or scratch)
-               """
-               return self.data.get("type")
-
-       @property
-       def _type_tag(self):
-               if self.type == "release":
-                       return "[R]"
-
-               elif self.type == "scratch":
-                       return "[S]"
-
-       @property
-       def name(self):
-               """
-                       The name of this build
-               """
-               return self.data.get("name")
-
-       @property
-       def priority(self):
-               """
-                       The priority of this build
-               """
-               return self.data.get("priority")
-
-       @property
-       def score(self):
-               """
-                       The score of this build
-               """
-               return self.data.get("score")
-
-       @property
-       def state(self):
-               """
-                       The state this build is in
-               """
-               return self.data.get("state")
-
-       def is_active(self):
-               return self.state == "building"
-
-       @property
-       def oneline(self):
-               s = [
-                       self.name,
-                       self._type_tag,
-                       "(%s)" % self.id,
-                       _("Score: %s") % self.score,
-                       _("Priority: %s") % self.priority,
-               ]
-
-               return " ".join(s)
-
-       def dump(self):
-               # Add a headline for the build
-               s = [
-                       self.oneline,
-               ]
-
-               # Add a short line for each job
-               for j in self.jobs:
-                       s.append("  %s" % j.oneline)
-
-               return "\n".join(s)
-
-
-class Job(_ClientObject):
-       def _load(self):
-               """
-                       Loads information about this job from the hub
-               """
-               return self.client.hub.get_job(self.id)
-
-       def __lt__(self, other):
-               return self.arch < other.arch
-
-       @property
-       def name(self):
-               """
-                       The name of this job
-               """
-               return self.data.get("name")
-
-       @property
-       def type(self):
-               """
-                       The type of this build
-               """
-               return self.data.get("type")
-
-       @property
-       def arch(self):
-               """
-                       The architecture of this job
-               """
-               return self.data.get("arch")
-
-       @property
-       def builder(self):
-               """
-                       The name of the builder that built this job
-               """
-               return self.data.get("builder")
-
-       @property
-       def duration(self):
-               """
-                       The duration the job took to build
-               """
-               return self.data.get("duration")
-
-       @property
-       def state(self):
-               """
-                       The state of this job
-               """
-               return self.data.get("state")
-
-       def is_active(self):
-               return self.state in ("dispatching", "running", "uploading")
-
-       def is_finished(self):
-               return self.state == "finished"
-
-       @property
-       def oneline(self):
-               s = [
-                       # Architecture
-                       "[%-8s]" % self.arch,
-
-                       # State
-                       "[%12s]" % self.state,
-               ]
-
-               if self.is_active():
-                       s.append(_("on %s") % self.builder)
-
-               elif self.is_finished():
-                       s.append(_("in %s") % ("%02d:%02d" % (self.duration // 60, self.duration % 60)))
-
-               return " ".join(s)
-
-       def dump(self):
-               s = []
-
-               # Name
-               s.append(self.name)
-
-               # Append tag for test buils
-               if self.type == "test":
-                       s.append("[T]")
-
-               # UUID
-               s.append("(%s)" % self.id)
-
-               # Show the builder for active jobs
-               if self.is_active() and self.builder:
-                       s.append(_("Builder: %s") % self.builder)
-
-               return " ".join(s)
index d9824d463ac5614dbdda048876d95f210693d45f..4d47965e3dd841f87f729a2e776b19fb133364aa 100644 (file)
@@ -83,7 +83,7 @@ class Hub(object):
                query_args = urllib.parse.urlencode(kwargs)
 
                # Add query arguments
-               if method in ("GET", "PUT"):
+               if method in ("GET", "PUT", "DELETE"):
                        url = "%s?%s" % (url, query_args)
 
                # Add any arguments to the body
@@ -195,7 +195,7 @@ class Hub(object):
        def get_build(self, uuid):
                return self._request("/builds/%s" % uuid, decode="json")
 
-       async def build(self, path, arches=None):
+       async def build(self, path, repo=None, arches=None):
                """
                        Create a new build on the hub
                """
@@ -206,7 +206,7 @@ class Hub(object):
 
                # Create a new build
                build_id = await self._request("POST", "/builds",
-                       upload_id=upload_id, arches=arches)
+                       upload_id=upload_id, repo=repo, arches=arches)
 
                log.debug("Build creates as %s" % build_id)
 
@@ -222,7 +222,15 @@ class Hub(object):
        def get_package(self, uuid):
                return self._request("/packages/%s" % uuid, decode="json")
 
-       # File uploads
+       # Uploads
+
+       async def list_uploads(self):
+               """
+                       Returns a list of all uploads
+               """
+               response = await self._request("GET", "/uploads")
+
+               return response.get("uploads")
 
        async def upload(self, path, filename=None, show_progress=True):
                """
@@ -265,6 +273,9 @@ class Hub(object):
                # Return the upload ID
                return response.get("id")
 
+       async def delete_upload(self, upload_id):
+               await self._request("DELETE", "/uploads", id=upload_id)
+
        @staticmethod
        def _stream_file(path, size, p, write):
                # Start the progressbar
index 1fcf261b191c7789eddbb89aa6a0edfb30fb6e36..698d238b90b8f24754fa457ceddad34ec5bc567f 100644 (file)
 
 import asyncio
 import argparse
-import os.path
 import sys
 import tempfile
-import time
 
-import pakfire.client
+import pakfire.config
+import pakfire.hub
+
 from pakfire.i18n import _
 
 class Cli(object):
+       def __init__(self):
+               # Read configuration
+               self.config = pakfire.config.Config("client.conf")
+
        def parse_cli(self):
                parser = argparse.ArgumentParser(
                        description = _("Pakfire Client command line interface"),
@@ -43,6 +47,8 @@ class Cli(object):
                        help=_("Package(s) to build"))
                build.add_argument("-a", "--arch",
                        help=_("Build the package(s) for the given architecture only"))
+               build.add_argument("--repo",
+                       help=_("Create the build in this repository"))
                build.set_defaults(func=self._build)
 
                # check-connection
@@ -53,23 +59,23 @@ class Cli(object):
                # upload
                upload = subparsers.add_parser("upload",
                        help=_("Upload a file to the build service"))
-               upload.add_argument("file", nargs="+",
-                       help=_("Filename"))
-               upload.set_defaults(func=self._upload)
-
-               # watch-build
-               watch_build = subparsers.add_parser("watch-build",
-                       help=_("Watch the status of a build"))
-               watch_build.add_argument("id",
-                       help=_("Build ID"))
-               watch_build.set_defaults(func=self._watch_build)
-
-               # watch-job
-               watch_job = subparsers.add_parser("watch-job",
-                       help=_("Watch the status of a job"))
-               watch_job.add_argument("id",
-                       help=_("Job ID"))
-               watch_job.set_defaults(func=self._watch_job)
+
+               upload_subparsers = upload.add_subparsers()
+
+               # upload list
+               upload_list = upload_subparsers.add_parser("list", help=_("List all uploads"))
+               upload_list.set_defaults(func=self._upload_list)
+
+               # upload new
+               upload_new = upload_subparsers.add_parser("new", help=_("Create a new upload"))
+               upload_new.add_argument("file", nargs="+", help=_("Filename"))
+               upload_new.set_defaults(func=self._upload_new)
+
+               # upload delete
+               upload_delete = upload_subparsers.add_parser("delete", help=_("Delete an upload"))
+               upload_delete.add_argument("upload_id", metavar="ID", nargs="+",
+                       help=_("One or multiple IDs"))
+               upload_delete.set_defaults(func=self._upload_delete)
 
                args = parser.parse_args()
 
@@ -84,12 +90,15 @@ class Cli(object):
                # Parse command line arguments
                args = self.parse_cli()
 
-               # Create the Client
-               client = pakfire.client.Client()
+               # Create connection to the hub
+               hub = self.connect_to_hub()
+
+               # Setup the callback
+               callback = args.func(hub, args)
 
                # Call function
                try:
-                       ret = asyncio.run(args.func(client, args))
+                       ret = asyncio.run(callback)
 
                # Catch invalid inputs
                except ValueError as e:
@@ -99,7 +108,19 @@ class Cli(object):
                # Return with exit code
                sys.exit(ret or 0)
 
-       async def _build(self, client, ns):
+       def connect_to_hub(self):
+               """
+                       Establishes a connection to the hub
+               """
+               huburl = self.config.get("client", "server", "https://pakfirehub.ipfire.org")
+
+               # keytab
+               keytab = self.config.get("client", "keytab")
+
+               # Create a connection to the hub
+               return pakfire.hub.Hub(huburl, keytab=keytab)
+
+       async def _build(self, hub, ns):
                # Create a temporary directory if we need to call dist
                tmp = tempfile.TemporaryDirectory(prefix="pakfire-client-")
 
@@ -108,13 +129,13 @@ class Cli(object):
 
                        # Build all packages
                        for package in ns.packages:
-                               await client.build(package, arches=ns.arch)
+                               await hub.build(package, arches=ns.arch, repo=ns.repo)
 
                finally:
                        tmp.cleanup()
 
-       async def _check_connection(self, client, ns):
-               response = await client.check_connection()
+       async def _check_connection(self, hub, ns):
+               response = await hub.check_connection()
 
                # Print the response from the service
                try:
@@ -122,9 +143,29 @@ class Cli(object):
                except KeyError:
                        pass
 
-       async def _upload(self, client, ns):
+       # Uploads
+
+       async def _upload_list(self, hub, ns):
+               uploads = await hub.list_uploads()
+
+               for upload in uploads:
+                       print(_("Upload %s") % upload.get("id"))
+
+                       attributes = {
+                               _("Filename")   : upload.get("filename"),
+                               _("Size")       : upload.get("size"),
+                               _("Created at") : upload.get("created_at"),
+                               _("Expires at") : upload.get("expires_at"),
+                       }
+
+                       for key, val in attributes.items():
+                               print ("  %-20s : %s" % (key, val))
+
+                       print() # newline
+
+       async def _upload_new(self, hub, ns):
                for file in ns.file:
-                       upload_id = await client.upload(file)
+                       upload_id = await hub.upload(file)
 
                        # Tell the user
                        print(_("%(file)s uploaded as %(id)s") % {
@@ -133,30 +174,14 @@ class Cli(object):
                                }
                        )
 
-       async def _watch_build(self, client, ns):
-               build = client.get_build(ns.id[0])
-
-               return self._watch_something(build)
-
-       async def _watch_job(self, client, ns):
-               job = client.get_job(ns.id[0])
-
-               return self._watch_something(job)
-
-       async def _watch_something(self, o):
-               while True:
-                       s = o.dump()
-                       print(s)
-
-                       # Break the loop if the build/job is not active any more
-                       # (since we don't expect any changes)
-                       if not o.is_active():
-                               break
-
-                       time.sleep(60)
+       async def _upload_delete(self, hub, ns):
+               """
+                       Delete uploads
+               """
+               for upload_id in ns.upload_id:
+                       await hub.delete_upload(upload_id)
 
-                       # Update data before the next loop is shown
-                       o.refresh()
+                       print(_("Deleted upload %s") % upload_id)
 
 
 if __name__ == "__main__":