Thread safety, cleaning
This commit is contained in:
parent
3afc739a1e
commit
c96d2494d2
@ -85,7 +85,7 @@ class Action:
|
||||
for a in self.parents() + self.sibblings() + self.children():
|
||||
if name in a.contextualize:
|
||||
return getattr(a, name)
|
||||
raise AttributeError(name)
|
||||
raise AttributeError(f'{type(self).__name__} has no {name}')
|
||||
|
||||
async def call(self, *args, **kwargs):
|
||||
print(f'{self}.call(*args, **kwargs) not implemented')
|
||||
@ -101,23 +101,34 @@ class Action:
|
||||
self.status = 'running'
|
||||
try:
|
||||
result = await self.call(*args, **kwargs)
|
||||
except WrongResult as e:
|
||||
except Exception as e:
|
||||
self.output_fail(e)
|
||||
self.status = 'fail'
|
||||
result = e.proc.rc
|
||||
proc = getattr(e, 'proc', None)
|
||||
result = proc.rc if proc else 1
|
||||
else:
|
||||
self.output_success()
|
||||
if self.status == 'running':
|
||||
self.status = 'success'
|
||||
finally:
|
||||
clean = getattr(self, 'clean', None)
|
||||
if clean:
|
||||
await clean(*args, **kwargs)
|
||||
return result
|
||||
|
||||
def output_start(self):
|
||||
if self.kwargs.get('quiet', False):
|
||||
return
|
||||
self.output.start(self)
|
||||
|
||||
def output_fail(self, exception=None):
|
||||
if self.kwargs.get('quiet', False):
|
||||
return
|
||||
self.output.fail(self, exception)
|
||||
|
||||
def output_success(self):
|
||||
if self.kwargs.get('quiet', False):
|
||||
return
|
||||
self.output.success(self)
|
||||
|
||||
def __repr__(self):
|
||||
@ -130,15 +141,16 @@ class Action:
|
||||
return ' '.join([
|
||||
self.output.colors['pink1']
|
||||
+ type(self).__name__
|
||||
+ self.output.colors['reset']
|
||||
+ self.output.colors['yellow']
|
||||
] + list(self.args) + [
|
||||
f'{self.output.colors["blue"]}{k}{self.output.colors["gray"]}={self.output.colors["green2"]}{v}'
|
||||
for k, v in self.kwargs_output().items()
|
||||
] + [self.output.colors['reset']])
|
||||
|
||||
def callable(self):
|
||||
from ..targets import Localhost
|
||||
async def cb(*a, **k):
|
||||
return await self(*a, **k)
|
||||
return await Localhost(self, quiet=True)(*a, **k)
|
||||
return cb
|
||||
|
||||
def kwargs_output(self):
|
||||
|
||||
@ -2,9 +2,5 @@ from .base import Action
|
||||
|
||||
|
||||
class Copy(Action):
|
||||
def __init__(self, *args):
|
||||
self.src = args[:-1]
|
||||
self.dst = args[-1]
|
||||
|
||||
def call(self, *args, **kwargs):
|
||||
self.copy(self.src, self.dst)
|
||||
async def call(self, *args, **kwargs):
|
||||
await self.copy(*self.args)
|
||||
|
||||
@ -12,10 +12,10 @@ class Pip(Action):
|
||||
def __init__(self, *pip_packages, pip=None, requirements=None):
|
||||
self.pip_packages = pip_packages
|
||||
self.requirements = requirements
|
||||
super().__init__(*pip_packages, pip=pip, requirements=requirements)
|
||||
|
||||
async def call(self, *args, **kwargs):
|
||||
breakpoint()
|
||||
self.pip = await self.which(('pip3', 'pip', 'pip2'))
|
||||
self.pip = await self.which('pip3', 'pip', 'pip2')
|
||||
if not self.pip:
|
||||
raise Exception('Could not find pip command')
|
||||
|
||||
|
||||
@ -60,6 +60,7 @@ class Output:
|
||||
self(
|
||||
self.colorize(251, '+')
|
||||
+ '\x1b[1;38;5;15;48;5;244m'
|
||||
+ ' '
|
||||
+ self.highlight(line, 'bash')
|
||||
+ self.colors['reset'],
|
||||
highlight=False
|
||||
|
||||
@ -14,6 +14,7 @@ class Actions(list):
|
||||
self.append(action)
|
||||
|
||||
def append(self, value):
|
||||
value = copy.deepcopy(value)
|
||||
value.parent = self.owner
|
||||
value.status = 'pending'
|
||||
super().append(value)
|
||||
@ -21,7 +22,7 @@ class Actions(list):
|
||||
|
||||
class Script(Action):
|
||||
root = '/'
|
||||
contextualize = ['shargs', 'exec', 'rexec', 'env', 'which']
|
||||
contextualize = ['shargs', 'exec', 'rexec', 'env', 'which', 'copy']
|
||||
|
||||
def __init__(self, *actions, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
@ -77,3 +78,7 @@ class Script(Action):
|
||||
p = os.path.join(self.root, path[1:], c)
|
||||
if os.path.exists(p):
|
||||
return p[len(str(self.root)):]
|
||||
|
||||
async def copy(self, *args):
|
||||
args = ['cp', '-ra'] + list(args)
|
||||
return await self.exec(*args)
|
||||
|
||||
@ -49,17 +49,27 @@ class Buildah(Localhost):
|
||||
|
||||
async def config(self, line):
|
||||
"""Run buildah config."""
|
||||
return await self.exec(f'buildah config {line} {self.ctr}')
|
||||
return await self.exec(f'buildah config {line} {self.ctr}', buildah=False)
|
||||
|
||||
async def copy(self, src, dst):
|
||||
async def mkdir(self, *dirs):
|
||||
return await self.exec(*['mkdir', '-p'] + list(dirs))
|
||||
|
||||
async def copy(self, *args):
|
||||
"""Run buildah copy to copy a file from host into container."""
|
||||
return await self.exec(f'buildah copy {self.ctr} {src} {self.mnt}{dst}')
|
||||
src = args[:-1]
|
||||
dst = args[-1]
|
||||
await self.mkdir(dst)
|
||||
|
||||
args = ['buildah', 'copy', self.ctr] + list(
|
||||
[str(a) for a in src]
|
||||
) + [str(dst)]
|
||||
return await self.exec(*args, buildah=False)
|
||||
|
||||
async def mount(self, src, dst):
|
||||
"""Mount a host directory into the container."""
|
||||
target = self.mnt / str(dst)[1:]
|
||||
await super().exec(f'mkdir -p {src} {target}')
|
||||
await super().exec(f'mount -o bind {src} {target}')
|
||||
await self.exec(f'mkdir -p {src} {target}')
|
||||
await self.exec(f'mount -o bind {src} {target}')
|
||||
self.mounts[src] = dst
|
||||
|
||||
async def umounts(self):
|
||||
@ -88,18 +98,19 @@ class Buildah(Localhost):
|
||||
def __repr__(self):
|
||||
return f'Build'
|
||||
|
||||
async def call(self, *args, debug=False, **kwargs):
|
||||
if Proc.test or os.getuid() == 0 or self.parent.parent:
|
||||
@property
|
||||
def _compatible(self):
|
||||
return Proc.test or os.getuid() == 0 or getattr(self.parent, 'parent', None)
|
||||
|
||||
async def call(self, *args, **kwargs):
|
||||
if self._compatible:
|
||||
self.ctr = (await self.exec('buildah', 'from', self.base, buildah=False)).out
|
||||
self.mnt = Path((await self.exec('buildah', 'mount', self.ctr, buildah=False)).out)
|
||||
|
||||
result = await super().call(*args, **kwargs)
|
||||
#await self.umounts()
|
||||
#await self.umount()
|
||||
await self.exec('buildah', 'rm', self.ctr, raises=False, buildah=False)
|
||||
return result
|
||||
return await super().call(*args, **kwargs)
|
||||
|
||||
from shlax.cli import cli
|
||||
debug = kwargs.get('debug', False)
|
||||
# restart under buildah unshare environment
|
||||
argv = [
|
||||
'buildah', 'unshare',
|
||||
@ -123,3 +134,8 @@ class Buildah(Localhost):
|
||||
)
|
||||
await proc.communicate()
|
||||
cli.exit_code = await proc.wait()
|
||||
|
||||
async def clean(self, *args, **kwargs):
|
||||
#await self.umounts()
|
||||
#await self.umount()
|
||||
await self.exec('buildah', 'rm', self.ctr, raises=False, buildah=False)
|
||||
|
||||
@ -4,6 +4,9 @@ inner = Run()
|
||||
other = Run('ls')
|
||||
middle = Buildah('alpine', inner, other)
|
||||
outer = Localhost(middle)
|
||||
middle = outer.actions[0]
|
||||
other = middle.actions[1]
|
||||
inner = middle.actions[0]
|
||||
|
||||
|
||||
def test_action_init_args():
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user