Skip to content

Full mc parity and v0.2.0 release pipeline - #1

Merged
andrasbacsai merged 65 commits into
mainfrom
feat/mc-full-parity
Sep 27, 2026
Merged

andrasbacsai merged 65 commits into
mainfrom
feat/mc-full-parity

Conversation

@andrasbacsai

Copy link
Copy Markdown
Member

Summary

Full mc parity for managing S3 and MinIO, and a proper release pipeline for v0.2.0.

  • All mc commands except support, license and update: object and bucket commands, bucket config, admin (IAM, server, trace/logs/heal, site replication, decommission, rebalance, ...), idp, batch, sql, watch.
  • Output, JSON, errors, exit codes and help pages match the pinned mc (tests/mc.version), checked by side-by-side parity tests against real mc.
  • Global flags, MC_* env vars, MC_HOST_<alias>, S3v2 signing, TLS trust prompt, connection deadlines.
  • Release: Linux (static), macOS (arm64, amd64) and Windows binaries, correct version data, CI gate, tag/version check, attestations. Version 0.2.0.

Status per command: MC_COMPATIBILITY.md. Details and known gaps: COMPATIBILITY.md.

Test plan

  • cargo test (1269 tests), clippy, fmt
  • Live tests against MinIO: 30 suites, 623 passed (MX_MC_PARITY=1 MX_SERVICES=all sh tests/live_minio.sh)
  • Help parity for every mc command path
  • Windows cross-build under wine (unit tests pass)
  • CI: Linux tests, macOS and Windows build jobs

🤖 Generated with Claude Code

andrasbacsai and others added 30 commits September 26, 2026 14:25
- Move clap Args/subcommand enums from cli.rs into their command modules;
  cli.rs keeps only global flags and the Commands enum.
- Split src/s3.rs into src/s3/{client,list,stat,delete,objects,multipart,
  bucket,lifecycle,lock,notify,admin,replication}.rs with re-exports.
- Add src/flags.rs: reusable flag groups (time filters, rewind, version id,
  versions, metadata, encryption, checksum) plus parsers and argv rewriting
  for mc's -vid / -sc short flags.
- Add src/globals.rs holding process-wide runtime settings.
- Add PutOptions/GetOptions/ListOptions wired into put/get/copy/multipart:
  metadata + standard headers, tags, storage class, SSE-C/S3/KMS, explicit
  checksums (forced past WhenRequired), object lock, ranges, zip extract,
  version listing, rewind resolution, incomplete uploads. Small uploads use
  PutObject; cross-server copies stream instead of buffering.
- mb gains --with-lock, --with-versioning, --region, -p.
- Register stub commands: retention, legalhold, event, undo, od, replicate,
  quota, ilm tier, ilm restore.
- Test harness: Live fixture, second server helpers, two-server
  live_minio.sh running every tests/live_*.rs, optional tests/minio.env,
  KMS-enabled server 1. Switch the pinned MinIO image to pgsty/minio since
  quay.io/minio images are no longer pullable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…it-upload/--limit-download, --dp, --no-color

- --insecure uses a hyper-rustls client with a no-verify certificate verifier (honors --resolve)
- PEM certificates in <config dir>/certs/CAs are trusted in addition to native roots
- --debug prints a redacted HTTP request/response trace to stderr
- -H/--custom-header adds headers to every request before signing
- --limit-upload/--limit-download throttle request/response bodies via a shared limiter
- --disable-pager/--dp and --no-color are accepted and stored in Globals
- tests/live_minio.sh starts a third MinIO with TLS (MX_TEST_TLS_URL, MX_TEST_TLS_CA)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- cat: multiple targets and stdin, --rewind, --version-id/-vid, --zip,
  --offset, --tail, --part-number, --enc-c with mc's combination rules
- head: -n/--lines, --rewind, --version-id, --zip, --enc-c, multiple
  targets and stdin
- get: --version-id, --enc-c
- put: -P/--parallel, -s/--part-size (human sizes), --storage-class/-sc,
  --disable-multipart, --checksum, --enc-c/--enc-s3/--enc-kms, hidden
  --if-not-exists (If-None-Match: *), multiple sources
- pipe: -sc, --attr, --tags, --concurrent, --part-size, --checksum, enc
  flags, local file targets; uses the global -q/--quiet
- find: --exec, --ignore, --name, --path, --regex, --print, --larger,
  --smaller, --older-than, --newer-than, --maxdepth, --versions,
  --watch (rescan), --metadata, --tags; alias-wide search
- s3/io_ext.rs: if-none-match client, rewind version lookup, find
  metadata/tag helpers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Implement `mx mirror SOURCE TARGET` for local->S3, S3->local, S3->S3 (same
or different server), local->local and alias-root mirrors (creating target
buckets). Change detection follows mc's difference.go (only-in-source,
size, newer source / active-active source mtime, metadata); differing
targets are reported as "Overwrite not allowed" unless --overwrite.

Flags: --overwrite, --remove, --dry-run, -w/--watch (periodic rescan),
--region, -a/--preserve, --active-active, --disable-multipart, --exclude,
--exclude-bucket, --exclude-storageclass, --older-than, --newer-than,
-sc/--storage-class, --attr, --retry, --summary, --skip-errors,
--max-workers, --checksum, --enc-c/--enc-s3/--enc-kms. Deprecated hidden
--force/--fake/--multi-master. --monitoring-address fails as unsupported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…SE and progress

- cp: multi-source, -r in all directions (local<->S3, S3->S3 incl. cross-server,
  local->local) following mc copy URL rules (dir vs dir/), --older-than/--newer-than,
  -sc, --attr (merged into source metadata for S3->S3), --tags, -a/--preserve
  (X-Amz-Meta-Mc-Attrs), --disable-multipart, --checksum, --enc-c/s3/kms, --rewind,
  --version-id/-vid, --legal-hold, --retention-mode/--retention-duration, --zip,
  --max-workers; server-side multipart copy (UploadPartCopy) above 5 GiB
- mv: mc flag subset, recursive, removes sources after successful copy
- output: TTY progress bar; mc `src` -> `tgt` lines + summary table otherwise;
  --json copyMessage per file plus accounting summary
- tests: unit, offline CLI (tests/cp_cli.rs) and live (tests/live_cp.rs)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- rm: multiple targets, --versions, --version-id, --non-current, --rewind,
  -I/--incomplete, --dry-run, --stdin, --older-than/--newer-than, --bypass,
  --dangerous, hidden --purge; mc flag rules and messages; DeleteObjects
  batches of 1000 with per-object results
- ls: --versions, --rewind, -I, --summarize, --storage-class filter, --zip
- stat: mc text layout for objects and buckets, -r, --versions,
  --version-id, --rewind, -v, --no-list, multiple targets, mc JSON fields
- du: --versions, --rewind; tree: --rewind
- rb: multiple targets, --force --dangerous ALIAS, not-empty message,
  --force no-op on missing buckets, MinIO force-delete fallback

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- retention set|clear|info with --default, --bypass, -r, --versions, --rewind, --version-id
- legalhold set|clear|info with -r, --versions, --rewind, --version-id
- event add|rm|ls with mc event names (put, delete, get, replica, ilm, scanner),
  --prefix/--suffix filters, -p/--ignore-existing and rm --force
- undo with --last, -r --force, --action PUT|DELETE, --dry-run
- od if=/of=/size=/parts=/skip= for upload, download and S3->S3 copies
- ilm restore with --days, -r, --versions, --version-id
- s3::lock and s3::notify helpers, offline and live tests; tests/minio.env
  configures a webhook notification target for live event tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- s3/admin.rs: SigV4-signed admin client on the smithy connector (honors
  --resolve), madmin EncryptData (PBKDF2 + sio AES-256-GCM, verified against
  madmin-go argon2id test vectors), go-humanize size helpers, quota and tier APIs
- s3/replication.rs: minio-go replication config model (XML with
  DeleteReplication, mc export JSON), add/edit/remove rule logic, remote
  target admin calls, metrics, resync, MRF/diff backlog
- quota set|info|clear; ilm tier add|edit|ls|info|check|verify|rm (minio, s3);
  replicate add|update|ls|status|resync start|status|cancel|export|import|rm|backlog
- tests: offline CLI tests with a recording fake server, live tests with two
  MinIO servers (live_minio.sh exports MX_TEST_URL2_INTERNAL)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…le, ping, ready, cors, encrypt

- share: download -r/--version-id, upload via SigV4 POST policy (curl command),
  -E max 7d, -T content type; mc share DB (<config dir>/share/{uploads,downloads}.json)
  and `share list upload|download`; mc text/JSON output
- tag set/list/remove: --version-id, --rewind, --versions, -r, set --exclude-folders
- version enable --excluded-prefixes/--exclude-folders (raw MinIO XML), info/suspend
  output like mc
- anonymous: set-json, get-json, list, links (-r), private synonym, prefix policies
  (port of minio-go pkg/policy canned policy merging)
- ilm rule add/edit/ls/rm/export/import with mc flags; lifecycle sent/read as raw
  XML so ExpiredObjectAllVersions and other MinIO extensions round-trip
- ping via /minio/health/live (-c, -e, -x, -i); ready via cluster health endpoints
  (--cluster-read, --maintenance); --distributed/--node fail clearly
- cors set accepts mc XML (or JSON, file or stdin), get prints XML; encrypt set
  sse-kms KEY; serde_json for all JSON output
- tests: unit, offline CLI (with local health stub), live_bucketcfg

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	Cargo.toml
#	src/commands/mirror.rs
#	src/lib.rs
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	tests/flags_cli.rs
Drop the duplicate list_key_versions helper from s3/bucket.rs; the
list.rs version returns the same newest-first ordering.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Admin API client honors --insecure and <config dir>/certs/CAs via shared
  helpers in net/tls.rs (insecure_connector, custom_ca_context)
- stat supports --enc-c (HEAD of SSE-C objects), like mc
- Strip amz-sdk-invocation-id/amz-sdk-request in modify_before_transmit:
  the SDK adds them after signing, so the old modify_before_signing strip
  was a no-op; lesson updated
- One size parser (flags::parse_size) and one retention validity parser
  (flags::parse_validity/retain_until) replace six duplicates
- Live tests: SSE-C over TLS (put/get/cat/cp/stat, S3->S3 re-encryption,
  multipart), admin API over TLS, tier transition + ilm restore; shared
  Tls fixture moved to tests/common/live.rs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- mirror: --remove never drops target buckets or purges versions; like mc,
  extraneous objects are removed one by one via the normal diff
- mirror: unreadable local entries mark the scan incomplete (reported, no
  deletions propagated in that pass)
- full_key: an empty relative name is the folder marker `dir/`, never the
  sibling `dir` (fixes rm/cp/mv -r, stat, tag, find, share, anonymous)
- rm -r ALIAS/BUCKET/FILE removes the object itself when nothing is under
  FILE/, and errors when neither exists
- rb --force: MinIO force-delete only on BucketNotEmpty (mc); bulk deletes
  report per-key DeleteObjects errors
- cp/mv: reject distinct sources that map to the same target
- replicate/--enc-c: never echo secrets in error messages

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- output::print_json: compact JSON line on non-TTY, one-space indent on TTY
  (Go HTML escaping); all --json prints converted
- mc error format: `PROG: <ERROR> msg. cause.` on stderr, JSON error
  document on stdout with --json; usage errors exit 1
- MC_* env vars for global flags (Go ParseBool semantics)
- MC_HOST_<alias> and MC_CONFIG_ENV_FILE aliases, merged in ConfigStore
- -v/--version with mc-shaped version text (commit id via build.rs)
- alias import|i, export|e short names
- tests: output_cli, live_output

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- tests/mc.version + tests/mc_ref.sh: build mc RELEASE.2025-08-13T08-35-41Z from the tag with
  docker (dl.min.io binaries are gone), cached in target/mc-ref/mc
- tests/common/parity.rs: paired mc/mx fixture (own HOME, work dir, bucket per tool; mx runs
  as `mc`), output normalizers, assert_parity / assert_json_parity with line and field diffs
- tests/live_mc_parity.rs: 127 cases (text + --json) across ls/stat/mb/rb/rm/cp/mv/put/pipe/
  cat/head/du/tree/find/diff/share/tag/version/anonymous/ilm/retention/legalhold/alias/mirror,
  errors and --version; 90 known gaps are #[ignore = "parity: ..."]
- live_minio.sh: MX_MC_PARITY=1 exports MX_MC_BIN; args after `--` go to the test harness
- CI: non-blocking mc-parity job with cached reference mc

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- src/error.rs: McError (mc typed errors + Go-marshaled cause.error), nonfatal()
  contexts for errorIf-style failures, Exit for already-reported errors
- src/s3/error.rs: minio-go style ErrorResponse decoding; .s3() keeps the server
  message, .s3_object() applies mc's NoSuchBucket/NoSuchKey translations
- src/usage.rs: Go-worded usage errors with SUPPORTED FLAGS rendered from clap,
  unknown commands with Did-you-mean suggestions
- mc messages per command (ls, stat, cat, head, rm, cp/mv, mb, rb, du, tree,
  find, diff, mirror, share, tag, version, encrypt, legalhold, retention, ...)
- unknown aliases are local paths; alias set probes the server like mc
- error JSON is compact on a non-TTY; flag help texts match mc

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… upload content types

- cp/mv: local sources printed as absolute paths, JSON totalSize always 0 (mc quirk)
- put/get: mc cp-style output (SRC -> TGT, summary table / JSON copy message + summary);
  setup errors reported with exit status 0 like mc; get failures print plain mc errors
- pipe: mc progress residue ` 0 B / ? `, result line kept with -q, JSON key order,
  Content-Type from the target name
- rm: JSON key order of mc rmMessage
- uploads from local files send the Content-Type guessed by extension
  (`s3::guess_content_type`, `PutOptions::local_source`)
- cp -a: xattrs uploaded as user metadata; source tags kept on streamed cross-server copy
- head: decompress gzip/bzip2 objects by Content-Type (local files by extension)
- parity: un-ignore 18 cases, add put/get/pipe/cp/rm variants; fix speed normalizer order

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n deadlines

- mirror: mc summary (table / JSON accountStat) at the end of every non-watch
  run, no per-object lines with --dry-run (transferred doubled like mc),
  initial-pass removals as `` -> `TGT`, removals counted in totalCount,
  endpoint URLs in errors, missing target bucket reported while mirroring,
  invalid-argument cause for non-folder sources, lines printed with -q
- mirror --monitoring-address: Prometheus /metrics with mc's mc_mirror_*
  counters and replication duration histogram
- find: mc keys (alias/bucket/key, absolute local paths incl. folders), mc
  JSON (type/etag), raw S3 prefix, mc match path and --maxdepth truncation
- diff: mc `< > !` lines with endpoint URLs and --json {first,second,diff}
- od/undo: mc error messages/causes; od shows local sources absolute
- hidden global --conn-read-deadline/--conn-write-deadline mapped to SDK
  read/connect timeouts
- parity: un-ignore mirror/find/diff cases, add mirror/find/diff/od/undo cases

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ypt, --version

- alias: per-alias list blocks, remove JSON keeps empty URL, import stores the
  document as-is ("Imported"), optional FILE arg, export from stored config
- share: presigned URLs without the SDK x-id param, no trailing blank line,
  JSON keeps & unescaped
- ilm rule ls/export: go-pretty alignment, updatedAt (withUpdatedAt), server
  error on missing lifecycle
- retention/legalhold: mc centerText, no extra blank line, JSON error/validity,
  single-object error handling, set --default skips the lock check
- version enable/suspend JSON empty versioning; encrypt info errors when unset
- NoSuchBucket via bucket-location lookup (tags, versioning, lock config)
- ping -a/--node via new admin ServerInfo (src/s3/admin_info.rs), Go url.URL
  JSON, minio console summary table
- --version: mc four-line block with mx's own RELEASE tag (commit time)
- new parity cases; un-ignored alias/share/ilm/lock/version/version_shape cases

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ilm tier: azure (incl. service principal) and gcs tiers, edit/update with
  account key, SP and GCS credentials; madmin TierConfig/TierCreds JSON;
  mc validation messages, errInvalidArgument causes and admin-connection
  errors; lipgloss tables without padding; typed tier info JSON
- admin API errors carry madmin ErrorResponse detail; bucket sub-resource
  errors use minio-go's; Go-style transport errors
- quota: go-humanize size parsing and errors, madmin request body
- replicate status: mc tablewriter text (single target and summary),
  --nodes pretty table, JSON re-marshaled through minio-go MetricsV2 and
  madmin BucketTarget types
- replicate backlog: mc JSON documents; text fails like mc without a TTY
- replicate ls/export/rm/import/resync JSON shapes like mc
- parity harness: second server alias, shared names, drop cleanups;
  68 parity cases for quota, ilm tier and replicate

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ls: mc lines and JSON, multiple targets (default `.`), local paths,
  mc folder detection, objects before prefixes, zip key layout
- stat: bucket Usage block (admin data usage), mc bucket/object/folder JSON
- du: mc recursion/depth semantics and tab-separated totals
- tree: mc glyphs, depth semantics, --json as recursive ls
- mb/rb: mc messages and JSON, multiple mb targets, mb folder markers,
  rb reports validation errors and continues
- parity: un-ignore listing cases, add local/folder/versions variants

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
andrasbacsai and others added 25 commits September 26, 2026 20:19
Rename Coolify-named tests to describe the mc behavior they cover and
replace the Coolify section in COMPATIBILITY.md with a neutral container
and release binaries section.

Update tests/container_smoke.sh for mc parity: usage errors exit 1 and
du/ping/tag/version output use mc's wording.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- admin API helpers: AdminRequest builder (query, JSON/madmin-encrypted body, encrypted
  response decryption incl. argon2id AES-GCM/ChaCha20), get_json/put_json/post_json/delete,
  JsonStream for long-lived NDJSON responses with Ctrl-C / closed-stdout termination
- s3::listen: ListenBucketNotification / ListenNotification streaming for watch
- CLI skeleton for every mc admin, idp, batch, sql, watch, update command (names, aliases,
  flags from mc --help); stubs fail with "not implemented yet"; deprecated hidden admin
  commands answer like mc
- live_minio.sh sources tests/services/*.sh (contract in README) with a two-pool MinIO
  service; suite globs ('live_mc_parity*') and CI runs every parity suite
- parity harness: {uniq} IAM names normalized to <UNIQ>, Parity::iam_cleanup sweep,
  mc_json helper

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
batch generate/start/list/status/describe/cancel via the MinIO admin API
(start-job, list-jobs, status-job, describe-job, cancel-job, generate-job,
batch-job realtime metrics) with madmin's static templates as fallback, mc's
tablewriter/go-humanize list table, JSON and errors, and the live status view.

sql runs S3 Select through the SDK event stream with mc's serialization
option parsing, defaults, CSV header handling, SSE-C and errorIf behavior.

Tests: unit, offline CLI (fake admin/S3 server, hand-built event-stream
frames), live (replicate to server 2, keyrotate with KMS, expire, sql incl.
gzip, recursive, SSE-C over TLS) and mc parity cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Implement every IAM admin subcommand over the MinIO admin API:
admin user (add/disable/enable/remove/list/info/policy, svcacct
add/list/remove/info/edit/enable/disable, sts info), admin group,
admin policy (create/remove/list/info/attach/detach/entities) and
admin accesskey (list/remove/info/create/edit/enable/disable/sts-revoke).

Text, JSON and errors follow mc (incl. Go JSON syntax errors, PathError
details, go-humanize expiry texts, madmin PolicyInfo marshaling).
Adds offline CLI tests, live tests and 9 mc parity tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- idp ldap/openid config commands (add/update/remove/list/info/enable/disable)
  over the idp-config admin API, mc's lipgloss boxes and restart notice
- idp ldap policy attach/detach/entities
- ldap/openid accesskey list/info/create/create-with-login/edit/enable/
  disable/remove/sts-revoke with mc's flag checks and messages
- AdminClient::send_anonymous for STS form posts; serde_json raw_value,
  libc (mktime for --expiry local time)
- OpenLDAP and Dex test services with dedicated MinIO servers, live and
  mc parity suites, offline CLI tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Implement the STREAM area: madmin ServiceTrace/GetLogs/Heal/BackgroundHealStatus
types and requests (src/s3/admin_stream.rs), mc short/verbose trace text and
JSON with matchOpts filters and --stats/--in, admin logs, admin heal (quiet,
JSON and terminal UI), and watch for buckets (listen API) and local directories
(inotify). Streaming commands exit 130/143 on SIGINT/SIGTERM like mc.

Tests: unit tests, tests/stream_cli.rs, tests/live_stream.rs,
tests/live_mc_parity_stream.rs (streaming harness in tests/common/parity.rs),
erasure-coded service tests/services/minio_ec.sh for heal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Site replication (add/update/remove/info/status/resync), pool
decommission and rebalance over the MinIO admin API with madmin types,
mc's argument checks, messages, tables and JSON. Adds offline CLI tests,
live tests and mc parity suites backed by dedicated servers
(tests/services/topo.sh).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ometheus, kms, scanner status, cluster, hidden deprecated commands)

- admin info: mc text layout (servers, pool table, totals) and full madmin.InfoMessage JSON
- admin service restart|unfreeze (+ hidden stop/freeze), admin update
- admin config get|set|reset|history|restore|export|import with madmin config parsing,
  Go tabwriter help output and mc's raw '%s' JSON error messages
- admin prometheus generate|metrics (HS512 bearer token, v2/v3, prom2json JSON)
- admin kms key create|status|list, admin scanner status (JSON stream, --bucket, --in)
- admin cluster bucket|iam import|export with mc file names and zip validation
- hidden admin tier/bucket/profile/subnet/health behave like mc; mx update reports
  that self-update is not supported
- AdminClient::send_unsigned for bearer-token metrics requests
- tests: unit, tests/server_cli.rs, tests/live_server.rs, tests/live_mc_parity_server.rs,
  dedicated test server tests/services/minio_server.sh

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…onn deadlines, admin -H/--debug, interactive replicate backlog

- AWS Signature V2 (minio-go request-signature-v2) as an SDK auth scheme for
  api S3v2 aliases, V2 presigned URLs and POST policies, V2 bucket
  sub-resource requests; anonymous aliases send unsigned requests
- alias set probes S3v4 then S3v2; mc path lookup auto rules
- TLS trust prompt for self-signed certificates on a terminal (certs/CAs),
  pinned self-signed CA certificates accepted like Go
- --conn-read/write-deadline as per-read/per-write socket deadlines
  (custom hyper stack for S3 and admin clients)
- admin requests honor -H and --debug traces
- replicate backlog inline interactive view on a terminal

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	tests/admin_skeleton_cli.rs
# Conflicts:
#	COMPATIBILITY.md
#	src/s3/admin.rs
#	tests/admin_skeleton_cli.rs
# Conflicts:
#	COMPATIBILITY.md
#	tests/admin_skeleton_cli.rs
#	tests/services/README.md
# Conflicts:
#	COMPATIBILITY.md
#	tests/admin_skeleton_cli.rs
#	tests/services/README.md
# Conflicts:
#	COMPATIBILITY.md
#	tests/admin_skeleton_cli.rs
# Conflicts:
#	src/s3/admin.rs
#	tests/services/README.md
…ounds

MinIO re-encodes the query with Go's url.Values.Encode (sorted keys,
request order of repeated values), so unsorted repeated values broke the
SigV4 signature. Sort pairs once in encode_query instead of in callers.
Remove the now-unused command stub helpers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Help (--help/-h, bare command groups, missing arguments, bare mx, urfave's
help subcommand) and usage-error flag rows now come from mc's rendered
pages, captured from the pinned mc into src/help/mc.txt (mx-only pages in
src/help/mx.txt). tests/live_mc_parity_help.rs walks mc's command tree and
compares every path (no server needed) and regenerates the data.

Also: deprecated admin stubs check flags/--help like mc, deprecation hints
name mc literally, group flag errors use urfave's Incorrect Usage, too few
positional arguments print the help.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- anonymous: -r/--recursive is a flag of anonymous itself (global), accepted
  before or after the operation; only links uses it. links lists in mc's order.
- ilm restore: --enc-c keys (parsed like mc before resolving the target) are
  sent on the restore-status HEAD. Port mc's flow: status of every selected
  object is checked even if its request failed, status line redrawn with mc's
  escape codes/dots, errors non-fatal (exit 0, JSON status success), no
  version-id/versions vs -r rejection (mc's check never fires).
- s3 errors: keep Server only when the XML body decodes (minio-go).
- Drop both flags from the help exception list and COMPATIBILITY.md notes.
- Tests: unit, CLI, live SSE-C (TLS), mc parity cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…heal loops

- admin heal: reject --force-start with --force-stop like madmin ("Unable to
  stop healing."); error on a start reply without clientToken and on a
  non-status poll reply instead of spinning
- admin update/heal: prompt when stdout+stderr are terminals (mc isTerminal);
  a confirmation read without newline fails with EOF like Go ReadString
- replicate backlog view: q/Ctrl-C during the fetch exits immediately
- admin logs: 500ms Ctrl-C-aware backoff between reconnects

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Portability: build and run on macOS and Windows. Local watch uses the
  notify crate off Linux (like mc's rjeczalik/notify), xattrs are Linux-only
  and Windows --preserve sends no attrs (both like mc), Windows abs paths are
  C:/..., no SIGTERM on Windows, Go OS name darwin, .exe trimmed from the app
  name, Windows OS error texts kept as is. Linux-specific tests are gated.
- Version data: Dockerfile ARGs MX_COMMIT_ID/SOURCE_DATE_EPOCH/MX_RELEASE;
  release builds show the tagged commit, RELEASE.<commit time> and mx 0.2.0.
- CI: workflow_call, macOS arm64/Intel and Windows build + unit tests +
  local smoke; mc-parity skippable.
- Release: tag/Cargo.toml version check, ci.yml as test gate, native builds
  for all five targets, mx -v check, SHA256SUMS, build provenance
  attestations for binaries and image, plain multi-arch index.
- Bump to 0.2.0; .gitattributes forces LF; fix container smoke help grep.
- Docs: real release assets, install per OS, attestation verification.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gitguardian

gitguardian Bot commented Sep 27, 2026

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 9 secrets following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secrets in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
37646091 Triggered Generic High Entropy Secret 5d46d60 src/flags.rs View secret
37663312 Triggered Generic CLI Secret a1508d5 tests/live_idp.rs View secret
37663311 Triggered Generic Password 5e7ba92 tests/services/openldap.sh View secret
37663313 Triggered Generic High Entropy Secret 0fd91de tests/server_cli.rs View secret
37663313 Triggered Generic High Entropy Secret 7a22aaf tests/server_cli.rs View secret
37663312 Triggered Generic CLI Secret 5e7ba92 tests/live_idp.rs View secret
37663310 Triggered JSON Web Token 7a22aaf src/s3/admin_server.rs View secret
37663310 Triggered JSON Web Token 0fd91de src/s3/admin_server.rs View secret
37663311 Triggered Generic Password a1508d5 tests/services/openldap.sh View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secrets safely. Learn here the best practices.
  3. Revoke and rotate these secrets.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

andrasbacsai and others added 3 commits September 27, 2026 12:32
rm and stat now handle local filesystem paths like mc's fsClient instead of
rejecting them: listings in mc's order, names relative to the target folder,
file metadata (Content-Type, X-Amz-Meta-Mc-Attrs, xattrs), mc's typed path
errors, rm -r/--force/--dry-run/--older-than/--newer-than/-I and the
--dangerous rule for top-level folders. Removal never follows symlinks and
only removes empty folders (mc deleteFile).

Shared helpers live in src/local_fs.rs; mc parity cases cover both commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@andrasbacsai
andrasbacsai merged commit 3e2c6ff into main Sep 27, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant