diff --git a/roles/htmlify-logs/library/htmlify.py b/roles/htmlify-logs/library/htmlify.py index 2b02f0c3a..90629c7f8 100644 --- a/roles/htmlify-logs/library/htmlify.py +++ b/roles/htmlify-logs/library/htmlify.py @@ -14,6 +14,11 @@ # under the License. import cgi +html_escape = getattr(cgi, 'escape', None) +if not html_escape: + import html + html_escape = html.escape + import argparse import gzip import sys @@ -95,7 +100,7 @@ def run(inpath, outpath): for i, line in enumerate(infile): i = i + 1 - line = cgi.escape(line.rstrip('\n')) + line = html_escape(line.rstrip('\n')) outfile.write('<a name="l%s" class="l%s" href="#l%s">' % (i, i, i)) outfile.write(line.rstrip('\n')) outfile.write("</a>\n") diff --git a/roles/htmlify-logs/library/test-fixtures/reference/job-output.txt b/roles/htmlify-logs/library/test-fixtures/reference-cgi/job-output.txt similarity index 100% rename from roles/htmlify-logs/library/test-fixtures/reference/job-output.txt rename to roles/htmlify-logs/library/test-fixtures/reference-cgi/job-output.txt diff --git a/roles/htmlify-logs/library/test-fixtures/reference-html/job-output.txt b/roles/htmlify-logs/library/test-fixtures/reference-html/job-output.txt new file mode 100644 index 000000000..3f3d4e995 --- /dev/null +++ b/roles/htmlify-logs/library/test-fixtures/reference-html/job-output.txt @@ -0,0 +1,112 @@ +<html> +<head> +<style> +a {color: #000; text-decoration: none} +a:hover {text-decoration: underline} +#selector, #selector a {color: #888} +#selector a:hover {color: #c00} +.highlight { + background-color: rgb(255, 255, 204); +} +</style> +</head> +<body> +<pre> +<a name="l1" class="l1" href="#l1">2018-08-01 00:43:51.328884 | Job console starting...</a> +<a name="l2" class="l2" href="#l2">2018-08-01 00:44:01.742989 | PRE-RUN START: [trusted : opendev.org/openstack/project-config/playbooks/base/pre.yaml@master]</a> +<a name="l3" class="l3" href="#l3">2018-08-01 00:44:04.693529 | </a> +<a name="l4" class="l4" href="#l4">2018-08-01 00:44:04.693765 | PLAY [localhost]</a> +<a name="l5" class="l5" href="#l5">2018-08-01 00:44:04.736664 | </a> +<a name="l6" class="l6" href="#l6">2018-08-01 00:44:04.736863 | TASK [emit-job-header : Setup log path fact]</a> +<a name="l7" class="l7" href="#l7">2018-08-01 00:44:04.804077 | localhost | ok</a> +<a name="l8" class="l8" href="#l8">2018-08-01 00:44:04.870027 | </a> +<a name="l9" class="l9" href="#l9">2018-08-01 00:44:04.870264 | TASK [set-zuul-log-path-fact : Set log path for a change]</a> +<a name="l10" class="l10" href="#l10">2018-08-01 00:44:04.942854 | localhost | skipping: Conditional result was False</a> +<a name="l11" class="l11" href="#l11">2018-08-01 00:44:04.970178 | </a> +<a name="l12" class="l12" href="#l12">2018-08-01 00:44:04.970405 | TASK [set-zuul-log-path-fact : Set log path for a ref update]</a> +<a name="l13" class="l13" href="#l13">2018-08-01 00:44:05.067095 | localhost | ok</a> +<a name="l14" class="l14" href="#l14">2018-08-01 00:44:05.094186 | </a> +<a name="l15" class="l15" href="#l15">2018-08-01 00:44:05.094430 | TASK [set-zuul-log-path-fact : Set log path for a periodic job]</a> +<a name="l16" class="l16" href="#l16">2018-08-01 00:44:05.152841 | localhost | skipping: Conditional result was False</a> +<a name="l17" class="l17" href="#l17">2018-08-01 00:44:05.188754 | </a> +<a name="l18" class="l18" href="#l18">2018-08-01 00:44:05.189030 | TASK [emit-job-header : Print job information]</a> +<a name="l19" class="l19" href="#l19">2018-08-01 00:44:05.317656 | # Job Information</a> +<a name="l20" class="l20" href="#l20">2018-08-01 00:44:05.318162 | Ansible Version: 2.5.7</a> +<a name="l21" class="l21" href="#l21">2018-08-01 00:44:05.318269 | Job: trigger-readthedocs-webhook</a> +<a name="l22" class="l22" href="#l22">2018-08-01 00:44:05.318371 | Pipeline: post</a> +<a name="l23" class="l23" href="#l23">2018-08-01 00:44:05.318469 | Executor: ze09.openstack.org</a> +<a name="l24" class="l24" href="#l24">2018-08-01 00:44:05.318567 | Triggered by: https://opendev.org/x/gerrit-dash-creator/commit/ee5167a518de07c325f326df212c92e5c1e786a9</a> +<a name="l25" class="l25" href="#l25">2018-08-01 00:44:05.318663 | Log URL (when completed): http://logs.openstack.org/ee/ee5167a518de07c325f326df212c92e5c1e786a9/post/trigger-readthedocs-webhook/f677f03</a> +<a name="l26" class="l26" href="#l26">2018-08-01 00:44:05.349043 | </a> +<a name="l27" class="l27" href="#l27">2018-08-01 00:44:05.349250 | PLAY [all]</a> +<a name="l28" class="l28" href="#l28">2018-08-01 00:44:05.385083 | </a> +<a name="l29" class="l29" href="#l29">2018-08-01 00:44:05.385308 | TASK [Gather network facts]</a> +<a name="l30" class="l30" href="#l30">2018-08-01 00:44:07.104842 | ubuntu-xenial | ok</a> +<a name="l31" class="l31" href="#l31">2018-08-01 00:44:07.167964 | </a> +<a name="l32" class="l32" href="#l32">2018-08-01 00:44:07.168193 | TASK [add-build-sshkey : Check to see if ssh key was already created for this build]</a> +<a name="l33" class="l33" href="#l33">2018-08-01 00:44:07.760495 | ubuntu-xenial -> localhost | ok</a> +<a name="l34" class="l34" href="#l34">2018-08-01 00:44:07.799900 | </a> +<a name="l35" class="l35" href="#l35">2018-08-01 00:44:07.800163 | TASK [add-build-sshkey : Create Temp SSH key]</a> +<a name="l36" class="l36" href="#l36">2018-08-01 00:44:08.445211 | ubuntu-xenial -> localhost | Generating public/private rsa key pair.</a> +<a name="l37" class="l37" href="#l37">2018-08-01 00:44:08.445859 | ubuntu-xenial -> localhost | Your identification has been saved in /var/lib/zuul/builds/f677f0312811438a8db3fa38953649c7/work/f677f0312811438a8db3fa38953649c7_id_rsa.</a> +<a name="l38" class="l38" href="#l38">2018-08-01 00:44:08.445989 | ubuntu-xenial -> localhost | Your public key has been saved in /var/lib/zuul/builds/f677f0312811438a8db3fa38953649c7/work/f677f0312811438a8db3fa38953649c7_id_rsa.pub.</a> +<a name="l39" class="l39" href="#l39">2018-08-01 00:44:08.446099 | ubuntu-xenial -> localhost | The key fingerprint is:</a> +<a name="l40" class="l40" href="#l40">2018-08-01 00:44:08.446205 | ubuntu-xenial -> localhost | SHA256:ZNugwiDo1mjkhNQt/GnNoH3XQgo+uU/jA8NtHUKCPiY zuul@ze09</a> +<a name="l41" class="l41" href="#l41">2018-08-01 00:44:08.446320 | ubuntu-xenial -> localhost | The key's randomart image is:</a> +<a name="l42" class="l42" href="#l42">2018-08-01 00:44:08.446424 | ubuntu-xenial -> localhost | +---[RSA 1024]----+</a> +<a name="l43" class="l43" href="#l43">2018-08-01 00:44:08.446527 | ubuntu-xenial -> localhost | | .o o |</a> +<a name="l44" class="l44" href="#l44">2018-08-01 00:44:08.446630 | ubuntu-xenial -> localhost | |+ = = . . |</a> +<a name="l45" class="l45" href="#l45">2018-08-01 00:44:08.446732 | ubuntu-xenial -> localhost | |+oo * X * . |</a> +<a name="l46" class="l46" href="#l46">2018-08-01 00:44:08.446834 | ubuntu-xenial -> localhost | |=EoB O X B . |</a> +<a name="l47" class="l47" href="#l47">2018-08-01 00:44:08.446936 | ubuntu-xenial -> localhost | | *o.* * S + |</a> +<a name="l48" class="l48" href="#l48">2018-08-01 00:44:08.447037 | ubuntu-xenial -> localhost | |o * = . |</a> +<a name="l49" class="l49" href="#l49">2018-08-01 00:44:08.447138 | ubuntu-xenial -> localhost | | B . |</a> +<a name="l50" class="l50" href="#l50">2018-08-01 00:44:08.447239 | ubuntu-xenial -> localhost | | + |</a> +<a name="l51" class="l51" href="#l51">2018-08-01 00:44:08.447339 | ubuntu-xenial -> localhost | | . |</a> +<a name="l52" class="l52" href="#l52">2018-08-01 00:44:08.447440 | ubuntu-xenial -> localhost | +----[SHA256]-----+</a> +<a name="l53" class="l53" href="#l53">2018-08-01 00:44:08.447643 | ubuntu-xenial -> localhost | ok: Runtime: 0:00:00.022230</a> +<a name="l54" class="l54" href="#l54">here is a line with some <escapes></a> +</pre> +</body> +<script> +var old_highlight; + +function remove_highlight() { + if (old_highlight) { + items = document.getElementsByClassName(old_highlight); + for (var i = 0; i < items.length; i++) { + items[i].className = items[i].className.replace('highlight',''); + } + } +} + +function update_selector(highlight) { + var selector = document.getElementById('selector'); + if (selector) { + var links = selector.getElementsByTagName('a'); + for (var i = 0; i < links.length; i++) { + links[i].hash = "#" + highlight; + } + } +} + +function highlight_by_hash(event) { + var highlight = window.location.hash.substr(1); + // handle changes to highlighting separate from reload + if (event) { + highlight = event.target.hash.substr(1); + } + remove_highlight(); + if (highlight) { + elements = document.getElementsByClassName(highlight); + for (var i = 0; i < elements.length; i++) { + elements[i].className += " highlight"; + } + update_selector(highlight); + old_highlight = highlight; + } +} +document.onclick = highlight_by_hash; +highlight_by_hash(); +</script> +</html> diff --git a/roles/htmlify-logs/library/test_htmlify.py b/roles/htmlify-logs/library/test_htmlify.py index 16aef34cf..d58a53399 100644 --- a/roles/htmlify-logs/library/test_htmlify.py +++ b/roles/htmlify-logs/library/test_htmlify.py @@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import cgi import gzip import os @@ -30,7 +31,10 @@ class TestHTMLify(testtools.TestCase): def _test_file(self, fn, ref_fn): in_path = os.path.join(FIXTURE_DIR, 'in', fn) - ref_path = os.path.join(FIXTURE_DIR, 'reference', ref_fn) + if getattr(cgi, 'escape', None): + ref_path = os.path.join(FIXTURE_DIR, 'reference-cgi', ref_fn) + else: + ref_path = os.path.join(FIXTURE_DIR, 'reference-html', ref_fn) out_root = self.useFixture(fixtures.TempDir()).path out_path = os.path.join(out_root, fn) run(in_path, out_path) diff --git a/tox.ini b/tox.ini index 1bbbd9dc1..acda17e30 100644 --- a/tox.ini +++ b/tox.ini @@ -2,6 +2,7 @@ minversion = 1.6 skipsdist = True envlist = linters +ignore_basepython_conflict = True [testenv] basepython = python3