-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathdeploy.py
executable file
·127 lines (115 loc) · 4.25 KB
/
deploy.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import docker
import json
import os
import sys
import tarfile
import time
import requests
import subprocess
DEBUG = os.environ.get('DEIS_DEBUG') in ('true', '1')
registryLocation = os.getenv('DEIS_REGISTRY_LOCATION', 'on-cluster')
def log_output(stream, decode):
error = False
for chunk in stream:
if isinstance(chunk, bytes):
# Convert to dict, since docker-py returns some errors as raw bytes.
chunk = eval(chunk)
if 'error' in chunk:
error = True
print(chunk['error'])
elif decode:
stream_chunk = chunk.get('stream')
if stream_chunk:
# Must handle chunks as bytes to avoid UnicodeEncodeError.
encoded_chunk = stream_chunk.encode('utf-8')
sys.stdout.buffer.write(encoded_chunk)
elif DEBUG:
print(chunk)
sys.stdout.flush()
if error:
# HACK: delay so stderr is logged before this dockerbuilder pod exits.
time.sleep(3)
exit(1)
def log(msg):
if DEBUG:
print(msg)
def get_registry_name():
hostname = os.getenv('DEIS_REGISTRY_HOSTNAME', "")
hostname = hostname.replace("https://", "").replace("http://", "")
if registryLocation == "off-cluster":
organization = os.getenv('DEIS_REGISTRY_ORGANIZATION')
regName = ""
# empty hostname means dockerhub and hence no need to prefix the image
if hostname != "":
regName = hostname + "/"
# Registries may have organizations/namespaces under them which needs to
# be prefixed to the image
if organization != "":
regName = regName + organization
return regName
elif registryLocation == "ecr":
return hostname
elif registryLocation == "gcr":
return hostname + "/" + os.getenv('DEIS_REGISTRY_GCS_PROJ_ID')
else:
return "{}:{}".format(os.getenv("DEIS_REGISTRY_SERVICE_HOST"),
os.getenv("DEIS_REGISTRY_SERVICE_PORT"))
def download_file(tar_path):
os.putenv('BUCKET_FILE', "/var/run/secrets/deis/objectstore/creds/builder-bucket")
if os.getenv('BUILDER_STORAGE') == "minio":
os.makedirs("/tmp/objectstore/minio")
bucketFile = open('/tmp/objectstore/minio/builder-bucket', 'w')
bucketFile.write('git')
bucketFile.close()
os.putenv('BUCKET_FILE', "/tmp/objectstore/minio/builder-bucket")
elif os.getenv('BUILDER_STORAGE') in ["azure", "swift"]:
os.putenv('CONTAINER_FILE', "/var/run/secrets/deis/objectstore/creds/builder-container")
command = [
"objstorage",
"--storage-type="+os.getenv('BUILDER_STORAGE'),
"download",
tar_path,
"apptar"
]
subprocess.check_call(command)
tar_path = os.getenv('TAR_PATH')
if tar_path:
if os.path.exists("/var/run/secrets/deis/objectstore/creds/"):
download_file(tar_path)
else:
r = requests.get(tar_path)
with open("apptar", "wb") as app:
app.write(r.content)
log("download tar file complete")
with tarfile.open("apptar", "r:gz") as tar:
tar.extractall("/app/")
log("extracting tar file complete")
buildargs = json.loads(os.getenv('DOCKER_BUILD_ARGS', '{}'))
# inject docker build args into the Dockerfile so we get around Dockerfiles that don't have things
# like PORT defined.
with open("/app/Dockerfile", "a") as dockerfile:
# ensure we are on a new line
dockerfile.write("\n")
for envvar in buildargs:
dockerfile.write("ARG {}\n".format(envvar))
client = docker.Client(version='auto')
if registryLocation != "on-cluster":
registry = os.getenv('DEIS_REGISTRY_HOSTNAME', 'https://index.docker.io/v1/')
username = os.getenv('DEIS_REGISTRY_USERNAME')
password = os.getenv('DEIS_REGISTRY_PASSWORD')
client.login(username=username, password=password, registry=registry)
registry = get_registry_name()
imageName, imageTag = os.getenv('IMG_NAME').split(":", 1)
repo = registry + "/" + os.getenv('IMG_NAME')
stream = client.build(
tag=repo,
stream=True,
decode=True,
rm=True,
pull=True,
path='/app',
buildargs=buildargs)
log_output(stream, True)
print("Pushing to registry")
stream = client.push(registry+'/'+imageName, tag=imageTag, stream=True)
log_output(stream, False)