Problema

Los repositorios oficiales de muchas distribuciones entregan versiones de open‑vm‑tools que quedan rezagadas respecto al código fuente upstream. Ese desfase retrasa correcciones de kernel, mejoras del controlador de memoria balloon y parches de vulnerabilidades (CVE). Cuando se ejecutan máquinas virtuales en entornos mixtos –Ubuntu, Debian, RHEL‑based, Fedora o openSUSE– el administrador termina con paquetes inconsistentes: algunos hosts reciben correcciones críticas y otros siguen con versiones vulnerables. La solución manual (descargar el tarball, compilar en cada host y gestionar dependencias) genera contaminación del entorno y dificulta la reproducibilidad.

Causa

  1. Política de estabilización de la distro – Las distribuciones priorizan la estabilidad sobre la novedad, por lo que retardan la incorporación de cambios upstream.
  2. Diferencias en el sistema de paquetes – .deb y .rpm manejan dependencias distintas; empaquetar una misma fuente para ambas familias requiere ajustes específicos.
  3. Falta de canal de distribución interno – Sin un repositorio propio, cada host necesita compilar localmente o confiar en paquetes obsoletos.
  4. Entornos heterogéneos – Cuando una flota incluye varias versiones de RHEL (8/9) o diferentes sabores de SUSE, la gestión manual se vuelve insostenible.

Solución

Adoptar un flujo de trabajo basado en contenedores para la compilación y en Ansible para la distribución. El proceso se divide en tres fases:

  1. Construcción aislada

    • Un Dockerfile prepara un entorno de compilación con todas las dependencias necesarias (gcc, make, librerías de desarrollo, etc.).
    • Dentro del contenedor se clona el repositorio upstream de open‑vm‑tools, se ejecuta ./configure con los flags adecuados y se generan los paquetes .deb y .rpm mediante dpkg‑deb y rpmbuild.
    • El artefacto resultante se exporta a un volumen host o a un bucket S3 interno, evitando cualquier rastro de compilación en los nodos de producción.
  2. Repositorio interno

    • Los paquetes creados se publican en un repositorio HTTP/HTTPS interno (por ejemplo, usando aptly para .deb y createrepo_c para .rpm).
    • Cada nodo apunta a ese repositorio mediante su archivo de fuentes (/etc/apt/sources.list.d/ o /etc/yum.repos.d/).
    • La versión del paquete se controla con un número de release propio, lo que permite actualizaciones controladas.
  3. Despliegue con Ansible

    • Un rol de Ansible declara las dependencias del paquete, asegura que el repositorio interno está configurado y ejecuta apt-get install -y open-vm-tools o dnf install -y open-vm-tools.
    • El rol también detecta paquetes instalados desde los repositorios de la distro y los elimina antes de instalar la versión compilada, garantizando una única fuente.
    • Finalmente, el rol verifica que el servicio vmtoolsd está activo y habilitado, y ejecuta una prueba de comunicación con el hipervisor (por ejemplo, vmware-toolbox-cmd -v).

Este enfoque es reutilizable para cualquier software que sufra el mismo desfase entre upstream y repositorios oficiales: basta cambiar la URL del código fuente y adaptar los flags de configuración.

Cuándo aplicar esta solución

  • Entornos con varios tipos de distro donde la versión empaquetada por la distro es demasiado antigua para los requisitos de seguridad o funcionales.
  • Flotas que requieren parches de CVE rápidamente y no pueden esperar al ciclo de actualización de la distro.
  • Infraestructuras donde la consistencia de versiones es crítica (por ejemplo, clusters de Kubernetes que dependen de la misma versión de herramientas de virtualización).
  • No aplica si la distribución ya ofrece versiones al día o si el software en cuestión no tiene un proceso de compilación reproducible (por ejemplo, paquetes puramente binarios sin código fuente).

Código

# 1. Construir la imagen de compilación
docker build -t vmtools-builder -f Dockerfile.builder .

# 2. Ejecutar la compilación y extraer paquetes
docker run --rm -v $(pwd)/out:/out vmtools-builder \
    bash -c "
    git clone https://github.com/vmware/open-vm-tools.git /src &&
    cd /src &&
    ./configure --prefix=/usr &&
    make -j$(nproc) &&
    make install DESTDIR=/out/pkg &&
    fpm -s dir -t deb -n open-vm-tools -v $(git rev-parse --short HEAD) /out/pkg &&
    fpm -s dir -t rpm -n open-vm-tools -v $(git rev-parse --short HEAD) /out/pkg
    "

# 3. Publicar paquetes en repositorio interno (ejemplo con apt repository)
aptly repo add vmtools_repo out/*.deb
aptly publish repo -distribution=stable vmtools_repo http://repo.internal/apt

# 4. Ejecutar rol Ansible (asumiendo que el rol se llama vmware_tools_builder)
ansible-playbook -i inventory.yml -b -e repo_url=http://repo.internal/apt \
    site.yml --tags vmware_tools_builder

Verificación

  1. Comprobar versión instalada

    vmware-toolbox-cmd -v
    

    La salida debe coincidir con el hash corto usado en la compilación.

  2. Validar estado del servicio

    systemctl is-active vmtoolsd && systemctl is-enabled vmtoolsd
    

    Ambos comandos deben devolver active y enabled.

  3. Revisar origen del paquete

    dpkg -s open-vm-tools | grep ^Version
    apt-cache policy open-vm-tools
    

    La política debe mostrar el repositorio interno como la fuente prioritaria.

  4. Prueba de funcionalidad
    Ejecuta vmware-toolbox-cmd stat raw y verifica que se reportan los valores de memoria balloon y tiempo de arranque sin errores.

Notas adicionales

  • Cache de dependencias: mantener una capa de Docker con las herramientas de compilación evita descargar paquetes en cada build y acelera el proceso.
  • Firmado de paquetes: si la política de seguridad lo exige, firma los .deb con debsign y los .rpm con rpmsign antes de publicarlos.
  • Rotación de versiones: conserva al menos dos versiones anteriores en el repositorio interno; permite rollback rápido si una actualización introduce regressiones.
  • Compatibilidad de kernel: algunas versiones de open‑vm‑tools requieren headers específicos. Añade la instalación de kernel-devel o linux-headers al Dockerfile para evitar fallos de compilación.
  • Ansible idempotencia: el rol debe usar package con state=present y update_cache=yes para que la ejecución sea segura en hosts ya configurados.
  • Monitorización: incluye una alerta en tu sistema de observabilidad que dispare si el proceso vmtoolsd deja de estar activo; así detectas rápidamente problemas de despliegue.