Рубрики
Uncategorized

Как Nix-Shell сохранила здравомыслие нашей команды

Первоначально опубликовано в: … Теги с реактивным, JavaScript, DevOps, Docker.

Первоначально опубликовано в: https://medium.com/att-israel/how-nix-shell-saved-our-teams-sanity-a22fe6668d0e

Мы разрабатываем большое реактивное нативное приложение, которое сильно зависит от новых компонентов, уже написанных в Java, C ++ и Целью-с. Это означает, что нам нужно было разработать, построить и тестировать множество различных платформ на сложных средах разработчика и инструменты сборки, которые часто меняются с обновлениями платформы.

Это стало нагрузкой на наши команды, с разбросами знаний во многих разработчиках, руководствах установки, файлов Readme и внутренних страниц Wiki. Ожидалось, что установки займется несколько дней, и даже незначительное изменение версии зависимости привело к непоследовательности с помощью неясных сообщений об ошибках.

Некоторые предложили докеренные среды, но после нескольких попыток, NIX стал нашим инструментом выбора. NIX позволяет нам использовать ту же среду разработки через Linux и MacOS с точными зависимостями для таких инструментов, как Cmake, Ninja, Android NDK и т. Д. При установленном NIX при открытии репозитория разработчик приветствует все необходимые зависимости в их оболочке. Мы используем Linux для Android Builds и MacOS для Android и Apple Builds.

Итак, что такое NIX?

NIX — это как менеджер пакетов и инструмент сборки. Как правило, эти два являются отдельными вещами, такими как RPM и делают. Это единство становится полезным при модели развертывания источника NIX, в которой построены пакеты из источника. Большую часть времени пакет прозрачно заменяется для кэшированного двоичного бинара с сервера (до тех пор, пока хэш инструкции по сборке одинаково.)

NIX приоритеты приоритеты консистенции, а для достижения этой заставляет вас объявлять все зависимости и вкладываться явно, в то время как песочние среды сборки из вашей среды оболочки и Интернета. Не только пакет, созданный из источника, но и его зависимостей и их зависимостей, которые могут зависеть друг от друга, как узлы в сетке графа. Nix-env, менеджер пакета

С Nix-env вы можете управлять пользовательскими средами. Nix-Env создает абстрактный слой над катаниями на бин на вашем пути с SymLinks To/Nix/Store. Как он использует ссылки SymLink, это может сделать несколько важных вещей:

  • Он отслеживает версий вашей среды, а в O (1) время он может откатиться к другой версии, изменив SymLink в предыдущий профиль.
  • Установки и удаление являются атомными. Более поздняя версия не ссылается, пока установка не будет завершена.
  • В качестве зависимостей не установлены в глобальной папке, несколько пользователей на машине не могут переопределить или компромиссные зависимости друг друга, и поэтому разрешено устанавливать пакеты без привилегий.

Это возможно, потому что каждая версия пакета установлена в другом каталоге под/Nix/Store, и стирание зависимости не удаляет ее с диска до тех пор, пока она не будет полностью отказаться и собранным мусором.

NIX принимает управление версиями в свои руки, используя инструкции по сборке и его вход. Даже малейшее изменение представляет собой новую версию, так как хеш отличается. Компоненты проживают в магазине NIX, рядом со всеми их зависимостями, как:

/nix/store/f2rrk276criwxn19bf82cglym4dkv9gr-ninja-1.9.0.drv
/nix/store/iwm3knkdi294rj50w9ai5rdwaglgr362-ninja-1.9.0/

Последние символы — это атрибут для читаемого человеком имени. NIX-ENV управляется с помощью команды nix-env и каталога .nix-профиля.

Проблема установки на Mac

NIX может быть установлен для одного пользователя (кто владеет/nix), либо в виде нескольких пользователей (в каком корневом roots/nix). Однако на MAC не будет больше не будет работать, так как корневая файловая система (что-то ниже/) было прочитано только с MacOS 10.15. NIX не может триветировать изменить путь для магазина NIX, так как весь их двоичный кеш был скомпилирован с/nix/хранить в качестве его пути. Текущий обходной путь состоит в том, чтобы изменить путь, но установите его как незашифрованные (зашифрованные в покое) тома APFS.

$ sh <(curl -L https://nixos.org/nix/install) --darwin-use-unencrypted-nix-store-volume --daemon

Установка объяснит, что это будет делать, и будет запрашивать суперпользовательский доступ, который он позвонит десятки раз. Вот как громкость магазина Nix выглядит с дисковой утилитой:

И вот это в поисках:

Объем магазина Nix в Finder. По какой-то причине Timestamp Unix находится в 0 (и я выдал мой часовой пояс). NIX-Shell, виртуальная среда

Однако это было NIX-Shell, которая оказала влияние на нас. С Nix-Shell, мы можем создавать виртуальные среды для каждого проекта, без необходимости устанавливать зависимости на уровне пользователя или систем с Nix-Env.

Просто добавьте файл Shell.nix в вашем проекте. Затем, когда вы вводите Nix-Shell, среда и все зависимости готовы к использованию. Этот файл, конечно, привержен для контроля источника и совместно среди всех разработчиков. Файловые перечислены зависимости, переменные среды и крючки оболочки, которые должны работать при загрузке. Пример Shell.Nix файл с двумя разными источниками NixPKGS.

Это может быть дополнительно интегрировано в оболочку с помощью DireNV, что автоматически активирует среду при изменении каталога; И Лорри, процесс демона, который контролирует Shell.nix проекта для изменений, и автоматически перезагружает среду, если она имеет. NIV облегчает управление зависимостями проекта с файлом Sources.json, как менеджер пакета более высокого порядка для NIX-Shell.

Некоторые предпочитают использование NIX-Shell через NIX-ENV для целых среды пользовательского уровня, так как ее можно контролировать в изолированном, декларативном способе. Домашний менеджер позволяет конфигурации пользовательских (не глобальных) пакетов и «точечных файлов». «Посмотрите, что вы можете сделать в Никсес Вики. Наконец, NIX-Drawin позволяет конфигурацию вашего MAC, как Nixos делает с помощью файла configuration.nix.

Nix-Shell может быть продлен в вашу ОС с инструментами выше, но он также может быть использован в более узком, определенном способе. Можно запустить команды в NIX-Shell, не входя в его интерактивную оболочку с помощью:

nix-shell --run "node ./index.js".

И можно указать NIX-Shell в качестве интерпретатора для файла с Shebang в верхней части файла:

#! /usr/bin/env nix-shell
#! nix-shell -i real-interpreter -p packages...

Вышеуказанный файл будет выполнен внутри NIX-оболочки, наряду с его средой.

Nix-Build, инструмент сборки

NIX-Build — это менеджер по сборке с правильностью в его главном приоритете. То есть все сборки будут идентичны тем же инструментам сборки и входных данных.

Генеральные менеджеры принимают источники, такие как исходный код и зависимости, и вызывают генераторы, такие как компиляторы, для создания, таких как двоичные файлы. И источники, так и производные являются компонентами. Это задача инструментов, таких как Make, Cmake, Ant или Gradle.

NIX сборки основаны на выработке, который представляет собой набор, который перечислены точными (хэшированными) зависимостями и точными (хэшированными) сценариями сборки, которые выглядят так:

Derive([("out","/nix/store/winl36i87aydwj5qgrz0nbc7kq3w0yzi-user-environment","","")],[],["/nix/store/kygr761f08l1nanw27lfxkg8qibf0qn1-env-manifest.nix"],"builtin","builtin:buildenv",[],[("allowSubstitutes",""),("builder","builtin:buildenv"),("derivations","true 5 1 /nix/store/9nqninr2aaicvmq83q10d5a1hwagbzyc-hello-2.10 true 5 1 /nix/store/df26nnjiw55rvv6mxy4kapps9h4kfvw7-niv-0.2.19-bin true 5 1 /nix/store/f3swypnb5zi5yd3w7k2ycwyv6b3sv8fa-direnv-2.28.0 true 5 1 /nix/store/vgdizqicd30k4183ssq7g6i07dvys6xl-home-manager-path true -10 1 /nix/store/4023c0ymrxsg1x36jxmnircqjl1y9fkq-nodejs-14.17.6"),("manifest","/nix/store/kygr761f08l1nanw27lfxkg8qibf0qn1-env-manifest.nix"),("name","user-environment"),("out","/nix/store/winl36i87aydwj5qgrz0nbc7kq3w0yzi-user-environment"),("preferLocalBuild","1"),

Выражения NIX, язык

Вышеуказанное является минимутированной версией его человечески читабельной версии, написанная функционально с экспрессией NIX:

https://gist.github.com/ronenlh/c2c9ca9ed319bfadd212f2eb15e29629#file-default-nix

Весь файл является одной функцией. Строки от 1 до 6 описывают множество, переданное как единственный параметр. Набор определяет все зависимости, необходимые для создания компонента.: В строке 6 определяет начало тела функции.

Все тело — это вызов stdenv.mkderivation, который минимизирует данные в вывод, написанный выше. REC — это функция, которая обеспечит рекурсию внутри набора данных, что позволяет определить определение значений с точки зрения других клавиш в наборе.

Для дидактических целей синтаксис можно переписать как javaScript лямбда как:

({ stdenv, ... }) => stdenv.mkDerivation(rec({ ... }))

Значение SRC извлекается с удаленного URL и подтверждена с помощью хеша. SRC — ожидаемый ключ для стандартного инструмента сборки, который выполнит стандартную Autoconf (./Configure; make; make install) скрипт оболочки.

Можно экспериментировать с языком NIX в интерактивной оболочке. NixPKGS, репозиторий пакета

Вышеуказанная функция еще не вызывается, так как у нас нет параметров для функции. Мы можем достичь того же результата с другим REC, который рекурсивно определяет необходимые компоненты и его параметры. например.,

rec {
  lib1 = import package1/default.nix { };
  program2 = import package2/default.nix { inherit lib1; };
}

Это превращает все зависимости в график зависимости, а до тех пор, пока они являются ациклическими, NIX может построить все их. Этот набор может быть абстрактным с функцией CallPackage. Вот как это делается в коллекции пакетов NIX в этом удивительном файле All-Packages.

Этот файл неявно запрашивает, когда мы устанавливаем пакет в виде:

nix-env -i hello

Это эквивалент:

nix-env -f .../all-packages.nix -i hello

Оба будут строятся и установлены привет. NIX будет представлять все зависимости как график и построить их по мере необходимости. Важно отметить, что NIX ленивый: параметры не оцениваются, пока не вызывается, что означает, что зависимости не будут построены до (или если).

Файл для всех пакетов может быть изменен с помощью команды NIX-канала. Каналы отсортированы по стабильности стабильности. Как я могу установить определенную версию пакета с NIX?

Репозиторий NixPKGS включает в себя последние версии пакетов (согласно выбранной ветви устойчивости). Пакеты зависят друг от друга и построены в целом. Для вывода определенной версии зависимости необходимо вообще перейти на другую версию NixPKG. Отличная утилита для обратного поиска ревизии NixPKGS в соответствии с версией пакета — это поиск пакета Nix Lazamar.

Лучше всего всегда прикрепить зависимости ваших создателей к определенному пересмотру NIXPKGS, для консистенции (так как вы делаете с Docker), и чтобы обновить до последней версии NIXPKGS на Nix-Env, в соответствии с выбранным выбранным каналом Nix ( Как бы вы сделали с домой).

Другие инструменты NIX

  • Nixos — использование примитивов, перечисленных выше, строит и настраивает все распределение Linux. Вся никс определяется внутри репозитория NixPKGS, что невероятно.
  • Nixops — связанные с облачным развертыванием, развертывает конфигурации системы Nixos в удаленные машины, а также положения облачных ресурсов.
  • Инструмент Hydra — CI, который периодически проверяет исходный код проекта, создает его, тестирует его и производит отчеты для разработчиков. Гидра используется для проверки состояния стабильности каналов NIX.
  • Функция Flakes -an предстоящая функция, которая удалит большую часть хлопот зависимости закрепления синтаксическим сахаром. Каждому фиксируемую зависимости хэш будет храниться внутри файла flake.lock. Это интуитивно понятно для NPM/пряжи или пользователей груза.

Итак, почему бы не докер?

НИКС и контейнерные двигатели, такие как Docker — два очень разных инструмента. Одним из них является менеджер по пакету и сборку, другой — это механизм изоляции ресурсов, который виртуализирует операционную систему хоста. Оба имеют большие механизмы кэширования для них, и оба могут использоваться для последовательной среды на машинах Linux. См. Ниже о том, как речь мигрировал из Docker в NIX.

Основная абстракция Docker — это контейнер: свободно изолированная, легкая, портативная и инкапсулированная среда, которая содержит все необходимое для запуска приложения. Контейнер — который работает — это описывается изображением только для чтения. Изображение создается DockerFile, где каждая директива создает отдельный слой, помеченный его криптографическим хешем и кэшированным.

Как слои, изображения могут быть построены друг на друга и вертикально сложены, например, официальное изображение узла построено сверху крошечного альпийского изображения Linux. Приложение вашего узла, вероятно, будет сложено на верхней части изображения узла.

Слои образа Docker Node (Узел: Slim) из Docker Hub

Контейнеры определяют реализацию изображения или слоя в терминах другого, его родителя. NIX создает новые функциональные возможности путем сборки или составления зависимостей. NIX требует от явных зависимостей, и эти зависимости являются черными коробками и потребляются через их интерфейс.

Тем не менее, DockerFiles не должен быть линейным. Многоэтапные сборки вводят новую абстракт: сцена. New Publickit Docker’s Docker Travers проходит из нижней части (целевой стадии), чтобы вернуться в структуру данных графа, пропуская ненужные, а этапы строительства одновременно применимы.

График многоэтапной сборки Buildkit, начиная с дна (целевой этап) к вершине, отбрасывая ненужные этапы. От «Докерфайла лучших практик» разговора: https://youtu.be/jofsaz3h1qm?t=1169.

Одолжение состава над наследством

Трудно изменить слои в Docker, так как мы не уверены, что делает каждый компонент или как он повлияет на нижний слой. Кроме того, разработчики противоречат от изменения более высоких слоев, когда они рискуют восстановить все нижние слои в DockerFile. Это также является узким местом производительности с точки зрения параллелизма, так как Docker строит слои в последовательности, а ненужные этапы будут излишне построены, а затем выброшены.

Docker имеет большое преимущество, которое сразу же знакома для разработчиков и OPS одинаково. NIX возник в качестве докторов. Тезис, и это иногда чувствует себя так. Но дизайн, который не принимает изменений во внимание, рискует крупным редизайном в будущем. Штаты машин Docker Hashes, Nix Hashes Точные компоненты сборки. Как объяснено ранее, два инструмента подают разные цели.

В нашем случае мы строили библиотеку для клиентского приложения, поэтому не было необходимости отправлять контейнер для машины, как бы имелся бы тот случай при разработке узла микросервиса в Kubernetes. Нам просто нужно было поделиться последовательной средой сборки для создания репливируемых сборки. Кроме того, с NIX-Shell, мы все еще можем использовать наш локальный Xcode и остальные стеновые сады MacOS для нашего телевизора и IOS.

Случай замены

Reclit — это совместное в браузере IDE с поддержкой огромного количества языков. Порядок начался с отдельным изображением докера для каждого языка, но пришел к выводу, что было проще и эффективнее использовать одно монолитное изображение: Полиготт. Это стало огромным бременем для поддержания, по их собственным словам, как «каждый новый пакет создает новый захватывающий способ, которые могут сломаться».

С NIX, реплики сами пользователи могут определять бесконечные комбинации капенбовочных сред без необходимости поддерживать монолитное изображение докера. Каждая машина имеет/NIX/Store (со всеми кэшированными дворами) установлена, поэтому экземпляр их среды является немедленным.

Как это сравнивается с домом?

Домашний — невероятный инструмент, который стал второй природой для большинства пользователей MacOS. Установки работают из коробки и интуитивно используют.

Как и NIX, домородицы строят из источника, если он не находит «бутылку», то есть предварительно построенный двоичный. Точно так же — и по той же причине — домой должен быть установлен в путь по умолчанию (/opt/homebrew на Apple Silicon или/usr/local On Intel), чтобы насладиться предварительно сборки двоичными файлами. Эта папка называется погребом.

Домашний номер использует Ruby для своих формул, который предоставляет инструкции и метаданные для домогота для установки программного обеспечения. Формула определяется как класс, который наследует от формулы. Это следует за объектно-ориентированной парадигмой, в отличие от функциональных снисходов NIX, которые определяются функцией.

class Wget < Formula
  homepage "https://www.gnu.org/software/wget/"
  url "https://ftp.gnu.org/gnu/wget/wget-1.15.tar.gz"
  sha256 "52126be8cf1bddd7536886e74c053ad7d0ed2aa89b4b630f76785bac21695fcd"

  def install
    system "./configure", "--prefix=#{prefix}"
    system "make", "install"
  end
end

Длительность может использоваться в Linux (ранее в LinuxBrew), хотя дистрибутивы Linux часто имеют популярные менеджеры пакетов. Похож на Nix-каналы Brew использует «краны», которые являются сторонние репозитории.

Огромная популярность домелки в Mac дает ему преимущество перед надежностью на основе сборки NIX и вдумчивый график зависимости. Большинство установок предварительно построены и «просто работа».

Заключение

С точки зрения маркетинга я обнаруживаю, что NIX не хватает брендинга и отличительных имен для своих услуг (кроме гидры и хлопьев), что затрудняет поиск документации. NIX имеет объединенную документацию Nix и Nixos, поэтому тривиальные поиски новичков о NIX-ENV легко приводят к решениям модификации Configuration.Nix, которая применима только к Nixos.

Использование/NIX/Store было немного не обычным со стороны NIX, поскольку он нарушает рекомендации FHS. Было бы более уместно поставить его в/вари где-нибудь. Я не думаю, что MacOS следует за FHS, но теперь корневой уровень (/) уровень чтения только в MacOS, а NIX должен был почесать голову, чтобы найти обходные пути.

NIX не так интуитивно понятен, как другие инструменты сборки, но он превосходит по правильности. Таким образом, он стремится иметь строгость науки и показывает тяжелую работу от академии. Он был принят общинами функциональных языков, таких как Haskell, и Nixos, представляют интерес всего сообщества Linux.

Оригинал: «https://dev.to/ronenl/how-nix-shell-saved-our-teams-sanity-101k»