diff --git a/fdroidserver/build.py b/fdroidserver/build.py index c146b95f..8f844a06 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -41,6 +41,7 @@ from . import scanner from . import vmtools from .common import FDroidPopen, SdkToolsPopen from .exception import FDroidException, BuildException, VCSException +from .vmtools import FDroidBuildVmException try: import paramiko @@ -264,7 +265,16 @@ def vm_new_get_clean_builder(serverdir, reset=False): vm.snapshot_revert('fdroidclean') vm.up() - return get_vagrant_sshinfo() + try: + sshinfo = vm.sshinfo() + except FDroidBuildVmException: + # workaround because libvirt sometimes likes to forget + # about ssh connection info even thou the vm is running + vm.halt() + vm.up() + sshinfo = vm.sshinfo() + + return sshinfo def vm_get_clean_builder(reset=False): diff --git a/fdroidserver/vmtools.py b/fdroidserver/vmtools.py index ec28ed48..f48ea2d5 100644 --- a/fdroidserver/vmtools.py +++ b/fdroidserver/vmtools.py @@ -236,6 +236,33 @@ class FDroidBuildVm(): boxname, boxpath) shutil.rmtree(boxpath) + def sshinfo(self): + """Get ssh connection info for a vagrant VM + + :returns: A dictionary containing 'hostname', 'port', 'user' + and 'idfile' + """ + import paramiko + try: + _check_call(['vagrant ssh-config > sshconfig'], + cwd=self.srvdir, shell=True) + vagranthost = 'default' # Host in ssh config file + sshconfig = paramiko.SSHConfig() + with open(joinpath(self.srvdir, 'sshconfig'), 'r') as f: + sshconfig.parse(f) + sshconfig = sshconfig.lookup(vagranthost) + idfile = sshconfig['identityfile'] + if isinstance(idfile, list): + idfile = idfile[0] + elif idfile.startswith('"') and idfile.endswith('"'): + idfile = idfile[1:-1] + return {'hostname': sshconfig['hostname'], + 'port': int(sshconfig['port']), + 'user': sshconfig['user'], + 'idfile': idfile} + except subprocess.CalledProcessError as e: + raise FDroidBuildVmException("Error getting ssh config") from e + def snapshot_create(self, snapshot_name): raise NotImplementedError('not implemented, please use a sub-type instance')