Skip to content

Commit

Permalink
Add regctl promotion to accelerate image promotion (#102)
Browse files Browse the repository at this point in the history
Signed-off-by: Matthew DeVenny <[email protected]>
  • Loading branch information
matthewdevenny authored Sep 26, 2024
1 parent bf939fd commit 1f87229
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 37 deletions.
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()
}
}

0 comments on commit 1f87229

Please sign in to comment.