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 support for --name in all other neuro commands #648

Merged
merged 8 commits into from
Apr 3, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ Display status of a job.
**Usage:**

```bash
neuro job status [OPTIONS] ID
neuro job status [OPTIONS] JOB
```

**Options:**
Expand All @@ -269,7 +269,7 @@ Execute command in a running job.
**Usage:**

```bash
neuro job exec [OPTIONS] ID CMD...
neuro job exec [OPTIONS] JOB CMD...
```

**Options:**
Expand All @@ -290,7 +290,7 @@ Forward a port of a running job exposed with -ssh option to a local port.
**Usage:**

```bash
neuro job port-forward [OPTIONS] ID LOCAL_PORT REMOTE_PORT
neuro job port-forward [OPTIONS] JOB LOCAL_PORT REMOTE_PORT
```

**Options:**
Expand All @@ -310,7 +310,7 @@ Print the logs for a container.
**Usage:**

```bash
neuro job logs [OPTIONS] ID
neuro job logs [OPTIONS] JOB
```

**Options:**
Expand All @@ -329,7 +329,7 @@ Kill job\(s).
**Usage:**

```bash
neuro job kill [OPTIONS] ID...
neuro job kill [OPTIONS] JOB_LIST...
```

**Options:**
Expand All @@ -348,7 +348,7 @@ Display GPU/CPU/Memory usage.
**Usage:**

```bash
neuro job top [OPTIONS] ID
neuro job top [OPTIONS] JOB
```

**Options:**
Expand Down Expand Up @@ -955,7 +955,7 @@ Display status of a job.
**Usage:**

```bash
neuro status [OPTIONS] ID
neuro status [OPTIONS] JOB
```

**Options:**
Expand All @@ -974,7 +974,7 @@ Execute command in a running job.
**Usage:**

```bash
neuro exec [OPTIONS] ID CMD...
neuro exec [OPTIONS] JOB CMD...
```

**Options:**
Expand All @@ -995,7 +995,7 @@ Forward a port of a running job exposed with -ssh option to a local port.
**Usage:**

```bash
neuro port-forward [OPTIONS] ID LOCAL_PORT REMOTE_PORT
neuro port-forward [OPTIONS] JOB LOCAL_PORT REMOTE_PORT
```

**Options:**
Expand All @@ -1015,7 +1015,7 @@ Print the logs for a container.
**Usage:**

```bash
neuro logs [OPTIONS] ID
neuro logs [OPTIONS] JOB
```

**Options:**
Expand All @@ -1034,7 +1034,7 @@ Kill job\(s).
**Usage:**

```bash
neuro kill [OPTIONS] ID...
neuro kill [OPTIONS] JOB_LIST...
```

**Options:**
Expand All @@ -1053,7 +1053,7 @@ Display GPU/CPU/Memory usage.
**Usage:**

```bash
neuro top [OPTIONS] ID
neuro top [OPTIONS] JOB
```

**Options:**
Expand Down
14 changes: 10 additions & 4 deletions neuromation/cli/formatters/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,24 @@ def __call__(self, job: JobDescription) -> str:
)
if job.name:
out.append(style("Name", bold=True) + f": {job.name}")
job_alias = job.name
else:
job_alias = job.id
if job.http_url:
out.append(style("Http URL", bold=True) + f": {job.http_url}")
out.append(style("Shortcuts", bold=True) + ":")
out.append(f" neuro status {job.id} " + style("# check job status", dim=True))

out.append(
f" neuro status {job_alias} " + style("# check job status", dim=True)
)
out.append(
f" neuro logs {job.id} " + style("# monitor job stdout", dim=True)
f" neuro logs {job_alias} " + style("# monitor job stdout", dim=True)
)
out.append(
f" neuro top {job.id} "
f" neuro top {job_alias} "
+ style("# display real-time job telemetry", dim=True)
)
out.append(f" neuro kill {job.id} " + style("# kill job", dim=True))
out.append(f" neuro kill {job_alias} " + style("# kill job", dim=True))
return "\n".join(out)


Expand Down
40 changes: 24 additions & 16 deletions neuromation/cli/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
)
from .rc import Config
from .ssh_utils import connect_ssh
from .utils import alias, async_cmd, command, group, volume_to_verbose_str
from .utils import alias, async_cmd, command, group, resolve_job, volume_to_verbose_str


log = logging.getLogger(__name__)
Expand Down Expand Up @@ -266,7 +266,7 @@ async def submit(


@command(context_settings=dict(ignore_unknown_options=True))
@click.argument("id")
@click.argument("job")
@click.argument("cmd", nargs=-1, type=click.UNPROCESSED, required=True)
@click.option(
"-t",
Expand All @@ -281,19 +281,20 @@ async def submit(
)
@async_cmd
async def exec(
cfg: Config, id: str, tty: bool, no_key_check: bool, cmd: Sequence[str]
cfg: Config, job: str, tty: bool, no_key_check: bool, cmd: Sequence[str]
) -> None:
"""
Execute command in a running job.
"""
cmd = shlex.split(" ".join(cmd))
async with cfg.make_client() as client:
id = await resolve_job(client, job)
retcode = await client.jobs.exec(id, tty, no_key_check, cmd)
sys.exit(retcode)


@command(context_settings=dict(ignore_unknown_options=True))
@click.argument("id")
@click.argument("job")
@click.argument("local_port", type=int)
@click.argument("remote_port", type=int)
@click.option(
Expand All @@ -303,27 +304,28 @@ async def exec(
)
@async_cmd
async def port_forward(
cfg: Config, id: str, no_key_check: bool, local_port: int, remote_port: int
cfg: Config, job: str, no_key_check: bool, local_port: int, remote_port: int
) -> None:
"""
Forward a port of a running job exposed with -ssh option
to a local port.
"""
async with cfg.make_client() as client:
id = await resolve_job(client, job)
retcode = await client.jobs.port_forward(
id, no_key_check, local_port, remote_port
)
sys.exit(retcode)


@command(deprecated=True, hidden=True)
@click.argument("id")
@click.argument("job")
@click.option(
"--user", help="Container user name", default=JOB_SSH_USER, show_default=True
)
@click.option("--key", help="Path to container private key.")
@async_cmd
async def ssh(cfg: Config, id: str, user: str, key: str) -> None:
async def ssh(cfg: Config, job: str, user: str, key: str) -> None:
"""
Starts ssh terminal connected to running job.

Expand All @@ -336,13 +338,14 @@ async def ssh(cfg: Config, id: str, user: str, key: str) -> None:
git_key = cfg.github_rsa_path

async with cfg.make_client() as client:
id = await resolve_job(client, job)
await connect_ssh(client, id, git_key, user, key)


@command()
@click.argument("id")
@click.argument("job")
@async_cmd
async def logs(cfg: Config, id: str) -> None:
async def logs(cfg: Config, job: str) -> None:
"""
Print the logs for a container.
"""
Expand All @@ -351,6 +354,7 @@ async def logs(cfg: Config, id: str) -> None:
)

async with cfg.make_client(timeout=timeout) as client:
id = await resolve_job(client, job)
async for chunk in client.jobs.monitor(id):
if not chunk:
break
Expand Down Expand Up @@ -426,26 +430,28 @@ async def ls(


@command()
@click.argument("id")
@click.argument("job")
@async_cmd
async def status(cfg: Config, id: str) -> None:
async def status(cfg: Config, job: str) -> None:
"""
Display status of a job.
"""
async with cfg.make_client() as client:
id = await resolve_job(client, job)
res = await client.jobs.status(id)
click.echo(JobStatusFormatter()(res))


@command()
@click.argument("id")
@click.argument("job")
@async_cmd
async def top(cfg: Config, id: str) -> None:
async def top(cfg: Config, job: str) -> None:
"""
Display GPU/CPU/Memory usage.
"""
formatter = JobTelemetryFormatter()
async with cfg.make_client() as client:
id = await resolve_job(client, job)
print_header = True
async for res in client.jobs.top(id):
if print_header:
Expand All @@ -456,17 +462,19 @@ async def top(cfg: Config, id: str) -> None:


@command()
@click.argument("id", nargs=-1, required=True)
@click.argument("job_list", nargs=-1, required=True)
atemate marked this conversation as resolved.
Show resolved Hide resolved
@async_cmd
async def kill(cfg: Config, id: Sequence[str]) -> None:
async def kill(cfg: Config, job_list: Sequence[str]) -> None:
"""
Kill job(s).
"""
errors = []
async with cfg.make_client() as client:
for job in id:
for job in job_list:
job = await resolve_job(client, job)
try:
await client.jobs.kill(job)
# TODO (ajuszkowski) printing should be on the cli level
print(job)
except ValueError as e:
errors.append((job, e))
Expand Down
20 changes: 19 additions & 1 deletion neuromation/cli/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import logging
import re
import shlex
import sys
Expand All @@ -19,13 +20,15 @@

import click

from neuromation.client import Volume
from neuromation.client import Client, JobDescription, Volume
from neuromation.utils import run

from .rc import Config, ConfigFactory, save
from .version_utils import AbstractVersionChecker, DummyVersionChecker, VersionChecker


log = logging.getLogger(__name__)

_T = TypeVar("_T")

DEPRECATED_HELP_NOTICE = " " + click.style("(DEPRECATED)", fg="red")
Expand Down Expand Up @@ -322,3 +325,18 @@ def volume_to_verbose_str(volume: Volume) -> str:
f"'{volume.storage_path}' mounted to '{volume.container_path}' "
f"in {('ro' if volume.read_only else 'rw')} mode"
)


async def resolve_job(client: Client, id_or_name: str) -> str:
jobs: List[JobDescription] = []
try:
jobs = await client.jobs.list(name=id_or_name)
except Exception as e:
log.error(f"Failed to resolve job-name '{id_or_name}' to a job-ID: {e}")
if jobs:
job_id = jobs[-1].id
log.debug(f"Job name '{id_or_name}' resolved to job ID '{job_id}'")
else:
job_id = id_or_name

return job_id
1 change: 1 addition & 0 deletions python/CHANGELOG.D/648.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support job names.
atemate marked this conversation as resolved.
Show resolved Hide resolved
Loading