def paasta_push_to_registry(args): """Upload a docker image to a registry""" service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, args.soa_dir) cmd = build_command(service, args.commit) loglines = [] returncode, output = _run(cmd, timeout=3600, log=True, stream=True, component='build', service=service, loglevel='debug') if returncode != 0: loglines.append('ERROR: Failed to promote image for %s.' % args.commit) output = get_jenkins_build_output_url() if output: loglines.append('See output: %s' % output) else: loglines.append('Successfully pushed image for %s to registry' % args.commit) for logline in loglines: _log( service=service, line=logline, component='build', level='event', ) return returncode
def paasta_push_to_registry(args): """Upload a docker image to a registry""" service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service) cmd = build_command(service, args.commit) loglines = [] returncode, output = _run( cmd, timeout=3600, log=True, component='build', service=service, loglevel='debug' ) if returncode != 0: loglines.append('ERROR: Failed to promote image for %s.' % args.commit) output = get_jenkins_build_output_url() if output: loglines.append('See output: %s' % output) else: loglines.append('Successfully pushed image for %s to registry' % args.commit) for logline in loglines: _log( service=service, line=logline, component='build', level='event', ) return returncode
def paasta_wait_for_deployment(args): """Wrapping wait_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) try: validate_full_git_sha(args.commit) except ArgumentTypeError: refs = remote_git.list_remote_refs(args.git_url) commits = short_to_full_git_sha(short=args.commit, refs=refs) if len(commits) != 1: raise ValueError( "%s matched %d git shas (with refs pointing at them). Must match exactly 1." % (args.commit, len(commits)), ) args.commit = commits[0] try: validate_service_name(service, soa_dir=args.soa_dir) validate_deploy_group(args.deploy_group, service, args.soa_dir) validate_git_sha( args.commit, args.git_url, args.deploy_group, service, ) except (GitShaError, DeployGroupError, NoSuchService) as e: paasta_print(PaastaColors.red('{}'.format(e))) return 1 try: wait_for_deployment( service=service, deploy_group=args.deploy_group, git_sha=args.commit, soa_dir=args.soa_dir, timeout=args.timeout, ) _log( service=service, component='deploy', line=("Deployment of {} for {} complete".format( args.commit, args.deploy_group)), level='event', ) except (KeyboardInterrupt, TimeoutError, NoSuchCluster): report_waiting_aborted(service, args.deploy_group) return 1 return 0
def service_dir_check(service, soa_dir): """Check whether directory service exists in /nail/etc/services :param service: string of service name we wish to inspect """ try: validate_service_name(service, soa_dir) print PaastaCheckMessages.service_dir_found(service, soa_dir) except NoSuchService: print PaastaCheckMessages.service_dir_missing(service, soa_dir)
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" deploy_group = args.deploy_group service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service) return mark_for_deployment(git_url=args.git_url, deploy_group=deploy_group, service=service, commit=args.commit)
def paasta_generate_pipeline(args): """Generate a Jenkins build pipeline. :param args: argparse.Namespace obj created from sys.args by cli""" service = args.service or guess_service_name() try: validate_service_name(service) except NoSuchService as service_not_found: print service_not_found sys.exit(1) generate_pipeline(service=service)
def paasta_push_to_registry(args: argparse.Namespace) -> int: """Upload a docker image to a registry""" service = args.service if service and service.startswith("services-"): service = service.split("services-", 1)[1] validate_service_name(service, args.soa_dir) image_identifier = build_image_identifier(args.commit, None, args.image_version) if not args.force: try: if is_docker_image_already_in_registry(service, args.soa_dir, args.commit, args.image_version): print( "The docker image is already in the PaaSTA docker registry. " "I'm NOT overriding the existing image. " "Add --force to override the image in the registry if you are sure what you are doing." ) return 0 except RequestException as e: registry_uri = get_service_docker_registry(service, args.soa_dir) print( "Can not connect to the PaaSTA docker registry '%s' to verify if this image exists.\n" "%s" % (registry_uri, str(e))) return 1 cmd = build_command(service, args.commit, args.image_version) loglines = [] returncode, output = _run( cmd, timeout=3600, log=True, component="build", service=service, loglevel="debug", ) if returncode != 0: loglines.append("ERROR: Failed to promote image for %s." % image_identifier) output = get_jenkins_build_output_url() if output: loglines.append("See output: %s" % output) else: loglines.append("Successfully pushed image for %s to registry" % image_identifier) _log_audit( action="push-to-registry", action_details={"commit": args.commit}, service=service, ) for logline in loglines: _log(service=service, line=logline, component="build", level="event") return returncode
def paasta_cook_image(args, service=None, soa_dir=None): """Build a docker image""" if not service: service = args.service if service.startswith('services-'): service = service.split('services-', 1)[1] if not soa_dir: soa_dir = args.yelpsoa_config_root validate_service_name(service, soa_dir) run_env = os.environ.copy() default_tag = 'paasta-cook-image-{}-{}'.format(service, get_username()) tag = run_env.get('DOCKER_TAG', default_tag) run_env['DOCKER_TAG'] = tag if not makefile_responds_to('cook-image'): paasta_print( 'ERROR: local-run now requires a cook-image target to be present in the Makefile. See' 'http://paasta.readthedocs.io/en/latest/about/contract.html', file=sys.stderr, ) return 1 try: cmd = 'make cook-image' returncode, output = _run( cmd, env=run_env, log=True, component='build', service=service, loglevel='debug', ) if returncode != 0: _log( service=service, line='ERROR: make cook-image failed for %s.' % service, component='build', level='event', ) else: action_details = { 'tag': tag, } _log_audit( action='cook-image', action_details=action_details, service=service, ) return returncode except KeyboardInterrupt: paasta_print('\nProcess interrupted by the user. Cancelling.', file=sys.stderr) return 2
def paasta_generate_pipeline(args): """Generate a Jenkins build pipeline. :param args: argparse.Namespace obj created from sys.args by cli""" service = args.service or guess_service_name() soa_dir = DEFAULT_SOA_DIR try: validate_service_name(service, soa_dir=soa_dir) except NoSuchService as service_not_found: print service_not_found return 1 generate_pipeline(service=service, soa_dir=soa_dir)
def paasta_generate_pipeline(args): """Generate a Jenkins build pipeline. :param args: argparse.Namespace obj created from sys.args by cli""" service = args.service or guess_service_name() soa_dir = DEFAULT_SOA_DIR try: validate_service_name(service, soa_dir=soa_dir) except NoSuchService as service_not_found: paasta_print(service_not_found) return 1 generate_pipeline(service=service, soa_dir=soa_dir)
def paasta_wait_for_deployment(args): """Wrapping wait_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith("services-"): service = service.split("services-", 1)[1] if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) args.commit = validate_git_sha(sha=args.commit, git_url=args.git_url) version = DeploymentVersion(sha=args.commit, image_version=args.image_version) try: validate_service_name(service, soa_dir=args.soa_dir) validate_deploy_group(args.deploy_group, service, args.soa_dir) validate_version_is_latest(version, args.git_url, args.deploy_group, service) except (VersionError, DeployGroupError, NoSuchService) as e: print(PaastaColors.red(f"{e}")) return 1 try: asyncio.run( wait_for_deployment( service=service, deploy_group=args.deploy_group, git_sha=args.commit, image_version=args.image_version, soa_dir=args.soa_dir, timeout=args.timeout, polling_interval=args.polling_interval, diagnosis_interval=args.diagnosis_interval, time_before_first_diagnosis=args.time_before_first_diagnosis, )) _log( service=service, component="deploy", line=(f"Deployment of {version} for {args.deploy_group} complete"), level="event", ) except (KeyboardInterrupt, TimeoutError, NoSuchCluster): report_waiting_aborted(service, args.deploy_group) return 1 return 0
def paasta_push_to_registry(args): """Upload a docker image to a registry""" service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, args.soa_dir) if not args.force: try: if is_docker_image_already_in_registry(service, args.soa_dir, args.commit): paasta_print( "The docker image is already in the PaaSTA docker registry. " "I'm NOT overriding the existing image. " "Add --force to override the image in the registry if you are sure what you are doing.", ) return 0 except RequestException as e: registry_uri = get_service_docker_registry(service, args.soa_dir) paasta_print("Can not connect to the PaaSTA docker registry '%s' to verify if this image exists.\n" "%s" % (registry_uri, str(e))) return 1 cmd = build_command(service, args.commit) loglines = [] returncode, output = _run( cmd, timeout=3600, log=True, component='build', service=service, loglevel='debug', ) if returncode != 0: loglines.append('ERROR: Failed to promote image for %s.' % args.commit) output = get_jenkins_build_output_url() if output: loglines.append('See output: %s' % output) else: loglines.append('Successfully pushed image for %s to registry' % args.commit) _log_audit( action='push-to-registry', action_details={'commit': args.commit}, service=service, ) for logline in loglines: _log( service=service, line=logline, component='build', level='event', ) return returncode
def paasta_get_latest_deployment(args): service = args.service deploy_group = args.deploy_group soa_dir = args.soa_dir validate_service_name(service, soa_dir) git_sha = get_currently_deployed_sha(service=service, deploy_group=deploy_group, soa_dir=soa_dir) if not git_sha: paasta_print(PaastaColors.red("A deployment could not be found for %s in %s" % (deploy_group, service))) return 1 else: paasta_print(git_sha) return 0
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" deploy_group = args.deploy_group service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service) return mark_for_deployment( git_url=args.git_url, deploy_group=deploy_group, service=service, commit=args.commit )
def paasta_get_latest_deployment(args): service = args.service deploy_group = args.deploy_group soa_dir = args.soa_dir validate_service_name(service, soa_dir) git_sha = get_currently_deployed_sha(service=service, deploy_group=deploy_group, soa_dir=soa_dir) if not git_sha: print PaastaColors.red("A deployment could not be found for %s in %s" % (deploy_group, service)) return 1 else: print git_sha return 0
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" cluster, instance = args.clusterinstance.split('.') service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service) returncode = mark_for_deployment(git_url=args.git_url, cluster=cluster, instance=instance, service=service, commit=args.commit) sys.exit(returncode)
def paasta_cook_image(args, service=None, soa_dir=None): """Build a docker image""" if not service: service = args.service if service.startswith("services-"): service = service.split("services-", 1)[1] if not soa_dir: soa_dir = args.yelpsoa_config_root validate_service_name(service, soa_dir) run_env = os.environ.copy() default_tag = "paasta-cook-image-{}-{}".format(service, get_username()) tag = run_env.get("DOCKER_TAG", default_tag) run_env["DOCKER_TAG"] = tag if not makefile_responds_to("cook-image"): print( "ERROR: local-run now requires a cook-image target to be present in the Makefile. See" "http://paasta.readthedocs.io/en/latest/about/contract.html", file=sys.stderr, ) return 1 try: cmd = "make cook-image" returncode, output = _run( cmd, env=run_env, log=True, component="build", service=service, loglevel="debug", ) if returncode != 0: _log( service=service, line="ERROR: make cook-image failed for %s." % service, component="build", level="event", ) else: action_details = {"tag": tag} _log_audit(action="cook-image", action_details=action_details, service=service) return returncode except KeyboardInterrupt: print("\nProcess interrupted by the user. Cancelling.", file=sys.stderr) return 2
def paasta_wait_for_deployment(args): """Wrapping wait_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) args.commit = validate_git_sha(sha=args.commit, git_url=args.git_url) try: validate_service_name(service, soa_dir=args.soa_dir) validate_deploy_group(args.deploy_group, service, args.soa_dir) validate_git_sha_is_latest( args.commit, args.git_url, args.deploy_group, service, ) except (GitShaError, DeployGroupError, NoSuchService) as e: paasta_print(PaastaColors.red(f'{e}')) return 1 try: wait_for_deployment( service=service, deploy_group=args.deploy_group, git_sha=args.commit, soa_dir=args.soa_dir, timeout=args.timeout, ) _log( service=service, component='deploy', line=("Deployment of {} for {} complete".format( args.commit, args.deploy_group)), level='event', ) except (KeyboardInterrupt, TimeoutError, NoSuchCluster): report_waiting_aborted(service, args.deploy_group) return 1 return 0
def perform_performance_check(args): service = args.service if service.startswith("services-"): service = service.split("services-", 1)[1] validate_service_name(service, args.soa_dir) try: submit_performance_check_job(service=service, soa_dir=args.soa_dir) except Exception as e: print( "Something went wrong with the performance check. Safely bailing. No need to panic." ) print("Here was the error:") print(str(e))
def paasta_itest(args): """Build and test a docker image""" service = args.service soa_dir = args.soa_dir if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, soa_dir=soa_dir) tag = build_docker_tag(service, args.commit) run_env = os.environ.copy() run_env['DOCKER_TAG'] = tag cmd = "make itest" loglines = [] _log( service=service, line='starting itest for %s.' % args.commit, component='build', level='event' ) returncode, output = _run( cmd, env=run_env, timeout=3600, log=True, component='build', service=service, loglevel='debug', stream=True, ) if returncode != 0: loglines.append( 'ERROR: itest failed for %s.' % args.commit ) output = get_jenkins_build_output_url() if output: loglines.append('See output: %s' % output) else: loglines.append('itest passed for %s.' % args.commit) if not check_docker_image(service, args.commit): loglines.append('ERROR: itest has not created %s' % tag) returncode = 1 for logline in loglines: _log( service=service, line=logline, component='build', level='event', ) return returncode
def paasta_itest(args): """Build and test a docker image""" service = args.service soa_dir = args.soa_dir if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, soa_dir=soa_dir) tag = build_docker_tag(service, args.commit) run_env = os.environ.copy() run_env['DOCKER_TAG'] = tag cmd = "make itest" loglines = [] _log( service=service, line='starting itest for %s.' % args.commit, component='build', level='event' ) returncode, output = _run( cmd, env=run_env, timeout=3600, log=True, component='build', service=service, loglevel='debug' ) if returncode != 0: loglines.append( 'ERROR: itest failed for %s.' % args.commit ) output = get_jenkins_build_output_url() if output: loglines.append('See output: %s' % output) else: loglines.append('itest passed for %s.' % args.commit) if not check_docker_image(service, args.commit): loglines.append('ERROR: itest has not created %s' % tag) returncode = 1 for logline in loglines: _log( service=service, line=logline, component='build', level='event', ) return returncode
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" cluster, instance = args.clusterinstance.split('.') service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service) returncode = mark_for_deployment( git_url=args.git_url, cluster=cluster, instance=instance, service=service, commit=args.commit ) sys.exit(returncode)
def perform_performance_check(args): service = args.service if service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, args.soa_dir) try: submit_performance_check_job( service=service, soa_dir=args.soa_dir, ) except Exception as e: print "Something went wrong with the performance check. Safely bailing. No need to panic." print "Here was the error:" print str(e)
def paasta_wait_for_deployment(args): """Wrapping wait_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) try: validate_service_name(service, soa_dir=args.soa_dir) validate_deploy_group(args.deploy_group, service, args.soa_dir) validate_git_sha(args.commit, args.git_url, args.deploy_group, service) except (GitShaError, DeployGroupError, NoSuchService) as e: paasta_print(PaastaColors.red('{}'.format(e))) return 1 try: wait_for_deployment( service=service, deploy_group=args.deploy_group, git_sha=args.commit, soa_dir=args.soa_dir, timeout=args.timeout) _log( service=service, component='deploy', line=("Deployment of {0} for {1} complete".format( args.commit, args.deploy_group)), level='event') except (KeyboardInterrupt, TimeoutError): paasta_print("Waiting for deployment aborted.") return 1 except NoInstancesFound: return 1 return 0
def paasta_get_latest_deployment(args): service = args.service deploy_group = args.deploy_group soa_dir = args.soa_dir validate_service_name(service, soa_dir) git_url = get_git_url( service=service, soa_dir=soa_dir, ) remote_refs = list_remote_refs(git_url) _, git_sha = get_latest_deployment_tag(remote_refs, deploy_group) if not git_sha: print PaastaColors.red("A deployment could not be found for %s in %s" % (deploy_group, service)) return 1 else: print git_sha return 0
def paasta_itest(args): """Build and test a docker image""" service = args.service soa_dir = args.soa_dir if service and service.startswith("services-"): service = service.split("services-", 1)[1] validate_service_name(service, soa_dir=soa_dir) tag = build_docker_tag(service, args.commit) run_env = os.environ.copy() run_env["DOCKER_TAG"] = tag cmd = "make itest" loglines = [] _log( service=service, line="starting itest for %s." % args.commit, component="build", level="event", ) returncode, output = _run( cmd, env=run_env, timeout=args.timeout, log=True, component="build", service=service, loglevel="debug", ) if returncode != 0: loglines.append("ERROR: itest failed for %s." % args.commit) output = get_jenkins_build_output_url() if output: loglines.append("See output: %s" % output) else: loglines.append("itest passed for %s." % args.commit) if not check_docker_image(service, args.commit): loglines.append("ERROR: itest has not created %s" % tag) returncode = 1 for logline in loglines: _log(service=service, line=logline, component="build", level="event") return returncode
def paasta_cook_image(args, service=None, soa_dir=None): """Build a docker image""" if service: service = service else: service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, soa_dir) run_env = os.environ.copy() default_tag = 'paasta-cook-image-%s-%s' % (service, get_username()) tag = run_env.get('DOCKER_TAG', default_tag) run_env['DOCKER_TAG'] = tag if not makefile_responds_to('cook-image'): sys.stderr.write('ERROR: local-run now requires a cook-image target to be present in the Makefile. See ' 'http://paasta.readthedocs.io/en/latest/about/contract.html\n') return 1 try: cmd = 'make cook-image' returncode, output = _run( cmd, env=run_env, log=True, component='build', service=service, loglevel='debug' ) if returncode != 0: _log( service=service, line='ERROR: make cook-image failed for %s.' % service, component='build', level='event', ) return returncode except KeyboardInterrupt: sys.stderr.write('\nProcess interrupted by the user. Cancelling.\n') return 2
def paasta_wait_for_deployment(args): """Wrapping wait_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) try: validate_service_name(service, soa_dir=args.soa_dir) validate_deploy_group(args.deploy_group, service, args.soa_dir) validate_git_sha(args.commit, args.git_url, args.deploy_group, service) except (GitShaError, DeployGroupError, NoSuchService) as e: paasta_print(PaastaColors.red('{}'.format(e))) return 1 try: wait_for_deployment(service=service, deploy_group=args.deploy_group, git_sha=args.commit, soa_dir=args.soa_dir, timeout=args.timeout) _log(service=service, component='deploy', line=("Deployment of {0} for {1} complete". format(args.commit, args.deploy_group)), level='event') except (KeyboardInterrupt, TimeoutError): paasta_print("Waiting for deployment aborted.") return 1 except NoInstancesFound: return 1 return 0
def paasta_push_to_registry(args): """Upload a docker image to a registry""" service = args.service if service and service.startswith("services-"): service = service.split("services-", 1)[1] validate_service_name(service) cmd = build_command(service, args.commit) loglines = [] returncode, output = _run(cmd, timeout=3600, log=True, component="build", service=service, loglevel="debug") if returncode != 0: loglines.append("ERROR: Failed to promote image for %s." % args.commit) output = get_jenkins_build_output_url() if output: loglines.append("See output: %s" % output) else: loglines.append("Successfully pushed image for %s to registry" % args.commit) for logline in loglines: _log(service=service, line=logline, component="build", level="event") sys.exit(returncode)
def paasta_get_latest_deployment(args): service = args.service deploy_group = args.deploy_group soa_dir = args.soa_dir validate_service_name(service, soa_dir) git_sha = get_currently_deployed_sha(service=service, deploy_group=deploy_group, soa_dir=soa_dir) if not git_sha: paasta_print( PaastaColors.red( f"A deployment could not be found for {deploy_group} in {service}" ), file=sys.stderr, ) return 1 else: paasta_print(git_sha) return 0
def paasta_cook_image(args, service=None, soa_dir=None): """Build a docker image""" if service: service = service else: service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, soa_dir) run_env = os.environ.copy() default_tag = 'paasta-cook-image-%s-%s' % (service, get_username()) tag = run_env.get('DOCKER_TAG', default_tag) run_env['DOCKER_TAG'] = tag if not makefile_responds_to('cook-image'): sys.stderr.write( 'ERROR: local-run now requires a cook-image target to be present in the Makefile. See ' 'http://paasta.readthedocs.io/en/latest/about/contract.html\n') return 1 try: cmd = 'make cook-image' returncode, output = _run(cmd, env=run_env, log=True, component='build', service=service, loglevel='debug') if returncode != 0: _log( service=service, line='ERROR: make cook-image failed for %s.' % service, component='build', level='event', ) return returncode except KeyboardInterrupt: sys.stderr.write('\nProcess interrupted by the user. Cancelling.\n') return 2
def paasta_get_docker_image(args): service = args.service deploy_group = args.deploy_group soa_dir = args.soa_dir validate_service_name(service, soa_dir) deployments = load_v2_deployments_json(service=service, soa_dir=soa_dir) docker_image = deployments.get_docker_image_for_deploy_group(deploy_group) if not docker_image: print( PaastaColors.red( f"There is no {service} docker_image for {deploy_group}. Has it been deployed yet?" ), file=sys.stderr, ) return 1 else: registry_uri = get_service_docker_registry(service=service, soa_dir=soa_dir) docker_url = f"{registry_uri}/{docker_image}" print(docker_url) return 0
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith("services-"): service = service.split("services-", 1)[1] validate_service_name(service, soa_dir=args.soa_dir) deploy_group = args.deploy_group in_use_deploy_groups = list_deploy_groups(service=service, soa_dir=args.soa_dir) _, invalid_deploy_groups = validate_given_deploy_groups( in_use_deploy_groups, [deploy_group] ) if len(invalid_deploy_groups) == 1: paasta_print( PaastaColors.red( "ERROR: These deploy groups are not currently used anywhere: %s.\n" % (",").join(invalid_deploy_groups) ) ) paasta_print( PaastaColors.red( "This isn't technically wrong because you can mark-for-deployment before deploying there" ) ) paasta_print( PaastaColors.red( "but this is probably a typo. Did you mean one of these in-use deploy groups?:" ) ) paasta_print(PaastaColors.red(" %s" % (",").join(in_use_deploy_groups))) paasta_print() paasta_print(PaastaColors.red("Continuing regardless...")) if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) commit = validate_git_sha(sha=args.commit, git_url=args.git_url) old_git_sha = get_currently_deployed_sha(service=service, deploy_group=deploy_group) if old_git_sha == commit: paasta_print( "Warning: The sha asked to be deployed already matches what is set to be deployed:" ) paasta_print(old_git_sha) paasta_print("Continuing anyway.") if args.verify_image: if not is_docker_image_already_in_registry(service, args.soa_dir, commit): raise ValueError( "Failed to find image in the registry for the following sha %s" % commit ) deploy_info = get_deploy_info(service=service, soa_dir=args.soa_dir) deploy_process = MarkForDeploymentProcess( service=service, deploy_info=deploy_info, deploy_group=deploy_group, commit=commit, old_git_sha=old_git_sha, git_url=args.git_url, auto_rollback=args.auto_rollback, block=args.block, soa_dir=args.soa_dir, timeout=args.timeout, auto_certify_delay=args.auto_certify_delay, auto_abandon_delay=args.auto_abandon_delay, auto_rollback_delay=args.auto_rollback_delay, ) ret = deploy_process.run() return ret
def paasta_cook_image( args: Optional[argparse.Namespace], service: Optional[str] = None, soa_dir: Optional[str] = None, ) -> int: """Build a docker image""" if not service: if args is None: print( "ERROR: No arguments or service passed to cook-image - unable to determine what service to cook an image for", file=sys.stderr, ) return 1 service = args.service if service and service.startswith("services-"): service = service.split("services-", 1)[1] if not soa_dir: if args is None: print( "ERROR: No arguments or soadir passed to cook-image - unable to determine where to look for soa-configs", file=sys.stderr, ) return 1 soa_dir = args.yelpsoa_config_root validate_service_name(service, soa_dir) run_env = os.environ.copy() if args is not None and args.commit is not None: # if we're given a commit, we're likely being called by Jenkins or someone # trying to push the cooked image to our registry - as such, we should tag # the cooked image as `paasta itest` would. tag = build_docker_tag(service, args.commit, args.image_version) else: default_tag = "paasta-cook-image-{}-{}".format(service, get_username()) tag = run_env.get("DOCKER_TAG", default_tag) run_env["DOCKER_TAG"] = tag if not makefile_responds_to("cook-image"): print( "ERROR: local-run now requires a cook-image target to be present in the Makefile. See " "http://paasta.readthedocs.io/en/latest/about/contract.html.", file=sys.stderr, ) return 1 try: cmd = "make cook-image" returncode, output = _run( cmd, env=run_env, log=True, component="build", service=service, loglevel="debug", ) if returncode != 0: _log( service=service, line="ERROR: make cook-image failed for %s." % service, component="build", level="event", ) else: action_details = {"tag": tag} _log_audit( action="cook-image", action_details=action_details, service=service ) return returncode except KeyboardInterrupt: print("\nProcess interrupted by the user. Cancelling.", file=sys.stderr) return 2
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, soa_dir=args.soa_dir) in_use_deploy_groups = list_deploy_groups( service=service, soa_dir=args.soa_dir, ) _, invalid_deploy_groups = validate_given_deploy_groups( in_use_deploy_groups, [args.deploy_group]) if len(invalid_deploy_groups) == 1: print PaastaColors.red( "ERROR: These deploy groups are not currently used anywhere: %s.\n" % (",").join(invalid_deploy_groups)) print PaastaColors.red( "This isn't technically wrong because you can mark-for-deployment before deploying there" ) print PaastaColors.red( "but this is probably a typo. Did you mean one of these in-use deploy groups?:" ) print PaastaColors.red(" %s" % (",").join(in_use_deploy_groups)) print "" print PaastaColors.red("Continuing regardless...") if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) old_git_sha = get_currently_deployed_sha(service=service, deploy_group=args.deploy_group) if old_git_sha == args.commit: print "Warning: The sha asked to be deployed already matches what is set to be deployed:" print old_git_sha print "Continuing anyway." ret = mark_for_deployment( git_url=args.git_url, deploy_group=args.deploy_group, service=service, commit=args.commit, ) if args.block: try: print "Waiting for deployment of {0} for '{1}' complete...".format( args.commit, args.deploy_group) wait_for_deployment(service=service, deploy_group=args.deploy_group, git_sha=args.commit, soa_dir=args.soa_dir, timeout=args.timeout) line = "Deployment of {0} for {1} complete".format( args.commit, args.deploy_group) _log(service=service, component='deploy', line=line, level='event') except (KeyboardInterrupt, TimeoutError): print "Waiting for deployment aborted. PaaSTA will continue to try to deploy this code." print "If you wish to see the status, run:" print "" print " paasta status -s %s -v" % service print "" ret = 1 if old_git_sha is not None and old_git_sha != args.commit: print "" print "If you wish to roll back, you can run:" print "" print PaastaColors.bold( " paasta rollback --service %s --deploy-group %s --commit %s " % (service, args.deploy_group, old_git_sha)) return ret
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, soa_dir=args.soa_dir) in_use_deploy_groups = { config.get_deploy_group() for config in get_instance_config_for_service( service=service, soa_dir=args.soa_dir, ) } _, invalid_deploy_groups = validate_given_deploy_groups( in_use_deploy_groups, [args.deploy_group]) if len(invalid_deploy_groups) == 1: print PaastaColors.red( "ERROR: These deploy groups are not currently used anywhere: %s.\n" % (",").join(invalid_deploy_groups)) print PaastaColors.red( "This isn't technically wrong because you can mark-for-deployment before deploying there" ) print PaastaColors.red( "but this is probably a typo. Did you mean one of these in-use deploy groups?:" ) print PaastaColors.red(" %s" % (",").join(in_use_deploy_groups)) print "" print PaastaColors.red("Continuing regardless...") ret = mark_for_deployment( git_url=args.git_url, deploy_group=args.deploy_group, service=service, commit=args.commit, ) if args.block: try: line = "Waiting for deployment of {0} to {1} complete".format( args.commit, args.deploy_group) log.info(line) wait_for_deployment(service=service, deploy_group=args.deploy_group, git_sha=args.commit, soa_dir=args.soa_dir, timeout=args.timeout) line = "Deployment of {0} to {1} complete".format( args.commit, args.deploy_group) _log(service=service, component='deploy', line=line, level='event') except KeyboardInterrupt: print "Waiting for deployment aborted. PaaSTA will continue to try to deploy this code." print "If you wish to see the status, run:" print "" print " paasta status -s %s -v" % service print "" print "Or if you wish to rollback:" print "" print " paasta rollback -s %s -d %s" % (service, args.deploy_group) sys.exit(1) except TimeoutError: sys.exit(1) return ret
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, soa_dir=args.soa_dir) in_use_deploy_groups = list_deploy_groups( service=service, soa_dir=args.soa_dir, ) _, invalid_deploy_groups = validate_given_deploy_groups( in_use_deploy_groups, [args.deploy_group]) if len(invalid_deploy_groups) == 1: paasta_print( PaastaColors.red( "ERROR: These deploy groups are not currently used anywhere: %s.\n" % (",").join(invalid_deploy_groups))) paasta_print( PaastaColors.red( "This isn't technically wrong because you can mark-for-deployment before deploying there" )) paasta_print( PaastaColors.red( "but this is probably a typo. Did you mean one of these in-use deploy groups?:" )) paasta_print( PaastaColors.red(" %s" % (",").join(in_use_deploy_groups))) paasta_print() paasta_print(PaastaColors.red("Continuing regardless...")) if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) old_git_sha = get_currently_deployed_sha(service=service, deploy_group=args.deploy_group) if old_git_sha == args.commit: paasta_print( "Warning: The sha asked to be deployed already matches what is set to be deployed:" ) paasta_print(old_git_sha) paasta_print("Continuing anyway.") ret = mark_for_deployment( git_url=args.git_url, deploy_group=args.deploy_group, service=service, commit=args.commit, ) if args.block: try: wait_for_deployment(service=service, deploy_group=args.deploy_group, git_sha=args.commit, soa_dir=args.soa_dir, timeout=args.timeout) line = "Deployment of {} for {} complete".format( args.commit, args.deploy_group) _log(service=service, component='deploy', line=line, level='event') except (KeyboardInterrupt, TimeoutError): if args.auto_rollback is True: if old_git_sha == args.commit: paasta_print( "Error: --auto-rollback was requested, but the previous sha" ) paasta_print( "is the same that was requested with --commit. Can't rollback" ) paasta_print("automatically.") else: paasta_print( "Auto-Rollback requested. Marking the previous sha") paasta_print("(%s) for %s as desired." % (args.deploy_group, old_git_sha)) mark_for_deployment( git_url=args.git_url, deploy_group=args.deploy_group, service=service, commit=old_git_sha, ) else: paasta_print( "Waiting for deployment aborted. PaaSTA will continue to try to deploy this code." ) paasta_print("If you wish to see the status, run:") paasta_print() paasta_print(" paasta status -s %s -v" % service) paasta_print() ret = 1 except NoInstancesFound: return 1 if old_git_sha is not None and old_git_sha != args.commit and not args.auto_rollback: paasta_print() paasta_print("If you wish to roll back, you can run:") paasta_print() paasta_print( PaastaColors.bold( " paasta rollback --service %s --deploy-group %s --commit %s " % (service, args.deploy_group, old_git_sha))) return ret
def apply_args_filters( args, ) -> Mapping[str, Mapping[str, Mapping[str, Type[InstanceConfig]]]]: """ Take an args object and returns the dict of cluster:service:instances Currently, will filter by clusters, instances, services, and deploy_groups If no instances are found, will print a message and try to find matching instances for each service :param args: args object containing attributes to filter by :returns: Dict of dicts, in format {cluster_name: {service_name: {instance1, instance2}}} """ clusters_services_instances: DefaultDict[ str, DefaultDict[str, Dict[str, Type[InstanceConfig]]] ] = defaultdict(lambda: defaultdict(dict)) if args.service: try: validate_service_name(args.service, soa_dir=args.soa_dir) except NoSuchService: paasta_print( PaastaColors.red(f'The service "{args.service}" does not exist.') ) all_services = list_services(soa_dir=args.soa_dir) suggestions = difflib.get_close_matches( args.service, all_services, n=5, cutoff=0.5 ) if suggestions: paasta_print(PaastaColors.red(f"Did you mean any of these?")) for suggestion in suggestions: paasta_print(PaastaColors.red(f" {suggestion}")) return clusters_services_instances all_services = [args.service] else: all_services = list_services(soa_dir=args.soa_dir) if args.service is None and args.owner is None: args.service = figure_out_service_name(args, soa_dir=args.soa_dir) if args.clusters: clusters = args.clusters.split(",") else: clusters = list_clusters() if args.instances: instances = args.instances.split(",") else: instances = None filters = get_filters(args) i_count = 0 for service in all_services: if args.service and service != args.service: continue for instance_conf in get_instance_configs_for_service( service, soa_dir=args.soa_dir, clusters=clusters, instances=instances ): if all([f(instance_conf) for f in filters]): cluster_service = clusters_services_instances[ instance_conf.get_cluster() ][service] cluster_service[instance_conf.get_instance()] = instance_conf.__class__ i_count += 1 if i_count == 0 and args.service and args.instances: for service in args.service.split(","): verify_instances(args.instances, service, clusters) return clusters_services_instances
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, soa_dir=args.soa_dir) in_use_deploy_groups = list_deploy_groups( service=service, soa_dir=args.soa_dir, ) _, invalid_deploy_groups = validate_given_deploy_groups( in_use_deploy_groups, [args.deploy_group]) if len(invalid_deploy_groups) == 1: paasta_print( PaastaColors.red( "ERROR: These deploy groups are not currently used anywhere: %s.\n" % (",").join(invalid_deploy_groups), )) paasta_print( PaastaColors.red( "This isn't technically wrong because you can mark-for-deployment before deploying there", )) paasta_print( PaastaColors.red( "but this is probably a typo. Did you mean one of these in-use deploy groups?:" )) paasta_print( PaastaColors.red(" %s" % (",").join(in_use_deploy_groups))) paasta_print() paasta_print(PaastaColors.red("Continuing regardless...")) if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) try: validate_full_git_sha(args.commit) except ArgumentTypeError: refs = remote_git.list_remote_refs(args.git_url) commits = short_to_full_git_sha(short=args.commit, refs=refs) if len(commits) != 1: raise ValueError( "%s matched %d git shas (with refs pointing at them). Must match exactly 1." % (args.commit, len(commits)), ) args.commit = commits[0] old_git_sha = get_currently_deployed_sha(service=service, deploy_group=args.deploy_group) if old_git_sha == args.commit: paasta_print( "Warning: The sha asked to be deployed already matches what is set to be deployed:" ) paasta_print(old_git_sha) paasta_print("Continuing anyway.") if args.verify_image: if not is_docker_image_already_in_registry(service, args.soa_dir, args.commit): raise ValueError( 'Failed to find image in the registry for the following sha %s' % args.commit) ret = mark_for_deployment( git_url=args.git_url, deploy_group=args.deploy_group, service=service, commit=args.commit, ) if args.block and ret == 0: try: wait_for_deployment( service=service, deploy_group=args.deploy_group, git_sha=args.commit, soa_dir=args.soa_dir, timeout=args.timeout, ) line = "Deployment of {} for {} complete".format( args.commit, args.deploy_group) _log( service=service, component='deploy', line=line, level='event', ) except (KeyboardInterrupt, TimeoutError): if args.auto_rollback is True: if old_git_sha == args.commit: paasta_print( "Error: --auto-rollback was requested, but the previous sha" ) paasta_print( "is the same that was requested with --commit. Can't rollback" ) paasta_print("automatically.") else: paasta_print( "Auto-Rollback requested. Marking the previous sha") paasta_print("(%s) for %s as desired." % (args.deploy_group, old_git_sha)) mark_for_deployment( git_url=args.git_url, deploy_group=args.deploy_group, service=service, commit=old_git_sha, ) else: report_waiting_aborted(service, args.deploy_group) ret = 1 except NoSuchCluster: report_waiting_aborted(service, args.deploy_group) if old_git_sha is not None and old_git_sha != args.commit and not args.auto_rollback: paasta_print() paasta_print("If you wish to roll back, you can run:") paasta_print() paasta_print( PaastaColors.bold( " paasta rollback --service %s --deploy-group %s --commit %s " % ( service, args.deploy_group, old_git_sha, )), ) return ret
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, soa_dir=args.soa_dir) deploy_group = args.deploy_group in_use_deploy_groups = list_deploy_groups( service=service, soa_dir=args.soa_dir, ) _, invalid_deploy_groups = validate_given_deploy_groups( in_use_deploy_groups, [deploy_group]) if len(invalid_deploy_groups) == 1: paasta_print( PaastaColors.red( "ERROR: These deploy groups are not currently used anywhere: %s.\n" % (",").join(invalid_deploy_groups), )) paasta_print( PaastaColors.red( "This isn't technically wrong because you can mark-for-deployment before deploying there", )) paasta_print( PaastaColors.red( "but this is probably a typo. Did you mean one of these in-use deploy groups?:" )) paasta_print( PaastaColors.red(" %s" % (",").join(in_use_deploy_groups))) paasta_print() paasta_print(PaastaColors.red("Continuing regardless...")) if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) commit = validate_git_sha(sha=args.commit, git_url=args.git_url) old_git_sha = get_currently_deployed_sha(service=service, deploy_group=deploy_group) if old_git_sha == commit: paasta_print( "Warning: The sha asked to be deployed already matches what is set to be deployed:" ) paasta_print(old_git_sha) paasta_print("Continuing anyway.") if args.verify_image: if not is_docker_image_already_in_registry(service, args.soa_dir, commit): raise ValueError( 'Failed to find image in the registry for the following sha %s' % commit) deploy_info = get_deploy_info(service=service, soa_dir=args.soa_dir) slack_notifier = SlackDeployNotifier( deploy_info=deploy_info, service=service, deploy_group=deploy_group, commit=commit, old_commit=old_git_sha, git_url=args.git_url, ) ret = mark_for_deployment( git_url=args.git_url, deploy_group=deploy_group, service=service, commit=commit, ) slack_notifier.notify_after_mark(ret=ret) if args.block and ret == 0: try: wait_for_deployment( service=service, deploy_group=deploy_group, git_sha=commit, soa_dir=args.soa_dir, timeout=args.timeout, ) line = f"Deployment of {commit} for {deploy_group} complete" _log( service=service, component='deploy', line=line, level='event', ) slack_notifier.notify_after_good_deploy() except (KeyboardInterrupt, TimeoutError): if args.auto_rollback is True: if old_git_sha == commit: paasta_print( "Error: --auto-rollback was requested, but the previous sha" ) paasta_print( "is the same that was requested with --commit. Can't rollback" ) paasta_print("automatically.") else: paasta_print( "Auto-Rollback requested. Marking the previous sha") paasta_print( f"({deploy_group}) for {old_git_sha} as desired.") mark_for_deployment( git_url=args.git_url, deploy_group=deploy_group, service=service, commit=old_git_sha, ) slack_notifier.notify_after_auto_rollback() else: report_waiting_aborted(service, deploy_group) slack_notifier.notify_after_abort() ret = 1 except NoSuchCluster: report_waiting_aborted(service, deploy_group) slack_notifier.notify_after_abort() if old_git_sha is not None and old_git_sha != commit and not args.auto_rollback: paasta_print() paasta_print("If you wish to roll back, you can run:") paasta_print() paasta_print( PaastaColors.bold( " paasta rollback --service {} --deploy-group {} --commit {} " .format( service, deploy_group, old_git_sha, )), ) return ret
def paasta_mark_for_deployment(args): """Wrapping mark_for_deployment""" if args.verbose: log.setLevel(level=logging.DEBUG) else: log.setLevel(level=logging.INFO) service = args.service if service and service.startswith('services-'): service = service.split('services-', 1)[1] validate_service_name(service, soa_dir=args.soa_dir) in_use_deploy_groups = list_deploy_groups( service=service, soa_dir=args.soa_dir, ) _, invalid_deploy_groups = validate_given_deploy_groups(in_use_deploy_groups, [args.deploy_group]) if len(invalid_deploy_groups) == 1: paasta_print(PaastaColors.red( "ERROR: These deploy groups are not currently used anywhere: %s.\n" % (",").join(invalid_deploy_groups))) paasta_print(PaastaColors.red( "This isn't technically wrong because you can mark-for-deployment before deploying there")) paasta_print(PaastaColors.red("but this is probably a typo. Did you mean one of these in-use deploy groups?:")) paasta_print(PaastaColors.red(" %s" % (",").join(in_use_deploy_groups))) paasta_print() paasta_print(PaastaColors.red("Continuing regardless...")) if args.git_url is None: args.git_url = get_git_url(service=service, soa_dir=args.soa_dir) old_git_sha = get_currently_deployed_sha(service=service, deploy_group=args.deploy_group) if old_git_sha == args.commit: paasta_print("Warning: The sha asked to be deployed already matches what is set to be deployed:") paasta_print(old_git_sha) paasta_print("Continuing anyway.") ret = mark_for_deployment( git_url=args.git_url, deploy_group=args.deploy_group, service=service, commit=args.commit, ) if args.block: try: wait_for_deployment(service=service, deploy_group=args.deploy_group, git_sha=args.commit, soa_dir=args.soa_dir, timeout=args.timeout) line = "Deployment of {0} for {1} complete".format(args.commit, args.deploy_group) _log( service=service, component='deploy', line=line, level='event' ) except (KeyboardInterrupt, TimeoutError): if args.auto_rollback is True: if old_git_sha == args.commit: paasta_print("Error: --auto-rollback was requested, but the previous sha") paasta_print("is the same that was requested with --commit. Can't rollback") paasta_print("automatically.") else: paasta_print("Auto-Rollback requested. Marking the previous sha") paasta_print("(%s) for %s as desired." % (args.deploy_group, old_git_sha)) mark_for_deployment( git_url=args.git_url, deploy_group=args.deploy_group, service=service, commit=old_git_sha, ) else: paasta_print("Waiting for deployment aborted. PaaSTA will continue to try to deploy this code.") paasta_print("If you wish to see the status, run:") paasta_print() paasta_print(" paasta status -s %s -v" % service) paasta_print() ret = 1 except NoInstancesFound: return 1 if old_git_sha is not None and old_git_sha != args.commit and not args.auto_rollback: paasta_print() paasta_print("If you wish to roll back, you can run:") paasta_print() paasta_print(PaastaColors.bold(" paasta rollback --service %s --deploy-group %s --commit %s " % ( service, args.deploy_group, old_git_sha)) ) return ret