utils.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. from __future__ import unicode_literals
  2. from __future__ import absolute_import
  3. from __future__ import division
  4. from .. import __version__
  5. import datetime
  6. from docker import version as docker_py_version
  7. import os
  8. import platform
  9. import subprocess
  10. import ssl
  11. def yesno(prompt, default=None):
  12. """
  13. Prompt the user for a yes or no.
  14. Can optionally specify a default value, which will only be
  15. used if they enter a blank line.
  16. Unrecognised input (anything other than "y", "n", "yes",
  17. "no" or "") will return None.
  18. """
  19. answer = raw_input(prompt).strip().lower()
  20. if answer == "y" or answer == "yes":
  21. return True
  22. elif answer == "n" or answer == "no":
  23. return False
  24. elif answer == "":
  25. return default
  26. else:
  27. return None
  28. # http://stackoverflow.com/a/5164027
  29. def prettydate(d):
  30. diff = datetime.datetime.utcnow() - d
  31. s = diff.seconds
  32. if diff.days > 7 or diff.days < 0:
  33. return d.strftime('%d %b %y')
  34. elif diff.days == 1:
  35. return '1 day ago'
  36. elif diff.days > 1:
  37. return '{0} days ago'.format(diff.days)
  38. elif s <= 1:
  39. return 'just now'
  40. elif s < 60:
  41. return '{0} seconds ago'.format(s)
  42. elif s < 120:
  43. return '1 minute ago'
  44. elif s < 3600:
  45. return '{0} minutes ago'.format(s / 60)
  46. elif s < 7200:
  47. return '1 hour ago'
  48. else:
  49. return '{0} hours ago'.format(s / 3600)
  50. def mkdir(path, permissions=0o700):
  51. if not os.path.exists(path):
  52. os.mkdir(path)
  53. os.chmod(path, permissions)
  54. return path
  55. def find_candidates_in_parent_dirs(filenames, path):
  56. """
  57. Given a directory path to start, looks for filenames in the
  58. directory, and then each parent directory successively,
  59. until found.
  60. Returns tuple (candidates, path).
  61. """
  62. candidates = [filename for filename in filenames
  63. if os.path.exists(os.path.join(path, filename))]
  64. if len(candidates) == 0:
  65. parent_dir = os.path.join(path, '..')
  66. if os.path.abspath(parent_dir) != os.path.abspath(path):
  67. return find_candidates_in_parent_dirs(filenames, parent_dir)
  68. return (candidates, path)
  69. def split_buffer(reader, separator):
  70. """
  71. Given a generator which yields strings and a separator string,
  72. joins all input, splits on the separator and yields each chunk.
  73. Unlike string.split(), each chunk includes the trailing
  74. separator, except for the last one if none was found on the end
  75. of the input.
  76. """
  77. buffered = str('')
  78. separator = str(separator)
  79. for data in reader:
  80. buffered += data
  81. while True:
  82. index = buffered.find(separator)
  83. if index == -1:
  84. break
  85. yield buffered[:index + 1]
  86. buffered = buffered[index + 1:]
  87. if len(buffered) > 0:
  88. yield buffered
  89. def call_silently(*args, **kwargs):
  90. """
  91. Like subprocess.call(), but redirects stdout and stderr to /dev/null.
  92. """
  93. with open(os.devnull, 'w') as shutup:
  94. return subprocess.call(*args, stdout=shutup, stderr=shutup, **kwargs)
  95. def is_mac():
  96. return platform.system() == 'Darwin'
  97. def is_ubuntu():
  98. return platform.system() == 'Linux' and platform.linux_distribution()[0] == 'Ubuntu'
  99. def get_version_info(scope):
  100. versioninfo = 'docker-compose version: %s' % __version__
  101. if scope == 'compose':
  102. return versioninfo
  103. elif scope == 'full':
  104. return versioninfo + '\n' \
  105. + "docker-py version: %s\n" % docker_py_version \
  106. + "%s version: %s\n" % (platform.python_implementation(), platform.python_version()) \
  107. + "OpenSSL version: %s" % ssl.OPENSSL_VERSION
  108. else:
  109. raise RuntimeError('passed unallowed value to `cli.utils.get_version_info`')