6 from Remote import Remote
7 from Table import Table
8 from logger import Logfile
11 class Node(dict, Remote):
15 'hostname': None, # Node Hostname
16 'host': 'localhost', # host where node lives
17 'redir_ssh_port': '51022', # Port on host where ssh is redirected to virtual node
18 'vserver': None, # vserver where this node lives
19 'type': 'vm', # type of node
21 'nodenetworks': [], # node networks
22 'homedir': '/var/VirtualMachines/',
23 'rootkey': '/etc/planetlab/root_ssh_key.rsa', # path to root ssh key
27 def __init__(self, config, fields = {}):
29 # XX Filter out fields not specified in fields
30 dict.__init__(self, self.fields)
32 # Merge defined fields with defaults
35 self.__init_logfile__()
37 get_host_command = Remote.get_remote_command
38 get_host_scp_command = Remote.get_scp_command
40 def __init_logfile__(self, filename = None):
42 filename = '/var/log/%s.log' % self['hostname']
43 self.logfile = Logfile(filename)
45 def rotate_logfile(self):
46 if os.path.isfile(self.logfile.filename):
47 (status, output) = utils.commands("ls %s*" % self.logfile.filename)
48 files = output.split("\n")
50 lastfile = files[-1:][0]
51 index = lastfile.split(self.logfile.filename)[1].replace(".", "")
55 index = str(int(index) + 1)
56 utils.commands("mv %s %s.%s" % (self.logfile.filename, self.logfile.filename, index))
58 def get_host_ip(self):
59 self.__init_logfile__()
61 # Used to get ip of this nodes host
62 ip_command = "/sbin/ifconfig eth0 | grep -v inet6 | grep inet | awk '{print$2;}'"
63 (status, output) = self.host_commands(ip_command)
64 ip = re.findall(r'[0-9\.]+', output)[0]
67 def get_remote_command(self, command, user = 'root', key = None):
68 if key is None and 'rootkey' in self:
71 options += " -o StrictHostKeyChecking=no "
73 options += " -i %(key)s" % locals()
74 host = self['hostname']
75 if 'type' in self and self['type'] in ['vm']:
76 if 'redir_ssh_port' in self and self['redir_ssh_port']:
77 options += " -p %s " % self['redir_ssh_port']
78 host = self.get_host_ip()
79 command = "ssh %(options)s %(user)s@%(host)s \'%(command)s\'" % locals()
80 return self.get_host_command(command)
82 def get_scp_command(self, localfile, remotefile, direction, recursive = False, user = 'root', key = None):
85 options += " -o StrictHostKeyChecking=no "
89 options += " -i %(key)s "% locals()
91 options += " -i %s " % self['rootkey']
93 # Are we copying to a real node or a virtual node hosted
95 host = self['hostname']
96 if 'type' in self and self['type'] in ['vm']:
97 if 'redir_ssh_port' in self and self['redir_ssh_port']:
98 options += " -p %s " % self['redir_ssh_port']
99 host = self.get_host_ip()
101 if direction in ['to']:
102 command = "scp %(options)s %(localfile)s %(user)s@%(host)s:/%(remotefile)s" % locals()
103 elif direction in ['from']:
104 command = "scp %(options)s %(user)s$%(host)s:/%(remotefile)s %(localfile)s" % locals()
106 raise Error, "Invalid direction, must be 'to' or 'from'."
109 # Host remote commands
110 def host_popen(self, command, fatal = True):
111 command = self.get_host_command(command)
112 return utils.popen(command, fatal, self.config.verbose)
114 def host_popen3(self, command):
115 command = self.get_host_command(command)
116 return utils.popen3(command, self.config.verbose)
118 def host_commands(self, command, fatal = True):
119 command = self.get_host_command(command)
120 return utils.commands(command, fatal, self.config.verbose)
122 # Slice remote commands
123 def slice_popen(self, command, user = 'root', key = None, fatal = True):
124 command = self.get_remote_command(command, user, key)
125 return utils.popen(command, fatal)
127 def slice_popen3(self, command, user = 'root', key = None, fatal = True):
128 command = self.get_remote_command(command, user, key)
129 return utils.popen3(command, fatal)
131 def slice_commands(self, command, user = 'root', key = None, fatal = True):
132 command = self.get_remote_command(command, user, key)
133 return utils.commands(command, fatal)
136 def scp_to_host(self, localfile, remotefile, recursive = False):
137 command = self.get_host_scp_command(localfile, remotefile, 'to', recursive)
138 return utils.commands(command)
140 def scp_from_host(self, localfile, remotefile, recursive = False):
141 command = self.get_host_scp_command(localfile, remotefile, 'from', recursive)
142 return utils.commands(command)
145 def scp_to(self, localfile, remotefile, recursive = False, user = 'root', key = None):
146 # if node is vm, we must scp file(s) to host machine first
147 # then run scp from there
148 if 'type' in self and self['type'] in ['vm']:
149 fileparts = localfile.split(os.sep)
150 filename = fileparts[-1:][0]
151 tempfile = '/tmp/%(filename)s' % locals()
152 self.scp_to_host(localfile, tempfile, recursive)
153 command = self.get_scp_command(tempfile, remotefile, 'to', recursive, user, key)
154 return self.host_commands(command)
157 command = self.get_scp_command(localfile, remotefile, 'to', recursive, user, key)
158 return utils.commands(command)
160 def scp_from(self, localfile, remotefile, recursive = False, user = 'root', key = None):
161 # if node is vm, we must scp file(s) onto host machine first
162 # then run scp from there
163 if 'type' in self and self['type'] in ['vm']:
164 fileparts = remotefile.split(os.sep)
165 filename = fileparts[-1:]
166 tempfile = '/tmp/%(filename)s' % locals()
167 self.scp_from_host(remotefile, tempfile, recursive)
168 command = self.get_scp_command(localfile, tempfile, 'from', recursive, user, key)
169 return self.host_commands(command)
172 command = self.get_scp_command(localfile, remotefile, 'from', recursive, user, key)
173 return utils.commands(command)
175 def is_ready(self, timeout=10):
176 # Node is considered ready when Node Manager has started avuseradd processes have stopped
178 def __init__(self, name, description, system, cmd, check, inverse = False):
183 self.description = description
184 self.inverse = inverse
186 def run(self, verbose = True):
188 utils.header(self.description)
189 (status, output) = self.system(self.cmd)
190 if self.inverse and output.find(self.check) == -1:
191 if verbose: utils.header("%s Passed Test" % self.name)
193 elif not self.inverse and output and output.find(self.check) -1:
194 if verbose: utils.header("%s Passed Test" % self.name)
197 if verbose: utils.header("%s Failed Test" % self.name)
201 start_time = time.time()
202 end_time = start_time + 60 * timeout
203 vcheck_cmd = "ps -elfy | grep vuseradd | grep -v grep"
204 grep_cmd = "grep 'Starting Node Manager' %s" % self.logfile.filename
206 '1': test("NodeManager", "Checking if NodeManager has started", utils.commands, grep_cmd, "OK"),
207 '2': test("vuseradd", "Checking if vuseradd is done", self.commands, vcheck_cmd, "vuseradd", True)
210 while time.time() < end_time and ready == False:
217 results[step] = result = test.run(self.config.verbose)
220 # Check results. We are ready if all passed
221 if not set(results.values()).intersection([False, None]):
224 if self.config.verbose:
225 utils.header("%s not ready. Waiting 30 seconds. %s seconds left" % \
226 (self['hostname'], int(end_time - time.time())) )
231 class Nodes(list, Table):
233 def __init__(self, config, nodes):
234 nodelist = [Node(config, node) for node in nodes]
235 list.__init__(self, nodelist)