]> git.ipfire.org Git - pakfire.git/commitdiff
builder: Add option to log the build into a file.
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 25 Apr 2011 15:59:25 +0000 (17:59 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 25 Apr 2011 15:59:25 +0000 (17:59 +0200)
pakfire/builder.py
pakfire/depsolve.py
pakfire/logger.py

index d69be2938971a26473192f2c8476cd92af38d559..124c7c7957ceae37c5e385df8811cd604b30f6cc 100644 (file)
@@ -15,6 +15,7 @@ import uuid
 import base
 import chroot
 import depsolve
+import logger
 import packages
 import repository
 import transaction
@@ -25,15 +26,62 @@ from i18n import _
 from errors import BuildError, BuildRootLocked, Error
 
 
+BUILD_LOG_HEADER = """
+ ____       _     __ _            _           _ _     _
+|  _ \ __ _| | __/ _(_)_ __ ___  | |__  _   _(_) | __| | ___ _ __
+| |_) / _` | |/ / |_| | '__/ _ \ | '_ \| | | | | |/ _` |/ _ \ '__|
+|  __/ (_| |   <|  _| | | |  __/ | |_) | |_| | | | (_| |  __/ |
+|_|   \__,_|_|\_\_| |_|_|  \___| |_.__/ \__,_|_|_|\__,_|\___|_|
+
+       Time    : %(time)s
+       Host    : %(host)s
+       Version : %(version)s
+
+"""
+
 class Builder(object):
        # The version of the kernel this machine is running.
        kernel_version = os.uname()[2]
 
-       def __init__(self, pkg=None, distro_config=None, build_id=None, **pakfire_args):
+       def __init__(self, pkg=None, distro_config=None, build_id=None, logfile=None,
+                       **pakfire_args):
                pakfire_args.update({
                        "builder" : True,
                })
 
+               # Save the build id and generate one if no build id was provided.
+               if not build_id:
+                       build_id = "%s" % uuid.uuid4()
+
+               self.build_id = build_id
+
+               # Setup the logging.
+               if logfile:
+                       self.log = logging.getLogger(self.build_id)
+                       # Propage everything to the root logger that we will see something
+                       # on the terminal.
+                       self.log.propagate = 1
+                       self.log.setLevel(logging.INFO)
+
+                       # Add the given logfile to the logger.
+                       h = logging.FileHandler(logfile)
+                       self.log.addHandler(h)
+
+                       # Format the log output for the file.
+                       f = logger.BuildFormatter()
+                       h.setFormatter(f)
+               else:
+                       # If no logile was given, we use the root logger.
+                       self.log = logging.getLogger()
+
+               logdata = {
+                       "host"    : socket.gethostname(),
+                       "time"    : time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()),
+                       "version" : "Pakfire %s" % PAKFIRE_VERSION,
+               }
+               for line in BUILD_LOG_HEADER.splitlines():
+                       self.log.info(line % logdata)
+
                # Create pakfire instance.
                self.pakfire = base.Pakfire(distro_config=distro_config, **pakfire_args)
                self.distro = self.pakfire.distro
@@ -59,12 +107,6 @@ class Builder(object):
                # Save the build time.
                self.build_time = int(time.time())
 
-               # Save the build id and generate one if no build id was provided.
-               if not build_id:
-                       build_id = uuid.uuid4()
-
-               self.build_id = build_id
-
        def get_pkg(self):
                return getattr(self, "_pkg", None)
 
@@ -77,8 +119,10 @@ class Builder(object):
 
                # Log the package information.
                if not isinstance(self._pkg, packages.Makefile):
-                       dump = self._pkg.dump(long=True)
-                       self.log.info(dump)
+                       self.log.info("Package information:")
+                       for line in self._pkg.dump(long=True).splitlines():
+                               self.log.info("  %s" % line)
+                       self.log.info("")
 
                assert self.pkg
 
@@ -232,7 +276,7 @@ class Builder(object):
                        else:
                                ds.add_requires(r)
                ds.resolve()
-               ds.dump()
+               ds.dump(logger=self.log)
 
                ts = transaction.Transaction(self.pakfire, ds)
                ts.run()
@@ -255,11 +299,6 @@ class Builder(object):
 
                self.install(pkgs)
 
-       @property
-       def log(self):
-               # XXX for now, return the root logger
-               return logging.getLogger()
-
        def chrootPath(self, *args):
                # Remove all leading slashes
                _args = []
@@ -491,7 +530,7 @@ class Builder(object):
 
                return env
 
-       def do(self, command, shell=True, personality=None, *args, **kwargs):
+       def do(self, command, shell=True, personality=None, logger=None, *args, **kwargs):
                ret = None
                try:
                        # Environment variables
@@ -523,7 +562,7 @@ class Builder(object):
                                personality=personality,
                                shell=False,
                                env=env,
-                               logger=self.log,
+                               logger=logger,
                                *args,
                                **kwargs
                        )
@@ -616,7 +655,7 @@ class Builder(object):
                self.create_icecream_toolchain()
 
                try:
-                       self.make("build")
+                       self.make("build", logger=self.log)
 
                except Error:
                        raise BuildError, "The build command failed."
index 7dbc4ef8be9081112abbbb1595fedc2ec9cc8e75..06e47bff6164e870b13a69b61a5cde46aee932ad 100644 (file)
@@ -220,7 +220,11 @@ class DependencySet(object):
                s.append("")
                return s
 
-       def dump(self):
+       def dump(self, logger=None):
+               # If no logger was given, we use the root logger.
+               if not logger:
+                       logger = logging.getLogger()
+
                width = 80
                line = "=" * width
 
@@ -261,4 +265,4 @@ class DependencySet(object):
                s.append("")
 
                for line in s:
-                       logging.info(line)
+                       logger.info(line)
index ab77778990fbe4c880bcea0977ec543767ace7eb..1c4eb8e2eece3ec9046ca6e9b9ce85d784625d55 100644 (file)
@@ -1,6 +1,7 @@
 #!/usr/bin/python
 
 import logging
+import time
 
 def setup_logging(config):
        """
@@ -35,3 +36,26 @@ def setup_logging(config):
        handler = logging.FileHandler(config.get("logfile"))
        handler.setLevel(logging.DEBUG)
        l.addHandler(handler)
+
+
+class BuildFormatter(logging.Formatter):
+       def __init__(self):
+               self._fmt = "[%(asctime)s] %(message)s"
+               self.datefmt = None
+
+               self.starttime = time.time()
+
+       def converter(self, recordtime):
+               """
+                       This returns a timestamp relatively to the time when we started
+                       the build.
+               """
+               recordtime -= self.starttime
+
+               return time.gmtime(recordtime)
+
+       def formatTime(self, record, datefmt=None):
+               ct = self.converter(record.created)
+               t = time.strftime("%H:%M:%S", ct)
+               s = "%s,%03d" % (t, record.msecs)
+               return s