# Lucia Guevgeozian <lucia.guevgeozian_odizzio@inria.fr>
from nepi.execution.attribute import Attribute, Flags, Types
-from nepi.execution.resource import ResourceManager, clsinit_copy, ResourceState, \
- reschedule_delay
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+ ResourceState, reschedule_delay
from nepi.resources.linux.node import LinuxNode
from nepi.resources.planetlab.plcapi import PLCAPIFactory
from nepi.util.execfuncs import lexec
+from nepi.util import sshfuncs
from random import randint
import time
"associated to a PlanetLab user account"
_backend = "planetlab"
+ ## XXX A.Q. This lock could use a more descriptive name and
+ # an explanatory comment
lock = threading.Lock()
@classmethod
cls._register_attribute(min_cpu)
cls._register_attribute(max_cpu)
cls._register_attribute(timeframe)
-
def __init__(self, ec, guid):
super(PlanetlabNode, self).__init__(ec, guid)
return self._plapi
- def discover(self):
+ def do_discover(self):
"""
Based on the attributes defined by the user, discover the suitable nodes
"""
- hostname = self.get("hostname")
+ hostname = self._get_hostname()
+ print self.guid, hostname
if hostname:
# the user specified one particular node to be provisioned
# check with PLCAPI if it is alvive
node_id = self._query_if_alive(hostname=hostname)
node_id = node_id.pop()
+ print self.guid, node_id
# check that the node is not blacklisted or being provisioned
# by other RM
with PlanetlabNode.lock:
plist = self.plapi.reserved()
blist = self.plapi.blacklisted()
+ print self.guid,plist
+ print self.guid,blist
if node_id not in blist and node_id not in plist:
# check that is really alive, by performing ping
else:
self._put_node_in_provision(node_id)
self._node_to_provision = node_id
- super(PlanetlabNode, self).discover()
+ super(PlanetlabNode, self).do_discover()
else:
self.fail_node_not_available(hostname)
if node_id:
self._node_to_provision = node_id
- super(PlanetlabNode, self).discover()
+ super(PlanetlabNode, self).do_discover()
else:
self.fail_not_enough_nodes()
- def provision(self):
+ def do_provision(self):
"""
Add node to user's slice after verifing that the node is functioning
correctly
provision_ok = False
ssh_ok = False
proc_ok = False
- timeout = 1200
+ timeout = 120
while not provision_ok:
node = self._node_to_provision
try:
self._set_hostname_attr(node)
except:
- self.discover()
+ with PlanetlabNode.lock:
+ self._blacklist_node(node)
+ self.do_discover()
+ continue
+
self._add_node_to_slice(node)
# check ssh connection
with PlanetlabNode.lock:
self._blacklist_node(node)
self._delete_node_from_slice(node)
- self.discover()
+ self.set('hostname', None)
+ self.do_discover()
continue
# check /proc directory is mounted (ssh_ok = True)
with PlanetlabNode.lock:
self._blacklist_node(node)
self._delete_node_from_slice(node)
- self.discover()
+ self.set('hostname', None)
+ self.do_discover()
continue
else:
ip = self._get_ip(node)
self.set("ip", ip)
- super(PlanetlabNode, self).provision()
+ super(PlanetlabNode, self).do_provision()
def _filter_based_on_attributes(self):
"""
Retrive the list of nodes ids that match user's constraints
"""
+
# Map user's defined attributes with tagnames of PlanetLab
timeframe = self.get("timeframe")[0]
attr_to_tags = {
filters['run_level'] = 'boot'
filters['boot_state'] = 'boot'
filters['node_type'] = 'regular'
- filters['>last_contact'] = int(time.time()) - 2*3600
+ #filters['>last_contact'] = int(time.time()) - 2*3600
# adding node_id or hostname to the filters to check for the particular
# node
alive_nodes_id = self._get_nodes_id(filters)
if len(alive_nodes_id) == 0:
- self.fail_discovery()
+ self.fail_node_not_alive(self, hostname)
else:
nodes_id = list()
for node_id in alive_nodes_id:
return nodes_id
def _choose_random_node(self, nodes):
- """
+ """
From the possible nodes for provision, choose randomly to decrese the
probability of different RMs choosing the same node for provision
"""
plist = self.plapi.reserved()
if node_id not in blist and node_id not in plist:
ping_ok = self._do_ping(node_id)
+ print " ### ping_ok #### %s guid %s" % (ping_ok, self.guid)
if not ping_ok:
self._blacklist_node(node_id)
else:
# discovered node for provision, added to provision list
self._put_node_in_provision(node_id)
+ print "node_id %s , guid %s" % (node_id, self.guid)
return node_id
def _get_nodes_id(self, filters):
return self.plapi.get_nodes(filters, fields=['node_id'])
def _add_node_to_slice(self, node_id):
- self.info(" Selecting node ... ")
+ self.info(" Selected node to provision ")
slicename = self.get("username")
with PlanetlabNode.lock:
slice_nodes = self.plapi.get_slice_nodes(slicename)
slicename = self.get("username")
self.plapi.delete_slice_node(slicename, [node])
+ def _get_hostname(self):
+ hostname = self.get("hostname")
+ ip = self.get("ip")
+ if hostname:
+ return hostname
+ elif ip:
+ hostname = sshfuncs.gethostbyname(ip)
+ return hostname
+ else:
+ return None
+
def _set_hostname_attr(self, node):
"""
Query PLCAPI for the hostname of a certain node id and sets the
"""
ping_ok = False
ip = self._get_ip(node_id)
- command = "ping -c2 %s | echo \"PING OK\"" % ip
+ print "ip de do_ping %s, guid %s" % (ip, self.guid)
+ if not ip: return ping_ok
+
+ command = "ping -c2 %s" % ip
(out, err) = lexec(command)
- if not out.find("PING OK") < 0:
+ print "out de do_ping %s, guid %s" % (out, self.guid)
+ if not out.find("2 received") < 0:
ping_ok = True
-
+
+ print "ping_ok de do_ping %s, guid %s" % (ping_ok, self.guid)
return ping_ok
def _blacklist_node(self, node):
"""
Query PLCAPI for the IP of a node with certain node id
"""
- ip = self.plapi.get_interfaces({'node_id':node_id}, fields=['ip'])
- ip = ip[0]['ip']
+ hostname = self.plapi.get_nodes(node_id, ['hostname'])[0]
+ print "#### HOSTNAME ##### %s ### guid %s " % (hostname['hostname'], self.guid)
+ ip = sshfuncs.gethostbyname(hostname['hostname'])
+ if not ip:
+ # Fail while trying to find the IP
+ return None
return ip
def fail_discovery(self):
- self.fail()
msg = "Discovery failed. No candidates found for node"
self.error(msg)
raise RuntimeError, msg
- def fail_node_not_alive(self, hostname):
- msg = "Node %s not alive, pick another node" % hostname
+ def fail_node_not_alive(self, hostname=None):
+ msg = "Node %s not alive" % hostname
raise RuntimeError, msg
def fail_node_not_available(self, hostname):
- msg = "Node %s not available for provisioning, pick another \
- node" % hostname
+ msg = "Node %s not available for provisioning" % hostname
raise RuntimeError, msg
def fail_not_enough_nodes(self):