virtualbox.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # -*- coding: utf-8 -*-
  2. # Import Python libs
  3. from __future__ import absolute_import, print_function, unicode_literals
  4. import logging
  5. import os
  6. import salt.utils.json
  7. import salt.utils.virtualbox
  8. # Import Salt Testing libs
  9. import tests.integration.cloud.helpers
  10. # Import Salt libs
  11. from salt.ext import six
  12. from tests.support.case import ShellCase
  13. from tests.support.runtests import RUNTIME_VARS
  14. from tests.support.unit import TestCase, skipIf
  15. # Create the cloud instance name to be used throughout the tests
  16. INSTANCE_NAME = tests.integration.cloud.helpers.random_name()
  17. PROVIDER_NAME = "virtualbox"
  18. CONFIG_NAME = PROVIDER_NAME + "-config"
  19. PROFILE_NAME = PROVIDER_NAME + "-test"
  20. DEPLOY_PROFILE_NAME = PROVIDER_NAME + "-deploy-test"
  21. DRIVER_NAME = "virtualbox"
  22. BASE_BOX_NAME = "__temp_test_vm__"
  23. BOOTABLE_BASE_BOX_NAME = "SaltMiniBuntuTest"
  24. # Setup logging
  25. log = logging.getLogger(__name__)
  26. @skipIf(salt.utils.virtualbox.HAS_LIBS is False, "virtualbox has to be installed")
  27. class VirtualboxTestCase(TestCase):
  28. def setUp(self):
  29. self.vbox = salt.utils.virtualbox.vb_get_box()
  30. def assertMachineExists(self, name, msg=None):
  31. try:
  32. self.vbox.findMachine(name)
  33. except Exception as e: # pylint: disable=broad-except
  34. if msg:
  35. self.fail(msg)
  36. else:
  37. self.fail(e.message)
  38. def assertMachineDoesNotExist(self, name):
  39. self.assertRaisesRegex(
  40. Exception,
  41. "Could not find a registered machine",
  42. self.vbox.findMachine,
  43. name,
  44. )
  45. @skipIf(
  46. salt.utils.virtualbox.HAS_LIBS is False,
  47. "salt-cloud requires virtualbox to be installed",
  48. )
  49. class VirtualboxCloudTestCase(ShellCase):
  50. def run_cloud(self, arg_str, catch_stderr=False, timeout=None):
  51. """
  52. Execute salt-cloud with json output and try to interpret it
  53. @return:
  54. @rtype: dict
  55. """
  56. config_path = os.path.join(RUNTIME_VARS.FILES, "conf")
  57. arg_str = "--out=json -c {0} {1}".format(config_path, arg_str)
  58. # arg_str = "{0} --log-level=error".format(arg_str)
  59. log.debug("running salt-cloud with %s", arg_str)
  60. output = self.run_script("salt-cloud", arg_str, catch_stderr, timeout=timeout)
  61. # Sometimes tuples are returned???
  62. if isinstance(output, tuple) and len(output) == 2:
  63. output = output[0]
  64. # Attempt to clean json output before fix of https://github.com/saltstack/salt/issues/27629
  65. valid_initial_chars = ["{", "[", '"']
  66. for line in output[:]:
  67. if len(line) == 0 or (line[0] not in valid_initial_chars):
  68. output.pop(0)
  69. else:
  70. break
  71. if len(output) == 0:
  72. return dict()
  73. else:
  74. return salt.utils.json.loads("".join(output))
  75. def run_cloud_function(self, function, kw_function_args=None, **kwargs):
  76. """
  77. A helper to call `salt-cloud -f function provider`
  78. @param function:
  79. @type function:
  80. @param kw_function_args: Keyword arguments for the argument string in the commandline
  81. @type dict:
  82. @param kwargs: For the `run_cloud` function
  83. @type kwargs:
  84. @return:
  85. @rtype: dict
  86. """
  87. args = []
  88. # Args converted in the form of key1='value1' ... keyN='valueN'
  89. if kw_function_args:
  90. args = [
  91. "{0}='{1}'".format(key, value)
  92. for key, value in six.iteritems(kw_function_args)
  93. ]
  94. output = self.run_cloud(
  95. "-f {0} {1} {2}".format(function, CONFIG_NAME, " ".join(args)), **kwargs
  96. )
  97. return output.get(CONFIG_NAME, {}).get(PROVIDER_NAME, {})
  98. def run_cloud_action(self, action, instance_name, **kwargs):
  99. """
  100. A helper to call `salt-cloud -a action instance_name`
  101. @param action:
  102. @type action: str
  103. @param instance_name:
  104. @type instance_name: str
  105. @return:
  106. @rtype: dict
  107. """
  108. output = self.run_cloud(
  109. "-a {0} {1} --assume-yes".format(action, instance_name), **kwargs
  110. )
  111. return output.get(CONFIG_NAME, {}).get(PROVIDER_NAME, {})