Layers refactor

This commit is contained in:
jpic 2020-08-08 16:08:01 +02:00
parent cd9ccec19c
commit 9124e93dca
2 changed files with 41 additions and 31 deletions

View File

@ -1,21 +1,52 @@
import copy import json
import os import os
import re import re
class Layers(set):
def __init__(self, image):
self.image = image
async def ls(self, target):
"""Fetch layers from localhost"""
ret = set()
results = await target.parent.exec(
'buildah images --json',
quiet=True,
)
results = json.loads(results.out)
prefix = 'localhost/' + self.image.repository + ':layer-'
for result in results:
if not result.get('names', None):
continue
for name in result['names']:
if name.startswith(prefix):
self.add(name)
return self
async def rm(self, target, tags=None):
"""Drop layers for this image"""
if tags is None:
tags = [layer for layer in await self.ls(target)]
await target.exec('podman', 'rmi', *tags)
class Image: class Image:
PATTERN = re.compile( PATTERN = re.compile(
'^((?P<backend>[a-z]*)://)?((?P<registry>[^/]*[.][^/]*)/)?((?P<repository>[^:]+))?(:(?P<tags>.*))?$' # noqa '^((?P<backend>[a-z]*)://)?((?P<registry>[^/]*[.][^/]*)/)?((?P<repository>[^:]+))?(:(?P<tags>.*))?$' # noqa
, re.I , re.I
) )
def __init__(self, arg=None, format=None, backend=None, registry=None, repository=None, tags=None): def __init__(self, arg=None, format=None, backend=None, registry=None,
repository=None, tags=None):
self.arg = arg self.arg = arg
self.format = format self.format = format
self.backend = backend self.backend = backend
self.registry = registry self.registry = registry
self.repository = repository self.repository = repository
self.tags = tags or [] self.tags = tags or []
self.layers = Layers(self)
match = re.match(self.PATTERN, arg) match = re.match(self.PATTERN, arg)
if match: if match:
@ -53,8 +84,3 @@ class Image:
for tag in self.tags: for tag in self.tags:
await action.exec('buildah', 'push', f'{self.repository}:{tag}') await action.exec('buildah', 'push', f'{self.repository}:{tag}')
def layer(self, key):
layer = copy.deepcopy(self)
layer.tags = ['layer-' + key]
return layer

View File

@ -43,16 +43,15 @@ class Buildah(Target):
if not self.is_runnable(): if not self.is_runnable():
os.execvp('buildah', ['buildah', 'unshare'] + sys.argv) os.execvp('buildah', ['buildah', 'unshare'] + sys.argv)
# program has been replaced return # process has been replaced
layers = await self.layers() layers = await self.image.layers.ls(self)
keep = await self.cache_setup(layers, *actions) keep = await self.cache_setup(self.image.layers, *actions)
keepnames = [*map(lambda x: 'localhost/' + str(x), keep)] keepnames = [*map(lambda x: 'localhost/' + str(x), keep)]
self.invalidate = [name for name in layers if name not in keepnames] self.invalidate = [name for name in self.image.layers if name not in keepnames]
if self.invalidate: if self.invalidate:
self.output.info('Invalidating old layers') self.output.info('Invalidating old layers')
await self.parent.exec( await self.image.layers.rm(self.parent, self.invalidate)
'buildah', 'rmi', *self.invalidate, raises=False)
if actions: if actions:
actions = actions[len(keep):] actions = actions[len(keep):]
@ -68,23 +67,6 @@ class Buildah(Target):
return await super().__call__(*actions) return await super().__call__(*actions)
async def layers(self):
ret = set()
results = await self.parent.exec(
'buildah images --json',
quiet=True,
)
results = json.loads(results.out)
prefix = 'localhost/' + self.image.repository + ':layer-'
for result in results:
if not result.get('names', None):
continue
for name in result['names']:
if name.startswith(prefix):
ret.add(name)
return ret
async def cache_setup(self, layers, *actions): async def cache_setup(self, layers, *actions):
keep = [] keep = []
self.image_previous = Image(self.base) self.image_previous = Image(self.base)
@ -115,7 +97,9 @@ class Buildah(Target):
action_key = str(action) action_key = str(action)
key = prefix + action_key key = prefix + action_key
sha1 = hashlib.sha1(key.encode('ascii')) sha1 = hashlib.sha1(key.encode('ascii'))
return self.image.layer(sha1.hexdigest()) action_image = copy.deepcopy(self.image)
action_image.tags = ['layer-' + sha1.hexdigest()]
return action_image
async def action(self, action, reraise=False): async def action(self, action, reraise=False):
stop = await super().action(action, reraise) stop = await super().action(action, reraise)