5 # Mark Huang <mlhuang@cs.princeton.edu>
6 # Copyright (C) 2006 The Trustees of Princeton University
17 # /etc/planetlab/plc_config.py is a Python fragment maintained by
18 # PlanetLabConf that contains PLC configuration variables.
20 sys.path.append("/etc/planetlab")
21 from plc_config import *
23 print "Warning: Configuration file /etc/planetlab/plc_config.py not found"
24 PLC_NAME = "PlanetLab"
25 PLC_SLICE_PREFIX = "pl"
26 PLC_MAIL_SUPPORT_ADDRESS = "support@planet-lab.org"
27 PLC_MAIL_SLICE_ADDRESS = "SLICE@slices.planet-lab.org"
29 def format_bytes(bytes, si = True):
31 Formats bytes into a string
36 # Officially, a kibibyte
39 if bytes >= (kilo * kilo * kilo):
40 return "%.1f GB" % (bytes / (kilo * kilo * kilo))
41 elif bytes >= 1000000:
42 return "%.1f MB" % (bytes / (kilo * kilo))
44 return "%.1f KB" % (bytes / kilo)
46 return "%.0f bytes" % bytes
48 def format_period(seconds):
50 Formats a period in seconds into a string
53 if seconds == (24 * 60 * 60):
55 elif seconds == (60 * 60):
57 elif seconds > (24 * 60 * 60):
58 return "%.1f days" % (seconds / 24. / 60. / 60.)
59 elif seconds > (60 * 60):
60 return "%.1f hours" % (seconds / 60. / 60.)
62 return "%.1f minutes" % (seconds / 60.)
64 return "%.0f seconds" % seconds
68 Check PID file. Exit if already running. Update PID file.
72 pidfile = file("/var/run/%s.pid" % prog, "r")
73 pid = pidfile.readline().strip()
75 if os.path.isdir("/proc/" + pid):
76 print "Error: Another copy of %s is still running (%s)" % (prog, pid)
81 pidfile = file("/var/run/%s.pid" % prog, "w")
82 pidfile.write(str(os.getpid()))
86 os.unlink("/var/run/%s.pid" % prog)
88 def slicemail(slice, subject, body):
89 sendmail = os.popen("/usr/sbin/sendmail -N never -t -f%s" % PLC_MAIL_SUPPORT_ADDRESS, "w")
91 # PLC has a separate list for pl_mom messages
92 if PLC_MAIL_SUPPORT_ADDRESS == "support@planet-lab.org":
93 to = ["pl-mom@planet-lab.org"]
95 to = [PLC_MAIL_SUPPORT_ADDRESS]
97 if slice is not None and slice != "root":
98 to.append(PLC_MAIL_SLICE_ADDRESS.replace("SLICE", slice))
100 header = {'from': "%s Support <%s>" % (PLC_NAME, PLC_MAIL_SUPPORT_ADDRESS),
102 'version': sys.version.split(" ")[0],
108 Content-type: text/plain
112 X-Mailer: Python/%(version)s
115 """.lstrip() % header)
125 Simple file-like class for redirecting stdout and stderr to /var/log/messages
128 def write(self, text):
135 Daemonize self. Detach from terminal, close all open files, and fork twice.
140 # Detach from terminal
151 # Close all open file descriptors
153 maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
154 if (maxfd == resource.RLIM_INFINITY):
156 for fd in range(0, maxfd):
162 # Redirect stdin to /dev/null
163 os.open("/dev/null", os.O_RDWR)
167 Simple interface to local Node Manager API
170 def __init__(self, url = "http://localhost:812/", timeout = 30):
172 Open a new connection to the local Node Manager
174 socket.setdefaulttimeout(timeout)
176 self.nm = xmlrpclib.ServerProxy(url)
177 except Exception, err:
178 print "Warning: Exception received while opening connection to Node Manager:", err
181 def query(self, slice, attributes):
183 Get values of various slice attributes from the local Node Manager
186 attributes - [(attribute_name, return_value_if_not_set), ...]
189 values = [attribute[1] for attribute in attributes]
191 if self.nm is not None:
192 # Read rspec (the NM hash code for the slice)
193 rcap = open("/var/run/pl_nm/%s.vm_rcap" % slice, "r")
194 rspec = rcap.readline().strip()
197 (rc, result) = self.nm.nm_inspect(rspec, attributes)
198 if rc == 0 and type(result) == list and len(result) == len(values):