feat: server-side cp/mv and new objects set-access command#99
Merged
Conversation
Adopt the new @tigrisdata/storage primitives so the CLI no longer
streams object bytes through the client for remote↔remote operations.
This addresses the perf/correctness gap tracked in TIG-8731.
Changes:
- `tigris cp` (remote→remote): one `copy(src, dest, { srcBucket,
destBucket })` call replaces the previous head + get + put flow.
Server-side CopyObject, no client traffic, source metadata preserved.
- `tigris mv` (remote→remote): same-bucket calls use `move(...)` for
a metadata-only rename via `X-Tigris-Rename: true` (one round-trip).
Cross-bucket calls fall back to `copy(...)` + `remove(...)` — still
server-side, no client traffic. The server doesn't support
cross-bucket move atomically, hence the split.
- New `tigris objects set-access <bucket> <key> --access` command
using `setObjectAccess`. Dedicated home for the ACL operation that
was previously mixed into `objects set`.
- `tigris objects set` marked `deprecated: true` with an onDeprecated
message redirecting to `tigris objects set-access` (ACL) and
`tigris mv` (rename). Implementation switched off the deprecated
`updateObject` to `move` + `setObjectAccess` to avoid the SDK-level
deprecation warning.
- Folder marker semantics (zero-byte objects ending in `/`) preserved
via the existing put('') + remove() branch in both cp and mv.
Tests:
- Unit / spec-completeness suites pick up `objects set-access`
automatically (659 passing).
- Integration tests add a second bucket fixture and exercise the new
paths: cross-bucket cp (source kept, dest created), cross-bucket
mv (source gone, dest created), `objects set-access` with public/
private and the missing-flag error.
Out of scope (follow-up): mv -r parallelism and per-key --json
failure reporting (TIG-8731 AC items 3 and 4).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
MantasMiksys
approved these changes
May 11, 2026
6 tasks
designcode
added a commit
that referenced
this pull request
May 11, 2026
) Picks up @tigrisdata/storage@3.5.2 which fixes `403 SignatureDoesNotMatch` from `copy`, `move`, and `updateObject` when the object key contains `/` or any character that requires percent-encoding (space, `?`, `=`, etc.) and the request is signed with access-key SigV4. This unblocks the integration tests that have been failing on main since #99 landed: - `folder auto-detection > should auto-detect folder for cp/mv` - `file to folder operations > *` - `wildcard folder marker operations > *` - `cp/mv command - additional branches > should *match wildcard*` OAuth/session-token callers were unaffected because that auth path skips SigV4 signing entirely, which is why this only surfaced once the CI integration suite started exercising `copy`/`move` with access keys after the cp/mv SDK swap in #99. Verified locally with access-key auth against a real bucket: - nested-key cp (`folder/file.txt`) - special-char key cp (`folder/my file.txt`) - same-bucket rename via `mv` Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes TIG-8731.
Summary
Adopt the new
@tigrisdata/storageprimitives (copy,move,setObjectAccess) so the CLI no longer streams object bytes through the client for remote↔remote operations. Same-bucketmvbecomes metadata-only viaX-Tigris-Rename: true; cross-bucketcp/mvuse server-sideCopyObject.Changes
tigris cp(remote→remote) — onecopy(src, dest, { srcBucket, destBucket })call replaces the priorhead + get + putflow. Server-side CopyObject, no client traffic, source metadata preserved.tigris mv(remote→remote) — split:move(...)(metadata-only rename, one round-trip).copy(...)+remove(...)(server-side, no client traffic). The server doesn't support cross-bucket move atomically; the SDK enforces this.tigris objects set-access <bucket> <key> --accesscommand usingsetObjectAccess. Dedicated home for the ACL operation that was previously mixed intoobjects set.tigris objects setmarkeddeprecated: truewith anonDeprecatedmessage redirecting totigris objects set-access(ACL) andtigris mv(rename). Implementation switched off the SDK-deprecatedupdateObjecttomove+setObjectAccess./continue to use theput('') + remove()branch in both cp and mv (CopyObject on trailing-slash keys is ambiguous across S3 implementations).Acceptance criteria (TIG-8731)
tigris mvis metadata-only (no bytes through client).tigris mvuses server-side copy + remove (no bytes through client).cp.tscross-bucket path.mv -rparallelism (default 32) — follow-up PR, independent CLI work.--jsonper-key failure reporting — follow-up PR, same loops.Test plan
npm run lintandnpm run format:checkpassnpm testpasses (659 unit / spec tests)npm run buildsucceedscpkeeps source, creates destinationmvremoves source, creates destinationobjects set-access --access public/privatesucceedsobjects set-accesswithout--accessexits non-zero🤖 Generated with Claude Code
Note
Medium Risk
Changes core
cp/mvobject-transfer behavior to rely on new server-side storage primitives, which could affect data movement semantics (especially cross-bucket moves and folder markers) if the SDK/server behavior differs from the previous stream-based implementation.Overview
Switches remote→remote
cpandmvto use new@tigrisdata/storageserver-side primitives so object bytes no longer stream through the CLI.cpnow usescopy()(with aput('')fallback for folder markers), andmvusesmove()for same-bucket renames andcopy()+remove()for cross-bucket moves.Adds a new
objects set-accesscommand backed bysetObjectAccess, and marksobjects setas deprecated inspecs.yaml;objects setis reimplemented to rename viamove()first (when--new-keyis provided) and then update ACL viasetObjectAccess.Bumps
@tigrisdata/storageto^3.5.1and extends integration coverage with cross-bucketcp/mvandobjects set-accesstests.Reviewed by Cursor Bugbot for commit 7e124e7. Bugbot is set up for automated code reviews on this repo. Configure here.