#!/usr/bin/python2.7 import os import sys import subprocess import glob import time import getopt import sqlite3 import ssl import urllib2 from xml.dom import minidom import json def fmt_date(): return time.strftime("%Y%m%d") # get all of the installed software types by checking the SR urls # return a list, and run routine on all of them def discover_software(): conn = sqlite3.connect("/opt/slapos/slapproxy.db") cur = conn.cursor() qry = cur.execute("SELECT DISTINCT software_release FROM partition11") return [row[0] for row in qry if row[0]] def get_connection_information(software_release): conn = sqlite3.connect("/opt/slapos/slapproxy.db") cur = conn.cursor() qry = cur.execute("SELECT connection_xml FROM partition11 WHERE connection_xml IS NOT NULL AND software_release=?", (software_release,) ) xml = None for row in qry: xml = str(row[0]) break if xml is None: print software_release return (None, None) instance = minidom.parseString(xml) try: el = instance.getElementsByTagName('parameter')[0] value = el.childNodes[0].nodeValue except: return "error" if not value.startswith("{"): value = "\"" + value + "\"" json_text = json.loads(value) if 'family-admin' in json_text: return (json_text['family-admin'], json_text['inituser-password']) elif 'insecure' in json_text: return (json_text, None) else: return (None, None) def check_tables(): conn = sqlite3.connect("/opt/slapos/slapproxy.db") cur = conn.cursor() qry = cur.execute("SELECT CASE WHEN tbl_name = 'partition11' THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = 'partition11' AND type = 'table'") if qry is None: print "tables aren't ready yet, your build may have failed, check logs in /opt/slapos/log/" sys.exit(0) def get_build_status(): try: f = open("/opt/slapos/log/slapos-node-software-" + fmt_date() + ".log") except: f = open("/opt/slapos/log/slapos-node-software.log") lines = f.readlines() if "Finished software releases" not in lines[-1]: return False if "ERROR" in lines[-3]: return "error" return True # Check if the last two lines show the software finished building. # If an error came just before this, we'll report failure. # Otherwise it passed and we can move on. # We want to open today's log, as it is most up to date def status(software_release): build = get_build_status() if build: zope_ip, pw = get_connection_information(software_release) print ("Build successful, connect to:\n" " " + zope_ip) if pw is not None: print (" with\n" " username: zope password: " + pw) elif not build: print "Your software is still building, be patient it can take awhile" sys.exit(2) elif build == "error": print "An error occurred while building, check /opt/slapos/log/slapos-node-software-" + \ fmt_date() + ".log for details" sys.exit(2) ipv6 = None # check if the services are actually running (run slapos node and parse output) if pw is None: zope_ip = "https://" + zope_ip[zope_ip.index("@")+1:] original_zope_ip = zope_ip if "[" in zope_ip and "]" in zope_ip: ipv6 = zope_ip[zope_ip.index("[")+1:zope_ip.index("]")] with open("/etc/hosts", "ra+") as f: if " erp5-instance" not in f.read(): f.write("\n%s erp5-instance\n" % ipv6) zope_ip = zope_ip.replace("[" + ipv6 + "]", "erp5-instance") ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE try: r1 = urllib2.urlopen(zope_ip, context=ctx) except urllib2.URLError, e: print "At least one of your services isn't running! Check with slapos node" print "restart a service with slapos node restart slappart:service" print "" print "DEBUG information: %s" % e sys.exit(2) if r1.getcode() != 200: print "At least one of your services isn't running! Check with slapos node" print "restart a service with slapos node restart slappart:service" sys.exit(2) if ipv6: print "" print "The URL above may require extra configuration if you want to access it" print "from another machine. You can install an apache locally and include the" print "the follow rewrite rule (http version):" print """ RewriteRule ^/(.*) %s/VirtualHostBase/http/%%{HTTP_HOST}/VirtualHostRoot/$1 [L,P] or (https version): RewriteRule ^/(.*) %s/VirtualHostBase/https/%%{HTTP_HOST}/VirtualHostRoot/$1 [L,P] """ % (original_zope_ip, original_zope_ip) def info(software_release): if get_build_status(): print get_connection_information(software_release) else: print "Information unavailable at this time, run " + sys.argv[0] + " -s for details" def usage(): print ("Get the status and information of your ERP5 build\n" "Usage:") print (" --help (-h): Print this message and exit\n" " --status (-s): Print the status of the build\n" " --info (-i): Print the partition tables\n" " --dump (-d): Dump the entire database (alias for slapos proxy show)\n") def dump(): subprocess.call(["slapos", "proxy", "show", "-u", "/opt/slapos/slapproxy.db"]) def main(argv): # parse command line options try: opts, args = getopt.getopt(argv, "sihd", ["status", "info", "help", "dump"]) except getopt.error, msg: usage() sys.exit(2) if len(opts) == 0: usage() sys.exit(2) # process arguments for opt, arg in opts: if opt in ("-h", "--help"): usage() sys.exit() elif opt in ("-s", "--status"): check_tables() for sr in discover_software(): status(sr) elif opt in ("-i", "--info"): check_tables() for sr in discover_software(): info(sr) elif opt in ("-d", "--dump"): dump() if __name__ == "__main__": main(sys.argv[1:])