From c92c1b2f9167f99286bd68a9199962c0c78ca4ce Mon Sep 17 00:00:00 2001 From: Anders Lantz Date: Wed, 19 Oct 2022 10:40:35 +0200 Subject: [PATCH 1/9] Major rework of networking, to support multi deployment setups HarborManagerContainer.groovy * Now also modifies the supplied docker compose file to move all containers to a custom network Container.groovy * Some renaming of variables and methods needed, because the groovy autogenerated methods led to confusion and inconsistency. --- pom.xml | 2 +- .../devstack/container/Container.groovy | 46 ++++--- .../impl/HarborManagerContainer.groovy | 118 ++++++++++++++---- .../devstack/deployment/Deployment.groovy | 21 +--- .../impl/BitbucketH2Deployment.groovy | 19 +-- .../deployment/impl/HarborDeployment.groovy | 30 ++++- .../impl/JenkinsAndHarborDeployment.groovy | 30 +++-- .../deployment/impl/JenkinsDeployment.groovy | 8 ++ .../impl/JsmAndBitbucketH2Deployment.groovy | 4 + .../deployment/impl/JsmH2Deployment.groovy | 7 +- .../com/eficode/devstack/DevStackSpec.groovy | 18 ++- .../devstack/container/ContainerTest.groovy | 8 +- .../impl/HarborDeploymentTest.groovy | 14 ++- .../JenkinsAndHarborDeploymentTest.groovy | 16 ++- 14 files changed, 242 insertions(+), 99 deletions(-) diff --git a/pom.xml b/pom.xml index 3b27c8a..83c5e82 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.eficode devstack - 2.0.0-SNAPSHOT-groovy-${groovy.major.version} + 2.0.1-SNAPSHOT-groovy-${groovy.major.version} jar DevStack - Parent pom diff --git a/src/main/groovy/com/eficode/devstack/container/Container.groovy b/src/main/groovy/com/eficode/devstack/container/Container.groovy index b15d25e..2bf90e1 100644 --- a/src/main/groovy/com/eficode/devstack/container/Container.groovy +++ b/src/main/groovy/com/eficode/devstack/container/Container.groovy @@ -46,15 +46,14 @@ trait Container { abstract String containerMainPort abstract String containerImage abstract String containerImageTag + ArrayList containerDefaultNetworks = ["bridge"] ArrayList customEnvVar = [] - //String containerNetworkName = "bridge" String defaultShell = "/bin/bash" String containerId ArrayList mounts = [] void prepareBindMount(String sourceAbs, String target, boolean readOnly = true) { - assert !isCreated(): "Bind mounts cant be prepared for already created container" Mount newMount = new Mount().tap { m -> m.source = sourceAbs @@ -89,7 +88,6 @@ trait Container { c.hostname = self.containerName c.env = self.customEnvVar - } return containerCreateRequest @@ -102,7 +100,7 @@ trait Container { * @param entrypoint ex: ["tail", "-f", "/dev/null"] * @return container id */ - String createContainer(ArrayList cmd, ArrayList entrypoint) { + String createContainer(ArrayList cmd = [], ArrayList entrypoint = []) { assert ping(): "Error connecting to docker engine" @@ -119,14 +117,14 @@ trait Container { EngineResponseContent response = dockerClient.createContainer(containerCreateRequest, self.containerName) assert response.content.warnings.isEmpty(): "Error when creating ${self.containerName} container:" + response.content.warnings.join(",") + ArrayList networks = containerDefaultNetworks.collect {createBridgeNetwork(it)} + assert setContainerNetworks(networks) : "Error setting container networks to:" + containerDefaultNetworks + containerId = response.content.id return containerId } - String createContainer() { - return createContainer([], []) - } boolean runOnFirstStartup() { return true @@ -248,10 +246,8 @@ trait Container { if (status == ContainerState.Status.Created) { return true //Created but not started - } else if (status == null) { - return true //Not even created } else { - return false + return status == null } } @@ -469,28 +465,39 @@ trait Container { * @param networkNameOrId * @return Network if found, null if not */ - Network getNetwork(String networkNameOrId) { + Network getDockerNetwork(String networkNameOrId) { Network network = networkClient.networks().content.find { it.name == networkNameOrId || it.id == networkNameOrId } return network } + /** + * Gets networks based on name or id, note there might be multiple networks with the same name + * @param networkNameOrIds + * @return Networks if found, null if not + */ + ArrayList getDockerNetworks(ArrayListnetworkNameOrIds) { + + ArrayList networks = networkClient.networks().content.findAll { it.name in networkNameOrIds || it.id in networkNameOrIds } + + return networks + } boolean networkIsValid(Network network) { - return getNetwork(network.id) != null + return getDockerNetwork(network.id) != null } /** * Get the networks that this container is connected too * @return */ - ArrayList getContainerNetworks() { + ArrayList getConnectedContainerNetworks() { Map rawResponse = inspectContainer().networkSettings.networks ArrayList networks = [] rawResponse.keySet().each { networkId -> - Network network = getNetwork(networkId) + Network network = getDockerNetwork(networkId) if (network != null) { networks.add(network) @@ -509,7 +516,7 @@ trait Container { ArrayList getContainerBridgeNetworks() { - return getContainerNetworks().findAll { it.driver == "bridge" } + return getConnectedContainerNetworks().findAll { it.driver == "bridge" } } @@ -533,7 +540,7 @@ trait Container { log.trace("\tVerifying container was added to network") - if (containerNetworks.find { it.id == network.id } != null) { + if (connectedContainerNetworks.find { it.id == network.id } != null) { log.info("\tContainer was successfully added to network") return true } @@ -550,7 +557,7 @@ trait Container { networkClient.disconnectNetwork(network.id, containerId) log.trace("\tVerifying container was disconnected from network") - if (!containerNetworks.find { it.id == network.id }) { + if (!connectedContainerNetworks.find { it.id == network.id }) { log.info("\tContainer was successfully disconnected from network") return true } @@ -569,8 +576,7 @@ trait Container { log.info("Setting container networks") log.info("\tBeginning by disconnecting any networks it should no longer be connected to") - ArrayList networks = containerNetworks - containerNetworks.each { connectedNetwork -> + connectedContainerNetworks.each { connectedNetwork -> if (newNetworks.id.find { newNetworkId -> newNetworkId != connectedNetwork.id }) { assert disconnectContainerFromNetwork(connectedNetwork): "Error disconnecting container (${containerName}) from network: ${connectedNetwork.name} (${connectedNetwork.id})" @@ -580,7 +586,7 @@ trait Container { } log.info("\tFinished disconnecting container from unwanted networks, now connecting to new networks") - ArrayList connectedNetworks = containerNetworks + ArrayList connectedNetworks = connectedContainerNetworks newNetworks.each { wantedNetwork -> if (connectedNetworks.id.find { wantedNetwork.id }) { diff --git a/src/main/groovy/com/eficode/devstack/container/impl/HarborManagerContainer.groovy b/src/main/groovy/com/eficode/devstack/container/impl/HarborManagerContainer.groovy index b040f3c..14c879a 100644 --- a/src/main/groovy/com/eficode/devstack/container/impl/HarborManagerContainer.groovy +++ b/src/main/groovy/com/eficode/devstack/container/impl/HarborManagerContainer.groovy @@ -6,6 +6,7 @@ import org.apache.groovy.json.internal.LazyMap import java.nio.file.Files import java.nio.file.Path +import java.util.Map.Entry class HarborManagerContainer extends DoodContainer { @@ -85,61 +86,134 @@ class HarborManagerContainer extends DoodContainer { cd harbor && \\ ls -la && \\ echo status: \$? - """, 100) + """, 200) assert cmdOutput.last() == "status: 0": "Error downloading and extracting harbor:" + cmdOutput.join("\n") log.info("\tFinished downloading and extracting Harbor") - /** - * Fetch template config file, update it and put it back in the manager container - */ + assert modifyInstallYml() : "Error updating Harbor install config file: harbor.yml" - Path tmpDir= Files.createTempDirectory("harbor-conf") + log.info("\tStarting installation") + cmdOutput = runBashCommandInContainer(installPath + "/harbor/install.sh ; echo status: \$?", 400 ) + assert cmdOutput.last().contains("status: 0"): "Error installing harbor:" + cmdOutput.join("\n") + + + assert modifyDockerCompose() : "Error modifying Harbors docker-compose file" + + cmdOutput = runBashCommandInContainer("cd " + installPath + "/harbor && docker-compose up -d && echo status: \$?", 80) + assert cmdOutput.last().contains("status: 0"): "Error applying the modified docker-compose file:" + cmdOutput.join("\n") + + return true + + } + + + /** + * Modifies the default docker-compose file so that all pods connect to the correct network (containerDefaultNetworks) + * @return + */ + boolean modifyDockerCompose() { + + + + + log.info("\tCustomizing Harbor docker compose") + Path tmpDir= Files.createTempDirectory("harbor-compose") String tmpDirPath = tmpDir.toFile().absolutePath - ArrayList files = copyFilesFromContainer("${installPath}/harbor/harbor.yml.tmpl", tmpDirPath + "/") - assert files.size() == 1 && files.first().name == "harbor.yml.tmpl" : "Error, could not find template config file" + ArrayList files = copyFilesFromContainer("${installPath}/harbor/docker-compose.yml", tmpDirPath + "/") + + assert files.size() == 1 && files.first().name == "docker-compose.yml" : "Error, could not find docker-compose.yml file" File yamlFile = files.first() + log.debug("\t\tRetried docker compose file from container:" + yamlFile.absolutePath) + + + LazyMap originalYml = new YamlSlurper().parse(yamlFile) as LazyMap + LazyMap modifiedYml = new YamlSlurper().parse(yamlFile) as LazyMap + + + + modifiedYml.services.each {Entry service -> + log.debug("\t"*3 + "Customising Docker Service:" + service.key) + + service.value.networks = containerDefaultNetworks + log.trace("\t"*4 + "Set networks to:" + service.value.networks) + log.trace("\t"*4 + "Used to be:" + originalYml.services.get(service.key).networks) + + } + + log.debug("\t"*3 + "Customising Docker Network") + modifiedYml.remove("networks") + + Map networks = [:] + containerDefaultNetworks.each {networkName -> + networks.put(networkName as String,["external": true, "name":networkName] as LazyMap ) + } + modifiedYml.put("networks", networks) + //modifiedYml.put("networks", ["default": [external: [name: networkName]]]) + + log.trace("\t"*4 + "Set networks to:" + modifiedYml.networks) + log.trace("\t"*4 + "Used to be:" + originalYml.networks) - LazyMap yaml = new YamlSlurper().parse(yamlFile) as LazyMap - LazyMap modifiedYaml = modifyHarborYml(yaml) YamlBuilder yamlBuilder = new YamlBuilder() - yamlBuilder(modifiedYaml) + yamlBuilder(modifiedYml) - File modifiedYamlFile = new File(tmpDirPath + "/harbor.yml") - modifiedYamlFile.createNewFile() - modifiedYamlFile.write(yamlBuilder.toString().replaceAll("\"", "")) - assert copyFileToContainer(modifiedYamlFile.absolutePath, installPath + "/harbor/") : "Error copying updated YAML file to container" + yamlFile.write(yamlBuilder.toString()) + + assert copyFileToContainer(yamlFile.absolutePath, installPath + "/harbor/") : "Error copying updated YAML file to container" tmpDir.deleteDir() log.info("\tFinished customizing installation configuration") - log.info("\tStarting installation") - cmdOutput = runBashCommandInContainer(installPath + "/harbor/install.sh ; echo status: \$?", 400 ) - assert cmdOutput.last().contains("status: 0"): "Error installing harbor:" + cmdOutput.join("\n") + return true + + } + /** + * Fetch template config file, update it and put it back in the manager container + */ + boolean modifyInstallYml() { - return true + Path tmpDir= Files.createTempDirectory("harbor-conf") + String tmpDirPath = tmpDir.toFile().absolutePath - } - LazyMap modifyHarborYml(LazyMap originalYml) { + ArrayList files = copyFilesFromContainer("${installPath}/harbor/harbor.yml.tmpl", tmpDirPath + "/") - LazyMap modifiedYml = originalYml + assert files.size() == 1 && files.first().name == "harbor.yml.tmpl" : "Error, could not find template config file" + File yamlFile = files.first() + + + LazyMap originalYml = new YamlSlurper().parse(yamlFile) as LazyMap + + LazyMap modifiedYml = originalYml modifiedYml.hostname = host modifiedYml.http.port = port modifiedYml.remove("https") modifiedYml.data_volume = dataPath - return modifiedYml + + YamlBuilder yamlBuilder = new YamlBuilder() + yamlBuilder(modifiedYml) + + File modifiedYamlFile = new File(tmpDirPath + "/harbor.yml") + modifiedYamlFile.createNewFile() + modifiedYamlFile.write(yamlBuilder.toString().replaceAll("\"", "")) + + assert copyFileToContainer(modifiedYamlFile.absolutePath, installPath + "/harbor/") : "Error copying updated YAML file to container" + tmpDir.deleteDir() + + log.info("\tFinished customizing installation configuration") + + return true } } diff --git a/src/main/groovy/com/eficode/devstack/deployment/Deployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/Deployment.groovy index ff331da..79f7122 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/Deployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/Deployment.groovy @@ -1,12 +1,14 @@ package com.eficode.devstack.deployment import com.eficode.devstack.container.Container +import de.gesellix.docker.remote.api.core.Frame +import de.gesellix.docker.remote.api.core.StreamCallback import org.slf4j.Logger import org.slf4j.LoggerFactory trait Deployment { - static Logger log = LoggerFactory.getLogger(this.class) + abstract Logger log // = LoggerFactory.getLogger(self.class) abstract ArrayList containers abstract String friendlyName String deploymentNetworkName = "bridge" @@ -14,23 +16,6 @@ trait Deployment { abstract boolean setupDeployment() - /* - void setupSecureDockerConnection(String host, String certPath) { - - log.info("Setting up secure connection to docker engine") - assert getContainers() != null && !getContainers().empty: "Deployment has no containers defined" - - - getContainers().each { - assert it.setupSecureRemoteConnection(host, certPath): "Error setting up secure connection to docker engine" - log.info("\tSecure connection setup for container:" + getFriendlyName()) - } - log.info("\tSuccessfully setup secure connections to docker engine") - } - - */ - - boolean startDeployment() { log.info("Starting deployment: " + this.friendlyName) diff --git a/src/main/groovy/com/eficode/devstack/deployment/impl/BitbucketH2Deployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/impl/BitbucketH2Deployment.groovy index e0667d6..f948d56 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/impl/BitbucketH2Deployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/impl/BitbucketH2Deployment.groovy @@ -4,9 +4,12 @@ import com.eficode.atlassian.bitbucketInstanceManager.BitbucketInstanceManagerRe import com.eficode.devstack.container.Container import com.eficode.devstack.container.impl.BitbucketContainer import com.eficode.devstack.deployment.Deployment +import org.slf4j.Logger +import org.slf4j.LoggerFactory -class BitbucketH2Deployment implements Deployment{ +class BitbucketH2Deployment implements Deployment { + Logger log = LoggerFactory.getLogger(this.class) String friendlyName = "Bitbucket H2 Deployment" BitbucketInstanceManagerRest bitbucketRest ArrayList containers = [] @@ -25,7 +28,7 @@ class BitbucketH2Deployment implements Deployment{ } BitbucketContainer getBitbucketContainer() { - return containers.find {it instanceof BitbucketContainer} as BitbucketContainer + return containers.find { it instanceof BitbucketContainer } as BitbucketContainer } String getBitbucketContainerId() { @@ -45,21 +48,21 @@ class BitbucketH2Deployment implements Deployment{ log.info("Setting up deployment:" + friendlyName) - assert bitbucketLicense : "Error no Bitbucket License has been setup" + assert bitbucketLicense: "Error no Bitbucket License has been setup" + + bitbucketContainer.containerDefaultNetworks = [this.deploymentNetworkName] bitbucketContainer.createContainer() + log.info("\tCreated Bitbucket container:" + bitbucketContainer.id) - log.info("\tConfiguring container to join network:" + this.deploymentNetworkName) - bitbucketContainer.connectContainerToNetwork(bitbucketContainer.getNetwork(this.deploymentNetworkName)) - assert bitbucketContainer.startContainer() : "Error starting Bitbucket container:" + bitbucketContainer.id + assert bitbucketContainer.startContainer(): "Error starting Bitbucket container:" + bitbucketContainer.id log.info("\tStarted Bitbucket container") - log.info("\tSetting up local H2 database, License, Name etc") - assert bitbucketRest.setApplicationProperties(bitbucketLicense, "Bitbucket", bitbucketBaseUrl) : "Error setting up H2 database for Bitbucket" + assert bitbucketRest.setApplicationProperties(bitbucketLicense, "Bitbucket", bitbucketBaseUrl): "Error setting up H2 database for Bitbucket" log.info("\t\tApplication basics setup successfully") diff --git a/src/main/groovy/com/eficode/devstack/deployment/impl/HarborDeployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/impl/HarborDeployment.groovy index 0c3006f..c4d9d7e 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/impl/HarborDeployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/impl/HarborDeployment.groovy @@ -1,15 +1,20 @@ package com.eficode.devstack.deployment.impl import com.eficode.devstack.container.Container -import com.eficode.devstack.container.impl.DoodContainer import com.eficode.devstack.container.impl.HarborManagerContainer import com.eficode.devstack.deployment.Deployment +import de.gesellix.docker.remote.api.ContainerState import de.gesellix.docker.remote.api.ContainerSummary +import de.gesellix.docker.remote.api.ContainerWaitExitError +import org.slf4j.Logger +import org.slf4j.LoggerFactory class HarborDeployment implements Deployment{ + Logger log = LoggerFactory.getLogger(this.class) String friendlyName = "Harbor Deployment" ArrayList containers = [] + String deploymentNetworkName = "harbor" HarborDeployment(String baseUrl, String harborVersion = "v2.6.0", String baseDir = "/opt/", String dockerHost = "", String dockerCertPath = "") { @@ -28,8 +33,24 @@ class HarborDeployment implements Deployment{ @Override boolean setupDeployment() { - managerContainer.createContainer([],["tail", "-f", "/dev/null"]) - managerContainer.startContainer() + + managerContainer.containerDefaultNetworks = [deploymentNetworkName] + assert managerContainer.createContainer([],["tail", "-f", "/dev/null"]) : "Error creating container" + assert managerContainer.startContainer() : "Error starting container" + + sleep(1000) + long start = System.currentTimeMillis() + while (harborContainers.state.find {it != ContainerState.Status.Running.value}) { + + log.info("\tWaiting for containers to start") + harborContainers.collectEntries {[it.names.first(), it.state]}.each {log.debug("\t\t" + it)} + + assert start + (2*60000) < System.currentTimeMillis() : "Timed out waiting for harbor containers to start" + sleep(1500) + } + + return true + } @Override @@ -40,6 +61,7 @@ class HarborDeployment implements Deployment{ ArrayList cmdOutput = managerContainer.runBashCommandInContainer("cd ${managerContainer.installPath}/harbor ; docker-compose start ; echo status: \$?", 120 ) assert cmdOutput.last() == "status: 0": "Error starting harbor:" + cmdOutput.join("\n") + return true } @@ -86,7 +108,7 @@ class HarborDeployment implements Deployment{ ArrayList containers = managerContainer.dockerClient.ps().content - containers = containers.findAll { it.image.startsWith("goharbor") || it.names.first() == managerContainer.containerName} + containers = containers.findAll { it.image.startsWith("goharbor") || it.names.first() == "/" + managerContainer.containerName} return containers diff --git a/src/main/groovy/com/eficode/devstack/deployment/impl/JenkinsAndHarborDeployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/impl/JenkinsAndHarborDeployment.groovy index 0776550..a658e36 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/impl/JenkinsAndHarborDeployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/impl/JenkinsAndHarborDeployment.groovy @@ -4,6 +4,8 @@ import com.eficode.devstack.container.Container import com.eficode.devstack.container.impl.HarborManagerContainer import com.eficode.devstack.container.impl.JenkinsContainer import com.eficode.devstack.deployment.Deployment +import org.slf4j.Logger +import org.slf4j.LoggerFactory import java.util.concurrent.Callable import java.util.concurrent.ExecutorService @@ -12,33 +14,22 @@ import java.util.concurrent.Future class JenkinsAndHarborDeployment implements Deployment { + Logger log = LoggerFactory.getLogger(this.class) String friendlyName = "Jenkins and Harbor Deployment" String deploymentNetworkName = "jenkins_and_harbor" ArrayList subDeployments = [] JenkinsAndHarborDeployment(String jenkinsBaseUrl, String harborBaseUrl, String dockerHost = "", String dockerCertPath = "") { + subDeployments = [ new JenkinsDeployment(jenkinsBaseUrl, dockerHost, dockerCertPath), new HarborDeployment(harborBaseUrl, "v2.6.1", "/tmp/", dockerHost, dockerCertPath) ] - } - private class SetupDeploymentTask implements Callable { - - Deployment deployment - - SetupDeploymentTask(Deployment deployment) { - this.deployment = deployment - } - @Override - Boolean call() throws Exception { - this.deployment.setupDeployment() - } - } JenkinsDeployment getJenkinsDeployment() { return subDeployments.find { it instanceof JenkinsDeployment } as JenkinsDeployment @@ -64,6 +55,19 @@ class JenkinsAndHarborDeployment implements Deployment { this.containers = containers } + private class SetupDeploymentTask implements Callable { + + Deployment deployment + + SetupDeploymentTask(Deployment deployment) { + this.deployment = deployment + } + + @Override + Boolean call() throws Exception { + this.deployment.setupDeployment() + } + } boolean setupDeployment() { diff --git a/src/main/groovy/com/eficode/devstack/deployment/impl/JenkinsDeployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/impl/JenkinsDeployment.groovy index 7af0717..b339085 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/impl/JenkinsDeployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/impl/JenkinsDeployment.groovy @@ -5,11 +5,14 @@ import com.eficode.devstack.container.impl.JenkinsContainer import com.eficode.devstack.deployment.Deployment import kong.unirest.Unirest import kong.unirest.UnirestInstance +import org.slf4j.Logger +import org.slf4j.LoggerFactory import java.util.concurrent.TimeoutException class JenkinsDeployment implements Deployment{ + Logger log = LoggerFactory.getLogger(this.class) String friendlyName = "Jenkins Deployment" ArrayList containers = [] String baseUrl @@ -21,6 +24,8 @@ class JenkinsDeployment implements Deployment{ jenkinsContainer.containerName = JenkinsContainer.extractDomainFromUrl(jenkinsBaseUrl) jenkinsContainer.containerMainPort = JenkinsContainer.extractPortFromUrl(jenkinsBaseUrl) + + } JenkinsContainer getJenkinsContainer() { @@ -30,7 +35,10 @@ class JenkinsDeployment implements Deployment{ @Override boolean setupDeployment() { + + jenkinsContainer.containerDefaultNetworks = [this.deploymentNetworkName] jenkinsContainer.createContainer() + boolean containerSetupSuccess = jenkinsContainer.startContainer() assert containerSetupSuccess : "Error starting Jenkins container" log.info("\tJenkins container has started") diff --git a/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy index 9b5fdc2..116545f 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy @@ -6,6 +6,8 @@ import com.eficode.devstack.container.Container import com.eficode.devstack.container.impl.BitbucketContainer import com.eficode.devstack.container.impl.JsmContainer import com.eficode.devstack.deployment.Deployment +import org.slf4j.Logger +import org.slf4j.LoggerFactory import java.util.concurrent.Callable import java.util.concurrent.ExecutorService @@ -14,9 +16,11 @@ import java.util.concurrent.Future class JsmAndBitbucketH2Deployment implements Deployment { + String friendlyName = "JIRA and Bitbucket H2 Deployment" String containerNetworkName = "jsm_and_bitbucket" ArrayList subDeployments = [] + Logger log = LoggerFactory.getLogger(this.class) Map jiraAppsToInstall = [:] String jiraLicense diff --git a/src/main/groovy/com/eficode/devstack/deployment/impl/JsmH2Deployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/impl/JsmH2Deployment.groovy index 4af0f85..6aa0871 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/impl/JsmH2Deployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/impl/JsmH2Deployment.groovy @@ -4,10 +4,13 @@ import com.eficode.atlassian.jiraInstanceManager.JiraInstanceManagerRest import com.eficode.devstack.container.Container import com.eficode.devstack.container.impl.JsmContainer import com.eficode.devstack.deployment.Deployment +import org.slf4j.Logger +import org.slf4j.LoggerFactory class JsmH2Deployment implements Deployment{ String friendlyName = "JIRA H2 Deployment" + Logger log = LoggerFactory.getLogger(this.class) JiraInstanceManagerRest jiraRest ArrayList containers = [] Map appsToInstall = [:] @@ -76,12 +79,10 @@ class JsmH2Deployment implements Deployment{ assert jiraLicense : "Error no Jira License has been setup" + jsmContainer.containerDefaultNetworks = [deploymentNetworkName] jsmContainer.createContainer() log.info("\tCreated jsm container:" + jsmContainer.id) - log.info("\tConfiguring container to join network:" + this.deploymentNetworkName) - jsmContainer.connectContainerToNetwork(jsmContainer.getNetwork(this.deploymentNetworkName)) - assert jsmContainer.startContainer() : "Error starting JSM container:" + jsmContainer.id log.info("\tStarted JSM container") diff --git a/src/test/groovy/com/eficode/devstack/DevStackSpec.groovy b/src/test/groovy/com/eficode/devstack/DevStackSpec.groovy index 400cc6e..392d9ce 100644 --- a/src/test/groovy/com/eficode/devstack/DevStackSpec.groovy +++ b/src/test/groovy/com/eficode/devstack/DevStackSpec.groovy @@ -1,12 +1,13 @@ package com.eficode.devstack - +import com.eficode.devstack.container.impl.AlpineContainer import de.gesellix.docker.client.DockerClientImpl import de.gesellix.docker.engine.DockerClientConfig import de.gesellix.docker.engine.DockerEnv import de.gesellix.docker.remote.api.ContainerInspectResponse import de.gesellix.docker.remote.api.ContainerState import de.gesellix.docker.remote.api.ContainerSummary +import de.gesellix.docker.remote.api.Network import org.apache.commons.io.FileUtils import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -28,6 +29,9 @@ class DevStackSpec extends Specification { @Shared ArrayList cleanupContainerPorts + @Shared + ArrayList cleanupDockerNetworkNames = [] + @Shared boolean disableCleanup = false @@ -42,6 +46,7 @@ class DevStackSpec extends Specification { dockerClient = resolveDockerClient() if (!disableCleanup) { cleanupContainers() + cleanupNetworks() } } @@ -50,11 +55,22 @@ class DevStackSpec extends Specification { def cleanup() { if (!disableCleanup) { cleanupContainers() + cleanupNetworks() } } + boolean cleanupNetworks() { + + AlpineContainer alp = new AlpineContainer(dockerRemoteHost, dockerCertPath) + cleanupDockerNetworkNames.each {networkName -> + Network network = alp.getDockerNetwork(networkName) + log.info("\tRemoving network ${network.name} " + network?.id[0..7]) + assert alp.removeNetwork(network) : "Error removing network:" + network.toString() + } + + } boolean cleanupContainers() { diff --git a/src/test/groovy/com/eficode/devstack/container/ContainerTest.groovy b/src/test/groovy/com/eficode/devstack/container/ContainerTest.groovy index d3ee3ad..28c3807 100644 --- a/src/test/groovy/com/eficode/devstack/container/ContainerTest.groovy +++ b/src/test/groovy/com/eficode/devstack/container/ContainerTest.groovy @@ -93,8 +93,8 @@ class ContainerTest extends DevStackSpec { alpine1.removeNetwork(removedNetwork) - alpine1.getNetwork(removedNetwork.id) == null - alpine1.getNetwork(removedNetwork.name) == null + alpine1.getDockerNetwork(removedNetwork.id) == null + alpine1.getDockerNetwork(removedNetwork.name) == null log.info("\tRemoval of networks was tested successfully") @@ -135,8 +135,8 @@ class ContainerTest extends DevStackSpec { then: "They should both be able to ping each other using containerName and ip" - alpine1.getContainerNetworks() == [spockNetwork] - alpine2.getContainerNetworks() == [spockNetwork] + alpine1.getConnectedContainerNetworks() == [spockNetwork] + alpine2.getConnectedContainerNetworks() == [spockNetwork] alpine1.runBashCommandInContainer("ping -c 1 " + alpine2.containerName).any { it.contains("0% packet loss") } alpine2.runBashCommandInContainer("ping -c 1 " + alpine1.containerName).any { it.contains("0% packet loss") } alpine1.runBashCommandInContainer("ping -c 1 " + alpine2.ips.first()).any { it.contains("0% packet loss") } diff --git a/src/test/groovy/com/eficode/devstack/deployment/impl/HarborDeploymentTest.groovy b/src/test/groovy/com/eficode/devstack/deployment/impl/HarborDeploymentTest.groovy index 3ccf195..1ffdadc 100644 --- a/src/test/groovy/com/eficode/devstack/deployment/impl/HarborDeploymentTest.groovy +++ b/src/test/groovy/com/eficode/devstack/deployment/impl/HarborDeploymentTest.groovy @@ -49,16 +49,24 @@ class HarborDeploymentTest extends DevStackSpec { hd.setupDeployment() + //hd.managerContainer.runAfterDockerSetup() + then: Unirest.get(harborBaseUrl).basicAuth("admin", "Harbor12345").asEmpty().status == 200 - hd.getContainers().every { it.status() == ContainerState.Status.Running } + hd.harborContainers.id.contains(hd.managerContainer.inspectContainer().id) //Make sure harborContainers returns manager container as well + hd.harborContainers.every { it.state in [ContainerState.Status.Running.value, ContainerState.Status.Restarting.value] } + hd.harborContainers.every {it.networkSettings.networks.keySet().toList() == [hd.deploymentNetworkName]} + hd.harborContainers.collect {it.names.first()}.every {containerName -> + String hostname = containerName[1..-1] + hd.managerContainer.runBashCommandInContainer("ping ${hostname} -c 1 && echo Status: \$?", 5).last().contains("Status: 0") + } when: "Stopping the deployment" hd.stopDeployment() then: "All containers should remain but have status Exited" - hd.getContainers().every { it.status() == ContainerState.Status.Exited } + hd.harborContainers.every { it.state == ContainerState.Status.Exited.value } when: "Staring the deployment" ArrayList containerIdsBeforeStart = hd.getHarborContainers().id @@ -79,7 +87,7 @@ class HarborDeploymentTest extends DevStackSpec { where: dockerHost | certPath | harborBaseUrl | harborVersion | harborBaseDir "" | "" | "http://localhost" | "v2.6.0" | "/tmp" - dockerRemoteHost | dockerCertPath | "http://harbor.domain.se" | "v2.6.0" | "/tmp" + //dockerRemoteHost | dockerCertPath | "http://harbor.domain.se" | "v2.6.0" | "/tmp" } } diff --git a/src/test/groovy/com/eficode/devstack/deployment/impl/JenkinsAndHarborDeploymentTest.groovy b/src/test/groovy/com/eficode/devstack/deployment/impl/JenkinsAndHarborDeploymentTest.groovy index ce1c9eb..556b804 100644 --- a/src/test/groovy/com/eficode/devstack/deployment/impl/JenkinsAndHarborDeploymentTest.groovy +++ b/src/test/groovy/com/eficode/devstack/deployment/impl/JenkinsAndHarborDeploymentTest.groovy @@ -1,9 +1,9 @@ -package com.eficode.devstack.deployment.impl; +package com.eficode.devstack.deployment.impl import com.eficode.devstack.DevStackSpec import org.slf4j.LoggerFactory -public class JenkinsAndHarborDeploymentTest extends DevStackSpec { +class JenkinsAndHarborDeploymentTest extends DevStackSpec { def setupSpec() { @@ -37,11 +37,23 @@ public class JenkinsAndHarborDeploymentTest extends DevStackSpec { def "test setupDeployment"(String jenkinsBaseUrl, String harborBaseUrl, String dockerHost, String certPath) { setup: + String networkName = "custom-network-" + System.currentTimeMillis().toString()[-5..-1] + cleanupDockerNetworkNames.add(networkName) + + JenkinsAndHarborDeployment jh = new JenkinsAndHarborDeployment(jenkinsBaseUrl, harborBaseUrl, dockerHost, certPath) + jh.deploymentNetworkName = networkName expect: jh.setupDeployment() + when: "Collecting all networks used by harbor and jenkins containers" + ArrayList harborNetworks = jh.harborDeployment.harborContainers.networkSettings.networks.collect {it.keySet()}.flatten().unique() + ArrayList jenkinsNetworks = jh.jenkinsContainer.connectedContainerNetworks.name.unique() + + then: "They should all be in the same networks" + harborNetworks == jenkinsNetworks + where: jenkinsBaseUrl | harborBaseUrl | dockerHost | certPath "http://jenkins.domain.se:8080" | "http://harbor.domain.se" | dockerRemoteHost | dockerCertPath From 29a8dfa5664e6de0eddb7bc4565e304300f77a8e Mon Sep 17 00:00:00 2001 From: Anders Lantz Date: Wed, 19 Oct 2022 11:51:16 +0200 Subject: [PATCH 2/9] HarborManagerContainer.groovy * Bug in bash setup script Container.groovy * Bug in status() HarborDeployment.groovy * Improved stopAndRemoveDeployment() so it can stop deployment even if manager container is missing pom.xml * Fixed problems with shading --- pom.xml | 12 ++++ .../devstack/container/Container.groovy | 2 +- .../impl/HarborManagerContainer.groovy | 2 +- .../devstack/deployment/Deployment.groovy | 3 +- .../deployment/impl/HarborDeployment.groovy | 66 ++++++++++++++----- .../impl/JenkinsAndHarborDeployment.groovy | 10 ++- 6 files changed, 74 insertions(+), 21 deletions(-) diff --git a/pom.xml b/pom.xml index 83c5e82..02064cd 100644 --- a/pom.xml +++ b/pom.xml @@ -157,9 +157,21 @@ standalone + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + org.codehaus.groovy:groovy + org.codehaus.groovy:groovy-astbuilder com.google.code.gson:gson org.apache.httpcomponents commons-* diff --git a/src/main/groovy/com/eficode/devstack/container/Container.groovy b/src/main/groovy/com/eficode/devstack/container/Container.groovy index 2bf90e1..9a1b30f 100644 --- a/src/main/groovy/com/eficode/devstack/container/Container.groovy +++ b/src/main/groovy/com/eficode/devstack/container/Container.groovy @@ -266,7 +266,7 @@ trait Container { } ContainerState.Status status() { - return inspectContainer().state.status + return inspectContainer()?.state?.status } boolean stopAndRemoveContainer(Integer timeoutS = 5) { diff --git a/src/main/groovy/com/eficode/devstack/container/impl/HarborManagerContainer.groovy b/src/main/groovy/com/eficode/devstack/container/impl/HarborManagerContainer.groovy index 14c879a..8dcffd8 100644 --- a/src/main/groovy/com/eficode/devstack/container/impl/HarborManagerContainer.groovy +++ b/src/main/groovy/com/eficode/devstack/container/impl/HarborManagerContainer.groovy @@ -79,7 +79,7 @@ class HarborManagerContainer extends DoodContainer { cmdOutput = runBashCommandInContainer(""" - mkdir -p "${installPath}" && \\ + mkdir -p "${installPath}" && \\ cd "${installPath}" && \\ wget https://github.com/goharbor/harbor/releases/download/$harborVersion/harbor-online-installer-${harborVersion}.tgz && \\ tar xzvf harbor-online-installer-${harborVersion}.tgz && \\ diff --git a/src/main/groovy/com/eficode/devstack/deployment/Deployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/Deployment.groovy index 79f7122..ce30e14 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/Deployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/Deployment.groovy @@ -8,7 +8,8 @@ import org.slf4j.LoggerFactory trait Deployment { - abstract Logger log // = LoggerFactory.getLogger(self.class) + + Logger log = LoggerFactory.getLogger(this.class) abstract ArrayList containers abstract String friendlyName String deploymentNetworkName = "bridge" diff --git a/src/main/groovy/com/eficode/devstack/deployment/impl/HarborDeployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/impl/HarborDeployment.groovy index c4d9d7e..c26e973 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/impl/HarborDeployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/impl/HarborDeployment.groovy @@ -3,13 +3,14 @@ package com.eficode.devstack.deployment.impl import com.eficode.devstack.container.Container import com.eficode.devstack.container.impl.HarborManagerContainer import com.eficode.devstack.deployment.Deployment +import de.gesellix.docker.client.DockerClientImpl import de.gesellix.docker.remote.api.ContainerState import de.gesellix.docker.remote.api.ContainerSummary import de.gesellix.docker.remote.api.ContainerWaitExitError import org.slf4j.Logger import org.slf4j.LoggerFactory -class HarborDeployment implements Deployment{ +class HarborDeployment implements Deployment { Logger log = LoggerFactory.getLogger(this.class) String friendlyName = "Harbor Deployment" @@ -17,7 +18,7 @@ class HarborDeployment implements Deployment{ String deploymentNetworkName = "harbor" - HarborDeployment(String baseUrl, String harborVersion = "v2.6.0", String baseDir = "/opt/", String dockerHost = "", String dockerCertPath = "") { + HarborDeployment(String baseUrl, String harborVersion = "v2.6.0", String baseDir = "/opt/", String dockerHost = "", String dockerCertPath = "") { HarborManagerContainer managerContainer = new HarborManagerContainer(baseUrl, harborVersion, baseDir, dockerHost, dockerCertPath) @@ -27,7 +28,7 @@ class HarborDeployment implements Deployment{ } HarborManagerContainer getManagerContainer() { - this.containers.find {it instanceof HarborManagerContainer} as HarborManagerContainer + this.containers.find { it instanceof HarborManagerContainer } as HarborManagerContainer } @Override @@ -35,17 +36,17 @@ class HarborDeployment implements Deployment{ managerContainer.containerDefaultNetworks = [deploymentNetworkName] - assert managerContainer.createContainer([],["tail", "-f", "/dev/null"]) : "Error creating container" - assert managerContainer.startContainer() : "Error starting container" + assert managerContainer.createContainer([], ["tail", "-f", "/dev/null"]): "Error creating container" + assert managerContainer.startContainer(): "Error starting container" sleep(1000) long start = System.currentTimeMillis() - while (harborContainers.state.find {it != ContainerState.Status.Running.value}) { + while (harborContainers.state.find { it != ContainerState.Status.Running.value }) { log.info("\tWaiting for containers to start") - harborContainers.collectEntries {[it.names.first(), it.state]}.each {log.debug("\t\t" + it)} + harborContainers.collectEntries { [it.names.first(), it.state] }.each { log.debug("\t\t" + it) } - assert start + (2*60000) < System.currentTimeMillis() : "Timed out waiting for harbor containers to start" + assert start + (2 * 60000) < System.currentTimeMillis(): "Timed out waiting for harbor containers to start" sleep(1500) } @@ -58,7 +59,7 @@ class HarborDeployment implements Deployment{ assert managerContainer.startContainer() sleep(5000) - ArrayList cmdOutput = managerContainer.runBashCommandInContainer("cd ${managerContainer.installPath}/harbor ; docker-compose start ; echo status: \$?", 120 ) + ArrayList cmdOutput = managerContainer.runBashCommandInContainer("cd ${managerContainer.installPath}/harbor ; docker-compose start ; echo status: \$?", 120) assert cmdOutput.last() == "status: 0": "Error starting harbor:" + cmdOutput.join("\n") return true @@ -68,8 +69,9 @@ class HarborDeployment implements Deployment{ @Override boolean stopDeployment() { + assert managerContainer.startContainer() - ArrayList cmdOutput = managerContainer.runBashCommandInContainer("cd ${managerContainer.installPath}/harbor ; docker-compose stop ; echo status: \$?", 120 ) + ArrayList cmdOutput = managerContainer.runBashCommandInContainer("cd ${managerContainer.installPath}/harbor ; docker-compose stop ; echo status: \$?", 120) assert cmdOutput.last() == "status: 0": "Error stopping harbor:" + cmdOutput.join("\n") assert managerContainer.stopContainer() @@ -77,20 +79,49 @@ class HarborDeployment implements Deployment{ } @Override - boolean stopAndRemoveDeployment(){ + boolean stopAndRemoveDeployment() { + + log.info("Stopping and removing ${this.class}") + + if (!managerContainer.created) { + //Manager container does not exist + ArrayList harbContainers = harborContainers + if (harbContainers) { + //There are still harbor containers around + log.info("\tThe manager container does not exist, removing harbor containers manually") + + DockerClientImpl dockerClient = managerContainer.dockerClient + harbContainers.each { container -> + + log.debug("\t\tKilling and removing:" + container.names) + try { + dockerClient.kill(container.id) + } catch (ignored){} + + dockerClient.rm(container.id) + + } + + } + + return true + + + } + assert managerContainer.startContainer() - ArrayList cmdOutput = managerContainer.runBashCommandInContainer("cd ${managerContainer.installPath}/harbor ; docker-compose down ; echo status: \$?", 120 ) + ArrayList cmdOutput = managerContainer.runBashCommandInContainer("cd ${managerContainer.installPath}/harbor ; docker-compose down ; echo status: \$?", 120) assert cmdOutput.last() == "status: 0": "Error downing harbor:" + cmdOutput.join("\n") - cmdOutput = managerContainer.runBashCommandInContainer("cd ${managerContainer.basePath} ; ls -I data -I install | wc -l", 5 ) + cmdOutput = managerContainer.runBashCommandInContainer("cd ${managerContainer.basePath} ; ls -I data -I install | wc -l", 5) if (cmdOutput != ["0"]) { log.warn("\tNot cleaning up base path ${managerContainer.basePath}, found unexpected content") - }else { - cmdOutput = managerContainer.runBashCommandInContainer("rm -rf ${managerContainer.basePath} ; echo status: \$?", 120 ) + } else { + cmdOutput = managerContainer.runBashCommandInContainer("rm -rf ${managerContainer.basePath} ; echo status: \$?", 120) assert cmdOutput.last() == "status: 0": "Error cleaning up base path ${managerContainer.basePath}: " + cmdOutput.join("\n") } @@ -99,16 +130,17 @@ class HarborDeployment implements Deployment{ } + //TODO should return DevStack container objects, and filter more closely /** * Gets all containers running a Harbor image and the harbor manager container. * NOTE: this is a soft check that likely will return false positives * @return */ - ArrayListgetHarborContainers() { + ArrayList getHarborContainers() { ArrayList containers = managerContainer.dockerClient.ps().content - containers = containers.findAll { it.image.startsWith("goharbor") || it.names.first() == "/" + managerContainer.containerName} + containers = containers.findAll { it.image.startsWith("goharbor") || it.names.first() == "/" + managerContainer.containerName } return containers diff --git a/src/main/groovy/com/eficode/devstack/deployment/impl/JenkinsAndHarborDeployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/impl/JenkinsAndHarborDeployment.groovy index a658e36..a92f0d0 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/impl/JenkinsAndHarborDeployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/impl/JenkinsAndHarborDeployment.groovy @@ -21,7 +21,6 @@ class JenkinsAndHarborDeployment implements Deployment { JenkinsAndHarborDeployment(String jenkinsBaseUrl, String harborBaseUrl, String dockerHost = "", String dockerCertPath = "") { - subDeployments = [ new JenkinsDeployment(jenkinsBaseUrl, dockerHost, dockerCertPath), new HarborDeployment(harborBaseUrl, "v2.6.1", "/tmp/", dockerHost, dockerCertPath) @@ -122,6 +121,15 @@ class JenkinsAndHarborDeployment implements Deployment { } + @Override + boolean stopAndRemoveDeployment() { + + subDeployments.each{ + it.stopAndRemoveDeployment() + } + + } + } From f4eb288f1419ac7f1882e84e59a8fe1d85095467 Mon Sep 17 00:00:00 2001 From: Anders Lantz Date: Wed, 9 Nov 2022 13:55:31 +0100 Subject: [PATCH 3/9] Untested DockerClientDS.groovy * Extendes the default DockerClientImpl with an exec command that allows a ExecConfig to be supplied Container.groovy * Now uses DockerClientDS * runCommandInContainer now alloes user, group and working dir to be supplied pom.xml * Excluded most/all of groovy from standalone jar to not conflict with the hosting groovy version, consider perhaps instead setting groovy with scope provided --- Environments/Terraform/main.tf | 4 +- pom.xml | 14 +++-- .../devstack/container/Container.groovy | 53 +++++++++++----- .../deployment/impl/HarborDeployment.groovy | 40 ++++++++++++- .../devstack/util/DockerClientDS.groovy | 60 +++++++++++++++++++ .../com/eficode/devstack/DevStackSpec.groovy | 16 ++--- .../devstack/container/ContainerTest.groovy | 22 +++++++ .../impl/BitbucketH2DeploymentTest.groovy | 2 +- 8 files changed, 176 insertions(+), 35 deletions(-) create mode 100644 src/main/groovy/com/eficode/devstack/util/DockerClientDS.groovy diff --git a/Environments/Terraform/main.tf b/Environments/Terraform/main.tf index 90fc945..16a3e9a 100644 --- a/Environments/Terraform/main.tf +++ b/Environments/Terraform/main.tf @@ -288,9 +288,9 @@ resource "aws_lb" "load-balancer" { name = "${var.tags.useCase}-${var.tags.owner}-lb" internal = false - load_balancer_type = "network" + load_balancer_type = "application" subnets = [aws_subnet.base-stack-public-subnet.id] - + enable_deletion_protection = false } diff --git a/pom.xml b/pom.xml index 02064cd..a14b7af 100644 --- a/pom.xml +++ b/pom.xml @@ -170,8 +170,10 @@ - org.codehaus.groovy:groovy - org.codehaus.groovy:groovy-astbuilder + org.codehaus.groovy:* + + com.google.code.gson:gson org.apache.httpcomponents commons-* @@ -179,12 +181,12 @@ - + true + true diff --git a/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy index 116545f..197cb4f 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy @@ -135,7 +135,7 @@ class JsmAndBitbucketH2Deployment implements Deployment { threadPool.shutdown() - while (!jsmFuture.done && !bitbucketFuture.done) { + while (!jsmFuture.done || !bitbucketFuture.done) { log.info("Waiting for deployments to finish") log.info("\tJSM Finished:" + jsmFuture.done) log.info("\tBitbucket Finished:" + bitbucketFuture.done) From 0342c1d0ab4baa910ac6d2693f8dde1891666dd6 Mon Sep 17 00:00:00 2001 From: Anders Lantz Date: Thu, 24 Nov 2022 17:50:55 +0100 Subject: [PATCH 5/9] JsmAndBitbucketH2Deployment.groovy * Updated Version of JiraShortcuts used CreateBitbucketLink.groovy * Updated to use the latest JiraShortcuts --- .github/workflows/publish-maven-package.yml | 1 + .../deployment/impl/JsmAndBitbucketH2Deployment.groovy | 2 +- .../deployment/jira/scripts/CreateBitbucketLink.groovy | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-maven-package.yml b/.github/workflows/publish-maven-package.yml index 8c2e50a..94e8f7a 100644 --- a/.github/workflows/publish-maven-package.yml +++ b/.github/workflows/publish-maven-package.yml @@ -52,6 +52,7 @@ jobs: echo Compiling, Packaging and Installing Groovy 2.5 version of library to local m2 directory mvn install -f pom.xml -DcreateChecksum=true -Dgroovy.major.version=2.5 -Dgroovy.version=2.5.18 -Dspock-core.version=2.2-groovy-2.5 -DjiraShortcuts.version=2.0-SNAPSHOT-groovy-2.5 -Dbitbucketinstancemanager.version=0.0.3-SNAPSHOT-groovy-2.5 + - name: Copying JAR files run: | echo Copying the new JAR files to repository which will be added to git branch "packages" diff --git a/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy index 197cb4f..3c424e9 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy @@ -168,7 +168,7 @@ class JsmAndBitbucketH2Deployment implements Deployment { log.info("\tInstalling JiraShortcuts app") //Needed for setting up applink to bitbucket assert installJiraApps( [ - "https://github.com/eficode/JiraShortcuts/raw/packages/repository/com/eficode/atlassian/JiraShortcuts/2.0-SNAPSHOT-groovy-3.0/JiraShortcuts-2.0-SNAPSHOT-groovy-3.0.jar": "" + "https://github.com/eficode/JiraShortcuts/raw/packages/repository/com/eficode/atlassian/jira/jiraShortcuts/2.0.1-SNAPSHOT-groovy-3.0/jiraShortcuts-2.0.1-SNAPSHOT-groovy-3.0.jar":"" ] ) : "Error installing JiraShortcuts JIRA apps" log.info("\t\tFinished installing JiraShortcuts JIRA Apps") diff --git a/src/main/resources/com/eficode/devstack/deployment/jira/scripts/CreateBitbucketLink.groovy b/src/main/resources/com/eficode/devstack/deployment/jira/scripts/CreateBitbucketLink.groovy index 689665f..7924fb9 100644 --- a/src/main/resources/com/eficode/devstack/deployment/jira/scripts/CreateBitbucketLink.groovy +++ b/src/main/resources/com/eficode/devstack/deployment/jira/scripts/CreateBitbucketLink.groovy @@ -17,8 +17,8 @@ import com.atlassian.applinks.api.ApplicationLink import com.atlassian.applinks.api.application.bitbucket.BitbucketApplicationType import com.onresolve.scriptrunner.runner.customisers.WithPlugin -@WithPlugin("com.eficode.atlassian.JiraShortcuts") -import com.eficode.atlassian.JiraShortcuts.JiraShortcuts +@WithPlugin("com.eficode.atlassian.jiraShortcuts") +import com.eficode.atlassian.jira.jiraShortcuts.JiraShortcuts import org.apache.log4j.Level import org.apache.log4j.Logger From b7cdde41a4dfa371554300da52630f633c3504bb Mon Sep 17 00:00:00 2001 From: Anders Lantz Date: Thu, 24 Nov 2022 17:54:30 +0100 Subject: [PATCH 6/9] pom.xml * Updated Version of JiraShortcuts used --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 10d0f29..1bfb820 100644 --- a/pom.xml +++ b/pom.xml @@ -39,8 +39,8 @@ - com.eficode.atlassian - JiraShortcuts + com.eficode.atlassian.jira + jiraShortcuts ${jiraShortcuts.version} @@ -259,7 +259,7 @@ 3.0 3.0.11 2.2-groovy-3.0 - 2.0-SNAPSHOT-groovy-3.0 + 2.0.1-SNAPSHOT-groovy-3.0 0.0.3-SNAPSHOT-groovy-3.0 From 213cbab7fc49cbf2b5f5b9b2d21880c3f747e56e Mon Sep 17 00:00:00 2001 From: Anders Lantz Date: Thu, 24 Nov 2022 17:58:11 +0100 Subject: [PATCH 7/9] pom.xml * Updated Version of JiraShortcuts used --- .github/workflows/publish-maven-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-maven-package.yml b/.github/workflows/publish-maven-package.yml index 94e8f7a..b6eca14 100644 --- a/.github/workflows/publish-maven-package.yml +++ b/.github/workflows/publish-maven-package.yml @@ -50,7 +50,7 @@ jobs: run: | echo Compiling, Packaging and Installing Groovy 2.5 version of library to local m2 directory - mvn install -f pom.xml -DcreateChecksum=true -Dgroovy.major.version=2.5 -Dgroovy.version=2.5.18 -Dspock-core.version=2.2-groovy-2.5 -DjiraShortcuts.version=2.0-SNAPSHOT-groovy-2.5 -Dbitbucketinstancemanager.version=0.0.3-SNAPSHOT-groovy-2.5 + mvn install -f pom.xml -DcreateChecksum=true -Dgroovy.major.version=2.5 -Dgroovy.version=2.5.18 -Dspock-core.version=2.2-groovy-2.5 -DjiraShortcuts.version=2.0.1-SNAPSHOT-groovy-2.5 -Dbitbucketinstancemanager.version=0.0.3-SNAPSHOT-groovy-2.5 - name: Copying JAR files From 00d044378f1d1df9e06f848224a7116a68808994 Mon Sep 17 00:00:00 2001 From: Anders Lantz Date: Thu, 24 Nov 2022 18:18:41 +0100 Subject: [PATCH 8/9] JsmAndBitbucketH2Deployment.groovy, CreateBitbucketLink.groovy * Tweaks --- .../deployment/impl/JsmAndBitbucketH2Deployment.groovy | 3 ++- .../deployment/jira/scripts/CreateBitbucketLink.groovy | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy b/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy index 3c424e9..f311dd6 100644 --- a/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy +++ b/src/main/groovy/com/eficode/devstack/deployment/impl/JsmAndBitbucketH2Deployment.groovy @@ -164,11 +164,12 @@ class JsmAndBitbucketH2Deployment implements Deployment { log.info("\t\tFinished installing user defined JIRA Apps") } - if (!jiraAppsToInstall.any { it.key.contains("JiraShortcuts") }) { + if (!jiraAppsToInstall.any { it.key.contains("jiraShortcuts") }) { log.info("\tInstalling JiraShortcuts app") //Needed for setting up applink to bitbucket assert installJiraApps( [ "https://github.com/eficode/JiraShortcuts/raw/packages/repository/com/eficode/atlassian/jira/jiraShortcuts/2.0.1-SNAPSHOT-groovy-3.0/jiraShortcuts-2.0.1-SNAPSHOT-groovy-3.0.jar":"" + ] ) : "Error installing JiraShortcuts JIRA apps" log.info("\t\tFinished installing JiraShortcuts JIRA Apps") diff --git a/src/main/resources/com/eficode/devstack/deployment/jira/scripts/CreateBitbucketLink.groovy b/src/main/resources/com/eficode/devstack/deployment/jira/scripts/CreateBitbucketLink.groovy index 7924fb9..96d0870 100644 --- a/src/main/resources/com/eficode/devstack/deployment/jira/scripts/CreateBitbucketLink.groovy +++ b/src/main/resources/com/eficode/devstack/deployment/jira/scripts/CreateBitbucketLink.groovy @@ -17,7 +17,7 @@ import com.atlassian.applinks.api.ApplicationLink import com.atlassian.applinks.api.application.bitbucket.BitbucketApplicationType import com.onresolve.scriptrunner.runner.customisers.WithPlugin -@WithPlugin("com.eficode.atlassian.jiraShortcuts") +@WithPlugin("com.eficode.atlassian.jira.jiraShortcuts") import com.eficode.atlassian.jira.jiraShortcuts.JiraShortcuts import org.apache.log4j.Level import org.apache.log4j.Logger From c083d33448b7ad0159dd1512a75db49152095a53 Mon Sep 17 00:00:00 2001 From: Anders Lantz Date: Thu, 8 Dec 2022 14:17:43 +0100 Subject: [PATCH 9/9] pom.xml * Bumped jirainstancemanager to 1.3.0 * Bumped maven-shade-plugin to 3.4.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1bfb820..211a7ed 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ com.eficode.atlassian jirainstancemanager - 1.1.0-SNAPSHOT + 1.3.0-SNAPSHOT-groovy-${groovy.major.version} @@ -143,7 +143,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.4.0 + 3.4.1 package