mirror of
ssh://git.janware.com/janware/proj/jw-pkg
synced 2026-04-24 09:13:37 +02:00
lib.FileContext.put(): Add parameter "atomic"
Add the parameter "atomic" to put() / _put(). If instructs the implementation to take extra precautions to make sure the operation either succeeds or fails entirely, i.e. doesn't leave a broken target file behind. Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
bbb2d16956
commit
94eee5c4bb
3 changed files with 16 additions and 26 deletions
|
|
@ -292,6 +292,7 @@ class ExecContext(Base):
|
||||||
owner: str|None,
|
owner: str|None,
|
||||||
group: str|None,
|
group: str|None,
|
||||||
mode: str|None,
|
mode: str|None,
|
||||||
|
atomic: bool,
|
||||||
) -> Result:
|
) -> Result:
|
||||||
|
|
||||||
from .util import pretty_cmd
|
from .util import pretty_cmd
|
||||||
|
|
@ -303,18 +304,19 @@ class ExecContext(Base):
|
||||||
try:
|
try:
|
||||||
if wd is not None:
|
if wd is not None:
|
||||||
path = wd + '/' + path
|
path = wd + '/' + path
|
||||||
tmp = (await __run(['mktemp', path + '.XXXXXX'])).stdout.decode().strip()
|
|
||||||
cmds: list[dict[str, str|list[str]|bool]] = []
|
cmds: list[dict[str, str|list[str]|bool]] = []
|
||||||
cmds.append({'cmd': ['tee', tmp], 'cmd_input': content})
|
out = (await __run(['mktemp', path + '.XXXXXX'])).stdout.decode().strip() if atomic else path
|
||||||
|
cmds.append({'cmd': ['tee', out], 'cmd_input': content})
|
||||||
if owner is not None and group is not None:
|
if owner is not None and group is not None:
|
||||||
cmds.append({'cmd': ['chown', f'{owner}:{group}', tmp]})
|
cmds.append({'cmd': ['chown', f'{owner}:{group}', out]})
|
||||||
elif owner is not None:
|
elif owner is not None:
|
||||||
cmds.append({'cmd': ['chown', owner, tmp]})
|
cmds.append({'cmd': ['chown', owner, out]})
|
||||||
elif group is not None:
|
elif group is not None:
|
||||||
cmds.append({'cmd': ['chgrp', group, tmp]})
|
cmds.append({'cmd': ['chgrp', group, out]})
|
||||||
if mode is not None:
|
if mode is not None:
|
||||||
cmds.append({'cmd': ['chmod', mode, tmp]})
|
cmds.append({'cmd': ['chmod', mode, out]})
|
||||||
cmds.append({'cmd': ['mv', tmp, path]})
|
if atomic:
|
||||||
|
cmds.append({'cmd': ['mv', out, path]})
|
||||||
for cmd in cmds:
|
for cmd in cmds:
|
||||||
log(DEBUG, f'{self.log_name}: Running {pretty_cmd(cmd['cmd'], wd)}')
|
log(DEBUG, f'{self.log_name}: Running {pretty_cmd(cmd['cmd'], wd)}')
|
||||||
ret = await __run(**cmd)
|
ret = await __run(**cmd)
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ class FileContext(abc.ABC):
|
||||||
owner: str|None,
|
owner: str|None,
|
||||||
group: str|None,
|
group: str|None,
|
||||||
mode: str|None,
|
mode: str|None,
|
||||||
|
atomic: bool,
|
||||||
) -> Result:
|
) -> Result:
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
@ -98,13 +99,14 @@ class FileContext(abc.ABC):
|
||||||
wd: str|None = None,
|
wd: str|None = None,
|
||||||
throw: bool = True,
|
throw: bool = True,
|
||||||
verbose: bool|None = None,
|
verbose: bool|None = None,
|
||||||
title: str=None,
|
title: str = None,
|
||||||
owner: str|None=None,
|
owner: str|None = None,
|
||||||
group: str|None=None,
|
group: str|None = None,
|
||||||
mode: str|None=None,
|
mode: str|None = None,
|
||||||
|
atomic: bool = False
|
||||||
) -> Result:
|
) -> Result:
|
||||||
return await self._put(content, path, wd=wd, throw=throw, verbose=verbose,
|
return await self._put(content, path, wd=wd, throw=throw, verbose=verbose,
|
||||||
title=title, owner=owner, group=group, mode=mode)
|
title=title, owner=owner, group=group, mode=mode, atomic=atomic)
|
||||||
|
|
||||||
async def _close(self) -> None:
|
async def _close(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -44,17 +44,3 @@ class Curl(Base):
|
||||||
path = '/' + path
|
path = '/' + path
|
||||||
cmd.append(self.__base_url + path)
|
cmd.append(self.__base_url + path)
|
||||||
return await self.__ec.run(cmd, throw=throw, verbose=verbose)
|
return await self.__ec.run(cmd, throw=throw, verbose=verbose)
|
||||||
|
|
||||||
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:
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue