import os
import socket
+import distro
+
from i18n import _
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):
"""
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
# ARM
"armv5tel" : ["armv5tel",],
"armv5tejl" : ["armv5tel",],
+ "armv6l" : ["armv5tel",],
"armv7l" : ["armv7hl", "armv5tel",],
"armv7hl" : ["armv7hl", "armv5tel",],
}
"""
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"):
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.
# 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")
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)
class Mountpoint(object):
- def __init__(self, pakfire, path, root="/"):
- self.pakfire = pakfire
+ def __init__(self, path, root="/"):
self.path = path
self.root = root