def build_new_container(self): try: log("No image found. Rebuilding container. This may take a while.") self.client.images.build(path=self.dockerfile_dir, dockerfile=self.dockerfile, tag=self.image_name()) log("Container built: " + self.image_name()) except BuildError as e: error( "Container build failed. Check the following output for errors:" ) for message in e.build_log: error(message) sys.exit(1)
def run_command(self, command): if not self.container: self.container = self.client.containers.run( self.image_name(), "sleep 1d", volumes={ self.git_dir: { "bind": self.jarvis_directory(), 'mode': 'rw' } }, working_dir=self.jarvis_directory(), detach=True) self.container.__class__.exec_run = monkey_patched_exec_run exec_id, output = self.container.exec_run(command, environment={ "CI": True, "JARVIS_CI": True }) try: for line in output: verbatim(line.strip().decode("utf-8")) except UnicodeError as e: # This issue usually happens when you're running something like Perl in the container. # Perl ignores the encoding setting of stdout and spits out incompatible encodings... warn( "Failed to decode the output as unicode. Falling back to printing undecoded byte strings. Sorry!" ) for line in output: verbatim(line.strip()) exit_code = get_exit_code(self.client, exec_id) if exit_code != 0: error("Command finished with exit code " + str(exit_code)) sys.exit(exit_code) else: log("Command finished with exit code " + str(exit_code), colour="blue")
def execute_in(self, container: DockerContainer): log("Executing Stage: " + self.name, colour="green") log("=" * 80) log(self.script, colour="blue") container.run_command(self.script)
def rebuild_image_if_changed(self): try: self.client.images.get(self.image_name()) log("Found previously built container image " + self.image_name()) except ImageNotFound: self.build_new_container()
def execute_in(self, container: DockerContainer): for stage in self.stages: stage.execute_in(container) log("As always Sir, a great pleasure watching you work!", colour="green")