Improvements in pipeline-library: [minionsPresent]

* Replacing 10hr sleep with event based check for minions check
* Fixing minionsPresent function
  - wrong description
  - put a note that it uses an assumtion to get list from compound
  - fixing self object call (target should be master no pepperenv)
  - fixing inacurate function calls within minionsPresent function
* Addinf minionsPresentFromList function
  - it uses array to get list of minions
  - it does not truncate fqdn to shortname

Change-Id: Ida8d7ee4f0e1f42988c89486d1212b634217d4dd
diff --git a/src/com/mirantis/mk/Orchestrate.groovy b/src/com/mirantis/mk/Orchestrate.groovy
index a6630d3..231f83b 100644
--- a/src/com/mirantis/mk/Orchestrate.groovy
+++ b/src/com/mirantis/mk/Orchestrate.groovy
@@ -81,17 +81,59 @@
 }
 
 def installInfraKvm(master) {
+    def common = new com.mirantis.mk.Common()
     def salt = new com.mirantis.mk.Salt()
     salt.fullRefresh(master, 'I@linux:system')
+    def infra_conpund = 'I@salt:control'
+    def minions = []
+    def wait_timeout = 10
+    def retries = wait_timeout * 30
 
     salt.enforceState(master, 'I@salt:control', ['salt.minion'], true, false, null, false, 60, 2)
     salt.enforceState(master, 'I@salt:control', ['linux.system', 'linux.network', 'ntp', 'rsyslog'])
     salt.enforceState(master, 'I@salt:control', 'libvirt')
     salt.enforceState(master, 'I@salt:control', 'salt.control')
 
-    sleep(600)
+    timeout(wait_timeout) {
+        common.infoMsg("Waiting for minions to come up...")
+        if (salt.testTarget(master, infra_conpund)) {
+            // Gathering minions
+            for ( infra_node in salt.getMinionsSorted(master, infra_conpund) ) {
+                def pillar = salt.getPillar(master, infra_node, 'salt:control:cluster')
+                if ( !pillar['return'].isEmpty() ) {
+                    for ( cluster in pillar['return'][0].values() ) {
+                        def engine = cluster.values()[0]['engine']
+                        def domain = cluster.values()[0]['domain']
+                        def node = cluster.values()[0]['node']
+                        if ( engine == "virt" ) {
+                            def nodes = node.values()
+                            if ( !nodes.isEmpty() ) {
+                                for ( vm in nodes ) {
+                                    if ( vm['name'] != null ) {
+                                        def vm_fqdn = vm['name'] + '.' + domain
+                                        if ( !minions.contains(vm_fqdn) ) {
+                                            minions.add(vm_fqdn)
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
 
+        def minions_compound = minions.join(' or ')
+        common.infoMsg('Waiting for next minions to register: ' + minions_compound,)
+        salt.minionsPresentFromList(master, 'I@salt:master', minions, true, null, true, retries, 1)
+        common.infoMsg('Waiting for minions to respond')
+        salt.minionsReachable(master, 'I@salt:master', minions_compound )
+
+    }
+
+    common.infoMsg("All minions are up.")
     salt.fullRefresh(master, '* and not kvm*')
+
 }
 
 def installInfra(master) {
diff --git a/src/com/mirantis/mk/Salt.groovy b/src/com/mirantis/mk/Salt.groovy
index a1781cf..b587f1b 100644
--- a/src/com/mirantis/mk/Salt.groovy
+++ b/src/com/mirantis/mk/Salt.groovy
@@ -264,6 +264,7 @@
 def minionPresent(saltId, target, minion_name, waitUntilPresent = true, batch=null, output = true, maxRetries = 200, answers = 1) {
     minion_name = minion_name.replace("*", "")
     def common = new com.mirantis.mk.Common()
+    common.infoMsg("Looking for minion: " + minion_name)
     def cmd = 'salt-key | grep ' + minion_name
     if (waitUntilPresent){
         def count = 0
@@ -296,8 +297,8 @@
 }
 
 /**
- * Checks if salt minion is in a list of salt master's accepted keys
- * @usage minionPresent(saltId, 'I@salt:master', 'I@salt:minion', true, null, true, 200, 3)
+ * Checks if salt minions are in a list of salt master's accepted keys by matching compound
+ * @usage minionsPresent(saltId, 'I@salt:master', 'I@salt:minion', true, null, true, 200, 3)
  * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
  * @param target Performs tests on this target node
  * @param target_minions all targeted minions to test (for ex. I@salt:minion)
@@ -309,10 +310,31 @@
  * @return output of salt command
  */
 def minionsPresent(saltId, target = 'I@salt:master', target_minions = '', waitUntilPresent = true, batch=null, output = true, maxRetries = 200, answers = 1) {
-    def target_hosts = getMinionsSorted(pepperEnv, target_minions)
+    def target_hosts = getMinionsSorted(saltId, target_minions)
     for (t in target_hosts) {
-        def tgt = salt.stripDomainName(t)
-        salt.minionPresent(pepperEnv, target, tgt, waitUntilPresent, batch, output, maxRetries, answers)
+        def tgt = stripDomainName(t)
+        minionPresent(saltId, target, tgt, waitUntilPresent, batch, output, maxRetries, answers)
+    }
+}
+
+/**
+ * Checks if salt minions are in a list of salt master's accepted keys by matching a list
+ * @usage minionsPresentFromList(saltId, 'I@salt:master', ["cfg01.example.com", "bmk01.example.com"], true, null, true, 200, 3)
+ * @param saltId Salt Connection object or pepperEnv (the command will be sent using the selected method)
+ * @param target Performs tests on this target node
+ * @param target_minions list to test (for ex. ["cfg01.example.com", "bmk01.example.com"])
+ * @param waitUntilPresent return after the minion becomes present (default true)
+ * @param batch salt batch parameter integer or string with percents (optional, default null - disable batch)
+ * @param output print salt command (default true)
+ * @param maxRetries finite number of iterations to check status of a command (default 200)
+ * @param answers how many minions should return (optional, default 1)
+ * @return output of salt command
+ */
+def minionsPresentFromList(saltId, target = 'I@salt:master', target_minions = [], waitUntilPresent = true, batch=null, output = true, maxRetries = 200, answers = 1) {
+    def common = new com.mirantis.mk.Common()
+    for (tgt in target_minions) {
+        common.infoMsg("Checking if minion " + tgt + " is present")
+        minionPresent(saltId, target, tgt, waitUntilPresent, batch, output, maxRetries, answers)
     }
 }