Package starcluster :: Module node
[hide private]
[frames] | no frames]

Source Code for Module starcluster.node

  1  import os 
  2  import socket 
  3  from starcluster import exception 
  4  from starcluster import ssh 
  5  from starcluster.logger import log 
6 7 -def ssh_to_node(node_id, cfg, user='root'):
8 ec2 = cfg.get_easy_ec2() 9 instances = ec2.get_all_instances() 10 node = None 11 for instance in instances: 12 if instance.dns_name == node_id: 13 node = instance 14 break 15 elif instance.id == node_id: 16 node = instance 17 break 18 if node: 19 key = cfg.get_key(node.key_name) 20 os.system('ssh -i %s %s@%s' % (key.key_location, user, 21 node.dns_name)) 22 else: 23 log.error("node %s does not exist" % node_id)
24
25 -def get_node(node_id, cfg):
26 """Factory for Node class""" 27 ec2 = cfg.get_easy_ec2() 28 instances = ec2.get_all_instances() 29 node = None 30 for instance in instances: 31 if instance.dns_name == node_id: 32 node = instance 33 break 34 elif instance.id == node_id: 35 node = instance 36 break 37 if not node: 38 raise exception.InstanceDoesNotExist(node_id) 39 key_location = cfg.keys.get(node.key_name, {}).get('key_location') 40 alias = node_id 41 node = Node(node, key_location, node_id) 42 return node
43
44 -class Node(object):
45 """ 46 This class represents a single compute node in a StarCluster. 47 48 It contains all useful metadata for the node such as the internal/external 49 hostnames, ips, etc as well as a paramiko ssh object for executing commands, 50 creating/modifying files on the node. 51 52 Takes boto.ec2.instance.Instance, key_location, and alias as input and 53 optionally a user to ssh as (defaults to root) 54 """
55 - def __init__(self, instance, key_location, alias, user='root'):
56 self.instance = instance 57 self.key_location = key_location 58 self.alias = alias 59 self.user = user 60 self._ssh = None
61 62 @property
63 - def ip_address(self):
64 return self.instance.ip_address
65 66 @property
67 - def public_dns_name(self):
68 return self.instance.public_dns_name
69 70 @property
71 - def private_ip_address(self):
72 return self.instance.private_ip_address
73 74 @property
75 - def private_dns_name(self):
76 return self.instance.private_dns_name
77 78 @property
79 - def private_dns_name_short(self):
80 return self.instance.private_dns_name.split('.')[0]
81 82 @property
83 - def id(self):
84 return self.instance.id
85 86 @property
87 - def block_device_mapping(self):
88 return self.instance.block_device_mapping
89 90 @property
91 - def dns_name(self):
92 return self.instance.dns_name
93 94 @property
95 - def state(self):
96 return self.instance.state
97 98 @property
99 - def launch_time(self):
100 return self.instance.launch_time
101 102 @property
103 - def key_name(self):
104 return self.instance.key_name
105 106 @property
107 - def arch(self):
108 return self.instance.architecture
109 110 @property
111 - def instance_type(self):
112 return self.instance.instance_type
113 114 @property
115 - def image_id(self):
116 return self.instance.image_id
117 118 @property
119 - def placement(self):
120 return self.instance.placement
121 122 @property
123 - def network_names(self):
124 """ Returns all network names for this node in a dictionary""" 125 names = {} 126 names['INTERNAL_IP'] = self.private_ip_address 127 names['INTERNAL_NAME'] = self.private_dns_name 128 names['INTERNAL_NAME_SHORT'] = self.private_dns_name_short 129 names['INTERNAL_ALIAS'] = self.alias 130 return names
131 132 @property
133 - def spot_id(self):
134 return self.instance.spot_instance_request_id
135
136 - def is_master(self):
137 return self.alias == "master"
138
139 - def stop(self):
140 return self.instance.stop()
141
142 - def is_ssh_up(self):
143 timeout = 10.0 144 s = socket.socket() 145 s.settimeout(timeout) 146 try: 147 s.connect((self.dns_name, 22)) 148 s.close() 149 return True 150 except socket.timeout: 151 log.debug( 152 "connecting to port 22 on timed out after % seconds" % timeout) 153 except socket.error: 154 log.debug("ssh not up for %s" % self.dns_name) 155 return False
156
157 - def is_up(self):
158 self.update() 159 if not self.is_ssh_up(): 160 return False 161 if self.private_ip_address is None: 162 log.debug("instance %s has no private_ip_address" % self.id) 163 log.debug( 164 "attempting to determine private_ip_address for instance %s" % \ 165 self.id) 166 try: 167 private_ip = self.ssh.execute( 168 'python -c "import socket; print socket.gethostbyname(\'%s\')"' % \ 169 self.private_dns_name)[0].strip() 170 log.debug("determined instance %s's private ip to be %s" % \ 171 (self.id, private_ip)) 172 self.instance.private_ip_address = private_ip 173 except Exception,e: 174 print e 175 return False 176 return True
177
178 - def update(self):
179 retval = self.instance.update() 180 if hasattr(self.instance.updated, 'private_ip_address'): 181 updated_ip = self.instance.updated.private_ip_address 182 if updated_ip and not self.instance.private_ip_address: 183 self.instance.private_ip_address = updated_ip 184 return retval
185 186 @property
187 - def ssh(self):
188 if not self._ssh: 189 self._ssh = ssh.Connection(self.instance.dns_name, 190 username=self.user, 191 private_key=self.key_location) 192 return self._ssh
193
194 - def get_hosts_entry(self):
195 """ Returns /etc/hosts entry for this node """ 196 etc_hosts_line = "%(INTERNAL_IP)s %(INTERNAL_NAME)s %(INTERNAL_NAME_SHORT)s %(INTERNAL_ALIAS)s" 197 etc_hosts_line = etc_hosts_line % self.network_names 198 return etc_hosts_line
199
200 - def __del__(self):
201 if self._ssh: 202 self._ssh.close()
203