Skip to content

Commit 1940501

Browse files
committed
Integrate S3ObjectIndex functionality into gardenlinux.s3.Bucket
Signed-off-by: Tobias Wolf <wolf@b1-systems.de>
1 parent 947d5fa commit 1940501

File tree

5 files changed

+69
-142
lines changed

5 files changed

+69
-142
lines changed

src/gardenlinux/s3/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@
66

77
from .bucket import Bucket
88
from .s3_artifacts import S3Artifacts
9-
from .s3_object_index import S3ObjectIndex
109

11-
__all__ = ["Bucket", "S3Artifacts", "S3ObjectIndex"]
10+
__all__ = ["Bucket", "S3Artifacts"]

src/gardenlinux/s3/bucket.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
"""
66

77
import boto3
8+
import json
89
import logging
10+
from os import PathLike
11+
from pathlib import Path
12+
from time import time
913
from typing import Any, Optional
1014

1115
from ..logger import LoggerSetup
@@ -111,6 +115,36 @@ def download_fileobj(self, key, fp, *args, **kwargs):
111115

112116
self._logger.info(f"Downloaded {key} from S3 as binary data")
113117

118+
def read_cache_file_or_filter(self, cache_file, cache_ttl: int = 3600, **kwargs):
119+
"""
120+
Read S3 object keys from cache if valid or filter for S3 object keys.
121+
122+
:param cache_file: Path to cache file
123+
:param cache_ttl: Cache time-to-live in seconds
124+
125+
:returns: S3 object keys read or filtered
126+
127+
:since: 0.9.0
128+
"""
129+
130+
if not isinstance(cache_file, PathLike):
131+
cache_file = Path(cache_file)
132+
133+
if cache_file.exists() and (time() - cache_file.stat().st_mtime) < cache_ttl:
134+
with cache_file.open("r") as fp:
135+
return json.loads(fp.read())
136+
137+
artifacts = [
138+
s3_object.key
139+
for s3_object in self._bucket.objects.filter(Prefix=prefix).all()
140+
]
141+
142+
if cache_file is not None:
143+
with cache_file.open("w") as fp:
144+
fp.write(json.dumps(artifacts))
145+
146+
return artifacts
147+
114148
def upload_file(self, file_name, key, *args, **kwargs):
115149
"""
116150
boto3: Upload a file to an S3 object.

src/gardenlinux/s3/s3_artifacts.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ def __init__(
5555

5656
self._bucket = Bucket(bucket_name, endpoint_url, s3_resource_config)
5757

58+
@property
59+
def bucket(self):
60+
"""
61+
Returns the underlying S3 bucket.
62+
63+
:return: (boto3.Bucket) S3 bucket
64+
:since: 0.9.0
65+
"""
66+
67+
return self._bucket
68+
5869
def download_to_directory(
5970
self,
6071
cname,

src/gardenlinux/s3/s3_object_index.py

Lines changed: 0 additions & 140 deletions
This file was deleted.

tests/s3/test_bucket.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,29 @@ def test_download_file(s3_setup):
6969
assert target_path.read_text() == "some data"
7070

7171

72+
def read_cache_file_or_filter(s3_setup):
73+
"""
74+
Try to read with cache
75+
"""
76+
77+
env = s3_setup
78+
env.s3.Object(env.bucket_name, "file.txt").put(Body=b"some data")
79+
80+
bucket = Bucket(env.bucket_name, s3_resource_config={"region_name": REGION})
81+
cache_file = env.tmp_path / "s3.cache.json"
82+
83+
result = bucket.read_cache_file_or_filter(cache_file, 1, Prefix="file")
84+
assert result == ["file.txt"]
85+
86+
env.s3.Object(env.bucket_name, "file2.txt").put(Body=b"some data")
87+
88+
result = bucket.read_cache_file_or_filter(cache_file, 3600, Prefix="file")
89+
assert result == ["file.txt"]
90+
91+
result = bucket.read_cache_file_or_filter(cache_file, 1, Prefix="file")
92+
assert result == ["file.txt", "file2.txt"]
93+
94+
7295
def test_upload_fileobj(s3_setup):
7396
"""
7497
Upload a file-like in-memory object to the bucket

0 commit comments

Comments
 (0)