Merge "Fix for restart fails in the installFoundationInfraOnTarget function"
diff --git a/src/com/mirantis/mk/KaasUtils.groovy b/src/com/mirantis/mk/KaasUtils.groovy
index d37c5f2..a6dfb5f 100644
--- a/src/com/mirantis/mk/KaasUtils.groovy
+++ b/src/com/mirantis/mk/KaasUtils.groovy
@@ -64,6 +64,7 @@
// optional demo deployment customization
def awsOnDemandDemo = env.ALLOW_AWS_ON_DEMAND ? env.ALLOW_AWS_ON_DEMAND.toBoolean() : false
+ def awsOnRhelDemo = false
def enableOSDemo = true
def enableBMDemo = true
@@ -95,6 +96,12 @@
awsOnDemandDemo = true
common.warningMsg('Forced running additional kaas deployment with AWS provider, triggered on patchset using custom keyword: \'[aws-demo]\' ')
}
+ if (commitMsg ==~ /(?s).*\[aws-rhel-demo\].*/) {
+ awsOnDemandDemo = false
+ awsOnRhelDemo = true
+ common.warningMsg('Forced running additional kaas deployment with AWS provider on RHEL, triggered on patchset using custom keyword: \'[aws-rhel-demo]\'.' +
+ 'Upgrade scenario for Mgmt or Child cluster is not supported currently in such deployment')
+ }
if (commitMsg ==~ /(?s).*\[disable-os-demo\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*disable-os-demo\.*/) {
enableOSDemo = false
common.errorMsg('Openstack demo deployment will be aborted, VF -1 will be set')
@@ -124,6 +131,10 @@
switch (multiregionalMappings['managementLocation']) {
case 'aws':
awsOnDemandDemo = true
+ if (awsOnRhelDemo) {
+ // Run only one variant: standard AWS deployment (on Ubuntu) or on RHEL
+ awsOnDemandDemo = false
+ }
common.warningMsg('Forced running additional kaas deployment with AWS provider according multiregional demo request')
break
case 'os':
@@ -141,6 +152,7 @@
Mgmt conformance testing scheduled: ${runMgmtConformance}
Mgmt UI e2e testing scheduled: ${runUie2e}
AWS provider deployment scheduled: ${awsOnDemandDemo}
+ AWS provider on RHEL deployment scheduled: ${awsOnRhelDemo}
OS provider deployment scheduled: ${enableOSDemo}
BM provider deployment scheduled: ${enableBMDemo}
Multiregional configuration: ${multiregionalMappings}
@@ -155,6 +167,7 @@
runMgmtConformanceEnabled : runMgmtConformance,
fetchServiceBinariesEnabled: fetchServiceBinaries,
awsOnDemandDemoEnabled : awsOnDemandDemo,
+ awsOnDemandRhelDemoEnabled : awsOnRhelDemo,
bmDemoEnabled : enableBMDemo,
osDemoEnabled : enableOSDemo,
multiregionalConfiguration : multiregionalMappings]
@@ -386,7 +399,7 @@
booleanParam(name: 'DEPLOY_CHILD_CLUSTER', value: triggers.deployChildEnabled),
booleanParam(name: 'UPGRADE_CHILD_CLUSTER', value: triggers.upgradeChildEnabled),
booleanParam(name: 'RUN_CHILD_CFM', value: triggers.runChildConformanceEnabled),
- booleanParam(name: 'ALLOW_AWS_ON_DEMAND', value: triggers.awsOnDemandDemoEnabled),
+ booleanParam(name: 'ALLOW_AWS_ON_DEMAND', value: triggers.awsOnDemandDemoEnabled || triggers.awsOnDemandRhelDemoEnabled),
]
// customize multiregional demo
diff --git a/src/com/mirantis/mk/Lock.groovy b/src/com/mirantis/mk/Lock.groovy
new file mode 100644
index 0000000..7700419
--- /dev/null
+++ b/src/com/mirantis/mk/Lock.groovy
@@ -0,0 +1,142 @@
+import org.jfrog.hudson.pipeline.common.types.ArtifactoryServer
+import java.util.concurrent.TimeoutException
+
+class Lock {
+ String name, id, path
+ Integer retryInterval, timeout, expiration
+ Boolean force
+ Map lockExtraMetadata
+ ArtifactoryServer artifactoryServer
+
+ private String lockFileContent
+ private String lockFileContentCache
+
+ final private String fileUri
+
+ final private def common = new com.mirantis.mk.Common()
+ final private def artifactoryTools = new com.mirantis.mk.Artifactory()
+
+ // Constructor
+ public Lock(Map args) {
+ // Mandatory
+ this.name = args.name
+ this.artifactoryServer = args.artifactoryServer
+
+ // Defaults
+ this.id = args.get('id', '')
+ this.path = args.get('path', 'binary-dev-local/locks')
+ this.retryInterval = args.get('retryInterval', 5*60)
+ this.timeout = args.get('timeout', 3*60*60)
+ this.expiration = args.get('expiration', 24*60*60)
+ this.force = args.get('force', false)
+ this.lockExtraMetadata = args.get('lockExtraMetadata', [:])
+
+ // Internal
+ this.fileUri = "/${path}/${name}.yaml".toLowerCase()
+ }
+
+ final private Map artObj
+ // getPasswordCredentials() is CPS-transformed function and cannot be used in constructor
+ final private Map getArtObj() {
+ def artifactoryCreds = common.getPasswordCredentials(artifactoryServer.getCredentialsId())
+ return [
+ 'url': "${artifactoryServer.getUrl()}/artifactory",
+ 'creds': [
+ 'username': artifactoryCreds['username'],
+ 'password': artifactoryCreds['password'],
+ ]
+ ]
+ }
+
+ // getter for lockFileContent
+ final private String getLockFileContent() {
+ if (this.lockFileContentCache == null) {
+ try {
+ this.lockFileContentCache = artifactoryTools.restCall(this.artObj, this.fileUri, 'GET', null, [:], '')
+ } catch (Exception e) {
+ this.lockFileContentCache = ''
+ }
+ }
+ return this.lockFileContentCache
+ }
+
+ public void lock() {
+ if (this.force) {
+ common.infoMsg("Ignore lock checking due 'force' flag presence")
+ } else {
+ waitLockReleased()
+ }
+ createLockFile()
+ }
+
+ public void unlock() {
+ if (!isLockFileExist()) {
+ common.infoMsg("Lock file '${this.artObj['url']}${this.fileUri}' does not exist. No need to remove it")
+ // No need to continue if file does not exist
+ return
+ }
+
+ Map lockMeta = common.readYaml2(text: this.lockFileContent ?: '{}')
+ if (this.force || (this.id && this.id == lockMeta.get('lockID', ''))) {
+ artifactoryTools.restCall(this.artObj, this.fileUri, 'DELETE', null, [:], '')
+ common.infoMsg("Lock file '${this.artObj['url']}${this.fileUri}' has been removed")
+ } else {
+ throw new RuntimeException("Given lock ID '${this.id}' is not equal to '${lockMeta.get('lockID')}' ID in lock file")
+ }
+ }
+
+ private void createLockFile() {
+ this.id = UUID.randomUUID().toString()
+
+ Calendar now = Calendar.getInstance()
+ Calendar expiredAt = now.clone()
+ expiredAt.add(Calendar.SECOND, this.expiration)
+
+ Map lockMeta = [
+ 'lockID': this.id,
+ 'createdAt': now.getTime().toString(),
+ 'expiredAt': expiredAt.getTime().toString(),
+ ]
+ lockMeta.putAll(this.lockExtraMetadata)
+
+ def commonMCP = new com.mirantis.mcp.Common()
+ artifactoryTools.restCall(this.artObj, this.fileUri, 'PUT', commonMCP.dumpYAML(lockMeta), [:], '')
+ common.infoMsg("Lock file '${this.artObj['url']}${this.fileUri}' has been created")
+ }
+
+ private void waitLockReleased() {
+ Long startTime = System.currentTimeMillis()
+ while (isLocked()) {
+ if (System.currentTimeMillis() - startTime >= timeout*1000 ) {
+ throw new TimeoutException("Execution of waitLock timed out after ${this.timeout} seconds")
+ }
+ common.infoMsg("'${this.name}' is locked. Retry in ${this.retryInterval} seconds")
+ sleep(this.retryInterval*1000)
+ }
+ }
+
+ private Boolean isLocked() {
+ if (!isLockFileExist()) {
+ common.infoMsg("Lock file for '${this.name}' does not exist")
+ return false
+ } else if (isLockExpired()) {
+ common.infoMsg("Lock '${this.name}' has been expired")
+ return false
+ }
+ return true
+ }
+
+ private Boolean isLockFileExist() {
+ return !this.lockFileContent.isEmpty()
+ }
+
+ private Boolean isLockExpired() {
+ if (!isLockFileExist()) {
+ return true
+ }
+ Map lockMeta = common.readYaml2(text: this.lockFileContent ?: '{}')
+ Date expirationTime = new Date(lockMeta.get('expiredAt', '01/01/1970'))
+ Date currentTime = new Date()
+ return currentTime.after(expirationTime)
+ }
+}