Skip to content

Commit 4cf9493

Browse files
committed
Fix merge conflict.
2 parents ed1e225 + 2924871 commit 4cf9493

File tree

9 files changed

+106
-11
lines changed

9 files changed

+106
-11
lines changed

.github/workflows/development.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
PY_VER: ${{matrix.py_ver}}
4141
MYSQL_VER: ${{matrix.mysql_ver}}
4242
ALPINE_VER: "3.10"
43-
MINIO_VER: RELEASE.2019-09-26T19-42-35Z
43+
MINIO_VER: RELEASE.2021-09-03T03-56-13Z
4444
COMPOSE_HTTP_TIMEOUT: "120"
4545
COVERALLS_SERVICE_NAME: travis-ci
4646
COVERALLS_REPO_TOKEN: fd0BoXG46TPReEem0uMy7BJO5j0w1MQiY

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
### 0.13.3 -- TBD
44
* Bugfix - Dependencies not properly loaded on populate. (#902) PR #919
55
* Bugfix - Replace use of numpy aliases of built-in types with built-in type. (#938) PR #939
6+
* Bugfix - Fix error handling of remove_object function in `s3.py` (#952) PR #955
67

78
### 0.13.2 -- May 7, 2021
89
* Update `setuptools_certificate` dependency to new name `otumat`

LNX-docker-compose.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ services:
3232
interval: 1s
3333
fakeservices.datajoint.io:
3434
<<: *net
35-
image: datajoint/nginx:v0.0.17
35+
image: datajoint/nginx:v0.0.18
3636
environment:
3737
- ADD_db_TYPE=DATABASE
3838
- ADD_db_ENDPOINT=db:3306
@@ -77,6 +77,9 @@ services:
7777
- -c
7878
- |
7979
set -e
80+
wget -P /home/dja/.local/bin/ https://dl.min.io/client/mc/release/linux-amd64/mc
81+
chmod +x /home/dja/.local/bin/mc
82+
mc alias set myminio/ http://minio:9000 datajoint datajoint
8083
pip install --user -r test_requirements.txt
8184
pip install -e .
8285
pip freeze | grep datajoint

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ A number of labs are currently adopting DataJoint and we are quickly getting the
108108
PY_VER=3.7
109109
ALPINE_VER=3.10
110110
MYSQL_VER=5.7
111-
MINIO_VER=RELEASE.2019-09-26T19-42-35Z
111+
MINIO_VER=RELEASE.2021-09-03T03-56-13Z
112112
UID=1000
113113
GID=1000
114114
```

datajoint/external.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,12 @@ def used(self):
314314
return self & [FreeTable(self.connection, ref['referencing_table']).proj(hash=ref['column_name'])
315315
for ref in self.references]
316316

317-
def delete(self, *, delete_external_files=None, limit=None, display_progress=True):
317+
def delete(self, *, delete_external_files=None, limit=None, display_progress=True, errors_as_string=True):
318318
"""
319319
:param delete_external_files: True or False. If False, only the tracking info is removed from the
320320
external store table but the external files remain intact. If True, then the external files
321321
themselves are deleted too.
322+
:param errors_as_string: If True any errors returned when deleting from external files will be strings
322323
:param limit: (integer) limit the number of items to delete
323324
:param display_progress: if True, display progress as files are cleaned up
324325
:return: if deleting external files, returns errors
@@ -346,7 +347,8 @@ def delete(self, *, delete_external_files=None, limit=None, display_progress=Tru
346347
try:
347348
self._remove_external_file(external_path)
348349
except Exception as error:
349-
error_list.append((uuid, external_path, str(error)))
350+
error_list.append((uuid, external_path,
351+
str(error) if errors_as_string else error))
350352
return error_list
351353

352354

datajoint/s3.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,11 @@ def get_size(self, name):
7676
except minio.error.S3Error as e:
7777
if e.code == 'NoSuchKey':
7878
raise errors.MissingExternalFile
79-
else:
80-
raise e
79+
raise e
8180

8281
def remove_object(self, name):
8382
logger.debug('remove_object: {}:{}'.format(self.bucket, name))
8483
try:
8584
self.client.remove_object(self.bucket, str(name))
86-
except minio.ResponseError:
85+
except minio.error.MinioException:
8786
raise errors.DataJointError('Failed to delete %s from s3 storage' % name)

docs-parts/intro/Releases_lang1.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
----------------------
33
* Bugfix - Dependencies not properly loaded on populate. (#902) PR #919
44
* Bugfix - Replace use of numpy aliases of built-in types with built-in type. (#938) PR #939
5+
* Bugfix - Fix error handling of remove_object function in `s3.py` (#952) PR #955
56

67
0.13.2 -- May 7, 2021
78
----------------------

local-docker-compose.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ services:
3434
interval: 1s
3535
fakeservices.datajoint.io:
3636
<<: *net
37-
image: datajoint/nginx:v0.0.17
37+
image: datajoint/nginx:v0.0.18
3838
environment:
3939
- ADD_db_TYPE=DATABASE
4040
- ADD_db_ENDPOINT=db:3306
@@ -82,6 +82,9 @@ services:
8282
- -c
8383
- |
8484
set -e
85+
wget -P /home/dja/.local/bin/ https://dl.min.io/client/mc/release/linux-amd64/mc
86+
chmod +x /home/dja/.local/bin/mc
87+
mc alias set myminio/ http://minio:9000 datajoint datajoint
8588
pip install --user nose nose-cov coveralls flake8 ptvsd
8689
pip install -e .
8790
pip freeze | grep datajoint

tests/test_s3.py

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
from . import S3_CONN_INFO
2-
32
from minio import Minio
3+
import json
44
import urllib3
55
import certifi
6-
from nose.tools import assert_true
6+
from nose.tools import assert_true, raises
7+
from .schema_external import schema, SimpleRemote
8+
from datajoint.errors import DataJointError
9+
import os
10+
from datajoint.hash import uuid_from_buffer
11+
from datajoint.blob import pack
712

813

914
class TestS3:
@@ -51,3 +56,84 @@ def test_connection_secure():
5156
http_client=http_client)
5257

5358
assert_true(minio_client.bucket_exists(S3_CONN_INFO['bucket']))
59+
60+
@staticmethod
61+
@raises(DataJointError)
62+
def test_remove_object_exception():
63+
# https://github.com/datajoint/datajoint-python/issues/952
64+
65+
# Initialize minioClient with an endpoint and access/secret keys.
66+
minio_client = Minio(
67+
'minio:9000',
68+
access_key='jeffjeff',
69+
secret_key='jeffjeff',
70+
secure=False)
71+
72+
# Create new user
73+
os.system('mc admin user add myminio jeffjeff jeffjeff')
74+
# json for test policy for permissionless user
75+
testpolicy = {
76+
"Version": "2012-10-17",
77+
"Statement": [
78+
{
79+
"Action": [
80+
"s3:GetBucketLocation",
81+
"s3:ListBucket",
82+
"s3:ListBucketMultipartUploads",
83+
"s3:ListAllMyBuckets"
84+
],
85+
"Effect": "Allow",
86+
"Resource": [
87+
"arn:aws:s3:::datajoint.test",
88+
"arn:aws:s3:::datajoint.migrate"
89+
],
90+
"Sid": ""
91+
},
92+
{
93+
"Action": [
94+
"s3:GetObject",
95+
"s3:ListMultipartUploadParts"
96+
],
97+
"Effect": "Allow",
98+
"Resource": [
99+
"arn:aws:s3:::datajoint.test/*",
100+
"arn:aws:s3:::datajoint.migrate/*"
101+
],
102+
"Sid": ""
103+
}
104+
]
105+
}
106+
107+
# Write test json to tmp directory so we can use it to create a new user policy
108+
with open('/tmp/policy.json', 'w') as f:
109+
f.write(json.dumps(testpolicy))
110+
111+
# Add the policy and apply it to the user
112+
os.system('mc admin policy add myminio test /tmp/policy.json')
113+
os.system('mc admin policy set myminio test user=jeffjeff')
114+
115+
# Insert some test data and remove it so that the external table is populated
116+
test = [1, [1, 2, 3]]
117+
SimpleRemote.insert1(test)
118+
SimpleRemote.delete()
119+
120+
# Save the old external table minio client
121+
old_client = schema.external['share'].s3.client
122+
123+
# Apply our new minio client to the external table that has permissions restrictions
124+
schema.external['share'].s3.client = minio_client
125+
126+
# This method returns a list of errors
127+
error_list = schema.external['share'].delete(delete_external_files=True,
128+
errors_as_string=False)
129+
130+
# Teardown
131+
os.system('mc admin policy remove myminio test')
132+
os.system('mc admin user remove myminio jeffjeff')
133+
schema.external['share'].s3.client = old_client
134+
schema.external['share'].delete(delete_external_files=True)
135+
os.remove("/tmp/policy.json")
136+
137+
# Raise the error we want if the error matches the expected uuid
138+
if str(error_list[0][0]) == str(uuid_from_buffer(pack(test[1]))):
139+
raise error_list[0][2]

0 commit comments

Comments
 (0)