Merge "Add correct salt minions update"
diff --git a/src/com/mirantis/mk/Debian.groovy b/src/com/mirantis/mk/Debian.groovy
index 6e74379..6d74ab0 100644
--- a/src/com/mirantis/mk/Debian.groovy
+++ b/src/com/mirantis/mk/Debian.groovy
@@ -294,9 +294,10 @@
common.retry(3, 5) {
salt.cmdRun(env, target, 'salt-call pkg.refresh_db failhard=true', true, batch)
}
+ /* first try to upgrade salt components since they demand asynchronous upgrade */
+ upgradeSaltPackages(env, target)
def cmd = "export DEBIAN_FRONTEND=noninteractive; apt-get -y -q --allow-downgrades -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" ${mode}"
salt.cmdRun(env, target, cmd, true, batch)
-
rebootRequired = salt.runSaltProcessStep(env, target, 'file.file_exists', ['/var/run/reboot-required'], batch, true, 5)['return'][0].values()[0].toBoolean()
if (rebootRequired) {
if (!postponeReboot) {
@@ -310,3 +311,36 @@
common.errorMsg("Invalid upgrade mode specified: ${mode}. Has to be 'upgrade' or 'dist-upgrade'")
}
}
+
+/**
+* Upgrade salt packages on target asynchronously, wait minions' availability.
+*
+* @param env Salt Connection object or env Salt command map
+* @param target Salt target to upgrade packages on.
+* @param timeout Sleep timeout when doing retries.
+* @param attempts Number of attemps to wait for.
+*/
+def upgradeSaltPackages(env, target, timeout=60, attempts=20) {
+ def common = new com.mirantis.mk.Common()
+ def salt = new com.mirantis.mk.Salt()
+ def saltUpgradeCmd =
+ 'export DEBIAN_FRONTEND=noninteractive; apt-get -y -q ' +
+ '-o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" ' +
+ 'install --only-upgrade salt-master salt-common salt-api salt-minion'
+
+ common.infoMsg("Upgrading SaltStack on ${target}")
+ salt.cmdRun(env, target, saltUpgradeCmd, false, null, true, [], [], true)
+ /* wait for 2 mins before checking the availability of minions to give
+ apt some time to finish updating so the dpkg releases its locks */
+ sleep(120)
+ /* taken from upgrade-mcp-release */
+ common.retry(attempts, timeout) {
+ salt.minionsReachable(env, 'I@salt:master', target)
+ def running = salt.runSaltProcessStep(env, target, 'saltutil.running', [], null, true, 5)
+ for (value in running.get("return")[0].values()) {
+ if (value != []) {
+ throw new Exception("Not all salt-minions are ready for execution")
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/mirantis/mk/Salt.groovy b/src/com/mirantis/mk/Salt.groovy
index 30957e5..2c58e9a 100644
--- a/src/com/mirantis/mk/Salt.groovy
+++ b/src/com/mirantis/mk/Salt.groovy
@@ -332,9 +332,10 @@
* @param output do you want to print output
* @param saltArgs additional salt args eq. ["runas=aptly"]
* @param replacing list with maps for deletion in info message (passwords, logins, etc)
+ * @param async run commands with async client (default false)
* @return output of salt command
*/
-def cmdRun(saltId, target, cmd, checkResponse = true, batch=null, output = true, saltArgs = [], replacing = []) {
+def cmdRun(saltId, target, cmd, checkResponse = true, batch=null, output = true, saltArgs = [], replacing = [], async = false) {
def common = new com.mirantis.mk.Common()
def originalCmd = cmd
common.infoSensitivityMsg("Running command ${cmd} on ${target}", true, replacing)
@@ -345,7 +346,8 @@
// add cmd name to salt args list
saltArgs << cmd
- def out = runSaltCommand(saltId, 'local', ['expression': target, 'type': 'compound'], 'cmd.run', batch, saltArgs.reverse())
+ def client = async ? 'local_async' : 'local'
+ def out = runSaltCommand(saltId, client, ['expression': target, 'type': 'compound'], 'cmd.run', batch, saltArgs.reverse())
if (checkResponse) {
// iterate over all affected nodes and check success return code
if (out["return"]){