Как записать воспроизводимый профиль в nix (особенно из nix-env)? - PullRequest
0 голосов
/ 09 мая 2018

Итак, наконец-то я начал получать стабильную среду nix, в которой я могу заниматься практически всеми своими разработками. Ура!

Теперь я хочу сделать его воспроизводимым, как в yarn.lock (для тех, кто знаком с npm / yarn в javascript land) или Pipfile.lock (очень похоже на Python) .

По сути, идея состоит в том, чтобы у меня был способ создать аналогичный файл блокировки всякий раз, когда я запускаю nix-env -if my-env.nix или после выполнения этой команды, если это так. Из этого файла блокировки я мог затем точно восстановить свой профиль nix, вплоть до точных версий зависимостей и суб-зависимостей установленного профиля. Это можно проверить в git или в любом другом месте после тестирования новых улучшений, и, таким образом, будет поддерживаться запись среды.

Мне кажется, это был бы один из наиболее очевидных вариантов использования Nix и одно из основных преимуществ по сравнению с простым использованием Docker (хотя оба они не являются взаимоисключающими), поэтому я прошу прощения, если пропустил некоторые соответствующая документация.

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Вероятно, вы ищете файл shell.nix, подобный следующему:

let
  pkgs = import (fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/696c6bed4e8e2d9fd9b956dea7e5d49531e9d13f.tar.gz";
    sha256 = "1v3yrpj542niyxp0h3kffsdjwlrkvj0mg4ljb85d142gyn3sdzd4";
  }) {};
in pkgs.mkShell {
  buildInputs = with pkgs; [
    git
    hello
  ];
}

После вызова nix-shell (который по умолчанию использует файл shell.nix в текущем каталоге), выВы будете в окружении с git и hello из указанной ревизии nixpkgs.Это может быть воспроизведено среди всех пользователей nix (хорошо, почти *).Я действительно могу рекомендовать использовать shell.nix файлы для всех разработок.

В качестве альтернативы есть также менее известный флаг -r для nix-env, который гласит, что

- удалить-all, -r

Сначала удалите все ранее установленные пакеты.Это эквивалентно запуску nix-env -e '. *' Вначале, за исключением того, что все происходит в одной транзакции.

Вы можете эффективно использовать его для замены ~/.nix-profile/manifest.nix с состоянием.Создайте файл env.nix, содержащий:

let
  pkgs = import <nixpkgs> {};
in {
  inherit (pkgs) git hello;
}

Теперь запущенный nix-env -ir env.nix установит ровно git и hello и удалит все остальное, чтобы вы могли воспроизвести ваши установки nix-env с помощью этого единственного файла,Чтобы установить дополнительные вещи: добавьте его в файл и снова введите команду.Вы также можете прикрепить nixpkgs к определенной версии, как в приведенном выше файле, чтобы не беспокоиться о вашей nix-channel настройке (которая также является сохраняющей состояние).

Edit : также можно получить некоторыепакеты из вашего канала и некоторые конкретные версии nixpkgs:

let
  pkgs = import <nixpkgs> {};
  fixed = import (fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/696c6bed4e8e2d9fd9b956dea7e5d49531e9d13f.tar.gz";
    sha256 = "1v3yrpj542niyxp0h3kffsdjwlrkvj0mg4ljb85d142gyn3sdzd4";
  }) {};
in {
  inherit (pkgs) git;
  inherit (fixed) hello;
}

*: Конфигурация nix, оверлеи и ваша система (Linux / Mac) могут по-прежнему влиять на это.Во избежание этого рекомендуется использовать import <nixpkgs> { config = {}; overlays = []; } для разработки.

0 голосов
/ 09 мая 2018

После многих предложений от пользователей IRC я ​​смог собрать следующий скрипт, который принимает выражение nix в качестве единственного аргумента, копирует файл деривации и записывает версии nixpkgs локально при установке указанной среды:

#!/bin/bash

if [ -z "$1" ] || [ "${1: -4}" != ".nix" ] || [ ! -f "$1" ]
  then
      echo "No .nix file supplied"
      exit -1
fi

ENV_DRV=$(nix-instantiate "$1")
cp "$ENV_DRV" ./env_backup.drv
chmod u+rw ./env_backup.drv
nix-env --set "$ENV_DRV"


NIXPKGS_VERSION=$(nix-instantiate --eval '<nixpkgs/lib>' -A version)
NIXOS_VERSION=$(nix-instantiate --eval '<nixos/lib>' -A version)

printf "nixpkgs: %s\\nnixos: %s" "$NIXPKGS_VERSION" "${NIXOS_VERSION}" > .nix_versions

Предупреждение : в вашем выражении nix должен быть пакет nix, поскольку мы используем nix-env --set.

Я еще не пробовал использовать скопированный файл .drv, но его нужно каким-то образом восстановить в хранилище nix; Я в основном включил это в качестве крайней меры и для отладки. Вывод в .nix_versions должен быть более полезным, поскольку они содержат хэши git commit (после последнего "."), Которые можно использовать для использования правильной ревизии nixpkgs (благодаря infinisil в IRC):

pkgs = import "${(import <nixpkgs> {}).fetchFromGitHub { owner = "NixOS"; repo = "nixpkgs"; rev = "<your revision hash>"; sha256 = "<the hash of the output>"; }}" {}

Чтобы заполнить хеш, либо предоставьте неправильный хеш, чтобы получить правильный хеш, либо просто используйте следующее: nix-prefetch-url --unpack github.com/nixos/nixpkgs/archive/<revision>.tar.gz.

Или, если вы вручную проверяете nixpkgs, вы можете просто сделать, например ::

with import ((builtins.getEnv "HOME") + "/workspace/nixpkgs") { }; # or:
with import "../nixpkgs" { }; # or similar

Я еще не проверял подобные вещи с nix-shell, но надеюсь сделать это в ближайшее время.

...