Skip to content

Commit

Permalink
Fix operator image name and tag parsing
Browse files Browse the repository at this point in the history
Signed-off-by: Mykola Morhun <mmorhun@redhat.com>
  • Loading branch information
mmorhun committed Jun 1, 2021
1 parent 68b3356 commit c1076f2
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 10 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@
"modulePathIgnorePatterns": [
"<rootDir>/dist"
],
"testRegex": "/test/(api|tasks)/.*.test.ts",
"testRegex": "/test/(api|tasks|other)/.*.test.ts",
"testEnvironment": "node",
"moduleFileExtensions": [
"ts",
Expand Down
16 changes: 7 additions & 9 deletions src/tasks/installers/operator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { ChectlContext } from '../../api/context'
import { KubeHelper } from '../../api/kube'
import { VersionHelper } from '../../api/version'
import { CHE_CLUSTER_CRD, CHE_OPERATOR_SELECTOR, OPERATOR_DEPLOYMENT_NAME, OPERATOR_TEMPLATE_DIR } from '../../constants'
import { safeLoadFromYamlFile } from '../../util'
import { safeLoadFromYamlFile, getImageNameAndTag } from '../../util'
import { KubeTasks } from '../kube'

import { createEclipseCheCluster, createNamespaceTask, patchingEclipseCheCluster } from './common-tasks'
Expand Down Expand Up @@ -319,10 +319,9 @@ export class OperatorTasks {
title: 'Detecting existing version...',
task: async (ctx: any, task: any) => {
ctx.deployedCheOperatorImage = this.retrieveContainerImage(ctx.deployedCheOperatorYaml)
const deployedCheOperatorImageAndTag = ctx.deployedCheOperatorImage.split(':', 2)
ctx.deployedCheOperatorImageName = deployedCheOperatorImageAndTag[0]
ctx.deployedCheOperatorImageTag = deployedCheOperatorImageAndTag.length === 2 ? deployedCheOperatorImageAndTag[1] : 'latest'
ctx.deployedCheOperatorImage = ctx.deployedCheOperatorImageName + ':' + ctx.deployedCheOperatorImageTag
const [deployedImage, deployedTag] = getImageNameAndTag(ctx.deployedCheOperatorImage)
ctx.deployedCheOperatorImageName = deployedImage
ctx.deployedCheOperatorImageTag = deployedTag

if (flags['che-operator-image']) {
ctx.newCheOperatorImage = flags['che-operator-image']
Expand All @@ -331,10 +330,9 @@ export class OperatorTasks {
const newCheOperatorYaml = safeLoadFromYamlFile(path.join(flags.templates, OPERATOR_TEMPLATE_DIR, 'operator.yaml')) as V1Deployment
ctx.newCheOperatorImage = this.retrieveContainerImage(newCheOperatorYaml)
}
const newCheOperatorImageAndTag = ctx.newCheOperatorImage.split(':', 2)
ctx.newCheOperatorImageName = newCheOperatorImageAndTag[0]
ctx.newCheOperatorImageTag = newCheOperatorImageAndTag.length === 2 ? newCheOperatorImageAndTag[1] : 'latest'
ctx.newCheOperatorImage = ctx.newCheOperatorImageName + ':' + ctx.newCheOperatorImageTag
const [newImage, newTag] = getImageNameAndTag(ctx.newCheOperatorImage)
ctx.newCheOperatorImageName = newImage
ctx.newCheOperatorImageTag = newTag

task.title = `${task.title} ${ctx.deployedCheOperatorImageTag} -> ${ctx.newCheOperatorImageTag}`
}
Expand Down
38 changes: 38 additions & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,44 @@ export function base64Decode(arg: string): string {
return Buffer.from(arg, 'base64').toString('ascii')
}

/**
* Separates docker image repository and tag.
* @param image string with image and tag separated by a colon
* @returns image name (including registry and account) and image tag correspondingly
*/
export function getImageNameAndTag(image: string): [string, string] {
let deployedCheOperatorImageName: string
let deployedCheOperatorImageTag: string

if (image.includes('@')) {
// Image is referenced via a digest
const index = image.indexOf('@')
deployedCheOperatorImageName = image.substring(0, index)
deployedCheOperatorImageTag = image.substring(index + 1)
} else {
// Image is referenced via a tag
const lastColonIndex = image.lastIndexOf(':')
if (lastColonIndex === -1) {
// Image name without a tag
deployedCheOperatorImageName = image
deployedCheOperatorImageTag = 'latest'
} else {
let beforeLastColon = image.substring(0, lastColonIndex)
let afterLastColon = image.substring(lastColonIndex + 1)
if (afterLastColon.includes('/')) {
// The colon is for registry port and not for a tag
deployedCheOperatorImageName = image
deployedCheOperatorImageTag = 'latest'
} else {
// The colon separates image name from the tag
deployedCheOperatorImageName = beforeLastColon
deployedCheOperatorImageTag = afterLastColon
}
}
}
return [deployedCheOperatorImageName, deployedCheOperatorImageTag]
}

/**
* Returns the tag of the image.
*/
Expand Down
42 changes: 42 additions & 0 deletions test/other/util.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*********************************************************************
* Copyright (c) 2021 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

import { expect, fancy } from 'fancy-test'

import { getImageNameAndTag } from '../../src/util'

describe('Util tests', () => {
describe('Test getImageNameAndTag', () => {
// test data format: full image reference, image repository, tag
const data = [
['registry.io/account/image:tag', 'registry.io/account/image', 'tag'],
['registry.io/account/image', 'registry.io/account/image', 'latest'],
['account/image:4387', 'account/image', '4387'],
['docker-registry.default.svc:5000/namespace/operator-image:tag2.6', 'docker-registry.default.svc:5000/namespace/operator-image', 'tag2.6'],
['registry.io:5000/account/image', 'registry.io:5000/account/image', 'latest'],
['the-image@sha256:12b235c10daa7e4358fe26c4cff725dcf218e0100d680a9722c8ac76170c32ed', 'the-image', 'sha256:12b235c10daa7e4358fe26c4cff725dcf218e0100d680a9722c8ac76170c32ed'],
['registry.io/account/image@sha256:82b23dc10daf7e43a8fe26c4cffc25acf268e0110168009722f8ac76170c8ce2', 'registry.io/account/image', 'sha256:82b23dc10daf7e43a8fe26c4cffc25acf268e0110168009722f8ac76170c8ce2'],
['registry.io:1234/image@sha256:12b235c10daa7e4358fe26c4cff725dcf218e0100d680a9722c8ac76170c32ed', 'registry.io:1234/image', 'sha256:12b235c10daa7e4358fe26c4cff725dcf218e0100d680a9722c8ac76170c32ed'],
]
fancy.it('Should parse image repository and tag', () => {
for (const testCaseData of data) {
const image = testCaseData[0]
const expectedImageRepo = testCaseData[1]
const expectedImageTag = testCaseData[2]

const [imageRepo, imageTag] = getImageNameAndTag(image)

expect(imageRepo).to.equal(expectedImageRepo)
expect(imageTag).to.equal(expectedImageTag)
}
})
})

})

0 comments on commit c1076f2

Please sign in to comment.