110 lines
3.1 KiB
Python
110 lines
3.1 KiB
Python
import collections
|
|
import copy
|
|
from glob import glob
|
|
import subprocess
|
|
|
|
from .build import BuildScript
|
|
|
|
|
|
PACKAGE_MANAGERS = dict(
|
|
apk=dict(
|
|
update='apk update',
|
|
upgrade='apk upgrade',
|
|
install='apk add',
|
|
),
|
|
)
|
|
|
|
|
|
class Container(collections.UserDict):
|
|
cfg = dict()
|
|
|
|
def __init__(self, profile=None, **cfg):
|
|
newcfg = copy.deepcopy(self.cfg)
|
|
newcfg.update(cfg)
|
|
super().__init__(**newcfg)
|
|
self.profile = profile or 'default'
|
|
|
|
def __getitem__(self, name, type=None):
|
|
try:
|
|
result = super().__getitem__(name)
|
|
except KeyError:
|
|
if hasattr(self, name + '_get'):
|
|
result = self[name] = getattr(self, name + '_get')()
|
|
else:
|
|
raise
|
|
else:
|
|
if isinstance(result, (dict, list, tuple, switch)):
|
|
return self.switch_value(result)
|
|
return result
|
|
|
|
def switch_value(self, value):
|
|
_switch = lambda v: v.value(self) if isinstance(v, switch) else v
|
|
|
|
if isinstance(value, dict):
|
|
return {
|
|
k: self.switch_value(v)
|
|
for k, v in value.items()
|
|
if self.switch_value(v) is not None
|
|
}
|
|
elif isinstance(value, (list, tuple)):
|
|
return [
|
|
self.switch_value(i)
|
|
for i in value
|
|
if self.switch_value(i) is not None
|
|
]
|
|
else:
|
|
return _switch(value)
|
|
|
|
def script_build(self):
|
|
return BuildScript(self)
|
|
|
|
def package_manager_get(self):
|
|
for mgr in PACKAGE_MANAGERS.keys():
|
|
cmd = ['podman', 'run', self['base'], 'which', mgr]
|
|
try:
|
|
subprocess.check_call(cmd)
|
|
return mgr
|
|
break
|
|
except subprocess.CalledProcessError:
|
|
continue
|
|
raise Exception('Package manager not supported yet')
|
|
|
|
def package_manager_cmd(self, cmd):
|
|
return PACKAGE_MANAGERS[self['package_manager']][cmd]
|
|
|
|
def packages_install(self, script):
|
|
cache = f'.cache/{self["package_manager"]}'
|
|
script.mount(
|
|
'$(pwd)/' + cache,
|
|
f'/var/cache/{self["package_manager"]}'
|
|
)
|
|
|
|
cached = False
|
|
if self['package_manager'] == 'apk':
|
|
# special step to enable apk cache
|
|
script.run('ln -s /var/cache/apk /etc/apk/cache')
|
|
script.append(f'''
|
|
if [ -n "$(find .cache/apk/ -name APKINDEX.* -mtime +3)" ]; then
|
|
buildah run $ctr -- {self.package_manager_cmd("update")}
|
|
fi
|
|
''')
|
|
|
|
script.run(self.package_manager_cmd('upgrade'))
|
|
script.run(' '.join([
|
|
self.package_manager_cmd('install'),
|
|
' '.join(self.get('packages', []))
|
|
]))
|
|
|
|
|
|
class switch:
|
|
def __init__(self, **values):
|
|
"""Instanciate a switch to vary values based on container profile."""
|
|
self.values = values
|
|
|
|
def value(self, container):
|
|
"""Return value from container profile or default."""
|
|
return self.values.get(
|
|
container.profile,
|
|
self.values.get('default', None)
|
|
)
|