def _daemonize(self): ## @守护进程主方法@ ## create - fork 1 调用fork()以便父进程可以退出 try: pid = os.fork() if pid > 0: sys.exit(0) ## 父进程退出 except OSError, e: sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) saveLog("Robot Daemo fork #1 failed:"+str(e.strerror)) sys.exit(1)
def stop(self): ## 停止守护进程 ## 从 pidfile 里获取 PID try: pf = file(self.pidfile,'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None if not pid: message = "pidfile %s does not exist. Robot Daemo not running?\n" sys.stderr.write(message % self.pidfile) return # not an error in a restart ## kill 掉守护进程 try: while 1: saveLog("Robot Daemo Starting shutdown...") os.kill(pid, SIGTERM) time.sleep(0.1) saveLog("Shutdown completed !") except OSError, err: err = str(err) if err.find("No such process") > 0: if os.path.exists(self.pidfile): os.remove(self.pidfile) else: saveLog('Stop error,'+str(err)) sys.exit(1)
def doWork(self): ''' 传入一个SQL语句队列对象 参数说明 self.id: 数据库记录编号,用于回填执行结果 self.cmd: 命令 self.type: 命令类型 self.ip: 需要执行该命令的IP地址 self.dependID: 依赖的PID, 即需要等该PID执行完以后才开始运行 ''' self.id = self.sqlRes['iId'] self.cmd = str(self.sqlRes['sCmd']) self.type = self.sqlRes['eType'] self.dependID = self.sqlRes['iDependID'] self.ip = self.sqlRes['sIP'] self.sshPort = self.sqlRes['sSSHport'] self.connDb() ## 连接数据库 if self.dependID: if not self.getDependPidStatus(self.dependID): return ## 执行待执行的命令 ## 定义ssh连接参数 ## 按类型执行命令 if self.type == 'local': ## 即为 本地命令,在中央服本地运行 fullCmd = self.cmd elif self.type == 'remote': ## 即为 远程命令 fullCmd = 'ssh -p%s %s root@%s "%s"' % (self.sshPort,self.sOption,self.ip,self.cmd) elif self.type == 'scp': ## SCP推送文件/目录 tmpCmd = self.cmd.split() srcFile = tmpCmd[0] dstFile = tmpCmd[1] fullCmd = 'scp -r -P%s %s%s root@%s:%s' % (self.sshPort,self.sOption,srcFile,self.ip,dstFile) elif self.type == 'scp_back': ## 从远程服务器拉取文件/目录 tmpCmd = self.cmd.split() srcFile = tmpCmd[0] dstFile = tmpCmd[1] fullCmd = 'scp -r -P%s %s root@%s:%s %s' % (self.sshPort,self.sOption,self.ip,srcFile,dstFile) elif self.type == 'rsync': ## rsync推送文件/目录到远程服务器 tmpCmd = self.cmd.split() srcFile = tmpCmd[0] dstFile = tmpCmd[1] fullCmd = 'rsync -az -e "ssh -p%s %s" %s root@%s:%s' % (self.sshPort,self.sOption,srcFile,self.ip,dstFile) else: ## 否则为不支持的命令类型 saveLog("你输入的命令:%s 不在本机支持的命令类型范围内,请重新输入." % (fullCmd)) print "你输入的命令:%s 不在本机支持的命令类型范围内,请重新输入." % (fullCmd) return ## 开始执行命令 saveLog("%s 开始执行." % fullCmd) self.upStatus(self.id, 2) ## 状态置为2, 即正在运行... try: ssh_master(self.ip) except Exception, err: saveLog("创建 ssh socket 失败: %s" % str(err))
os.remove(self.pidfile) def start(self): ## 开启守护进程 ## 检测 pidfile 以判断守护进程有没有在运行 try: pf = file(self.pidfile,'r') pid = int(pf.read().strip()) pf.close() except IOError,e: pid = None ##saveLog("Robot Daemo ioerror :"+str(e)) if pid: message = "Start error,pidfile %s already exist. Daemon already running?\n" saveLog(message) sys.stderr.write(message % self.pidfile) sys.exit(1) ## 启动 saveLog("Starting Robot Daemon...") self._daemonize() pf = file(self.pidfile,'r') pid = int(pf.read().strip()) pf.close() saveLog("Start completed, pid: %s" % pid) self._run() def stop(self): ## 停止守护进程 ## 从 pidfile 里获取 PID
dstFile = tmpCmd[1] fullCmd = 'rsync -az -e "ssh -p%s %s" %s root@%s:%s' % (self.sshPort,self.sOption,srcFile,self.ip,dstFile) else: ## 否则为不支持的命令类型 saveLog("你输入的命令:%s 不在本机支持的命令类型范围内,请重新输入." % (fullCmd)) print "你输入的命令:%s 不在本机支持的命令类型范围内,请重新输入." % (fullCmd) return ## 开始执行命令 saveLog("%s 开始执行." % fullCmd) self.upStatus(self.id, 2) ## 状态置为2, 即正在运行... try: ssh_master(self.ip) except Exception, err: saveLog("创建 ssh socket 失败: %s" % str(err)) try: p = subprocess.Popen(fullCmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) out, errInfo = p.communicate() ## 返回一个元组,元组第一个元素为标准输出,第二个元素为标准错误输出 if p.returncode != 0: ## 如果stderr不为空,表示命令运行有误,状态置为4 stat = 4 else: stat = 3 ## 运行成功,状态置为3 except Exception, err: saveLog("执行命令,等待命令返回值发生未知错误. %s --- %s" % (str(err), type(self.cmd))) saveLog("%s 执行完成,命令返回值: %s" % (fullCmd,str(stat))) self.upReturnContents(self.id, stat, out) ## 更新命令运行后的返回内容