1 # A Job consists of many "Tasks".
2 # A task is the run of an external tool, with proper methods for failure handling
4 from Tools.CList import CList
7 NOT_STARTED, IN_PROGRESS, FINISHED, FAILED = range(4)
8 def __init__(self, name):
10 self.workspace = "/tmp"
16 self.state_changed = CList()
18 self.status = self.NOT_STARTED
20 # description is a dict
21 def fromDescription(self, description):
24 def createDescription(self):
27 def addTask(self, task):
29 self.tasks.append(task)
31 def start(self, callback):
32 assert self.callback is None
33 self.callback = callback
34 self.status = self.IN_PROGRESS
39 if self.current_task == len(self.tasks):
40 self.callback(self, [])
41 self.status = self.FINISHED
44 self.tasks[self.current_task].run(self.taskCallback)
47 def taskCallback(self, res):
49 print ">>> Error:", res
50 self.status = self.FAILED
52 self.callback(self, res)
54 self.current_task += 1
58 def __init__(self, job, name):
60 self.immediate_preconditions = [ ]
61 self.global_preconditions = [ ]
62 self.postconditions = [ ]
63 self.returncode = None
64 self.initial_input = None
71 def setCommandline(self, cmd, args):
75 def setTool(self, tool):
78 self.global_preconditions.append(ToolExistsPrecondition())
79 self.postconditions.append(ReturncodePostcondition())
81 def checkPreconditions(self, immediate = False):
84 preconditions = self.immediate_preconditions
86 preconditions = self.global_preconditions
87 for precondition in preconditions:
88 if not precondition.check(self):
89 not_met.append(precondition)
92 def run(self, callback):
93 failed_preconditions = self.checkPreconditions(True) + self.checkPreconditions(False)
94 if len(failed_preconditions):
95 callback(failed_preconditions)
99 self.callback = callback
100 from enigma import eConsoleAppContainer
101 self.container = eConsoleAppContainer()
102 self.container.appClosed.get().append(self.processFinished)
103 self.container.dataAvail.get().append(self.processOutput)
105 assert self.cmd is not None
106 assert len(self.args) >= 1
108 print "execute:", self.container.execute(self.cmd, self.args), self.cmd, self.args
109 if self.initial_input:
110 self.writeInput(self.initial_input)
115 def cleanup(self, failed):
118 def processOutput(self, data):
121 def processFinished(self, returncode):
122 self.returncode = returncode
128 for postcondition in self.postconditions:
129 if not postcondition.check(self):
130 not_met.append(postcondition)
132 self.callback(not_met)
137 def writeInput(self, input):
138 self.container.write(input)
142 self.active_jobs = [ ]
143 self.failed_jobs = [ ]
144 self.job_classes = [ ]
145 self.active_job = None
147 def AddJob(self, job):
148 self.active_jobs.append(job)
152 if self.active_job is None:
153 if len(self.active_jobs):
154 self.active_job = self.active_jobs.pop(0)
155 self.active_job.start(self.jobDone)
157 def jobDone(self, job, problems):
158 print "job", job, "completed with", problems
160 self.failed_jobs.append(self.active_job)
162 self.active_job = None
166 #class PartitionExistsPostcondition:
167 # def __init__(self, device):
168 # self.device = device
170 # def check(self, task):
172 # return os.access(self.device + "part1", os.F_OK)
174 #class CreatePartitionTask(Task):
175 # def __init__(self, device):
176 # Task.__init__(self, _("Create Partition"))
177 # self.device = device
178 # self.setTool("/sbin/sfdisk")
179 # self.args += ["-f", self.device + "disc"]
180 # self.initial_input = "0,\n;\n;\n;\ny\n"
181 # self.postconditions.append(PartitionExistsPostcondition(self.device))
183 #class CreateFilesystemTask(Task):
184 # def __init__(self, device, partition = 1, largefile = True):
185 # Task.__init__(self, _("Create Filesystem"))
186 # self.setTool("/sbin/mkfs.ext")
188 # self.args += ["-T", "largefile"]
189 # self.args.append("-m0")
190 # self.args.append(device + "part%d" % partition)
192 #class FilesystemMountTask(Task):
193 # def __init__(self, device, partition = 1, filesystem = "ext3"):
194 # Task.__init__(self, _("Mounting Filesystem"))
195 # self.setTool("/bin/mount")
196 # if filesystem is not None:
197 # self.args += ["-t", filesystem]
198 # self.args.append(device + "part%d" % partition)
200 #class DiskspacePrecondition:
201 # def __init__(self, diskspace_required):
202 # self.diskspace_required = diskspace_required
204 # def check(self, task):
205 # return getFreeDiskspace(task.workspace) >= self.diskspace_required
207 class ToolExistsPrecondition:
208 def check(self, task):
210 return os.access(task.cmd, os.X_OK)
212 class ReturncodePostcondition:
213 def check(self, task):
214 return task.returncode == 0
216 #class HDDInitJob(Job):
217 # def __init__(self, device):
218 # Job.__init__(self, _("Initialize Harddisk"))
219 # self.device = device
220 # self.fromDescription(self.createDescription())
222 # def fromDescription(self, description):
223 # self.device = description["device"]
224 # self.addTask(CreatePartitionTask(self.device))
225 # self.addTask(CreateFilesystemTask(self.device))
226 # self.addTask(FilesystemMountTask(self.device))
228 # def createDescription(self):
229 # return {"device": self.device}
231 job_manager = JobManager()