Commit Graph
2841 Commits
Author SHA1 Message Date
Ben McClelland 7e9f556252 feat: add webui concurrent uploads with progress tracking
Queue uploads with a concurrency limit, track per-file and aggregate progress,
and preserve batch bucket/prefix context.

Limit concurrent uploads to three. Display aggregate byte progress as a
percentage and bytesDone / bytesTotal, completion and failure totals, and the
number of active uploads in the message box. Display Queued, Uploading, and
Failed files with individual progress bars; completed uploads remain in the
aggregate totals without filling the live file list.

Allow queued and active uploads to be cancelled from the progress widget. Remove
queued uploads immediately, abort active object and multipart part requests, and
abort a multipart upload on the server after its upload ID is available.
2026-09-21 09:52:41 -07:00
Ben McClellandandGitHub 97c997cb76 Merge pull request #2428 from versity/sis/cors-before-auth-all-routes
fix: apply bucket CORS right before auth middleware
2026-09-21 09:30:43 -07:00
Ben McClellandandGitHub ff05358f0b Merge pull request #2423 from versity/ben/dashboard-err
fix: hide webui user management when server in single-user mode
2026-09-21 09:16:35 -07:00
Ben McClellandandGitHub e2b7b33bac Merge pull request #2420 from versity/ben/mpu-contentlength
fix: use content-legnth for PutObject and UploadPart allocation sizes
2026-09-21 09:16:14 -07:00
niksis02 d313772685 fix: apply bucket CORS right before auth middleware
Move `applyBucketCORS` directly after `BucketObjectNameValidator` in every route so error responses still include CORS headers.
2026-09-21 17:50:13 +04:00
Ben McClellandandGitHub 38f12c85fa Merge pull request #2421 from versity/ben/rdma-legacy-headers
fix: remove legacy rdma header descriptors
2026-09-20 13:15:06 -07:00
Ben McClelland 3db22f3d38 fix: hide webui user management when server in single-user mode
Single-root deployments reject /list-users with XAdminMethodNotSupported.
Treat that response as a capability signal so the dashboard suppresses
the expected error and removes unsupported user-management controls.
2026-09-20 13:07:11 -07:00
Ben McClelland 9c98084309 fix: remove legacy rdma header descriptors
These headers are not used by the cuda cuObject client/server
interactions, so are not needed in this server implementation.
2026-09-20 12:15:43 -07:00
Ben McClelland 20a5778aac fix: use content-legnth for PutObject and UploadPart allocation sizes
X-Amz-Decoded-Content-Length describes decoded aws-chunked payloads and must
not control a plain request. Using it for a plain UploadPart lets a larger
decoded header drive backend preallocation; the posix multipart path does not
truncate the staged part, so completion publishes a zero-filled tail.

Select the decoded length only for aws-chunked readers. Plain PutObject and
UploadPart now use Content-Length for both short-body validation and backend
allocation.
2026-09-20 11:46:23 -07:00
DavvyyandGitHub d03ac3c299 fix: reject a PutObject whose body ends before Content-Length
* fix(s3api): reject a PUT whose body ends before Content-Length

With a plain (non-aws-chunked) request body, a PutObject whose body ends
before Content-Length bytes have arrived is committed as a complete but
shorter object. Real S3 rejects this with IncompleteBody and the object
never becomes visible.

Nothing on that path compares bytes received against Content-Length:
fasthttp reports a connection closed mid-body as a plain io.EOF (the
conversion to io.ErrUnexpectedEOF exists only on the chunked
transfer-encoding branch), the authentication middleware leaves an
UNSIGNED-PAYLOAD body unwrapped, and io.Copy treats io.EOF as a normal
end of stream.

ErrIncompleteBody already exists and is enforced by the chunk readers.
This adds the equivalent check for plain bodies, in the controller so
that every backend is covered, and only when the body is not already an
aws-chunked reader.

POST-Object is deliberately untouched: it is a separate handler whose
ContentLength is an upper bound, so a byte-count check there would
break browser form uploads.

* test(s3api): cover ContentLengthReader

Complete and empty bodies, truncated bodies (including an EOF delivered
together with the final bytes, and one byte per Read), a body longer
than announced, and pass-through of a non-EOF error.

* fix(s3api): check plain bodies against Content-Length, not the decoded length

Review catch: the controller replaces contentLength with
X-Amz-Decoded-Content-Length whenever that header is present, regardless
of payload type, and the previous commit fed that value to
ContentLengthReader. A complete plain upload whose decoded header is
larger than Content-Length was then rejected with IncompleteBody, where
it had succeeded before.

AWS S3 ignores X-Amz-Decoded-Content-Length on a plain body and stores
Content-Length bytes. The decoded length only describes aws-chunked
payloads, and those skip this wrapper anyway, so the check now reads the
raw Content-Length header.

If the header is missing or unparseable the body is left unwrapped: an
aws-chunked request without Content-Length is already rejected earlier
with ErrMissingContentLength, so there is nothing to check here.

* test(integration): cover aborted uploads and the decoded-length case

Three tests, as requested in review.

PutObject_aborted_plain_body       plain PUT, body ends early -> no object
PutObject_aborted_streaming_body   same for an aws-chunked upload
PutObject_plain_body_with_decoded_length
                                   complete plain PUT carrying
                                   X-Amz-Decoded-Content-Length still
                                   succeeds and stores Content-Length bytes

The abort is driven by a reader that fails partway, so the transport
tears the connection down mid-body - that is what a client that dies or
cancels looks like on the wire. Sending a short body with a normal
reader would not reproduce it: net/http would simply report the
mismatch itself.

The third test is the regression the review found. It fails without the
accompanying fix.

* test(integration): replace the bogus streaming abort test with a real one

The reviewer is right: putObjectAborted always sends
x-amz-content-sha256: UNSIGNED-PAYLOAD, and the gateway decides aws-chunked
from that header alone, so PutObject_aborted_streaming_body took the same
plain path as the test above it. It duplicated the plain test instead of
covering the streaming one.

Dropped it and added UnsignedStreamingPayloadTrailer_aborted_connection in
tests/integration/unsigned_streaming_payload_trailer.go, where it belongs.

UnsignedStreamingPayloadTrailer_incomplete_body already covers malformed and
truncated framing, but every case there is a COMPLETE request. The new test is
the other shape: valid framing whose bytes simply stop arriving.
2026-09-20 11:18:15 -07:00
915fc7a20f fix: return InvalidArgument for an empty website configuration
* fix: return InvalidArgument for an empty website configuration

`PutBucketWebsite` parsed an empty `<WebsiteConfiguration/>` into a zero-value config, and `WebsiteConfiguration.Validate` reported the nil `IndexDocument` as `MalformedXML`. S3 reports the missing index document as an `InvalidArgument` request error naming the argument instead:

    InvalidArgument: A value for IndexDocument Suffix must be provided if RedirectAllRequestsTo is empty

That branch now returns the error with `ArgumentName=IndexDocument` and `ArgumentValue=null`, matching the response in the report. Genuinely malformed XML, and a `RedirectAllRequestsTo` that conflicts with the other fields, still return `MalformedXML`.

Fixes #2260

* test: cover an empty website configuration in the PutBucketWebsite integration suite

Add a `PutBucketWebsite_empty_configuration` case that sends the empty `<WebsiteConfiguration/>` payload from the report and asserts the `InvalidArgument` response, including `ArgumentName=IndexDocument` and `ArgumentValue=null`.

The SDK collapses the error into a generic API error that drops the argument fields, so the request is signed by hand and the raw response checked with `checkHTTPResponseApiErr`, the same helper the other argument-field assertions use. The case fails against the previous behaviour with `expected error code to be InvalidArgument, instead got MalformedXML`.

---------

Co-authored-by: Tung Lam <lamphamabtung96@gmail.com>
2026-09-20 11:04:22 -07:00
Ben McClellandandGitHub f1fa2a2e48 Merge pull request #2405 from iRioxe/fix-cors-check
Hidden actual error message cause of CORS check Error on PUT/<bucket-name>?object-lock=
2026-09-20 11:03:51 -07:00
Ben McClellandandGitHub 1246a08cfa Merge pull request #2411 from versity/iRioxe/fix-deleted-file-hang
fix: clear stale delete-marker metadata on reupload
2026-09-16 16:27:42 -07:00
iRioxeandBen McClelland 00fa54d391 fix: clear stale delete-marker metadata on reupload
When versioning uses sidecar metadata, deleting the current object can leave
the delete-marker attribute behind after the data file is removed. A later
PUT or multipart completion using the same key then inherits that stale
marker and the object remains hidden from the normal object view.

Clear the marker when publishing a replacement, including orphaned sidecar
and suspended-versioning cases, and remove all object metadata when deleting
the final version without an older version to restore.

Co-authored-by: Ben McClelland <ben.mcclelland@versity.com>
2026-09-16 16:05:03 -07:00
Ben McClellandandGitHub bce4ad4870 Merge pull request #2410 from versity/sis/helm-webui-prefix-iam-storage
feat: admin API path prefix, Helm WebUI prefixes and separate IAM storage
2026-09-16 15:37:41 -07:00
Ben McClellandandGitHub 2e28162d1f Merge pull request #2406 from versity/sis/posix-preexisting-dataset-fixes
fix: treat root-level non-directory entries as non-existing buckets in posix
2026-09-16 15:31:08 -07:00
niksis02 966a6a8650 feat: admin API path prefix, Helm WebUI prefixes and separate IAM storage
Closes #2322

The admin API could not be served under a path prefix. Admin requests are SigV4-signed over the full path, so a reverse proxy or Gateway API route cannot strip a prefix before forwarding. That made it impossible to serve the WebUI and the admin API under one hostname. The new `--admin-path-prefix` (`VGW_ADMIN_PATH_PREFIX`) option mounts the admin routes under a single-segment prefix such as `/admin`, on `--admin-port` or, when that is unset, on the S3 port. Admin clients include the prefix in their endpoint URL, which the admin CLI and the WebUI already support.

The prefix is limited to unreserved characters, because clients and the gateway encode other characters differently when signing. When the admin API shares the S3 port, the prefix must also differ from `--webui-s3-prefix`, otherwise the WebUI mount answers the admin requests. Auto-detected WebUI admin gateway URLs and the startup banner now include the prefix. The admin routes served on the S3 port now reuse `S3AdminRouter` instead of a duplicated route list. This also stops the standalone admin server from recording bucket creation under the `ActionAdminListBuckets` action.

The Helm chart now exposes `webui.pathPrefix`, `webui.s3Prefix` and `admin.pathPrefix`. The WebUI gateway lists are also passed when only `webui.s3Prefix` is set, since the WebUI hosted on the S3 port does not require `webui.enabled`.

Internal IAM data can now live on its own volume. `iam.dir` sets the IAM directory, and `iam.persistence` creates or references a dedicated PVC when `iam.enabled` is true and `iam.type` is `internal`. Otherwise IAM data stays in the `iam` subdirectory of the backend data volume, so existing releases are unaffected.

The chart now rejects overlapping storage directories. `iam.dir` must be an absolute path outside `/mnt/data`, `gateway.backend.sidecarDir` and `gateway.backend.versioningDir`, and those three directories must not overlap each other. Deleting a bucket removes `<dir>/<bucket>` from the sidecar and versioning directories, so with nested directories, deleting a suitably named bucket could wipe IAM accounts, object versions or the entire backend data directory.
2026-09-16 23:09:14 +04:00
niksis02 cc48b7568c fix: treat root-level non-directory entries as non-existing buckets in posix
A posix gateway serving a preexisting dataset treats every directory under the root as a bucket. But the bucket checks only stat the path, so a regular file, FIFO or symlink at the root passed for a bucket. Only `ListBuckets` skipped these entries.

With a root-level file as the bucket, `HeadBucket`, `ListObjects`, `ListObjectsV2`, `ListMultipartUploads`, `GetBucketAcl`, `GetBucketLocation`, `GetBucketVersioning` and the bucket config getters returned a successful response. `PutBucketAcl`, `PutBucketTagging`, `PutBucketPolicy`, `PutBucketCors`, ... and the admin `ChangeBucketOwner` also succeeded, storing gateway metadata on the file itself or in the sidecar directory. `DeleteObject` and `DeleteObjects` reported success. `CreateMultipartUpload`, `UploadPart`, `UploadPartCopy`, `ListParts`, `CompleteMultipartUpload`, `ListObjectVersions` and `DeleteBucket` returned `InternalError` with not a directory. `PutObject` and `CopyObject` returned `ObjectParentIsFile`. `GetObject`, `HeadObject`, `GetObjectAttributes` and the object tagging, legal hold and retention actions returned `NoSuchKey`, and `AbortMultipartUpload` returned `NoSuchUpload`. A symlink loop at the root returned `InternalError` for every action.

Bucket existence is now checked in one place, `doesBucketExist`, and `ScoutFS` uses it too through the exported `DoesBucketExist`. A bucket is a directory under the root, or a symlink to a directory when `--bucketlinks` is enabled. Any other entry returns `NoSuchBucket` for all bucket and object actions. `CreateBucket` on such an entry returns `BucketAlreadyExists` without reading its metadata.

This also enforces `--bucketlinks` for all actions. Before, it only affected `ListBuckets`: a symlinked directory was hidden from the listing, but every other action followed the link and used it as a bucket even with the option disabled. Without `--bucketlinks` such symlinks now return `NoSuchBucket`.
2026-09-16 20:14:09 +04:00
Ben McClellandandGitHub cc04196772 Merge pull request #2409 from versity/sis/azurite-ci-readiness-wait
fix: replace fixed sleep with readiness polling in azurite CI
2026-09-16 08:18:24 -07:00
6518246f63 fix: omit ObjectLockConfiguration Rule when there is no default retention
* fix: omit ObjectLockConfiguration Rule when there is no default retention

ParseBucketLockConfigurationOutput always set Rule, so a bucket with object lock enabled and no default retention answered GET ?object-lock with an empty <Rule></Rule>. AWS S3 omits the element, and the AWS SDK v2 clients that read the rule from it follow the empty element with a malformed request.

Fixes #2397

* test: cover GetObjectLockConfiguration with no default retention in the integration suite and drop the stale non-nil Rule expectation from the controller unit test

---------

Co-authored-by: Tung Lam <lamphamabtung96@gmail.com>
2026-09-16 08:16:55 -07:00
niksis02 03a6e82e3e fix: replace fixed sleep with readiness polling in azurite CI
The azurite workflow waited a hardcoded `sleep 40` for the gateway container to compile and start listening before running tests. The container cold-builds `versitygw` from source on every run via `CompileDaemon`, and as the codebase grew that build increasingly exceeded the 40s budget, so tests started against a port with nothing
listening yet and failed with connection resets. Poll `http://127.0.0.1:7070/` with `curl` until it responds, bounded by a `timeout`, so the wait scales with actual build time instead of a stale constant.
2026-09-16 18:57:12 +04:00
Ben McClellandandGitHub c111b7d063 Merge pull request #2407 from versity/ben/staticcheck
fix: staticcheck on cuObject stubs
2026-09-15 15:42:35 -07:00
Ben McClellandandGitHub ded3993707 Merge pull request #2402 from versity/test/location_constraint_exception_fix
test: location constraint exception fix
2026-09-15 15:42:24 -07:00
Ben McClellandandGitHub ee86497f19 Merge pull request #2393 from versity/sis/posix-dataset-conversion
feat: add utils command to convert preexisting posix datasets
2026-09-15 15:39:36 -07:00
Ben McClellandandGitHub 5e660ac87a Merge pull request #2383 from JoshPigott/fix/object-verson-mtime
fix: object verson mtime
2026-09-15 14:28:59 -07:00
Ben McClelland c339f39b8c fix: staticcheck on cuObject stubs
The unsupported-platform cuObject stubs returned freshly constructed error
values, which let staticcheck prove caller error checks were always true on
non-Linux builds. Return shared package-level errors instead so the stubs
keep the same runtime behavior without triggering SA4023.
2026-09-15 14:26:47 -07:00
Ben McClellandandGitHub 6ce2e82afc Merge pull request #2403 from versity/ben/make-rdma
fix: add explicit RDMA build constraints
2026-09-15 14:03:46 -07:00
iRioxe acc14a99e0 change cors check order ; test 2026-09-15 21:19:06 +02:00
Eric EntzelandBen McClelland 3610eddf40 fix: add explicit RDMA build constraints
Gate native RDMA, cuObject, and cuobjclient implementations behind the
rdma build tag while keeping fallback stubs available for standard builds.
Preserve the separate cuobjclient_host configuration, clarify unsupported
platform errors, and update Makefile RDMA targets to pass the required tags
and disable VCS stamping.

Co-authored-by: Ben McClelland <ben.mcclelland@versity.com>
2026-09-15 11:03:51 -07:00
Luke McCrone 1252315573 test: location constraint exception fix 2026-09-15 14:06:42 -03:00
Ben McClellandandGitHub 4dc0debf8f Merge pull request #2396 from versity/dependabot/go_modules/dev-dependencies-6fd8f4cbf2
chore(deps): bump the dev-dependencies group with 29 updates
2026-09-14 15:05:27 -07:00
Ben McClellandandGitHub ec446b4abd Merge pull request #2395 from versity/dependabot/github_actions/github/codeql-action-4.38.0
chore(deps): bump github/codeql-action from 4.37.9 to 4.38.0
2026-09-14 15:05:02 -07:00
Michał "DualFroz" FoxandGitHub 91e4790870 Merge pull request #2389 from dualfroz/fix-illegal-location-constraint
Return IllegalLocationConstraintException for a mismatched LocationConstraint
2026-09-14 15:03:16 -07:00
dependabot[bot]andGitHub 57c256d5c2 chore(deps): bump the dev-dependencies group with 29 updates
Bumps the dev-dependencies group with 29 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/Azure/azure-sdk-for-go/sdk/storage/azblob](https://github.com/Azure/azure-sdk-for-go) | `1.8.0` | `1.8.1` |
| [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2) | `1.46.0` | `1.47.0` |
| [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2) | `1.33.3` | `1.33.4` |
| [github.com/aws/aws-sdk-go-v2/credentials](https://github.com/aws/aws-sdk-go-v2) | `1.20.3` | `1.20.4` |
| [github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager](https://github.com/aws/aws-sdk-go-v2) | `0.4.3` | `0.4.6` |
| [github.com/aws/aws-sdk-go-v2/service/iam](https://github.com/aws/aws-sdk-go-v2) | `1.63.0` | `1.64.0` |
| [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) | `1.111.0` | `1.113.1` |
| [github.com/aws/aws-sdk-go-v2/service/sts](https://github.com/aws/aws-sdk-go-v2) | `1.49.0` | `1.50.0` |
| [github.com/davecgh/go-spew](https://github.com/davecgh/go-spew) | `1.1.1` | `1.1.2-0.20180830191138-d8f796af33cc` |
| [github.com/valyala/fasthttp](https://github.com/valyala/fasthttp) | `1.73.0` | `1.74.0` |
| [golang.org/x/sync](https://github.com/golang/sync) | `0.22.0` | `0.23.0` |
| [golang.org/x/sys](https://github.com/golang/sys) | `0.47.0` | `0.48.0` |
| [github.com/andybalholm/brotli](https://github.com/andybalholm/brotli) | `1.2.3` | `1.2.4` |
| [github.com/aws/aws-sdk-go-v2/feature/ec2/imds](https://github.com/aws/aws-sdk-go-v2) | `1.19.2` | `1.20.0` |
| [github.com/aws/aws-sdk-go-v2/internal/configsources](https://github.com/aws/aws-sdk-go-v2) | `1.5.2` | `1.5.3` |
| [github.com/aws/aws-sdk-go-v2/internal/endpoints/v2](https://github.com/aws/aws-sdk-go-v2) | `2.8.2` | `2.8.3` |
| [github.com/aws/aws-sdk-go-v2/internal/v4a](https://github.com/aws/aws-sdk-go-v2) | `1.5.2` | `1.5.3` |
| [github.com/aws/aws-sdk-go-v2/service/internal/checksum](https://github.com/aws/aws-sdk-go-v2) | `1.11.2` | `1.11.3` |
| [github.com/aws/aws-sdk-go-v2/service/internal/presigned-url](https://github.com/aws/aws-sdk-go-v2) | `1.14.2` | `1.14.3` |
| [github.com/aws/aws-sdk-go-v2/service/internal/s3shared](https://github.com/aws/aws-sdk-go-v2) | `1.20.2` | `1.20.3` |
| [github.com/aws/aws-sdk-go-v2/service/signin](https://github.com/aws/aws-sdk-go-v2) | `1.9.0` | `1.10.0` |
| [github.com/aws/aws-sdk-go-v2/service/sso](https://github.com/aws/aws-sdk-go-v2) | `1.37.0` | `1.38.0` |
| [github.com/aws/aws-sdk-go-v2/service/ssooidc](https://github.com/aws/aws-sdk-go-v2) | `1.42.0` | `1.43.0` |
| [github.com/gofiber/schema](https://github.com/gofiber/schema) | `1.8.5` | `1.8.6` |
| [github.com/gofiber/utils/v2](https://github.com/gofiber/utils) | `2.4.3` | `2.5.1` |
| [golang.org/x/crypto](https://github.com/golang/crypto) | `0.56.0` | `0.57.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.58.0` | `0.59.0` |
| [golang.org/x/text](https://github.com/golang/text) | `0.41.0` | `0.42.0` |
| [golang.org/x/time](https://github.com/golang/time) | `0.15.0` | `0.16.0` |


Updates `github.com/Azure/azure-sdk-for-go/sdk/storage/azblob` from 1.8.0 to 1.8.1
- [Release notes](https://github.com/Azure/azure-sdk-for-go/releases)
- [Commits](https://github.com/Azure/azure-sdk-for-go/compare/sdk/azcore/v1.8.0...sdk/azidentity/v1.8.1)

Updates `github.com/aws/aws-sdk-go-v2` from 1.46.0 to 1.47.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.46.0...v1.47.0)

Updates `github.com/aws/aws-sdk-go-v2/config` from 1.33.3 to 1.33.4
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.33.3...config/v1.33.4)

Updates `github.com/aws/aws-sdk-go-v2/credentials` from 1.20.3 to 1.20.4
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.20.3...service/mq/v1.20.4)

Updates `github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager` from 0.4.3 to 0.4.6
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/feature/s3/transfermanager/v0.4.3...feature/s3/transfermanager/v0.4.6)

Updates `github.com/aws/aws-sdk-go-v2/service/iam` from 1.63.0 to 1.64.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.63.0...service/s3/v1.64.0)

Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.111.0 to 1.113.1
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.111.0...service/s3/v1.113.1)

Updates `github.com/aws/aws-sdk-go-v2/service/sts` from 1.49.0 to 1.50.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.49.0...service/s3/v1.50.0)

Updates `github.com/davecgh/go-spew` from 1.1.1 to 1.1.2-0.20180830191138-d8f796af33cc
- [Commits](https://github.com/davecgh/go-spew/commits)

Updates `github.com/valyala/fasthttp` from 1.73.0 to 1.74.0
- [Release notes](https://github.com/valyala/fasthttp/releases)
- [Commits](https://github.com/valyala/fasthttp/compare/v1.73.0...v1.74.0)

Updates `golang.org/x/sync` from 0.22.0 to 0.23.0
- [Commits](https://github.com/golang/sync/compare/v0.22.0...v0.23.0)

Updates `golang.org/x/sys` from 0.47.0 to 0.48.0
- [Commits](https://github.com/golang/sys/compare/v0.47.0...v0.48.0)

Updates `github.com/andybalholm/brotli` from 1.2.3 to 1.2.4
- [Commits](https://github.com/andybalholm/brotli/compare/v1.2.3...v1.2.4)

Updates `github.com/aws/aws-sdk-go-v2/feature/ec2/imds` from 1.19.2 to 1.20.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/v1.20.0/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/m2/v1.19.2...v1.20.0)

Updates `github.com/aws/aws-sdk-go-v2/internal/configsources` from 1.5.2 to 1.5.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/m2/v1.5.2...service/m2/v1.5.3)

Updates `github.com/aws/aws-sdk-go-v2/internal/endpoints/v2` from 2.8.2 to 2.8.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/internal/endpoints/v2.8.2...internal/endpoints/v2.8.3)

Updates `github.com/aws/aws-sdk-go-v2/internal/v4a` from 1.5.2 to 1.5.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/m2/v1.5.2...service/m2/v1.5.3)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/checksum` from 1.11.2 to 1.11.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.11.2...service/pcs/v1.11.3)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/presigned-url` from 1.14.2 to 1.14.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/service/mq/v1.14.3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/pi/v1.14.2...service/mq/v1.14.3)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/s3shared` from 1.20.2 to 1.20.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.20.2...v1.20.3)

Updates `github.com/aws/aws-sdk-go-v2/service/signin` from 1.9.0 to 1.10.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/v1.10.0/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.9.0...v1.10.0)

Updates `github.com/aws/aws-sdk-go-v2/service/sso` from 1.37.0 to 1.38.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.37.0...v1.38.0)

Updates `github.com/aws/aws-sdk-go-v2/service/ssooidc` from 1.42.0 to 1.43.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.42.0...v1.43.0)

Updates `github.com/gofiber/schema` from 1.8.5 to 1.8.6
- [Release notes](https://github.com/gofiber/schema/releases)
- [Commits](https://github.com/gofiber/schema/compare/v1.8.5...v1.8.6)

Updates `github.com/gofiber/utils/v2` from 2.4.3 to 2.5.1
- [Release notes](https://github.com/gofiber/utils/releases)
- [Commits](https://github.com/gofiber/utils/compare/v2.4.3...v2.5.1)

Updates `golang.org/x/crypto` from 0.56.0 to 0.57.0
- [Commits](https://github.com/golang/crypto/compare/v0.56.0...v0.57.0)

Updates `golang.org/x/net` from 0.58.0 to 0.59.0
- [Commits](https://github.com/golang/net/compare/v0.58.0...v0.59.0)

Updates `golang.org/x/text` from 0.41.0 to 0.42.0
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.41.0...v0.42.0)

Updates `golang.org/x/time` from 0.15.0 to 0.16.0
- [Commits](https://github.com/golang/time/compare/v0.15.0...v0.16.0)

---
updated-dependencies:
- dependency-name: github.com/Azure/azure-sdk-for-go/sdk/storage/azblob
  dependency-version: 1.8.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2
  dependency-version: 1.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/config
  dependency-version: 1.33.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/credentials
  dependency-version: 1.20.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager
  dependency-version: 0.4.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/iam
  dependency-version: 1.64.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/s3
  dependency-version: 1.113.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/sts
  dependency-version: 1.50.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/davecgh/go-spew
  dependency-version: 1.1.2-0.20180830191138-d8f796af33cc
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/valyala/fasthttp
  dependency-version: 1.74.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/sync
  dependency-version: 0.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/sys
  dependency-version: 0.48.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/andybalholm/brotli
  dependency-version: 1.2.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/feature/ec2/imds
  dependency-version: 1.20.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/internal/configsources
  dependency-version: 1.5.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/internal/endpoints/v2
  dependency-version: 2.8.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/internal/v4a
  dependency-version: 1.5.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/checksum
  dependency-version: 1.11.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/presigned-url
  dependency-version: 1.14.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/s3shared
  dependency-version: 1.20.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/signin
  dependency-version: 1.10.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/sso
  dependency-version: 1.38.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/ssooidc
  dependency-version: 1.43.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/gofiber/schema
  dependency-version: 1.8.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/gofiber/utils/v2
  dependency-version: 2.5.1
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/crypto
  dependency-version: 0.57.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/net
  dependency-version: 0.59.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/text
  dependency-version: 0.42.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/time
  dependency-version: 0.16.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-14 21:29:11 +00:00
dependabot[bot]andGitHub 3742fa6571 chore(deps): bump github/codeql-action from 4.37.9 to 4.38.0
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.37.9 to 4.38.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v4.37.9...v4.38.0)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-14 21:08:00 +00:00
Ben McClellandandGitHub 9eea7dabe9 Merge pull request #2386 from versity/sis/oidc-discovery-urls
feat: add per-provider OIDC discovery URL override
2026-09-14 11:22:44 -07:00
niksis02 13b6bb061c feat: add utils command to convert preexisting posix datasets
Closes #2304

Adds `versitygw utils convert-posix-dataset` (alias `cpd`), which makes a posix dataset not created by the gateway fully compatible with the posix backend. Every top level directory is treated as a bucket and gets a private ACL owned by `--access-key-id` (defaults to the root `--access`) and `BucketOwnerEnforced` object ownership; root level files are ignored. Metadata is stored in xattrs, or in `--sidecar-dir` when set.

`--calculate-etag` and `--checksum-algorithm` optionally compute the MD5 ETag and the `FULL_OBJECT` checksum of every object in a single streamed read. Objects are converted concurrently, tunable with `--concurrency` and `--read-buffer-size`. Existing bucket and object metadata is never overwritten.
2026-09-14 20:53:08 +04:00
Ben McClellandandGitHub fd8de62c6f Merge pull request #2349 from versity/test/website_redirect
Test/website redirect
2026-09-14 08:06:02 -07:00
niksis02 1c1272c8a5 feat: add per-provider OIDC discovery URL override
`AssumeRoleWithWebIdentity` always fetched a provider's discovery document from `<provider url>/.well-known/openid-configuration`, so an identity provider that issues tokens naming a public issuer while serving its metadata and keys on a cluster-internal path could not be used: reaching it meant relaxing the endpoint checks for every registered provider. `--oidc-discovery-url` moves that one fetch to an operator-named endpoint, which is how keys can be looked up over an optimized private path while the tokens themselves stay verifiable from the public internet against the issuer alone, as the JWT spec requires.

The flag takes `<provider url>=<discovery url>` pairs, can be repeated once per provider, and is also read from `VGW_IAM_OIDC_DISCOVERY_URLS` as a comma-separated list; the Helm chart exposes the same list as `iamServer.oidc.discoveryUrls`. The discovery URL is fetched exactly as written, so it must carry the `/.well-known/openid-configuration` path when the provider serves it there. A malformed pair is rejected at startup rather than at the first assume-role call.

Only the fetch moves. The provider URL is still what a token's `iss` claim is matched against, the fetched document's own `issuer` field must still equal it, and the key set still comes from the `jwks_uri` that document publishes. A configured discovery endpoint is named by the operator at startup rather than by a request, so it and the `jwks_uri` it publishes waive the private-address check for that provider's fetch chain only, without `--oidc-allow-private-endpoints` and its far broader effect on every other provider. Transport rules are unchanged: a plaintext discovery URL still requires `--oidc-allow-insecure-transport`.

Thumbprint auto-fetch follows the override and pins the discovery endpoint's certificate chain, since that is the host every later fetch is verified against.
2026-09-14 15:12:51 +04:00
Luke McCrone 642b65f1f1 test: website redirect test, multipart upload util cleanup, install updates 2026-09-13 11:36:46 -03:00
JoshPigott 11a517c3a1 fix: avoid nil-pointer panic in mtime 2026-09-13 17:05:54 +12:00
Ben McClellandandGitHub f002073a07 Merge pull request #2385 from crsolucoes/webui-upload-progress-indicator
webui: show upload progress in the Explorer
2026-09-11 17:09:48 -07:00
b1f8cea9f6 webui: show upload progress in the Explorer
Uploading a large file through the Explorer gives no feedback at all
today — the toast only fires once at the start ("Uploading...") and
once at the end ("Uploaded"), so a multi-GB multipart upload looks
completely stalled to the user for however long it actually takes,
with no way to tell it apart from a hung connection.

Adds a small persistent widget (bottom-right, in the same visual
style as the existing toasts) that tracks bytes uploaded / total
bytes across the whole upload batch, updating after each part of a
multipart upload completes (or once a small single-PUT file
finishes). It disappears once the batch is done, right before the
existing success/failure toast.

No changes to any upload/network behavior — this only observes
progress already being made by the existing uploadMultipart/putObject
calls and renders it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 16:05:02 -07:00
Ben McClellandandGitHub a0a07ba10b Merge pull request #2387 from versity/test/mc_hotfix
test: mc hotfix
2026-09-11 15:50:23 -07:00
Luke McCrone d13b5dfc62 test: mc hotfix 2026-09-11 19:23:11 -03:00
Ben McClellandandGitHub 678ce3738e Merge pull request #2384 from versity/sis/azure-accessdenied-err-mapping
fix: map azure `AuthorizationPermissionMismatch` to `AccessDenied`
2026-09-11 07:59:53 -07:00
Ben McClellandandGitHub 843bed4380 Merge pull request #2359 from versity/ben/lock-options
fix: make conditional publish lock modes explicit
2026-09-11 07:57:08 -07:00
niksis02 859f81fb5d fix: map azure AuthorizationPermissionMismatch to AccessDenied
Originated from #2302

When the Azure credential is valid but its RBAC role does not grant a data action, Azure answers with `403 AuthorizationPermissionMismatch`. This code had no mapping, so the gateway returned `500 InternalError` to the S3 client. A common case is `CompleteMultipartUpload` under a managed identity with `Storage Blob Data Contributor`: the Get Blob Tags call on the `.sgwtmp` multipart staging blob needs `blobs/tags/read`, which that role does not include.

`azErrToS3err` now maps `AuthorizationPermissionMismatch` to `AccessDenied`. `parseMpError` used to return the raw Azure error for every code except `NoSuchKey`, so the new mapping never reached the multipart paths. It now also passes `AccessDenied` through, and the client gets a `403 AccessDenied` instead of a `500 InternalError`.
2026-09-11 16:41:41 +04:00
JoshPigott 0ab0db4479 fix: object verson mtime 2026-09-11 17:18:20 +12:00
Ben McClelland 9c363b280a fix: make conditional publish lock modes explicit
Conditional PUTs require a lock primitive that excludes competing gateway
processes sharing a backend filesystem. A successful flock call does not prove
that property: some clustered filesystem configurations accept flock but scope
it to one node, silently leaving cross-gateway check-and-publish races open.

Add an object-lock mode that lets operators select flock or fcntl for
filesystems where that primitive is cluster-coherent, local for the existing
per-process behavior, or none to reject conditional writes with NotImplemented.
Keep the legacy disable flag as an alias for local.

Shared lock modes now verify the selected primitive on the root lock filesystem
during startup and fail closed if it cannot be used. Runtime lock failures no
longer silently downgrade to process-local exclusion. The startup check cannot
establish cross-node coherence, so that remains an explicit operator
requirement.

ScoutFS defaults to none since posix locks are not cluster consistent, but
allow setting local for single node deployments.

Fixes #2351
2026-09-10 19:01:56 -07:00