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)
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)
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, )
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, )
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)