DEPENDS_PIDFILE = '/tmp/nepi-depends.pid'
DEPENDS_LOGFILE = '/tmp/nepi-depends.log'
+
RPM_FUSION_URL = 'http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm'
RPM_FUSION_URL_F12 = 'http://download1.rpmfusion.org/free/fedora/releases/12/Everything/x86_64/os/rpmfusion-free-release-12-1.noarch.rpm'
if not api:
api = plcapi.PLCAPI()
self._api = api
- self._sliceapi = sliceapi
+ self._sliceapi = sliceapi or api
# Attributes
self.hostname = None
self.maxLoad = None
self.min_num_external_ifaces = None
self.max_num_external_ifaces = None
- self.timeframe = 'm'
+ self._timeframe = 'w'
# Applications and routes add requirements to connected nodes
self.required_packages = set()
self.ident_path = None
self.server_key = None
self.home_path = None
- self.enable_cleanup = False
+ self.enable_proc_cleanup = False
+ self.enable_home_cleanup = False
# Those are filled when an actual node is allocated
self._node_id = None
# Logging
self._logger = logging.getLogger('nepi.testbeds.planetlab')
+
+ def set_timeframe(self, timeframe):
+ if timeframe == "latest":
+ self._timeframe = ""
+ elif timeframe == "month":
+ self._timeframe = "m"
+ elif timeframe == "year":
+ self._timeframe = "y"
+ else:
+ self._timeframe = "w"
+
+ def get_timeframe(self):
+ if self._timeframe == "":
+ return "latest"
+ if self._timeframe == "m":
+ return "month"
+ if self._timeframe == "y":
+ return "year"
+ return "week"
+
+ timeframe = property(get_timeframe, set_timeframe)
def _nepi_testbed_environment_setup_get(self):
command = cStringIO.StringIO()
for envval in envvals:
command.write(' ; export %s=%s' % (envkey, envval))
return command.getvalue()
+
def _nepi_testbed_environment_setup_set(self, value):
pass
+
_nepi_testbed_environment_setup = property(
_nepi_testbed_environment_setup_get,
_nepi_testbed_environment_setup_set)
self._logger.info("Finding candidates for %s", self.make_filter_description())
fields = ('node_id',)
- replacements = {'timeframe':self.timeframe}
+ replacements = {'timeframe':self._timeframe}
# get initial candidates (no tag filters)
basefilters = self.build_filters({}, self.BASEFILTERS)
if attr in applicable:
tagfilter = rootfilters.copy()
tagfilter['tagname'] = tagname % replacements
- tagfilter[expr % replacements] = getattr(self,attr)
+ tagfilter[expr % replacements] = str(getattr(self,attr))
tagfilter['node_id'] = list(candidates)
-
+
candidates &= set(map(operator.itemgetter('node_id'),
self._sliceapi.GetNodeTags(filters=tagfilter, fields=fields)))
def resolvable(node_id):
try:
- addr = socket.gethostbyname(hostnames[node_id])
+ addr = server.gethostbyname(hostnames[node_id])
return addr is not None
except:
return False
def rate_nodes(self, nodes):
rates = collections.defaultdict(int)
tags = collections.defaultdict(dict)
- replacements = {'timeframe':self.timeframe}
+ replacements = {'timeframe':self._timeframe}
tagnames = [ tagname % replacements
for tagname, weight, default in self.RATE_FACTORS ]
orig_attrs['max_num_external_ifaces'] = self.max_num_external_ifaces
self.min_num_external_ifaces = None
self.max_num_external_ifaces = None
- self.timeframe = 'm'
+ if not self._timeframe: self._timeframe = 'w'
- replacements = {'timeframe':self.timeframe}
+ replacements = {'timeframe':self._timeframe}
for attr, tag in self.BASEFILTERS.iteritems():
if tag in info:
orig_attrs['server_key'] = self.server_key
self.server_key = info['ssh_rsa_key']
- self.hostip = socket.gethostbyname(self.hostname)
+ self.hostip = server.gethostbyname(self.hostname)
try:
self.__orig_attrs
RPM_FUSION_URL = self.RPM_FUSION_URL
rpmFusion = (
- 'rpm -q $(rpm -q -p %(RPM_FUSION_URL)s) || sudo -S rpm -i %(RPM_FUSION_URL)s'
+ 'rpm -q rpmfusion-free-release || sudo -S rpm -i %(RPM_FUSION_URL)s'
) % {
'RPM_FUSION_URL' : RPM_FUSION_URL
}
else:
rpmFusion = ''
-
+
if rpmFusion:
(out,err),proc = server.popen_ssh_command(
rpmFusion,
- host = self.hostname,
+ host = self.hostip,
port = None,
user = self.slicename,
agent = None,
if proc.wait():
if self.check_bad_host(out,err):
self.blacklist()
- raise RuntimeError, "Failed to set up application: %s %s" % (out,err,)
+ raise RuntimeError, "Failed to set up application on host %s: %s %s" % (self.hostname, out,err,)
# Launch p2p yum dependency installer
self._yum_dependencies.async_setup()
raise UnresponsiveNodeError, "Unresponsive host %s" % (self.hostname,)
# Ensure the node is clean (no apps running that could interfere with operations)
- if self.enable_cleanup:
- self.do_cleanup()
-
+ if self.enable_proc_cleanup:
+ self.do_proc_cleanup()
+ if self.enable_home_cleanup:
+ self.do_home_cleanup()
+
def wait_dependencies(self, pidprobe=1, probe=0.5, pidmax=10, probemax=10):
# Wait for the p2p installer
if self._yum_dependencies and not self._installed:
# they have to be created for deployment
(out,err),proc = server.eintr_retry(server.popen_ssh_command)(
"echo 'ALIVE'",
- host = self.hostname,
+ host = self.hostip,
port = None,
user = self.slicename,
agent = None,
return False
def destroy(self):
- if self.enable_cleanup:
- self.do_cleanup()
+ if self.enable_proc_cleanup:
+ self.do_proc_cleanup()
def blacklist(self):
if self._node_id:
import util
util.appendBlacklist(self.hostname)
- def do_cleanup(self):
+ def do_proc_cleanup(self):
if self.testbed().recovering:
# WOW - not now
return
- self._logger.info("Cleaning up %s", self.hostname)
+ self._logger.info("Cleaning up processes on %s", self.hostname)
cmds = [
"sudo -S killall python tcpdump || /bin/true ; "
cmd % {
'slicename' : self.slicename ,
},
- host = self.hostname,
+ host = self.hostip,
port = None,
user = self.slicename,
agent = None,
retry = 3
)
proc.wait()
-
+
+ def do_home_cleanup(self):
+ if self.testbed().recovering:
+ # WOW - not now
+ return
+
+ self._logger.info("Cleaning up home on %s", self.hostname)
+
+ cmds = [
+ "find . -maxdepth 1 \( -name '.cache' -o -name '.local' -o -name '.config' -o -name 'nepi-*' \) -execdir rm -rf {} + "
+ ]
+
+ for cmd in cmds:
+ (out,err),proc = server.popen_ssh_command(
+ # Some apps need two kills
+ cmd,
+ host = self.hostip,
+ port = None,
+ user = self.slicename,
+ agent = None,
+ ident_key = self.ident_path,
+ server_key = self.server_key,
+ tty = True, # so that ps -N -T works as advertised...
+ timeout = 60,
+ retry = 3
+ )
+ proc.wait()
+
def prepare_dependencies(self):
# Configure p2p yum dependency installer
if self.required_packages and not self._installed:
if len(routes) > MAX_VROUTE_ROUTES:
return 'sliceip'
- vsys_vnet = ipaddr.IPNetwork(vsys_vnet)
+ vsys_vnet = ipaddr.IPv4Network(vsys_vnet)
for route in routes:
- dest, prefix, nexthop, metric = route
- dest = ipaddr.IPNetwork("%s/%d" % (dest,prefix))
+ dest, prefix, nexthop, metric, device = route
+ dest = ipaddr.IPv4Network("%s/%d" % (dest,prefix))
nexthop = ipaddr.IPAddress(nexthop)
if dest not in vsys_vnet or nexthop not in vsys_vnet:
return 'sliceip'
return 'vroute'
def format_route(self, route, dev, method, action):
- dest, prefix, nexthop, metric = route
+ dest, prefix, nexthop, metric, device = route
if method == 'vroute':
return (
"%s %s%s gw %s %s" % (
"( sudo -S bash -c 'cat /vsys/%(method)s.out >&2' & ) ; sudo -S bash -c 'cat > /vsys/%(method)s.in' ; sleep 0.5" % dict(
home = server.shell_escape(self.home_path),
method = method),
- host = self.hostname,
+ host = self.hostip,
port = None,
user = self.slicename,
agent = None,
def check_bad_host(self, out, err):
badre = re.compile(r'(?:'
- r"curl: [(]\d+[)] Couldn't resolve host 'download1[.]rpmfusion[.]org'"
+ #r"curl: [(]\d+[)] Couldn't resolve host 'download1[.]rpmfusion[.]org'"
r'|Error: disk I/O error'
r')',
re.I)
return badre.search(out) or badre.search(err)
+