source: soft/build_system/build_system/bm/tags/2.1/BuildManager/build.py @ 1

Last change on this file since 1 was 1, checked in by fasma, 12 years ago

Initial Import from Mandriva's soft revision 224062 and package revision 45733

File size: 8.9 KB
Line 
1from BuildManager.fileutil import *
2from BuildManager.package import *
3from BuildManager import *
4import thread
5import popen2
6import select
7import fcntl
8import thread
9import sys, os
10import time
11import shutil
12
13__all__ = ["PackageBuilder"]
14
15GLOBAL_PKGLIST_LOCK = thread.allocate_lock()
16
17STAGE_UNPACK = 0
18STAGE_PREP = 1
19STAGE_COMPILE = 2
20STAGE_INSTALL = 3
21STAGE_SOURCE = 4
22STAGE_BINARY = 5
23STAGE_ALL = 6
24
25STAGE_DICT = {"unpack": STAGE_UNPACK,
26              "prep": STAGE_PREP,
27              "compile": STAGE_COMPILE,
28              "install": STAGE_INSTALL,
29              "source": STAGE_SOURCE,
30              "binary": STAGE_BINARY,
31              "all": STAGE_ALL}
32
33class PackageBuilder:
34    def __init__(self, opts):
35        self.opts = opts
36        self.stage = STAGE_DICT[opts.mode]
37
38    def run(self):
39        self.pkglist = PackageList()
40        logger.info("creating package list")
41        for filename in self.opts.args:
42            pkg = Package(filename, self.opts.build_log)
43            for ignore in self.opts.ignore:
44                if ignore.match(pkg.name):
45                    break
46            else:
47                self.pkglist.append(pkg)
48        for dir in self.opts.filter_renew:
49            filterpkglist(pkglist, dir, "not_has_ge")
50        for dir in self.opts.filter_refresh:
51            filterpkglist(pkglist, dir, "not_has_lt")
52        self.pkgsleft = len(self.pkglist)
53        if self.pkgsleft == 0:
54            logger.info("no packages to process")
55            return True
56        elif self.pkgsleft > 1 and self.pkgsleft % 10 != 0:
57            logger.info("package list has %d packages" % pkgsleft)
58        self.pkglist_lock = thread.allocate_lock()
59        self.failures = 0
60        if self.opts.parallel != 1:
61            logger.info("starting threads")
62            for i in range(self.opts.parallel-1):
63                thread.start_new_thread(self_processlist, ())
64        self._processlist()
65        while self.pkgsleft > 0:
66            time.sleep(2)
67        return not self.failures
68
69    def _processlist(self):
70        while 1:
71            self.pkglist_lock.acquire()
72            if not self.pkglist:
73                self.pkglist_lock.release()
74                return 1
75            if self.pkgsleft % 10 == 0:
76                logger.info("package list has %d packages" % self.pkgsleft)
77            pkg = self.pkglist.pop(0)
78            logger.info("processing package %s-%s-%s" %
79                        (pkg.name, pkg.version, pkg.release))
80            self.pkglist_lock.release()
81            ret = buildpkg(pkg=pkg,
82                           stage=self.stage,
83                           unpack_dir=self.opts.unpack_dir,
84                           passtrough=" ".join(self.opts.options),
85                           show_log=self.opts.show_log,
86                           dryrun=self.opts.dryrun)
87            if ret:
88                if pkg.type == "srpm":
89                    if self.opts.move_succeeded_srpm:
90                        move_file(pkg.file,
91                                  self.opts.move_succeeded_srpm,
92                                  dryrun=self.opts.dryrun)
93                    elif self.opts.copy_succeeded_srpm:
94                        copy_file(pkg.file,
95                                  self.opts.copy_succeeded_srpm,
96                                  dryrun=self.opts.dryrun)
97                    elif self.opts.remove_succeeded_srpm:
98                        logger.info("removing %s" % pkg.file)
99                        if not self.opts.dryrun:
100                            os.unlink(pkg.file)
101                if self.opts.move_srpm:
102                    dir = os.path.join(pkg.builddir, "SRPMS")
103                    for file in os.listdir(dir):
104                        move_file(os.path.join(dir, file),
105                                  self.opts.move_srpm,
106                                  dryrun=self.opts.dryrun)
107                if self.opts.move_rpm:
108                    dir = os.path.join(pkg.builddir, "RPMS")
109                    for subdir in os.listdir(dir):
110                        subdir = os.path.join(dir, subdir)
111                        for file in os.listdir(subdir):
112                            move_file(os.path.join(subdir, file),
113                                      self.opts.move_rpm,
114                                      dryrun=self.opts.dryrun)
115                if self.opts.move_log:
116                    move_file(pkg.log,
117                              self.opts.move_log,
118                              dryrun=self.dryrun)
119                if self.opts.clean or self.opts.clean_on_success:
120                    if pkg.builddir != "/":
121                        logger.info("cleaning build directory")
122                        if not self.opts.dryrun:
123                            shutil.rmtree(pkg.builddir)
124            else:
125                self.failures += 1
126                if pkg.type == "srpm":
127                    if self.opts.move_failed_srpm:
128                        move_file(pkg.file,
129                                  self.opts.move_failed_srpm,
130                                  dryrun=self.opts.dryrun)
131                    elif self.opts.copy_failed_srpm:
132                        copy_file(pkg.file,
133                                  self.opts.copy_failed_srpm,
134                                  dryrun=self.opts.dryrun)
135                    elif self.opts.remove_failed_srpm:
136                        logger.info("removing %s" % pkg.file)
137                        if not self.opts.dryrun:
138                            os.unlink(pkg.file)
139                if self.opts.move_failed_log:
140                    move_file(pkg.log,
141                              self.opts.move_failed_log,
142                              dryrun=self.opts.dryrun)
143                if self.opts.clean:
144                    if pkg.builddir != "/":
145                        logger.info("cleaning build directory")
146                        if not self.opts.dryrun:
147                            shutil.rmtree(pkg.builddir)
148            self.pkglist_lock.acquire()
149            self.pkgsleft -= 1
150            self.pkglist_lock.release()
151
152def filterpkglist(pkglist, directory, rule):
153    filterlist = PackageList()
154    logger.info("creating package list filter for "+directory)
155    for filename in os.listdir(directory):
156        filename = os.path.join(directory, filename)
157        if os.path.isfile(filename):
158            filterlist.append(Package(filename))
159    logger.info("filtering")
160    if rule[:4] == "not_":
161        filterfunc_tmp = getattr(filterlist, rule[4:])
162        filterfunc = lambda x: not filterfunc_tmp(x)
163    else:
164        filterfunc = getattr(filterlist, rule)
165    pkglist[:] = filter(filterfunc, pkglist)
166
167
168def buildpkglist(pkglist, stage, unpack_dir, passtrough="",
169                 show_log=0, dryrun=0):
170    while 1:
171        GLOBAL_PKGLIST_LOCK.acquire()
172        if not pkglist:
173            GLOBAL_PKGLIST_LOCK.release()
174            return 1
175        pkg = pkglist[0]
176        del pkglist[0]
177        GLOBAL_PKGLIST_LOCK.release()
178        buildpkg(pkg, stage, unpack_dir, passtrough, show_log, dryrun)
179
180def buildpkg(pkg, stage, unpack_dir, passtrough="", show_log=0, dryrun=0):
181    stagestr = ["unpacking",
182                "running prep stage",
183                "running prep and compile stage",
184                "running prep, compile, and install stages",
185                "building source package",
186                "building binary packages",
187                "building source and binary packages"][stage]
188    logger.info(stagestr)
189    ret = 0
190    if pkg.type == "srpm" and not (dryrun or pkg.unpack(unpack_dir)):
191        logger.error("failed unpacking")
192        return 0
193    else:
194        status = 0
195        if stage != STAGE_UNPACK:
196            stagechar = ["p","c","i","s","b","a"][stage-1]
197            if not dryrun and os.path.isdir(pkg.builddir+"/BUILDROOT"):
198                tmppath = " --define '_tmppath %s/BUILDROOT'" % pkg.builddir
199            else:
200                tmppath = ""
201            cmd = "rpm -b%s --define '_topdir %s'%s %s %s 2>&1" % \
202                  (stagechar,pkg.builddir,tmppath,passtrough,pkg.spec)
203            logger.debug("rpm command: "+cmd)
204            if not dryrun:
205                log = open(pkg.log, "w")
206                pop = popen2.Popen3(cmd)
207                fc = pop.fromchild
208                flags = fcntl.fcntl (fc.fileno(), fcntl.F_GETFL, 0)
209                flags = flags | os.O_NONBLOCK
210                fcntl.fcntl (fc.fileno(), fcntl.F_SETFL, flags)
211                while 1:
212                    r,w,x = select.select([fc.fileno()], [], [], 2)
213                    if r:
214                        data = fc.read()
215                        if show_log:
216                            sys.stdout.write(data)
217                        log.write(data)
218                        log.flush()
219                    status = pop.poll()
220                    if status != -1:
221                        break
222                log.close()
223        if status == 0:
224            logger.info("succeeded!")
225            ret = 1
226        else:
227            logger.error("failed!")
228            ret = 0
229    return ret
230
231# vim:ts=4:sw=4
Note: See TracBrowser for help on using the repository browser.