Refactor into visitor pattern
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
from .base import Base # noqa
|
||||
from .config import Config # noqa
|
||||
from .copy import Copy # noqa
|
||||
from .packages import Packages # noqa
|
||||
from .pip import Pip # noqa
|
||||
from .run import Run # noqa
|
||||
from .tag import Tag # noqa
|
||||
from .user import User # noqa
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
class Base:
|
||||
def __init__(self, base):
|
||||
self.base = base
|
||||
@@ -0,0 +1,7 @@
|
||||
class Config:
|
||||
def __init__(self, **values):
|
||||
self.values = values
|
||||
|
||||
def post_build(self, script):
|
||||
for key, value in self.values.items():
|
||||
script.config(f'--{key} {value}')
|
||||
@@ -0,0 +1,26 @@
|
||||
class Copy:
|
||||
def __init__(self, src, dst):
|
||||
self.src = src
|
||||
self.dst = dst
|
||||
|
||||
def init_build(self, script):
|
||||
count = self.dst.count(':')
|
||||
self.mode = None
|
||||
self.owner = None
|
||||
if count == 2:
|
||||
self.dst, self.mode, self.owner = self.dst.split(':')
|
||||
elif count == 1:
|
||||
self.dst, self.mode = self.dst.split(':')
|
||||
self.owner = script.variable('user')
|
||||
|
||||
def build(self, script):
|
||||
if isinstance(self.src, list):
|
||||
script.run(f'sudo mkdir -p {self.dst}')
|
||||
for item in self.src:
|
||||
script.append(f'cp -a {item} $mnt{self.dst}')
|
||||
|
||||
if self.mode:
|
||||
script.run(f'sudo chmod {self.mode} $mnt{self.dst}')
|
||||
|
||||
if self.owner:
|
||||
script.run(f'sudo chown -R {self.owner} $mnt{self.dst}')
|
||||
@@ -0,0 +1,54 @@
|
||||
import subprocess
|
||||
|
||||
|
||||
class Packages:
|
||||
mgrs = dict(
|
||||
apk=dict(
|
||||
update='sudo apk update',
|
||||
upgrade='sudo apk upgrade',
|
||||
install='sudo apk add',
|
||||
),
|
||||
)
|
||||
|
||||
def __init__(self, *packages):
|
||||
self.packages = list(packages)
|
||||
|
||||
def pre_build(self, script):
|
||||
for mgr, cmds in self.mgrs.items():
|
||||
cmd = [
|
||||
'podman',
|
||||
'run',
|
||||
script.container.variable('base'),
|
||||
'which',
|
||||
mgr
|
||||
]
|
||||
print('+ ' + ' '.join(cmd))
|
||||
try:
|
||||
subprocess.check_call(cmd)
|
||||
self.mgr = mgr
|
||||
self.cmds = cmds
|
||||
break
|
||||
except subprocess.CalledProcessError:
|
||||
continue
|
||||
|
||||
def build(self, script):
|
||||
cache = f'.cache/{self.mgr}'
|
||||
script.mount(
|
||||
'$(pwd)/' + cache,
|
||||
f'/var/cache/{self.mgr}'
|
||||
)
|
||||
|
||||
if self.mgr == 'apk':
|
||||
# special step to enable apk cache
|
||||
script.run('ln -s /var/cache/apk /etc/apk/cache')
|
||||
script.append(f'''
|
||||
old="$(find .cache/apk/ -name APKINDEX.* -mtime +3)"
|
||||
if [ -n "$old" ] || ! ls .cache/apk/APKINDEX.*; then
|
||||
{script._run(self.cmds['update'])}
|
||||
else
|
||||
echo Cache recent enough, skipping index update.
|
||||
fi
|
||||
''')
|
||||
|
||||
script.run(self.cmds['upgrade'])
|
||||
script.run(' '.join([self.cmds['install']] + self.packages))
|
||||
@@ -0,0 +1,25 @@
|
||||
class Pip:
|
||||
def __init__(self, *pip_packages):
|
||||
self.pip_packages = pip_packages
|
||||
|
||||
def build(self, script):
|
||||
script.append(f'''
|
||||
if {script._run("bash -c 'type pip3'")}; then
|
||||
_pip=pip3
|
||||
elif {script._run("bash -c 'type pip'")}; then
|
||||
_pip=pip
|
||||
elif {script._run("bash -c 'type pip2'")}; then
|
||||
_pip=pip2
|
||||
fi
|
||||
''')
|
||||
script.mount('.cache/pip', '/root/.cache/pip')
|
||||
script.run('sudo $_pip install --upgrade pip')
|
||||
source = [p for p in self.pip_packages if p.startswith('/')]
|
||||
if source:
|
||||
script.run(
|
||||
f'sudo $_pip install --upgrade --editable {" ".join(source)}'
|
||||
)
|
||||
|
||||
nonsource = [p for p in self.pip_packages if not p.startswith('/')]
|
||||
if nonsource:
|
||||
script.run(f'sudo $_pip install --upgrade {" ".join(source)}')
|
||||
@@ -0,0 +1,7 @@
|
||||
class Run:
|
||||
def __init__(self, *commands):
|
||||
self.commands = commands
|
||||
|
||||
def build(self, script):
|
||||
for command in self.commands:
|
||||
script.run(command)
|
||||
@@ -0,0 +1,6 @@
|
||||
class Tag:
|
||||
def __init__(self, tag):
|
||||
self.tag = tag
|
||||
|
||||
def post_build(self, script):
|
||||
script.append(f'umounts && trap - 0 && buildah commit $ctr {self.tag}')
|
||||
@@ -0,0 +1,37 @@
|
||||
from .packages import Packages
|
||||
|
||||
|
||||
class User:
|
||||
"""Secure the image with a user"""
|
||||
|
||||
def __init__(self, username, uid, home):
|
||||
self.username = username
|
||||
self.uid = uid
|
||||
self.home = home
|
||||
self.user_created = False
|
||||
|
||||
def init_build(self, script):
|
||||
"""Inject the Packages visitor if necessary."""
|
||||
packages = script.container.visitor('packages')
|
||||
if not packages:
|
||||
index = script.container.visitors.index(self)
|
||||
script.container.visitors.insert(index, Packages())
|
||||
|
||||
def pre_build(self, script):
|
||||
"""Inject the shadow package for the usermod command"""
|
||||
if script.container.variable('mgr') == 'apk':
|
||||
script.container.variable('packages').append('shadow')
|
||||
|
||||
def build(self, script):
|
||||
script.append(f'''
|
||||
if buildah run $ctr -- id {self.uid}; then
|
||||
i=$(buildah run $ctr -- id -n {self.uid})
|
||||
buildah run $ctr -- usermod --home-dir {self.home} --no-log-init {self.uid} $i
|
||||
else
|
||||
buildah run $ctr -- useradd --home-dir {self.home} --uid {self.uid} {self.username}
|
||||
fi
|
||||
''') # noqa
|
||||
self.user_created = True
|
||||
|
||||
def post_build(self, script):
|
||||
script.config(f'--user {self.username}')
|
||||
Reference in New Issue
Block a user