def _build(self): last_build_duration = files.fetch_action_arg( 'build', 'last_build_duration') schema.validate() started_build_time = time.time() container_name = "{}:{}".format(self.config['name'], uuid.uuid4()) print("Starting build {}".format(container_name)) template_parameters = config_helpers.\ get_template_parameters(self.config) params = "" for key, val in template_parameters.items(): params += "{}={} ".format(key.upper(), val) build_cmd = "CONTAINER_NAME={} {}make build".format( container_name, params) if self.args['--verbose']: build_process = process_helpers.run_popen(build_cmd, shell=True, stdout=True, stderr=True) else: build_process = process_helpers.run_popen(build_cmd, shell=True) with process_helpers.prevent_deadlock(build_process): progress_bar.duration_progress( 'Building {}'.format( self.config["name"]), last_build_duration, lambda: build_process.poll() is not None) if build_process.poll() != 0: # When we have an error, get the stdout and error output # and display them both with the error output in red. output, error_msg = build_process.communicate() if output: print(output.decode("utf-8")) if error_msg: error_handling.throw_error(error_msg.decode("utf-8"), 'red') built_time = time.time() # Write last container to file with open('.build.json', 'w') as f: f.write(json.dumps({ "last_container": container_name, "last_build_duration": built_time - started_build_time })) print("Built {}".format(container_name))
def test_prevent_deadlock(pipe_output): """Assert that we iterate over the correct amount of output from the 'subprocess' """ proc_mock = MagicMock() proc_mock.stdout.readline = pipe_output with prevent_deadlock(proc_mock): pass # python2 treats `iter()` a bit differently and won't count the # sentinel as an iteration loop if sys.version_info[0] < 3: pipe_output.length -= 1 assert proc_mock.stdout.readline.call_count == pipe_output.length
def _poll_docker_proc(self): """used only in the case of non-verbose deploy mode to dump loading bar and any error that happened """ last_push_duration = files.fetch_action_arg( 'push', 'last_push_duration') with process_helpers.prevent_deadlock(self.push_process): progress_bar.duration_progress( 'Pushing {}'.format(self.config["name"]), last_push_duration, lambda: self.push_process.poll() is not None) # If the push fails, get stdout/stderr messages and display them # to the user, with the error message in red. if self.push_process.poll() != 0: push_stdout, push_error = self.push_process.communicate() print(push_stdout.decode("utf-8")) error_handling.throw_error(push_error.decode("utf-8"), 'red')