Skip to content

Commit

Permalink
feat(fixuid): Add Dockerfile comments to disable or customize fixuid …
Browse files Browse the repository at this point in the history
…automic configuration

Close #135
  • Loading branch information
Toilal committed Dec 21, 2020
1 parent 4012cbf commit e855efc
Show file tree
Hide file tree
Showing 19 changed files with 245 additions and 19 deletions.
84 changes: 67 additions & 17 deletions ddb/feature/fixuid/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,30 +272,80 @@ def _get_cmd_and_entrypoint(parser):
cmd = None
return cmd, entrypoint

@staticmethod
def _has_fixuid_disabled_comment(lines: Iterable[str]):
return FixuidDockerComposeAction._has_comment(
['no-fixuid', 'fixuid-no', 'fixuid-disabled?', 'disabled?-fixuid'], lines)

@staticmethod
def _has_fixuid_manual_comment(lines: Iterable[str]):
return FixuidDockerComposeAction._has_comment(
['manual-fixuid', 'fixuid-manual', 'custom-fixuid', 'fixuid-custom'], lines)

@staticmethod
def _has_fixuid_manual_entrypoint_comment(lines: Iterable[str]):
return FixuidDockerComposeAction._has_comment(
['manual-fixuid-entrypoint',
'fixuid-manual-entrypoint',
'custom-fixuid-entrypoint',
'fixuid-custom-entrypoint'], lines)

@staticmethod
def _has_fixuid_manual_install_comment(lines: Iterable[str]):
return FixuidDockerComposeAction._has_comment(
('manual-fixuid-install',
'fixuid-manual-install',
'custom-fixuid-install',
'fixuid-custom-install'), lines)

@staticmethod
def _has_comment(keywords: Iterable[str], lines: Iterable[str]):
patterns = [r'^#\s*' + keyword + r'\s*$' for keyword in keywords]
for line in lines:
for pattern in patterns:
if re.match(pattern, line):
print(pattern)
print(line)
return True
return False

def _apply_fixuid_from_parser(self, parser: CustomDockerfileParser, service: BuildServiceDef):
cmd, entrypoint = FixuidDockerComposeAction._get_cmd_and_entrypoint(parser)
fixuid_entrypoint = FixuidDockerComposeAction._add_fixuid_entrypoint(entrypoint)
if fixuid_entrypoint:
parser.entrypoint = fixuid_entrypoint
if cmd:
parser.cmd = cmd
if self._has_fixuid_disabled_comment(parser.lines):
return False

target = copy_from_url(config.data["fixuid.url"],
service.context,
"fixuid.tar.gz")
if target:
events.file.generated(source=None, target=target)

if self._dockerfile_lines[0] + "\n" not in parser.lines:
last_instruction_user = parser.get_last_instruction("USER")
last_instruction_entrypoint = parser.get_last_instruction("ENTRYPOINT")
if last_instruction_user:
parser.add_lines_at(last_instruction_user, *self._dockerfile_lines)
elif last_instruction_entrypoint:
parser.add_lines_at(last_instruction_entrypoint, *self._dockerfile_lines)
else:
parser.add_lines(*self._dockerfile_lines)
return True
return False
manual_entrypoint = self._has_fixuid_manual_entrypoint_comment(parser.lines)
manual_install = self._has_fixuid_manual_install_comment(parser.lines)
manual = self._has_fixuid_manual_comment(parser.lines)

ret = False
if not manual:
if not manual_entrypoint:
cmd, entrypoint = FixuidDockerComposeAction._get_cmd_and_entrypoint(parser)
fixuid_entrypoint = FixuidDockerComposeAction._add_fixuid_entrypoint(entrypoint)
if fixuid_entrypoint:
parser.entrypoint = fixuid_entrypoint
if cmd:
parser.cmd = cmd
ret = True

if not manual_install and self._dockerfile_lines[0] + "\n" not in parser.lines:
last_instruction_user = parser.get_last_instruction("USER")
last_instruction_entrypoint = parser.get_last_instruction("ENTRYPOINT")
if last_instruction_user:
parser.add_lines_at(last_instruction_user, *self._dockerfile_lines)
elif last_instruction_entrypoint:
parser.add_lines_at(last_instruction_entrypoint, *self._dockerfile_lines)
else:
parser.add_lines(*self._dockerfile_lines)
ret = True

return ret

def _remove_fixuid_from_parser(self, parser: CustomDockerfileParser, service: BuildServiceDef):
baseimage_config = FixuidDockerComposeAction._get_image_config(parser.baseimage)
Expand Down
11 changes: 10 additions & 1 deletion docs/features/fixuid.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,13 @@ been generated. The entrypoint is changed to run fixuid before the default entry
commands.

As many other ddb features are available through [jsonnet feature](./jsonnet.md), you should really consider using
it. This will help you to build simpler, shorter and smarter `docker-compose` configuration.
it. This will help you to build simpler, shorter and smarter `docker-compose` configuration.

!!! info "Disable or customize fixuid automatic configuration"

You may need to disable fixuid automatic configuration. Use the following comments in your Dockerfile.jinja.

- `# fixuid-disable`: Disable both download of fixuid.tar.gz and whole auto-configuration. Use this to disable fixuid totally for this Dockerfile.
- `# fixuid-manual`: Only keep download of fixuid.tar.gz. Use this to configure fixuid totally manually in the Dockerfile.
- `# fixuid-manual-install`: Keep download of fixuid.tar.gz and auto-configuration of ENTRYPOINT. You still have to install fixuid manually in the Dockerfile.
- `# fixuid-manual-entrypoint`: Keep download of fixuid.tar.gz and installation of required files. You still have to invoke fixuid manually in the Entrypoint.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version: "3.7"
services:
docker:
build: docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM alpine:edge

#fixuid-manual-entrypoint
USER nobody

CMD '/ep'
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM alpine:edge

#fixuid-manual-entrypoint
ADD fixuid.tar.gz /usr/local/bin
RUN chown root:root /usr/local/bin/fixuid && chmod 4755 /usr/local/bin/fixuid && mkdir -p /etc/fixuid
COPY fixuid.yml /etc/fixuid/config.yml
USER nobody

CMD '/ep'
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
user: nobody
group: nobody
paths:
- /
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version: "3.7"
services:
docker:
build: docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM alpine:edge

#fixuid-manual-install
USER nobody

CMD '/ep'
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM alpine:edge

#fixuid-manual-install
USER nobody

CMD '/ep'
ENTRYPOINT ["fixuid", "-q"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
user: nobody
group: nobody
paths:
- /
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version: "3.7"
services:
docker:
build: docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM alpine:edge

#fixuid-manual
USER nobody

CMD '/ep'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM alpine:edge

#fixuid-manual
USER nobody

CMD '/ep'
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
user: nobody
group: nobody
paths:
- /
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version: "3.7"
services:
docker:
build: docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM alpine:edge

#no-fixuid
USER nobody

CMD '/ep'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM alpine:edge

#no-fixuid
USER nobody

CMD '/ep'
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
user: nobody
group: nobody
paths:
- /
85 changes: 84 additions & 1 deletion tests/feature/fixuid/test_fixuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ def test_from_mysql_fixuid_removed(self, project_loader):
config = yaml.load(config_file, yaml.SafeLoader)

events.docker.docker_compose_config(config)
events.file.found(os.path.join("docker", "fixuid.yml"))

with open(os.path.join("docker", "Dockerfile.expected"), "r") as f:
expected = f.read()
Expand All @@ -104,3 +103,87 @@ def test_from_mysql_fixuid_removed(self, project_loader):
assert content == expected

assert not os.path.exists(os.path.join("docker", "fixuid.tar.gz"))

def test_no_fixuid(self, project_loader):
project_loader("no-fixuid")
register_default_caches()

features.register(FixuidFeature())
load_registered_features()
register_actions_in_event_bus(True)

with open('docker-compose.yml', 'r') as config_file:
config = yaml.load(config_file, yaml.SafeLoader)

events.docker.docker_compose_config(config)

with open(os.path.join("docker", "Dockerfile.expected"), "r") as f:
expected = f.read()
with open(os.path.join("docker", "Dockerfile"), "r") as f:
content = f.read()
assert content == expected

assert not os.path.exists(os.path.join("docker", "fixuid.tar.gz"))

def test_fixuid_manual(self, project_loader):
project_loader("fixuid-manual")
register_default_caches()

features.register(FixuidFeature())
load_registered_features()
register_actions_in_event_bus(True)

with open('docker-compose.yml', 'r') as config_file:
config = yaml.load(config_file, yaml.SafeLoader)

events.docker.docker_compose_config(config)

with open(os.path.join("docker", "Dockerfile.expected"), "r") as f:
expected = f.read()
with open(os.path.join("docker", "Dockerfile"), "r") as f:
content = f.read()
assert content == expected

assert os.path.exists(os.path.join("docker", "fixuid.tar.gz"))

def test_fixuid_manual_install(self, project_loader):
project_loader("fixuid-manual-install")
register_default_caches()

features.register(FixuidFeature())
load_registered_features()
register_actions_in_event_bus(True)

with open('docker-compose.yml', 'r') as config_file:
config = yaml.load(config_file, yaml.SafeLoader)

events.docker.docker_compose_config(config)

with open(os.path.join("docker", "Dockerfile.expected"), "r") as f:
expected = f.read()
with open(os.path.join("docker", "Dockerfile"), "r") as f:
content = f.read()
assert content == expected

assert os.path.exists(os.path.join("docker", "fixuid.tar.gz"))

def test_fixuid_manual_entrypoint(self, project_loader):
project_loader("fixuid-manual-entrypoint")
register_default_caches()

features.register(FixuidFeature())
load_registered_features()
register_actions_in_event_bus(True)

with open('docker-compose.yml', 'r') as config_file:
config = yaml.load(config_file, yaml.SafeLoader)

events.docker.docker_compose_config(config)

with open(os.path.join("docker", "Dockerfile.expected"), "r") as f:
expected = f.read()
with open(os.path.join("docker", "Dockerfile"), "r") as f:
content = f.read()
assert content == expected

assert os.path.exists(os.path.join("docker", "fixuid.tar.gz"))

0 comments on commit e855efc

Please sign in to comment.