Nixos.org: Unterschied zwischen den Versionen

Aus lugvswiki
Zur Navigation springenZur Suche springen
(orthografische Optimierungen + Back link)
 
(2 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
 
==Einführung in nixos.org==
 
==Einführung in nixos.org==
  
''Zusammenfassung aus einer Email an die Mailingliste von Marc:''
+
Paketliste: https://search.nixos.org/packages oder Overlays auf Github (unterschiedliche Qualität)
  
Die wichtigsten Features:
+
Webseite: https://nixos.org
  
URL: [http://nixos.org nixos.org]
+
Dokumentation: https://nixos.org/manual/nixos/stable/
WIKI: [http://nixos.org/wiki/Main_Page nixos.org/wiki/Main_Page] (Mit Verweis zu Mailingliste)
 
IRC:  [irc://irc.freenode.net irc.freenode.net]  #nixos
 
Unterstützte Architekturen: [http://de.wikipedia.org/wiki/SheevaPlug SheevaPlug], [http://de.wikipedia.org/wiki/I686 i686], [http://de.wikipedia.org/wiki/X64 x64], [http://de.wikipedia.org/wiki/Raspberry_Pi (Raspberry) PI], vielleicht noch ein paar mehr.
 
  
 +
Zusammenfassung:
 +
Nixos basiert auf dem Nix Paket manager welcher es erlaubt deterministisch also immer gleich Abhängigkeiten zu definieren.
 +
Wenn sich eine Abhängigkeit ändert ändert sich der Paktetpfad (ähnlich einem Git-Hash) und alle darauf basierenden Abhängigkeiten bekommen neue Pfade (Versionen).
 +
Vorteil: Gleicher Pfad gleiches Verhalten, dh.h auch Bisecting z.B mit git möglich !
 +
Nachteil: Bei kleinen Änderungen muss viel neu heruntergeladen werden.
  
2 repositories nixos (system) und nixpkgs (Pakete) bilden mit /etc/nixos/configuration.nix (System-Konfiguration) ein Linux System.
+
Pakete werden durch Garbage Collector Roots (Fäden) vor dem Garbage Collector (Müllschlucker) bewart.
 +
D.h. solange ein Paket über einen Symlink über eine User Installation oder über eine System-Konfiguration noch erreicht werden kann wird das Paket nicht gelöscht.
  
 +
PATH etc werden über spezielle User Profiles gemanaged und ersetzen /user/local/bin usw.
  
Einzelne Pakete werden ähnlich wie git Commits mit Hash versehen. Beispiel:
+
Damit sind atomic Upgrades möglich durch switchen von Symlinks.
  
/nix/store/hash-glibc-2.10
+
Nixos erlaubt es ein Paket mit Abhängigkeiten zu archivieren (Nar Archive)
/nix/store/hASH-glibc-2.11o
+
und offline woanders zu importieren/installieren.
/nix/store/HASH-firefox/bin/firefox (rpath wählt die passende gilbc)
 
  
 +
Auch können Pakete mit Abhängkeiten über nix-store --copy-closure differentiell kopiert werden.
  
Damit ist es möglich verschiedene Programmversionen mit leicht variierenden Abhängigkeiten auf der gleichen Festplatte zu speichern und entsprechend Umgebungen für Virtual-Machines etc. zur Verfügung zu stellen.
+
Pakete und Systeme können also ohne das laufende System zu stören auf mehreren PCs verteilt je nach Architektur auf Build-Slaves vorbereitet werden. Jedes Paket wird in einer Sandbox (chroot) installiert, so dass jedes Paket nur seine eigenen Abhängigkeiten sieht. Damit wird erreicht dass jede Installation soweit möglich bis auf Kleinigkeiten wie Zeit bzw CPU Architektur oder RAM Größe das gleiche reproduzierbare Verhalten zeigt.
  
 +
Zum Beispiel wenn man was unter Ubuntu kompiliert kann das configure Ergebnis von anderen installierten aber nicht relevanten Paketen und Header Dateien abhängen. Dh. 2 Ubuntu Installationen können verschiedenes Verhalten produzieren.
  
Jedes Paket hat klar definierte buildtime/runtime Abhängigkeiten, was ein einfaches vollständiges Kopieren auf andere Computer ermöglicht.
+
Dadurch dass jedes Paket mit jeder Version seinen eigenen  /nix/store/... Namen mit Hash hat kann man mehrere Generationen gleichzeitig auf der gleichen Partition installiert haben und beim Boot-Prozess auswählen welche Version man will. Dann wird /etc/ gemäß des im Store vorbereiteten Systems angepasst. Bootet man eine alte Version mit altem MySQL kann diese allerdings mit einem aktualisierten /var/db/.. mysql Verzeichnis nichts mehr anfangen. Aber deswegen gibt es ja z.B BTRFS.
  
 +
Am besten erklährt man die Vorteile der configuration.nix welche Hardware Profile laden kann an einem Beispeil, weswegen
 +
auch der Installationsprozess eine Hardware Datei und eine Sytem-Configurations-Datei erstellt.
  
Wenn keine Binaries von der offiziellen Hydra-Buildfarm verwendet werden können (z.B. weil man eigene Patches verwenden will), kann man die Builds auf mehrere Rechner verteilen.
+
Es demonstriert deutlich wie einfach es ist
 +
* Dokmuentation
 +
* Verhalten
 +
* Software (environment.systemPackages)
 +
* Cron-Jobs z.B. Backups
 +
in wenigen Dateien übersichtlich zu konfigurieren und zu duplizieren aber auch
 +
an den PC anzupassen. Leider muss man bei Thunderbird z.B. immer noch manuell
 +
Sprachpakete nachintsallieren, weil jene in ~/.thunderbird gespeichert werden.
  
 +
z.B. können so auch BTRFS Snapshots einmal pro Tag automatisch konfiguriert werden.
  
Mehrere System-Konfigurationen auf der gleichen Festplatte bedeutet auch, dass man die "alten" Konfigurationen über Grub-Boot-Menues automatisch zur Verfügung stellen kann, wenn also ein neues Setup nicht bootet, weil man einen Treiber vergessen hat ist es kein Problem: man bootet das alte, behebt das Problem und versucht alles noch einmal.
+
Die Installation kann theoretisch vereinfacht werden indem man ein Shell Script
 +
mit curl läd welches /etc/nixos/configuration.nix oder module runterläd bzw die
 +
Festplatte formatiert.
  
 +
Durch den inkrementellen Aufbau der Pakete + einrichten von /etc/* beim Booten
 +
können auch abgebrochene Installationen fortgesetzt werden. Es werden nur die
 +
noch fehlenden noch nicht im /nix/store vorhandenen Pakete identifiziert und
 +
installiert.
  
Dadurch das alle Pakete, die ein System ausmachen, im /nix/store vorbereitet werden können ohne das laufende System zu beeinträchtigen ist eine Umstellung auf eine neue Version in sehr kurzer Zeit möglich. Es reicht aus PATH neu zu setzen, /etc neu zu füllen und alle Services neu zu starten.
+
Gleichzeitig kann man durch sogenannte derivations eigene Software z.B. von
 +
Github konfigurieren und installieren.
  
  
Für User gibt es dann noch eigene Profile, so dass jeder User seine eigene Software installieren kann.
+
<pre>
 +
# beispiel eigenes Software Paket
  
 +
name = mkDerivation {
 +
  name = "mein-paket-von-github"
 +
  src = fetchGithub { # z.B. mit nix-prefetch-git holen
 +
    owner = "...";
 +
    name = "...";
 +
    hash = ".."
 +
  };
 +
  buildDepends = [ readline ];
 +
  meta = { .. }
 +
}
 +
# fertig details bitte Orignial-Dokumentation nachschauen.
 +
</pre>
  
Ein Nachteil der Reproduzierbarkeit (von beidem: funktionierenden Setups und Bugs) ist das Security Update Problem: Wenn eine Lücke in curl gefunden wird (wie erst vor kurzem, Weiterleitung auf ftp:// ähnliche Protokolle), dann reicht es nicht aus curl so zu ersetzen, sondern alles muss neu kompiliert werden.
+
Wenn man also wie hier gezeigt /home und / auf unterschiedlichen BTRFS
 +
subvolumes hat kann man System/Home unabhängig bei Bedarf zurücksetzen *EGAL*
 +
was der Benutzer gemacht hat.
 +
Ausfallzeiten länger als 5min eigentlich kaum möglich ausser man
 +
Hardware-Probleme.
  
 +
Allerdings muss man regelmäßig alte Snapshots löschen (und PC bischen Zeit
 +
geben). Das ist aber planbar.
  
Beispiel /etc/nixos/configuration.nix aus dem Manual: [http://hydra.nixos.org/build/4201682/download/1/nixos/manual.html http://hydra.nixos.org/build/4201682/download/1/nixos/manual.html]
+
Deswegn ist das alles ein ziemlich idiotensicheres Setup.
  
<nowiki>
+
Wenn wirklich Interesse besteht müsste man das alles nochmal testen.
  {pkgs, config}:{
+
Aber als Idee / Vorstellung ist dies schonmal gut.
  
  # pkgs: alle installierbaren Pakete
+
<pre>
 +
# shell script zum formatieren und installieren von Nixos nach booten von CD
  
  # config: Die System-Konfiguration
+
DEV=nbd0
 +
ENCRYPT=none
 +
SWAP_SIZE=30GiB
 +
BOOT_SIZE=512MiB
 +
# partition prefix
 +
P=p
 +
# BOOT_SIZE=1GiB
 +
MOUNT_POINT=/mnt
  
{
 
  
  boot.loader.grub.device = "/dev/sda";
+
set -x
 +
parted /dev/${DEV} -- mklabel gpt
 +
parted /dev/${DEV} -- mkpart primary $BOOT_SIZE -$SWAP_SIZE
 +
parted /dev/${DEV} -- mkpart primary linux-swap -$SWAP_SIZE 100%
 +
parted /dev/${DEV} -- mkpart primary 1MiB $BOOT_SIZE -$SWAP_SIZE 100%
 +
parted /dev/${DEV} -- mkpart ESP fat32 1MiB $BOOT_SIZE
 +
parted /dev/${DEV} -- set 3 boot on
  
   fileSystems."/".device = "/dev/disk/by-label/nixos";
+
case $ENCRYPT in
 +
   none)
 +
    mkfs.btrfs /dev/${DEV}${P}1
 +
    ROOT_DEVICE=/dev/${DEV}${P}1
 +
    ;;
 +
  luks)
 +
    MAPPER_NAME=${DEV}${P}1
 +
    cryptsetup --verbose --verify-passphrase luksFormat /dev/${DEV}${P}1
 +
    cryptsetup luksOpen /dev/${DEV}${P}1 ${MAPPER_NAME}
 +
    mkfs.btrfs /dev/mapper/${MAPPER_NAME}
 +
    ROOT_DEVICE=/dev/mapper/${MAPPER_NAME}
 +
    ;;
 +
esac
 +
mkswap -L swap /dev/${DEV}${P}2
 +
mkfs.fat -F 32 -n boot /dev/${DEV}${P}3
 +
mount $ROOT_DEVICE $MOUNT_POINT
 +
mkdir /mnt/boot
 +
mount /dev/${DEV}${P}3 $MOUNT_POINT/boot
 +
nixos-generate-config --root $MOUNT_POINT
 +
# sed -i 's/# \(boot.loader.grub.device\)/\1/' $MOUNT_POINT/etc/nixos/configuration.nix
 +
nixos-install --root $MOUNT_POINT
  
  swapDevices = [ { device = "/dev/disk/by-label/swap"; } ];
+
</pre>
  
  # mit openssh Server support
+
<pre>
 +
#configuration.nix
 +
{pkgs , config, ...}:
 +
let
 +
inherit (pkgs) lib;
 +
inherit (lib) mkMerge mkOverride;
 +
in
 +
{
  
   services.sshd.enable = true;
+
   imports =
 +
    [
 +
        ./disk-configuration.nix
 +
        ./shared-configuration.nix
 +
        ./hardware-configuration.nix
 +
    ];
 +
  config = {
 +
    boot.loader.grub.configurationName = "x68_64";
 +
  };
  
  services.sshd.permitRootLogin = true;
+
}
 +
</pre>
  
  # und so weiter
+
<pre>
}
 
</nowiki>
 
  
Wer mehr Interesse hat dem kann ich Zugang zu einer virtual-machine geben, zum testen und ausprobieren.
+
shared-configuration.nix
 +
{pkgs , config, ...}:
  
 +
let
  
Hier noch ein Beispiel, dass auch compile time Parameter einfach konfiguriert werden können, so dass vom nixos Distributions-Default einfach abgewichen werden kann:
+
  inherit (pkgs) lib;
[https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/configurable.nix https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/configurable.nix]
+
  inherit (lib) mkMerge mkOverride;
  
 +
in
  
Ein User würde z.B. in dieser Art und Weise python support für Vim aktivieren, und dann eine für ihn kompilierte Version bekommen:
+
{
  
<nowiki>
+
  imports =
  ~/.nixpkgs/config.nix:
+
    [
 +
    ];
  
{
 
  
    packageOverrides = p: {
+
  config = {
 +
        nixpkgs.config.allowBroken = true;
  
      vim_configurable = p.vim_configurable.override { pythonSupport = true; }
+
        hardware.pulseaudio.enable = true;
 +
        networking.networkmanager.enable = true;
 +
        networking.firewall.enable = true;
 +
        networking.firewall.allowedTCPPorts = [];
  
    }
+
      # networking.useDHCP = true;
  
}
+
        programs.bash.promptInit = "";
</nowiki>
+
        environment.pathsToLink = ["/"];
  
 +
        environment.sessionVariables = { TERMINFO_DIRS = "/run/current-system/sw/share/terminfo"; };
  
Dementsprechend einfach ist es auch dev/preview/alpha/beta/.. Programme zu supporten.
+
        i18n.defaultLocale = "de_DE.UTF-8";
 +
        time.timeZone=  "Europe/Berlin";
  
 +
# services.blueman.enable = true;
 +
        environment.systemPackages = [
 +
          pkgs.iotop
 +
          pkgs.pciutils
 +
          pkgs.gwenview
 +
pkgs.evince
 +
pkgs.okular
 +
# pkgs.acroread
 +
        # ] ++ (attrValues pkgs.plasma5) ++ [
 +
          #  pkgs.plasma-nm
 +
          pkgs.bluedevil
  
KDE zum Beispiel ist unterstützt, GNOME Desktop soweit ich weiß nicht.  
+
          pkgs.vim
 +
          pkgs.kate
 +
          pkgs.firefox
  
  
Es sind nur 20-30 mehr oder weniger "Freizeit-Entwickler", die das System voranbringen.
 
  
  
Die Vorteile sind immer dann ganz besonders deutlich, wenn geringe Script-Features sinnvoll sind, z.B. beim definieren von systemd mit php-fpm Pools (die gleichen Sockets müssen an verschiedenen Stellen definiert werden: systemd, damit es php-fpm Daemon starten kann, apache und nginx, damit sie wissen wohin sie sich verbinden müssen etc). In solchen Fällen kann man dann einmal ein Nixos-Modul schreiben, und kann damit die Arbeit deutlich reduzieren.
+
          # /backup/mount-disk kann durch /volumes ersetzt werden
 +
          # /backup/references eventuell auf /volumes verschieben ?
 +
          ( pkgs.writeScriptBin "erstelle-backup-externe-festplatte" ''
 +
          #!/bin/sh -e
 +
          set -x
 +
          mkdir -p /backup/mount-disk
 +
          mkdir -p /backup/mount-backup
 +
          mkdir -p /backup/references
  
 +
          mount /dev/sda3 /backup/mount-disk
 +
          mount /dev/disk/by-uuid/1b6a7b15-f6bd-4c0c-b735-aaf928ee79db /backup/mount-backup -o compress=zstd:1
  
Natürlich gibt's ab und zu auch Probleme, zB python/ruby etc erwarten manchmal, dass alles in einem Verzeichnis installiert wird. Hier muss dann manchmal doch einiges gepatcht werden.
+
          for subvol in home system; do
 +
            echo backup hup $subvol
 +
            btrfs-backup-nach.sh "benutzer-backup-$subvol" "/backup/mount-disk/$subvol" "/backup/references/benutzer-backup-$subvol" /backup/mount-backup
 +
          done
  
----
+
          umount /backup/mount-disk
Zurück zur [[Hauptseite]]
+
          umount /backup/mount-backup
 +
 
 +
          echo "BACKUP FERTIG"
 +
          '')
 +
 
 +
          ( pkgs.writeScriptBin "btrfs-backup-nach.sh" ''
 +
#!/bin/sh -e
 +
set -o pipefail
 +
 
 +
# mount: mount point
 +
# target: the name of the external disk
 +
# for each name a reference is kept so that next backup is differential and fast
 +
 
 +
target=$1
 +
mount=''${2:-/backup}
 +
 
 +
# identify that the target destination is the expected one.
 +
# this is done by expecting backup-dummy$target filename to be there
 +
dummy="$mount/backup-dummy$target"
 +
 
 +
[ -n "target" ] || { echo "usage: ./backup.sh external-disk /backup "; exit 1; }
 +
 
 +
[ -f "$dummy" ] || {
 +
        echo "$dummy file to identify backup location not found. Shall I touch it? [y/N]"
 +
        read reply
 +
        if [ "$reply" == "y" ]; then
 +
                touch "$dummy"
 +
        else
 +
                echo 'failing'; exit 1
 +
        fi
 +
}
 +
 
 +
backup(){
 +
  local name="$1"
 +
  local from="$2"
 +
  # where to store subvolumes and keep last for incremental update
 +
  local dir_in_from="$3"
 +
  local to="$4"
 +
 
 +
  now=$(date '+%Y-%m-%d_%H%M%S')
 +
 
 +
  mkdir -p "$dir_in_from"
 +
 
 +
  if [ -f "$dir_in_from/last-backup-''${name}" ]; then
 +
    local last=$(cat "$dir_in_from/last-backup-''${name}" 2>/dev/null || true)
 +
    echo 'snapshotting from'
 +
    btrfs subvolume snapshot -r "$from" "$dir_in_from/$name-$now"
 +
    echo 'updating target'
 +
    btrfs send -p "$dir_in_from/$last" "$dir_in_from/$name-$now" | btrfs receive "$to"
 +
    echo 'deleting old reference'
 +
    btrfs subvolume delete "$dir_in_from/$last"
 +
    echo "new snapshot is is $name-$now"
 +
    echo "$name-$now" > "$dir_in_from/last-backup-''${name}"
 +
  else
 +
    echo "creating initial snapshot as reference"
 +
    btrfs subvolume snapshot -r "$from" "$dir_in_from/$name-$now"
 +
    echo "sending initial data .. might take long"
 +
    btrfs send "$dir_in_from/$name-$now" | btrfs receive "$to"
 +
    echo "$name-$now" > "$dir_in_from/last-backup-''${name}"
 +
  fi
 +
}
 +
 
 +
backup "$@"
 +
          ''
 +
          )
 +
 
 +
          ( pkgs.writeScriptBin "nixos-aktualisieren" ''
 +
            #!/bin/sh
 +
            set -e
 +
            set -x
 +
            sudo erstelle-snapshots
 +
            sudo nix-channel --update
 +
            sudo nixos-rebuild boot
 +
            echo 'Aktualisierung fertig bitte neu starten. Thunderbird Extensios -> Deutsche Übersetzungen neu installieren'
 +
          ''
 +
          )
 +
 
 +
          ( pkgs.writeScriptBin "erstelle-snapshots" ''
 +
            #!/bin/sh
 +
            set -x
 +
              echo "system"
 +
              ${pkgs.btrfsProgs}/bin/btrfs subvolume snapshot -r / /subvolumes/system-$(${pkgs.coreutils}/bin/date +'%Y-%m-%d_%H%M%S')
 +
              echo "home"
 +
              ${pkgs.btrfsProgs}/bin/btrfs subvolume snapshot -r /home /subvolumes/home-$(${pkgs.coreutils}/bin/date +'%Y-%m-%d_%H%M%S')
 +
              echo "fertig"
 +
          ''
 +
          )
 +
 
 +
          (
 +
            pkgs.writeScriptBin "hilfe" ''
 +
            #!/bin/sh
 +
            ${pkgs.utillinux}/bin/more <<EOF
 +
            Bei Problemen -> LUGVS Mailinglist
 +
 
 +
            User Linux Group Villingen Schwenningen einmal pro Monat
 +
                Siehe https://lug-vs.org/lugvswiki/index.php/Hauptseite,
 +
                Die kennen sich jedoch mit Nixos.org Linux nicht aus
 +
 
 +
                Haben auch Mailingliste
 +
 
 +
            Chat Hilfe zu Nixos (English)
 +
                Terminal eingaben irssi
 +
                Dann eingeben /connect irc.liberachact.net
 +
                Dann eingeben /join #nixos
 +
 
 +
            Remote Desktop sharing (Support)
 +
                anydesk nutzen
 +
 
 +
            System aktualisieren (kann nichts passieren, weil alte Versionen bleiben bestehen)
 +
                sudo nixos-aktualisieren
 +
                Eventuell muss bei Thunderbird hinterher Deutsche Sprachpakete
 +
                neu installiert werden.
 +
 
 +
 
 +
            Backups (gleiche Festplatte mit BTRFS)
 +
                sudo erstelle-snapshot eingeben
 +
 
 +
                Backups liegen unter /subvolumes
 +
                Schützt nicht vor Festplatten-Crash / versagen
 +
 
 +
            Backup externe Festplatte (btrfs send) empfohlen:
 +
                sudo erstelle-backup-externe-festplatte
 +
 
 +
 
 +
            System aufräumen (alte Versionen löschen - also nur wenn neue Version geht)
 +
                sudo nix-collect-garbage -d
 +
                Wenn danach Anwendungen nicht mehr korrekt funktionieren eventuell in
 +
                ~/.config/* Dateien löschen und erneut probieren
 +
                (vorher sudo erstelle-snapshot ausführen)
 +
 
 +
            iphone mounten (wegen Bildern)
 +
                google ifuse. z.B.
 +
                sudo ifuse /mnt
 +
 
 +
            Android mounten
 +
                sudo mtpfs /mnt
 +
 
 +
            Drucken -> Cups kann eingerichtet werden. Wenns aber nur 1-2 Seiten
 +
                sind kurz zu Frau Burger gehen oder zu meiner Mutter, PDF mitbringen.
 +
 
 +
                  Drucken -> "Print To File" oder "In Datei Drucken"
 +
                  PDF Speicherort angeben.
 +
 
 +
              Zum Enrichten langfristig:
 +
                  sudo nano /etc/nixos/shared-configuration.nix
 +
                  dort siehe printing (Treiber müssen hinzugefügt werden)
 +
 
 +
 
 +
 
 +
            Manuell Backups externes Medium:
 +
                Externe Festplatte ist besser weil Festplatte kaputt gehen kann
 +
                (einfach manuell kopieren, gibt auch viele Tools)
 +
 
 +
                Beispiel
 +
                mount /dev/sdb1 /mnt
 +
                rsync -ra --delete /home/benutzer/ /mnt/backup-home-benutzer/
 +
                umount /mnt
 +
 
 +
            System-Check
 +
                smartmontools ist installiert
 +
 
 +
                Dateisystem:
 +
                  sudo btrfs scrub start /dev/sda
 +
                  # bischen warten..
 +
                  # dann immer wieder bis fertig ist:
 +
                  sudo btrfs scrub status /dev/sda
 +
 
 +
                Paket-Check
 +
                  sudo nix-store --verify --check-contents
 +
 
 +
                Festplatte Eigenauskunft S.M.A.R.T auslesen
 +
                  sudo smartctl -a /dev/sda
 +
 
 +
                  Die werte sollten über den TRESH werten liegen.
 +
 
 +
                Memory (beim booten memtest wählen)
 +
 
 +
            Habe-Ich-Internet-Test
 +
                ping www.gmx.de
 +
 
 +
            root werden:
 +
                sudo anwendung
 +
                sudo su -> wieder shell
 +
 
 +
            USB Stick (oder Kamera)
 +
                mount /dev/sdb1 /mnt
 +
                .. Daten kopieren
 +
                umount /mnt
 +
 
 +
                Statt sda1 eventuell sdb2 (zweite Partition) oder sdbX für zweiten USB Stick etc
 +
 
 +
                Partitionen (USB Stick) finden:
 +
                sudo fdisk -l
 +
                auf Grösse achten
 +
 
 +
                Können das auch als Script automatisieren oder udev-rule
 +
 
 +
            Programme:
 +
                audacity: Audio
 +
                scalc (Tabellen)
 +
                simpress (Präsentationen)
 +
                gimp: Bilder
 +
                Krita: Malen
 +
                Firefox: Internet
 +
                Thunderbird: E-Mails
 +
                Blender: 3d test und 3d Malen, 3d Animation und mehr
 +
                mplayer/vlc: videos und Mediadateien aufmachen + Streaming
 +
            EOF
 +
            ''
 +
            )
 +
 
 +
          pkgs.irssi
 +
          pkgs.utillinux
 +
          pkgs.nettools
 +
          # pkgs.firefox
 +
          pkgs.chromium
 +
          pkgs.libreoffice
 +
          pkgs.audacity
 +
          pkgs.krita
 +
          pkgs.inkscape
 +
          pkgs.gimp
 +
          pkgs.thunderbird
 +
          pkgs.gnome3.nautilus
 +
          pkgs.ifuse # mount iphone
 +
          pkgs.mtpfs # mountandroid
 +
          pkgs.anydesk # Es funktioniert einfach...
 +
          pkgs.smartmontools
 +
          pkgs.blender
 +
          pkgs.mplayer
 +
          pkgs.vlc
 +
        ];
 +
 
 +
        services.printing = {
 +
          enable = true;
 +
          # drivers = [ pkgs.hlip ];
 +
        };
 +
 
 +
        programs.zsh.enable = true;
 +
        programs.zsh.promptInit = ''
 +
          if [ "$TERM" != dumb ]; then
 +
            # prompt walters
 +
            autoload -U promptinit && promptinit
 +
          fi
 +
        '';
 +
 
 +
        users.users.benutzer = {
 +
          isNormalUser = true;
 +
          home = "/home/benutzer";
 +
          description = "benutzer";
 +
          extraGroups = [ "wheel" "networkmanager" ];
 +
          # openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
 +
        };
 +
 
 +
 
 +
      environment.etc."nix/machines".target = "nix/machines.sample";
 +
 
 +
      fileSystems."/tmp" = { device = "tmpfs"; fsType = "tmpfs"; options = ["size=20000m" "mode=1777"]; };
 +
 
 +
      fonts.fontconfig.enable = true;
 +
      fonts.enableFontDir = true;
 +
      fonts.fonts = [ ];
 +
 
 +
      nixpkgs.config.permittedInsecurePackages = [
 +
        "openssl-1.0.2u"
 +
      ];
 +
      nixpkgs.config.allowUnfree = true;
 +
      nixpkgs.config.android_sdk.accept_license = true;
 +
      nixpkgs.config.ruby.tags = true;
 +
      # nixpkgs.config.packageOverrides = p: {
 +
 
 +
 
 +
 
 +
      nix = {
 +
          package = pkgs.nixUnstable;
 +
          daemonNiceLevel = 20;
 +
          useSandbox = true;
 +
      };
 +
 
 +
      programs.ssh.startAgent = false;
 +
      programs.gnupg.agent.enable = true;
 +
 
 +
      # services.cron.systemCronJobs =
 +
      #  let
 +
      #    backupscript = pkgs.writeScriptBin "backupscript" ''
 +
      #    #!/bin/sh
 +
      #    ${pkgs.btrfsProgs}/bin/btrfs subvolume snapshot / /root/root-of-fs-$(${pkgs.coreutils}/bin/date +'%Y-%m-%d_%H%M%S')
 +
      #    '';
 +
      #  in
 +
      #    [
 +
      #      "0 10,15 * * * root ${backupscript}"
 +
      #    ];
 +
 
 +
 
 +
      services.nfs.server.enable = true;
 +
 
 +
      services.ntp.enable = true;
 +
 
 +
      # services.openssh = {
 +
      #  enable    = true;
 +
      #  allowSFTP = true;
 +
      #  # startOn  = "never";
 +
      #  passwordAuthentication = true;
 +
      # };
 +
 
 +
 
 +
      security.sudo = {
 +
        enable = true;
 +
        configFile = mkOverride 20 ''
 +
          root        ALL=(ALL) SETENV: ALL
 +
          benutzer    ALL=(ALL) NOPASSWD: ALL
 +
 
 +
          # Users in the \"wheel\" group can do anything.
 +
          # %wheel      ALL=(ALL) SETENV: ALL
 +
          '';
 +
      };
 +
 
 +
      documentation.nixos.enable = false;  # takes too much time to build
 +
 
 +
      services.xserver.enable = true;
 +
      services.xserver.autorun = true;
 +
      services.xserver.layout = "de";
 +
 
 +
      services.xserver.wacom.enable = true;
 +
      services.xserver.enableTCP = true;
 +
      services.xserver.resolutions = [];
 +
      # services.xserver.windowManager.default = "wmii";
 +
 
 +
      services.xserver.desktopManager.plasma5.enable = true;
 +
      services.xserver.desktopManager.lxqt.enable = true;
 +
 
 +
      systemd.services.nix-daemon.serviceConfig.IOSchedulingClass = "idle";
 +
      systemd.services.nix-daemon.serviceConfig.CPUShares = 123;
 +
      systemd.services.nix-daemon.serviceConfig.MemoryLimit = "10G";
 +
      # users.defaultUserShell = "/var/run/current-system/sw/bin/zsh";
 +
  };
 +
 
 +
}
 +
</pre>
 +
 
 +
 
 +
<pre>
 +
# hardware-configuration.nix
 +
# vom Installationscript erstellt
 +
{ config, lib, pkgs, ... }:
 +
 
 +
{
 +
  imports =
 +
    [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
 +
    ];
 +
 
 +
  boot.initrd.availableKernelModules = [ "btrfs" "ehci_pci" "ahci" "usb_storage" "sd_mod" "sr_mod" "rtsx_usb_sdmmc" ];
 +
  boot.kernelParams = [ ];
 +
  # boot.kernelPackages = pkgs.linuxPackages_testing; # oder 20
 +
  boot.blacklistedKernelModules = [ ];
 +
 
 +
  powerManagement = {
 +
    enable = true;
 +
    cpuFreqGovernor = "ondemand";
 +
  };
 +
 
 +
  # services.logind.lidSwitch = "ignore";
 +
  # services.xserver.videoDrivers = [ "ati_unfree" ];
 +
  # boot.kernelPackages = pkgs.linuxPackages_latest;
 +
  # boot.kernelParams = [ "amd_iommu=pt" "ivrs_ioapic[32]=00:14.0" "iommu=soft" ];
 +
  # services.xserver.videoDrivers = [ "amdgpu" ];
 +
  # services.xserver.videoDrivers = [ "ati_unfree" ];
 +
  hardware.firmware = [pkgs.firmwareLinuxNonfree pkgs.sof-firmware];
 +
  hardware.cpu.amd.updateMicrocode = true;
 +
  hardware.enableAllFirmware = true;
 +
  # hardware.enableRedistributableFirmware = true;
 +
  # hardware.opengl.enable = true;
 +
  # hardware.opengl.driSupport = true;
 +
  hardware.opengl.driSupport = true;
 +
  # programs.light.enable = true;
 +
}
 +
</pre>
 +
 
 +
== Zusammenfassung: ==
 +
 
 +
Eine fast automatische Installation wäre so möglich:
 +
 
 +
<pre>
 +
# iso runterladen
 +
# booten
 +
# sudo su
 +
 
 +
# automatisch formatieren und configuration.nix Template anlegen
 +
DEV=/dev/sda
 +
curl https://script-noch-zu-erstellen-was-foramtiert-dann-mounted-dann-configuration.nix-anlegt > /tmp/script
 +
. /tmp/script
 +
# nixos-hardware-scan
 +
# nixos-install ..
 +
# shutdown -r now
 +
</pre>
 +
 
 +
Das Sytsem hätte dann
 +
- lugvs dokumentation mit hilfe-lugvs aufrufbar oder ähnlich auch was vieles weitere erinnert
 +
- regelmäßige Snapshots
 +
- ein Backup Script für externe Festplatte inkrementell mit BTRFS
 +
- einfache Update Scripte um sich selbst solange zu aktualisieren bis sich die
 +
  Wörter in configuration.nix verändern. Manchmal kommt was dazu oder wird
 +
  umbenannt.
 +
 
 +
Aber ein Crash oder halbfertiges System beim Benutzer (Update-Probleme) sind
 +
passieren nicht mehr oder sind zurückstellbar in kalkulierbaren 5 Minuten.
 +
 
 +
 
 +
 
 +
== Wie geht nutzt man z.B. Python oder Haskell mit NixOS? ==
 +
 
 +
<pre>
 +
cabal2nix_init(){
 +
  local dir=$(basename `pwd`)
 +
  local defaultGHC=${1:-ghc921}
 +
 
 +
$(nix-build -A cabal2nix $NIXPKGS_ALL)/bin/cabal2nix . > $dir.nix
 +
 
 +
cat > default.nix << EOF
 +
{ nixpkgs ? import <nixpkgs> {}, compiler ? "${defaultGHC}" }:
 +
nixpkgs.haskell.packages.\${compiler}.callPackage ./$dir.nix { }
 +
EOF
 +
 
 +
cat > shell.nix << EOF
 +
{ nixpkgs ? import <nixpkgs> {}, compiler ? "${defaultGHC}" }:
 +
(import ./default.nix { inherit nixpkgs compiler; }).env
 +
EOF
 +
 
 +
# nix-shell -A env ./default.nix
 +
</pre>
 +
 
 +
das cabal2nix_init Script erstellt einige .nix Dateien die dann genutzt werden
 +
um die Abhängikgeiten im Store bereitzustellen. Dann kann mit nix-shell eine Shell
 +
bereitgestellt werden wo ghc ghc-pkg cabal etc vorhanden sind und jene finden.
 +
D.h. einem ./Setup configure && ./Setup build steht nichts mehr im Wege.
 +
 
 +
Das geht meistens gut - manchmal leider auch nicht.
 +
 
 +
Ähnliche Tools gibts für Ruby, Python ..
 +
 
 +
Auf die Art und Weise lassen sich auch derivations generieren so dass man
 +
Software über environment.systemPackages schnell installieren kann.
 +
 
 +
Nach meiner Meinung ist das alles einfacher als Pakete für Debian / Suse
 +
bereitzustellen (wenns klappt)

Aktuelle Version vom 26. Mai 2022, 17:01 Uhr

Einführung in nixos.org

Paketliste: https://search.nixos.org/packages oder Overlays auf Github (unterschiedliche Qualität)

Webseite: https://nixos.org

Dokumentation: https://nixos.org/manual/nixos/stable/

Zusammenfassung: Nixos basiert auf dem Nix Paket manager welcher es erlaubt deterministisch also immer gleich Abhängigkeiten zu definieren. Wenn sich eine Abhängigkeit ändert ändert sich der Paktetpfad (ähnlich einem Git-Hash) und alle darauf basierenden Abhängigkeiten bekommen neue Pfade (Versionen). Vorteil: Gleicher Pfad gleiches Verhalten, dh.h auch Bisecting z.B mit git möglich ! Nachteil: Bei kleinen Änderungen muss viel neu heruntergeladen werden.

Pakete werden durch Garbage Collector Roots (Fäden) vor dem Garbage Collector (Müllschlucker) bewart. D.h. solange ein Paket über einen Symlink über eine User Installation oder über eine System-Konfiguration noch erreicht werden kann wird das Paket nicht gelöscht.

PATH etc werden über spezielle User Profiles gemanaged und ersetzen /user/local/bin usw.

Damit sind atomic Upgrades möglich durch switchen von Symlinks.

Nixos erlaubt es ein Paket mit Abhängigkeiten zu archivieren (Nar Archive) und offline woanders zu importieren/installieren.

Auch können Pakete mit Abhängkeiten über nix-store --copy-closure differentiell kopiert werden.

Pakete und Systeme können also ohne das laufende System zu stören auf mehreren PCs verteilt je nach Architektur auf Build-Slaves vorbereitet werden. Jedes Paket wird in einer Sandbox (chroot) installiert, so dass jedes Paket nur seine eigenen Abhängigkeiten sieht. Damit wird erreicht dass jede Installation soweit möglich bis auf Kleinigkeiten wie Zeit bzw CPU Architektur oder RAM Größe das gleiche reproduzierbare Verhalten zeigt.

Zum Beispiel wenn man was unter Ubuntu kompiliert kann das configure Ergebnis von anderen installierten aber nicht relevanten Paketen und Header Dateien abhängen. Dh. 2 Ubuntu Installationen können verschiedenes Verhalten produzieren.

Dadurch dass jedes Paket mit jeder Version seinen eigenen /nix/store/... Namen mit Hash hat kann man mehrere Generationen gleichzeitig auf der gleichen Partition installiert haben und beim Boot-Prozess auswählen welche Version man will. Dann wird /etc/ gemäß des im Store vorbereiteten Systems angepasst. Bootet man eine alte Version mit altem MySQL kann diese allerdings mit einem aktualisierten /var/db/.. mysql Verzeichnis nichts mehr anfangen. Aber deswegen gibt es ja z.B BTRFS.

Am besten erklährt man die Vorteile der configuration.nix welche Hardware Profile laden kann an einem Beispeil, weswegen auch der Installationsprozess eine Hardware Datei und eine Sytem-Configurations-Datei erstellt.

Es demonstriert deutlich wie einfach es ist

  • Dokmuentation
  • Verhalten
  • Software (environment.systemPackages)
  • Cron-Jobs z.B. Backups

in wenigen Dateien übersichtlich zu konfigurieren und zu duplizieren aber auch an den PC anzupassen. Leider muss man bei Thunderbird z.B. immer noch manuell Sprachpakete nachintsallieren, weil jene in ~/.thunderbird gespeichert werden.

z.B. können so auch BTRFS Snapshots einmal pro Tag automatisch konfiguriert werden.

Die Installation kann theoretisch vereinfacht werden indem man ein Shell Script mit curl läd welches /etc/nixos/configuration.nix oder module runterläd bzw die Festplatte formatiert.

Durch den inkrementellen Aufbau der Pakete + einrichten von /etc/* beim Booten können auch abgebrochene Installationen fortgesetzt werden. Es werden nur die noch fehlenden noch nicht im /nix/store vorhandenen Pakete identifiziert und installiert.

Gleichzeitig kann man durch sogenannte derivations eigene Software z.B. von Github konfigurieren und installieren.


# beispiel eigenes Software Paket

name = mkDerivation {
  name = "mein-paket-von-github"
  src = fetchGithub { # z.B. mit nix-prefetch-git holen
    owner = "...";
    name = "...";
    hash = ".."
  };
  buildDepends = [ readline ];
  meta = { .. }
}
# fertig details bitte Orignial-Dokumentation nachschauen.

Wenn man also wie hier gezeigt /home und / auf unterschiedlichen BTRFS subvolumes hat kann man System/Home unabhängig bei Bedarf zurücksetzen *EGAL* was der Benutzer gemacht hat. Ausfallzeiten länger als 5min eigentlich kaum möglich ausser man Hardware-Probleme.

Allerdings muss man regelmäßig alte Snapshots löschen (und PC bischen Zeit geben). Das ist aber planbar.

Deswegn ist das alles ein ziemlich idiotensicheres Setup.

Wenn wirklich Interesse besteht müsste man das alles nochmal testen. Aber als Idee / Vorstellung ist dies schonmal gut.

# shell script zum formatieren und installieren von Nixos nach booten von CD

DEV=nbd0
ENCRYPT=none
SWAP_SIZE=30GiB
BOOT_SIZE=512MiB
# partition prefix
P=p
# BOOT_SIZE=1GiB
MOUNT_POINT=/mnt


set -x
parted /dev/${DEV} -- mklabel gpt
parted /dev/${DEV} -- mkpart primary $BOOT_SIZE -$SWAP_SIZE
parted /dev/${DEV} -- mkpart primary linux-swap -$SWAP_SIZE 100%
parted /dev/${DEV} -- mkpart primary 1MiB $BOOT_SIZE -$SWAP_SIZE 100%
parted /dev/${DEV} -- mkpart ESP fat32 1MiB $BOOT_SIZE
parted /dev/${DEV} -- set 3 boot on

case $ENCRYPT in
  none)
    mkfs.btrfs /dev/${DEV}${P}1
    ROOT_DEVICE=/dev/${DEV}${P}1
    ;;
  luks)
    MAPPER_NAME=${DEV}${P}1
    cryptsetup --verbose --verify-passphrase luksFormat /dev/${DEV}${P}1
    cryptsetup luksOpen /dev/${DEV}${P}1 ${MAPPER_NAME}
    mkfs.btrfs /dev/mapper/${MAPPER_NAME}
    ROOT_DEVICE=/dev/mapper/${MAPPER_NAME}
    ;;
esac
mkswap -L swap /dev/${DEV}${P}2
mkfs.fat -F 32 -n boot /dev/${DEV}${P}3
mount $ROOT_DEVICE $MOUNT_POINT
mkdir /mnt/boot
mount /dev/${DEV}${P}3 $MOUNT_POINT/boot
nixos-generate-config --root $MOUNT_POINT
# sed -i 's/# \(boot.loader.grub.device\)/\1/' $MOUNT_POINT/etc/nixos/configuration.nix
nixos-install --root $MOUNT_POINT

#configuration.nix
{pkgs , config, ...}:
let
inherit (pkgs) lib;
inherit (lib) mkMerge mkOverride;
in
{

  imports =
    [
         ./disk-configuration.nix
         ./shared-configuration.nix
         ./hardware-configuration.nix
    ];
  config = {
    boot.loader.grub.configurationName = "x68_64";
  };

}

shared-configuration.nix
{pkgs , config, ...}:

let

  inherit (pkgs) lib;
  inherit (lib) mkMerge mkOverride;

in

{

  imports =
    [
    ];


  config = {
        nixpkgs.config.allowBroken = true;

        hardware.pulseaudio.enable = true;
        networking.networkmanager.enable = true;
        networking.firewall.enable = true;
        networking.firewall.allowedTCPPorts = [];

      # networking.useDHCP = true;

        programs.bash.promptInit = "";
        environment.pathsToLink = ["/"];

        environment.sessionVariables = { TERMINFO_DIRS = "/run/current-system/sw/share/terminfo"; };

        i18n.defaultLocale = "de_DE.UTF-8";
        time.timeZone=  "Europe/Berlin";

#	services.blueman.enable = true;
        environment.systemPackages = [
          pkgs.iotop
          pkgs.pciutils
          pkgs.gwenview
pkgs.evince
pkgs.okular
# pkgs.acroread
         # ] ++ (attrValues pkgs.plasma5) ++ [
          #  pkgs.plasma-nm
          pkgs.bluedevil

          pkgs.vim
          pkgs.kate
          pkgs.firefox




          # /backup/mount-disk kann durch /volumes ersetzt werden
          # /backup/references eventuell auf /volumes verschieben ?
          ( pkgs.writeScriptBin "erstelle-backup-externe-festplatte" ''
          #!/bin/sh -e
          set -x
          mkdir -p /backup/mount-disk
          mkdir -p /backup/mount-backup
          mkdir -p /backup/references

          mount /dev/sda3 /backup/mount-disk
          mount /dev/disk/by-uuid/1b6a7b15-f6bd-4c0c-b735-aaf928ee79db /backup/mount-backup -o compress=zstd:1

          for subvol in home system; do
            echo backup hup $subvol
            btrfs-backup-nach.sh "benutzer-backup-$subvol" "/backup/mount-disk/$subvol" "/backup/references/benutzer-backup-$subvol" /backup/mount-backup
          done

          umount /backup/mount-disk
          umount /backup/mount-backup

          echo "BACKUP FERTIG"
          '')

          ( pkgs.writeScriptBin "btrfs-backup-nach.sh" ''
#!/bin/sh -e
set -o pipefail

# mount: mount point
# target: the name of the external disk
# for each name a reference is kept so that next backup is differential and fast

target=$1
mount=''${2:-/backup}

# identify that the target destination is the expected one.
# this is done by expecting backup-dummy$target filename to be there
dummy="$mount/backup-dummy$target"

[ -n "target" ] || { echo "usage: ./backup.sh external-disk /backup "; exit 1; }

[ -f "$dummy" ] || {
        echo "$dummy file to identify backup location not found. Shall I touch it? [y/N]"
        read reply
        if [ "$reply" == "y" ]; then
                touch "$dummy"
        else
                echo 'failing'; exit 1
        fi
}

backup(){
  local name="$1"
  local from="$2"
  # where to store subvolumes and keep last for incremental update
  local dir_in_from="$3"
  local to="$4"

  now=$(date '+%Y-%m-%d_%H%M%S')

  mkdir -p "$dir_in_from"

  if [ -f "$dir_in_from/last-backup-''${name}" ]; then
    local last=$(cat "$dir_in_from/last-backup-''${name}" 2>/dev/null || true)
    echo 'snapshotting from'
    btrfs subvolume snapshot -r "$from" "$dir_in_from/$name-$now"
    echo 'updating target'
    btrfs send -p "$dir_in_from/$last" "$dir_in_from/$name-$now" | btrfs receive "$to"
    echo 'deleting old reference'
    btrfs subvolume delete "$dir_in_from/$last"
    echo "new snapshot is is $name-$now"
    echo "$name-$now" > "$dir_in_from/last-backup-''${name}"
  else
    echo "creating initial snapshot as reference"
    btrfs subvolume snapshot -r "$from" "$dir_in_from/$name-$now"
    echo "sending initial data .. might take long"
    btrfs send "$dir_in_from/$name-$now" | btrfs receive "$to"
    echo "$name-$now" > "$dir_in_from/last-backup-''${name}"
  fi
}

backup "$@"
          ''
          )

          ( pkgs.writeScriptBin "nixos-aktualisieren" ''
             #!/bin/sh
             set -e
             set -x
             sudo erstelle-snapshots
             sudo nix-channel --update
             sudo nixos-rebuild boot
             echo 'Aktualisierung fertig bitte neu starten. Thunderbird Extensios -> Deutsche Übersetzungen neu installieren'
          ''
          )

          ( pkgs.writeScriptBin "erstelle-snapshots" ''
             #!/bin/sh
             set -x
              echo "system"
              ${pkgs.btrfsProgs}/bin/btrfs subvolume snapshot -r / /subvolumes/system-$(${pkgs.coreutils}/bin/date +'%Y-%m-%d_%H%M%S')
              echo "home"
              ${pkgs.btrfsProgs}/bin/btrfs subvolume snapshot -r /home /subvolumes/home-$(${pkgs.coreutils}/bin/date +'%Y-%m-%d_%H%M%S')
              echo "fertig"
          ''
          )

          (
            pkgs.writeScriptBin "hilfe" ''
            #!/bin/sh
            ${pkgs.utillinux}/bin/more <<EOF
            Bei Problemen -> LUGVS Mailinglist

            User Linux Group Villingen Schwenningen einmal pro Monat
                Siehe https://lug-vs.org/lugvswiki/index.php/Hauptseite,
                Die kennen sich jedoch mit Nixos.org Linux nicht aus

                Haben auch Mailingliste

            Chat Hilfe zu Nixos (English)
                Terminal eingaben irssi
                Dann eingeben /connect irc.liberachact.net
                Dann eingeben /join #nixos

            Remote Desktop sharing (Support)
                anydesk nutzen

            System aktualisieren (kann nichts passieren, weil alte Versionen bleiben bestehen)
                sudo nixos-aktualisieren
                Eventuell muss bei Thunderbird hinterher Deutsche Sprachpakete
                neu installiert werden.


            Backups (gleiche Festplatte mit BTRFS)
                sudo erstelle-snapshot eingeben

                Backups liegen unter /subvolumes
                Schützt nicht vor Festplatten-Crash / versagen

            Backup externe Festplatte (btrfs send) empfohlen:
                sudo erstelle-backup-externe-festplatte


            System aufräumen (alte Versionen löschen - also nur wenn neue Version geht)
                sudo nix-collect-garbage -d
                Wenn danach Anwendungen nicht mehr korrekt funktionieren eventuell in
                ~/.config/* Dateien löschen und erneut probieren
                (vorher sudo erstelle-snapshot ausführen)

            iphone mounten (wegen Bildern)
                google ifuse. z.B. 
                sudo ifuse /mnt

            Android mounten 
                sudo mtpfs /mnt

            Drucken -> Cups kann eingerichtet werden. Wenns aber nur 1-2 Seiten
                sind kurz zu Frau Burger gehen oder zu meiner Mutter, PDF mitbringen.

                  Drucken -> "Print To File" oder "In Datei Drucken"
                  PDF Speicherort angeben.

              Zum Enrichten langfristig:
                  sudo nano /etc/nixos/shared-configuration.nix
                  dort siehe printing (Treiber müssen hinzugefügt werden)



            Manuell Backups externes Medium:
                Externe Festplatte ist besser weil Festplatte kaputt gehen kann
                (einfach manuell kopieren, gibt auch viele Tools)

                Beispiel
                mount /dev/sdb1 /mnt
                rsync -ra --delete /home/benutzer/ /mnt/backup-home-benutzer/
                umount /mnt

            System-Check
                smartmontools ist installiert

                Dateisystem:
                  sudo btrfs scrub start /dev/sda
                  # bischen warten..
                  # dann immer wieder bis fertig ist:
                  sudo btrfs scrub status /dev/sda

                Paket-Check
                  sudo nix-store --verify --check-contents

                Festplatte Eigenauskunft S.M.A.R.T auslesen
                  sudo smartctl -a /dev/sda

                  Die werte sollten über den TRESH werten liegen.

                Memory (beim booten memtest wählen)

            Habe-Ich-Internet-Test
                ping www.gmx.de

            root werden:
                sudo anwendung
                sudo su -> wieder shell

            USB Stick (oder Kamera)
                mount /dev/sdb1 /mnt
                .. Daten kopieren
                umount /mnt

                Statt sda1 eventuell sdb2 (zweite Partition) oder sdbX für zweiten USB Stick etc

                Partitionen (USB Stick) finden:
                sudo fdisk -l
                auf Grösse achten

                Können das auch als Script automatisieren oder udev-rule

            Programme:
                audacity: Audio
                scalc (Tabellen)
                simpress (Präsentationen)
                gimp: Bilder
                Krita: Malen
                Firefox: Internet
                Thunderbird: E-Mails
                Blender: 3d test und 3d Malen, 3d Animation und mehr
                mplayer/vlc: videos und Mediadateien aufmachen + Streaming
            EOF
            ''
            )

          pkgs.irssi
          pkgs.utillinux
          pkgs.nettools
          # pkgs.firefox
          pkgs.chromium
          pkgs.libreoffice
          pkgs.audacity
          pkgs.krita
          pkgs.inkscape
          pkgs.gimp
          pkgs.thunderbird
          pkgs.gnome3.nautilus
          pkgs.ifuse # mount iphone
          pkgs.mtpfs # mountandroid
          pkgs.anydesk # Es funktioniert einfach...
          pkgs.smartmontools
          pkgs.blender
          pkgs.mplayer
          pkgs.vlc
        ];

        services.printing = {
          enable = true;
          # drivers = [ pkgs.hlip ];
        };

        programs.zsh.enable = true;
        programs.zsh.promptInit = ''
          if [ "$TERM" != dumb ]; then
            # prompt walters
            autoload -U promptinit && promptinit 
          fi
        '';

        users.users.benutzer = {
          isNormalUser = true;
          home = "/home/benutzer";
          description = "benutzer";
          extraGroups = [ "wheel" "networkmanager" ];
          # openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
        };


      environment.etc."nix/machines".target = "nix/machines.sample";

      fileSystems."/tmp" = { device = "tmpfs"; fsType = "tmpfs"; options = ["size=20000m" "mode=1777"]; };

      fonts.fontconfig.enable = true;
      fonts.enableFontDir = true;
      fonts.fonts = [ ];

      nixpkgs.config.permittedInsecurePackages = [
        "openssl-1.0.2u"
      ];
      nixpkgs.config.allowUnfree = true;
      nixpkgs.config.android_sdk.accept_license = true;
      nixpkgs.config.ruby.tags = true;
      # nixpkgs.config.packageOverrides = p: {



       nix = {
          package = pkgs.nixUnstable;
          daemonNiceLevel = 20;
          useSandbox = true;
       };

      programs.ssh.startAgent = false;
      programs.gnupg.agent.enable = true;

      # services.cron.systemCronJobs =
      #   let
      #     backupscript = pkgs.writeScriptBin "backupscript" ''
      #     #!/bin/sh
      #     ${pkgs.btrfsProgs}/bin/btrfs subvolume snapshot / /root/root-of-fs-$(${pkgs.coreutils}/bin/date +'%Y-%m-%d_%H%M%S')
      #     '';
      #   in
      #     [
      #       "0 10,15 * * * root ${backupscript}"
      #     ];


      services.nfs.server.enable = true;

      services.ntp.enable = true;

      # services.openssh = {
      #   enable    = true;
      #   allowSFTP = true;
      #   # startOn  = "never";
      #   passwordAuthentication = true;
      # };


      security.sudo = {
        enable = true; 
        configFile = mkOverride 20 ''
          root        ALL=(ALL) SETENV: ALL
          benutzer    ALL=(ALL) NOPASSWD: ALL

          # Users in the \"wheel\" group can do anything.
          # %wheel      ALL=(ALL) SETENV: ALL
          ''; 
      };

      documentation.nixos.enable = false;  # takes too much time to build

      services.xserver.enable = true;
      services.xserver.autorun = true;
      services.xserver.layout = "de";

      services.xserver.wacom.enable = true;
      services.xserver.enableTCP = true;
      services.xserver.resolutions = [];
      # services.xserver.windowManager.default = "wmii";

      services.xserver.desktopManager.plasma5.enable = true;
      services.xserver.desktopManager.lxqt.enable = true;

      systemd.services.nix-daemon.serviceConfig.IOSchedulingClass = "idle";
      systemd.services.nix-daemon.serviceConfig.CPUShares = 123;
      systemd.services.nix-daemon.serviceConfig.MemoryLimit = "10G";
      # users.defaultUserShell = "/var/run/current-system/sw/bin/zsh";
  };

}


# hardware-configuration.nix
# vom Installationscript erstellt
{ config, lib, pkgs, ... }:

{
  imports =
    [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
    ];

  boot.initrd.availableKernelModules = [ "btrfs" "ehci_pci" "ahci" "usb_storage" "sd_mod" "sr_mod" "rtsx_usb_sdmmc" ];
  boot.kernelParams = [ ];
  # boot.kernelPackages = pkgs.linuxPackages_testing; # oder 20
  boot.blacklistedKernelModules = [ ];

  powerManagement = {
    enable = true;
    cpuFreqGovernor = "ondemand";
  };

  # services.logind.lidSwitch = "ignore";
  # services.xserver.videoDrivers = [ "ati_unfree" ];
  # boot.kernelPackages = pkgs.linuxPackages_latest;
  # boot.kernelParams = [ "amd_iommu=pt" "ivrs_ioapic[32]=00:14.0" "iommu=soft" ];
  # services.xserver.videoDrivers = [ "amdgpu" ];
  # services.xserver.videoDrivers = [ "ati_unfree" ];
  hardware.firmware = [pkgs.firmwareLinuxNonfree pkgs.sof-firmware];
  hardware.cpu.amd.updateMicrocode = true;
  hardware.enableAllFirmware = true;
  # hardware.enableRedistributableFirmware = true;
  # hardware.opengl.enable = true;
  # hardware.opengl.driSupport = true;
  hardware.opengl.driSupport = true;
  # programs.light.enable = true;
}

Zusammenfassung:

Eine fast automatische Installation wäre so möglich:

# iso runterladen
# booten
# sudo su

# automatisch formatieren und configuration.nix Template anlegen
DEV=/dev/sda
curl https://script-noch-zu-erstellen-was-foramtiert-dann-mounted-dann-configuration.nix-anlegt > /tmp/script
. /tmp/script
# nixos-hardware-scan
# nixos-install ..
# shutdown -r now

Das Sytsem hätte dann - lugvs dokumentation mit hilfe-lugvs aufrufbar oder ähnlich auch was vieles weitere erinnert - regelmäßige Snapshots - ein Backup Script für externe Festplatte inkrementell mit BTRFS - einfache Update Scripte um sich selbst solange zu aktualisieren bis sich die

 Wörter in configuration.nix verändern. Manchmal kommt was dazu oder wird
 umbenannt.

Aber ein Crash oder halbfertiges System beim Benutzer (Update-Probleme) sind passieren nicht mehr oder sind zurückstellbar in kalkulierbaren 5 Minuten.


Wie geht nutzt man z.B. Python oder Haskell mit NixOS?

cabal2nix_init(){
  local dir=$(basename `pwd`)
  local defaultGHC=${1:-ghc921}

$(nix-build -A cabal2nix $NIXPKGS_ALL)/bin/cabal2nix . > $dir.nix

cat > default.nix << EOF
{ nixpkgs ? import <nixpkgs> {}, compiler ? "${defaultGHC}" }:
nixpkgs.haskell.packages.\${compiler}.callPackage ./$dir.nix { }
EOF

cat > shell.nix << EOF
{ nixpkgs ? import <nixpkgs> {}, compiler ? "${defaultGHC}" }:
(import ./default.nix { inherit nixpkgs compiler; }).env
EOF

# nix-shell -A env ./default.nix

das cabal2nix_init Script erstellt einige .nix Dateien die dann genutzt werden um die Abhängikgeiten im Store bereitzustellen. Dann kann mit nix-shell eine Shell bereitgestellt werden wo ghc ghc-pkg cabal etc vorhanden sind und jene finden. D.h. einem ./Setup configure && ./Setup build steht nichts mehr im Wege.

Das geht meistens gut - manchmal leider auch nicht.

Ähnliche Tools gibts für Ruby, Python ..

Auf die Art und Weise lassen sich auch derivations generieren so dass man Software über environment.systemPackages schnell installieren kann.

Nach meiner Meinung ist das alles einfacher als Pakete für Debian / Suse bereitzustellen (wenns klappt)