def test_writedockerfile_without_docker_cmd(): _, tmp_file = tempfile.mkstemp() dockerfile.write_dockerfile(destination=tmp_file, docker_command=None, path_prefix="/pre", base_image="foo_bar") actual = open(tmp_file, 'r').read() expected = """FROM foo_bar WORKDIR /pre ENV FAIRING_RUNTIME 1 RUN if [ -e requirements.txt ];then pip install --no-cache -r requirements.txt; fi COPY /pre /pre""" assert actual == expected
def test_writedockerfile_with_early_install_reqs(): _, tmp_file = tempfile.mkstemp() dockerfile.write_dockerfile(destination=tmp_file, docker_command=["python", "main.py"], path_prefix="/pre", base_image="foo_bar", install_reqs_before_copy=True) actual = open(tmp_file, 'r').read() expected = """FROM foo_bar WORKDIR /pre ENV FAIRING_RUNTIME 1 COPY /pre/requirements.txt /pre RUN if [ -e requirements.txt ];then pip install --no-cache -r requirements.txt; fi COPY /pre /pre CMD python main.py""" assert actual == expected
def _build(self): """build the docker image""" docker_command = self.preprocessor.get_command() logger.warning("Docker command: {}".format(docker_command)) if not docker_command: logger.warning( "Not setting a command for the output docker image.") install_reqs_before_copy = self.preprocessor.is_requirements_txt_file_present( ) if self.dockerfile_path: dockerfile_path = self.dockerfile_path else: dockerfile_path = dockerfile.write_dockerfile( docker_command=docker_command, path_prefix=self.preprocessor.path_prefix, base_image=self.base_image, install_reqs_before_copy=install_reqs_before_copy, executable_path_prefix=self.executable_path_prefix) self.preprocessor.output_map[dockerfile_path] = 'Dockerfile' context_file, context_hash = self.preprocessor.context_tar_gz() self.image_tag = self.full_image_name(context_hash) logger.warning('Building docker image {}...'.format(self.image_tag)) with open(context_file, 'rb') as fileobj: bld = self.docker_client.build(path='.', custom_context=True, fileobj=fileobj, tag=self.image_tag, encoding='utf-8') for line in bld: self._process_stream(line)
def gen_cmd(self, option): """ generate podman cmd for builder and publisher :param option: options for which cmd to generate, 'build' or 'publish' """ if option == 'build': docker_command = self.preprocessor.get_command() logger.warning("Podman command: {}".format(docker_command)) if not docker_command: logger.warning("Not setting a command for the podman image.") install_reqs_before_copy = self.preprocessor.is_requirements_txt_file_present( ) if self.dockerfile_path: dockerfile_path = self.dockerfile_path else: dockerfile_path = dockerfile.write_dockerfile( docker_command=docker_command, path_prefix=self.preprocessor.path_prefix, base_image=self.base_image, install_reqs_before_copy=install_reqs_before_copy) self.preprocessor.output_map[dockerfile_path] = 'Dockerfile' self.context_file, context_hash = self.preprocessor.context_tar_gz( ) self.image_tag = self.full_image_name(context_hash) cmd = 'podman build -t {} - < {}'.format(self.image_tag, self.context_file) elif option == 'publish': cmd = 'podman push {} --tls-verify={}' \ .format(self.image_tag, str(self.tls_verify).lower()) else: raise Exception('Generate command failed with option - ' + option) return cmd
def test_writedockerfile_with_docker_cmd(): _, tmp_file = tempfile.mkstemp() dockerfile.write_dockerfile(destination=tmp_file, docker_command=["python", "main.py"], path_prefix="/pre", base_image="foo_bar") actual = open(tmp_file, 'r').read() expected = """FROM foo_bar WORKDIR /pre ENV FAIRING_RUNTIME 1 RUN if [ -e requirements.txt ];then if [ "$(whoami)" = "root" ];\ then pip install --no-cache -r requirements.txt;\ else pip install --user --no-cache -r requirements.txt; fi; fi COPY /pre /pre CMD python main.py""" assert actual == expected
def build(self): logging.info("Building image using cluster builder.") install_reqs_before_copy = self.preprocessor.is_requirements_txt_file_present( ) if self.dockerfile_path: dockerfile_path = self.dockerfile_path else: dockerfile_path = dockerfile.write_dockerfile( path_prefix=self.preprocessor.path_prefix, base_image=self.base_image, install_reqs_before_copy=install_reqs_before_copy, executable_path_prefix=self.executable_path_prefix) self.preprocessor.output_map[dockerfile_path] = 'Dockerfile' context_path, context_hash = self.preprocessor.context_tar_gz() self.image_tag = self.full_image_name(context_hash) self.context_source.prepare(context_path) labels = {'fairing-builder': 'kaniko'} labels['fairing-build-id'] = str(uuid.uuid1()) pod_spec = self.context_source.generate_pod_spec( self.image_tag, self.push) for fn in self.pod_spec_mutators: fn(self.manager, pod_spec, self.namespace) pod_spec_template = client.V1PodTemplateSpec( metadata=client.V1ObjectMeta( generate_name="fairing-builder-", labels=labels, namespace=self.namespace, annotations={"sidecar.istio.io/inject": "false"}, ), spec=pod_spec) job_spec = client.V1JobSpec( template=pod_spec_template, parallelism=1, completions=1, backoff_limit=0, ) build_job = client.V1Job(api_version="batch/v1", kind="Job", metadata=client.V1ObjectMeta( generate_name="fairing-builder-", labels=labels, ), spec=job_spec) created_job = client. \ BatchV1Api(). \ create_namespaced_job(self.namespace, build_job) self.manager.log(name=created_job.metadata.name, namespace=created_job.metadata.namespace, selectors=labels, container="kaniko") # Invoke upstream clean ups self.context_source.cleanup() # Cleanup build_job if requested by user # Otherwise build_job will be cleaned up by Kubernetes GC if self.cleanup: logging.warning("Cleaning up job {}...".format( created_job.metadata.name)) client. \ BatchV1Api(). \ delete_namespaced_job( created_job.metadata.name, created_job.metadata.namespace, body=client.V1DeleteOptions(propagation_policy='Foreground') )