Initial upload osce
[tools/obs-tools.git] / osce
1 #!/usr/bin/python
2 import sys, locale, os
3
4 obs_prj_name = 'SLP:Main'
5 osce_root  = '/var/tmp/osce-root'
6 osce_pkgs  = osce_root + '/pkgs'
7 build_root = osce_root + '/build'
8 output_dir = osce_root + '/output'
9 relative_source_dir = '/.source'
10 source_dir = build_root + relative_source_dir
11 chroot_dir = osce_root + '/chroot'
12
13 chroot_mounts = ['/proc', '/proc/sys/fs/binfmt_misc', '/sys', '/dev', '/dev/pts']
14
15 # this is a hack to make osc work as expected with utf-8 characters,
16 # no matter how site.py is set...
17 reload(sys)
18 loc = locale.getdefaultlocale()[1]
19 if not loc:
20     loc = sys.getdefaultencoding()
21 sys.setdefaultencoding(loc)
22 del sys.setdefaultencoding
23
24 from osc import core, oscerr
25 # Injection code for osc.core to fix the empty XML bug
26 def solid_get_files_meta(self, revision='latest', skip_service=True):
27     from time import sleep
28     retry_count = 3
29     while retry_count > 0:
30         fm = core.show_files_meta(self.apiurl, self.prjname, self.name,
31                                   revision=revision, meta=self.meta)
32         try:
33             root = core.ET.fromstring(fm)
34             break
35         except:
36             print 'corrupted or empty obs server response ,retrying ...'
37             sleep(1)
38             retry_count -= 1
39     if not retry_count:
40         # all the re-try failed, abort
41         raise oscerr.OscIOError(None, 'cannet fetch files meta xml from server')
42     # look for "too large" files according to size limit and mark them
43     for e in root.findall('entry'):
44         size = e.get('size')
45         if size and self.size_limit and int(size) > self.size_limit \
46             or skip_service and (e.get('name').startswith('_service:') or e.get('name').startswith('_service_')):
47             e.set('skipped', 'true')
48     return core.ET.tostring(root)
49 core.Package.get_files_meta = solid_get_files_meta
50
51 # run
52 result = 0
53 curr_dir = os.getcwd() 
54 dummy_spec = '''
55 Name:       mkchroot
56 Summary:    mkchroot
57 Version:    0.1
58 Release:    1
59 Group:      SLP/SCM 
60 License:    SLP SCM
61
62 BuildRequires: zypper wget strace which git gdb vim
63
64 %description
65 dummy spec for creating chroot env.
66
67 %prep
68 %build
69 '''
70
71 build_template = '''%build
72 build_source=`pwd`
73 if [ -d ''' + relative_source_dir + ''' ]; then
74      cd %_builddir
75      rm -rf $build_source
76      ln -sf ''' + relative_source_dir + ''' $build_source
77      cd $build_source
78 fi
79 '''
80
81 build_template2 = '''
82 %global _enable_debug_package 0
83 %global debug_package %{nil}
84 '''
85
86 build_template3 = '''%ifarch %{arm}
87 %define EFL_TARGET arm
88 export RPM_OPT_FLAGS="-Wall -O2 -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security  -fmessage-length=0 -march=armv7-a -mtune=cortex-a8 -mlittle-endian -mfpu=vfpv3 -mfloat-abi=softfp -D__SOFTFP__"
89 %else
90 %define EFL_TARGET i386
91 export RPM_OPT_FLAGS="-Wall -O2 -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables"
92 %endif
93 CFLAGS="$RPM_OPT_FLAGS"
94 CXXFLAGS="$RPM_OPT_FLAGS"
95 export CFLAGS
96 export CXXFLAGS
97 '''
98
99 def osce_specfile_info(specfile):
100     specname = None
101     pkg_name = None
102     pkg_version = None
103     if not os.path.exists(specfile):
104         return specname, pkg_name, pkg_version
105     fp = open(specfile, 'r')
106     speclines = fp.readlines()
107     fp.close()
108     
109     for line in speclines:
110         if line.lower().strip().find('name') == 0 and line.find(':') > -1:
111             pkg_name = line.split(':')[1].strip()
112         if line.lower().strip().find('version') == 0 and line.find(':') > -1:
113             pkg_version = line.split(':')[1].strip()
114
115     specname = specfile.split('/')[-1]
116     specname = specname[:specname.rfind('.spec')]
117     if specname != pkg_name:
118         print('spec file name and package name are not the same')
119         specname = None
120         pkg_name = None
121     return specname, pkg_name, pkg_version
122
123 def osce_find_specfile(pkg_dir='./'):
124     specfile = None
125
126     for arg in sys.argv:
127         if arg.find('.spec') > -1:
128             if os.path.exists(arg):
129                 specfile = '(%s/%s)' % (pkg_dir, arg)
130                 return specfile
131
132     for dirname, dirnames, filenames in os.walk(pkg_dir):
133         for filename in filenames:
134             if filename.find('.spec') > -1 and filename != 'tmp.spec':
135                 specfile = filename
136                 break
137         if specfile is not None:
138             break
139
140     specfile = os.path.abspath('%s/%s' % (pkg_dir, specfile))
141     
142     if os.path.exists(specfile):
143         print('specfile : %s' % specfile)
144         return specfile
145     else:
146         print('cannot find specfile : %s' % specfile)
147         return None  
148
149 def osce_get_random_pkgdir():
150     if os.path.exists('%s/%s' % (osce_pkgs, obs_prj_name)):
151         for dirname, dirnames, filenames in os.walk('%s/%s' % (osce_pkgs, obs_prj_name)):
152            for pkgdir in dirnames:
153                if pkgdir != '.osc':
154                    return '%s/%s/%s' % (osce_pkgs, obs_prj_name, pkgdir)
155     return None
156
157 def osce_cmd_run():
158     from osc import commandline, babysitter
159     cmdline = commandline.Osc()
160
161     result = babysitter.run(cmdline)
162     return result
163
164 def osce_sys_run(cmdln_or_args):
165     print(cmdln_or_args)
166     
167     os.system(cmdln_or_args)
168
169 def osce_mount_srcdir(sourcedir=os.getcwd()):
170     if not os.path.exists(source_dir):
171         osce_sys_run('sudo mkdir -p ' + source_dir)
172     if os.path.exists(source_dir) and os.path.exists(sourcedir):
173         cmdline = 'sudo mount --bind %s %s' % (sourcedir, source_dir)
174     osce_sys_run(cmdline)
175
176 def osce_umount(mount_dir):
177     fp = open('/proc/mounts', 'r')
178     mounts = fp.readlines()
179     fp.close()
180
181     for mount in reversed(mounts):
182         mountpoint = mount.split(' ')[1]
183         if mountpoint.find(mount_dir) > -1:
184             osce_sys_run('sudo umount %s' % mountpoint)
185
186 def osce_clear():
187     for dirname, dirnames, filenames in os.walk('.'):
188         for filename in filenames:
189             if filename == 'tmp.spec':
190                 osce_sys_run('rm %s' % filename)
191
192     osce_umount(source_dir)
193
194     fp = open('/proc/mounts', 'r')
195     mounts = fp.read()
196     fp.close()
197    
198     if os.path.exists(source_dir) and mounts.find(source_dir) < 0:
199         osce_sys_run('sudo rmdir %s ' % source_dir)
200
201 def osce_chrootex_mount():
202     for mnt in chroot_mounts:
203         cmdline = 'sudo mount --bind %s %s%s' % (mnt, chroot_dir, mnt)
204         osce_sys_run(cmdline)
205
206 def osce_chrootex_umount():
207     osce_umount(chroot_dir)
208
209 def osce_mkchrootex():
210     dummyproj_dir = osce_pkgs + '/dummy'
211     dummypkg_dir = dummyproj_dir + '/dummy'
212
213     if os.path.exists(dummyproj_dir):
214         osce_sys_run('sudo rm -rf %s' % dummyproj_dir)
215
216     osce_sys_run('sudo mkdir -p %s' % dummyproj_dir)
217     os.chdir(dummyproj_dir)
218     osce_sys_run('sudo chown `whoami` %s' % dummyproj_dir)
219     osce_sys_run('osce init %s' % obs_prj_name) 
220     osce_sys_run('osce mkpac dummy') 
221
222     if not os.path.exists(dummypkg_dir + '/dummy.spec'):
223         fd = open(dummypkg_dir + '/dummy.spec', 'w')
224         fd.write(dummy_spec)
225         fd.close()
226
227     if not os.path.exists(chroot_dir):
228         osce_sys_run('sudo mkdir -p ' + chroot_dir)
229
230     os.chdir(dummypkg_dir)
231     osce_sys_run('osc build armv7el dummy.spec --clean --local-package --no-verify --root=%s/ ' % chroot_dir)
232     osce_chrootex_mount()
233     osce_sys_run('sudo chroot %s rpm -e rpm-x86-arm rpm-libs-x86-arm rpm-build-x86-arm' % chroot_dir)
234     if len(chroot_dir) > 6:
235         osce_sys_run('sudo rm %s/var/lib/rpm/__db*' % chroot_dir)
236     osce_sys_run('sudo chroot %s zypper addrepo http://165.213.148.149:82/SLP:/Base/standard/SLP:Base.repo' % chroot_dir)
237     osce_sys_run('sudo chroot %s zypper addrepo http://165.213.148.149:82/SLP:/System/standard/SLP:System.repo' % chroot_dir)
238     osce_sys_run('sudo chroot %s zypper addrepo http://165.213.148.149:82/SLP:/Main/standard/SLP:Main.repo' % chroot_dir)
239     osce_sys_run('sudo chroot %s zypper refresh' % chroot_dir)
240     osce_sys_run('sudo chroot %s rpmdb --rebuilddb' % chroot_dir)
241     osce_sys_run('sudo chroot ' + chroot_dir )
242     osce_chrootex_umount()
243
244 def osce_chrootex():
245     if os.path.exists(chroot_dir):
246         osce_chrootex_mount()
247         osce_sys_run('sudo chroot ' + chroot_dir )
248         osce_chrootex_umount()
249
250 def osce_check__buildcmd():
251     from osc import build
252     buildfile = build.__file__
253
254     source = '''            repositories.append(repository)
255
256     packageQueries = packagequery.PackageQueries(wanted_arch)
257
258     for repository in repositories:'''
259
260     fp = open(buildfile, 'r')
261     buildcontent = fp.read()
262     fp.close()
263
264     if buildcontent.find(source) > -1:
265         print('------please execute below command to patch build.py---THIS WILL BE FIXED---')
266         print('''sudo sed --in-place "s/    packageQueries = packagequery.PackageQueries(wanted_arch)/    if wanted_arch == 'armv7el':\\n        wanted_arch = 'armv7l'\\n\\n    if wanted_arch == 'armv8el':\\n        wanted_arch = 'armv7hl'\\n\\n    packageQueries = packagequery.PackageQueries(wanted_arch)/g" %s''' % buildfile)
267         print('----------------------------------------------------------------------------')
268
269         sys.exit(-1)
270     del sys.modules["osc.build"]
271
272 def osce_build():
273     sys.argv = sys.argv + ['--ccache', '--no-verify', '--release=999', '--build-uid=0:0', '--no-checks', '--disable-debuginfo', '--offline']
274     sys.argv = sys.argv + ['--keep-pkgs=%s' % output_dir, '--oldpackages=%s' % output_dir]
275     sys.argv = sys.argv + ['--prefer-pkgs=%s' % output_dir, '--root=%s' % build_root ]
276
277     if '--timerebase' in sys.argv:
278         sys.argv.remove('--timerebase')
279         os.system('sudo touch ' + build_root + '/timebase')
280         os.system('sudo find ' + build_root + '/usr -newer ' + build_root + '/timebase -exec touch 06302051 {} \\;')
281         os.system('sudo find ' + build_root + '/lib -newer ' + build_root + '/timebase -exec touch 06302051 {} \\;')
282
283     debug_mode = False
284     if '--debug' in sys.argv:
285         sys.argv.remove('--debug')
286         sys.argv.remove('--disable-debuginfo')
287         debug_mode = True
288
289     if '--online' in sys.argv:
290         sys.argv.remove('--online')
291         sys.argv.remove('--offline')
292
293     if os.path.exists(source_dir):
294         specfile = osce_find_specfile()
295         if specfile is None:
296             return
297         fp = open(specfile, 'r')
298         speccontent = fp.read()
299         fp.close()
300
301         if debug_mode:
302             speccontent = speccontent.replace('%build', build_template)
303         else:
304             speccontent = build_template2 + speccontent
305             speccontent = speccontent.replace('%build', build_template + build_template3)
306
307         fp = open('tmp.spec', 'w')
308         fp.write(speccontent)
309         fp.close()
310          
311         sys.argv = sys.argv + ['tmp.spec']
312
313     osce_check__buildcmd()
314     osce_cmd_run()
315
316 def osce_prepare_git_done():
317     cmdline = 'osce clear'
318     osce_sys_run(cmdline)
319 # cd git directory
320     os.chdir(curr_dir)
321     # copy output file to under the current path
322     os.system('find %s/home/abuild/rpmbuild/RPMS/ -name "*.rpm" -type f -exec cp -f {} %s' % (build_root, curr_dir + "/.."))
323
324 def osce_prepare_git():
325     print('osce_prepare_git')
326     import shutil
327
328     if not os.path.exists(osce_pkgs) or  len(osce_pkgs) < 6:
329         print('choose another directory')
330         return
331
332     if not os.path.exists(curr_dir + '/packaging'):
333         print('cannot find packaging directory')
334         return
335
336 # check packaging directory
337 # extract package name from the spec file
338 # if multiple specfile exist, then request spec file name to be built as an option
339
340     specfile = osce_find_specfile('%s/packaging' % curr_dir)
341     if specfile is None:
342         osce_prepare_git_done()
343         return
344
345     specname, pkg_name, pkg_version = osce_specfile_info(specfile)
346
347     if pkg_name is None or pkg_version is None or specname is None:
348         osce_prepare_git_done()
349         return
350 # OBSPKGDIR = osce_pkgs
351 # cd $OBSPKGDIR
352     os.chdir(osce_pkgs)
353 # check whether the PKG dir exists or not, 
354 # how can get the proj name? take another option? obs_prj_name
355 # osce checkout $PROJ $PKG
356     obs_pkg_dir = '%s/%s/%s' % (osce_pkgs, obs_prj_name, pkg_name)
357     if not os.path.exists(obs_pkg_dir):
358         cmdline = 'osce checkout %s %s' % (obs_prj_name, pkg_name)
359         osce_sys_run(cmdline)
360 # cd $PKG
361     os.chdir(obs_pkg_dir)
362 # remove source files, copy packaging/* , empty tarball (name-version.tar.gz, name-version/)
363
364     if os.path.exists(obs_pkg_dir) and  len(os.getcwd()) > 6:
365         cmdline = 'rm -rf *'    
366         osce_sys_run(cmdline)
367     else:
368         osce_prepare_git_done()
369         return
370
371     cmdline = 'cp %s/packaging/* %s/' %(curr_dir, obs_pkg_dir)    
372     osce_sys_run(cmdline)
373     if not os.path.exists('%s-%s' % (pkg_name, pkg_version)):
374         os.mkdir('%s-%s' % (pkg_name, pkg_version))
375     else:
376         osce_prepare_git_done()
377         return
378
379     shutil.make_archive('%s-%s' % (pkg_name, pkg_version), 'gztar', '.', '%s-%s' % (pkg_name, pkg_version)) 
380
381     if '--clean' in sys.argv or not os.path.exists(build_root):
382         specfile = '%s.spec' % specname
383         if os.path.exists(specfile):
384             fp = open(specfile, 'r')
385             specs = fp.read()
386             fp.close()
387             fp = open(specfile, 'w')
388             fp.write(specs[:specs.find('%prep') + 6])
389             fp.close()
390             
391             osce_sys_run(' '.join(sys.argv))
392             os.chdir(curr_dir)
393             if '--clean' in sys.argv:
394                 sys.argv.remove('--clean') 
395 # osce srcmnt $gitdirectory
396     cmdline = 'osce srcmnt %s' % curr_dir
397     osce_sys_run(cmdline)
398 # osce build 
399     cmdline = ' '.join(sys.argv)
400     osce_sys_run(cmdline)
401 # osce clear
402     osce_prepare_git_done()
403
404 def osce_chroot():
405     if os.path.exists(build_root):
406         osce_sys_run('sudo chroot ' + build_root + ' su abuild')
407
408 def osce_mktar():
409     options = ["--exclude='.git*'", "--exclude='CMakeFiles'", "--exclude='CMakeCache.txt'"]
410
411     specfile = osce_find_specfile('%s/packaging' % curr_dir)
412
413     if specfile is None:
414         return
415
416     specname, pkg_name, pkg_version = osce_specfile_info(specfile)
417
418     if pkg_name is None or pkg_version is None or specname is None:
419         return
420
421     cmdline = '''tar --transform 's,^,/%s-%s/,' %s -zcvf ../%s-%s.tar.gz *''' % (pkg_name, pkg_version, ' '.join(options), pkg_name, pkg_version)
422     osce_sys_run(cmdline)
423
424 def main():
425
426     if not os.path.exists(osce_pkgs):
427         os.makedirs(osce_pkgs)
428
429     if 'clear' in sys.argv:
430         osce_clear()
431         return
432
433     if 'srcmnt' in sys.argv:
434         osce_clear()
435         if os.path.exists(sys.argv[2]):
436             osce_mount_srcdir(sys.argv[2])
437         return
438     
439     if 'mktar' in sys.argv:
440         osce_mktar()
441         return
442
443     if 'chroot' in sys.argv:
444         osce_chroot()
445         return
446
447     if 'mkchrootex' in sys.argv:
448         osce_mkchrootex()
449         return
450
451     if 'chrootex' in sys.argv:
452         osce_chrootex()
453         return
454     
455     if 'checkout' in sys.argv:
456 #        sys.argv = sys.argv + ['--current-dir']
457         print('checkout')
458
459     if '--clean' in sys.argv:
460         osce_clear()
461     
462     if 'build' in sys.argv:
463         for dirname, dirnames, filenames in os.walk('.'):
464             for dirtype in dirnames:
465                 if dirtype == '.git':
466                     osce_prepare_git()
467                     return
468                 elif dirtype == '.osc':   
469                     osce_build()
470                     return
471         print('cannot find .git or .osc directory') 
472         return
473
474     osce_cmd_run()
475     
476 if __name__ == "__main__":
477     main()
478
479