Browse Source
This runs gerrit in a container on review-dev01 using podman. Remove an unused web_server.py file that we found from copying it from puppet to ansible. Change-Id: I399d3cf8471bc8063022b0db0ff81718b2ee2941changes/06/630406/69
27 changed files with 1645 additions and 185 deletions
@ -1,178 +0,0 @@
|
||||
#!/usr/bin/env python |
||||
# |
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may |
||||
# not use this file except in compliance with the License. You may obtain |
||||
# a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
||||
# License for the specific language governing permissions and limitations |
||||
# under the License. |
||||
|
||||
""" |
||||
This is a simple test server that serves up the web content locally |
||||
as if it was a working remote server. It also proxies all the live |
||||
date/*.json files into the local test server, so that the Ajax async |
||||
loading works without hitting Cross Site Scripting violations. |
||||
""" |
||||
|
||||
import argparse |
||||
import BaseHTTPServer |
||||
import os.path |
||||
import urllib2 |
||||
|
||||
import requests |
||||
|
||||
# Values for these set via cli defaults |
||||
GERRIT_UPSTREAM = "" |
||||
ZUUL_UPSTREAM = "" |
||||
|
||||
|
||||
def replace_urls(line, port): |
||||
line = line.replace( |
||||
GERRIT_UPSTREAM, |
||||
"http://localhost:%s" % port) |
||||
line = line.replace( |
||||
ZUUL_UPSTREAM, |
||||
"http://localhost:%s" % port) |
||||
return line |
||||
|
||||
|
||||
class GerritHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
||||
"""A request handler to create a magic local Gerrit server""" |
||||
|
||||
def do_POST(self): |
||||
data = self.rfile.read(int(self.headers['content-length'])) |
||||
headers = {} |
||||
# we need to trim some of the local headers in order for this |
||||
# request to remain valid. |
||||
for header in self.headers: |
||||
if header not in ("host", "origin", "connection"): |
||||
headers[header] = self.headers[header] |
||||
resp = requests.post("%s%s" % |
||||
(GERRIT_UPSTREAM, self.path), |
||||
headers=headers, |
||||
data=data) |
||||
|
||||
# Process request back to client |
||||
self.send_response(resp.status_code) |
||||
for header in resp.headers: |
||||
# Requests has now decoded the response so it's no longer |
||||
# a gzip stream, which also means content-length is |
||||
# wrong. So we remove content-encoding, then drop |
||||
# content-length because if provided Gerrit strictly uses |
||||
# it for reads. We also drop all the keep-alive related |
||||
# headers, our server doesn't do that. |
||||
if header not in ("connection", "content-length", |
||||
"keep-alive", "content-encoding"): |
||||
self.send_header(header, resp.headers[header]) |
||||
self.end_headers() |
||||
self.wfile.write(resp.text) |
||||
|
||||
def do_GET(self): |
||||
# possible local file path |
||||
local_path = self.path.replace('/static/', '').split('?')[0] |
||||
|
||||
# if the file exists locally, we'll serve it up directly |
||||
if os.path.isfile(local_path): |
||||
self.send_response(200, "Success") |
||||
self.end_headers() |
||||
with open(local_path) as f: |
||||
for line in f.readlines(): |
||||
line = replace_urls(line, self.server.server_port) |
||||
self.wfile.write(line) |
||||
print "Loaded from local override" |
||||
return |
||||
|
||||
# First we'll look for a zuul status call, /status doesn't map |
||||
# to gerrit so we can overload the localhost server for this. |
||||
if self.path.startswith("/status"): |
||||
try: |
||||
zuul_url = "%s%s" % (ZUUL_UPSTREAM, self.path) |
||||
# BUG(sdague): for some reason SSL connections to zuul |
||||
# from python 2.7 blow up with an SSL exception |
||||
zuul_url = zuul_url.replace('https', 'http') |
||||
response = urllib2.urlopen(zuul_url) |
||||
self.send_response(200, "Success") |
||||
for header in response.info(): |
||||
# need to reset content-length otherwise jquery complains |
||||
if header not in ("connection", "content-length", |
||||
"keep-alive", "content-encoding"): |
||||
self.send_header(header, response.info()[header]) |
||||
self.end_headers() |
||||
|
||||
for line in response.readlines(): |
||||
line = replace_urls(line, self.server.server_port) |
||||
self.wfile.write(line) |
||||
return |
||||
except urllib2.HTTPError as e: |
||||
self.send_response(e.code) |
||||
self.end_headers() |
||||
self.wfile.write(e.read()) |
||||
return |
||||
except urllib2.URLError as e: |
||||
print "URLError on %s" % (zuul_url) |
||||
print e |
||||
|
||||
# If you've not built local data to test with, instead grab |
||||
# the data off the production server on the fly and serve it |
||||
# up from our server. |
||||
try: |
||||
response = urllib2.urlopen("%s%s" % |
||||
(GERRIT_UPSTREAM, self.path)) |
||||
self.send_response(200, "Success") |
||||
for header in response.info(): |
||||
self.send_header(header, response.info()[header]) |
||||
self.end_headers() |
||||
|
||||
for line in response.readlines(): |
||||
line = replace_urls(line, self.server.server_port) |
||||
self.wfile.write(line) |
||||
except urllib2.HTTPError as e: |
||||
self.send_response(e.code) |
||||
self.end_headers() |
||||
self.wfile.write(e.read()) |
||||
|
||||
|
||||
def parse_opts(): |
||||
parser = argparse.ArgumentParser(description=__doc__) |
||||
parser.add_argument('-p', '--port', |
||||
help='port to bind to [default: 8001]', |
||||
type=int, |
||||
default=8001) |
||||
parser.add_argument('-z', '--zuul-url', |
||||
help='url for zuul server', |
||||
default="https://zuul.openstack.org") |
||||
parser.add_argument('-g', '--gerrit-url', |
||||
help='url for gerrit server', |
||||
default="https://review.opendev.org") |
||||
return parser.parse_args() |
||||
|
||||
|
||||
def main(): |
||||
global ZUUL_UPSTREAM |
||||
global GERRIT_UPSTREAM |
||||
opts = parse_opts() |
||||
ZUUL_UPSTREAM = opts.zuul_url |
||||
GERRIT_UPSTREAM = opts.gerrit_url |
||||
server_address = ('', opts.port) |
||||
httpd = BaseHTTPServer.HTTPServer(server_address, GerritHandler) |
||||
|
||||
print "Test Server is running at http://localhost:%s" % opts.port |
||||
print "Ctrl-C to exit" |
||||
print |
||||
|
||||
while True: |
||||
httpd.handle_request() |
||||
|
||||
if __name__ == '__main__': |
||||
try: |
||||
main() |
||||
except KeyboardInterrupt: |
||||
print "\n" |
||||
print "Thanks for testing! Please come again." |
@ -0,0 +1,5 @@
|
||||
gerrit_id: 3000 |
||||
gerrit_user_name: gerrit2 |
||||
gerrit_home_dir: /home/gerrit2 |
||||
gerrit_site_dir: "{{ gerrit_home_dir }}/review_site" |
||||
gerrit_run_init: false |
@ -0,0 +1,259 @@
|
||||
<html><body><div> |
||||
|
||||
<h1> |
||||
OpenStack Project Individual Contributor License Agreement |
||||
</h1> |
||||
|
||||
<!-- |
||||
This is the current OpenStack Project Individual Contributor License Agreement |
||||
reformatted for HTML from the original "RevisedCLA.doc" with SHA1 sum |
||||
0467dd893d276cefde614e063a363b995d67e5ee provided by Jonathan Bryce, Executive |
||||
Director on behalf of The OpenStack Foundation on Monday, January 7, 2013. No |
||||
textual content was changed except to replace quote marks with their strict |
||||
ASCII equivalents, add the original LLC CLA text as a block quote, and restore |
||||
a previously inapplicable statement (sentence #2 of paragraph #2) adapted from |
||||
the Apache Software Foundation ICLA at his direction. |
||||
--> |
||||
|
||||
<p><em> |
||||
In order to clarify the intellectual property license granted with |
||||
Contributions from any person or entity, the OpenStack Project (the "Project") |
||||
must have a Contributor License Agreement ("Agreement") on file that has been |
||||
signed by each Contributor, indicating agreement to the license terms below. |
||||
This license is for your protection as a Contributor as well as the protection |
||||
of OpenStack Foundation as Project manager (the "Project Manager") and the |
||||
Project users; it does not change your rights to use your own Contributions for |
||||
any other purpose. |
||||
</em></p> |
||||
|
||||
<p><em> |
||||
You accept and agree to the following terms and conditions for Your present and |
||||
future Contributions submitted to the Project Manager. In return, the Project |
||||
Manager shall not use Your Contributions in a way that is contrary to the |
||||
public benefit or inconsistent with its nonprofit status and bylaws in effect |
||||
at the time of the Contribution. Except for the license granted herein to the |
||||
Project Manager and recipients of software distributed by the Project Manager, |
||||
You reserve all right, title, and interest in and to Your Contributions. |
||||
</em></p> |
||||
|
||||
<ol> |
||||
|
||||
<li><p><strong> |
||||
Definitions. |
||||
</strong> |
||||
"You" (or "Your") shall mean the copyright owner or legal entity authorized by |
||||
the copyright owner that is making this Agreement with the Project Manager. For |
||||
legal entities, the entity making a Contribution and all other entities that |
||||
control, are controlled by, or are under common control with that entity are |
||||
considered to be a single Contributor. For the purposes of this definition, |
||||
"control" means (i) the power, direct or indirect, to cause the direction or |
||||
management of such entity, whether by contract or otherwise, or (ii) ownership |
||||
of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial |
||||
ownership of such entity. "Contribution" shall mean any original work of |
||||
authorship, including any modifications or additions to an existing work, that |
||||
is intentionally submitted by You to the Project Manager for inclusion in, or |
||||
documentation of, any of the projects owned or managed by the Project Manager |
||||
(the "Work"). For the purposes of this definition, "submitted" means any form of |
||||
electronic, verbal, or written communication sent to the Project Manager or its |
||||
representatives, including but not limited to communication on electronic |
||||
mailing lists, source code control systems, and issue tracking systems that are |
||||
managed by, or on behalf of, the Project Manager for the purpose of discussing |
||||
and improving the Work, but excluding communication that is conspicuously marked |
||||
or otherwise designated in writing by You as "Not a Contribution." |
||||
</p></li> |
||||
|
||||
<li><p><strong> |
||||
Grant of Copyright License. |
||||
</strong> |
||||
Subject to the terms and conditions of this Agreement, You hereby grant to the |
||||
Project Manager and to recipients of software distributed by the Project |
||||
Manager a perpetual, worldwide, non-exclusive, no-charge, royalty-free, |
||||
irrevocable copyright license to reproduce, prepare derivative works of, |
||||
publicly display, publicly perform, sublicense, and distribute Your |
||||
Contributions and such derivative works. |
||||
</p></li> |
||||
|
||||
<li><p><strong> |
||||
Grant of Patent License. |
||||
</strong> |
||||
Subject to the terms and conditions of this Agreement, You hereby grant to the |
||||
Project Manager and to recipients of software distributed by the Project |
||||
Manager a perpetual, worldwide, non-exclusive, no-charge, royalty-free, |
||||
irrevocable (except as stated in this section) patent license to make, have |
||||
made, use, offer to sell, sell, import, and otherwise transfer the Work, where |
||||
such license applies only to those patent claims licensable by You that are |
||||
necessarily infringed by Your Contribution(s) alone or by combination of Your |
||||
Contribution(s) with the Work to which such Contribution(s) was submitted. If |
||||
any entity institutes patent litigation against You or any other entity |
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that Your |
||||
Contribution, or the Work to which You have contributed, constitutes direct or |
||||
contributory patent infringement, then any patent licenses granted to that |
||||
entity under this Agreement for that Contribution or Work shall terminate as of |
||||
the date such litigation is filed. |
||||
</p></li> |
||||
|
||||
<li><p> |
||||
You represent that you are legally entitled to grant the above license. If your |
||||
employer(s) has rights to intellectual property that you create that includes |
||||
your Contributions, You represent that you have received permission to make |
||||
Contributions on behalf of that employer, that your employer has waived such |
||||
rights for your Contributions to the Project Manager, or that your employer has |
||||
executed a separate Corporate Contributor License Agreement with the Project |
||||
Manager. |
||||
</p></li> |
||||
|
||||
<li><p> |
||||
You represent that each of Your Contributions is Your original creation (see |
||||
Section 7 for submissions on behalf of others). You represent that Your |
||||
Contribution submissions include complete details of any third-party license or |
||||
other restriction (including, but not limited to, related patents and |
||||
trademarks) of which you are personally aware and which are associated with any |
||||
part of Your Contributions. |
||||
</p></li> |
||||
|
||||
<li><p> |
||||
You are not expected to provide support for Your Contributions, except to the |
||||
extent You desire to provide support. You may provide support for free, for a |
||||
fee, or not at all. Unless required by applicable law or agreed to in writing, |
||||
You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR |
||||
CONDITIONS OF ANY KIND, either express or implied, including, without |
||||
limitation, any warranties or conditions of TITLE, NONINFRINGEMENT, |
||||
MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. |
||||
</p></li> |
||||
|
||||
<li><p> |
||||
Should You wish to submit work that is not Your original creation, You may |
||||
submit it to the Project Manager separately from any Contribution, identifying |
||||
the complete details of its source and of any license or other restriction |
||||
(including, but not limited to, related patents, trademarks, and license |
||||
agreements) of which you are personally aware, and conspicuously marking the |
||||
work as "Submitted on behalf of a third-party: [named here]". |
||||
</p></li> |
||||
|
||||
<li><p> |
||||
You agree to notify the Project Manager of any facts or circumstances of which |
||||
you become aware that would make these representations inaccurate in any |
||||
respect. |
||||
</p></li> |
||||
|
||||
<li><p> |
||||
In addition, if you have provided a Contribution (as defined in the LLC |
||||
Contribution License Agreement below) to the Project under the Contribution |
||||
License Agreement to OpenStack, LLC ("LLC Contribution Agreement"), you agree |
||||
that OpenStack, LLC may assign the LLC Contribution Agreement along with all |
||||
its rights and obligations under the LLC Contribution License Agreement to the |
||||
Project Manager. |
||||
</p></li> |
||||
|
||||
</ol> |
||||
|
||||
<blockquote> |
||||
<p><em>In order to clarify the intellectual property license granted with |
||||
Contributions from any person or entity, the OpenStack Project (the "Project") |
||||
must have a Contributor License Agreement ("Agreement") on file that has been |
||||
signed by each Contributor, indicating agreement to the license terms below. |
||||
This license is for your protection as a Contributor as well as the protection |
||||
of OpenStack, LLC as Project manager (the "Project Manager") and the Project |
||||
users; it does not change your rights to use your own Contributions for any |
||||
other purpose. If you have not already done so, please complete and sign this |
||||
Individual License Agreement by following the instructions embedded below. |
||||
After you fill in the required information and apply your digital signature to |
||||
the Agreement, the signature service will generate an email to you. You must |
||||
confirm your digital signature as instructed in this email to complete the |
||||
signing process. The signature service will then send you a signed copy of this |
||||
Agreement for your records.</em></p> |
||||
|
||||
<p><em>You accept and agree to the following terms and conditions for Your |
||||
present and future Contributions submitted to the Project Manager. Except for |
||||
the license granted herein to the Project Manager and recipients of software |
||||
distributed by the Project Manager, You reserve all right, title, and interest |
||||
in and to Your Contributions.</em></p> |
||||
|
||||
<ol> |
||||
|
||||
<li><p><strong>Definitions</strong>"You" (or "Your") shall mean the copyright |
||||
owner or legal entity authorized by the copyright owner that is making this |
||||
Agreement with the Project Manager. For legal entities, the entity making a |
||||
Contribution and all other entities that control, are controlled by, or are |
||||
under common control with that entity are considered to be a single |
||||
Contributor. For the purposes of this definition, "control" means (i) the |
||||
power, direct or indirect, to cause the direction or management of such entity, |
||||
whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or |
||||
more of the outstanding shares, or (iii) beneficial ownership of such |
||||
entity. "Contribution" shall mean any original work of authorship, including |
||||
any modifications or additions to an existing work, that is intentionally |
||||
submitted by You to the Project Manager for inclusion in, or documentation of, |
||||
any of the projects owned or managed by the Project Manager (the "Work"). For |
||||
the purposes of this definition, "submitted" means any form of electronic, |
||||
verbal, or written communication sent to the Project Manager or its |
||||
representatives, including but not limited to communication on electronic |
||||
mailing lists, source code control systems, and issue tracking systems that are |
||||
managed by, or on behalf of, the Project Manager for the purpose of discussing |
||||
and improving the Work, but excluding communication that is conspicuously |
||||
marked or otherwise designated in writing by You as "Not a |
||||
Contribution."</p></li> |
||||
|
||||
<li><p><strong>Grant of Copyright License.</strong> Subject to the terms and |
||||
conditions of this Agreement, You hereby grant to the Project Manager and to |
||||
recipients of software distributed by the Project Manager a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright |
||||
license to reproduce, prepare derivative works of, publicly display, publicly |
||||
perform, sublicense, and distribute Your Contributions and such derivative |
||||
works.</p></li> |
||||
|
||||
<li><p><strong>Grant of Patent License.</strong> Subject to the terms and |
||||
conditions of this Agreement, You hereby grant to the Project Manager and to |
||||
recipients of software distributed by the Project Manager a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as |
||||
stated in this section) patent license to make, have made, use, offer to sell, |
||||
sell, import, and otherwise transfer the Work, where such license applies only |
||||
to those patent claims licensable by You that are necessarily infringed by Your |
||||
Contribution(s) alone or by combination of Your Contribution(s) with the Work |
||||
to which such Contribution(s) was submitted. If any entity institutes patent |
||||
litigation against You or any other entity (including a cross-claim or |
||||
counterclaim in a lawsuit) alleging that Your Contribution, or the Work to |
||||
which You have contributed, constitutes direct or contributory patent |
||||
infringement, then any patent licenses granted to that entity under this |
||||
Agreement for that Contribution or Work shall terminate as of the date such |
||||
litigation is filed.</p></li> |
||||
|
||||
<li><p>You represent that you are legally entitled to grant the above license. |
||||
If your employer(s) has rights to intellectual property that you create that |
||||
includes your Contributions, You represent that you have received permission to |
||||
make Contributions on behalf of that employer, that your employer has waived |
||||
such rights for your Contributions to the Project Manager, or that your |
||||
employer has executed a separate Corporate Contributor License Agreement with |
||||
the Project Manager.</p></li> |
||||
|
||||
<li><p>You represent that each of Your Contributions is Your original creation |
||||
(see Section 7 for submissions on behalf other others). You represent that Your |
||||
Contribution submissions include complete details of any third-party license or |
||||
other restriction (including, but not limited to, related patents and |
||||
trademarks) of which you are personally aware and which are associated with any |
||||
part of Your Contributions.</p></li> |
||||
|
||||
<li><p>You are not expected to provide support for Your Contributions, except |
||||
to the extent You desire to provide support. You may provide support for free, |
||||
for a fee, or not at all. Unless required by applicable law or agreed to in |
||||
writing, You provide Your Contributions on as "AS IS" BASIS, WITHOUT WARRANTIES |
||||
OR CONDITIONS OR ANY KIND, either express or implied, including, without |
||||
limitation, any warranties or conditions of TITLE, NONINFRINGEMENT, |
||||
MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.</p></li> |
||||
|
||||
<li><p>Should You wish to submit work that is not Your original creation, You |
||||
may submit it to the Project Manager separately from any Contribution, |
||||
identifying the complete details of its source and of any license or other |
||||
restriction (including, but not limited to, related patents, trademarks, and |
||||
license agreements) of which you are personally aware, and conspicuously |
||||
marking the work as "Submitted on behalf of a third-party: [named |
||||
here]".</p></li> |
||||
|
||||
<li><p>You agree to notify the Project Manager of any facts or circumstances of |
||||
which you become aware that would make these representations inaccurate in any |
||||
respect.</p></li> |
||||
|
||||
</ol> |
||||
|
||||
</blockquote> |
||||
|
||||
</div></body></html> |
@ -0,0 +1,179 @@
|
||||
body {color: #000 !important;} |
||||
a,a:visited {color: #264D69 !important; text-decoration: none;} |
||||
a:hover {color: #000 !important; text-decoration: underline} |
||||
|
||||
a.gwt-InlineHyperlink {background: none !important} |
||||
|
||||
#openstack-logo img { height: 40px; } |
||||
#openstack-logo h1 { margin: 20px; } |
||||
#gerrit_header #openstack-logo h1 { margin: 20px 0 0 0; } |
||||
|
||||
#gerrit_header {display: block !important; position: relative; top: -60px; margin-bottom: -60px; width: 200px; padding-left: 17px} |
||||
#gerrit_header h1 {font-family: 'PT Sans', sans-serif; font-weight: normal; letter-spacing: -1px} |
||||
|
||||
#gerrit_topmenu {background: none; position:relative; top: 0px; left: 220px; margin-right: 220px} |
||||
|
||||
#gerrit_topmenu tbody tr td table {border: 0} |
||||
|
||||
#gerrit_topmenu tbody tr td table.gwt-TabBar {color: #353535; border-bottom: 1px solid #C5E2EA;} |
||||
#gerrit_topmenu .gwt-Button {padding: 3px 6px} |
||||
.gwt-TabBarItem-selected {color: #CF2F19 !important; border-bottom: 3px solid #CF2F19;} |
||||
.gwt-TabBarItem {color: #353535; border-right: 0 !important} |
||||
.gwt-TabBar .gwt-TabBarItem, .gwt-TabBar .gwt-TabBarRest, .gwt-TabPanelBottom {background: 0 !important;} |
||||
|
||||
#gerrit_topmenu .searchTextBox {width: 250px} |
||||
|
||||
#change_infoTable { |
||||
border-collapse: collapse; |
||||
} |
||||
|
||||
#change_infoTable th { |
||||
padding: 2px 4px 2px 6px; |
||||
background-color: #eef3f5; |
||||
font-style: italic; |
||||
text-align: left; |
||||
} |
||||
|
||||
#change_infoTable td { |
||||
padding: 2px 4px 2px 6px; |
||||
border-bottom: 1px solid #eef3f5; |
||||
border-right: 1px solid #eef3f5; |
||||
} |
||||
|
||||
#change_infoTable tr:last-child td { |
||||
border: none; |
||||
} |
||||
|
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 { |
||||
padding-left: 10px; |
||||
padding-right: 10px; |
||||
} |
||||
|
||||
/* Section headers */ |
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 |
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-headerLine, |
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 |
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-sectionHeader { |
||||
margin-top: 10px !important; |
||||
margin-bottom: 10px !important; |
||||
} |
||||
|
||||
/* Commit message */ |
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 |
||||
.com-google-gerrit-client-change-CommitBox_BinderImpl_GenCss_style-text::first-line { |
||||
font-weight: bold !important; |
||||
} |
||||
|
||||
/* Commit metadata */ |
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 |
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-commitColumn |
||||
.com-google-gerrit-client-change-CommitBox_BinderImpl_GenCss_style-header th { |
||||
padding: 2px 4px 2px 6px; |
||||
background-color: #eef3f5; |
||||
font-style: italic; |
||||
text-align: left; |
||||
} |
||||
|
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 |
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-commitColumn |
||||
.com-google-gerrit-client-change-CommitBox_BinderImpl_GenCss_style-header td { |
||||
border-bottom: 1px solid #eef3f5; |
||||
padding: 2px 4px 2px 6px; |
||||
} |
||||
|
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 |
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-commitColumn |
||||
.com-google-gerrit-client-change-CommitBox_BinderImpl_GenCss_style-header td:last-child { |
||||
border-right: 1px solid #eef3f5; |
||||
} |
||||
|
||||
/* increase the middle info column to fill empty space (for wide |
||||
monitors), but ensure there is a sufficient lower bound to kick in |
||||
horiz scroll bar. This will relieve the preasure on the hideci test |
||||
results. */ |
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-infoColumn { |
||||
width: 100% !important; |
||||
min-width: 400px; |
||||
} |
||||
|
||||
/* Review history */ |
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 |
||||
.com-google-gerrit-client-change-Message_BinderImpl_GenCss_style-name { |
||||
font-weight: bold !important; |
||||
} |
||||
.com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-cs2 |
||||
.com-google-gerrit-client-change-Message_BinderImpl_GenCss_style-messageBox { |
||||
width: inherit; |
||||
max-width: 1168px; |
||||
} |
||||
|
||||
.comment_test_name { |
||||
display: inline-block; |
||||
*display: inline; |
||||
*zoom: 1; |
||||
width: auto !important; |
||||
width: 25em; |
||||
min-width: 20em; |
||||
padding-bottom: 2pt; |
||||
} |
||||
|
||||
.comment_test_result { |
||||
} |
||||
|
||||
.result_SUCCESS { |
||||
color: #007f00; |
||||
} |
||||
.result_FAILURE, .result_POST_FAILURE, .result_TIMED_OUT, .result_RETRY_LIMIT, .result_DISK_FULL { |
||||
color: #cf2f19; |
||||
} |
||||
.result_UNSTABLE, .result_WARNING { |
||||
color: #e39f00; |
||||
} |
||||
.result_LOST { |
||||
color: #e39f00; |
||||
} |
||||
li.comment_test {list-style-type: none; } |
||||
|
||||
/* this is for support of 'Display Person Name In Review Category' */ |
||||
.cAPPROVAL { |
||||
max-width: 100px; |
||||
overflow: hidden; |
||||
} |
||||
/* fixes to make this like old gerrit */ |
||||
.changeTable td.dataCell { |
||||
height: 1em; |
||||
} |
||||
|
||||
/* don't make the non voting stand out more than the voting */ |
||||
table.infoTable td.notVotable, |
||||
.changeTable td.dataCell.labelNotApplicable { |
||||
background: inherit; |
||||
} |
||||
|
||||
.test_result_table { |
||||
border-collapse: collapse; |
||||
} |
||||
|
||||
.test_result_table tr { |
||||
border-left: 1px solid #eef3f5; |
||||
border-right: 1px solid #eef3f5; |
||||
} |
||||
|
||||
.test_result_table td.header { |
||||
background-color: #eef3f5; |
||||
} |
||||
|
||||
.test_result_table td { |
||||
padding: 2px 4px 2px 6px; |
||||
border: 1px solid #eef3f5; |
||||
} |
||||
|
||||
.addMemberTextBox { |
||||
width: 20em; |
||||
} |
||||
|
||||
/* css attribute selector to make -1s show up red in new screen */ |
||||
[title="Doesn't seem to work"], |
||||
[title="This patch needs further work before it can be merged"] { |
||||
color: red; |
||||
} |
@ -0,0 +1,6 @@
|
||||
<div id="openstack-logo"> |
||||
<script type="text/javascript" src="static/jquery.js" /> |
||||
<script type="text/javascript" src="static/jquery-visibility.js"></script> |
||||
<script type="text/javascript" src="static/hideci.js" /> |
||||
<a href="/"><h1><img src="static/title.svg" style="vertical-align:middle;" /></h1></a> |
||||
</div> |
@ -0,0 +1,16 @@
|
||||
version: '3' |
||||
|
||||
services: |
||||
gerrit: |
||||
image: docker.io/opendevorg/gerrit:2.13 |
||||
network_mode: host |
||||
user: gerrit |
||||
volumes: |
||||
- /home/gerrit2/review_site/cache:/var/gerrit/cache |
||||
- /home/gerrit2/review_site/etc:/var/gerrit/etc |
||||
- /home/gerrit2/review_site/git:/var/gerrit/git |
||||
- /home/gerrit2/review_site/tmp:/var/gerrit/tmp |
||||
- /home/gerrit2/review_site/hooks:/var/gerrit/hooks |
||||
- /home/gerrit2/review_site/index:/var/gerrit/index |
||||
- /home/gerrit2/review_site/logs:/var/log/gerrit |
||||
- /home/gerrit2/review_site/static:/var/gerrit/static |
@ -0,0 +1,4 @@
|
||||
#!/bin/sh |
||||
|
||||
# Use timeout to kill any process running longer than 10 minutes. |
||||
timeout -k 2m 10m /usr/local/bin/update-bug change-abandoned "$@" |
@ -0,0 +1,4 @@
|
||||
#!/bin/sh |
||||
|
||||
# Use timeout to kill any process running longer than 10 minutes. |
||||
timeout -k 2m 10m /usr/local/bin/update-bug change-merged "$@" |
@ -0,0 +1,11 @@
|
||||
# Directions for web crawlers. |
||||
# See http://www.robotstxt.org/wc/norobots.html. |
||||
|
||||
User-agent: HTTrack |
||||
User-agent: puf |
||||
User-agent: MSIECrawler |
||||
User-agent: Nutch |
||||
Disallow: / |
||||
|
||||
User-agent: msnbot |
||||
Crawl-delay: 1 |
@ -0,0 +1,575 @@
|
||||
// Copyright (c) 2014 VMware, Inc.
|
||||
// Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
// this regex matches the hash part of review pages
|
||||
var hashRegex = /^\#\/c\/([\d]+)((\/\d+)([.][.](\d+))?)?\/?$/; |
||||
// this regex matches CI comments
|
||||
var ciRegex = /^(.* CI|Jenkins|Zuul)$/; |
||||
// this regex matches "Patch set #"
|
||||
var psRegex = /^(Uploaded patch set|Patch Set) (\d+)(:|\.)/; |
||||
// this regex matches merge failure messages
|
||||
var mergeFailedRegex = /Merge Failed\./; |
||||
// this regex matches the name of CI systems we trust to report merge failures
|
||||
var trustedCIRegex = /^(OpenStack CI|Jenkins|Zuul)$/; |
||||
// this regex matches the name+pipeline that we want at the top of the CI list
|
||||
var firstPartyCI = /^(Jenkins|Zuul)/; |
||||
// this regex matches the pipeline markup
|
||||
var pipelineNameRegex = /Build \w+ \(([-\w]+) pipeline\)/; |
||||
// The url to full status information on running jobs
|
||||
var zuulStatusURL = 'https://zuul.openstack.org'; |
||||
// The json URL to check for running jobs
|
||||
var zuulStatusJSON = 'https://zuul.openstack.org/status/change/'; |
||||
|
||||
// This is a variable to determine if we're in debugging mode, which
|
||||
// lets you globally set it to see what's going on in the flow.
|
||||
var hideci_debug = false; |
||||
// This is a variable to enable zuul integration, we default it off so
|
||||
// that it creates no additional load, and that it's easy to turn off
|
||||
// the feature.
|
||||
var zuul_inline = false; |
||||
|
||||
/** |
||||
dbg(...) - prints a list of items out to the javascript |
||||
console.log. This allows us to leave tracing in this file which is a |
||||
no-op by default, but can be triggered if you enter a javascript |
||||
console and set hideci_debug = true. |
||||
*/ |
||||
function dbg () { |
||||
if (hideci_debug == true) { |
||||
for (var i = 0; i < arguments.length; i++) { |
||||
console.log(arguments[i]); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
function format_time(ms, words) { |
||||
if (ms == null) { |
||||
return "unknown"; |
||||
} |
||||
var seconds = (+ms)/1000; |
||||
var minutes = Math.floor(seconds/60); |
||||
var hours = Math.floor(minutes/60); |
||||
seconds = Math.floor(seconds % 60); |
||||
minutes = Math.floor(minutes % 60); |
||||
r = ''; |
||||
if (words) { |
||||
if (hours) { |
||||
r += hours; |
||||
r += ' hr '; |
||||
} |
||||
r += minutes + ' min'; |
||||
} else { |
||||
if (hours < 10) r += '0'; |
||||
r += hours + ':'; |
||||
if (minutes < 10) r += '0'; |
||||
r += minutes + ':'; |
||||
if (seconds < 10) r += '0'; |
||||
r += seconds; |
||||
} |
||||
return r; |
||||
} |
||||
|
||||
var ci_parse_psnum = function($panel) { |
||||
var match = psRegex.exec($panel.html()); |
||||
if (match !== null) { |
||||
return parseInt(match[2]); |
||||
} |
||||
return 0; |
||||
}; |
||||
|
||||
var ci_parse_is_merge_conflict = function($panel) { |
||||
return (mergeFailedRegex.exec($panel.html()) !== null); |
||||
}; |
||||
|
||||
var ci_find_pipeline = function($panel) { |
||||
var match = pipelineNameRegex.exec($panel.html()); |
||||
if (match !== null) { |
||||
return match[1]; |
||||
} else { |
||||
return null; |
||||
} |
||||
}; |
||||
|
||||
var ci_parse_results = function($panel) { |
||||
var result_list = []; |
||||
var test_results = $panel.find("li.comment_test"); |
||||
var pipeline = null; |
||||
if (test_results !== null) { |
||||
test_results.each(function(i, li) { |
||||
var result = {}; |
||||
if ($(li).find("a").length > 0) { |
||||
result["name"] = $(li).find("span.comment_test_name").find("a")[0].innerHTML; |
||||
result["link"] = $(li).find("span.comment_test_name").find("a")[0]; |
||||
} |
||||
else { |
||||
result["name"] = $(li).find("span.comment_test_name")[0].innerHTML; |
||||
} |
||||
result["result"] = $(li).find("span.comment_test_result")[0]; |
||||
result_list.push(result); |
||||
}); |
||||
} |
||||
return result_list; |
||||
}; |
||||
|
||||
/*** |
||||
* function ci_group_by_ci_pipeline - create a group by structure for |
||||
* iterating on CI's pipelines |
||||
* |
||||
* This function takes the full list of comments, the current patch |
||||
* number, and builds an array of (ci_name_pipelinename, comments array) |
||||
* tuples. That makes it very easy to process during the display |
||||
* phase to ensure we only display the latest result for every CI |
||||
* pipeline. |
||||
* |
||||
* Comments that do not have a parsable pipeline (3rd party ci |
||||
* systems) get collapsed by name, and we specify 'check' for their |
||||
* pipeline. |
||||
* |
||||
**/ |
||||
|
||||
var ci_group_by_ci_pipeline = function(current, comments) { |
||||
var ci_pipelines = []; |
||||
var ci_pipeline_comments = []; |
||||
for (var i = 0; i < comments.length; i++) { |
||||
var comment = comments[i]; |
||||
if ((comment.psnum != current) || !comment.is_ci || (comment.results.length == 0)) { |
||||
continue; |
||||
} |
||||
var name_pipeline = comment.name; |
||||
if (comment.pipeline !== null) { |
||||
name_pipeline += ' ' + comment.pipeline; |
||||
} |
||||
|
||||
var index = ci_pipelines.indexOf(name_pipeline); |
||||
if (index == -1) { |
||||
// not found, so create new entries
|
||||
ci_pipelines.push(name_pipeline); |
||||
ci_pipeline_comments.push([comment]); |
||||
} else { |
||||
ci_pipeline_comments[index].push(comment); |
||||
} |
||||
} |
||||
|
||||
function sort_by_name(a,b) { |
||||
if (a[0] < b[0]) |
||||
return -1; |
||||
else if (a[0] > b[0]) |
||||
return 1; |
||||
else |
||||
return 0; |
||||
} |
||||
|
||||
var results = []; |
||||
var notfirstparty = []; |
||||
// we want to separate out first party CI results to always be the
|
||||
// top of the list, and third party CI to come after, so that
|
||||
// hunting for first party CI isn't tough.
|
||||
for (i = 0; i < ci_pipelines.length; i++) { |
||||
if (firstPartyCI.test(ci_pipelines[i])) { |
||||
results.push([ci_pipelines[i], ci_pipeline_comments[i]]); |
||||
} else { |
||||
notfirstparty.push([ci_pipelines[i], ci_pipeline_comments[i]]); |
||||
} |
||||
} |
||||
|
||||
notfirstparty.sort(sort_by_name); |
||||
|
||||
for (i = 0; i < notfirstparty.length; i++) { |
||||
results.push(notfirstparty[i]); |
||||
} |
||||
return results; |
||||
}; |
||||
|
||||
var ci_parse_comments = function() { |
||||
var comments = []; |
||||
$("p").each(function() { |
||||
var match = psRegex.exec($(this).html()); |
||||
if (match !== null) { |
||||
var psnum = parseInt(match[2]); |
||||
var top = $(this).parent().parent().parent(); |
||||
// old change screen
|
||||
var name = top.attr("name"); |
||||
if (!name) { |
||||
// new change screen
|
||||
name = $(this).parent().parent().parent().children().children()[0].innerHTML; |
||||
top = $(this).parent().parent().parent().parent(); |
||||
} |
||||
var comment = {}; |
||||
comment.name = name; |
||||
|
||||
var date_cell = top.find(".commentPanelDateCell"); |
||||
if (date_cell.attr("title")) { |
||||
// old change screen
|
||||
comment.date = date_cell.attr("title"); |
||||
} else { |
||||
// new change screen
|
||||
comment.date = $(this).parent().parent().parent().children().children()[2].innerHTML |
||||
} |
||||
var comment_panel = $(this).parent(); |
||||
comment.psnum = psnum; |
||||
comment.merge_conflict = ci_parse_is_merge_conflict(comment_panel); |
||||
comment.pipeline = ci_find_pipeline(comment_panel); |
||||
comment.results = ci_parse_results(comment_panel); |
||||
comment.is_ci = (ciRegex.exec(comment.name) !== null); |
||||
comment.is_trusted_ci = (trustedCIRegex.exec(comment.name) !== null); |
||||
comment.ref = top; |
||||
dbg("Found comment", comment); |
||||
comments.push(comment); |
||||
} |
||||
}); |
||||
return comments; |
||||
}; |
||||
|
||||
var ci_latest_patchset = function(comments) { |
||||
var psnum = 0; |
||||
for (var i = 0; i < comments.length; i++) { |
||||
psnum = Math.max(psnum, comments[i].psnum); |
||||
} |
||||
return psnum; |
||||
}; |
||||
|
||||
var ci_is_merge_conflict = function(comments) { |
||||
var latest = ci_latest_patchset(comments); |
||||
var conflict = false; |
||||
for (var i = 0; i < comments.length; i++) { |
||||
var comment = comments[i]; |
||||
// only if we are actually talking about the latest patch set
|
||||
if (comment.psnum == latest) { |
||||
if (comment.is_trusted_ci) { |
||||
conflict = comment.merge_conflict; |
||||
} |
||||
} |
||||
} |
||||
return conflict; |
||||
}; |
||||
|
||||
var ci_prepare_results_table = function() { |
||||
// Create a table and insert it after the approval table
|
||||
var table = $("table.test_result_table")[0]; |
||||
if (!table) { |
||||
table = document.createElement("table"); |
||||
$(table).addClass("test_result_table"); |
||||
$(table).addClass("infoTable").css({"margin-top":"1em", "margin-bottom":"1em"}); |
||||
|
||||
var approval_table = $("div.approvalTable"); |
||||
if (approval_table.length) { |
||||
var outer_table = document.createElement("table"); |
||||
$(outer_table).insertBefore(approval_table); |
||||
var outer_table_row = document.createElement("tr"); |
||||
$(outer_table).append(outer_table_row); |
||||
var td = document.createElement("td"); |
||||
$(outer_table_row).append(td); |
||||
$(td).css({"vertical-align":"top"}); |
||||
$(td).append(approval_table); |
||||
td = document.createElement("td"); |
||||
$(outer_table_row).append(td); |
||||
$(td).css({"vertical-align":"top"}); |
||||
$(td).append(table); |
||||
} else { |
||||
var big_table_row = $("div.screen>div>div>table>tbody>tr"); |
||||
var td = $(big_table_row).children()[1]; |
||||
$(td).append(table); |
||||
} |
||||
} else { |
||||
$(table).empty(); |
||||
} |
||||
return table; |
||||
}; |
||||
|
||||
var ci_display_results = function(comments) { |
||||
var table = ci_prepare_results_table(); |
||||
if (ci_is_merge_conflict(comments)) { |
||||
var mc_header = $("<tr>").append($('<td class="merge_conflict" colpsan="2">Patch in Merge Conflict</td>')); |
||||
mc_header.css('width', '400'); |
||||
mc_header.css('font-weight', 'bold'); |
||||
mc_header.css('color', 'red'); |
||||
mc_header.css('padding-left', '2em'); |
||||
$(table).append(mc_header); |
||||
|
||||
return; |
||||
} |
||||
var current = ci_latest_patchset(comments); |
||||
var ci_pipelines = ci_group_by_ci_pipeline(current, comments); |
||||
for (var i = 0; i < ci_pipelines.length; i++) { |
||||
var ci_pipeline_name = ci_pipelines[i][0]; |
||||
var ci_pipeline_comments = ci_pipelines[i][1]; |
||||
// the most recent comment on a pipeline
|
||||
var last = ci_pipeline_comments.length - 1; |
||||
var comment = ci_pipeline_comments[last]; |
||||
var rechecks = ""; |
||||
if (last > 0) { |
||||
rechecks = " (" + last + " rechecks)"; |
||||
} |
||||
|
||||
var header = $("<tr>").append($('<td class="header">' + ci_pipeline_name + rechecks + '</td>')); |
||||
header.append('<td class="header ci_date">' + comment.date + '</td>'); |
||||
$(table).append(header); |
||||
for (var j = 0; j < comment.results.length; j++) { |
||||
var result = comment.results[j]; |
||||
var tr = $("<tr>"); |
||||
if ("link" in result) { |
||||
tr.append($("<td>").append($(result["link"]).clone())); |
||||
} |
||||
else { |
||||
tr.append($("<td>").text(result["name"])); |
||||
} |
||||
tr.append($("<td>").append($(result["result"]).clone())); |
||||
$(table).append(tr); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
var set_cookie = function (name, value) { |
||||
document.cookie = name + "=" + value + "; path=/"; |
||||
}; |
||||
|
||||
var read_cookie = function (name) { |
||||
var nameEQ = name + "="; |
||||
var ca = document.cookie.split(';'); |
||||
for (var i = 0; i < ca.length; i++) { |
||||
var c = ca[i]; |
||||
while (c.charAt(0) == ' ') { |
||||
c = c.substring(1, c.length); |
||||
} |
||||
if (c.indexOf(nameEQ) == 0) { |
||||
return c.substring(nameEQ.length, c.length); |
||||
} |
||||
} |
||||
return null; |
||||
}; |
||||
|
||||
var ci_toggle_visibility = function(comments, showOrHide) { |
||||
if (!comments) { |
||||
comments = ci_parse_comments(); |
||||
} |
||||
$.each(comments, function(i, comment) { |
||||
if (comment.is_ci && !comment.is_trusted_ci) { |
||||
$(comment.ref).toggle(showOrHide); |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
var ci_hide_ci_comments = function(comments) { |
||||
if (!comments) { |
||||
comments = ci_parse_comments(); |
||||
} |
||||
$.each(comments, function(i, comment) { |
||||
if (comment.is_ci && !comment.is_trusted_ci) { |
||||
$(comment.ref).hide(); |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
var ci_page_loaded = function() { |
||||
if (hashRegex.test(window.location.hash)) { |
||||
dbg("Searching for ci results on " + window.location.hash); |
||||
$("#toggleci").show(); |
||||
var comments = ci_parse_comments(); |
||||
ci_display_results(comments); |
||||
var showOrHide = 'true' == read_cookie('show-ci-comments'); |
||||
if (!showOrHide) { |
||||
ci_hide_ci_comments(comments); |
||||
} |
||||
if (zuul_inline === true) { |
||||
ci_zuul_for_change(comments); |
||||
} |
||||
} else { |
||||
$("#toggleci").hide(); |
||||
} |
||||
}; |
||||
|
||||
var ci_current_change = function() { |
||||
var change = hashRegex.exec(window.location.hash); |
||||
if (change.length > 1) { |
||||
return change[1]; |
||||
} |
||||
return null; |
||||
}; |
||||
|
||||
// recursively find the zuul status change, will be much more
|
||||
// efficient once zuul supports since json status.
|
||||
var ci_find_zuul_status = function (data, change_psnum) { |
||||
var objects = []; |
||||
for (var i in data) { |
||||
if (!data.hasOwnProperty(i)) continue; |
||||
if (typeof data[i] == 'object') { |
||||
objects = objects.concat(ci_find_zuul_status(data[i], |
||||
change_psnum)); |
||||
} else if (i == 'id' && data.id == change_psnum) { |
||||
objects.push(data); |
||||
} |
||||
} |
||||
return objects; |
||||
}; |
||||
|
||||
var ci_zuul_all_status = function(jobs) { |
||||
var status = "passing"; |
||||
for (var i = 0; i < jobs.length; i++) { |
||||
if (jobs[i].result && jobs[i].result != "SUCCESS") { |
||||
status = "failing"; |
||||
break; |
||||
} |
||||
} |
||||
return status; |
||||
}; |
||||
|
||||
var ci_zuul_display_status = function(status) { |
||||
var zuul_table = $("table.zuul_result_table")[0]; |
||||
if (!zuul_table) { |
||||
var test_results = $("table.test_result_table")[0]; |
||||
zuul_table = document.createElement("table"); |
||||
$(zuul_table).addClass("zuul_result_table"); |
||||
$(zuul_table).addClass("infoTable").css({"margin-bottom":"1em"}); |
||||
if (test_results) { |
||||
$(test_results).prepend(zuul_table); |
||||
} |
||||
} |
||||
$(zuul_table).empty(); |
||||
$(zuul_table).show(); |
||||
$(zuul_table).append("<tr><td class='header'>Change currently being tested (<a href='" + zuulStatusURL + "'>full status</a>)</td></tr>"); |
||||
for (var i = 0; i < status.length; i++) { |
||||
var item = status[i]; |
||||
var pipeline = item.jobs[0].pipeline; |
||||
var passing = (item.failing_reasons && item.failing_reasons.length > 0) ? "failing" : "passing"; |
||||
var timeleft = item.remaining_time; |
||||
var row = "<tr><td>"; |
||||
if (pipeline != null) { |
||||
row += pipeline + " pipeline: " + passing; |
||||
row += " (" + format_time(timeleft, false) + " left)"; |
||||
} else { |
||||
row += "in between pipelines, status should update shortly"; |
||||
} |
||||
row += "</td></tr>"; |
||||
|
||||
$(zuul_table).append(row); |
||||
} |
||||
}; |
||||
|
||||
var ci_zuul_clear_status = function () { |
||||
var zuul_table = $("table.zuul_result_table")[0]; |
||||
if (zuul_table) { |
||||
$(zuul_table).hide(); |
||||
} |
||||
}; |
||||
|
||||
var ci_zuul_process_changes = function(data, change_psnum) { |
||||
var zuul_status = ci_find_zuul_status(data, change_psnum); |
||||
if (zuul_status.length) { |
||||
ci_zuul_display_status(zuul_status); |
||||
} else { |
||||
ci_zuul_clear_status(); |
||||
} |
||||
}; |
||||
|
||||
var ci_zuul_for_change = function(comments) { |
||||
if (!comments) { |
||||
comments = ci_parse_comments(); |
||||
} |
||||
var change = ci_current_change(); |
||||
var psnum = ci_latest_patchset(comments); |
||||
var change_psnum = change + "," + psnum; |
||||
|
||||
// do the loop recursively in ajax
|
||||
(function poll() { |
||||
$.ajax({ |
||||
url: zuulStatusJSON + change_psnum, |
||||
type: "GET", |
||||
success: function(data) { |
||||
dbg("Found zuul data for " + change_psnum, data); |
||||
ci_zuul_process_changes(data, change_psnum); |
||||
}, |
||||
dataType: "json", |
||||
complete: setTimeout(function() { |
||||
// once we are done with this cycle in the loop we
|
||||
// schedule ourselves again in the future with
|
||||
// setTimeout. However, by the time the function
|
||||
// actually gets called, other things might have
|
||||
// happened, and we may want to just dump the data
|
||||
// instead.
|
||||
//
|
||||
// the UI might have gone hidden (user was bored,
|
||||
// switched to another tab / window).
|
||||
//
|
||||
// the user may have navigated to another review url,
|
||||
// so the data returned is not relevant.
|
||||
//
|
||||
// both cases are recoverable when the user navigates
|
||||
// around, because a new "thread" gets started on
|
||||
// ci_page_load.
|
||||
//
|
||||
// BUG(sdague): there is the possibility that the user
|
||||
// navigates away from a page and back fast enough
|
||||
// that the first "thread" is not dead, and a second
|
||||
// one is started. greghaynes totally said he'd come
|
||||
// up with a way to fix that.
|
||||
if (window.zuul_enable_status_updates == false) { |
||||
return; |
||||
} |
||||
var current = ci_current_change(); |
||||
if (current && change_psnum.indexOf(current) != 0) { |
||||
// window url is dead, so don't schedule any more future
|
||||
// updates for this url.
|
||||
return; |
||||
} |
||||
poll(); |
||||
}, 15000), |
||||
timeout: 5000 |
||||
}); |
||||
})(); |
||||
}; |
||||
|
||||
|
||||
window.onload = function() { |
||||
var input = document.createElement("input"); |
||||
input.id = "toggleci"; |
||||
input.type = "button"; |
||||
input.className = "gwt-Button"; |
||||
input.value = "Toggle Extra CI"; |
||||
input.onclick = function () { |
||||
// Flip the cookie
|
||||
var showOrHide = 'true' == read_cookie('show-ci-comments'); |
||||
set_cookie('show-ci-comments', showOrHide ? 'false' : 'true'); |
||||
// Hide or Show existing comments based on cookie
|
||||
ci_toggle_visibility(null, !showOrHide); |
||||
}; |
||||
document.body.appendChild(input); |
||||
|
||||
MutationObserver = window.MutationObserver || window.WebKitMutationObserver; |
||||
var observer = new MutationObserver(function(mutations, observer) { |
||||
var span = $("span.rpcStatus"); |
||||
$.each(mutations, function(i, mutation) { |
||||
if (mutation.target === span[0] && |
||||
mutation.attributeName === "style" && |
||||
(!(span.is(":visible")))) { |
||||
ci_page_loaded(); |
||||
} |
||||
}); |
||||
}); |
||||
observer.observe(document, { |
||||
subtree: true, |
||||
attributes: true |
||||
}); |
||||
|
||||
$(document).on({ |
||||
'show.visibility': function() { |
||||
window.zuul_enable_status_updates = true; |
||||
ci_page_loaded(); |
||||
}, |
||||
'hide.visibility': function() { |
||||
window.zuul_enable_status_updates = false; |
||||
} |
||||
}); |
||||
}; |
@ -0,0 +1,14 @@
|
||||
<html><body><div> |
||||
|
||||
<h1> |
||||
Gerrit System Role Accounts Proxy CLA |
||||
</h1> |
||||
|
||||
<p> |
||||
This is not a real CLA and cannot be signed. See <a |
||||
href="https://docs.openstack.org/infra/manual/developers.html#account-setup">the |
||||
account setup instructions</a> for more information on OpenStack Contributor |
||||
License Agreements. |
||||
</p> |
||||
|
||||
</div></body></html> |
@ -0,0 +1,16 @@
|
||||
<html><body><div> |
||||
|
||||
<h1> |
||||
OpenStack Project U.S. Government Contributor License Agreement |
||||
</h1> |
||||
|
||||
<p> |
||||
This agreement is not managed through Gerrit. If you need to sign the U.S. |
||||
Government Contributor License Agreement, please contact the OpenStack |
||||
Foundation to initiate the process. See <a |
||||
href="https://docs.openstack.org/infra/manual/developers.html#account-setup">the |
||||
account setup instructions</a> for more information on OpenStack Contributor |
||||
License Agreements. |
||||
</p> |
||||
|
||||
</div></body></html> |
@ -0,0 +1,170 @@
|
||||
# TODO(mordred) We should do *something* where this could use a zuul cloned |
||||
# copy of project-config instead. This is needed not just for things like |
||||
# manage-projects (which could be run completely differently and non-locally) |
||||
# but also for things like notify-impact, which is currently run by a gerrit |
||||
# hook inside of the container via jeepyb. |
||||
- name: Clone project-config repo |
||||
git: |
||||
repo: https://opendev.org/openstack/project-config |
||||
dest: /opt/project-config |
||||
force: yes |
||||
|
||||
- name: Synchronize podman-compose directory |
||||
synchronize: |
||||
src: gerrit-podman/ |
||||
dest: /etc/gerrit-podman/ |
||||
|
||||
- name: Create Gerrit Group |
||||
group: |
||||
name: "{{ gerrit_user_name }}" |
||||
gid: "{{ gerrit_id }}" |
||||
system: yes |
||||
|
||||
- name: Create Gerrit User |
||||
user: |
||||
name: "{{ gerrit_user_name }}" |
||||
uid: "{{ gerrit_id }}" |
||||
comment: Gerit User |
||||
shell: /bin/bash |
||||
home: "{{ gerrit_home_dir }}" |
||||
group: "{{ gerrit_user_name }}" |
||||
create_home: yes |
||||
system: yes |
||||
|
||||
- name: Ensure review_site directory exists |
||||
file: |
||||
state: directory |
||||
path: "{{ gerrit_site_dir }}" |
||||
owner: "{{ gerrit_user_name }}" |
||||
group: "{{ gerrit_user_name }}" |
||||
mode: 0755 |
||||
|
||||
- name: Ensure Gerrit volume directories exists |
||||
file: |
||||
state: directory |
||||
path: "{{ gerrit_site_dir }}/{{ item }}" |
||||
owner: "{{ gerrit_user_name }}" |
||||
group: "{{ gerrit_user_name }}" |
||||
mode: 0755 |
||||
loop: |
||||
- etc |
||||
- git |
||||
- index |
||||
- cache |
||||
- static |
||||
- hooks |
||||
- tmp |
||||
- logs |
||||
|
||||