Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save git commit of builds in started.json in addition to version #988

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 31 additions & 17 deletions jenkins/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,14 @@ def checkout(repo, branch, pull):
call([git, 'checkout', 'FETCH_HEAD'])


def start(gsutil, paths, stamp, node_name, version):
def start(gsutil, paths, stamp, node_name, version, git_commit):
"""Construct and upload started.json."""
data = {
'timestamp': stamp,
'jenkins-node': node_name,
'node': node_name,
'version': version,
'git-commit': git_commit,
}
gsutil.upload_json(paths.started, data)

Expand Down Expand Up @@ -333,29 +334,42 @@ def node():


def find_version():
"""Determine and return the version of the build."""
version_file = 'version'
if os.path.isfile(version_file):
# e2e tests which download kubernetes use this path:
with open(version_file) as fp:
return fp.read().strip()

version_script = 'hack/lib/version.sh'
if os.path.isfile(version_script):
cmd = [
'bash', '-c', (
"""Determine and return the version and git commit of the build."""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we just going to ignore this file now? what was making it before?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's written when the tarball is created - https://github.com/kubernetes/kubernetes/blob/master/build-tools/lib/release.sh#L428.

it should be the same as the GitVersion in kubectl version - but since we're parsing that already, it didn't seem like reading another file was necessary anymore.

try:
# First try using kubectl
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is going to work for a dockerized test.

Copy link
Member Author

@ixdy ixdy Nov 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, now that I think about this, I think neither the previous version of this nor this kubectl version work correctly for CI, since we haven't extracted the kubernetes tarball by this point.

for loc in ('client/bin', 'platforms/linux/amd64'):
kubectl_bin = os.path.join(loc, 'kubectl')
if os.path.isfile(kubectl_bin):
kubectl_version_output = call([kubectl_bin, 'version', '--client'], output=True)
m = re.match(
'Client Version: version.Info\{.*GitVersion:"(?P<version>[^"]+)".*GitCommit:"(?P<commit>[^"]+)".*\}',
kubectl_version_output)
if m:
return m.group('version'), m.group('commit')

# If we can't find kubectl, try using the version.sh script
version_script = 'hack/lib/version.sh'
if os.path.isfile(version_script):
cmd = [
'bash', '-c', (
"""
set -o errexit
set -o nounset
export KUBE_ROOT=.
source %s
kube::version::get_version_vars
echo $KUBE_GIT_VERSION
echo $KUBE_GIT_COMMIT
""" % version_script)
]
return call(cmd, output=True).strip()
]
version_lines = call(cmd, output=True).splitlines()
if len(version_lines) == 2:
return version_lines[0], version_lines[1]

except subprocess.CalledProcessError:
pass

return 'unknown'
return 'unknown', 'unknown'


class Paths(object): # pylint: disable=too-many-instance-attributes,too-few-public-methods
Expand Down Expand Up @@ -579,7 +593,7 @@ def bootstrap(job, repo, branch, pull, root):
os.chdir(root)
checkout(repo, branch, pull)
logging.info('Configure environment...')
version = find_version()
version, git_commit = find_version()
setup_magic_environment(job)
setup_credentials()
if pull:
Expand All @@ -588,7 +602,7 @@ def bootstrap(job, repo, branch, pull, root):
paths = ci_paths(job, build)
gsutil = GSUtil()
logging.info('Start %s at %s...', build, version)
start(gsutil, paths, started, node(), version)
start(gsutil, paths, started, node(), version, git_commit)
success = False
try:
cmd = [job_script(job)]
Expand Down
58 changes: 58 additions & 0 deletions jenkins/bootstrap_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,64 @@ def testAllJobsHaveErrExit(self):
'%s not found in %s' % (expected, job_path))


def FailCall(cmd, **kw):
"""Simulate a subprocess exiting nonzero:"""
raise subprocess.CalledProcessError(1, cmd, None)


class FindVersionTest(unittest.TestCase):

test_cases = [
('v1.4.1', '33cf7b9acbb2cb7c9c72a10d6636321fb180b159'),
('v1.5.0-alpha.2.484+04a74570323eae', '04a74570323eae3fc843ca7a6c34c28ada2847a9'),
]

def testVersionFromKubectl(self):
for p in ('client/bin', 'platforms/linux/amd64'):
kubectl = os.path.join(p, 'kubectl')
with Stub(os.path, 'isfile', lambda f: f == kubectl):
with Stub(bootstrap, 'call', lambda *a, **kw: kubectl_output):
for test_case in self.test_cases:
# More correct would be to update Major and Minor, but that takes
# effort.
kubectl_output = (
'Client Version: version.Info{Major:"1", Minor:"4", '
'GitVersion:"%s", GitCommit:"%s", '
'GitTreeState:"clean", BuildDate:"2016-10-10T18:19:49Z", '
'GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"}\n'
% test_case)
self.assertEqual(bootstrap.find_version(), test_case)

def testKubectlFailures(self):
with Stub(os.path, 'isfile', lambda f: f == 'platforms/linux/amd64/kubectl'):
with Stub(bootstrap, 'call', lambda *a, **kw: 'something bad'):
self.assertEqual(('unknown', 'unknown'), bootstrap.find_version())

with Stub(bootstrap, 'call', FailCall):
self.assertEqual(('unknown', 'unknown'), bootstrap.find_version())

def testVersionFromHackScript(self):
for test_case in self.test_cases:
script_output = '%s\n%s\n' % test_case
with Stub(os.path, 'isfile', lambda f: f == 'hack/lib/version.sh'):
with Stub(bootstrap, 'call', lambda *a, **kw: script_output):
self.assertEqual(bootstrap.find_version(), test_case)

def testHackScriptFailures(self):
with Stub(os.path, 'isfile', lambda f: f == 'hack/lib/version.sh'):
with Stub(bootstrap, 'call', lambda *a, **kw: ''):
self.assertEqual(('unknown', 'unknown'), bootstrap.find_version())

with Stub(bootstrap, 'call', lambda *a, **kw: 'one\ntwo\nthree\n'):
self.assertEqual(('unknown', 'unknown'), bootstrap.find_version())

with Stub(bootstrap, 'call', FailCall):
self.assertEqual(('unknown', 'unknown'), bootstrap.find_version())

def testNoKubectlOrHackScript(self):
with Stub(os.path, 'isfile', lambda *a, **kw: False):
self.assertEqual(('unknown', 'unknown'), bootstrap.find_version())


if __name__ == '__main__':
unittest.main()