diff --git a/.gitignore b/.gitignore index a0a805b..6c15e6f 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,6 @@ infra/proxy/acme/ *.swp .DS_Store Thumbs.db + +# Docker garage +garage/garage.toml diff --git a/garage/docker-compose.yml b/garage/docker-compose.yml new file mode 100644 index 0000000..b91b6a9 --- /dev/null +++ b/garage/docker-compose.yml @@ -0,0 +1,17 @@ +services: + garage: + image: dxflrs/garage:v1.0.1 + container_name: enervision-garage + ports: + - "127.0.0.1:3900:3900" + - "127.0.0.1:3901:3901" + - "127.0.0.1:3903:3903" + volumes: + - ./garage.toml:/etc/garage.toml:ro + - garage-meta:/var/lib/garage/meta + - garage-data:/var/lib/garage/data + restart: unless-stopped + +volumes: + garage-meta: + garage-data: diff --git a/garage/garage.toml.example b/garage/garage.toml.example new file mode 100644 index 0000000..b90b729 --- /dev/null +++ b/garage/garage.toml.example @@ -0,0 +1,20 @@ +metadata_dir = "/var/lib/garage/meta" +data_dir = "/var/lib/garage/data" +db_engine = "sqlite" + +replication_factor = 1 + +rpc_bind_addr = "[::]:3901" +rpc_public_addr = "127.0.0.1:3901" +# Générer la vôtre : python -c "import secrets; print(secrets.token_hex(32))" +rpc_secret = "change_me" + +[s3_api] +s3_region = "garage" +api_bind_addr = "[::]:3900" +root_domain = ".s3.garage.localhost" + +[admin] +api_bind_addr = "[::]:3903" +# Générer la vôtre avec la même commande que rpc_secret +admin_token = "change_me" diff --git a/garage/tests/test_garage_smoke.py b/garage/tests/test_garage_smoke.py new file mode 100644 index 0000000..da4b9b4 --- /dev/null +++ b/garage/tests/test_garage_smoke.py @@ -0,0 +1,55 @@ +""" +Tests de fumée pour Garage — vérifie que le cluster local accepte +vraiment des écritures et les rend intactes, pas juste qu'il démarre. +""" +import os +import uuid + +import boto3 +import pytest + +ENDPOINT_URL = "http://127.0.0.1:3900" +ACCESS_KEY = os.environ["GARAGE_ACCESS_KEY"] +SECRET_KEY = os.environ["GARAGE_SECRET_KEY"] +BUCKET = "enervision-raw-test" + + +@pytest.fixture +def client(): + return boto3.client( + "s3", + endpoint_url=ENDPOINT_URL, + aws_access_key_id=ACCESS_KEY, + aws_secret_access_key=SECRET_KEY, + region_name="garage", + ) + + +def test_bucket_exists(client): + response = client.list_buckets() + noms = [b["Name"] for b in response["Buckets"]] + assert BUCKET in noms + + +def test_upload_and_download_roundtrip(client): + cle = f"test-{uuid.uuid4()}.txt" + contenu = b"contenu de test EnerVision" + + client.put_object(Bucket=BUCKET, Key=cle, Body=contenu) + + reponse = client.get_object(Bucket=BUCKET, Key=cle) + recupere = reponse["Body"].read() + + assert recupere == contenu + + client.delete_object(Bucket=BUCKET, Key=cle) + + +def test_deleted_object_is_really_gone(client): + cle = f"test-suppression-{uuid.uuid4()}.txt" + client.put_object(Bucket=BUCKET, Key=cle, Body=b"a supprimer") + + client.delete_object(Bucket=BUCKET, Key=cle) + + with pytest.raises(client.exceptions.NoSuchKey): + client.get_object(Bucket=BUCKET, Key=cle)