From 920ae672cf4ee0740dfdf30a4296a6254853827c Mon Sep 17 00:00:00 2001 From: AntonSelezev Date: Wed, 30 Sep 2026 18:01:08 +0300 Subject: [PATCH 1/6] update package --- APIs/XMPP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/APIs/XMPP b/APIs/XMPP index 37cb4ac3..dfe96287 160000 --- a/APIs/XMPP +++ b/APIs/XMPP @@ -1 +1 @@ -Subproject commit 37cb4ac30d6ed64e95ecd7084766d274fa1e5e9f +Subproject commit dfe96287b3907469825453151dc50e3f93aac029 From 39142ebc4fbd29841d57baa078e12fe5246e6d51 Mon Sep 17 00:00:00 2001 From: AntonSelezev Date: Mon, 5 Oct 2026 15:24:50 +0300 Subject: [PATCH 2/6] v0.37.3: update submodule --- APIs/XMPP | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/APIs/XMPP b/APIs/XMPP index dfe96287..cb894f3a 160000 --- a/APIs/XMPP +++ b/APIs/XMPP @@ -1 +1 @@ -Subproject commit dfe96287b3907469825453151dc50e3f93aac029 +Subproject commit cb894f3a0a3b6e85747a9bbe40531d49ddf0169c diff --git a/package-lock.json b/package-lock.json index 88d43e8c..dd0d5828 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sama", - "version": "0.37.2", + "version": "0.37.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sama", - "version": "0.37.2", + "version": "0.37.3", "license": "GPL-3.0", "dependencies": { "@ai-sdk/google": "^2.0.16", diff --git a/package.json b/package.json index 3f17c317..f9337f27 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sama", - "version": "0.37.2", + "version": "0.37.3", "description": "Simple but Advanced Messaging Alternative", "main": "index.js", "type": "module", From 3c0456b94556e7b74df2c3fd98a988f8f3db5c0e Mon Sep 17 00:00:00 2001 From: AntonSelezev Date: Mon, 5 Oct 2026 17:02:42 +0300 Subject: [PATCH 3/6] use garage - delete minio --- .env.docker | 18 +- .env.example | 25 +- app/config/default.js | 9 +- .../services/storage/clients/Provider.js | 4 +- .../services/storage/clients/minio.js | 35 -- app/providers/services/storage/clients/s3.js | 1 + docker-compose-full.yml | 25 +- package-lock.json | 451 +----------------- package.json | 1 - prefs/docker-compose/services/backend.yml | 3 +- prefs/docker-compose/services/s3.yml | 22 +- prefs/garage/garage.toml | 18 + prefs/garage/init.sh | 18 + 13 files changed, 80 insertions(+), 550 deletions(-) delete mode 100644 app/providers/services/storage/clients/minio.js create mode 100644 prefs/garage/garage.toml create mode 100755 prefs/garage/init.sh diff --git a/.env.docker b/.env.docker index efbf2d0c..f4784a4d 100644 --- a/.env.docker +++ b/.env.docker @@ -6,14 +6,16 @@ MONGODB_URL=mongodb://172.25.0.4/samadb REDIS_URL=redis://172.25.0.5:6379 -STORAGE_DRIVER=minio - -MINIO_ROOT_USER=e7walulcatDu7waekVSk -MINIO_ROOT_PASSWORD=PYiRFiqUljLFRdKvwnVQ -MINIO_ACCESS_KEY=hJZWjTyRnxkvcu2gQS5m -MINIO_SECRET_KEY=k4QiBO1i8GZSP69U8CnImqhHhAQJGHWl8PKDJRXJ -MINIO_BUCKET_NAME=samabucket -MINIO_USE_SSL=false +STORAGE_DRIVER=s3 + +# Garage (S3-compatible), see prefs/garage +GARAGE_RPC_SECRET=6faa4ec263e89f1f5707a1c45a886d74658f5a3e5b4dde056bc6be20f959c2cf +GARAGE_ADMIN_TOKEN=R+zcAoZ6LuQ+ylu+J6H3fNBKd3sZOMjCq8sOlpg4NFc= +S3_ACCESS_KEY=GK420ff84841bcd9d58d606e2e +S3_SECRET_KEY=451ca1503caa256a9491875800bb2fdf1eec356a5bc079c298b95f0fb13f1776 +S3_BUCKET_NAME=samabucket +S3_REGION=garage +S3_FORCE_PATH_STYLE=true CONVERSATION_MAX_PARTICIPANTS=50 CONVERSATION_PRELOAD_COUNT=30 diff --git a/.env.example b/.env.example index a965cd96..8fc42766 100644 --- a/.env.example +++ b/.env.example @@ -22,15 +22,19 @@ APP_REPL_SOCKET_HANDLER=/tmp/net-repl.socket APP_REPL_FILE_IN=/tmp/pipe-repl.in APP_REPL_FILE_OUT=/tmp/pipe-repl.out -STORAGE_DRIVER=minio +STORAGE_DRIVER=s3 # If you set STORAGE_DRIVER=s3, then fill the below envs # -S3_ACCESS_KEY=key -S3_SECRET_KEY=secret -S3_ENDPOINT= +# Defaults below point to the local Garage from docker-compose (prefs/garage). +# For AWS S3: leave S3_ENDPOINT empty, set S3_FORCE_PATH_STYLE=false +# +S3_ACCESS_KEY=GK420ff84841bcd9d58d606e2e +S3_SECRET_KEY=451ca1503caa256a9491875800bb2fdf1eec356a5bc079c298b95f0fb13f1776 +S3_ENDPOINT=http://127.0.0.1:9010 S3_BUCKET_NAME=samabucket -S3_REGION=us-east-1 +S3_REGION=garage +S3_FORCE_PATH_STYLE=true # If you set STORAGE_DRIVER=spaces, then fill the below envs # @@ -40,17 +44,6 @@ SPACES_ENDPOINT=127.0.0.1 SPACES_BUCKET_NAME=samabucket SPACES_REGION=us-east-1 -# If you set STORAGE_DRIVER=minio, then fill the below envs -# -MINIO_ROOT_USER=e7walulcatDu7waekVSk -MINIO_ROOT_PASSWORD=PYiRFiqUljLFRdKvwnVQ -MINIO_ACCESS_KEY=hJZWjTyRnxkvcu2gQS5m -MINIO_SECRET_KEY=k4QiBO1i8GZSP69U8CnImqhHhAQJGHWl8PKDJRXJ -MINIO_ENDPOINT=127.0.0.1 -MINIO_BUCKET_NAME=samabucket -MINIO_PORT=9010 -MINIO_USE_SSL=false - CONVERSATION_MAX_PARTICIPANTS=50 CONVERSATION_PRELOAD_COUNT=30 MESSAGE_PRELOAD_COUNT=30 diff --git a/app/config/default.js b/app/config/default.js index 03f264e0..512c7d3a 100644 --- a/app/config/default.js +++ b/app/config/default.js @@ -61,20 +61,13 @@ const CONFIG = { driver: process.env.STORAGE_DRIVER ?? "s3", uploadUrlExpiresIn: process.env.FILE_UPLOAD_URL_EXPIRES_IN, downloadUrlExpiresIn: process.env.FILE_DOWNLOAD_URL_EXPIRES_IN, - minio: { - key: process.env.MINIO_ACCESS_KEY, - secret: process.env.MINIO_SECRET_KEY, - endpoint: process.env.MINIO_ENDPOINT || null, - bucket: process.env.MINIO_BUCKET_NAME, - port: process.env.MINIO_PORT ?? 9010, - useSSL: process.env.MINIO_USE_SSL === CONSTANTS.ENV_TRUE, - }, s3: { key: process.env.S3_ACCESS_KEY, secret: process.env.S3_SECRET_KEY, endpoint: process.env.S3_ENDPOINT || null, bucket: process.env.S3_BUCKET_NAME, region: process.env.S3_REGION ?? "us-east-1", + forcePathStyle: process.env.S3_FORCE_PATH_STYLE === CONSTANTS.ENV_TRUE, }, spaces: { key: process.env.SPACES_ACCESS_KEY, diff --git a/app/providers/services/storage/clients/Provider.js b/app/providers/services/storage/clients/Provider.js index 70b1ac52..94dc52ea 100644 --- a/app/providers/services/storage/clients/Provider.js +++ b/app/providers/services/storage/clients/Provider.js @@ -1,6 +1,5 @@ import config from "../../../../config/index.js" -import MinioStorageClient from "./minio.js" import S3StorageClient from "./s3.js" import SpacerStorageClient from "./spaces.js" @@ -9,8 +8,7 @@ import RegisterProvider from "../../../../common/RegisterProvider.js" const name = "StorageDriverClient" const storageDriverName = config.get("storage.driver") -const StorageDriverClient = - storageDriverName === "minio" ? MinioStorageClient : storageDriverName === "spaces" ? SpacerStorageClient : S3StorageClient +const StorageDriverClient = storageDriverName === "spaces" ? SpacerStorageClient : S3StorageClient class StorageDriverClientRegisterProvider extends RegisterProvider { register(slc) { diff --git a/app/providers/services/storage/clients/minio.js b/app/providers/services/storage/clients/minio.js deleted file mode 100644 index 2845a1d1..00000000 --- a/app/providers/services/storage/clients/minio.js +++ /dev/null @@ -1,35 +0,0 @@ -import { Client } from "minio" - -import BaseStorageClient from "./base.js" - -class MinioStorageClient extends BaseStorageClient { - constructor(config, helpers) { - super(config, helpers) - - this.minioClient = new Client({ - accessKey: this.config.get("storage.minio.key"), - secretKey: this.config.get("storage.minio.secret"), - endPoint: this.config.get("storage.minio.endpoint"), - port: +this.config.get("storage.minio.port"), - useSSL: this.config.get("storage.minio.useSSL"), - }) - - this.bucketName = this.config.get("storage.minio.bucket") - } - - async getUploadUrl(fileName) { - const objectId = this.helpers.getUniqueId() - - const presignedUrl = await this.minioClient.presignedPutObject(this.bucketName, objectId, this.expireUploadUrl) - - return { objectId, url: presignedUrl } - } - - async getDownloadUrl(fileId) { - const url = await this.minioClient.presignedGetObject(this.bucketName, fileId, this.expireDownloadUrl) - - return url - } -} - -export default MinioStorageClient diff --git a/app/providers/services/storage/clients/s3.js b/app/providers/services/storage/clients/s3.js index 3646196f..adddc20a 100644 --- a/app/providers/services/storage/clients/s3.js +++ b/app/providers/services/storage/clients/s3.js @@ -14,6 +14,7 @@ class S3StorageClient extends BaseStorageClient { }, endpoint: this.config.get("storage.s3.endpoint"), region: this.config.get("storage.s3.region"), + forcePathStyle: this.config.get("storage.s3.forcePathStyle"), }) this.bucketName = this.config.get("storage.s3.bucket") diff --git a/docker-compose-full.yml b/docker-compose-full.yml index a54b29ef..78136fbb 100644 --- a/docker-compose-full.yml +++ b/docker-compose-full.yml @@ -58,8 +58,7 @@ services: volumes: - ./.env.docker:/app/.env environment: - - MINIO_ENDPOINT=${MINIO_ENDPOINT:-172.25.0.2} - - MINIO_PORT=${MINIO_PORT:-9000} + - S3_ENDPOINT=${S3_ENDPOINT:-http://172.25.0.2:9000} sama-push-daemon: build: @@ -96,26 +95,26 @@ services: - ./prefs/server-dashboard/.env.server-dashboard:/app/.env s3: - image: minio/minio + image: dxflrs/garage:v2.4.1 networks: sama_network: ipv4_address: 172.25.0.2 ports: - - "9011:9001" + - "9011:3903" - "9010:9000" volumes: - - data:/data + - data:/var/lib/garage + - ./prefs/garage/garage.toml:/etc/garage.toml:ro env_file: - ./.env.docker - command: server --address 0.0.0.0:9000 --console-address :9001 /data healthcheck: - test: ["CMD", "mc", "ready", "local"] + test: ["CMD", "/garage", "status"] interval: 30s timeout: 20s retries: 3 s3-service: - image: minio/mc + image: curlimages/curl networks: sama_network: ipv4_address: 172.25.0.3 @@ -124,13 +123,9 @@ services: condition: service_healthy env_file: - ./.env.docker - entrypoint: > - /bin/sh -c " - /usr/bin/mc alias set sama http://s3:9000 $${MINIO_ROOT_USER} $${MINIO_ROOT_PASSWORD}; - /usr/bin/mc mb sama/samabucket; - /usr/bin/mc policy set public sama/samabucket; - /usr/bin/mc admin user svcacct add --access-key $${MINIO_ACCESS_KEY} --secret-key $${MINIO_SECRET_KEY} sama $${MINIO_ROOT_USER} - " + volumes: + - ./prefs/garage/init.sh:/init.sh:ro + entrypoint: ["/bin/sh", "/init.sh"] mongo: image: mongo:6.0.11 diff --git a/package-lock.json b/package-lock.json index dd0d5828..f853f252 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,6 @@ "jsonwebtoken": "^8.5.1", "lodash": "4.17.21", "migrate-mongo": "^12.1.3", - "minio": "^7.0.32", "moment": "2.30.1", "mongodb": "^6.13.0", "pino": "9.7.0", @@ -2021,12 +2020,6 @@ "@types/webidl-conversions": "*" } }, - "node_modules/@zxing/text-encoding": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz", - "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==", - "optional": true - }, "node_modules/ai": { "version": "5.0.51", "resolved": "https://registry.npmjs.org/ai/-/ai-5.0.51.tgz", @@ -2096,11 +2089,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, "node_modules/atomic-sleep": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", @@ -2110,17 +2098,6 @@ "node": ">=8.0.0" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2136,14 +2113,6 @@ "node": ">=8" } }, - "node_modules/block-stream2": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-2.1.0.tgz", - "integrity": "sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==", - "dependencies": { - "readable-stream": "^3.4.0" - } - }, "node_modules/bowser": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", @@ -2171,11 +2140,6 @@ "node": ">=8" } }, - "node_modules/browser-or-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz", - "integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==" - }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -2191,14 +2155,6 @@ "node": ">=16.20.1" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "engines": { - "node": "*" - } - }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -2381,19 +2337,6 @@ "node": ">=12" } }, - "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2627,27 +2570,6 @@ } } }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/denque": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", @@ -2786,14 +2708,6 @@ "node": ">=8" } }, - "node_modules/filter-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", - "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -2827,14 +2741,6 @@ "node": ">=8" } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -2868,14 +2774,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/generic-pool": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", @@ -2893,20 +2791,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/get-port": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", @@ -2979,17 +2863,6 @@ "node": "*" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -3004,65 +2877,6 @@ "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dependencies": { - "get-intrinsic": "^1.2.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -3113,7 +2927,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/ioredis": { "version": "5.3.2", @@ -3144,29 +2959,6 @@ "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", "license": "MIT" }, - "node_modules/ipaddr.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -3179,17 +2971,6 @@ "node": ">=8" } }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3207,20 +2988,6 @@ "node": ">=8" } }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -3251,20 +3018,6 @@ "node": ">=8" } }, - "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dependencies": { - "which-typed-array": "^1.1.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -3400,11 +3153,6 @@ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "license": "(AFL-2.1 OR BSD-3-Clause)" }, - "node_modules/json-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-stream/-/json-stream-1.0.0.tgz", - "integrity": "sha512-H/ZGY0nIAg3QcOwE1QN/rK/Fa7gJn7Ii5obwp6zyPO4xiPNwpIMjqy2gwjBEGqzkF/vSWEIBQCBuN19hYiL6Qg==" - }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -3658,25 +3406,6 @@ "mongodb": "^4.4.1 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/minimatch": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", @@ -3698,30 +3427,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minio": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minio/-/minio-7.1.3.tgz", - "integrity": "sha512-xPrLjWkTT5E7H7VnzOjF//xBp9I40jYB4aWhb2xTFopXXfw+Wo82DDWngdUju7Doy3Wk7R8C4LAgwhLHHnf0wA==", - "dependencies": { - "async": "^3.2.4", - "block-stream2": "^2.1.0", - "browser-or-node": "^2.1.1", - "buffer-crc32": "^0.2.13", - "fast-xml-parser": "^4.2.2", - "ipaddr.js": "^2.0.1", - "json-stream": "^1.0.0", - "lodash": "^4.17.21", - "mime-types": "^2.1.35", - "query-string": "^7.1.3", - "through2": "^4.0.2", - "web-encoding": "^1.1.5", - "xml": "^1.0.1", - "xml2js": "^0.5.0" - }, - "engines": { - "node": "^16 || ^18 || >=20" - } - }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -4247,23 +3952,6 @@ "node": ">=6" } }, - "node_modules/query-string": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", - "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", - "dependencies": { - "decode-uri-component": "^0.2.2", - "filter-obj": "^1.1.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/quick-format-unescaped": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", @@ -4294,19 +3982,6 @@ "integrity": "sha512-+/dSQfo+3FYwYygUs/V2BBdwGa9nFtakDwKt4l0bnvNB53TNT++QSFewwHX9qXrZJuMe9j+TUaU21lm5ARgqdQ==", "license": "ISC" }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -4419,11 +4094,6 @@ "node": ">=10" } }, - "node_modules/sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" - }, "node_modules/secure-json-parse": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", @@ -4469,20 +4139,6 @@ "randombytes": "^2.1.0" } }, - "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", - "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -4552,14 +4208,6 @@ "memory-pager": "^1.0.2" } }, - "node_modules/split-on-first": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", - "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", - "engines": { - "node": ">=6" - } - }, "node_modules/split2": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", @@ -4574,22 +4222,6 @@ "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" }, - "node_modules/strict-uri-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", - "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -4694,14 +4326,6 @@ "real-require": "^0.2.0" } }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dependencies": { - "readable-stream": "3" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4772,23 +4396,6 @@ "node": ">= 10.0.0" } }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, "node_modules/uuid": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", @@ -4827,17 +4434,6 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "node_modules/web-encoding": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/web-encoding/-/web-encoding-1.1.5.tgz", - "integrity": "sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==", - "dependencies": { - "util": "^0.12.3" - }, - "optionalDependencies": { - "@zxing/text-encoding": "0.9.0" - } - }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -4875,24 +4471,6 @@ "node": ">= 8" } }, - "node_modules/which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", @@ -4960,31 +4538,6 @@ } } }, - "node_modules/xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==" - }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index f9337f27..7307d0fc 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "jsonwebtoken": "^8.5.1", "lodash": "4.17.21", "migrate-mongo": "^12.1.3", - "minio": "^7.0.32", "moment": "2.30.1", "mongodb": "^6.13.0", "pino": "9.7.0", diff --git a/prefs/docker-compose/services/backend.yml b/prefs/docker-compose/services/backend.yml index 65bb9ced..e6743169 100644 --- a/prefs/docker-compose/services/backend.yml +++ b/prefs/docker-compose/services/backend.yml @@ -10,8 +10,7 @@ services: mongo: condition: service_healthy environment: - - MINIO_ENDPOINT=${MINIO_ENDPOINT:-172.25.0.2} - - MINIO_PORT=${MINIO_PORT:-9000} + - S3_ENDPOINT=${S3_ENDPOINT:-http://172.25.0.2:9000} networks: sama_network: ipv4_address: 172.25.0.7 diff --git a/prefs/docker-compose/services/s3.yml b/prefs/docker-compose/services/s3.yml index 8158caca..f6f29b14 100644 --- a/prefs/docker-compose/services/s3.yml +++ b/prefs/docker-compose/services/s3.yml @@ -2,26 +2,26 @@ version: "3.8" services: s3: - image: minio/minio + image: dxflrs/garage:v2.4.1 networks: sama_network: ipv4_address: 172.25.0.2 ports: - - "9011:9001" + - "9011:3903" - "9010:9000" volumes: - - data:/data + - data:/var/lib/garage + - ../../garage/garage.toml:/etc/garage.toml:ro env_file: - ../../../.env.docker - command: server --address 0.0.0.0:9000 --console-address :9001 /data healthcheck: - test: ["CMD", "mc", "ready", "local"] + test: ["CMD", "/garage", "status"] interval: 30s timeout: 20s retries: 3 s3-service: - image: minio/mc + image: curlimages/curl networks: sama_network: ipv4_address: 172.25.0.3 @@ -30,10 +30,6 @@ services: condition: service_healthy env_file: - ../../../.env.docker - entrypoint: > - /bin/sh -c " - /usr/bin/mc alias set sama http://s3:9000 $${MINIO_ROOT_USER} $${MINIO_ROOT_PASSWORD}; - /usr/bin/mc mb sama/samabucket; - /usr/bin/mc policy set public sama/samabucket; - /usr/bin/mc admin user svcacct add --access-key $${MINIO_ACCESS_KEY} --secret-key $${MINIO_SECRET_KEY} sama $${MINIO_ROOT_USER} - " + volumes: + - ../../garage/init.sh:/init.sh:ro + entrypoint: ["/bin/sh", "/init.sh"] diff --git a/prefs/garage/garage.toml b/prefs/garage/garage.toml new file mode 100644 index 00000000..0d8fac6c --- /dev/null +++ b/prefs/garage/garage.toml @@ -0,0 +1,18 @@ +# Single-node Garage for local/docker setup. +# rpc_secret and admin_token come from GARAGE_RPC_SECRET / GARAGE_ADMIN_TOKEN in .env.docker +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" + +[s3_api] +# must match S3_REGION in .env.docker +s3_region = "garage" +api_bind_addr = "[::]:9000" + +[admin] +api_bind_addr = "[::]:3903" diff --git a/prefs/garage/init.sh b/prefs/garage/init.sh new file mode 100755 index 00000000..dee82158 --- /dev/null +++ b/prefs/garage/init.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# One-shot Garage setup: single-node layout, access key, bucket. Safe to re-run. +A="${GARAGE_ADMIN_URL:-http://s3:3903}/v2" + +get() { curl -s -H "Authorization: Bearer $GARAGE_ADMIN_TOKEN" "$A/$1"; } +post() { curl -s -H "Authorization: Bearer $GARAGE_ADMIN_TOKEN" -H "Content-Type: application/json" -d "$2" "$A/$1"; echo; } +first_id() { grep -o '"id": *"[0-9a-f]*"' | head -1 | grep -o '[0-9a-f]\{16,\}'; } + +if get GetClusterStatus | grep -q '"layoutVersion": *0[,}]'; then + NODE=$(get GetClusterStatus | first_id) + post UpdateClusterLayout "{\"roles\":[{\"id\":\"$NODE\",\"zone\":\"dc1\",\"capacity\":10000000000,\"tags\":[]}]}" + post ApplyClusterLayout '{"version":1}' +fi + +post ImportKey "{\"accessKeyId\":\"$S3_ACCESS_KEY\",\"secretAccessKey\":\"$S3_SECRET_KEY\",\"name\":\"sama\"}" +post CreateBucket "{\"globalAlias\":\"$S3_BUCKET_NAME\"}" +BUCKET=$(get "GetBucketInfo?globalAlias=$S3_BUCKET_NAME" | first_id) +post AllowBucketKey "{\"bucketId\":\"$BUCKET\",\"accessKeyId\":\"$S3_ACCESS_KEY\",\"permissions\":{\"read\":true,\"write\":true,\"owner\":true}}" From 32cf6c0b903d07ad0d7b014341cbe3757731209b Mon Sep 17 00:00:00 2001 From: AntonSelezev Date: Mon, 5 Oct 2026 17:14:48 +0300 Subject: [PATCH 4/6] add logs --- .env.docker | 3 +++ .github/workflows/tests.yml | 3 +++ test/attachments.spec.js | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.env.docker b/.env.docker index f4784a4d..2c64a5eb 100644 --- a/.env.docker +++ b/.env.docker @@ -1,5 +1,8 @@ NODE_ENV=testing +LOG_LEVEL=trace +LOG_SINGLE_LINE=false + APP_PORT=9001 MONGODB_URL=mongodb://172.25.0.4/samadb diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 09028fa5..1da59f0d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,6 +23,9 @@ jobs: - name: Run tests single node run: docker compose exec sama-server sh -c "MONGODB_URL=mongodb://172.25.0.4/samatests npm run test" + - name: Run tests cluster + run: docker compose exec sama-server sh -c "MONGODB_URL=mongodb://172.25.0.4/samatests npm run test:cluster" + - name: Stop the SAMA resources if: always() run: docker compose -f docker-compose-full.yml down -v --rmi all diff --git a/test/attachments.spec.js b/test/attachments.spec.js index 4eeca3d3..a4ecc469 100644 --- a/test/attachments.spec.js +++ b/test/attachments.spec.js @@ -97,7 +97,7 @@ describe("Attachments", async () => { assert.equal(Object.keys(responseData.response.file_urls).length, 2) }) - it("should fail file limit exceded", async () => { + it("should fail file limit exceeded", async () => { const requestData = { request: { create_files: [ From 8f5bc3d2a0999c0c1366ada507d7353c2cfe1f42 Mon Sep 17 00:00:00 2001 From: AntonSelezev Date: Mon, 5 Oct 2026 17:40:38 +0300 Subject: [PATCH 5/6] test run fix: process kill in docker/debian --- test/cluster/utils.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/cluster/utils.js b/test/cluster/utils.js index cc1283b2..5dba0a1e 100644 --- a/test/cluster/utils.js +++ b/test/cluster/utils.js @@ -81,10 +81,22 @@ const createPipeStream = (tag, nodeSubprocess) => export const spawnNode = async (cmd, env, tag, notWaitReady) => { const nodeSubprocess = spawn(cmd, [], { shell: true, + detached: true, // own process group: sh -> npm -> node env: env ? { ...process.env, ...env } : void 0, stdio: ["ignore", "pipe", "pipe"], }) + // pid is /bin/sh; dash (Docker/Debian) doesn't forward signals, so kill the whole group + nodeSubprocess.kill = (signal = "SIGTERM") => { + try { + process.kill(-nodeSubprocess.pid, signal) + } catch { + return false // group already gone, same as ChildProcess.kill + } + nodeSubprocess.killed = true + return true + } + const nodeSubprocessReadyPromise = notWaitReady ? true : new Promise((resolve, reject) => { From 3b3f38138cbc83005e65cb4b978a6050e0026148 Mon Sep 17 00:00:00 2001 From: AntonSelezev Date: Mon, 5 Oct 2026 17:43:18 +0300 Subject: [PATCH 6/6] changelog: v0.37.3 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68590764..a2863983 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.37.3 + +### Updated + +- use `garage` instead of `minio` for file storage + ## 0.37.2 ### Features