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

Add regctl promotion to accelerate image promotion #102

Merged
merged 3 commits into from
Sep 26, 2024
Merged
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
102 changes: 74 additions & 28 deletions src/com/boxboat/jenkins/pipeline/promote/BoxPromote.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class BoxPromote extends BoxBase<PromoteConfig> implements Serializable {
public String overrideEvent
public String promoteToVersion
public String registryKey
public boolean useRegctlPromote = false

protected String imageSummary
protected SemVer baseSemVer
Expand Down Expand Up @@ -235,46 +236,91 @@ class BoxPromote extends BoxBase<PromoteConfig> implements Serializable {
refTag = "latest"
}

config.images.each { image ->
promoteFromRegistry.withCredentials {
image.pull()
}
String result = Config.pipeline.sh(returnStdout: true, script: """regctl version || echo 'No regctl - using docker' """)?.trim()
System.println(result)
if (result.contains("No regctl - using docker") || !this.useRegctlPromote) {
config.images.each { image ->
promoteFromRegistry.withCredentials {
image.pull()
}

imageSummary += "\n${image.path} promoted"
imageSummary += "\n\tfrom ${formatImageSummary(image, promotion.event, promoteFromRegistry)}"
imageSummary += "\n${image.path} promoted"
imageSummary += "\n\tfrom ${formatImageSummary(image, promotion.event, promoteFromRegistry)}"

pushRegistries.each { pushRegistry ->
def newImageSemVer = image.copy()
newImageSemVer.host = pushRegistry.host
newImageSemVer.namespace = pushRegistry.namespace
newImageSemVer.tag = promoteVersionString
pushRegistries.each { pushRegistry ->
def newImageSemVer = image.copy()
newImageSemVer.host = pushRegistry.host
newImageSemVer.namespace = pushRegistry.namespace
newImageSemVer.tag = promoteVersionString

def newImageRef
def newImageRef

// Don't push a reftag if we are not writing back
if (writebackBuildVersions) {
newImageRef = image.copy()
newImageRef.tag = refTag
image.reTag(newImageRef)
}
// Don't push a reftag if we are not writing back
if (writebackBuildVersions) {
newImageRef = image.copy()
newImageRef.tag = refTag
image.reTag(newImageRef)
}

image.reTag(newImageSemVer)
image.reTag(newImageSemVer)

pushRegistry.withCredentials {
newImageSemVer.push()
if (newImageRef) {
newImageRef.push()
}
}

imageSummary += "\n\tto ${formatImageSummary(newImageSemVer, promotion.promoteToEvent, pushRegistry)}"

pushRegistry.withCredentials {
newImageSemVer.push()
if (newImageRef) {
newImageRef.push()
imageSummary += "\n\t ${formatImageSummary(newImageRef, promotion.promoteToEvent, pushRegistry)}"
}
}
if (writebackBuildVersions) {
buildVersions.setEventImageVersion(pushEvent, image, promoteVersionString, metadata)
}
}
} else {
config.images.each { image ->
imageSummary += "\n${image.path} promoted"
imageSummary += "\n\tfrom ${formatImageSummary(image, promotion.event, promoteFromRegistry)}"

pushRegistries.each { pushRegistry ->
def newImageSemVer = image.copy()
newImageSemVer.host = pushRegistry.host
newImageSemVer.namespace = pushRegistry.namespace
newImageSemVer.tag = promoteVersionString

def newImageRef

// Don't push a reftag if we are not writing back
if (writebackBuildVersions) {
newImageRef = image.copy()
newImageRef.tag = refTag

pushRegistry.withCredentials {
Config.pipeline.sh """
regctl image copy ${image.getUrl()} ${newImageRef.getUrl()}
"""
}
}

pushRegistry.withCredentials {
Config.pipeline.sh """
regctl image copy ${image.getUrl()} ${newImageSemVer.getUrl()}
"""
}

imageSummary += "\n\tto ${formatImageSummary(newImageSemVer, promotion.promoteToEvent, pushRegistry)}"
imageSummary += "\n\tto ${formatImageSummary(newImageSemVer, promotion.promoteToEvent, pushRegistry)}"

if (newImageRef) {
imageSummary += "\n\t ${formatImageSummary(newImageRef, promotion.promoteToEvent, pushRegistry)}"
if (newImageRef) {
imageSummary += "\n\t ${formatImageSummary(newImageRef, promotion.promoteToEvent, pushRegistry)}"
}
}
if (writebackBuildVersions) {
buildVersions.setEventImageVersion(pushEvent, image, promoteVersionString, metadata)
}
}
if (writebackBuildVersions) {
buildVersions.setEventImageVersion(pushEvent, image, promoteVersionString, metadata)
}
}
if (writebackBuildVersions) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@Library('jenkins-shared-library@master')
import com.boxboat.jenkins.pipeline.promote.*

import static org.junit.Assert.assertEquals

def execute() {

params.promotionKey = "stage"
def promote = new BoxPromote(
globalConfigPath: "com/boxboat/jenkins/config.example.yaml",
config: [
baseVersion: "0.1.0",
gitTagDisable: true,
images: [
"test/a",
"test/b",
],
],
useRegctlPromote: true,
)

node() {
promote.wrap {
stage('Promote'){
promote.promote()
assertEquals(true, promote.writebackBuildVersions)
}
}
}

}

return this
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,21 @@ package com.boxboat.jenkins.test.pipeline.deploy.kubernetes
import com.boxboat.jenkins.pipeline.deploy.kubernetes.KubePod
import org.junit.Test

import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertTrue

class KubePodTest {

@Test
void testKubeLogs() {
def kubeLogs = KubePod.pollScript(outFile: "out.log", namespace: "test-ns", container: "nginx", labels: "a=b,c=d")
assertEquals("""
${System.getProperty('java.io.tmpdir')}/sharedLibraryScripts/pod-logs.sh -o "out.log" -n "test-ns" -l "a=b,c=d" -c "nginx"
""".trim(), kubeLogs.trim())
def kubeLogs = KubePod.pollScript(outFile: "out.log", namespace: "test-ns", container: "nginx", labels: "a=b,c=d").trim()
assertTrue(kubeLogs.trim().endsWith("""/sharedLibraryScripts/pod-logs.sh -o "out.log" -n "test-ns" -l "a=b,c=d" -c "nginx" """.trim()))

}

@Test
void testKubeExec() {
def kubeExec = KubePod.execScript(namespace: "test-ns", labels: "a=b,c=d", container: "nginx", command: ["cat", "test.yaml"])
assertEquals("""
${System.getProperty('java.io.tmpdir')}/sharedLibraryScripts/pod-exec.sh -n "test-ns" -l "a=b,c=d" -c "nginx" "cat" "test.yaml"
""".trim(), kubeExec.trim())
def kubeExec = KubePod.execScript(namespace: "test-ns", labels: "a=b,c=d", container: "nginx", command: ["cat", "test.yaml"]).trim()
assertTrue(kubeExec.endsWith("""/sharedLibraryScripts/pod-exec.sh -n "test-ns" -l "a=b,c=d" -c "nginx" "cat" "test.yaml" """.trim()))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,11 @@ class PromoteTest extends PipelineBase {
script.execute()
printCallStack()
}

@Test
void promoteRegctlTest() throws Exception {
def script = loadScript("${this.scriptBase}promoteRegctl.jenkins")
script.execute()
printCallStack()
}
}