def run_hosted_deploy(app: App, pr_number: int): image = build_docker_image(app, pr_number) service_name = gen_service_name(app.name, pr_number) new(img=image, name=service_name, env=gen_env_variables(app, pr_number)) if pr_number == 0: for domain in app.config["first_party_domains"]: add_domain(name=service_name, domain=domain)
def initialize_sandbox(force=False): with db_lock("sandboxes", g.username): initialized = check_sandbox_initialized(g.username) if initialized and not force: raise Exception("Sandbox is already initialized") elif initialized: sh("rm", "-rf", get_working_directory(g.username)) Path(get_working_directory(g.username)).mkdir(parents=True, exist_ok=True) os.chdir(get_working_directory(g.username)) sh("git", "init") sh( "git", "fetch", "--depth=1", f"https://{get_secret(secret_name='GITHUB_ACCESS_TOKEN')}@github.com/{REPO}", "master", ) sh("git", "checkout", "FETCH_HEAD", "-f") os.mkdir("published") # needed for lazy-loading builds if is_prod_build(): add_domain(name="sandbox", domain=f"{g.username}.sb.cs61a.org") with connect_db() as db: db("UPDATE sandboxes SET initialized=TRUE WHERE username=%s", [g.username])
def start(): username = request.form.get("username") try: sh("id", "-u", username) user_exists = True except subprocess.CalledProcessError: user_exists = False if is_prod_build(): domain = f"{username}.{get_host()}" else: domain = f"{username}-{get_host()}" if not user_exists: print(f"User {username} doesn't exist, creating...", file=sys.stderr) sh("useradd", "-b", "/save", "-m", username, "-s", "/bin/bash") print( f"Proxying {domain} to {get_hosted_app_name()}...", file=sys.stderr, ) add_domain( name=get_hosted_app_name(), domain=domain, proxy_set_header={ "Host": "$host", "Upgrade": "$http_upgrade", "Connection": "upgrade", "Accept-Encoding": "gzip", }, ) sh("chown", "-R", username, f"/save/{username}") print("Home folder owner set.", file=sys.stderr) sh("mkdir", "-p", "/save/.cache") sh("chmod", "a+rw", "/save/.cache") if not get_server_pid(username): print(f"Server for {username} is not running, starting...", file=sys.stderr) with db_lock("ide", username): passwd = gen_salt(24) port = get_open_port() config = { "bind-addr": f"127.0.0.1:{port}", "auth": "password", "password": passwd, } with open(f"/save/{username}/.code-server.yaml", "w") as csc: yaml.dump(config, csc) sh("chown", "-R", username, f"/save/{username}/.code-server.yaml") print("Configuration ready.", file=sys.stderr) sanitized = os.environ.copy() del sanitized["DATABASE_URL"] del sanitized["APP_HOME"] del sanitized["APP_MASTER_SECRET"] del sanitized["ENV"] del sanitized["INSTANCE_CONNECTION_NAME"] sanitized["PORT"] = str(port) print("Environment sanitized.", file=sys.stderr) subprocess.Popen(get_server_cmd(username), env=sanitized) print("Subprocess opened.", file=sys.stderr) conf = Server( Location( "/", include="proxy_params", proxy_pass=f"http://127.0.0.1:{port}", proxy_set_header={ "Host": "$host", "Upgrade": "$http_upgrade", "Connection": "upgrade", "Accept-Encoding": "gzip", }, ), server_name=domain, listen=NGINX_PORT, error_page=f"502 https://{get_host()}", ) with open(f"/etc/nginx/sites-enabled/{domain}", "w") as f: f.write(str(conf)) sh("nginx", "-s", "reload") print("NGINX configuration written and server restarted.", file=sys.stderr) if not os.path.exists(f"/save/{username}/berkeley-cs61a"): print(f"Copy of repo for {username} not found.", file=sys.stderr) if os.path.exists("/save/root/berkeley-cs61a"): print("Found a known good repo, copying...", file=sys.stderr) shutil.copytree( "/save/root/berkeley-cs61a", f"/save/{username}/berkeley-cs61a", symlinks=True, ) print( "Tree copied. Writing Visual Studio Code associations...", file=sys.stderr, ) os.mkdir(f"/save/{username}/berkeley-cs61a/.vscode") with open(f"/save/{username}/berkeley-cs61a/.vscode/settings.json", "w") as f: f.write(VSCODE_ASSOC) print("Done.", file=sys.stderr) sh("chown", "-R", username, f"/save/{username}/berkeley-cs61a") print("Tree owner changed.", file=sys.stderr) print("Waiting for code-server to come alive, if needed...", file=sys.stderr) while requests.get(f"https://{domain}").status_code != 200: time.sleep(1) print("code-server is alive.", file=sys.stderr) print("IDE ready.", file=sys.stderr) return redirect(session.pop(SK_RETURN_TO, url_for("index")))
def start(): username = request.form.get("username") try: sh("id", "-u", username) user_exists = True except subprocess.CalledProcessError: user_exists = False if not user_exists: sh("useradd", "-b", "/save", "-m", username, "-s", "/bin/bash") add_domain( name=get_hosted_app_name(), domain=f"{username}.{get_host()}", proxy_set_header={ "Host": "$host", "Upgrade": "$http_upgrade", "Connection": "upgrade", "Accept-Encoding": "gzip", }, ) if not get_server_pid(username): with db_lock("ide", username): passwd = gen_salt(24) config = { "socket": f"/tmp/ide-{username}.sock", "auth": "password", "password": passwd, "home": f"https://{get_host()}", } with open(f"/save/{username}/.code-server.yaml", "w") as csc: yaml.dump(config, csc) sanitized = os.environ.copy() del sanitized["DATABASE_URL"] del sanitized["APP_HOME"] del sanitized["APP_MASTER_SECRET"] del sanitized["ENV"] del sanitized["INSTANCE_CONNECTION_NAME"] subprocess.Popen(get_server_cmd(username), env=sanitized) sh("sleep", "2") # give the server a couple of seconds to start up sh("chmod", "666", f"/tmp/ide-{username}.sock") conf = Server( Location( "/", include="proxy_params", proxy_pass=f"http://unix:/tmp/ide-{username}.sock", proxy_set_header={ "Host": "$host", "Upgrade": "$http_upgrade", "Connection": "upgrade", "Accept-Encoding": "gzip", }, ), server_name=f"{username}.{get_host()}", listen=NGINX_PORT, error_page=f"502 https://{get_host()}", ) with open(f"/etc/nginx/sites-enabled/{username}.{get_host()}", "w") as f: f.write(str(conf)) sh("nginx", "-s", "reload") if not os.path.exists(f"/save/{username}/berkeley-cs61a"): if os.path.exists("/save/berkeley-cs61a"): shutil.copytree( "/save/berkeley-cs61a", f"/save/{username}/berkeley-cs61a", symlinks=True, ) sh("chown", "-R", username, f"/save/{username}/berkeley-cs61a") return redirect(url_for("index"))