If no configuration file is passed to platydock generate a minimal Dockerfile.

This commit is contained in:
Fabio Manganiello 2023-08-20 02:35:25 +02:00
parent 199ac5f0f7
commit 28ba042810
Signed by untrusted user: blacklight
GPG key ID: D90FBA7F76362774
8 changed files with 94 additions and 49 deletions

View file

@ -1,8 +1,12 @@
FROM alpine FROM alpine
ADD . /install ADD . /install
WORKDIR /var/lib/platypush WORKDIR /var/lib/platypush
RUN DOCKER_CTX=1 /install/platypush/install/scripts/alpine/install.sh ARG DOCKER_CTX=1
ENV DOCKER_CTX=1
RUN /install/platypush/install/scripts/alpine/install.sh
RUN cd /install && pip install -U --no-input --no-cache-dir . RUN cd /install && pip install -U --no-input --no-cache-dir .
RUN rm -rf /install RUN rm -rf /install
@ -11,4 +15,7 @@ EXPOSE 8008
VOLUME /etc/platypush VOLUME /etc/platypush
VOLUME /var/lib/platypush VOLUME /var/lib/platypush
CMD /run.sh CMD platypush \
--start-redis \
--config /etc/platypush/config.yaml \
--workdir /var/lib/platypush

View file

@ -1,10 +1,16 @@
FROM debian FROM debian
ADD . /install ADD . /install
WORKDIR /var/lib/platypush WORKDIR /var/lib/platypush
ARG DEBIAN_FRONTEND=noninteractive
ENV DEBIAN_FRONTEND=noninteractive
ARG DOCKER_CTX=1
ENV DOCKER_CTX=1
RUN apt update RUN apt update
RUN DOCKER_CTX=1 /install/platypush/install/scripts/debian/install.sh RUN /install/platypush/install/scripts/debian/install.sh
RUN cd /install && pip install -U --no-input --no-cache-dir . RUN cd /install && pip install -U --no-input --no-cache-dir . --break-system-packages
RUN rm -rf /install RUN rm -rf /install
RUN apt autoclean -y RUN apt autoclean -y
RUN apt autoremove -y RUN apt autoremove -y
@ -15,4 +21,7 @@ EXPOSE 8008
VOLUME /etc/platypush VOLUME /etc/platypush
VOLUME /var/lib/platypush VOLUME /var/lib/platypush
CMD /run.sh CMD platypush \
--start-redis \
--config /etc/platypush/config.yaml \
--workdir /var/lib/platypush

View file

@ -1,9 +1,15 @@
FROM ubuntu FROM ubuntu
ADD . /install ADD . /install
WORKDIR /var/lib/platypush WORKDIR /var/lib/platypush
ARG DEBIAN_FRONTEND=noninteractive
ENV DEBIAN_FRONTEND=noninteractive
ARG DOCKER_CTX=1
ENV DOCKER_CTX=1
RUN apt update RUN apt update
RUN DOCKER_CTX=1 /install/platypush/install/scripts/debian/install.sh RUN /install/platypush/install/scripts/debian/install.sh
RUN cd /install && pip install -U --no-input --no-cache-dir . RUN cd /install && pip install -U --no-input --no-cache-dir .
RUN rm -rf /install RUN rm -rf /install
RUN apt autoclean -y RUN apt autoclean -y
@ -15,4 +21,7 @@ EXPOSE 8008
VOLUME /etc/platypush VOLUME /etc/platypush
VOLUME /var/lib/platypush VOLUME /var/lib/platypush
CMD /run.sh CMD platypush \
--start-redis \
--config /etc/platypush/config.yaml \
--workdir /var/lib/platypush

View file

@ -1 +1 @@
DEBIAN_FRONTEND=noninteractive apt install -y apt install -y

View file

@ -1,8 +0,0 @@
#!/bin/sh
# This script is used as a default entry point for Docker containers
DOCKER_CTX=1 platypush \
--start-redis \
--config /etc/platypush/config.yaml \
--workdir /var/lib/platypush

View file

@ -14,15 +14,9 @@ CMD="$(cat "${SCRIPT_PATH}/PKGCMD")"
REQUIREMENTS="$(cat "${SCRIPT_PATH}/../../requirements/${OS}.txt" | tr '\n' ' ')" REQUIREMENTS="$(cat "${SCRIPT_PATH}/../../requirements/${OS}.txt" | tr '\n' ' ')"
SUDO= SUDO=
# If we are running in a Docker context then we want to copy the docker-run.sh
# script where we can easily find it.
if [ -n "$DOCKER_CTX" ]; then
cp -v /install/platypush/install/scripts/docker-run.sh /run.sh
fi
# If we aren't running in a Docker context, or the user is not root, we should # If we aren't running in a Docker context, or the user is not root, we should
# use sudo to install system packages. # use sudo to install system packages.
if [[ "$(id -u)" != "0" ]] || [ -z "$DOCKER_CTX" ]; then if [ $(id -u) -ne 0 ] || [ -z "$DOCKER_CTX" ]; then
if ! type sudo >/dev/null; then if ! type sudo >/dev/null; then
echo "sudo executable not found, I can't install system packages" >&2 echo "sudo executable not found, I can't install system packages" >&2
exit 1 exit 1

View file

@ -4,7 +4,6 @@ Dockerfile for Platypush starting from a configuration file.
""" """
import argparse import argparse
from enum import Enum
import inspect import inspect
import os import os
import pathlib import pathlib
@ -12,23 +11,12 @@ import sys
from typing import Iterable from typing import Iterable
from platypush.config import Config from platypush.config import Config
from platypush.utils.manifest import Dependencies, InstallContext, PackageManagers from platypush.utils.manifest import (
BaseImage,
Dependencies,
class BaseImage(Enum): InstallContext,
""" PackageManagers,
Supported base images for Dockerfiles. )
"""
ALPINE = 'alpine'
DEBIAN = 'debian'
UBUNTU = 'ubuntu'
def __str__(self) -> str:
"""
Explicit __str__ override for argparse purposes.
"""
return self.value
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
@ -67,6 +55,7 @@ class DockerfileGenerator:
self.cfgfile, self.cfgfile,
pkg_manager=pkg_manager, pkg_manager=pkg_manager,
install_context=InstallContext.DOCKER, install_context=InstallContext.DOCKER,
base_image=self.image,
) )
is_after_expose_cmd = False is_after_expose_cmd = False
@ -135,7 +124,11 @@ def main():
'-h', '--help', dest='show_usage', action='store_true', help='Show usage' '-h', '--help', dest='show_usage', action='store_true', help='Show usage'
) )
parser.add_argument( parser.add_argument(
'cfgfile', type=str, nargs='?', help='The path to the configuration file.' 'cfgfile',
type=str,
nargs='?',
help='The path to the configuration file. If not specified a minimal '
'Dockerfile with no extra dependencies will be generated.',
) )
parser.add_argument( parser.add_argument(
'--image', '--image',
@ -154,11 +147,15 @@ def main():
return 0 return 0
if not opts.cfgfile: if not opts.cfgfile:
opts.cfgfile = os.path.join(
str(pathlib.Path(inspect.getfile(Config)).parent),
'config.auto.yaml',
)
print( print(
f'Please specify a configuration file.\nRun {sys.argv[0]} --help to get the available options.', f'No configuration file specified. Using {opts.cfgfile}.',
file=sys.stderr, file=sys.stderr,
) )
return 1
dockerfile = DockerfileGenerator(opts.cfgfile, image=opts.image).generate() dockerfile = DockerfileGenerator(opts.cfgfile, image=opts.image).generate()
print(dockerfile) print(dockerfile)

View file

@ -31,6 +31,22 @@ _available_package_manager = None
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class BaseImage(Enum):
"""
Supported base images for Dockerfiles.
"""
ALPINE = 'alpine'
DEBIAN = 'debian'
UBUNTU = 'ubuntu'
def __str__(self) -> str:
"""
Explicit __str__ override for argparse purposes.
"""
return self.value
@dataclass @dataclass
class PackageManager: class PackageManager:
""" """
@ -55,7 +71,7 @@ class PackageManagers(Enum):
APT = PackageManager( APT = PackageManager(
executable='apt', executable='apt',
command=('DEBIAN_FRONTEND=noninteractive', 'apt', 'install', '-y'), command=('apt', 'install', '-y'),
) )
PACMAN = PackageManager( PACMAN = PackageManager(
@ -142,6 +158,9 @@ class Dependencies:
pkg_manager: Optional[PackageManagers] = None pkg_manager: Optional[PackageManagers] = None
""" Override the default package manager detected on the system. """ """ Override the default package manager detected on the system. """
install_context: InstallContext = InstallContext.NONE install_context: InstallContext = InstallContext.NONE
""" The installation context - Docker, virtual environment or bare metal. """
base_image: Optional[BaseImage] = None
""" Base image used in case of Docker installations. """
@property @property
def _is_venv(self) -> bool: def _is_venv(self) -> bool:
@ -154,17 +173,34 @@ class Dependencies:
self.install_context == InstallContext.VENV or sys.prefix != sys.base_prefix self.install_context == InstallContext.VENV or sys.prefix != sys.base_prefix
) )
@property
def _is_docker(self) -> bool:
"""
:return: True if the dependencies scanning logic is running either in a
Docker environment.
"""
return (
self.install_context == InstallContext.DOCKER
or 'DOCKER_CTX' in os.environ
or os.path.isfile('/.dockerenv')
)
@classmethod @classmethod
def from_config( def from_config(
cls, cls,
conf_file: Optional[str] = None, conf_file: Optional[str] = None,
pkg_manager: Optional[PackageManagers] = None, pkg_manager: Optional[PackageManagers] = None,
install_context: InstallContext = InstallContext.NONE, install_context: InstallContext = InstallContext.NONE,
base_image: Optional[BaseImage] = None,
) -> "Dependencies": ) -> "Dependencies":
""" """
Parse the required dependencies from a configuration file. Parse the required dependencies from a configuration file.
""" """
deps = cls(pkg_manager=pkg_manager, install_context=install_context) deps = cls(
pkg_manager=pkg_manager,
install_context=install_context,
base_image=base_image,
)
for manifest in Manifests.by_config(conf_file, pkg_manager=pkg_manager): for manifest in Manifests.by_config(conf_file, pkg_manager=pkg_manager):
deps.before += manifest.install.before deps.before += manifest.install.before
@ -179,7 +215,7 @@ class Dependencies:
Generates the package manager commands required to install the given Generates the package manager commands required to install the given
dependencies on the system. dependencies on the system.
""" """
wants_sudo = self.install_context != InstallContext.DOCKER and os.getuid() != 0 wants_sudo = not (self._is_docker or os.getuid() == 0)
pkg_manager = self.pkg_manager or PackageManagers.scan() pkg_manager = self.pkg_manager or PackageManagers.scan()
if self.packages and pkg_manager: if self.packages and pkg_manager:
yield ' '.join( yield ' '.join(
@ -196,8 +232,9 @@ class Dependencies:
the system. the system.
""" """
wants_break_system_packages = not ( wants_break_system_packages = not (
# Docker installations shouldn't require --break-system-packages in pip # Docker installations shouldn't require --break-system-packages in
self.install_context == InstallContext.DOCKER # pip, except for Debian
(self._is_docker and self.base_image != BaseImage.DEBIAN)
# --break-system-packages has been introduced in Python 3.10 # --break-system-packages has been introduced in Python 3.10
or sys.version_info < (3, 11) or sys.version_info < (3, 11)
# If we're in a virtual environment then we don't need # If we're in a virtual environment then we don't need