Skip to content

Commit

Permalink
Compress Docker images with zstandard
Browse files Browse the repository at this point in the history
  • Loading branch information
marco-c committed Jan 5, 2021
1 parent 9ff28f9 commit c1d297a
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .isort.cfg
@@ -1,6 +1,6 @@
[settings]
known_first_party = taskboot
known_third_party = boto3,botocore,docker,dockerfile_parse,github,pytest,requests,setuptools,taskcluster,taskcluster_urls,twine,yaml
known_third_party = boto3,botocore,docker,dockerfile_parse,github,pytest,requests,setuptools,taskcluster,taskcluster_urls,twine,yaml,zstandard
force_single_line = True
default_section=FIRSTPARTY
line_length=159
15 changes: 7 additions & 8 deletions .taskcluster.yml
Expand Up @@ -79,9 +79,9 @@ tasks:
pip install --no-cache-dir --quiet . &&
taskboot --target=/src build --image=$IMAGE --tag=$VERSION --write /image.tar Dockerfile"
artifacts:
public/taskboot/image.tar:
public/taskboot/image.tar.zst:
expires: {$fromNow: '2 weeks'}
path: /image.tar
path: /image.tar.zst
type: file
scopes:
- docker-worker:capability:privileged
Expand All @@ -102,22 +102,21 @@ tasks:
features:
dind: true
maxRunTime: 3600
image: python:3.7-alpine
image: python:3.7
env:
IMAGE: mozilla/taskboot
REGISTRY: registry.hub.docker.com
VERSION: "${tag}"
command:
- sh
- -lxce
- "apk add --no-cache git --quiet &&
git clone --quiet ${repository} /src && cd /src && git checkout ${head_rev} -b taskboot &&
- "git clone --quiet ${repository} /src && cd /src && git checkout ${head_rev} -b taskboot &&
pip install --no-cache-dir --quiet . &&
taskboot --target=/src build --build-tool=dind --image=$IMAGE --tag=$VERSION --write /image.tar tests/dockerfile.empty"
artifacts:
public/taskboot/test-dind.tar:
public/taskboot/test-dind.tar.zst:
expires: {$fromNow: '2 weeks'}
path: /image.tar
path: /image.tar.zst
type: file
metadata:
name: TaskBoot docker build using Docker in Docker
Expand All @@ -138,7 +137,7 @@ tasks:
maxRunTime: 3600
image:
type: task-image
path: public/taskboot/test-dind.tar
path: public/taskboot/test-dind.tar.zst
taskId: {$eval: as_slugid("docker_build_dind")}
metadata:
name: TaskBoot docker run DinD image
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Expand Up @@ -8,3 +8,4 @@ taskcluster==38.0.4
taskcluster-urls==13.0.1
twine==2.0.0
yarl<1.4.0
zstandard==0.15.1
8 changes: 7 additions & 1 deletion taskboot/build.py
Expand Up @@ -18,6 +18,7 @@
from taskboot.docker import Img
from taskboot.docker import patch_dockerfile
from taskboot.utils import retry
from taskboot.utils import zstd_compress

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -95,6 +96,7 @@ def build_image(target, args):
# Write the produced image
if output:
build_tool.save(tags, output)
zstd_compress(output)

# Push the produced image
if args.push:
Expand Down Expand Up @@ -167,7 +169,11 @@ def build_compose(target, args):

# Write the produced image
if output:
build_tool.save(tags, os.path.join(output, "{}.tar".format(name)))
output_path = os.path.join(output, f"{name}.tar")

build_tool.save(tags, output_path)

zstd_compress(output_path)

logger.info("Compose file fully processed.")

Expand Down
9 changes: 9 additions & 0 deletions taskboot/push.py
Expand Up @@ -4,6 +4,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import logging
import os

import requests
import taskcluster
Expand All @@ -15,6 +16,7 @@
from taskboot.utils import download_artifact
from taskboot.utils import load_artifacts
from taskboot.utils import load_named_artifacts
from taskboot.utils import zstd_decompress

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -62,6 +64,9 @@ def push_artifact(queue, push_tool, task_id, artifact_name, custom_tag=None):
and push it on remote repo
"""
path = download_artifact(queue, task_id, artifact_name)
path, ext = os.path.splitext(path)
assert ext == "zst"
zstd_decompress(path)
push_tool.push_archive(path, custom_tag)


Expand Down Expand Up @@ -91,6 +96,10 @@ def heroku_release(target, args):
# Push the Docker image
custom_tag_name = f"{HEROKU_REGISTRY}/{args.heroku_app}/{heroku_dyno_name}"

artifact_path, ext = os.path.splitext(artifact_path)
assert ext == "zst"
zstd_decompress(artifact_path)

skopeo.push_archive(artifact_path, custom_tag_name)

# Get the Docker image id
Expand Down
19 changes: 19 additions & 0 deletions taskboot/utils.py
Expand Up @@ -12,6 +12,7 @@

import requests
import taskcluster
import zstandard

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -172,3 +173,21 @@ def load_named_artifacts(config, source_task_id, arguments, output_directory=Non
)

yield (name, artifact_name, artifact_path)


def zstd_compress(path: str) -> None:
cctx = zstandard.ZstdCompressor(threads=-1)
with open(path, "rb") as input_f:
with open(f"{path}.zst", "wb") as output_f:
cctx.copy_stream(input_f, output_f)

os.remove(path)


def zstd_decompress(path: str) -> None:
dctx = zstandard.ZstdDecompressor()
with open(f"{path}.zst", "rb") as input_f:
with open(path, "wb") as output_f:
dctx.copy_stream(input_f, output_f)

os.remove(f"{path}.zst")

0 comments on commit c1d297a

Please sign in to comment.