* Update swift from branch 'master'
to 5ba1fbf86b961915b09f89ef4a2a437cf8d4df5c
- Merge "proxy_logging: unit test first-byte.timing metrics"
- proxy_logging: unit test first-byte.timing metrics
Add some test assertions to cover the first-byte timing metrics
introduced in the related change.
Add ttfb param to log_request docstring.
Change-Id: I530652dd672d7d4e5eac351ccbad318773414f7d
Related-Change: I1611e34846e586703e9d3709fa64e8df41f2d685
* Update swift from branch 'master'
to 22c4c9ba1cdb525f2f9c291fc1541d36cd6e3eb7
- Merge "proxy-logging: emit stats more consistently"
- proxy-logging: emit stats more consistently
Change-Id: I526bbcc59c9eb5923c3784d5d06bc38998cb48db
* Update swift from branch 'master'
to dcf9c7ef5453e09cc586bdff03aca19f3427106f
- Merge "test: assert behavior of proxy_logging metrics"
- test: assert behavior of proxy_logging metrics
Change-Id: I651ddd40e9115a56727096d4a3aa84589146308f
* Update swift from branch 'master'
to 6387949a540e871e19062de8131503a8ac2ceef7
- lower-constraints: update to mock 3.0
The main motivation here is that mock.call becomes a namedtuple and you
can say `m.call_args_list[0].args` instead of `m.call_args_list[0][0]`
Change-Id: Ibb1a64ef0bfdebf06d26636cdb6ea191c10705f7
* Update swift from branch 'master'
to 0e5aeb50457345801ad70aed0c367e1f9820e113
- Merge "s3api: Fix handling of non-ascii access keys"
- s3api: Fix handling of non-ascii access keys
We stuff the access key into the request path until we get back a
more-authoritative account name from auth. But it needs to be a WSGI
string when we do!
Closes-Bug: #2058748
Change-Id: I34adb8141cc9e62d17a27f01c63f40d1dd25991c
* Update swift from branch 'master'
to cdc4f264d28df3039e9350b40b59086677f7bbc1
- Merge "recon-cron: Tolerate missing directories"
- recon-cron: Tolerate missing directories
Any of these directories may get unlinked between when we saw them in
their parent's directory listing and when we go to descend.
Change-Id: I1dfc0ee1d9e70cb0600557cde980bd5880bd40b3
* Update swift from branch 'master'
to 537b6885e37cb1830992f8586400fe6f8d7f2345
- Merge "Update master for stable/2024.1"
- Update master for stable/2024.1
Add file to the reno documentation build to show release notes for
stable/2024.1.
Use pbr instruction to increment the minor version number
automatically so that master versions are higher than the versions on
stable/2024.1.
Sem-Ver: feature
Change-Id: Ic940ff424aef9cc402bf54ebe5e5fc16330fc25c
* Update swift from branch 'master'
to d3938c35471f12bc7f625c2bbbe44e980d30b25a
- Merge "CI: Move probe tests to centos 9 stream"
- CI: Move probe tests to centos 9 stream
Pin selenium to 3.x for now, until we can run down the issues with 4.x
Change-Id: I596415d17f77f48a6e8a63a61b734a8ca0865847
* Update swift from branch 'master'
to fd3997f027eeadc9a7783a1cc26372e28e644ff8
- Merge "tests: Update CORS geckodriver"
- tests: Update CORS geckodriver
Change-Id: I5ab762dfe0f85e346c4868ec4540884ba5f0a7f4
* Update swift from branch 'master'
to 27ef11ea14240d8611dd1cbadaf8412727c85f49
- test: implement cache expiration time in MockMemcached
Change-Id: I16ec414f87ac1a5e1e87e7560290c5ef0ca4f7cf
* Update swift from branch 'master'
to b6dc24dbc0eca46141544dcdaabe7cdc281c9ce7
- Merge "s3api test for zero byte mpu"
- s3api test for zero byte mpu
Change-Id: I89050cead3ef2d5f8ebfc9cb58f736f33b1c44fe
* Update swift from branch 'master'
to 891d06345e337189fdbb213fc91528a20e3f4c23
- Merge "s3api: Support GET/HEAD request with ?partNumber"
- s3api: Support GET/HEAD request with ?partNumber
Co-Authored-By: Alistair Coles <alistairncoles@gmail.com>
Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>
Closes-Bug: #1735284
Change-Id: Ib396309c706fbc6bc419377fe23fcf5603a89f45
* Update swift from branch 'master'
to 60db1f847c7c10bb56202935043468057725968d
- Merge "slo: part-number=N query parameter support"
- slo: part-number=N query parameter support
This change allows individual SLO segments to be downloaded by adding
an extra 'part-number' query parameter to the GET request. You can
also retrieve the Content-Length of an individual segment with a HEAD
request.
Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>
Co-Authored-By: Alistair Coles <alistairncoles@gmail.com>
Change-Id: I7af0dc9898ca35f042b52dd5db000072f2c7512e
* Update swift from branch 'master'
to 5f95b6b26db1c86dd9c5276c4124dd80041df75f
- AUTHORS/CHANGELOG for 2.33.0
Change-Id: I6b0a074fca4d6bd3b8b95888ae8721a62f3a6df0
* Update swift from branch 'master'
to 7941cf0efcef6e9147304b7d071ba3c31ec3ec8d
- Merge "CI: Bring unit test jobs in line with 2024.1 tested runtimes"
- CI: Bring unit test jobs in line with 2024.1 tested runtimes
The last time I really looked at this was probably Yoga, when we were
targetting 3.6 through 3.9 (and left 3.7 and 3.8 as experimental jobs).
Now, though, OpenStack is targetting 3.8 through 3.11; as before, we
can assume that if tests pass on those two versions, they should pass
on the versions in-between, too. (But still have them as experimental,
on-demand jobs).
See https://governance.openstack.org/tc/reference/runtimes/2024.1.html
Keep 2.7 and 3.6 testing as our own self-imposed minimums.
Change-Id: I7700aa3c93df311644655e7ebaf0b67aa692ee80
* Update swift from branch 'master'
to 2c4ff7bf2cbe09d1722257fc67eef638345ea0e5
- Merge "CI: Update rolling-upgrade jobs to point to unmaintained branches"
- CI: Update rolling-upgrade jobs to point to unmaintained branches
Change-Id: I936d9074ab60e34b379fb207d63f10bd5c3a4312
* Update swift from branch 'master'
to b6f59714719283a7933b886d3e8ec5c82222dd75
- Merge "reno: Update master for unmaintained/wallaby"
- reno: Update master for unmaintained/wallaby
Update the wallaby release notes configuration to build from
unmaintained/wallaby.
Change-Id: Ieb2d4542d395bb1f4498beab0d9ec146fad7ba84
* Update swift from branch 'master'
to e951a42788c0157dbbd4dc886f95d782df05f4d4
- Merge "reno: Update master for unmaintained/victoria"
- reno: Update master for unmaintained/victoria
Update the victoria release notes configuration to build from
unmaintained/victoria.
Change-Id: I5a420de74a2ef5096135511dfea2489419414856
* Update swift from branch 'master'
to dc379af8936e043a01bd11e7fa3d24df03037a61
- reno: Update master for unmaintained/xena
Update the xena release notes configuration to build from
unmaintained/xena.
Change-Id: I72576af46cc13fac0a7a69461b673931c8b8496e
* Update swift from branch 'master'
to 6a426f7fa08014f6d4b6b04f5e51c8870f77eeaf
- sharder: Add periodic_warnings_interval to example config
Change-Id: Ie3c64646373580b70557f2720a13a5a0c5ef7097
* Update swift from branch 'master'
to 0f6ecb641b2aca99b8bcc48d8e855d22132780b0
- Merge "docs: add discussion of content-type metadata"
- docs: add discussion of content-type metadata
Change-Id: I2aa13e2b23bda86c51ef6aaa69ea3fd0075bb9ad
* Update swift from branch 'master'
to 4135133a63eb8dea52601593765dd853bbea30a0
- memcachering: change failed to yield log message
Currently when the memcachering `_get_conns` method runs out of memcached
servers to try and so fails to yield anything we log a:
All memcached servers error-limited
However, this error message isn't entirely accurate. It can also fail
because it failed to connect all it's memcached servers not just because
they're error limited.
You can disable error-limiting of memcached servers. So in this case
this error message is a red-herring.
Downstream we use a mcrouter client on each node which itself talks to a
bunch of memcache servers. Therefore in swift's memcachering client we
only configure the 1 mcrouter client as a single server in the ring.
Because of this we disable memcached error-limiting.
If the node gets too overloaded we've had timeouts talking to the local
mcrouter client. This fires off error-limitted log messages which can
confuse things.
Because it's possible to turn off error-limiting, the log line isn't
quite adequate anymore. So this patch changes it to:
No more memcached servers to try
Change-Id: I97fb4f3ee2ac45831aae14a782b2c6dc73e82d85
* Update swift from branch 'master'
to 627448362abc1f83d9385165de232f47545f18e7
- Merge "CI: Remove centos-7 jobs"
- CI: Remove centos-7 jobs
CentOS 7 will go EOL later this year, and infra wants to drop the nodes
soon-ish -- don't make them wait on our account.
The only major loss is py2 probe tests, but officially, yoga was the
last release we pledged to support py2.
Change-Id: I8f6c247c21f16aa4717569cc69308f846c6a0245
* Update swift from branch 'master'
to dd066946a1543cc9e377475281a1c0a4f9563f59
- Merge "CI: fix rolling-upgrade jobs"
- CI: fix rolling-upgrade jobs
train and ussuri are now EOL; drop them.
yoga has moved from stable to unmaintained.
Change-Id: I3516823fdacbe8fd3c2434c0de9dedd1d82980fe
* Update swift from branch 'master'
to 6cc5262bb7a0099494f7cb0db6328bf1c984abc3
- Merge "CI: pin python-dateutil for py2"
- CI: pin python-dateutil for py2
Their 2.9.0 release is known-broken for py27-py35.
Change-Id: I40c1724fa673ac252f5052ac85006788ba69d5c7
* Update swift from branch 'master'
to 3478803a95dd139223dcb943370b570832ceeb8c
- Merge "zero bytes manifests are not legacy"
- zero bytes manifests are not legacy
Change-Id: I7c8adb129b8770eee501748a378f3adc42c8cd39
* Update swift from branch 'master'
to e9cf2a31aad877e14df428d360a67e00be4019d0
- Merge "tests: Clear txn id on init for all debug loggers"
- tests: Clear txn id on init for all debug loggers
Since we fake out all the greenthread stuff to run in the main thread,
we can (sometimes?) find that a transaction ID has already been set,
leading to failures in test_bad_request_app_logging like
AssertionError: b'X-Trans-Id: test-trans-id' not found
in b'X-Trans-Id: tx...'
By resetting the logger's txn_id, we're assured that our mock will be
run and the expected transaction ID will be used.
Change-Id: I465eed5372a2a5e591f80a09676f4b7f091cd444
* Update swift from branch 'master'
to 0947e94f664a3542daf8463cfc6e3dbe596ab1d4
- Merge "staticweb: Work with prefix-based tempurls"
- staticweb: Work with prefix-based tempurls
Note that there's a bit of a privilege escalation as prefix-based
tempurls can now be used to perform listings -- but only on containers
with staticweb enabled. Since having staticweb enabled was previously
pretty useless unless the container was both public and
publicly-listable, I think it's probably fine.
This also allows tempurls to be used at the container level, but only
for staticweb responses.
Change-Id: I7949185fdd3b64b882df01d54a8bc158ce2d7032
* Update swift from branch 'master'
to 4c5f41cc1f7a679388e924f4ed20304a5609080c
- Merge "Fix diskfile test failing on macOS"
- Fix diskfile test failing on macOS
The existing test fails on macOS because the value of errno.ENODATA is
platform dependent. On macOS ENODATA is 96:
% man 2 intro|grep ENODATA
96 ENODATA No message available.
Change-Id: Ibc760e641d4351ed771f2321dba27dc4e5b367c1
* Update swift from branch 'master'
to 07c8e8bcdc3fdaccfd016f48af71c42b46b987b4
- Merge "Object-server: add periodic greenthread yielding during file read."
- Object-server: add periodic greenthread yielding during file read.
Currently, when object-server serves GET request and DiskFile
reader iterate over disk file chunks, there is no explicit
eventlet sleep called. When network outpace the slow disk IO,
it's possible one large and slow GET request could cause
eventlet hub not to schedule any other green threads for a
long period of time. To improve this, this patch add a
configurable sleep parameter into DiskFile reader, which
is 'cooperative_period' with a default value of 0 (disabled).
Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>
Change-Id: I80b04bad0601b6cd6caef35498f89d4ba70a4fd4
* Update swift from branch 'master'
to 2500fbeea99683ef8ca525b9a7c565a0ab4d00a4
- proxy: don't use recoverable_node_timeout with x-newest
Object GET requests with a truthy X-Newest header are not resumed if a
backend request times out. The GetOrHeadHandler therefore uses the
regular node_timeout when waiting for a backend connection response,
rather than the possibly shorter recoverable_node_timeout. However,
previously while reading data from a backend response the
recoverable_node_timeout would still be used with X-Newest requests.
This patch simplifies GetOrHeadHandler to never use
recoverable_node_timeout when X-Newest is truthy.
Change-Id: I326278ecb21465f519b281c9f6c2dedbcbb5ff14
* Update swift from branch 'master'
to 8061dfb1c38de338f7eee29b0819c26825e31a3a
- proxy-server: de-duplicate _get_next_response_part method
Both GetOrHeadHandler (used for replicated policy GETs) and
ECFragGetter (used for EC policy GETs) have _get_next_response_part
methods that are very similar. This patch replaces them with a single
method in the common GetterBase superclass.
Both classes are modified to use *only* the Request instance passed to
their constructors. Previously their entry methods
(GetOrHeadHandler.get_working_response and
ECFragGetter.response_parts_iter) accepted a Request instance as an
arg and the class then variably referred to that or the Request
instance passed to the constructor. Both instances must be the same
and it is therefore safer to only allow the Request to be passed to
the constructor.
The 'newest' keyword arg is dropped from the GetOrHeadHandler
constructor because it is never used.
This refactoring patch makes no intentional behavioral changes, apart
from the text of some error log messages which have been changed to
differentiate replicated object GETs from EC fragment GETs.
Change-Id: I148e158ab046929d188289796abfbbce97dc8d90
* Update swift from branch 'master'
to 50336c509877e7c325823498cd67bf6cf4f4bef3
- Merge "test: all primary error limit is error"
- test: all primary error limit is error
Change-Id: Ib790be26a2b990f313484f9ebdc99b8dc14613c9
* Update swift from branch 'master'
to fe8227e56c5259477bbff4e5c50cf1ea852d0501
- Merge "reno: Update master for unmaintained/yoga"
- reno: Update master for unmaintained/yoga
Update the yoga release notes configuration to build from
unmaintained/yoga.
Change-Id: I3ef2117e0e00c2a1dc02ab018baae04ebfeb7214
* Update swift from branch 'master'
to 439dc93cc4611e752bcaef64fa8383f0d1669a87
- Merge "Add ClosingIterator class; be more explicit about closes"
- Add ClosingIterator class; be more explicit about closes
... in document_iters_to_http_response_body.
We seemed to be relying a little too heavily upon prompt garbage
collection to log client disconnects, leading to failures in
test_base.py::TestGetOrHeadHandler::test_disconnected_logging
under python 3.12.
Closes-Bug: #2046352
Co-Authored-By: Alistair Coles <alistairncoles@gmail.com>
Change-Id: I4479d2690f708312270eb92759789ddce7f7f930
* Update swift from branch 'master'
to 3aba22fde584fe8f81feed97ae48c29142369f57
- Merge "Stop using deprecated datetime.utc* functions"
- Stop using deprecated datetime.utc* functions
Change-Id: I9a205a4191e9b26784e507262cb66a1190c2bc71
* Update swift from branch 'master'
to 51ae9b00c917d963d0477120b4a5a20373ea79e8
- Merge "lint: Consistently use assertIsInstance"
- lint: Consistently use assertIsInstance
This has been available since py32 and was backported to py27; there
is no point in us continuing to carry the old idiom forward.
Change-Id: I21f64b8b2970e2dd5f56836f7f513e7895a5dc88
* Update swift from branch 'master'
to ad4137100522fca069bc08b8df80c6cf3d4e387b
- Merge "lint: Up-rev hacking"
- lint: Up-rev hacking
Last time we did this was nearly 4 years ago; drag ourselves into
something approaching the present. Address a few new pyflakes issues
that seem reasonable to enforce:
E275 missing whitespace after keyword
E231 missing whitespace after ','
E721 do not compare types, for exact checks use `is` / `is not`,
for instance checks use `isinstance()`
Main motivator is that the old hacking kept us on an old version
of flake8 et al., which no longer work with newer Pythons.
Change-Id: I54b46349fabb9776dcadc6def1cfb961c123aaa0
* Update swift from branch 'master'
to 4d3f9fe952360f0c0eb1d8507f2dd6903096fa90
- Merge "sharding: don't replace own_shard_range without an epoch"
- sharding: don't replace own_shard_range without an epoch
We've observed a root container suddenly thinks it's unsharded when it's
own_shard_range is reset. This patch blocks a remote osr with an epoch
of None from overwriting a local epoched OSR.
The only way we've observed this happen is when a new replica or handoff
node creates a container and it's new own_shard_range is created without
an epoch and then replicated to older primaries.
However, if a bad node with a non-epoched OSR is on a primary, it's
newer timestamp would prevent pulling the good osr from it's peers. So
it'll be left stuck with it's bad one.
When this happens expect to see a bunch of:
Ignoring remote osr w/o epoch: x, from: y
When an OSR comes in from a replica that doesn't have an epoch when
it should, we do a pre-flight check to see if it would remove the epoch
before emitting the error above. We do this because when sharding is
first initiated it's perfectly valid to get OSR's without epochs from
replicas. This is expected and harmless.
Closes-bug: #1980451
Change-Id: I069bdbeb430e89074605e40525d955b3a704a44f
* Update swift from branch 'master'
to 1936f6735cbef8b3aa9bc8ca2e222c394df797e0
- replicator: Rename update_deleted to revert
This is a more-intuitive name for what's going on and it's been working
well for us in the reconstructor.
Change-Id: Id935de4ca9eb6f38b0d587eaed8d13c54bd89d60
* Update swift from branch 'master'
to afe31b4c01881aa761f7ecc8942245301cadc476
- Merge "tests: Fix float expectations for py312"
- tests: Fix float expectations for py312
From https://docs.python.org/3/whatsnew/3.12.html :
sum() now uses Neumaier summation to improve accuracy and
commutativity when summing floats or mixed ints and floats.
At least, I *think* that's what was causing the ring builder failures.
Partial-Bug: #2046352
Change-Id: Icae2f1e3e95f216d214636bd5a6d1f40aacab20d
* Update swift from branch 'master'
to 0cb02a6ce5ddcd8615799072fd7b98b3db076313
- Merge "proxy: don't send multi-part terminator when no parts sent"
- proxy: don't send multi-part terminator when no parts sent
If the proxy timed out while reading a replicated policy multi-part
response body, it would transform the ChunkReadTimeout to a
StopIteration. This masks the fact that the backend read has
terminated unexpectedly. The document_iters_to_multipart_byteranges
would complete iterating over parts and send a multipart terminator
line, even though no parts may have been sent.
This patch removes the conversion of ChunkReadTmeout to StopIteration.
The ChunkReadTimeout that is now raised prevents the
document_iters_to_multipart_byteranges 'for' loop completing and
therefore stops the multi-part terminator line being sent. It is
raised from the GetOrHeadHandler similar to other scenarios that raise
ChunkReadTimeouts while the resp body is being read.
A ChunkReadTimeout exception handler is removed in the
_iter_parts_from_response method. This handler was previously never
reached (because StopIteration rather than ChunkReadTimeout was raised
from _get_next_response_part), but if it were reached (i.e. with this
change) then it would repeat logging of the error and repeat
incrementing the node's error counter.
This change in the GetOrHeadHandler mimics a similar change in the
ECFragGetter [1].
[1] Related-Chage: I0654815543be3df059eb2875d9b3669dbd97f5b4
Co-Authored-By: Tim Burke <tim.burke@gmail.com>
Change-Id: I6dd53e239f5e7eefcf1c74229a19b1df1c989b4a
* Update swift from branch 'master'
to 486fb234478ca43c6dac13a007b07edd3998ed5d
- Merge "proxy: only use listing shards cache for 'auto' listings"
- proxy: only use listing shards cache for 'auto' listings
The proxy should NOT read or write to memcache when handling a
container GET that explicitly requests 'shard' or 'object' record
type. A request for 'shard' record type may specify 'namespace'
format, but this request is unrelated to container listings or object
updates and passes directly to the backend.
This patch also removes unnecessary JSON serialisation and
de-serialisation of namespaces within the proxy GET path when a
sharded object listing is being built. The final response body will
contain a list of objects so there is no need to write intermediate
response bodies with a list of namespaces.
Requests that explicitly specify record type of 'shard' will of
course still have the response body with serialised shard dicts that
is returned from the backend.
Change-Id: Id79c156432350c11c52a4004d69b85e9eb904ca6
* Update swift from branch 'master'
to 5c659b1a6d31d47faaff1cc0066c732877e04838
- Merge "Prevent installation of known-broken eventlet"
- Prevent installation of known-broken eventlet
See https://github.com/eventlet/eventlet/pull/890
It's a relatively minor breakage, triggered by clients hitting a funny
corner of the HTTP spec, but it does prevent our unit tests from passing
and may surprise some clients.
Change-Id: Id29ba545e4ac7887c63fa62b75469988a2c6773c
* Update swift from branch 'master'
to bdbabbb809f20196698baa8b6ffa57ed9e1645b7
- Merge "test: swift.proxy_logging_status is really lazy (in a good way!)"
- test: swift.proxy_logging_status is really lazy (in a good way!)
Related-Change-Id: I9b5cc6d5fb69a2957b8c4846ce1feed8c115e6b6
Change-Id: I5dda9767c1c66597291211a087f7c917ba990651
* Update swift from branch 'master'
to 4eda676e2e22ddeb13b22833781f2c38c32bc757
- Merge "Support swift.proxy_logging_status in request env"
- Support swift.proxy_logging_status in request env
When logging a request, if the request environ has a
swift.proxy_logging_status item then use its value for the log
message status int.
The swift.proxy_logging_status hint may be used by other middlewares
when the desired logged status is different from the wire_status_int.
If the proxy_logging middleware detects a client disconnect then any
swift.proxy_logging_status item is ignored and a 499 status int is
logged, as per current behaviour. i.e.:
* client disconnect overrides swift.proxy_logging_status and the
response status
* swift.proxy_logging_status overrides the response status
If the proxy_logging middleware catches an exception then the logged
status int will be 500 regardless of any swift.proxy_logging_status
item.
Co-Authored-By: Alistair Coles <alistairncoles@gmail.com>
Change-Id: I9b5cc6d5fb69a2957b8c4846ce1feed8c115e6b6
* Update swift from branch 'master'
to a16e1f55a742f33bdfda55d38d6962a785fe5c97
- Improve unit tests for proxy GET ChunkReadTimeouts
Unit test changes only:
- Add tests for some resuming replicated GET scenarios.
- Add test to cover resuming GET fast_forward "failing" when range
read is complete.
- Add test to verify different node_timeout for account and container
vs object controller getters.
- Refactor proxy.test_server.py tests to split out different
scenarios.
Drive-by: remove some ring device manipulation setup that's not needed.
Change-Id: I38c7fa648492c9bd2173ecf92f89e423bee4abf3
Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>
* Update swift from branch 'master'
to b1836f93682b25ca8af79b9cc5ab5021c977a22a
- Update malformed_example.db to actually be malformed
Seems since somewhere around sqlite 3.40+ our in tests malformed sqlite
db isn't malformed anymore. I don't actually know how it was malformed
but looking in a hex editor it seems to have a bunch of null
truncated in the middle of the file. Which maybe isn't an issue anymore?
Instead I've gone and messed up what looks like to be the marker before
defining the test table data at the end of file, so from:
00001FF0 00 00 00 00 00 00 00 00 00 00 00 03 01 02 0F 31 ...............1
^^
To:
00001FF0 00 00 00 00 00 00 00 00 00 00 00 FF 01 02 0F 31 ...............1
^^
Basically FF'ed the start of the data marker (at least what I'm calling
it).
Closes-Bug: #2051067
Change-Id: I2a10adffa39abbf7e97718b7228de298209140f8
* Update swift from branch 'master'
to 1d9ab5d0a8372e907ae0f1029e743b7a97554aaa
- Merge "Only try to install py2 dev libraries for py2 jobs"
- Only try to install py2 dev libraries for py2 jobs
Change-Id: I744416ffaf245c278ebce6350854b99c0eed88e3