· 7 years ago · Mar 20, 2018, 01:50 PM
1import base64
2import json
3
4import docker
5import boto3
6import sys
7import click
8import os
9
10env_list = ['dev', 'test', 'prod']
11
12access_key = 'AKIAII2HDKJB52AXQ5IQ'
13secret_key = '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'
14region = 'eu-west-2'
15
16repo = '621275034485.dkr.ecr.eu-west-2.amazonaws.com/petsquare'
17td_family = 'petsquare-dev'
18
19clusters = {
20 'dev': 'default',
21 'test': 'default',
22 'prod': 'petsquare-prod'
23}
24
25
26def process_docker_api_line(payload):
27 for segment in payload.decode("utf-8").split('\n'):
28 line = segment.strip()
29 if line:
30 try:
31 line_payload = json.loads(line)
32 except ValueError as ex:
33 print("Could not decipher payload from API: " + str(ex))
34 continue
35 if line_payload:
36 if "errorDetail" in line_payload:
37 error = line_payload["errorDetail"]
38 sys.stderr.write(error["message"])
39 raise RuntimeError("Error on build - code " + str(error["code"]))
40 elif "stream" in line_payload:
41 sys.stdout.write(line_payload["stream"])
42
43
44def build_and_push_to_ecr(path, env):
45 local_tag = 'petsquare:{}-latest'.format(env)
46
47 ecr_client = boto3.client('ecr', region_name=region)
48 docker_api = docker.APIClient()
49
50 print("Building image " + local_tag)
51 for line in docker_api.build(path=path, tag=local_tag, stream=True):
52 process_docker_api_line(line)
53
54 auth = ecr_client.get_authorization_token()
55 token = auth["authorizationData"][0]["authorizationToken"]
56 username, password = base64.b64decode(token).decode("utf-8").split(':')
57
58 auth_config_payload = {'username': username, 'password': password}
59
60 version_tag = repo + ':{}-latest'.format(env)
61
62 print('Tagging version', version_tag)
63 if not docker_api.tag(local_tag, version_tag):
64 raise RuntimeError("Tag appeared to fail: " + version_tag)
65
66 print('Pushing to repo', version_tag)
67 for line in docker_api.push(version_tag, stream=True, auth_config=auth_config_payload):
68 process_docker_api_line(line)
69 print('Success!')
70 if docker_api.remove_image(version_tag, force=True):
71 print('Remove source local image completed')
72
73
74def update_tasks():
75 ecs_client = boto3.client(
76 'ecs',
77 aws_access_key_id=access_key,
78 aws_secret_access_key=secret_key,
79 region_name=region
80 )
81 td_response = ecs_client.list_task_definitions(
82 familyPrefix='petsquare-dev',
83 status='ACTIVE',
84 sort='DESC',
85 )
86 last_td = td_response['taskDefinitionArns'][0].split('/')[-1]
87 ecs_client.register_task_definition(containerDefinitions=[
88 {
89 "portMappings": [
90 {
91 "hostPort": 80,
92 "protocol": "tcp",
93 "containerPort": 81
94 }
95 ],
96 "cpu": 0,
97 "memory": 1024,
98 "image": "621275034485.dkr.ecr.eu-west-2.amazonaws.com/petsquare:dev-latest",
99 "name": "petsquare-dev"
100 }
101 ], family=td_family)
102
103 ecs_client.deregister_task_definition(
104 taskDefinition=last_td
105 )
106
107 task_response = ecs_client.list_tasks(
108 cluster='default',
109 family=td_family,
110 desiredStatus='RUNNING',
111 )
112 for arn in task_response['taskArns']:
113 ecs_client.stop_task(
114 cluster='default',
115 task=arn
116 )
117 ecs_client.run_task(
118 cluster='default',
119 taskDefinition=td_family,
120 count=2
121 )
122
123
124@click.command()
125@click.option('--env', help='Env: dev/test/prod', prompt='Env')
126@click.option('--path', prompt='Dockerfile path',
127 help='Path to Dockerfile')
128def perform_update(env, path):
129 if env not in env_list:
130 raise RuntimeError('Wrong env param')
131 if not os.path.exists(path):
132 raise RuntimeError('Wrong path to Dockerfile')
133
134 build_and_push_to_ecr(path=path, env=env)
135
136if __name__ == '__main__':
137 perform_update()