source: PSPA/madxPSPA/testing/MadWindowsCompileClient.py @ 457

Last change on this file since 457 was 430, checked in by touze, 11 years ago

import madx-5.01.00

File size: 9.5 KB
Line 
1#!/usr/bin/python
2
3import re
4import os
5import sys
6import traceback
7import shutil
8import time
9
10import socket
11
12# public:
13
14def releaseForWindows(tag): # to be called by MadTrigRelease.pl
15    try:
16        client = windowsReleaseClient()
17        client.release(tag)
18        return 'success'
19    except:
20        exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()
21        traceback.print_tb(exceptionTraceback)
22        return 'failure'
23
24# private:
25
26def getMonthAsString(monthInt):
27    monthStrs = ['Jan','Fev','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
28    monthStr = monthStrs[monthInt-1]     
29    return monthStr
30
31class windowsReleaseClient:
32
33    def __init__(self):
34        self.megabytes = 0 # the size of the binary
35        self.version = 'undefined' # defined in release
36        self.startTimeStr = '' # defined in remoteCompile()
37        self.endTimeStr = ''# defined in remoteCompile()
38        pass
39   
40    def extractSVN(self,tag): # populate /user/nougaret/MAD-X-WINDOWS
41
42        currentDir = os.getcwd()
43
44        os.chdir('/user/nougaret/MAD-X-WINDOWS')
45
46        shutil.rmtree('madX',ignore_errors=True) # clean-up
47        #cmd = 'cvs -d :gserver:isscvs.cern.ch:/local/reps/madx '+\
48        #          'checkout -r '+tag+' '+\
49        #          'madX'
50        cmd = 'svn co svn+ssh://svn.cern.ch/reps/madx/tags/' +\
51              tag +'/madX'+ ' madX'       
52        print cmd
53        os.system(cmd)
54        os.chdir(currentDir) # back to initial location
55
56    def remoteCompile(self):
57        thisLinuxHost = socket.gethostname()
58        windowsHost = 'abpc10788'             # The remote host
59        toWindowsHostPort = 7070              # The same port as used by the server
60        #fromWindowsHostPort = 7071
61        s = None
62        for res in socket.getaddrinfo(windowsHost, toWindowsHostPort,\
63                                      socket.AF_INET, socket.SOCK_STREAM):
64            af, socktype, proto, canonname, sa = res
65            try:
66                s = socket.socket(af, socktype, proto)
67            except socket.error, msg:
68                s = None
69                continue
70            try:
71                s.connect(sa)
72            except socket.error, msg:
73                s.close()
74                s = None
75                continue
76            break
77        if s is None:
78            print 'could not open socket'
79            sys.exit(1)
80        s.send(thisLinuxHost+' asks: Compile MAD for Windows!')
81        print('send compilation request to the Windows host...')
82        startTime = time.localtime()
83        self.startTimeStr = str(startTime.tm_mday)+' '+getMonthAsString(startTime.tm_mon)+\
84                      ' '+str(startTime.tm_year)+ ' '+str(startTime.tm_hour)+':'+str(startTime.tm_min)
85        data = s.recv(1024) # blocking on reception (what about the time out???)
86        s.close()
87        endTime = time.localtime()
88        self.endTimeStr = str(endTime.tm_mday)+' '+getMonthAsString(endTime.tm_mon)+\
89                      ' '+str(endTime.tm_year)+ ' '+str(endTime.tm_hour)+':'+str(endTime.tm_min)       
90        print 'Received', repr(data)
91
92    def checkCompileOutcome(self):
93        # look into MAD-X-WINDOWS and check whether a fresh madx.exe is present
94        try:
95            os.system('rm ./outfile') # if any
96        except:
97            pass
98        os.system('ls -l /user/nougaret/MAD-X-WINDOWS/madX/madx.exe > ./outfile')
99        f = open('./outfile','r')
100        lines = f.readlines()
101        f.close()
102        os.system('rm ./outfile')
103        if len(lines) != 1:
104            raise('error trying to access ./outfile for checking madx.exe')
105        else:
106            singleLine = lines[0]
107            pattern = re.compile(r'(\d+)[\s\t]+([\w\W]{3})[\s\t]+(\d{1,2})[\s\t]+(\d{2}):(\d{2})')
108            m = pattern.search(singleLine)
109            if m:
110                size = float(m.group(1))
111                month = m.group(2)
112                day = m.group(3)
113                hour = m.group(4) # can be year if from last year, in which case 200X instead of xx:yy
114                min = m.group(5)
115                self.megabytes = size/1000000.0 # for subsequent use when generating HTML page
116                print("size="+str(self.megabytes)+", month="+month+", day="+day+",hour="+hour+", min="+min)
117                # compare with local time - should not be older than 5 minutes
118                now = time.localtime()
119                #monthStrs = ['Jan','Fev','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
120                #monthStr = monthStrs[now.tm_mon-1]
121                monthStr = getMonthAsString(now.tm_mon)
122                print("now.tm_mon="+monthStr+", now.tm_day="+str(now.tm_mday)+\
123                      ",now.tm_hour="+str(now.tm_hour)+", min="+str(now.tm_min)) 
124                print('monthStr='+monthStr+', month='+month+', now.tm_mday='+str(now.tm_mday)+', day='+day)
125                if (monthStr==month) and (now.tm_mday==int(day)):
126                    # check if generated less than 5 minutes ago
127                    nowTotalMinutes = 60*(now.tm_hour) + now.tm_min # minutes elapsed since now
128                    totalMinutes = 60*int(hour) + int(min) # minutes elapsed since madx.exe created
129                    print("nowTotalMinutes="+str(nowTotalMinutes)+", totalMinutes="+str(totalMinutes))
130                    print("differences in minutes="+str(nowTotalMinutes-totalMinutes))
131                    if (nowTotalMinutes - totalMinutes)>5:
132                        raise('madx.exe is older than 5 minutes old. abort.')
133                    else:
134                        # done
135                        pass
136                else:
137                    raise('madx.exe is too old. abort.')
138                print("now year="+str(now.tm_year)+", month="+str(now.tm_mon)+\
139                      ", day="+str(now.tm_mday)+", hour="+str(now.tm_hour)+", min="+str(now.tm_min))
140            else:
141                raise('fail to match the date')
142        pass
143        print("completed checkCompileOutcome")
144       # could also gather the executable size here
145   
146
147    def generateHtmlOutput(self):
148        # move MAD-X fresh executable to the AFS web folder
149        executablesAfsWebFolder = '/afs/cern.ch/user/n/nougaret/www/mad/windows-binaries'       
150        # (it has already been put into MAD-X-WINDOWS/madX by the Windows host)
151        os.system('cp /user/nougaret/MAD-X-WINDOWS/madX/madx.exe '+\
152                 executablesAfsWebFolder + '/madx.exe' ) # hard-coded!
153        # now produce the HTML page (may be static actually)
154        htmlFile = executablesAfsWebFolder + '/executables.htm'
155        contents =''
156        contents += "<p>Version "+ self.version+" compiled with Intel ifort and Microsoft Visual C++:</p>\n";
157        contents += "<table width=\"75%\" border=\"0\">\n";
158        oddOrEven = 'even' # to colorize successive lines differently
159
160        contents += "<tr class=\"odd\"><td>Download</td><td><a href=\"./madx.exe\">madx.exe</a></td><td>("+\
161                    str(self.megabytes)+" Megabytes)</td><td>for the latest version.</td></tr>\n";
162   
163        contents += "</table>\n"
164        contents += "<p>Version 3.04.53 compiled with Lahey Fortran and accepting sequences with BV flag, as until March 2009:</p>\n"
165        contents += "<table width=\"75%\" border=\"0\">\n"
166        contents += "<tr class=\"even\"><td>Download</td><td><a href=\"./madx-old.exe\">madx-old.exe</a></td><td>(2.6132 Megabytes)</td><td>for the archived version, without PTC.</td></tr>\n"
167        contents += "<tr class=\"odd\"><td>Download</td><td><a href=\"./madxp-old.exe\">madxp-old.exe</a></td><td>(6.7554 Megabytes)</td><td>for the archived version, including PTC.</td></tr>\n"
168        contents += "</table>\n"
169
170        # create web page in the correct AFS web folder location
171        html = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">'
172        html += "<html>\n"
173        html += "<head>\n"
174        html += "<title>MAD-X downloadable executables</title>\n"
175        html += "<link rel=stylesheet href=\"../MadTestWebStyle.css\" type=\"text/css\">" # CSS one level up
176        html += "</head>\n"
177        html += "<!-- generated by Windows compilation script -->\n"
178        html += "<body>\n"
179        html += "<p>Windows compilation started "+self.startTimeStr+", ended "+self.endTimeStr+"</p>\n"
180        html += contents
181        html += "</body>\n"
182        html += "</html>\n"
183
184        htmlFile = executablesAfsWebFolder + '/executables.htm'
185        f = open(htmlFile,'w')
186        f.write(html)
187        f.close()
188   
189
190    def release(self,tag):
191        pattern = re.compile(r'^madX\-(\d+)_(\d+)_(\d+).*$') # pro, dev ok
192        m = pattern.match(tag)
193        if m:
194            major = m.group(1)
195            medium = m.group(2)
196            minor = m.group(3)
197            self.version = major + '.' + medium + '.' + minor
198        else:
199            raise('ill-formed release tag')
200        # first extract the SVN on NFS
201        self.extractSVN(tag)
202        # then remote invoke compilation on the Windows machine
203        self.remoteCompile()
204        # control the outcome of the compilation
205        self.checkCompileOutcome()
206        # generate HTML information and link to the executable
207        self.generateHtmlOutput()
208
209       
210if __name__ == '__main__':
211
212    if len(sys.argv) != 2:
213        raise('expect exactly one argument: release tag') 
214    else:
215        tag = sys.argv[1]
216        print "/"+tag+"/"
217        pattern = re.compile(r'^madX\-(\d+)_(\d+)_(\d+).+$') # pro, dev ok
218        m = pattern.match(tag)
219        if not m:
220            raise('argument release-tag is ill-formed')
221   
222        outcome = releaseForWindows(tag) # the main function
223        print outcome
Note: See TracBrowser for help on using the repository browser.