Skip to contentSkip to conversation

Webhob: helper based on webservice

PATCH In review Xiaotong lv 2 participants 4 messages Jun 5, 2012

lore
Share & tools
lore
#0 lore raw

cover Webhob: helper based on webservice

This helper is a bitbake ui, based on soaplib 1.0 lib to implement a webservice interface.
I defined 2 webservice methods, they are runCommand(param) and getEvent().
Different languages can remotely call the 2 methods to communicate with bitbake. such as php, java, js, python and so on.
1. runCommand(param) method is responsible for sending commands to bitbake server.
the param format is:
{
'function' : string (required, function name)
'param_type': array(string) (optional, params types, values only are 'string', 'list' or 'bool')
'params' : array(string) (optional, string param corresponds to itself,
list type corresponds to 'str1 str2 str3 ....', bool type corresponds to 'true' or 'false'
)
}

some examples:
1). to call bitbake server.runCommand(["initCooker"])
param style is:
{
'function': 'initCokker'
}
2). to call bitbake server.runCommand(["getVariable", "BBLAYERS"])
param style is:
{
'function' : 'getVariable'
'param_type' : ['string']
'params' : ['BBLASYERS']
}
3). to call bitbake server.runCommand(["buildTargets", list(recipe_queue), 'build'])
param style is:
{
'function' : 'buildTargets'
'param_type' : ['list','string']
'params' : ['recipe1 recipe2 recipe2 recipe4 ....', 'build']
}

2. getEvent() is respinsible for getting the event results generated by bitbake event objects, it returns a standard json format data. some examples:
1) to get some async configurations:

      [{'event': 'ConfigFilesFound',
       'values': 'poky-bleeding poky-lsb poky poky-tiny defaultsetup',
       'variable': 'distro'},
       {'event': 'CommandCompleted'}
      ]
      [{'event': 'ConfigFilesFound',
        'values': 'atom-pc routerstationpro mpc8315e-rdb beagleboard qemumips qemuarm qemux86-64 qemux86 qemuppc',
        'variable': 'machine'},
       {'event': 'CommandCompleted'}
        'values': 'i586 x86_64 i686',
        'variable': 'machine-sdk'},
       {'event': 'CommandCompleted'}
      ]
      [{'event': 'FilesMatchingFound',
        'matches': 'rootfs_rpm.bbclass rootfs_deb.bbclass rootfs_ipk.bbclass',
        'pattern': 'rootfs_'},
       {'event': 'CommandCompleted'}
      ]

    2) some recipe progress values
         [{'current': 24,
          'event': 'TreeDataPreparationProgress',
          'msg': 'Preparing tree data: 24/1105',
          'total': 1105},
         {'current': 25,
          'event': 'TreeDataPreparationProgress',
          'msg': 'Preparing tree data: 25/1105',
          'total': 1105},
         {'current': 26,
          'event': 'TreeDataPreparationProgress',
          'msg': 'Preparing tree data: 26/1105',
          'total': 1105},
         {'current': 27,
          'event': 'TreeDataPreparationProgress',
          'msg': 'Preparing tree data: 27/1105',
          'total': 1105},
         {'current': 28,
          'event': 'TreeDataPreparationProgress',
          'msg': 'Preparing tree data: 28/1105',
          'total': 1105},
         {'current': 29,
          'event': 'TreeDataPreparationProgress',
          'msg': 'Preparing tree data: 29/1105',
          'total': 1105}]

    3) some task building values
         [{'event': 'TaskSucceeded',
          'message': 'package libpcre-native-8.21-r1: task do_populate_sysroot: Succeeded',
          'package': 'libpcre-native-8.21-r1',
          'pid': 30382,
          'task': 'do_populate_sysroot'},
         {'event': 'runQueueTaskCompleted',
          'pid': 0,
          'taskid': 753,
          'taskstring': 'virtual:native:/home/xiaotong/workspace/python/poky-contrib/meta/recipes-support/libpcre/libpcre_8.21.bb, do_populate_sysroot'},
         {'event': 'runQueueTaskStarted',
          'noexec': False,
          'pid': 0,
          'stats': {'active': 0, 'completed': 324, 'failed': 0},
          'taskid': 709,
          'taskstring': 'virtual:native:/home/xiaotong/workspace/python/poky-contrib/meta/recipes-support/db/db_5.1.19.bb, do_populate_sysroot'},
         {'event': 'TaskStarted',
          'message': 'package db-native-5.1.19-r4: task do_populate_sysroot: Started',
          'package': 'db-native-5.1.19-r4',
          'pid': 30447,

The following changes since commit 11eab3487db83bd1f4ca65de2767afbdc9958af0:

Webhob: a general helper interface based on webservice (2012-06-02 06:00:10 -0400)

are available in the git repository at:
git://git.yoctoproject.org/poky-contrib xtlv/webhob-webservice
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=xtlv/webhob-webservice

Xiaotong lv (1):
Webhob: Clean up the code and modify some errors

 bitbake/lib/bb/ui/crumbs/webserviceeventhandler.py |   20 ++++---
 bitbake/lib/bb/ui/webhob_webservice.py             |   53 ++++++++-----------
 2 files changed, 33 insertions(+), 40 deletions(-)
Signature · 1 line
1.7.4.4
#1 lore raw

PATCH 1/1 Webhob: Clean up the code and modify some errors

---
 bitbake/lib/bb/ui/crumbs/webserviceeventhandler.py |   20 ++++---
 bitbake/lib/bb/ui/webhob_webservice.py             |   53 ++++++++-----------
 2 files changed, 33 insertions(+), 40 deletions(-)
bitbake/lib/bb/ui/crumbs/webserviceeventhandler.py +11 -9
index dc6f316..eaa8729 100644
@@ -27,12 +27,14 @@ class WSEventHandler:
         if self.ret_value:
             self.ret_value = {}
 
-    def event_model_to_jsondata(self, data):
+    #To convert the list in recipe and packages tree model into string type.
+    #so that the tree model can be converted into standard json data
+    def treemodel_list_tostring(self, data):
         for k, v in data.iteritems():
             if isinstance(v, dict):
-                data[k] = self.event_model_to_jsondata(v)
+                data[k] = self.treemodel_list_tostring(v)
             elif isinstance(v, list):
-                data[k] = " ".join(v)
+                data[k] = ' '.join(v)
             else:
                 data[k] = v
         return data
@@ -45,12 +47,12 @@ class WSEventHandler:
 
         if isinstance(event, bb.event.PackageInfo):
             self.ret_value["event"] = bb.event.getName(event)
-            self.ret_value["pkginfolist"] = self.event_model_to_jsondata(event._pkginfolist)
+            self.ret_value["pkginfolist"] = self.treemodel_list_tostring(event._pkginfolist)
         elif isinstance(event, bb.event.SanityCheckPassed):
             self.ret_value["event"] = bb.event.getName(event)
 
         #Handler these logs, do we need to do some logging filtering under logging.INFO level.
-        #cause maybe some logging are unuseful but this can affect the webservice efficiency 
+        #cause maybe some loggings are unuseful but this can affect the webservice efficiency.
         #and client user experience
         elif isinstance(event, logging.LogRecord):
                 self.ret_value["event"] = bb.event.getName(event)
@@ -63,7 +65,7 @@ class WSEventHandler:
         elif isinstance(event, bb.event.TargetsTreeGenerated):
             self.ret_value["event"] = bb.event.getName(event)
             if event._model:
-                self.ret_value["model"] = self.event_model_to_jsondata(event._model)
+                self.ret_value["model"] = self.treemodel_list_tostring(event._model)
 
         elif isinstance(event, bb.event.ConfigFilesFound):
             self.ret_value["event"] = bb.event.getName(event)
@@ -121,7 +123,7 @@ class WSEventHandler:
 
         elif isinstance(event, bb.event.MultipleProviders):
             self.ret_value["event"] = bb.event.getName(event)
-            self.ret_value["candidates"] = ", ".join(event._candidates)
+            self.ret_value["candidates"] = ' '.join(event._candidates)
             self.ret_value["runtime"] = event._runtime
             self.ret_value["item"] = event._item
 
@@ -166,7 +168,7 @@ class WSEventHandler:
             self.ret_value["taskid"] = event.taskid
             self.ret_value["stats"] = {'completed':event.stats.completed,
                                        'active':event.stats.active,
-                                       'active':event.stats.failed
+                                       'failed':event.stats.failed
                                        }
             self.ret_value["pid"] = event.pid
 
@@ -185,4 +187,4 @@ class WSEventHandler:
             self.ret_value["taskstring"] = event.taskstring
             self.ret_value["pid"] = event.pid
 
-        return self.ret_value
\ No newline at end of file
+        return self.ret_value
bitbake/lib/bb/ui/webhob_webservice.py +22 -31

87 lines not on this page · raw message

Signature · 1 line
1.7.4.4
#2 lore raw

Re: [PATCH 1/1] Webhob: Clean up the code and modify some errors

I hope this patch can be merged into your first patch (the base patch), which is missing.

--
Shane

Xiaotong lv wrote on 2012-06-06:

Quoted 144 lines
---
 bitbake/lib/bb/ui/crumbs/webserviceeventhandler.py |   20 ++++---
 bitbake/lib/bb/ui/webhob_webservice.py             |   53

++++++++----------- 2 files changed, 33 insertions(+), 40 deletions(-)

(quoted diff) +0 -0

b/bitbake/lib/bb/ui/crumbs/webserviceeventhandler.py index dc6f316..eaa8729 100644 --- a/bitbake/lib/bb/ui/crumbs/webserviceeventhandler.py +++ b/bitbake/lib/bb/ui/crumbs/webserviceeventhandler.py @@ -27,12 +27,14 @@ class WSEventHandler:

         if self.ret_value:
             self.ret_value = {}
bitbake/lib/bb/ui/crumbs/webserviceeventhandler.py +5 -4
-    def event_model_to_jsondata(self, data):
+    #To convert the list in recipe and packages tree model into string type.
+    #so that the tree model can be converted into standard json data
+    def treemodel_list_tostring(self, data):
         for k, v in data.iteritems():
             if isinstance(v, dict):
-                data[k] = self.event_model_to_jsondata(v)
+                data[k] = self.treemodel_list_tostring(v)
             elif isinstance(v, list):
-                data[k] = " ".join(v)
+                data[k] = ' '.join(v)
             else:
                 data[k] = v
         return data
@@ -45,12 +47,12 @@ class WSEventHandler:
 
         if isinstance(event, bb.event.PackageInfo):
             self.ret_value["event"] = bb.event.getName(event)
-            self.ret_value["pkginfolist"] =

self.event_model_to_jsondata(event._pkginfolist) + self.ret_value["pkginfolist"] = self.treemodel_list_tostring(event._pkginfolist)
elif isinstance(event, bb.event.SanityCheckPassed):
self.ret_value["event"] = bb.event.getName(event)
#Handler these logs, do we need to do some logging filtering
under logging.INFO level.
- #cause maybe some logging are unuseful but this can affect the
webservice efficiency
+ #cause maybe some loggings are unuseful but this can affect the
webservice efficiency.
#and client user experience
elif isinstance(event, logging.LogRecord):
self.ret_value["event"] = bb.event.getName(event)

bitbake/lib/bb/ui/crumbs/webserviceeventhandler.py +0 -1
@@ -63,7 +65,7 @@ class WSEventHandler:
         elif isinstance(event, bb.event.TargetsTreeGenerated):
             self.ret_value["event"] = bb.event.getName(event)
             if event._model:
-                self.ret_value["model"] =

self.event_model_to_jsondata(event._model) + self.ret_value["model"] = self.treemodel_list_tostring(event._model)

elif isinstance(event, bb.event.ConfigFilesFound):
self.ret_value["event"] = bb.event.getName(event)

bitbake/lib/bb/ui/crumbs/webserviceeventhandler.py +2 -3
@@ -121,7 +123,7 @@ class WSEventHandler:
 
         elif isinstance(event, bb.event.MultipleProviders):
             self.ret_value["event"] = bb.event.getName(event)
-            self.ret_value["candidates"] = ", ".join(event._candidates)
+            self.ret_value["candidates"] = ' '.join(event._candidates)
             self.ret_value["runtime"] = event._runtime
             self.ret_value["item"] = event._item
@@ -166,7 +168,7 @@ class WSEventHandler:
             self.ret_value["taskid"] = event.taskid
             self.ret_value["stats"] = {'completed':event.stats.completed,
                                        'active':event.stats.active,
-                                       'active':event.stats.failed
+                                       'failed':event.stats.failed
                                        }
             self.ret_value["pid"] = event.pid
@@ -185,4 +187,4 @@ class WSEventHandler:
             self.ret_value["taskstring"] = event.taskstring
             self.ret_value["pid"] = event.pid
-        return self.ret_value \ No newline at end of file +       

return self.ret_value diff --git a/bitbake/lib/bb/ui/webhob_webservice.py b/bitbake/lib/bb/ui/webhob_webservice.py index c4544e1..1dd474a 100755 --- a/bitbake/lib/bb/ui/webhob_webservice.py +++ b/bitbake/lib/bb/ui/webhob_webservice.py @@ -51,7 +51,6 @@ class Param(ClassSerializer):

     If a client to call runCommand() method, the following is param
     format: param = {
         'function'   = 'string' -        'param_num'  = 'int'
         'param_type' = ['string','list','bool'] 'params'     =
         ['str','str1 str2 str3...','true or false']
     }
(quoted diff) +0 -1
@@ -59,7 +58,6 @@ class Param(ClassSerializer):
 
     __namespace__ = "param" function = String -    param_num = Integer
     param_type = Array(String) params = Array(String)
@@ -71,34 +69,27 @@ class WebServiceWrap(DefinitionBase):
     def runCommand(self, param):
         command = [] function = param.function -        param_num =
         param.param_num param_type = param.param_type params =
         param.params
-        if param_num>0: -            if None in
 param.__dict__.values(): -               return "Fatal: function,

param_num, param_type, params values cannot be None." - - if
len(params) != param_num and len(params) != param_num: - return "Fatal: param_type and params length should be equal to
param_num" - + if function:
command.append(function)
- for item in param_type: - if item ==
'string': - command.append(params.pop(0)) -
elif item == 'bool': -
command.append(bool(params.pop(0))) - elif item == 'list':
- command.append(params.pop(0).split()) -
else: - command = [] - return "Fatal:
only 'string', 'bool', 'list' should be in param_type" - - if
param_num == 0 and param.function: - command.append(function)
- - if not command: - return "Fatal: function,
param_num values cannot be None." + else: + return
"Error: key(function) value cannot be required." + + if
param_type and params: + if len(param_type) == len(params): +

               for item in param_type: +                    if item ==
'string': +                        command.append(params.pop(0)) +      
             elif item == 'bool': +                       

command.append(bool(params.pop(0))) + elif item ==
'list': + command.append(params.pop(0).split()) +
else: + return "Error: only
'string', 'bool', 'list' should be in param_type" + else: +
return "Error: key(param_type) value length should be equal
to params"

ret = WebServiceWrap.server.runCommand(command) return json.dumps(ret)

bitbake/lib/bb/ui/webhob_webservice.py +4 -4
@@ -124,10 +115,10 @@ def main (server = None, eventHandler = None):
     port = 0
     for i in sys.argv[1:]:
         pattern = r'(\d+.\d+.\d+.\d+):(\d+)'
-        if re.match(pattern, i):
-            ip = i.split(':')
-            host = ip[0]
-            port = int(ip[1])
+        match = re.match(pattern, i)
+        if match:
+            host = match.group(1)
+            port = int(match.group(2))
             break if not host and not port: sys.exit('Fatal: using
             bitbake -u webhob_webservice
 ip:port\n')

bitbake/lib/bb/ui/webhob_webservice.py def main (server = None, eventHandler = None): · line 132

Quoted 8 lines
bitbake/lib/bb/ui/webhob_webservice.py +1 -1
@@ -135,7 +126,7 @@ def main (server = None, eventHandler = None):
     try:
         from wsgiref.simple_server import make_server
         server = make_server(host, port, Application([WebServiceWrap],
 'tns'))
-        print "Webservice UI runnning \nWSDL is at: http://%s:%s/?wsdl" %
 (host, port)
+        print "Webservice UI runnning... \nWSDL is at:
 http://%s:%s/?wsdl" % (host, port)

server.serve_forever() except ImportError: print "Fatal: webservice server code requires Python >= 2.5"

#3 lore raw
In reply to Xiaotong lv

Xiaotong, I think you missed some patch.
When you say "clean up the code", what is your code base?

You should send out http://git.yoctoproject.org/cgit.cgi/poky-contrib/commit/?h=xtlv/webhob-webservice&id=11eab3487db83bd1f4ca65de2767afbdc9958af0 first.

--
Shane

Xiaotong lv wrote on 2012-06-06:

Quoted 114 lines

This helper is a bitbake ui, based on soaplib 1.0 lib to implement a webservice interface. I defined 2 webservice methods, they are runCommand(param) and getEvent(). Different languages can remotely call the 2 methods to communicate with bitbake. such as php, java, js, python and so on. 1. runCommand(param) method is responsible for sending commands to bitbake server.
the param format is:
{
'function' : string (required, function name)
'param_type': array(string) (optional, params types, values
only are 'string', 'list' or 'bool') 'params' : array(string)
(optional, string param
corresponds to itself,
list type corresponds to 'str1 str2 str3 ....', bool type
corresponds to 'true' or 'false'
)
}

some examples:
1). to call bitbake server.runCommand(["initCooker"])
param style is:
{
'function': 'initCokker'
}
2). to call bitbake server.runCommand(["getVariable", "BBLAYERS"])
param style is:
{
'function' : 'getVariable'
'param_type' : ['string']
'params' : ['BBLASYERS']
}
3). to call bitbake server.runCommand(["buildTargets",
list(recipe_queue), 'build'])

        param style is:
        {
          'function'   : 'buildTargets'
          'param_type' : ['list','string']
          'params'     : ['recipe1 recipe2 recipe2 recipe4 ....', 'build']
        }
2. getEvent() is respinsible for getting the event results generated by bitbake
event objects, it returns a standard json format data.
   some examples:
   1)  to get some async configurations:
      [{'event': 'ConfigFilesFound',
       'values': 'poky-bleeding poky-lsb poky poky-tiny defaultsetup',
       'variable': 'distro'},
       {'event': 'CommandCompleted'}
      ]
      [{'event': 'ConfigFilesFound',
        'values': 'atom-pc routerstationpro mpc8315e-rdb beagleboard
        qemumips qemuarm qemux86-64 qemux86 qemuppc', 'variable':
        'machine'}, {'event': 'CommandCompleted'} 'values': 'i586 x86_64
        i686', 'variable': 'machine-sdk'},
       {'event': 'CommandCompleted'}
      ]
      [{'event': 'FilesMatchingFound',
        'matches': 'rootfs_rpm.bbclass rootfs_deb.bbclass
        rootfs_ipk.bbclass', 'pattern': 'rootfs_'},
       {'event': 'CommandCompleted'}
      ]
    2) some recipe progress values
         [{'current': 24,
          'event': 'TreeDataPreparationProgress', 'msg': 'Preparing tree
          data: 24/1105', 'total': 1105}, {'current': 25, 'event':
          'TreeDataPreparationProgress', 'msg': 'Preparing tree data:
          25/1105', 'total': 1105}, {'current': 26, 'event':
          'TreeDataPreparationProgress', 'msg': 'Preparing tree data:
          26/1105', 'total': 1105}, {'current': 27, 'event':
          'TreeDataPreparationProgress', 'msg': 'Preparing tree data:
          27/1105', 'total': 1105}, {'current': 28, 'event':
          'TreeDataPreparationProgress', 'msg': 'Preparing tree data:
          28/1105', 'total': 1105}, {'current': 29, 'event':
          'TreeDataPreparationProgress', 'msg': 'Preparing tree data:
          29/1105', 'total': 1105}]
    3) some task building values
         [{'event': 'TaskSucceeded',
          'message': 'package libpcre-native-8.21-r1: task
          do_populate_sysroot: Succeeded', 'package':
          'libpcre-native-8.21-r1', 'pid': 30382, 'task':
          'do_populate_sysroot'}, {'event': 'runQueueTaskCompleted',
          'pid': 0, 'taskid': 753, 'taskstring':
'virtual:native:/home/xiaotong/workspace/python/poky-contrib/meta/recipes
-support/libpcre/libpcre_8.21.bb, do_populate_sysroot'},
         {'event': 'runQueueTaskStarted',
          'noexec': False,
          'pid': 0,
          'stats': {'active': 0, 'completed': 324, 'failed': 0},
          'taskid': 709,
          'taskstring':
'virtual:native:/home/xiaotong/workspace/python/poky-contrib/meta/recipes
-support/db/db_5.1.19.bb, do_populate_sysroot'},
         {'event': 'TaskStarted',
          'message': 'package db-native-5.1.19-r4: task
          do_populate_sysroot: Started', 'package':
          'db-native-5.1.19-r4', 'pid': 30447,

The following changes since commit
11eab3487db83bd1f4ca65de2767afbdc9958af0:

Webhob: a general helper interface based on webservice (2012-06-02
06:00:10 -0400)

are available in the git repository at:
git://git.yoctoproject.org/poky-contrib xtlv/webhob-webservice
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=xtlv/webhob-webs
erv ice

Xiaotong lv (1):
Webhob: Clean up the code and modify some errors

 bitbake/lib/bb/ui/crumbs/webserviceeventhandler.py |   20 ++++---
 bitbake/lib/bb/ui/webhob_webservice.py             |   53

++++++++----------- 2 files changed, 33 insertions(+), 40 deletions(-)