111 lines
3.2 KiB
Python
111 lines
3.2 KiB
Python
|
import importlib
|
||
|
import os
|
||
|
|
||
|
from fabric.api import hide, local, settings, task
|
||
|
from fabric.api import get as _get, put as _put, run as _run, sudo as _sudo
|
||
|
|
||
|
dconf = None
|
||
|
|
||
|
|
||
|
def load_driver_conf():
|
||
|
driver_conf = os.environ.get('DRIVER_CONFIG', 'driver_config')
|
||
|
if driver_conf.endswith('.py'):
|
||
|
driver_conf = driver_conf[:-len('.py')]
|
||
|
dmod = importlib.import_module(driver_conf)
|
||
|
global dconf
|
||
|
if not dconf:
|
||
|
dconf = dmod
|
||
|
return dmod
|
||
|
|
||
|
|
||
|
def parse_bool(value):
|
||
|
if not isinstance(value, bool):
|
||
|
value = str(value).lower() == 'true'
|
||
|
return value
|
||
|
|
||
|
|
||
|
@task
|
||
|
def run(cmd, **kwargs):
|
||
|
try:
|
||
|
if dconf.HOST_CONN == 'remote':
|
||
|
res = _run(cmd, **kwargs)
|
||
|
elif dconf.HOST_CONN == 'local':
|
||
|
res = local(cmd, capture=True, **kwargs)
|
||
|
else: # docker
|
||
|
opts = ''
|
||
|
cmdd = cmd
|
||
|
if cmd.endswith('&'):
|
||
|
cmdd = cmd[:-1].strip()
|
||
|
opts = '-d '
|
||
|
res = local('docker exec {} -ti {} /bin/bash -c "{}"'.format(
|
||
|
opts, dconf.CONTAINER_NAME, cmdd),
|
||
|
capture=True, **kwargs)
|
||
|
except TypeError as e:
|
||
|
err = str(e).strip()
|
||
|
if 'unexpected keyword argument' in err:
|
||
|
offender = err.rsplit(' ', 1)[-1][1:-1]
|
||
|
kwargs.pop(offender)
|
||
|
res = run(cmd, **kwargs)
|
||
|
else:
|
||
|
raise e
|
||
|
return res
|
||
|
|
||
|
|
||
|
@task
|
||
|
def sudo(cmd, user=None, **kwargs):
|
||
|
if dconf.HOST_CONN == 'remote':
|
||
|
res = _sudo(cmd, user=user, **kwargs)
|
||
|
|
||
|
elif dconf.HOST_CONN == 'local':
|
||
|
pre_cmd = 'sudo '
|
||
|
if user:
|
||
|
pre_cmd += '-u {} '.format(user)
|
||
|
res = local(pre_cmd + cmd, capture=True, **kwargs)
|
||
|
|
||
|
else: # docker
|
||
|
user = user or 'root'
|
||
|
opts = '-ti -u {}'.format(user or 'root')
|
||
|
if user == 'root':
|
||
|
opts += ' -w /'
|
||
|
res = local('docker exec {} {} /bin/bash -c "{}"'.format(
|
||
|
opts, dconf.CONTAINER_NAME, cmd), capture=True)
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
@task
|
||
|
def get(remote_path, local_path, use_sudo=False):
|
||
|
use_sudo = parse_bool(use_sudo)
|
||
|
|
||
|
if dconf.HOST_CONN == 'remote':
|
||
|
res = _get(remote_path, local_path, use_sudo=use_sudo)
|
||
|
elif dconf.HOST_CONN == 'local':
|
||
|
pre_cmd = 'sudo ' if use_sudo else ''
|
||
|
opts = '-r' if os.path.isdir(remote_path) else ''
|
||
|
res = local('{}cp {} {} {}'.format(pre_cmd, opts, remote_path, local_path))
|
||
|
else: # docker
|
||
|
res = local('docker cp {}:{} {}'.format(dconf.CONTAINER_NAME, remote_path, local_path))
|
||
|
return res
|
||
|
|
||
|
|
||
|
@task
|
||
|
def put(local_path, remote_path, use_sudo=False):
|
||
|
use_sudo = parse_bool(use_sudo)
|
||
|
|
||
|
if dconf.HOST_CONN == 'remote':
|
||
|
res = _put(local_path, remote_path, use_sudo=use_sudo)
|
||
|
elif dconf.HOST_CONN == 'local':
|
||
|
pre_cmd = 'sudo ' if use_sudo else ''
|
||
|
opts = '-r' if os.path.isdir(local_path) else ''
|
||
|
res = local('{}cp {} {} {}'.format(pre_cmd, opts, local_path, remote_path))
|
||
|
else: # docker
|
||
|
res = local('docker cp {} {}:{}'.format(local_path, dconf.CONTAINER_NAME, remote_path))
|
||
|
return res
|
||
|
|
||
|
|
||
|
@task
|
||
|
def file_exists(filename):
|
||
|
with settings(warn_only=True), hide('warnings'):
|
||
|
res = run('[ -f {} ]'.format(filename))
|
||
|
return res.return_code == 0
|