Commits

Walter Dörwald committed 175a19d

Add a new class ll.misc.SysInfo that provides system info.

Comments (0)

Files changed (2)

 	return mod
 
 
+class SysInfo(object):
+	"""
+	A :class:`SysInfo` object contains information about the host, user, python
+	version and script. Available attributes are ``host_name``, ``host_fqdn``,
+	``host_ip``, ``host_sysname``, ``host_nodename``, ``host_release``,
+	``host_version``, ``host_machine``, ``user_name``, ``user_uid``, ``user_gid``,
+	``user_gecos``, ``user_dir``, ``user_shell``, ``python_executable``,
+	``python_version``, ``pid`` and ``scriptname``.
+
+	:class:`SysInfo` object also support a mimimal dictionary interface (i.e.
+	:meth:`__getitem__` and :meth:`__iter__`).
+	"""
+
+	_keys = {"host_name", "host_fqdn", "host_ip", "host_sysname", "host_nodename", "host_release", "host_version", "host_machine", "python_executable", "python_version", "pid", "scriptname"}
+
+	def __init__(self, encoding="utf-8", errors="replace"):
+		import socket, pwd
+
+		def _string(s):
+			if isinstance(s, str):
+				s = s.decode(encoding, errors)
+			return s
+
+		self.host_name = _string(socket.gethostname())
+		self.host_fqdn = _string(self.host_name)
+		self.host_ip = _string(socket.gethostbyname(self.host_name))
+		(self.host_sysname, self.host_nodename, self.host_release, self.host_version, self.host_machine) = map(_string, os.uname())
+		(self.user_name, _, self.user_uid, self.user_gid, self.user_gecos, self.user_dir, self.user_shell) = map(_string, pwd.getpwuid(os.getuid()))
+		self.python_executable = _string(sys.executable)
+		self.python_version = ("{}.{}.{}" if sys.version_info.micro else "{}.{}").format(*sys.version_info)
+		self.pid = os.getpid()
+		self.scriptname = _string(sys._getframe(-1).f_code.co_filename)
+
+	def __getitem__(self, key):
+		if key in self._keys:
+			return getattr(self, key)
+		raise KeyError(key)
+
+	def __iter__(self):
+		return iter(self._keys)
+
+	
 def prettycsv(rows, padding="   "):
 	"""
 	Format table :var:`rows`.

src/ll/sisyphus.py

 
 	maxtime = 5 * 60
 
-	logfilename = u"~<?print user_name?>/ll.sisyphus/log/<?print projectname?>/<?print jobname?>/<?print starttime.format('%Y-%m-%d-%H-%M-%S-%f')?>.sisyphuslog"
-	loglinkname = u"~<?print user_name?>/ll.sisyphus/log/<?print projectname?>/<?print jobname?>/current.sisyphuslog"
-	pidfilename = u"~<?print user_name?>/ll.sisyphus/run/<?print projectname?>/<?print jobname?>.pid"
+	logfilename = u"~/ll.sisyphus/log/<?print projectname?>/<?print jobname?>/<?print starttime.format('%Y-%m-%d-%H-%M-%S-%f')?>.sisyphuslog"
+	loglinkname = u"~/ll.sisyphus/log/<?print projectname?>/<?print jobname?>/current.sisyphuslog"
+	pidfilename = u"~/ll.sisyphus/run/<?print projectname?>/<?print jobname?>.pid"
 
 	log2file = True
 
 
 	def _setup(self):
 		self.info = AttrDict()
+		self.info.sysinfo = misc.SysInfo(self.inputencoding, self.inputerrors)
 		self.info.projectname = self._string(self.projectname)
 		self.info.jobname = self._string(self.jobname)
 
 			maxtime = datetime.timedelta(seconds=maxtime)
 		self.info.maxtime = maxtime
 
-		# Get PID
-		self.info.pid = os.getpid()
-
-		# Get host info
-		host_name = socket.gethostname()
-		self.info.host_name = self._string(socket.gethostname())
-		self.info.host_fqdn = self._string(socket.getfqdn(host_name))
-		self.info.host_ip = self._string(socket.gethostbyname(host_name))
-
-		# Get uname info
-		(self.info.host_sysname, self.info.host_nodename, self.info.host_release, self.info.host_version, self.info.host_machine) = map(self._string, os.uname())
-
-		# Get user info
-		(self.info.user_name, _, self.info.user_uid, self.info.user_gid, self.info.user_gecos, self.info.user_dir, self.info.user_shell) = map(self._string, pwd.getpwuid(os.getuid()))
-
-		# Get filename of the executing script
-		filename = sys._getframe(-1).f_code.co_filename
-		self.info.filename = self._string(filename)
-
 		# Get source code
 		try:
-			with open(filename.rstrip("c"), "rb") as f:
+			with open(self.info.sysinfo.scriptname.rstrip("c"), "rb") as f:
 				source = f.read()
 				lines = source.splitlines()
 				# find encoding in the first two lines
 
 		self._createlogfile()
 
-		self.log.sisyphus.info(u"{info.filename} (pid {info.pid})".format(info=self.info))
+		self.log.sisyphus.info(u"{0.sysinfo.scriptname} (pid {0.sysinfo.pid})".format(self.info))
 		try: # is there a pid file from a running job?
 			pidfile = open(pidfilename, "r")
 		except IOError, exc: # no pid file => the job has finished without problems
 		"""
 		if not self.pidfilewritten:
 			with contextlib.closing(url.File(pidfilename).openwrite()) as file:
-				file.write(str(self.info.pid))
+				file.write(str(self.info.sysinfo.pid))
 			self.pidfilewritten = True
 
 	def _killpid(self, pidfilename):