from nepi.resources.linux.application import LinuxApplication
from nepi.resources.linux.node import OSType
+from nepi.util.sshfuncs import ProcStatus
+from nepi.util.timefuncs import strfnow, strfdiff
import os
@clsinit_copy
def __init__(self, ec, guid):
super(LinuxCCND, self).__init__(ec, guid)
- def trace(self, name, attr = TraceAttr.ALL, block = 512, offset = 0):
- self.info("Retrieving '%s' trace %s " % (name, attr))
-
- path = os.path.join(self.app_home, name)
-
- command = "(test -f %s && echo 'success') || echo 'error'" % path
- (out, err), proc = self.node.execute(command)
-
- if (err and proc.poll()) or out.find("error") != -1:
- msg = " Couldn't find trace %s " % name
- self.error(msg, out, err)
- return None
-
- if attr == TraceAttr.PATH:
- return path
-
- if attr == TraceAttr.ALL:
- (out, err), proc = self.node.check_output(self.app_home, name)
-
- if err and proc.poll():
- msg = " Couldn't read trace %s " % name
- self.error(msg, out, err)
- return None
-
- return out
-
- if attr == TraceAttr.STREAM:
- cmd = "dd if=%s bs=%d count=1 skip=%d" % (path, block, offset)
- elif attr == TraceAttr.SIZE:
- cmd = "stat -c%%s %s " % path
-
- (out, err), proc = self.node.execute(cmd)
-
- if err and proc.poll():
- msg = " Couldn't find trace %s " % name
- self.error(msg, out, err)
- return None
-
- if attr == TraceAttr.SIZE:
- out = int(out.strip())
-
- return out
-
def deploy(self):
if not self.get("command"):
self.set("command", self._default_command)
super(LinuxCCND, self).deploy()
- def start(self):
- command = self.get("command")
- env = self.get("env")
- stdin = "stdin" if self.get("stdin") else None
- stdout = "stdout" if self.get("stdout") else "stdout"
- stderr = "stderr" if self.get("stderr") else "stderr"
- sudo = self.get("sudo") or False
- x11 = self.get("forwardX11") or False
- failed = False
-
- if not command:
- # If no command was given, then the application
- # is directly marked as FINISHED
- self._state = ResourceState.FINISHED
-
- self.info("Starting command '%s'" % command)
-
- if x11:
- # If X11 forwarding was specified, then the application
- # can not run detached, so instead of invoking asynchronous
- # 'run' we invoke synchronous 'execute'.
- if not command:
- msg = "No command is defined but X11 forwarding has been set"
- self.error(msg)
- self._state = ResourceState.FAILED
- raise RuntimeError, msg
-
- # Export environment
- environ = "\n".join(map(lambda e: "export %s" % e, env.split(" ")))\
- if env else ""
-
- command = environ + command
- command = self.replace_paths(command)
-
- # Mark application as started before executing the command
- # since after the thread will be blocked by the execution
- # until it finished
- super(LinuxApplication, self).start()
-
- # If the command requires X11 forwarding, we
- # can't run it asynchronously
- (out, err), proc = self.node.execute(command,
- sudo = sudo,
- stdin = stdin,
- forward_x11 = x11)
-
- self._state = ResourceState.FINISHED
-
- if proc.poll() and err:
- failed = True
- else:
- # Command was previously uploaded, now run the remote
- # bash file asynchronously
- cmd = "bash ./app.sh"
- (out, err), proc = self.node.run(cmd, self.app_home,
- stdin = stdin,
- stdout = stdout,
- stderr = stderr,
- sudo = sudo)
-
- # check if execution errors occurred
- msg = " Failed to start command '%s' " % command
-
- if proc.poll() and err:
- self.error(msg, out, err)
- raise RuntimeError, msg
-
- # Check status of process running in background
- pid, ppid = self.node.wait_pid(self.app_home)
- if pid: self._pid = int(pid)
- if ppid: self._ppid = int(ppid)
-
- # If the process is not running, check for error information
- # on the remote machine
- if not self.pid or not self.ppid:
- (out, err), proc = self.node.check_output(self.app_home, 'stderr')
- self.error(msg, out, err)
-
- msg2 = " Setting state to Failed"
- self.debug(msg2)
- self._state = ResourceState.FAILED
-
- raise RuntimeError, msg
-
- super(LinuxApplication, self).start()
-
def stop(self):
command = self.get('command') or ''
state = self.state
@property
def state(self):
if self._state == ResourceState.STARTED:
- # To avoid overwhelming the remote hosts and the local processor
- # with too many ssh queries, the state is only requested
- # every 'state_check_delay' seconds.
+ # we executed the ccndstart command. This should have started
+ # a remote ccnd daemon. The way we can query wheather ccnd is
+ # still running is by executing the ccndstatus command.
state_check_delay = 0.5
if strfdiff(strfnow(), self._last_state_check) > state_check_delay:
- # check if execution errors occurred
- (out, err), proc = self.node.check_errors(self.app_home)
+ env = self.get('env') or ""
+ environ = self.node.format_environment(env, inline = True)
+ command = environ + "; ccndstatus"
+ command = self.replace_paths(command)
+
+ (out, err), proc = self.node.execute(command)
- if out or err:
- if err.find("No such file or directory") >= 0 :
- # The resource is marked as started, but the
- # command was not yet executed
- return ResourceState.READY
+ retcode = proc.poll()
- msg = " Failed to execute command '%s'" % self.get("command")
+ if retcode == 1 and err.find("No such file or directory") > -1:
+ # ccnd is not running (socket not found)
+ self._state = ResourceState.FINISHED
+ elif retcode:
+ # other error
+ msg = " Failed to execute command '%s'" % command
self.error(msg, out, err)
self._state = ResourceState.FAILED
- elif self.pid and self.ppid:
- status = self.node.status(self.pid, self.ppid)
-
- if status == ProcStatus.FINISHED:
- self._state = ResourceState.FINISHED
-
-
self._last_state_check = strfnow()
return self._state
return (
# Evaluate if ccnx binaries are already installed
" ( "
- " test -f ${EXP_HOME}/ccnx/bin/ccnd"
+ " test -f ${EXP_HOME}/ccnx/bin/ccnd && "
+ " echo 'sources found, nothing to do' "
" ) || ( "
# If not, untar and build
" ( "
return (
# Evaluate if ccnx binaries are already installed
" ( "
- " test -f ${EXP_HOME}/ccnx/bin/ccnd"
+ " test -f ${EXP_HOME}/ccnx/bin/ccnd && "
+ " echo 'sources found, nothing to do' "
" ) || ( "
+ # If not, install
" mkdir -p ${EXP_HOME}/ccnx/bin && "
" cp -r ${SOURCES}/ccnx ${EXP_HOME}"
" )"
"prefix" : "CCND_PREFIX",
})
- env = "PATH=$PATH:${EXP_HOME}/ccnx/bin"
- for key in envs.keys():
- val = self.get(key)
- if val:
- env += " %s=%s" % (key, val)
+ env = "PATH=$PATH:${EXP_HOME}/ccnx/bin "
+ env += " ".join(map(lambda k: "%s=%s" % (envs.get(k), self.get(k)) \
+ if self.get(k) else "", envs.keys()))
return env