Browse code

Cleaning up the code

Divya Thaluru authored on 2015/06/03 09:38:59
Showing 7 changed files
... ...
@@ -1,21 +1,9 @@
1
-import subprocess
2 1
 from Logger import Logger
3 2
 from CommandUtils import CommandUtils
4
-import os
5
-import threading
6
-import time
7 3
 from constants import constants
8
-
9
-chrootRootPath="/mnt"
4
+import os.path
10 5
 
11 6
 class ChrootUtils(object):
12
-    counter=1
13
-    lockForCounter=threading.Lock()
14
-    lockForTrackingChroots=threading.Lock()
15
-    lockForCreateChroot=threading.Lock()
16
-    activeChroots=[]
17
-    failureFlag=False
18
-    numChroots=1
19 7
     
20 8
     def __init__(self,logName=None,logPath=None):
21 9
         if logName is None:
... ...
@@ -26,124 +14,34 @@ class ChrootUtils(object):
26 26
         self.logPath=logPath
27 27
         self.logger=Logger.getLogger(logName,logPath)
28 28
         
29
-    def _getChrootUniqueID(self):
30
-        ChrootUtils.lockForCounter.acquire()
31
-        chrootID=chrootRootPath+"/photonroot"+str(ChrootUtils.counter)
32
-        while os.path.isdir(chrootID):
33
-            ChrootUtils.counter = ChrootUtils.counter +1
34
-            chrootID=chrootRootPath+"/photonroot"+str(ChrootUtils.counter)
35
-        ChrootUtils.counter = ChrootUtils.counter +1
36
-        ChrootUtils.lockForCounter.release()
37
-        return chrootID
38
-    
39
-    def updateParams(self):
40
-        process = subprocess.Popen(["df" ,chrootRootPath],shell=True,stdout=subprocess.PIPE)
41
-        retval = process.wait()
42
-        if retval != 0:
43
-            self.logger.error("Unable to check free space. Unknown error.")
44
-            return False
45
-        output = process.communicate()[0]
46
-        device, size, used, available, percent, mountpoint = output.split("\n")[1].split()
47
-        c =  int(available)/600000
48
-        ChrootUtils.numChroots=int(c)
49
-        self.logger.info("Updated number of chroots:"+str(ChrootUtils.numChroots))
50
-    
51
-    def checkFreeSpace(self):
52
-        process = subprocess.Popen(["df" ,chrootRootPath],shell=True,stdout=subprocess.PIPE)
53
-        retval = process.wait()
54
-        if retval != 0:
55
-            self.logger.error("Unable to check free space. Unknown error.")
56
-            return False
57
-        output = process.communicate()[0]
58
-        device, size, used, available, percent, mountpoint = output.split("\n")[1].split()
59
-        if available > 600000:
60
-            self.logger.info("Free Space available "+ available)
61
-            return True
62
-        return False
63
-    
64
-    def createChroot(self):
65
-        if ChrootUtils.failureFlag:
66
-            return False
67
-        
68
-        ChrootUtils.lockForCreateChroot.acquire()
69
-        if ChrootUtils.failureFlag:
70
-            ChrootUtils.lockForCreateChroot.release()
71
-            return False
72
-        
73
-        startTime=currentTime=time.time()
74
-        timeOut=1800
75
-        freeSpaceAvailable=False
76
-        while currentTime < startTime + timeOut:
77
-            #if self.checkFreeSpace():
78
-            if len(ChrootUtils.activeChroots) < ChrootUtils.numChroots:
79
-                freeSpaceAvailable=True
80
-                break
81
-            time.sleep(100)
82
-            
83
-        if not freeSpaceAvailable:
84
-            self.logger.error("Unable to create chroot. No sufficient free space is available.")
85
-            ChrootUtils.lockForCreateChroot.release()
86
-            ChrootUtils.failureFlag=True
87
-            return False,None
88
-        
89
-        chrootID=self._getChrootUniqueID()
29
+    def createChroot(self,chrootName):
30
+        chrootID=constants.buildRootPath+"/"+chrootName
31
+        if os.path.isdir(chrootID):
32
+            if not self.destroyChroot(chrootID):
33
+                self.logger.error("Given chroot "+chrootID+" is already exists. unable to destroy it ")
34
+                return False,None
90 35
         # need to add timeout for this step
91 36
         # http://stackoverflow.com/questions/1191374/subprocess-with-timeout
92
-        process = subprocess.Popen("mkdir -p "+chrootID,shell=True,stdout=subprocess.PIPE)
93
-        retval = process.wait()
94
-        
95
-        ChrootUtils.lockForCreateChroot.release()
96
-        
97
-        if retval != 0:
98
-            self.logger.error("Unable to create chroot:"+ chrootID +".Unknown error.")
99
-            return False,None
100
-        
101
-        ChrootUtils.lockForTrackingChroots.acquire()
102
-        ChrootUtils.activeChroots.append(chrootID) 
103
-        ChrootUtils.lockForTrackingChroots.release()           
104
-        return True,chrootID
105
-    
106
-    def createChroot1(self,chrootID):
107
-        # need to add timeout for this step
108
-        # http://stackoverflow.com/questions/1191374/subprocess-with-timeout
109
-        process = subprocess.Popen("mkdir -p "+chrootID,shell=True,stdout=subprocess.PIPE)
110
-        retval = process.wait()
111
-        
112
-        if retval != 0:
37
+        cmdUtils=CommandUtils()
38
+        returnVal=cmdUtils.runCommandInShell("mkdir -p "+chrootID)
39
+        if not returnVal:
113 40
             self.logger.error("Unable to create chroot:"+ chrootID +".Unknown error.")
114 41
             return False,None
115
-        
116 42
         return True,chrootID
117 43
     
118 44
     def destroyChroot(self,chrootID):
119
-        '''
120
-        validChroot = True
121
-        ChrootUtils.lockForTrackingChroots.acquire()
122
-        if chrootID not in ChrootUtils.activeChroots:
123
-            validChroot = False
124
-        else:
125
-            ChrootUtils.activeChroots.remove(chrootID)
126
-        ChrootUtils.lockForTrackingChroots.release()
127
-        if not validChroot:
128
-            self.logger.error("Given chroot:"+chrootID+" is not a valid chroot. It is not created by ChrootUtils.")
129
-            return False
130
-        '''
131 45
         # need to add timeout for this step
132 46
         # http://stackoverflow.com/questions/1191374/subprocess-with-timeout
133
-        process = subprocess.Popen("./cleanup-build-root.sh "+chrootID,shell=True,stdout=subprocess.PIPE)
134
-        retval = process.wait()
135
-        if retval != 0:
47
+        cmdUtils=CommandUtils()
48
+        returnVal=cmdUtils.runCommandInShell("./cleanup-build-root.sh "+chrootID)
49
+        if not returnVal:
50
+            self.logger.error("Unable to destroy chroot:"+ chrootID +".Unknown error.")
51
+            return False
52
+        
53
+        returnVal=cmdUtils.runCommandInShell("rm -rf "+chrootID)
54
+        if not returnVal:
136 55
             self.logger.error("Unable to destroy chroot:"+ chrootID +".Unknown error.")
137 56
             return False
138
-        cmdUtils=CommandUtils()
139
-        cmdUtils.runCommandInShell("rm -rf "+chrootID)
140 57
         self.logger.info("Successfully destroyed chroot:"+chrootID)
141 58
         return True
142
-    
143
-    def cleanUpActiveChroots(self):
144
-        ChrootUtils.lockForTrackingChroots.acquire()
145
-        listChroots=self.activeChroots[:]
146
-        ChrootUtils.lockForTrackingChroots.release()
147
-        for chrootID in listChroots:
148
-            self.destroyChroot(chrootID)
149
-        self.logger.info("Successfully destroyed all active chroots")
59
+    
150 60
\ No newline at end of file
... ...
@@ -20,27 +20,11 @@ class PackageBuilder(object):
20 20
         self.listAvailableCyclicPackages = listAvailableCyclicPackages
21 21
         self.listNodepsPackages = ["glibc","gmp","zlib","file","binutils","mpfr","mpc","gcc","ncurses","util-linux","groff","perl","texinfo","rpm","openssl","go"]
22 22
     
23
-    #assumes tool chain is already built
24
-    def prepareBuildRoot(self):
23
+    def prepareBuildRoot(self,chrootName):
25 24
         chrootID=None
26 25
         try:
27 26
             chrUtils = ChrootUtils(self.logName,self.logPath)
28
-            returnVal,chrootID = chrUtils.createChroot()
29
-            if not returnVal:
30
-                raise Exception("Unable to prepare build root")
31
-            tUtils=ToolChainUtils(self.logName,self.logPath)
32
-            tUtils.installToolChain(chrootID)
33
-        except Exception as e:
34
-            if chrootID is not None:
35
-                chrUtils.destroyChroot(chrootID)
36
-            raise e
37
-        return chrootID
38
-    
39
-    def prepareBuildRoot1(self,chrootID):
40
-        #chrootID=None
41
-        try:
42
-            chrUtils = ChrootUtils(self.logName,self.logPath)
43
-            returnVal,chrootID = chrUtils.createChroot1(chrootID)
27
+            returnVal,chrootID = chrUtils.createChroot(chrootName)
44 28
             if not returnVal:
45 29
                 raise Exception("Unable to prepare build root")
46 30
             tUtils=ToolChainUtils(self.logName,self.logPath)
... ...
@@ -85,9 +69,10 @@ class PackageBuilder(object):
85 85
     def buildPackage(self,package):
86 86
         #should initialize a logger based on package name
87 87
         chrUtils = ChrootUtils(self.logName,self.logPath)
88
-        chrootID="build-"+package
88
+        chrootName="build-"+package
89
+        chrootID=None
89 90
         try:
90
-            chrootID = self.prepareBuildRoot1(chrootID)
91
+            chrootID = self.prepareBuildRoot(chrootName)
91 92
             destLogPath=constants.logPath+"/build-"+package
92 93
             if not os.path.isdir(destLogPath):
93 94
                 cmdUtils = CommandUtils()
... ...
@@ -2,14 +2,11 @@ from PackageBuildDataGenerator import PackageBuildDataGenerator
2 2
 from Logger import Logger
3 3
 import threading
4 4
 from constants import constants
5
-import time
6
-from PackageBuilder import PackageBuilder
7 5
 import os
8 6
 from PackageUtils import PackageUtils
9 7
 from ToolChainUtils import ToolChainUtils
10 8
 from Scheduler import Scheduler
11 9
 from ThreadPool import ThreadPool
12
-from WorkerThread import WorkerThread
13 10
 import subprocess
14 11
 
15 12
 class PackageManager(object):
... ...
@@ -41,20 +38,6 @@ class PackageManager(object):
41 41
             return False
42 42
         return True
43 43
     
44
-    def getRequiredPackages(self,package):
45
-        listRequiredRPMPackages=[]
46
-        listRequiredRPMPackages.extend(constants.specData.getBuildRequiresForPackage(package))
47
-        listRequiredRPMPackages.extend(constants.specData.getRequiresAllForPackage(package))
48
-        
49
-        listRequiredPackages=[]
50
-        for pkg in listRequiredRPMPackages:
51
-            basePkg=constants.specData.getSpecName(pkg)
52
-            if basePkg not in listRequiredPackages:
53
-                listRequiredPackages.append(basePkg)
54
-        
55
-        return listRequiredPackages
56
-                
57
-    
58 44
     def readAlreadyAvailablePackages(self):
59 45
         listAvailablePackages=[]
60 46
         listRPMFiles=[]
... ...
@@ -100,68 +83,6 @@ class PackageManager(object):
100 100
         
101 101
         return True
102 102
     
103
-    def checkIfAnyThreadsAreCompleted(self):
104
-        readyToLaunchMoreThreads = False
105
-        listThreadsObjToRemove=[]
106
-        for t in self.listThreads:
107
-            self.logger.debug("Checking thread "+t +", whether it is completed or not")
108
-            #check if any thread is completed. If completed, we can start more threads.
109
-            if self.mapOutputThread.has_key(t):
110
-                output = self.mapOutputThread[t]
111
-                self.logger.info("Output of thread "+t+" "+str(output))
112
-                if not output:
113
-                    self.logger.error("Thread "+ t+" is failed ")
114
-                    self.logger.error("Unable to build package "+t)
115
-                    raise Exception("Package builder failed")
116
-                else:
117
-                    self.logger.debug("Still running, not completed yet")
118
-                    readyToLaunchMoreThreads=True
119
-                    self.listPackagesToBuild.remove(t)
120
-                    self.listOfPackagesAlreadyBuilt.append(t)
121
-                    listThreadsObjToRemove.append(t)
122
-                    if self.mapPackageToCycle.has_key(t):
123
-                        self.listAvailableCyclicPackages.append(t)
124
-        
125
-        if not readyToLaunchMoreThreads:
126
-            return False
127
-            
128
-        for k in listThreadsObjToRemove:
129
-            tObj=self.listThreads.pop(k)
130
-            if tObj.isAlive():
131
-                self.logger.info("Thread is alive")
132
-            else:
133
-                self.logger.info("Thread is dead")
134
-            self.logger.info(tObj.isAlive())
135
-
136
-        return True
137
-    
138
-    #just to be safe, we have this method
139
-    def checkIfAnyThreadsAreHanged(self):
140
-        currentTime = time.time()
141
-        listThreadsHanged=[]
142
-        for t in self.listThreads:
143
-            self.logger.debug("Checking thread "+t +", whether it is hanged or not")
144
-            if not self.mapOutputThread.has_key(t):
145
-                self.logger.debug("Calculating running time for thread "+t)
146
-                launchTime = self.mapThreadsLaunchTime[t]
147
-                if (currentTime - launchTime) > 7200.0:
148
-                    listThreadsHanged.append(t)
149
-            
150
-        if len(listThreadsHanged) > 0:
151
-            self.logger.info("Following threads are hanged")
152
-            self.logger.info(listThreadsHanged)
153
-            raise Exception("Threads are hanged")
154
-    
155
-    def waitTillNewThreadsCanBeSpawned(self):
156
-        if len(self.listThreads) == 0:
157
-            return
158
-        while True:
159
-            if self.checkIfAnyThreadsAreCompleted():
160
-                break
161
-            self.checkIfAnyThreadsAreHanged()
162
-            self.logger.info("Sleeping for 10 seconds")
163
-            time.sleep(10)
164
-    
165 103
     def buildToolChain(self):
166 104
         try:
167 105
             tUtils=ToolChainUtils()
... ...
@@ -174,7 +95,7 @@ class PackageManager(object):
174 174
         return True
175 175
     
176 176
     def calculatePossibleNumWorkerThreads(self):
177
-        process = subprocess.Popen(["df" ,"/mnt"],shell=True,stdout=subprocess.PIPE)
177
+        process = subprocess.Popen(["df" ,constants.buildRootPath],shell=True,stdout=subprocess.PIPE)
178 178
         retval = process.wait()
179 179
         if retval != 0:
180 180
             self.logger.error("Unable to check free space. Unknown error.")
... ...
@@ -183,7 +104,7 @@ class PackageManager(object):
183 183
         device, size, used, available, percent, mountpoint = output.split("\n")[1].split()
184 184
         c =  int(available)/600000
185 185
         numChroots=int(c)
186
-        self.logger.info("Updated number of chroots:"+str(numChroots))
186
+        self.logger.info("Possible number of worker threads:"+str(numChroots))
187 187
         return numChroots
188 188
     
189 189
     def buildPackages (self, listPackages):
... ...
@@ -211,6 +132,8 @@ class PackageManager(object):
211 211
         ThreadPool.listAvailableCyclicPackages=self.listAvailableCyclicPackages
212 212
         ThreadPool.logger=self.logger
213 213
         ThreadPool.statusEvent=statusEvent
214
+        
215
+        
214 216
         i=0
215 217
         while i < numWorkerThreads:
216 218
             workerName="WorkerThread"+str(i)
... ...
@@ -221,11 +144,12 @@ class PackageManager(object):
221 221
         statusEvent.wait()
222 222
         
223 223
         Scheduler.stopScheduling=True
224
-        
225 224
         setFailFlag=False
226 225
         allPackagesBuilt=False
226
+        
227 227
         if Scheduler.isAnyPackagesFailedToBuild():
228 228
             setFailFlag=True
229
+        
229 230
         if Scheduler.isAllPackagesBuilt():
230 231
             allPackagesBuilt=True
231 232
         
... ...
@@ -245,87 +169,3 @@ class PackageManager(object):
245 245
             w.join()
246 246
         
247 247
         self.logger.info("Terminated")
248
-        
249
-        
250
-        
251
-            
252
-        
253
-
254
-    
255
-    def buildPackages1 (self, listPackages):
256
-        
257
-        if not self.buildToolChain():
258
-            return False
259
-
260
-        returnVal=self.calculateParams(listPackages)
261
-        if not returnVal:
262
-            self.logger.error("Unable to set paramaters. Terminating the package manager.")
263
-            return False
264
-        
265
-        returnVal = True
266
-        try:
267
-            while len(self.listPackagesToBuild) > 0:
268
-                #Free some threads to launch next threads
269
-                self.waitTillNewThreadsCanBeSpawned()
270
-                
271
-                listOfPackagesCanBeBuild=self.findNextPackageToBuild()
272
-                if len(listOfPackagesCanBeBuild) == 0 and len(self.listPackagesToBuild) != 0:
273
-                    self.logger.info("Waiting for current threads to complete to launch building new packages")
274
-                
275
-                for pkg in listOfPackagesCanBeBuild:
276
-                    currentTime = time.time()
277
-                    pkgBuilder = PackageBuilder(self.mapPackageToCycle,self.listAvailableCyclicPackages,"build-"+pkg,constants.logPath)
278
-                    t = threading.Thread(target=pkgBuilder.buildPackageThreadAPI,args=(pkg,self.mapOutputThread,pkg))
279
-                    self.listThreads[pkg]=t
280
-                    self.mapThreadsLaunchTime[pkg]=currentTime
281
-                    self.logger.info("Launching thread for package:"+pkg)
282
-                    t.start()
283
-                    self.logger.info("Started the thread for "+pkg)
284
-                
285
-                if len(self.listThreads) == 0 and len(self.listPackagesToBuild) != 0:
286
-                    self.logger.error("Following packages are waiting for unknown package")
287
-                    self.logger.error(self.listPackagesToBuild)
288
-                    raise Exception("Invalid Schedule order")
289
-                    
290
-            self.logger.info( "Successfully built all the packages")
291
-
292
-        except Exception as e:
293
-            self.logger.error(str(e))
294
-            self.logger.error("Caught exception.")
295
-            self.logger.error("Failed and exited gracefully")
296
-            returnVal = False
297
-        finally:
298
-            self.waitForRemainingThreads()
299
-        return returnVal
300
-    
301
-    def waitForRemainingThreads(self):
302
-        self.logger.info("Waiting for all remaining threads to complete")
303
-        for t in self.listThreads:
304
-            self.listThreads[t].join()
305
-        return
306
-
307
-    def findNextPackageToBuild(self):
308
-        listOfPackagesNextToBuild=[]
309
-        self.logger.info("Checking for next possible packages to build")
310
-        for pkg in self.listPackagesToBuild:
311
-            if self.listThreads.has_key(pkg):
312
-                continue
313
-            listRequiredPackages=self.getRequiredPackages(pkg)
314
-            canBuild=True
315
-            self.logger.info("Required packages for "+ pkg + " are:")
316
-            self.logger.info(listRequiredPackages)
317
-            for reqPkg in listRequiredPackages:
318
-                if reqPkg not in self.listOfPackagesAlreadyBuilt:
319
-                    canBuild=False
320
-                    self.logger.info(reqPkg+" is not available. So we cannot build "+ pkg +" at this moment.")
321
-                    break
322
-            if canBuild:
323
-                listOfPackagesNextToBuild.append(pkg)
324
-        return listOfPackagesNextToBuild
325
-                
326
-                 
327
-            
328
-            
329
-        
330
-    
331
-    
... ...
@@ -4,7 +4,6 @@ from Logger import Logger
4 4
 from PackageUtils import PackageUtils
5 5
 import shutil
6 6
 from constants import constants
7
-import subprocess
8 7
 
9 8
 class ToolChainUtils(object):
10 9
     __built_successfull=False
... ...
@@ -44,14 +43,16 @@ class ToolChainUtils(object):
44 44
             "libpipeline", "gdbm","perl","texinfo","rpm",
45 45
             "autoconf","automake", "groff", "man-db", "man-pages","elfutils","cpio"]
46 46
     
47
-    def prepareChroot(self,chrootID,toolsArchive=""):
48
-        process = subprocess.Popen([self.prepareBuildRootCmd, chrootID,  constants.specPath,  constants.rpmPath, constants.toolsPath,toolsArchive])
49
-        returnVal = process.wait()
50
-        if returnVal != 0:
47
+    def prepareChroot(self,chrootID,toolsArchive=None):
48
+        cmdUtils=CommandUtils()
49
+        prepareChrootCmd=self.prepareBuildRootCmd+" "+chrootID+" "+constants.specPath+" "+constants.rpmPath+" "+constants.toolsPath
50
+        if toolsArchive is not None:
51
+            prepareChrootCmd=prepareChrootCmd+" "+toolsArchive
52
+        returnVal=cmdUtils.runCommandInShell(prepareChrootCmd)
53
+        if not returnVal:
51 54
             self.logger.error("Prepare build root script failed.Unable to prepare chroot.")
52 55
             raise Exception("Prepare build root script failed")
53 56
 
54
-        cmdUtils=CommandUtils()
55 57
         cmdUtils.runCommandInShell("mkdir -p "+chrootID+constants.topDirPath+"/RPMS")
56 58
         cmdUtils.runCommandInShell("mkdir -p "+chrootID+constants.topDirPath+"/RPMS/x86_64")
57 59
         cmdUtils.runCommandInShell("mkdir -p "+chrootID+constants.topDirPath+"/RPMS/noarch")
... ...
@@ -64,7 +65,8 @@ class ToolChainUtils(object):
64 64
         chrootID=None
65 65
         chrUtils = ChrootUtils(self.logName,self.logPath)
66 66
         try:
67
-            returnVal,chrootID = chrUtils.createChroot()
67
+            chrootName="build-toolchain"
68
+            returnVal,chrootID = chrUtils.createChroot(chrootName)
68 69
             if not returnVal:
69 70
                 raise Exception("creating chroot failed")
70 71
             self.prepareChroot(chrootID)
... ...
@@ -68,8 +68,6 @@ def main():
68 68
     
69 69
     listPackages1=["nano","swig","wget"]
70 70
 
71
-    chrUtils = ChrootUtils()
72
-    chrUtils.updateParams()
73 71
     pkgManager = PackageManager()
74 72
     pkgManager.buildPackages(listPackages)
75 73
  
... ...
@@ -10,6 +10,7 @@ class constants(object):
10 10
     topDirPath=""
11 11
     specData=None
12 12
     testPath="test"
13
+    buildRootPath="/mnt"
13 14
     
14 15
     
15 16
     @staticmethod
... ...
@@ -23,7 +23,10 @@ BUILDROOT=$1
23 23
 SPEC_PATH=$2
24 24
 RPM_PATH=$3
25 25
 TOOLS_PATH=$4
26
-TOOLS_ARCHIVE=$5
26
+TOOLS_ARCHIVE=""
27
+if [ $# -ge 5 ]; then
28
+    TOOLS_ARCHIVE=$5
29
+fi
27 30
 PARENT=/usr/src/photon
28 31
 rm -rf ${BUILDROOT}/*
29 32