5 # Mark Huang <mlhuang@cs.princeton.edu>
6 # Copyright (C) 2006 The Trustees of Princeton University
15 # /etc/planetlab/plc_config.py is a Python fragment maintained by
16 # PlanetLabConf that contains PLC configuration variables.
18 sys.path.append("/etc/planetlab")
19 from plc_config import *
21 print "Warning: Configuration file /etc/planetlab/plc_config.py not found"
22 PLC_NAME = "PlanetLab"
23 PLC_SLICE_PREFIX = "pl"
24 PLC_MAIL_SUPPORT_ADDRESS = "root@" + socket.gethostname()
25 PLC_MAIL_SLICE_ADDRESS = "SLICE@" + socket.gethostname()
27 def format_bytes(bytes, si = True):
29 Formats bytes into a string
34 # Officially, a kibibyte
37 if bytes >= (kilo * kilo * kilo):
38 return "%.1f GB" % (bytes / (kilo * kilo * kilo))
39 elif bytes >= 1000000:
40 return "%.1f MB" % (bytes / (kilo * kilo))
42 return "%.1f KB" % (bytes / kilo)
44 return "%.0f bytes" % bytes
46 def format_period(seconds):
48 Formats a period in seconds into a string
51 if seconds == (24 * 60 * 60):
53 elif seconds == (60 * 60):
55 elif seconds > (24 * 60 * 60):
56 return "%.1f days" % (seconds / 24. / 60. / 60.)
57 elif seconds > (60 * 60):
58 return "%.1f hours" % (seconds / 60. / 60.)
60 return "%.1f minutes" % (seconds / 60.)
62 return "%.0f seconds" % seconds
66 Check PID file. Exit if already running. Update PID file.
70 pidfile = file("/var/run/%s.pid" % prog, "r")
71 pid = pidfile.readline().strip()
73 if os.path.isdir("/proc/" + pid):
74 print "Error: Another copy of %s is still running (%s)" % (prog, pid)
79 pidfile = file("/var/run/%s.pid" % prog, "w")
80 pidfile.write(str(os.getpid()))
84 os.unlink("/var/run/%s.pid" % prog)
86 def slicemail(slice, subject, body):
87 sendmail = os.popen("/usr/sbin/sendmail -N never -t -f%s" % PLC_MAIL_SUPPORT_ADDRESS, "w")
89 to = [PLC_MAIL_MOM_LIST_ADDRESS]
91 if slice is not None and slice != "root":
92 to.append(PLC_MAIL_SLICE_ADDRESS.replace("SLICE", slice))
94 header = {'from': "%s Support <%s>" % (PLC_NAME, PLC_MAIL_SUPPORT_ADDRESS),
96 'version': sys.version.split(" ")[0],
102 Content-type: text/plain
106 X-Mailer: Python/%(version)s
109 """.lstrip() % header)
119 Simple file-like class for redirecting stdout and stderr to /var/log/messages
122 def write(self, text):
129 Daemonize self. Detach from terminal, close all open files, and fork twice.
134 # Detach from terminal
145 # Close all open file descriptors
147 maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
148 if (maxfd == resource.RLIM_INFINITY):
150 for fd in range(0, maxfd):
156 # Redirect stdin to /dev/null
157 os.open("/dev/null", os.O_RDWR)
161 Simple interface to local Node Manager API
164 def __init__(self, url = "http://localhost:812/", timeout = 30):
166 Open a new connection to the local Node Manager
168 socket.setdefaulttimeout(timeout)
170 self.nm = xmlrpclib.ServerProxy(url)
171 except Exception, err:
172 print "Warning: Exception received while opening connection to Node Manager:", err
175 def query(self, slice, attributes):
177 Get values of various slice attributes from the local Node Manager
180 attributes - [(attribute_name, return_value_if_not_set), ...]
183 values = [attribute[1] for attribute in attributes]
185 if self.nm is not None:
186 # Read rspec (the NM hash code for the slice)
187 rcap = open("/var/run/pl_nm/%s.vm_rcap" % slice, "r")
188 rspec = rcap.readline().strip()
191 (rc, result) = self.nm.nm_inspect(rspec, attributes)
192 if rc == 0 and type(result) == list and len(result) == len(values):