From 650ae14ceda72dcb294bde4d08988a7ed26ab0ff Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Jul 2020 13:51:11 +0200 Subject: [PATCH] Markdown test --- doc/manual/command-ref/nix-copy-closure.md | 78 +++++++++ doc/manual/introduction/about-nix.md | 181 +++++++++++++++++++++ doc/manual/introduction/quick-start.md | 79 +++++++++ doc/manual/manual.md | 8 + flake.nix | 21 +++ 5 files changed, 367 insertions(+) create mode 100644 doc/manual/command-ref/nix-copy-closure.md create mode 100644 doc/manual/introduction/about-nix.md create mode 100644 doc/manual/introduction/quick-start.md create mode 100644 doc/manual/manual.md diff --git a/doc/manual/command-ref/nix-copy-closure.md b/doc/manual/command-ref/nix-copy-closure.md new file mode 100644 index 000000000..037334c4d --- /dev/null +++ b/doc/manual/command-ref/nix-copy-closure.md @@ -0,0 +1,78 @@ +Title: nix-copy-closure + +# Name + +`nix-copy-closure` - copy a closure to or from a remote machine via SSH + +# Synopsis + +`nix-copy-closure` [`--to` | `--from`] [`--gzip`] [`--include-outputs`] [`--use-substitutes` | `-s`] [`-v`] _user@machine_ _paths_ + +# Description + +`nix-copy-closure` gives you an easy and efficient way to exchange +software between machines. Given one or more Nix store _paths_ on the +local machine, `nix-copy-closure` computes the closure of those paths +(i.e. all their dependencies in the Nix store), and copies all paths +in the closure to the remote machine via the `ssh` (Secure Shell) +command. With the `--from` option, the direction is reversed: the +closure of _paths_ on a remote machine is copied to the Nix store on +the local machine. + +This command is efficient because it only sends the store paths +that are missing on the target machine. + +Since `nix-copy-closure` calls `ssh`, you may be asked to type in the +appropriate password or passphrase. In fact, you may be asked _twice_ +because `nix-copy-closure` currently connects twice to the remote +machine, first to get the set of paths missing on the target machine, +and second to send the dump of those paths. If this bothers you, use +`ssh-agent`. + +# Options + +*`--to`* +: Copy the closure of _paths_ from the local Nix store to the Nix + store on _machine_. This is the default. + +*`--from`* +: Copy the closure of _paths_ from the Nix store on _machine_ to the + local Nix store. + +*`--gzip`* +: Enable compression of the SSH connection. + +*`--include-outputs`* +: Also copy the outputs of store derivations included in the closure. + +*`--use-substitutes` / `-s`* +: Attempt to download missing paths on the target machine using Nix’s + substitute mechanism. Any paths that cannot be substituted on the + target are still copied normally from the source. This is useful, + for instance, if the connection between the source and target + machine is slow, but the connection between the target machine and + `nixos.org` (the default binary cache server) is + fast. + +*`-v`* +: Show verbose output. + +# Environment variables + +*`NIX_SSHOPTS`* +: Additional options to be passed to `ssh` on the command + line. + +# Examples + +Copy Firefox with all its dependencies to a remote machine: + + $ nix-copy-closure --to alice@itchy.labs $(type -tP firefox) + +Copy Subversion from a remote machine and then install it into a user +environment: + + $ nix-copy-closure --from alice@itchy.labs \ + /nix/store/0dj0503hjxy5mbwlafv1rsbdiyx1gkdy-subversion-1.4.4 + $ nix-env -i /nix/store/0dj0503hjxy5mbwlafv1rsbdiyx1gkdy-subversion-1.4.4 + diff --git a/doc/manual/introduction/about-nix.md b/doc/manual/introduction/about-nix.md new file mode 100644 index 000000000..b3cd00bd3 --- /dev/null +++ b/doc/manual/introduction/about-nix.md @@ -0,0 +1,181 @@ +# About Nix + +Nix is a _purely functional package manager_. This means that it +treats packages like values in purely functional programming languages +such as Haskell — they are built by functions that don’t have +side-effects, and they never change after they have been built. Nix +stores packages in the _Nix store_, usually the directory +`/nix/store`, where each package has its own unique subdirectory such +as + + /nix/store/b6gvzjyb2pg0kjfwrjmg1vfhh54ad73z-firefox-33.1/ + +where `b6gvzjyb2pg0…` is a unique identifier for the package that +captures all its dependencies (it’s a cryptographic hash of the +package’s build dependency graph). This enables many powerful +features. + +## Multiple versions + +You can have multiple versions or variants of a package +installed at the same time. This is especially important when +different applications have dependencies on different versions of the +same package — it prevents the “DLL hell”. Because of the hashing +scheme, different versions of a package end up in different paths in +the Nix store, so they don’t interfere with each other. + +An important consequence is that operations like upgrading or +uninstalling an application cannot break other applications, since +these operations never “destructively” update or delete files that are +used by other packages. + +## Complete dependencies + +Nix helps you make sure that package dependency specifications are +complete. In general, when you’re making a package for a package +management system like RPM, you have to specify for each package what +its dependencies are, but there are no guarantees that this +specification is complete. If you forget a dependency, then the +package will build and work correctly on _your_ machine if you have +the dependency installed, but not on the end user's machine if it's +not there. + +Since Nix on the other hand doesn’t install packages in “global” +locations like `/usr/bin` but in package-specific directories, the +risk of incomplete dependencies is greatly reduced. This is because +tools such as compilers don’t search in per-packages directories such +as `/nix/store/5lbfaxb722zp…-openssl-0.9.8d/include`, so if a package +builds correctly on your system, this is because you specified the +dependency explicitly. This takes care of the build-time dependencies. + +Once a package is built, runtime dependencies are found by scanning +binaries for the hash parts of Nix store paths (such as `r8vvq9kq…`). +This sounds risky, but it works extremely well. + +## Multi-user support + +Nix has multi-user support. This means that non-privileged users can +securely install software. Each user can have a different _profile_, +a set of packages in the Nix store that appear in the user’s `PATH`. +If a user installs a package that another user has already installed +previously, the package won’t be built or downloaded a second time. +At the same time, it is not possible for one user to inject a Trojan +horse into a package that might be used by another user. + +## Atomic upgrades and rollbacks + +Since package management operations never overwrite packages in the +Nix store but just add new versions in different paths, they are +_atomic_. So during a package upgrade, there is no time window in +which the package has some files from the old version and some files +from the new version — which would be bad because a program might well +crash if it’s started during that period. + +And since packages aren’t overwritten, the old versions are still +there after an upgrade. This means that you can _roll back_ to the +old version: + + $ nix-env --upgrade some-packages + $ nix-env --rollback + +## Garbage collection + +When you uninstall a package like this… + + $ nix-env --uninstall firefox + +the package isn’t deleted from the system right away (after all, you +might want to do a rollback, or it might be in the profiles of other +users). Instead, unused packages can be deleted safely by running the +_garbage collector_: + + $ nix-collect-garbage + +This deletes all packages that aren’t in use by any user profile or by +a currently running program. + +## Functional package language + +Packages are built from _Nix expressions_, which is a simple +functional language. A Nix expression describes everything that goes +into a package build action (a “derivation”): other packages, sources, +the build script, environment variables for the build script, etc. +Nix tries very hard to ensure that Nix expressions are +_deterministic_: building a Nix expression twice should yield the same +result. + +Because it’s a functional language, it’s easy to support +building variants of a package: turn the Nix expression into a +function and call it any number of times with the appropriate +arguments. Due to the hashing scheme, variants don’t conflict with +each other in the Nix store. + +## Transparent source/binary deployment + +Nix expressions generally describe how to build a package from +source, so an installation action like + + $ nix-env --install firefox + +_could_ cause quite a bit of build activity, as not only Firefox but +also all its dependencies (all the way up to the C library and the +compiler) would have to built, at least if they are not already in the +Nix store. This is a _source deployment model_. For most users, +building from source is not very pleasant as it takes far too long. +However, Nix can automatically skip building from source and instead +use a _binary cache_, a web server that provides pre-built +binaries. For instance, when asked to build +`/nix/store/b6gvzjyb2pg0…-firefox-33.1` from source, Nix would first +check if the file `https://cache.nixos.org/b6gvzjyb2pg0….narinfo` +exists, and if so, fetch the pre-built binary referenced from there; +otherwise, it would fall back to building from source. + +## Nix Packages collection + +We provide a large set of Nix expressions containing hundreds of +existing Unix packages, the _Nix Packages collection_ (Nixpkgs). + +## Managing build environments + +Nix is extremely useful for developers as it makes it easy to +automatically set up the build environment for a package. Given a Nix +expression that describes the dependencies of your package, the +command `nix-shell` will build or download those dependencies if +they’re not already in your Nix store, and then start a Bash shell in +which all necessary environment variables (such as compiler search +paths) are set. + +For example, the following command gets all dependencies of the +Pan newsreader, as described by [its +Nix expression](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/networking/newsreaders/pan/default.nix): + + $ nix-shell '' -A pan + +You’re then dropped into a shell where you can edit, build and test +the package: + + [nix-shell]$ tar xf $src + [nix-shell]$ cd pan-* + [nix-shell]$ ./configure + [nix-shell]$ make + [nix-shell]$ ./pan/gui/pan + +## Portability + +Nix runs on Linux and macOS. + +## NixOS + +NixOS is a Linux distribution based on Nix. It uses Nix not just for +package management but also to manage the system configuration (e.g., +to build configuration files in `/etc`). This means, among other +things, that it is easy to roll back the entire configuration of the +system to an earlier state. Also, users can install software without +root privileges. For more information and downloads, see the [NixOS +homepage](https://nixos.org/). + +## License + +Nix is released under the terms of the [GNU LGPLv2.1 or (at your +option) any later +version](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html). diff --git a/doc/manual/introduction/quick-start.md b/doc/manual/introduction/quick-start.md new file mode 100644 index 000000000..21c03e3cf --- /dev/null +++ b/doc/manual/introduction/quick-start.md @@ -0,0 +1,79 @@ +# Quick Start + +This chapter is for impatient people who don't like reading +documentation. For more in-depth information you are kindly referred +to subsequent chapters. + +1. Install single-user Nix by running the following: + + $ bash <(curl -L https://nixos.org/nix/install) + + This will install Nix in `/nix`. The install script will create + `/nix` using `sudo`, so make sure you have sufficient rights. (For + other installation methods, see + [here](../installation/installation.md).) + +1. See what installable packages are currently available in the + channel: + + $ nix-env -qa + docbook-xml-4.3 + docbook-xml-4.5 + firefox-33.0.2 + hello-2.9 + libxslt-1.1.28 + … + +1. Install some packages from the channel: + + $ nix-env -i hello + + This should download pre-built packages; it should not build them + locally (if it does, something went wrong). + +1. Test that they work: + + $ which hello + /home/eelco/.nix-profile/bin/hello + $ hello + Hello, world! + +1. Uninstall a package: + + $ nix-env -e hello + +1. You can also test a package without installing it: + + $ nix-shell -p hello + + This builds or downloads GNU Hello and its dependencies, then drops + you into a Bash shell where the `hello` command is present, all + without affecting your normal environment: + + [nix-shell:~]$ hello + Hello, world! + + [nix-shell:~]$ exit + + $ hello + hello: command not found + +1. To keep up-to-date with the channel, do: + + $ nix-channel --update nixpkgs + $ nix-env -u '*' + + The latter command will upgrade each installed package for which + there is a “newer” version (as determined by comparing the version + numbers). + +1. If you're unhappy with the result of a `nix-env` action (e.g., an + upgraded package turned out not to work properly), you can go back: + + $ nix-env --rollback + +1. You should periodically run the Nix garbage collector to get rid of + unused packages, since uninstalls or upgrades don't actually delete + them: + + $ nix-collect-garbage -d diff --git a/doc/manual/manual.md b/doc/manual/manual.md new file mode 100644 index 000000000..58e37436f --- /dev/null +++ b/doc/manual/manual.md @@ -0,0 +1,8 @@ +Title: Nix Package Manager Guide + +1. Introduction + 1. [About Nix](./introduction/about-nix.md) + 1. [Quick Start](./introduction/quick-start.md) +1. Command Reference + 1. Utilities + 1. [nix-copy-closure](./command-ref/nix-copy-closure.md) diff --git a/flake.nix b/flake.nix index a707e90e7..dfe4ecd49 100644 --- a/flake.nix +++ b/flake.nix @@ -66,6 +66,7 @@ libxslt docbook5 docbook_xsl_ns + lowdown autoconf-archive autoreconfHook @@ -187,6 +188,26 @@ }; + lowdown = with final; stdenv.mkDerivation { + name = "lowdown-0.7.1"; + + src = fetchurl { + url = https://kristaps.bsd.lv/lowdown/snapshots/lowdown-0.7.1.tar.gz; + hash = "sha512-1daoAQfYD0LdhK6aFhrSQvadjc5GsSPBZw0fJDb+BEHYMBLjqiUl2A7H8N+l0W4YfGKqbsPYSrCy4vct+7U6FQ=="; + }; + + outputs = [ "out" "dev" ]; + + buildInputs = [ which ]; + + configurePhase = + '' + ./configure \ + PREFIX=${placeholder "dev"} \ + BINDIR=${placeholder "out"}/bin + ''; + }; + }; hydraJobs = {