* Implements the -l/--long flag for the ipfs ls command to display Unix-style file permissions and modification times, similar to the traditional ls -l. When the --long flag is used, the output includes: - File mode/permissions in Unix format (e.g., -rw-r--r--, drwxr-xr-x) - File hash (CID) - File size (when --size is also specified) - Modification time in human-readable format - File name The permission string implementation handles all file types and special bits: - File types: regular (-), directory (d), symlink (l), named pipe (p), socket (s), character device (c), block device (b) - Special permission bits: setuid (s/S), setgid (s/S), sticky (t/T) - Lowercase when execute bit is set, uppercase when not set The timestamp format follows Unix ls conventions: - Recent files (within 6 months): "Jan 02 15:04" - Older files: "Jan 02 2006" Signed-off-by: sneax <paladesh600@gmail.com> * fix(ls): correct --long flag header order and help text - fix header column order: was "Mode Hash Size Name ModTime" but data outputs "Mode Hash Size ModTime Name", now headers match data order - remove redundant if/else branch in directory output that had identical code in both branches - add example output to help text showing format with mode, hash, size, mtime, and name columns - document that files without preserved metadata show '----------' for mode and '-' for mtime - add changelog entry for v0.40 * test(ls): add format stability tests for --long flag add tests to prevent formatting regressions in ipfs ls --long output: unit tests (core/commands/ls_test.go): - TestFormatMode: 20 cases covering all file types (regular, dir, symlink, pipe, socket, block/char devices) and special permission bits (setuid, setgid, sticky with/without execute) - TestFormatModTime: zero time, old time (year format), future time, format length consistency integration tests (test/cli/ls_test.go): - explicit full output comparison with deterministic CIDs to catch any formatting changes - header column order verification for --long with --size=true/false - files without preserved metadata (---------- and - placeholders) - directory output (trailing slash, d prefix in mode) requested in: https://github.com/ipfs/kubo/pull/11103#issuecomment-3745043561 * fix(ls): improve --long flag docs and fix minor issues - improved godocs for formatMode and formatModTime functions - fixed permBit signature: char rune → char byte (avoids unnecessary cast) - clarified help text: mode/mtime are optional UnixFS metadata - documented that times are displayed in UTC - fixed flaky time test by using 1 month ago instead of 1 hour - removed hardcoded CID assertion that would break on DAG changes * fix(ls): show "-" for missing mode in --long output display "-" instead of "----------" when mode metadata is not preserved. this avoids ambiguity with Unix mode 0000 and matches how missing mtime is already displayed. follows common Unix tool conventions (ps, netstat) where "-" indicates "not available". --------- Signed-off-by: sneax <paladesh600@gmail.com> Co-authored-by: Marcin Rataj <lidel@lidel.org>
9.0 KiB
Kubo changelog v0.40
This release was brought to you by the Shipyard team.
v0.40.0
- Overview
- 🔦 Highlights
- 🧹 Automatic cleanup of interrupted imports
- Routing V1 HTTP API now exposed by default
- Track total size when adding pins
- Improved IPNS over PubSub validation
- New
ipfs diag datastorecommands - 🚇 Improved
ipfs p2ptunnels with foreground mode - Improved
ipfs dag statoutput - Skip bad keys when listing
- Accelerated DHT Client and Provide Sweep now work together
- ⏱️ Configurable gateway request duration limit
- 🔧 Recovery from corrupted MFS root
- 📋 Long listing format for
ipfs ls - 📦️ Dependency updates
- 📝 Changelog
- 👨👩👧👦 Contributors
Overview
🔦 Highlights
🧹 Automatic cleanup of interrupted imports
If you cancel ipfs add or ipfs dag import mid-operation, Kubo now automatically cleans up incomplete data on the next daemon start. Previously, interrupted imports would leave orphan blocks in your repository that were difficult to identify and remove without pins and running explicit garbage collection.
Batch operations also use less memory now. Block data is written to disk immediately rather than held in RAM until the batch commits.
Under the hood, the block storage layer (flatfs) was rewritten to use atomic batch operations via a temporary staging directory. See go-ds-flatfs#142 for details.
Routing V1 HTTP API now exposed by default
The Routing V1 HTTP API is now exposed by default at http://127.0.0.1:8080/routing/v1. This allows light clients in browsers to use Kubo Gateway as a delegated routing backend instead of running a full DHT client. Support for IPIP-476: Delegated Routing DHT Closest Peers API is included. Can be disabled via Gateway.ExposeRoutingAPI.
Track total size when adding pins
Adds total size progress tracking of pinned nodes during ipfs pin add --progress. The output now shows the total size of the pinned dag.
Example output:
Fetched/Processed 336 nodes (83 MB)
Improved IPNS over PubSub validation
IPNS over PubSub implementation in Kubo is now more reliable. Duplicate messages are rejected even in large networks where messages may cycle back after the in-memory cache expires.
Kubo now persists the maximum seen sequence number per peer to the datastore (go-libp2p-pubsub#BasicSeqnoValidator), providing stronger duplicate detection that survives node restarts. This addresses message flooding issues reported in #9665.
Kubo's pubsub is optimized for IPNS use case. For custom pubsub applications requiring different validation logic, use go-libp2p-pubsub directly in a dedicated binary.
New ipfs diag datastore commands
New experimental commands for low-level datastore inspection:
ipfs diag datastore get <key>- Read raw value at a datastore key (use--hexfor hex dump)ipfs diag datastore count <prefix>- Count entries matching a datastore prefix
The daemon must not be running when using these commands. Run ipfs diag datastore --help for usage examples.
🚇 Improved ipfs p2p tunnels with foreground mode
P2P tunnels can now run like SSH port forwarding: start a tunnel, use it, and it cleans up automatically when you're done.
The new --foreground (-f) flag for ipfs p2p listen and ipfs p2p forward keeps the command running until interrupted. When you Ctrl+C, send SIGTERM, or stop the service, the tunnel is removed automatically:
$ ipfs p2p listen /x/ssh /ip4/127.0.0.1/tcp/22 --foreground
Listening on /x/ssh, forwarding to /ip4/127.0.0.1/tcp/22, waiting for interrupt...
^C
Received interrupt, removing listener for /x/ssh
Without --foreground, commands return immediately and tunnels persist until explicitly closed (existing behavior).
See docs/p2p-tunnels.md for usage examples.
Improved ipfs dag stat output
The ipfs dag stat command has been improved for better terminal UX:
- Progress output now uses a single line with carriage return, avoiding terminal flooding
- Progress is auto-detected: shown only in interactive terminals by default
- Human-readable sizes are now displayed alongside raw byte counts
Example progress (interactive terminal):
Fetched/Processed 84 blocks, 2097152 bytes (2.1 MB)
Example summary output:
Summary
Total Size: 2097152 (2.1 MB)
Unique Blocks: 42
Shared Size: 1048576 (1.0 MB)
Ratio: 1.500000
Use --progress=true to force progress even when piped, or --progress=false to disable it.
Skip bad keys when listing
Change the ipfs key list behavior to log an error and continue listing keys when a key cannot be read from the keystore or decoded.
Accelerated DHT Client and Provide Sweep now work together
Previously, provide operations could start before the Accelerated DHT Client discovered enough peers, causing sweep mode to lose its efficiency benefits. Now, providing waits for the initial network crawl (about 10 minutes). Your content will be properly distributed across DHT regions after initial DHT map is created. Check ipfs provide stat to see when providing begins.
⏱️ Configurable gateway request duration limit
Gateway.MaxRequestDuration sets an absolute deadline for gateway requests. Unlike RetrievalTimeout (which resets on each data write and catches stalled transfers), this is a hard limit on the total time a request can take.
The default 1 hour limit (previously hardcoded) can now be adjusted to fit your deployment needs. This is a fallback that prevents requests from hanging indefinitely when subsystem timeouts are misconfigured or fail to trigger. Returns 504 Gateway Timeout when exceeded.
🔧 Recovery from corrupted MFS root
If your daemon fails to start because the MFS root is not a directory (due to misconfiguration, operational error, or disk corruption), you can now recover without deleting and recreating your repository in a new IPFS_PATH.
The new ipfs files chroot command lets you reset the MFS (Mutable File System) root or restore it to a known valid CID:
# Reset MFS to an empty directory
$ ipfs files chroot --confirm
# Or restore from a previously saved directory CID
$ ipfs files chroot --confirm QmYourBackupCID
See ipfs files chroot --help for details.
📋 Long listing format for ipfs ls
The ipfs ls command now supports --long (-l) flag for displaying Unix-style file permissions and modification times. This works with files added using --preserve-mode and --preserve-mtime. See ipfs ls --help for format details and examples.
📦️ Dependency updates
- update
go-libp2pto v0.46.0- Reduced WebRTC log noise by using debug level for pion errors (go-libp2p#3426).
- Fixed mDNS discovery on Windows and macOS by filtering addresses to reduce packet size (go-libp2p#3434).
- update
quic-goto v0.57.1 (incl. v0.56.0 + v0.57.0) - update
p2p-forgeto v0.7.0 - update
go-ds-pebbleto v0.5.8- updates
github.com/cockroachdb/pebbleto v2.1.3 to enable Go 1.26 support
- updates
- update
go-libp2p-pubsubto v0.15.0