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):
15 self.state_changed = CList()
17 self.status = self.NOT_STARTED
19 # description is a dict
20 def fromDescription(self, description):
23 def createDescription(self):
26 def addTask(self, task):
27 self.tasks.append(task)
29 def start(self, callback):
30 assert self.callback is None
31 self.callback = callback
32 self.status = self.IN_PROGRESS
37 if self.current_task == len(self.tasks):
38 self.callback(self, [])
39 self.status = self.FINISHED
42 self.tasks[self.current_task].run(self.taskCallback)
45 def taskCallback(self, res):
47 print ">>> Error:", res
48 self.status = self.FAILED
50 self.callback(self, res)
52 self.current_task += 1
56 def __init__(self, name):
58 self.workspace = "/tmp"
59 self.immediate_preconditions = [ ]
60 self.global_preconditions = [ ]
61 self.postconditions = [ ]
62 self.returncode = None
63 self.initial_input = None
68 def setCommandline(self, cmd, args):
72 def setTool(self, tool):
75 self.global_preconditions.append(ToolExistsPrecondition())
76 self.postconditions.append(ReturncodePostcondition())
78 def checkPreconditions(self, immediate = False):
81 preconditions = self.immediate_preconditions
83 preconditions = self.global_preconditions
84 for precondition in preconditions:
85 if not precondition.check(self):
86 not_met.append(precondition)
89 def run(self, callback):
90 failed_preconditions = self.checkPreconditions(True)
91 if len(failed_preconditions):
92 errback(failed_preconditions)
95 self.callback = callback
96 from enigma import eConsoleAppContainer
97 self.container = eConsoleAppContainer()
98 self.container.appClosed.get().append(self.processFinished)
99 self.container.dataAvail.get().append(self.processOutput)
101 assert self.cmd is not None
102 assert len(self.args) >= 1
104 print "execute:", self.container.execute(self.cmd, self.args), self.cmd, self.args
105 if self.initial_input:
106 self.writeInput(self.initial_input)
111 def cleanup(self, failed):
114 def processOutput(self, data):
117 def processFinished(self, returncode):
118 self.returncode = returncode
124 for postcondition in self.postconditions:
125 if not postcondition.check(self):
126 not_met.append(postcondition)
128 self.callback(not_met)
133 def writeInput(self, input):
134 self.container.write(input)
138 self.active_jobs = [ ]
139 self.failed_jobs = [ ]
140 self.job_classes = [ ]
141 self.active_job = None
143 def AddJob(self, job):
144 self.active_jobs.append(job)
148 if self.active_job is None:
149 if len(self.active_jobs):
150 self.active_job = self.active_jobs.pop(0)
151 self.active_job.start(self.jobDone)
153 def jobDone(self, job, problems):
154 print "job", job, "completed with", problems
156 self.failed_jobs.append(self.active_job)
158 self.active_job = None
162 #class PartitionExistsPostcondition:
163 # def __init__(self, device):
164 # self.device = device
166 # def check(self, task):
168 # return os.access(self.device + "part1", os.F_OK)
170 #class CreatePartitionTask(Task):
171 # def __init__(self, device):
172 # Task.__init__(self, _("Create Partition"))
173 # self.device = device
174 # self.setTool("/sbin/sfdisk")
175 # self.args += ["-f", self.device + "disc"]
176 # self.initial_input = "0,\n;\n;\n;\ny\n"
177 # self.postconditions.append(PartitionExistsPostcondition(self.device))
179 #class CreateFilesystemTask(Task):
180 # def __init__(self, device, partition = 1, largefile = True):
181 # Task.__init__(self, _("Create Filesystem"))
182 # self.setTool("/sbin/mkfs.ext")
184 # self.args += ["-T", "largefile"]
185 # self.args.append("-m0")
186 # self.args.append(device + "part%d" % partition)
188 #class FilesystemMountTask(Task):
189 # def __init__(self, device, partition = 1, filesystem = "ext3"):
190 # Task.__init__(self, _("Mounting Filesystem"))
191 # self.setTool("/bin/mount")
192 # if filesystem is not None:
193 # self.args += ["-t", filesystem]
194 # self.args.append(device + "part%d" % partition)
196 #class DiskspacePrecondition:
197 # def __init__(self, diskspace_required):
198 # self.diskspace_required = diskspace_required
200 # def check(self, task):
201 # return getFreeDiskspace(task.workspace) >= self.diskspace_required
203 #class ToolExistsPrecondition:
204 # def check(self, task):
206 # return os.access(task.cmd, os.X_OK)
208 #class ReturncodePostcondition:
209 # def check(self, task):
210 # return task.returncode == 0
212 #class HDDInitJob(Job):
213 # def __init__(self, device):
214 # Job.__init__(self, _("Initialize Harddisk"))
215 # self.device = device
216 # self.fromDescription(self.createDescription())
218 # def fromDescription(self, description):
219 # self.device = description["device"]
220 # self.addTask(CreatePartitionTask(self.device))
221 # self.addTask(CreateFilesystemTask(self.device))
222 # self.addTask(FilesystemMountTask(self.device))
224 # def createDescription(self):
225 # return {"device": self.device}
227 job_manager = JobManager()