def launch_ssh_cloudflared(password="",
                           verbose=False,
                           kill_other_processes=False):

    # Kill any cloudflared process if running
    if kill_other_processes:
        os.system("kill -9 $(ps aux | grep 'cloudflared' | awk '{print $2}')")

    # Download cloudflared
    if not os.path.isfile("cloudflared"):
        run_command(
            "wget -q -nc https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-amd64.tgz"
        )
        run_command("tar zxf cloudflared-stable-linux-amd64.tgz")
    else:
        if verbose:
            print("DEBUG: Skipping cloudflared installation")

    # Install the openssh server
    deb_install("openssh-server", verbose=verbose)

    # Set the password
    run_with_pipe("echo root:{} | chpasswd".format(password))

    # Configure the openSSH server
    run_command("mkdir -p /var/run/sshd")
    os.system("echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config")
    if password:
        os.system('echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config')

    expose_env_variable("LD_LIBRARY_PATH")
    expose_env_variable("COLAB_TPU_ADDR")
    expose_env_variable("COLAB_GPU")
    expose_env_variable("TBE_CREDS_ADDR")
    expose_env_variable("TF_FORCE_GPU_ALLOW_GROWTH")
    expose_env_variable("TPU_NAME")
    expose_env_variable("XRT_TPU_CONFIG")

    os.system('service ssh start')

    extra_params = []
    info = None
    # Create tunnel and retry if failed
    for i in range(10):
        proc = Popen(shlex.split(
            f'./cloudflared tunnel --url ssh://localhost:22 --logfile ./cloudflared.log --metrics localhost:45678 {" ".join(extra_params)}'
        ),
                     stdout=PIPE)
        if verbose:
            print(f"Cloudflared process: PID={proc.pid}")
        time.sleep(3)
        try:
            info = get_argo_tunnel_config()
            break
        except:
            os.kill(proc.pid, signal.SIGKILL)
            if verbose:
                print(f"DEBUG: Killing {proc.pid}. Retrying again ...")
            continue

    if verbose:
        print("DEBUG:", info)

    if info:
        # print("Successfully running on ", "{}:{}".format(host, port))
        if importlib.util.find_spec("IPython") and 'ipykernel' in sys.modules:
            from IPython.display import display, HTML
            display(HTML(render_template("launch_ssh_cloudflared.html", info)))
        else:
            print(
                "Now, you need to setup your client machine by following these steps:"
            )
            print("""
    1) Download Cloudflared (Argo Tunnel) from https://developers.cloudflare.com/argo-tunnel/getting-started/installation, then copy the absolute path to the cloudflare binary.
    2) Append the following to your SSH config file (usually under ~/.ssh/config):

        Host *.trycloudflare.com
            HostName %h
            User root
            Port 22
            ProxyCommand <PUT_THE_ABSOLUTE_CLOUDFLARE_PATH_HERE> access ssh --hostname %h

*) Connect with SSH Terminal
    To connect using your terminal, type this command: 
        ssh {domain}

*) Connect with VSCode Remote SSH
    You can also connect with VSCode Remote SSH (Ctrl+Shift+P and type "Connect to Host..."). Then, paste the following hostname in the opened command palette:
        {domain}
""".format(**info))

    #     print("[Optional] You can also connect with VSCode SSH Remote extension by:")
    #     print(f"""
    # 1. Set the following configuration into your SSH config file (~/.ssh/config):

    #     Host *.trycloudflare.com
    #         HostName %h
    #         User root
    #         Port {port}
    #         ProxyCommand <PUT_THE_ABSOLUTE_CLOUDFLARE_PATH_HERE> access ssh --hostname %h

    # 2. Connect to Remote SSH on VSCode (Ctrl+Shift+P and type "Connect to Host...") and paste this hostname:
    #     {host}
    #     """)
    #     print(f'''

    #   ''')
    else:
        print(proc.stdout.readlines())
        raise Exception(
            "It looks like something went wrong, please make sure your token is valid"
        )
    proc.stdout.close()
Example #2
0
def init_git_cloudflared(repositoryUrl,
                         branch="",
                         personal_token="",
                         email=None,
                         username=None,
                         verbose=False):
    # Add the Personal access token if available
    full_url = repositoryUrl.replace(
        "github.com", personal_token +
        "@github.com") if personal_token else repositoryUrl

    if not personal_token:
        response = requests.get(full_url)
        if response.status_code == 200:
            logger.info("✔️ Public repository")
        else:
            # Get username if not passed
            username_input = input(
                "Enter your username: (leave it empty if it's '{}')\n".format(
                    username))
            username = quote(username_input or username)
            # Get password
            from getpass import getpass
            password = quote(getpass('Enter your password: \n'))
            if password:
                full_url = repositoryUrl.replace(
                    "github.com",
                    "{}:{}@github.com".format(username, password))

    # Clone the repository then add the folder to the sys.path
    _run_command(
        "git clone {} {}".format(
            # Branch argument
            "--branch {}".format(branch) if branch else "",
            # Url argument
            full_url),
        callback=parse_cloning_output)

    repo_name = os.path.basename(repositoryUrl)
    repo_name, _ = os.path.splitext(repo_name)

    # Checkout the branch
    os.system(f'cd {repo_name}')

    # Make sure that even if the repository is public, the personal token is still in the origin remote url
    if personal_token:
        os.system("git remote set-url origin {}".format(full_url))

    # Add the email and username
    if email: os.system('git config --global user.email "{}"'.format(email))
    if username:
        os.system('git config --global user.name "{}"'.format(username))

    # Bring the public key from the repository and paste it in the authorized_keys
    os.system(
        "mkdir -p ~/.ssh && curl -s -L -f {} {}/{}/.colab_ssh/authorized_keys >> ~/.ssh/authorized_keys"
        .format(("-H 'Authorization: token {}'".format(personal_token))
                if personal_token else "",
                repositoryUrl.split(".git")[0].replace(
                    "github.com", "raw.githubusercontent.com"), branch))

    # Print the VSCode direct link
    try:
        output = get_argo_tunnel_config()
        link = f"vscode://vscode-remote/ssh-remote+root@{output['domain']}:{output['port']}{os.getcwd()}/{repo_name}"
        if importlib.util.find_spec("IPython") and 'ipykernel' in sys.modules:
            from IPython.display import HTML, display
            display(
                HTML(
                    render_template("init_git.html", {
                        **output, "link": link,
                        "repo_name": repo_name
                    })))


#       display(
#         HTML(
#           f"""[Optional] You can open the cloned folder using VSCode, by clicking
# <a href='{link}'>{repo_name}</a>
#           """
#         )
#       )
        else:
            # Support for terminal
            print(
                f"[Optional] You can open the cloned folder using VSCode, by going to this url:\n{link}"
            )
    except Exception as e:
        if verbose:
            print(e)