diff --git a/.pylint-dict b/.pylint-dict index cc95b1f0e6..fbd2ca816d 100644 --- a/.pylint-dict +++ b/.pylint-dict @@ -20,6 +20,7 @@ epel filename init io +Kubernetes linter metadata mkdir @@ -33,6 +34,7 @@ rpmspec repo rpmlint scality +sdk skopeo sls timestamp diff --git a/buildchain/buildchain/config.py b/buildchain/buildchain/config.py index d7ef2b7256..735b805926 100644 --- a/buildchain/buildchain/config.py +++ b/buildchain/buildchain/config.py @@ -52,11 +52,12 @@ class ExtCommand(enum.Enum): """External commands used by the build chain.""" - GIT = os.getenv('GIT_BIN', 'git') - HARDLINK = os.getenv('HARDLINK_BIN', 'hardlink') - MKISOFS = os.getenv('MKISOFS_BIN', 'mkisofs') - SKOPEO = os.getenv('SKOPEO_BIN', 'skopeo') - VAGRANT = os.getenv('VAGRANT_BIN', 'vagrant') + GIT = os.getenv('GIT_BIN', 'git') + HARDLINK = os.getenv('HARDLINK_BIN', 'hardlink') + MKISOFS = os.getenv('MKISOFS_BIN', 'mkisofs') + SKOPEO = os.getenv('SKOPEO_BIN', 'skopeo') + VAGRANT = os.getenv('VAGRANT_BIN', 'vagrant') + OPERATOR_SDK = os.getenv('OPERATOR_SDK_BIN', 'operator-sdk') @property def command_name(self) -> str: diff --git a/buildchain/buildchain/constants.py b/buildchain/buildchain/constants.py index 7c8606f2b0..7eb61ba183 100644 --- a/buildchain/buildchain/constants.py +++ b/buildchain/buildchain/constants.py @@ -6,7 +6,7 @@ from pathlib import Path import subprocess -from typing import Optional +from typing import Optional, FrozenSet from buildchain import ROOT # Re-export ROOT through this module. from buildchain import config @@ -39,6 +39,8 @@ STATIC_CONTAINER_REGISTRY : Path = Path( ROOT, 'buildchain/static-container-registry' ) +# Path to the storage-operator source directory. +STORAGE_OPERATOR_ROOT : Path = ROOT/'storage-operator' # }}} # Vagrant parameters {{{ @@ -103,3 +105,8 @@ def git_ref() -> Optional[str]: GIT_REF = git_ref() # }}} + +STORAGE_OPERATOR_SOURCES : FrozenSet[Path] = frozenset([ + filepath for filepath in STORAGE_OPERATOR_ROOT.rglob('*.go') + if 'vendor' not in str(filepath.parent) +]) diff --git a/buildchain/buildchain/image.py b/buildchain/buildchain/image.py index 9f4da184ef..c8e5740cb7 100644 --- a/buildchain/buildchain/image.py +++ b/buildchain/buildchain/image.py @@ -344,6 +344,13 @@ def show() -> str: }, task_dep=['_image_mkdir_root'], ), + targets.OperatorImage( + name='storage-operator', + version='latest', + destination=constants.ISO_IMAGE_ROOT, + task_dep=['_image_mkdir_root'], + file_dep=list(constants.STORAGE_OPERATOR_SOURCES) + ), ) diff --git a/buildchain/buildchain/targets/__init__.py b/buildchain/buildchain/targets/__init__.py index 0e9dc0cbba..ac9c63c85a 100644 --- a/buildchain/buildchain/targets/__init__.py +++ b/buildchain/buildchain/targets/__init__.py @@ -9,6 +9,7 @@ from buildchain.targets.directory import Mkdir from buildchain.targets.file_tree import FileTree from buildchain.targets.local_image import LocalImage +from buildchain.targets.operator_image import OperatorImage from buildchain.targets.package import Package from buildchain.targets.remote_image import RemoteImage from buildchain.targets.repository import Repository diff --git a/buildchain/buildchain/targets/operator_image.py b/buildchain/buildchain/targets/operator_image.py new file mode 100644 index 0000000000..b3d13c0f43 --- /dev/null +++ b/buildchain/buildchain/targets/operator_image.py @@ -0,0 +1,54 @@ +# coding: utf-8 + + +"""Provides container image construction for Kubernetes Operator. + +Those are very similar to the locally built images, except that they are build +by the `operator-sdk` command (which also takes care of compiling the Go code) +instead of calling Docker directly. +""" + + +from pathlib import Path +import shlex +from typing import Any, List + +import doit # type: ignore + +from buildchain import config +from buildchain import constants +from buildchain import types + +from . import local_image + + +class OperatorImage(local_image.LocalImage): + """A locally built container image for a Kubernetes Operator.""" + def __init__( + self, name: str, version: str, destination: Path, **kwargs: Any + ): + """Initialize an operator container image. + + Arguments: + name: image name + version: image version + destination: where to save the result + + Keyword Arguments: + They are passed to `Target` init method. + """ + dockerfile = constants.ROOT/name/'build'/'Dockerfile' + kwargs.setdefault('task_dep', []).append('check_for:operator-sdk') + super().__init__( + name=name, version=version, dockerfile=dockerfile, + destination=destination, save_on_disk=True, build_args=None, + **kwargs + ) + + def _do_build(self) -> List[types.Action]: + """Return the actions used to build the image.""" + cwd = constants.ROOT/self.name + cmd = ' '.join(map(shlex.quote, [ + config.ExtCommand.OPERATOR_SDK.value, 'build', self.tag + ])) + return [doit.action.CmdAction(cmd, cwd=cwd)]