Commits

Moises Henriquez committed 0d0e8d8

Working bot. Added support for building from URLs and local sources.

  • Participants
  • Parent commits a98477f

Comments (0)

Files changed (6)

     def __init__(self, parent=None):
         threading.Thread.__init__(self)
         self.name = 'job-dispatcher'
-#        threading.Thread.__init__(self)
-#        self.set_name(self.name)
         self.parent = parent
-#        self.db = sqlite3.connect('/tmp/vpackager.db')
 
     def _get_next_job(self):
+        return dbutils.GetNextJob()
         db = sqlite3.connect('/tmp/vpackager.db')
         c = db.cursor()
         c.execute('select * from queue')
         return ret
 
     def _log_job_start(self, _id):
-        db = sqlite3.connect('/tmp/vpackager.db')
-        c = db.cursor()
-        # Get the details from the queue
-        t = (_id,)
-        c.execute('delete from history where id=?',t)
-        c.execute('select id,app,ver,srcURI,descURI,release from queue where id=?',t)
-        res = c.next()
-        c.execute('''insert into history
-        (id,app,ver,srcURI,descURI,release, buildstart) 
-        values (?,?,?,?,?,?,CURRENT_TIMESTAMP)''', res)
-        c.execute('select * from history')
-        #print c.fetchall()
-        c.close()
-        db.commit()
+        return dbutils.LogJobStart(_id)
 
     def _log_job_end(self, _id, stdoutpath, result):
-        db = sqlite3.connect('/tmp/vpackager.db')
-        c = db.cursor()
-        t = (_id,)
-        c.execute('''update history set buildend=CURRENT_TIMESTAMP where
-                id=?''',t)
-        t = (stdoutpath,_id)
-        c.execute('''update history set stdout=? where id=?''',t)
-        t = (result, _id)
-        c.execute('''update history set result=? where id=?''',t)
-        c.close()
-        db.commit()
+        return dbutils.LogJobEnd(_id, stdoutpath, result)
+
+    def _refresh_views(self):
+        self.parent.historyman._refresh_history_display()
+        self.parent.queueman._update_queue()
 
     def run(self):
         while self.parent._bot_run:
             time.sleep(0.25)
-            (_id,pkg,ver,src,desc,rel) = self._get_next_job()
+            njob = dbutils.GetNextJob()
+            if njob is None:
+                # NO new job in queue
+                self.parent._bot_run = False
+                print "Stopping bot because there is nothing to do"
+                return
+            # clear the textview
+            buf = self.parent.outputplayer.get_buffer()
+            buf.delete(buf.get_bounds()[0], buf.get_bounds()[1])
+
+            (_id,pkg,ver,src,desc,rel,_type,toinstall) = njob
+            # Log the build start time
             self._log_job_start(_id)
+            # Update GUI displays for queue and history
+            self._refresh_views()
             self.parent.job_indicator.set_markup('<b>%s-%s</b>'%(pkg,ver))
             if src.startswith('/'):
                 srcob = buildutils.Source(src)
-                sbpath = srcob.makeSlackBuild(buildno = rel)
-#                print sbpath
-                os.chdir(os.path.dirname(sbpath))
-#                os.chdir(srcob.__myhome)
-                if not desc.startswith('/'):
-                # Download the description
-                    urllib.urlretrieve(desc, 'slack-desc')
-                else:
-                    shutil.copy(desc, 'slack-desc')
-                job = srcob.buildSlackBuild()
-                job.observer.add_callback(self.parent._play_output)
-                job.run()
-                while job._popen_running:
-                    time.sleep(1)
-                retval = job.popen.returncode
-                if retval > 0:
-                    result='FAIL'
-                else:
-                    result='Success'
-#                print 'job ended with code', job.popen.returncode
-                # remove the job from the queue
-                db = sqlite3.connect('/tmp/vpackager.db')
-                c = db.cursor()
-                t=(_id,)
-                c.execute('delete from queue where id=?',t)
-                c.close()
-                db.commit()
-                # Log the job result
-                self._log_job_end(_id, 'foo.txt',result)
-                # Refresh the history display
-                self._parent.historyman._refresh_history_display()
-
-
-
-    def _run_job(self, pkg, ver, src, desc, rel):
-        _src_dir = buildutils._sources_home
-        _prevdir = os.getcwd()
-        os.chdir(_src_dir)
-        if src.startswith('/'):
-            srcob = buildutils.Source(src)
-            srcob.makeSlackBuild(buildno=rel)
-            # ^^ that method also copies the source to the right place, so we
-            # just need to cd into it.
-            os.chdir(srcob.__myhome)
-            if not desc.startswith('/'):
-                # Download the description file
+            else:
+                srcob = buildutils.SourceURL(app = pkg, version=ver,
+                        srctype=_type, link=src)
+            sbpath = srcob.makeSlackBuild(buildno = rel)
+            # cd to the right place
+            os.chdir(os.path.dirname(sbpath))
+            if desc.startswith('/'):
+                shutil.copy2(desc, 'slack-desc')
+            else:
                 urllib.urlretrieve(desc, 'slack-desc')
             job = srcob.buildSlackBuild()
-            job.observer.add_callback(self._parent._play_output)
+            job.observer.add_callback(self.parent._play_output)
             job.run()
             while job._popen_running:
                 time.sleep(1)
-            print 'Job ended with code', job.popen.returncode
+            retval = job.popen.returncode
+            if retval > 0:
+                result = 'Fail'
+            else:
+                result = 'Success'
 
-
-
+            # Save the output to a log file
+            buf = self.parent.outputplayer.get_buffer()
+            #logpath = sbpath.replace('.SlackBuild', '.build_log')
+            logpath = os.path.join(os.path.dirname(srcob.srclocation),
+                    '%s.build_log'% srcob.app)
+            output = buf.get_text(buf.get_bounds()[0], buf.get_bounds()[1])
+            f = open(logpath, 'w')
+            f.write(output)
+            f.close()
+            # Log the build result to the database
+            self._log_job_end(_id, logpath, result)
+            # Refresh the GUI display of the history and queue
+            self._refresh_views()
+            if result == "Success" and toinstall == "1":
+                # install the package
+                print 'we should be installing this package here'
 
 
 
         gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
         self.set_title('vpackager')
         self.connect('destroy', self._exit)
-        self.set_size_request(600, 400)
+        self.set_size_request(950, 500)
         self.body = gtk.VBox()
         self.outputplayer = None
+        self.historyman = None
+        self.queueman = None
         self._bot_run = False
         self.body.pack_start(self._get_menubar(), False, True, 4)
         self.body.pack_start(self._get_notebook(), True, True, 4)
         self.body.pack_start(self._get_bottombar(), False, False, 4)
 
-        self.queueman = None
-        self.historyman = None
-
         self.add(self.body)
 
     def _play_output(self, line):

File historymanager.py

     def __init__(self):
         gtk.VBox.__init__(self)
         self.model = gtk.ListStore(
-                int, str, str, str, str, str, str, str, str)
+                int, str, str, str, str, str, str, str, str, str, str)
         self.pack_start(gtk.Label('Job History'), False, True, 2)
-        self.pack_start(self._get_tree())
+        scroll = gtk.ScrolledWindow()
+        scroll.set_policy(gtk.POLICY_AUTOMATIC,
+                gtk.POLICY_AUTOMATIC)
+        self.pack_start(scroll, True, True, 2)
+        scroll.add(self._get_tree())
+#        self.pack_start(self._get_tree())
         self.show_all()
+        self._refresh_history_display()
 
 
     def _get_tree(self):
         self.tree = gtk.TreeView(model = self.model)
         i = 0
         for field in ('ID', 'Package', 'Version', 'Source URI', 'Description',
-                'Build Start', 'Build End', 'Output', 'Result'):
+                'Release','Type', 'Build Start', 'Build End', 'Output', 'Result'):
             col = gtk.TreeViewColumn(field)
+            col.set_resizable(True)
             crt = gtk.CellRendererText()
             col.pack_start(crt)
             col.add_attribute(crt, 'text', i)
 
     def _refresh_history_display(self):
         self.tree.set_model(
-                gtk.ListStore(int,str, str, str, str, str, str, str, str))
+                gtk.ListStore(int,str, str, str, str, str, str, str, str, str,str))
         lst = dbutils.GetHistory()
         for entry in lst:
-            self.tree.get_moel().append(entry)
+            self.tree.get_model().append(entry)
 

File jobmanage.py

             desc = dia.DescURI
             srcuri = dia.SrcURI
             rel = dia.release
+            srctype = dia.srctype
+            toinstall = dia.install
             dia.destroy()
-            dbutils.NewJob(app, ver, srcuri, desc, rel)
+            dbutils.NewJob(app, ver, srcuri, desc, rel, srctype, toinstall)
             return self._update_queue()
 
     def _btDeleteClick(self, widget=None):
 
     def _update_queue(self):
         self.tree.set_model(
-                gtk.ListStore(int, str, str, str, str, str))
+                gtk.ListStore(int,str, str, str, str, str, str,str))
         lst = dbutils.GetQueue()
         for entry in lst:
             self.tree.get_model().append(entry)
 
     def _get_tree(self):
-        mod = gtk.ListStore(int, str, str, str, str, str)
+        mod = gtk.ListStore(int, str, str, str, str, str, str, str)
         self.tree = gtk.TreeView(model = mod)
         self.tree.connect('cursor-changed', self._tree_click_event)
 
         i = 0
         for field in ('ID', 'Application', 'Version',
-                'Source URI', 'Description', 'Release'):
+                'Source URI', 'Description', 'Release','Type', 'Install'):
             col = gtk.TreeViewColumn(field)
+            col.set_resizable(True)
             cr = gtk.CellRendererText()
             col.pack_start(cr)
             col.add_attribute(cr, 'text', i)

File vpackager/buildutils.py

         ### The only diff from using this vs sbbuilder itself is that
         ### This app can guess what type of slackbuild needs to be
         ### created for the app to build.
-        _currdir = os.getcwd()
         try:
             os.makedirs(_sources_home)
         except:
         except:
             raise SourceCopyError
         # Return to the original path
-        os.chdir(_currdir)
+ #       os.chdir(_currdir)
 
         sbpath = os.path.join(
             self.__myhome, self.ver, 'src', '%s.SlackBuild'% self.app)
         self.__dump = None
         return self.builder
 
+class SourceURL(object):
+    """ Source object created from a URL rather than a local path"""
+    def __init__(self, app='',version='',srctype='default',link=''):
+        self.app = app
+        self.ver = version
+        self.builder = srctype
+        self.link = link
 
+    def makeSlackBuild(self, buildno='1', packager='vpackager'):
+        """ Generate the build script for this source """
+        try:
+            os.makedirs(_sources_home)
+        except:
+            pass
+        try:
+            os.chdir(_sources_home)
+        except:
+            raise MissingSourcesHomeError
+        cm = 'sbbuilder --package=%s --version=%s --type=%s '% (self.app,
+                self.ver, self.builder) + \
+                '--build=%s --user=%s --link=%s'% (buildno,
+                        packager, self.link)
+        proc = bottools.Execute(cm)
+        proc.run()
+        if proc.popen.returncode > 0:
+            # SB creation returned an error
+            raise SlackBuildCreationError
+        self.__myhome = os.path.join(_sources_home, self.app)
+        self.srclocation = os.path.join(self.__myhome, self.ver, 'src')
+        self.pkg = os.path.join(
+                _sources_home, self.app, 'package_%s-%s'% (self.app, self.ver))
+        sbpath = os.path.join(self.__myhome, self.ver, 'src', '%s.SlackBuild'% self.app)
+        if os.path.exists(sbpath):
+            return sbpath
+
+        return None
+
+    def buildSlackBuild(self):
+        """ Execute the build script generated by the class"""
+        # Make sure we are at the correct location
+        os.chdir(self.srclocation)
+        return bottools.Execute('sh %s.SlackBuild'% self.app)
+
+
+
+

File vpackager/dbutils.py

 __author_email__ = 'moc.liamg@xnl.E0M'[::-1]
 __version__ = '0.1'
 
-db = sqlite3.connect('/tmp/vpackager.db')
+dbpath = '/tmp/vpackager.db'
 
 def __create_queue_table():
     """ Create the job queue table. NEVER to be called from the program
     itself!"""
+    db = sqlite3.connect(dbpath)
     c = db.cursor()
     c.execute("""create table queue
     (id integer primary key autoincrement,
-    app text, ver text, srcURI text, descURI text, release text)""")
+    app text, ver text, srcURI text, descURI text, release text, type text,
+    install text)""")
     db.commit()
     c.close()
 
 def __create_history_table():
     """ Create the job history table. NEVER to be called from the program
     itself!"""
+    db = sqlite3.connect(dbpath)
     c = db.cursor()
     # The id integer comes from the job queue table, so we can have some
     # consistancy here.
     srcURI text,
     descURI text,
     release text,
+    type text,
     buildstart text,
     buildend text,
     stdout text,
 
     return
 
-def NewJob(app, ver, srcURI, descURI, release):
+def NewJob(app, ver, srcURI, descURI, release, _type, install):
+
     """ Add a job to the job queue"""
-    t = (app, ver, srcURI, descURI, release)
+    db = sqlite3.connect(dbpath)
+    t = (app, ver, srcURI, descURI, release, _type, install)
     c = db.cursor()
-    c.execute("insert into queue (app, ver, srcURI, descURI, release) values (?,?,?,?,?)", t)
+    c.execute("""insert into queue (app, ver, srcURI, descURI, release, Type,
+    install) values (?,?,?,?,?,?,?)""", t)
 
     db.commit()
     c.close()
 
 def RemoveJob(_id):
     """ Delete a job from the job queue"""
+    db = sqlite3.connect(dbpath)
     c = db.cursor()
     t = (_id,)
     c.execute('delete from queue where id=?', t)
     db.commit()
     c.close()
 
-def LogJobStart(jobid, app, ver, src, desc, release, starttime):
-    """ Move job from queue to history and add the timestamp to the build
+def LogJobStart(jobid):
+    """ Move job from queue to history and add the timestamp to the buidl
     start"""
-    t = (jobid, app, ver, src, desc, release, starttime)
+    db = sqlite3.connect(dbpath)
     c = db.cursor()
-    c.execute('''insert into history (id, app, ver, srcURI, descURI, release,
-    buildstart) values (?,?,?,?,?,?,?)''', t)
-    c.execute('remove from queue where id=?',jobid)
+    t = (jobid,)
+    c.execute('''select id,app,ver,srcURI,descURI,release,type from queue where
+    id=?''',t)
+    res = c.next()
+    c.execute('''insert into history (id,app,ver,srcURI,descURI,
+    release,type,buildstart,result)
+    values (?,?,?,?,?,?,?,CURRENT_TIMESTAMP,'Running')''',res)
+    t = (jobid,)
+    c.execute('delete from queue where id=?',t)
+    c.close()
+    db.commit()
 
+def LogJobEnd(jobid, stdoutpath, result):
+    """ Update the job history to log the end time and end result of the
+    build."""
+    db = sqlite3.connect(dbpath)
+    c = db.cursor()
+    t = (jobid,)
+    c.execute('''update history set buildend=CURRENT_TIMESTAMP where
+            id=?''',t)
+    t = (stdoutpath, jobid)
+    c.execute('''update history set stdout=? where id=?''',t)
+    t = (result, jobid)
+    c.execute('''update history set result=? where id=?''',t)
+    c.close()
     db.commit()
-    c.close()
 
 def GetNextJob():
     """ Find the next job in line to be built"""
+    db = sqlite3.connect(dbpath)
     c = db.cursor()
     c.execute('select * from queue')
     try:
         ret = c.next()
     except StopIteration:
-        ret = []
+        ret = None
     c.close()
     return ret
 
 def GetQueue():
     """ Return a list of all pending jobs"""
+    db = sqlite3.connect(dbpath)
     c = db.cursor()
     ret = c.execute('select * from queue').fetchall()
     c.close()
 
 def GetHistory():
     """ Return a list of all processed jobs"""
+    db = sqlite3.connect(dbpath)
     c = db.cursor()
     ret = c.execute('select * from history').fetchall()
     c.close()

File vpackager/guitools.py

         self.app = None
         self.ver = None
         self.release = 1
+        self.install = False
         self.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
         self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
         self.set_has_separator(True)
         cbRel.pack_start(cr)
         cbRel.add_attribute(cr, 'text', 0)
         cbRel.set_active(0)
+
+        lSrcType = gtk.Label('Source Type')
+        types = gtk.ListStore(str)
+        for _type in ('Auto','Autotools','Python','CMake','Perl','Waf'):
+            types.append([_type])
+        cbsrcsel = gtk.ComboBox(types)
+        cbsrcsel.connect('changed', self._srctype_changed)
+        crt = gtk.CellRendererText()
+        cbsrcsel.pack_start(crt)
+        cbsrcsel.add_attribute(crt, 'text', 0)
+        cbsrcsel.set_active(0)
+
         bbox.pack_start(lbuild, False, False, 2)
         bbox.pack_start(cbRel, False, False, 2)
-        body.pack_start(bbox, False, True, 4)
+        bbox.pack_start(lSrcType, False, False, 2)
+        bbox.pack_start(cbsrcsel, False, False, 2)
+        body.pack_start(bbox, False, True, 2)
+        cbInstallPkg = gtk.CheckButton(
+                label='Install this package after it is compiled')
+        cbInstallPkg.connect('toggled', self._cbInstallpkg_changed)
+        body.pack_start(cbInstallPkg, False, True, 2)
+
+
         cbRel.connect('changed', self._release_changed)
 
-
         self.body = body
         body.show_all()
 
+    def _cbInstallpkg_changed(self, widget=None):
+        self.install = widget.get_active()
+
+    def _srctype_changed(self, widget=None):
+        selected = widget.get_model()[widget.get_active()][0].lower()
+        if selected in ('auto', 'autotools'):
+            self.srctype = 'default'
+        else:
+            self.srctype = selected
+
     def _release_changed(self, widget=None):
         self.release = widget.get_model()[widget.get_active()][0]