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 get_host_ip(self):
46 self.__init_logfile__()
48 # Used to get ip of this nodes host
49 ip_command = "/sbin/ifconfig eth0 | grep -v inet6 | grep inet | awk '{print$2;}'"
50 (status, output) = self.host_commands(ip_command)
51 ip = re.findall(r'[0-9\.]+', output)[0]
54 def get_remote_command(self, command, user = 'root', key = None):
55 if key is None and 'rootkey' in self:
58 options += " -o StrictHostKeyChecking=no "
60 options += " -i %(key)s" % locals()
61 host = self['hostname']
62 if 'type' in self and self['type'] in ['vm']:
63 if 'redir_ssh_port' in self and self['redir_ssh_port']:
64 options += " -p %s " % self['redir_ssh_port']
65 host = self.get_host_ip()
66 command = "ssh %(options)s %(user)s@%(host)s \'%(command)s\'" % locals()
67 return self.get_host_command(command)
69 def get_scp_command(self, localfile, remotefile, direction, recursive = False, user = 'root', key = None):
72 options += " -o StrictHostKeyChecking=no "
76 options += " -i %(key)s "% locals()
78 options += " -i %s " % self['rootkey']
80 # Are we copying to a real node or a virtual node hosted
82 host = self['hostname']
83 if 'type' in self and self['type'] in ['vm']:
84 if 'redir_ssh_port' in self and self['redir_ssh_port']:
85 options += " -p %s " % self['redir_ssh_port']
86 host = self.get_host_ip()
88 if direction in ['to']:
89 command = "scp %(options)s %(localfile)s %(user)s@%(host)s:/%(remotefile)s" % locals()
90 elif direction in ['from']:
91 command = "scp %(options)s %(user)s$%(host)s:/%(remotefile)s %(localfile)s" % locals()
93 raise Error, "Invalid direction, must be 'to' or 'from'."
96 # Host remote commands
97 def host_popen(self, command, fatal = True):
98 command = self.get_host_command(command)
99 return utils.popen(command, fatal, self.config.verbose)
101 def host_popen3(self, command):
102 command = self.get_host_command(command)
103 return utils.popen3(command, self.config.verbose)
105 def host_commands(self, command, fatal = True):
106 command = self.get_host_command(command)
107 return utils.commands(command, fatal, self.config.verbose)
109 # Slice remote commands
110 def slice_popen(self, command, user = 'root', key = None, fatal = True):
111 command = self.get_remote_command(command, user, key)
112 return utils.popen(command, fatal)
114 def slice_popen3(self, command, user = 'root', key = None, fatal = True):
115 command = self.get_remote_command(command, user, key)
116 return utils.popen3(command, fatal)
118 def slice_commands(self, command, user = 'root', key = None, fatal = True):
119 command = self.get_remote_command(command, user, key)
120 return utils.commands(command, fatal)
123 def scp_to_host(self, localfile, remotefile, recursive = False):
124 command = self.get_host_scp_command(localfile, remotefile, 'to', recursive)
125 return utils.commands(command)
127 def scp_from_host(self, localfile, remotefile, recursive = False):
128 command = self.get_host_scp_command(localfile, remotefile, 'from', recursive)
129 return utils.commands(command)
132 def scp_to(self, localfile, remotefile, recursive = False, user = 'root', key = None):
133 # if node is vm, we must scp file(s) to host machine first
134 # then run scp from there
135 if 'type' in self and self['type'] in ['vm']:
136 fileparts = localfile.split(os.sep)
137 filename = fileparts[-1:][0]
138 tempfile = '/tmp/%(filename)s' % locals()
139 self.scp_to_host(localfile, tempfile, recursive)
140 command = self.get_scp_command(tempfile, remotefile, 'to', recursive, user, key)
141 return self.host_commands(command)
144 command = self.get_scp_command(localfile, remotefile, 'to', recursive, user, key)
145 return utils.commands(command)
147 def scp_from(self, localfile, remotefile, recursive = False, user = 'root', key = None):
148 # if node is vm, we must scp file(s) onto host machine first
149 # then run scp from there
150 if 'type' in self and self['type'] in ['vm']:
151 fileparts = remotefile.split(os.sep)
152 filename = fileparts[-1:]
153 tempfile = '/tmp/%(filename)s' % locals()
154 self.scp_from_host(remotefile, tempfile, recursive)
155 command = self.get_scp_command(localfile, tempfile, 'from', recursive, user, key)
156 return self.host_commands(command)
159 command = self.get_scp_command(localfile, remotefile, 'from', recursive, user, key)
160 return utils.commands(command)
162 def is_ready(self, timeout=8):
163 # Node is considered ready when vuseradd processes have stopped
165 start_time = time.time()
166 end_time = start_time + 60 * timeout
167 while time.time() < end_time and ready == False:
168 command = "ps -elfy | grep vuseradd | grep -v grep"
169 (output, errors) = self.popen(command, False)
170 if output and output.find('vuseradd') or errors:
171 if self.config.verbose:
172 utils.header('%s is not ready. waiting 30 seconds' % self['hostname'])
176 if self.config.verbose:
177 utils.header('%s is ready' % self['hostname'])
181 class Nodes(list, Table):
183 def __init__(self, config, nodes):
184 nodelist = [Node(config, node) for node in nodes]
185 list.__init__(self, nodelist)