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

Clean up and fix manual on profiles #8531

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Ericson2314
Copy link
Member

Motivation

  • Profile files section no longer conflates profiles in general and nix-env / nix profile profiles of mixing packages together in particular.

  • Deleting store info corrected (there is a foot-gun in Nix with --delete-generations old!)

Context

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.

Copy link
Contributor

@fricklerhandwerk fricklerhandwerk left a comment

Choose a reason for hiding this comment

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

I think the general direction is good, but it makes an already existing problem worse: This file is completely included in the nix-env and nix profile man pages under the "Files" section. But really we only need the location of those profile directories there.

I suggest splitting out yet another PR (yes, this is more work for you, but reviewing a page worth of technical documentation is also a lot of work) that completes the specification, and splits this page such that only the relevant bits are included in the man pages and link to this page for the complete spec. There we can pick apart the big new chunk, which is just too much to handle for me at this point.

doc/manual/src/command-ref/nix-env/delete-generations.md Outdated Show resolved Hide resolved
doc/manual/src/command-ref/nix-env/delete-generations.md Outdated Show resolved Hide resolved
doc/manual/src/command-ref/nix-env/delete-generations.md Outdated Show resolved Hide resolved
doc/manual/src/command-ref/nix-env/delete-generations.md Outdated Show resolved Hide resolved
doc/manual/src/command-ref/files/profiles.md Outdated Show resolved Hide resolved
Comment on lines +58 to +67
## Symlink tree profile

Typical profiles created by [`nix-env`](@docroot@/command-ref/nix-env.md) (and indirectly by [`nix-channel`](@docroot@/command-ref/nix-channel.md) too) have additional structure.
The contents of each generation is not just can arbitrary store object, but a symlink tree merging together various other store objects.

Additionally, the store object contains a manifest file, providing some info on what those merged store objects are and where they came from:
- [`manifest.nix`](@docroot@/command-ref/files/manifest.nix.md) used by [`nix-env`](@docroot@/command-ref/nix-env.md).
- [`manifest.json`](@docroot@/command-ref/files/manifest.json.md) used by [`nix profile`](@docroot@/command-ref/new-cli/nix3-profile.md) (experimental).

### Filesystem layout
Copy link
Contributor

Choose a reason for hiding this comment

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

I really doubt that is important to show at all. But if you absolutely insist:

All of this could be summarised as FS layout. Are there atypical nix-env profiles? Let's reuse the wording on the manifest files.

Suggested change
## Symlink tree profile
Typical profiles created by [`nix-env`](@docroot@/command-ref/nix-env.md) (and indirectly by [`nix-channel`](@docroot@/command-ref/nix-channel.md) too) have additional structure.
The contents of each generation is not just can arbitrary store object, but a symlink tree merging together various other store objects.
Additionally, the store object contains a manifest file, providing some info on what those merged store objects are and where they came from:
- [`manifest.nix`](@docroot@/command-ref/files/manifest.nix.md) used by [`nix-env`](@docroot@/command-ref/nix-env.md).
- [`manifest.json`](@docroot@/command-ref/files/manifest.json.md) used by [`nix profile`](@docroot@/command-ref/new-cli/nix3-profile.md) (experimental).
### Filesystem layout
### Filesystem layout
Profiles created by [`nix-env`](@docroot@/command-ref/nix-env.md) (and indirectly by [`nix-channel`](@docroot@/command-ref/nix-channel.md)) have additional structure.
The contents of each profile is not just an arbitrary store object, but a tree of symlinks merging together multiple store objects.
Additionally, each profile contains a manifest file, specifying those store objects and recording their provenance:
- [`manifest.nix`](@docroot@/command-ref/files/manifest.nix.md) used by [`nix-env`](@docroot@/command-ref/nix-env.md).
- [`manifest.json`](@docroot@/command-ref/files/manifest.json.md) used by [`nix profile`](@docroot@/command-ref/new-cli/nix3-profile.md) (experimental).

Line 61 is still pretty weak, it doesn't tell me anything. It would be good to briefly state why it's done that way, e.g. because it's one store object per package? Apparently that tree has a particular structure to abide to Unix conventions?

Copy link
Member Author

Choose a reason for hiding this comment

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

I used "typically" because, nix-env --set is the low level command to directly create a generation with arbitrary contents.

Perhaps it would make more sense to talk about the manifest and then the symlinking. The manifest describes the "input" to the symlinking algorithm.

Copy link
Contributor

Choose a reason for hiding this comment

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

I used "typically" because, nix-env --set is the low level command to directly create a generation with arbitrary contents.

Then let's be more concrete and say which subcommand does it and what's the difference. "Typically" is just too vague to say anything useful.

A profile is a directory of symlinks to files in the Nix store.
## Profile

Profiles are a basic version control mechanism built atop more core Nix constructs and symlinks.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Profiles are a basic version control mechanism built atop more core Nix constructs and symlinks.
Profiles are a basic version control mechanism for package management with Nix.

Also the page should start with the Profiles section, and have a subsection for the profile data model and file system representation.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think this is true. The nix-env profiles with the symlink trees are for package mangement, but profiles in general are just versioning. E.g. NixOS generations aren't really package management per-se (imaging if there was no ad-hoc system packages, just stuff for configuration), but they do use it for versioning.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, agreed on the semantics. But still let's not vaguely refer to "core Nix constructs". What are those supposed to be, and can we refer to a definition at the moment?

This sentence so far is not helpful to me at all. What is to be version-controlled here? Maybe we can leave it out entirely?

doc/manual/src/command-ref/files/profiles.md Outdated Show resolved Hide resolved
doc/manual/src/command-ref/files/profiles.md Outdated Show resolved Hide resolved
Comment on lines +19 to +35
Profiles are represented on disk by symlinks within a directory that obey a certain structure.
Profiles have names, which allows storing more than one profile in the same directory.
The symlinks of a single profile all begin with the name of profile, which identifies which symlinks belong to which profile within a directory.
A combined `<profile-directory>/<profile-name>` path uniquely identifies a profile on the local file system, by specifying both its location and name.

Each generation is represented by a symlink with a name with 3 dash-separated components: `<profile-name>-<generation-number>-link`.
The leading `profile-` identifies which profile the generation belongs to.
The trailing `-link` identifies this symlink as a generation symlink.
The middle generation number is the "key" part of the generation key-value pair.
The symlink target is a store paths, which in turn point to the store object that is the "value" part of the generation key-value pair.
The creation time of the symlink is used for time-based garbage collection operations of generations.
Other metadata is not used.

The current/active generation is specified by a symlink that is just the name of the profile: `<profile-name>`.
The target of the symlink is *not* a store path, but instead the name of a generation symlink (which is a relative path to that symlink within the current directory).

Each of these symlinks is a root for the Nix garbage collector.
Copy link
Contributor

Choose a reason for hiding this comment

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

This is way too much for me to unpack in a review. I think I understand what you're doing here, but the phrasing confuses me a lot. I would rather represent this with more structure, and do that in a separate PR so we can merge the good bits from this one.

- An map of zero or more generations, each mapping a *generation number* to a [store object](@docroot@/glossary.md#gloss-store-object).

- An optional *current* or *active* generation, which is one of those in the map.

Copy link
Member

Choose a reason for hiding this comment

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

This definition is precise but doesn't really explain what profiles are for, other than a "basic version control mechanism". It should probably have some introductory line that explains that profiles enable atomic upgrades and rollbacks of (sets of) packages.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is the "files" section I thought was supposed to be more about how things are represented on disk. I think separately the concepts / data model itself should be documented without this minutiae.

(C.f. Platonic "file system object"s vs the grubby details of normalizing timestamps, permissions, file system ACLs, and other such things.)

Profiles are a basic version control mechanism built atop more core Nix constructs and symlinks.
Profiles consiste of

- An map of zero or more generations, each mapping a *generation number* to a [store object](@docroot@/glossary.md#gloss-store-object).
Copy link
Member

Choose a reason for hiding this comment

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

Note that nix profile no longer exposes the term "generation" and instead uses "version". Maybe we should do that here as well.

The symlinks of a single profile all begin with the name of profile, which identifies which symlinks belong to which profile within a directory.
A combined `<profile-directory>/<profile-name>` path uniquely identifies a profile on the local file system, by specifying both its location and name.

Each generation is represented by a symlink with a name with 3 dash-separated components: `<profile-name>-<generation-number>-link`.
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this be in the "filesystem layout" subsection?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think I mean that to just be "example" really, as per the above I think this whole chapter is "filesystem layout".

@Ericson2314
Copy link
Member Author

Happy to split again. Did that in #8565

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/flakes-as-a-unified-format-for-profiles/29476/7

Profile files section no longer conflates profiles in general and
`nix-env` / `nix profile` profiles of mixing packages together in
particular.

Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
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.

None yet

4 participants