Ir al contenido

Blog ·

Un script que sabe que habla con un contenedor

Siete campos opcionales donde la ausencia significa no determinado, una tabla cuya prueba deriva sus casos, y un sistema operativo en la lista equivocada.

Por Provibr

Una máquina anfitriona de Proxmox puede ejecutar dos cosas muy distintas: una máquina virtual completa con núcleo y firmware propios, y un contenedor que comparte el núcleo del anfitrión. De lejos las dos son «un servidor» y el panel las trata en una sola lista. De cerca difieren de maneras que importan a quien escribe automatización, y hasta esta ronda un script no podía distinguirlas.

Es una mala posición. Un script que pide a un contenedor ampliar un disco virtual, montar una imagen ISO o arrancar por red no pide algo difícil; pide algo que no existe. El fallo llega cuatro capas más tarde, como una orden aceptada, encolada, enviada y luego rechazada por un agente.

Siete campos, y ausente significa no determinado

Los scripts y los webhooks reciben ahora un grupo de hechos sobre lo que hay debajo de un servidor: su clase, la plantilla de la que sale, si es no privilegiado, el almacenamiento donde vive su raíz, sus puntos de montaje, lo que de verdad puede hacer y lo que no.

Cualquiera de esos campos puede faltar, y faltar significa no determinado. Es la misma regla que sigue la columna subyacente, donde la clase nunca se rellenó en silencio, y existe porque la alternativa es peor que inútil. Una instantánea que escribe «máquina virtual» cuando nadie lo midió nunca es una conjetura entregada a un script que tomará una decisión con ella.

Así que una clase desconocida no se convierte en un valor por omisión. El campo desaparece por completo del contexto de representación, y leerlo es entonces un error duro en el momento de guardar el flujo, en vez de una cadena vacía que vuelve falsa una condición en silencio. Es el mismo razonamiento que eliminar un grupo de variables que un disparador no puede aportar: en voz alta al guardar gana a en silencio durante la ejecución.

Es además el primer grupo anidado del catálogo de variables. Un nombre de campo con un punto dentro suele ser una trampa en esta base de código, porque el catálogo de traducción trata el punto como un nivel; aquí la clave del catálogo lo aplana a propósito mientras la ruta del contexto baja un nivel más, y una prueba fija la suposición de que hay exactamente un punto.

Las rutas del anfitrión no viajan

Un montaje enlazado en la configuración de un contenedor parece una clave, una ruta del anfitrión y un punto de montaje. Esa ruta es un directorio del hipervisor, y nunca debe salir de ahí.

La regla en nuestra propia documentación es tajante: los clientes no obtienen jamás por Provibr un intérprete de órdenes del anfitrión, una ruta de su sistema de ficheros ni una credencial de administración del hipervisor. Una instantánea de variables es exactamente esa vía. Acaba en un script, en el cuerpo de un webhook en casa de un tercero y en una fila de auditoría.

Por eso la instantánea nunca lleva el origen. Queda lo que un cliente puede saber de su propio contenedor: qué clave es, dónde está montada dentro del contenedor y de qué clase de origen viene. Una forma de texto fija, porque un script lee esto partiendo por un separador y no analizando prosa: mp1:bind:/srv dice que hay un montaje enlazado en /srv, y no dice absolutamente nada de dónde sale en el anfitrión.

Eso vale también para un montaje de volumen. Un nombre de almacenamiento no es una ruta del anfitrión, pero sí es la nomenclatura propia del hipervisor, y ninguna pregunta de script lo necesita. El nombre del almacenamiento aparece una vez, aparte, como una sola palabra que el cliente ya vio al pedirlo.

El precio de este diseño se declara en vez de esconderse: los hechos de montaje salen de la configuración que el agente lee durante una copia de seguridad, así que un contenedor que nunca tuvo copia no produce ningún punto de montaje. El campo falta entonces, y eso es lo correcto, porque una lista vacía afirmaría que el contenedor no tiene puntos de montaje.

Una tabla cuya prueba deriva sus propios casos

Ya existía una tabla escrita que dice, por cada orden de máquina virtual, si un contenedor puede con ella y por qué no. Faltaba una tabla que cubriera todas las órdenes que puede llevar una integración de Proxmox, incluidas las copias de seguridad y las cuatro lecturas que describen la integración y no un huésped concreto.

Sin esa distinción, una criba no puede separar «no hay juicio anotado» de «esto no va de un huésped en absoluto», y el único comportamiento seguro para lo segundo es dejar pasar. Esa es justo la rama silenciosa con la que este proyecto se sigue quemando.

Por eso la tabla nueva se deriva de la escrita en vez de escribirse al lado, y la prueba no enumera casos. Calcula el conjunto alcanzable a partir de los registros, tomando toda clase de orden que el proveedor Proxmox no rechaza y que además sirve a un recurso huésped, más las lecturas nombradas en el propio descriptor del proveedor, y exige entonces una declaración por clase. Veintisiete órdenes de huésped y cuatro lecturas de integración, y la prueba se demostró primero en rojo y después en verde.

Una prueba por caso no puede encontrar un caso que falta. Esta base de código ha aprendido esa lección tres veces ya, y esta es la tercera forma de la misma salvaguarda.

Una orden falta a propósito, y el comentario dice dónde buscarla. Ejecutar una orden dentro de un contenedor significaría hoy correrla como administrador en el hipervisor, fuera del contenedor, con los permisos del anfitrión. Eso no es una función de scripts con poca huella; es un intérprete de órdenes del anfitrión con nombre amable. Quien la construya tendrá una ronda propia, con un ejecutor dentro del huésped, un permiso propio y un rastro de auditoría propio.

Un rechazo antes del envío no deja fila

La pasarela ya rechazaba órdenes imposibles. Ese rechazo le ocurre a una orden que ya existe: la fila está en la base de datos, la operación se creó, y el cliente mira cómo falla un encargo.

Lo que se pedía era validación antes del envío, y esa es justo la diferencia. Pedirle a un contenedor su hardware virtual debe dar una frase y no una fila de auditoría.

Las dos cribas no pueden desfasarse, porque leen la misma tabla. No es una segunda verdad; es la misma verdad, una capa antes. La pasarela sigue haciendo falta para la petición repetida o falsificada que nunca pasa por la función del panel.

El motivo del rechazo se muestra como un solo mensaje con una rama por motivo, y la salvaguarda a su alrededor exige dos cosas: una rama por cada motivo, y que las frases se diferencien entre sí. Una rama ausente en una selección de idioma cae al valor por omisión y dice algo que es cierto y no significa nada, y ese modo de fallo ya lo conoce este proyecto.

El sistema operativo en la lista equivocada

El hallazgo que solo dio una base de datos real no tenía nada que ver con lo anterior.

Las entradas de sistema operativo guardaban antes su origen de instalación en una columna y ahora en dos, leyéndose la antigua como reserva para filas que ningún escritor nuevo tocó jamás. Las plantillas de contenedor llegaron después y van a una columna propia, y en una fila nueva se proyectan también a la antigua.

La reserva no sabía nada de eso. Leía una referencia de contenedor en la columna antigua como plantilla de máquina virtual, de modo que un sistema operativo con solo una plantilla de contenedor aparecía en la lista de máquinas virtuales del flujo de pedido, sin clase de cómputo, y un pedido hecho contra él habría encallado más tarde en un origen de clonado sin identificador que clonar.

El arreglo es una rama: una referencia de contenedor en la columna antigua no es un origen de máquina virtual. No se pierde nada, porque el lado del contenedor lee su propia columna y ninguna otra, y las filas lo bastante antiguas para necesitar la reserva no pueden llevar por construcción una referencia de contenedor: esa columna todavía no existía.

Un segundo hallazgo salió de una captura de pantalla y no de una comprobación. En la lista de cosas que un contenedor no puede hacer figuraba una orden de pago que pertenece a otro proveedor y que en Proxmox no existe para ninguna de las dos clases. Cierta, y completamente fuera de lugar en la página de detalle de un contenedor. Se retiró de esa lista.

Lo que anotaríamos

  1. Ausente es una respuesta. Si no conoce la clase, no ponga un valor por omisión. Una conjetura entregada a la automatización es peor que un hueco que el script puede ver.
  2. La seguridad de permisos es una propiedad de la forma, no de quien llama. Diseñe la instantánea de modo que la ruta del anfitrión no esté dentro, y ningún lector futuro podrá filtrarla.
  3. Una forma de texto fija gana a la prosa. Alguien va a partir esto por un separador.
  4. Derive los casos del registro. Una prueba por caso es estructuralmente incapaz de encontrar el caso que nadie escribió.
  5. Rechace antes de registrar. Un rechazo que produce una fila de auditoría ya le ha contado al cliente la historia equivocada.
  6. Mire las capturas de pantalla. La entrada fuera de lugar era cierta, pasó todas las comprobaciones y a un ojo humano le pareció mal al instante.

Para que quede claro qué es esto: los contenedores se pueden pedir en Proxmox y los hechos de cómputo están en producción. Varias cosas no están probadas. Nada de ello se ejerció en esta ronda contra un hipervisor real, los hechos de montaje dependen de que haya habido al menos una copia de seguridad, una frase del flujo de pedido sigue diciendo «la VM» sobre un contenedor, y el contador de licencias sigue contando un contenedor como máquina virtual.

Del trabajo de plataforma de Provibr. Por qué un contenedor no privilegiado es una medición y no un ajuste está en no privilegiado es una medición, no un ajuste, y qué puntos de montaje contiene y cuáles no una copia de un contenedor está en lo que una copia de seguridad no contiene.

Empiece con un host y un agente

Cree una cuenta, instale el agente con un solo comando y conecte su primer host de Proxmox. El periodo de prueba dura 14 días y no pide ningún dato de pago.