Пример #1
0
def main():
    argparser = argparse.ArgumentParser()
    subparsers = argparser.add_subparsers(dest='command')
    build_parser = subparsers.add_parser('build',
                                         help='Build an image from given path')

    build_parser.add_argument('deployment',
                              help='Path to directory with dockerfile')

    trigger_change_group = build_parser.add_mutually_exclusive_group()
    trigger_change_group.add_argument(
        '--commit-range',
        help=
        'Trigger image rebuilds only if files in image directory have changed in this git commit range'
    )
    # FIXME: Needs a better name?
    trigger_change_group.add_argument(
        '--check-registry',
        action='store_true',
        help=
        "Trigger image rebuild if image with expected name and tag is not in upstream registry."
    )
    build_parser.add_argument(
        '--push',
        action='store_true',
    )

    deploy_parser = subparsers.add_parser(
        'deploy', help='Deploy a chart to the given environment')

    deploy_parser.add_argument('deployment')
    deploy_parser.add_argument('chart')
    deploy_parser.add_argument('environment',
                               choices=['develop', 'staging', 'prod'])
    deploy_parser.add_argument('--namespace', default=None)
    deploy_parser.add_argument(
        '--set',
        action='append',
    )
    deploy_parser.add_argument('--version', )

    args = argparser.parse_args()

    if args.command == 'build':
        if args.push or args.check_registry:
            auth.registry_auth(args.deployment)
        client = docker.from_env()
        imagebuilder.build_deployment(client, args.deployment,
                                      args.commit_range, args.check_registry,
                                      args.push)
    elif args.command == 'deploy':
        auth.cluster_auth(args.deployment)
        helm.deploy(args.deployment, args.chart, args.environment,
                    args.namespace, args.set, args.version)
Пример #2
0
def main():
    argparser = argparse.ArgumentParser()
    subparsers = argparser.add_subparsers(dest='command')
    build_parser = subparsers.add_parser('build',
                                         help='Build an image from given path')

    build_parser.add_argument('deployment',
                              help='Path to directory with dockerfile')
    build_parser.add_argument(
        '--commit-range',
        help=
        'Trigger image rebuilds only if path has changed in this commit range')
    build_parser.add_argument(
        '--push',
        action='store_true',
    )

    deploy_parser = subparsers.add_parser(
        'deploy', help='Deploy a chart to the given environment')

    deploy_parser.add_argument('deployment')
    deploy_parser.add_argument('chart')
    deploy_parser.add_argument('environment',
                               choices=['develop', 'staging', 'prod'])
    deploy_parser.add_argument('--namespace', default=None)
    deploy_parser.add_argument(
        '--set',
        action='append',
    )
    deploy_parser.add_argument('--version', )

    args = argparser.parse_args()

    if args.command == 'build':
        client = docker.from_env()
        if args.push:
            auth.registry_auth(args.deployment)
        imagebuilder.build_deployment(client, args.deployment,
                                      args.commit_range, args.push)
    elif args.command == 'deploy':
        auth.cluster_auth(args.deployment)
        helm.deploy(args.deployment, args.chart, args.environment,
                    args.namespace, args.set, args.version)
Пример #3
0
def deploy(deployment,
           chart,
           environment,
           namespace=None,
           helm_config_overrides_implicit=None,
           helm_config_overrides_string=None,
           version=None,
           timeout=None,
           force=False,
           atomic=False,
           cleanup_on_fail=False):
    """
    Deploy a JupyterHub.

    Expects the following files to exist in current directory

    {chart}/ (Helm deployment chart)
    deployments/
    - {deployment}
        - image/ (optional)
        - secrets/
            - {environment}.yaml
        - config/
          - common.yaml
          - {environment}.yaml

    A docker image from deployments/{deployment}/image is expected to be
    already built and available with imagebuilder.
    `jupyterhub.singleuser.image.tag` will be automatically set to this image
    tag.
    """
    if helm_config_overrides_implicit is None:
        helm_config_overrides_implicit = []
    if helm_config_overrides_string is None:
        helm_config_overrides_string = []

    config = get_config(deployment)

    name = f'{deployment}-{environment}'

    if namespace is None:
        namespace = name
    helm_config_files = [
        f for f in [
            os.path.join('deployments', deployment, 'config', 'common.yaml'),
            os.path.join('deployments', deployment, 'config',
                         f'{environment}.yaml'),
        ] if os.path.exists(f)
    ]

    helm_secret_files = [
        f for f in [
            # Support for secrets in same repo
            os.path.join('deployments', deployment, 'secrets',
                         f'{environment}.yaml'),
            # Support for secrets in a submodule repo
            os.path.join('secrets', 'deployments', deployment, 'secrets',
                         f'{environment}.yaml'),
        ] if os.path.exists(f)
    ]

    if config.get('images'):
        for image in config['images']['images']:
            # We can support other charts that wrap z2jh by allowing various
            # config paths where we set image tags and names.
            # We default to one sublevel, but we can do multiple levels.
            # With the PANGEO chart, we this could be set to `pangeo.jupyterhub.singleuser.image`
            helm_config_overrides_string.append(
                f'{image.helm_substitution_path}.tag={image.tag}')
            helm_config_overrides_string.append(
                f'{image.helm_substitution_path}.name={image.name}')

    with ExitStack() as stack:
        decrypted_secret_files = [
            stack.enter_context(decrypt_file(f)) for f in helm_secret_files
        ]

        # Just in time for k8s access, activate the cluster credentials
        stack.enter_context(cluster_auth(deployment))
        helm_upgrade(
            name,
            namespace,
            chart,
            helm_config_files + decrypted_secret_files,
            helm_config_overrides_implicit,
            helm_config_overrides_string,
            version,
            timeout,
            force,
            atomic,
            cleanup_on_fail,
        )
Пример #4
0
def main():
    argparser = argparse.ArgumentParser()
    subparsers = argparser.add_subparsers(dest='command')
    build_parser = subparsers.add_parser(
        'build', help='Build an image for a given deployment')

    build_parser.add_argument('deployment',
                              help='Name of deployment to build image of')

    trigger_change_group = build_parser.add_mutually_exclusive_group()
    trigger_change_group.add_argument(
        '--commit-range',
        help=
        'Trigger image rebuilds only if files in image directory have changed in this git commit range',
        default=commitrange.get_commit_range())
    # FIXME: Needs a better name?
    trigger_change_group.add_argument(
        '--check-registry',
        action='store_true',
        help=
        "Trigger image rebuild if image with expected name and tag is not in upstream registry."
    )
    build_parser.add_argument('--push',
                              action='store_true',
                              help="Push image after building")
    build_parser.add_argument(
        '--no-cache',
        action='store_true',
        help="Don't pull previous image to re-use cache from")

    build_parser.add_argument(
        '--image',
        # FIXME: Have a friendlier way to reference this
        help='Fully qualified docker image names to build',
        action='append')

    deploy_parser = subparsers.add_parser(
        'deploy', help='Deploy a chart to the given environment')

    deploy_parser.add_argument('deployment')
    deploy_parser.add_argument('chart')
    deploy_parser.add_argument('environment',
                               choices=['develop', 'staging', 'prod'])
    deploy_parser.add_argument('--namespace', default=None)
    deploy_parser.add_argument(
        '--set',
        action='append',
    )
    deploy_parser.add_argument(
        '--set-string',
        action='append',
    )
    deploy_parser.add_argument('--version', )
    deploy_parser.add_argument('--timeout')
    deploy_parser.add_argument('--force', action='store_true')
    deploy_parser.add_argument('--atomic', action='store_true')
    deploy_parser.add_argument('--cleanup-on-fail', action='store_true')

    args = argparser.parse_args()

    try:
        config = hubploy.config.get_config(args.deployment)
    except hubploy.config.DeploymentNotFoundError as e:
        print(e, file=sys.stderr)
        sys.exit(1)

    if args.command == 'build':
        if not args.check_registry and not args.commit_range:
            # commit_range autodetection failed, and check registry isn't set
            # FIXME: Provide an actually useful error message
            print(
                "Could not auto-detect commit-range, and --check-registry is not set",
                file=sys.stderr)
            print("Specify --commit-range manually, or pass --check-registry",
                  file=sys.stderr)
            sys.exit(1)

        with auth.registry_auth(args.deployment, args.push,
                                args.check_registry):

            all_images = config.get('images', {}).get('images', {})

            if args.image:
                build_images = [i for i in all_images if i.name in args.image]
            else:
                build_images = all_images

            print(f"Building {len(build_images)} images")
            for image in build_images:
                if image.needs_building(check_registry=args.check_registry,
                                        commit_range=args.commit_range):
                    print(f"Building image {image.name}")
                    image.build(not args.no_cache)
                    if args.push:
                        image.push()

    elif args.command == 'deploy':
        with auth.cluster_auth(args.deployment):
            helm.deploy(
                args.deployment,
                args.chart,
                args.environment,
                args.namespace,
                args.set,
                args.set_string,
                args.version,
                args.timeout,
                args.force,
                args.atomic,
                args.cleanup_on_fail,
            )
Пример #5
0
def main():
    argparser = argparse.ArgumentParser()
    subparsers = argparser.add_subparsers(dest='command')
    build_parser = subparsers.add_parser('build',
                                         help='Build an image from given path')

    build_parser.add_argument('deployment',
                              help='Path to directory with dockerfile')

    trigger_change_group = build_parser.add_mutually_exclusive_group()
    trigger_change_group.add_argument(
        '--commit-range',
        help=
        'Trigger image rebuilds only if files in image directory have changed in this git commit range',
        default=commitrange.get_commit_range())
    # FIXME: Needs a better name?
    trigger_change_group.add_argument(
        '--check-registry',
        action='store_true',
        help=
        "Trigger image rebuild if image with expected name and tag is not in upstream registry."
    )
    build_parser.add_argument(
        '--push',
        action='store_true',
    )

    deploy_parser = subparsers.add_parser(
        'deploy', help='Deploy a chart to the given environment')

    deploy_parser.add_argument('deployment')
    deploy_parser.add_argument('chart')
    deploy_parser.add_argument('environment',
                               choices=['develop', 'staging', 'prod'])
    deploy_parser.add_argument('--namespace', default=None)
    deploy_parser.add_argument(
        '--set',
        action='append',
    )
    deploy_parser.add_argument('--version', )
    deploy_parser.add_argument('--timeout')
    deploy_parser.add_argument('--force', action='store_true')

    args = argparser.parse_args()

    config = hubploy.config.get_config(args.deployment)

    if args.command == 'build':
        if not args.check_registry and not args.commit_range:
            # commit_range autodetection failed, and check registry isn't set
            # FIXME: Provide an actually useful error message
            print(
                "Could not auto-detect commit-range, and --check-registry is not set",
                file=sys.stderr)
            print("Specify --commit-range manually, or pass --check-registry",
                  file=sys.stderr)
            sys.exit(1)

        if args.push or args.check_registry:
            auth.registry_auth(args.deployment)

        for image in config.get('images', {}).get('images', {}):
            if image.needs_building(check_registry=args.check_registry,
                                    commit_range=args.commit_range):
                image.fetch_parent_image()
                image.build()
                if args.push:
                    image.push()

    elif args.command == 'deploy':
        auth.cluster_auth(args.deployment)
        helm.deploy(args.deployment, args.chart, args.environment,
                    args.namespace, args.set, args.version, args.timeout,
                    args.force)