Desarrollo

Todo el código fuente de VyOS está alojado en GitHub bajo la organización de VyOS que se puede encontrar aquí: https://github.com/vyos

Nuestro código se divide en varios módulos. VyOS se compone de varios paquetes individuales, algunos de ellos son bifurcaciones de paquetes ascendentes y se sincronizan periódicamente con los ascendentes, por lo que mantener todo el código fuente en un solo repositorio sería muy inconveniente y lento. Ahora hay un esfuerzo continuo para consolidar todos los paquetes de marco/configuración específicos de VyOS en el paquete vyos-1x, pero la estructura básica seguirá siendo la misma, solo que cada vez menos paquetes mientras el código base se reescribe de Perl/BASH en Uso de Python y definición de interfaz basada en XML para la CLI.

El repositorio que contiene todos los scripts de compilación ISO es: https://github.com/vyos/vyos-build

El archivo README.md lo guiará para usar este repositorio de nivel superior.

Enviar un parche

Los parches siempre son más que bienvenidos. Para tener un repositorio limpio y fácil de mantener, tenemos algunas pautas al trabajar con Git. Un repositorio limpio facilita la generación automática de un archivo de registro de cambios.

Un buen método para escribir mensajes de confirmación es echar un vistazo al historial de los archivos invocando git log path/to/file.txt.

Preparar parche/confirmar

En un gran sistema, como VyOS, que se compone de múltiples componentes, es imposible realizar un seguimiento de todos los cambios y errores/solicitudes de funciones en la cabeza. Usamos un rastreador de errores conocido como Phabricator ("rastreador de problemas" sería un mejor término, pero este se mantuvo).

La información se utiliza de tres maneras:

  • Mantenga un registro del progreso (lo que ya hemos hecho en esta rama y lo que aún tenemos que hacer).

  • Preparar notas de lanzamiento para próximos lanzamientos

  • Ayude a los futuros mantenedores de VyOS (¡podría ser usted!) a averiguar por qué se cambiaron ciertas cosas en el código base o por qué se agregaron ciertas características

Para que este enfoque funcione, cada cambio debe asociarse con un número de tarea (con el prefijo T) y un componente. Si no hay un informe de error/solicitud de funciones para los cambios que va a realizar, primero debe crear una tarea Phabricator. Una vez que haya una entrada en Phabricator, debe hacer referencia a su id en su mensaje de confirmación, como se muestra a continuación:

  • ddclient: T1030: creación automática de directorios en tiempo de ejecución

  • Jenkins: agregue el ID de compromiso actual de Git para construir la descripción

Si no hay una referencia de Phabricator en las confirmaciones de su solicitud de extracción, debemos pedirle que modifique el mensaje de confirmación. De lo contrario tendremos que rechazarlo.

Escribir buenos mensajes de confirmación

El formato debe ser y está inspirado en: https://git-scm.com/book/ch5-2.html También vale la pena leer https://chris.beams.io/posts/git-commit/

  • Un resumen único y breve de la confirmación (se recomiendan 50 caracteres o menos, sin exceder los 80 caracteres) que contenga un prefijo del componente cambiado y la referencia de Phabricator correspondiente, por ejemplo, snmp: T1111: o ethernet: T2222:` ` - se pueden concatenar múltiples componentes como en ``snmp: ethernet: T3333

  • En algunos contextos, la primera línea se trata como el asunto de un correo electrónico y el resto del texto como el cuerpo. La línea en blanco que separa el resumen del cuerpo es fundamental (a menos que omita el cuerpo por completo); herramientas como rebase pueden confundirse si ejecuta las dos juntas.

  • Seguido de un mensaje que describe todos los detalles como:

    • Qué/por qué/cómo se ha cambiado algo hace que la vida de todos sea más fácil cuando se trabaja con git bisect

    • Todo el texto del mensaje de confirmación debe ajustarse a 72 caracteres si es posible, lo que facilita la lectura de los registros de confirmación con git log en una terminal estándar (que resulta ser 80x25)

    • Si corresponde, se debe hacer una referencia a una confirmación anterior que vincule bien esas confirmaciones al navegar por el historial: Después de confirmar abcd12ef ("snmp: este es un titular"), falta una declaración de importación de Python, arrojando la siguiente excepción: ABCDEF

  • Utilice siempre la opción -x para el comando git cherry-pick cuando retroceda o reenvíe la transferencia de una confirmación individual. Esto agrega automáticamente la línea: (cherry pick from commit<ID> ) al mensaje de confirmación de los autores originales, lo que facilita la división de problemas.

  • ¡Cada conjunto de cambios debe ser consistente (autocontenido)! No corrija varios errores en una sola confirmación. Si ya trabajó en varias correcciones en el mismo archivo, use git add –patch para agregar solo las partes relacionadas con el problema en su próxima confirmación.

Límites:

  • Solo aceptamos correcciones de errores en paquetes que no sean https://github.com/vyos/vyos-1x, ya que ninguna funcionalidad nueva debe usar las plantillas de estilo antiguo (node.def y el código Perl/BASH. Use el nuevo estilo XML /Python en su lugar.

Envíe sus parches utilizando la conocida solicitud de extracción de GitHub contra nuestros repositorios que se encuentran en la organización VyOS GitHub en https://github.com/vyos

Determinar el paquete fuente

Suponga que desea realizar un cambio en la secuencia de comandos webproxy pero aún no sabe cuál de los muchos paquetes de VyOS incluye este archivo. Puede determinar el nombre del paquete de VyOS en cuestión usando el comando dpkg -S de Debian de su instalación de VyOS en ejecución.

vyos@vyos:~ dpkg -S /opt/vyatta/sbin/vyatta-update-webproxy.pl
vyatta-webproxy: /opt/vyatta/sbin/vyatta-update-webproxy.pl

Esto significa que el archivo en cuestión (/opt/vyatta/sbin/vyatta-update-webproxy.pl) se encuentra en el paquete vyatta-webproxy que se puede encontrar aquí: https://github. com/vyos/vyatta-webproxy

Fork Repository y enviar Patch

Bifurcar el repositorio y enviar una solicitud de extracción de GitHub es la forma preferida de enviar sus cambios a VyOS. Puede bifurcar cualquier repositorio de VyOS a su propia cuenta de GitHub simplemente agregando /fork a la URL de cualquier repositorio en GitHub. Por ejemplo, para bifurcar el repositorio vyos-1x, abra la siguiente URL en su navegador favorito: https://github.com/vyos/vyos-1x/fork

Luego puede continuar con la clonación de su bifurcación o agregar un nuevo control remoto a su repositorio local:

  • Clonar: git clon https://github.com/<user> /vyos-1x.git

  • Bifurcación: git remoto agregar myfork https://github.com/<user> /vyos-1x.git

Para registrarlo como el autor de la corrección, identifíquese en Git configurando su nombre y correo electrónico. Esto se puede hacer localmente para este único repositorio git config o globalmente usando git config --global.

git config --global user.name "J. Random Hacker"
git config --global user.email "[email protected]"

Realice sus cambios y guárdelos. Haga lo siguiente para todos los archivos de cambios para registrarlos en su confirmación de Git creada:

  • Agregue un archivo al índice de Git usando git add myfile, o para un directorio completo: git add somedir/*

  • Confirma los cambios llamando a git commit. Utilice un título de compromiso significativo (lea arriba) y no olvide hacer referencia al ID de Phabricator.

  • Envíe el parche git push y cree la solicitud de extracción de GitHub.

Adjuntar parche a la tarea de Pfabricator

Siga los pasos anteriores sobre cómo &quot;bifurcar el repositorio para enviar un parche&quot;. En lugar de cargar &quot;empujar&quot; sus cambios a GitHub, puede exportar los parches/compromisos y enviarlos amainers@vyos.net o adjuntarlos directamente al error (preferido al correo electrónico)

  • Exporte la última confirmación al archivo de parche: git format-patch o exporte las dos últimas confirmaciones a sus archivos de parche apropiados: git format-patch -2

Directrices de codificación

Como cualquier otro proyecto, también tenemos algunas pequeñas pautas sobre nuestro código fuente. Las reglas que tenemos no existen para castigarlo, las reglas existen para ayudarnos a todos. Al tener un estilo de codificación consistente, se vuelve muy fácil para los colaboradores nuevos y antiguos navegar a través de las fuentes y toda la lógica implícita de cualquier archivo fuente.

Python 3 deberá ser utilizado. ¿Cuánto tiempo podemos mantener vivo Python 2 de todos modos? No deben tomarse en consideración consideraciones sobre la compatibilidad con Python 2 en ningún momento.

Formateo

  • Python: las pestañas no se utilizarán. Cada nivel de sangría debe ser de 4 espacios.

  • XML: las tabulaciones no se utilizarán. Cada nivel de sangría debe ser de 2 espacios.

Nota

Hay extensiones para, por ejemplo, VIM (xmllint) que le ayudarán a obtener los niveles de sangría correctos. Agregue lo siguiente a su archivo .vimrc: au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2&gt;/dev/null ahora puede llamar al linter usando ``gg=G` ` en modo comando.

Generación de texto

El procesador de plantillas debe usarse para generar archivos de configuración. El formato de cadena incorporado puede usarse para formatos simples orientados a líneas donde cada línea es independiente, como las reglas de iptables. El procesador de plantillas debe usarse para formatos estructurados de varias líneas, como los que usa ISC DHCPd.

El procesador de plantillas predeterminado para el código VyOS es Jinja2.

Resumen

Al modificar el código fuente, recuerde estas reglas de la campaña de eliminación heredada:

  • No hay nuevas funciones en Perl

  • Sin definiciones de comandos de estilo antiguo

  • No hay código incompatible con Python3

Pitón

El cambio al lenguaje de programación Python para código nuevo no es simplemente un cambio de lenguaje, sino una oportunidad para repensar y mejorar el enfoque de programación.

Seamos realistas: VyOS está lleno de código espagueti donde la lógica para leer la configuración de VyOS, generar configuraciones de daemon y reiniciar procesos está toda mezclada.

Python (o cualquier otro lenguaje, para el caso) no brinda protección automática contra un mal diseño, por lo que también debemos diseñar pautas de diseño y seguirlas para mantener el sistema extensible y mantenible.

Pero estamos aquí para ayudarlo y queremos guiarlo a través de cómo puede convertirse en un buen colaborador de VyOS. Las reglas que tenemos no existen para castigarlo, las reglas existen para ayudarnos a todos. ¿Qué significa? Al tener un estilo de codificación consistente, se vuelve muy fácil para los nuevos contribuyentes y también para los contribuyentes antiguos navegar a través de las fuentes y toda la lógica implícita del código de espagueti.

Please use the following template as good starting point when developing new modules or even rewrite a whole bunch of code in the new style XML/Python interface.

Estructura y comportamiento del script de configuración

Su secuencia de comandos de configuración o secuencia de comandos de modo de operación, que también está escrita en Python3, debe tener un salto de línea de 80 caracteres. Esto parece un poco extraño hoy en día, pero como algunas personas también trabajan de forma remota o programan usando vi(m), este es un buen estándar en el que espero podamos confiar.

Además, esto también ayuda al navegar por el código base de GitHub en un dispositivo móvil si eres un científico loco.

#!/usr/bin/env python3
#
# Copyright (C) 2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import sys

from vyos.config import Config
from vyos import ConfigError

def get_config():
    if config:
        conf = config
    else:
        conf = Config()

    # Base path to CLI nodes
    base = ['...', '...']
    # Convert the VyOS config to an abstract internal representation
    config_data = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
    return config_data

def verify(config):
    # Verify that configuration is valid
    if invalid:
        raise ConfigError("Descriptive message")
    return True

def generate(config):
    # Generate daemon configs
    pass

def apply(config):
    # Apply the generated configs to the live system
    pass

try:
    c = get_config()
    verify(c)
    generate(c)
    apply(c)
except ConfigError as e:
    print(e)
    sys.exit(1)

La función get_config() debe convertir la configuración de VyOS en una representación interna abstracta. No se permite que ninguna otra función llame a vyos.config. Config método de objeto directamente. La razón de esto es que cuando las lecturas de configuración se mezclan con otra lógica, es muy difícil cambiar la sintaxis de configuración, ya que debe eliminar todas las apariciones de la sintaxis anterior. Si el código específico de la sintaxis se limita a una sola función, el resto del código se puede dejar intacto siempre que la representación interna siga siendo compatible.

Otra ventaja es la capacidad de prueba del código. Burlarse de todo el subsistema de configuración es difícil, mientras que construir una representación interna a mano es mucho más simple.

La función verify() toma su representación interna de la configuración y verifica si es válida; de lo contrario, debe generar ConfigError con un mensaje de error que describe el problema y posiblemente sugiere cómo solucionarlo. No debe realizar ningún cambio en el sistema. La razón para esto es nuevamente la capacidad de prueba y, en el futuro, cuando el backend de configuración esté listo y cada script se reescriba de esta manera, la capacidad de ejecutar la prueba de confirmación (&quot;commit test&quot; como en JunOS) y cancelar la confirmación antes de realizar cualquier cambio en el sistema si se encuentra un error en cualquier componente.

La función generate() genera archivos de configuración para los componentes del sistema.

La función apply() aplica la configuración generada al sistema en vivo. Debe usar una recarga no disruptiva siempre que sea posible. Puede ejecutar operaciones disruptivas, como el reinicio del proceso daemon, si un componente en particular no admite la recarga no disruptiva, o cuando la degradación esperada del servicio es mínima (por ejemplo, en el caso de servicios auxiliares como LLDPd). En el caso de servicios de alto impacto, como el demonio de VPN y los protocolos de enrutamiento, cuando se admite la recarga no disruptiva para algunos pero no todos los tipos de cambios de configuración, los autores de scripts deben hacer un esfuerzo para determinar si se puede realizar un cambio de configuración de forma no disruptiva. y solo recurrir al reinicio disruptivo si no se puede evitar.

A menos que sea absolutamente necesario, los scripts de configuración no deben modificar directamente la configuración activa de los componentes del sistema. Siempre que sea posible, los scripts deben generar un archivo o archivos de configuración que se puedan aplicar con un solo comando, como recargar un servicio a través de systemd init. Se desaconseja especialmente insertar declaraciones una por una, por ejemplo, al configurar las reglas de netfilter, guardarlas en un archivo y cargarlo con iptables-restore siempre debe ser preferible a ejecutar iptables directamente.

Las funciones apply() y generate() pueden `` generar ConfigError`` si, por ejemplo, el demonio no pudo iniciarse con la configuración actualizada. No debería ser un sustituto de la verificación de configuración adecuada en la función verify(). Deben realizarse todos los esfuerzos razonables para verificar que la configuración generada es válida y será aceptada por el daemon, incluidas, cuando sea necesario, verificaciones cruzadas con otros subárboles de configuración de VyOS.

Las excepciones, incluido VyOSError (que genera vyos.config.Config en operaciones de configuración incorrectas, como tratar de usar list_nodes() en un nodo sin etiqueta) no deben silenciarse o atrapado y reelevado como error de configuración. Seguro que esto no se verá bien en la pantalla del usuario, pero mejorará mucho los informes de errores y ayudará a los usuarios (y la mayoría de los usuarios de VyOS son profesionales de TI) a hacer su propia depuración también.

Para facilitar la orientación, le sugerimos que eche un vistazo a la implementación de ntp.py o interfaces-bonding.py (para nodos de etiquetas). Ambos archivos se pueden encontrar en el repositorio vyos-1x.

XML (usado para definiciones CLI)

La finalización de bash (o mejor vbash) en VyOS se define en templates. Las plantillas son archivos de texto (llamados node.def) almacenados en un árbol de directorios. Los nombres de los directorios definen los nombres de los comandos y los archivos de plantilla definen el comportamiento de los comandos. Antes de VyOS 1.2 (crux), estos archivos se creaban a mano. Después de un complejo proceso de rediseño, la nueva plantilla de estilo se genera automáticamente a partir de un archivo de entrada XML.

Las definiciones de interfaz XML para VyOS vienen con un esquema RelaxNG y se encuentran en el módulo vyos-1x. Este esquema es un esquema ligeramente modificado de VyConf alias VyOS 2.0, por lo que las definiciones de interfaz de VyOS 1.2.x serán reutilizables en las versiones de Nextgen VyOS con cambios mínimos.

Lo mejor de los esquemas no es solo que las personas pueden conocer la gramática completa con certeza, sino también que se puede verificar automáticamente. El script scripts/build-command-templates que convierte las definiciones XML en plantillas de estilo antiguo también las verifica contra el esquema, por lo que una mala definición hará que la compilación del paquete falle. Estoy de acuerdo en que el formato es detallado, pero ahora no hay otro formato que permita esto. Además, un editor XML especializado puede aliviar el problema de la verbosidad.

Ejemplo:

<?xml version="1.0"?>
<!-- Cron configuration -->
<interfaceDefinition>
  <node name="system">
    <children>
      <node name="task-scheduler">
        <properties>
          <help>Task scheduler settings</help>
        </properties>
        <children>
          <tagNode name="task" owner="${vyos_conf_scripts_dir}/task_scheduler.py">
            <properties>
              <help>Scheduled task</help>
              <valueHelp>
                <format>&lt;string&gt;</format>
                <description>Task name</description>
              </valueHelp>
              <priority>999</priority>
            </properties>
            <children>
              <leafNode name="crontab-spec">
                <properties>
                  <help>UNIX crontab time specification string</help>
                </properties>
              </leafNode>
              <leafNode name="interval">
                <properties>
                  <help>Execution interval</help>
                  <valueHelp>
                    <format>&lt;minutes&gt;</format>
                    <description>Execution interval in minutes</description>
                  </valueHelp>
                  <valueHelp>
                    <format>&lt;minutes&gt;m</format>
                    <description>Execution interval in minutes</description>
                  </valueHelp>
                  <valueHelp>
                    <format>&lt;hours&gt;h</format>
                    <description>Execution interval in hours</description>
                  </valueHelp>
                  <valueHelp>
                    <format>&lt;days&gt;d</format>
                    <description>Execution interval in days</description>
                  </valueHelp>
                  <constraint>
                    <regex>[1-9]([0-9]*)([mhd]{0,1})</regex>
                  </constraint>
                </properties>
              </leafNode>
              <node name="executable">
                <properties>
                  <help>Executable path and arguments</help>
                </properties>
                <children>
                  <leafNode name="path">
                    <properties>
                      <help>Path to executable</help>
                    </properties>
                  </leafNode>
                  <leafNode name="arguments">
                    <properties>
                      <help>Arguments passed to the executable</help>
                    </properties>
                  </leafNode>
                </children>
              </node>
            </children>
          </tagNode>
        </children>
      </node>
    </children>
  </node>
</interfaceDefinition>

Las definiciones de comandos son puramente declarativas y no pueden contener ninguna lógica. Toda la lógica para generar archivos de configuración para aplicaciones de destino, reiniciar servicios, etc., se implementa en scripts de configuración.

Preprocesador GNU

Los archivos de definición de interfaz XML utilizan la extensión de archivo xml.in que se implementó en T1843. Las definiciones de interfaz XML tienden a tener mucho código duplicado en áreas como:

  • VIF (incl. VIF-S/VIF-C)

  • DIRECCIÓN

  • Descripción

  • Habilitado Deshabilitado

En lugar de proporcionar todos esos nodos XML varias veces, ahora se incluyen archivos con características predefinidas. Breve descripción:

Todos los archivos de entrada XML de definición de interfaz (sufijo .in) se enviarán al preproceso de GCC y la salida se almacenará en la carpeta build/interface-definitions. El script scripts/build-command-templates mencionado anteriormente opera en la carpeta build/interface-definitions para generar todos los nodos CLI requeridos.

$ make interface_definitions
install -d -m 0755 build/interface-definitions
install -d -m 0755 build/op-mode-definitions
Generating build/interface-definitions/intel_qat.xml from interface-definitions/intel_qat.xml.in
Generating build/interface-definitions/interfaces-bonding.xml from interface-definitions/interfaces-bonding.xml.in
Generating build/interface-definitions/cron.xml from interface-definitions/cron.xml.in
Generating build/interface-definitions/pppoe-server.xml from interface-definitions/pppoe-server.xml.in
Generating build/interface-definitions/mdns-repeater.xml from interface-definitions/mdns-repeater.xml.in
Generating build/interface-definitions/tftp-server.xml from interface-definitions/tftp-server.xml.in
[...]

Pautas

uso de numeros

El uso de números en nombres de comandos debe evitarse a menos que un número sea parte de un nombre de protocolo o similar. Por lo tanto, protocols ospfv3 está perfectamente bien, pero algo como server-1 es cuestionable en el mejor de los casos.

Cadena de ayuda

Para garantizar una apariencia uniforme y mejorar la legibilidad, debemos seguir un conjunto de pautas de manera constante.

Mayúsculas y puntuación

La primera palabra de cada cadena de ayuda debe estar en mayúscula. No debe haber un punto al final de las cadenas de ayuda.

Justificación: este parece ser el estándar no escrito en las CLI de dispositivos de red y un buen compromiso estético.

Ejemplos:

  • Bueno: &quot;Algoritmo de frobnicación&quot;

  • Malo: &quot;algoritmo de frobnicación&quot;

  • Malo: &quot;Algoritmo de frobnicación&quot;.

  • Horrible: &quot;algoritmo de frobnicación&quot;.

Uso de abreviaturas y siglas

Las abreviaturas y los acrónimos deben estar en mayúscula.

Ejemplos:

  • Bueno: &quot;Tiempo de espera de conexión TCP&quot;

  • Incorrecto: &quot;tiempo de espera de conexión tcp&quot;

  • Horrible: &quot;Tiempo de espera de conexión TCP&quot;

Los acrónimos también deben escribirse en mayúscula para distinguirlos visualmente de las palabras normales:

Ejemplos:

  • Bueno: RADIUS (como en la autenticación remota para servicios de acceso telefónico de usuarios)

  • Malo: radio (a menos que se trate de la distancia entre el centro de un círculo y cualquiera de sus puntos)

Algunas abreviaturas se escriben tradicionalmente en mayúsculas y minúsculas. Generalmente, si contiene palabras &quot;over&quot; o &quot;version&quot;, la letra debe estar en minúscula. Si hay una ortografía aceptada (especialmente si está definida por un RFC u otro estándar), debe seguirse.

Ejemplos:

  • Bueno: PPPoE, IPsec

  • Malo: PPPOE, IPSEC

  • Malo: PPPOE, IPSEC

uso de verbos

Los verbos deben evitarse. Si se puede omitir un verbo, omítalo.

Ejemplos:

  • Bueno: &quot;Tiempo de espera de conexión TCP&quot;

  • Incorrecto: &quot;Establecer tiempo de espera de conexión TCP&quot;

Si un verbo es esencial, mantenlo. Por ejemplo, en el texto de ayuda de set system ipv6 disabled-forwarding, &quot;Deshabilitar el reenvío de IPv6 en todas las interfaces&quot; es una redacción perfectamente justificada.

Prefiero los infinitivos

Los verbos, cuando son necesarios, deben estar en su forma infinitiva.

Ejemplos:

  • Bueno: &quot;Deshabilitar el reenvío de IPv6&quot;

  • Incorrecto: &quot;Deshabilita el reenvío de IPv6&quot;

Migración de la CLI antigua

Viejo concepto/sintaxis

Nueva sintaxis

notas

minodo/nodo.def

<node name=»mynode»> </node>

Uso de nodos hoja (nodos con valores)<leafNode> etiqueta en su lugar

mynode/node.tag , etiqueta:

<tagNode name=»mynode> </node>

ayuda: Mi nodo

<properties><help>mi nodo</help>

val_ayuda:<format> ; alguna cuerda

<properties><valueHelp><format>formato</format><description> alguna cuerda</description>

No agregue corchetes angulares alrededor del formato, se insertarán automáticamente

sintaxis: expresión: patrón

<properties><constraint><regex>…

<constraintErrorMessage>se mostrará en caso de falla

sintaxis:expresión: $VAR(@) en &quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot;

Ninguno

Usar expresiones regulares

sintaxis: expresión: exec …

<properties> <constraint> <validator> <name =»foo» argument=»bar»>

Se ejecutará &quot;${vyos_libexecdir}/validators/foo bar $VAR(@)&quot;,<constraintErrorMessage> se mostrará en caso de falla

sintaxis:expresión: (expresión aritmética)

Ninguno

Se puede agregar un validador aritmético externo si hay demanda, es mejor dejar la validación compleja para los scripts de tiempo de confirmación

prioridad: 999

<properties><priority>999</priority>

Deje un comentario que explique por qué se eligió la prioridad (por ejemplo, &quot;después de configurar las interfaces&quot;)

multi:

<properties> <multi/>

Solo aplicable a los nodos hoja

permitido: echo foo bar

<properties><completionHelp><list>barra de comida</list>

permitido: cli-shell-api listNodes vpn ipsec esp-group

<properties><completionHelp><path>vpn ipsec esp-grupo</path> …

permitido: /ruta/al/script

<properties><completionHelp><script> /path/to/script </script>…

por defecto:

Ninguno

Mover valores predeterminados a scripts

cometer:expresión:

Ninguno

Todas las verificaciones de tiempo de compromiso deben estar en la función de verificación () del script

comenzar:/crear:/eliminar:

Ninguno

Toda la lógica debe estar en los scripts.

Código de fondo de C++

El analizador CLI que se usa en VyOS es una combinación de bash, bash-completion helper y la biblioteca de back-end de C++ [vyatta-cfg](https://github.com/vyos/vyatta-cfg). Esta sección es una referencia de los comandos CLI comunes y el punto de entrada respectivo en el código C/C++.

Integración continua

VyOS utiliza Jenkins como nuestro servicio de integración continua (CI). Nuestro servidor VyOS CI es de acceso público aquí: https://ci.vyos.net. Puede obtener una breve descripción general de todos los componentes necesarios enviados en una ISO de VyOS.

Para construir nuestros módulos, utilizamos un script Pipeline de CI/CD. Todos y cada uno de los componentes de VyOS vienen con su propio Jenkinsfile que es (más o menos) una copia. Pipeline utiliza el contenedor Docker de la sección Construir ISO, pero en lugar de compilarlo desde el origen en cada ejecución, siempre buscamos una copia nueva (si es necesario) de Dockerhub.

Cada módulo se crea bajo demanda si se encuentra una nueva confirmación en la rama en cuestión. Después de una ejecución exitosa, los paquetes Debian resultantes se implementarán en nuestro repositorio Debian, que se usa durante el tiempo de compilación. Se encuentra aquí: http://dev.packages.vyos.net/repositories/.