Skip to content

Commit

Permalink
machine: Add a new command dvc machine status (#6649)
Browse files Browse the repository at this point in the history
* machine: Add a new command `dvc machine status`

fix#6482
1. add a new command `dvc machien status`
2. add a unit test for the cli call.
3. add a unit test for the shown result.

* Update dvc/command/machine.py

Co-authored-by: Saugat Pachhai <[email protected]>

* Update dvc/command/machine.py

Co-authored-by: Saugat Pachhai <[email protected]>

* Update machine.py

* Remove sensitive fields

* Update dvc/machine/__init__.py

Co-authored-by: Casper da Costa-Luis <[email protected]>

* Update tests/func/machine/__init__.py

Co-authored-by: Casper da Costa-Luis <[email protected]>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Use white list to limit shown fields

Co-authored-by: Saugat Pachhai <[email protected]>
Co-authored-by: Casper da Costa-Luis <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
4 people authored Oct 19, 2021
1 parent 6d96ecb commit 966dc8a
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 8 deletions.
29 changes: 29 additions & 0 deletions dvc/command/machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,22 @@ def run(self):
return 0


class CmdMachineStatus(CmdBase):
SHOWN_FIELD = ["name", "cloud", "instance_hdd_size", "instance_ip"]

def run(self):
if self.repo.machine is None:
raise MachineDisabledError

all_status = self.repo.machine.status(self.args.name)
for i, status in enumerate(all_status, start=1):
ui.write(f"instance_num_{i}:")
for field in self.SHOWN_FIELD:
value = status.get(field, None)
ui.write(f"\t{field:20}: {value}")
return 0


class CmdMachineDestroy(CmdBase):
def run(self):
if self.repo.machine is None:
Expand Down Expand Up @@ -306,6 +322,19 @@ def add_parser(subparsers, parent_parser):
)
machine_create_parser.set_defaults(func=CmdMachineCreate)

machine_STATUS_HELP = "List the status of a running machine."
machine_status_parser = machine_subparsers.add_parser(
"status",
parents=[parent_config_parser, parent_parser],
description=append_doc_link(machine_STATUS_HELP, "machine/status"),
help=machine_STATUS_HELP,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
machine_status_parser.add_argument(
"name", help="Name of the running machine."
)
machine_status_parser.set_defaults(func=CmdMachineStatus)

machine_DESTROY_HELP = "Destroy an machine instance."
machine_destroy_parser = machine_subparsers.add_parser(
"destroy",
Expand Down
6 changes: 6 additions & 0 deletions dvc/machine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
import os
from typing import (
TYPE_CHECKING,
Any,
Dict,
Iterable,
Iterator,
Mapping,
Optional,
Tuple,
Expand Down Expand Up @@ -200,3 +202,7 @@ def get_sshfs(self, name: Optional[str]):
def run_shell(self, name: Optional[str]):
config, backend = self.get_config_and_backend(name)
return backend.run_shell(**config)

def status(self, name: str) -> Iterator[Dict[Any, Any]]:
config, backend = self.get_config_and_backend(name)
return backend.instances(**config)
10 changes: 10 additions & 0 deletions tests/func/machine/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import textwrap

CONFIG_TEXT = textwrap.dedent(
"""\
[feature]
machine = true
['machine "foo"']
cloud = aws
"""
)
9 changes: 1 addition & 8 deletions tests/func/machine/test_machine_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,7 @@

from dvc.main import main

CONFIG_TEXT = textwrap.dedent(
"""\
[feature]
machine = true
['machine \"foo\"']
cloud = aws
"""
)
from . import CONFIG_TEXT


@pytest.mark.parametrize(
Expand Down
43 changes: 43 additions & 0 deletions tests/func/machine/test_machine_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import json

from tpi.terraform import TerraformBackend

from dvc.command.machine import CmdMachineStatus
from dvc.main import main

from . import CONFIG_TEXT

STATUS = """{
"aws_security_group": null,
"cloud": "aws",
"id": "iterative-2jyhw8j9ieov6",
"image": "ubuntu-bionic-18.04-amd64-server-20210818",
"instance_gpu": null,
"instance_hdd_size": 35,
"instance_ip": "123.123.123.123",
"instance_launch_time": "2021-08-25T07:13:03Z",
"instance_type": "m",
"name": "test-resource",
"region": "us-west",
"spot": false,
"spot_price": -1,
"ssh_name": null,
"ssh_private": "-----BEGIN RSA PRIVATE KEY-----\\n",
"startup_script": "IyEvYmluL2Jhc2g=",
"timeouts": null
}"""


def test_status(tmp_dir, scm, dvc, mocker, capsys):
(tmp_dir / ".dvc" / "config").write_text(CONFIG_TEXT)
status = json.loads(STATUS)

mocker.patch.object(
TerraformBackend, "instances", autospec=True, return_value=[status]
)

assert main(["machine", "status", "foo"]) == 0
cap = capsys.readouterr()
assert "instance_num_1:" in cap.out
for key in CmdMachineStatus.SHOWN_FIELD:
assert f"\t{key:20}: {status[key]}" in cap.out
14 changes: 14 additions & 0 deletions tests/unit/command/test_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
CmdMachineModify,
CmdMachineRemove,
CmdMachineSsh,
CmdMachineStatus,
)

DATA = {
Expand Down Expand Up @@ -56,6 +57,19 @@ def test_create(tmp_dir, dvc, mocker):
m.assert_called_once_with("foo")


def test_status(tmp_dir, dvc, mocker):
cli_args = parse_args(["machine", "status", "foo"])
assert cli_args.func == CmdMachineStatus

cmd = cli_args.func(cli_args)
m = mocker.patch.object(
cmd.repo.machine, "status", autospec=True, return_value=[]
)

assert cmd.run() == 0
m.assert_called_once_with("foo")


def test_destroy(tmp_dir, dvc, mocker):
cli_args = parse_args(["machine", "destroy", "foo"])
assert cli_args.func == CmdMachineDestroy
Expand Down

0 comments on commit 966dc8a

Please sign in to comment.