Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support storing UnixFS 1.5 Mode and ModTime #10478

Merged
merged 30 commits into from
Aug 21, 2024
Merged

Conversation

gammazero
Copy link
Contributor

@gammazero gammazero commented Aug 13, 2024

Replaces #7754 written by @kstuart

Depends on:

Feature Progress

  • Can ipfs add with preserved mode and/or last modification time
    • on files
    • on directories
  • Can ipfs add with custom mode and/or last modification time
    • on files
    • on directories
  • Can ipfs get restoring mode and/or last modification time
    • on files
    • on directories
    • in archives
  • Can ipfs files chmod to change mode
    • on files
    • on directories
  • Can ipfs files touch to change last modification time
    • on files
    • on directories
  • Automatically update the last modification time when file data is changed or truncated (e.g. ipfs files write)
  • Can add files and directories with mode and/or modification time using multipart-form data
  • ipfs files stat reports mode and last modification time
    Note:
  • Adds support to kubo/core/rpc (may require additional tests).

Remaining Work before Merging

  • CI sharness needs to pass (details)
  • including mode/mtime while raw leaves are enabled should force use of dag-pb envelope and never produce a single raw block (details)
    • needs explicit test with --cid-version 0 and --cid-version 1

Related PRs

Implementation Notes

  • When adding files and directories without opting to store a mode or modification time the same CIDs are generated that would have been created before this feature was implemented (opt-in).
  • The Go runtime currently has no native support for restoring file mode and modification time on symbolic-links, support for restoring the last modification time has been added for Linux distributions and the following BSDs: freebsd, netbsd, openbsd, dragonflybsd.
  • Automatically updating a modification time will only occur if a modification time was previously stored.
  • When creating an archive, for compatibility, time resolution is to the second; Nanoseconds are not supported.

IPFS Add (CLI)

The ipfs add options --preserve-mode and --preserve-mtime are used to store the original mode and last modified time of the file being added, the options --mode, --mtime and --mtime-nsecs are used to store custom values, a custom value of 0 is a no-op as is providing --mtime-nsecs without --mtime.

The preserve flags and custom options are mutually exclusive, if both are provided the custom options take precedence.


Closes #6920
cc #10436

This commit introduces initial Mode and ModTime support
for single filesystem files and webfiles.

The ipfs add options --preserve-mode and --preserve-mtime are
used to store the original mode and last modified time of the
file being added, the options --mode, --mtime and --mtime-nsecs
are used to store custom values.

A custom value of 0 is a no-op.

The preserve flags and custom options are mutually exclusive,
if both are provided the custom options take precedence.

Majority of of the code was from #7754 written by kstuart

Replaces #7753

Closes #6920
@gammazero gammazero requested a review from a team as a code owner August 13, 2024 04:45
probably safer to error here, than printing line - if command was
executed over http it might be printed on the server, or break cli tools
that expect specific stdout rather than this line
@lidel lidel force-pushed the feat/unixfs1.5-mode-mtime branch 2 times, most recently from dfd32ed to f0fea76 Compare August 13, 2024 23:37
lidel and others added 3 commits August 14, 2024 01:54
was missing executable flag, so was skipped on ci
this should re-enable it
Copy link
Member

@lidel lidel Aug 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gammazero we seem to miss CIDv1 test here. CIDV1 uses --raw-leaves=true by default, and there is an edge case with small files that produce a single block that is both root and raw leave that was missed.

To reproduce the bug, below does not seem to preserve mode and mtime (small file produces raw block):

$ touch ./file # create empty file
$ chmod 654 ./file # custom mode
$ ipfs add --preserve-mode --preserve-mtime --cid-version 1 -Q ./file
bafkreihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku
$ ipfs files stat /ipfs/bafkreihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku
Size: 0
CumulativeSize: 0
ChildBlocks: 0
Type: file
Mode: not set (not set)
Mtime: not set

I think if user passes --preserve-* option, it should take precedence over --raw-leaves if the produced DAG is a single block.

Rationale:

  • A raw block has no surface for storing mode and mtime. Only dag-pb can store it, so --preserve-* options should make the root block dag-pb instead raw.
  • Alternative is erroring when both --raw-leaves=true and --preserve-* are passed and root block of one of files is raw, but that is a very bad ux: if someone imports a big directory, and has a small file deep inside, we don't want to error in the middle of a long import.

Copy link
Member

@lidel lidel Aug 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we've discussed this today, my understanding of next steps here is to implement below:

  • if the file is small enough to fit in a single block
    • and if both raw-leaves=true is set (likely implicitly due to CIDv1) and storing mode/mtime was requested by user (always explicit opt-in)
      • the default behavior will be to wrap block in dag-pb to create surface for storing mode/mtime

Copy link
Contributor Author

@gammazero gammazero Aug 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: Explicitly disable raw leaves if preserving mode or modification time.

@lidel Please check if my latest update does what is asked for above, without having to explicitly look at block sizes.

Copy link
Member

@lidel lidel Aug 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @gammazero. I think this is sensible UX to unblock 0.30.0-rc1.
We can refine if we get some feedback from users who requested mod/mtime that its not enough.

FYSA I've adjusted UX a bit in 01e6823, making it error in specific case when user explicitly passed raw-leaves flag to CLI/RPC, rather than having it enabled as implicit behavior of --cid-version 1.

test/sharness/t0047-add-mode-mtime.sh Show resolved Hide resolved
@lidel lidel mentioned this pull request Aug 14, 2024
32 tasks
lidel and others added 11 commits August 14, 2024 16:50
this will show us what values are read by 'stat' and compared by 'test'
when run on CI (tests fail there, but pass locally, so we need more
verbose log to debug this)
mountdir was used for both in and out, this isolates things
to ensure we dont mix inputs with outputs
turns out some github workers run with umask 002
which changes the default mode of files created with 'touch'

https://github.com/orgs/community/discussions/40876
#10478
Previously it only worked for a single object or top-level directory. This was only for rpc, as used by ipget, as it was already working for normal ipfs get.
this follows 'no surprises' rule.

if user provided --raw-leaves=true explicitly, means they care, and we error
to let them correct parameter manually

if user added file without raw-leaves flag, but we have cidv1 which
implies raw-leaves,  we assume user does not mind changing implicit
raw-leaves behavior
Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @kstuart and @gammazero.

Switched to boxo main with ipfs/boxo#653, identified touch|chmod bugs are fixed. CI is green.

Merging to start release of kubo 0.30.0-rc1 tomorrow and get some user feedback from folks that asked for mode and mtime.

@lidel lidel merged commit 263edb2 into master Aug 21, 2024
14 checks passed
@lidel lidel deleted the feat/unixfs1.5-mode-mtime branch August 21, 2024 00:02
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.

[BOUNTY] Implement UnixFSv1.5 in go-ipfs
2 participants