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

Make nix-modules available when defining user environments. #4493

Closed
wants to merge 3 commits into from

Conversation

ts468
Copy link
Contributor

@ts468 ts468 commented Oct 12, 2014

A new user specific configuration file is introduced.
It is located in "~/.nixuser/configuration.nix".
The idea is to have a declarative approach for defining the user environment
at some point. The configuration file acts as the input of a module evaluation
system, similar to "/etc/nixos/configuration.nix" for the NixOS configuration.

A new file "nixos/modules/nixuser-module-list.nix" is added.
The file lists modules that are made available both for system configuration
and for user configuration.
The file is imported by "nixos/modules/module-list.nix" and is used in
"pkgs/top-level/all-packages.nix".

@Fuuzetsu Fuuzetsu added the 0.kind: enhancement Add something new label Oct 12, 2014
@ts468
Copy link
Contributor Author

ts468 commented Oct 12, 2014

The PR itself does not change any derivation or package. It only provides a hook for nix-modules to be used in the nix packages configuration.

, # Allow a nixuser configuration attribute set to be passed in as an
# argument. Otherwise, it's read from $NIXUSER_CONFIG or
# ~/.nixuser/configuration.nix.
nixuserConfig ? null
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it make sense to make this a function?

@aristidb
Copy link
Contributor

I think it would be better if there was an actual usage, to estimate how close to the right approach this is. ;)

@lucabrunox
Copy link
Contributor

What's the problem in doing imports = [ my-module-list.nix ]; instead ?

On Sun, Oct 12, 2014 at 3:11 PM, Aristid Breitkreuz <
[email protected]> wrote:

I think it would be better if there was an actual usage, to estimate how
close to the right approach this is. ;)


Reply to this email directly or view it on GitHub
#4493 (comment).

www.debian.org - The Universal Operating System

Thomas Strobel added 2 commits October 12, 2014 15:55
A new user specific configuration file is introduced.
It is located in "~/.nixuser/configuration.nix".
The idea is to have a declarative approach for defining the user environment
at some point. The configuration file acts as the input of a module evaluation
system, similar to "/etc/nixos/configuration.nix" for the NixOS configuration.

A new file "nixos/modules/nixuser-module-list.nix" is added.
The file lists modules that are made available both for system configuration
and for user configuration.
The file is imported by "nixos/modules/module-list.nix" and is used in
"pkgs/top-level/all-packages.nix".
VimProfile allows to wrap vim with different configurations.
A configuration is composed by enabling and customizing pre-defined modules.
A module is a set of vim plugins and vimrc statements that are tightly linked.
Configurations are hierarchical and can inherit from each other.
The base of each hierarchy of configurations is a distingued default configuration.
Enabled vim configurations appear as normal package in nix, and have to be
installed accordingly.

The vimProfiles are declared either for system wide installations in
/etc/nixos/configuration.nix, or for each user in ~/.nixuser/configuration.nix.

An example for a vim configuration, here the content of ~/.nixuser/configuration.nix:

{ config, pkgs, ... }:
with pkgs;
{
  programs.vim =
    { enable = true;
      leader = " ";
      general.enable = true;
      statusline.enable = true;
      profiles =
        {  # Haskell configuration
          hvim =
            { enable = true;
              exec = { package = pkgs.vim_configurable; bin = "bin/vim"; };
              search.enable = true;
              # leader can be overwritten independently for each module
              search.leader = "|";
              text.enable = true;
              sidebar.enable = true;
              # overwrite default key binding
              sidebar.toggleUndo = "<Leader>uu";
              completion.enable = true;
              haskell.enable = true;
            };
          # graphical Haskell configuration
          hqvim =
            { enable = true;
              # set the name to call the wrapped vim
              name = "Hvim";
              parent = "hvim";
              exec = { package = pkgs.qvim; bin = "bin/qvim"; };
              # just as an example that inherited modules can also be disabled
              search.enable = false;
            };
          # same configuration as for default, but with qvim
          qvim =
            { # don't make that profile installable
              enable = false;
              exec = { package = pkgs.qvim; bin = "bin/qvim"; };
              # if no name attribute is given, the attribute name
              # of the configuration is taken: "qvim"
            };
          # alias declaration for qvim
          gvim =
            { enable = true;
              # inherit from a configuration by its attribute name
              # you can inherit from a disabled configuration as well
              parent = "qvim";
              # add statement to the generated vimrc; it is inserted
              # before any module statement
              vimrc = ''
                " Leader key timeout
                set tm=2000
                '';
            };
        };
    };
}

The declaration above defines the following packages in nix:
"vimProfile.hvim", "vimProfile.hqvim" and "vimProfile.gvim".
When the default profile is enabled, it is automatically installed with
the package "vim".
An un-wrapped vim package is always available with "vimPlain".
@ts468
Copy link
Contributor Author

ts468 commented Oct 12, 2014

@aristidb , I don't quite understand what you want to make a function. Do you mean it should be possible to pass in a configuration through a function argument like for "nixpkgs/config.nix"?

@lethalman, sorry, I'm lost. Where would you suggest to import what?

@lucabrunox
Copy link
Contributor

@ts468 I don't get the usefulness of this PR, can you explain? If you want
to load a list of modules which is not in nixpkgs, you can use imports = [ ... ];, instead of introducing another way to import nix expressions.

On Sun, Oct 12, 2014 at 4:06 PM, ts468 [email protected] wrote:

@aristidb https://github.com/aristidb , I don't quite understand what
you want to make a function. Do you mean it should be possible to pass in a
configuration through a function argument like for "nixpkgs/config.nix"?

@lethalman https://github.com/lethalman, sorry, I'm lost. Where would
you suggest to import what?


Reply to this email directly or view it on GitHub
#4493 (comment).

www.debian.org - The Universal Operating System

@ts468
Copy link
Contributor Author

ts468 commented Oct 12, 2014

@lethalman, what I want to have is a "nixuser" configuration file, similar to what "/etc/nixos/configuration.nix" is for NixOS.
I want to be able to pass a user specific configuration to a set of modules---which are provided like any nixos module---, evaluate the modules, and then, in all-packages.nix, configure the packages in nixpkgs.

In particular for vimProfiles, I start with a configuration for different vim profiles, that is a collection of vim plugins and customized key bindings, and then generate a package for each vim profile. The packages can then be installed independently.

It is also possible to declare and install the packages within the NixOS system configuration.
To collect all packages that are meaningful for the nixuser and the nixos configuration, I added "nixos/modules/nixuser-module-list.nix"

Does that help and make sense?

@offlinehacker
Copy link
Contributor

I just use nixops for my local system, and it works great.

On Sun, Oct 12, 2014 at 5:42 PM, ts468 [email protected] wrote:

@lethalman https://github.com/lethalman, what I want to have is a
"nixuser" configuration file, similar to what
"/etc/nixos/configuration.nix" is for NixOS.
I want to be able to pass a user specific configuration to a set of
modules---which are provided like any nixos module---, evaluate the
modules, and then, in all-packages.nix, configure the packages in nixpkgs.

In particular for vimProfiles, I start with a configuration for different
vim profiles, that is a collection of vim plugins and customized key
bindings, and then generate a package for each vim profile. The packages
can then be installed independently.

It is also possible to declare and install the packages within the NixOS
system configuration.
To collect all packages that are meaningful for the nixuser and the nixos
configuration, I added "nixos/modules/nixuser-module-list.nix"

Does that help and make sense?


Reply to this email directly or view it on GitHub
#4493 (comment).

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.11 (GNU/Linux)

mQENBFEY1PEBCADPOfERF2wo4qeoq9L1m2z4pKfWqNd4B6BsoFUWPNd7BXmY+9JG
jJddSkmYobWec7XjAFTBL0Xbttt+rK9SIED2dCOmU1FYMQElhGlM3PNA3kaiQFeV
ijgH318GCfZzDd0dWa5TN/IshVeWXwgngsIEmZTVf1VSeb3eO3B8Fxe3zsSLUq0b
71MmU5eLVP9pMkm5V5BTYp+lV70FIekKygkKq+uTDo1csWUatbs4Qvgv37Bymy2t
oTwOBXGoinQk5N/6asR1jWs3vKv0L0SruoZy/kEG/jXb4l2OZUP85EVMganYKouE
OchVmcmhBdWV+t3HK4r2ATfyEcMRzvzSflA1ABEBAAG0Jkpha2EgSHVkb2tsaW4g
PGpha2FodWRva2xpbkBnbWFpbC5jb20+iQE+BBMBAgAoBQJRGNTxAhsDBQkB4TOA
BgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRD6Zxi5hZclKnXNCACLOKa8abQp
eTWv9SXUwC7LVM5pP2mXcgn+Ipqr6YWBdLx4Iij0YlvUok9VeKvwTpUlT+cx++o3
wCM3AYrUyJE+zrtw49lInUmutz9seqJLU895oq+D+UuGoORrLBpEZrYR5f83uUmQ
E3Z1ZmWrNGXYtITWDtVZD/KauMF2nkPcmy/XaYXhd4WHD81DGNlKtGAHig6A3Phc
8Mr0A4yLDeRQJm8lCFEsxMJUNTupgY+ybbsMfVGx1gQvvGOTioV8CLCoRchUCCcm
YPArFg40KzIDSNjwdo9EVZDnlPx1hbOppfQydxP+JVnZsqoYmVY4UhIWi/NfOl3V
UMjl338INW1zuQENBFEY1PEBCADRSIfelOMjaTH7IfpMFFUc5Gys//njFnW9QAUg
wyfs2AFxUp6vKQ7nxXQiJXVhKTwe9iqo+oGxaHp4AeTjC7vXsfMuF5g5lfttbAo3
YEobEe6OG5so41nbwan6SyeIIQ2AmQqJBw8TKKMSec2qUN0Pw7iZRs0o9uJM/obG
DPsAsMOQgNLxJyMCP7X2jBtDXxkMFVHMmk50Tl3h3Fi9qWuNxgTXjs0tUvKkXiu2
Pco952jnm7HpCIKBek2pqR/UJXXb5qxy5G6Lc0qaMWZ5GKnSMTJmTY6Xl44EnaLK
zh0rqgF9qpoWck470ZbiGASMtB008hy2l0cyxUfvDaS3tY4hABEBAAGJASUEGAEC
AA8FAlEY1PECGwwFCQHhM4AACgkQ+mcYuYWXJSoT6AgAkvzvC0EGmeCR3cn9O3Gf
yG00Kqk9/1gJvlphis7AAce8iUgU+4xd94Vp0u8rghpdy88xKN5lF1W2YZQmmBaf
AVe6b7TOg6kxc3GKkVsWDxNyQKkpB46BwefIGaSljH7502X9aEWosrqWyJJNYCtt
QDit4BysX0Ww3Ka5Rx6ZFhC9ybPKoW2i8JwpyBaXDt7R2k+PC/ClBf9qzL+sb2es
zh/zCMVKNdm8KUITHU/5lgn2qZpUFZwiASPCMGGFP9u8g6UKeUTYTPD+GWaHIW63
RAgNIAffxx0M1r3P/2ipkAdI3NX/1iBKDQNG8Odsf+BswFKrNCnyUDdLPvJAhODS
gw==
=tmrm
-----END PGP PUBLIC KEY BLOCK-----


configFile = getEnv "NIXUSER_CONFIG";
homeDir = getEnv "HOME";
configFile2 = homeDir + "/.nixuser/configuration.nix";
Copy link
Member

Choose a reason for hiding this comment

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

Any reason for not using ~/.nixpkgs/config.nix as a base file for user-land modules, from which we can extract options / config?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For two reasons.
On the one hand I didn't want to change the way how ~/.nixpkgs/config.nix is used.
On the other hand the content of ~/.nixpkgs/config.nix can be integrated into ~/.nixuser/configuration.nix as attribute set nixpkgs.config. That way there would be a clear symmetry between the NixOS configuration under /etc/nixos/configuration.nix, and the new nixuser configuration under ~/.nixuser/configuration.nix

Copy link
Member

Choose a reason for hiding this comment

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

I don't like having yet-another directory. Having this file under ~/.nixpkgs/configuration.nix would be better than ~/.nixuser directory. Then moving the package override within this configuration.nix file sounds indeed like a good idea for making configurations system wide.

To be honest I think this deserve its own pull-request, independently of the vim configuration.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm just afraid that moving configuration.nix under ~/.nixpkgs as well could lead to confusions, especially for people who are new to Nix/NixOS. Wouldn't it be better to have it under ~/.nixuser for now, and then to phase out ~/.nixpkgs slowly?

I will provide a separated PR for the ~/.nixuser/configuration.nix related changes. The vimProfile stuff is only here to show a use case of the new configuration possibility.

@nbp
Copy link
Member

nbp commented Oct 12, 2014

I do not understand why these vim configuration is part of NixOS.
Is there any reason for not having these modules next to the vim packages?

@ts468
Copy link
Contributor Author

ts468 commented Oct 12, 2014

@nbp, thank you very much for your detailed feedback and your suggestions how to improve the contribution! I highly appreciate it!

About whether to have these modules next to the vim packages. You're right, they would somehow belong there. But as I haven't found any module definitions in the definitions under pkgs/... so far, I thought they would not belong there. Especially as there is nixos/modules/programs/..., where similar modules are placed. What would you suggest? Where would be the best place to put the modules under?

@nbp
Copy link
Member

nbp commented Oct 12, 2014

Especially as there is nixos/modules/programs/..., where similar modules are placed. What would you suggest? Where would be the best place to put the modules under?

I will look at it next week, ...

We should move these out-side and make sure that we have default modules for user-profiles such as we can produce user-activation scripts, which can be sourced within shell configurations.

Then these configurations would be used for both NixOS and Nixpkgs user configurations.

@ts468
Copy link
Contributor Author

ts468 commented Oct 12, 2014

@nbp, please let me know if I can be of any help or assistance with that!

Deprecate ~/.nixpkgs/config.nix
Create separate directory for nixuser nix modules.
Improve coding style in vimProfiles/default.nix.
@ghost
Copy link

ghost commented Oct 14, 2014

I would prefer do it entirely in config.nix, like:

  allowUnfree = true;

  pkgs.modules = [
    <nixpkgs/pkgs/modules/xterm.nix>
    ./modules/vim
  ];

  pkgs.xterm = {
    background = "black";
    foreground = "grey";
    faceName = "terminus";
    faceSize = 12;
  };

then nix-env -iA nixpkgs.xterm should just install the configured/wrapped version of xterm.

nixpkgs could provide sensiable default configurations for apps and profiles, overrided by user.
by profiles, I mean shareable configurations like icons, gio modules, gtk theme, etc.

related: #3990, #4369

@edwtjo
Copy link
Member

edwtjo commented Oct 14, 2014

Doesn't configuration modules and an overloaded NIX_PATH provide the same functionality as this PR, i.e. adding something like NIX_PATH="myuserdefaults=$MY_USER_DEFAULT_NIX_PATH:$NIX_PATH" nix-env -iA attr?

@ts468
Copy link
Contributor Author

ts468 commented Oct 14, 2014

@iyzsong, the final goal is to have a declarative user environment, like also mentioned in the issue that you linked (#3990). However, "/.nixpkgs/config.nix" is just about packages, and the overrides done in "/.nixpkgs/config.nix" can already now be absorbed in "~/.nixuser/configuration.nix" under an attribute nixpkgs.config, exactly like in "/etc/nixos/configuration.nix". Just give it a try. :)

@edwtjo, I haven't tried what you suggested, so I don't know if it works, but even if it would, I still think it is not very convenient to use.

@ghost
Copy link

ghost commented Oct 14, 2014

Yes, It's what we all want.
for me, user environment include:

  • applications(or packages): xterm, openbox...
  • profiles(or environment, settings): theme, input-method...
  • session: a fully configured desktop environment, may include user services etc.

IMO, this PR is not clean, and may be unnecessary.
As mention by edwtjo, what you want can be done without touch nixpkgs,
by using evalModules like nix-rehash.
Applications modules like vim better managed yourself, decentralized
to reduce the overhead of nixpkgs.
Profiles modules should go into nixpkgs, to solve the problems like gtk3 apps.

https://github.com/kiberpipa/nix-rehash/blob/master/nix-services/default.nix

@nbp
Copy link
Member

nbp commented Oct 14, 2014

@ts468, I will probably take a few lines from the nixpkgs modificcation that you made, but by intent is to add a new directory at the top-level of nixpkgs, and make it such as the files which are under programs, can be shared by both nixos and this user-environment configuration.

Thus these program specific configurations would have to be valid modules for both the user-environment configuration and nixos configurations (when possible).

This way we would have a declarative way to define user-environments.

I still have some work to do on the nix/secret branch, and I will get back to this ASAP.

@ghost
Copy link

ghost commented Oct 15, 2014

how about make config.nix just really a module, since it requires document anyway?

here I introduce callPackageModule, when eval, combine config and pkg to get the drv, the customized package.

let
  pkgs = import <nixpkgs> {};

  basic = { config, lib, ... }: {
    options.drv = lib.mkOption {
      type = lib.types.package;
    };

    # document ~/.nixpkgs/config.nix here!
    options.allowUnfree = lib.mkOption {
      description = "whether to allow install unfree things";
      type = lib.types.boolean;
      default = false;
    };
  };

  callPackageModule = pkg: (pkgs.lib.evalModules {
    modules = [ basic pkg pkgs.config ];
    args = { inherit pkgs; };
    check = false; # :-
  }).config.drv;

in {
  xterm-customized = callPackageModule ./xterm.nix;
}

xterm.nix:

{ config, lib, pkgs, ... }:

with lib; let
  cfg = config.xterm;
in {
  options.xterm = {
    foreground = mkOption {
      description = "foreground color";
      type = types.str;
      default = "grey";
      example = "#000000";
    };

    background = mkOption {
      description = "background color";
      type = types.str;
      default = "black";
      example = "#ffffff";
    };
  };

  config = {
    drv = pkgs.writeScriptBin "xterm" ''
      #!${pkgs.stdenv.shell}
      exec ${pkgs.xterm}/bin/xterm -fg '${cfg.foreground}' -bg '${cfg.background}' "$@"
    '';
  };
}

related: #4505

@nbp
Copy link
Member

nbp commented Oct 17, 2014

@iyzsong, we should not configure programs by making wrappers, but by providing configuration files, such as .Xresources and using xrdb/xmerge to load it.

Otherwise, yes, we could think of making ~/.nixpkgs/config.nix a part of a module, but I think we should look at this issue after. I have always been inclined avoid breaking previous stuff, but here we are bootstraping a new way to deal with the user environment, and I do not want that to be blocked on a non-existent issue. Currently ~/.nixpkgs/config.nix solves another problem which is selecting packages, and a nix user environment is about configuring these packages.

@ts468
Copy link
Contributor Author

ts468 commented Oct 17, 2014

@nbp, thank you very much for going to have a look at how to set up a nixuser environment! For me it's not urgent, so please take your time and finish your work on the nix/secret branch first.

With my last changes I already set up a top level directory named "nixuser", which is structured similar to "nixos". The content of the new directory "nixuser" is automatically made available to nixos as well. If you're happy with that approach, I could have a look at moving further modules from nixos to nixuser.

@ghost
Copy link

ghost commented Oct 18, 2014

after some thinking, I hover callPackageModule more.
a package module is self-contained, refer other modules by imports,
we can easily host a collections of package modules out of nixpkgs.

@ts468, in the approach you show, all modules evaluated by a single evalModules call, just like NixOS.
I'm afraid this is inconvenient, we have to maintain modules-list.nix for all packages,
and have to be careful not introduce unwanted packages to user.

@nbp, yeah, the xterm.nix is only a example, ideally I'll use builtins.toXML and xsltproc to transform config.xterm to XResources :)
IMO, for user environment as a whole contain both packages and configurations,
selecting and configuring means the same thing.

needless to say, the config.nix is already a valid module, since it has no options declaration, even evaluated by various evalModules call from `callPackageModule', the existed way it was used doesn't changed, nothing should break.

@ts468
Copy link
Contributor Author

ts468 commented Aug 14, 2015

The follow-up on this PR is #9250.

@ts468 ts468 closed this Aug 14, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: enhancement Add something new
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants