dodo_utils.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import subprocess
  2. import time
  3. import os
  4. import fnmatch
  5. from doit import loader
  6. def wait_net_service(server, port, timeout=None):
  7. """ Wait for network service to appear
  8. @param timeout: in seconds, if None or 0 wait forever
  9. @return: True of False, if timeout is None may return only True or
  10. throw unhandled network exception
  11. """
  12. import socket
  13. import errno
  14. s = socket.socket()
  15. if timeout:
  16. from time import time as now
  17. # time module is needed to calc timeout shared between two exceptions
  18. end = now() + timeout
  19. while True:
  20. try:
  21. if timeout:
  22. next_timeout = end - now()
  23. if next_timeout < 0:
  24. return False
  25. else:
  26. s.settimeout(next_timeout)
  27. s.connect((server, port))
  28. except socket.timeout as err:
  29. # this exception occurs only if timeout is set
  30. if timeout:
  31. return False
  32. except (ConnectionRefusedError, ConnectionAbortedError):
  33. pass
  34. except socket.error as err:
  35. # catch timeout exception from underlying network library
  36. # this one is different from socket.timeout
  37. if type(err.args) != tuple or err.errno != errno.ETIMEDOUT:
  38. raise
  39. else:
  40. s.close()
  41. return True
  42. def wait_pgsql_db(container, dbname, user, timeout=60):
  43. container_id = subprocess.check_output(
  44. 'docker ps -qf name=feedati_db'.split()).decode('utf8').strip()
  45. print('container db=', container_id)
  46. cmd = ['docker', 'exec', container_id,
  47. 'psql', '-h', 'localhost', '-U', user, '-w', dbname]
  48. for i in range(timeout):
  49. try:
  50. subprocess.check_output(cmd, shell=False)
  51. except subprocess.CalledProcessError as exc:
  52. if exc.returncode == 2: # there's some more to wait
  53. time.sleep(1)
  54. continue
  55. raise
  56. else:
  57. return True
  58. def up2date_anyimages():
  59. cmd = "docker images -q feedati/*".split()
  60. output = subprocess.check_output(cmd).strip()
  61. if output:
  62. return True
  63. return False
  64. def up2date_hasimage(imagename):
  65. def fun():
  66. cmd = ' '.join(['docker', 'volume', 'ls',
  67. '-qf', 'name=%s' % imagename])
  68. out = subprocess.check_output(cmd, shell=True).decode('utf8').strip()
  69. if out:
  70. return True
  71. return False
  72. return fun
  73. def run(cmd, **kwargs):
  74. def fun():
  75. subprocess.check_call(cmd, **kwargs)
  76. return True
  77. return fun
  78. def run_task_func(taskf):
  79. ret = taskf()
  80. tasks = loader.generate_tasks(taskf.__name__, ret, taskf.__doc__)
  81. try:
  82. from doit.task import Stream
  83. stream = Stream(0)
  84. except ImportError:
  85. stream = None
  86. def fun():
  87. for task in tasks:
  88. if stream is None:
  89. task.execute()
  90. else:
  91. task.execute(stream)
  92. return True
  93. if tasks:
  94. fun.__doc__ = '\n'.join(t.doc for t in tasks)
  95. return fun
  96. def scan_dir(dirname, extension=None):
  97. if extension is None:
  98. extension = '*'
  99. for root, dirnames, filenames in os.walk(dirname):
  100. for fname in fnmatch.filter(filenames, extension):
  101. yield os.path.join(root, fname)