def images(): images = ECR().get_images() print('') print_green('Image Pushed At | Image Tags') print_green('----------------------------------------------------------') for image in sorted(images, key=itemgetter('imagePushedAt'), reverse=True): if 'imageTags' not in image.keys(): continue print("%s | %s" % (image['imagePushedAt'], ', '.join(image['imageTags'])))
def k8s_delete(context, namespace=None, yaml_file_name=None): if yaml_file_name is None: yaml_file_name = context kubernetes_yml = os.path.join(os.getcwd(), "hokusai/%s.yml" % yaml_file_name) if not os.path.isfile(kubernetes_yml): raise HokusaiError("Yaml file %s does not exist." % kubernetes_yml) kctl = Kubectl(context, namespace=namespace) shout(kctl.command("delete -f %s" % kubernetes_yml), print_output=True) print_green("Deleted Kubernetes environment %s" % kubernetes_yml)
def gitcompare(org_name, git_compare_link): ecr = ECR() staging_tag = ecr.find_git_sha1_image_tag('staging') if staging_tag is None: raise HokusaiError("Could not find a tag for staging. Aborting.") production_tag = ecr.find_git_sha1_image_tag('production') if production_tag is None: raise HokusaiError("Could not find a git SHA1 tag for production. Aborting.") print_green(git_compare_link % (org_name, config.project_name, production_tag, staging_tag))
def push(tag, build, force, overwrite, skip_latest=False): if force is None and shout('git status --porcelain'): raise HokusaiError("Working directory is not clean. Aborting.") if force is None and shout('git status --porcelain --ignored'): raise HokusaiError( "Working directory contains ignored files and/or directories. Aborting." ) ecr = ECR() if not ecr.project_repo_exists(): raise HokusaiError( "ECR repo %s does not exist... did you run `hokusai setup` for this project?" % config.project_name) shout(ecr.get_login()) if tag is None: tag = shout('git rev-parse HEAD').strip() if overwrite is None and ecr.tag_exists(tag): raise HokusaiError("Tag %s already exists in registry. Aborting." % tag) if build: docker_compose_yml = os.path.join(os.getcwd(), 'hokusai/build.yml') legacy_docker_compose_yml = os.path.join(os.getcwd(), 'hokusai/common.yml') if not os.path.isfile(docker_compose_yml) and not os.path.isfile( legacy_docker_compose_yml): raise HokusaiError("Yaml files %s / %s do not exist." % (docker_compose_yml, legacy_docker_compose_yml)) if os.path.isfile(docker_compose_yml): shout("docker-compose -f %s -p hokusai build" % docker_compose_yml, print_output=True) if os.path.isfile(legacy_docker_compose_yml): shout("docker-compose -f %s -p hokusai build" % legacy_docker_compose_yml, print_output=True) build_tag = "hokusai_%s:latest" % config.project_name shout("docker tag %s %s:%s" % (build_tag, ecr.project_repo, tag)) shout("docker push %s:%s" % (ecr.project_repo, tag), print_output=True) print_green("Pushed %s to %s:%s" % (build_tag, ecr.project_repo, tag)) if skip_latest: return shout("docker tag %s %s:%s" % (build_tag, ecr.project_repo, 'latest')) shout("docker push %s:%s" % (ecr.project_repo, 'latest'), print_output=True) print_green("Pushed %s to %s:%s" % (build_tag, ecr.project_repo, 'latest'))
def retag(tag_to_change, tag_to_match): ecr = ECR() if not ecr.project_repo_exists(): raise HokusaiError("Project repo does not exist. Aborting.") try: ecr.retag(tag_to_match, tag_to_change) print_green( "Updated ECR '%s' tag to point to the image that '%s' tag points to." % (tag_to_change, tag_to_match), newline_after=True) except (ValueError, ClientError) as e: raise HokusaiError("Updating ECR tag failed due to the error: '%s'" % str(e))
def gitdiff(): ecr = ECR() staging_tag = ecr.find_git_sha1_image_tag('staging') if staging_tag is None: raise HokusaiError("Could not find a tag for staging. Aborting.") production_tag = ecr.find_git_sha1_image_tag('production') if production_tag is None: raise HokusaiError( "Could not find a git SHA1 tag for production. Aborting.") print_green("Comparing %s to %s" % (production_tag, staging_tag)) for remote in shout('git remote').splitlines(): shout("git fetch %s" % remote) shout("git diff %s %s" % (production_tag, staging_tag), print_output=True)
def k8s_delete(context, namespace=None, filename=None): if filename is None: yaml_template = TemplateSelector().get(os.path.join(CWD, HOKUSAI_CONFIG_DIR, context)) else: yaml_template = TemplateSelector().get(filename) if filename is None: configmap = ConfigMap(context, namespace=namespace) configmap.destroy() print_green("Deleted configmap %s-environment" % config.project_name) kctl = Kubectl(context, namespace=namespace) yaml_spec = YamlSpec(yaml_template).to_file() shout(kctl.command("delete -f %s" % yaml_spec), print_output=True) print_green("Deleted Kubernetes environment %s" % yaml_template)
def configure(kubectl_version, bucket_name, key_name, platform, install_to, install_config_to): print_green("Downloading and installing kubectl...") urllib.urlretrieve( "https://storage.googleapis.com/kubernetes-release/release/v%s/bin/%s/amd64/kubectl" % (kubectl_version, platform), os.path.join('/tmp', 'kubectl')) os.chmod(os.path.join('/tmp', 'kubectl'), 0755) shutil.move(os.path.join('/tmp', 'kubectl'), os.path.join(install_to, 'kubectl')) print_green("Configuring kubectl...") if not os.path.isdir(install_config_to): mkpath(install_config_to) bucket = boto3.resource('s3').Bucket(bucket_name) bucket.download_file(key_name, os.path.join(install_config_to, 'config'))
def k8s_update(context, namespace=None, filename=None, check_branch="master", check_remote=None, skip_checks=False, dry_run=False): if filename is None: kubernetes_yml = os.path.join(CWD, HOKUSAI_CONFIG_DIR, "%s.yml" % context) else: kubernetes_yml = filename if not os.path.isfile(kubernetes_yml): raise HokusaiError("Yaml file %s does not exist." % kubernetes_yml) if not skip_checks: current_branch = None for branchname in shout('git branch').splitlines(): if '* ' in branchname: current_branch = branchname.replace('* ', '') break if 'detached' in current_branch: raise HokusaiError("Not on any branch! Aborting.") if current_branch != check_branch: raise HokusaiError("Not on %s branch! Aborting." % check_branch) remotes = [check_remote ] if check_remote else shout('git remote').splitlines() for remote in remotes: shout("git fetch %s" % remote) if returncode("git diff --quiet %s/%s" % (remote, current_branch)): raise HokusaiError( "Local branch %s is divergent from %s/%s. Aborting." % (current_branch, remote, current_branch)) kctl = Kubectl(context, namespace=namespace) if dry_run: shout(kctl.command("apply -f %s --dry-run" % kubernetes_yml), print_output=True) print_green("Updated Kubernetes environment %s (dry run)" % kubernetes_yml) else: shout(kctl.command("apply -f %s" % kubernetes_yml), print_output=True) print_green("Updated Kubernetes environment %s" % kubernetes_yml)
def test(build, cleanup, filename, service_name): if filename is None: yaml_template = TemplateSelector().get( os.path.join(CWD, HOKUSAI_CONFIG_DIR, TEST_YML_FILE)) else: yaml_template = TemplateSelector().get(filename) docker_compose_yml = YamlSpec(yaml_template).to_file() follow_extends(docker_compose_yml) def on_cleanup(*args): shout("docker-compose -f %s -p hokusai stop" % docker_compose_yml) shout("docker-compose -f %s -p hokusai rm --force" % docker_compose_yml) if cleanup: for sig in EXIT_SIGNALS: signal.signal(sig, on_cleanup) opts = ' --abort-on-container-exit' if build: Docker().build() if service_name is None: service_name = config.project_name print_green("Starting test environment... Press Ctrl+C to stop.", newline_after=True) try: shout("docker-compose -f %s -p hokusai up%s" % (docker_compose_yml, opts), print_output=True) return_code = int(shout("docker wait hokusai_%s_1" % service_name)) except CalledProcessError: if cleanup: on_cleanup() raise HokusaiError('Tests Failed') if return_code: raise HokusaiError('Tests Failed - Exit Code: %s\n' % return_code, return_code=return_code) else: print_green("Tests Passed") if cleanup: on_cleanup() return return_code
def k8s_delete(context, namespace=None, filename=None): if filename is None: kubernetes_yml = os.path.join(CWD, HOKUSAI_CONFIG_DIR, "%s.yml" % context) else: kubernetes_yml = filename if not os.path.isfile(kubernetes_yml): raise HokusaiError("Yaml file %s does not exist." % kubernetes_yml) if filename is None: configmap = ConfigMap(context, namespace=namespace) configmap.destroy() print_green("Deleted configmap %s-environment" % config.project_name) kctl = Kubectl(context, namespace=namespace) shout(kctl.command("delete -f %s" % kubernetes_yml), print_output=True) print_green("Deleted Kubernetes environment %s" % kubernetes_yml)
def configure(kubectl_version, bucket_name, key_name, config_file, platform, install_to, install_config_to): if not ((bucket_name and key_name) or config_file): raise HokusaiError("Must define bucket_name and key_name or config_file") print_green("Downloading and installing kubectl...") urllib.urlretrieve("https://storage.googleapis.com/kubernetes-release/release/v%s/bin/%s/amd64/kubectl" % (kubectl_version, platform), os.path.join('/tmp', 'kubectl')) os.chmod(os.path.join('/tmp', 'kubectl'), 0755) shutil.move(os.path.join('/tmp', 'kubectl'), os.path.join(install_to, 'kubectl')) print_green("Configuring kubectl...") if not os.path.isdir(install_config_to): mkpath(install_config_to) if bucket_name and key_name: client = boto3.client('s3', region_name=get_region_name()) client.download_file(bucket_name, key_name, os.path.join(install_config_to, 'config')) else: shutil.copy(config_file, os.path.join(install_config_to, 'config'))
def refresh(self): for deployment in self.cache: print_green("Refreshing %s..." % deployment['metadata']['name'], newline_after=True) shout( self.kctl.command("rollout restart deployment/%s" % deployment['metadata']['name'])) print_green("Waiting for refresh to complete...") rollout_commands = [ self.kctl.command("rollout status deployment/%s" % deployment['metadata']['name']) for deployment in self.cache ] return_codes = shout_concurrent(rollout_commands, print_output=True) if any(return_codes): raise HokusaiError("Refresh failed!")
def configure(kubectl_version, bucket_name, key_name, config_file, install_to, install_config_to): if global_config.is_present( ) and global_config.kubectl_version is not None: kubectl_version = global_config.kubectl_version if not kubectl_version: raise HokusaiError("You must supply a kubectl_version") if global_config.is_present( ) and global_config.kubectl_config_file is not None: uri = urlparse(global_config.kubectl_config_file) if uri.scheme == 's3': bucket_name = uri.netloc key_name = uri.path if uri.scheme == 'file': key_name = uri.path if not ((bucket_name and key_name) or config_file): raise HokusaiError("You must define valid config_file") print_green("Downloading and installing kubectl...", newline_before=True, newline_after=True) tmpdir = tempfile.mkdtemp() urlretrieve( "https://storage.googleapis.com/kubernetes-release/release/v%s/bin/%s/amd64/kubectl" % (kubectl_version, platform.system().lower()), os.path.join(tmpdir, 'kubectl')) os.chmod(os.path.join(tmpdir, 'kubectl'), 0o755) shutil.move(os.path.join(tmpdir, 'kubectl'), os.path.join(install_to, 'kubectl')) shutil.rmtree(tmpdir) print_green("Configuring kubectl...", newline_after=True) if not os.path.isdir(install_config_to): mkpath(install_config_to) if bucket_name and key_name: client = boto3.client('s3', region_name=get_region_name()) client.download_file(bucket_name, key_name.lstrip('/'), os.path.join(install_config_to, 'config')) else: shutil.copy(config_file, os.path.join(install_config_to, 'config'))
def images(reverse_sort, limit, filter_tags, digests): images = ECR().images sorted_images = sorted(images, key=itemgetter('imagePushedAt'), reverse=not reverse_sort) filtered_images = filter(lambda image: 'imageTags' in image.keys(), sorted_images) if filter_tags: filtered_images = filter( lambda image: filter_tags in ', '.join(image['imageTags']), filtered_images) if digests: print_green( 'Image Pushed At | Image Digest | Image Tags', newline_before=True) print_green( '--------------------------------------------------------------------------------------------------------------------------------------' ) else: print_green('Image Pushed At | Image Tags', newline_before=True) print_green( '----------------------------------------------------------') for image in filtered_images[:limit]: image_tags = ', '.join(image['imageTags']) if digests: line = "%s | %s | %s" % (image['imagePushedAt'], image['imageDigest'], image_tags) else: line = "%s | %s" % (image['imagePushedAt'], image_tags) if 'production' in image['imageTags']: print_green(line) elif 'staging' in image['imageTags']: print_yellow(line) else: print_smart(line) print_yellow("%d more images available" % (len(filtered_images) - len(filtered_images[:limit])), newline_before=True, newline_after=True)
def pull(tag, local_tag): ecr = ECR() if not ecr.project_repo_exists(): raise HokusaiError( "ECR repo %s does not exist... did you run `hokusai setup` for this project?" % config.project_name) shout(ecr.get_login(), mask=(r'^(docker login -u) .+ (-p) .+ (.+)$', r'\1 ****** \2 ***** \3')) shout("docker pull %s:%s" % (ecr.project_repo, tag)) shout("docker tag %s:%s hokusai_%s:%s" % (ecr.project_repo, tag, config.project_name, local_tag)) print_green("Pulled %s:%s to hokusai_%s:%s" % (ecr.project_repo, tag, config.project_name, local_tag), newline_after=True)
def push(tag, local_tag, build, filename, force, overwrite, skip_latest=False): if force is None and shout('git status --porcelain'): raise HokusaiError("Working directory is not clean. Aborting.") if force is None and shout('git status --porcelain --ignored'): raise HokusaiError( "Working directory contains ignored files and/or directories. Aborting." ) ecr = ECR() if not ecr.project_repo_exists(): raise HokusaiError( "ECR repo %s does not exist... did you run `hokusai setup` for this project?" % config.project_name) shout(ecr.get_login(), mask=(r'^(docker login -u) .+ (-p) .+ (.+)$', r'\1 ****** \2 ***** \3')) if tag is None: tag = shout('git rev-parse HEAD').strip() if overwrite is None and ecr.tag_exists(tag): raise HokusaiError("Tag %s already exists in registry. Aborting." % tag) if build: Docker().build(filename) build_tag = "hokusai_%s:%s" % (config.project_name, local_tag) shout("docker tag %s %s:%s" % (build_tag, ecr.project_repo, tag)) shout("docker push %s:%s" % (ecr.project_repo, tag), print_output=True) print_green("Pushed %s to %s:%s" % (build_tag, ecr.project_repo, tag), newline_after=True) if skip_latest: return shout("docker tag %s %s:%s" % (build_tag, ecr.project_repo, 'latest')) shout("docker push %s:%s" % (ecr.project_repo, 'latest'), print_output=True) print_green("Pushed %s to %s:%s" % (build_tag, ecr.project_repo, 'latest'), newline_after=True)
def k8s_create(context, tag='latest', namespace=None, yaml_file_name=None): if yaml_file_name is None: yaml_file_name = context kubernetes_yml = os.path.join(CWD, "%s/%s.yml" % (HOKUSAI_CONFIG_DIR, yaml_file_name)) if not os.path.isfile(kubernetes_yml): raise HokusaiError("Yaml file %s does not exist." % kubernetes_yml) ecr = ECR() if not ecr.project_repo_exists(): raise HokusaiError("ECR repository %s does not exist... did you run `hokusai setup` for this project?" % config.project_name) if not ecr.tag_exists(tag): raise HokusaiError("Image tag %s does not exist... did you run `hokusai registry push`?" % tag) if tag is 'latest' and not ecr.tag_exists(context): ecr.retag(tag, context) print_green("Updated tag 'latest' -> %s" % context) kctl = Kubectl(context, namespace=namespace) shout(kctl.command("create --save-config -f %s" % kubernetes_yml), print_output=True) print_green("Created Kubernetes environment %s" % kubernetes_yml)
def gitlog(): ecr = ECR() staging_deployment = Deployment('staging') staging_tag = staging_deployment.current_tag if staging_tag is None: raise HokusaiError("Could not find a tag for staging. Aborting.") staging_tag = ecr.find_git_sha1_image_tag(staging_tag) if staging_tag is None: raise HokusaiError("Could not find a git SHA1 tag for tag %s. Aborting." % staging_tag) production_deployment = Deployment('production') production_tag = production_deployment.current_tag if production_tag is None: raise HokusaiError("Could not find a tag for production. Aborting.") production_tag = ecr.find_git_sha1_image_tag(production_tag) if production_tag is None: raise HokusaiError("Could not find a git SHA1 for tag %s. Aborting." % production_tag) print_green("Comparing %s to %s" % (production_tag, staging_tag)) shout("git log --right-only %s..%s" % (production_tag, staging_tag), print_output=True)
def k8s_create(context, tag='latest', namespace=None, filename=None, environment=()): if filename is None: yaml_template = TemplateSelector().get(os.path.join(CWD, HOKUSAI_CONFIG_DIR, context)) else: yaml_template = TemplateSelector().get(filename) ecr = ECR() if not ecr.project_repo_exists(): raise HokusaiError("ECR repository %s does not exist... did you run `hokusai setup` for this project?" % config.project_name) if not ecr.tag_exists(tag): raise HokusaiError("Image tag %s does not exist... did you run `hokusai registry push`?" % tag) if tag == 'latest' and not ecr.tag_exists(context): ecr.retag(tag, context) print_green("Updated tag 'latest' -> %s" % context) if filename is None: configmap = ConfigMap(context, namespace=namespace) for s in environment: if '=' not in s: raise HokusaiError("Error: environment variables must be of the form 'KEY=VALUE'") split = s.split('=', 1) configmap.update(split[0], split[1]) configmap.create() print_green("Created configmap %s-environment" % config.project_name) kctl = Kubectl(context, namespace=namespace) yaml_spec = YamlSpec(yaml_template).to_file() shout(kctl.command("create --save-config -f %s" % yaml_spec), print_output=True) print_green("Created Kubernetes environment %s" % yaml_template)
def create_new_app_yaml(source_file, app_name): with open(source_file, 'r') as stream: try: yaml_content = list(yaml.load_all(stream)) except yaml.YAMLError as exc: raise HokusaiError("Cannot read source yaml file %s." % source_file) for c in yaml_content: update_namespace(c, clean_string(app_name)) new_namespace = OrderedDict([('apiVersion', 'v1'), ('kind', 'Namespace'), ('metadata', { 'name': clean_string(app_name) })]) yaml_content = [new_namespace] + yaml_content with open("hokusai/%s.yml" % app_name, 'w') as output: output.write(YAML_HEADER) yaml.safe_dump_all(yaml_content, output, default_flow_style=False) print_green("Created hokusai/%s.yml" % app_name)
def test(build, cleanup): docker_compose_yml = os.path.join(os.getcwd(), 'hokusai/test.yml') if not os.path.isfile(docker_compose_yml): raise HokusaiError("Yaml file %s does not exist." % docker_compose_yml) def on_cleanup(*args): shout("docker-compose -f %s -p hokusai stop" % docker_compose_yml) shout("docker-compose -f %s -p hokusai rm --force" % docker_compose_yml) if cleanup: for sig in EXIT_SIGNALS: signal.signal(sig, on_cleanup) opts = ' --abort-on-container-exit' if build: opts += ' --build' print_green("Starting test environment... Press Ctrl+C to stop.") try: shout("docker-compose -f %s -p hokusai up%s" % (docker_compose_yml, opts), print_output=True) return_code = int( shout("docker wait hokusai_%s_1" % config.project_name)) except CalledProcessError: if cleanup: on_cleanup() raise HokusaiError('Tests Failed') if return_code: raise HokusaiError('Tests Failed - Exit Code: %s\n' % return_code, return_code=return_code) else: print_green("Tests Passed") if cleanup: on_cleanup() return return_code
def create_new_app_yaml(source_file, app_name): yaml_spec = YamlSpec(source_file).to_file() with open(yaml_spec, 'r') as stream: try: yaml_content = list(yaml.load_all(stream, Loader=yaml.FullLoader)) except yaml.YAMLError as exc: raise HokusaiError("Cannot read source yaml file %s." % source_file) for c in yaml_content: update_namespace(c, clean_string(app_name)) new_namespace = OrderedDict([('apiVersion', 'v1'), ('kind', 'Namespace'), ('metadata', { 'name': clean_string(app_name) })]) yaml_content = [new_namespace] + yaml_content with open(os.path.join(CWD, HOKUSAI_CONFIG_DIR, "%s.yml" % app_name), 'w') as output: output.write(YAML_HEADER) yaml.safe_dump_all(yaml_content, output, default_flow_style=False) print_green("Created %s/%s.yml" % (HOKUSAI_CONFIG_DIR, app_name))
def update(context, tag, migration, constraint, git_remote, timeout, namespace=None, resolve_tag_sha1=True): if migration is not None: print_green("Running migration '%s' on %s..." % (migration, context), newline_after=True) return_code = CommandRunner(context, namespace=namespace).run( tag, migration, constraint=constraint, tty=False) if return_code: raise HokusaiError("Migration failed with return code %s" % return_code, return_code=return_code) Deployment(context, namespace=namespace).update(tag, constraint, git_remote, timeout, resolve_tag_sha1=resolve_tag_sha1) print_green("Deployment updated to %s" % tag)
def environment_create(context): kubernetes_yml = os.path.join(os.getcwd(), "hokusai/%s.yml" % context) if not os.path.isfile(kubernetes_yml): raise HokusaiError("Yaml file %s does not exist for given context." % kubernetes_yml) ecr = ECR() if not ecr.project_repository_exists(): raise HokusaiError( "ECR repository %s does not exist... did you run `hokusai setup` for this project?" % config.project_name) if not ecr.tag_exists('latest'): raise HokusaiError( "Image tag 'latest' does not exist... did you run `hokusai push`?") if not ecr.tag_exists(context): ecr.retag('latest', context) print_green("Updated tag 'latest' -> %s" % context) kctl = Kubectl(context) shout(kctl.command("create --save-config -f %s" % kubernetes_yml), print_output=True) print_green("Created remote environment %s" % context)
def gitcompare(org_name, git_compare_link): ecr = ECR() staging_deployment = Deployment('staging') staging_tag = staging_deployment.current_tag if staging_tag is None: raise HokusaiError("Could not find a tag for staging. Aborting.") staging_tag = ecr.find_git_sha1_image_tag(staging_tag) if staging_tag is None: raise HokusaiError( "Could not find a git SHA1 tag for tag %s. Aborting." % staging_tag) production_deployment = Deployment('production') production_tag = production_deployment.current_tag if production_tag is None: raise HokusaiError("Could not find a tag for production. Aborting.") production_tag = ecr.find_git_sha1_image_tag(production_tag) if production_tag is None: raise HokusaiError("Could not find a git SHA1 for tag %s. Aborting." % production_tag) print_green(git_compare_link % (org_name, config.project_name, production_tag, staging_tag))
def promote(migration, constraint, git_remote): ecr = ECR() deploy_from = Deployment('staging') tag = deploy_from.current_tag if tag is None: raise HokusaiError("Could not find a tag for staging. Aborting.") tag = ecr.find_git_sha1_image_tag(tag) if tag is None: print_red("Could not find a git SHA1 for tag %s. Aborting." % tag) return -1 print_green("Deploying tag %s to production..." % tag) if migration is not None: print_green("Running migration '%s' on production..." % migration) return_code = CommandRunner('production').run(tag, migration, constraint=constraint) if return_code: raise HokusaiError("Migration failed with return code %s" % return_code, return_code=return_code) deploy_to = Deployment('production').update(tag, constraint, git_remote) print_green("Promoted staging to production at %s" % tag)
def update(self, tag, constraint): print_green("Deploying %s to %s..." % (tag, self.context)) if self.context != tag: ecr = ECR() ecr.retag(tag, self.context) print_green("Updated tag %s -> %s" % (tag, self.context)) deployment_tag = "%s--%s" % ( self.context, datetime.datetime.utcnow().strftime("%Y-%m-%d--%H-%M-%S")) ecr.retag(tag, deployment_tag) print_green("Updated tag %s -> %s" % (tag, deployment_tag)) if config.pre_deploy is not None: print_green("Running pre-deploy hook '%s' on %s..." % (config.pre_deploy, self.context)) return_code = CommandRunner(self.context).run( tag, config.pre_deploy, constraint=constraint) if return_code: raise HokusaiError( "Pre-deploy hook failed with return code %s" % return_code, return_code=return_code) deployment_timestamp = datetime.datetime.utcnow().strftime("%s%f") for deployment in self.cache: containers = deployment['spec']['template']['spec']['containers'] container_names = [container['name'] for container in containers] deployment_targets = [{ "name": name, "image": "%s:%s" % (config.aws_ecr_registry, tag) } for name in container_names] patch = { "spec": { "template": { "metadata": { "labels": { "deploymentTimestamp": deployment_timestamp } }, "spec": { "containers": deployment_targets } } } } print_green("Patching deployment %s..." % deployment['metadata']['name']) shout( self.kctl.command( "patch deployment %s -p '%s'" % (deployment['metadata']['name'], json.dumps(patch)))) print_green("Waiting for rollout to complete...") rollout_commands = [ self.kctl.command("rollout status deployment/%s" % deployment['metadata']['name']) for deployment in self.cache ] return_code = shout_concurrent(rollout_commands) if return_code: raise HokusaiError("Deployment failed!", return_code=return_code) if config.post_deploy is not None: print_green("Running post-deploy hook '%s' on %s..." % (config.post_deploy, self.context)) return_code = CommandRunner(self.context).run( tag, config.post_deploy, constraint=constraint) if return_code: raise HokusaiError( "Post-deploy hook failed with return code %s" % return_code, return_code=return_code)
def check_ok(check_item): print_green('\u2714 ' + check_item + ' found')
def k8s_status(context, resources, pods, describe, top, namespace=None, filename=None): if filename is None: yaml_template = TemplateSelector().get( os.path.join(CWD, HOKUSAI_CONFIG_DIR, context)) else: yaml_template = TemplateSelector().get(filename) kctl = Kubectl(context, namespace=namespace) yaml_spec = YamlSpec(yaml_template).to_file() if describe: kctl_cmd = "describe" output = "" else: kctl_cmd = "get" output = " -o wide" if resources: print_green("Resources", newline_before=True) print_green("===========") shout(kctl.command("%s -f %s%s" % (kctl_cmd, yaml_spec, output)), print_output=True) if pods: print_green("Pods", newline_before=True) print_green("===========") shout(kctl.command("%s pods --selector app=%s,layer=application%s" % (kctl_cmd, config.project_name, output)), print_output=True) if top: print_green("Top Pods", newline_before=True) print_green("===========") shout(kctl.command("top pods --selector app=%s,layer=application" % config.project_name), print_output=True)