派生自 blallo/Feedati
119 行
3.3 KiB
Python
119 行
3.3 KiB
Python
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)
|