def ping(): # check state and return status if STATE.process is None: return STATE.status if STATE.process.poll() == None: return STATE.status DEBUG("ping found old process but no longer running.") STATE.status = 3 return STATE.status
def ping(): newstatus = detachable.ping() if newstatus != CONFIG.status: DEBUG("Ping changing status from " + str(CONFIG.status) + " to " + str(newstatus)) CONFIG.status = newstatus CONFIG.msg = detachable.geterrors() CONFIG.timestamp = CONFIG.timestamp + 1 putIntFile(CONFIG.dataroot + buildinstancedir(CONFIG.id) + "/STATUS", newstatus) return currentResponse()
def startServer(s): global settings, state svr = resolveServerId(s) url = "http://" + svr + "/WEBRC?request=" + settings.action DEBUG("URL TO START: [" + url + "]") try: r = urllib2.urlopen(url) except Exception, e: ERROR(" Cannot reach server " + s + " " + e.message) raise return False
def start(action, args, workdir): global STATE # could also use PYTHONUNBUFFERED DEBUG("Starting subprocess: voltdb " + action + args) STATE.process = subprocess.Popen("voltdb " + action + args, shell=True, cwd=workdir, stdout=subprocess.PIPE) STATE.pid = STATE.process.pid subthread = threading.Thread(target=subprocreader, args=(STATE.process, )) subthread.start() STATE.status = 1
def initServer(s): global settings, state # Get current status of server DEBUG("init server [" + s + "]") svr = resolveServerId(s) url = "http://" + svr + "/WEBRC?request=init" try: r = urllib2.urlopen(url) except Exception, e: ERROR(" Cannot reach server " + s + " " + e.message) raise return False
def checkJsonData(j, field): data = "" status = -1 retval = "" DEBUG("Json string " + j) try: data = json.loads(j) except: WARNING("can't read JSON") return retval if ("data" in data): d = data["data"] if (field in d): retval = d[field] else: DEBUG("no field " + field + " in data") else: WARNING("No data in JSON") return retval
def getTextFile(f): result = "" if not os.path.exists(f): DEBUG(f + " not found") return result try: fid = open(f, "r") result = fid.read() fid.close() except Exception as e: WARNING(e) return result
def updatehostcount(config,hostcount): setmessage("") DEBUG("update host count to " + str(hostcount) + " on deployment file " + config) try: xml = ET.fromstring(config) except Exception as e: setmessage("Invalid deployment file. Cannot parse XML.") ERROR("Invalid deployment file. Cannot parse XML.") return None cluster = xml.find('cluster') DEBUG("Cluster: " + str(cluster)) if cluster is None: setmessage("Invalid deployment file. No <cluster> element.") ERROR("Invalid deployment file. No <cluster> element.") return None if ('hostcount' in cluster.attrib): cluster.attrib['hostcount'] = str(hostcount) else: # Add hostcount cluster.attrib['hostcount'] = hostcount return ET.tostring(xml)
def writedeploymentfile (config, filespec, hostcount): setmessage("") if config == "": ERROR("no XML to write as deployment file.") return False x = updatehostcount(config,hostcount) if x is None: return False try: fid = open(filespec ,"w") DEBUG("writing deployment file " + filespec) result = fid.write(x) fid.close() return True except Exception as e: setmessage("INTERNAL ERROR CAN'T WRITE FILE: " + str(e)) ERROR("INTERNAL ERROR CAN'T WRITE FILE: " + str(e)) return False
def init(data): indata = {} #DEBUG("INCOMING DATA: " + str(data)) if (len(data) > 0): indata = json.loads(data) #DEBUG("LOADED DATA: " + str(indata)) if ('ip' in indata) and (CONFIG.ip == ""): CONFIG.ip = indata['ip'] DEBUG("Setting IP to " + CONFIG.ip + " from client.") instance = findInstance(1) if not instance: instance = createInstance(1) if instance: CONFIG.id = 1 CONFIG.status = instance.status CONFIG.pid = instance.pid CONFIG.data = instance.data retval = currentResponse() return (retval)
def prepServer(s): global settings, state svr = resolveServerId(s) # Set the hosts and deployment (as necessary) data = {} data["hoststring"] = settings.hoststring data["deployment"] = settings.deployment data["args"] = settings.args jdata = json.dumps(data) urldata = urllib.urlencode({"data": jdata}) url = "http://" + svr + "/WEBRC?request=set&" + urldata DEBUG("Prep server url: " + url) try: r = urllib2.urlopen(url) except Exception, e: ERROR(" Cannot reach server " + s + " " + e.message) raise return False
def subprocreader(p): global STATE INFO("In subprocess...") STATE.status = 1 while True: if p.poll() != None: break line = p.stdout.readline().rstrip() DEBUG("subprocess: " + line.rstrip()) # Find when server is up if line.find("Server completed initialization") == 0: STATE.status = 2 # log errors if line.find("FATAL") == 0 or line.find("ERROR") == 0: STATE.errorlog[STATE.errorlogptr] = line STATE.errorlogptr = STATE.errorlogptr + 1 if STATE.errorlogptr == 5: STATE.errorlogptr = 0 INFO("end of process") STATE.status = 3 return
def set(data): # Cannot set if database is running if CONFIG.status == 1 or CONFIG.status == 2: WARNING("Cannot SET while database is starting or running") return ping() # set the specified data (received as JSON) d = json.loads(data) DEBUG("SET(): " + str(d)) hostcount = 1 if "hoststring" in d: CONFIG.data["hoststring"] = d["hoststring"] hosts = d["hoststring"].split(",") hostcount = len(hosts) if "deployment" in d: CONFIG.data["deployment"] = d["deployment"] if "args" in d: CONFIG.data["args"] = d["args"] # and then return the resulting instance and/or error CONFIG.timestamp = CONFIG.timestamp + 1 return currentResponse()
def resolveServerId(s): svr = s if svr == "": svr = "localhost" if svr.find(":") < 0: svr = svr + ":8000" DEBUG("Reolve Server as [" + svr + "]") return svr
def parseCli(conf): global settings flags = [] flagargs = [] arguments = [] currentflag = "" flagargument = False i = 0 for a in sys.argv: i = i + 1 if i == 1: continue # skip the script name if a[0:1] == "-": if flagargument: ERROR("expecting value for argument " + currentflag) exit() fl = "" flarg = "" if a[0:2] == "--": fl = a[2:] p = fl.find("=") if p < 0: p = fl.find(":") if p >= 0: flarg = fl[p + 1:] fl = fl[0:p] else: fl = a[1:] if len(fl) > 1: flarg = fl[1:] fl = fl[0:1] # Check if flag is valid and/or needs arguments if checkCliFlag(fl): if flarg == "": currentflag = fl flagargument = True else: flags.append(fl) flagargs.append(flarg) else: flags.append(fl) flagargs.append(flarg) else: # Catch arguments if flagargument: flags.append(currentflag) flagargs.append(a) flagargument = False currentflag = "" else: if len(conf.action) == 0: conf.action = a else: arguments.append(a) DEBUG("Flags: " + str(len(flags))) DEBUG("Args: " + str(len(arguments))) for i in range(0, len(flags)): if flags[i] == "deployment" or flags[i] == "d": try: deploy = "" with open(flagargs[i], "r") as df: for line in df: # Compress the deployment if len(deploy) > 0: deploy = deploy + "\n" deploy = deploy + line.strip() conf.deployment = deploy except Exception, e: ERROR("cannot read deployment file.\n" + str(e)) exit() if flags[i] == "replica" or flags[i] == "r": conf.args = conf.args + " --replica" if flags[i] == "debug": SET_DEBUG(True)
try: r = urllib2.urlopen(url) except Exception, e: ERROR(" Cannot reach server " + s + " " + e.message) raise return False jdata = r.read() status = checkJsonStatus(jdata) state.server[s] = status # If this is the first server, and no deployment file is defined, # load the deployment file, etc. # Validate anything but create or add (join, recover...) #print "DEBUG INIT(), Deployment: " + checkJsonData(jdata,"deployment") if s == settings.hoststring.split(",")[0]: DEBUG("This is the first server in the list [" + s + "]. Parsing data.") if settings.deployment == "": settings.deployment = retval = checkJsonData(jdata, "deployment") if status == 1 or status == 2: ERROR("a database is already running on server " + s) return False #else: # DEBUG("status is " + str(status)) return True def prepServer(s): global settings, state svr = resolveServerId(s)