def cmd_list(args, config): gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") out("[ok]\n") url = "%s/list/" % endpoint params = { "version": __version__, "site_key": site_key, } try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.HTTPError, e: out("\nReceived an error [%d: %s]" % (e.code, e.read())) sys.exit(1)
def cmd_delete(args, config): instance_label = args.label[0] gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") out("[ok]\n") text = "ARE YOU SURE YOU WANT TO DELETE THIS INSTANCE? [Y/N] " out(text) user_input = raw_input() if user_input != "Y": out("Exiting without deleting the instance.\n") sys.exit(0) text = "Deleting... " url = "%s/delete/" % endpoint params = {"version": __version__, "site_key": site_key, "instance_label": instance_label} try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.HTTPError, e: out("\nReceived an error [%d: %s]" % (e.code, e.read())) sys.exit(1)
def cmd_list(args, config): gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") out("[ok]\n") url = "%s/list/" % endpoint params = { "version": __version__, "site_key": site_key, } response = make_api_call(config, url, urllib.urlencode(params)) data = json.loads(response.read()) if data["status"] == "success": out("\n") instances = sorted(data["instances"], key=lambda v: v["label"]) if instances: for instance in instances: out("%s [%s] %s\n" % (instance["label"], instance["kind"], instance["last_deployment"]["sha"][:8])) else: out("No instances found.\n") else: error("%s\n" % data["message"])
def cmd_manage(args, config): instance_label = args.label[0] operation = args.operation[0] opargs = args.opargs gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") out("[ok]\n") url = "%s/manage/" % endpoint params = {"version": __version__, "site_key": site_key, "instance_label": instance_label, "operation": operation} handlers = [http.MultipartPostHandler] if not sys.stdin.isatty(): params["stdin"] = sys.stdin pb = ProgressBar(0, 100, 77) out("Pushing stdin to Gondor... \n") handlers.extend([http.UploadProgressHandler(pb, ssl=True), http.UploadProgressHandler(pb, ssl=False)]) params = params.items() for oparg in opargs: params.append(("arg", oparg)) try: response = make_api_call(config, url, params, extra_handlers=handlers) except urllib2.HTTPError, e: out("\nReceived an error [%d: %s]" % (e.code, e.read())) sys.exit(1)
def cmd_sqldump(args, config): label = args.label[0] gondor_dirname = ".gondor" repo_root = utils.find_nearest(os.getcwd(), gondor_dirname) local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(repo_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") # request SQL dump and stream the response through uncompression err("Dumping database... ") url = "%s/sqldump/" % endpoint params = { "version": __version__, "site_key": site_key, "label": label, } try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.HTTPError, e: out("\nReceived an error [%d: %s]" % (e.code, e.read())) sys.exit(1)
def cmd_manage(args, env, config): instance_label = args.label[0] operation = args.operation[0] opargs = args.opargs url = "%s/manage/" % config["gondor.endpoint"] params = { "version": __version__, "site_key": config["gondor.site_key"], "instance_label": instance_label, "operation": operation, } handlers = [ http.MultipartPostHandler, ] if not sys.stdin.isatty(): params["stdin"] = sys.stdin pb = ProgressBar(0, 100, 77) out("Pushing stdin to Gondor... \n") handlers.extend([ http.UploadProgressHandler(pb, ssl=True), http.UploadProgressHandler(pb, ssl=False) ]) params = params.items() for oparg in opargs: params.append(("arg", oparg)) try: response = make_api_call(config, url, params, extra_handlers=handlers) except urllib2.HTTPError, e: api_error(e)
def cmd_manage(args, env, config): instance_label = args.label[0] operation = args.operation[0] opargs = args.opargs if operation == "database:load" and not args.yes: out("This command will destroy all data in the database for %s\n" % instance_label) answer = raw_input("Are you sure you want to continue? [y/n]: ") if answer != "y": sys.exit(1) url = "%s/instance/manage/" % config["gondor.endpoint"] params = { "version": __version__, "site_key": config["gondor.site_key"], "instance_label": instance_label, "operation": operation, } handlers = [ http.MultipartPostHandler, ] if operation in ["database:load"]: if opargs: filename = os.path.abspath(os.path.expanduser(opargs[0])) try: fp = open(filename, "rb") except IOError: error("unable to open %s\n" % filename) out("Compressing file... ") fd, tmp = tempfile.mkstemp() fpc = gzip.open(tmp, "wb") try: while True: chunk = fp.read(8192) if not chunk: break fpc.write(chunk) finally: fpc.close() out("[ok]\n") params["stdin"] = open(tmp, "rb") pb = ProgressBar(0, 100, 77) out("Pushing file to Gondor... \n") handlers.extend([ http.UploadProgressHandler(pb, ssl=True), http.UploadProgressHandler(pb, ssl=False) ]) else: error("%s takes one argument.\n" % operation) params = params.items() for oparg in opargs: params.append(("arg", oparg)) try: response = make_api_call(config, url, params, extra_handlers=handlers) except urllib2.HTTPError, e: api_error(e)
def cmd_list(args, env, config): url = "%s/list/" % config["gondor.endpoint"] params = { "version": __version__, "site_key": config["gondor.site_key"], } try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.HTTPError, e: api_error(e)
def cmd_open(args, env, config): url = "%s/instance/detail/" % config["gondor.endpoint"] params = { "version": __version__, "site_key": config["gondor.site_key"], "label": args.label[0], } url += "?%s" % urllib.urlencode(params) try: response = make_api_call(config, url) except urllib2.HTTPError, e: api_error(e)
def cmd_dashboard(args, env, config): params = { "version": __version__, "site_key": config["gondor.site_key"], } if args.label: url = "%s/instance/detail/" % config["gondor.endpoint"] params["label"] = args.label else: url = "%s/site/detail/" % config["gondor.endpoint"] url += "?%s" % urllib.urlencode(params) try: response = make_api_call(config, url) except urllib2.HTTPError, e: api_error(e)
def cmd_sqldump(args, env, config): label = args.label[0] # request SQL dump and stream the response through uncompression err("Dumping database... ") url = "%s/sqldump/" % config["gondor.endpoint"] params = { "version": __version__, "site_key": config["gondor.site_key"], "label": label, } try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.HTTPError, e: api_error(e)
def cmd_create(args, config): gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") label = args.label[0] kind = args.kind if kind is None: kind = "dev" try: repo_root = utils.find_nearest(os.getcwd(), ".git") except OSError: try: repo_root = utils.find_nearest(os.getcwd(), ".hg") except OSError: error("unable to find a supported version control directory. Looked for .git and .hg.\n") else: vcs = "hg" else: vcs = "git" out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") out("[ok]\n") text = "Creating instance on Gondor... " url = "%s/create/" % endpoint params = { "version": __version__, "site_key": site_key, "label": label, "kind": kind, "project_root": os.path.basename(project_root), } try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.HTTPError, e: out("\nReceived an error [%d: %s]" % (e.code, e.read())) sys.exit(1)
def cmd_env_set(args, env, config): url = "%s/site/env/" % config["gondor.endpoint"] bits = args.bits params = [ ("version", __version__), ("site_key", config["gondor.site_key"]), ] # api will reject the else case if bits: if "=" in bits[0]: # set var(s) on site params.extend([("variable", v) for v in bits]) else: # set var(s) on instance params.append(("label", bits[0])) params.extend([("variable", v) for v in bits[1:]]) try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.HTTPError, e: api_error(e)
def cmd_create(args, config): gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") label = args.label[0] kind = args.kind if kind is None: kind = "dev" out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") out("[ok]\n") text = "Creating instance on Gondor... " url = "%s/create/" % endpoint params = { "version": __version__, "site_key": site_key, "label": label, "kind": kind, "project_root": os.path.basename(project_root), } response = make_api_call(config, url, urllib.urlencode(params)) data = json.loads(response.read()) if data["status"] == "error": message = "error" elif data["status"] == "success": message = "ok" else: message = "unknown" out("\r%s[%s] \n" % (text, message)) if data["status"] == "success": out("\nRun: gondor deploy %s HEAD" % label) out("\nVisit: %s\n" % data["url"]) else: error("%s\n" % data["message"])
def cmd_delete(args, config): instance_label = args.label[0] gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") out("[ok]\n") text = "ARE YOU SURE YOU WANT TO DELETE THIS INSTANCE? [Y/N] " out(text) user_input = raw_input() if user_input != "Y": out("Exiting without deleting the instance.\n") sys.exit(0) text = "Deleting... " url = "%s/delete/" % endpoint params = { "version": __version__, "site_key": site_key, "instance_label": instance_label, } response = make_api_call(config, url, urllib.urlencode(params)) data = json.loads(response.read()) if data["status"] == "error": message = "error" elif data["status"] == "success": message = "ok" else: message = "unknown" out("\r%s[%s] \n" % (text, message)) if data["status"] == "error": error("%s\n" % data["message"])
def cmd_create(args, env, config): label = args.label[0] kind = args.kind if kind is None: kind = "dev" text = "Creating instance on Gondor... " url = "%s/create/" % config["gondor.endpoint"] params = { "version": __version__, "site_key": config["gondor.site_key"], "label": label, "kind": kind, "project_root": os.path.basename(env["project_root"]), } try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.HTTPError, e: api_error(e)
def cmd_delete(args, env, config): instance_label = args.label[0] text = "ARE YOU SURE YOU WANT TO DELETE THIS INSTANCE? [Y/N] " out(text) user_input = raw_input() if user_input != "Y": out("Exiting without deleting the instance.\n") sys.exit(0) text = "Deleting... " url = "%s/delete/" % config["gondor.endpoint"] params = { "version": __version__, "site_key": config["gondor.site_key"], "instance_label": instance_label, } try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.HTTPError, e: api_error(e)
def cmd_env(args, env, config): url = "%s/site/env/" % config["gondor.endpoint"] bits = args.bits params = [ ("version", __version__), ("site_key", config["gondor.site_key"]), ] if args.scoped: params.append(("scoped", "1")) # default case is to get all vars on site if bits: # check if bits[0] is upper-case; if so we know it is not an instance # label if bits[0].isupper(): # get explicit var(s) on site params.extend([("key", k) for k in bits]) else: # get var(s) on instance params.append(("label", bits[0])) params.extend([("key", k) for k in bits[1:]]) url += "?%s" % urllib.urlencode(params) try: response = make_api_call(config, url) except urllib2.HTTPError, e: api_error(e)
def cmd_list(args, config): gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") out("[ok]\n") url = "%s/list/" % endpoint params = { "version": __version__, "site_key": site_key, } response = make_api_call(config, url, urllib.urlencode(params)) data = json.loads(response.read()) if data["status"] == "success": out("\n") instances = sorted(data["instances"], key=lambda v: v["label"]) if instances: for instance in instances: out("%s [%s] %s\n" % ( instance["label"], instance["kind"], instance["last_deployment"]["sha"][:8] )) else: out("No instances found.\n") else: error("%s\n" % data["message"])
def cmd_run(args, env, config): instance_label = args.instance_label[0] command = args.command_ if args.detached: err("Spawning... ") else: err("Attaching... ") url = "%s/instance/run/" % config["gondor.endpoint"] params = { "version": __version__, "site_key": config["gondor.site_key"], "instance_label": instance_label, "project_root": os.path.relpath(env["project_root"], env["repo_root"]), "detached": {True: "true", False: "false"}[args.detached], "command": " ".join(command), "app": json.dumps(config["app"]), } if sys.platform == "win32": params["term"] = "win32" if "TERM" in os.environ: try: params.update({ "tc": utils.check_output(["tput", "cols"]).strip(), "tl": utils.check_output(["tput", "lines"]).strip(), }) except (OSError, subprocess.CalledProcessError): # if the above fails then no big deal; we just can't set correct # terminal info so it will default some common values pass try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.HTTPError, e: err("[failed]\n") api_error(e)
def cmd_run(args, env, config): instance_label = args.instance_label[0] command = args.command_[0] cmdargs = args.cmdargs params = {"cmdargs": cmdargs} if command == "createsuperuser": try: # Get a username while 1: username = raw_input("Username: "******"Error: That username is invalid. Use only letters, digits and underscores.\n") username = None continue break # Get an email while 1: email = raw_input("Email address: ") if not EMAIL_RE.search(email): sys.stderr.write("Error: That email address is invalid.\n") email = None else: break # Get a password while 1: password = getpass.getpass() password2 = getpass.getpass("Password (again): ") if password != password2: sys.stderr.write("Error: Your passwords didn't match.\n") password = None continue if password.strip() == "": sys.stderr.write("Error: Blank passwords aren't allowed.\n") password = None continue break except KeyboardInterrupt: sys.stderr.write("\nOperation cancelled.\n") sys.exit(1) params = { "username": username, "email": email, "password": password, } out("Executing... ") url = "%s/run/" % config["gondor.endpoint"] params = { "version": __version__, "site_key": config["gondor.site_key"], "instance_label": instance_label, "project_root": os.path.relpath(env["project_root"], env["repo_root"]), "command": command, "params": json.dumps(params), "app": json.dumps(config["app"]), } try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.HTTPError, e: api_error(e)
def cmd_deploy(args, config): label = args.label[0] commit = args.commit[0] gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") tarball = None try: out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") vcs = local_config.get("gondor", "vcs") app_config = { "requirements_file": config_value(local_config, "app", "requirements_file"), "wsgi_entry_point": config_value(local_config, "app", "wsgi_entry_point"), "migrations": config_value(local_config, "app", "migrations"), } out("[ok]\n") if vcs == "git": try: repo_root = utils.find_nearest(os.getcwd(), ".git") except OSError: error("unable to find a .git directory.\n") sha = utils.check_output("git rev-parse %s" % commit).strip() if commit == "HEAD": commit = sha tarball = os.path.abspath( os.path.join(repo_root, "%s-%s.tar" % (label, sha))) git_archive_all.archive_git(tarball, 'tar', repo_root) cmd = "(cd %s && gzip %s)" % (repo_root, tarball) tarball += '.gz' elif vcs == "hg": try: repo_root = utils.find_nearest(os.getcwd(), ".hg") except OSError: error("unable to find a .hg directory.\n") branches_stdout = utils.check_output("hg branches") tags_stdout = utils.check_output("hg tags") refs = {} for line in branches_stdout.splitlines() + tags_stdout.splitlines( ): m = re.search(r"([\w\d\.-]+)\s*([\d]+):([\w]+)$", line) if m: refs[m.group(1)] = m.group(3) try: sha = refs[commit] except KeyError: error("could not map '%s' to a SHA\n" % commit) tarball = os.path.abspath( os.path.join(repo_root, "%s-%s.tar.gz" % (label, sha))) cmd = "(cd %s && hg archive -p . -t tgz -r %s %s)" % ( repo_root, commit, tarball) else: error("'%s' is not a valid version control system for Gondor\n" % vcs) out("Building tarball from %s... " % commit) subprocess.call([cmd], shell=True) out("[ok]\n") pb = ProgressBar(0, 100, 77) out("Pushing tarball to Gondor... \n") url = "%s/deploy/" % endpoint params = { "version": __version__, "site_key": site_key, "label": label, "sha": sha, "commit": commit, "tarball": open(tarball, "rb"), "project_root": os.path.relpath(project_root, repo_root), "app": json.dumps(app_config), } handlers = [ http.MultipartPostHandler, http.UploadProgressHandler(pb, ssl=True), http.UploadProgressHandler(pb, ssl=False) ] try: response = make_api_call(config, url, params, extra_handlers=handlers) except KeyboardInterrupt: out("\nCanceling uploading... [ok]\n") sys.exit(1) else: out("\n") data = json.loads(response.read()) finally: if tarball: os.unlink(tarball) if data["status"] == "error": error("%s\n" % data["message"]) if data["status"] == "success": deployment_id = data["deployment"] if "url" in data: instance_url = data["url"] else: instance_url = None # poll status of the deployment out("Deploying... ") while True: params = { "version": __version__, "site_key": site_key, "instance_label": label, "task_id": deployment_id, } url = "%s/task_status/" % endpoint try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.URLError: # @@@ add max retries continue data = json.loads(response.read()) if data["status"] == "error": out("[error]\n") error("%s\n" % data["message"]) if data["status"] == "success": if data["state"] == "deployed": out("[ok]\n") if instance_url: out("\nVisit: %s\n" % instance_url) break elif data["state"] == "failed": out("[failed]\n") out("\n%s\n" % data["reason"]) sys.exit(1) elif data["state"] == "locked": out("[locked]\n") out("\nYour deployment failed due to being locked. This means there is another deployment already in progress.\n" ) sys.exit(1) else: time.sleep(2)
def cmd_run(args, config): instance_label = args.instance_label[0] command = args.command_[0] cmdargs = args.cmdargs params = {"cmdargs": cmdargs} gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") vcs = local_config.get("gondor", "vcs") app_config = { "requirements_file": config_value(local_config, "app", "requirements_file"), "wsgi_entry_point": config_value(local_config, "app", "wsgi_entry_point"), "migrations": config_value(local_config, "app", "migrations"), "staticfiles": config_value(local_config, "app", "staticfiles"), } out("[ok]\n") if vcs == "git": try: repo_root = utils.find_nearest(os.getcwd(), ".git") except OSError: error("unable to find a .git directory.\n") elif vcs == "hg": try: repo_root = utils.find_nearest(os.getcwd(), ".hg") except OSError: error("unable to find a .hg directory.\n") else: error("'%s' is not a valid version control system for Gondor\n" % vcs) if command == "createsuperuser": try: # Get a username while 1: username = raw_input("Username: "******"Error: That username is invalid. Use only letters, digits and underscores.\n") username = None continue break # Get an email while 1: email = raw_input("Email address: ") if not EMAIL_RE.search(email): sys.stderr.write("Error: That email address is invalid.\n") email = None else: break # Get a password while 1: password = getpass.getpass() password2 = getpass.getpass("Password (again): ") if password != password2: sys.stderr.write("Error: Your passwords didn't match.\n") password = None continue if password.strip() == "": sys.stderr.write("Error: Blank passwords aren't allowed.\n") password = None continue break except KeyboardInterrupt: sys.stderr.write("\nOperation cancelled.\n") sys.exit(1) params = { "username": username, "email": email, "password": password, } out("Executing... ") url = "%s/run/" % endpoint params = { "version": __version__, "site_key": site_key, "instance_label": instance_label, "project_root": os.path.relpath(project_root, repo_root), "command": command, "params": json.dumps(params), "app": json.dumps(app_config), } try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.HTTPError, e: out("\nReceived an error [%d: %s]" % (e.code, e.read())) sys.exit(1)
def cmd_sqldump(args, config): label = args.label[0] gondor_dirname = ".gondor" repo_root = utils.find_nearest(os.getcwd(), gondor_dirname) local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(repo_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") # request SQL dump and stream the response through uncompression err("Dumping database... ") url = "%s/sqldump/" % endpoint params = { "version": __version__, "site_key": site_key, "label": label, } response = make_api_call(config, url, urllib.urlencode(params)) data = json.loads(response.read()) if data["status"] == "error": error("%s\n" % data["message"]) if data["status"] == "success": task_id = data["task"] while True: params = { "version": __version__, "site_key": site_key, "instance_label": label, "task_id": task_id, } url = "%s/task_status/" % endpoint try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.URLError: # @@@ add max retries continue data = json.loads(response.read()) if data["status"] == "error": err("[error]\n") error("%s\n" % data["message"]) if data["status"] == "success": if data["state"] == "finished": err("[ok]\n") break elif data["state"] == "failed": err("[failed]\n") err("\n%s\n" % data["reason"]) sys.exit(1) elif data["state"] == "locked": err("[locked]\n") err("\nYour database dump failed due to being locked. " "This means there is another database dump already " "in progress.\n") sys.exit(1) else: time.sleep(2) d = zlib.decompressobj(16 + zlib.MAX_WBITS) cs = 16 * 1024 response = urllib2.urlopen(data["result"]["public_url"]) while True: chunk = response.read(cs) if not chunk: break out(d.decompress(chunk))
def cmd_deploy(args, config): label = args.label[0] commit = args.commit[0] gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") tar_path, tarball_path = None, None try: out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") vcs = local_config.get("gondor", "vcs") app_config = { "requirements_file": config_value(local_config, "app", "requirements_file"), "wsgi_entry_point": config_value(local_config, "app", "wsgi_entry_point"), "migrations": config_value(local_config, "app", "migrations"), "staticfiles": config_value(local_config, "app", "staticfiles"), } include_files = [ x.strip() for x in config_value(local_config, "files", "include", "").split("\n") if x ] out("[ok]\n") if vcs == "git": try: repo_root = utils.find_nearest(os.getcwd(), ".git") except OSError: error("unable to find a .git directory.\n") check, sha = utils.run_proc(["git", "rev-parse", commit]) if check != 0: error("could not map '%s' to a SHA\n" % commit) if commit == "HEAD": commit = sha tar_path = os.path.abspath(os.path.join(repo_root, "%s-%s.tar" % (label, sha))) cmd = ["git", "archive", "--format=tar", commit, "-o", tar_path] elif vcs == "hg": try: repo_root = utils.find_nearest(os.getcwd(), ".hg") except OSError: error("unable to find a .hg directory.\n") branches_stdout = utils.run_proc(["hg", "branches"])[1] tags_stdout = utils.run_proc(["hg", "tags"])[1] refs = {} for line in branches_stdout.splitlines() + tags_stdout.splitlines(): m = re.search(r"([\w\d\.-]+)\s*([\d]+):([\w]+)$", line) if m: refs[m.group(1)] = m.group(3) try: sha = refs[commit] except KeyError: error("could not map '%s' to a SHA\n" % commit) tar_path = os.path.abspath(os.path.join(repo_root, "%s-%s.tar" % (label, sha))) cmd = ["hg", "archive", "-p", ".", "-t", "tar", "-r", commit, tar_path] else: error("'%s' is not a valid version control system for Gondor\n" % vcs) out("Archiving code from %s... " % commit) check, output = utils.run_proc(cmd, cwd=repo_root) if check != 0: error(output) out("[ok]\n") if include_files: out("Adding untracked files... ") try: tar_fp = tarfile.open(tar_path, "a") for f in include_files: tar_fp.add(os.path.abspath(os.path.join(repo_root, f)), arcname=f) finally: tar_fp.close() out("[ok]\n") tarball_path = os.path.abspath(os.path.join(repo_root, "%s-%s.tar.gz" % (label, sha))) out("Building tarball... ") with open(tar_path, "rb") as tar_fp: try: tarball = gzip.open(tarball_path, mode="wb") tarball.writelines(tar_fp) finally: tarball.close() out("[ok]\n") pb = ProgressBar(0, 100, 77) out("Pushing tarball to Gondor... \n") url = "%s/deploy/" % endpoint with open(tarball_path, "rb") as tarball: params = { "version": __version__, "site_key": site_key, "label": label, "sha": sha, "commit": commit, "tarball": tarball, "project_root": os.path.relpath(project_root, repo_root), "app": json.dumps(app_config), } handlers = [ http.MultipartPostHandler, http.UploadProgressHandler(pb, ssl=True), http.UploadProgressHandler(pb, ssl=False) ] try: response = make_api_call(config, url, params, extra_handlers=handlers) except KeyboardInterrupt: out("\nCanceling uploading... [ok]\n") sys.exit(1) except urllib2.HTTPError, e: out("\nReceived an error [%d: %s]" % (e.code, e.read())) sys.exit(1) else:
def cmd_run(args, config): instance_label = args.instance_label[0] command = args.command_[0] cmdargs = args.cmdargs params = {"cmdargs": cmdargs} gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") vcs = local_config.get("gondor", "vcs") app_config = { "requirements_file": config_value(local_config, "app", "requirements_file"), "wsgi_entry_point": config_value(local_config, "app", "wsgi_entry_point"), "migrations": config_value(local_config, "app", "migrations"), } out("[ok]\n") if vcs == "git": try: repo_root = utils.find_nearest(os.getcwd(), ".git") except OSError: error("unable to find a .git directory.\n") elif vcs == "hg": try: repo_root = utils.find_nearest(os.getcwd(), ".hg") except OSError: error("unable to find a .hg directory.\n") else: error("'%s' is not a valid version control system for Gondor\n" % vcs) if command == "createsuperuser": try: # Get a username while 1: username = raw_input("Username: "******"Error: That username is invalid. Use only letters, digits and underscores.\n" ) username = None continue break # Get an email while 1: email = raw_input("Email address: ") if not EMAIL_RE.search(email): sys.stderr.write("Error: That email address is invalid.\n") email = None else: break # Get a password while 1: password = getpass.getpass() password2 = getpass.getpass("Password (again): ") if password != password2: sys.stderr.write("Error: Your passwords didn't match.\n") password = None continue if password.strip() == "": sys.stderr.write( "Error: Blank passwords aren't allowed.\n") password = None continue break except KeyboardInterrupt: sys.stderr.write("\nOperation cancelled.\n") sys.exit(1) params = { "username": username, "email": email, "password": password, } out("Executing... ") url = "%s/run/" % endpoint params = { "version": __version__, "site_key": site_key, "instance_label": instance_label, "project_root": os.path.relpath(project_root, repo_root), "command": command, "params": json.dumps(params), "app": json.dumps(app_config), } response = make_api_call(config, url, urllib.urlencode(params)) data = json.loads(response.read()) if data["status"] == "error": out("[error]\n") error("%s\n" % data["message"]) if data["status"] == "success": task_id = data["task"] while True: params = { "version": __version__, "site_key": site_key, "instance_label": instance_label, "task_id": task_id, } url = "%s/task_status/" % endpoint response = make_api_call(config, url, urllib.urlencode(params)) data = json.loads(response.read()) if data["status"] == "error": out("[error]\n") out("\nError: %s\n" % data["message"]) if data["status"] == "success": if data["state"] == "executed": out("[ok]\n") out("\n%s" % data["result"]["output"]) break elif data["state"] == "failed": out("[failed]\n") out("\n%s\n" % data["reason"]) sys.exit(1) elif data["state"] == "locked": out("[locked]\n") out("\nYour execution failed due to being locked. This means there is another execution already in progress.\n" ) sys.exit(1) else: time.sleep(2)
instance_url = data["url"] else: instance_url = None # poll status of the deployment out("Deploying... ") while True: params = { "version": __version__, "site_key": site_key, "instance_label": label, "task_id": deployment_id, } url = "%s/task_status/" % endpoint try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.URLError: # @@@ add max retries continue data = json.loads(response.read()) if data["status"] == "error": out("[error]\n") error("%s\n" % data["message"]) if data["status"] == "success": if data["state"] == "deployed": out("[ok]\n") if instance_url: out("\nVisit: %s\n" % instance_url) break elif data["state"] == "failed": out("[failed]\n")
def cmd_manage(args, config): instance_label = args.label[0] operation = args.operation[0] opargs = args.opargs gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") out("[ok]\n") url = "%s/manage/" % endpoint params = { "version": __version__, "site_key": site_key, "instance_label": instance_label, "operation": operation, } handlers = [ http.MultipartPostHandler, ] if not sys.stdin.isatty(): params["stdin"] = sys.stdin pb = ProgressBar(0, 100, 77) out("Pushing stdin to Gondor... \n") handlers.extend([ http.UploadProgressHandler(pb, ssl=True), http.UploadProgressHandler(pb, ssl=False) ]) params = params.items() for oparg in opargs: params.append(("arg", oparg)) response = make_api_call(config, url, params, extra_handlers=handlers) if not sys.stdin.isatty(): out("\n") out("Running... ") data = json.loads(response.read()) if data["status"] == "error": out("[error]\n") error("%s\n" % data["message"]) if data["status"] == "success": task_id = data["task"] while True: params = { "version": __version__, "site_key": site_key, "instance_label": instance_label, "task_id": task_id, } url = "%s/task_status/" % endpoint response = make_api_call(config, url, urllib.urlencode(params)) data = json.loads(response.read()) if data["status"] == "error": out("[error]\n") out("\nError: %s\n" % data["message"]) if data["status"] == "success": if data["state"] == "finished": out("[ok]\n") break elif data["state"] == "failed": out("[failed]\n") out("\n%s\n" % data["reason"]) sys.exit(1) elif data["state"] == "locked": out("[locked]\n") out("\nYour task failed due to being locked. This means there is another task already in progress.\n") sys.exit(1) else: time.sleep(2)
def cmd_manage(args, config): instance_label = args.label[0] operation = args.operation[0] opargs = args.opargs gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") out("[ok]\n") url = "%s/manage/" % endpoint params = { "version": __version__, "site_key": site_key, "instance_label": instance_label, "operation": operation, } handlers = [ http.MultipartPostHandler, ] if not sys.stdin.isatty(): params["stdin"] = sys.stdin pb = ProgressBar(0, 100, 77) out("Pushing stdin to Gondor... \n") handlers.extend([ http.UploadProgressHandler(pb, ssl=True), http.UploadProgressHandler(pb, ssl=False) ]) params = params.items() for oparg in opargs: params.append(("arg", oparg)) response = make_api_call(config, url, params, extra_handlers=handlers) if not sys.stdin.isatty(): out("\n") out("Running... ") data = json.loads(response.read()) if data["status"] == "error": out("[error]\n") error("%s\n" % data["message"]) if data["status"] == "success": task_id = data["task"] while True: params = { "version": __version__, "site_key": site_key, "instance_label": instance_label, "task_id": task_id, } url = "%s/task_status/" % endpoint response = make_api_call(config, url, urllib.urlencode(params)) data = json.loads(response.read()) if data["status"] == "error": out("[error]\n") out("\nError: %s\n" % data["message"]) if data["status"] == "success": if data["state"] == "finished": out("[ok]\n") break elif data["state"] == "failed": out("[failed]\n") out("\n%s\n" % data["reason"]) sys.exit(1) elif data["state"] == "locked": out("[locked]\n") out("\nYour task failed due to being locked. This means there is another task already in progress.\n" ) sys.exit(1) else: time.sleep(2)
"version": __version__, "site_key": config["gondor.site_key"], "label": label, "sha": sha, "commit": commit, "tarball": tarball, "project_root": os.path.relpath(env["project_root"], env["repo_root"]), "app": json.dumps(config["app"]), } handlers = [ http.MultipartPostHandler, http.UploadProgressHandler(pb, ssl=True), http.UploadProgressHandler(pb, ssl=False) ] try: response = make_api_call(config, url, params, extra_handlers=handlers) except KeyboardInterrupt: out("\nCanceling uploading... [ok]\n") sys.exit(1) except urllib2.HTTPError, e: api_error(e) else: out("\n") data = json.loads(response.read()) finally: if tar_path and os.path.exists(tar_path): os.unlink(tar_path) if tarball_path and os.path.exists(tarball_path): os.unlink(tarball_path)
def cmd_sqldump(args, config): label = args.label[0] gondor_dirname = ".gondor" repo_root = utils.find_nearest(os.getcwd(), gondor_dirname) local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(repo_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") # request SQL dump and stream the response through uncompression err("Dumping database... ") url = "%s/sqldump/" % endpoint params = { "version": __version__, "site_key": site_key, "label": label, } response = make_api_call(config, url, urllib.urlencode(params)) data = json.loads(response.read()) if data["status"] == "error": error("%s\n" % data["message"]) if data["status"] == "success": task_id = data["task"] while True: params = { "version": __version__, "site_key": site_key, "instance_label": label, "task_id": task_id, } url = "%s/task_status/" % endpoint try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.URLError: # @@@ add max retries continue data = json.loads(response.read()) if data["status"] == "error": err("[error]\n") error("%s\n" % data["message"]) if data["status"] == "success": if data["state"] == "finished": err("[ok]\n") break elif data["state"] == "failed": err("[failed]\n") err("\n%s\n" % data["reason"]) sys.exit(1) elif data["state"] == "locked": err("[locked]\n") err("\nYour database dump failed due to being locked. " "This means there is another database dump already " "in progress.\n") sys.exit(1) else: time.sleep(2) d = zlib.decompressobj(16+zlib.MAX_WBITS) cs = 16 * 1024 response = urllib2.urlopen(data["result"]["public_url"]) while True: chunk = response.read(cs) if not chunk: break out(d.decompress(chunk))
def cmd_deploy(args, config): label = args.label[0] commit = args.commit[0] gondor_dirname = ".gondor" try: project_root = utils.find_nearest(os.getcwd(), gondor_dirname) except OSError: error("unable to find a .gondor directory.\n") tarball = None try: out("Reading configuration... ") local_config = ConfigParser.RawConfigParser() local_config.read(os.path.join(project_root, gondor_dirname, "config")) endpoint = config_value(local_config, "gondor", "endpoint", DEFAULT_ENDPOINT) site_key = local_config.get("gondor", "site_key") vcs = local_config.get("gondor", "vcs") app_config = { "requirements_file": config_value(local_config, "app", "requirements_file"), "wsgi_entry_point": config_value(local_config, "app", "wsgi_entry_point"), "migrations": config_value(local_config, "app", "migrations"), } out("[ok]\n") if vcs == "git": try: repo_root = utils.find_nearest(os.getcwd(), ".git") except OSError: error("unable to find a .git directory.\n") sha = utils.check_output("git rev-parse %s" % commit).strip() if commit == "HEAD": commit = sha tarball = os.path.abspath(os.path.join(repo_root, "%s-%s.tar" % (label, sha))) git_archive_all.archive_git(tarball,'tar',repo_root) cmd = "(cd %s && gzip %s)" % (repo_root, tarball) tarball += '.gz' elif vcs == "hg": try: repo_root = utils.find_nearest(os.getcwd(), ".hg") except OSError: error("unable to find a .hg directory.\n") branches_stdout = utils.check_output("hg branches") tags_stdout = utils.check_output("hg tags") refs = {} for line in branches_stdout.splitlines() + tags_stdout.splitlines(): m = re.search(r"([\w\d\.-]+)\s*([\d]+):([\w]+)$", line) if m: refs[m.group(1)] = m.group(3) try: sha = refs[commit] except KeyError: error("could not map '%s' to a SHA\n" % commit) tarball = os.path.abspath(os.path.join(repo_root, "%s-%s.tar.gz" % (label, sha))) cmd = "(cd %s && hg archive -p . -t tgz -r %s %s)" % (repo_root, commit, tarball) else: error("'%s' is not a valid version control system for Gondor\n" % vcs) out("Building tarball from %s... " % commit) subprocess.call([cmd], shell=True) out("[ok]\n") pb = ProgressBar(0, 100, 77) out("Pushing tarball to Gondor... \n") url = "%s/deploy/" % endpoint params = { "version": __version__, "site_key": site_key, "label": label, "sha": sha, "commit": commit, "tarball": open(tarball, "rb"), "project_root": os.path.relpath(project_root, repo_root), "app": json.dumps(app_config), } handlers = [ http.MultipartPostHandler, http.UploadProgressHandler(pb, ssl=True), http.UploadProgressHandler(pb, ssl=False) ] try: response = make_api_call(config, url, params, extra_handlers=handlers) except KeyboardInterrupt: out("\nCanceling uploading... [ok]\n") sys.exit(1) else: out("\n") data = json.loads(response.read()) finally: if tarball: os.unlink(tarball) if data["status"] == "error": error("%s\n" % data["message"]) if data["status"] == "success": deployment_id = data["deployment"] if "url" in data: instance_url = data["url"] else: instance_url = None # poll status of the deployment out("Deploying... ") while True: params = { "version": __version__, "site_key": site_key, "instance_label": label, "task_id": deployment_id, } url = "%s/task_status/" % endpoint try: response = make_api_call(config, url, urllib.urlencode(params)) except urllib2.URLError: # @@@ add max retries continue data = json.loads(response.read()) if data["status"] == "error": out("[error]\n") error("%s\n" % data["message"]) if data["status"] == "success": if data["state"] == "deployed": out("[ok]\n") if instance_url: out("\nVisit: %s\n" % instance_url) break elif data["state"] == "failed": out("[failed]\n") out("\n%s\n" % data["reason"]) sys.exit(1) elif data["state"] == "locked": out("[locked]\n") out("\nYour deployment failed due to being locked. This means there is another deployment already in progress.\n") sys.exit(1) else: time.sleep(2)