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

Add "mila-cpu" and "mila-gpu" entries in ~/.ssh/config in mila init #28

Merged
merged 31 commits into from
Apr 4, 2023

Conversation

lebrice
Copy link
Collaborator

@lebrice lebrice commented Jan 26, 2023

  • Refactor some of the code of the mila init command.
  • Add a "mila-cpu" and "mila-gpu" entry to ~/.ssh/config if the user wants them.
    • "mila-cpu": Asks for a cpu-only job in the unkillable partition, with 2 cpus and 16 Gb of RAM.
    • "mila-gpu": Asks for a GPU job in the unkillable partition, with 2 cpus and 16 Gb of RAM.

The main goal of this is to avoid having users of the cluster click the "mila" button in the VSCode Remote Explorer panel, as it connects them to the login node. This way, they now directly have a way to connect to
a compute node.

This is fairly equivalent to using these parameters to mila code:

mila code . --alloc --partition=unkillable --cpus-per-task=2 --mem=16G

Todos:

  • Write tests. Work in progress: still unable to feed the user inputs to the
    questions. I'd need some help with this @breuleux.

  • Make sure that the ssh entries are added in the right place when there are existing entries. Maybe confirm with @olexa?

    • Very hard / next to impossible to do without having to replicate the ssh-config resolution logic. For now, users might have to reorder some entries.

@lebrice lebrice changed the title Add entries mila init Add "mila-cpu" and "mila-gpu" entries in ~/.ssh/config in mila init Jan 27, 2023
@lebrice lebrice marked this pull request as ready for review January 27, 2023 17:17
@lebrice lebrice changed the base branch from dev to master January 27, 2023 17:26
@lebrice lebrice requested a review from breuleux January 27, 2023 20:43
exit("No ssh configuration file was found.")
sshpath = cfgpath.parent
if not sshpath.exists():
sshpath.mkdir(mode=0o700, exist_ok=True)
Copy link
Member

@satyaog satyaog Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this also chmod the dir if it already exists? Should it as this could also resolve some milatools unrelated issues?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5cade2d


def setup_ssh_config_interactive(
ssh_config_path: Union[str, Path] = "~/.ssh/config",
_input: Optional[PipeInput] = None,
Copy link
Member

@satyaog satyaog Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Soince this is only used for testing, should we instead use unittest.mock.patch to mock the questionary with functools.partials? E.g.

with prompt_toolkit.input.defaults.create_pipe_input() as inp:
    with unittest.mock.patch("questionary.confirm", new=functools.partial(questionary.confirm, input=inp)):
        inp.send_text("Y")
        [...]

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5647ea0

def _confirm_changes(
ssh_config: SSHConfig, hosts: list[str], _input: Optional[PipeInput] = None
) -> bool:
print(T.bold("The following code will be appended to your ~/.ssh/config:\n"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print(T.bold("The following code will be appended to your ~/.ssh/config:\n"))
print(T.bold("The following code will be appended or modified in your ~/.ssh/config:\n"))

since there is potentially a rename on *.server.mila.quebec?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this change (not sure in which commit exactly)

Comment on lines 74 to 78
def test_creates_ssh_config_file(tmp_path: Path):
ssh_config_path = tmp_path / "ssh_config"
with set_user_inputs(["y", "bob\r", "y", "y", "y", "y", "y"]) as input_pipe:
setup_ssh_config_interactive(tmp_path / "ssh_config", _input=input_pipe)
assert ssh_config_path.exists()
Copy link
Member

@satyaog satyaog Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    with set_user_inputs(["y", "bob\r", "y", "y", "y", "y", "y"]) as input_pipe:
        with unittest.mock.patch("questionary.confirm", new=functools.partial(questionary.confirm, input=input_pipe)), \
        with unittest.mock.patch("questionary.text", new=functools.partial(questionary.text, input=input_pipe)):
            setup_ssh_config_interactive(tmp_path / "ssh_config")

?

Copy link
Member

@satyaog satyaog Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def test_creates_ssh_config_file(tmp_path: Path, file_regression):
    [...]
    with open("ssh_config_path") as _f:
        file_regression.check(_f.read())

with pytest-regression?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5647ea0 for the first part, and 14f005c + 2b6d6cb for file_regression

with open(ssh_config_path) as f:
resulting_contents = f.read()

assert resulting_contents == expected_contents
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert resulting_contents == expected_contents
file_regression.check(resulting_contents)

with pytest-regression?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 14f005c

@satyaog
Copy link
Member

satyaog commented Jan 31, 2023

I have some suggestions but I think this is good and could be merged as is (although I would merge it after #32)

# If there is already something in the config file, the new entries should be appended at
# the end.
# TODO: Confirm this with @Olexa
expected_contents = initial_contents + _join_blocks(*expected_blocks)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ChatGPT tells me that the first matching entry is used so it depends on the behaviour we look for. If we don't want to mess with existing things, then appending will not break anything. But if we do think we know better, then entries should be added first so they take precedence on what was already existing

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I think it would be quite complicated to try to insert the new entries exactly where they should be, given an existing set of SSH entries, since we'd have to check for matches and everything.
This is why I was looking for Olexa's input as well.

We could also do something that works in ~90% of all cases, and requires the user to manually reorder entries in their .ssh/config the rest of the time. Not sure.


# Check for a mila entry in ssh config
# NOTE: If there is no `mila` entry, ssh_config.host("mila") returns an empty dictionary.
username = ssh_config.host("mila").get("user")
Copy link
Member

@satyaog satyaog Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not catch a Host that could look like

Host                            mila alias1 [...]
        User                    username
        [...]

even if ssh mila would match that existing configuration

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e111649

@lebrice
Copy link
Collaborator Author

lebrice commented Feb 1, 2023

Okay I'm pretty much done playing around with this. Let me know what you think @satyaog @breuleux .

@bouthilx
Copy link
Member

@satyaog Review needed :)

- Refactor some of the code of the `mila init` command.
- Add a "mila-cpu" and "mila-gpu" entry to ~/.ssh/config if the user
wants.
  - "mila-cpu": Asks for a cpu-only job in the unkillable partition,
with 2 cpus and 16 Gb of RAM.
  - "mila-gpu": Asks for a GPU job in the unkillable partition, with 2
cpus and 16 Gb of RAM.

The main goal of this is to avoid having users of the cluster click the
"mila" button in the VSCode Remote Explorer panel, as it connects them
to the login node. This way, they now directly have a way to connect to
a compute node.

This is fairly equivalent to using these parameters to `mila code`:
```
mila code . --alloc --partition=unkillable --cpus-per-task=2 --mem=16G
```

Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
- Work in progress. Still unable to feed the user inputs to the
questions. I'd need some help with this @breuleux.

Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
lebrice and others added 11 commits April 4, 2023 16:12
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
Signed-off-by: Fabrice Normandin <fabrice.normandin@gmail.com>
@breuleux breuleux merged commit 2d2867b into mila-iqia:master Apr 4, 2023
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

Successfully merging this pull request may close these issues.

None yet

4 participants