Guix es el sistema operativo más avanzado.

Los sistemas operativos (SO) son un tema extenso. Durante décadas, un enfoque ha dominado aquí: Unix. De hecho, la mayoría de los sistemas modernos, incluidas la mayoría de las distribuciones de GNU / Linux, * BSD y macOS, se adhieren a la arquitectura Unix. (No hay Windows, pero casi no hay nada interesante sobre este tema).

En 2000, Rob Pike hizo una presentación sobre por qué la investigación de software de sistemas no es relevante . Debido al pesimismo o al desprecio por la comunidad, parece haber ignorado por completo las quejas recopiladas por muchos usuarios de Unix en The Unix-Haters Handbook (1994). El libro es deliberadamente sarcástico, pero señala algunos problemas críticos con los sistemas Unix, y aún no se han resuelto.

En 2006, Elko Dositra publicó su disertación, "Un modelo de implementación de software completamente funcional" , que describe el administrador de paquetes Nix funcional. En 2008, el autor publicó NixOS: una distribución de Linux totalmente funcional . Si bien NixOS reutiliza una gran cantidad de software gratuito para sistemas Unix, está tan lejos del diseño y la filosofía de Unix que difícilmente se le pueda llamar un "sistema Unix".

Nix es un gran avance en ingeniería de sistemas. Este sistema operativo no solo resolvió muchos problemas de Unix (incluidas las críticas de la colección antes mencionada), sino que también abrió el camino para muchas otras funciones y estudios que pueden desempeñar un papel muy importante en nuestro tiempo, cuando la fiabilidad y la seguridad se han convertido en el tema principal de muchos temas científicos, públicos y políticos. debate

Pike estaba equivocado. Y esto prueba otro punto más general: probablemente sea más prudente abstenerse de declarar cualquier investigación irrelevante si no puede probar la imposibilidad de un mayor desarrollo. Y el informe mencionado difícilmente puede considerarse una prueba matemática. Solo reforzó la idea de que Unix es "lo suficientemente bueno" y que debe aceptar sus características y problemas.

Afortunadamente, este pesimismo innecesario resultó ser miope y no duró mucho: solo un par de años después, el sistema Nix demostró que estaba equivocado.

Apariencia Guix


Guix es el administrador de paquetes en Nix, y GuixSD es el sistema operativo, el equivalente de NixOS, que pretende ser un "sistema operativo totalmente programable". De hecho, casi todo aquí está escrito y configurado en el Esquema Guile : desde la gestión de paquetes Guix hasta el sistema de inicialización de pastor GNU .

Guix es significativamente diferente de los sistemas operativos Unix. Puede ver la documentación y evaluar el grado de cambio:


Beneficios de Guix


Los beneficios de Guix son revolucionarios hasta el punto de que el resto del sistema operativo se parece a sistemas heredados en comparación con él.

Mis características favoritas personales:

  • Invulnerabilidad del sistema: Guix mantiene un historial de todos los cambios tanto en el sistema como a nivel de usuario. Si la actualización rompe algo, siempre puede retroceder. Esto hace que el sistema sea prácticamente invulnerable .
  • Integridad: dado que la configuración es declarativa, le da al usuario o administrador del sistema un control completo. En otras variantes de Unix, es mucho más difícil decir cuándo cambia algún archivo de configuración aleatorio.
  • Sistema operativo totalmente programable: programe las configuraciones del sistema y use un sistema de control de versiones. Se pueden configurar muchos servicios del sistema en el esquema Guile: desde las reglas de udev hasta Xorg, PAM, etc. ¡Gracias a Guile, la configuración puede estar condicionada al hardware o incluso al nombre del host!
  • Reemplazo directo para otros administradores de paquetes (no tan buenos): ¿por qué administrar por separado los paquetes Emacs, Python o TeXlive si hay una única interfaz para todos (ver más abajo )! Es más fácil escribir y mantener declaraciones para los perfiles de usuario.
  • Definiciones de paquetes de Guile: es mucho más eficiente desarrollar definiciones de paquetes a granel . Sustituye favorablemente conceptos como los indicadores USE Portage (ver más abajo ).
  • Varias formas de emitir paquetes: Un paquete Guix puede tener varias "formas de emitir", que se utilizan para separar los diversos componentes (bibliotecas, herramientas adicionales, documentación, etc.). En otros sistemas operativos (generalmente Debian), es más difícil adivinar qué paquetes encajan entre sí.
  • Entradas no multiplicadoras: en la terminología de Guix, las "entradas" son dependencias del paquete. El perfil de usuario y el entorno contienen solo paquetes instalados explícitamente por el usuario y no necesariamente sus dependencias. Por ejemplo, vea inxi , una herramienta para informar información del sistema: si solo estoy interesado en informes sobre el sistema / equipo inxi, no es necesario agregar de dos a tres docenas de herramientas adicionales de línea de comando a PATH . Guix le permite mostrar en el perfil del usuario solo lo que realmente necesita.
  • Entornos Guix: cuando ejecuta el guix environment SOME-PACKAGES Guix configura un entorno temporal donde se presentan todos los requisitos para SOME-PACKAGES . Esto se puede usar para configurar fácilmente el entorno de compilación para el proyecto, así como para otros fines (ver más abajo). Una gran calidad: le permiten ejecutar programas sin instalarlos en el perfil del usuario.
  • Actualizaciones parciales: 100% compatibles. Esta es probablemente la causa principal de fallas en versiones flotantes como Arch Linux y Gentoo: dado que solo se admiten varias versiones al mismo tiempo (generalmente solo una), todo el sistema debe actualizarse como un todo. Esto significa más tráfico con cada actualización. Con Guix, cualquier paquete se actualiza individualmente.
  • Integración continua o por qué Guix puede funcionar sin mantenedores de paquetes: gracias a compilaciones reproducibles y soporte para actualizaciones parciales, si el paquete funciona en Guix, funcionará "siempre" y alguna dependencia no se romperá durante la próxima actualización (más precisamente, si la dependencia rompe el paquete, entonces esto se arregla trivialmente para usar la versión correcta de la biblioteca). Por lo tanto, el trabajo con paquetes se puede transferir a “granjas de ensamblaje” (una en Hydra del proyecto Nix, la otra en Cuirass ). Compare esto con la mayoría de las otras comunidades GNU / Linux, que requieren docenas de mantenedores para actualizar miles de paquetes. Este enfoque no escala: al final, estas distribuciones se estancan en un par de miles de paquetes. En Guix, la cantidad de paquetes puede crecer sin temor al colapso. Al mismo tiempo, los contribuyentes pueden usarse de manera más eficiente.

    En Guix, construir desde la fuente es igual de fácil. De hecho, esto no es tan importante para el usuario final: Guix puede regresar fácilmente al ensamblaje desde las fuentes si el paquete terminado no está disponible.
  • guix import y guix refresh : cree o actualice definiciones de paquetes de forma automática y recursiva. Cientos de definiciones se procesan simultáneamente. Tales características enfatizan los beneficios de un lenguaje de programación real en el sistema operativo. Lo cual es una tarea difícil en la mayoría de los sistemas operativos, es relativamente fácil de implementar en Guix.
  • Canales Guix: ¡una de mis funciones favoritas! Arch Linux o Gentoo requiere que crees un repositorio local. Dado que no admiten actualizaciones parciales, el usuario debe realizar algún mantenimiento de vez en cuando (es decir, asegurarse de que las actualizaciones de dependencia no rompan los paquetes). Los canales Guix reemplazan rentablemente las superposiciones AUR de Arch Linux y Gentoo, lo que permite a cualquier persona distribuir sus definiciones de paquetes, por ejemplo, desde los repositorios de Git. Nuevamente, esto garantiza una total transparencia (sobornos, historial, etc.).
  • Emacs-Guix : Hasta donde yo sé, ¡Guix es la única distribución que viene con la interfaz de usuario Emacs más potente!
  • Paquetes Guix : una alternativa real a contenedores como Docker. La mayoría de los sistemas de contenedores sufren problemas críticos: no se pueden reproducir y, en realidad, son binarios opacos, lo cual es categóricamente inaceptable para los usuarios que se preocupan por la confianza, la seguridad y la privacidad. Por el contrario, los paquetes Guix son absolutamente claros, reproducibles y transparentes.
  • guix system vm y guix system disk-image : Guix hace que sea trivial reproducir todo el sistema actual como USB en vivo, dentro de la VM o en una máquina remota.

Guix en comparación con la competencia


Debian, Arch Linux y la mayoría de las otras distribuciones de GNU / Linux


Las distribuciones de GNU / Linux generalmente no tienen los beneficios antes mencionados de Guix. Las deficiencias más críticas:

  • Falta de soporte para múltiples versiones de paquetes o "dependencia del infierno". Digamos que el último mpv requiere un nuevo ffmpeg, pero la actualización de ffmpeg rompe la mayoría de los otros programas. Estamos atrapados en un dilema: romper algunos paquetes o guardar versiones antiguas. Peor aún, puede que no haya un paquete adecuado o que no haya soporte para el sistema operativo. Este problema es inherente a la mayoría de las distribuciones que no pueden garantizar el cumplimiento de su tarea principal: un paquete para cualquier programa.
  • Dependencia crítica de los mantenedores. La gestión de paquetes no funcional significa que todos los paquetes deben ser constantemente probados para verificar su compatibilidad. Esto es mucho trabajo duro para aquellos a quienes se les confió esta tarea. En la práctica, esto significa que la calidad de la gestión de paquetes depende en gran medida de las personas. Una distribución sin un número suficiente de mantenedores inevitablemente sufrirá y posiblemente morirá. Este requisito de mano de obra normalmente no se escala y, a medida que aumenta el número de paquetes, conduce a un aumento en la complejidad (tanto en la base del código como en la administración).

Gentoo, * BSD


Gentoo y otras distribuciones con el administrador de paquetes de Portage tienen una característica famosa: USE banderas para activar funciones en todo el sistema (por ejemplo, silenciar, habilitar el soporte de GUI, etc.).

Las banderas USE hacen que sea trivial habilitar o deshabilitar funciones del autor del paquete (y la ventaja es que se prueban). Por otro lado, Portage no le permite configurar características que no están pensadas de antemano. Por ejemplo, si un paquete tiene un sonido adicional, pero el autor no ha establecido el indicador correspondiente, el usuario no podrá hacer nada al respecto (excepto crear una nueva definición de paquete).

En comparación, Guix le permite personalizar completamente todo, aunque con un poco más de código Scheme. En pseudocódigo, se ve más o menos así:

 (loop-over (TARGET-PACKAGES) (package (inherit TARGET) (changes-here... including patches, build options, etc.)) 

Tal lote de código establece las definiciones de TARGET-PACKAGES con sus cambios. No es necesario realizar ninguno de los cambios en la definición del paquete. En cualquier momento, el usuario conserva el control total sobre los cambios que se pueden realizar en los paquetes.

Me encantó Gentoo, pero después de cambiar a Guix, las limitaciones de Portage se hicieron evidentes.

  • El sistema de bandera USE no permite la personalización de funciones arbitrarias no planificadas.
  • El uso de indicadores agrega una clase completa de complejidad (consulte la semántica de átomos bastante complicada) para describir y administrar la relación de funciones entre paquetes. Guix elimina completamente este nivel de complejidad utilizando el esquema Guile para programar relaciones.

Además, Portage sufre el mismo problema con la falta de soporte adecuado para múltiples versiones, y los indicadores aumentan significativamente la escala del problema (una queja frecuente sobre Portage): cuando se aplican indicadores USE incompatibles a algunas dependencias, el usuario debe buscar manualmente una solución. A veces esto significa que la función requerida no es aplicable (al menos sin un trabajo significativo en las definiciones de paquetes).

En la práctica, Guix proporciona paquetes precompilados, un gran ahorro de tiempo en comparación con Gentoo (aunque Portage admite la distribución de paquetes binarios).

* Los sistemas BSD (por ejemplo, FreeBSD) sufren problemas similares en make config .

Nix


Nix fue un avance histórico en la investigación del sistema operativo, y Guix tomó prestada casi todas sus ideas de allí. Hoy, Nix sigue siendo uno de los mejores sistemas operativos activos. Guix probablemente no habría existido de no ser por un defecto.

En mi opinión, Guix resuelve el problema principal de Nix: en lugar de su propio lenguaje específico de dominio (DSL), aquí se usa un lenguaje de programación Guile Scheme basado en Lisp.

"Implementar su propio lenguaje de programación" es un error muy común en el desarrollo de software. Esto golpeó muchos proyectos donde el lenguaje de configuración o programación sufrió las siguientes desventajas:

  • expresividad y capacidades limitadas;
  • Otro idioma para el aprendizaje (pero no algo muy útil y universal), que requiere un poco de esfuerzo por parte del usuario y, por lo tanto, crea una barrera de entrada;
  • código menos legible (al menos al principio);
  • a menudo pobre rendimiento.

Hay tantos proyectos en idiomas locales o demasiado limitados:

  • XML, HTML (aún mejor: S-XML )
  • Make, Autoconf, Automake, Cmake, etc.
  • Bash, Zsh, Fish (aún mejor: Eshell o scsh )
  • JSON, TOML, YAML
  • Portage a Nix Ebuild y muchas otras reglas de sintaxis para las definiciones de paquetes del sistema operativo
  • Firefox cuando se usa XUL (desde entonces Mozilla lo ha abandonado) y la mayoría de los otros lenguajes locales para extensiones
  • SQL
  • Octave, R, PARI / GP, la mayoría de los programas científicos (por ejemplo, Common Lisp, Racket y otro esquema)
  • Expresiones regulares ( rx en Emacs , PEG en Racket , etc.)
  • sed, AWK, etc.
  • La mayoría de las configuraciones de inicio, incluido systemd (incluso mejor: GNU Shepherd )
  • cron (aún mejor: mcron )
  • conky (no totalmente programable, aunque esta debería ser la característica más esperada de un programa similar)
  • TeX, LaTeX (y todos los derivados), asíntota (aún mejor: garabato , skribilo , aún en desarrollo; a partir de enero de 2019, TeX / LaTeX todavía se usa como un paso intermedio en la preparación del PDF)
  • La mayoría de los programas con configuraciones que no usan un lenguaje de programación de propósito general.

Reinventar la rueda no suele ser una buena idea. Cuando se trata de herramientas tan importantes como los lenguajes de programación, esto tiene consecuencias muy dramáticas. Se requieren esfuerzos adicionales innecesarios, se producen errores. La comunidad se está dispersando. Las comunidades más consolidadas son más eficientes y hacen un mejor uso de su tiempo si mejoran los lenguajes de programación existentes y bien desarrollados.

No solo para el escritorio


Guix admite varias arquitecturas (i686, x86_64, ARMv7 y AArch64 a partir de enero de 2019), y planea admitir más núcleos fuera del ecosistema Linux (digamos * BSD, GNU Hurd, ¡ o tal vez su propio sistema!).

Esto convierte a Guix en una gran herramienta para implementar servidores (reproducibles) y otros sistemas especializados. Creo que en los sistemas embebidos, Guix puede competir muy bien con OpenWRT (aunque llevará un poco de trabajo portarlos a los sistemas embebidos).

USB en vivo con reproducción automática


Anteriormente, mencioné guix system disk-image : por ejemplo, le permite recrear el sistema actual en una unidad flash USB.

Por lo tanto, un clon del sistema actual es fácil de conectar en cualquier lugar y replicar el entorno actual exacto (menos el hardware). Puede incluir datos de usuario allí: claves PGP, correo electrónico. Todo está disponible inmediatamente después de la descarga.

Obviamente, la clonación funciona más lejos de la máquina en la que está instalado el clon: en lugar de la Guix "desnuda", se implementa un sistema operativo completo, listo para funcionar.

Sustitución de otros gestores de paquetes


Emacs, Python, Ruby ... y el poder del guix environment


Guix puede reemplazar cualquier administrador de paquetes, incluidos los administradores de paquetes de lenguajes de programación. Tiene varias ventajas:

  • Reproducibilidad ubicua.
  • Retrocesos ubicuos.
  • No es necesario aprender otro administrador de paquetes.

En este punto, debe mencionar el guix environment . Este comando configura un entorno temporal con solo un conjunto específico de paquetes, como virtualenv . La característica principal es que es universal para todos los idiomas y sus combinaciones.

Texlive


(Descargo de responsabilidad: a partir de enero de 2019, el sistema de compilación TeXlive para Guix se está rediseñando).

TeXlive recibió una mención especial porque es especialmente terrible :), lo que una vez más confirma el papel salvador de Guix.

La mayoría de los sistemas operativos basados ​​en Unix suelen distribuir TeXlive como parte de un conjunto de paquetes. Por ejemplo, Arch Linux tiene una docena de estos. Si necesita algunos paquetes de TeX de diferentes conjuntos, Arch Linux no deja más remedio que instalar miles de paquetes (posiblemente innecesarios), y TeXlive ocupa mucho espacio: cientos de megabytes.

Alternativamente, puede instalar TeXlive manualmente, pero seamos sinceros: tlmgr es solo un mal administrador de paquetes y requiere un trabajo tedioso adicional.

Con Guix, los paquetes de TeXlive se instalan por separado, como todo lo demás, lo que le ayuda a mantener su propio conjunto de paquetes de TeXlive o incluso a crear especificaciones de entorno virtual para compilar documentos específicos.

El núcleo


Muchos sistemas operativos ofrecen solo soporte limitado para núcleos personalizados. Si los usuarios desean alejarse del núcleo predeterminado, entonces el núcleo no estándar debe mantenerse manualmente.

Se sabe que Gentoo "requiere" el núcleo del usuario como el paso de instalación recomendado (¿obligatorio?). Sin embargo, esto no es un requisito previo, y los propios usuarios deben admitir la configuración del kernel.

En Guix, el núcleo es un paquete regular totalmente personalizable, como cualquier otro. Puede configurar todo y pasar el archivo de configuración del núcleo a la definición del paquete.

Por ejemplo, las siguientes son definiciones de un kernel de Linux no libre con el controlador iwlwifi (advertencia: no recomiendo usar controladores propietarios, ya que representan una seria amenaza para su privacidad y libertad):

 (define-module (ambrevar linux-custom) #:use-module (guix gexp) #:use-module (guix packages) #:use-module (guix download) #:use-module (guix git-download) #:use-module (guix build-system trivial) #:use-module ((guix licenses) #:prefix license:) #:use-module (gnu packages linux) #:use-module (srfi srfi-1)) (define-public linux-nonfree (package (inherit linux-libre) (name "linux-nonfree") (version (package-version linux-libre)) (source (origin (method url-fetch) (uri (string-append "https://www.kernel.org/pub/linux/kernel/v4.x/" "linux-" version ".tar.xz")) (sha256 (base32 "1lm2s9yhzyqra1f16jrjwd66m3jl43n5k7av2r9hns8hdr1smmw4")))) (native-inputs `(("kconfig" ,(local-file "./linux-custom.conf")) ,@(alist-delete "kconfig" (package-native-inputs linux-libre)))))) (define (linux-firmware-version) "9d40a17beaf271e6ad47a5e714a296100eef4692") (define (linux-firmware-source version) (origin (method git-fetch) (uri (git-reference (url (string-append "https://git.kernel.org/pub/scm/linux/kernel" "/git/firmware/linux-firmware.git")) (commit version))) (file-name (string-append "linux-firmware-" version "-checkout")) (sha256 (base32 "099kll2n1zvps5qawnbm6c75khgn81j8ns0widiw0lnwm8s9q6ch")))) (define-public linux-firmware-iwlwifi (package (name "linux-firmware-iwlwifi") (version (linux-firmware-version)) (source (linux-firmware-source version)) (build-system trivial-build-system) (arguments `(#:modules ((guix build utils)) #:builder (begin (use-modules (guix build utils)) (let ((source (assoc-ref %build-inputs "source")) (fw-dir (string-append %output "/lib/firmware/"))) (mkdir-p fw-dir) (for-each (lambda (file) (copy-file file (string-append fw-dir (basename file)))) (find-files source "iwlwifi-.*\\.ucode$|LICENSE\\.iwlwifi_firmware$")) #t)))) (home-page "https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi") (synopsis "Non-free firmware for Intel wifi chips") (description "Non-free iwlwifi firmware") (license (license:non-copyleft "https://git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/tree/LICENCE.iwlwifi_firmware?id=HEAD")))) 

El kernel personalizado y el firmware se pueden incluir condicionalmente en la configuración actual del sistema (algunos archivos config.scm ):

 (define *lspci* (let* ((port (open-pipe* OPEN_READ "lspci")) (str (get-string-all port))) (close-pipe port) str)) (operating-system (host-name "...") ;;... (kernel (cond ((string-match "Network controller: Intel Corporation Wireless 8888" *lspci*) linux-nonfree) (#t linux-libre))) (firmware (append (list linux-firmware-iwlwifi) %base-firmware)) 

Luego, siga estos pasos para instalar una nueva configuración del sistema:

 sudo -E guix system reconfigure config.scm 

Sin siquiera instalar un nuevo núcleo, puede crear directamente una imagen lista para arrancar desde una unidad USB.

Los juegos


Dado que los paquetes Guix usan tecnologías avanzadas (por ejemplo, las últimas versiones de Mesa) y permiten el ajuste completo del kernel, esta es una plataforma ideal para juegos y, en particular, para empaquetar juegos.

Desafortunadamente, la industria del juego está lejos de ser una filosofía de software libre, y muy pocos juegos se empaquetan como parte del proyecto oficial Guix.

Aunque Guix favorece el software libre y no acepta ninguna propiedad en su repositorio, irónicamente, muchas características avanzadas hacen de Guix el administrador de paquetes ideal para el software propietario.

Algunos de los beneficios:

  • guix environment permite ejecutar cualquier aplicación en un contenedor aislado que restringe el acceso a la red, oculta el sistema de archivos (no hay riesgo de que el programa propietario robe algunos de sus archivos, digamos, billetera bitcoin o claves PGP) e incluso información a nivel del sistema como como nombre de usuario Esto es necesario para ejecutar cualquier programa de código cerrado no confiable.
  • Gestión de paquetes funcionales: los programas de código cerrado generalmente no resisten la prueba del tiempo y se rompen cuando una dependencia de la biblioteca cambia su API. Como Guix define los paquetes sobre cualquier versión de cualquier dependencia (sin conflictos con el sistema actual), Guix le permite crear paquetes para juegos con código fuente cerrado que funcionarán para siempre.
  • Entorno reproducible: los programas de código cerrado generalmente están mal portados y pueden comportarse de manera diferente en sistemas con dependencias ligeramente diferentes. La propiedad de reproducibilidad de Guix implica que si hacemos que el paquete Guix funcione una vez, siempre funcionará (excepto por un fallo de hardware o un cambio de configuración de hardware).

Por estas razones, Guix es una herramienta ideal para empaquetar y distribuir juegos de código cerrado.

Sin embargo, este es un gran tema separado, que es mejor dejar para otro artículo.

Consejos y trucos


Emacs-guix


Uno de los sorprendentes beneficios de Guix es la interfaz Emacs-Guix , que le permite instalar y eliminar paquetes, actualizar selectivamente, buscar, pasar a la definición de paquetes, administrar generaciones, imprimir las "diferencias" entre ellos y mucho más.

Tiene modos de desarrollo para ensamblaje y programación, así como un entorno interactivo especial llamado Scheme REPL . Esta es una interfaz de usuario única para el sistema operativo.

También está la interfaz de Helm System Packages , que se superpone parcialmente con Emacs-Guix, pero me parece más agradable para búsquedas rápidas de paquetes y operaciones rápidas.

Almacenamiento de datos


Como Guix almacena varias generaciones de configuraciones de sistema (incluido el historial completo de paquetes), requiere más espacio en disco que otros sistemas operativos.

, 2018 25 ( , ), 50 .

guix gc , « », , .

Emacs-Guix mx guix-store-dead-item , .

, guix gc --references guix gc --requisites . guix build ... , .

, , , :

 $ guix gc --references $(guix build -d coreutils) | grep builder /gnu/store/v02xky6f5rvjywd7ficzi5pyibbmk6cq-coreutils-8.29-guile-builder 


A menudo es útil generar un manifiesto de todos los paquetes instalados en un perfil.

Esto se puede hacer usando el siguiente script de Guile:

 (use-modules (guix profiles) (ice-9 match) (ice-9 pretty-print)) (match (command-line) ((_ where) (pretty-print `(specifications->manifest ',(map manifest-entry-name (manifest-entries (profile-manifest where)))))) (_ (error "Please provide the path to a Guix profile."))) 

Por ejemplo, ejecútelo en su perfil ~/.guix-profile:

 $ guile -s manifest-to-manifest.scm ~/.guix-profile 

Mis dotfiles rastrean el historial de paquetes instalados. Como también mantengo la versión de Guix, puedo volver al estado exacto de mi sistema en cualquier momento en el pasado.

Referencias


Algunas interfaces web:


Documentos:


Paquetes no oficiales:

Source: https://habr.com/ru/post/es436938/


All Articles