scripts/analyse-9p-simpletrace.py | 89 ++++++++++++++++---------------- scripts/analyse-locks-simpletrace.py | 3 +- scripts/analyze-migration.py | 11 ++-- scripts/dump-guest-memory.py | 1 + scripts/ordereddict.py | 4 +- scripts/replay-dump.py | 21 ++++---- scripts/signrom.py | 1 + scripts/simpletrace.py | 5 +- scripts/vmstate-static-checker.py | 89 ++++++++++++++++---------------- scripts/device-crash-test | 3 +- scripts/kvm/kvm_flightrecorder | 21 ++++---- scripts/kvm/vmxcap | 1 + scripts/qmp/qemu-ga-client | 10 ++-- scripts/qmp/qmp | 24 +++++---- scripts/qmp/qmp-shell | 40 +++++++------- scripts/qmp/qom-fuse | 11 ++-- scripts/qmp/qom-get | 12 +++-- scripts/qmp/qom-list | 16 +++--- scripts/qmp/qom-set | 10 ++-- scripts/qmp/qom-tree | 16 +++--- tests/docker/docker.py | 11 ++-- tests/docker/travis.py | 15 +++--- tests/guest-debug/test-gdbstub.py | 1 + tests/image-fuzzer/qcow2/__init__.py | 3 +- tests/image-fuzzer/qcow2/fuzz.py | 1 + tests/image-fuzzer/qcow2/layout.py | 3 +- tests/image-fuzzer/runner.py | 42 +++++++-------- tests/migration/guestperf/engine.py | 29 ++++++----- tests/migration/guestperf/plot.py | 17 +++--- tests/migration/guestperf/shell.py | 19 +++---- tests/qemu-iotests/093 | 2 +- tests/qemu-iotests/096 | 4 +- tests/qemu-iotests/118 | 24 ++++----- tests/qemu-iotests/136 | 2 +- tests/qemu-iotests/149 | 3 +- tests/qemu-iotests/165 | 3 +- tests/qemu-iotests/iotests.py | 5 +- tests/qemu-iotests/nbd-fault-injector.py | 7 +-- tests/qemu-iotests/qcow2.py | 39 +++++++------- tests/qemu-iotests/qed.py | 17 +++--- tests/vm/basevm.py | 3 +- 41 files changed, 337 insertions(+), 301 deletions(-)
TESTING NEEDED: Due to the amount of changes, I didn't test all scripts touched by this series. If you are responsible for any of the touched files, I would appreciate help on testing the series. From the futurize[1] documentation: > This applies fixes that modernize Python 2 code without > changing the effect of the code. With luck, this will not > introduce any bugs into the code, or will at least be trivial > to fix. The changes are those that bring the Python code > up-to-date without breaking Py2 compatibility. The resulting > code will be modern Python 2.6-compatible code plus __future__ > imports from the following set: > > from __future__ import absolute_import > from __future__ import division > from __future__ import print_function > [...] > The goal for this stage is to create most of the diff for the > entire porting process, but without introducing any bugs. It > should be uncontroversial and safe to apply to every Python 2 > package. The subsequent patches introducing Python 3 > compatibility should then be shorter and easier to review. This series run all the fixers from futurize --stage1 on all Python code in the tree. To make review and testing easier, I have run the fixers separately instead of doing all changes in a single patch. [1] http://python-future.org/automatic_conversion.html Eduardo Habkost (10): python: futurize -f libfuturize.fixes.fix_print_with_import python: futurize -f libfuturize.fixes.fix_absolute_import python: futurize -f libfuturize.fixes.fix_next_call python: futurize -f lib2to3.fixes.fix_has_key python: futurize -f lib2to3.fixes.fix_standarderror python: futurize -f lib2to3.fixes.fix_reduce python: futurize -f lib2to3.fixes.fix_tuple_params python: futurize -f lib2to3.fixes.fix_renames python: futurize -f lib2to3.fixes.fix_except python: futurize -f lib2to3.fixes.fix_numliterals scripts/analyse-9p-simpletrace.py | 89 ++++++++++++++++---------------- scripts/analyse-locks-simpletrace.py | 3 +- scripts/analyze-migration.py | 11 ++-- scripts/dump-guest-memory.py | 1 + scripts/ordereddict.py | 4 +- scripts/replay-dump.py | 21 ++++---- scripts/signrom.py | 1 + scripts/simpletrace.py | 5 +- scripts/vmstate-static-checker.py | 89 ++++++++++++++++---------------- scripts/device-crash-test | 3 +- scripts/kvm/kvm_flightrecorder | 21 ++++---- scripts/kvm/vmxcap | 1 + scripts/qmp/qemu-ga-client | 10 ++-- scripts/qmp/qmp | 24 +++++---- scripts/qmp/qmp-shell | 40 +++++++------- scripts/qmp/qom-fuse | 11 ++-- scripts/qmp/qom-get | 12 +++-- scripts/qmp/qom-list | 16 +++--- scripts/qmp/qom-set | 10 ++-- scripts/qmp/qom-tree | 16 +++--- tests/docker/docker.py | 11 ++-- tests/docker/travis.py | 15 +++--- tests/guest-debug/test-gdbstub.py | 1 + tests/image-fuzzer/qcow2/__init__.py | 3 +- tests/image-fuzzer/qcow2/fuzz.py | 1 + tests/image-fuzzer/qcow2/layout.py | 3 +- tests/image-fuzzer/runner.py | 42 +++++++-------- tests/migration/guestperf/engine.py | 29 ++++++----- tests/migration/guestperf/plot.py | 17 +++--- tests/migration/guestperf/shell.py | 19 +++---- tests/qemu-iotests/093 | 2 +- tests/qemu-iotests/096 | 4 +- tests/qemu-iotests/118 | 24 ++++----- tests/qemu-iotests/136 | 2 +- tests/qemu-iotests/149 | 3 +- tests/qemu-iotests/165 | 3 +- tests/qemu-iotests/iotests.py | 5 +- tests/qemu-iotests/nbd-fault-injector.py | 7 +-- tests/qemu-iotests/qcow2.py | 39 +++++++------- tests/qemu-iotests/qed.py | 17 +++--- tests/vm/basevm.py | 3 +- 41 files changed, 337 insertions(+), 301 deletions(-) -- 2.14.3
Hi,
This series seems to have some coding style problems. See output below for
more information:
Type: series
Message-id: 20180511222052.8734-1-ehabkost@redhat.com
Subject: [Qemu-devel] [RFC 00/10] [TESTING NEEDED] python: futurize --stage1 (Python 3 compatibility)
=== TEST SCRIPT BEGIN ===
#!/bin/bash
BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done
exit $failed
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
t [tag update] patchew/20180510204148.11687-1-babu.moger@amd.com -> patchew/20180510204148.11687-1-babu.moger@amd.com
* [new tag] patchew/20180511222052.8734-1-ehabkost@redhat.com -> patchew/20180511222052.8734-1-ehabkost@redhat.com
Switched to a new branch 'test'
29e77f7e45 python: futurize -f lib2to3.fixes.fix_numliterals
06044c1048 python: futurize -f lib2to3.fixes.fix_except
aecdedee26 python: futurize -f lib2to3.fixes.fix_renames
2be7292f53 python: futurize -f lib2to3.fixes.fix_tuple_params
0b3e5f083c python: futurize -f lib2to3.fixes.fix_reduce
6d7a39f3c6 python: futurize -f lib2to3.fixes.fix_standarderror
0c8beeea09 python: futurize -f lib2to3.fixes.fix_has_key
4f0075d69d python: futurize -f libfuturize.fixes.fix_next_call
66698bae73 python: futurize -f libfuturize.fixes.fix_absolute_import
b48c4f449d python: futurize -f libfuturize.fixes.fix_print_with_import
=== OUTPUT BEGIN ===
Checking PATCH 1/10: python: futurize -f libfuturize.fixes.fix_print_with_import...
ERROR: line over 90 characters
#40: FILE: scripts/analyse-9p-simpletrace.py:86:
+ print("RERROR (tag =", tag, ", id =", symbol_9p[id], ", err = \"", os.strerror(err), "\")")
ERROR: line over 90 characters
#44: FILE: scripts/analyse-9p-simpletrace.py:89:
+ print("TVERSION (tag =", tag, ", msize =", msize, ", version =", version, ")")
ERROR: line over 90 characters
#48: FILE: scripts/analyse-9p-simpletrace.py:92:
+ print("RVERSION (tag =", tag, ", msize =", msize, ", version =", version, ")")
ERROR: line over 90 characters
#52: FILE: scripts/analyse-9p-simpletrace.py:95:
+ print("TATTACH (tag =", tag, ", fid =", fid, ", afid =", afid, ", uname =", uname, ", aname =", aname, ")")
ERROR: line over 90 characters
#56: FILE: scripts/analyse-9p-simpletrace.py:98:
+ print("RATTACH (tag =", tag, ", qid={type =", type, ", version =", version, ", path =", path, "})")
ERROR: line over 90 characters
#64: FILE: scripts/analyse-9p-simpletrace.py:104:
+ print("RSTAT (tag =", tag, ", mode =", mode, ", atime =", atime, ", mtime =", mtime, ", length =", length, ")")
ERROR: line over 90 characters
#68: FILE: scripts/analyse-9p-simpletrace.py:107:
+ print("TGETATTR (tag =", tag, ", fid =", fid, ", request_mask =", hex(request_mask), ")")
ERROR: line over 90 characters
#72: FILE: scripts/analyse-9p-simpletrace.py:110:
+ print("RGETATTR (tag =", tag, ", result_mask =", hex(result_mask), ", mode =", oct(mode), ", uid =", uid, ", gid =", gid, ")")
ERROR: line over 90 characters
#76: FILE: scripts/analyse-9p-simpletrace.py:113:
+ print("TWALK (tag =", tag, ", fid =", fid, ", newfid =", newfid, ", nwnames =", nwnames, ")")
ERROR: line over 90 characters
#80: FILE: scripts/analyse-9p-simpletrace.py:116:
+ print("RWALK (tag =", tag, ", nwnames =", nwnames, ", qids =", hex(qids), ")")
WARNING: line over 80 characters
#84: FILE: scripts/analyse-9p-simpletrace.py:119:
+ print("TOPEN (tag =", tag, ", fid =", fid, ", mode =", oct(mode), ")")
ERROR: line over 90 characters
#88: FILE: scripts/analyse-9p-simpletrace.py:122:
+ print("ROPEN (tag =", tag, ", qid={type =", type, ", version =", version, ", path =", path, "}, iounit =", iounit, ")")
ERROR: line over 90 characters
#92: FILE: scripts/analyse-9p-simpletrace.py:125:
+ print("TLCREATE (tag =", tag, ", dfid =", dfid, ", flags =", oct(flags), ", mode =", oct(mode), ", gid =", gid, ")")
ERROR: line over 90 characters
#96: FILE: scripts/analyse-9p-simpletrace.py:128:
+ print("RLCREATE (tag =", tag, ", qid={type =", type, ", version =", version, ", path =", path, "}, iounit =", iounit, ")")
WARNING: line over 80 characters
#100: FILE: scripts/analyse-9p-simpletrace.py:131:
+ print("TFSYNC (tag =", tag, ", fid =", fid, ", datasync =", datasync, ")")
ERROR: line over 90 characters
#108: FILE: scripts/analyse-9p-simpletrace.py:137:
+ print("TREAD (tag =", tag, ", fid =", fid, ", off =", off, ", max_count =", max_count, ")")
WARNING: line over 80 characters
#112: FILE: scripts/analyse-9p-simpletrace.py:140:
+ print("RREAD (tag =", tag, ", count =", count, ", err =", err, ")")
ERROR: line over 90 characters
#116: FILE: scripts/analyse-9p-simpletrace.py:143:
+ print("TREADDIR (tag =", tag, ", fid =", fid, ", offset =", offset, ", max_count =", max_count, ")")
ERROR: line over 90 characters
#120: FILE: scripts/analyse-9p-simpletrace.py:146:
+ print("RREADDIR (tag =", tag, ", count =", count, ", retval =", retval, ")")
ERROR: line over 90 characters
#124: FILE: scripts/analyse-9p-simpletrace.py:149:
+ print("TWRITE (tag =", tag, ", fid =", fid, ", off =", off, ", count =", count, ", cnt =", cnt, ")")
WARNING: line over 80 characters
#128: FILE: scripts/analyse-9p-simpletrace.py:152:
+ print("RWRITE (tag =", tag, ", total =", total, ", err =", err, ")")
ERROR: line over 90 characters
#132: FILE: scripts/analyse-9p-simpletrace.py:155:
+ print("TCREATE (tag =", tag, ", fid =", fid, ", perm =", oct(perm), ", name =", name, ", mode =", oct(mode), ")")
ERROR: line over 90 characters
#136: FILE: scripts/analyse-9p-simpletrace.py:158:
+ print("RCREATE (tag =", tag, ", qid={type =", type, ", version =", version, ", path =", path, "}, iounit =", iounit, ")")
ERROR: line over 90 characters
#140: FILE: scripts/analyse-9p-simpletrace.py:161:
+ print("TSYMLINK (tag =", tag, ", fid =", fid, ", name =", name, ", symname =", symname, ", gid =", gid, ")")
ERROR: line over 90 characters
#144: FILE: scripts/analyse-9p-simpletrace.py:164:
+ print("RSYMLINK (tag =", tag, ", qid={type =", type, ", version =", version, ", path =", path, "})")
ERROR: line over 90 characters
#152: FILE: scripts/analyse-9p-simpletrace.py:170:
+ print("TLINK (tag =", tag, ", dfid =", dfid, ", oldfid =", oldfid, ", name =", name, ")")
ERROR: line over 90 characters
#160: FILE: scripts/analyse-9p-simpletrace.py:176:
+ print("TWSTAT (tag =", tag, ", fid =", fid, ", mode =", oct(mode), ", atime =", atime, "mtime =", mtime, ")")
ERROR: line over 90 characters
#164: FILE: scripts/analyse-9p-simpletrace.py:179:
+ print("TMKNOD (tag =", tag, ", fid =", fid, ", mode =", oct(mode), ", major =", major, ", minor =", minor, ")")
ERROR: line over 90 characters
#168: FILE: scripts/analyse-9p-simpletrace.py:182:
+ print("TLOCK (tag =", tag, ", fid =", fid, "type =", type, ", start =", start, ", length =", length, ")")
ERROR: line over 90 characters
#176: FILE: scripts/analyse-9p-simpletrace.py:188:
+ print("TGETLOCK (tag =", tag, ", fid =", fid, "type =", type, ", start =", start, ", length =", length, ")")
ERROR: line over 90 characters
#180: FILE: scripts/analyse-9p-simpletrace.py:191:
+ print("RGETLOCK (tag =", tag, "type =", type, ", start =", start, ", length =", length, ", proc_id =", proc_id, ")")
ERROR: line over 90 characters
#184: FILE: scripts/analyse-9p-simpletrace.py:194:
+ print("TMKDIR (tag =", tag, ", fid =", fid, ", name =", name, ", mode =", mode, ", gid =", gid, ")")
ERROR: line over 90 characters
#188: FILE: scripts/analyse-9p-simpletrace.py:197:
+ print("RMKDIR (tag =", tag, ", qid={type =", type, ", version =", version, ", path =", path, "}, err =", err, ")")
ERROR: line over 90 characters
#192: FILE: scripts/analyse-9p-simpletrace.py:200:
+ print("TXATTRWALK (tag =", tag, ", fid =", fid, ", newfid =", newfid, ", xattr name =", name, ")")
ERROR: line over 90 characters
#200: FILE: scripts/analyse-9p-simpletrace.py:206:
+ print("TXATTRCREATE (tag =", tag, ", fid =", fid, ", name =", name, ", xattrsize =", size, ", flags =", flags, ")")
WARNING: line over 80 characters
#843: FILE: scripts/vmstate-static-checker.py:182:
+ print("expected field \"" + s_item["field"] + "\",", end=' ')
WARNING: line over 80 characters
#899: FILE: scripts/vmstate-static-checker.py:293:
+ print("Section \"" + sec + "\", Description \"" + desc + "\":", end=' ')
WARNING: line over 80 characters
#1007: FILE: scripts/vmstate-static-checker.py:419:
+ print("Section \"" + sec + "\": Entry \"" + entry + "\"", end=' ')
WARNING: line over 80 characters
#1127: FILE: tests/image-fuzzer/runner.py:41:
+ "'--config' and '--command' options are not supported.", file=sys.stderr)
WARNING: line over 80 characters
#1138: FILE: tests/image-fuzzer/runner.py:161:
+ print("Error: The working directory '%s' cannot be used. Reason: %s"\
ERROR: line over 90 characters
#1167: FILE: tests/image-fuzzer/runner.py:359:
+ print("Error: %s\n\nTry 'runner.py --help' for more information" % e, file=sys.stderr)
WARNING: line over 80 characters
#1229: FILE: tests/migration/guestperf/engine.py:121:
+ print("Sleeping %d seconds for initial guest workload run" % self._sleep)
ERROR: line over 90 characters
#1247: FILE: tests/migration/guestperf/engine.py:220:
+ print("Sleeping %d seconds for final guest workload run" % self._sleep)
WARNING: line over 80 characters
#1256: FILE: tests/migration/guestperf/engine.py:231:
+ print("Iter %d: remain %5dMB of %5dMB (total %5dMB @ %5dMb/sec)" % (
ERROR: line over 90 characters
#1268: FILE: tests/migration/guestperf/engine.py:241:
+ print("No completion after %d iterations over RAM" % scenario._max_iters)
ERROR: line over 90 characters
#1284: FILE: tests/migration/guestperf/engine.py:255:
+ print("Switching to post-copy after %d iterations" % scenario._post_copy_iters)
WARNING: line over 80 characters
#1293: FILE: tests/migration/guestperf/engine.py:263:
+ print("Pausing VM after %d iterations" % scenario._pause_iters)
ERROR: line over 90 characters
#1651: FILE: tests/qemu-iotests/qcow2.py:226:
+ print("'%s' is not a valid group, try 'incompatible', 'compatible', or 'autoclear'" % group)
total: 36 errors, 12 warnings, 1481 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 2/10: python: futurize -f libfuturize.fixes.fix_absolute_import...
Checking PATCH 3/10: python: futurize -f libfuturize.fixes.fix_next_call...
Checking PATCH 4/10: python: futurize -f lib2to3.fixes.fix_has_key...
Checking PATCH 5/10: python: futurize -f lib2to3.fixes.fix_standarderror...
Checking PATCH 6/10: python: futurize -f lib2to3.fixes.fix_reduce...
Checking PATCH 7/10: python: futurize -f lib2to3.fixes.fix_tuple_params...
Checking PATCH 8/10: python: futurize -f lib2to3.fixes.fix_renames...
Checking PATCH 9/10: python: futurize -f lib2to3.fixes.fix_except...
Checking PATCH 10/10: python: futurize -f lib2to3.fixes.fix_numliterals...
=== OUTPUT END ===
Test command exited with code: 1
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
On Fri, 05/11 19:20, Eduardo Habkost wrote: > TESTING NEEDED: Due to the amount of changes, I didn't test all > scripts touched by this series. If you are responsible for any > of the touched files, I would appreciate help on testing the > series. The tests/docker and tests/vm changes look good to me: Acked-by: Fam Zheng <famz@redhat.com>
On 2018-05-12 00:20, Eduardo Habkost wrote: > TESTING NEEDED: Due to the amount of changes, I didn't test all > scripts touched by this series. If you are responsible for any > of the touched files, I would appreciate help on testing the > series. All the iotests* still pass, so for my part: Tested-by: Max Reitz <mreitz@redhat.com> *That is, the ones I run, which includes all Python tests but 149.
* Eduardo Habkost (ehabkost@redhat.com) wrote: > TESTING NEEDED: Due to the amount of changes, I didn't test all > scripts touched by this series. If you are responsible for any > of the touched files, I would appreciate help on testing the > series. Running the 'analyze-migration.py' script on a simple machine gives the same output before and after. Also running vmstate-static-checker.py gives the same output when run between my system's qemu and my current head. Dave > From the futurize[1] documentation: > > > This applies fixes that modernize Python 2 code without > > changing the effect of the code. With luck, this will not > > introduce any bugs into the code, or will at least be trivial > > to fix. The changes are those that bring the Python code > > up-to-date without breaking Py2 compatibility. The resulting > > code will be modern Python 2.6-compatible code plus __future__ > > imports from the following set: > > > > from __future__ import absolute_import > > from __future__ import division > > from __future__ import print_function > > > [...] > > The goal for this stage is to create most of the diff for the > > entire porting process, but without introducing any bugs. It > > should be uncontroversial and safe to apply to every Python 2 > > package. The subsequent patches introducing Python 3 > > compatibility should then be shorter and easier to review. > > This series run all the fixers from futurize --stage1 on all > Python code in the tree. To make review and testing easier, I > have run the fixers separately instead of doing all changes in a > single patch. > > [1] http://python-future.org/automatic_conversion.html > > Eduardo Habkost (10): > python: futurize -f libfuturize.fixes.fix_print_with_import > python: futurize -f libfuturize.fixes.fix_absolute_import > python: futurize -f libfuturize.fixes.fix_next_call > python: futurize -f lib2to3.fixes.fix_has_key > python: futurize -f lib2to3.fixes.fix_standarderror > python: futurize -f lib2to3.fixes.fix_reduce > python: futurize -f lib2to3.fixes.fix_tuple_params > python: futurize -f lib2to3.fixes.fix_renames > python: futurize -f lib2to3.fixes.fix_except > python: futurize -f lib2to3.fixes.fix_numliterals > > scripts/analyse-9p-simpletrace.py | 89 ++++++++++++++++---------------- > scripts/analyse-locks-simpletrace.py | 3 +- > scripts/analyze-migration.py | 11 ++-- > scripts/dump-guest-memory.py | 1 + > scripts/ordereddict.py | 4 +- > scripts/replay-dump.py | 21 ++++---- > scripts/signrom.py | 1 + > scripts/simpletrace.py | 5 +- > scripts/vmstate-static-checker.py | 89 ++++++++++++++++---------------- > scripts/device-crash-test | 3 +- > scripts/kvm/kvm_flightrecorder | 21 ++++---- > scripts/kvm/vmxcap | 1 + > scripts/qmp/qemu-ga-client | 10 ++-- > scripts/qmp/qmp | 24 +++++---- > scripts/qmp/qmp-shell | 40 +++++++------- > scripts/qmp/qom-fuse | 11 ++-- > scripts/qmp/qom-get | 12 +++-- > scripts/qmp/qom-list | 16 +++--- > scripts/qmp/qom-set | 10 ++-- > scripts/qmp/qom-tree | 16 +++--- > tests/docker/docker.py | 11 ++-- > tests/docker/travis.py | 15 +++--- > tests/guest-debug/test-gdbstub.py | 1 + > tests/image-fuzzer/qcow2/__init__.py | 3 +- > tests/image-fuzzer/qcow2/fuzz.py | 1 + > tests/image-fuzzer/qcow2/layout.py | 3 +- > tests/image-fuzzer/runner.py | 42 +++++++-------- > tests/migration/guestperf/engine.py | 29 ++++++----- > tests/migration/guestperf/plot.py | 17 +++--- > tests/migration/guestperf/shell.py | 19 +++---- > tests/qemu-iotests/093 | 2 +- > tests/qemu-iotests/096 | 4 +- > tests/qemu-iotests/118 | 24 ++++----- > tests/qemu-iotests/136 | 2 +- > tests/qemu-iotests/149 | 3 +- > tests/qemu-iotests/165 | 3 +- > tests/qemu-iotests/iotests.py | 5 +- > tests/qemu-iotests/nbd-fault-injector.py | 7 +-- > tests/qemu-iotests/qcow2.py | 39 +++++++------- > tests/qemu-iotests/qed.py | 17 +++--- > tests/vm/basevm.py | 3 +- > 41 files changed, 337 insertions(+), 301 deletions(-) > > -- > 2.14.3 > -- Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
© 2016 - 2026 Red Hat, Inc.