diff options
Diffstat (limited to 'nixos/modules/programs')
-rw-r--r-- | nixos/modules/programs/atop.nix | 36 | ||||
-rw-r--r-- | nixos/modules/programs/bash/bash.nix | 217 | ||||
-rw-r--r-- | nixos/modules/programs/bash/command-not-found.nix | 51 | ||||
-rw-r--r-- | nixos/modules/programs/bash/command-not-found.pl | 48 | ||||
-rw-r--r-- | nixos/modules/programs/bash/inputrc | 36 | ||||
-rw-r--r-- | nixos/modules/programs/blcr.nix | 27 | ||||
-rw-r--r-- | nixos/modules/programs/environment.nix | 79 | ||||
-rw-r--r-- | nixos/modules/programs/info.nix | 36 | ||||
-rw-r--r-- | nixos/modules/programs/shadow.nix | 103 | ||||
-rw-r--r-- | nixos/modules/programs/shell.nix | 64 | ||||
-rw-r--r-- | nixos/modules/programs/ssh.nix | 68 | ||||
-rw-r--r-- | nixos/modules/programs/ssmtp.nix | 111 | ||||
-rw-r--r-- | nixos/modules/programs/venus.nix | 174 | ||||
-rw-r--r-- | nixos/modules/programs/virtualbox.nix | 47 | ||||
-rw-r--r-- | nixos/modules/programs/wvdial.nix | 71 | ||||
-rw-r--r-- | nixos/modules/programs/zsh/zinputrc | 42 | ||||
-rw-r--r-- | nixos/modules/programs/zsh/zsh.nix | 180 |
17 files changed, 1390 insertions, 0 deletions
diff --git a/nixos/modules/programs/atop.nix b/nixos/modules/programs/atop.nix new file mode 100644 index 000000000000..7fdaab9d67df --- /dev/null +++ b/nixos/modules/programs/atop.nix @@ -0,0 +1,36 @@ +# Global configuration for atop. + +{config, pkgs, ...}: + +with pkgs.lib; + +let cfg = config.programs.atop; + +in +{ + ###### interface + + options = { + + programs.atop = { + + settings = mkOption { + type = types.attrs; + default = {}; + example = { + flags = "a1f"; + interval = 5; + }; + description = '' + Parameters to be written to <filename>/etc/atoprc</filename> + ''; + }; + + }; + }; + + config = mkIf (cfg.settings != {}) { + environment.etc."atoprc".text = + concatStrings (mapAttrsToList (n: v: "${n} ${toString v}\n") cfg.settings); + }; +} diff --git a/nixos/modules/programs/bash/bash.nix b/nixos/modules/programs/bash/bash.nix new file mode 100644 index 000000000000..8cfe3f990adc --- /dev/null +++ b/nixos/modules/programs/bash/bash.nix @@ -0,0 +1,217 @@ +# This module defines global configuration for the Bash shell, in +# particular /etc/bashrc and /etc/profile. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + cfge = config.environment; + + cfg = config.programs.bash; + + bashCompletion = optionalString cfg.enableCompletion '' + # Check whether we're running a version of Bash that has support for + # programmable completion. If we do, enable all modules installed in + # the system (and user profile). + if shopt -q progcomp &>/dev/null; then + . "${pkgs.bashCompletion}/etc/profile.d/bash_completion.sh" + nullglobStatus=$(shopt -p nullglob) + shopt -s nullglob + for p in $NIX_PROFILES; do + for m in "$p/etc/bash_completion.d/"* "$p/share/bash-completion/completions/"*; do + . $m + done + done + eval "$nullglobStatus" + unset nullglobStatus p m + fi + ''; + + bashAliases = concatStringsSep "\n" ( + mapAttrsFlatten (k: v: "alias ${k}='${v}'") cfg.shellAliases + ); + +in + +{ + options = { + + programs.bash = { + + enable = mkOption { + default = true; + description = '' + Whenever to configure Bash as an interactive shell. + Note that this tries to make Bash the default + <option>users.defaultUserShell</option>, + which in turn means that you might need to explicitly + set this variable if you have another shell configured + with NixOS. + ''; + type = types.bool; + }; + + shellAliases = mkOption { + default = config.environment.shellAliases // { which = "type -P"; }; + description = '' + Set of aliases for bash shell. See <option>environment.shellAliases</option> + for an option format description. + ''; + type = types.attrs; # types.attrsOf types.stringOrPath; + }; + + shellInit = mkOption { + default = ""; + description = '' + Shell script code called during bash shell initialisation. + ''; + type = types.lines; + }; + + loginShellInit = mkOption { + default = ""; + description = '' + Shell script code called during login bash shell initialisation. + ''; + type = types.lines; + }; + + interactiveShellInit = mkOption { + default = ""; + description = '' + Shell script code called during interactive bash shell initialisation. + ''; + type = types.lines; + }; + + promptInit = mkOption { + default = '' + # Provide a nice prompt. + PROMPT_COLOR="1;31m" + let $UID && PROMPT_COLOR="1;32m" + PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] " + if test "$TERM" = "xterm"; then + PS1="\[\033]2;\h:\u:\w\007\]$PS1" + fi + ''; + description = '' + Shell script code used to initialise the bash prompt. + ''; + type = types.lines; + }; + + enableCompletion = mkOption { + default = false; + description = '' + Enable Bash completion for all interactive bash shells. + ''; + type = types.bool; + }; + + }; + + }; + + config = mkIf cfg.enable { + + programs.bash = { + + shellInit = '' + . ${config.system.build.setEnvironment} + + ${cfge.shellInit} + ''; + + loginShellInit = cfge.loginShellInit; + + interactiveShellInit = '' + ${cfge.interactiveShellInit} + + # Check the window size after every command. + shopt -s checkwinsize + + # Disable hashing (i.e. caching) of command lookups. + set +h + + ${cfg.promptInit} + ${bashCompletion} + ${bashAliases} + ''; + + }; + + environment.etc."profile".text = + '' + # /etc/profile: DO NOT EDIT -- this file has been generated automatically. + # This file is read for login shells. + + # Only execute this file once per shell. + if [ -n "$__ETC_PROFILE_SOURCED" ]; then return; fi + __ETC_PROFILE_SOURCED=1 + + # Prevent this file from being sourced by interactive non-login child shells. + export __ETC_PROFILE_DONE=1 + + ${cfg.shellInit} + ${cfg.loginShellInit} + + # Read system-wide modifications. + if test -f /etc/profile.local; then + . /etc/profile.local + fi + + if [ -n "''${BASH_VERSION:-}" ]; then + . /etc/bashrc + fi + ''; + + environment.etc."bashrc".text = + '' + # /etc/bashrc: DO NOT EDIT -- this file has been generated automatically. + + # Only execute this file once per shell. + if [ -n "$__ETC_BASHRC_SOURCED" -o -n "$NOSYSBASHRC" ]; then return; fi + __ETC_BASHRC_SOURCED=1 + + # If the profile was not loaded in a parent process, source + # it. But otherwise don't do it because we don't want to + # clobber overridden values of $PATH, etc. + if [ -z "$__ETC_PROFILE_DONE" ]; then + . /etc/profile + fi + + # We are not always an interactive shell. + if [ -n "$PS1" ]; then + ${cfg.interactiveShellInit} + fi + + # Read system-wide modifications. + if test -f /etc/bashrc.local; then + . /etc/bashrc.local + fi + ''; + + # Configuration for readline in bash. + environment.etc."inputrc".source = ./inputrc; + + users.defaultUserShell = mkDefault "/run/current-system/sw/bin/bash"; + + environment.pathsToLink = optionals cfg.enableCompletion [ + "/etc/bash_completion.d" + "/share/bash-completion" + ]; + + environment.shells = + [ "/run/current-system/sw/bin/bash" + "/var/run/current-system/sw/bin/bash" + "/run/current-system/sw/bin/sh" + "/var/run/current-system/sw/bin/sh" + "${pkgs.bashInteractive}/bin/bash" + "${pkgs.bashInteractive}/bin/sh" + ]; + + }; + +} diff --git a/nixos/modules/programs/bash/command-not-found.nix b/nixos/modules/programs/bash/command-not-found.nix new file mode 100644 index 000000000000..502320446a37 --- /dev/null +++ b/nixos/modules/programs/bash/command-not-found.nix @@ -0,0 +1,51 @@ +# This module provides suggestions of packages to install if the user +# tries to run a missing command in Bash. This is implemented using a +# SQLite database that maps program names to Nix package names (e.g., +# "pdflatex" is mapped to "tetex"). + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + commandNotFound = pkgs.substituteAll { + name = "command-not-found"; + dir = "bin"; + src = ./command-not-found.pl; + isExecutable = true; + inherit (pkgs) perl; + perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ") + [ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite ]); + }; + +in + +{ + + programs.bash.interactiveShellInit = + '' + # This function is called whenever a command is not found. + command_not_found_handle() { + local p=/run/current-system/sw/bin/command-not-found + if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then + # Run the helper program. + $p "$1" + # Retry the command if we just installed it. + if [ $? = 126 ]; then + "$@" + else + return 127 + fi + else + echo "$1: command not found" >&2 + return 127 + fi + } + ''; + + environment.systemPackages = [ commandNotFound ]; + + # TODO: tab completion for uninstalled commands! :-) + +} diff --git a/nixos/modules/programs/bash/command-not-found.pl b/nixos/modules/programs/bash/command-not-found.pl new file mode 100644 index 000000000000..916649059d37 --- /dev/null +++ b/nixos/modules/programs/bash/command-not-found.pl @@ -0,0 +1,48 @@ +#! @perl@/bin/perl -w @perlFlags@ + +use strict; +use DBI; +use DBD::SQLite; +use Config; + +my $program = $ARGV[0]; + +my $dbPath = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite"; + +my $dbh = DBI->connect("dbi:SQLite:dbname=$dbPath", "", "") + or die "cannot open database `$dbPath'"; +$dbh->{RaiseError} = 0; +$dbh->{PrintError} = 0; + +my $system = $ENV{"NIX_SYSTEM"} // $Config{myarchname}; + +my $res = $dbh->selectall_arrayref( + "select package from Programs where system = ? and name = ?", + { Slice => {} }, $system, $program); + +if (!defined $res || scalar @$res == 0) { + print STDERR "$program: command not found\n"; +} elsif (scalar @$res == 1) { + my $package = @$res[0]->{package}; + if ($ENV{"NIX_AUTO_INSTALL"} // "") { + print STDERR <<EOF; +The program ‘$program’ is currently not installed. It is provided by +the package ‘$package’, which I will now install for you. +EOF + ; + exit 126 if system("nix-env", "-i", $package) == 0; + } else { + print STDERR <<EOF; +The program ‘$program’ is currently not installed. You can install it by typing: + nix-env -i $package +EOF + } +} else { + print STDERR <<EOF; +The program ‘$program’ is currently not installed. It is provided by +several packages. You can install it by typing one of the following: +EOF + print STDERR " nix-env -i $_->{package}\n" foreach @$res; +} + +exit 127; diff --git a/nixos/modules/programs/bash/inputrc b/nixos/modules/programs/bash/inputrc new file mode 100644 index 000000000000..e4eabc052c5f --- /dev/null +++ b/nixos/modules/programs/bash/inputrc @@ -0,0 +1,36 @@ +# inputrc borrowed from CentOS (RHEL). + +set bell-style none + +set meta-flag on +set input-meta on +set convert-meta off +set output-meta on + +#set mark-symlinked-directories on + +$if mode=emacs + +# for linux console and RH/Debian xterm +"\e[1~": beginning-of-line +"\e[4~": end-of-line +"\e[5~": beginning-of-history +"\e[6~": end-of-history +"\e[3~": delete-char +"\e[2~": quoted-insert +"\e[5C": forward-word +"\e[5D": backward-word +"\e[1;5C": forward-word +"\e[1;5D": backward-word + +# for rxvt +"\e[8~": end-of-line + +# for non RH/Debian xterm, can't hurt for RH/DEbian xterm +"\eOH": beginning-of-line +"\eOF": end-of-line + +# for freebsd console +"\e[H": beginning-of-line +"\e[F": end-of-line +$endif diff --git a/nixos/modules/programs/blcr.nix b/nixos/modules/programs/blcr.nix new file mode 100644 index 000000000000..e1e31b4a56aa --- /dev/null +++ b/nixos/modules/programs/blcr.nix @@ -0,0 +1,27 @@ +{ config, pkgs, ... }: + +let + inherit (pkgs.lib) mkOption mkIf; + cfg = config.environment.blcr; + blcrPkg = config.boot.kernelPackages.blcr; +in + +{ + ###### interface + + options = { + environment.blcr.enable = mkOption { + default = false; + description = + "Whether to enable support for the BLCR checkpointing tool."; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + boot.kernelModules = [ "blcr" "blcr_imports" ]; + boot.extraModulePackages = [ blcrPkg ]; + environment.systemPackages = [ blcrPkg ]; + }; +} diff --git a/nixos/modules/programs/environment.nix b/nixos/modules/programs/environment.nix new file mode 100644 index 000000000000..f42df3514221 --- /dev/null +++ b/nixos/modules/programs/environment.nix @@ -0,0 +1,79 @@ +# This module defines a standard configuration for NixOS global environment. + +# Most of the stuff here should probably be moved elsewhere sometime. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + cfg = config.environment; + +in + +{ + + config = { + + environment.variables = + { LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive"; + LOCATE_PATH = "/var/cache/locatedb"; + NIXPKGS_CONFIG = "/etc/nix/nixpkgs-config.nix"; + NIX_PATH = + [ "/nix/var/nix/profiles/per-user/root/channels/nixos" + "nixpkgs=/etc/nixos/nixpkgs" + "nixos=/etc/nixos/nixos" + "nixos-config=/etc/nixos/configuration.nix" + "services=/etc/nixos/services" + ]; + PAGER = "less -R"; + EDITOR = "nano"; + }; + + environment.profiles = + [ "$HOME/.nix-profile" + "/nix/var/nix/profiles/default" + "/run/current-system/sw" + ]; + + # !!! fix environment.profileVariables definition and then move + # most of these elsewhere + environment.profileVariables = (i: + { PATH = [ "${i}/bin" "${i}/sbin" "${i}/lib/kde4/libexec" ]; + MANPATH = [ "${i}/man" "${i}/share/man" ]; + INFOPATH = [ "${i}/info" "${i}/share/info" ]; + PKG_CONFIG_PATH = [ "${i}/lib/pkgconfig" ]; + TERMINFO_DIRS = [ "${i}/share/terminfo" ]; + PERL5LIB = [ "${i}/lib/perl5/site_perl" ]; + ALSA_PLUGIN_DIRS = [ "${i}/lib/alsa-lib" ]; + GST_PLUGIN_PATH = [ "${i}/lib/gstreamer-0.10" ]; + KDEDIRS = [ "${i}" ]; + STRIGI_PLUGIN_PATH = [ "${i}/lib/strigi/" ]; + QT_PLUGIN_PATH = [ "${i}/lib/qt4/plugins" "${i}/lib/kde4/plugins" ]; + QTWEBKIT_PLUGIN_PATH = [ "${i}/lib/mozilla/plugins/" ]; + GTK_PATH = [ "${i}/lib/gtk-2.0" ]; + XDG_CONFIG_DIRS = [ "${i}/etc/xdg" ]; + XDG_DATA_DIRS = [ "${i}/share" ]; + MOZ_PLUGIN_PATH = [ "${i}/lib/mozilla/plugins" ]; + }); + + environment.extraInit = + '' + # reset TERM with new TERMINFO available (if any) + export TERM=$TERM + + unset ASPELL_CONF + for i in ${concatStringsSep " " (reverseList cfg.profiles)} ; do + if [ -d "$i/lib/aspell" ]; then + export ASPELL_CONF="dict-dir $i/lib/aspell" + fi + done + + export NIX_USER_PROFILE_DIR="/nix/var/nix/profiles/per-user/$USER" + export NIX_PROFILES="${concatStringsSep " " (reverseList cfg.profiles)}" + ''; + + }; + +} diff --git a/nixos/modules/programs/info.nix b/nixos/modules/programs/info.nix new file mode 100644 index 000000000000..30c25cf34206 --- /dev/null +++ b/nixos/modules/programs/info.nix @@ -0,0 +1,36 @@ +{config, pkgs, ...}: + +let + + # Quick hack to make the `info' command work properly. `info' needs + # a "dir" file containing all the installed Info files, which we + # don't have (it would be impure to have a package installation + # update some global "dir" file). So this wrapper script around + # "info" builds a temporary "dir" file on the fly. This is a bit + # slow (on a cold cache) but not unacceptably so. + infoWrapper = pkgs.writeScriptBin "info" + '' + #! ${pkgs.stdenv.shell} + + dir=$(mktemp --tmpdir -d "info.dir.XXXXXX") + + if test -z "$dir"; then exit 1; fi + + trap 'rm -rf "$dir"' EXIT + + shopt -s nullglob + + for i in $(IFS=:; echo $INFOPATH); do + for j in $i/*.info; do + ${pkgs.texinfo}/bin/install-info --quiet $j $dir/dir + done + done + + INFOPATH=$dir:$INFOPATH ${pkgs.texinfo}/bin/info "$@" + ''; # */ + +in + +{ + environment.systemPackages = [ infoWrapper pkgs.texinfo ]; +} diff --git a/nixos/modules/programs/shadow.nix b/nixos/modules/programs/shadow.nix new file mode 100644 index 000000000000..695c0b6620f7 --- /dev/null +++ b/nixos/modules/programs/shadow.nix @@ -0,0 +1,103 @@ +# Configuration for the pwdutils suite of tools: passwd, useradd, etc. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + loginDefs = + '' + DEFAULT_HOME yes + + SYS_UID_MIN 100 + SYS_UID_MAX 499 + UID_MIN 1000 + UID_MAX 29999 + + SYS_GID_MIN 100 + SYS_GID_MAX 499 + GID_MIN 1000 + GID_MAX 29999 + + TTYGROUP tty + TTYPERM 0620 + + # Ensure privacy for newly created home directories. + UMASK 077 + + # Uncomment this to allow non-root users to change their account + #information. This should be made configurable. + #CHFN_RESTRICT frwh + + ''; + +in + +{ + + ###### interface + + options = { + + users.defaultUserShell = pkgs.lib.mkOption { + description = '' + This option defines the default shell assigned to user + accounts. This must not be a store path, since the path is + used outside the store (in particular in /etc/passwd). + Rather, it should be the path of a symlink that points to the + actual shell in the Nix store. + ''; + type = types.uniq types.path; + }; + + }; + + + ###### implementation + + config = { + + environment.systemPackages = [ pkgs.shadow ]; + + environment.etc = + [ { # /etc/login.defs: global configuration for pwdutils. You + # cannot login without it! + source = pkgs.writeText "login.defs" loginDefs; + target = "login.defs"; + } + + { # /etc/default/useradd: configuration for useradd. + source = pkgs.writeText "useradd" + '' + GROUP=100 + HOME=/home + SHELL=${config.users.defaultUserShell} + ''; + target = "default/useradd"; + } + ]; + + security.pam.services = + [ { name = "chsh"; rootOK = true; } + { name = "chfn"; rootOK = true; } + { name = "su"; rootOK = true; forwardXAuth = true; } + { name = "passwd"; } + # Note: useradd, groupadd etc. aren't setuid root, so it + # doesn't really matter what the PAM config says as long as it + # lets root in. + { name = "useradd"; rootOK = true; } + { name = "usermod"; rootOK = true; } + { name = "userdel"; rootOK = true; } + { name = "groupadd"; rootOK = true; } + { name = "groupmod"; rootOK = true; } + { name = "groupmems"; rootOK = true; } + { name = "groupdel"; rootOK = true; } + { name = "login"; startSession = true; allowNullPassword = true; showMotd = true; updateWtmp = true; } + ]; + + security.setuidPrograms = [ "passwd" "chfn" "su" "newgrp" ]; + + }; + +} diff --git a/nixos/modules/programs/shell.nix b/nixos/modules/programs/shell.nix new file mode 100644 index 000000000000..679c4979dfa9 --- /dev/null +++ b/nixos/modules/programs/shell.nix @@ -0,0 +1,64 @@ +# This module defines a standard configuration for NixOS shells. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + cfg = config.environment; + +in + +{ + + config = { + + environment.shellAliases = + { ls = "ls --color=tty"; + ll = "ls -l"; + l = "ls -alh"; + }; + + environment.shellInit = + '' + # Set up the per-user profile. + mkdir -m 0755 -p $NIX_USER_PROFILE_DIR + if test "$(stat --printf '%u' $NIX_USER_PROFILE_DIR)" != "$(id -u)"; then + echo "WARNING: bad ownership on $NIX_USER_PROFILE_DIR" >&2 + fi + + if ! test -L $HOME/.nix-profile; then + if test "$USER" != root; then + ln -s $NIX_USER_PROFILE_DIR/profile $HOME/.nix-profile + else + # Root installs in the system-wide profile by default. + ln -s /nix/var/nix/profiles/default $HOME/.nix-profile + fi + fi + + # Subscribe the root user to the NixOS channel by default. + if [ "$USER" = root -a ! -e $HOME/.nix-channels ]; then + echo "http://nixos.org/channels/nixos-unstable nixos" > $HOME/.nix-channels + fi + + # Create the per-user garbage collector roots directory. + NIX_USER_GCROOTS_DIR=/nix/var/nix/gcroots/per-user/$USER + mkdir -m 0755 -p $NIX_USER_GCROOTS_DIR + if test "$(stat --printf '%u' $NIX_USER_GCROOTS_DIR)" != "$(id -u)"; then + echo "WARNING: bad ownership on $NIX_USER_GCROOTS_DIR" >&2 + fi + + # Set up a default Nix expression from which to install stuff. + if [ ! -e $HOME/.nix-defexpr -o -L $HOME/.nix-defexpr ]; then + rm -f $HOME/.nix-defexpr + mkdir $HOME/.nix-defexpr + if [ "$USER" != root ]; then + ln -s /nix/var/nix/profiles/per-user/root/channels $HOME/.nix-defexpr/channels_root + fi + fi + ''; + + }; + +} diff --git a/nixos/modules/programs/ssh.nix b/nixos/modules/programs/ssh.nix new file mode 100644 index 000000000000..5ec32376b60e --- /dev/null +++ b/nixos/modules/programs/ssh.nix @@ -0,0 +1,68 @@ +# Global configuration for the SSH client. + +{config, pkgs, ...}: + +with pkgs.lib; + +let cfg = config.programs.ssh; + cfgd = config.services.openssh; + +in +{ + ###### interface + + options = { + + programs.ssh = { + + forwardX11 = mkOption { + default = false; + description = '' + Whether to request X11 forwarding on outgoing connections by default. + This is useful for running graphical programs on the remote machine and have them display to your local X11 server. + Historically, this value has depended on the value used by the local sshd daemon, but there really isn't a relation between the two. + Note: there are some security risks to forwarding an X11 connection. + NixOS's X server is built with the SECURITY extension, which prevents some obvious attacks. + To enable or disable forwarding on a per-connection basis, see the -X and -x options to ssh. + The -Y option to ssh enables trusted forwarding, which bypasses the SECURITY extension. + ''; + }; + + setXAuthLocation = mkOption { + default = true; + description = '' + Whether to set the path to xauth for X11-forwarded connections. + Pulls in X11 dependency. + ''; + }; + + extraConfig = mkOption { + default = ""; + description = '' + Extra configuration text appended to <filename>ssh_config</filename>. + See the ssh_config(5) man page for help. + ''; + }; + }; + }; + + assertions = [{ assertion = if cfg.forwardX11 then cfg.setXAuthLocation else true; + message = "cannot enable X11 forwarding without setting xauth location";}]; + + config = { + environment.etc = + [ { # SSH configuration. Slight duplication of the sshd_config + # generation in the sshd service. + source = pkgs.writeText "ssh_config" '' + AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"} + ${optionalString cfg.setXAuthLocation '' + XAuthLocation ${pkgs.xorg.xauth}/bin/xauth + ''} + ForwardX11 ${if cfg.forwardX11 then "yes" else "no"} + ${cfg.extraConfig} + ''; + target = "ssh/ssh_config"; + } + ]; + }; +} diff --git a/nixos/modules/programs/ssmtp.nix b/nixos/modules/programs/ssmtp.nix new file mode 100644 index 000000000000..904989d57a09 --- /dev/null +++ b/nixos/modules/programs/ssmtp.nix @@ -0,0 +1,111 @@ +# Configuration for `ssmtp', a trivial mail transfer agent that can +# replace sendmail/postfix on simple systems. It delivers email +# directly to an SMTP server defined in its configuration file, wihout +# queueing mail locally. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + cfg = config.networking.defaultMailServer; + +in + +{ + + options = { + + networking.defaultMailServer = { + + directDelivery = mkOption { + default = false; + example = true; + description = '' + Use the trivial Mail Transfer Agent (MTA) + <command>ssmtp</command> package to allow programs to send + e-mail. If you don't want to run a “real” MTA like + <command>sendmail</command> or <command>postfix</command> on + your machine, set this option to <literal>true</literal>, and + set the option + <option>networking.defaultMailServer.hostName</option> to the + host name of your preferred mail server. + ''; + }; + + hostName = mkOption { + example = "mail.example.org"; + description = '' + The host name of the default mail server to use to deliver + e-mail. + ''; + }; + + domain = mkOption { + default = ""; + example = "example.org"; + description = '' + The domain from which mail will appear to be sent. + ''; + }; + + useTLS = mkOption { + default = false; + example = true; + description = '' + Whether TLS should be used to connect to the default mail + server. + ''; + }; + + useSTARTTLS = mkOption { + default = false; + example = true; + description = '' + Whether the STARTTLS should be used to connect to the default + mail server. (This is needed for TLS-capable mail servers + running on the default SMTP port 25.) + ''; + }; + + authUser = mkOption { + default = ""; + example = "foo@example.org"; + description = '' + Username used for SMTP auth. Leave blank to disable. + ''; + }; + + authPass = mkOption { + default = ""; + example = "correctHorseBatteryStaple"; + description = '' + Password used for SMTP auth. (STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE) + ''; + }; + + }; + + }; + + + config = mkIf cfg.directDelivery { + + environment.etc."ssmtp/ssmtp.conf".text = + '' + MailHub=${cfg.hostName} + FromLineOverride=YES + ${if cfg.domain != "" then "rewriteDomain=${cfg.domain}" else ""} + UseTLS=${if cfg.useTLS then "YES" else "NO"} + UseSTARTTLS=${if cfg.useSTARTTLS then "YES" else "NO"} + #Debug=YES + ${if cfg.authUser != "" then "AuthUser=${cfg.authUser}" else ""} + ${if cfg.authPass != "" then "AuthPass=${cfg.authPass}" else ""} + ''; + + environment.systemPackages = [pkgs.ssmtp]; + + }; + +} diff --git a/nixos/modules/programs/venus.nix b/nixos/modules/programs/venus.nix new file mode 100644 index 000000000000..2b3bfbc6c188 --- /dev/null +++ b/nixos/modules/programs/venus.nix @@ -0,0 +1,174 @@ +{config, pkgs, ...}: + +with pkgs.lib; +let + cfg = config.services.venus; + + configFile = pkgs.writeText "venus.ini" + '' + [Planet] + name = ${cfg.name} + link = ${cfg.link} + owner_name = ${cfg.ownerName} + owner_email = ${cfg.ownerEmail} + output_theme = ${cfg.cacheDirectory}/theme + output_dir = ${cfg.outputDirectory} + cache_directory = ${cfg.cacheDirectory} + items_per_page = ${toString cfg.itemsPerPage} + ${(concatStringsSep "\n\n" + (map ({ name, feedUrl, homepageUrl }: + '' + [${feedUrl}] + name = ${name} + link = ${homepageUrl} + '') cfg.feeds))} + ''; + +in +{ + + options = { + services.venus = { + enable = mkOption { + default = false; + type = types.bool; + description = '' + Planet Venus is an awesome ‘river of news’ feed reader. It downloads + news feeds published by web sites and aggregates their content + together into a single combined feed, latest news first. + ''; + }; + + dates = mkOption { + default = "*:0,15,30,45"; + type = types.string; + description = '' + Specification (in the format described by + <citerefentry><refentrytitle>systemd.time</refentrytitle> + <manvolnum>5</manvolnum></citerefentry>) of the time at + which the Venus will collect feeds. + ''; + }; + + user = mkOption { + default = "root"; + type = types.string; + description = '' + User for running venus script. + ''; + }; + + group = mkOption { + default = "root"; + type = types.string; + description = '' + Group for running venus script. + ''; + }; + + name = mkOption { + default = "NixOS Planet"; + type = types.string; + description = '' + Your planet's name. + ''; + }; + + link = mkOption { + default = "http://planet.nixos.org"; + type = types.string; + description = '' + Link to the main page. + ''; + }; + + ownerName = mkOption { + default = "Rok Garbas"; + type = types.string; + description = '' + Your name. + ''; + }; + + ownerEmail = mkOption { + default = "some@example.com"; + type = types.string; + description = '' + Your e-mail address. + ''; + }; + + outputTheme = mkOption { + default = "${pkgs.venus}/themes/classic_fancy"; + type = types.path; + description = '' + Directory containing a config.ini file which is merged with this one. + This is typically used to specify templating and bill of material + information. + ''; + }; + + outputDirectory = mkOption { + type = types.path; + description = '' + Directory to place output files. + ''; + }; + + cacheDirectory = mkOption { + default = "/var/cache/venus"; + type = types.path; + description = '' + Where cached feeds are stored. + ''; + }; + + itemsPerPage = mkOption { + default = 15; + type = types.int; + description = '' + How many items to put on each page. + ''; + }; + + feeds = mkOption { + default = []; + example = [ + { + name = "Rok Garbas"; + feedUrl= "http://url/to/rss/feed.xml"; + homepageUrl = "http://garbas.si"; + } + ]; + description = '' + List of feeds. + ''; + }; + + }; + }; + + config = mkIf cfg.enable { + + system.activationScripts.venus = + '' + mkdir -p ${cfg.outputDirectory} + chown ${cfg.user}:${cfg.group} ${cfg.outputDirectory} -R + rm -rf ${cfg.cacheDirectory}/theme + mkdir -p ${cfg.cacheDirectory}/theme + cp -R ${cfg.outputTheme}/* ${cfg.cacheDirectory}/theme + chown ${cfg.user}:${cfg.group} ${cfg.cacheDirectory} -R + ''; + + systemd.services.venus = + { description = "Planet Venus, an awesome ‘river of news’ feed reader"; + path = [ pkgs.venus ]; + script = "exec venus-planet ${configFile}"; + serviceConfig.User = "${cfg.user}"; + serviceConfig.Group = "${cfg.group}"; + environment.OPENSSL_X509_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt"; + startOn = cfg.dates; + }; + + }; +} diff --git a/nixos/modules/programs/virtualbox.nix b/nixos/modules/programs/virtualbox.nix new file mode 100644 index 000000000000..340fec0496ae --- /dev/null +++ b/nixos/modules/programs/virtualbox.nix @@ -0,0 +1,47 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +let virtualbox = config.boot.kernelPackages.virtualbox; in + +{ + boot.kernelModules = [ "vboxdrv" "vboxnetadp" "vboxnetflt" ]; + boot.extraModulePackages = [ virtualbox ]; + environment.systemPackages = [ virtualbox ]; + + users.extraGroups.vboxusers.gid = config.ids.gids.vboxusers; + + services.udev.extraRules = + '' + KERNEL=="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd" + KERNEL=="vboxnetctl", OWNER="root", GROUP="root", MODE="0600", TAG+="systemd" + SUBSYSTEM=="usb_device", ACTION=="add", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}" + SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}" + SUBSYSTEM=="usb_device", ACTION=="remove", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor" + SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor" + ''; + + # Since we lack the right setuid binaries, set up a host-only network by default. + + systemd.services."vboxnet0" = + { description = "VirtualBox vboxnet0 Interface"; + requires = [ "dev-vboxnetctl.device" ]; + after = [ "dev-vboxnetctl.device" ]; + wantedBy = [ "network.target" "sys-subsystem-net-devices-vboxnet0.device" ]; + path = [ virtualbox ]; + serviceConfig.RemainAfterExit = true; + serviceConfig.Type = "oneshot"; + script = + '' + if ! [ -e /sys/class/net/vboxnet0 ]; then + VBoxManage hostonlyif create + fi + ''; + postStop = + '' + VBoxManage hostonlyif remove vboxnet0 + ''; + }; + + networking.interfaces.vboxnet0 = { ipAddress = "192.168.56.1"; prefixLength = 24; }; +} diff --git a/nixos/modules/programs/wvdial.nix b/nixos/modules/programs/wvdial.nix new file mode 100644 index 000000000000..da3f7dce98a1 --- /dev/null +++ b/nixos/modules/programs/wvdial.nix @@ -0,0 +1,71 @@ +# Global configuration for wvdial. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + configFile = '' + [Dialer Defaults] + PPPD PATH = ${pkgs.ppp}/sbin/pppd + ${config.environment.wvdial.dialerDefaults} + ''; + + cfg = config.environment.wvdial; + +in +{ + ###### interface + + options = { + + environment.wvdial = { + + dialerDefaults = mkOption { + default = ""; + type = types.string; + example = ''Init1 = AT+CGDCONT=1,"IP","internet.t-mobile"''; + description = '' + Contents of the "Dialer Defaults" section of + <filename>/etc/wvdial.conf</filename>. + ''; + }; + + pppDefaults = mkOption { + default = '' + noipdefault + usepeerdns + defaultroute + persist + noauth + ''; + type = types.string; + description = "Default ppp settings for wvdial."; + }; + + }; + + }; + + ###### implementation + + config = mkIf (cfg.dialerDefaults != "") { + + environment = { + + etc = + [ + { source = pkgs.writeText "wvdial.conf" configFile; + target = "wvdial.conf"; + } + { source = pkgs.writeText "wvdial" cfg.pppDefaults; + target = "ppp/peers/wvdial"; + } + ]; + + }; + + }; + +} diff --git a/nixos/modules/programs/zsh/zinputrc b/nixos/modules/programs/zsh/zinputrc new file mode 100644 index 000000000000..6121f3e21f16 --- /dev/null +++ b/nixos/modules/programs/zsh/zinputrc @@ -0,0 +1,42 @@ +# Stolen from ArchWiki + +# create a zkbd compatible hash; +# to add other keys to this hash, see: man 5 terminfo +typeset -A key + +key[Home]=${terminfo[khome]} + +key[End]=${terminfo[kend]} +key[Insert]=${terminfo[kich1]} +key[Delete]=${terminfo[kdch1]} +key[Up]=${terminfo[kcuu1]} +key[Down]=${terminfo[kcud1]} +key[Left]=${terminfo[kcub1]} +key[Right]=${terminfo[kcuf1]} +key[PageUp]=${terminfo[kpp]} +key[PageDown]=${terminfo[knp]} + +# setup key accordingly +[[ -n "${key[Home]}" ]] && bindkey "${key[Home]}" beginning-of-line +[[ -n "${key[End]}" ]] && bindkey "${key[End]}" end-of-line +[[ -n "${key[Insert]}" ]] && bindkey "${key[Insert]}" overwrite-mode +[[ -n "${key[Delete]}" ]] && bindkey "${key[Delete]}" delete-char +[[ -n "${key[Up]}" ]] && bindkey "${key[Up]}" up-line-or-history +[[ -n "${key[Down]}" ]] && bindkey "${key[Down]}" down-line-or-history +[[ -n "${key[Left]}" ]] && bindkey "${key[Left]}" backward-char +[[ -n "${key[Right]}" ]] && bindkey "${key[Right]}" forward-char +[[ -n "${key[PageUp]}" ]] && bindkey "${key[PageUp]}" beginning-of-buffer-or-history +[[ -n "${key[PageDown]}" ]] && bindkey "${key[PageDown]}" end-of-buffer-or-history + +# Finally, make sure the terminal is in application mode, when zle is +# active. Only then are the values from $terminfo valid. +if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then + function zle-line-init () { + printf '%s' "${terminfo[smkx]}" + } + function zle-line-finish () { + printf '%s' "${terminfo[rmkx]}" + } + zle -N zle-line-init + zle -N zle-line-finish +fi diff --git a/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix new file mode 100644 index 000000000000..cff751934d7d --- /dev/null +++ b/nixos/modules/programs/zsh/zsh.nix @@ -0,0 +1,180 @@ +# This module defines global configuration for the zshell. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + cfge = config.environment; + + cfg = config.programs.zsh; + + zshAliases = concatStringsSep "\n" ( + mapAttrsFlatten (k: v: "alias ${k}='${v}'") cfg.shellAliases + ); + +in + +{ + + options = { + + programs.zsh = { + + enable = mkOption { + default = false; + description = '' + Whenever to configure Zsh as an interactive shell. + Note that this tries to make Zsh the default + <option>users.defaultUserShell</option>, + which in turn means that you might need to explicitly + set this variable if you have another shell configured + with NixOS. + ''; + type = types.bool; + }; + + shellAliases = mkOption { + default = config.environment.shellAliases; + description = '' + Set of aliases for zsh shell. See <option>environment.shellAliases</option> + for an option format description. + ''; + type = types.attrs; # types.attrsOf types.stringOrPath; + }; + + shellInit = mkOption { + default = ""; + description = '' + Shell script code called during zsh shell initialisation. + ''; + type = types.lines; + }; + + loginShellInit = mkOption { + default = ""; + description = '' + Shell script code called during zsh login shell initialisation. + ''; + type = types.lines; + }; + + interactiveShellInit = mkOption { + default = ""; + description = '' + Shell script code called during interactive zsh shell initialisation. + ''; + type = types.lines; + }; + + promptInit = mkOption { + default = '' + autoload -U promptinit && promptinit && prompt walters + ''; + description = '' + Shell script code used to initialise the zsh prompt. + ''; + type = types.lines; + }; + + }; + + }; + + config = mkIf cfg.enable { + + programs.zsh = { + + shellInit = '' + . ${config.system.build.setEnvironment} + + ${cfge.shellInit} + ''; + + loginShellInit = cfge.loginShellInit; + + interactiveShellInit = '' + ${cfge.interactiveShellInit} + + ${cfg.promptInit} + ${zshAliases} + + # Some sane history defaults + export SAVEHIST=2000 + export HISTSIZE=2000 + export HISTFILE=$HOME/.zsh_history + + setopt HIST_IGNORE_DUPS SHARE_HISTORY + ''; + + }; + + environment.etc."zshenv".text = + '' + # /etc/zshenv: DO NOT EDIT -- this file has been generated automatically. + # This file is read for all shells. + + # Only execute this file once per shell. + if [ -n "$__ETC_ZSHENV_SOURCED" ]; then return; fi + __ETC_ZSHENV_SOURCED=1 + + ${cfg.shellInit} + + # Read system-wide modifications. + if test -f /etc/zshenv.local; then + . /etc/zshenv.local + fi + ''; + + environment.etc."zprofile".text = + '' + # /etc/zprofile: DO NOT EDIT -- this file has been generated automatically. + # This file is read for login shells. + + # Only execute this file once per shell. + if [ -n "$__ETC_ZPROFILE_SOURCED" ]; then return; fi + __ETC_ZPROFILE_SOURCED=1 + + ${cfg.loginShellInit} + + # Read system-wide modifications. + if test -f /etc/zprofile.local; then + . /etc/zprofile.local + fi + ''; + + environment.etc."zshrc".text = + '' + # /etc/zshrc: DO NOT EDIT -- this file has been generated automatically. + # This file is read for interactive shells. + + # Only execute this file once per shell. + if [ -n "$__ETC_ZSHRC_SOURCED" -o -n "$NOSYSZSHRC" ]; then return; fi + __ETC_ZSHRC_SOURCED=1 + + . /etc/zinputrc + + ${cfg.interactiveShellInit} + + # Read system-wide modifications. + if test -f /etc/zshrc.local; then + . /etc/zshrc.local + fi + ''; + + environment.etc."zinputrc".source = ./zinputrc; + + environment.systemPackages = [ pkgs.zsh ]; + + users.defaultUserShell = mkDefault "/run/current-system/sw/bin/zsh"; + + environment.shells = + [ "/run/current-system/sw/bin/zsh" + "/var/run/current-system/sw/bin/zsh" + "${pkgs.zsh}/bin/zsh" + ]; + + }; + +} |