]> git.ipfire.org Git - pakfire.git/blobdiff - python/pakfire/system.py
system: Fix free memory.
[pakfire.git] / python / pakfire / system.py
index 8d99fb81554b7f1982a24e4e04b0f23ec4d24b8f..495ec9273d6ebd58cae55650c4aa5a9ca7892867 100644 (file)
@@ -25,6 +25,8 @@ import multiprocessing
 import os
 import socket
 
+import distro
+
 from i18n import _
 
 class System(object):
@@ -34,7 +36,20 @@ class System(object):
        """
        @property
        def hostname(self):
-               return socket.gethostname()
+               hn = socket.gethostname()
+
+               # If a host has got no domain part, we add one.
+               if not "." in hn:
+                       hn = "%s.localdomain" % hn
+
+               return hn
+
+       @property
+       def distro(self):
+               if not hasattr(self, "_distro"):
+                       self._distro = distro.Distribution()
+
+               return self._distro
 
        @property
        def native_arch(self):
@@ -49,7 +64,7 @@ class System(object):
                """
                        Return the architecture of the host we are running on.
                """
-               if not self.native_arch in self.supported_arches:
+               if self.supported_arches and not self.native_arch in self.supported_arches:
                        return self.supported_arches[0]
 
                return self.native_arch
@@ -69,6 +84,7 @@ class System(object):
                        # ARM
                        "armv5tel"  : ["armv5tel",],
                        "armv5tejl" : ["armv5tel",],
+                       "armv6l"    : ["armv5tel",],
                        "armv7l"    : ["armv7hl", "armv5tel",],
                        "armv7hl"   : ["armv7hl", "armv5tel",],
                }
@@ -91,24 +107,28 @@ class System(object):
                """
                return multiprocessing.cpu_count()
 
-       @property
-       def cpu_model(self):
-               # Determine CPU model
-               cpuinfo = {}
+       def parse_cpuinfo(self):
+               ret = {}
+
                with open("/proc/cpuinfo") as f:
                        for line in f.readlines():
-                               # Break at an empty line, because all information after that
-                               # is redundant.
-                               if not line:
-                                       break
-
                                try:
-                                       key, value = line.split(":")
+                                       # Split the lines by colons.
+                                       a, b = line.split(":")
+
+                                       # Strip whitespace.
+                                       a = a.strip()
+                                       b = b.strip()
+
+                                       ret[a] = b
                                except:
-                                       pass # Skip invalid lines
+                                       pass
 
-                               key, value = key.strip(), value.strip()
-                               cpuinfo[key] = value
+               return ret
+
+       @property
+       def cpu_model(self):
+               cpuinfo = self.parse_cpuinfo()
 
                ret = None
                if self.arch.startswith("arm"):
@@ -125,29 +145,119 @@ class System(object):
                return ret or _("Could not be determined")
 
        @property
-       def memory(self):
-               # Determine memory size
-               memory = 0
+       def cpu_bogomips(self):
+               cpuinfo = self.parse_cpuinfo()
+
+               for key in ("bogomips", "BogoMIPS"):
+                       bogomips = cpuinfo.get(key, None)
+
+                       if bogomips is None:
+                               continue
+
+                       return float(bogomips) * self.cpu_count
+
+       def get_loadavg(self):
+               return os.getloadavg()
+
+       @property
+       def loadavg1(self):
+               return self.get_loadavg()[0]
+
+       @property
+       def loadavg5(self):
+               return self.get_loadavg()[1]
+
+       @property
+       def loadavg15(self):
+               return self.get_loadavg()[2]
+
+       def has_overload(self):
+               """
+                       Checks, if the load average is not too high.
+
+                       On this is to be decided if a new job is taken.
+               """
+               # If there are more than 2 processes in the process queue per CPU
+               # core we will assume that the system has heavy load and to not request
+               # a new job.
+               return self.loadavg5 >= self.cpu_count * 2
+
+       def parse_meminfo(self):
+               ret = {}
+
                with open("/proc/meminfo") as f:
-                       line = f.readline()
+                       for line in f.readlines():
+                               try:
+                                       a, b, c = line.split()
 
-                       try:
-                               a, b, c = line.split()
-                       except:
-                               pass
-                       else:
-                               memory = int(b) * 1024
+                                       a = a.strip()
+                                       a = a.replace(":", "")
+                                       b = int(b)
+
+                                       ret[a] = b * 1024
+                               except:
+                                       pass
+
+               return ret
+
+       @property
+       def memory_total(self):
+               meminfo = self.parse_meminfo()
+
+               return meminfo.get("MemTotal", None)
+
+       # For compatibility
+       memory = memory_total
+
+       @property
+       def memory_free(self):
+               meminfo = self.parse_meminfo()
 
-               return memory
+               free = meminfo.get("MemFree", None)
+               if free:
+                       buffers = meminfo.get("Buffers")
+                       cached  = meminfo.get("Cached")
+
+                       return free + buffers + cached
+
+       @property
+       def swap_total(self):
+               meminfo = self.parse_meminfo()
+
+               return meminfo.get("SwapTotal", None)
+
+       @property
+       def swap_free(self):
+               meminfo = self.parse_meminfo()
+
+               return meminfo.get("SwapFree", None)
+
+       def get_mountpoint(self, path):
+               return Mountpoint(path)
+
+       @property
+       def parallelism(self):
+               """
+                       Calculates how many processes should be run
+                       simulatneously when compiling.
+               """
+               # Check how many processes would fit into the
+               # memory when each process takes up to 128MB.
+               multiplicator = self.memory / (128 * 1024 * 1024)
+               multiplicator = round(multiplicator)
+
+               # Count the number of online CPU cores.
+               cpucount = os.sysconf("SC_NPROCESSORS_CONF") * 2
+               cpucount += 1
+
+               return min(multiplicator, cpucount)
 
 
 # Create an instance of this class to only keep it once in memory.
 system = System()
 
 class Mountpoints(object):
-       def __init__(self, pakfire, root="/"):
-               self.pakfire = pakfire
-
+       def __init__(self, root="/"):
                self._mountpoints = []
 
                # Scan for all mountpoints on the system.
@@ -163,7 +273,7 @@ class Mountpoints(object):
                # If root is not equal to /, we are in a chroot and
                # our root must be a mountpoint to count files.
                if not root == "/":
-                       mp = Mountpoint(self.pakfire, "/", root=root)
+                       mp = Mountpoint("/", root=root)
                        self._mountpoints.append(mp)
 
                f = open("/proc/mounts")
@@ -184,7 +294,7 @@ class Mountpoints(object):
                        else:
                                mountpoint = os.path.join("/", mountpoint)
 
-                       mp = Mountpoint(self.pakfire, mountpoint, root=root)
+                       mp = Mountpoint(mountpoint, root=root)
 
                        if not mp in self._mountpoints:
                                self._mountpoints.append(mp)
@@ -224,8 +334,7 @@ class Mountpoints(object):
 
 
 class Mountpoint(object):
-       def __init__(self, pakfire, path, root="/"):
-               self.pakfire = pakfire
+       def __init__(self, path, root="/"):
                self.path = path
                self.root = root