text: from JumpScale import j
  import JumpScale.baselib.remote
  import sys
  # import importlib
  import imp
  try:
      import ujson as json
  except:
      import json
  
  import JumpScale.baselib.redis
  import copy
  import time
  import JumpScale.baselib.webdis
  
  from fabric.api import hide
  import time
  
  redis=j.clients.redis.getRedisClient("127.0.0.1", 9999)
  
  class Node():
      def __init__(self,name,args={}):
          self.model=j.core.admin.hrd.getDictFromPrefix("node.%s"%name)
          self.ssh=None
          self.args=args
  
      def executeCmds(self,cmds,die=True,insandbox=False):
          scriptRun=self.getScriptRun()
          out=scriptRun.out
          for line in cmds.split("\n"):
              if line.strip()<>"" and line[0]<>"#":
                  self.log("execcmd",line)
                  if insandbox:
                      line2="source /opt/jsbox/activate;%s"%line 
                  else:
                      line2=line               
                  try:                    
                      out+="%s\n"%self.ssh.run(line2)
                  except BaseException,e:
                      if die:
                          self.raiseError("execcmd","error execute:%s"%line,e)
  
      def killProcess(self,filterstr,die=True):
          found=self.getPids(filterstr)
          for item in found:
              self.log("killprocess","kill:%s"%item)
              try:
                  self.ssh.run("kill -9 %s"%item)
              except Exception,e:
                  if die:
                      self.raiseError("killprocess","kill:%s"%item,e)
  
      def getPids(self,filterstr,die=True):
          self.log("getpids","")
          with hide('output'):
              try:
                  out=self.ssh.run("ps ax")
              except Exception,e:
                  if die:
                      self.raiseError("getpids","ps ax",e)
          found=[]
          for line in out.split("\n"):
              if line.strip()<>"":
                  if line.find(filterstr)<>-1:
                      line=line.strip()
                      found.append(int(line.split(" ")[0]))   
          return found
  
      def deployssh(self):
          self.connectSSH()
          keyloc="/root/.ssh/id_dsa.pub"
          
          if not j.system.fs.exists(path=keyloc):
              if j.console.askYesNo("do you want to generate new local ssh key, if you have one please put it there manually!"):
                  do=j.system.process.executeWithoutPipe
                  do("ssh-keygen -t dsa")
              else:
                  j.application.stop()
          key=j.system.fs.fileGetContents(keyloc)
          self.ssh.ssh_authorize("root",key)
  
      def jpackageStop(self,name,filterstr,die=True):
          self.log("jpackagestop","%s (%s)"%(name,filterstr))
          try:
              self.ssh.run("source /opt/jsbox/activate;jpackage stop -n %s"%name)
          except Exception,e:
              if die:
                  self.raiseError("jpackagestop","%s"%name,e)
          
          found=self.getPids(filterstr)
          if len(found)>0:
              for item in found:
                  try:
                      self.ssh.run("kill -9 %s"%item)            
                  except:
                      pass
  
      def jpackageStart(self,name,filterstr,nrtimes=1,retry=1):
          found=self.getPids(filterstr)
          self.log("jpackagestart","%s (%s)"%(name,filterstr))
          for i in range(retry):
              if len(found)==nrtimes:
                  return
              scriptRun=self.getScriptRun()
              try:
                  self.ssh.run("source /opt/jsbox/activate;jpackage start -n %s"%name)  
              except Exception,e:
                  if die:
                      self.raiseError("jpackagestart","%s"%name,e)                          
              time.sleep(1)
              found=self.getPids(filterstr)
          if len(found)<nrtimes:
              self.raiseError("jpackagestart","could not jpackageStart %s"%name)
  
      def serviceStop(self,name,filterstr):
          self.log("servicestop","%s (%s)"%(name,filterstr))
          try:
              self.ssh.run("sudo stop %s"%name)
          except:
              pass
          found=self.getPids(filterstr)
          scriptRun=self.getScriptRun()
          if len(found)>0:
              for item in found:
                  try:
                      self.ssh.run("kill -9 %s"%item)            
                  except:
                      pass
          found=self.getPids(filterstr)
          if len(found)>0:
              self.raiseError("servicestop","could not serviceStop %s"%name)
  
      def serviceStart(self,name,filterstr,die=True):
          self.log("servicestart","%s (%s)"%(name,filterstr))
          found=self.getPids(filterstr)
          if len(found)==0:
              try:
                  self.ssh.run("sudo start %s"%name)          
              except:
                  pass            
          found=self.getPids(filterstr)
          if len(found)==0 and die:
              self.raiseError("servicestart","could not serviceStart %s"%name)            
  
      def serviceReStart(self,name,filterstr):
          self.serviceStop(name,filterstr)
          self.serviceStart(name,filterstr)
  
      def raiseError(self,action,msg,e=None):
          scriptRun=self.getScriptRun()
          scriptRun.state="ERROR"
          if e<>None:
              msg="Stack:\n%s\nError:\n%s\n"%(j.errorconditionhandler.parsePythonErrorObject(e),e)
              scriptRun.state="ERROR"
              scriptRun.error+=msg
  
          for line in msg.split("\n"):
              toadd="%-10s: %s\n" % (action,line)
              scriptRun.error+=toadd
              print "**ERROR** %-10s:%s"%(self.name,toadd)
          self.lastcheck=0
          j.admin.setNode(self)
          j.admin.setNode(self)
          raise RuntimeError("**ERROR**")
  
      def log(self,action,msg):
          out=""
          for line in msg.split("\n"):
              toadd="%-10s: %s\n" % (action,line)
              print "%-10s:%s"%(self.name,toadd)
              out+=toadd
  
      def setpasswd(self,passwd):
          #this will make sure new password is set
          self.log("setpasswd","")
          cl=j.tools.expect.new("sh")
          if self.args.seedpasswd=="":
             self.args.seedpasswd=self.findpasswd()
          try:
              cl.login(remote=self.name,passwd=passwd,seedpasswd=None)
          except Exception,e:
              self.raiseError("setpasswd","Could not set root passwd.")
  
      def findpasswd(self):
          self.log("findpasswd","find passwd for superadmin")
          cl=j.tools.expect.new("sh")
          for passwd in j.admin.rootpasswds:
              try:            
                  pass
                  cl.login(remote=self.name,passwd=passwd,seedpasswd=None)
              except Exception,e:
                  self.raiseError("findpasswd","could not login using:%s"%passwd,e)
                  continue
              self.passwd=passwd
              j.admin.setNode(self)
          return "unknown"
  
      def check(self):
          j.base.time.getTimeEpoch()
  
      def connectSSH(self):
          ip=self.model["ip"]
          port=self.model["port"]
          passwd=self.model["passwd"]
          self.ssh=j.remote.cuisine.connect(ip,port,passwd)
  
          # if j.system.net.pingMachine(self.args.remote,1):
          #     self.ip=self.args.remote
          # else:
          #     j.events.opserror_critical("Could not ping node:'%s'"% self.args.remote)
  
          return self.ssh
  
      def uploadFromCfgDir(self,ttype,dest,additionalArgs={}):
          dest=j.dirs.replaceTxtDirVars(dest)
          cfgdir=j.system.fs.joinPaths(self._basepath, "cfgs/%s/%s"%(j.admin.args.cfgname,ttype))
  
          additionalArgs["hostname"]=self.name
  
          cuapi=self.ssh
          if j.system.fs.exists(path=cfgdir):
              self.log("uploadcfg","upload from %s to %s"%(ttype,dest))
  
              tmpcfgdir=j.system.fs.getTmpDirPath()
              j.system.fs.copyDirTree(cfgdir,tmpcfgdir)
              j.dirs.replaceFilesDirVars(tmpcfgdir)
              j.application.config.applyOnDir(tmpcfgdir,additionalArgs=additionalArgs)
  
              items=j.system.fs.listFilesInDir(tmpcfgdir,True)
              done=[]
              for item in items:
                  partpath=j.system.fs.pathRemoveDirPart(item,tmpcfgdir)
                  partpathdir=j.system.fs.getDirName(partpath).rstrip("/")
                  if partpathdir not in done:
                      cuapi.dir_ensure("%s/%s"%(dest,partpathdir), True)
                      done.append(partpathdir)
                  try:            
                      cuapi.file_upload("%s/%s"%(dest,partpath),item)#,True,True)  
                  except Exception,e:
                      j.system.fs.removeDirTree(tmpcfgdir)
                      self.raiseError("uploadcfg","could not upload file %s to %s"%(ttype,dest))
              j.system.fs.removeDirTree(tmpcfgdir)
  
      def upload(self,source,dest):
          args=j.admin.args
          if not j.system.fs.exists(path=source):
              self.raiseError("upload","could not find path:%s"%source)
          self.log("upload","upload %s to %s"%(source,dest))
          # from IPython import embed
          # print "DEBUG NOW implement upload in Admin"  #@todo
          # embed()
      
          for item in items:
              partpath=j.system.fs.pathRemoveDirPart(item,cfgdir)
              partpathdir=j.system.fs.getDirName(partpath).rstrip("/")
              if partpathdir not in done:
                  print cuapi.dir_ensure("%s/%s"%(dest,partpathdir), True)
                  done.append(partpathdir)            
              cuapi.file_upload("%s/%s"%(dest,partpath),item)#,True,True)                       
  
      def __repr__(self):
          roles=",".join(self.roles)
          return ("%-10s %-10s %-50s %-15s %-10s %s"%(self.gridname,self.name,roles,self.ip,self.host,self.enabled))
  
      __str__=__repr__
  