diff --git a/.github/workflows/publish-maven-package.yml b/.github/workflows/publish-maven-package.yml
index 8c2e50a..b6eca14 100644
--- a/.github/workflows/publish-maven-package.yml
+++ b/.github/workflows/publish-maven-package.yml
@@ -50,7 +50,8 @@ 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
run: |
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 3b27c8a..211a7ed 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
@@ -39,8 +39,8 @@
- com.eficode.atlassian
- JiraShortcuts
+ com.eficode.atlassian.jira
+ jiraShortcuts
${jiraShortcuts.version}
@@ -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
@@ -157,28 +157,44 @@
standalone
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+
+
+
+
- org.codehaus.groovy:groovy
+ org.codehaus.groovy:*
+
+
com.google.code.gson:gson
org.apache.httpcomponents
commons-*
+ com.kohlschutter.junixsocket:junixsocket-core
-
+
true
+ true
@@ -243,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
diff --git a/src/main/groovy/com/eficode/devstack/container/Container.groovy b/src/main/groovy/com/eficode/devstack/container/Container.groovy
index b15d25e..878462a 100644
--- a/src/main/groovy/com/eficode/devstack/container/Container.groovy
+++ b/src/main/groovy/com/eficode/devstack/container/Container.groovy
@@ -1,6 +1,6 @@
package com.eficode.devstack.container
-import de.gesellix.docker.client.DockerClientImpl
+import com.eficode.devstack.util.DockerClientDS
import de.gesellix.docker.client.EngineResponseContent
import de.gesellix.docker.client.network.ManageNetworkClient
import de.gesellix.docker.engine.DockerClientConfig
@@ -11,6 +11,7 @@ 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.EndpointSettings
+import de.gesellix.docker.remote.api.ExecConfig
import de.gesellix.docker.remote.api.HostConfig
import de.gesellix.docker.remote.api.IdResponse
import de.gesellix.docker.remote.api.Mount
@@ -40,21 +41,20 @@ import java.util.regex.Pattern
trait Container {
Logger log = LoggerFactory.getLogger(self.class)
- DockerClientImpl dockerClient = new DockerClientImpl()
+ DockerClientDS dockerClient = new DockerClientDS()
ManageNetworkClient networkClient = dockerClient.getManageNetwork() as ManageNetworkClient
abstract String containerName
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 +89,6 @@ trait Container {
c.hostname = self.containerName
c.env = self.customEnvVar
-
}
return containerCreateRequest
@@ -98,11 +97,11 @@ trait Container {
/**
* Create container and override default docker cmd and entrypoint
- * @param cmd:
+ * @param cmd :
* @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 +118,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
@@ -145,7 +144,7 @@ trait Container {
dockerEnv.setCertPath(certPath)
dockerEnv.setTlsVerify("1")
dockerConfig.apply(dockerEnv)
- dockerClient = new DockerClientImpl(dockerConfig)
+ dockerClient = new DockerClientDS(dockerConfig)
networkClient = dockerClient.getManageNetwork() as ManageNetworkClient
@@ -248,10 +247,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
}
}
@@ -270,7 +267,7 @@ trait Container {
}
ContainerState.Status status() {
- return inspectContainer().state.status
+ return inspectContainer()?.state?.status
}
boolean stopAndRemoveContainer(Integer timeoutS = 5) {
@@ -469,28 +466,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(ArrayList networkNameOrIds) {
+
+ 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 +517,7 @@ trait Container {
ArrayList getContainerBridgeNetworks() {
- return getContainerNetworks().findAll { it.driver == "bridge" }
+ return getConnectedContainerNetworks().findAll { it.driver == "bridge" }
}
@@ -533,7 +541,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 +558,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 +577,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 +587,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 }) {
@@ -644,23 +651,45 @@ trait Container {
}
- ArrayList runBashCommandInContainer(String command, long timeoutS = 10) {
+ //Format is one of: `user`, `user:group`, `uid`, or `uid:gid`
+ ArrayList runCommandInContainer(String containerId, ArrayList commands, long timeoutS = 10, String userGroup = null, String workingDir = null) {
log.info("Executing bash command in container:")
log.info("\tContainer:" + self.containerName + " (${self.containerId})")
- log.info("\tCommand:" + command)
+ log.info("\tCommand:" + commands)
log.info("\tTimeout:" + timeoutS)
- if (log.isTraceEnabled()) {
- log.trace("\tDocker ping:" + dockerClient.ping().content as String)
- }
-
long cmdStart = System.currentTimeMillis()
+
+ ExecConfig execConfig = new ExecConfig()
+ execConfig.with { ex ->
+ ex.attachStdin = false
+ ex.attachStdout = true
+ ex.attachStderr = true
+ ex.detachKeys = null
+ ex.tty = false
+ ex.env = null
+ ex.cmd = commands
+ ex.privileged = null
+ ex.user = userGroup ?: null
+ ex.workingDir = workingDir ?: null
+ }
+
ContainerCallback callBack = new ContainerCallback()
- EngineResponse response = dockerClient.exec(self.containerId, [self.defaultShell, "-c", command], callBack, Duration.ofSeconds(timeoutS))
+ dockerClient.exec(containerId, commands, callBack, Duration.ofSeconds(timeoutS), execConfig)
+
+ log.trace("\tCommand finished after:" + ((System.currentTimeMillis() - cmdStart) / 1000).round() + "s")
- log.trace("\tCommand finished after:" + ((System.currentTimeMillis()-cmdStart)/1000).round() + "s" )
return callBack.output
+
+ }
+
+
+ ArrayList runBashCommandInContainer(String command, long timeoutS = 10, String user = null) {
+
+ return runCommandInContainer(self.containerId, [self.defaultShell, "-c", command], timeoutS, user)
+
+
}
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..8dcffd8 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 {
@@ -78,68 +79,141 @@ 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 && \\
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..ce30e14 100644
--- a/src/main/groovy/com/eficode/devstack/deployment/Deployment.groovy
+++ b/src/main/groovy/com/eficode/devstack/deployment/Deployment.groovy
@@ -1,12 +1,15 @@
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)
+
+ Logger log = LoggerFactory.getLogger(this.class)
abstract ArrayList containers
abstract String friendlyName
String deploymentNetworkName = "bridge"
@@ -14,23 +17,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..23493ff 100644
--- a/src/main/groovy/com/eficode/devstack/deployment/impl/HarborDeployment.groovy
+++ b/src/main/groovy/com/eficode/devstack/deployment/impl/HarborDeployment.groovy
@@ -1,18 +1,24 @@
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 com.eficode.devstack.util.DockerClientDS
+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"
ArrayList containers = []
+ 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)
@@ -22,14 +28,30 @@ class HarborDeployment implements Deployment{
}
HarborManagerContainer getManagerContainer() {
- this.containers.find {it instanceof HarborManagerContainer} as HarborManagerContainer
+ this.containers.find { it instanceof HarborManagerContainer } as HarborManagerContainer
}
@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 + (4 * 60000) > System.currentTimeMillis(): "Timed out waiting for harbor containers to start, waited:" + ((System.currentTimeMillis() - start)/1000).round().toString()
+ sleep(1500)
+ }
+
+ return true
+
}
@Override
@@ -37,17 +59,19 @@ 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
}
@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()
@@ -55,38 +79,102 @@ class HarborDeployment implements Deployment{
}
@Override
- boolean stopAndRemoveDeployment(){
+ boolean stopAndRemoveDeployment() {
+
+ log.info("Stopping and removing ${this.class}")
+
+
+ assert managerContainer.stopAndRemoveContainer()
+ ArrayList harbContainers = harborContainers
+ if (harbContainers) {
+ //There are still harbor containers around
+
+ DockerClientDS 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 harborContainers.isEmpty()
+
+ /*
+ 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")
+
+ DockerClientDS 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")
}
return managerContainer.stopAndRemoveContainer()
+ */
+
}
+ //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 0776550..a92f0d0 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,6 +14,7 @@ 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 = []
@@ -23,22 +26,9 @@ class JenkinsAndHarborDeployment implements Deployment {
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 +54,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() {
@@ -118,6 +121,15 @@ class JenkinsAndHarborDeployment implements Deployment {
}
+ @Override
+ boolean stopAndRemoveDeployment() {
+
+ subDeployments.each{
+ it.stopAndRemoveDeployment()
+ }
+
+ }
+
}
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..f311dd6 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
@@ -131,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)
@@ -160,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/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/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/main/groovy/com/eficode/devstack/util/DockerClientDS.groovy b/src/main/groovy/com/eficode/devstack/util/DockerClientDS.groovy
new file mode 100644
index 0000000..75bac8a
--- /dev/null
+++ b/src/main/groovy/com/eficode/devstack/util/DockerClientDS.groovy
@@ -0,0 +1,60 @@
+package com.eficode.devstack.util
+
+import com.eficode.devstack.util.DockerClientDS
+import de.gesellix.docker.client.DockerClientImpl
+import de.gesellix.docker.client.EngineResponseContent
+import de.gesellix.docker.engine.DockerClientConfig
+import de.gesellix.docker.engine.DockerEnv
+import de.gesellix.docker.remote.api.ExecConfig
+import de.gesellix.docker.remote.api.ExecStartConfig
+import de.gesellix.docker.remote.api.IdResponse
+import de.gesellix.docker.remote.api.core.Frame
+import de.gesellix.docker.remote.api.core.StreamCallback
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+import java.time.Duration
+
+import static java.net.Proxy.NO_PROXY
+
+class DockerClientDS extends DockerClientImpl {
+
+ private final Logger log = LoggerFactory.getLogger(DockerClientDS)
+
+
+ DockerClientDS() {
+ super()
+ }
+
+ DockerClientDS(String dockerHost) {
+ super(dockerHost)
+ }
+
+ DockerClientDS(DockerEnv env, Proxy proxy = NO_PROXY) {
+ super(env, proxy)
+ }
+
+ DockerClientDS(DockerClientConfig dockerClientConfig, Proxy proxy = NO_PROXY) {
+ super(dockerClientConfig, proxy)
+ }
+
+
+
+ EngineResponseContent exec(String containerId, List command, StreamCallback callback, Duration timeout, ExecConfig execConfig) {
+
+ log.info("docker exec '${containerId}' '${command}'")
+
+
+
+ EngineResponseContent execCreateResult = createExec(containerId, execConfig)
+ String execId = execCreateResult.content.id
+ ExecStartConfig execStartConfig = new ExecStartConfig(
+ (execConfig.detachKeys ?: false) as Boolean,
+ execConfig.tty
+ )
+ startExec(execId, execStartConfig, callback, timeout)
+ return execCreateResult
+
+ }
+
+}
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..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,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.jira.jiraShortcuts")
+import com.eficode.atlassian.jira.jiraShortcuts.JiraShortcuts
import org.apache.log4j.Level
import org.apache.log4j.Logger
diff --git a/src/test/groovy/com/eficode/devstack/DevStackSpec.groovy b/src/test/groovy/com/eficode/devstack/DevStackSpec.groovy
index 400cc6e..a611869 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 de.gesellix.docker.client.DockerClientImpl
+import com.eficode.devstack.container.impl.AlpineContainer
+import com.eficode.devstack.util.DockerClientDS
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
@@ -21,13 +22,16 @@ class DevStackSpec extends Specification {
String dockerCertPath = "resources/dockerCert"
@Shared
- DockerClientImpl dockerClient
+ DockerClientDS dockerClient
@Shared
ArrayList cleanupContainerNames
@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,17 +55,28 @@ 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() {
- DockerClientImpl dockerClient = resolveDockerClient()
+ DockerClientDS dockerClient = resolveDockerClient()
log.info("Cleaning up containers")
ArrayList containers = dockerClient.ps().content.collect {dockerClient.inspectContainer(it.id as String).content}
@@ -97,7 +113,7 @@ class DevStackSpec extends Specification {
}
- DockerClientImpl resolveDockerClient() {
+ DockerClientDS resolveDockerClient() {
log.info("Resolving Docker client")
@@ -134,7 +150,7 @@ class DevStackSpec extends Specification {
if (!dockerHost) {
log.info("\tNo remote host configured, returning local docker connection")
- return new DockerClientImpl()
+ return new DockerClientDS()
}
@@ -146,7 +162,7 @@ class DevStackSpec extends Specification {
if (!pemFiles.empty && ["ca.pem", "cert.pem", "key.pem"].every { expectedFile -> pemFiles.any { actualFile -> actualFile.name == expectedFile } }) {
log.info("\tFound Docker certs, returning Secure remote Docker connection")
try {
- DockerClientImpl dockerClient = setupSecureRemoteConnection(dockerRemoteHost, dockerCertPath)
+ DockerClientDS dockerClient = setupSecureRemoteConnection(dockerRemoteHost, dockerCertPath)
assert dockerClient.ping().content as String == "OK": "Error pinging remote Docker engine"
return dockerClient
} catch (ex) {
@@ -167,7 +183,7 @@ class DevStackSpec extends Specification {
* @param host ex: "https://docker.domain.se:2376"
* @param certPath folder containing ca.pem, cert.pem, key.pem
*/
- static DockerClientImpl setupSecureRemoteConnection(String host, String certPath) {
+ static DockerClientDS setupSecureRemoteConnection(String host, String certPath) {
DockerClientConfig dockerConfig = new DockerClientConfig(host)
DockerEnv dockerEnv = new DockerEnv(host)
@@ -175,7 +191,7 @@ class DevStackSpec extends Specification {
dockerEnv.setTlsVerify("1")
dockerConfig.apply(dockerEnv)
- return new DockerClientImpl(dockerConfig)
+ return new DockerClientDS(dockerConfig)
}
diff --git a/src/test/groovy/com/eficode/devstack/container/ContainerTest.groovy b/src/test/groovy/com/eficode/devstack/container/ContainerTest.groovy
index d3ee3ad..3c4de21 100644
--- a/src/test/groovy/com/eficode/devstack/container/ContainerTest.groovy
+++ b/src/test/groovy/com/eficode/devstack/container/ContainerTest.groovy
@@ -29,6 +29,28 @@ class ContainerTest extends DevStackSpec {
}
+ def testRunBashCommand(String dockerHost, String certPath) {
+
+ setup:
+ AlpineContainer alpine1 = new AlpineContainer(dockerHost, certPath)
+ alpine1.containerName = "spock-alpine1"
+ alpine1.createSleepyContainer()
+ alpine1.startContainer()
+
+ expect: "Test that the user parameter of runBashCommandInContainer works"
+ alpine1.runBashCommandInContainer("whoami") == ["root"]
+ alpine1.runBashCommandInContainer("adduser -D nisse && su nisse -c whoami") == ["nisse"]
+ alpine1.runBashCommandInContainer("whoami", 10, "nisse") == ["nisse"]
+
+
+ where:
+ dockerHost | certPath
+ "" | ""
+ dockerRemoteHost | dockerCertPath
+
+ }
+
+
def testNetworking(String dockerHost, String certPath) {
setup:
@@ -93,8 +115,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 +157,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/BitbucketH2DeploymentTest.groovy b/src/test/groovy/com/eficode/devstack/deployment/impl/BitbucketH2DeploymentTest.groovy
index a16d6e8..124922d 100644
--- a/src/test/groovy/com/eficode/devstack/deployment/impl/BitbucketH2DeploymentTest.groovy
+++ b/src/test/groovy/com/eficode/devstack/deployment/impl/BitbucketH2DeploymentTest.groovy
@@ -1,7 +1,7 @@
package com.eficode.devstack.deployment.impl
import com.eficode.devstack.DevStackSpec
-import de.gesellix.docker.client.DockerClientImpl
+import com.eficode.devstack.util.DockerClientDS
import de.gesellix.docker.engine.DockerClientConfig
import de.gesellix.docker.engine.DockerEnv
import kong.unirest.Unirest
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