command.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. from __future__ import unicode_literals
  2. from __future__ import absolute_import
  3. from ..packages.docker import Client
  4. from requests.exceptions import ConnectionError
  5. import errno
  6. import logging
  7. import os
  8. import re
  9. import yaml
  10. import six
  11. import sys
  12. from ..project import Project
  13. from ..service import ConfigError
  14. from .docopt_command import DocoptCommand
  15. from .formatter import Formatter
  16. from .utils import cached_property, docker_url, call_silently, is_mac, is_ubuntu
  17. from .errors import UserError
  18. log = logging.getLogger(__name__)
  19. class Command(DocoptCommand):
  20. base_dir = '.'
  21. def __init__(self):
  22. self.yaml_path = os.environ.get('FIG_FILE', None)
  23. def dispatch(self, *args, **kwargs):
  24. try:
  25. super(Command, self).dispatch(*args, **kwargs)
  26. except ConnectionError:
  27. if call_silently(['which', 'docker']) != 0:
  28. if is_mac():
  29. raise UserError("""
  30. Couldn't connect to Docker daemon. You might need to install docker-osx:
  31. https://github.com/noplay/docker-osx
  32. """)
  33. elif is_ubuntu():
  34. raise UserError("""
  35. Couldn't connect to Docker daemon. You might need to install Docker:
  36. http://docs.docker.io/en/latest/installation/ubuntulinux/
  37. """)
  38. else:
  39. raise UserError("""
  40. Couldn't connect to Docker daemon. You might need to install Docker:
  41. http://docs.docker.io/en/latest/installation/
  42. """)
  43. elif call_silently(['which', 'docker-osx']) == 0:
  44. raise UserError("Couldn't connect to Docker daemon - you might need to run `docker-osx shell`.")
  45. else:
  46. raise UserError("""
  47. Couldn't connect to Docker daemon at %s - is it running?
  48. If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
  49. """ % self.client.base_url)
  50. def perform_command(self, options, *args, **kwargs):
  51. if options['--file'] is not None:
  52. self.yaml_path = os.path.join(self.base_dir, options['--file'])
  53. return super(Command, self).perform_command(options, *args, **kwargs)
  54. @cached_property
  55. def client(self):
  56. return Client(docker_url())
  57. @cached_property
  58. def project(self):
  59. try:
  60. yaml_path = self.yaml_path
  61. if yaml_path is None:
  62. yaml_path = self.check_yaml_filename()
  63. config = yaml.load(open(yaml_path))
  64. except IOError as e:
  65. if e.errno == errno.ENOENT:
  66. log.error("Can't find %s. Are you in the right directory?", os.path.basename(e.filename))
  67. else:
  68. log.error(e)
  69. sys.exit(1)
  70. try:
  71. return Project.from_config(self.project_name, config, self.client)
  72. except ConfigError as e:
  73. raise UserError(six.text_type(e))
  74. @cached_property
  75. def project_name(self):
  76. project = os.path.basename(os.getcwd())
  77. project = re.sub(r'[^a-zA-Z0-9]', '', project)
  78. if not project:
  79. project = 'default'
  80. return project
  81. @cached_property
  82. def formatter(self):
  83. return Formatter()
  84. def check_yaml_filename(self):
  85. if os.path.exists(os.path.join(self.base_dir, 'fig.yaml')):
  86. log.warning("Fig just read the file 'fig.yaml' on startup, rather than 'fig.yml'")
  87. log.warning("Please be aware that fig.yml the expected extension in most cases, and using .yaml can cause compatibility issues in future")
  88. return os.path.join(self.base_dir, 'fig.yaml')
  89. else:
  90. return os.path.join(self.base_dir, 'fig.yml')