def _push(self): last_push_duration = files.fetch_action_arg('push', 'last_push_duration') self.container_name = files.fetch_action_arg('build', 'last_container') self.started_push_time = time.time() # TODO: unify these commands by factoring out docker command # based on config if 'gceProject' in self.config: self._push_gke() else: self._push_docker() progress_bar.duration_progress( 'Pushing ', last_push_duration, lambda: self.push_process.poll() is not None) if self.push_process.poll() != 0: push_error = self.push_process.communicate() print(colored(push_error[0], 'red')) print(colored(push_error[1], 'red')) sys.exit(1) with open('.push.json', 'w') as f: f.write( json.dumps({ "last_remote_container": self.remote_container_name, "last_push_duration": time.time() - self.started_push_time })) print("Pushed to {}".format(self.remote_container_name))
def _build(self): last_build_duration = files.fetch_action_arg('build', 'last_build_duration') started_build_time = time.time() container_name = "{}:{}".format(self.config['name'], uuid.uuid4()) print("Starting build {}".format(container_name)) # Add bar build_process = process_helpers.run_popen( "CONTAINER_NAME={} make build".format(container_name), shell=True) progress_bar.duration_progress( 'Building', last_build_duration, lambda: build_process.poll() is not None) if build_process.poll() != 0: print( colored(build_process.communicate()[0].decode("utf-8"), 'red')) sys.exit(1) 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_duration_progress_no_duration_done(progressbar): """Duration is None and we are done so nothing is called in the func""" duration_progress('activity', None, lambda: True) progressbar_obj = progressbar.ProgressBar.return_value.return_value progressbar_obj.next.assert_not_called() progressbar_obj.update.assert_not_called()
def test_duration_progress_no_duration_not_done(progressbar): """We have no duration, then we aren't done yet, then we enter the while loop for one iteration to update the bar and then terminate """ duration_progress('activity', None, MagicMock( side_effect=[False, False, False, True])) progressbar_obj = progressbar.ProgressBar.return_value.return_value progressbar_obj.next.assert_not_called() progressbar_obj.update.call_count == 3
def test_duration_progress_duration_done(progressbar): """We have a duration of 1 but then terminate immediately So we have a bar.next() call, then we update as we're done early and then `if not is_done()` is not called so func terminates """ duration_progress('activity', 1, lambda: True) progressbar_obj = progressbar.ProgressBar.return_value.return_value assert progressbar_obj.next.call_count == 1 assert progressbar_obj.update.call_count == 1
def test_duration_progress_not_done(progressbar): """We have a duration of 1 and then we aren't done once and then we finish, which means bar.next() is called twice inside of the for loop and and update happens once as we're done early """ duration_progress('activity', 1, MagicMock( side_effect=[False, True, True])) progressbar_obj = progressbar.ProgressBar.return_value.return_value assert progressbar_obj.next.call_count == 2 assert progressbar_obj.update.call_count == 1
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 _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')