def lookup_production_deploy_group_sha(self):
     prod_deploy_group = self.deploy_info.get('production_deploy_group',
                                              None)
     if prod_deploy_group is None:
         return None
     else:
         return get_currently_deployed_sha(service=self.service,
                                           deploy_group=prod_deploy_group)
def test_get_currently_deployed_sha(mock_load_v2_deployments_json,):
    mock_load_v2_deployments_json.return_value = DeploymentsJsonV2(
        service="fake-service",
        config_dict={
            "controls": {},
            "deployments": {"everything": {"git_sha": "abc", "docker_image": "foo"}},
        },
    )
    actual = deployment_utils.get_currently_deployed_sha(
        service="service", deploy_group="everything"
    )
    assert actual == "abc"
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 test_get_currently_deployed_sha(mock_load_v2_deployments_json, ):
    mock_load_v2_deployments_json.return_value = DeploymentsJson({
        "controls": {},
        "deployments": {
            "everything": {
                "git_sha": "abc",
                "docker_image": "foo",
            }
        }
    })
    actual = deployment_utils.get_currently_deployed_sha(
        service='service', deploy_group='everything')
    assert actual == "abc"
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 test_get_currently_deployed_sha(
    mock_load_v2_deployments_json,
):
    mock_load_v2_deployments_json.return_value = DeploymentsJson({
        "controls": {},
        "deployments": {
            "everything": {
                "git_sha": "abc",
                "docker_image": "foo",
            }
        }
    })
    actual = deployment_utils.get_currently_deployed_sha(service='service', deploy_group='everything')
    assert actual == "abc"
Exemple #7
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_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
Exemple #8
0
 def get_authors(self) -> str:
     # In order to avoid notifying people who aren't part of the current
     # service push, we calculate authors based on commits different since
     # the current production SHA, as opposed to the old SHA on this deploy
     # group.
     #
     # This avoids situations such as:
     #   * Notifying people from a previous push which went through stagef,
     #     if the new push goes through stageg.
     #   * Notifying everybody who has committed to a repo in the past year
     #     when updating a "legacy" deploy group (e.g. for yelp-main).
     prod_deploy_group = self.deploy_info.get("production_deploy_group")
     from_sha = None
     if prod_deploy_group is not None:
         from_sha = get_currently_deployed_sha(
             service=self.service, deploy_group=prod_deploy_group
         )
     # If there's no production deploy group, or the production deploy group
     # has never been deployed to, just use the old SHA from this deploy group.
     if from_sha is None:
         from_sha = self.old_git_sha
     return get_authors_to_be_notified(
         git_url=self.git_url, from_sha=from_sha, to_sha=self.commit
     )
Exemple #9
0
def paasta_rollback(args):
    """Call mark_for_deployment with rollback parameters
    :param args: contains all the arguments passed onto the script: service,
    deploy groups and sha. These arguments will be verified and passed onto
    mark_for_deployment.
    """
    soa_dir = args.soa_dir
    service = figure_out_service_name(args, soa_dir)

    deploy_info = get_deploy_info(service=service, soa_dir=args.soa_dir)
    deploy_authz_check(deploy_info, service)

    git_url = get_git_url(service, soa_dir)
    given_deploy_groups = {
        deploy_group for deploy_group in args.deploy_groups.split(",") if deploy_group
    }

    all_deploy_groups = list_deploy_groups(service=service, soa_dir=soa_dir)
    deploy_groups, invalid = validate_given_deploy_groups(
        all_deploy_groups, given_deploy_groups
    )

    if len(invalid) > 0:
        print(
            PaastaColors.yellow(
                "These deploy groups are not valid and will be skipped: %s.\n"
                % (",").join(invalid)
            )
        )

    if len(deploy_groups) == 0:
        print(
            PaastaColors.red(
                "ERROR: No valid deploy groups specified for %s.\n" % (service)
            )
        )
        return 1

    git_shas = get_git_shas_for_service(service, deploy_groups, soa_dir)
    commit = args.commit
    if not commit:
        print("Please specify a commit to mark for rollback (-k, --commit).")
        list_previous_commits(
            service, deploy_groups, bool(given_deploy_groups), git_shas
        )
        return 1
    elif commit not in git_shas and not args.force:
        print(PaastaColors.red("This Git SHA has never been deployed before."))
        print("Please double check it or use --force to skip this verification.\n")
        list_previous_commits(
            service, deploy_groups, bool(given_deploy_groups), git_shas
        )
        return 1

    returncode = 0

    for deploy_group in deploy_groups:
        rolled_back_from = get_currently_deployed_sha(service, deploy_group)
        returncode |= mark_for_deployment(
            git_url=git_url, service=service, deploy_group=deploy_group, commit=commit
        )

        # we could also gate this by the return code from m-f-d, but we probably care more about someone wanting to
        # rollback than we care about if the underlying machinery was successfully able to complete the request
        if rolled_back_from != commit:
            audit_action_details = {
                "rolled_back_from": rolled_back_from,
                "rolled_back_to": commit,
                "rollback_type": RollbackTypes.USER_INITIATED_ROLLBACK.value,
                "deploy_group": deploy_group,
            }
            _log_audit(
                action="rollback", action_details=audit_action_details, service=service
            )

    return returncode
Exemple #10
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)

    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
Exemple #11
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)

    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 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
Exemple #13
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)

    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
Exemple #14
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_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