import subprocess import time import os import fnmatch from doit import loader def wait_net_service(server, port, timeout=None): """ Wait for network service to appear @param timeout: in seconds, if None or 0 wait forever @return: True of False, if timeout is None may return only True or throw unhandled network exception """ import socket import errno s = socket.socket() if timeout: from time import time as now # time module is needed to calc timeout shared between two exceptions end = now() + timeout while True: try: if timeout: next_timeout = end - now() if next_timeout < 0: return False else: s.settimeout(next_timeout) s.connect((server, port)) except socket.timeout as err: # this exception occurs only if timeout is set if timeout: return False except (ConnectionRefusedError, ConnectionAbortedError): pass except socket.error as err: # catch timeout exception from underlying network library # this one is different from socket.timeout if type(err.args) != tuple or err.errno != errno.ETIMEDOUT: raise else: s.close() return True def wait_pgsql_db(container, dbname, user, timeout=60): container_id = subprocess.check_output( 'docker ps -qf name=feedati_db'.split()).decode('utf8').strip() print('container db=', container_id) cmd = ['docker', 'exec', container_id, 'psql', '-h', 'localhost', '-U', user, '-w', dbname] for i in range(timeout): try: subprocess.check_output(cmd, shell=False) except subprocess.CalledProcessError as exc: if exc.returncode == 2: # there's some more to wait time.sleep(1) continue raise else: return True def up2date_anyimages(): cmd = "docker images -q feedati/*".split() output = subprocess.check_output(cmd).strip() if output: return True return False def up2date_hasimage(imagename): def fun(): cmd = ' '.join(['docker', 'volume', 'ls', '-qf', 'name=%s' % imagename]) out = subprocess.check_output(cmd, shell=True).decode('utf8').strip() if out: return True return False return fun def run(cmd, **kwargs): def fun(): subprocess.check_call(cmd, **kwargs) return True return fun def run_task_func(taskf): ret = taskf() tasks = loader.generate_tasks(taskf.__name__, ret, taskf.__doc__) try: from doit.task import Stream stream = Stream(0) except ImportError: stream = None def fun(): for task in tasks: if stream is None: task.execute() else: task.execute(stream) return True if tasks: fun.__doc__ = '\n'.join(t.doc for t in tasks) return fun def scan_dir(dirname, extension=None): if extension is None: extension = '*' for root, dirnames, filenames in os.walk(dirname): for fname in fnmatch.filter(filenames, extension): yield os.path.join(root, fname)