forked from kubernetes/test-infra
-
Notifications
You must be signed in to change notification settings - Fork 1
/
kubernetes_build.py
executable file
·162 lines (144 loc) · 5.67 KB
/
kubernetes_build.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/env python
# Copyright 2016 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Need to figure out why this only fails on travis
# pylint: disable=bad-continuation
"""Builds kubernetes with specified config"""
import argparse
import os
import re
import subprocess
import sys
def check(*cmd):
"""Log and run the command, raising on errors."""
print >>sys.stderr, 'Run:', cmd
subprocess.check_call(cmd)
def check_no_stdout(*cmd):
"""Log and run the command, suppress stdout & stderr, raising on errors."""
print >>sys.stderr, 'Run:', cmd
null = open(os.devnull, 'w')
subprocess.check_call(cmd, stdout=null, stderr=null)
def check_output(*cmd):
"""Log and run the command, raising on errors, return output"""
print >>sys.stderr, 'Run:', cmd
return subprocess.check_output(cmd)
def check_build_exists(gcs, suffix):
""" check if a k8s/federation build with same version
already exists in remote path
"""
if not os.path.exists('hack/print-workspace-status.sh'):
print >>sys.stderr, 'hack/print-workspace-status.sh not found, continue'
return False
version = ''
try:
match = re.search(
r'gitVersion ([^\n]+)',
check_output('hack/print-workspace-status.sh')
)
if match:
version = match.group(1)
except subprocess.CalledProcessError as exc:
# fallback with doing a real build
print >>sys.stderr, 'Failed to get k8s version, continue: %s' % exc
return False
if version:
if not gcs:
gcs = 'kubernetes-release-dev'
gcs = 'gs://' + gcs
mode = 'ci'
if suffix:
mode += suffix
gcs = os.path.join(gcs, mode, version)
try:
check_no_stdout('gsutil', 'ls', gcs)
return True
except subprocess.CalledProcessError as exc:
print >>sys.stderr, 'gcs path %s does not exist yet, continue' % gcs
return False
def main(args):
# pylint: disable=too-many-branches
"""Build and push kubernetes.
This is a python port of the kubernetes/hack/jenkins/build.sh script.
"""
if os.path.split(os.getcwd())[-1] != 'kubernetes' and \
os.path.split(os.getcwd())[-1] != 'federation':
print >>sys.stderr, (
'Scenario should only run from either kubernetes or federation directory!')
sys.exit(1)
# pre-check if target build exists in gcs bucket or not
# if so, don't make duplicated builds
if check_build_exists(args.release, args.suffix):
print >>sys.stderr, 'build already exists, exit'
sys.exit(0)
env = {
# Skip gcloud update checking; do we still need this?
'CLOUDSDK_COMPONENT_MANAGER_DISABLE_UPDATE_CHECK': 'true',
# Don't run any unit/integration tests when building
'KUBE_RELEASE_RUN_TESTS': 'n',
}
push_build_args = ['--nomock', '--verbose', '--ci']
if args.suffix:
push_build_args.append('--gcs-suffix=%s' % args.suffix)
if args.federation:
# TODO: do we need to set these?
env['PROJECT'] = args.federation
env['FEDERATION_PUSH_REPO_BASE'] = 'gcr.io/%s' % args.federation
push_build_args.append('--federation')
if args.release_kind:
push_build_args.append('--release-kind=%s' % args.release_kind)
if args.release:
push_build_args.append('--bucket=%s' % args.release)
if args.registry:
push_build_args.append('--docker-registry=%s' % args.registry)
if args.hyperkube:
env['KUBE_BUILD_HYPERKUBE'] = 'y'
if args.extra_publish_file:
push_build_args.append('--extra-publish-file=%s' % args.extra_publish_file)
if args.allow_dup:
push_build_args.append('--allow-dup')
for key, value in env.items():
os.environ[key] = value
check('make', 'clean')
if args.fast:
check('make', 'quick-release')
else:
check('make', 'release')
check(args.push_build_script, *push_build_args)
if __name__ == '__main__':
PARSER = argparse.ArgumentParser(
'Build and push.')
PARSER.add_argument('--fast', action='store_true', help='Build quickly')
PARSER.add_argument(
'--release', help='Upload binaries to the specified gs:// path')
PARSER.add_argument(
'--suffix', help='Append suffix to the upload path if set')
PARSER.add_argument(
'--federation',
help='Push federation images to the specified project')
PARSER.add_argument(
'--release-kind',
default='kubernetes',
help='The release kind to push to GCS. Supported values are kubernetes or federation')
PARSER.add_argument(
'--registry', help='Push images to the specified docker registry')
PARSER.add_argument(
'--hyperkube', action='store_true', help='Build hyperkube image')
PARSER.add_argument(
'--extra-publish-file', help='Additional version file uploads to')
PARSER.add_argument(
'--allow-dup', action='store_true', help='Allow overwriting if the build exists on gcs')
PARSER.add_argument(
'--push-build-script', default='../release/push-build.sh', help='location of push-build.sh')
ARGS = PARSER.parse_args()
main(ARGS)