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 = "root@" + socket.gethostname()
27 PLC_MAIL_SLICE_ADDRESS = "SLICE@" + socket.gethostname()
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 to = [PLC_MAIL_MOM_LIST_ADDRESS]
93 if slice is not None and slice != "root":
94 to.append(PLC_MAIL_SLICE_ADDRESS.replace("SLICE", slice))
96 header = {'from': "%s Support <%s>" % (PLC_NAME, PLC_MAIL_SUPPORT_ADDRESS),
98 'version': sys.version.split(" ")[0],
104 Content-type: text/plain
108 X-Mailer: Python/%(version)s
111 """.lstrip() % header)
121 Simple file-like class for redirecting stdout and stderr to /var/log/messages
124 def write(self, text):
131 Daemonize self. Detach from terminal, close all open files, and fork twice.
136 # Detach from terminal
147 # Close all open file descriptors
149 maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
150 if (maxfd == resource.RLIM_INFINITY):
152 for fd in range(0, maxfd):
158 # Redirect stdin to /dev/null
159 os.open("/dev/null", os.O_RDWR)
163 Simple interface to local Node Manager API
166 def __init__(self, url = "http://localhost:812/", timeout = 30):
168 Open a new connection to the local Node Manager
170 socket.setdefaulttimeout(timeout)
172 self.nm = xmlrpclib.ServerProxy(url)
173 except Exception, err:
174 print "Warning: Exception received while opening connection to Node Manager:", err
177 def query(self, slice, attributes):
179 Get values of various slice attributes from the local Node Manager
182 attributes - [(attribute_name, return_value_if_not_set), ...]
185 values = [attribute[1] for attribute in attributes]
187 if self.nm is not None:
188 # Read rspec (the NM hash code for the slice)
189 rcap = open("/var/run/pl_nm/%s.vm_rcap" % slice, "r")
190 rspec = rcap.readline().strip()
193 (rc, result) = self.nm.nm_inspect(rspec, attributes)
194 if rc == 0 and type(result) == list and len(result) == len(values):