Thursday, September 17, 2015

NixOS

http://psg.skinforum.org/nixos.html

NixOS is a variant of Linux that uses declarative approach. Like how Cisco use a single IOS config file to define the function of a switch, router, firewall, NixOS can use a single configuration.nix file to declare all its settings.
Instead of using Puppet or Chef to configure the OS, NixOS natively use its own declarative language to define how the OS is to be configured. Their emphasis is on the "what" of the config instead of the "how". ie. define that you need an apache httpd server, instead of finding what rpm to install. But fact is, all the unix admin knowledge is still there, just condensed into a single parameter definition file. eg. enable sshd. use port 22. define user foo. assign the home dir /home/foo. give it /bin/zsh as shell.

Terminology

  • NixOS ...
  • Nix ...
  • Packages: NixOS call them disturbtions.



Initial install

  1. Create a bootable USB using Unetbootin based on a live dvd iso. (Unetbootin is like Lili usb creator, but this didn't work as of 2015.09.15 as it didn't know about NixOS yet and used generic Linux, which failed to boot). ref: NixOS wiki
  2. Pre create the file system on the desired hard drive (fdisk, mkfs, lvm if desired) ref: NixOS manual install page
  3. mount /dev/sda1 /mnt
  4. swapon /dev/sda2
  5. nixos-generate-config --root /mnt
  6. nano /etc/nixos/configuration.nix
    enable grub boot loader. add additional desired pkg
  7. nano /etc/nixos/hardware-config.nix
    ensure right disk is defined as device#1. use blkid /dev/sda1 to check disk UID.
  8. nixos install # this command must somehow be preprogrammed to write to /mnt, and look for configuration.nix rooted in there.
  9. give a pw for the root acc when prompted. If it didn't ask to set a password, something went wrong and nixos install need to be run again.
  10. reboot
Basic configuration.nix for a laptop with KDE gui
# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running �nixos-help�).


## run sudo nixos-rebuild switch
## to apply changed

{ config, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  # Use the GRUB 2 boot loader.
  boot.loader.grub.enable = true;
  boot.loader.grub.version = 2;
  # Define on which hard drive you want to install Grub.
  # boot.loader.grub.device = "/dev/sda";
  ##
  boot.loader.grub.device = "/dev/sda";

  # networking.hostName = "nixos"; # Define your hostname.
  networking.hostName = "nixon"; # Define your hostname.
  networking.hostId = "b6e466c1";
  networking.firewall.enable = true;
  networking.firewall.allowPing = true;
  networking.networkmanager.enable = true;  # https://nixos.org/nixos/manual/sec-networking.html#sec-wireless 10.1
  #networking.wireless.enable = true;   # true means use wpa_supplicant
  #networking.useDHCP = false;          # Don't run dhclient on wlan0, but break DNS
  networking.wicd.enable = false;       # https://nixos.org/wiki/WICD wicd-gtk to run gui client

  # Select internationalisation properties.
  # i18n = {
  #   consoleFont = "lat9w-16";
  #   consoleKeyMap = "us";
  #   defaultLocale = "en_US.UTF-8";
  # };

  # List packages installed in system profile. To search by name, run:
  # $ nix-env -qaP | grep wget
  # environment.systemPackages = with pkgs; [
  #   wget
  # ];

  # List services that you want to enable:

  # Enable the OpenSSH daemon.
  # services.openssh.enable = true;
  services.openssh.enable = true;

  # Enable CUPS to print documents.
  # services.printing.enable = true;

  # Enable the X11 windowing system.
   services.xserver.enable = true;
   services.xserver.layout = "us";
  # services.xserver.xkbOptions = "eurosign:e";

  # Enable the KDE Desktop Environment.
   services.xserver.displayManager.kdm.enable = true;
   services.xserver.desktopManager.kde4.enable = true;

  # Define a user account. Don't forget to set a password with �passwd�.
  # users.extraUsers.guest = {
  #   isNormalUser = true;
  #   uid = 1000;
  # };

  users.extraUsers.sn = {
    isNormalUser = true;
    uid = 501;
    home = "/home/sn";
    extraGroups = [ "wheel" "networkmanager" ];
    openssh.authorizedKeys.keys = [ "ssh-dss AABB... sn@grumpyxmas.com" ];
  };

  users.extraUsers.sa9 = {
    isNormalUser = true;
    uid = 999;
    home = "/home/sa9";
    extraGroups = [ "networkmanager" ];
    openssh.authorizedKeys.keys = [ "ssh-dss AABB... sa@grumpyxmas.com" ];
    hashedPassword = "testtesttest";
  };
  # removing a user from the config file will trigger a userdel.  but the home dir remains (understandably don't want to delete files)


  environment.systemPackages = with pkgs; [
        zsh wget vim
        htop
        openbox-menu
        python27Packages.ipython
        python34Packages.ipython
        gpgme
        # uge   # no uge, sge, gridengine yet
        docker kubernetes
        #chromiumWrapper    # this doens't seems to exist anymore
        chromium
        firefox   firefoxWrapper
        kde4.networkmanagement
        kde4.kdemultimedia
        kde4.kdegraphics
        kde4.kdeutils
        kde4.applications
        #pkgs.kde4.kdegames
        #pkgs.kde4.kdeedu
        kde4.kdebindings
        kde4.kdeaccessibility
        kde4.kde_baseapps
        kde4.kactivities
        kde4.kdeadmin
        kde4.kdeartwork
        kde4.kde_base_artwork
        kde4.kdenetwork
        kde4.kdepim
        kde4.kdepimlibs
        kde4.kdeplasma_addons
        kde4.kdesdk
        kde4.kdetoys
        kde4.kde_wallpapers
        kde4.kdewebdev
        kde4.oxygen_icons
        kde4.kdebase_workspace
        kde4.kdelibs
        kde4.kdevelop
        kde4.kdevplatform
        kde4.qtcurve
        kde4.ColorSchemes
        kde4.desktopthemes
        kde4.kscreensaver
        kde4.kwin_styles
        kde4.partitionManager
        kde4.qt4
        kde4.yakuake
        kde4.kgpg
  ];

  # package configuration
  nixpkgs.config.allowUnfree = true;
  nixpkgs.config.firefox.enableAdobeFlash = true; # for Firefox

  nixpkgs.config.chromium.enableAdobeFlash = true; # for Chromium
  nixpkgs.config.chromium.enablePepperFlash = true;
  nixpkgs.config.chromium.enablePepperPDF = true;

  security.sudo.wheelNeedsPassword = false;
  #security.sudo.extraCOnfig

}
Basic hardware-configuration.nix
# Do not modify this file!  It was generated by �nixos-generate-config�
# and may be overwritten by future invocations.  Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, ... }:

{
  imports =
    [ 
    ];

  boot.initrd.availableKernelModules = [ "ehci_pci" "ata_piix" "firewire_ohci" "usb_storage" ];
  boot.kernelModules = [ "kvm-intel" ];
  boot.extraModulePackages = [ ];

  fileSystems."/" =
    ##{ device = "/dev/disk/by-uuid/81c298dc-64e4-4dde-9986-069753dcdece";
    ##  don't know where the above uuid came from, don't match blkid info
    { device = "/dev/sda1";
      # aka /dev/sda1  label=nixos
      fsType = "ext4";
    };

  swapDevices =
    ##[ { device = "/dev/disk/by-uuid/3a9de093-d26c-464a-b900-0ca5e1243bb8"; }
    ##  don't know where the above uuid came from, don't match blkid info
    [ { device = "/dev/sda5"; }
      # aka /dev/sda5  label=swapspace
    ];

  nix.maxJobs = 4;
}

One can create many additional *.nix config and import them into the configuration.nix. Some like the modularity of it. The default config separate the hardware into its own specific file. Other may place a GUI desktop part into its own file, thus easy to trim it out for a headless server. Beyond that, I personally like one monolithic file, so that it is easy to run a diff between two servers to find what difference have been made that may explain functionality differences.
Other example config: ordinatechnic

Notes on *.nix config file
There should be a single { config, pkgs, ... }: section. If needed, change it to: { config, tba, pkgs, ... }: .
There are a couple of ways to add software package, I like:
environment.systemPackages = with pkgs; [      # it is a semi-colon in there, i do find it weired...
  kde4.applications
  kde4.kdeutils
  firefox
  vim
  emacs
  zsh
  w3m
  elinks
];

Another format used often in the NixOS manual
environment.systemPackages =
  [ pkgs.thunderbird
    pkgs.vim
    pkgs.emacs
    pkgs.kde4.pgpg        
  ];

# not sure for  pkgs.kde4.pgpg        

Changing config

  1. sudo vi /etc/nixos/configuration.nix
  2. sudo nixos-rebuild switch Reboot is NOT needed.

Ad-hoc package addition

NixOS allows the use of nix-env -i PKGNAME to add package. this is similar to yum install PKGNAME. But for a declarative OS, I think it is best to put everything in the config file.
One nice thing, say for a development machine, user can add their own package without needing root password and so such commands would be run by the user.

nix-env -i PKGNAME   # add   package, like yum install PKGNAME.
nix-env -e PKGNAME   # erase package, like rpm -e ...
nix-env -u    # upgrade all pkg that has update
nix-env -q   # list packages installed by user and not as root
nix-env -q --installed  # ??

nix-env -qa \*   # list avail pkg for install.  ie: yum list
nix-env -qaP '*' --description # --query --available --attr-path
nix-env --rollback  # undo (details??)

??    # rpm -qa 


nix-search vim
nix-install vim


Commands/Troubleshooting

nixos-rebuild switch # change/update system as per /etc/nixos/configuration.nix 
nixos-rebuild boot
nixos-rebuild switch -p test
nixos-rebuild build

nixos-option services.xserver.enable # find out what the config file has resulted.  ie, this is a read, not a set.

passwd username  # 

Reference