python3
authorparmentelat <thierry.parmentelat@inria.fr>
Thu, 6 Dec 2018 15:17:05 +0000 (16:17 +0100)
committerparmentelat <thierry.parmentelat@inria.fr>
Thu, 6 Dec 2018 15:17:05 +0000 (16:17 +0100)
build-conf-planetlab.py [deleted file]
lbuild-bridge.sh
lbuild-initvm.sh
lbuild-nightly.sh
module-log.py
run-nightlies.py [deleted file]
spec2make.py

diff --git a/build-conf-planetlab.py b/build-conf-planetlab.py
deleted file mode 100755 (executable)
index 69d1bfb..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/python
-###
-# Nightly build spec HOWTO
-#
-# *  To add a 'build spec', define a dictionary as in the following examples, filling in the values you would like to override in the defaults. Any values you leave out
-# will get picked up from the defaults at the bottom of this fiel.
-#
-# *  A build spec may define multiple builds encapsulating various combinations of the available parameter options. To do so, 
-# set a parameter to a list, and the parent script will automatically turn it into the combinations it encloses. e.g., the following
-# build spec defines 6 separate builds:
-#
-# my_build = {
-#   'fcdistro':['centos5','f8','f10'],
-#   'personality':['linux32','linux65']
-#
-# * If your parameters have dependencies - e.g. you only want to build the linu64 personality on f10, then define the parameter as a lambda operating
-# on the current build spec. e.g. in this case, it would be to the effect of lambda (build): if (build['fcdistro']=='f10') then ['linux32','linux64'] else ['linux32']
-#
-
-#caglar_k32_build = {
-#      'tags':'planetlab-k32-tags.mk',
-#      'fcdistro':['f12', 'centos5','f8'],
-#      'personality':['linux32','linux64'],
-#      'test':0,
-#      'release':'k32'
-#}
-
-sapans_k27_build = {
-       'tags':'planetlab-k27-tags.mk',
-       'fcdistro':['f12', 'centos5','f8'],
-       'personality':['linux32','linux64'],
-       'test':0,
-       'release':'k27'
-}
-
-marcs_k22_build = {
-       'tags':'planetlab-tags.mk',
-       'fcdistro':['f12', 'centos5','f8'],
-       'personality':['linux32','linux64'],
-       'test': 0,
-       'release':'k22',
-}
-
-###
-#
-# DEFAULTS 
-#
-# Any values that you leave out from the above specs will get filled in by the defaults specified below.
-# You shouldn't need to modify these values to add new builds
-
-__personality_to_arch__={'linux32':'i386','linux64':'x86_64'}
-__flag_to_test__={0:'-B', 1:''}
-
-def __check_out_build_script__(build):
-    import os
-    tmpname = os.popen('mktemp -d /tmp/'+build['build-script']+'.XXXXXX').read().rstrip('\n')
-    os.system("git clone --depth 1 %s %s" % (build['scmpath'], tmpname))
-    return "%s/%s" % (tmpname, build['build-script'])
-
-def __today__():
-    import datetime
-    return datetime.datetime.now().strftime("%Y-%m-%d")
-
-__default_build__ = {
-
-### Simple parameters
-    'tags':'planetlabs-tags.mk',
-    'fcdistro':'centos5',
-    'personality':'linux32',
-    'test':0,
-    'release':'k22',
-       'path':'/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin',
-       'sh':'/bin/bash',
-       'mailto':'build@lists.planet-lab.org',
-       'build-script':'vbuild-nightly.sh',
-       'webpath':'/vservers/build.planet-lab.org/var/www/html/install-rpms/archive',
-       'pldistro':'planetlab',
-       'date': __today__(),
-       'scmpath':'git://git.planet-lab.org/build.git',
-    'personality':'linux32',
-    'myplcversion':'4.3',
-
-### Parameters with dependencies: define paramater mappings as lambdas here
-
-    'arch':lambda build: __personality_to_arch__[build['personality']],
-    'runtests':lambda build: __flag_to_test__[build['test']],
-    'vbuildnightly':lambda build: __check_out_build_script__(build)
-}
index b0e3658..d3b2ab7 100755 (executable)
@@ -1,29 +1,30 @@
 #!/bin/bash
 
-# taking this bridge-initialization code out of lbuild-initvm.sh 
-# so we can use it on our libvirt/lxc local infra 
-# there's something very similar in 
+# taking this bridge-initialization code out of lbuild-initvm.sh
+# so we can use it on our libvirt/lxc local infra
+# there's something very similar in
 # tests/system/template-qemu/qemu-bridge-init
-# that the current code was actually based on, but 
-# nobody was ever bold enough to reconcile these two 
+# that the current code was actually based on, but
+# nobody was ever bold enough to reconcile these two
 
-# hard-wired 
+# hard-wired
 DEFAULT_PUBLIC_BRIDGE=br0
 
 ##############################
 # use /proc/net/dev instead of a hard-wired list
 function gather_interfaces () {
-    python <<EOF
-for line in file("/proc/net/dev"):
+    python3 <<EOF
+with open("/proc/net/dev") as feed:
+  for line in feed:
     if ':' not in line: continue
-    ifname=line.replace(" ","").split(":")[0]
-    if ifname.find("lo")==0: continue
-    if ifname.find("br")==0: continue
-    if ifname.find("virbr")==0: continue
-    if ifname.find("veth")==0: continue
-    if ifname.find("tap")==0: continue
-    if ifname.find("vif")==0: continue
-    print ifname
+    ifname = line.replace(" ","").split(":")[0]
+    if ifname.startswith("lo"): continue
+    if ifname.startswith("br"): continue
+    if ifname.startswith("virbr"): continue
+    if ifname.startswith("veth"): continue
+    if ifname.startswith("tap"): continue
+    if ifname.startswith("vif"): continue
+    print(ifname)
 EOF
 }
 
@@ -87,7 +88,7 @@ function create_bridge_if_needed() {
     sysctl net.bridge.bridge-nf-call-ip6tables=0
     sysctl net.bridge.bridge-nf-call-arptables=0
 
-    
+
     #Getting host IP/masklen
     address=$(ip addr show $if_lan | grep -v inet6 | grep inet | head --lines=1 | awk '{print $2;}')
     [ -z "$address" ] && { echo "ERROR: Could not determine IP address for $if_lan" ; exit 1 ; }
@@ -106,7 +107,7 @@ function create_bridge_if_needed() {
     echo "Activating promiscuous mode if_lan=$if_lan"
     ip link set $if_lan up promisc on
     sleep 2
-    # rely on dhcp to re assign IP.. 
+    # rely on dhcp to re assign IP..
     echo "Starting dhclient on $public_bridge"
     dhclient $public_bridge
     sleep 1
@@ -136,7 +137,7 @@ function create_bridge_if_needed() {
 }
 
 function main () {
-    if [[ -n "$@" ]] ; then 
+    if [[ -n "$@" ]] ; then
         public_bridge="$1"; shift
     else
         public_bridge="$DEFAULT_PUBLIC_BRIDGE"
index e4d3c6a..2725f0b 100755 (executable)
@@ -57,22 +57,21 @@ function gethostbyname () {
 # e.g. 21 -> 255.255.248.0
 function masklen_to_netmask () {
     local masklen=$1; shift
-    python <<EOF
+    python3 <<EOF
 import sys
-masklen=$masklen
-if not (masklen>=1 and masklen<=32):
-  print "Wrong masklen",masklen
+masklen = $masklen
+if not (1 <= masklen <= 32):
+  print("Wrong masklen", masklen)
   exit(1)
-result=[]
+result = []
 for i in range(4):
-    if masklen>=8:
+    if masklen >= 8:
        result.append(8)
-       masklen-=8
+       masklen -= 8
     else:
        result.append(masklen)
-       masklen=0
-print ".".join([ str(256-2**(8-i)) for i in result ])
-
+       masklen = 0
+print(".".join([ str(256-2**(8-i)) for i in result ]))
 EOF
 }
 
index 715d368..b8bdf44 100755 (executable)
@@ -72,27 +72,28 @@ function guest_ipv4() {
 function summary () {
     from=$1; shift
     echo "******************** BEG SUMMARY"
-    python - $from <<EOF
-#!/usr/bin/env python
+    python3 - $from <<EOF
+#!/usr/bin/env python3
 # read a full log and tries to extract the interesting stuff
 
-import sys,re
-m_show_line=re.compile(".* (BEG|END) (RPM|LXC).*|.*'boot'.*|\* .*| \* .*|.*is not installed.*|.*PROPFIND.*|.* (BEG|END).*:run_log.*|.* Within LXC (BEG|END) .*|.* MAIN (BEG|END).*")
-m_installing_any=re.compile('\r  (Installing:[^\]]*]) ')
-m_installing_err=re.compile('\r  (Installing:[^\]]*])(..+)')
-m_installing_end=re.compile('Installed:.*')
-m_installing_doc1=re.compile("(.*)install-info: No such file or directory for /usr/share/info/\S+(.*)")
-m_installing_doc2=re.compile("(.*)grep: /usr/share/info/dir: No such file or directory(.*)")
+import sys, re
+m_show_line = re.compile(
+".* (BEG|END) (RPM|LXC).*|.*'boot'.*|\* .*| \* .*|.*is not installed.*|.*PROPFIND.*|.* (BEG|END).*:run_log.*|.* Within LXC (BEG|END) .*|.* MAIN (BEG|END).*")
+m_installing_any = re.compile('\r  (Installing:[^\]]*]) ')
+m_installing_err = re.compile('\r  (Installing:[^\]]*])(..+)')
+m_installing_end = re.compile('Installed:.*')
+m_installing_doc1 = re.compile("(.*)install-info: No such file or directory for /usr/share/info/\S+(.*)")
+m_installing_doc2 = re.compile("(.*)grep: /usr/share/info/dir: No such file or directory(.*)")
 
 def summary (filename):
 
     try:
-        if filename=="-":
-            filename="stdin"
-            f=sys.stdin
+        if filename == "-":
+            filename = "stdin"
+            f = sys.stdin
         else:
-            f=open(filename)
-        echo=False
+            f = open(filename)
+        echo = False
         for line in f.xreadlines():
             # first off : discard warnings related to doc
             if m_installing_doc1.match(line):
@@ -103,12 +104,12 @@ def summary (filename):
                 line=begin+end
             # unconditionnally show these lines
             if m_show_line.match(line):
-                print '>>>',line,
+                print('>>>', line, end="")
             # an 'installing' line with messages afterwards : needs to be echoed
             elif m_installing_err.match(line):
                 (installing,error)=m_installing_err.match(line).groups()
-                print '>>>',installing
-                print '>>>',error
+                print('>>>',installing)
+                print('>>>',error)
                 echo=True
             # closing an 'installing' section
             elif m_installing_end.match(line):
@@ -117,14 +118,14 @@ def summary (filename):
             elif m_installing_any.match(line):
                 if echo:
                     installing=m_installing_any.match(line).group(1)
-                    print '>>>',installing
+                    print('>>>',installing)
                 echo=False
             # print lines when echo is true
             else:
-                if echo: print '>>>',line,
+                if echo: print('>>>',line, end="")
         f.close()
     except:
-        print 'Failed to analyze',filename
+        print('Failed to analyze',filename)
 
 for arg in sys.argv[1:]:
     summary(arg)
index 2241460..c9f7771 100755 (executable)
@@ -1,5 +1,4 @@
-#!/usr/bin/python
-# -*- mode:python; var: python-guess-indent:false; python-indent:4; -*-
+#!/usr/bin/python3
 
 import os
 import sys
@@ -7,190 +6,204 @@ import re
 from optparse import OptionParser
 
 modules_map = {
-    'general' : [ 'build', 'tests', ],
-    'server' : ['Monitor', 'MyPLC', 'PLCAPI', 'PLCRT', 'PLCWWW', 'PLEWWW', 'www-register-wizard', 
-               'PXEService', 'drupal', 'plcmdline',],
-    'node': [ 'linux-2.6', 'util-vserver', 'util-vserver-pl', 'chopstix-L0', 
-             'BootCD', 'BootManager', 'BootstrapFS', 'VserverReference', 
-             'DistributedRateLimiting', 'Mom', 'PingOfDeath', 
-             'NodeManager', 'NodeManager-optin', 'NodeManager-topo', 
-             'NodeUpdate', 'CoDemux', 
-             'nodeconfig', 'pl_sshd', 
-             'libnl', 'pypcilib', 'pyplnet',],
-    'wifi' : ['madwifi', 'PlanetBridge', 'hostapd',],
+    'general': ['build', 'tests', ],
+    'server': ['Monitor', 'MyPLC', 'PLCAPI', 'PLCRT', 'PLCWWW', 'PLEWWW', 'www-register-wizard',
+               'PXEService', 'drupal', 'plcmdline', ],
+    'node': ['linux-2.6', 'util-vserver', 'util-vserver-pl', 'chopstix-L0',
+             'BootCD', 'BootManager', 'BootstrapFS', 'VserverReference',
+             'DistributedRateLimiting', 'Mom', 'PingOfDeath',
+             'NodeManager', 'NodeManager-optin', 'NodeManager-topo',
+             'NodeUpdate', 'CoDemux',
+             'nodeconfig', 'pl_sshd',
+             'libnl', 'pypcilib', 'pyplnet', ],
+    'wifi': ['madwifi', 'PlanetBridge', 'hostapd', ],
     'emulation': ['dummynet_image', 'ipfw', ],
-    'netflow' : [ 'fprobe-ulog', 'pf2gui', 'pf2monitor', 'pf2slice', 'iproute2', 'iptables', 'silk',],
-    'sfa' : [ 'sfa', 'xmlrspecs', 'pyopenssl', ],
-    'vsys' : ['vsys', 'vsys-scripts', 'vsys-wrappers', 'inotify-tools'],
-    'deprecated' : [ 'proper', 'libhttpd++', 'oombailout', 'ulogd', 'patchdep', 'pdelta', 
-                    'sandbox', 'playground', 'infrastructure', 'util-python', 'vnetspec', 
-                    ],
-    }
+    'netflow': ['fprobe-ulog', 'pf2gui', 'pf2monitor', 'pf2slice', 'iproute2', 'iptables', 'silk', ],
+    'sfa': ['sfa', 'xmlrspecs', 'pyopenssl', ],
+    'vsys': ['vsys', 'vsys-scripts', 'vsys-wrappers', 'inotify-tools'],
+    'deprecated': ['proper', 'libhttpd++', 'oombailout', 'ulogd', 'patchdep', 'pdelta',
+                   'sandbox', 'playground', 'infrastructure', 'util-python', 'vnetspec',
+                   ],
+}
+
+epoch = '{2007-07-01}'
 
-epoch='{2007-07-01}'
 
 class ModuleHistory:
 
-    def __init__ (self, name, options):
-       self.name=name
-       self.options=options
-       self.user_commits=[]
-       self.user_revs={}
-       self.current_rev=None
-       self.current_user=None
-       
-    valid=re.compile('\Ar[0-9]+ \|')
-    tagging=re.compile('\ATagging|\ASetting tag')
+    def __init__(self, name, options):
+        self.name = name
+        self.options = options
+        self.user_commits = []
+        self.user_revs = {}
+        self.current_rev = None
+        self.current_user = None
+
+    valid = re.compile(r'\Ar[0-9]+ \|')
+    tagging = re.compile(r'\ATagging|\ASetting tag')
 
     @staticmethod
-    def sort ( (u1,c1), (u2,c2) ): return c2-c1
+    def sort_key(u, c):
+        return c
 
-    def record(self,user,rev):
-       try:
-           self.user_revs[user].append(rev)
-       except:
-           self.user_revs[user] = [rev]
-       self.current_rev=rev
-       self.current_user=user
+    def record(self, user, rev):
+        try:
+            self.user_revs[user].append(rev)
+        except:
+            self.user_revs[user] = [rev]
+        self.current_rev = rev
+        self.current_user = user
 
     def ignore(self):
-       if (not self.current_user) or (not self.current_rev): return
-       user_list=self.user_revs[self.current_user]
-       if len(user_list) >= 1 and user_list[-1] == self.current_rev:
-           user_list.pop()
-
-    def scan (self):
-       cmd =  "svn log -r %s:%s http://svn.planet-lab.org/svn/%s " % (self.options.fromv,self.options.tov,self.name)
-       if self.options.verbose:
-           print 'running',cmd
-       f = os.popen(cmd)
-       for line in f:
-           if not self.valid.match(line): 
-               # mostly ignore commit body, except for ignoring the current commit if -i is set
-               if self.options.ignore_tags and self.tagging.match(line):
-                   # roll back these changes
-                   self.ignore()
-               continue
-           fields = line.split('|')
-           fields = [field.strip() for field in fields]
-           [rev,user,ctime,size] = fields[:4]
-           self.record(user,rev)
-       # translate into a list of tuples
-       user_commits = [ (user,len(revs)) for (user,revs) in self.user_revs.items() ]
-       user_commits.sort(self.sort)
-       self.user_commits=user_commits
+        if (not self.current_user) or (not self.current_rev):
+            return
+        user_list = self.user_revs[self.current_user]
+        if len(user_list) >= 1 and user_list[-1] == self.current_rev:
+            user_list.pop()
+
+    def scan(self):
+        cmd = "svn log -r %s:%s http://svn.planet-lab.org/svn/%s " % (
+            self.options.fromv, self.options.tov, self.name)
+        if self.options.verbose:
+            print('running', cmd)
+        f = os.popen(cmd)
+        for line in f:
+            if not self.valid.match(line):
+                # mostly ignore commit body, except for ignoring the current commit if -i is set
+                if self.options.ignore_tags and self.tagging.match(line):
+                    # roll back these changes
+                    self.ignore()
+                continue
+            fields = line.split('|')
+            fields = [field.strip() for field in fields]
+            [rev, user, ctime, size] = fields[:4]
+            self.record(user, rev)
+        # translate into a list of tuples
+        user_commits = [(user, len(revs))
+                        for (user, revs) in list(self.user_revs.items())]
+        user_commits.sort(key=self.sort_key)
+        self.user_commits = user_commits
 
     def show(self):
-       if len(self.user_commits) ==0: return
-       print '%s [%s-%s]'%(self.name,self.options.fromv,self.options.tov),
-       if self.options.ignore_tags:
-           print ' - Ignored tag commits'
-       else:
-           print ''
-       for (u,c) in self.user_commits:
-           print "\t",u,c
+        if len(self.user_commits) == 0:
+            return
+        print('%s [%s-%s]' %
+              (self.name, self.options.fromv, self.options.tov), end=' ')
+        if self.options.ignore_tags:
+            print(' - Ignored tag commits')
+        else:
+            print('')
+        for (u, c) in self.user_commits:
+            print("\t", u, c)
+
 
 class Aggregate:
 
-    def __init__ (self,options):
-       # key=user, value=commits
-       self.options=options
-       self.user_commits_dict={}
-       self.user_commits=[]
-
-    def merge (self, modulehistory):
-       for (u,c) in modulehistory.user_commits:
-           try:
-               self.user_commits_dict[u] += c
-           except:
-               self.user_commits_dict[u] = c
-
-    def sort (self):
-       user_commits = [ (u,c) for (u,c) in self.user_commits_dict.items() ]
-       user_commits.sort(ModuleHistory.sort)
-       self.user_commits=user_commits
-       
+    def __init__(self, options):
+        # key=user, value=commits
+        self.options = options
+        self.user_commits_dict = {}
+        self.user_commits = []
+
+    def merge(self, modulehistory):
+        for (u, c) in modulehistory.user_commits:
+            try:
+                self.user_commits_dict[u] += c
+            except:
+                self.user_commits_dict[u] = c
+
+    def sort(self):
+        user_commits = [(u, c)
+                        for (u, c) in list(self.user_commits_dict.items())]
+        user_commits.sort(ModuleHistory.sort)
+        self.user_commits = user_commits
+
     def show(self):
-       print 'Overall',
-       if self.options.ignore_tags:
-           print ' - Ignored tag commits'
-       else:
-           print ''
-       for (u,c) in self.user_commits:
-           print "\t",u,c
+        print('Overall', end=' ')
+        if self.options.ignore_tags:
+            print(' - Ignored tag commits')
+        else:
+            print('')
+        for (u, c) in self.user_commits:
+            print("\t", u, c)
+
 
 class Modules:
-    
-    def __init__ (self,map):
-       self.map=map
+
+    def __init__(self, map):
+        self.map = map
 
     def categories(self):
-       return self.map.keys()
-
-    def all_modules(self,categories=None):
-       if not categories: categories=self.categories()
-       elif not isinstance(categories,list): categories=[categories]
-       result=[]
-       for category in categories:
-           result += self.map[category]
-       return result
-
-    def locate (self,keywords):
-       result=[]
-       for kw in keywords:
-           if self.map.has_key(kw):
-               result += self.map[kw]
-           else:
-               result += [kw]
-       return result
-
-    def list(self,scope):
-       for (cat,mod_list) in self.map.items():
-           for mod in mod_list:
-               if mod in scope:
-                   print cat,mod
-
-def main ():
-    usage="%prog [module_or_category ...]"
+        return list(self.map.keys())
+
+    def all_modules(self, categories=None):
+        if not categories:
+            categories = self.categories()
+        elif not isinstance(categories, list):
+            categories = [categories]
+        result = []
+        for category in categories:
+            result += self.map[category]
+        return result
+
+    def locate(self, keywords):
+        result = []
+        for kw in keywords:
+            if kw in self.map:
+                result += self.map[kw]
+            else:
+                result += [kw]
+        return result
+
+    def list(self, scope):
+        for (cat, mod_list) in list(self.map.items()):
+            for mod in mod_list:
+                if mod in scope:
+                    print(cat, mod)
+
+
+def main():
+    usage = "%prog [module_or_category ...]"
     parser = OptionParser(usage=usage)
-    parser.add_option("-f", "--from", action = "store", dest='fromv',
-                     default = epoch, help = "The revision to start from, default %s"%epoch)
-    parser.add_option("-t", "--to", action = "store", dest='tov',
-                     default = 'HEAD', help = "The revision to end with, default HEAD")
-    parser.add_option("-n","--no-aggregate", action='store_false',dest='aggregate',default=True,
-                     help='Do not aggregate over modules')
-    parser.add_option("-v","--verbose", action='store_true',dest='verbose',default=False,
-                     help='Run in verbose/debug mode')
-    parser.add_option("-i","--ignore-tags",action='store_true',dest='ignore_tags',
-                     help='ignore commits related to tagging')
-    parser.add_option("-l","--list",action='store_true',dest='list_modules',
-                     help='list available modules and categories')
+    parser.add_option("-f", "--from", action="store", dest='fromv',
+                      default=epoch, help="The revision to start from, default %s" % epoch)
+    parser.add_option("-t", "--to", action="store", dest='tov',
+                      default='HEAD', help="The revision to end with, default HEAD")
+    parser.add_option("-n", "--no-aggregate", action='store_false', dest='aggregate', default=True,
+                      help='Do not aggregate over modules')
+    parser.add_option("-v", "--verbose", action='store_true', dest='verbose', default=False,
+                      help='Run in verbose/debug mode')
+    parser.add_option("-i", "--ignore-tags", action='store_true', dest='ignore_tags',
+                      help='ignore commits related to tagging')
+    parser.add_option("-l", "--list", action='store_true', dest='list_modules',
+                      help='list available modules and categories')
     # pass this to the invoked shell if any
     (options, args) = parser.parse_args()
 
-    map=Modules(modules_map)
+    map = Modules(modules_map)
     if not args:
-       modules=map.all_modules()
+        modules = map.all_modules()
     else:
-       modules=map.locate(args)
+        modules = map.locate(args)
 
     if options.list_modules:
-       map.list(modules)
-       return
+        map.list(modules)
+        return
 
-    if len(modules) <=1:
-       options.aggregate=False
+    if len(modules) <= 1:
+        options.aggregate = False
 
     aggregate = Aggregate(options)
     for module in modules:
-       history=ModuleHistory(module,options)
-       history.scan()
-       history.show()
-       aggregate.merge(history)
+        history = ModuleHistory(module, options)
+        history.scan()
+        history.show()
+        aggregate.merge(history)
 
     if options.aggregate:
-       aggregate.sort()
-       aggregate.show()
+        aggregate.sort()
+        aggregate.show()
+
 
 if __name__ == '__main__':
     main()
diff --git a/run-nightlies.py b/run-nightlies.py
deleted file mode 100755 (executable)
index 09f60b3..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-#!/usr/bin/python
-# This script makes the declaration of builds declarative. In the past, our build system involved constructing a set of command lines
-# that would get executed with parameters such as the name of the distribution, the kernel version and so on. Unfortunately, the code
-# that went into creating these command lines was shared between people and often when someone modified his build, other builds would 
-# break. With this script, each build is declared as a Python dict, such as in the following example:
-#
-# caglars_k32_build = {
-#         'tags':'planetlab-k32-tags.mk',
-#         'fcdistro':['centos5', 'f12','f8'],
-#         'personality':['linux32','linux64'],
-#         'test':0,
-#         'release':'k32'
-# }
-#
-# This declaration corresponds to 6 builds - with static values of 'tags', 'test' and 'release' and every combination of the values provided for
-# 'fcdistro' and 'personality', i.e. 3x2. 
-#
-# More complex dependencies can be added, e.g. to build linux64 only for f12, you can set the values of the options to functions:
-#
-# caglars_k32_build = {
-#         'tags':'planetlab-k32-tags.mk',
-#         'fcdistro':['centos5', 'f12','f8'],
-#         'personality': lambda build: if (build['fcdistro']=='f12') then return ['linux32', 'linux64'] else return ['linux32']
-#         'test':0,
-#         'release':'k32'
-# }
-#
-# Naturally, you can achieve the same result by breaking the above declaration into two dicts, rather than using only one
-
-
-import os
-import re
-import shlex
-import subprocess
-import time
-from optparse import OptionParser
-
-PARALLEL_BUILD = False
-
-# Assemble a list of builds from a single build spec
-def interpret_build(build, param_names, current_concrete_build={}, concrete_build_list=[]):
-    if (param_names==[]):
-        concrete_build_list.extend([current_concrete_build])
-    else:
-        (cur_param_name,remaining_param_names)=(param_names[0],param_names[1:])
-        cur_param = build[cur_param_name]
-
-        # If it's a list, produce a concrete build for each element of the list
-        if (type(cur_param)==type([])):
-            for value in cur_param:
-                new_concrete_build = current_concrete_build.copy()
-                new_concrete_build[cur_param_name] = value
-                concrete_build_list = interpret_build(build, remaining_param_names, new_concrete_build, concrete_build_list)
-
-        # If not, just tack on the value and move on
-        else:
-            current_concrete_build[cur_param_name] = cur_param
-            concrete_build_list = interpret_build(build, remaining_param_names, current_concrete_build,concrete_build_list)
-
-    return concrete_build_list
-
-
-# Fill in parameters that are not defined in __default_build__
-def complete_build_spec_with_defaults (build, default_build):
-    for default_param in default_build.keys():
-        if (not build.has_key(default_param)):
-            build[default_param]=default_build[default_param]
-    return build
-
-
-# Turn a concrete build into a commandline
-
-def concrete_build_to_commandline(concrete_build):
-
-    cmdline = '''%(sh)s 
-        %(vbuildnightly)s
-        -b pl-%(fcdistro)s-%(arch)s-%(myplcversion)s-%(release)s-%(date)s
-        -f %(fcdistro)s 
-        -m %(mailto)s 
-        -p %(personality)s
-        -d %(pldistro)s
-        -r %(webpath)s
-        -s %(scmpath)s
-        -t %(tags)s
-        -w %(webpath)s/%(pldistro)s/%(fcdistro)s
-        %(runtests)s'''.replace('\n','')
-
-    cmdline = cmdline % concrete_build
-
-    purge_spaces = re.compile('\s+')
-
-    return purge_spaces.sub(' ', cmdline)
-
-
-# reduce dependencies in a build 
-def reduce_dependencies(concrete_build):
-    for b in concrete_build.keys():
-        val = concrete_build[b]
-        if (type(val)==type(lambda x:x)):
-            concrete_build[b] = val(concrete_build)
-    return concrete_build
-
-
-# Turn build parameter dicts into commandlines and execute them
-def process_builds (builds, build_names, default_build, options):
-    for build_name in build_names:
-        build = complete_build_spec_with_defaults (builds[build_name], default_build)
-        concrete_builds_without_deps = interpret_build (build, build.keys(), {}, [])
-        concrete_builds = map(reduce_dependencies, concrete_builds_without_deps)
-        commandlines = map(concrete_build_to_commandline, concrete_builds)
-        for commandline in commandlines:
-            if PARALLEL_BUILD == True:
-                args = shlex.split(commandline)
-                subprocess.Popen(args)
-                # work around the vserver race
-                time.sleep(60)
-            else:       
-                if (build_name.startswith(options.prefix) and not options.pretend):
-                    os.system(commandline)
-                else:
-                    print "### Skipping the following build###\n"
-                    print commandline
-
-def main():
-    parser = OptionParser()
-    parser.add_option("-c", "--config-file", dest="config_file",
-                  help="Config file with build declarations", metavar="FILE", default = '/etc/build-conf-planetlab.py')
-    parser.add_option("-p", "--pretend",
-                  dest="pretend", default=False, action="store_true",
-                  help="don't run only print")
-
-    parser.add_option("-o", "--only-build", dest="prefix",
-                  help="Only build declarations starting with this prefix", metavar="PREFIX", default = '')
-
-    (options, args) = parser.parse_args ()
-
-    config_file = options.config_file
-
-    builds = {}
-    try:
-        execfile(config_file, builds)
-    except IOError, e:
-        raise IOError, "Could not open %s\n" % config_file
-
-
-    config_file_attributes = builds.keys()
-    build_names = [e for e in config_file_attributes if not e.startswith('__')]     
-
-    try:
-        default_build = builds['__default_build__']
-    except KeyError:
-        raise KeyError, "Please define the default build config in %s\n" % config_file
-
-    process_builds(builds, build_names, default_build, options)
-
-
-if __name__ == "__main__":
-    main()
-
index a2bc7bf..2f59af5 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 import sys
 import os.path
@@ -6,94 +6,111 @@ import rpm
 
 from optparse import OptionParser
 
-def main ():
-    usage="%prog [rpmbuild-options] specfile pkg-name"
-    parser=OptionParser(usage=usage)
-    parser.add_option('-t','--target',action='store',dest='target',default=None,
-                      help='specify target arch')
-    parser.add_option('-w','--whitelist-rpms',action='store',dest='whitelist',default='',
-                      help='comma separated list of rpms to expose in makefile')
-    parser.add_option('-1','--with',action='store',dest='with',default='',
-                      help='accept but ignore --with option')
-    parser.add_option('-0','--without',action='store',dest='without',default='',
-                      help='accept but ignore --without option')
-    parser.add_option('-d','--define',action='store',dest='define',default='',
-                      help='accept but ignore --define option')
-    (options,args) = parser.parse_args()
+
+def main():
+    usage = "%prog [rpmbuild-options] specfile pkg-name"
+    parser = OptionParser(usage=usage)
+    parser.add_option(
+        '-t', '--target', action='store', dest='target', default=None,
+        help='specify target arch')
+    parser.add_option(
+        '-w', '--whitelist-rpms', action='store', dest='whitelist', default='',
+        help='comma separated list of rpms to expose in makefile')
+    parser.add_option(
+        '-1', '--with', action='store', dest='with', default='',
+        help='accept but ignore --with option')
+    parser.add_option(
+        '-0', '--without', action='store', dest='without', default='',
+        help='accept but ignore --without option')
+    parser.add_option(
+        '-d', '--define', action='store', dest='define', default='',
+        help='accept but ignore --define option')
+    (options, args) = parser.parse_args()
 
     try:
-        [specfile,package_name]=args
+        specfile, package_name = args
     except:
         parser.print_help()
         sys.exit(1)
 
-    ts=rpm.TransactionSet()
-    specobj = ts.parseSpec(specfile)
-    for (fullsource,_,__) in specobj.sources:
-        #print '###fullsource=',fullsource
-        print "%s.tarballs += SOURCES/%s" %(package_name,os.path.basename(fullsource))
-        for suffix in [".tar.gz", ".tgz", ".tar.bz2", ".tar.xz" ] : 
-            #print "# trying %s"%suffix
+    transaction_set = rpm.TransactionSet()
+    specobj = transaction_set.parseSpec(specfile)
+    for (fullsource, _, _) in specobj.sources:
+        # print '###fullsource=',fullsource
+        print("%s.tarballs += SOURCES/%s" %
+              (package_name, os.path.basename(fullsource)))
+        for suffix in [".tar.gz", ".tgz", ".tar.bz2", ".tar.xz"]:
+            # print "# trying %s"%suffix
             if fullsource.endswith(suffix):
-                sourcename=fullsource.replace(suffix,"")
-                print "%s.source := SOURCES/%s" %(package_name,os.path.basename(sourcename))
+                sourcename = fullsource.replace(suffix, "")
+                print("%s.source := SOURCES/%s" %
+                      (package_name, os.path.basename(sourcename)))
                 break
 
     # Get SRPM name from name of first package
-    package=specobj.packages[0]
-    header0=package.header
-    name=header0.format('%{name}')
-    version=header0.format('%{version}')
-    release=header0.format('%{release}')
-    print "%s.srpm := SRPMS/%s-%s-%s.src.rpm"%(package_name, name, version, release)
+    package = specobj.packages[0]
+    header0 = package.header
+    name = header0.format('%{name}')
+    version = header0.format('%{version}')
+    release = header0.format('%{release}')
+    print("%s.srpm := SRPMS/%s-%s-%s.src.rpm" %
+          (package_name, name, version, release))
 
     target = options.target
-    whitelist=[ x for x in options.whitelist.split(',') if x]
+    whitelist = [x for x in options.whitelist.split(',') if x]
     # Print non-empty packages
-    counter=0
+    counter = 0
     for package in specobj.packages:
         counter += 1
-        header=package.header
-        name=header.format('%{name}')
-        version=header.format('%{version}')
-        release=header.format('%{release}')
-        arch=target or header.format('%{arch}')
-        
+        header = package.header
+        name = header.format('%{name}')
+        version = header.format('%{version}')
+        release = header.format('%{release}')
+        arch = target or header.format('%{arch}')
+
         # skip dummy entries
-        if not (name and version and release and arch) : continue
+        if not (name and version and release and arch):
+            continue
 
         # select relevant packages
         # could not find the magic recipe to do this properly yet
         # so ugly temporary hack :
         # when whitelisted, we expose the first package plus the white-listed ones
         # otherwise we expose everything
-        relevant=False
-        if not whitelist: relevant=True
+        relevant = False
+        if not whitelist:
+            relevant = True
         else:
-            if counter==1: relevant=True
-            else: relevant=name in whitelist
+            if counter == 1:
+                relevant = True
+            else:
+                relevant = name in whitelist
 
         if relevant:
             # attach (add) rpm path to package
-            print "%s.rpms += RPMS/%s/%s-%s-%s.%s.rpm"%\
-                (package_name, arch, name, version, release, arch)
+            print("%s.rpms += RPMS/%s/%s-%s-%s.%s.rpm" %
+                  (package_name, arch, name, version, release, arch))
             # convenience
-            print "%s.rpmnames += %s"%\
-                (package_name, name);
+            print("%s.rpmnames += %s" %
+                  (package_name, name))
             # attach path to rpm name
-            print "%s.rpm-path := RPMS/%s/%s-%s-%s.%s.rpm"%\
-                (name,arch, name, version, release, arch)
+            print("%s.rpm-path := RPMS/%s/%s-%s-%s.%s.rpm" %
+                  (name, arch, name, version, release, arch))
             # attach package to rpm name for backward resolution - should be unique
-            print "%s.package := %s"%\
-                (name,package_name)
-            
-    for macro in ["release" , "name" , "version" , "taglevel" , ] :
-        format="%%{%s}"%macro
-        try:     print "%s.rpm-%s := %s"%(package_name,macro,header0.format(format))
-        except : print "# %s.rpm-%s undefined"%(package_name,macro)
+            print("%s.package := %s" %
+                  (name, package_name))
+
+    for macro in ["release", "name", "version", "taglevel", ]:
+        format = "%%{%s}" % macro
+        try:
+            print("%s.rpm-%s := %s" %
+                  (package_name, macro, header0.format(format)))
+        except:
+            print("# %s.rpm-%s undefined" % (package_name, macro))
 
     # export arch
-    print "%s.rpm-arch := %s"%(package_name,target)
+    print("%s.rpm-arch := %s" % (package_name, target))
+
 
 if __name__ == '__main__':
     main()