[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:12:58 PST 2017
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)
--
2.1.4
More information about the yocto
mailing list