[yocto] [[PATCH][yocto-autobuilder]] bin/forcebuild.py: Add a script to support force a build
Aníbal Limón
anibal.limon at linux.intel.com
Wed Feb 1 12:14:48 PST 2017
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.
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)
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.yoctoproject.org/pipermail/yocto/attachments/20170201/3bc93b5d/attachment.pgp>
More information about the yocto
mailing list