[SCM] Samba Shared Repository - branch master updated

Jelmer Vernooij jelmer at samba.org
Sat Oct 2 21:24:34 MDT 2010


The branch, master has been updated
       via  60e25ab land: Force always emailing when there is no other mechanism of progress reporting.
       via  0bb970d land: Attach tarball of logs rather than individual logs to keep the mail size reasonable.
       via  997165b land: Some cosmetic fixes.
       via  288b217 land: Attach test output files to result emails.
       via  f6b254c land: Add --revision argument.
       via  d8e81a1 land-remote: Run remote land command unbuffered.
      from  0e11d18 s4-kdc Fix up after import of new lorikeet-heimdal

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 60e25ab06bfe4aefcb06c1376074d717460d67af
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Sun Oct 3 04:24:46 2010 +0200

    land: Force always emailing when there is no other mechanism of progress reporting.

commit 0bb970dd8126f939f8612ba05553a5715789facd
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Sun Oct 3 03:56:09 2010 +0200

    land: Attach tarball of logs rather than individual logs to keep the
    mail size reasonable.

commit 997165b23e98c3709c0e7d7eeecec8a96c8d0265
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Sun Oct 3 02:16:11 2010 +0200

    land: Some cosmetic fixes.

commit 288b217a8f6f26b9e22abc71c8e05d6368eaaf3f
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Sun Oct 3 01:31:11 2010 +0200

    land: Attach test output files to result emails.

commit f6b254c65d5e0cf33c56c666fb6bde1058288edf
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Sun Oct 3 00:50:53 2010 +0200

    land: Add --revision argument.

commit d8e81a19de99c6784267d45843b8295b4e40fc7c
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Sun Oct 3 00:10:47 2010 +0200

    land-remote: Run remote land command unbuffered.

-----------------------------------------------------------------------

Summary of changes:
 script/land-remote.py |   36 +++++++++++--
 script/land.py        |  140 +++++++++++++++++++++++++++++++++----------------
 2 files changed, 126 insertions(+), 50 deletions(-)


Changeset truncated at 500 lines:

diff --git a/script/land-remote.py b/script/land-remote.py
index 75f1b41..a705165 100755
--- a/script/land-remote.py
+++ b/script/land-remote.py
@@ -4,9 +4,12 @@
 # Published under the GPL, v3 or later
 
 import optparse
+import os
 import subprocess
 import sys
 
+samba_master = os.getenv('SAMBA_MASTER', 'git://git.samba.org/samba.git')
+
 parser = optparse.OptionParser("autoland-remote [options] [trees...]")
 parser.add_option("--remote-repo", help="Location of remote repository (default: temporary repository)", type=str, default=None)
 parser.add_option("--host", help="Host to land on (SSH connection string)", type=str, default="sn-devel-104.sn.samba.org")
@@ -14,11 +17,16 @@ parser.add_option("--foreground", help="Don't daemonize", action="store_true", d
 parser.add_option("--email", help="Email address to send build/test output to", type=str, default=None, metavar="EMAIL")
 parser.add_option("--always-email", help="always send email, even on success", action="store_true")
 parser.add_option("--rebase-master", help="rebase on master before testing", default=False, action='store_true')
+parser.add_option("--push-master", help="push to samba.org master on success",
+                  default=False, action='store_true')
+parser.add_option("--pushto", help="push to a git url on success",
+                  default=None, type='str')
 parser.add_option("--rebase", help="rebase on the given tree before testing", default=None, type='str')
 parser.add_option("--passcmd", help="command to run on success", default=None)
 parser.add_option("--tail", help="show output while running", default=False, action="store_true")
 parser.add_option("--keeplogs", help="keep logs", default=False, action="store_true")
 parser.add_option("--nocleanup", help="don't remove test tree", default=False, action="store_true")
+parser.add_option("--revision", help="revision to compile if not HEAD", default=None, type=str)
 parser.add_option("--fix-whitespace", help="fix whitespace on rebase",
                   default=False, action="store_true")
 parser.add_option("--fail-slowly", help="continue running tests even after one has already failed",
@@ -30,6 +38,10 @@ if not opts.foreground and not opts.email:
     print "Not running in foreground and --email not specified."
     sys.exit(1)
 
+if not opts.foreground and opts.push_master:
+    print "Unable to push to master when not running in foreground."
+    sys.exit(1)
+
 if not opts.remote_repo:
     print "%s$ mktemp -d" % opts.host
     f = subprocess.Popen(["ssh", opts.host, "mktemp", "-d"], stdout=subprocess.PIPE)
@@ -38,8 +50,9 @@ if not opts.remote_repo:
         sys.exit(1)
     remote_repo = stdout.rstrip()
     print "Remote tempdir: %s" % remote_repo
-    # Bootstrap, git.samba.org is close to sn-devel
-    remote_args = ["git", "clone", "git://git.samba.org/samba.git", remote_repo]
+    # Bootstrap, git.samba.org is usually more easily accessible.
+    #remote_args = ["git", "clone", samba_master, remote_repo]
+    remote_args = ["if [ -d /data/git/samba.git ]; then git clone --shared /data/git/samba.git %s; else git clone --shared %s %s; fi" % (remote_repo, samba_master, remote_repo)]
     #remote_args = ["git", "init", remote_repo]
     print "%s$ %s" % (opts.host, " ".join(remote_args))
     subprocess.check_call(["ssh", opts.host] + remote_args)
@@ -47,10 +60,20 @@ else:
     remote_repo = opts.remote_repo
 
 print "Pushing local branch"
-args = ["git", "push", "--force", "git+ssh://%s/%s" % (opts.host, remote_repo), "HEAD:land"]
+
+if opts.revision is not None:
+    revision = opts.revision
+else:
+    revision = "HEAD"
+args = ["git", "push", "--force", "git+ssh://%s/%s" % (opts.host, remote_repo), "%s:land" % revision]
 print "$ " + " ".join(args)
 subprocess.check_call(args)
-remote_args = ["cd", remote_repo, ";", "git", "checkout", "land", ";", "python", "./script/land.py", "--repository=%s" % remote_repo]
+remote_args = ["cd", remote_repo, ";", "git", "checkout", "land", ";", "python", "-u", "./script/land.py", "--repository=%s" % remote_repo]
+
+if (opts.email and not (opts.foreground or opts.pushto or opts.push_master)):
+    # Force always emailing if there's nothing else to do
+    opts.always_email = True
+
 if opts.email:
     remote_args.append("--email=%s" % opts.email)
 if opts.always_email:
@@ -71,6 +94,11 @@ if opts.rebase:
     remote_args.append("--rebase=%s" % opts.rebase)
 if opts.passcmd:
     remote_args.append("--passcmd=%s" % opts.passcmd)
+if opts.pushto:
+    remote_args.append("--pushto=%s" % opts.pushto)
+if opts.push_master:
+    remote_args.append("--push-master")
+
 remote_args += extra_args
 print "%s$ %s" % (opts.host, " ".join(remote_args))
 args = ["ssh", "-A", opts.host] + remote_args
diff --git a/script/land.py b/script/land.py
index 632f844..27dfaee 100755
--- a/script/land.py
+++ b/script/land.py
@@ -4,6 +4,7 @@
 # Copyright Jelmer Vernooij 2010
 # released under GNU GPL v3 or later
 
+from cStringIO import StringIO
 import fcntl
 from subprocess import call, check_call, Popen, PIPE
 import os, tarfile, sys, time
@@ -15,7 +16,9 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../lib/subunit/pytho
 import subunit
 import testtools
 import subunithelper
+from email.mime.application import MIMEApplication
 from email.mime.text import MIMEText
+from email.mime.multipart import MIMEMultipart
 
 samba_master = os.getenv('SAMBA_MASTER', 'git://git.samba.org/samba.git')
 samba_master_ssh = os.getenv('SAMBA_MASTER_SSH', 'git+ssh://git.samba.org/data/git/samba.git')
@@ -93,6 +96,12 @@ def run_cmd(cmd, dir=None, show=None, output=False, checkfail=True, shell=False)
         return call(cmd, cwd=dir, shell=shell)
 
 
+def clone_gitroot(test_master, revision="HEAD"):
+    run_cmd(["git", "clone", "--shared", gitroot, test_master])
+    if revision != "HEAD":
+        run_cmd(["git", "checkout", revision])
+
+
 class TreeStageBuilder(object):
     """Handle building of a particular stage for a tree.
     """
@@ -163,7 +172,8 @@ class SubunitTreeStageBuilder(TreeStageBuilder):
         self.subunit_path = os.path.join(gitroot,
             "%s.%s.subunit" % (self.tree.tag, self.name))
         self.tree.logfiles.append(
-            (self.subunit_path, os.path.basename(self.subunit_path)))
+            (self.subunit_path, os.path.basename(self.subunit_path),
+             "text/x-subunit"))
         self.subunit = open(self.subunit_path, 'w')
 
         formatter = subunithelper.PlainFormatter(False, True, {})
@@ -189,7 +199,6 @@ class SubunitTreeStageBuilder(TreeStageBuilder):
         except IOError:
             return None
         else:
-            self.tree.stdout.write(data)
             self.buffered += data
             buffered = ""
             for l in self.buffered.splitlines(True):
@@ -216,8 +225,10 @@ class TreeBuilder(object):
         self.next = 0
         self.stdout_path = os.path.join(gitroot, "%s.stdout" % (self.tag, ))
         self.stderr_path = os.path.join(gitroot, "%s.stderr" % (self.tag, ))
-        self.logfiles = [(self.stdout_path, os.path.basename(self.stdout_path)),
-                         (self.stderr_path, os.path.basename(self.stderr_path))]
+        self.logfiles = [
+            (self.stdout_path, os.path.basename(self.stdout_path), "text/plain"),
+            (self.stderr_path, os.path.basename(self.stderr_path), "text/plain"),
+            ]
         if options.verbose:
             print("stdout for %s in %s" % (self.name, self.stdout_path))
             print("stderr for %s in %s" % (self.name, self.stderr_path))
@@ -238,7 +249,7 @@ class TreeBuilder(object):
         cleanup_list.append(self.prefix)
         os.makedirs(self.sdir)
         run_cmd(["rm",  "-rf", self.sdir])
-        run_cmd(["git", "clone", "--shared", gitroot, self.sdir])
+        clone_gitroot(self.sdir, revision)
         self.start_next()
 
     def start_next(self):
@@ -262,7 +273,7 @@ class TreeBuilder(object):
         self.next += 1
 
     def remove_logs(self):
-        for path, name in self.logfiles:
+        for path, name, mime_type in self.logfiles:
             os.unlink(path)
 
     @property
@@ -360,15 +371,23 @@ class BuildList(object):
         self.kill_kids()
         return (0, None, None, None, "All OK")
 
-    def tarlogs(self, fname):
-        tar = tarfile.open(fname, "w:gz")
+    def tarlogs(self, name=None, fileobj=None):
+        tar = tarfile.open(name=name, fileobj=fileobj, mode="w:gz")
         for b in self.tlist:
-            for (path, name) in b.logfiles:
+            for (path, name, mime_type) in b.logfiles:
                 tar.add(path, arcname=name)
         if os.path.exists("autobuild.log"):
             tar.add("autobuild.log")
         tar.close()
 
+    def attach_logs(self, outer):
+        f = StringIO()
+        self.tarlogs(fileobj=f)
+        msg = MIMEApplication(f.getvalue(), "x-gzip")
+        msg.add_header('Content-Disposition', 'attachment',
+                       filename="logs.tar.gz")
+        outer.attach(msg)
+
     def remove_logs(self):
         for b in self.tlist:
             b.remove_logs()
@@ -421,13 +440,16 @@ def daemonize(logfile):
 
 def rebase_tree(url):
     print("Rebasing on %s" % url)
-    run_cmd(["git", "remote", "add", "-t", "master", "master", url], show=True, dir=test_master)
+    run_cmd(["git", "remote", "add", "-t", "master", "master", url], show=True,
+            dir=test_master)
     run_cmd(["git", "fetch", "master"], show=True, dir=test_master)
     if options.fix_whitespace:
-        run_cmd(["git", "rebase", "--whitespace=fix", "master/master"], show=True, dir=test_master)
+        run_cmd(["git", "rebase", "--whitespace=fix", "master/master"],
+                show=True, dir=test_master)
     else:
         run_cmd(["git", "rebase", "master/master"], show=True, dir=test_master)
-    diff = run_cmd(["git", "--no-pager", "diff", "HEAD", "master/master"], dir=test_master, output=True)
+    diff = run_cmd(["git", "--no-pager", "diff", "HEAD", "master/master"],
+        dir=test_master, output=True)
     if diff == '':
         print("No differences between HEAD and master/master - exiting")
         sys.exit(0)
@@ -435,49 +457,55 @@ def rebase_tree(url):
 def push_to(url):
     print("Pushing to %s" % url)
     if options.mark:
-        run_cmd("EDITOR=script/commit_mark.sh git commit --amend -c HEAD", dir=test_master, shell=True)
-        # the notes method doesn't work yet, as metze hasn't allowed refs/notes/* in master
-        # run_cmd("EDITOR=script/commit_mark.sh git notes edit HEAD", dir=test_master)
-    run_cmd(["git", "remote", "add", "-t", "master", "pushto", url], show=True, dir=test_master)
-    run_cmd(["git", "push", "pushto", "+HEAD:master"], show=True, dir=test_master)
+        run_cmd("EDITOR=script/commit_mark.sh git commit --amend -c HEAD",
+            dir=test_master, shell=True)
+        # the notes method doesn't work yet, as metze hasn't allowed
+        # refs/notes/* in master
+        # run_cmd("EDITOR=script/commit_mark.sh git notes edit HEAD",
+        #     dir=test_master)
+    run_cmd(["git", "remote", "add", "-t", "master", "pushto", url], show=True,
+        dir=test_master)
+    run_cmd(["git", "push", "pushto", "+HEAD:master"], show=True,
+        dir=test_master)
 
 def_testbase = os.getenv("AUTOBUILD_TESTBASE", "/memdisk/%s" % os.getenv('USER'))
 
 parser = OptionParser()
-parser.add_option("", "--repository", help="repository to run tests for", default=None, type=str)
-parser.add_option("", "--tail", help="show output while running", default=False, action="store_true")
-parser.add_option("", "--keeplogs", help="keep logs", default=False, action="store_true")
-parser.add_option("", "--nocleanup", help="don't remove test tree", default=False, action="store_true")
-parser.add_option("", "--testbase", help="base directory to run tests in (default %s)" % def_testbase,
+parser.add_option("--repository", help="repository to run tests for", default=None, type=str)
+parser.add_option("--revision", help="revision to compile if not HEAD", default=None, type=str)
+parser.add_option("--tail", help="show output while running", default=False, action="store_true")
+parser.add_option("--keeplogs", help="keep logs", default=False, action="store_true")
+parser.add_option("--nocleanup", help="don't remove test tree", default=False, action="store_true")
+parser.add_option("--testbase", help="base directory to run tests in (default %s)" % def_testbase,
                   default=def_testbase)
-parser.add_option("", "--passcmd", help="command to run on success", default=None)
-parser.add_option("", "--verbose", help="show all commands as they are run",
+parser.add_option("--passcmd", help="command to run on success", default=None)
+parser.add_option("--verbose", help="show all commands as they are run",
                   default=False, action="store_true")
-parser.add_option("", "--rebase", help="rebase on the given tree before testing",
+parser.add_option("--rebase", help="rebase on the given tree before testing",
                   default=None, type='str')
-parser.add_option("", "--rebase-master", help="rebase on %s before testing" % samba_master,
+parser.add_option("--rebase-master", help="rebase on %s before testing" % samba_master,
                   default=False, action='store_true')
-parser.add_option("", "--pushto", help="push to a git url on success",
+parser.add_option("--pushto", help="push to a git url on success",
                   default=None, type='str')
-parser.add_option("", "--push-master", help="push to %s on success" % samba_master_ssh,
+parser.add_option("--push-master", help="push to %s on success" % samba_master_ssh,
                   default=False, action='store_true')
-parser.add_option("", "--mark", help="add a Tested-By signoff before pushing",
+parser.add_option("--mark", help="add a Tested-By signoff before pushing",
                   default=False, action="store_true")
-parser.add_option("", "--fix-whitespace", help="fix whitespace on rebase",
+parser.add_option("--fix-whitespace", help="fix whitespace on rebase",
                   default=False, action="store_true")
-parser.add_option("", "--retry", help="automatically retry if master changes",
+parser.add_option("--retry", help="automatically retry if master changes",
                   default=False, action="store_true")
-parser.add_option("", "--email", help="send email to the given address on failure",
+parser.add_option("--email", help="send email to the given address on failure",
                   type='str', default=None)
-parser.add_option("", "--always-email", help="always send email, even on success",
+parser.add_option("--always-email", help="always send email, even on success",
                   action="store_true")
-parser.add_option("", "--daemon", help="daemonize after initial setup",
+parser.add_option("--daemon", help="daemonize after initial setup",
                   action="store_true")
-parser.add_option("", "--fail-slowly", help="continue running tests even after one has already failed",
+parser.add_option("--fail-slowly", help="continue running tests even after one has already failed",
                   action="store_true")
 
 
-def email_failure(status, failed_task, failed_stage, failed_tag, errstr):
+def email_failure(blist, status, failed_task, failed_stage, failed_tag, errstr):
     '''send an email to options.email about the failure'''
     user = os.getenv("USER")
     text = '''
@@ -505,18 +533,26 @@ The top commit for the tree that was built was:
 
 %s
 
-''' % (failed_task, errstr, user, failed_tag, user, failed_tag, user, user, top_commit_msg)
-    msg = MIMEText(text)
-    msg['Subject'] = 'autobuild failure for task %s during %s' % (failed_task, failed_stage)
+''' % (failed_task, errstr, user, failed_tag, user, failed_tag, user, user,
+       get_top_commit_msg(test_master))
+
+    msg = MIMEMultipart()
+    msg['Subject'] = 'autobuild failure for task %s during %s' % (
+        failed_task, failed_stage)
     msg['From'] = 'autobuild at samba.org'
     msg['To'] = options.email
 
+    main = MIMEText(text)
+    msg.attach(main)
+
+    blist.attach_logs(msg)
+
     s = smtplib.SMTP()
     s.connect()
     s.sendmail(msg['From'], [msg['To']], msg.as_string())
     s.quit()
 
-def email_success():
+def email_success(blist):
     '''send an email to options.email about a successful build'''
     user = os.getenv("USER")
     text = '''
@@ -539,13 +575,18 @@ you can get full logs of all tasks in this job here:
 The top commit for the tree that was built was:
 
 %s
-''' % top_commit_msg
+''' % (get_top_commit_msg(test_master),)
 
-    msg = MIMEText(text)
+    msg = MIMEMultipart()
     msg['Subject'] = 'autobuild success'
     msg['From'] = 'autobuild at samba.org'
     msg['To'] = options.email
 
+    main = MIMEText(text, 'plain')
+    msg.attach(main)
+
+    blist.attach_logs(msg)
+
     s = smtplib.SMTP()
     s.connect()
     s.sendmail(msg['From'], [msg['To']], msg.as_string())
@@ -571,7 +612,13 @@ if gitroot is None:
     raise Exception("Failed to find git root under %s" % repository)
 
 # get the top commit message, for emails
-top_commit_msg = run_cmd(["git", "log", "-1"], dir=gitroot, output=True)
+if options.revision is not None:
+    revision = options.revision
+else:
+    revision = "HEAD"
+
+def get_top_commit_msg(reporoot):
+    return run_cmd(["git", "log", "-1"], dir=reporoot, output=True)
 
 try:
     os.makedirs(testbase)
@@ -588,7 +635,7 @@ while True:
     try:
         run_cmd(["rm", "-rf", test_master])
         cleanup_list.append(test_master)
-        run_cmd(["git", "clone", "--shared", gitroot, test_master])
+        clone_gitroot(test_master, revision)
     except:
         cleanup()
         raise
@@ -627,7 +674,7 @@ if status == 0:
         blist.tarlogs("logs.tar.gz")
         print("Logs in logs.tar.gz")
     if options.always_email:
-        email_success()
+        email_success(blist)
     blist.remove_logs()
     cleanup()
     print(errstr)
@@ -636,7 +683,8 @@ else:
     blist.tarlogs("logs.tar.gz")
 
     if options.email is not None:
-        email_failure(status, failed_task, failed_stage, failed_tag, errstr)
+        email_failure(blist, status, failed_task, failed_stage, failed_tag,
+            errstr)
 
     cleanup()
     print(errstr)


-- 
Samba Shared Repository


More information about the samba-cvs mailing list