Muehlenhoff has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/236562

Change subject: Use compound matching for minion targeting
......................................................................

Use compound matching for minion targeting

Change-Id: Ieb65c3d4d0af2c3e8784e3ec7340df9f7afc54ef
---
M debian/changelog
M docs/TODO
M master/debdeploy
3 files changed, 84 insertions(+), 77 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/operations/debs/debdeploy 
refs/changes/62/236562/1

diff --git a/debian/changelog b/debian/changelog
index 15cd1bb..b0cbe9f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,8 @@
 
   * Add a Salt returner for local logging
   * Add workaround for Salt bug writing out it's return status to stdout
+  * Use compound matching to properly support server groups with
+    overlapping grains
 
  -- Moritz Muehlenhoff <[email protected]>  Mon, 07 Sep 2015 15:20:01 
+0200
 
diff --git a/docs/TODO b/docs/TODO
index 24053d5..95272f6 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -7,7 +7,6 @@
 - Add a command to generate a YAML file interactively
 - Write initiated deployment jobs into a logfile
 - Provide logrotate configs
-- Display a warning if a host matches twice for a given grain
 
 New feature work:
 - Central package database to easily search for affected binary packages
diff --git a/master/debdeploy b/master/debdeploy
index c22d292..6559956 100755
--- a/master/debdeploy
+++ b/master/debdeploy
@@ -47,90 +47,91 @@
                 print opt.updatefile, "hasn't been deployed yet for this 
server group (identified by grain", i, ")"
                 sys.exit(0)
 
+        # The jid is identical for all minions in a debdeploy run
         if rollback_mode:
             jid = joblogdb.get_rollbackid(opt.updatefile, i)
         else:
             jid = joblogdb.get_jobid(opt.updatefile, i)
 
-        # SaltRunner always emits its status on stdout, 
https://github.com/saltstack/salt/issues/21392
-        # Can be dropped once fixed upstream
-        with open('/dev/null', 'w') as discard_output:
-            oldstdout = sys.stdout
-            sys.stdout = discard_output
-            job = runner.cmd('jobs.print_job', (jid,))
-            sys.stdout = oldstdout
-        if not job:
-            print "Job " + str(jid) + " hasn't finished yet, please check 
again later"
-            sys.exit(0)
+    # SaltRunner always emits its status on stdout, 
https://github.com/saltstack/salt/issues/21392
+    # Can be dropped once fixed upstream
+    with open('/dev/null', 'w') as discard_output:
+        oldstdout = sys.stdout
+        sys.stdout = discard_output
+        job = runner.cmd('jobs.print_job', (jid,))
+        sys.stdout = oldstdout
+    if not job:
+        print "Job " + str(jid) + " hasn't finished yet, please check again 
later"
+        sys.exit(0)
 
-        res = job[jid]['Result']
-        if not res:
-            print "Job hasn't finished yet, please check again later"
-            sys.exit(0)
+    res = job[jid]['Result']
+    if not res:
+        print "Job hasn't finished yet, please check again later"
+        sys.exit(0)
 
-        amount_of_hosts += len(res.keys())
+    amount_of_hosts += len(res.keys())
 
-        for host in res:
-            added = res[host]['return']['additions']
-            removed = res[host]['return']['removals']
-            updated = res[host]['return']['updated']
-            restart = res[host]['return']['restart']
+    for host in res:
+        added = res[host]['return']['additions']
+        removed = res[host]['return']['removals']
+        updated = res[host]['return']['updated']
+        restart = res[host]['return']['restart']
 
-            print host + ":"
-            if added:
-                print "  Added packages:", host['return']['additions']
-                for added_pkg in host['return']['additions']:
-                    if not add_cnt.get(added_pkg, None):
-                        add_cnt[added_pkg] = 1
-                    else:
-                        add_cnt[added_pkg] += 1
-
-            elif removed:
-                print "  Removed packages:", host['return']['removals']
-                for removed_pkg in host['return']['removals']:
-                    if not remove_cnt.get(removed_pkg, None):
-                        remove_cnt[removed_pkg] = 1
-                    else:
-                        remove_cnt[removed_pkg] += 1
-
-            elif len(updated.keys()) > 0:
-                print "  Updated packages:"
-                for k in updated:
-                    print "    " + k + ": " + updated[k][0] + " -> " + 
updated[k][1]
-
-                    updated_idx = k + ": " + updated[k][0] + " -> " + 
updated[k][1]
-                    if not update_cnt.get(updated_idx, None):
-                        update_cnt[updated_idx] = 1
-                    else:
-                        update_cnt[updated_idx] += 1
-
-            else:
-                print "  No change"
-
-
-            if restart:
-                for process in restart:
-                    if len(process) > 0:
-                        if not restart_cnt.get(process, None):
-                            restart_cnt[process] = 1
-                        else:
-                            restart_cnt[process] += 1
-
-            # Detect installation errors and collect them to display an error 
list
-            # across all Salt grains
-            # apt doesn't provide more fine-grained error reporting other than
-            # 0/success and 100/error, so we need to parse stderr for some 
common
-            # error patterns
-            if res[host]['return']['aptreturn'] == 100:
-                if res[host]['return']['apterrlog'].find("Could not get lock 
/var/lib/dpkg/lock") != -1:
-                    install_errors.append(host + ": The dpkg status database 
is locked, possibly a conflicting package installation")
+        print host + ":"
+        if added:
+            print "  Added packages:", host['return']['additions']
+            for added_pkg in host['return']['additions']:
+                if not add_cnt.get(added_pkg, None):
+                    add_cnt[added_pkg] = 1
                 else:
-                    install_errors.append(host + ": Unknown installation 
error")
+                    add_cnt[added_pkg] += 1
 
-            if opt.verbose:
-                print
-                indented = ['  ' + l for l in 
res[host]['return']['aptlog'].splitlines()]
-                print "\n".join(indented)
+        elif removed:
+            print "  Removed packages:", host['return']['removals']
+            for removed_pkg in host['return']['removals']:
+                if not remove_cnt.get(removed_pkg, None):
+                    remove_cnt[removed_pkg] = 1
+                else:
+                    remove_cnt[removed_pkg] += 1
+
+        elif len(updated.keys()) > 0:
+            print "  Updated packages:"
+            for k in updated:
+                print "    " + k + ": " + updated[k][0] + " -> " + 
updated[k][1]
+
+                updated_idx = k + ": " + updated[k][0] + " -> " + updated[k][1]
+                if not update_cnt.get(updated_idx, None):
+                    update_cnt[updated_idx] = 1
+                else:
+                    update_cnt[updated_idx] += 1
+
+        else:
+            print "  No change"
+
+
+        if restart:
+            for process in restart:
+                if len(process) > 0:
+                    if not restart_cnt.get(process, None):
+                        restart_cnt[process] = 1
+                    else:
+                        restart_cnt[process] += 1
+
+        # Detect installation errors and collect them to display an error list
+        # across all Salt grains
+        # apt doesn't provide more fine-grained error reporting other than
+        # 0/success and 100/error, so we need to parse stderr for some common
+        # error patterns
+        if res[host]['return']['aptreturn'] == 100:
+            if res[host]['return']['apterrlog'].find("Could not get lock 
/var/lib/dpkg/lock") != -1:
+                install_errors.append(host + ": The dpkg status database is 
locked, possibly a conflicting package installation")
+            else:
+                install_errors.append(host + ": Unknown installation error")
+
+        if opt.verbose:
+            print
+            indented = ['  ' + l for l in 
res[host]['return']['aptlog'].splitlines()]
+            print "\n".join(indented)
 
     print 
     print 
@@ -200,7 +201,7 @@
     print "Rolling out", source, ":",
     print update_desc[update_type]
 
-
+    target = ""
     if update_type in ["daemon-cluster", "reboot", "reboot-cluster"]:
         print "Not implemented yet"
         sys.exit(1)
@@ -216,8 +217,13 @@
 
         if opt.verbose:
             print "Grain:", i
-        jid = client.cmd_async(i, 'debdeploy-minion.deploy', [source, 
update_type, update.fixes], expr_form='grain', ret='debdeploy-log')
-        logging.info("Initiated rollout for " + source + " on grain " + i + 
"(salt job id: " + str(jid) + ")")
+
+        target += 'G@' + i + ' or '
+
+    target = target[:-4]
+    jid = client.cmd_async(target, 'debdeploy-minion.deploy', [source, 
update_type, update.fixes], expr_form='compound', ret='debdeploy-log')
+    logging.info("Initiated rollout for " + source + " on grain compound " + 
target + "(salt job id: " + str(jid) + ")")
+    for i in grains:
         joblogdb.add_job(update_file, i, jid)
 
 

-- 
To view, visit https://gerrit.wikimedia.org/r/236562
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ieb65c3d4d0af2c3e8784e3ec7340df9f7afc54ef
Gerrit-PatchSet: 1
Gerrit-Project: operations/debs/debdeploy
Gerrit-Branch: master
Gerrit-Owner: Muehlenhoff <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to