async def mkdir(self, path, mode=511, **kwargs): async with self.connect_sftp() as sftp: attrs = asyncssh.SFTPAttrs() attrs.permissions = mode for k, v in kwargs.items(): attrs.__setattr__(k, v) await sftp.mkdir(self.absolute(path), attrs)
async def put_string_script(self, script_body, remotefile, **kwds): """ A convenience for copying over a local script before remote execution. The ssh connection and SFTP subsystem are created and set up if needed. Resulting remote file has mode `755`. Parameters: script_body (str): the **contents** of the script to create **WARNING** this is **not** a filename. remotefile: filename on the remote end kwds: passed along to http://asyncssh.readthedocs.io/en/latest/api.html#asyncssh.SFTPClient.open i.e. for setting ``encoding`` or ``errors``. Returns: True if all went well, or raise exception """ await self.sftp_connect_lazy() sftp_attrs = asyncssh.SFTPAttrs() sftp_attrs.permissions = 0o755 try: async with self.sftp_client.open(remotefile, pflags_or_mode='w', attrs=sftp_attrs, **kwds) as writer: await writer.write(script_body) except Exception as exc: self.debug_line( "Could not create remotefile {} - exception={}".format( remotefile, exc)) raise exc return True
async def _writefile(self, origin, target, mtime): path = self.sftp.encode(os.path.dirname(target)) curpath = b'/' if posixpath.isabs(path) else (self.sftp._cwd or b'') for part in path.split(b'/'): curpath = posixpath.join(curpath, part) try: await self.sftp.mkdir(curpath, asyncssh.SFTPAttrs()) except asyncssh.SFTPFailure: mode = await self.sftp._mode(curpath) if not stat.S_ISDIR(mode): path = curpath.decode('utf-8', errors='replace') raise asyncssh.SFTPFailure( f'{path} is not a directory') from None data = BytesIO(origin).read() async with self.open_sem: attrs = asyncssh.SFTPAttrs(atime=mtime.timestamp(), mtime=mtime.timestamp()) async with self.sftp.open(target, 'wb', attrs) as dst: await dst.write(data) await dst.utime(times=(mtime.timestamp(), mtime.timestamp()))