1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
# vim: set sw=4 sts=4 et :
# Copyright: 2008 Gentoo Foundation
# Author(s): Nirbheek Chauhan <nirbheek.chauhan@gmail.com>
# License: GPL-2
#
# Immortal lh!
#
# XXX: This is purely yay-something-works code
# This will change radically with time
import re, subprocess, sys, os
import os.path as osp
from .. import const
class Jobuild(object):
"""A jobuild"""
def __init__(self, jobdir, atom):
"""
@param jobdir: Job directory (of the form tmpdir/maint/job_name)
@type jobdir: string
@param atom: Atom for finding the corresponding jobuild
@type jobdir: string
"""
self.name = atom
self.jobdir = jobdir
self.path = self._best_jobuild(atom)
def __str__(self):
return '%s jobuild object' % self.name
def _split_atom(self, atom):
regex = re.compile(r'^([<>]?=)?([a-zA-Z0-9_+-]+)/([a-zA-Z0-9_+-]+)(-|$)([0-9]+\.[0-9]+)?') # Fancy regex aye?
# >= bheekling / test-beagle - 1.0
# bheekling / build-brasero
parts = regex.findall(atom)
if not parts:
# FIXME: Custom exceptions
raise 'Invalid atom %s' % atom
parts = parts[0]
if parts[3] and not parts[4]:
# FIXME: Custom exceptions
raise 'Invalid atom %s' % atom
parts = (parts[0], parts[1], parts[2], parts[4],)
if (parts[0] and not parts[3]) or (parts[3] and not parts[0]):
# FIXME: Custom exceptions
raise 'Invalid atom %s' % atom
return parts
def _get_all_pv_sorted(self, data):
files = os.listdir('%(jobtage)s/%(maint)s/%(pn)s' % data)
for file in files[:]:
if not file.endswith('.jobuild'):
files.remove(file)
else:
files[files.index(file)] = '=%s/%s' % (data['maint'], osp.basename(file)[:-8],) # .jobuild is 8 characters
# =maint/pn-pv
pv = []
for atom in files:
pv.append(self._split_atom(atom)[3])
pv.sort()
return pv
def _best_jobuild(self, atom):
parts = self._split_atom(atom)
data = {'op': parts[0],
'maint': parts[1],
'pn': parts[2],
'pv': parts[3],
'jobtage': '%s/jobtage' % self.jobdir}
if data['op'] == '=':
pass # Nothing to be done
elif not data['op']:
pv = self._get_all_pv_sorted(data)
data['pv'] = pv[-1]
elif data['op'] == '>=':
pv = self._get_all_pv_sorted(data)
if pv[-1] >= data['pv']:
data['pv'] = pv[-1]
else:
raise 'No matching jobuild found for atom \"%s\"' % atom
elif data['op'] == '<=':
pv = self._get_all_pv_sorted(data)
pv.reverse()
for i in pv:
if i <= data['pv']:
data['pv'] = i
break
if i == pv[-1]: # If it's the last pv..
raise 'No matching jobuild found for atom \"%s\"' % atom
return '%(jobtage)s/%(maint)s/%(pn)s/%(pn)s-%(pv)s.jobuild' % data
class Processor(object):
"""Jobuild processor"""
def __init__(self, jobuild, chroot):
"""
@param jobuild: Jobuild to process
@type jobuild: L{autotua.jobuild.Jobuild}
@param chroot: Chroot to use for processing the jobuild
@type chroot: L{autotua.chroot.WorkChroot}
"""
self.jobuild = jobuild
self.chroot = chroot
def run_phase(self, phase):
"""Run the specified phase of the jobuild"""
args = {'phase': phase,
'jobuild': self.jobuild.path,
'chroot': self.chroot.dir,}
self._msg('RUN_PHASE "%(phase)s" "%(jobuild)s" "%(chroot)s"' % args)
def get_var(self, var):
"""
Parse jobuild and get a variable
(yay-something-works function)
"""
args = {'var': var,
'jobuild': self.jobuild.path,}
return self._msg('GET_VAR "%(var)s" "%(jobuild)s"' % args)
def _msg(self, msg):
# Messages goto 3 and then to /dev/tty1
# stderr goes to stdout
# stdout goes to ${LOGFILE}
process = subprocess.Popen('\"%s\"/bin/jobuild.sh %s 3>&2 2>&1 | tee -a \"%s\"' % (const.AUTOTUA_DIR, msg, const.LOGFILE), shell=True, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
process.stdin.write('ping\n')
response = process.stderr.readline()[:-1] # Remove trailing newline
if not response == 'pong':
# FIXME: Custom exceptions
raise 'Communication error: received %s when expecting "pong"' % response
response = process.stderr.read()[:-1] # Remove trailing newline
return response
|