diff --git a/src/python/jw/pkg/lib/ExecContext.py b/src/python/jw/pkg/lib/ExecContext.py index 6cb8d747..ebbf0f16 100644 --- a/src/python/jw/pkg/lib/ExecContext.py +++ b/src/python/jw/pkg/lib/ExecContext.py @@ -286,6 +286,122 @@ class ExecContext(abc.ABC): cc.check_exit_code(ret) return ret + async def _get( + self, + path: str, + wd: str|None, + throw: bool, + verbose: bool|None, + title: str + ) -> Result: + ret = Result(None, None, 1) + if wd is not None: + path = wd + '/' + path + with self.CallContext(self, title=title, cmd=['cat', path], + cmd_input=InputMode.NonInteractive, wd=None, + log_prefix='|', throw=throw, verbose=verbose) as cc: + try: + ret = await self._run( + cmd=cc.cmd, + wd=wd, + verbose=cc.verbose, + cmd_input=cc.cmd_input, + env=None, + interactive=cc.interactive, + log_prefix=cc.log_prefix + ) + except Exception as e: + return cc.exception(ret, e) + cc.check_exit_code(ret) + return ret + + async def get( + self, + path: str, + wd: str|None = None, + throw: bool = True, + verbose: bool|None = None, + title: str=None, + owner: str|None=None, + group: str|None=None, + mode: str|None=None, + ) -> Result: + return await self._get(path, wd=wd, throw=throw, verbose=verbose, title=title) + + async def _put( + self, + content: bytes, + path: str, + wd: str|None, + throw: bool, + verbose: bool|None, + title: str, + owner: str|None, + group: str|None, + mode: str|None, + ) -> Result: + + from .util import pretty_cmd + + async def __run(cmd: list[str], cmd_input: Input=InputMode.NonInteractive) -> Result: + with self.CallContext(self, title=title, cmd=cmd, cmd_input=cmd_input, wd=None, + log_prefix='|', throw=True, verbose=verbose) as cc: + try: + ret = await self._run( + cmd=cc.cmd, + wd=cc.wd, + verbose=cc.verbose, + cmd_input=cc.cmd_input, + env=None, + interactive=cc.interactive, + log_prefix=cc.log_prefix + ) + except Exception as e: + return cc.exception(ret, e) + cc.check_exit_code(ret) + return ret + + ret = Result(None, None, 1) + try: + if wd is not None: + path = wd + '/' + path + tmp = (await __run(['mktemp', path + '.XXXXXX'])).stdout.decode().strip() + cmds: list[dict[str, str|list[str]|bool]] = [] + cmds.append({'cmd': ['tee', tmp], 'cmd_input': content}) + if owner is not None and group is not None: + cmds.append({'cmd': ['chown', f'{owner}:{group}', tmp]}) + elif owner is not None: + cmds.append({'cmd': ['chown', owner, tmp]}) + elif group is not None: + cmds.append({'cmd': ['chgrp', group, tmp]}) + if mode is not None: + cmds.append({'cmd': ['chmod', mode, tmp]}) + cmds.append({'cmd': ['mv', tmp, path]}) + for cmd in cmds: + log(DEBUG, f'{self.log_name}: Running {pretty_cmd(cmd['cmd'], wd)}') + ret = await __run(**cmd) + return ret + except: + if throw: + raise + return cc.exception(ret, e) + return ret + + async def put( + self, + content: str, + path: str, + wd: str|None = None, + throw: bool = True, + verbose: bool|None = None, + title: str=None, + owner: str|None=None, + group: str|None=None, + mode: str|None=None, + ) -> Result: + return await self._put(content, path, wd=wd, throw=throw, verbose=verbose, + title=title, owner=owner, group=group, mode=mode) + @classmethod def create(cls, uri: str, *args, **kwargs) -> Self: tokens = re.split(r'://', uri)