shlax/podctl/build.py
2020-02-03 05:25:04 +01:00

114 lines
3.3 KiB
Python

import asyncio
import os
import asyncio
import signal
import subprocess
import textwrap
from .script import Script
class WrongResult(Exception):
pass
class Build(Script):
def __init__(self, container):
super().__init__()
self.container = container
self.log = []
self.mounts = dict()
async def cmd(self, line):
log = dict(cmd=line)
self.log.append(log)
line = self.unshare(line)
print(self.container.name + ' | ' + line)
def protocol_factory():
from .console_script import BuildStreamProtocol
return BuildStreamProtocol(
self.container,
limit=asyncio.streams._DEFAULT_LIMIT,
loop=self.loop,
)
transport, protocol = await self.loop.subprocess_shell(
protocol_factory,
line,
)
proc = asyncio.subprocess.Process(
transport,
protocol,
self.loop,
)
result = await proc.wait()
if result:
raise WrongResult(proc)
return proc
'''
proc = await asyncio.create_subprocess_shell(
line,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
'''
async def append(self, value):
for line in value.split('\n'):
if line.startswith('#') or not line.strip():
continue
log = dict(proc=await self.cmd(line))
log['stdout'], log['stderr'] = await log['proc'].communicate()
return log['stdout']
def unshare(self, line):
return 'buildah unshare ' + line
async def config(self, line):
return await self.append(f'buildah config {line} {self.ctr}')
def _run(self, cmd, inject=False):
user = self.container.variable('username')
_cmd = textwrap.dedent(cmd)
if cmd.startswith('sudo '):
_cmd = _cmd[5:]
heredoc = False
for i in ('\n', '>', '<', '|', '&'):
if i in _cmd:
heredoc = True
break
if heredoc:
_cmd = ''.join(['bash -eux <<__EOF\n', _cmd.strip(), '\n__EOF'])
if cmd.startswith('sudo '):
return f'buildah run --user root {self.ctr} -- {_cmd}'
elif user and self.container.variable('user_created'):
return f'buildah run --user {user} {self.ctr} -- {_cmd}'
else:
return f'buildah run {self.ctr} -- {_cmd}'
async def run(self, cmd):
return await self.append(self._run(cmd))
async def copy(self, src, dst):
return await self.append(f'buildah copy {self.ctr} {src} {dst}')
async def mount(self, src, dst):
await self.run('sudo mkdir -p ' + dst)
await self.append('mkdir -p ' + src)
await self.append(f'mount -o bind {src} {self.mnt}{dst}')
#await self.append('mounts=("$mnt' + dst + '" "${mounts[@]}")')
self.mounts[dst] = src
async def umounts(self):
for src, dst in self.mounts:
await self.append('buildah unmount ' + dst)
await self.append('buildah unmount ' + self.ctr)
def which(self, cmd):
for path in self.container.paths:
if os.path.exists(os.path.join(path, cmd)):
return True