def get_patch(version): ''' From "2.3.45" latest published npm version return "45" to use as major.minor when se.kth.automaticPublish is true. Defaults to None if no patch is found in the version string. ''' result = None start_version = 0 if not version: raise PipelineException('No version passed to get patch from.') if version.count('.') == 1: return result try: patch_version_index = version.rfind(".") + 1 patch_version = version[patch_version_index:] result = int(patch_version) except: raise PipelineException( f"Could not get the patch version from '{version}'.") return result
def get_image_only_semver(data): if data[pipeline_data.IMAGE_NAME] is None: raise PipelineException("Missing the name of the image.") if data[pipeline_data.SEM_VER] is None: raise PipelineException("Missing the SemVer for the image.") return '{}:{}'.format(data[pipeline_data.IMAGE_NAME], data[pipeline_data.SEM_VER])
def get_image(data): if data[pipeline_data.IMAGE_NAME] is None: raise PipelineException("Missing the name of the image.") if data[pipeline_data.IMAGE_VERSION] is None: raise PipelineException("Missing the version for the image.") return '{}:{}'.format(data[pipeline_data.IMAGE_NAME], data[pipeline_data.IMAGE_VERSION])
def get_tags_from_response(self, response): # pragma: no cover try: response = response.json() return response['tags'] except ValueError as json_err: raise PipelineException('Could not parse JSON response ("{}") from registry API: {}' .format(response.text, json_err)) except KeyError: raise PipelineException('Registry API response contains no key "tags". Response was: {}' .format(response.text))
def call_api_endpoint(self, url, user, password): # pragma: no cover try: response = get(url, auth=HTTPBasicAuth(user, password)) if response.status_code == 200: return response if response.status_code == 404: raise PipelineException( 'Could not find any images in registry for {}'.format(url)) except HTTPError as http_err: raise PipelineException('HTTPError when calling registry API: {}' .format(http_err.response)) except (ConnectTimeout, RequestException) as req_err: raise PipelineException('Timeout or request exception when calling registry API: {}' .format(req_err))
def get_tags_from_response(self, response): #pragma: no cover try: response = response.json() if environment.get_push_azure(): return [version['name'] for version in response['tags']] else: return response['tags'] except ValueError as json_err: raise PipelineException( 'Could not parse JSON response ("{}") from registry API: {}'. format(response.text, json_err)) except KeyError: raise PipelineException( 'Registry API response contains no key "tags". Response was: {}' .format(response.text))
def verify_image_version_in_tags(self, tags, data): if not data[pipeline_data.IMAGE_VERSION] in tags: self.log.error( 'Pushed tag could not be found in tag list on registry') raise PipelineException( 'Could not verify tag with remote registry') self.log.info('Found tag in tag list. Verification successful.') return True
def run_pipeline_step(self, data): if not self.step_environment_ok(): return data if not self.step_data_is_ok(data): return data try: self.run_step(data) except PipelineException as p_ex: p_ex.set_data(data) except Exception as ex: p_ex = PipelineException(str(ex), str(ex)) p_ex.set_data(data) raise p_ex if self.next_step: self.next_step.run_pipeline_step(data) return data
def compose_dry_run(self, data): try: output = docker.run_dry_run_compose( file_util.get_absolue_path( DryRunStep.DRY_RUN_COMPOSE_FILENAME), data) self.log.debug('Output from dry run was: %s', output) except Exception as ex: raise PipelineException(str(ex), self.get_slack_message(ex, data))
def run_with_output(cmd, log_cmd=True): log = logging.getLogger(__name__) try: if log_cmd: log.info('Running command with output: "%s"', cmd) output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True) if output: return output.decode('utf-8') except subprocess.CalledProcessError as cpe: if cpe.output: raise PipelineException(cpe.output.decode('utf-8')) raise PipelineException(f"{str(cpe)}") except: raise PipelineException("Unabled exception. {}".format( sys.exc_info()[0]))
def run_pipeline_step(self, data): if not self.step_environment_ok(): return data if not self.step_data_is_ok(data): return data self.log.info('Running "%s"', self.get_step_name()) try: self.run_step(data) except PipelineException as p_ex: p_ex.set_data(data) raise except Exception as ex: p_ex = PipelineException(str(ex), str(ex)) p_ex.set_data(data) raise p_ex if self.next_step: self.next_step.run_pipeline_step(data) return data
def run_step(self, data): image_id = self.run_build(data) image_grep_output = self.verify_built_image(image_id) size = self.get_image_size(image_grep_output) data[pipeline_data.IMAGE_SIZE] = size if size == '0' or size == 'N/A': raise PipelineException('Built image has no size') data[pipeline_data.LOCAL_IMAGE_ID] = image_id self.log.info('Built image with id "%s" and size "%s"', image_id, size) return data
def test_run_step(self): data = {pipeline_data.NPM_CONF_NODE_VERSION: '10.4.5'} step = InitNodeEnvironmentStep() step.get_nvm_installed_version = mock.MagicMock() step.get_nvm_installed_version.side_effect = PipelineException('N/A\n') step.install_version = mock.MagicMock() step.run_step(data) step.install_version.assert_called_with('10.4.5') step.install_version.reset_mock() step.get_nvm_installed_version.side_effect = PipelineException( 'Error!\n') sys.exit = mock.MagicMock() step.run_step(data) sys.exit.assert_called_once() step.install_version.reset_mock() step.get_nvm_installed_version.side_effect = None step.get_nvm_installed_version.return_value = '10.4.5' step.run_step(data) step.install_version.assert_not_called()
def compose_dry_run(self, data): self.log.info( 'Doing a dry run using "/docker-compose.yml" to test the newly built Docker iamge' ) try: output = docker.run_dry_run_compose( file_util.get_absolue_path( DryRunStep.DRY_RUN_COMPOSE_FILENAME), data) self.log.debug('Output from dry run was: %s', output) except Exception as ex: raise PipelineException(str(ex), self.get_slack_message(ex, data))
def run_with_output(cmd, log_cmd=False, check=False): log = logging.getLogger("-") try: if log_cmd: log.info("Command: '%s'", cmd) result = subprocess.run(args=["/bin/bash", "-i", "-c", cmd], capture_output=True, check=check, encoding='utf-8') if result: if result.stdout: return result.stdout if result.stderr: return result.stderr except subprocess.CalledProcessError as cpe: log.info(str(cpe)) raise PipelineException(f'{cpe.output}') except: raise PipelineException(f'Unhandled exception when execution command.')
def run_step(self, data): try: image_id = self.run_build(data) image_grep_output = self.verify_built_image(image_id) size = self.get_image_size(image_grep_output) data[pipeline_data.IMAGE_SIZE] = size if size == '0' or size == 'N/A': raise PipelineException('Built image has no size') data[pipeline_data.LOCAL_IMAGE_ID] = image_id self.log.info('Built image with id "%s" and size "%s"', image_id, size) except: self.handle_step_error("Unknown error when building Docker image.", sys.exc_info()[0]) self.step_ok() return data
def get_major_minor(version): ''' Gets the major minor didgits = "[1.2].3" ''' if not version: raise PipelineException('No version passed to get major.minor from.') if version.count('.') == 1: return version patch_version_index = version.rfind(".") result = version[:patch_version_index] return result
def test_slack_message_is_not_regular_message(self): exception = PipelineException("Regular message", "Slack message") self.assertEqual(str(exception), "Regular message")
def test_no_slack_message(self): exception = PipelineException("Regular message") self.assertEqual(exception.slack_message, "Regular message")