NixOs: use servicios en sistemas operativos que no sean nixos, eventualmente solo con derechos de usuario

NixOs: use servicios en sistemas operativos que no sean nixos, eventualmente solo con derechos de usuario

Me gustaría saber cómo ejecutar un servicio descrito, como en un módulo en un sistema operativo que no sea Nix. Por ejemplo digamos que tengo el archivo:

{config, pkgs, ... }:
{
  systemd.user.services.mytestservice = {
    description = "Mytestservice";
    script = "while true; do echo 'YES'; sleep 1; done";
    wantedBy = [ "default.target" ];
 };
}

(o eventualmente sin el usuario systemd.services.mytestservice =:)

¿Cómo puedo compilarlo y ejecutarlo en un sistema operativo que no sea Nixos, eventualmente por parte de usuarios que no sean root?

Respuesta1

Agradecimiento: ¡Muchas gracias cleverpor todas las explicaciones!

Primero escribamos el archivo de configuración en myconfiguration.nix:

{config, pkgs, ... }:

{
  # You can actually remove the user, and still use it
  # as a user if you link it in ~/.config/systemd/user/
  # (do not forget to remove the `user` it in anything.nix
  # as well)
  systemd.user.services.mytestservice = {
   description = "Mytestservice";
   script = "while true; do echo 'YES'; sleep 1; done";
   # Or:
   # serviceConfig = {
   #   ExecStart = "${pkgs.bash}/bin/bash -c \"while true; do echo 'YES'; sleep 1; done\"";
   # };
   wantedBy = [ "default.target" ];
 };
}

Entonces, puedes hacer varias cosas:

  • compilarlo
  • instalarlo

Para compilar únicamente, puedes hacer:

nix-build '<nixpkgs/nixos>' -I nixos-config=myconfiguration.nix -A 'config.systemd.user.units."mytestservice.service".unit'

La idea es que esto cargue el archivo default.nixen la carpeta /your/nixpkgs/copy/nixos/(para obtener la ruta de nixpkgs, verifica la variable NIX_PATHque contiene varias "subclaves" como : NIX_PATH=nixpkgs=/your/nixpkgs/copy/:othervar=thepath), que está disponible en línea.aquí. Este archivo también requiere <nixos-config>, que usamos -Ipara agregar una entrada nixos-config a la NIX_PATHvariable de entorno. Luego, sin -A, intentará construir un nixos completo, por lo que simplemente especificamos que solo queremos esta unidad de servicio.

Esto producirá un archivo mytestservice.serviceque se verá así:

$ cat result/mytestservice.service 
[Unit]
Description=Mytestservice

[Service]
Environment="LOCALE_ARCHIVE=/nix/store/zzhablipzgpv8mvlcvagqjnham6lr944-glibc-locales-2.27/lib/locale/locale-archive"
Environment="PATH=/nix/store/bv1lw6a2kw0mn2y3lxhi43180idx6sp9-coreutils-8.31/bin:/nix/store/s1n4vl1f3in3nacalrc3xam0vyzpsfvs-findutils-4.6.0/bin:/nix/store/7d9bi31h40hky30f5scqx7r6wn311ain-gnugrep-3.3/bin:/nix/store/qg4qbkbca7qapfzpa8p991yjf944fc3w-gnused-4.7/bin:/nix/store/6bvd29jny80ka8df9prr5hrl5yz7d98k-systemd-239.20190219/bin:/nix/store/bv1lw6a2kw0mn2y3lxhi43180idx6sp9-coreutils-8.31/sbin:/nix/store/s1n4vl1f3in3nacalrc3xam0vyzpsfvs-findutils-4.6.0/sbin:/nix/store/7d9bi31h40hky30f5scqx7r6wn311ain-gnugrep-3.3/sbin:/nix/store/qg4qbkbca7qapfzpa8p991yjf944fc3w-gnused-4.7/sbin:/nix/store/6bvd29jny80ka8df9prr5hrl5yz7d98k-systemd-239.20190219/sbin"
Environment="TZDIR=/nix/store/20wmykp8fj2izxdj8lic8ggcfpdid5ka-tzdata-2019a/share/zoneinfo"



ExecStart=/nix/store/1f0wk7l4p7xv257dci8xxqz1k8nai9va-unit-script-mytestservice-start 

Ahora, si quieres poder llamarlo, necesitas instalarlo:

nix-env -f '<nixpkgs/nixos>' -I nixos-config=myconfiguration.nix -iA 'config.systemd.user.units."mytestservice.service".unit'

Esto vinculará el mytestservice.serviceen ~/.nix-profile/mytestservice.service. Pero systemctl espera que esté en formato ~/.config/systemd/user/, por lo que lo vinculamos:

ln -s ~/.nix-profile/mytestservice.service ~/.config/systemd/user/

Luego necesitamos recargar el demonio y podemos intentar jugar con él:

systemctl --user daemon-reload
systemctl --user start mytestservice.service

Sin embargo, tenga en cuenta que los comandos de compilación/instalación son complicados y largos de escribir, por lo que podemos crear un archivo, por ejemplo anything.nix, que compilará todo por nosotros:

let
  eval = import <nixpkgs/nixos> {
    configuration = ./myconfiguration.nix;
  };
  pkgs = import <nixpkgs>{};
in pkgs.buildEnv {
  name = "things";
  paths = [
    eval.config.systemd.user.units."mytestservice.service".unit
  ];
}

Ahora puedes compilar con:

nix-build anything.nix

e instalar con

nix-env -f anything.nix -i things

Tenga en cuenta que es posible que deba eliminar la primera vez el archivo que instalamos con el otro método, usando algo como:

nix-env --query
nix-env --uninstall unit-mytestservice.service

Finalmente, ambos códigos systemd.servicesparecen systemd.services.usersser utilizables con este método :D

información relacionada