This commit is contained in:
jerger 2023-02-28 09:32:26 +01:00
parent 54e3f7f41a
commit ce24ab6fc2
7 changed files with 145 additions and 59 deletions

View file

@ -19,7 +19,7 @@ from .devops_terraform_build import DevopsTerraformBuild, create_devops_terrafor
from .devops_build import DevopsBuild, create_devops_build_config, get_devops_build, get_tag_from_latest_commit
from .credential import gopass_password_from_path, gopass_field_from_path
from .domain import Validateable, Build
from .application import BuildService
from .domain import Validateable, Build, DockerBuild
from .application import BuildService, DockerBuildService
__version__ = "${version}"

View file

@ -1,8 +1,54 @@
from .domain import Build
from .python_util import execute
from .domain import Build, DockerBuild
from .infrastructure import FileApi, ResourceApi, DockerApi
class BuildService():
def __init__(self):
self.file_api = FileApi()
def initialize_build_dir(self, build: Build):
execute('rm -rf ' + build.build_path(), shell=True)
execute('mkdir -p ' + build.build_path(), shell=True)
self.file_api.clean_dir(build.build_path())
class DockerBuildService():
def __init__(self):
self.build_service = BuildService()
self.file_api = FileApi()
self.resource_api = ResourceApi()
self.docker_api = DockerApi()
def __copy_build_resource_file_from_package__(self, build: DockerBuild):
data = self.resource_api.read_resource("src/main/resources/docker/" + build.name)
self.file_api.write_to_file(build.build_path() + '/' + build.name, data)
def __copy_build_resources_from_package__(self, build: DockerBuild):
self.__copy_build_resource_file_from_package__(
'image/resources/install_functions.sh')
def __copy_build_resources_from_dir__(self, build: DockerBuild):
self.file_api.cp_force(build.docker_build_commons_path(), build.build_path())
def initialize_build_dir(self, build: DockerBuild):
self.build_service.initialize_build_dir(build)
self.file_api.clean_dir(build.build_path() + '/image/resources')
if build.use_package_common_files:
self.__copy_build_resources_from_package__(build)
else:
self.__copy_build_resources_from_dir__(build)
self.file_api.cp_recursive('image', build.build_path())
self.file_api.cp_recursive('test', build.build_path())
def image(self, build: DockerBuild):
self.docker_api.image(build.name(), build.build_path())
def drun(self, build: DockerBuild):
self.docker_api.drun(build.name())
def dockerhub_login(self, build: DockerBuild):
self.docker_api.dockerhub_login(build.dockerhub_user, build.dockerhub_password)
def dockerhub_publish(self, build: DockerBuild):
self.docker_api.dockerhub_publish(build.name(), build.dockerhub_user, build.docker_publish_tag)
def test(self, build: DockerBuild):
self.docker_api.test(build.name(), build.build_path())

View file

@ -11,13 +11,14 @@ def create_devops_build_config(stage, project_root_path, module,
def get_devops_build(project):
return project.get_property('devops_build')
# def get_tag_from_latest_commit():
# try:
# value = run('git describe --abbrev=0 --tags --exact-match', shell=True,
# capture_output=True, check=True)
# return value.stdout.decode('UTF-8').rstrip()
# except CalledProcessError:
# return None
# TODO: Remove from here!
def get_tag_from_latest_commit():
try:
value = run('git describe --abbrev=0 --tags --exact-match', shell=True,
capture_output=True, check=True)
return value.stdout.decode('UTF-8').rstrip()
except CalledProcessError:
return None
class DevopsBuild:

View file

@ -1,7 +1,5 @@
import sys
from subprocess import run
from pkg_resources import resource_string
from .python_util import filter_none
from .domain import DockerBuild
from .application import DockerBuildService
from .devops_build import DevopsBuild, create_devops_build_config
def create_devops_docker_build_config(stage,
@ -28,43 +26,11 @@ def create_devops_docker_build_config(stage,
class DevopsDockerBuild(DevopsBuild):
def __init__(self, project, config):
super().__init__(project, config)
project.build_depends_on('dda-python-terraform')
self.dockerhub_user = config['dockerhub_user']
self.dockerhub_password = config['dockerhub_password']
self.use_package_common_files = config['use_package_common_files']
self.build_commons_path = config['build_commons_path']
self.docker_build_commons_dir_name = config['docker_build_commons_dir_name']
self.docker_publish_tag = config['docker_publish_tag']
def docker_build_commons_path(self):
mylist = [self.build_commons_path,
self.docker_build_commons_dir_name]
return '/'.join(filter_none(mylist)) + '/'
def copy_build_resource_file_from_package(self, name):
run('mkdir -p ' + self.build_path() + '/image/resources', shell=True, check=True)
my_data = resource_string(
__name__, "src/main/resources/docker/" + name)
with open(self.build_path() + '/' + name, "w", encoding="utf-8") as output_file:
output_file.write(my_data.decode(sys.stdout.encoding))
def copy_build_resources_from_package(self):
self.copy_build_resource_file_from_package(
'image/resources/install_functions.sh')
def copy_build_resources_from_dir(self):
run('cp -f ' + self.docker_build_commons_path() +
'* ' + self.build_path(), shell=True, check=True)
self.build = DockerBuild(project, config)
self.docker_build_service = DockerBuildService()
def initialize_build_dir(self):
super().initialize_build_dir()
if self.use_package_common_files:
self.copy_build_resources_from_package()
else:
self.copy_build_resources_from_dir()
run('cp -r image ' + self.build_path(), shell=True, check=True)
run('cp -r test ' + self.build_path(), shell=True, check=True)
self.docker_build_service.initialize_build_dir(self.build)
def image(self):
run('docker build -t ' + self.name() +

View file

@ -3,18 +3,21 @@ from .python_util import filter_none
class Validateable():
def __validate_is_not_empty__(self, field_name: str) -> List[str]:
value = self.__dict__[field_name]
if value is None or value == '':
return [f"Field '{field_name}' may not be empty."]
else:
return []
def validate(self) -> List[str]:
return []
def is_valid(self) -> bool:
return len(self.validate()) < 1
def validate_is_not_empty(self, field_name: str) -> List[str]:
value = self.__dict__[field_name]
if value is None or value == '':
return [f"Field '{field_name}' may not be empty."]
else:
return []
class Build(Validateable):
@ -48,3 +51,20 @@ class Build(Validateable):
for key in keys:
result[key] = self.get(key)
return result
class DockerBuild(Build):
def __init__(self, project, config):
super().__init__(project, config)
project.build_depends_on('dda-python-terraform')
self.dockerhub_user = config['dockerhub_user']
self.dockerhub_password = config['dockerhub_password']
self.use_package_common_files = config['use_package_common_files']
self.build_commons_path = config['build_commons_path']
self.docker_build_commons_dir_name = config['docker_build_commons_dir_name']
self.docker_publish_tag = config['docker_publish_tag']
def docker_build_commons_path(self):
list = [self.build_commons_path,
self.docker_build_commons_dir_name]
return '/'.join(filter_none(list)) + '/'

View file

@ -0,0 +1,53 @@
from pathlib import Path
from sys import stdout
from pkg_resources import resource_string
from .python_util import execute
class ResourceApi():
def read_resource(self, path: str) -> bytes:
return resource_string(__name__, path)
class FileApi():
def clean_dir(self, directory: str):
execute('rm -rf ' + directory, shell=True)
execute('mkdir -p ' + directory, shell=True)
def cp_force(self, src: str, target_dir: str):
execute('cp -f ' + src + '* ' + target_dir, shell=True)
def cp_recursive(self, src: str, target_dir: str):
execute('cp -r ' + src + ' ' + target_dir, shell=True)
def write_to_file(self, path: Path, data: bytes):
with open(path, "w", encoding=stdout.encoding) as output_file:
output_file.write(data.decode(stdout.encoding))
class DockerApi():
def image(self, name: str, path: Path):
execute('docker build -t ' + name +
' --file ' + path + '/image/Dockerfile '
+ path + '/image', shell=True)
def drun(self, name: str):
execute('docker run -it --entrypoint="" ' +
name + ' /bin/bash', shell=True)
def dockerhub_login(self, username: str, password: str):
execute('docker login --username ' + username +
' --password ' + password, shell=True)
def dockerhub_publish(self, name: str, username: str, tag=None):
if tag is not None:
execute('docker tag ' + name + ' ' + username +
'/' + name + ':' + tag, shell=True)
execute('docker push ' + username +
'/' + name + ':' + tag, shell=True)
execute('docker tag ' + name + ' ' + username +
'/' + name + ':latest', shell=True)
execute('docker push ' + username +
'/' + name + ':latest', shell=True)
def test(self, name: str, path: Path):
execute('docker build -t ' + name + '-test ' +
'--file ' + path + '/test/Dockerfile '
+ path + '/test', shell=True)

View file

@ -6,7 +6,7 @@ class TestValidateable(Validateable):
self.field = value
def validate(self):
return self.validate_is_not_empty('field')
return self.__validate_is_not_empty__('field')
def test_should_validate_non_empty_strings():