forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CI] Print ES docker images versions (elastic#186885)
## Summary When we're seeing errors in FTR or on the serverless verification pipeline, we have difficulty connecting back what version of ES-Serverless is behind the tag `:latest`. With a recent addition to the ES Serverless docker image, this info is now contained in labels of the image. This PR highlights this info in the verification pipeline, as well as the FTR output from `kbn-es`. - Serverless verification pipeline: https://buildkite.com/elastic/kibana-elasticsearch-serverless-verify-and-promote/builds/1454 - FTR: ![Screenshot 2024-06-25 at 17 30 48 (1)](https://github.com/elastic/kibana/assets/4738868/b6244f99-52e8-4fc6-ac22-e69e01254f1f)
- Loading branch information
Showing
6 changed files
with
265 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
.buildkite/scripts/steps/es_serverless/annotate_runtime_parameters.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#!/usr/bin/env bash | ||
|
||
set -euo pipefail | ||
|
||
KIBANA_GITHUB_URL="https://github.com/elastic/kibana" | ||
ES_SERVERLESS_GITHUB_URL="https://github.com/elastic/elasticsearch-serverless" | ||
|
||
if [[ -z "$ES_SERVERLESS_IMAGE" ]]; then | ||
echo "ES_SERVERLESS_IMAGE is not set" | ||
exit 1 | ||
elif [[ "$ES_SERVERLESS_IMAGE" != *"docker.elastic.co"* ]]; then | ||
echo "ES_SERVERLESS_IMAGE should be a docker.elastic.co image" | ||
exit 1 | ||
fi | ||
|
||
# Pull the target image | ||
if [[ $ES_SERVERLESS_IMAGE != *":git-"* ]]; then | ||
docker pull "$ES_SERVERLESS_IMAGE" | ||
ES_SERVERLESS_VERSION=$(docker inspect --format='{{json .Config.Labels}}' "$ES_SERVERLESS_IMAGE" | jq -r '.["org.opencontainers.image.revision"]' | cut -c1-12) | ||
|
||
IMAGE_WITHOUT_TAG=$(echo "$ES_SERVERLESS_IMAGE" | cut -d: -f1) | ||
ES_SERVERLESS_IMAGE_FULL="${IMAGE_WITHOUT_TAG}:git-${ES_SERVERLESS_VERSION}" | ||
else | ||
ES_SERVERLESS_IMAGE_FULL=$ES_SERVERLESS_IMAGE | ||
ES_SERVERLESS_VERSION=$(echo "$ES_SERVERLESS_IMAGE_FULL" | cut -d: -f2 | cut -d- -f2) | ||
fi | ||
|
||
buildkite-agent annotate --context kibana-commit --style info "Kibana version: $BUILDKITE_BRANCH / [$BUILDKITE_COMMIT]($KIBANA_GITHUB_URL/commit/$BUILDKITE_COMMIT)" | ||
buildkite-agent annotate --context es-serverless-commit --style info "ES Serverless version: [$ES_SERVERLESS_VERSION]($ES_SERVERLESS_GITHUB_URL/commit/$ES_SERVERLESS_VERSION)" | ||
|
||
cat << EOF | buildkite-agent annotate --context es-serverless-image --style info | ||
ES Serverless image: \`${ES_SERVERLESS_IMAGE_FULL}\` | ||
To run this locally: | ||
\`\`\` | ||
node scripts/es serverless --image $ES_SERVERLESS_IMAGE_FULL | ||
\`\`\` | ||
EOF |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import execa from 'execa'; | ||
import memoize from 'lodash/memoize'; | ||
|
||
export const extractImageInfo = memoize(async (image: string) => { | ||
try { | ||
const { stdout: labelsJson } = await execa( | ||
'docker', | ||
['inspect', '--format', '{{json .Config.Labels}}', image], | ||
{ | ||
encoding: 'utf8', | ||
} | ||
); | ||
return JSON.parse(labelsJson); | ||
} catch (e) { | ||
return {}; | ||
} | ||
}); | ||
|
||
export async function getImageVersion(image: string): Promise<string | null> { | ||
const imageLabels = await extractImageInfo(image); | ||
return imageLabels['org.opencontainers.image.revision'] || null; | ||
} | ||
|
||
export async function getCommitUrl(image: string): Promise<string | null> { | ||
const imageLabels = await extractImageInfo(image); | ||
const repoSource = imageLabels['org.opencontainers.image.source'] || null; | ||
const revision = imageLabels['org.opencontainers.image.revision'] || null; | ||
|
||
if (!repoSource || !revision) { | ||
return null; | ||
} else { | ||
return `${repoSource}/commit/${revision}`; | ||
} | ||
} | ||
|
||
export async function getServerlessImageTag(image: string): Promise<string | null> { | ||
const sha = await getImageVersion(image); | ||
if (!sha) { | ||
return null; | ||
} else { | ||
return `git-${sha.slice(0, 12)}`; | ||
} | ||
} |
87 changes: 87 additions & 0 deletions
87
packages/kbn-es/src/utils/extract_serverless_image_info.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import { | ||
extractImageInfo, | ||
getCommitUrl, | ||
getImageVersion, | ||
getServerlessImageTag, | ||
} from './extract_image_info'; | ||
|
||
jest.mock('execa'); | ||
const execa = jest.requireMock('execa'); | ||
|
||
describe('extractImageInfo', () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('calls docker, once, and only once for one image', async () => { | ||
const image = 'nevermind'; | ||
const image2 = 'nevermind2'; | ||
const labelsJson = '{"org.opencontainers.image.revision": "revision"}'; | ||
execa.mockResolvedValue({ stdout: labelsJson }); | ||
|
||
await extractImageInfo(image); | ||
await extractImageInfo(image); | ||
expect(execa).toHaveBeenCalledTimes(1); | ||
|
||
await extractImageInfo(image2); | ||
expect(execa).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
it('should return image labels as an object', () => { | ||
const image = 'nevermind123'; | ||
const obj = { 'org.opencontainers.image.revision': 'revision', extra: 123 }; | ||
const labelsJson = JSON.stringify(obj); | ||
execa.mockResolvedValue({ stdout: labelsJson }); | ||
|
||
const imageInfo = extractImageInfo(image); | ||
|
||
expect(imageInfo).resolves.toEqual(obj); | ||
}); | ||
}); | ||
|
||
describe('getImageVersion', () => { | ||
it("should return the image's revision", () => { | ||
const image = 'test-image'; | ||
const labels = { 'org.opencontainers.image.revision': 'deadbeef1234' }; | ||
execa.mockResolvedValue({ stdout: JSON.stringify(labels) }); | ||
|
||
const imageVersion = getImageVersion(image); | ||
|
||
expect(imageVersion).resolves.toBe('deadbeef1234'); | ||
}); | ||
}); | ||
|
||
describe('getCommitUrl', () => { | ||
it('should return the commit url', () => { | ||
const image = 'docker.elastic.co/elasticsearch/elasticsearch:7.15.0'; | ||
const labels = { | ||
'org.opencontainers.image.source': 'https://github.com/elastic/elasticsearch', | ||
'org.opencontainers.image.revision': 'deadbeef1234', | ||
}; | ||
execa.mockResolvedValue({ stdout: JSON.stringify(labels) }); | ||
|
||
expect(getCommitUrl(image)).resolves.toBe( | ||
'https://github.com/elastic/elasticsearch/commit/deadbeef1234' | ||
); | ||
}); | ||
}); | ||
|
||
describe('getServerlessImageTag', () => { | ||
it('should return the image tag', () => { | ||
const image = 'docker.elastic.co/elasticsearch-ci/elasticsearch-serverless:latest'; | ||
const labels = { 'org.opencontainers.image.revision': 'deadbeef12345678' }; | ||
execa.mockResolvedValue({ stdout: JSON.stringify(labels) }); | ||
|
||
const imageTag = getServerlessImageTag(image); | ||
|
||
expect(imageTag).resolves.toBe('git-deadbeef1234'); | ||
}); | ||
}); |