X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=juju%2Fmachine.py;h=23b41c614bd36019140c136255fed8ab6ff72188;hb=c50c361a8b9a3bbf1a33f5659e492b481f065cd2;hp=18c333c17c11e3e29ccd9348aa62f7257719247d;hpb=49fe19ff5754ae8ce9365cd7bddbcd33f565bd69;p=osm%2FN2VC.git diff --git a/juju/machine.py b/juju/machine.py index 18c333c..23b41c6 100644 --- a/juju/machine.py +++ b/juju/machine.py @@ -1,9 +1,12 @@ +import asyncio import logging +import os from dateutil.parser import parse as parse_date from . import model, utils from .client import client +from .errors import JujuError log = logging.getLogger(__name__) @@ -124,20 +127,56 @@ class Machine(model.ModelEntity): ) return await self.ann_facade.Set([ann]) - def scp( - self, source_path, user=None, destination_path=None, proxy=False, - scp_opts=None): + async def scp_to(self, source, destination, user='ubuntu', proxy=False, + scp_opts=''): """Transfer files to this machine. - :param str source_path: Path of file(s) to transfer + :param str source: Local path of file(s) to transfer + :param str destination: Remote destination of transferred files :param str user: Remote username - :param str destination_path: Destination of transferred files on - remote machine :param bool proxy: Proxy through the Juju API server :param str scp_opts: Additional options to the `scp` command + """ + if proxy: + raise NotImplementedError('proxy option is not implemented') + + address = self.dns_name + destination = '%s@%s:%s' % (user, address, destination) + await self._scp(source, destination, scp_opts) + async def scp_from(self, source, destination, user='ubuntu', proxy=False, + scp_opts=''): + """Transfer files from this machine. + + :param str source: Remote path of file(s) to transfer + :param str destination: Local destination of transferred files + :param str user: Remote username + :param bool proxy: Proxy through the Juju API server + :param str scp_opts: Additional options to the `scp` command """ - raise NotImplementedError() + if proxy: + raise NotImplementedError('proxy option is not implemented') + + address = self.dns_name + source = '%s@%s:%s' % (user, address, source) + await self._scp(source, destination, scp_opts) + + async def _scp(self, source, destination, scp_opts): + """ Execute an scp command. Requires a fully qualified source and + destination. + """ + cmd = [ + 'scp', + '-i', os.path.expanduser('~/.local/share/juju/ssh/juju_id_rsa'), + '-o', 'StrictHostKeyChecking=no', + source, destination + ] + cmd += scp_opts.split() + loop = self.model.loop + process = await asyncio.create_subprocess_exec(*cmd, loop=loop) + await process.wait() + if process.returncode != 0: + raise JujuError("command failed: %s" % cmd) def ssh( self, command, user=None, proxy=False, ssh_opts=None): @@ -206,3 +245,18 @@ class Machine(model.ModelEntity): """ return parse_date(self.safe_data['instance-status']['since']) + + @property + def dns_name(self): + """Get the DNS name for this machine. This is a best guess based on the + addresses available in current data. + + May return None if no suitable address is found. + """ + for scope in ['public', 'local-cloud']: + addresses = self.safe_data['addresses'] or [] + addresses = [address for address in addresses + if address['scope'] == scope] + if addresses: + return addresses[0]['value'] + return None