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

Refactor Store hierarchy with a new IndirectRootStore interface #8243

Merged
merged 3 commits into from
Jul 24, 2023

Conversation

Ericson2314
Copy link
Member

@Ericson2314 Ericson2314 commented Apr 20, 2023

Motivation

  • This is preparatory work needed for the "mounted ssh store" feature implemented in Mounted SSH Store #7912. That feature is very useful for Nix with NFS, as in common in organization settings.

  • Even without the above feature, I think it bring greater clarity to the relationship between the existing stores, and between addIndirectRoot and addPermRoot.

    As an example of the above:

    • Without this, SSHStore had a remote-side addIndirectRoot implementation, but that makes no no sense. SSHStore does not expose the ambient file system, and so one should run the risk of accidentally making symlinks on the remote side that make no sense.
  • With this, SSHStore does not have an addIndirectRoot method at all.

See the extensive API docs for more details.

Context

#7912 will be rebased on top once this is merged. It will then be much smaller.

The commits here are separated for easier review.

#5729 is somewhat related, though in this case we are cleaning up the subclasses not Store itself.

(Note can review commit-by-commit.)

Checklist for maintainers

Maintainers: tick if completed or explain if not relevant

  • agreed on idea
  • agreed on implementation strategy
  • tests, as appropriate
    • functional tests - tests/**.sh
    • unit tests - src/*/tests
    • integration tests - tests/nixos/*
  • documentation in the manual
  • documentation in the internal API docs
  • code and comments are self-explanatory
  • commit message explains why the change was made
  • new feature or incompatible change: updated release notes

Priorities

Add 👍 to pull requests you find important.

@github-actions github-actions bot added the store Issues and pull requests concerning the Nix store label Apr 20, 2023
@Ericson2314 Ericson2314 mentioned this pull request Apr 20, 2023
7 tasks
@thufschmitt thufschmitt self-assigned this May 12, 2023
@fricklerhandwerk
Copy link
Contributor

fricklerhandwerk commented May 15, 2023

Discussed in Nix team meeting 2023-05-12:

  • @Ericson2314:
    • Preperatory refactor for the "mounted SSH store" concept.
    • Original PR, and this step, already discussed in prior meeting; agreed on this tentative implementation strategy (behind experimental feature)
    • Have split this PR because it is ready to go (whereas the rest needs tests etc., since it is new feature)
    • Want to keep things moving so outside contributor feels progress (this is a yak shave they are stuck waiting for)
  • assigned @thufschmitt for review

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2023-05-12-nix-team-meeting-minutes-54/28197/1

Copy link
Member

@thufschmitt thufschmitt left a comment

Choose a reason for hiding this comment

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

I'm a bit “meh” on that change. I see where it's coming from, but at the same time, the API and implementation of IndirectRootStore::addPermRoot pretty much force any instance of it to be baked by a locally mounted filesystem. This means that – unless I'm overlooking something – any instance of IndirectRootStore could be made an instance of LocalFSStore (and benefit from some performance benefits by bypassing the daemon where it can be).

(Btw, 781ead0 seems unrelated to that PR except that it is also part of #7912)

Comment on lines 83 to 85
* - The base Store class has Store::addTempRoot() because for a store
* that doesn't support garbage collection at all, a temporary GC root
* is safely implementable as no-op.
Copy link
Member

Choose a reason for hiding this comment

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

This is debatable when the same store can be accessed in different ways where one can be gc-ed and the other can't (For instance I can't add a root over ssh, but that doesn't prevent someone from gc-ing that store locally)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah that is a good point. I guess I will reward this comment as tech debt TODO instead :).

Copy link
Member Author

Choose a reason for hiding this comment

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

Added below.

Comment on lines 87 to 92
* - The derived LocalFSStore class has LocalFSStore::addPermRoot,
* which is not part of this class because it relies on the notion of
* an ambient file system. There are stores (`ssh-ng://`, for one),
* that *do* support garbage collection but *don't* expose any file
* system, and LocalFSStore::addPermRoot thus does not make sense for
* them.
Copy link
Member

Choose a reason for hiding this comment

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

That's not true any more since addPermRoot is part of IndirectRootStore, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

No the abstract method is still in LocalFSStore. IndirectRootStore merely has an implementation. The next PR ads another implementation.

src/libstore/indirect-root-store.hh Outdated Show resolved Hide resolved
* possible implementations many of which make no sense. Having this and
* that invariant enforced cuts down that space.
*/
struct IndirectRootStore : public virtual LocalFSStore
Copy link
Member

Choose a reason for hiding this comment

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

I think that name is not great. The most important bit here isn't that the store can register indirect roots (any ssh-ng could in theory), but that it can register permanent roots (although addPermRoot is implemented and final here, it only makes sense for stores that have a local filesystem baking)

Copy link
Member Author

Choose a reason for hiding this comment

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

The important bit is in fact the indirect roots.

it only makes sense for stores that have a local filesystem baking

It is a subclass of LocalFSStore, so unless you meant something like "non ssh/NFS" by "local" that is in fact always the case.

LocalFSStore defines addPermRoot. So the point of this class isn't to define that interfaec, but to merely implement it. The point is the indirect root implementation.

@Ericson2314
Copy link
Member Author

@thufschmitt I think you got the inheritance backwards.

Any instance of IndirectRootStore could be made an instance of LocalFSStore (and benefit from some performance benefits by bypassing the daemon where it can be).

Any instance must be that, because IndirectRootStore is the addPermRoot implementation while LocalFSStore just defines the addPermRoot interface.

@Ericson2314 Ericson2314 force-pushed the indirect-root-store branch 2 times, most recently from fa61b44 to 00edcac Compare June 6, 2023 22:45
@Ericson2314
Copy link
Member Author

(Btw, 781ead0 seems unrelated to that PR except that it is also part of #7912)

It is needed so that UdsRemoteStore::addIndirectRoot can be implemented in a separate file.

@thufschmitt
Copy link
Member

I think you got the inheritance backwards.

Indeed, I missed the “IndirectRootStore inherits from LocalFSSTore” bit. But that still doesn't seem right to me: It's not clear why we need an extra class for this (we could simply have this be part of the LocalFSStore interface). Is there any store that could have a reason to be made a LocalFSStore but not an IndirectRootStore?

Also,

SSHStore had a remote-side addIndirectRoot implementation, but that makes no no sense

Feels a bit weak as a justification to me. This feels less of an issue to me than having to leak the ConnectionHandles from the remote store implementation just for the sake of deferring the implementation of addIndirectRoot

@Ericson2314
Copy link
Member Author

Ericson2314 commented Jun 8, 2023

Is there any store that could have a reason to be made a LocalFSStore but not an IndirectRootStore?

Yes, the MountedSSHStore in the folllow-up PR.

The client only does addPermRoot, and the server (or intermediary if another daemon) does the rest, in order to race conditions / the need for extra synchronization.

The table, which I save for that follow-up PR, is supposed to answer this question (given these leaf classes, we have these combinations to support with intermediate classes...).

This feels less of an issue to me than having to leak the ConnectionHandles from the remote store implementation just for the sake of deferring the implementation of addIndirectRoot

I made the type protected in the subclass so it doesn't actually leak. I would be happy to put it in a separate header too so things that don't care / can't use it don't even see it.

@thufschmitt thufschmitt assigned tomberek and unassigned thufschmitt Jul 24, 2023
This is because `StoreConfig` also uses it.
Copy link
Contributor

@tomberek tomberek left a comment

Choose a reason for hiding this comment

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

Comments help describe the structure and motivation. Implementation makes sense, builds, and allows for the planned future changes in #7912 (and any additional alternative store implementations, also can be useful for layered stores)

Will need to do subclass-specific implementations in the next commit.
This isn't because there will be multiple variations of the daemon
protocol (whew!) but because different clients pick and choose different
parts to use.
See the API doc comments for details.
@Ericson2314 Ericson2314 force-pushed the indirect-root-store branch from 00edcac to 60d8dd7 Compare July 24, 2023 13:20
@Ericson2314 Ericson2314 enabled auto-merge July 24, 2023 13:23
@Ericson2314 Ericson2314 merged commit 40c77f3 into NixOS:master Jul 24, 2023
@Ericson2314 Ericson2314 deleted the indirect-root-store branch July 24, 2023 14:08
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2023-07-24-nix-team-meeting-minutes-74/31116/1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
store Issues and pull requests concerning the Nix store
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

6 participants