Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
f1d55f5
Fix OSError if mech destroy #57
May 4, 2019
a67380c
This fixes #59: json.decoder.JSONDecodeError: Expecting property name…
Jun 8, 2019
204c779
show instance name when ssh-config command is run
mkinney Jan 3, 2020
1180354
add command line option to disable shared folder
mkinney Jan 5, 2020
ee1e270
add ability to override vcpus/mem
mkinney Jan 8, 2020
0f043f6
Merge remote-tracking branch 'dodo5522/fix-json-decode-error-by-broke…
mkinney Feb 1, 2020
b2d9b92
Merge remote-tracking branch 'origin/disable-shared-folder-option' in…
mkinney Feb 1, 2020
b173b0b
Merge remote-tracking branch 'origin/mem-and-vcpu' into multi-pr
mkinney Feb 1, 2020
2684174
Merge remote-tracking branch 'origin/show-instance-name-in-ssh-config…
mkinney Feb 1, 2020
d461bbf
add info on how to install from diff repo; update example
mkinney Feb 1, 2020
321fd37
add info in readme about new up options
mkinney Feb 1, 2020
578a811
flake8 fixes; add contributing file
mkinney Feb 1, 2020
7b20319
move all files under this dir .mech
mkinney Feb 1, 2020
13e265a
get list/destroy to work as expected
mkinney Feb 1, 2020
1681233
got mech up and ls working with multiple
mkinney Feb 2, 2020
3c4a20b
enable most commands to deal with single or multiple instances
mkinney Feb 2, 2020
fff0393
add docstrings; get scp working
mkinney Feb 2, 2020
377097d
test that snapshot add/list/delete work as expected
mkinney Feb 2, 2020
46333dc
validate mech box add/list/remove work as expected
mkinney Feb 2, 2020
e6faeb6
update help info
mkinney Feb 2, 2020
f89d149
add bats and simple int tests
mkinney Feb 3, 2020
1e263c3
add two instances test; added name to up/delete
mkinney Feb 3, 2020
82e800b
document the int tests
mkinney Feb 3, 2020
57d8021
update doc/TODOs
mkinney Feb 3, 2020
38842c6
add direnv
mkinney Feb 3, 2020
8109fff
migrate TODO notes into project board
mkinney Feb 3, 2020
a76f29e
change debug logging; pass named values; validate creating box from file
mkinney Feb 3, 2020
19b9176
improve int testing
mkinney Feb 3, 2020
1223951
add int testing for most functionality
mkinney Feb 3, 2020
e014e37
validate provisioning works as expected
mkinney Feb 4, 2020
166d406
validate shared_folders functionality
mkinney Feb 4, 2020
58c2b32
provision on start; add option to disable provisioining
mkinney Feb 4, 2020
cb6fa81
fix bugs that running the int tests would have caught
mkinney Feb 5, 2020
6185a44
refactor to a MechInstance class
mkinney Feb 5, 2020
a11eef9
no need to change dirs
mkinney Feb 5, 2020
7be0e95
add detailed list for instances
mkinney Feb 5, 2020
f0f5818
add/remove instances from Mechfile
mkinney Feb 5, 2020
70829d7
remove unused code; refactor path; improve comments
mkinney Feb 5, 2020
4f36fb8
remove unused methods
mkinney Feb 5, 2020
0d09ad6
initial unit tests
mkinney Feb 6, 2020
2ff2934
ignore these long lines
mkinney Feb 6, 2020
8388f4b
add some initial tests
mkinney Feb 7, 2020
4add67a
add code coverage; add more tests
mkinney Feb 7, 2020
d03fdc6
figured out how to *unit test* mech list
mkinney Feb 7, 2020
0b5e76d
disable deprecated warnings for now; mock out the utils.locate function
mkinney Feb 8, 2020
3673cfe
added unit tests for mech port
mkinney Feb 8, 2020
5dea760
add mech box list unit tests
mkinney Feb 8, 2020
ccfe195
pylint fixes
mkinney Feb 8, 2020
28e9a05
pylint the tests
mkinney Feb 8, 2020
2ca6d3a
pylint fixes
mkinney Feb 9, 2020
bf908a4
add mech snapshot list/save unittest
mkinney Feb 9, 2020
821cb33
remove puts_err calls; added mech snapshot delete unittest
mkinney Feb 9, 2020
01e4555
add some mech up and mech ssh-config unit tests
mkinney Feb 9, 2020
b9b83e1
add mech snapshot save unit tests
mkinney Feb 10, 2020
5e804b5
working on utils.build_mechfile_entry unittests
mkinney Feb 10, 2020
0d001b4
improved build_mechfile unit tests
mkinney Feb 10, 2020
0bac6bc
add mech box add/remove unittests
mkinney Feb 10, 2020
c8c6309
add unit test for mech init
mkinney Feb 10, 2020
ffb630c
add unittests for mech add/init
mkinney Feb 10, 2020
ab940df
add unittests for mech remove
mkinney Feb 10, 2020
32d56b4
add unittests for mech up
mkinney Feb 10, 2020
23b56fe
add another case for mech up
mkinney Feb 10, 2020
3525b07
add unittest for mech ps
mkinney Feb 10, 2020
1edbc9a
add more unittests pause/resume/stop; remove sleeps
mkinney Feb 10, 2020
a2f25c3
add more unittests mech ssh/suspend/ip
mkinney Feb 11, 2020
f55de9f
add mech provision unittests
mkinney Feb 11, 2020
7960703
migrate some test code into fixtures
mkinney Feb 11, 2020
f379177
pylint tests
mkinney Feb 11, 2020
74db045
pylint fixes
mkinney Feb 11, 2020
5a8e1b8
pylint fixes and additional unittests
mkinney Feb 11, 2020
ba49272
add unittest for update_vmx
mkinney Feb 11, 2020
dece82e
run pytest with multiple cpus
mkinney Feb 11, 2020
2a074d4
update info about seeing slowest pytest tests
mkinney Feb 11, 2020
50d896b
add more unittests to test_utils
mkinney Feb 11, 2020
d1ba7b9
unittest additions
mkinney Feb 12, 2020
abb5282
add ability to run int tests from pytest
mkinney Feb 12, 2020
7a61454
show how to run all tests from pytest
mkinney Feb 12, 2020
bf07d3f
more comments about running tests
mkinney Feb 12, 2020
ba9e262
after cleaning some .mech dirs, found unit test was using them and ha…
mkinney Feb 12, 2020
1fd9b68
add more unittests
mkinney Feb 12, 2020
945e76c
add test_tar unittest
mkinney Feb 12, 2020
6c2d077
add no-nat (eg bridged) networking
mkinney Feb 12, 2020
3c40866
args should use dash not underbar
mkinney Feb 12, 2020
8a24afb
add zsh completions
mkinney Feb 13, 2020
2f722b1
add bash completions
mkinney Feb 13, 2020
9de79b9
add ability to have multiple shared folders
mkinney Feb 14, 2020
0241c38
adding copyright
mkinney Feb 15, 2020
9935ed6
add initial workflow
mkinney Feb 15, 2020
5c2cfec
add docopt to deps
mkinney Feb 15, 2020
7b49d4b
add more deps
mkinney Feb 15, 2020
9f4f22c
move code into constructor; mock a few more things
mkinney Feb 15, 2020
34012db
do not test on python 2.7, it is dead, jim
mkinney Feb 15, 2020
ba15adc
mock get_provider
mkinney Feb 15, 2020
81d0790
drop test under python 3.5
mkinney Feb 15, 2020
5d1a3d7
give up on python 3.6
mkinney Feb 16, 2020
02f2250
fix issues that int tests found; init_from_file is intermittently fai…
mkinney Feb 16, 2020
b8cd3a8
refactor so each class in own file; all utils in utils.py
mkinney Feb 16, 2020
7799da5
refactor utils.provision
mkinney Feb 16, 2020
5f7160a
refactor variable names/comments
mkinney Feb 16, 2020
3ec0d52
add badge
mkinney Feb 16, 2020
7166419
fix badge
mkinney Feb 16, 2020
2b496cc
retrying badge
mkinney Feb 16, 2020
84c374d
add codecov.io
mkinney Feb 16, 2020
b4eeccc
add codecov badge in readme
mkinney Feb 16, 2020
d336310
add init from json int test
mkinney Feb 16, 2020
bc74773
add more utils unittests
mkinney Feb 16, 2020
f40c0ee
add more unittests for utils
mkinney Feb 16, 2020
8648061
remove options that are not implemented
mkinney Feb 16, 2020
00aba98
add upgradevm option; but there seems to be a bug in vmrun
mkinney Feb 16, 2020
533b81a
add a few more lines of unittest coverage
mkinney Feb 16, 2020
c4611da
add some unittests to vmrun
mkinney Feb 16, 2020
96d506b
set executable/provider in test
mkinney Feb 16, 2020
c41cdde
added unit test for vmrun.get_guest_ip_address
mkinney Feb 16, 2020
1f63830
only create vmrun object with user/pass when we need to
mkinney Feb 17, 2020
0e93177
added add-me option
mkinney Feb 17, 2020
ad91f68
add unit tests for vmrun class
mkinney Feb 17, 2020
5f12d24
add use-me/remove-vagrant options
mkinney Feb 17, 2020
afe6089
revamp the ssh output
mkinney Feb 18, 2020
7b4dfd7
fix issues that int tests caught; update readme with current help; li…
mkinney Feb 18, 2020
048386b
convert bats int tests to pure python
mkinney Feb 19, 2020
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
Prev Previous commit
Next Next commit
refactor utils.provision
  • Loading branch information
mkinney committed Feb 16, 2020
commit 7799da53c0f7713d0277ffa6e04f0446a42a7af2
5 changes: 2 additions & 3 deletions mech/mech.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,7 @@ def up(self, arguments): # pylint: disable=invalid-name
print(colored.yellow("VM ({}) was already started on an "
"unknown IP address".format(instance)))
if not disable_provisioning:
utils.provision(instance, inst.vmx, inst.user, inst.password,
inst.provision, show=False)
utils.provision(inst, show=False)

# allows "mech start" to alias to "mech up"
start = up
Expand Down Expand Up @@ -823,7 +822,7 @@ def provision(self, arguments):
inst = MechInstance(instance)

if inst.created:
utils.provision(instance, inst.vmx, inst.user, inst.password, inst.provision, show)
utils.provision(inst, show)
else:
print("VM not created.")

Expand Down
72 changes: 44 additions & 28 deletions mech/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,25 +404,24 @@ def test_build_mechfile_entry_file_location_external_bad_location():
def test_provision_no_instance():
"""Test provisioning."""
with raises(SystemExit, match=r"Need to provide an instance to provision"):
mech.utils.provision(instance=None, vmx=None, user=None, password=None,
provision_config=None, show=None)
mech.utils.provision(instance=None, show=None)


def test_provision_no_vmx():
"""Test provisioning."""
mock_inst = MagicMock()
mock_inst.vmx = None
with raises(SystemExit, match=r"Need to provide vmx.*"):
mech.utils.provision(instance='first', vmx=None, user=None, password=None,
provision_config=None, show=None)
mech.utils.provision(instance=mock_inst, show=None)


@patch('mech.vmrun.VMrun.installed_tools')
def test_provision_no_vmare_tools(mock_installed_tools):
"""Test provisioning."""
mock_inst = MagicMock()
mock_installed_tools.return_value = None
with raises(SystemExit, match=r"Cannot provision if VMware Tools are not installed"):
mech.utils.provision(instance='first', vmx='/tmp/first/some.vmx',
user='vagrant', password='vagrant', provision_config=None,
show=None)
mech.utils.provision(instance=mock_inst, show=None)


@patch('mech.utils.provision_file')
Expand All @@ -431,8 +430,9 @@ def test_provision_file_no_provisioning(mock_installed_tools, mock_provision_fil
"""Test provisioning."""
mock_installed_tools.return_value = "running"
mock_provision_file.return_value = None
mech.utils.provision(instance='first', vmx='/tmp/first/some.vmx', user='vagrant',
password='vagrant', provision_config=[], show=None)
mock_inst = MagicMock()
mock_inst.provision = []
mech.utils.provision(instance=mock_inst, show=None)
out, _ = capfd.readouterr()
assert re.search(r'Nothing to provision', out, re.MULTILINE)

Expand All @@ -450,8 +450,11 @@ def test_provision_file(mock_installed_tools, mock_copy_file, capfd):
"destination": "/tmp/file1.txt",
},
]
mech.utils.provision(instance='first', vmx='/tmp/first/some.vmx', user='vagrant',
password='vagrant', provision_config=config, show=None)
mock_inst = MagicMock()
mock_inst.name = 'first'
mock_inst.vmx = '/tmp/first/some.vmx'
mock_inst.provision = config
mech.utils.provision(instance=mock_inst, show=None)
out, _ = capfd.readouterr()
assert re.search(r'Copying ', out, re.MULTILINE)

Expand All @@ -470,8 +473,11 @@ def test_provision_file_could_not_copy_file_to_guest(mock_installed_tools,
"destination": "/tmp/file1.txt",
},
]
mech.utils.provision(instance='first', vmx='/tmp/first/some.vmx', user='vagrant',
password='vagrant', provision_config=config, show=None)
mock_inst = MagicMock()
mock_inst.name = 'first'
mock_inst.vmx = '/tmp/first/some.vmx'
mock_inst.provision = config
mech.utils.provision(instance=mock_inst, show=None)
out, _ = capfd.readouterr()
assert re.search(r'Not Provisioned', out, re.MULTILINE)

Expand All @@ -487,9 +493,11 @@ def test_provision_file_show(mock_installed_tools, capfd):
"destination": "/tmp/file1.txt",
},
]
mech.utils.provision(instance='first', vmx='/tmp/first/some.vmx',
user='vagrant', password='vagrant',
provision_config=config, show=True)
mock_inst = MagicMock()
mock_inst.name = 'first'
mock_inst.vmx = '/tmp/first/some.vmx'
mock_inst.provision = config
mech.utils.provision(instance=mock_inst, show=True)
out, _ = capfd.readouterr()
assert re.search(r'instance:', out, re.MULTILINE)

Expand Down Expand Up @@ -520,9 +528,11 @@ def test_provision_shell(mock_installed_tools, mock_copy_file,
"inline": "echo hello from inline"
},
]
mech.utils.provision(instance='first', vmx='/tmp/first/some.vmx',
user='vagrant', password='vagrant',
provision_config=config, show=None)
mock_inst = MagicMock()
mock_inst.name = 'first'
mock_inst.vmx = '/tmp/first/some.vmx'
mock_inst.provision = config
mech.utils.provision(instance=mock_inst, show=None)
out, _ = capfd.readouterr()
mock_installed_tools.assert_called()
mock_copy_file.assert_called()
Expand Down Expand Up @@ -550,9 +560,11 @@ def test_provision_shell_show_only(mock_installed_tools, capfd):
],
},
]
mech.utils.provision(instance='first', vmx='/tmp/first/some.vmx',
user='vagrant', password='vagrant',
provision_config=config, show=True)
mock_inst = MagicMock()
mock_inst.name = 'first'
mock_inst.vmx = '/tmp/first/some.vmx'
mock_inst.provision = config
mech.utils.provision(instance=mock_inst, show=True)
out, _ = capfd.readouterr()
mock_installed_tools.assert_called()
assert re.search(r' instance:', out, re.MULTILINE)
Expand All @@ -573,9 +585,11 @@ def test_provision_shell_with_issue(mock_installed_tools, mock_provision_shell,
],
},
]
mech.utils.provision(instance='first', vmx='/tmp/first/some.vmx',
user='vagrant', password='vagrant',
provision_config=config, show=None)
mock_inst = MagicMock()
mock_inst.name = 'first'
mock_inst.vmx = '/tmp/first/some.vmx'
mock_inst.provision = config
mech.utils.provision(instance=mock_inst, show=None)
out, _ = capfd.readouterr()
mock_installed_tools.assert_called()
mock_provision_shell.assert_called()
Expand All @@ -590,9 +604,11 @@ def test_provision_with_unknown_type(mock_installed_tools, capfd):
"type": "foo",
},
]
mech.utils.provision(instance='first', vmx='/tmp/first/some.vmx',
user='vagrant', password='vagrant',
provision_config=config, show=None)
mock_inst = MagicMock()
mock_inst.name = 'first'
mock_inst.vmx = '/tmp/first/some.vmx'
mock_inst.provision = config
mech.utils.provision(instance=mock_inst, show=None)
out, _ = capfd.readouterr()
mock_installed_tools.assert_called()
assert re.search(r'Not Provisioned', out, re.MULTILINE)
58 changes: 27 additions & 31 deletions mech/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def update_vmx(path, numvcpus=None, memsize=None, no_nat=False):


def load_mechfile(should_exist=True):
"""Load the Mechfile from disk and return the object."""
"""Load the Mechfile from disk and return the mechfile as a dictionary."""
mechfile_fullpath = os.path.join(main_dir(), 'Mechfile')
LOGGER.debug("mechfile_fullpath:%s", mechfile_fullpath)
if os.path.isfile(mechfile_fullpath):
Expand All @@ -206,14 +206,12 @@ def load_mechfile(should_exist=True):
print(colored.red("Invalid Mechfile." + os.linesep))
else:
if should_exist:
print(colored.red(textwrap.fill(
"Could not find a Mechfile in the current directory. "
"A Mech environment is required to run this command. Run `mech init` "
"to create a new Mech environment. Or specify the name of the VM you would "
"like to start with `mech up <name>`. A final option is to change to a "
"directory with a Mechfile and to try again."
)))
sys.exit(1)
sys.exit(colored.red(textwrap.fill(
"Could not find a Mechfile in the current directory. "
"A Mech environment is required to run this command. Run `mech init` "
"to create a new Mech environment. Or specify the name of the VM you would "
"like to start with `mech up <name>`. A final option is to change to a "
"directory with a Mechfile and to try again.")))
else:
return {}

Expand Down Expand Up @@ -356,8 +354,7 @@ def init_box(name, box=None, box_version=None, location=None, force=False, save=
save=save,
requests_kwargs=requests_kwargs)
if not name_version_box:
print(colored.red("Cannot find a valid box with a VMX file in it"))
sys.exit(1)
sys.exit(colored.red("Cannot find a valid box with a VMX file in it"))

box_parts = box.split('/')
box_dir = os.path.join(*filter(None, (mech_dir(), 'boxes',
Expand All @@ -377,8 +374,7 @@ def init_box(name, box=None, box_version=None, location=None, force=False, save=
startupinfo.dwFlags |= subprocess.SW_HIDE | subprocess.STARTF_USESHOWWINDOW
proc = subprocess.Popen(cmd, cwd=instance_path, startupinfo=startupinfo)
if proc.wait():
print(colored.red("Cannot extract box"))
sys.exit(1)
sys.exit(colored.red("Cannot extract box"))
else:
tar = tarfile.open(box_file, 'r')
tar.extractall(instance_path)
Expand All @@ -388,8 +384,7 @@ def init_box(name, box=None, box_version=None, location=None, force=False, save=

vmx = locate(instance_path, '*.vmx')
if not vmx:
print(colored.red("Cannot locate a VMX file"))
sys.exit(1)
sys.exit(colored.red("Cannot locate a VMX file"))

update_vmx(vmx, numvcpus=numvcpus, memsize=memsize, no_nat=no_nat)
return vmx
Expand Down Expand Up @@ -506,11 +501,9 @@ def add_box_url(name, box, box_version, url, force=False, save=True, requests_kw
finally:
os.unlink(the_file.name)
except requests.HTTPError as exc:
print(colored.red("Bad response: %s" % exc))
sys.exit(1)
sys.exit(colored.red("Bad response: %s" % exc))
except requests.ConnectionError:
print(colored.red("Couldn't connect to '%s'" % url))
sys.exit(1)
sys.exit(colored.red("Couldn't connect to '%s'" % url))
return name, box_version, box


Expand Down Expand Up @@ -538,11 +531,9 @@ def add_box_file(box=None, box_version=None, filename=None, url=None, force=Fals
valid_tar = True
break
if i.startswith('/') or i.startswith('..'):
print(colored.red(textwrap.fill(
"This box is comprised of filenames starting with '/' or '..' "
"Exiting for the safety of your files."
)))
sys.exit(1)
sys.exit(colored.red(textwrap.fill(
"This box is comprised of filenames starting with '/' or '..' "
"Exiting for the safety of your files.")))

if valid_tar:
if save:
Expand Down Expand Up @@ -601,31 +592,36 @@ def get_requests_kwargs(arguments):
return requests_kwargs


def provision(instance, vmx, user, password, provision_config, show):
def provision(instance, show=False):
"""Provision an instance.

provision types:
Args:
instance (MechInstance): an instance
show (bool): just print the provisioning

Notes:
Valid provision types are:
file: copies files to instances
shell: executes scripts

"""

if not instance or instance == '':
if not instance:
sys.exit(colored.red("Need to provide an instance to provision()."))

if not vmx or not user or not password:
if instance.vmx is None or instance.user is None or instance.password is None:
sys.exit(colored.red("Need to provide vmx/user/password to provision()."))

print(colored.green('Provisioning instance:{}'.format(instance)))

vmrun = VMrun(vmx, user, password)
vmrun = VMrun(instance.vmx, instance.user, instance.password)
# cannot run provisioning if vmware tools are not installed
if not vmrun.installed_tools():
sys.exit(colored.red("Cannot provision if VMware Tools are not installed."))

provisioned = 0
if provision_config:
for i, pro in enumerate(provision_config):
if instance.provision:
for i, pro in enumerate(instance.provision):
provision_type = pro.get('type')
if provision_type == 'file':
source = pro.get('source')
Expand Down