2 HomeCU tool for deploying containers and updating ECS. 10 from .
import REGISTRIES
11 from .
import get_client_oauth_data
12 from .ecr
import push_odyssey_images
13 from concurrent
import futures
17 """ Deploy an Odyssey stack. 19 The basic delivery for a deploy is a set of docker containers. A 20 docker registry acts as the gateway between build and execution. The 21 role of this script is to deliver new images to the registry and then 22 update ECS task definitions to commence a rolling update. """ 27 allowed_states = {
'ready',
'active',
'partial_deploy'}
29 def setup_args(self, parser):
31 self.add_argument(
'--verbose',
'-v', action=
'store_true')
32 self.add_argument(
'--passphrase', env=
'ODYSSEY_STACK_PASSPHRASE',
33 help=
'To avoid being prompted for a passphrase on ' 34 'protected stacks, you can set it on the command ' 35 'line or via the env.')
40 raise SystemExit(
'Stack not found: %s' % args.stack)
41 stack.check_passphrase(args.passphrase)
43 stack.update_state(
'deploying')
47 stack.update_state(
'partial_deploy')
48 stack._save(
'Deploy failure of %s from %s' % (
49 os.environ[
'GIT_REV'], os.environ[
'PROJECT_NAME']))
52 stack.update_state(
'active')
53 stack._save(
'Deployed %s from %s' % (os.environ[
'GIT_REV'],
54 os.environ[
'PROJECT_NAME']))
56 def deploy(self, args, stack):
57 registry = REGISTRIES[stack.region]
59 push_odyssey_images(args.stack, stack.region, args.verbose)
62 "stack_url":
'https://%s' % stack.dns[0],
63 "stack_domain": stack.dns[0],
65 "db_host": stack.db[
'host'],
66 "db_port": str(stack.db[
'port']),
67 "db_name": stack.db[
'name'],
68 "db_user": stack.db[
'user'],
69 "db_password": stack.db[
'password'],
70 "oauth2_client_id": oauth_client[0],
71 "oauth2_client_secret": oauth_client[1],
73 for i, n
in enumerate(random.sample(range(12000, 60000), 10)):
74 template_vars[
'randport%d' % i] = n
76 client = boto3.client(
'ecs', region_name=stack.region)
78 for task
in os.scandir(
'tasks'):
79 if not task.name.endswith(
'.json'):
81 with open(task.path)
as f:
82 data = json.loads(f.read() % template_vars)
83 taskdef = data[
'definition']
84 service = data[
'service']
86 for cdef
in taskdef[
'containerDefinitions']:
87 env = dict((x[
'name'], x[
'value'])
88 for x
in cdef.get(
'environment', []))
90 cdef[
'environment'] = [{
93 }
for key, value
in env.items()]
94 if not stack.has_resource(
'ecs-task-definition',
96 print(
"Adding new task definition:", taskdef[
'family'])
97 stack.add_resource(
'ecs-task-definition', taskdef[
'family'],
98 family=taskdef[
'family'])
100 print(
"Updating existing task definition:", taskdef[
'family'])
101 task = client.register_task_definition(**taskdef)[
'taskDefinition']
103 print(
"Updating Service: %s -> v%d" % (service,
105 client.update_service(**{
106 "cluster": stack.cluster,
108 "taskDefinition": taskdef[
'family']
110 service_tasks[service] = task
112 count = stack.deploy.get(
'count', 0)
115 "updated": base.localnow().isoformat(),
116 "project": os.environ[
'PROJECT_NAME'],
117 "build_ident": os.environ[
'OPERATOR_IDENT'],
118 "git_rev": os.environ[
'GIT_REV'],
119 "git_branch": os.environ[
'GIT_BRANCH'],
120 "git_repo": os.environ[
'GIT_REPO'],
121 "docker_version": os.environ[
'DOCKER_VERSION'],
122 "service_tasks": service_tasks
def deploy(self, args, stack)
def get_client_oauth_data(domain)
def add_stack_argument(self, *args, env=DEFAULT_STACK_ENV, help=None, metavar='STACK_NAME', **kwargs)
def get_stack(self, name)
def check_requirements(self, stack)