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