def run(context, command, tag, with_config, with_secrets, env): config = HokusaiConfig().check() try: select_context(context) except HokusaiCommandError, e: print_red(repr(e)) return -1
def unset_secrets(context, secrets): config = HokusaiConfig().check() try: select_context(context) except HokusaiCommandError, e: print_red(repr(e)) return -1
def pull_config(context): config = HokusaiConfig().check() try: select_context(context) except HokusaiCommandError, e: print_red(repr(e)) return -1
def stack_up(context): HokusaiConfig().check() kubernetes_yml = os.path.join(os.getcwd(), "hokusai/%s.yml" % context) if not os.path.isfile(kubernetes_yml): print_red("Yaml file %s does not exist for given context." % kubernetes_yml) return -1 try: select_context(context) except HokusaiCommandError, e: print_red(repr(e)) return -1
def push_config(context): HokusaiConfig().check() if not os.path.isfile( os.path.join(os.getcwd(), 'hokusai', "%s-config.yml" % context)): print_red("Secrets file hokusai/%s-config.yml does not exist" % context) return -1 try: select_context(context) except HokusaiCommandError, e: print_red(repr(e)) return -1
def development(): HokusaiConfig().check() docker_compose_yml = os.path.join(os.getcwd(), 'hokusai/development.yml') if not os.path.isfile(docker_compose_yml): print_red("Yaml file %s does not exist." % docker_compose_yml) return -1 def cleanup(*args): return 0 for sig in EXIT_SIGNALS: signal.signal(sig, cleanup) call(verbose("docker-compose -f %s up --build" % docker_compose_yml), shell=True)
def images(): config = HokusaiConfig().check() try: print('\n') print_green('REMOTE IMAGES') print_green('---------------------------') check_call("docker images %s" % config.aws_ecr_registry, shell=True) print('\n') print_green('LOCAL IMAGES') print_green('---------------------------') check_call("docker images build_%s" % config.project_name, shell=True) check_call("docker images ci_%s" % config.project_name, shell=True) print('\n') except CalledProcessError: return -1 return 0
def pull(): config = HokusaiConfig().check() try: login_command = check_output(verbose("aws ecr get-login --region %s" % config.aws_ecr_region), shell=True) check_call(verbose(login_command), shell=True) print_green("Pulling from %s..." % config.aws_ecr_registry) check_output(verbose("docker pull %s --all-tags" % config.aws_ecr_registry), shell=True) print_green("Pull succeeded") except CalledProcessError: print_red('Pull failed') return -1 return 0
def test(): config = HokusaiConfig().check() docker_compose_yml = os.path.join(os.getcwd(), 'hokusai/test.yml') if not os.path.isfile(docker_compose_yml): print_red("Yaml file %s does not exist." % docker_compose_yml) return -1 # stop any running containers def cleanup(*args): print_red('Tests Failed For Unexpected Reasons\n') call(verbose("docker-compose -f %s -p ci stop" % docker_compose_yml), shell=True) return -1 # catch exit, do cleanup for sig in EXIT_SIGNALS: signal.signal(sig, cleanup) # build and run the composed services if call(verbose("docker-compose -f %s -p ci up --build -d" % docker_compose_yml), shell=True) != 0: print_red("Docker Compose Failed\n") return -1 # wait for the test service to complete and grab the exit code try: test_exit_code = int(check_output(verbose("docker wait ci_%s_1" % config.project_name), shell=True)) except CalledProcessError: print_red('Docker wait failed.') call(verbose("docker-compose -f %s -p ci stop" % docker_compose_yml), shell=True) return -1 # output the logs for the test (for clarity) call(verbose("docker logs ci_%s_1" % config.project_name), shell=True) # inspect the output of the test and display respective message if test_exit_code != 0: print_red('Tests Failed - Exit Code: %s\n' % test_exit_code) else: print_green("Tests Passed") # cleanup call(verbose("docker-compose -f %s -p ci stop" % docker_compose_yml), shell=True) return test_exit_code
def push(tag, test_build): config = HokusaiConfig().check() try: login_command = check_output("aws ecr get-login --region %s" % config.aws_ecr_region, shell=True) check_call(login_command, shell=True) if test_build: build = "ci_%s:latest" % config.project_name else: build = "build_%s:latest" % config.project_name check_call("docker tag %s %s:%s" % (build, config.aws_ecr_registry, tag), shell=True) check_call("docker push %s:%s" % (config.aws_ecr_registry, tag), shell=True) print_green("Pushed %s to %s:%s" % (build, config.aws_ecr_registry, tag)) except CalledProcessError: print_red('Push failed') return -1 return 0
def init(project_name, aws_account_id, aws_ecr_region, framework, base_image, run_command, development_command, test_command, port, target_port, with_memcached, with_redis, with_mongo, with_postgres, with_rabbitmq): mkpath(os.path.join(os.getcwd(), 'hokusai')) config = HokusaiConfig().create(project_name.lower().replace('_', '-'), aws_account_id, aws_ecr_region) if framework == 'rack': dockerfile = env.get_template("Dockerfile-ruby.j2") if run_command is None: run_command = 'bundle exec foreman start' if development_command is None: development_command = 'bundle exec foreman start' if test_command is None: test_command = 'bundle exec rake' runtime_environment = { 'development': ["RACK_ENV=development"], 'test': ["RACK_ENV=test"], 'staging': [{'name': 'RACK_ENV', 'value': 'staging'}], 'production': [{'name': 'RACK_ENV', 'value': 'production'}] } elif framework == 'nodejs': dockerfile = env.get_template("Dockerfile-node.j2") if run_command is None: run_command = 'node index.js' if development_command is None: development_command = 'node index.js' if test_command is None: test_command = 'npm test' runtime_environment = { 'development': ["NODE_ENV=development"], 'test': ["NODE_ENV=test"], 'staging': [{'name': 'NODE_ENV', 'value': 'staging'}], 'production': [{'name': 'NODE_ENV', 'value': 'production'}] } elif framework == 'elixir': dockerfile = env.get_template("Dockerfile-elixir.j2") if run_command is None: run_command = 'mix run --no-halt' if development_command is None: development_command = 'mix run' if test_command is None: test_command = 'mix test' runtime_environment = { 'development': ["MIX_ENV=dev"], 'test': ["MIX_ENV=test"], 'staging': [{'name': 'MIX_ENV', 'value': 'prod'}], 'production': [{'name': 'MIX_ENV', 'value': 'prod'}] } with open(os.path.join(os.getcwd(), 'Dockerfile'), 'w') as f: f.write(dockerfile.render(base_image=base_image, command=run_command, target_port=target_port)) with open(os.path.join(os.getcwd(), 'hokusai', "common.yml"), 'w') as f: services = { config.project_name: { 'build': '../' } } data = OrderedDict([ ('version', '2'), ('services', services) ]) payload = YAML_HEADER + yaml.safe_dump(data, default_flow_style=False) f.write(payload) for idx, compose_environment in enumerate(['development', 'test']): with open(os.path.join(os.getcwd(), 'hokusai', "%s.yml" % compose_environment), 'w') as f: services = { config.project_name: { 'extends': { 'file': 'common.yml', 'service': config.project_name } } } if compose_environment == 'development': services[config.project_name]['command'] = development_command services[config.project_name]['ports'] = ["%s:%s" % (port, target_port)] if compose_environment == 'test': services[config.project_name]['command'] = test_command services[config.project_name]['environment'] = runtime_environment[compose_environment] if with_memcached: services['memcached'] = { 'image': 'memcached' } if compose_environment == 'development': services['memcached']['ports'] = ["11211:11211"] services[config.project_name]['environment'].append('MEMCACHED_SERVERS=memcached:11211') if with_redis: services['redis'] = { 'image': 'redis:3.2-alpine' } if compose_environment == 'development': services['redis']['ports'] = ["6379:6379"] services[config.project_name]['environment'].append("REDIS_URL=redis://redis:6379/%d" % idx) if with_mongo: services['mongodb'] = { 'image': 'mongo:3.0', 'command': 'mongod --smallfiles' } if compose_environment == 'development': services['mongodb']['ports'] = ["27017:27017"] services[config.project_name]['environment'].append("MONGO_URL=mongodb://mongodb:27017/%s" % compose_environment) if with_postgres: services['postgres'] = { 'image': 'postgres:9.4' } if compose_environment == 'development': services['postgres']['ports'] = ["5432:5432"] services[config.project_name]['environment'].append("DATABASE_URL=postgresql://postgres/%s" % compose_environment) if with_rabbitmq: services['rabbitmq'] = { 'image': 'rabbitmq:3.6-management' } if compose_environment == 'development': services['rabbitmq']['ports'] = ["5672:5672","15672:15672"] services[config.project_name]['environment'].append("RABBITMQ_URL=amqp://rabbitmq/%s" % compose_environment) data = OrderedDict([ ('version', '2'), ('services', services) ]) payload = YAML_HEADER + yaml.safe_dump(data, default_flow_style=False) f.write(payload) for stack in ['staging', 'production']: with open(os.path.join(os.getcwd(), 'hokusai', "%s.yml" % stack), 'w') as f: environment = runtime_environment[stack] if with_memcached: environment.append({'name': 'MEMCACHED_SERVERS', 'value': "%s-memcached:11211" % config.project_name}) if with_redis: environment.append({'name': 'REDIS_URL', 'value': "redis://%s-redis:6379/0" % config.project_name}) if with_mongo: environment.append({'name': 'MONGO_URL', 'value': "mongodb://%s-mongodb:27017/%s" % (config.project_name, stack)}) if with_postgres: environment.append({'name': 'DATABASE_URL', 'value': "postgresql://%s-postgres/%s" % (config.project_name, stack)}) if with_rabbitmq: environment.append({'name': 'RABBITMQ_URL', 'value': "amqp://%s-rabbitmq/%s" % (config.project_name, stack)}) deployment_data = build_deployment(config.project_name, "%s:%s" % (config.aws_ecr_registry, stack), target_port, environment=environment, always_pull=True) service_data = build_service(config.project_name, port, target_port=target_port, internal=False) stack_yaml = deployment_data + service_data if with_memcached: stack_yaml += build_deployment("%s-memcached" % config.project_name, 'memcached', 11211) stack_yaml += build_service("%s-memcached" % config.project_name, 11211) if with_redis: stack_yaml += build_deployment("%s-redis" % config.project_name, 'redis:3.2-alpine', 6379) stack_yaml += build_service("%s-redis" % config.project_name, 6379) if with_mongo: stack_yaml += build_deployment("%s-mongodb" % config.project_name, 'mongodb:3.0', 27017) stack_yaml += build_service("%s-mongodb" % config.project_name, 27017) if with_postgres: stack_yaml += build_deployment("%s-postgres" % config.project_name, 'postgres:9.4', 5432) stack_yaml += build_service("%s-postgres" % config.project_name, 5432) if with_rabbitmq: stack_yaml += build_deployment("%s-rabbitmq" % config.project_name, 'rabbitmq:3.6-management', 5672) stack_yaml += build_service("%s-rabbitmq" % config.project_name, 5672) f.write(stack_yaml) print_green("Config created in ./hokusai")