Merge "Fixed null reference in test-salt-formulas pipeline"
diff --git a/cicd-lab-pipeline.groovy b/cicd-lab-pipeline.groovy
index 7cb6f55..cb8e951 100644
--- a/cicd-lab-pipeline.groovy
+++ b/cicd-lab-pipeline.groovy
@@ -163,6 +163,9 @@
             }
 
             stage("Deploy Docker services") {
+                // We need /etc/aptly-publisher.yaml to be present before
+                // services are deployed
+                salt.enforceState(saltMaster, 'I@aptly:publisher', 'aptly.publisher', true)
                 retry(3) {
                     sleep(5)
                     salt.enforceState(saltMaster, 'I@docker:swarm:role:master', 'docker.client')
diff --git a/cloud-deploy-pipeline.groovy b/cloud-deploy-pipeline.groovy
index 41e0cca..623a45d 100644
--- a/cloud-deploy-pipeline.groovy
+++ b/cloud-deploy-pipeline.groovy
@@ -17,6 +17,8 @@
  *   STACK_TEST                 Run tests (bool)
  *   STACK_CLEANUP_JOB          Name of job for deleting stack
  *
+ *   STACK_COMPUTE_COUNT        Number of compute nodes to launch
+ *
  *   AWS_STACK_REGION           CloudFormation AWS region
  *   AWS_API_CREDENTIALS        AWS Access key ID with  AWS secret access key
  *   AWS_SSH_KEY                AWS key pair name (used for SSH access)
@@ -50,6 +52,7 @@
 _MAX_PERMITTED_STACKS = 2
 overwriteFile = "/srv/salt/reclass/classes/cluster/override.yml"
 
+
 timestamps {
     node {
         try {
@@ -121,7 +124,6 @@
                     SALT_MASTER_URL = "http://${saltMasterHost}:6969"
                 } else if (STACK_TYPE == 'aws') {
 
-                    def venv_path = 'aws_venv'
 
                     if (STACK_REUSE.toBoolean() == true && STACK_NAME == '') {
                         error("If you want to reuse existing stack you need to provide it's name")
@@ -145,6 +147,7 @@
                     currentBuild.description = STACK_NAME
 
                     // prepare configuration
+                    def venv_path = 'aws_venv'
                     def env_vars = aws.getEnvVars(AWS_API_CREDENTIALS, AWS_STACK_REGION)
 
                     if (STACK_REUSE.toBoolean() == false) {
@@ -155,7 +158,10 @@
                         aws.setupVirtualEnv(venv_path)
 
                         // start stack
-                        def stack_params = ["ParameterKey=KeyName,ParameterValue=" + AWS_SSH_KEY]
+                        def stack_params = [
+                            "ParameterKey=KeyName,ParameterValue=" + AWS_SSH_KEY,
+                            "ParameterKey=CmpNodeCount,ParameterValue=" + STACK_COMPUTE_COUNT
+                        ]
                         def template_file = 'cfn/' + STACK_TEMPLATE + '.yml'
                         aws.createStack(venv_path, env_vars, template_file, STACK_NAME, stack_params)
                     }
@@ -207,14 +213,29 @@
 
                 stage('Install Kubernetes control') {
 
-                    // Overwrite Kubernetes vars if specified
-                    if (env.getEnvironment().containsKey("KUBERNETES_HYPERKUBE_IMAGE")) {
-                        salt.runSaltProcessStep(saltMaster, 'I@salt:master', 'file.append', overwriteFile, "    kubernetes_hyperkube_image: ${KUBERNETES_HYPERKUBE_IMAGE}")
-                    }
-
                     orchestrate.installKubernetesControl(saltMaster)
+
                 }
 
+                stage('Scale Kubernetes computes') {
+                    if (STACK_TYPE == 'aws') {
+                        // configure aws
+                        def venv_path = 'aws_venv'
+                        def env_vars = aws.getEnvVars(AWS_API_CREDENTIALS, AWS_STACK_REGION)
+
+                        // get stack info
+                        def scaling_group = aws.getOutputs(venv_path, env_vars, STACK_NAME, 'ComputesScalingGroup')
+
+                        //update autoscaling group
+                        aws.updateAutoscalingGroup(venv_path, env_vars, scaling_group, ["--desired-capacity " + STACK_COMPUTE_COUNT])
+
+                        // wait for computes to boot up
+                        sleep(120)
+                    }
+
+                    orchestrate.installKubernetesCompute(saltMaster)
+
+                }
 
                 if (common.checkContains('STACK_INSTALL', 'contrail')) {
                     state('Install Contrail for Kubernetes') {
diff --git a/lab-pipeline.groovy b/lab-pipeline.groovy
index 3522eac..2a95a49 100644
--- a/lab-pipeline.groovy
+++ b/lab-pipeline.groovy
@@ -44,8 +44,9 @@
  *   CALICO_CNI_IMAGE            Docker repository and tag for calico CNI image
  *   CALICO_NODE_IMAGE           Docker repository and tag for calico node image
  *   CALICOCTL_IMAGE             Docker repository and tag for calicoctl image
+ *   MTU                         MTU for Calico
  *   NETCHECKER_AGENT_IMAGE      Docker repository and tag for netchecker agent image
- *   NETCHECKER_SERVER_IMAGE      Docker repository and tag for netchecker server image
+ *   NETCHECKER_SERVER_IMAGE     Docker repository and tag for netchecker server image
  *
  */
 
@@ -117,7 +118,7 @@
                     // Verify possibility of create stack for given user and stack type
                     //
                     wrap([$class: 'BuildUser']) {
-                        if (env.BUILD_USER_ID && !env.BUILD_USER_ID.equals("jenkins") && !STACK_REUSE.toBoolean()) {
+                        if (env.BUILD_USER_ID && !env.BUILD_USER_ID.equals("jenkins") && !env.BUILD_USER_ID.equals("mceloud") && !STACK_REUSE.toBoolean()) {
                             def existingStacks = openstack.getStacksForNameContains(openstackCloud, "${env.BUILD_USER_ID}-${JOB_NAME}", openstackEnv)
                             if(existingStacks.size() >= _MAX_PERMITTED_STACKS){
                                 STACK_DELETE = "false"
@@ -183,6 +184,9 @@
                     if (env.getEnvironment().containsKey('KUBERNETES_HYPERKUBE_IMAGE')) {
                         salt.runSaltProcessStep(saltMaster, 'I@salt:master', 'reclass.cluster_meta_set', 'kubernetes_hyperkube_image', KUBERNETES_HYPERKUBE_IMAGE)
                     }
+                    if (env.getEnvironment().containsKey('MTU')) {
+                        salt.runSaltProcessStep(saltMaster, 'I@salt:master', 'reclass.cluster_meta_set', 'kubernetes_mtu', MTU)
+                    }
                     // Overwrite Calico vars if specified
                     if (env.getEnvironment().containsKey('CALICO_CNI_IMAGE')) {
                         salt.runSaltProcessStep(saltMaster, 'I@salt:master', 'reclass.cluster_meta_set', 'kubernetes_calico_cni_image', CALICO_CNI_IMAGE)
@@ -336,7 +340,7 @@
                 if (STACK_DELETE.toBoolean() == true) {
                     common.errorMsg('Heat job cleanup triggered')
                     stage('Trigger cleanup job') {
-                        build job: STACK_CLEANUP_JOB, parameters: [[$class: 'StringParameterValue', name: 'HEAT_STACK_NAME', value: STACK_NAME]]
+                        build job: STACK_CLEANUP_JOB, parameters: [[$class: 'StringParameterValue', name: 'STACK_NAME', value: STACK_NAME]]
                     }
                 } else {
                     if (currentBuild.result == 'FAILURE') {