Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows remote development with SSH: SSH only set up for WSL #3662

Open
yw5aj opened this issue Jun 13, 2024 · 3 comments
Open

Windows remote development with SSH: SSH only set up for WSL #3662

yw5aj opened this issue Jun 13, 2024 · 3 comments

Comments

@yw5aj
Copy link

yw5aj commented Jun 13, 2024

Hi all,

First of all, thank you for the amazing tool!

I've been trying to use Sky Pilot with Windows and my set-up with WSL is all great. Except for that one thing: when I try to use it as a development cluster, the ssh is only set up with WSL. Therefore, when I open VS Code I cannot locate the set up SSH config because it's in its parent Windows environment, not WSL. Could anyone help share some guidance on this?

Best,
Shawn

@romilbhardwaj
Copy link
Collaborator

Hey @yw5aj - currently we don't have a good solution for supporting windows native ssh configs. A workaround could be to copy over the contents of the wsl:~/.sky/generated/ssh/* to your windows %USERPROFILE%\.ssh\config?

You may also need to copy over wsl:~/.ssh/sky-key to a location on your windows path and edit the IdentityFile path in your ssh config.

@yw5aj
Copy link
Author

yw5aj commented Jun 13, 2024

Thank you @romilbhardwaj ! It works well as you instructed. Got a script to do that in case it helps others in the future.

Would be wondering if Windows support would be in sight - this might be able to become slightly more elegant :)

import os
import subprocess
import shutil

def wsl_to_windows_path(wsl_path):
    """
    Convert a WSL path to a Windows path.
    """
    result = subprocess.run(['wsl', 'wslpath', '-w', wsl_path], stdout=subprocess.PIPE, text=True)
    return result.stdout.strip()

def copy_ssh_files_to_config(wsl_ssh_dir, windows_ssh_dir):
    """
    Copy non-hidden SSH files from WSL to a single config file in the Windows SSH directory.
    """
    try:
        if not os.path.exists(windows_ssh_dir):
            os.makedirs(windows_ssh_dir)

        wsl_files = subprocess.run(['wsl', 'ls', wsl_ssh_dir], stdout=subprocess.PIPE, text=True).stdout.split()
        config_path = os.path.join(windows_ssh_dir, 'config')

        with open(config_path, 'w') as config_file:
            for file_name in wsl_files:
                if not file_name.startswith('.'):
                    wsl_file_path = os.path.join(wsl_ssh_dir, file_name)
                    with open(wsl_to_windows_path(wsl_file_path), 'r') as file:
                        config_file.write(file.read())
                        config_file.write('\n')
        print("SSH files copied to config successfully.")
    except PermissionError as e:
        print(f"Permission error copying SSH files: {e}. Please ensure you have proper permissions.")
    except Exception as e:
        print(f"Error copying SSH files: {e}")

def update_ssh_config(windows_ssh_dir, identity_file):
    """
    Update the SSH config file to use the correct IdentityFile path.
    """
    try:
        config_path = os.path.join(windows_ssh_dir, 'config')
        if os.path.isfile(config_path):
            with open(config_path, 'r') as file:
                lines = file.readlines()

            with open(config_path, 'w') as file:
                for line in lines:
                    if line.strip().startswith('IdentityFile'):
                        file.write(f'  IdentityFile {identity_file}\n')
                    else:
                        file.write(line)
        print("SSH config file updated successfully.")
    except PermissionError as e:
        print(f"Permission error updating SSH config file: {e}. Please ensure you have proper permissions.")
    except Exception as e:
        print(f"Error updating SSH config file: {e}")

def copy_ssh_key_from_wsl(wsl_ssh_dir, windows_ssh_dir, key_file):
    """
    Copy the sky-key from WSL to Windows SSH directory.
    """
    try:
        wsl_key_path = os.path.join(wsl_ssh_dir, key_file)
        windows_key_path = os.path.join(windows_ssh_dir, key_file)
        if os.path.exists(windows_key_path):
            print(f"{key_file} already exists in {windows_ssh_dir}. Copy skipped.")
        else:
            shutil.copy(wsl_to_windows_path(wsl_key_path), windows_key_path)
            print("sky-key copied successfully.")
    except PermissionError as e:
        print(f"Permission error copying sky-key: {e}. Please ensure you have proper permissions.")
    except Exception as e:
        print(f"Error copying sky-key: {e}")

def set_permissions(identity_file):
    """
    Set correct permissions for the SSH key file.
    """
    try:
        os.system(f'icacls {identity_file} /inheritance:r')
        os.system(f'icacls {identity_file} /grant:r {os.getlogin()}:(R)')
        print("Permissions set successfully.")
    except PermissionError as e:
        print(f"Permission error setting permissions: {e}. Please ensure you have proper permissions.")
    except Exception as e:
        print(f"Error setting permissions: {e}")

if __name__ == "__main__":
    wsl_ssh_dir = "~/.sky/generated/ssh/"
    windows_ssh_dir = os.path.expanduser("~/.ssh/")
    identity_file = os.path.join(windows_ssh_dir, "sky-key")

    copy_ssh_files_to_config(wsl_ssh_dir, windows_ssh_dir)
    copy_ssh_key_from_wsl("~/.ssh/", windows_ssh_dir, "sky-key")
    update_ssh_config(windows_ssh_dir, identity_file)
    set_permissions(identity_file)

@yw5aj
Copy link
Author

yw5aj commented Jun 13, 2024

Just a thought: we can get the Windows home folder via something like wslpath "$(cmd.exe /c "echo %USERPROFILE%" 2>/dev/null | tr -d '\r')" within WSL. Could we technically just copy over the sky-key at the same time when this file is created, and create the files needed during sky launch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants