Skip to content

Commit

Permalink
feat(fixuid): use docker cli instead of docker-py
Browse files Browse the repository at this point in the history
Close #207
  • Loading branch information
Toilal committed Oct 14, 2021
1 parent 0fd82e1 commit cba2394
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 42 deletions.
58 changes: 17 additions & 41 deletions ddb/feature/fixuid/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
import re
import shlex
from collections import namedtuple
from subprocess import CalledProcessError
from typing import Iterable

import docker
from chmod_monkey import tmp_chmod
from dockerfile_parse import DockerfileParser
from dotty_dict import Dotty

from ..copy.actions import copy_from_url
from ...action import Action
from ...action.action import EventBinding
from ...cache import global_cache
from ...config import config
from ...context import context
from ...event import events
from ...utils.file import force_remove
from ...utils.process import run

BuildServiceDef = namedtuple("BuildServiceDef", "context dockerfile")

Expand All @@ -28,7 +28,7 @@ class CustomDockerfileParser(DockerfileParser):
Custom class to implement entrypoint property with the same behavior as cmd property.
"""

def get_last_instruction(self, instruction_type, instruction_condition = lambda instruction: True):
def get_last_instruction(self, instruction_type, instruction_condition=lambda instruction: True):
"""
Determine the final instruction_type instruction, if any, in the final build stage.
instruction_types from earlier stages are ignored.
Expand Down Expand Up @@ -178,44 +178,22 @@ def name(self) -> str:
return "fixuid:docker"

@staticmethod
def _get_registry_data(image):
def _get_inspect_data(image):
context.log.warning("Loading registry data id for image %s...", image)
client = docker.from_env()
registry_data = client.images.get_registry_data(image)
context.log.success("Id retrieved for image %s (%s)", image, registry_data.id)
return registry_data

@staticmethod
def _load_image_attrs(image):
registry_data_id_cache_key = "docker.image.name." + image + ".registry_data"
registry_data_id = global_cache().get(registry_data_id_cache_key)
registry_data = None
if not registry_data_id:
registry_data = FixuidDockerComposeAction._get_registry_data(image)
registry_data_id = registry_data.id
global_cache().set(registry_data_id_cache_key, registry_data_id)
else:
context.log.notice("Id retrieved for image %s (%s) (from cache)", image, registry_data_id)

image_attrs_cache_key = "docker.image.id." + registry_data_id + ".attrs"
image_attrs = global_cache().get(image_attrs_cache_key)

if not image_attrs:
if not registry_data:
registry_data = FixuidDockerComposeAction._get_registry_data(image)
context.log.warning("Loading attributes for image %s...", image)
pulled_image = registry_data.pull()
image_attrs = pulled_image.attrs
global_cache().set(image_attrs_cache_key, image_attrs)
context.log.success("Attributes retrieved for image %s", image)
else:
context.log.notice("Attributes retrieved for image %s (from cache)", image)
return image_attrs
try:
output = run('docker', 'inspect', '--format', '\'{{json .}}\'', image)
except CalledProcessError:
run('docker', 'pull', '-q', image)
output = run('docker', 'inspect', '--format', '\'{{json .}}\'', image)
output = output.decode().strip('\\\'\n').rstrip('\\\'\n')
inspect_data = json.loads(output)
context.log.success("Inspect data retrieved for image %s (%s)", image, inspect_data['Id'])
return inspect_data

@staticmethod
def _get_image_config(image):
if image and image != 'scratch':
attrs = FixuidDockerComposeAction._load_image_attrs(image)
attrs = FixuidDockerComposeAction._get_inspect_data(image)
if attrs and 'Config' in attrs:
return attrs['Config']
return None
Expand Down Expand Up @@ -261,13 +239,11 @@ def _get_cmd_and_entrypoint(parser):
if not entrypoint:
baseimage_config = FixuidDockerComposeAction._get_image_config(parser.baseimage)
if baseimage_config and 'Entrypoint' in baseimage_config:
entrypoint = baseimage_config['Entrypoint']
entrypoint = json.dumps(entrypoint)
entrypoint = json.dumps(baseimage_config['Entrypoint'])
if not cmd and not reset_cmd:
baseimage_config = FixuidDockerComposeAction._get_image_config(parser.baseimage)
if baseimage_config and 'Cmd' in baseimage_config:
cmd = baseimage_config['Cmd']
cmd = json.dumps(cmd)
cmd = json.dumps(baseimage_config['Cmd'])
if not cmd:
cmd = None
return cmd, entrypoint
Expand Down Expand Up @@ -333,7 +309,7 @@ def _apply_fixuid_from_parser(self, parser: CustomDockerfileParser, service: Bui
ret = True

if not manual_install and self._dockerfile_lines[0] + "\n" not in parser.lines:
last_instruction_user = parser\
last_instruction_user = parser \
.get_last_instruction("USER",
lambda instruction: instruction.get('value') and
instruction.get('value').lower() != 'root')
Expand Down
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"jsonnet-binary",
"zgitignore",
"cached-property",
"docker[tls]", # Because newer version makes communication fails with current docker registry
"dockerfile-parse",
"cfssl>=0.0.3b243",
"cryptography",
Expand Down

0 comments on commit cba2394

Please sign in to comment.