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

nixuser: declarative user environments #9250

Open
wants to merge 11 commits into
base: master
from

Conversation

@ts468
Contributor

ts468 commented Aug 14, 2015

What is Nix User Profile (NixUP)? NixUP is a declarative configuration for the user environment. It is an equivalent to the NixOS configuration method that is based around 'nixos-rebuild' and '/etc/nixos/configuration.nix'. NixUP provides a module system for configuring the user environment and is intended as a replacement for the imperative 'nix-env' commands. NixUP allows to, e.g., install packages, manage user defined services and to manage resources.

NixUP consists of a new program, called 'nixup' and a declarative configuration rooted at '$XDG_CONFIG_HOME/nixup/profile.nix' (e.g. ~/.config/nixup/profile.nix). Basically, the workflow for managing the NixUP user profile is the same as how the NixOS system configuration is being managed. The 'profile.nix' is edited by the user, and then turned into an active environment through 'nixup'.

The important commands for using 'nixup' are:

nixup build
-- Builds a user profile. By default the profile is defined
in $XDG_CONFIG_HOME/nixup/profile.nix.

nixup login
-- Builds a user profile that will be activated on the next login.
That is similar to nixos-rebuild boot.

nixup switch
-- Builds a user profile and immediately switches to it.

nixup edit
-- Opens an editor with the current configuration.

NixUP also brings an small program that helps to install and to remove software packages. If 'config.imperativeNix.enable=true' is set in the 'profile.nix' configuration, then a program 'nix-package' becomes available that manages a list of packages to be installed into the user environment. By default the list is maintained at '$XDG_CONFIG_HOME/nixup/packages.nix', from where the list is read by a module of the NixUP system.

The commands for using 'nix-package' are:

nix-package install hello

nix-package remove hello

Note that the packages are not pinned at a particular version but are linked to the currently active nixpkgs channel. A way to pin a package will be provided later.

Besides managing software packages, NixUP also provides a way to manage user controlled services. NixUP allows to define services for 'systemd --user', similarly to how NixOS allows to define services for 'systemd'. That means that the feature of managing services within NixUP is bound very tightly to 'systemd', and will not be available on other platforms like OSX or Windows.

The last interesting feature of NixUP is that is allows to manage resources. That means, it allows to define files in 'profile.nix' that are then linked into the $HOME directory of a user, or into any sub-directory of $HOME. The necessary sub-directories and links are created as needed, and automatically removed when the 'profile.nix' changes. Automatically created sub-directories are removed if they are empty after all links have been removed. So NixUP has a built-in way for managing, e.g., dot-files.

@ts468

This comment has been minimized.

Contributor

ts468 commented Aug 14, 2015

Could I get some feedback and ideas about how to name the configuration tree for nixuser, please?

@nbp Can it be merged with #4594?

@jgeerds

This comment has been minimized.

Member

jgeerds commented Aug 14, 2015

Great work! 👍

@jagajaga

This comment has been minimized.

Member

jagajaga commented Aug 14, 2015

Why do we need this when we have .nixpkgs/config.nix where we can write our environments?
I think that's an redundant work and can confuse people.

@ts468

This comment has been minimized.

Contributor

ts468 commented Aug 14, 2015

Just to preempt a discussion about WHY we need it, don't be tricked by the simplicity of the settings that are available so far. Nixuser is intended as a central place where user environment related configuration options can be collected. So it goes beyond an individually created .nixpkgs/config.nix.

@jagajaga

This comment has been minimized.

Member

jagajaga commented Aug 14, 2015

That's an extra thing. I really don't see anything we don't have now that you want there.
The only thing we miss --- managing user dotfiles.

@dezgeg

This comment has been minimized.

Contributor

dezgeg commented Aug 14, 2015

For instance, per-user declarative systemd services (with e.g. the same start/stop and restart-if-config-changed logic that nixos-rebuild has) is something that needs nixuser-rebuild and can't be done with .nixpkgs/config.nix alone.

@ts468

This comment has been minimized.

Contributor

ts468 commented Aug 14, 2015

@jagajaga maybe you want to write a nixuser module to manage dot-files?---It would be great contribution!

@dezgeg

This comment has been minimized.

Contributor

dezgeg commented Aug 14, 2015

The Obligatory Bikeshed: The filename configuration.nix is sort-of already taken, in particular man configuration.nix already brings up the NixOS manual. Maybe something like ~/.nixuser/user-config.nix?

@nbp

This comment has been minimized.

Member

nbp commented Aug 14, 2015

Could I get some feedback and ideas about how to name the configuration tree for nixuser, please?

I will look deeply into it later.

@nbp Can it be merged with #4594?

I think so.

The problem I wanted to avoid is that we have to edit a configuration file to add packages.

I think nix-env is a convenient tool for installing new packages. But nixuser-rebuild only provide a NixOS like approach, which is not a user friendly CLI for installing/uninstalling packages.

@ts468

This comment has been minimized.

Contributor

ts468 commented Aug 14, 2015

@dezgeg Thanks for pointing that conflict out! I hoped we could mirror nixos-rebuild as much as possible and that motivated ~/.nixuser/configure.nix. Also, what do you think about nixup (nix user profile) instead of nixuser? It's used in #4594 and would also be a good choice. I'm just trying to collect opinions :)

@nbp Thanks for going to have a look! Let me know once I can go ahead with merging our two PRs. However, having an explicit configuration file where all installed packages have to be listed is exactly what I want to achieve! To me it is one of the most important features of NixOS that the whole configuration is in one file or place, and if possible I would like to have (exactly) the same for nixuser/nixup. And, text editors are still a very good CLI based configuration tool, i think ;) But of course you're right that a nice GUI would be highly appreciated! Maybe we can generate one semi-automatically from the module definitions, I think @matejc has been working on something like that.

@jagajaga

This comment has been minimized.

Member

jagajaga commented Aug 14, 2015

@copumpkin

This comment has been minimized.

Member

copumpkin commented Aug 15, 2015

Does this depend on NixOS, or could it work on other Nix platforms?

@ts468

This comment has been minimized.

Contributor

ts468 commented Aug 15, 2015

@copumpkin I think it should work on other platforms as well, but I haven't tested it.

@nbp

This comment has been minimized.

Member

nbp commented Aug 15, 2015

@nbp Can it be merged with #4594?

Apart from the options for managing the nixpkgs configuration, and the user packages / path, it seems that our implementations can safely be merged, except for renaming integration.

Honestly, I prefer the approach taken in NixOS, which is to have a central list of build targets stored in user.build, and then the top-level script nixuser-rebuild should pull any installable targets from this attribute set.

The interesting part of NixUP is the implementation of the activation script and the resources files, which ideally should be executed by the shell at the start-up of the shell. This activation script serves as an init-system for the user home directory.

I am not convinced by the -rebuild in the nixuser-rebuild name, as I consider this to be an implementation detail.

However, having an explicit configuration file where all installed packages have to be listed is exactly what I want to achieve! To me it is one of the most important features of NixOS that the whole configuration is in one file or place, and if possible I would like to have (exactly) the same for nixuser/nixup. And, text editors are still a very good CLI based configuration tool, i think ;) But of course you're right that a nice GUI would be highly appreciated! Maybe we can generate one semi-automatically from the module definitions, I think @matejc has been working on something like that.

I agree, being able to define packages declaratively is nice, but the imperative style provided by nix-env is convenient.

What I was thinking about was to let the CLI tool generate the modules which are adding the packages in the environment.

@ts468

This comment has been minimized.

Contributor

ts468 commented Aug 15, 2015

@nbp Thanks for your feedback, I'll take it into account! I already had a closer look at how to merge the two implementations, and I have to say, I just started to fully understand and appreciate all the nice details that you put into NixUP! I think you've done an amazing job! Thank you very much for putting it together, it would be a shame if your work wouldn't make it upstream. I just hope I don't break too much while merging the two PRs.

I was reading up on the mailing list again about your introduction of your PR, especially the question when to activate a new user environment. I think it should be possible to have different options like nixup switch or nixup login or nixup shell to distinguish between an immediate activation, an activation with a new login or an activation just for the current shell. What do you think?

I like the idea about your CLI very much. What about a hidden configuration file outside of the nixup/nixuser configuration tree that is only managed by an CLI, and then sourced appropriately? I could imagine to have, e.g., ~/.nixup/profile/managed/{permanent,temporary} where packages are added or removed. The difference could be that the temporary packages are only available until the next rebuild of the declarative environment, whereas permanent packages are kept until they are removed. Could that work?

@nbp

This comment has been minimized.

Member

nbp commented Aug 15, 2015

I was reading up on the mailing list again about your introduction of your PR, especially the question when to activate a new user environment. I think it should be possible to have different options like nixup switch or nixup login or nixup shell to distinguish between an immediate activation, an activation with a new login or an activation just for the current shell. What do you think?

The problem, is that as opposed to NixOS, we can have multiple instances of the shell, which can share some common configuration, such as agent program which are running in the background, as long as there is one session open.

Doing it for the current shell sounds interesting, but then the question is how do you ensure that the configuration files are only visible within the current shell and only within any application started by this shell.

Since I read about buildFHSUserEnv, I was wondering if we could use a mount-point namespace solution to make such testing mechanism possible. Then the question, is why do we have a different solution for the testing mechanism and the standard mechanism. If we are going that way, then we should do it for everything. The problem, is that mount-point namespaces are a Linux only feature, as far as know, which makes this unpractical for MacOS users.

I like the idea about your CLI very much. What about a hidden configuration file outside of the nixup/nixuser configuration tree that is only managed by an CLI, and then sourced appropriately?

Yes, that's what I was thinking about, which is to have a ~/.nixup/generated/user.packages.firefox.nix module generated when you install firefox from the command line. And do the same for every option which is defined from the command line.

Basically, the name of the file is used as a simple way to manipulate each definition without having any knowledge on how modules are written & handled.

I could imagine to have, e.g., ~/.nixup/profile/managed/{permanent,temporary} where packages are added or removed. The difference could be that the temporary packages are only available until the next rebuild of the declarative environment, whereas permanent packages are kept until they are removed. Could that work?

That's sounds doable, but I would not worry about that right now.

@ts468 ts468 force-pushed the ts468:upstream.nixuser branch 2 times, most recently from 452a569 to f2fd2f5 Aug 23, 2015

@ts468

This comment has been minimized.

Contributor

ts468 commented Aug 23, 2015

I've pushed an updated version of the declarative user environment. I tried to merge with #4594. Have a look and give me some feedback, please!

@bjornfor

This comment has been minimized.

Contributor

bjornfor commented Aug 23, 2015

(I haven't had the time read everything, so I hope I'm not saying something silly, or something already suggested.)

Is it planned to be able to hook into user environments from /etc/nixos/configuration.nix?

I'm thinking that if "~/.nixup/profile.nix" contains

{ config, pkgs, ... }:
{
  user.packages = with pkgs; [ vim firefox thunderbird ];
}

then a similar option can exist in /etc/nixos/configuration.nix (options gets merged):

{ config, pkgs, ... }:
{
  users.extraUsers.<name>.packages = with pkgs; [ vim firefox thunderbird ];
}

Basically, options in "~/.nixup/profile.nix" can be rooted in configuration.nix at "users.extraUsers..*" (or something like it).

@ts468 ts468 force-pushed the ts468:upstream.nixuser branch from f2fd2f5 to 577c859 Aug 23, 2015

@ts468

This comment has been minimized.

Contributor

ts468 commented Aug 23, 2015

@bjornfor Thanks for your interest! Indeed, it is planed to make all NixUP options that are available under "~/.nixup/profile.nix" also available in the NixOS configuration, probably under "users.extraUsers..profile". However, I'm just not so sure how to merge the options defined in NixOS and NixUP, yet. Should they just be added up? Should the options defined in NixOS be defaults that can be overwritten with NixUP, or should that be prohibited? If you have any suggestions or ideas that would be great! :)

@nbp

This comment has been minimized.

Member

nbp commented Aug 24, 2015

Basically, options in "~/.nixup/profile.nix" can be rooted in configuration.nix at "users.extraUsers..*" (or something like it).

This can be done quite easily, as by design modules are valid submodules.

@benley

This comment has been minimized.

Member

benley commented Aug 29, 2015

I would love to be able to use something like this on non-NixOS systems, fwiw. One can approximate it with buildEnv in ~/.nixpkgs/config.nix, but it would be very, very nice to have something that actually handles user dotfiles.

# as subcomponents (e.g. the container feature, or nixops if network
# expressions are ever made modular at the top level) can just use
# types.submodule instead of using eval-config.nix
{ # !!! system can be set modularly, would be nice to remove

This comment has been minimized.

@anderspapitto

anderspapitto Aug 30, 2015

Contributor

can these first three (system, pkgs, baseModules) already be addressed (which I guess would mean removed, based on the comments?)

@@ -0,0 +1,4 @@
# TODO: remove this file. There is lib.maybeEnv now

This comment has been minimized.

@anderspapitto

anderspapitto Aug 30, 2015

Contributor

can this already be done?

ts468 added some commits Oct 18, 2017

nixos pam: add option "sessionCommands"
Add the option "sessionCommands" to security.pam.services. "sessionCommands"
gets executed by PAM right before the systemd user session is started.
Prepare nixos-rebuild.sh for NixUP
Nixos-rebuild.sh is generalized to be equally usable for NixOS and
for NixUP. Nixos-rebuild.sh is also renamed to nix__-rebuild.sh.
The changes do not affect the behaviour for NixOS.
Prepare switch-to-configuration.pl for NixUP
switch-to-configuration.sh is generalized to be equally usable
for NixOS and for NixUP.
The changes do not affect the behaviour for NixOS.

ts468 added some commits Nov 6, 2017

nixos nixup: add NixUP initialisation hooks
Add the configuration option "config.nixup.enable" which integrates the
activation scripts of NixUP into the user login and session handling of NixOS,
and provides the "nixup-rebuild" tool for managing NixUP.
Init NixUP.
Add the NixUP module system.

@ts468 ts468 force-pushed the ts468:upstream.nixuser branch from 0616978 to 3deede4 Nov 16, 2017

@davidak

This comment has been minimized.

Contributor

davidak commented Dec 16, 2017

This looks amazing. I also donated 50€.

Any progress since last comment?

@nbp

This comment has been minimized.

Member

nbp commented Jan 17, 2018

@ts468 I see that I am being asked for review, but at the same time I see 2000 lines addition. Is there a way to split this work in multiple digest PR?

showSyntax
;;
switch|boot|test|build|dry-build|dry-run|dry-activate|build-vm|build-vm-with-bootloader)
switch_*|boot_nixos|login_nixup|test_nixos|build_*|dry-build_nixos|dry-run_*|dry-activate_nixos|build-vm_nixos|build-vm-with-bootloader_nixos|edit_nixos)

This comment has been minimized.

@bobvanderlinden

bobvanderlinden Jan 27, 2018

Contributor

Doesn't this (and changes of commandline flags below) break the existing usage of nixos-rebuild?

@throwup

This comment has been minimized.

throwup commented Feb 1, 2018

Sorry if I am asking something that should already be clear but is this:

@bjornfor Thanks for your interest! Indeed, it is planed to make all NixUP options that are available under "~/.nixup/profile.nix" also available in the NixOS configuration, probably under "users.extraUsers..profile". However, I'm just not so sure how to merge the options defined in NixOS and NixUP, yet. Should they just be added up? Should the options defined in NixOS be defaults that can be overwritten with NixUP, or should that be prohibited? If you have any suggestions or ideas that would be great! :)

still a feature you intend to add? I like to define my system using a single git repository and would rather not link stuff to home directories manually. I read in another message, that this, based on how it's implemented, might "automatically" work, but I am not proficient enough at nix to judge that.

@timokau

This comment has been minimized.

Member

timokau commented Feb 23, 2018

What is blocking this right now? Is there any way to help push this forward?

@dasJ

This comment has been minimized.

Contributor

dasJ commented Mar 5, 2018

Yes, it is possible this gets into 18.03? Apart from some conflicts I don't see anything keeping it from merged

@IvanMalison

This comment has been minimized.

Contributor

IvanMalison commented Apr 16, 2018

@ts468 status?

@drvink

This comment has been minimized.

Contributor

drvink commented Apr 22, 2018

Is there a reason this has remained unmerged after nearly three years? The author's work is going to waste--it already needs another rebase and forward-porting effort now. It would be nice to at least hear from the Nix maintainers whether there are plans to integrate similar functionality.

@Nadrieril

This comment has been minimized.

Contributor

Nadrieril commented Apr 22, 2018

I personally think home-manager would be a better basis for this, as it is more featureful and actively developped

@IvanMalison

This comment has been minimized.

Contributor

IvanMalison commented Jun 4, 2018

Is there a reason this has remained unmerged after nearly three years? The author's work is going to waste--it already needs another rebase and forward-porting effort now. It would be nice to at least hear from the Nix maintainers whether there are plans to integrate similar functionality.

I personally think home-manager would be a better basis for this, as it is more featureful and actively developped

It would still be nice to hear something official from the maintainers, so that users of whichever system (be it nixup or homemanager) know which one is likely to be maintained and usable moving forward.

@bobvanderlinden bobvanderlinden referenced this pull request Jun 13, 2018

Open

Initial home contents #41858

4 of 8 tasks complete
@sheyll

This comment has been minimized.

sheyll commented Sep 16, 2018

Bumped into this, any progress?

@tbenst

This comment has been minimized.

tbenst commented Oct 22, 2018

If I understand correctly, one trade-off of NixUP vs home-manager is that NixUP requires NixOS whereas home-manager supports eg Ubuntu. Is my impression accurate? Hopefully, whatever solution is decided on will support other linux distros for home management, as some users will always have to deal with some non-NixOS systems.

@8573

This comment has been minimized.

Contributor

8573 commented Oct 26, 2018

Are there any similar proposals for declarative user environment management (or simply declarative dotfile management) that would be configured on a system-wide basis, in /etc/nixos/configuration.nix (e.g., in the users option hierarchy), rather than on a per-user basis, in configuration files inside the users' managed home directories?

@kalbasit

This comment has been minimized.

Member

kalbasit commented Oct 27, 2018

@8573 home-manager is capable of configuring dotfiles from the NixOS configuration located at /etc/nixos/configuration.nix. See the home-manager module here

Personally, I took it a step further. I made a home module (similar to NixOS modules) controlled by options under the namespace mine. I have another NixOS module that sets the home-manager.users.<name> to a function call that returns the set of options controlling the home module mentioned above. See this host as an example and I set the users here.

To give credit where credit is due, my system is inspired and based on @dustinlacewell's dotfiles and the IRC community.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment