Merge "Small fix for cvp-ha job"
diff --git a/build-mirror-image.groovy b/build-mirror-image.groovy
index 33879c0..7a41304 100644
--- a/build-mirror-image.groovy
+++ b/build-mirror-image.groovy
@@ -100,24 +100,25 @@
 
         stage("Create Docker Registry"){
             common.infoMsg("Creating Docker Registry")
-            salt.enforceState(venvPepper, '*apt*', ['docker.host'], true, false, null, false, -1, 2)
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['docker run --restart always -d -p 5000:5000 --name registry registry:2'], null, true)
-            salt.enforceState(venvPepper, '*apt*', ['docker.client.registry'], true, false, null, false, -1, 2)
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['docker system prune --all --force'], null, true)
+            salt.enforceState(venvPepper, '*apt*', ["docker.host"], true, false, null, false, -1, 2)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["docker run --restart always -d -p 5000:5000 --name registry registry:2"], null, true)
+            salt.enforceState(venvPepper, '*apt*', ["docker.client.registry"], true, false, null, false, -1, 2)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["docker system prune --all --force"], null, true)
         }
 
         stage("Create Aptly"){
             common.infoMsg("Creating Aptly")
             salt.enforceState(venvPepper, '*apt*', ['aptly'], true, false, null, false, -1, 2)
             //TODO: Do it new way
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['aptly_mirror_update.sh -s -v', 'runas=aptly'], null, true)
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['nohup aptly api serve --no-lock > /dev/null 2>&1 </dev/null &', 'runas=aptly'], null, true)
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['aptly-publisher --timeout=1200 publish -v -c /etc/aptly-publisher.yaml --architectures amd64 --url http://127.0.0.1:8080 --recreate --force-overwrite', 'runas=aptly'], null, true)
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['aptly db cleanup', 'runas=aptly'], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["aptly_mirror_update.sh -s -v", "runas=aptly"], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["nohup aptly api serve --no-lock > /dev/null 2>&1 </dev/null &", "runas=aptly"], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["aptly-publisher --timeout=1200 publish -v -c /etc/aptly-publisher.yaml --architectures amd64 --url http://127.0.0.1:8080 --recreate --force-overwrite", "runas=aptly"], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["aptly db cleanup", "runas=aptly"], null, true)
             //NEW way
-            //salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv", 'runas=aptly'], null, true)
-            //salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.script', ['salt://aptly/files/aptly_publish_update.sh', "args=-acrfv", 'runas=aptly'], null, true)
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/aptly/aptly-update.sh -O /srv/scripts/aptly-update.sh'], null, true)
+            //salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv", "runas=aptly"], null, true)
+            //salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.script', ['salt://aptly/files/aptly_publish_update.sh', "args=-acrfv", "runas=aptly"], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/aptly/aptly-update.sh -O /srv/scripts/aptly-update.sh"], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["chmod +x /srv/scripts/aptly-update.sh"], null, true)
         }
 
         stage("Create Git mirror"){
@@ -127,22 +128,22 @@
 
         stage("Create PyPi mirror"){
             common.infoMsg("Creating PyPi mirror")
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['pip install pip2pi'], null, true)
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/pypi_mirror/requirements.txt -O /srv/pypi_mirror/requirements.txt'], null, true)
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['pip2pi /srv/pypi_mirror/packages/ -r /srv/pypi_mirror/requirements.txt'], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["pip install pip2pi"], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/pypi_mirror/requirements.txt -O /srv/pypi_mirror/requirements.txt"], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["pip2pi /srv/pypi_mirror/packages/ -r /srv/pypi_mirror/requirements.txt"], null, true)
         }
 
         stage("Create mirror of images"){
             common.infoMsg("Creating mirror of images")
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/images_mirror/images.txt -O /srv/images.txt'], null, true)
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/images_mirror/update-images.sh -O /srv/scripts/update-images.sh'], null, true)
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['chmod +x /srv/scripts/update-images.sh'], null, true)
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['/srv/scripts/update-images.sh -u http://ci.mcp.mirantis.net:8085/images'], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/images_mirror/images.txt -O /srv/images.txt"], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["wget https://raw.githubusercontent.com/Mirantis/mcp-common-scripts/${SCRIPTS_REF}/mirror-image/images_mirror/update-images.sh -O /srv/scripts/update-images.sh"], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["chmod +x /srv/scripts/update-images.sh"], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["/srv/scripts/update-images.sh -u http://ci.mcp.mirantis.net:8085/images"], null, true)
         }
 
         stage("Create instance snapshot"){
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['rm -rf /var/lib/cloud/sem/* /var/lib/cloud/instance /var/lib/cloud/instances/*'], null, true)
-            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['cloud-init init'], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["rm -rf /var/lib/cloud/sem/* /var/lib/cloud/instance /var/lib/cloud/instances/*"], null, true)
+            salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["cloud-init init"], null, true)
 
             retry(3, 5){
                 openstack.runOpenstackCommand("openstack server stop mcp-offline-mirror-${dateTime}", rcFile, openstackEnv)
diff --git a/cloud-deploy-pipeline.groovy b/cloud-deploy-pipeline.groovy
index 6f6e015..d051b30 100644
--- a/cloud-deploy-pipeline.groovy
+++ b/cloud-deploy-pipeline.groovy
@@ -38,6 +38,10 @@
  *  required for STACK_TYPE=physical
  *   SALT_MASTER_URL            URL of Salt master
 
+ *   BOOTSTRAP_EXTRA_REPO_PARAMS  optional parameter to define a list of extra repos with parameters
+ *                                which have to be added during bootstrap.
+ *                                Format: repo 1, repo priority 1, repo pin 1; repo 2, repo priority 2, repo pin 2;
+
  * Test settings:
  *   TEST_K8S_API_SERVER     Kubernetes API address
  *   TEST_K8S_CONFORMANCE_IMAGE   Path to docker image with conformance e2e tests
@@ -168,6 +172,12 @@
                         envParams.put('cfg_formula_pkg_revision', FORMULA_PKG_REVISION)
                     }
 
+                    // put extra repo definitions
+                    if (common.validInputParam('BOOTSTRAP_EXTRA_REPO_PARAMS')) {
+                        common.infoMsg("Setting additional repo during bootstrap to ${BOOTSTRAP_EXTRA_REPO_PARAMS}")
+                        envParams.put('cfg_bootstrap_extra_repo_params', BOOTSTRAP_EXTRA_REPO_PARAMS)
+                    }
+
                     openstack.createHeatStack(openstackCloud, STACK_NAME, STACK_TEMPLATE, envParams, HEAT_STACK_ENVIRONMENT, venv)
                 }
 
@@ -265,11 +275,15 @@
 
         if (common.checkContains('STACK_INSTALL', 'core')) {
             stage('Install core infrastructure') {
-                orchestrate.installFoundationInfra(venvPepper, STATIC_MGMT_NETWORK.toBoolean())
+                def staticMgmtNetwork = false
+                if (common.validInputParam('STATIC_MGMT_NETWORK')) {
+                    staticMgmtNetwork = STATIC_MGMT_NETWORK.toBoolean()
+                }
+                orchestrate.installFoundationInfra(venvPepper, staticMgmtNetwork)
 
                 if (common.checkContains('STACK_INSTALL', 'kvm')) {
                     orchestrate.installInfraKvm(venvPepper)
-                    orchestrate.installFoundationInfra(venvPepper, STATIC_MGMT_NETWORK.toBoolean())
+                    orchestrate.installFoundationInfra(venvPepper, staticMgmtNetwork)
                 }
 
                 orchestrate.validateFoundationInfra(venvPepper)
diff --git a/release-mcp-version.groovy b/release-mcp-version.groovy
index 4abaf5d..28b0bb4 100644
--- a/release-mcp-version.groovy
+++ b/release-mcp-version.groovy
@@ -16,7 +16,8 @@
  *   GIT_REPO_LIST
  */
 
-def common = new com.mirantis.mk.Common()
+common = new com.mirantis.mk.Common()
+git = new com.mirantis.mk.Git()
 
 def triggerAptlyPromoteJob(aptlyUrl, components, diffOnly, dumpPublish, packages, recreate, source, storages, target){
   build job: "aptly-promote-all-testing-stable", parameters: [
@@ -32,25 +33,37 @@
   ]
 }
 
-def triggerDockerMirrorJob(dockerCredentials, dockerRegistryUrl, dockerRegistry, mcpVersion, imageList) {
-  build job: "mirror-docker-images", parameters: [
+def triggerDockerMirrorJob(dockerCredentials, dockerRegistryUrl, mcpVersion, imageList) {
+  build job: "docker-images-mirror", parameters: [
     [$class: 'StringParameterValue', name: 'TARGET_REGISTRY_CREDENTIALS_ID', value: dockerCredentials],
     [$class: 'StringParameterValue', name: 'REGISTRY_URL', value: dockerRegistryUrl],
-    [$class: 'StringParameterValue', name: 'TARGET_REGISTRY', value: dockerRegistry],
     [$class: 'StringParameterValue', name: 'IMAGE_TAG', value: mcpVersion],
     [$class: 'StringParameterValue', name: 'IMAGE_LIST', value: imageList]
   ]
 }
 
 def gitRepoAddTag(repoURL, repoName, tag, credentials, ref = "HEAD"){
-    git.checkoutGitRepository(repoName, repoURL, "master")
+    git.checkoutGitRepository(repoName, repoURL, "master", credentials)
     dir(repoName) {
-        def checkTag = sh "git tag -l ${tag}"
+        def checkTag = sh(script: "git tag -l ${tag}", returnStdout: true)
         if(checkTag == ""){
-            sh 'git tag -a ${tag} ${ref} -m "Release of mcp version ${tag}"'
+            sh "git tag -a ${tag} ${ref} -m \"Release of mcp version ${tag}\""
+        }else{
+            def currentTagRef = sh(script: "git rev-list -n 1 ${tag}", returnStdout: true)
+            if(currentTagRef.equals(ref)){
+                common.infoMsg("Tag is already on the right ref")
+                return
+            }
+            else{
+                sshagent([credentials]) {
+                    sh "git push --delete origin ${tag}"
+                }
+                sh "git tag --delete ${tag}"
+                sh "git tag -a ${tag} ${ref} -m \"Release of mcp version ${tag}\""
+            }
         }
         sshagent([credentials]) {
-            sh "git push origin master ${tag}"
+            sh "git push origin ${tag}"
         }
     }
 }
diff --git a/upgrade-mcp-release.groovy b/upgrade-mcp-release.groovy
new file mode 100644
index 0000000..0341263
--- /dev/null
+++ b/upgrade-mcp-release.groovy
@@ -0,0 +1,67 @@
+/**
+ *
+ * Update Salt environment pipeline
+ *
+ * Expected parameters:
+ *   SALT_MASTER_URL            Salt API server location
+ *   SALT_MASTER_CREDENTIALS    Credentials to the Salt API
+ *   MCP_VERSION                Version of MCP to upgrade to
+ *   UPDATE_LOCAL_REPOS         Update local repositories
+ */
+
+// Load shared libs
+def salt = new com.mirantis.mk.Salt()
+def common = new com.mirantis.mk.Common()
+def python = new com.mirantis.mk.Python()
+def venvPepper = "venvPepper"
+
+node("python") {
+    try {
+        python.setupPepperVirtualenv(venvPepper, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
+
+        stage("Update Reclass"){
+            common.infoMsg("Updating reclass model")
+            salt.cmdRun(venvPepper, "I@salt:master", 'cd /srv/salt/reclass && git pull -r && git submodule update', false)
+            salt.runSaltProcessStep(venvPepper, 'I@salt:master', 'cmd.run', ['reclass-salt --top'], null, true)
+            salt.enforceState(venvPepper, "I@salt:master", 'reclass', true)
+        }
+
+        if(UPDATE_LOCAL_REPOS.toBoolean()){
+            stage("Update local repos"){
+                common.infoMsg("Updating local repositories")
+                salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["aptly publish list --raw | awk '{print \$2, \$1}' | xargs -n2 aptly publish drop", 'runas=aptly'], null, true)
+                salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["aptly snapshot list --raw | grep -E '*' | xargs -n 1 aptly snapshot drop", 'runas=aptly'], null, true)
+                salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ["aptly mirror list --raw | grep -E '*' | xargs -n 1 aptly mirror drop", 'runas=aptly'], null, true)
+                salt.enforceState(venvPepper, '*apt*', 'aptly', true)
+                salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.script', ['salt://aptly/files/aptly_mirror_update.sh', "args=-sv", 'runas=aptly'], null, true)
+                salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.script', ['salt://aptly/files/aptly_publish_update.sh', "args=-acfrv", 'runas=aptly'], null, true)
+
+                salt.enforceState(venvPepper, '*apt*', 'docker.client.registry', true)
+
+                salt.enforceState(venvPepper, '*apt*', 'git server', true)
+
+                salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['pip2pi /srv/pypi_mirror/packages/ -r /srv/pypi_mirror/requirements.txt'], null, true)
+
+                salt.runSaltProcessStep(venvPepper, '*apt*', 'cmd.run', ['/srv/scripts/update-images.sh'], null, true)
+            }
+        }
+
+        stage("Update APT repos"){
+            common.infoMsg("Updating APT repositories")
+            salt.enforceState(venvPepper, "I@linux:system", 'linux.system.repo', true)
+        }
+
+        stage("Update formulas"){
+            common.infoMsg("Updating salt formulas")
+            salt.cmdRun(venvPepper, "I@salt:master", 'apt-get clean && apt-get update && apt-get install -y salt-formula-*')
+
+            common.infoMsg("Running salt sync-all")
+            salt.runSaltProcessStep(venvPepper, '*', 'saltutil.sync_all', [], null, true)
+        }
+    }
+    catch (Throwable e) {
+        // If there was an error or exception thrown, the build failed
+        currentBuild.result = "FAILURE"
+        throw e
+    }
+}
\ No newline at end of file