command.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. from __future__ import unicode_literals
  2. from __future__ import absolute_import
  3. from requests.exceptions import ConnectionError, SSLError
  4. import errno
  5. import logging
  6. import os
  7. import re
  8. import yaml
  9. import six
  10. from ..project import Project
  11. from ..service import ConfigError
  12. from .docopt_command import DocoptCommand
  13. from .utils import call_silently, is_mac, is_ubuntu
  14. from .docker_client import docker_client
  15. from . import verbose_proxy
  16. from . import errors
  17. from .. import __version__
  18. log = logging.getLogger(__name__)
  19. class Command(DocoptCommand):
  20. base_dir = '.'
  21. def dispatch(self, *args, **kwargs):
  22. try:
  23. super(Command, self).dispatch(*args, **kwargs)
  24. except SSLError, 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', 'boot2docker']) == 0:
  35. raise errors.ConnectionErrorBoot2Docker()
  36. else:
  37. raise errors.ConnectionErrorGeneric(self.get_client().base_url)
  38. def perform_command(self, options, handler, command_options):
  39. if options['COMMAND'] == 'help':
  40. # Skip looking up the figfile.
  41. handler(None, command_options)
  42. return
  43. explicit_config_path = options.get('--file') or os.environ.get('FIG_FILE')
  44. project = self.get_project(
  45. self.get_config_path(explicit_config_path),
  46. project_name=options.get('--project-name'),
  47. verbose=options.get('--verbose'))
  48. handler(project, command_options)
  49. def get_client(self, verbose=False):
  50. client = docker_client()
  51. if verbose:
  52. version_info = six.iteritems(client.version())
  53. log.info("Fig version %s", __version__)
  54. log.info("Docker base_url: %s", client.base_url)
  55. log.info("Docker version: %s",
  56. ", ".join("%s=%s" % item for item in version_info))
  57. return verbose_proxy.VerboseProxy('docker', client)
  58. return client
  59. def get_config(self, config_path):
  60. try:
  61. with open(config_path, 'r') as fh:
  62. return yaml.safe_load(fh)
  63. except IOError as e:
  64. if e.errno == errno.ENOENT:
  65. raise errors.FigFileNotFound(os.path.basename(e.filename))
  66. raise errors.UserError(six.text_type(e))
  67. def get_project(self, config_path, project_name=None, verbose=False):
  68. try:
  69. return Project.from_config(
  70. self.get_project_name(config_path, project_name),
  71. self.get_config(config_path),
  72. self.get_client(verbose=verbose))
  73. except ConfigError as e:
  74. raise errors.UserError(six.text_type(e))
  75. def get_project_name(self, config_path, project_name=None):
  76. def normalize_name(name):
  77. return re.sub(r'[^a-zA-Z0-9]', '', name)
  78. project_name = project_name or os.environ.get('FIG_PROJECT_NAME')
  79. if project_name is not None:
  80. return normalize_name(project_name)
  81. project = os.path.basename(os.path.dirname(os.path.abspath(config_path)))
  82. if project:
  83. return normalize_name(project)
  84. return 'default'
  85. def get_config_path(self, file_path=None):
  86. if file_path:
  87. return os.path.join(self.base_dir, file_path)
  88. if os.path.exists(os.path.join(self.base_dir, 'fig.yaml')):
  89. log.warning("Fig just read the file 'fig.yaml' on startup, rather "
  90. "than 'fig.yml'")
  91. log.warning("Please be aware that fig.yml the expected extension "
  92. "in most cases, and using .yaml can cause compatibility "
  93. "issues in future")
  94. return os.path.join(self.base_dir, 'fig.yaml')
  95. return os.path.join(self.base_dir, 'fig.yml')