Skip to content
This repository has been archived by the owner on Dec 14, 2023. It is now read-only.

Commit

Permalink
Remove –dockerhub_username argument
Browse files Browse the repository at this point in the history
Unlikely to change anyway.
  • Loading branch information
pypt committed Jan 2, 2020
1 parent dafc40b commit 80890c5
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 95 deletions.
17 changes: 4 additions & 13 deletions dev/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,18 @@ def __init__(self, name: str, path: str, repository: str):
self.repository = repository


def _docker_images_to_build(all_apps_dir: str, docker_hub_username: str) -> List[DockerImageToBuild]:
def _docker_images_to_build(all_apps_dir: str) -> List[DockerImageToBuild]:
"""
Return an ordered list of Docker images to build.
:param all_apps_dir: Directory with app subdirectories.
:param docker_hub_username: Docker Hub username.
:return: List of Docker images to build in that order.
"""

images_to_build = []

for dependency in docker_images(
all_apps_dir=all_apps_dir,
only_belonging_to_user=True,
docker_hub_username=docker_hub_username,
):
container_name = container_dir_name_from_image_name(
image_name=dependency,
docker_hub_username=docker_hub_username,
)
for dependency in docker_images(all_apps_dir=all_apps_dir, only_belonging_to_user=True):
container_name = container_dir_name_from_image_name(image_name=dependency)
container_path = os.path.join(all_apps_dir, container_name)

if not os.path.isdir(container_path):
Expand All @@ -92,11 +84,10 @@ def _docker_images_to_build(all_apps_dir: str, docker_hub_username: str) -> List

parser = DockerHubPruneArgumentParser(description='Print commands to build all container images.')
args = parser.parse_arguments()
docker_hub_username_ = args.docker_hub_username()

image_tag = docker_tag_from_current_git_branch_name()

images = _docker_images_to_build(all_apps_dir=args.all_apps_dir(), docker_hub_username=docker_hub_username_)
images = _docker_images_to_build(all_apps_dir=args.all_apps_dir())

for image in images:
command = "docker build --cache-from {repo}:latest --tag {repo}:{tag} --tag {repo}:latest {path}".format(
Expand Down
15 changes: 5 additions & 10 deletions dev/pull.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,36 @@
import subprocess
from typing import List

from utils import docker_images, docker_tag_from_current_git_branch_name, DockerHubPruneArgumentParser
from utils import docker_images, docker_tag_from_current_git_branch_name, DockerHubPruneArgumentParser, DOCKERHUB_USER


def _docker_images_to_pull(all_apps_dir: str, docker_hub_username: str) -> List[str]:
def _docker_images_to_pull(all_apps_dir: str) -> List[str]:
"""
Return an ordered list of Docker images to pull.
:param all_apps_dir: Directory with container subdirectories.
:param docker_hub_username: Docker Hub username.
:return: List of tagged Docker images to pull in that order.
"""
return docker_images(
all_apps_dir=all_apps_dir,
only_belonging_to_user=False,
docker_hub_username=docker_hub_username,
)


def _docker_pull_commands(all_apps_dir: str, image_tag: str, docker_hub_username: str, prune_images: bool) -> List[str]:
def _docker_pull_commands(all_apps_dir: str, image_tag: str, prune_images: bool) -> List[str]:
"""
Return an ordered list of "docker pull" commands to run in order to pull all images.
:param all_apps_dir: Directory with container subdirectories.
:param image_tag: Docker image tag.
:param docker_hub_username: Docker Hub username.
:param prune_images: True if images are to be pruned after pulling each image to clean up disk space immediately.
:return: List of "docker pull" commands to run in order to pull all images.
"""
commands = []

for image in _docker_images_to_pull(all_apps_dir=all_apps_dir, docker_hub_username=docker_hub_username):
for image in _docker_images_to_pull(all_apps_dir=all_apps_dir):

if image.startswith(docker_hub_username_ + '/'):
if image.startswith(DOCKERHUB_USER + '/'):

# 1) First try to pull the image for the current branch
# 2) if that fails (e.g. the branch is new and it hasn't yet been built and tagged on Docker Hub), pull
Expand Down Expand Up @@ -83,12 +80,10 @@ def _docker_pull_commands(all_apps_dir: str, image_tag: str, docker_hub_username
if __name__ == '__main__':
parser = DockerHubPruneArgumentParser(description='Print commands to pull all container images.')
args = parser.parse_arguments()
docker_hub_username_ = args.docker_hub_username()

commands_ = _docker_pull_commands(
all_apps_dir=args.all_apps_dir(),
image_tag=docker_tag_from_current_git_branch_name(),
docker_hub_username=docker_hub_username_,
prune_images=args.prune_images(),
)

Expand Down
11 changes: 4 additions & 7 deletions dev/push.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,30 @@
import subprocess
from typing import List

from utils import docker_images, docker_tag_from_current_git_branch_name, DockerHubArgumentParser
from utils import docker_images, docker_tag_from_current_git_branch_name, DockerArgumentParser


def _docker_images_to_push(all_apps_dir: str, docker_hub_username: str) -> List[str]:
def _docker_images_to_push(all_apps_dir: str) -> List[str]:
"""
Return an ordered list of Docker images to push.
:param all_apps_dir: Directory with container subdirectories.
:param docker_hub_username: Docker Hub username.
:return: List of tagged Docker images to push in that order.
"""
return docker_images(
all_apps_dir=all_apps_dir,
only_belonging_to_user=True,
docker_hub_username=docker_hub_username,
)


if __name__ == '__main__':

parser = DockerHubArgumentParser(description='Print commands to push all container images.')
parser = DockerArgumentParser(description='Print commands to push all container images.')
args = parser.parse_arguments()
docker_hub_username_ = args.docker_hub_username()

image_tag = docker_tag_from_current_git_branch_name()

for image in _docker_images_to_push(all_apps_dir=args.all_apps_dir(), docker_hub_username=docker_hub_username_):
for image in _docker_images_to_push(all_apps_dir=args.all_apps_dir()):
command = ['docker', 'push', '{}:{}'.format(image, image_tag)]

if args.print_commands():
Expand Down
3 changes: 1 addition & 2 deletions dev/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ class TestUtils(TestCase):

def test_container_dir_name_from_image_name(self):
assert container_dir_name_from_image_name(
image_name='dockermediacloud/topics-fetch-twitter-urls:latest',
docker_hub_username='dockermediacloud',
image_name='dockermediacloud/topics-fetch-twitter-urls:latest'
) == 'topics-fetch-twitter-urls'

def test_container_dependency_tree(self):
Expand Down
82 changes: 19 additions & 63 deletions dev/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,37 @@
from typing import Dict, List, Set


def _image_name_from_container_name(container_name: str, docker_hub_username: str) -> str:
DOCKERHUB_USER = 'dockermediacloud'


def _image_name_from_container_name(container_name: str) -> str:
"""
Convert container directory name to an image name.
:param container_name: Container directory name.
:param docker_hub_username: Docker Hub username.
:return: Image name (with username, prefix and version).
"""
if not re.match(r'^[\w\-]+$', container_name):
raise ValueError("Container name is invalid: {}".format(container_name))

return '{username}/{container_name}'.format(
username=docker_hub_username,
username=DOCKERHUB_USER,
container_name=container_name,
)


def container_dir_name_from_image_name(image_name: str, docker_hub_username: str) -> str:
def container_dir_name_from_image_name(image_name: str) -> str:
"""
Convert image name to a container directory name.
:param image_name: Image name (with username, prefix and version).
:param docker_hub_username: Docker Hub username.
:return: Container directory name.
"""
container_name = image_name

expected_prefix = docker_hub_username + '/'
expected_prefix = DOCKERHUB_USER + '/'
if not container_name.startswith(expected_prefix):
raise ValueError("Image name '{}' is expected to start with '{}/'.".format(image_name, docker_hub_username))
raise ValueError("Image name '{}' is expected to start with '{}/'.".format(image_name, DOCKERHUB_USER))
container_name = container_name[len(expected_prefix):]

# Remove version
Expand All @@ -48,12 +49,11 @@ def container_dir_name_from_image_name(image_name: str, docker_hub_username: str
return container_name


def _docker_parent_image_name(dockerfile_path: str, docker_hub_username: str) -> str:
def _docker_parent_image_name(dockerfile_path: str) -> str:
"""
Return Docker parent image name (FROM value) from a Dockerfile.
:param dockerfile_path: Path to Dockerfile to parse.
:param docker_hub_username: Docker Hub username.
:return: FROM value as found in the Dockerfile.
"""
if not os.path.isfile(dockerfile_path):
Expand All @@ -71,31 +71,29 @@ def _docker_parent_image_name(dockerfile_path: str, docker_hub_username: str) ->
assert parent_image, "Parent image should be set at this point."

# Remove version tag if it's one of our own images
if parent_image.startswith(docker_hub_username + '/'):
if parent_image.startswith(DOCKERHUB_USER + '/'):
parent_image = re.sub(r':(.+?)$', '', parent_image)

return parent_image

raise ValueError("No FROM clause found in {}.".format(dockerfile_path))


def _image_belongs_to_username(image_name: str, docker_hub_username: str) -> bool:
def _image_belongs_to_username(image_name: str) -> bool:
"""
Determine whether an image is hosted under a given Docker Hub username and thus has to be built.
:param image_name: Image name (with username, prefix and version).
:param docker_hub_username: Docker Hub username.
:return: True if image is to be hosted on a Docker Hub account pointed to in configuration.
"""
return image_name.startswith(docker_hub_username + '/')
return image_name.startswith(DOCKERHUB_USER + '/')


def _container_dependency_map(all_apps_dir: str, docker_hub_username: str) -> Dict[str, str]:
def _container_dependency_map(all_apps_dir: str) -> Dict[str, str]:
"""
Determine which container depends on which parent image.
:param all_apps_dir: Directory with container subdirectories.
:param docker_hub_username: Docker Hub username.
:return: Map of dependent - dependency container directory names.
"""
if not os.path.isdir(all_apps_dir):
Expand All @@ -108,13 +106,11 @@ def _container_dependency_map(all_apps_dir: str, docker_hub_username: str) -> Di
container_name = os.path.basename(container_path)
image_name = _image_name_from_container_name(
container_name=container_name,
docker_hub_username=docker_hub_username,
)

dockerfile_path = os.path.join(container_path, 'Dockerfile')
parent_docker_image = _docker_parent_image_name(
dockerfile_path=dockerfile_path,
docker_hub_username=docker_hub_username,
)

parent_images[image_name] = parent_docker_image
Expand Down Expand Up @@ -162,31 +158,28 @@ def _ordered_container_dependencies(dependencies: Dict[str, str]) -> List[Set[st
return tree


def _ordered_dependencies_from_directory(all_apps_dir: str, docker_hub_username: str) -> List[Set[str]]:
def _ordered_dependencies_from_directory(all_apps_dir: str) -> List[Set[str]]:
"""
Return a list of sets of container names to build in order.
:param all_apps_dir: Directory with container subdirectories.
:param docker_hub_username: Docker Hub username.
:return: List of sets of container names in the order in which they should be built.
"""
dependency_map = _container_dependency_map(all_apps_dir=all_apps_dir, docker_hub_username=docker_hub_username)
dependency_map = _container_dependency_map(all_apps_dir=all_apps_dir)
ordered_dependencies = _ordered_container_dependencies(dependency_map)
return ordered_dependencies


def docker_images(all_apps_dir: str, only_belonging_to_user: bool, docker_hub_username: str) -> List[str]:
def docker_images(all_apps_dir: str, only_belonging_to_user: bool) -> List[str]:
"""
Return a list of Docker images to pull / build / push in the correct order.
:param all_apps_dir: Directory with container subdirectories.
:param only_belonging_to_user: If True, return only the images that belong to the configured user.
:param docker_hub_username: Docker Hub username.
:return: List of tagged Docker images to pull / build / push in the correct order.
"""
ordered_dependencies = _ordered_dependencies_from_directory(
all_apps_dir=all_apps_dir,
docker_hub_username=docker_hub_username,
)

images = []
Expand All @@ -195,7 +188,7 @@ def docker_images(all_apps_dir: str, only_belonging_to_user: bool, docker_hub_us
for dependency in sorted(level_dependencies):

if only_belonging_to_user:
if not _image_belongs_to_username(image_name=dependency, docker_hub_username=docker_hub_username):
if not _image_belongs_to_username(image_name=dependency):
continue

images.append(dependency)
Expand Down Expand Up @@ -381,44 +374,7 @@ def parse_arguments(self) -> DockerComposeArguments:
return DockerComposeArguments(self._parser.parse_args())


class DockerHubArguments(DockerArguments):
"""
Arguments that include Docker Hub credentials.
"""

def docker_hub_username(self) -> str:
"""
Return a Docker Hub username.
:return: Docker Hub username.
"""
return self._args.dockerhub_user


class DockerHubArgumentParser(DockerArgumentParser):
"""Argument parser which requires Docker Hub credentials."""

def __init__(self, description: str):
"""
Constructor.
:param description: Description of the script to print when "--help" is passed.
"""
super().__init__(description=description)

self._parser.add_argument('-u', '--dockerhub_user', required=False, type=str, default='dockermediacloud',
help='Docker Hub user that is hosting the images.')

def parse_arguments(self) -> DockerHubArguments:
"""
Parse arguments and return an object with parsed arguments.
:return: DockerHubArguments object.
"""
return DockerHubArguments(self._parser.parse_args())


class DockerHubPruneArguments(DockerHubArguments):
class DockerHubPruneArguments(DockerArguments):
"""
Arguments that include Docker Hub credentials and whether to prune images.
"""
Expand All @@ -432,7 +388,7 @@ def prune_images(self) -> bool:
return self._args.prune_images


class DockerHubPruneArgumentParser(DockerHubArgumentParser):
class DockerHubPruneArgumentParser(DockerArgumentParser):
"""Argument parser which requires Docker Hub credentials and allows users to prune images."""

def __init__(self, description: str):
Expand Down

0 comments on commit 80890c5

Please sign in to comment.