Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #3931: Add unversioned flag to Package.set() and Package.set_dir() #3927

Merged
merged 27 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5d31cd3
use list-objects as fallback
drernie Apr 3, 2024
54d072b
test_packages.test_set_dir_cannot_list_object_versions
drernie Apr 3, 2024
983475d
only call list_objects if e is AccessDenied
drernie Apr 3, 2024
43cbc61
Merge branch 'master' into set-dir-without-versions
drernie Apr 11, 2024
254202a
revert changes
drernie Apr 11, 2024
024b1bd
stub test_set_dir_cannot_list_object_versions
drernie Apr 11, 2024
16bf0ae
FAIL test_set_dir_allow_unversioned
drernie Apr 11, 2024
7d4ab0e
catch error
drernie Apr 11, 2024
600c934
pass test
drernie Apr 11, 2024
83ce73c
Update CHANGELOG.md
drernie Apr 11, 2024
56864f7
isort
drernie Apr 11, 2024
e3d4a02
update api doc
drernie Apr 11, 2024
41e83d2
reformat gendoc
drernie Apr 11, 2024
12fa8e7
indent docs more
drernie Apr 11, 2024
117763b
unversioned: bool
drernie Apr 11, 2024
127f4c2
filter objects to IsLatest sooner
drernie Apr 11, 2024
ee26cd7
toggle on 'unversioned' instead of error
drernie Apr 11, 2024
85676fe
fail test_set_package_entry_unversioned
drernie Apr 11, 2024
e070f0e
pass test_set_package_entry_unversioned
drernie Apr 11, 2024
b66dcb1
pycodestyle: shorten long lines
drernie Apr 11, 2024
6bb26e8
Update api/python/quilt3/packages.py
sir-sigurd Apr 12, 2024
0cc1376
rework tests
sir-sigurd Apr 12, 2024
e16e859
Update docs/CHANGELOG.md
sir-sigurd Apr 12, 2024
049b4bd
put the comment back
sir-sigurd Apr 12, 2024
37f03d1
lint
sir-sigurd Apr 12, 2024
ad1b9d9
Merge branch 'master' into set-dir-without-versions
drernie Apr 14, 2024
e845b36
Fix S3 URI reference in CHANGELOG
drernie Apr 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions api/python/quilt3/packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
legacy_calculate_checksum,
legacy_calculate_checksum_bytes,
list_object_versions,
list_objects,
list_url,
put_bytes,
)
Expand Down Expand Up @@ -910,11 +911,22 @@ def set_dir(self, lkey, path=None, meta=None, update_policy="incoming"):
src_path = src.path
if src.basename() != '':
src_path += '/'
objects, _ = list_object_versions(src.bucket, src_path)
try:
objects, _ = list_object_versions(src.bucket, src_path)
except botocore.exceptions.ClientError as e:
if e.response["Error"]["Code"] != "AccessDenied":
raise

# use list_objects instead
print(f"list_object_versions not available; using list_objects:\n{e}")
objects = list_objects(src.bucket, src_path, recursive=True)
for obj in objects:
obj["IsLatest"] = True

for obj in objects:
if not obj['IsLatest']:
continue
# Skip S3 pseduo directory files and Keys that end in /
sir-sigurd marked this conversation as resolved.
Show resolved Hide resolved
# Skip S3 pseudo-directory files and Keys that end in /
if obj['Key'].endswith('/'):
if obj['Size'] != 0:
warnings.warn(f'Logical keys cannot end in "/", skipping: {obj["Key"]}')
Expand Down
28 changes: 28 additions & 0 deletions api/python/tests/integration/test_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,17 @@ def setup_s3_stubber_resolve_pointer_not_found(self, pkg_registry, pkg_name, *,
}
)

def setup_s3_stubber_cannot_list_object_versions(self, pkg_registry, pkg_name):
self.s3_stubber.add_client_error(
method="list_object_versions",
service_error_code="AccessDenied",
http_status_code=404,
expected_params={
"Bucket": pkg_registry.root.bucket,
"Prefix": pkg_name,
},
)

def setup_s3_stubber_delete_pointer(self, pkg_registry, pkg_name, *, pointer):
self.s3_stubber.add_response(
method='delete_object',
Expand Down Expand Up @@ -631,6 +642,23 @@ def test_set_dir_wrong_update_policy(self):
pkg.set_dir("nested", DATA_DIR, update_policy='invalid_policy')
assert expected_err in str(e.value)

def test_set_dir_cannot_list_object_versions(self):
"""Verify that set_dir uses list_objects if list_object_versions fails."""
# uses setup_s3_stubber_cannot_list_object_versions
registry = 's3://test-bucket'
pkg_registry = self.S3PackageRegistryDefault(PhysicalKey.from_url(registry))
pkg_name = 'Quilt/test'
pkg = Package()

with patch('quilt3.packages.list_object_versions', side_effect=Exception):
drernie marked this conversation as resolved.
Show resolved Hide resolved
pointers = {'latest': 'latest'}
self.setup_s3_stubber_list_pkg_pointers(pkg_registry, pkg_name, pointers=pointers)
drernie marked this conversation as resolved.
Show resolved Hide resolved
self.setup_s3_stubber_cannot_list_object_versions(pkg_registry, pkg_name)
pkg.set_dir(pkg_name)
drernie marked this conversation as resolved.
Show resolved Hide resolved
assert pkg._meta['dir'] == pkg_name
assert pkg._meta['registry'] == registry
assert pkg._meta['physical_keys'] == ['foo', 'bar']

def test_package_entry_meta(self):
pkg = (
Package()
Expand Down
Loading