Merge "move function to ceph class"
diff --git a/src/com/mirantis/mcp/MCPArtifactory.groovy b/src/com/mirantis/mcp/MCPArtifactory.groovy
index 272b1bc..fd01573 100644
--- a/src/com/mirantis/mcp/MCPArtifactory.groovy
+++ b/src/com/mirantis/mcp/MCPArtifactory.groovy
@@ -139,14 +139,8 @@
*/
def moveItem (String artifactoryURL, String sourcePath, String dstPath, boolean copy = false, boolean dryRun = false) {
def url = "${artifactoryURL}/api/${copy ? 'copy' : 'move'}/${sourcePath}?to=/${dstPath}&dry=${dryRun ? '1' : '0'}"
- withCredentials([
- [$class : 'UsernamePasswordMultiBinding',
- credentialsId : 'artifactory',
- passwordVariable: 'ARTIFACTORY_PASSWORD',
- usernameVariable: 'ARTIFACTORY_LOGIN']
- ]) {
- sh "bash -c \"curl -X POST -u ${ARTIFACTORY_LOGIN}:${ARTIFACTORY_PASSWORD} \'${url}\'\""
- }
+ def http = new com.mirantis.mk.Http()
+ return http.doPost(url, 'artifactory')
}
/**
@@ -522,7 +516,7 @@
}"""
artifactoryServer.upload(uploadSpec, newBuildInfo())
- def linkUrl = "${artifactoryServer.getUrl()}/artifactory/${config.get('artifactoryRepo')}"
+ def linkUrl = "${artifactoryServer.getUrl()}/${config.get('artifactoryRepo')}"
artifactsDescription = "Job artifacts uploaded to Artifactory: <a href=\"${linkUrl}\">${linkUrl}</a>"
} catch (Exception e) {
if (e =~ /no artifacts/) {
diff --git a/src/com/mirantis/mk/Artifactory.groovy b/src/com/mirantis/mk/Artifactory.groovy
index 9ac53bc..d126a1b 100644
--- a/src/com/mirantis/mk/Artifactory.groovy
+++ b/src/com/mirantis/mk/Artifactory.groovy
@@ -346,7 +346,7 @@
"files": [
{
"pattern": "${file}",
- "target": "${art.outRepo}",
+ "target": "artifactory/${art.outRepo}",
"props": "${props}"
}
]
@@ -477,7 +477,7 @@
"files": [
{
"pattern": "${chartPattern}",
- "target": "${repoName}/"
+ "target": "artifactory/${repoName}/"
}
]
}"""
diff --git a/src/com/mirantis/mk/Common.groovy b/src/com/mirantis/mk/Common.groovy
index 5027041..448935f 100644
--- a/src/com/mirantis/mk/Common.groovy
+++ b/src/com/mirantis/mk/Common.groovy
@@ -3,6 +3,8 @@
import static groovy.json.JsonOutput.prettyPrint
import static groovy.json.JsonOutput.toJson
+import groovy.time.TimeCategory
+
import com.cloudbees.groovy.cps.NonCPS
import groovy.json.JsonSlurperClassic
@@ -25,6 +27,31 @@
}
/**
+ * Return Duration for given datetime period with suffix
+ *
+ * @param input String in format '\d+[smhd]', to convert given number into seconds, minutes, hours
+ * and days duration respectively. For example: '7d' is for 7 days, '10m' - 10 minutes
+ * and so on. Return null if input in incorrect format
+ */
+def getDuration(String input) {
+ // Verify input format
+ if (!input.matches('[0-9]+[smhd]')) {
+ errorMsg("Incorrect input data for getDuration(): ${input}")
+ return
+ }
+ switch (input[-1]) {
+ case 's':
+ return TimeCategory.getSeconds(input[0..-2].toInteger())
+ case 'm':
+ return TimeCategory.getMinutes(input[0..-2].toInteger())
+ case 'h':
+ return TimeCategory.getHours(input[0..-2].toInteger())
+ case 'd':
+ return TimeCategory.getDays(input[0..-2].toInteger())
+ }
+}
+
+/**
* Return workspace.
* Currently implemented by calling pwd so it won't return relevant result in
* dir context
diff --git a/src/com/mirantis/mk/DockerImageScanner.groovy b/src/com/mirantis/mk/DockerImageScanner.groovy
index 536de37..8178564 100644
--- a/src/com/mirantis/mk/DockerImageScanner.groovy
+++ b/src/com/mirantis/mk/DockerImageScanner.groovy
@@ -31,7 +31,7 @@
case ~/^(tungsten|tungsten-operator)\/.*$/:
team_assignee = 'OpenContrail'
break
- case ~/^bm\/.*$/:
+ case ~/^(bm|general)\/.*$/:
team_assignee = 'BM/OS (KaaS BM)'
break
case ~/^openstack\/.*$/:
@@ -92,7 +92,7 @@
if (!found_key[0] && dict && image_short_name) {
dict.each { issue_key_name ->
if (!found_key[0]) {
- def s = dict[issue_key_name.key]['summary'] =~ /\b${image_short_name}\b/
+ def s = dict[issue_key_name.key]['summary'] =~ /(?<=[\/\[])${image_short_name}(?=\])/
if (s) {
if (image_full_name) {
def d = dict[issue_key_name.key]['description'] =~ /(?m)\b${image_full_name}\b/
@@ -126,7 +126,38 @@
return found_key
}
-def reportJiraTickets(String reportFileContents, String jiraCredentialsID, String jiraUserID, String jiraNamespace = 'PRODX') {
+def getLatestAffectedVersion(cred, productName, defaultJiraAffectedVersion = 'Backlog') {
+ def filterName = ''
+ if (productName == 'mosk') {
+ filterName = 'MOSK'
+ } else if (productName == 'kaas') {
+ filterName = 'KaaS'
+ } else {
+ return defaultJiraAffectedVersion
+ }
+
+ def search_api_url = "${cred.description}/rest/api/2/issue/createmeta?projectKeys=PRODX&issuetypeNames=Bug&expand=projects.issuetypes.fields"
+ def response = callREST("${search_api_url}", "${cred.username}:${cred.password}", 'GET')
+ def InputJSON = new JsonSlurper().parseText(response["responseText"])
+ def AffectedVersions = InputJSON['projects'][0]['issuetypes'][0]['fields']['versions']['allowedValues']
+
+ def versions = []
+ AffectedVersions.each{
+ if (it.containsKey('released') && it['released']) {
+ if (it.containsKey('name') && it['name'].startsWith(filterName)) {
+ if (it.containsKey('releaseDate') && it['releaseDate']) {
+ versions.add("${it['releaseDate']}`${it['name']}")
+ }
+ }
+ }
+ }
+ if (versions) {
+ return versions.sort()[-1].split('`')[-1]
+ }
+ return defaultJiraAffectedVersion
+}
+
+def reportJiraTickets(String reportFileContents, String jiraCredentialsID, String jiraUserID, String productName = '', String jiraNamespace = 'PRODX') {
def dict = [:]
@@ -181,6 +212,11 @@
}
}
+ def affectedVersion = ''
+ if (jiraNamespace == 'PRODX') {
+ affectedVersion = getLatestAffectedVersion(cred, productName)
+ }
+
def jira_summary = ''
def jira_description = ''
imageDict.each{
@@ -225,7 +261,7 @@
]
if (jiraNamespace == 'PRODX') {
basicIssueJSON['fields']['customfield_19000'] = [value:"${team_assignee}"]
- basicIssueJSON['fields']['versions'] = [["name": "Backlog"]]
+ basicIssueJSON['fields']['versions'] = [["name": affectedVersion]]
}
def post_issue_json = JsonOutput.toJson(basicIssueJSON)
def jira_comment = jira_description.replaceAll(/\n/, '\\\\n')
@@ -239,7 +275,7 @@
def post_comment_response = callREST("${uri}/${jira_key[0]}/comment", auth, 'POST', post_comment_json)
if ( post_comment_response['responseCode'] == 201 ) {
def issueCommentJSON = new JsonSlurper().parseText(post_comment_response["responseText"])
- print "\n\nComment was posted to ${jira_key[0]} for ${image_key} and ${image.key}"
+ print "\n\nComment was posted to ${jira_key[0]} ${affectedVersion} for ${image_key} and ${image.key}"
} else {
print "\nComment to ${jira_key[0]} Jira issue was not posted"
}
@@ -248,7 +284,7 @@
if (post_issue_response['responseCode'] == 201) {
def issueJSON = new JsonSlurper().parseText(post_issue_response["responseText"])
dict = updateDictionary(issueJSON['key'], dict, uri, auth, jiraUserID)
- print "\n\nJira issue was created ${issueJSON['key']} for ${image_key} and ${image.key}"
+ print "\n\nJira issue was created ${issueJSON['key']} ${affectedVersion} for ${image_key} and ${image.key}"
} else {
print "\n${image.key} CVE issues were not published\n"
}
diff --git a/src/com/mirantis/mk/Gerrit.groovy b/src/com/mirantis/mk/Gerrit.groovy
index 88da957..07c6b5d 100644
--- a/src/com/mirantis/mk/Gerrit.groovy
+++ b/src/com/mirantis/mk/Gerrit.groovy
@@ -320,11 +320,13 @@
* HOST, PORT and USER
* @param changeParams Parameters to identify Geriit change e.g.: owner, topic,
* status, branch, project
+ * @param extraFlags Additional flags for gerrit querry for example
+ * '--current-patch-set' or '--comments' as a simple string
*/
-def findGerritChange(credentialsId, LinkedHashMap gerritAuth, LinkedHashMap changeParams) {
+def findGerritChange(credentialsId, LinkedHashMap gerritAuth, LinkedHashMap changeParams, String extraFlags = '') {
scriptText = """
ssh -p ${gerritAuth['PORT']} ${gerritAuth['USER']}@${gerritAuth['HOST']} \
- gerrit query \
+ gerrit query ${extraFlags} \
--format JSON \
"""
changeParams.each {
diff --git a/src/com/mirantis/mk/Http.groovy b/src/com/mirantis/mk/Http.groovy
index b752b42..a7e0f97 100644
--- a/src/com/mirantis/mk/Http.groovy
+++ b/src/com/mirantis/mk/Http.groovy
@@ -55,7 +55,10 @@
response = connection.inputStream.text
try {
response_content = new groovy.json.JsonSlurperClassic().parseText(response)
- } catch (groovy.json.JsonException e) {
+ } catch (groovy.json.JsonException|java.lang.NullPointerException e) {
+ if(env.getEnvironment().containsKey('DEBUG') && env['DEBUG'] == "true"){
+ println("[HTTP] Cought exception while trying parsing response as JSON: ${e}")
+ }
response_content = response
}
if(env.getEnvironment().containsKey('DEBUG') && env['DEBUG'] == "true"){
diff --git a/src/com/mirantis/mk/KaasUtils.groovy b/src/com/mirantis/mk/KaasUtils.groovy
index 3af9777..5936ec8 100644
--- a/src/com/mirantis/mk/KaasUtils.groovy
+++ b/src/com/mirantis/mk/KaasUtils.groovy
@@ -48,9 +48,11 @@
def common = new com.mirantis.mk.Common()
// Available triggers and its sane defaults
+ def seedMacOs = env.SEED_MACOS ? env.SEED_MACOS.toBoolean() : false
def deployChild = env.DEPLOY_CHILD_CLUSTER ? env.DEPLOY_CHILD_CLUSTER.toBoolean() : false
def upgradeChild = env.UPGRADE_CHILD_CLUSTER ? env.UPGRADE_CHILD_CLUSTER.toBoolean() : false
def attachBYO = env.ATTACH_BYO ? env.ATTACH_BYO.toBoolean() : false
+ def upgradeBYO = env.UPGRADE_BYO ? env.UPGRADE_BYO.toBoolean() : false
def upgradeMgmt = env.UPGRADE_MGMT_CLUSTER ? env.UPGRADE_MGMT_CLUSTER.toBoolean() : false
def runUie2e = env.RUN_UI_E2E ? env.RUN_UI_E2E.toBoolean() : false
def runMgmtConformance = env.RUN_MGMT_CFM ? env.RUN_MGMT_CFM.toBoolean() : false
@@ -67,10 +69,14 @@
def awsOnDemandDemo = env.ALLOW_AWS_ON_DEMAND ? env.ALLOW_AWS_ON_DEMAND.toBoolean() : false
def awsOnRhelDemo = false
def vsphereOnDemandDemo = env.ALLOW_VSPHERE_ON_DEMAND ? env.ALLOW_VSPHERE_ON_DEMAND.toBoolean() : false
+ def equinixOnAwsDemo = false
def enableOSDemo = true
def enableBMDemo = true
def commitMsg = env.GERRIT_CHANGE_COMMIT_MESSAGE ? new String(env.GERRIT_CHANGE_COMMIT_MESSAGE.decodeBase64()) : ''
+ if (commitMsg ==~ /(?s).*\[seed-macos\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*seed-macos.*/) {
+ seedMacOs = true
+ }
if (commitMsg ==~ /(?s).*\[child-deploy\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*child-deploy.*/ || upgradeChild || runChildConformance) {
deployChild = true
}
@@ -81,8 +87,16 @@
if (commitMsg ==~ /(?s).*\[byo-attach\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*byo-attach.*/) {
attachBYO = true
}
- if (commitMsg ==~ /(?s).*\[mgmt-upgrade\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*mgmt-upgrade.*/) {
+ if (commitMsg ==~ /(?s).*\[byo-upgrade\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*byo-upgrade.*/) {
+ attachBYO = true
+ upgradeBYO = true
+ }
+ if (commitMsg ==~ /(?s).*\[mgmt-upgrade\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*mgmt-upgrade.*/ || upgradeBYO) {
upgradeMgmt = true
+ if (upgradeBYO) {
+ // TODO (vnaumov) remove such dependency right after we can verify byo upgrade w/o mgmt upgrade
+ common.warningMsg('Forced running kaas mgmt upgrade scenario, due byo demo scenario trigger: \'[byo-upgrade]\' ')
+ }
}
if (commitMsg ==~ /(?s).*\[ui-e2e\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*ui-e2e.*/) {
runUie2e = true
@@ -97,12 +111,14 @@
if (commitMsg ==~ /(?s).*\[fetch.*binaries\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*fetch.*binaries.*/) {
fetchServiceBinaries = true
}
- if (commitMsg ==~ /(?s).*\[aws-demo\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*aws-demo.*/ || attachBYO) {
+ if (commitMsg ==~ /(?s).*\[equinix-demo\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*equinix-demo.*/) {
+ equinixOnAwsDemo = true
+ common.warningMsg('Forced running child cluster deployment on EQUINIX METAL provider based on AWS management cluster, triggered on patchset using custom keyword: \'[equinix-demo]\' ')
+ }
+ if (commitMsg ==~ /(?s).*\[aws-demo\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*aws-demo.*/ || attachBYO || upgradeBYO || seedMacOs || equinixOnAwsDemo) {
awsOnDemandDemo = true
- if (attachBYO) {
- common.warningMsg('Forced running additional kaas deployment with AWS provider, due byo demo scenario trigger: \'[byo-attach]\' ')
- } else {
- common.warningMsg('Forced running additional kaas deployment with AWS provider, triggered on patchset using custom keyword: \'[aws-demo]\' ')
+ if (attachBYO || upgradeBYO || seedMacOs || equinixOnAwsDemo) {
+ common.warningMsg('Forced running additional kaas deployment with AWS provider, due applied trigger cross dependencies, follow docs to clarify info')
}
}
if (commitMsg ==~ /(?s).*\[aws-rhel-demo\].*/) {
@@ -143,12 +159,16 @@
}
switch (multiregionalMappings['managementLocation']) {
case 'aws':
+ common.warningMsg('Forced running additional kaas deployment with AWS provider according multiregional demo request')
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')
+
+ if (multiregionalMappings['regionLocation'] != 'aws' && seedMacOs) { // macstadium seed node has access only to *public* providers
+ error('incompatible triggers: [seed-macos] and multiregional deployment based on *private* regional provider cannot be applied simultaneously')
+ }
break
case 'os':
if (enableOSDemo == false) {
@@ -157,27 +177,36 @@
break
}
+ // calculate weight of current demo run to manage lockable resources
+ def demoWeight = (deployChild) ? 2 : 1 // management = 1, child = 1
+
common.infoMsg("""
+ Use MacOS node as seed: ${seedMacOs}
Child cluster deployment scheduled: ${deployChild}
Child cluster release upgrade scheduled: ${upgradeChild}
Child conformance testing scheduled: ${runChildConformance}
BYO cluster attachment scheduled: ${attachBYO}
+ Attached BYO cluster upgrade test scheduled: ${upgradeBYO}
Mgmt cluster release upgrade scheduled: ${upgradeMgmt}
Mgmt conformance testing scheduled: ${runMgmtConformance}
Mgmt UI e2e testing scheduled: ${runUie2e}
AWS provider deployment scheduled: ${awsOnDemandDemo}
AWS provider on RHEL deployment scheduled: ${awsOnRhelDemo}
VSPHERE provider deployment scheduled: ${vsphereOnDemandDemo}
+ EQUINIX child cluster deployment scheduled: ${equinixOnAwsDemo}
OS provider deployment scheduled: ${enableOSDemo}
BM provider deployment scheduled: ${enableBMDemo}
Multiregional configuration: ${multiregionalMappings}
Service binaries fetching scheduled: ${fetchServiceBinaries}
+ Current weight of the demo run: ${demoWeight} (Used to manage lockable resources)
Triggers: https://docs.google.com/document/d/1SSPD8ZdljbqmNl_FEAvTHUTow9Ki8NIMu82IcAVhzXw/""")
return [
+ useMacOsSeedNode : seedMacOs,
deployChildEnabled : deployChild,
upgradeChildEnabled : upgradeChild,
runChildConformanceEnabled : runChildConformance,
attachBYOEnabled : attachBYO,
+ upgradeBYOEnabled : upgradeBYO,
upgradeMgmtEnabled : upgradeMgmt,
runUie2eEnabled : runUie2e,
runMgmtConformanceEnabled : runMgmtConformance,
@@ -185,9 +214,11 @@
awsOnDemandDemoEnabled : awsOnDemandDemo,
awsOnDemandRhelDemoEnabled : awsOnRhelDemo,
vsphereOnDemandDemoEnabled : vsphereOnDemandDemo,
+ equinixOnAwsDemoEnabled : equinixOnAwsDemo,
bmDemoEnabled : enableBMDemo,
osDemoEnabled : enableOSDemo,
- multiregionalConfiguration : multiregionalMappings]
+ multiregionalConfiguration : multiregionalMappings,
+ demoWeight : demoWeight]
}
/**
@@ -410,12 +441,14 @@
string(name: 'SI_TESTS_DOCKER_IMAGE_TAG', value: siRefspec.siTestsDockerImageTag),
string(name: 'SI_PIPELINES_REFSPEC', value: siRefspec.siPipelines),
string(name: 'CUSTOM_RELEASE_PATCH_SPEC', value: patchSpec),
+ booleanParam(name: 'SEED_MACOS', value: triggers.useMacOsSeedNode),
booleanParam(name: 'UPGRADE_MGMT_CLUSTER', value: triggers.upgradeMgmtEnabled),
booleanParam(name: 'RUN_UI_E2E', value: triggers.runUie2eEnabled),
booleanParam(name: 'RUN_MGMT_CFM', value: triggers.runMgmtConformanceEnabled),
booleanParam(name: 'DEPLOY_CHILD_CLUSTER', value: triggers.deployChildEnabled),
booleanParam(name: 'UPGRADE_CHILD_CLUSTER', value: triggers.upgradeChildEnabled),
booleanParam(name: 'ATTACH_BYO', value: triggers.attachBYOEnabled),
+ booleanParam(name: 'UPGRADE_BYO', value: triggers.upgradeBYOEnabled),
booleanParam(name: 'RUN_CHILD_CFM', value: triggers.runChildConformanceEnabled),
booleanParam(name: 'ALLOW_AWS_ON_DEMAND', value: triggers.awsOnDemandDemoEnabled || triggers.awsOnDemandRhelDemoEnabled),
booleanParam(name: 'ALLOW_VSPHERE_ON_DEMAND', value: triggers.vsphereOnDemandDemoEnabled),
diff --git a/src/com/mirantis/mk/Ruby.groovy b/src/com/mirantis/mk/Ruby.groovy
index 4681d07..2e1e494 100644
--- a/src/com/mirantis/mk/Ruby.groovy
+++ b/src/com/mirantis/mk/Ruby.groovy
@@ -6,9 +6,9 @@
/**
* Ensures Ruby environment with given version (install it if necessary)
- * @param rubyVersion target ruby version (optional, default 2.2.3)
+ * @param rubyVersion target ruby version (optional, default 2.6.6)
*/
-def ensureRubyEnv(rubyVersion="2.4.1"){
+def ensureRubyEnv(rubyVersion="2.6.6"){
if (!fileExists("/var/lib/jenkins/.rbenv/versions/${rubyVersion}/bin/ruby")){
//XXX: patch ruby-build because debian package is quite old
sh "git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build || git -C ~/.rbenv/plugins/ruby-build pull origin master"