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

Move host and suite implementation logic to lib #216

Merged
merged 6 commits into from
Mar 29, 2021

Conversation

Pacman99
Copy link
Member

This is just the mkSuites and mkHosts part of the mkDevos PR. I would like to avoid changing mkSuites and mkHosts api, to make it easier to rebase changes into the mkDevos branch. But if necessary we can change them. And to that end, there is some more logic added to the flake.nix now which would ideally not be there if devos was meant to be a template. But since the goal is to move towards a lib function with template, this is just a step in that direction.

flake.nix Outdated
Comment on lines 39 to 53
suites = import ./suites;
users = os.mkProfileAttrs "${self}/users";
profiles = os.mkProfileAttrs "${self}/profiles";
userProfiles = os.mkProfileAttrs "${self}/users/profiles";
};

multiPkgs = os.mkPkgs;

outputs = {
nixosConfigurations =
import ./hosts (nixos.lib.recursiveUpdate inputs {
inherit multiPkgs extern;
defaultSystem = "x86_64-linux";
lib = nixos.lib.extend (final: prev: {
dev = self.lib;
});
});
nixosConfigurations = os.mkHosts {
dir = "${self}/hosts";
overrides = import ./overrides;
Copy link
Member Author

Choose a reason for hiding this comment

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

All paths here have to passed as strings or nix says paths aren't allowed to refer to the flake store path. Makes no sense to me since those paths are within the flake, but this is the workaround.

Copy link
Contributor

@blaggacao blaggacao Mar 27, 2021

Choose a reason for hiding this comment

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

That means even ./hosts does not work? If so, that's really "interesting".

Copy link
Member Author

Choose a reason for hiding this comment

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

Yup, I dealt with this in the mkFlake PR by converting everything to string using apply keys. But I don't have that option here. I think its because of builtins.readDir reacting weirdly to paths. But overall I think I've found when working with store paths, everything is just easier if their strings.

@@ -27,7 +27,7 @@ let mkProfileAttrs =
f = n: _:
lib.optionalAttrs
(lib.pathExists "${dir}/${n}/default.nix")
{ default = /. + "${dir}/${n}"; }
{ default = builtins.toPath "${dir}/${n}"; }
Copy link
Member Author

Choose a reason for hiding this comment

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

store paths cannot be appended to paths. This is a deprecated function(I think?), but it is the only way I found of converting a store path to a 'path' type. And we need these as paths for the disabledModules part of isoConfig to work.

Copy link
Collaborator

Choose a reason for hiding this comment

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

disabledModules should also work by using a partial path string relative to the systems nixpkgs/nixos/modules directory. So maybe this isn't needed after all.

Copy link
Member Author

Choose a reason for hiding this comment

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

But we are trying to disable paths in devos, so we can't pass anything relative to nixpkgs/nixos/modules. The other option is to set modulesPath to "profiles/" but I'm not sure if that breaks other things in the module system. I think its better to just include this change for now, to get these functions working. And in the future work out a way to pass these paths as strings and still get it to work with disabledModules. I want to avoid changing isoConfig in this PR.

Copy link
Contributor

@blaggacao blaggacao Mar 27, 2021

Choose a reason for hiding this comment

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

disabledModule is less brittle when working with keys. In a sharing model, modules can also come from external devos flakes.

Equality of store paths is cheap even in those scenarios. Equality of relative path-strings sets us up for trouble.

Copy link
Collaborator

@nrdxp nrdxp Mar 27, 2021

Choose a reason for hiding this comment

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

I believe this is the cause of the BORS failure. For whatever reason, the core in mkHosts and this the one imported here have different hashes, meaning toPath must have changed it somehow. We may want to figure out exactly how, or #136 may be reopened.

edit

actually I was wrong. I'm gonna work on this later tonight and try to at least determine the real cause.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems to work as just "${dir}/${n}", had you tried that before toPath?

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 I know that works. The reason this has to be passed as a path is for the disabledModules section of isoConfig. If you look here: https://github.com/NixOS/nixpkgs/blob/1dfe690209af14a91b32dbf2f379ca02d050e1a1/lib/modules.nix#L241

Any string passed to disabledModules is always appended to modulesPath. But if you pass it as a path, then it works.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ohh I just read your commit message, I guess toPath doesn't help either.

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 this PR will just break isoConfig then. We will need to find a better fix for that.

Copy link
Collaborator

@nrdxp nrdxp Mar 28, 2021

Choose a reason for hiding this comment

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

Ah, now I see, so we could probably just map (x: /. + x) to fix isoConfig. Or maybe we could remove the string context before converting to a path with /. so we can keep profiles as proper paths in the first place.

@blaggacao
Copy link
Contributor

blaggacao commented Mar 27, 2021

Can you check if it works with just declaring relative paths? (./hosts, etc.)

Otherwise this changes is already really enjoyable to see.

What's really nice about this:

  • in flake.nix we have the top level inputs
  • but we also can see what the precise inputs are for devos specific functions (in a clear and simple way)

So overall, I feel it's easier (even for newcomers with a little bit of programming knowledge) to "see what's going on".

@Pacman99
Copy link
Member Author

Can you check if it works with just declaring relative paths? (./hosts, etc.)

Heres the error I get:

error: access to path '/nix/store/i3z291bqqjmsgr4mpv8ys90da7h1nazy-hosts/NixOS.nix' is forbidden in restricted mode
(use '--show-trace' to show detailed location information)

I have no clue whats happening, because that store path that it is talking about actually exists and there is a README and NixOS.nix in there. Which means at some point some function ended up getting nix to create a new store path for the directory it was reading with the necessary files, and then error itself out because it doesn't ave access to those files.

Copy link
Contributor

@blaggacao blaggacao left a comment

Choose a reason for hiding this comment

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

Maybe this could be the culprit...

lib/devos/mkHosts.nix Show resolved Hide resolved
@Pacman99
Copy link
Member Author

So the only solution I can think of for the paths issue is change any lib function that uses builtins.readDir to convert the dir to a string before passing it to the builtin. I really don't like the solution though.

@blaggacao
Copy link
Contributor

blaggacao commented Mar 27, 2021

I really don't like the solution though.

If we call it an "anti corruption layer" against nix quircks, would that appease?

I think, as a general rule, working with paths is always a better option, simply because it is a richer type to mean the same.

@Pacman99
Copy link
Member Author

I would actually argue the opposite, specially for store paths. All of nixpkgs passes around store paths as strings. And I think nix in general treats paths as a shorthand to represent a string. So paths actually have more chance for corruption since they can be relative or absolute and can cause issues with builtin functions. String paths on the other hand are always absolute and they universally work on all builtin functions. While I would like users to be able to pass in paths, I think of it more of a convenience and the mkFlake PR does allow this and solves the issue by converting to string immediately.

@Pacman99
Copy link
Member Author

But for this PR since we are still in the stage of devos where users aren't necessarily meant to edit their flake.nix, It think the current solution is best to just pass the paths as strings for profiles/hosts.

@blaggacao
Copy link
Contributor

blaggacao commented Mar 27, 2021

LGTM! Let's address this separately and get this rather merged.

Strange thing that nixpkgs prefers strings over paths. At the very least it's bad semantics and an absent anti corruption fuse somewhere deep down.

As I understand it, paths are checked for equality by their internal nix store paths, hence wether relative or absolute, they seem to be always canonicalized.

@blaggacao
Copy link
Contributor

bors r+

@bors
Copy link
Contributor

bors bot commented Mar 27, 2021

👎 Rejected by too few approved reviews

Copy link
Contributor

@blaggacao blaggacao left a comment

Choose a reason for hiding this comment

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

LGTM (from cell phone)

@blaggacao
Copy link
Contributor

bors r+

bors bot added a commit that referenced this pull request Mar 27, 2021
216: Move host and suite implementation logic to lib r=blaggacao a=Pacman99

This is just the `mkSuites` and `mkHosts` part of the `mkDevos` PR. I would like to avoid changing mkSuites and mkHosts api, to make it easier to rebase changes into the mkDevos branch. But if necessary we can change them. And to that end, there is some more logic added to the flake.nix now which would ideally not be there if devos was meant to be a template. But since the goal is to move towards a lib function with template, this is just a step in that direction.

Co-authored-by: Pacman99 <pachum99@gmail.com>
@bors
Copy link
Contributor

bors bot commented Mar 27, 2021

Build failed:

@Pacman99
Copy link
Member Author

Pacman99 commented Mar 27, 2021

huh core is being imported twice in profilesTest. Ohh so core is being imported by mkHosts, and since profile's test imports allProfiles it gets imported twice. @nrdxp why was this not an issue before? I'm not sure what I changed to only trigger this now.

@nrdxp
Copy link
Collaborator

nrdxp commented Mar 27, 2021

Is it the same issue from #136? Essentially we fixed it by insuring that all profiles in mkProfilesAttrs a just a path to the profile, since the nix module system seems to compare the paths and remove redundant entries from imports, but it doesn't do the same for a module function.

Update

After pulling the branch and running nix flake check the profilesTest passed without issue. Perhaps this is another issue with stable nix. It could be that toPath was deprecated in the unstable branch and has different behavior in stable. In any case, we can probably just filter out core from allProfiles since it is always present via mkHosts regardless.

2nd Update

Okay, so I actually built profilesTest with nixStable and it passed on my machine locally. So I'm actually a bit confused about what caused the failure in CI now.

/cc @blaggacao @Pacman99

@blaggacao
Copy link
Contributor

👍 for filtering out core from allProfiles.

@Pacman99
Copy link
Member Author

Yeah I am a little confused, it should have been able to filter it out, relative and absolute paths compare well
Also random idea, maybe core could be a module thats enabled by default instead. So that way users can customize what they want out of core. something like devos.core.enable.

@Pacman99
Copy link
Member Author

bors try

bors bot added a commit that referenced this pull request Mar 27, 2021
@bors
Copy link
Contributor

bors bot commented Mar 27, 2021

try

Build failed:

@nrdxp
Copy link
Collaborator

nrdxp commented Mar 27, 2021

Since this PR also introduces new lib functions. A minimal test case is in order to ensure corner cases are worked out, or at least documented before merge. I am gonna try to help out with this later tonight when I have more time.

@Pacman99
Copy link
Member Author

Since this PR also introduces new lib functions. A minimal test case is in order to ensure corner cases are worked out, or at least documented before merge. I am gonna try to help out with this later tonight when I have more time.

That would be great! I'm not sure how to write tests for lib functions, so any demonstration would be helpful.

@nrdxp
Copy link
Collaborator

nrdxp commented Mar 28, 2021

Sorry for force push, meant to send it to divnix branch but got pushed to yours by mistake. I didn't actually change your commits, only added and then removed one, so it should still be the same. Just experimenting with the CI issue.

@Pacman99
Copy link
Member Author

Pacman99 commented Mar 28, 2021

#223 should fix the CI issue. But that requires a consensus to actually move core to modules, which is a fairly big change - not code wise but api wise, since historically core has always been a profile.

@nrdxp
Copy link
Collaborator

nrdxp commented Mar 28, 2021

Pushed two commits that fixed CI (even if #223 is merged, it's nice to know what actually caused the issue), and removed the call to builtins.toPath. Will try to work up some tests for these funcitons now.

@nrdxp
Copy link
Collaborator

nrdxp commented Mar 28, 2021

bors try

bors bot added a commit that referenced this pull request Mar 28, 2021
@bors
Copy link
Contributor

bors bot commented Mar 28, 2021

try

Build succeeded:

@Pacman99
Copy link
Member Author

added a test for suites and profiles. Not sure how to do one for mkHosts, since that results in a nixosSystem which is really large, so writing the expected for that might not be possible..

@nrdxp
Copy link
Collaborator

nrdxp commented Mar 29, 2021

mkHosts should be fine without testing, since its results are technically tested when the test VM is booted in profilesTest. Of course I would like to make some more elaborate tests in the future, which will all rely on the logic in mkHosts to provide the system environment.

An example that comes to mind is shutdown hang (I hate it when systemd hangs on shutdown, I'd at least like to know if an update to nixpkgs is gonna cause my system to do it).

@Pacman99
Copy link
Member Author

That makes sense, then hopefully the testSuites I added is enough.
I cleaned up git history, and since mkHosts test isn't needed, this ready for review.

Comment on lines 21 to 24
# all strings in disabledModules get appended to modulesPath
# so convert each to list which is not a string but can be coerced to one
disabledModules = map (x: [ x ])
(lib.remove modules.core suites.allProfiles);
Copy link
Member Author

Choose a reason for hiding this comment

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

Best fix I could come up with to ensure the profiles still get disabled since we now pass profiles as strings again.

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

and nix doesn't allow store paths to be appended to relative paths

convert each to a list which doesn't get appended to modulesPath
Copy link
Collaborator

@nrdxp nrdxp left a comment

Choose a reason for hiding this comment

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

bors r+

@bors
Copy link
Contributor

bors bot commented Mar 29, 2021

Build succeeded:

@bors bors bot merged commit ed17d9e into divnix:core Mar 29, 2021
@Pacman99 Pacman99 deleted the hosts-suites branch April 1, 2021 20:13
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.

3 participants