1
0

command.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. from __future__ import absolute_import
  2. from __future__ import unicode_literals
  3. import contextlib
  4. import logging
  5. import os
  6. import re
  7. import six
  8. from requests.exceptions import ConnectionError
  9. from requests.exceptions import SSLError
  10. from . import errors
  11. from . import verbose_proxy
  12. from .. import config
  13. from ..project import Project
  14. from .docker_client import docker_client
  15. from .utils import call_silently
  16. from .utils import get_version_info
  17. from .utils import is_mac
  18. from .utils import is_ubuntu
  19. log = logging.getLogger(__name__)
  20. @contextlib.contextmanager
  21. def friendly_error_message():
  22. try:
  23. yield
  24. except SSLError as e:
  25. raise errors.UserError('SSL error: %s' % e)
  26. except ConnectionError:
  27. if call_silently(['which', 'docker']) != 0:
  28. if is_mac():
  29. raise errors.DockerNotFoundMac()
  30. elif is_ubuntu():
  31. raise errors.DockerNotFoundUbuntu()
  32. else:
  33. raise errors.DockerNotFoundGeneric()
  34. elif call_silently(['which', 'docker-machine']) == 0:
  35. raise errors.ConnectionErrorDockerMachine()
  36. else:
  37. raise errors.ConnectionErrorGeneric(get_client().base_url)
  38. def project_from_options(base_dir, options):
  39. return get_project(
  40. base_dir,
  41. get_config_path_from_options(options),
  42. project_name=options.get('--project-name'),
  43. verbose=options.get('--verbose'),
  44. )
  45. def get_config_path_from_options(options):
  46. file_option = options.get('--file')
  47. if file_option:
  48. return file_option
  49. config_file = os.environ.get('COMPOSE_FILE')
  50. return [config_file] if config_file else None
  51. def get_client(verbose=False, version=None):
  52. client = docker_client(version=version)
  53. if verbose:
  54. version_info = six.iteritems(client.version())
  55. log.info(get_version_info('full'))
  56. log.info("Docker base_url: %s", client.base_url)
  57. log.info("Docker version: %s",
  58. ", ".join("%s=%s" % item for item in version_info))
  59. return verbose_proxy.VerboseProxy('docker', client)
  60. return client
  61. def get_project(base_dir, config_path=None, project_name=None, verbose=False):
  62. config_details = config.find(base_dir, config_path)
  63. project_name = get_project_name(config_details.working_dir, project_name)
  64. config_data = config.load(config_details)
  65. api_version = '1.21' if config_data.version < 2 else None
  66. client = get_client(verbose=verbose, version=api_version)
  67. return Project.from_config(project_name, config_data, client)
  68. def get_project_name(working_dir, project_name=None):
  69. def normalize_name(name):
  70. return re.sub(r'[^a-z0-9]', '', name.lower())
  71. project_name = project_name or os.environ.get('COMPOSE_PROJECT_NAME')
  72. if project_name is not None:
  73. return normalize_name(project_name)
  74. project = os.path.basename(os.path.abspath(working_dir))
  75. if project:
  76. return normalize_name(project)
  77. return 'default'