[yocto] [[PATCH][yocto-autobuilder]] bin/forcebuild.py: Add a script to support force a build

Lock, Joshua G joshua.g.lock at intel.com
Wed Feb 8 06:12:21 PST 2017


On Wed, 2017-02-01 at 14:14 -0600, Aníbal Limón wrote:
> I know we have the remote_kick.py [1] script but i don't know if is
> currently on use also this new script support list the options in
> builders and specify custom ones via cmdline.

I don't use remote_kick.py, I'm loathe to carry two scripts with a
similar purpose. Any idea how they differ?

Thanks,

Joshua

> Cheers,
> 	alimon
> 
> [1]
> http://git.yoctoproject.org/cgit/cgit.cgi/yocto-autobuilder/tree/bin/
> remote_kick.py
> 
> On 02/01/2017 02:12 PM, Aníbal Limón wrote:
> > The script supports to list avaialable builders and his options,
> > also can force a build if the builder is IDLE or not.
> > 
> > Also supports specify options via cmdline using python dictionaries
> > as string.
> > 
> > Signed-off-by: Aníbal Limón <anibal.limon at linux.intel.com>
> > ---
> >  bin/forcebuild.py | 183
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 183 insertions(+)
> >  create mode 100755 bin/forcebuild.py
> > 
> > diff --git a/bin/forcebuild.py b/bin/forcebuild.py
> > new file mode 100755
> > index 0000000..5fe61a0
> > --- /dev/null
> > +++ b/bin/forcebuild.py
> > @@ -0,0 +1,183 @@
> > +#!/usr/bin/env python
> > +
> > +# YoctoAutobuilder force build script
> > +#
> > +# Copyright (C) 2017 Intel Corporation
> > +#
> > +# This program is free software; you can redistribute it and/or
> > modify
> > +# it under the terms of the GNU General Public License version 2
> > as
> > +# published by the Free Software Foundation.
> > +#
> > +# This program is distributed in the hope that it will be useful,
> > +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > +# GNU General Public License for more details.
> > +#
> > +# You should have received a copy of the GNU General Public
> > License along
> > +# with this program; if not, write to the Free Software
> > Foundation, Inc.,
> > +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> > +
> > +import urllib2
> > +import urllib
> > +import cookielib
> > +import uuid
> > +import sys
> > +import argparse
> > +import json
> > +from bs4 import BeautifulSoup
> > +
> > +class YoctoAutobuilderAPI(object):
> > +    def __init__(self, server):
> > +        self.server = server
> > +        self.opener = urllib2.build_opener(
> > +                urllib2.HTTPCookieProcessor(cookielib.CookieJar())
> > )
> > +
> > +    def login(self, user, passwd):
> > +        data = urllib.urlencode(dict(username=user,
> > +                                     passwd=passwd))
> > +        url = self.server + "/login"
> > +        request = urllib2.Request(url, data)
> > +        result = self.opener.open(request).read()
> > +        if result.find("The username or password you entered were
> > not correct") > 0:
> > +            print("Invalid username or password")
> > +            return 1
> > +        return 0
> > +
> > +    def _get_builders(self):
> > +        url = "%s/json/builders/?as_text=1" % (self.server)
> > +        request = urllib2.Request(url)
> > +        json_raw_data = self.opener.open(request)
> > +
> > +        return json.load(json_raw_data)
> > +
> > +    def list_builders(self):
> > +        builders = self._get_builders()
> > +
> > +        if builders:
> > +            print('Available builders:\n')
> > +            for builder in builders:
> > +                print(builder)
> > +            return 0
> > +        else:
> > +            print('No available builders in this server.')
> > +            return 1
> > +
> > +    def _get_options_by_builder(self, builder):
> > +        options = {}
> > +
> > +        url = "%s/builders/%s" % (self.server, builder)
> > +        request = urllib2.Request(url)
> > +        html = self.opener.open(request).read()
> > +
> > +        inputs = BeautifulSoup(html, 'lxml').find_all('input')
> > +        for input in inputs:
> > +            type = input.attrs['type']
> > +            if  type == 'submit':
> > +                continue
> > +
> > +            options[input.attrs['name']] = input.attrs['value']
> > +
> > +        selects = BeautifulSoup(html, 'lxml').find_all('select')
> > +        for select in selects:
> > +            value = select.find_all('option',
> > selected=True)[0].getText()
> > +            options[select.attrs['name']] = value
> > +
> > +        return options
> > +
> > +    def list_options(self, builder):
> > +        builders = self._get_builders()
> > +        if not builder in builders:
> > +            print('Builder %s specified isn\'t available' %
> > builder)
> > +            return 1
> > +
> > +        opts = self._get_options_by_builder(builder)
> > +        print('Available options in builder %s:\n' % (builder))
> > +        for name in opts:
> > +            value = opts[name]
> > +            print('Name: %s, Default value: %s' % (name, value))
> > +
> > +    def force_build(self, builder, opts, idle_check=False):
> > +        builders = self._get_builders()
> > +        if not builder in builders:
> > +            print('Builder specified isn\'t available')
> > +            return 1
> > +
> > +        state = builders[builder]['state']
> > +        if idle_check and not state == 'idle':
> > +            print('Builder %s specified isn\'t IDLE, current state
> > %s' \
> > +                    % (builder, state))
> > +            return 1
> > +
> > +        opts = eval(opts) # FIXME: transform string argument into
> > dictionary, security?
> > +        current_opts = self._get_options_by_builder(builder)
> > +        for opt in opts:
> > +            if not opt in current_opts:
> > +                print('Option %s isn\'t supported by builder %s' %
> > \
> > +                        (opt, builder))
> > +                return 1
> > +            else:
> > +                current_opts[opt] = opts[opt]
> > +
> > +        url_params = urllib.urlencode(current_opts)
> > +        url = "%s/builders/%s/force" % (self.server, builder)
> > +        request = urllib2.Request(url, url_params)
> > +        result = self.opener.open(request)
> > +        if 'Forced build' in result.read():
> > +            return 0
> > +        else:
> > +            print("Failed to force build")
> > +            return 1
> > +
> > +def main():
> > +    parser = argparse.ArgumentParser(description="Yocto
> > Autobuilder force build script",
> > +            add_help=False)
> > +    parser.add_argument('-s', '--server', help='Server URL',
> > +            action='store', required=True)
> > +
> > +    parser.add_argument('-u', '--username', action='store',
> > required=True)
> > +    parser.add_argument('-p', '--password', action='store',
> > required=True)
> > +
> > +    group = parser.add_mutually_exclusive_group()
> > +    group.add_argument('--list-builders', help='List available
> > builders',
> > +            action='store_true')
> > +    group.add_argument('--list-options', help='List options by
> > builder',
> > +            action='store', metavar='BUILDER')
> > +    group.add_argument('--force-build', help='Force build by
> > builder',
> > +            action='store', metavar='BUILDER')
> > +    group.add_argument('--force-build-idle', help='Force build by
> > builder if is idle',
> > +            action='store', metavar='BUILDER')
> > +
> > +    parser.add_argument('-o', '--options', help='Custom options by
> > operation',
> > +            action='store')
> > +
> > +    parser.add_argument('-d', '--debug', help='Enable debug
> > output',
> > +            action='store_true')
> > +    parser.add_argument('-q', '--quiet', help='Print only errors',
> > +            action='store_true')
> > +
> > +    parser.add_argument('-h', '--help', action='help',
> > default=argparse.SUPPRESS,
> > +                        help='show this help message and exit')
> > +
> > +    args = parser.parse_args()
> > +
> > +    api = YoctoAutobuilderAPI(args.server)
> > +    if api.login(args.username, args.password):
> > +        return 1
> > +
> > +    if args.list_builders:
> > +        return api.list_builders()
> > +    elif args.list_options:
> > +        return api.list_options(args.list_options)
> > +    elif args.force_build:
> > +        return api.force_build(args.force_build, args.options)
> > +    elif args.force_build_idle:
> > +        return api.force_build(args.force_build_idle,
> > args.options, idle_check=True)
> > +
> > +if __name__ == '__main__':
> > +    try:
> > +        ret = main()
> > +    except Exception:
> > +        ret = 1
> > +        import traceback
> > +        traceback.print_exc()
> > +    sys.exit(ret)
> > 
> 
> 
---------------------------------------------------------------------
Intel Corporation (UK) Limited
Registered No. 1134945 (England)
Registered Office: Pipers Way, Swindon SN3 1RJ
VAT No: 860 2173 47

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


More information about the yocto mailing list