94 lines
3.2 KiB
Python
94 lines
3.2 KiB
Python
"""
|
|
instantiating, managing and rsyncing to test hosts
|
|
"""
|
|
|
|
import py
|
|
import sys, os
|
|
import execnet
|
|
from execnet.gateway_base import RemoteError
|
|
|
|
class GatewayManager:
|
|
RemoteError = RemoteError
|
|
def __init__(self, specs, hook, defaultchdir="pyexecnetcache"):
|
|
self.specs = []
|
|
self.hook = hook
|
|
self.group = execnet.Group()
|
|
for spec in specs:
|
|
if not isinstance(spec, execnet.XSpec):
|
|
spec = execnet.XSpec(spec)
|
|
if not spec.chdir and not spec.popen:
|
|
spec.chdir = defaultchdir
|
|
self.specs.append(spec)
|
|
|
|
def makegateways(self):
|
|
assert not list(self.group)
|
|
for spec in self.specs:
|
|
gw = self.group.makegateway(spec)
|
|
self.hook.pytest_gwmanage_newgateway(
|
|
gateway=gw, platinfo=gw._rinfo())
|
|
|
|
def rsync(self, source, notify=None, verbose=False, ignores=None):
|
|
""" perform rsync to all remote hosts.
|
|
"""
|
|
rsync = HostRSync(source, verbose=verbose, ignores=ignores)
|
|
seen = py.builtin.set()
|
|
gateways = []
|
|
for gateway in self.group:
|
|
spec = gateway.spec
|
|
if not spec._samefilesystem():
|
|
if spec not in seen:
|
|
def finished():
|
|
if notify:
|
|
notify("rsyncrootready", spec, source)
|
|
rsync.add_target_host(gateway, finished=finished)
|
|
seen.add(spec)
|
|
gateways.append(gateway)
|
|
if seen:
|
|
self.hook.pytest_gwmanage_rsyncstart(
|
|
source=source,
|
|
gateways=gateways,
|
|
)
|
|
rsync.send()
|
|
self.hook.pytest_gwmanage_rsyncfinish(
|
|
source=source,
|
|
gateways=gateways,
|
|
)
|
|
|
|
def exit(self):
|
|
self.group.terminate()
|
|
|
|
class HostRSync(execnet.RSync):
|
|
""" RSyncer that filters out common files
|
|
"""
|
|
def __init__(self, sourcedir, *args, **kwargs):
|
|
self._synced = {}
|
|
ignores= None
|
|
if 'ignores' in kwargs:
|
|
ignores = kwargs.pop('ignores')
|
|
self._ignores = ignores or []
|
|
super(HostRSync, self).__init__(sourcedir=sourcedir, **kwargs)
|
|
|
|
def filter(self, path):
|
|
path = py.path.local(path)
|
|
if not path.ext in ('.pyc', '.pyo'):
|
|
if not path.basename.endswith('~'):
|
|
if path.check(dotfile=0):
|
|
for x in self._ignores:
|
|
if path == x:
|
|
break
|
|
else:
|
|
return True
|
|
|
|
def add_target_host(self, gateway, finished=None):
|
|
remotepath = os.path.basename(self._sourcedir)
|
|
super(HostRSync, self).add_target(gateway, remotepath,
|
|
finishedcallback=finished,
|
|
delete=True,)
|
|
|
|
def _report_send_file(self, gateway, modified_rel_path):
|
|
if self._verbose:
|
|
path = os.path.basename(self._sourcedir) + "/" + modified_rel_path
|
|
remotepath = gateway.spec.chdir
|
|
py.builtin.print_('%s:%s <= %s' %
|
|
(gateway.spec, remotepath, path))
|