Categoría: debian

  • Expandiendo las Capacidades de Desarrollo: Proton Drive y Debian GNU/Linux

    Expandiendo las Capacidades de Desarrollo: Proton Drive y Debian GNU/Linux

    Capítulo 3: Mi Travesía Personal como Aspirante a Debian Maintainer

    Expandiendo las Capacidades de Desarrollo: Setup Híbrido con Proton Drive y Debian GNU/Linux

    8 de noviembre, 2025

    Las Limitaciones de Espacio con un ordenador portátil de 13 años

    Como desarrollador con más de 20 años de experiencia en Unix/Linux, he enfrentado un desafío constante: las limitaciones de almacenamiento local versus la necesidad de mantener múltiples proyectos activos, especialmente cuando trabajo en empaquetado complejo como Chromium Embedded Framework (CEF) para Debian. Recientemente, desarrollé una solución elegante que combina Proton Drive con automatización Linux para crear un ecosistema de desarrollo verdaderamente híbrido.

    El Problema: Limitaciones de Hardware Legacy

    Mi setup principal incluye un MacBook Pro 11,1 ejecutando Debian, con apenas 100GB de almacenamiento SSD. Con solo 15GB libres después de instalar las herramientas de desarrollo esenciales, cada proyecto de empaquetado se convierte en un juego de tetris de espacio en disco. Los builds de CEF pueden generar varios gigabytes de datos, y mantener múltiples iteraciones para debugging se vuelve imposible.

    Además, trabajo desde múltiples máquinas – la principal en casa y una laptop de viaje – lo que requiere sincronización manual constante de archivos de configuración, documentación técnica y progreso de desarrollo.

    La Solución: Arquitectura Híbrida con Proton Drive

    Componentes del Sistema

    1. Almacenamiento Local (SSD 100GB)

    • Trabajo activo y builds en curso
    • Máxima velocidad para compilación
    • Cache temporal del sistema

    2. Proton Drive (500GB)

    • Storage expandido cifrado end-to-end
    • Backup automático de trabajo
    • Sincronización entre máquinas
    • Archive de builds completados

    3. Storage Externo (SanDisk + CalDigit)

    • Almacenamiento masivo para builds históricos
    • Repositorios de packages grandes
    • Backup de sistemas completos

    Arquitectura de Directorios

    # Estructura local
    ~/development/debian/           # Trabajo activo (local SSD)
    ~/ProtonDrive/                  # Mount automático (Proton Drive)
    ├── cef-builds-archive/         # Builds completados
    ├── documentation-backup/       # Docs técnicas
    ├── config-backup/             # Configuraciones del sistema
    └── temp-builds/               # Storage temporal expandido
    
    # Estructura en Proton Drive
    protondrive:/sync/debian/       # Sync automático trabajo activo
    protondrive:/mount/             # Storage expandido montado
    

    Implementación Técnica

    1. Configuración de RClone

    RClone actúa como el puente entre el sistema local y Proton Drive, proporcionando tanto capacidades de sincronización como montaje de filesystem.

    # Instalación desde repositorios Debian
    sudo apt update
    sudo apt install rclone
    
    # Verificar instalación
    rclone --version
    
    # Configuración
    rclone config
    # Seleccionar: protondrive
    # Introducir credenciales de Proton Mail
    # Configurar 2FA si está habilitado
    

    2. Servicio de Sincronización Automática

    Creé un servicio systemd que sincroniza automáticamente el trabajo activo cada 4 horas:

    # ~/.config/systemd/user/proton-sync.service
    [Unit]
    Description=Sync Debian work to Proton Drive
    
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/rclone sync -L %h/development/debian protondrive:/sync/debian \
        --exclude="*.tmp" \
        --exclude="*.lock" \
        --exclude=".git/**" \
        --exclude="build/**" \
        --exclude="*.log" \
        --ignore-existing \
        --transfers=2 \
        --checkers=1 \
        --timeout=300s \
        --retries=3 \
        -q
    
    # ~/.config/systemd/user/proton-sync.timer
    [Unit]
    Description=Sync Debian work every 4 hours
    
    [Timer]
    OnCalendar=*-*-* 00,04,08,12,16,20:00:00
    Persistent=true
    
    [Install]
    WantedBy=timers.target
    

    Activación:

    systemctl --user daemon-reload
    systemctl --user enable --now proton-sync.timer
    

    3. Mount Automático de Storage Expandido

    Para casos donde necesito acceso directo a storage como si fuera un filesystem local:

    # ~/.config/systemd/user/proton-mount.service
    [Unit]
    Description=Mount Proton Drive storage
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=notify
    Environment=PATH=/usr/bin:/bin
    ExecStartPre=/bin/mkdir -p %h/ProtonDrive
    ExecStartPre=/bin/sh -c 'fusermount -u %h/ProtonDrive || true'
    ExecStart=/usr/bin/rclone mount protondrive:/mount %h/ProtonDrive \
        --vfs-cache-mode full \
        --vfs-cache-max-size 20G \
        --vfs-cache-max-age 24h \
        --buffer-size 32M \
        --dir-cache-time 1h \
        --allow-other
    ExecStop=/bin/fusermount -u %h/ProtonDrive
    Restart=on-failure
    RestartSec=15
    
    [Install]
    WantedBy=default.target
    

    Configuración previa necesaria:

    # Habilitar user_allow_other en fuse
    echo 'user_allow_other' | sudo tee -a /etc/fuse.conf
    
    # Habilitar linger para arranque automático
    sudo loginctl enable-linger $USER
    

    4. Scripts de Workflow

    Script de Pull (inicio de sesión de trabajo):

    #!/bin/bash
    # start-work.sh
    echo "Descargando últimos cambios..."
    rclone sync protondrive:/sync/debian $HOME/development/debian --progress -v
    echo "Listo para trabajar"
    

    Script de Push (fin de sesión de trabajo):

    #!/bin/bash
    # end-work.sh
    echo "Subiendo cambios..."
    rclone sync -L $HOME/development/debian protondrive:/sync/debian \
        --exclude="*.tmp" \
        --exclude="*.lock" \
        --exclude=".git/**" \
        --exclude="build/**" \
        --exclude="*.log" \
        --ignore-existing \
        --transfers=2 \
        --checkers=1 \
        --timeout=300s \
        --retries=3 \
        --stats=30s \
        --progress \
        -v
    echo "Trabajo guardado"
    

    Script de Archive para builds CEF:

    #!/bin/bash
    # archive-cef-build.sh
    BUILD_DATE=$(date +%Y%m%d_%H%M%S)
    echo "Archivando build CEF actual..."
    cp -r ~/development/debian/chromium-embedded-framework/build \
        ~/ProtonDrive/cef-builds-archive/cef-build-$BUILD_DATE
    echo "Build archivado en ~/ProtonDrive/cef-builds-archive/cef-build-$BUILD_DATE"
    

    Ventajas del Sistema

    1. Escalabilidad Transparente

    El laptop con 15GB libres ahora puede manejar proyectos de múltiples gigabytes sin impacto en el rendimiento local. Los builds activos permanecen en SSD para velocidad máxima, mientras el archive automático libera espacio continuamente.

    2. Continuidad Entre Máquinas

    El workflow pull/push permite cambiar entre máquina principal y laptop de viaje sin pérdida de contexto. Cada sesión comienza con start-work.sh y termina con end-work.sh, garantizando sincronización perfecta.

    3. Backup Automático Cifrado

    Con timer cada 4 horas, nunca pierdo más de 4 horas de trabajo. El cifrado end-to-end de Proton significa que incluso datos sensibles de clients están protegidos.

    4. Flexibilidad de Storage

    • Local: Máxima velocidad para trabajo activo
    • Mount: Acceso directo como filesystem para casos especiales
    • Sync: Backup automático sin intervención manual
    • Externo: Capacidad masiva para archive de largo plazo

    Casos de Uso Específicos

    Desarrollo CEF (Chromium Embedded Framework)

    Los builds de CEF generan varios GB de artifacts. La configuración permite:

    • Build activo en SSD local (velocidad)
    • Archive automático de builds completados
    • Sincronización de documentación técnica entre iteraciones
    • Backup de scripts de build y patches personalizados

    Trabajo Remoto y Viajes

    Antes del sistema, trabajar desde la laptop de viaje significaba:

    • Sincronización manual propensa a errores
    • Pérdida de contexto entre máquinas
    • Limitaciones de almacenamiento aún más severas

    Ahora es completamente transparente: start-work.sh en cualquier máquina restaura el contexto exacto de la última sesión.

    Monitoreo y Mantenimiento

    Verificación de Servicios

    # Ver estado de servicios
    systemctl --user status proton-sync.service
    systemctl --user status proton-mount.service
    
    # Ver próximas ejecuciones del timer
    systemctl --user list-timers proton-sync.timer
    
    # Logs detallados
    journalctl --user -u proton-sync.service --since today
    

    Scripts de Diagnóstico

    #!/bin/bash
    # check-proton-setup.sh
    echo "=== Estado del Sistema Proton Drive ==="
    
    # Verificar mount
    if mountpoint -q ~/ProtonDrive; then
        echo "✅ Storage expandido montado correctamente"
        df -h ~/ProtonDrive
    else
        echo "❌ Mount no disponible"
    fi
    
    # Verificar timer de sync
    if systemctl --user is-active proton-sync.timer >/dev/null; then
        echo "✅ Timer de sync activo"
        systemctl --user list-timers proton-sync.timer
    else
        echo "❌ Timer no activo"
    fi
    
    # Verificar conectividad
    if rclone ls protondrive:/sync/ >/dev/null 2>&1; then
        echo "✅ Conectividad con Proton Drive OK"
    else
        echo "❌ Problema de conectividad"
    fi
    

    Consideraciones de Rendimiento

    Red y Latencia

    • Upload: ~30-80 Mbps después de overhead de encriptación
    • Download: Near line speed con cache local activo
    • Latencia: Imperceptible para acceso a archivos cacheados

    Optimizaciones Implementadas

    • VFS cache full: 20GB cache local para acceso rápido
    • Transfers limitados: 2 transferencias concurrentes para estabilidad
    • Exclusiones inteligentes: Archivos temporales y logs excluidos del sync
    • Ignore existing: Evita conflictos en sincronización bidireccional

    Impacto en Productividad

    Métricas de Mejora

    • Storage efectivo: De 15GB a 515GB disponibles
    • Tiempo de setup entre máquinas: De 30+ minutos a <2 minutos
    • Pérdida máxima de trabajo: De días potenciales a máximo 4 horas
    • Flexibilidad de proyecto: Múltiples builds CEF simultáneos posibles

    Casos de Recuperación

    Durante el desarrollo, experimenté una desconexión inesperada que habría resultado en pérdida significativa de trabajo. El sistema automático había sincronizado el progreso 2 horas antes, permitiendo recuperación completa en minutos.

    Lecciones Aprendidas

    1. Automatización vs Control

    El balance entre timer automático (cada 4h) y scripts manuales (pull/push) proporciona tanto protección continua como control granular cuando es necesario.

    2. Exclusiones son Críticas

    La configuración inicial incluía logs de build (35MB cada uno), saturando la red. Las exclusiones inteligentes mejoraron el rendimiento dramáticamente.

    3. Systemd User Services

    Los servicios de usuario proporcionan automatización robusta sin requerir privilegios root, ideal para entornos de desarrollo personal.

    Conclusión

    Esta configuración híbrida resuelve múltiples limitaciones simultáneamente: espacio de almacenamiento, continuidad entre máquinas, backup automático y escalabilidad de proyectos. Para desarrolladores trabajando con proyectos complejos como empaquetado Debian o builds de software extensos, representa una solución elegante que combina lo mejor de storage local rápido con la flexibilidad y seguridad del cloud storage cifrado.

    Ventajas Clave del Sistema

    • Zero downtime por pérdida de trabajo
    • Escalabilidad transparente de almacenamiento
    • Continuidad perfecta entre múltiples máquinas
    • Backup automático cifrado sin intervención manual
    • Flexibilidad de storage adaptada a diferentes necesidades

    Próximos Pasos

    Este setup forma la base para expansiones futuras:

    • Integración con CI/CD para builds automáticos
    • Monitoreo avanzado con métricas de uso
    • Sincronización selectiva por proyectos
    • Archive automático basado en políticas de tiempo

    Para desarrolladores que enfrentan limitaciones similares de hardware legacy pero necesitan mantener productividad en proyectos modernos complejos, esta arquitectura híbrida proporciona una solución práctica y escalable.

    El código completo de configuración y scripts están disponibles en mi repositorio de dotfiles, y continuaré documentando mejoras y optimizaciones a medida que evolucione el sistema.


    Referencias Técnicas

  • From Documentation to Distribution: The Complete Stremio Debian Packaging Journey

    From Documentation to Distribution: The Complete Stremio Debian Packaging Journey

    How a simple documentation contribution evolved into a full-scale packaging solution with automated CI/CD, multi-distribution support, and deep technical problem-solving

    Author: Juan Manuel Méndez Rey
    Date: October 30, 2025
    Reading Time: 25 minutes
    Technical Level: Advanced


    The Beginning: A Documentation Gap

    Several years ago, while working with Stremio on Debian systems, I encountered the familiar frustration of Linux users everywhere: a great application with poor installation documentation. The official Stremio releases worked fine on some distributions, but Debian users were left to figure out dependencies, compilation steps, and integration challenges on their own.

    That’s when I contributed the original DEBIAN.md file to the Stremio shell repository. It was a straightforward build guide—install these dependencies, run these commands, copy these files. Simple, but functional.

    Years passed. Dependencies changed. Qt versions evolved. The simple build instructions became increasingly unreliable on modern Debian systems, and the GitHub issues piled up with frustrated users unable to compile Stremio.


    The Problem Grows

    By 2025, the situation had become untenable:

    • Dependency conflicts: The upstream .deb package required libmpv1, but modern Debian ships libmpv2
    • FHS violations: Upstream installed everything to /opt, violating Debian filesystem standards
    • Missing QML modules: Critical Qt5 components weren’t documented as dependencies
    • Compilation complexity: Users needed to install 15+ build dependencies to compile from source
    • No proper integration: Desktop files, icons, and system integration required manual work
    • The upstream .deb package is outdated, it is providing the 4.4.168 version.
    • The list continues…

    The GitHub issues were a testament to user frustration—dozens of reports about compilation failures, missing dependencies, and broken installations.


    The Debian Way: Proper Packaging

    Rather than continue patching documentation, I remembered a discussion with my friend, Arturo, about properly packaging Stremio for Debian, he created a RFP (Request for Package) for Stremio in 2020. Years passed and I went into my usual day to day work.
    This past month I decided I had to fulfill my old dream of becoming an official Debian contributor, so I decided to solve this properly through the Debian packaging system. In late 2025, I filed an Intent To Package (ITP) with Debian:

    The goal was simple: create properly-packaged Debian packages that would eventually enter the official Debian archive.

    Packaging Challenges

    Stremio presents unique packaging challenges:

    1. License separation: The desktop client is GPL-3.0 (free), but the streaming server is proprietary
    2. Modern dependencies: Requires current Qt5 WebEngine and libmpv versions
    3. Complex build system: Qt5 + Node.js + WebAssembly components
    4. Desktop integration: Proper icon installation, MIME types, and .desktop files
    5. Bundled dependencies: Upstream used git submodules for everything

    Following Debian policy, I separated the components:

    • stremio package (main/free) – GPL desktop client v4.4.169
    • stremio-server package (non-free) – Proprietary streaming server v4.20.12

    Technical Deep Dive: System Library Migration

    The most challenging aspect was replacing ALL bundled git submodules with Debian system libraries. This wasn’t just about dependencies—it required fixing fundamental runtime issues.

    Challenge 1: QtWebEngine Initialization Crash 🔥 CRITICAL

    Problem: Application crashed immediately on startup:

    Segmentation fault (core dumped)

    Root Cause Analysis:

    # GDB backtrace showed:
    #0  QQmlApplicationEngine::QQmlApplicationEngine()
    #1  main (argc=1, argv=0x7fffffffdc58) at main.cpp:120

    QtWebEngine must be initialized before QApplication constructor, but upstream code created QApplication first.

    Solution: Added critical initialization call in main.cpp:

    #include <QtWebEngine/QtWebEngine>
    
    int main(int argc, char *argv[]) {
        // CRITICAL: Initialize QtWebEngine before QApplication
        QtWebEngine::initialize();
    
        QApplication app(argc, argv);
        // ... rest of code
    }

    Impact: Resolved 100% of QML engine crashes. This single line prevents all QtWebEngine initialization failures.

    Patch: 0007-add-qtwebengine-initialize-fix.patch


    Challenge 2: SingleApplication Threading Incompatibility 🔥 CRITICAL

    Problem: System libsingleapplication-dev v3.3.4 caused segmentation faults when used with QQmlApplicationEngine.

    Investigation:

    # Test with system library:
    sudo apt install libsingleapplication-dev
    # Build and run: Segmentation fault
    
    # Test without SingleApplication:
    # Remove from CMakeLists.txt: Works perfectly

    Root Cause: System library sets up threading context incompatible with Qt5 QML engine initialization. The library uses internal threading mechanisms that conflict with QQmlApplicationEngine’s event loop.

    Solution: Custom CompatibleSingleApp implementation. This is also to replace one of the bundled submodules that recently modified its MIT license into a dubious license that could be incompatible for Debian DFSG guidelines. See https://github.com/itay-grudev/SingleApplication/issues/210

    • Pure QApplication subclass
    • IPC via QLocalSocket/QLocalServer
    • No threading conflicts
    • Full single-instance functionality

    Implementation (compatible_singleapp.h):

    #ifndef COMPATIBLE_SINGLEAPP_H
    #define COMPATIBLE_SINGLEAPP_H
    
    #include <QApplication>
    #include <QLocalServer>
    #include <QLocalSocket>
    
    class CompatibleSingleApp : public QApplication {
        Q_OBJECT
    
    public:
        CompatibleSingleApp(int &argc, char **argv, const QString &appId);
        ~CompatibleSingleApp();
    
        bool isPrimary() const { return m_isPrimary; }
        bool sendMessage(const QString &message);
    
    signals:
        void receivedMessage(const QString &message);
    
    private slots:
        void handleNewConnection();
    
    private:
        bool m_isPrimary;
        QLocalServer *m_server;
        QString m_socketName;
    };
    
    #endif

    Implementation (compatible_singleapp.cpp):

    #include "compatible_singleapp.h"
    #include <QLocalSocket>
    #include <QCryptographicHash>
    
    CompatibleSingleApp::CompatibleSingleApp(int &argc, char **argv, const QString &appId)
        : QApplication(argc, argv), m_isPrimary(false), m_server(nullptr) {
    
        // Generate unique socket name
        m_socketName = QString("stremio-") +
            QString::fromUtf8(QCryptographicHash::hash(appId.toUtf8(),
                                                         QCryptographicHash::Sha256).toHex().left(16));
    
        // Try to connect to existing instance
        QLocalSocket socket;
        socket.connectToServer(m_socketName);
    
        if (socket.waitForConnected(500)) {
            // Another instance is running
            m_isPrimary = false;
            socket.disconnectFromServer();
            return;
        }
    
        // We're the primary instance
        m_isPrimary = true;
    
        // Create server for IPC
        m_server = new QLocalServer(this);
        QLocalServer::removeServer(m_socketName);
    
        if (m_server->listen(m_socketName)) {
            connect(m_server, &QLocalServer::newConnection,
                    this, &CompatibleSingleApp::handleNewConnection);
        }
    }
    
    CompatibleSingleApp::~CompatibleSingleApp() {
        if (m_server) {
            m_server->close();
            QLocalServer::removeServer(m_socketName);
        }
    }
    
    bool CompatibleSingleApp::sendMessage(const QString &message) {
        if (m_isPrimary) return false;
    
        QLocalSocket socket;
        socket.connectToServer(m_socketName);
    
        if (!socket.waitForConnected(1000)) return false;
    
        QByteArray data = message.toUtf8();
        socket.write(data);
        socket.waitForBytesWritten();
        socket.disconnectFromServer();
    
        return true;
    }
    
    void CompatibleSingleApp::handleNewConnection() {
        QLocalSocket *socket = m_server->nextPendingConnection();
    
        if (socket) {
            connect(socket, &QLocalSocket::readyRead, this, [this, socket]() {
                QByteArray data = socket->readAll();
                emit receivedMessage(QString::fromUtf8(data));
                socket->deleteLater();
            });
        }
    }

    Results:

    • ✅ Zero threading conflicts
    • ✅ Full single-instance behavior
    • ✅ Message passing between instances
    • ✅ Clean integration with QQmlApplicationEngine

    Patches:

    • 0008-add-compatible-singleapp-implementation.patch
    • 0009-remove-system-singleapplication-add-compatible.patch

    Challenge 3: QProcess Environment Variables for Node.js Server 🔥 CRITICAL

    Problem: Streaming server failed to start with cryptic error:

    server-crash 0 null
    TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
        at Object.join (node:path:1292:7)

    Investigation:

    # Manual server test works:
    $ /usr/bin/node /usr/share/stremio/server.js
    EngineFS server started at http://127.0.0.1:11470
    
    # But QProcess launch fails:
    timeout 15s stremio
    # Error: server-crash 0 null

    Root Cause: QProcess does not inherit environment variables by default. Node.js server.js requires:

    • HOME – for configuration directory (~/.stremio-server)
    • USER – for process identification
    • PWD – for relative path resolution

    Solution: Explicit environment setup in stremioprocess.cpp:

    void Process::start(QStringList args) {
        // Set up environment variables for Node.js server
        QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    
        // Ensure essential environment variables are set for server.js
        if (!env.contains("HOME")) {
            env.insert("HOME", QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
        }
        if (!env.contains("USER")) {
            env.insert("USER", qgetenv("USER"));
        }
        if (!env.contains("PWD")) {
            env.insert("PWD", QDir::currentPath());
        }
    
        this->setProcessEnvironment(env);
    
        // Now start the process
        QProcess::start(this->program(), args);
    }

    Verification:

    # After fix:
    $ timeout 15s build/stremio 2>&1 | grep -A 5 "hls executables"
    hls executables located -> { ffmpeg: '/usr/bin/ffmpeg', ffsplit: null }
    Using app path -> /home/user/.stremio-server
    Enabling casting...
    Discovery of new external device "mpv" - MPV
    EngineFS server started at http://127.0.0.1:11470

    Impact: Complete resolution of streaming functionality. Users can now stream media via BitTorrent, use casting, and access all server features.

    Patch: 0011-fix-qprocess-environment-for-server-launch.patch


    Challenge 4: System Tray Widget Creation Timing

    Problem: Warning on startup:

    QWidget: Cannot create a QWidget without QApplication

    Root Cause: SystemTray widget created before QML engine fully initialized.

    Solution: Delayed creation until after engine->load() completes:

    // main.cpp
    QQmlApplicationEngine *engine = new QQmlApplicationEngine();
    engine->load(QUrl("qrc:/main.qml"));
    
    // NOW create system tray (after QML loaded)
    SystemTray *tray = new SystemTray(&app);

    Result: Clean startup without widget warnings.


    Build System Architecture: Dual Build Support

    The project maintains two parallel build systems for flexibility:

    CMake System (Primary)

    Used by release.makefile and package builds:

    # CMakeLists.txt
    cmake_minimum_required(VERSION 3.16)
    project(stremio)
    
    set(CMAKE_CXX_STANDARD 14)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    
    find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets Qml Quick WebEngine DBus)
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(MPV REQUIRED mpv)
    pkg_check_modules(OPENSSL REQUIRED openssl)
    
    # Sources including CompatibleSingleApp
    set(SOURCES
        main.cpp
        compatible_singleapp.cpp
        stremioprocess.cpp
        # ... other sources
    )
    
    # Headers for MOC
    set(HEADERS
        mainapplication.h
        compatible_singleapp.h
        stremioprocess.h
        # ... other headers
    )
    
    add_executable(stremio ${SOURCES} ${HEADERS} resources.qrc)
    
    target_link_libraries(stremio
        Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Qml Qt5::Quick Qt5::WebEngine Qt5::DBus
        ${MPV_LIBRARIES}
        ${OPENSSL_LIBRARIES}
    )
    
    install(TARGETS stremio DESTINATION bin)

    Build command:

    QT_DEFAULT_MAJOR_VERSION=5 make -f release.makefile
    # Result: 293KB optimized binary

    qmake System (Legacy)

    Used for manual builds and development:

    # stremio.pro
    QT += core gui widgets qml quick webengine dbus
    CONFIG += c++14
    
    SOURCES += \
        main.cpp \
        compatible_singleapp.cpp \
        stremioprocess.cpp \
        # ... other sources
    
    HEADERS += \
        mainapplication.h \
        compatible_singleapp.h \
        stremioprocess.h \
        # ... other headers
    
    RESOURCES += resources.qrc
    
    # System libraries
    unix:!macx {
        CONFIG += link_pkgconfig
        PKGCONFIG += mpv openssl
    }
    
    target.path = /usr/bin
    INSTALLS += target

    Build command:

    QT_SELECT=5 qmake
    QT_SELECT=5 make
    # Result: 278KB optimized binary

    Both systems produce working binaries with 100% system libraries.


    Debian Packaging: The Proper Way

    Package Structure

    stremio (4.4.169+dfsg-1):

    debian/
    ├── changelog                    # Version history with ITP closure
    ├── control                      # Dependencies and package metadata
    ├── copyright                    # GPL-3.0+ licensing details
    ├── rules                        # Build instructions (dh-based)
    ├── patches/                     # Quilt patches for system integration
    │   ├── 0001-Fix-server.js-path-for-FHS-compliance.patch
    │   ├── 0002-disable-server-download.patch
    │   ├── 0004-minimal-qthelper-integration.patch
    │   ├── 0005-cmake-system-libraries-v4.4.169.patch
    │   ├── 0007-add-qtwebengine-initialize-fix.patch
    │   ├── 0008-add-compatible-singleapp-implementation.patch
    │   ├── 0009-remove-system-singleapplication-add-compatible.patch
    │   ├── 0010-fix-qmake-install-paths.patch
    │   └── 0011-fix-qprocess-environment-for-server-launch.patch
    ├── stremio.desktop              # Desktop integration
    ├── stremio.install              # File installation rules
    ├── watch                        # Upstream version monitoring
    └── source/
        └── format                   # 3.0 (quilt) format

    Key debian/control sections:

    Source: stremio
    Section: video
    Priority: optional
    Maintainer: Juan Manuel Méndez Rey <vejeta@gmail.com>
    Build-Depends:
        debhelper-compat (= 13),
        cmake,
        qtbase5-dev,
        qt5-qmake,
        qt5-qmake-bin,
        qtdeclarative5-dev,
        qtwebengine5-dev,
        qttools5-dev,
        qml-module-qtwebchannel,
        qml-module-qt-labs-platform,
        qml-module-qtwebengine,
        qml-module-qtquick-dialogs,
        qml-module-qtquick-controls,
        qml-module-qt-labs-settings,
        qml-module-qt-labs-folderlistmodel,
        libmpv-dev,
        libssl-dev,
        nodejs,
        npm,
        pkg-kde-tools
    Standards-Version: 4.6.2
    Homepage: https://www.stremio.com/
    Vcs-Git: https://salsa.debian.org/mendezr/stremio.git
    Vcs-Browser: https://salsa.debian.org/mendezr/stremio
    
    Package: stremio
    Architecture: amd64
    Depends: ${shlibs:Depends}, ${misc:Depends},
             nodejs,
             mpv,
             librsvg2-2,
             qml-module-qtwebengine,
             qml-module-qtwebchannel,
             qml-module-qt-labs-platform,
             qml-module-qtquick-controls,
             qml-module-qtquick-dialogs,
             qml-module-qt-labs-settings,
             qml-module-qt-labs-folderlistmodel,
             qtbase5-dev-tools
    Description: Modern media center for streaming video content
     Stremio is a video streaming application that aggregates content from
     various sources. It features a modern Qt5/QML interface with support
     for add-ons, local playback via MPV, and integration with streaming
     services.
     .
     This package provides the desktop client with GPL-licensed components.

    Build process:

    # Development build
    QT_DEFAULT_MAJOR_VERSION=5 dpkg-buildpackage -us -uc
    
    # Package build with signature
    QT_DEFAULT_MAJOR_VERSION=5 dpkg-buildpackage -sa
    
    # Clean environment build
    sudo pbuilder build ../stremio_4.4.169+dfsg-1.dsc

    stremio-server Package (Independent Versioning)

    Critical Decision: Server uses independent version number tracking its upstream:

    Source: stremio-server
    Section: non-free/video
    Version: 4.20.12-1
    
    Package: stremio-server
    Architecture: all
    Depends: ${misc:Depends}, nodejs (>= 12)
    Description: BitTorrent streaming server for Stremio (proprietary)
     Proprietary streaming server component providing BitTorrent support,
     HLS transcoding, and casting functionality for Stremio.
     .
     Version 4.20.12 corresponds to upstream server.js release.

    Why independent versioning?

    • Server has different release cycle than client
    • Upstream server.js updates independently (v4.20.x)
    • Client updates independently (v4.4.x)
    • Follows industry practice: VS Code, Docker Desktop, Firefox ESR

    debian/copyright documents source:

    Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
    Upstream-Name: stremio-server
    Source: https://dl.strem.io/server/v4.20.12/desktop/server.js
    Comment: Pre-downloaded server.js included in source package to comply
     with Debian Policy prohibiting network access during builds.

    Beyond Debian: The Wolfi Contribution

    While working on Debian packaging, I also contributed Stremio packages to Wolfi Linux, the security-focused distribution used by Chainguard. This involved:

    • Melange build files: Cloud-native package format
    • Security hardening: ASLR, stack protection, RELRO
    • OSI license compliance: GPL components only (no proprietary server, the same server.js we separated in a non-free package for Debian)
    • Reproducible builds: Hermetic build environment

    Melange configuration example:

    package:
      name: stremio
      version: 4.4.169
      epoch: 0
      description: Modern media center for video streaming
      license: GPL-3.0-or-later
    
    environment:
      contents:
        packages:
          - qt5-qtbase-dev
          - qt5-qtdeclarative-dev
          - qt5-qtwebengine-dev
          - mpv-dev
          - openssl-dev
    
    pipeline:
      - uses: cmake/configure
      - uses: cmake/build
      - uses: cmake/install
    
    subpackages:
      - name: stremio-doc
        description: Documentation for stremio

    I used this parallel effort as an exercise to learn how different distributions do proper packaging across different distribution ecosystems.

    Pull Request:
    https://github.com/wolfi-dev/os/pull/69098
    GitHub Gists with examples of usage:
    https://gist.github.com/vejeta/859f100ef74b87eadf7f7541ead2a2b1


    The Distribution Challenge: GitHub-Powered APT Repository

    Official Debian inclusion takes time—months or years of review, testing, and refinement. Meanwhile, users needed a solution now. Traditional approaches like hosting packages on a personal server would create bandwidth and maintenance problems.

    The solution: Modern APT repository hosting using GitHub infrastructure.

    Architecture Overview

    ┌─────────────────────────────────────────────────────────┐
    │              Canonical Sources (Salsa)                  │
    │  https://salsa.debian.org/mendezr/stremio               │
    │  https://salsa.debian.org/mendezr/stremio-server        │
    └────────────────────┬────────────────────────────────────┘
                         │
                         │ Instant Webhook + Weekly Cron
                         ▼
    ┌─────────────────────────────────────────────────────────┐
    │          GitHub Repository (Build System)               │
    │      https://github.com/vejeta/stremio-debian           │
    │                                                          │
    │  • stremio-client/ (git submodule → Salsa)             │
    │  • stremio-server/ (git submodule → Salsa)             │
    │  • .github/workflows/                                   │
    │      - build-and-release.yml                            │
    │      - deploy-repository.yml                            │
    │      - sync-from-salsa.yml                              │
    │  • repository-scripts/                                  │
    │      - generate-apt-repo.sh                             │
    │      - sign-repository.sh                               │
    └────────────────────┬────────────────────────────────────┘
                         │
           ┌─────────────┴─────────────┐
           │                           │
           ▼                           ▼
    ┌──────────────┐          ┌────────────────┐
    │GitHub Releases│         │ GitHub Pages   │
    │              │          │                │
    │ Binary .debs │          │ APT Repository │
    │ Source files │          │ Signed metadata│
    │ Build logs   │          │ Global CDN     │
    └──────────────┘          └────────────────┘
                                       │
                                       ▼
                              ┌────────────────┐
                              │ Custom Domain  │
                              │ debian.vejeta  │
                              │     .com       │
                              └────────────────┘

    Multi-Distribution Strategy: Matrix Builds

    The Critical Discovery: Packages built on one Debian release don’t work on others due to ABI dependencies.

    Problem Example:

    # Package built on Debian Bookworm:
    $ dpkg -I stremio_4.4.169+dfsg-1_amd64.deb | grep Depends
    Depends: qtdeclarative-abi-5-15-8
    
    # But Debian Sid/Kali have:
    $ apt-cache show qtdeclarative5-dev | grep Provides
    Provides: qtdeclarative-abi-5-15-15
    
    # Result: Installation fails on Sid/Kali

    Solution: Build packages in native containers for each distribution:

    # .github/workflows/build-and-release.yml
    jobs:
      build-stremio-client:
        name: Build stremio (main/free) - ${{ matrix.distro }}
        runs-on: ubuntu-latest
        strategy:
          matrix:
            distro: [trixie, bookworm, sid, noble]
            include:
              - distro: trixie
                suite: stable
                os_type: debian
              - distro: bookworm
                suite: oldstable
                os_type: debian
              - distro: sid
                suite: unstable
                os_type: debian
              - distro: noble
                suite: lts
                os_type: ubuntu
        container:
          image: ${{ matrix.os_type }}:${{ matrix.distro }}
          options: --privileged
    
        steps:
          - name: Install build dependencies
            run: |
              apt-get update
              apt-get install -y \
                git git-buildpackage pristine-tar \
                debhelper-compat cmake \
                qtbase5-dev qt5-qmake qt5-qmake-bin \
                qtdeclarative5-dev qtwebengine5-dev qttools5-dev \
                qml-module-qtwebchannel qml-module-qt-labs-platform \
                qml-module-qtwebengine qml-module-qtquick-dialogs \
                qml-module-qtquick-controls qml-module-qt-labs-settings \
                qml-module-qt-labs-folderlistmodel \
                libmpv-dev libssl-dev nodejs npm pkg-kde-tools \
                devscripts lintian dpkg-dev fakeroot librsvg2-bin
    
          - name: Checkout repository with submodules
            uses: actions/checkout@v4
            with:
              fetch-depth: 0
              submodules: recursive
    
          - name: Configure git for gbp
            run: |
              git config --global user.email "vejeta@gmail.com"
              git config --global user.name "Juan Manuel Méndez Rey"
              git config --global --add safe.directory '*'
    
          - name: Create upstream tarball
            working-directory: stremio-client
            run: |
              VERSION=$(dpkg-parsechangelog -S Version | cut -d- -f1)
    
              # Try pristine-tar first
              if git rev-parse --verify pristine-tar >/dev/null 2>&1; then
                pristine-tar checkout ../stremio_${VERSION}.orig.tar.xz 2>/dev/null || \
                pristine-tar checkout ../stremio_${VERSION}.orig.tar.gz 2>/dev/null
              fi
    
              # Fallback to upstream tag
              if [ ! -f ../stremio_${VERSION}.orig.tar.* ]; then
                UPSTREAM_TAG=$(git tag -l "upstream/*" | grep -E "${VERSION%+*}" | tail -1)
                git archive --format=tar --prefix=stremio-${VERSION%+*}/ $UPSTREAM_TAG | \
                  xz > ../stremio_${VERSION}.orig.tar.xz
              fi
    
          - name: Build packages (source + binary)
            working-directory: stremio-client
            run: |
              QT_DEFAULT_MAJOR_VERSION=5 dpkg-buildpackage -us -uc -sa
    
          - name: Run lintian checks
            continue-on-error: true
            run: |
              lintian --info --display-info --pedantic stremio-client/../*.deb || true
    
          - name: Smoke test package (Ubuntu only)
            if: matrix.os_type == 'ubuntu'
            continue-on-error: true
            run: |
              echo "=== Ubuntu Package Smoke Test ==="
              apt install -y ./stremio-client/../*.deb || true
              which stremio && echo "✓ Binary found" || echo "✗ Binary not found"
              ldd /usr/bin/stremio | grep -E "(libQt5|libmpv|libcrypto)" || true
              export QT_QPA_PLATFORM=offscreen
              export QTWEBENGINE_DISABLE_SANDBOX=1
              timeout 10s stremio 2>&1 || echo "✓ GUI test completed"
    
          - name: Collect build artifacts
            run: |
              mkdir -p artifacts/stremio-client-${{ matrix.distro }}
    
              # Rename .deb with distro suffix
              for deb in stremio-client/../*.deb; do
                if [ -f "$deb" ]; then
                  filename=$(basename "$deb")
                  newname="${filename%.deb}-${{ matrix.distro }}.deb"
                  mv "$deb" "artifacts/stremio-client-${{ matrix.distro }}/$newname"
                fi
              done
    
              # Move other files
              mv stremio-client/../*.dsc artifacts/stremio-client-${{ matrix.distro }}/ 2>/dev/null || true
              mv stremio-client/../*.tar.* artifacts/stremio-client-${{ matrix.distro }}/ 2>/dev/null || true
              mv stremio-client/../*.buildinfo artifacts/stremio-client-${{ matrix.distro }}/ 2>/dev/null || true
              mv stremio-client/../*.changes artifacts/stremio-client-${{ matrix.distro }}/ 2>/dev/null || true
    
          - name: Upload build artifacts
            uses: actions/upload-artifact@v4
            with:
              name: stremio-client-packages-${{ matrix.distro }}
              path: artifacts/stremio-client-${{ matrix.distro }}/*.deb
              retention-days: 30

    Result: Each distribution gets packages with correct native dependencies:

    • debian:trixieqtdeclarative-abi-5-15-15
    • debian:bookwormqtdeclarable-abi-5-15-8
    • debian:sidqtdeclarable-abi-5-15-17
    • ubuntu:noble → Ubuntu-specific Qt5 dependencies

    APT Repository Generation

    Script: repository-scripts/generate-apt-repo.sh

    #!/bin/bash
    set -e
    
    PACKAGE_DIR="$1"    # packages/trixie/main
    REPO_DIR="$2"       # debian-repo
    SUITE="$3"          # trixie
    COMPONENT="$4"      # main
    
    echo "Generating APT repository for $SUITE/$COMPONENT"
    
    # Create directory structure
    mkdir -p "$REPO_DIR/dists/$SUITE/$COMPONENT/binary-amd64"
    mkdir -p "$REPO_DIR/pool/$SUITE/$COMPONENT"
    
    # Copy packages to pool
    if [ -d "$PACKAGE_DIR" ] && [ "$(ls -A $PACKAGE_DIR/*.deb 2>/dev/null)" ]; then
        cp "$PACKAGE_DIR"/*.deb "$REPO_DIR/pool/$SUITE/$COMPONENT/"
    fi
    
    # Generate Packages file
    cd "$REPO_DIR"
    dpkg-scanpackages --arch amd64 "pool/$SUITE/$COMPONENT" /dev/null > \
        "dists/$SUITE/$COMPONENT/binary-amd64/Packages"
    
    # Compress Packages file
    gzip -9 -k "dists/$SUITE/$COMPONENT/binary-amd64/Packages"
    
    echo "✓ Repository generated for $SUITE/$COMPONENT"

    APT Repository Structure:

    debian-repo/
    ├── dists/
    │   ├── trixie/
    │   │   ├── main/
    │   │   │   └── binary-amd64/
    │   │   │       ├── Packages
    │   │   │       └── Packages.gz
    │   │   ├── non-free/
    │   │   │   └── binary-amd64/
    │   │   │       ├── Packages
    │   │   │       └── Packages.gz
    │   │   ├── Release
    │   │   └── InRelease (GPG signed)
    │   ├── bookworm/
    │   │   └── [same structure]
    │   ├── sid/
    │   │   └── [same structure]
    │   └── noble/
    │       └── [same structure]
    ├── pool/
    │   ├── trixie/
    │   │   ├── main/
    │   │   │   └── stremio_4.4.169+dfsg-1_amd64.deb
    │   │   └── non-free/
    │   │       └── stremio-server_4.20.12-1_all.deb
    │   ├── bookworm/
    │   │   └── [same structure]
    │   ├── sid/
    │   │   └── [same structure]
    │   └── noble/
    │       └── [same structure]
    └── key.gpg

    Release File Generation with Checksums

    Workflow excerpt (.github/workflows/deploy-repository.yml):

    - name: Update Release files for all distributions
      run: |
        cd debian-repo
    
        update_release() {
          local SUITE=$1
    
          cat > dists/$SUITE/Release << EOF
        Origin: Stremio Debian Repository
        Label: Stremio
        Suite: $SUITE
        Codename: $SUITE
        Components: main non-free
        Architectures: amd64
        Description: Unofficial Debian packages for Stremio media center ($SUITE)
        Date: $(date -R -u)
        EOF
    
          # Add MD5Sum checksums
          echo "MD5Sum:" >> dists/$SUITE/Release
          find dists/$SUITE -type f ! -name "Release*" | while read file; do
              relative_path="${file#dists/$SUITE/}"
              md5=$(md5sum "$file" | awk '{print $1}')
              size=$(stat -c%s "$file")
              printf " %s %8d %s\n" "$md5" "$size" "$relative_path" >> dists/$SUITE/Release
          done
    
          # Add SHA1 checksums
          echo "SHA1:" >> dists/$SUITE/Release
          find dists/$SUITE -type f ! -name "Release*" | while read file; do
              relative_path="${file#dists/$SUITE/}"
              sha1=$(sha1sum "$file" | awk '{print $1}')
              size=$(stat -c%s "$file")
              printf " %s %8d %s\n" "$sha1" "$size" "$relative_path" >> dists/$SUITE/Release
          done
    
          # Add SHA256 checksums
          echo "SHA256:" >> dists/$SUITE/Release
          find dists/$SUITE -type f ! -name "Release*" | while read file; do
              relative_path="${file#dists/$SUITE/}"
              sha256=$(sha256sum "$file" | awk '{print $1}')
              size=$(stat -c%s "$file")
              printf " %s %8d %s\n" "$sha256" "$size" "$relative_path" >> dists/$SUITE/Release
          done
        }
    
        # Generate for all distributions
        update_release trixie
        update_release bookworm
        update_release sid
        update_release noble

    GPG Signing

    Script: repository-scripts/sign-repository.sh

    #!/bin/bash
    set -e
    
    REPO_DIR="$1"
    SUITE="$2"
    GPG_KEY_ID="$3"
    
    cd "$REPO_DIR/dists/$SUITE"
    
    # Clear sign Release file to create InRelease
    gpg --default-key "$GPG_KEY_ID" --clearsign --output InRelease Release
    
    # Detached signature for Release.gpg
    gpg --default-key "$GPG_KEY_ID" --armor --detach-sign --output Release.gpg Release
    
    echo "✓ Signed repository for $SUITE"

    GitHub Pages Deployment

    Workflow (simplified):

    - name: Setup Pages
      uses: actions/configure-pages@v4
    
    - name: Upload artifact
      uses: actions/upload-pages-artifact@v3
      with:
        path: debian-repo
    
    - name: Deploy to GitHub Pages
      uses: actions/deploy-pages@v4

    Result: APT repository served at https://debian.vejeta.com/ with:

    • ✅ Global CDN (CloudFlare)
    • ✅ HTTPS encryption
    • ✅ Unlimited bandwidth
    • ✅ Zero hosting costs
    • ✅ 99.9%+ uptime

    Critical Lessons Learned: Patch Development Best Practices

    During this project, I made significant efficiency mistakes in patch development. Here’s what I learned:

    The Inefficiency Problem

    What I did (5+ iterations of patch rework):

    1. Modified source files directly in working repository
    2. Generated patches from modified state
    3. Patches failed on clean upstream
    4. Repeated entire process multiple times

    Impact: ~70% wasted time in patch development

    The Correct Approach

    Efficient patch development workflow:

    # Step 1: Clean upstream baseline
    git clone --branch v4.4.169 https://github.com/Stremio/stremio-shell.git /tmp/patch-test
    cd /tmp/patch-test
    
    # Step 2: Analyze dependencies BEFORE making changes
    echo "=== Mapping file dependencies ==="
    grep -r "#include" *.cpp *.h | grep -v "Qt\|std"
    grep -r "class.*:" *.h
    grep -r "Q_OBJECT" *.h
    
    # Step 3: Make ONE fix at a time
    vim main.cpp  # Add QtWebEngine::initialize()
    git diff > /tmp/0007-qtwebengine-fix.patch
    
    # Step 4: Test patch application
    git checkout .
    patch -p1 < /tmp/0007-qtwebengine-fix.patch
    mkdir build && cd build && cmake .. && make
    
    # Step 5: If successful, continue to next fix
    # If failed, refine current patch before moving on

    Pre-Patch Analysis Template

    Before creating patches, ALWAYS complete this analysis:

    ## Files to Modify
    - [ ] main.cpp - QtWebEngine initialization
    - [ ] mainapplication.h - class definitions
    - [ ] CMakeLists.txt - build system
    - [ ] compatible_singleapp.h/cpp - new custom implementation
    
    ## Dependency Chain
    1. main.cpp includes → mainapplication.h
    2. mainapplication.h includes → singleapplication.h (to be replaced)
    3. CMakeLists.txt references → SingleApplication (to be removed)
    4. Qt MOC processes → Q_OBJECT classes (check for conflicts)
    
    ## Build Test Plan
    1. [ ] Clean cmake build
    2. [ ] Dependency verification (ldd)
    3. [ ] Runtime functionality test
    4. [ ] Package build test (dpkg-buildpackage)

    Validation Before «Ready» Declaration

    NEVER declare patches ready without:

    # MANDATORY validation workflow
    mkdir /tmp/patch-validation
    cd /tmp/patch-validation
    git clone --branch v4.4.169 <upstream-url> .
    
    # Apply ALL patches
    export QUILT_PATCHES=debian/patches
    quilt push -a || { echo "FAIL: Patch application"; exit 1; }
    
    # Complete build test
    mkdir build && cd build
    cmake .. && make || { echo "FAIL: Build"; exit 1; }
    
    # Package build test
    cd .. && dpkg-buildpackage -us -uc || { echo "FAIL: Package"; exit 1; }
    
    # Dependency check
    ldd build/stremio | grep -E "(libQt5|libmpv|libcrypto)"
    
    # ONLY NOW declare "patches ready"
    echo "✅ Validated and ready for production"

    This workflow prevents the «ready → fails → rework» cycle that wastes development time.


    Production Validation: Comprehensive Testing

    Isolated Environment Validation

    Test setup:

    # Create pristine environment
    mkdir /tmp/stremio-patch-validation
    cd /tmp/stremio-patch-validation
    git clone --branch v4.4.169 https://github.com/Stremio/stremio-shell.git .
    cp -r /path/to/debian .
    
    # Apply all patches
    export QUILT_PATCHES=debian/patches
    quilt push -a
    # Result: All 6 patches applied successfully
    
    # Test CMake build
    mkdir build && cd build
    cmake .. -DQT_DEFAULT_MAJOR_VERSION=5
    make -j$(nproc)
    # Result: 293KB binary with 100% system libraries
    
    # Test release.makefile
    cd .. && QT_DEFAULT_MAJOR_VERSION=5 make -f release.makefile
    # Result: Complete success including icon generation
    
    # Verify dependencies
    ldd build/stremio | head -5
    # Output:
    #   libQt5WebEngine.so.5 => /lib/x86_64-linux-gnu/libQt5WebEngine.so.5
    #   libQt5DBus.so.5 => /lib/x86_64-linux-gnu/libQt5DBus.so.5
    #   libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3
    #   libmpv.so.2 => /lib/x86_64-linux-gnu/libmpv.so.2

    Verification results:

    • ✅ Binary builds successfully (293KB)
    • ✅ GUI loads and displays
    • ✅ Single-instance behavior works
    • ✅ Streaming server starts (port 11470 responds)
    • ✅ System library integration complete
    • ✅ No crashes or threading issues

    Runtime Validation

    Complete functionality test:

    # Launch application
    ./build/stremio 2>&1 | tee /tmp/stremio-runtime.log
    
    # Verify server startup (first 15 seconds)
    timeout 15s ./build/stremio 2>&1 | grep -E "(server|streaming|port)"
    # Output:
    #   hls executables located -> { ffmpeg: '/usr/bin/ffmpeg', ffsplit: null }
    #   Using app path -> /home/user/.stremio-server
    #   Enabling casting...
    #   EngineFS server started at http://127.0.0.1:11470
    
    # Test server endpoint
    curl -s http://127.0.0.1:11470 && echo "✓ Server responding"
    
    # Test single-instance behavior
    ./build/stremio &
    PID1=$!
    sleep 2
    ./build/stremio   # Should detect first instance and exit
    wait $PID1

    User Experience: Installation Simplified

    I wanted other Debian users to have the chance to install these packages built with the highest standards as soon as possible while the package is still being reviewed by Debian Developers. My solution was to create a repository and through GitHub Actions, pull the sources of the packages from salsa.debian.org, build them automatically, make a release and provide a Debian repository built with GitHub Pages, so Debian users will have 99% of availability to fetch them.

    The end result is a one-command installation for users:

    For Debian Trixie (13 – current stable)

    wget -qO - https://debian.vejeta.com/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/stremio-debian.gpg
    echo "deb [signed-by=/usr/share/keyrings/stremio-debian.gpg] https://debian.vejeta.com trixie main non-free" | sudo tee /etc/apt/sources.list.d/stremio.list
    sudo apt update
    sudo apt install stremio stremio-server

    For Debian Sid / Kali Linux

    wget -qO - https://debian.vejeta.com/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/stremio-debian.gpg
    echo "deb [signed-by=/usr/share/keyrings/stremio-debian.gpg] https://debian.vejeta.com sid main non-free" | sudo tee /etc/apt/sources.list.d/stremio.list
    sudo apt update
    sudo apt install stremio stremio-server

    For Ubuntu 24.04 LTS (Noble) – EXPERIMENTAL

    wget -qO - https://debian.vejeta.com/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/stremio-debian.gpg
    echo "deb [signed-by=/usr/share/keyrings/stremio-debian.gpg] https://debian.vejeta.com noble main non-free" | sudo tee /etc/apt/sources.list.d/stremio.list
    sudo apt update
    sudo apt install stremio stremio-server

    Note: Ubuntu support is experimental with automated builds but limited manual testing. Community feedback welcome.


    Closing the Loop: Updating Documentation

    With a working solution deployed, I returned to where it all started—the documentation. I submitted a comprehensive pull request to update the original DEBIAN.md file I had contributed years earlier.

    The PR adds:

    • ✅ APT repository installation (new recommended method)
    • ✅ Complete dependency lists
    • ✅ Modern security practices (proper GPG key management)
    • ✅ Multi-distribution support (Debian + derivatives)
    • ✅ Maintained build instructions (preserved for developers)

    Community Impact

    Within hours of submitting the PR, I commented on 10+ existing GitHub issues where users had reported installation problems. The response was immediate and positive—users could finally install Stremio without compilation headaches.


    Technical Achievements Summary

    Packaging Excellence

    • Zero bundled dependencies: 100% Debian system libraries
    • FHS compliance: Proper /usr installation paths
    • License separation: GPL client (main) + proprietary server (non-free)
    • Policy compliance: Lintian-clean packaging
    • Independent versioning: Client v4.4.169 + Server v4.20.12

    Technical Solutions

    • QtWebEngine initialization fix: Single line prevents all QML crashes
    • CompatibleSingleApp: Custom thread-safe single-instance implementation
    • QProcess environment: Proper Node.js environment setup for streaming server
    • Dual build systems: CMake (293KB) and qmake (278KB) both working
    • System library integration: MPV, Qt5, OpenSSL, all QML modules

    Infrastructure

    • Multi-distribution builds: Trixie, Bookworm, Sid, Noble (experimental)
    • Automated CI/CD: GitHub Actions with matrix strategy
    • APT repository: GitHub Pages with global CDN
    • GPG signing: Cryptographically signed packages and metadata
    • Zero hosting costs: Unlimited bandwidth via GitHub
    • Download statistics: Built-in analytics via GitHub Releases

    Build Statistics

    • Binary size: 293KB optimized (vs 424KB debug)
    • Build time: ~10 minutes per distribution
    • Total distributions: 4 (3 Debian + 1 Ubuntu experimental)
    • Packages per release: 8 .deb files (4 distros × 2 packages)
    • Repository size: ~21 MB per release

    Looking Forward

    Immediate Goals

    Debian Submission Progress (ITP #943703):

    • [x] Source packages created following Debian Policy
    • [x] Lintian-clean packaging
    • [x] 100% system libraries
    • [x] FHS compliance
    • [x] Copyright file with complete licensing
    • [x] Watch files for upstream monitoring
    • [x] git-buildpackage workflow
    • [x] Packages hosted on Salsa
    • [x] ITP bug filed
    • [x] Preliminary Debian Developer review
    • [ ] Sponsorship obtained
    • [ ] Upload to Debian NEW queue

    Timeline: Submission planned for Q1 2025

    Professional Applications

    This work directly supports my goal of becoming an official Debian Package Maintainer. This could also serve as a guide for others to get experience with:

    • Packaging expertise: Modern Debian packaging workflows with complex applications
    • DevOps proficiency: CI/CD pipeline design and GitHub Actions automation
    • Problem-solving skills: Deep debugging (QtWebEngine, threading, environment issues)
    • Community engagement: Solving real user problems at scale
    • Infrastructure design: Scalable, cost-effective distribution systems
    • Documentation: Comprehensive technical writing for diverse audiences

    Future Evolution

    The architecture proved so successful that I’m considering replicating it for other packaging projects. The pattern of using GitHub infrastructure for APT repository hosting could benefit many projects struggling with distribution challenges.

    Potential applications:

    • Personal package repository for experimental Debian packages
    • Other media applications requiring complex Qt5/WebEngine setups
    • Cross-distribution packaging (Debian + Ubuntu + derivatives)

    Key Principles Reinforced

    This journey reinforced several fundamental principles:

    1. Documentation is Infrastructure

    Good documentation isn’t just text—it’s the foundation that enables user adoption and community growth. The original DEBIAN.md file evolved into a complete packaging and distribution solution.

    2. Packaging is Product Design

    How users install and maintain software is part of the user experience. Poor packaging creates friction; good packaging eliminates it. The difference between:

    • ❌ «Download, extract, install 15 dependencies, compile, copy files manually»
    • ✅ «apt install stremio»

    3. Modern Infrastructure Enables Scale

    By leveraging GitHub’s infrastructure (Actions, Pages, Releases), a single developer can provide enterprise-grade distribution infrastructure with zero operational overhead. This democratizes software distribution.

    4. Standards Enable Ecosystems

    Following Debian packaging standards meant the same packages work across multiple distributions (Debian, Ubuntu, Kali) and can integrate with the official Debian archive.

    5. Deep Technical Understanding Pays Off

    The critical fixes (QtWebEngine initialization, threading compatibility, environment variables) required deep understanding of:

    • Qt5 initialization order
    • QML engine threading model
    • QProcess environment inheritance
    • Node.js runtime requirements

    Surface-level knowledge wouldn’t have solved these problems.

    6. Proper Testing Prevents Rework

    The patch development lessons learned (70% time wasted on rework) demonstrate that upfront validation investment prevents significant downstream waste. Test against clean upstream early and often.

    7. Independent Versioning Respects Reality

    Using independent version numbers for stremio (4.4.169) and stremio-server (4.20.12) follows industry practice and accurately represents upstream development. Convenience versioning creates confusion.


    Acknowledgments

    • Stremio Team: For creating an excellent media center application
    • Debian Community: For packaging standards and infrastructure (Salsa)
    • GitHub: For free hosting, CI/CD, and unlimited bandwidth
    • Qt Project: For excellent cross-platform framework
    • Debian Developers (Arturo): For preliminary review and guidance on ITP #943703

    Technical Resources

    Source Repositories

    Upstream Projects

    Distribution Statistics

    • Repository Bandwidth: Unlimited (GitHub CDN)
    • Total Downloads: Tracked via GitHub Releases API
    • Uptime: 99.9%+ (GitHub SLA)
    • Build Success Rate: 100% (after fixes applied)

    Conclusion

    What started as a simple documentation contribution evolved into a comprehensive packaging and distribution solution. By combining traditional Debian packaging principles with modern CI/CD infrastructure, it’s possible to deliver professional-grade software distribution that scales globally.

    The journey from «how do I install this?» to «apt install stremio» represents more than technical progress—it’s about removing friction between great software and the people who want to use it.

    Sometimes the best solutions come full circle. Years after contributing installation documentation, I’ve returned to ensure that documentation describes a process that actually works reliably for everyone.

    The technical challenges (QtWebEngine initialization, threading compatibility, environment variables) required deep problem-solving and systematic debugging. The infrastructure challenges (multi-distribution builds, APT repository hosting, CI/CD automation) required modern DevOps practices and cloud-native thinking.

    But ultimately, this project is about enabling users. Every technical decision, every patch, every workflow optimization serves the goal of making Stremio accessible to Debian and Ubuntu users through a simple, reliable installation process.


    Part of ongoing contribution to become a Debian Package Maintainer

    If you found this article helpful, please consider:

    Last updated: October 30, 2025


    Appendix: Complete Command Reference

    Building from Source (Debian/Ubuntu)

    # Install build dependencies
    sudo apt install \
        git git-buildpackage pristine-tar \
        debhelper-compat cmake \
        qtbase5-dev qt5-qmake qt5-qmake-bin \
        qtdeclarative5-dev qtwebengine5-dev qttools5-dev \
        qml-module-qtwebchannel qml-module-qt-labs-platform \
        qml-module-qtwebengine qml-module-qtquick-dialogs \
        qml-module-qtquick-controls qml-module-qt-labs-settings \
        qml-module-qt-labs-folderlistmodel \
        libmpv-dev libssl-dev nodejs npm pkg-kde-tools \
        devscripts lintian dpkg-dev fakeroot librsvg2-bin
    
    # Clone repository
    git clone --recursive https://salsa.debian.org/mendezr/stremio.git
    cd stremio
    
    # Build with CMake
    mkdir build && cd build
    QT_DEFAULT_MAJOR_VERSION=5 cmake ..
    make -j$(nproc)
    
    # Or build with qmake
    QT_SELECT=5 qmake
    QT_SELECT=5 make -j$(nproc)
    
    # Or build package
    QT_DEFAULT_MAJOR_VERSION=5 dpkg-buildpackage -us -uc

    Testing Package Installation

    # Install package
    sudo dpkg -i ../stremio_*.deb
    
    # Fix dependencies if needed
    sudo apt install -f
    
    # Test binary
    stremio --version
    which stremio
    
    # Check dependencies
    ldd /usr/bin/stremio | grep -E "(libQt5|libmpv|libcrypto)"
    
    # Run application
    stremio

    Repository Management

    # Add GPG key
    wget -qO - https://debian.vejeta.com/key.gpg | \
        sudo gpg --dearmor -o /usr/share/keyrings/stremio-debian.gpg
    
    # Add repository (choose your distribution)
    echo "deb [signed-by=/usr/share/keyrings/stremio-debian.gpg] https://debian.vejeta.com trixie main non-free" | \
        sudo tee /etc/apt/sources.list.d/stremio.list
    
    # Update and install
    sudo apt update
    sudo apt install stremio stremio-server
    
    # Verify installation
    dpkg -L stremio
    systemctl --user status stremio-server  # If systemd service installed

    Debugging Runtime Issues

    # Run with debug output
    QT_DEBUG_PLUGINS=1 stremio
    
    # Run in headless mode (for testing)
    QT_QPA_PLATFORM=offscreen stremio
    
    # Disable WebEngine sandbox (for containers)
    QTWEBENGINE_DISABLE_SANDBOX=1 stremio
    
    # Check server process
    ps aux | grep server.js
    lsof -i :11470
    
    # Manual server test
    /usr/bin/node /usr/share/stremio/server.js
    
    # Test with gdb
    gdb --args stremio
    (gdb) run
    (gdb) bt  # If crash occurs

    End of Article


    Technical Depth: Production-grade implementation details
    Target Audience: Advanced developers, system administrators, Debian maintainers

  • Packaging Stremio for Debian: A Journey to 100% System Library Integration

    Packaging Stremio for Debian: A Journey to 100% System Library Integration

    Stremio for Debian: A Journey to 100% System Library Integration

    How I replaced every bundled dependency in a complex Qt5 application—and what I learned about patch development, threading bugs, and the art of debugging runtime crashes

    By Juan Manuel Méndez Rey

    Last Updated: October 3, 2025

    Tags: #debian #packaging #qt5 #technical-writing #system-libraries #debugging #free-software


    TL;DR

    I packaged Stremio for Debian by replacing 100% of its bundled dependencies (libmpv, Qt libraries, OpenSSL) with system libraries. Along the way, I debugged five critical issues: QtWebEngine initialization order, threading conflicts with SingleApplication, missing QML modules, Node.js environment variables in QProcess, and debhelper install file pitfalls. The real lesson? I repeated patch creation 5+ times because I tested against modified sources instead of clean upstream. This article shares both the technical solutions and the meta-lesson about efficient patch development workflow that could have saved me 70% of development time.

    Key Takeaway: When packaging complex applications, test your patches against pristine upstream at each step, not at the end.


    Package Status (October 2025)

    This article documents the technical work behind packaging Stremio for Debian. The package has achieved 100% system library integration and is currently:

    • Technical work: Complete and validated
    • ITP submitted: Under review by Debian Developer sponsor
    • Status: Awaiting upload approval
    • Repository: salsa.debian.org/mendezr/stremio

    This is a technical deep-dive into the challenges and solutions, not an announcement of package availability. The work continues through the Debian review process.


    Introduction

    When I set out to package Stremio—a popular media center application—for Debian, I had one clear goal: achieve 100% system library integration. No bundled dependencies, no git submodules, just clean integration with Debian’s ecosystem. What seemed like a straightforward build system migration turned into a deep dive into Qt5 threading models, runtime initialization order, and the subtle art of creating minimal, maintainable patches.

    This is the story of that journey, the technical challenges I faced, and—perhaps most importantly—the lessons I learned about efficient patch development that could have saved me days of rework.

    The Challenge: System Libraries or Bust

    Stremio’s upstream repository arrived with several bundled dependencies as git submodules:

    • libmpv for video playback
    • qthelper for Qt utilities
    • singleapplication for single-instance behavior
    • OpenSSL libraries

    The Debian way is clear: use system-provided libraries. This isn’t just philosophical purity—it’s about security updates, dependency management, and integration with the broader ecosystem.

    The goal: Replace every bundled dependency with its Debian system library equivalent.

    The result: A working .deb package with a 293KB optimized binary using 100% system libraries.

    The journey: Five major technical hurdles, each revealing deeper insights into Qt5 application architecture.

    The First Victory (That Wasn’t)

    Initial packaging seemed straightforward. I modified CMakeLists.txt to use system libraries:

    find_package(PkgConfig REQUIRED)
    pkg_check_modules(MPV REQUIRED mpv)
    find_package(Qt5 REQUIRED COMPONENTS Core Gui Qml Quick WebEngine)
    find_package(OpenSSL REQUIRED)

    The build succeeded. Dependencies looked perfect:

    $ ldd build/stremio | head -5
        libQt5WebEngine.so.5 => /lib/x86_64-linux-gnu/libQt5WebEngine.so.5
        libQt5DBus.so.5 => /lib/x86_64-linux-gnu/libQt5DBus.so.5
        libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3
        libmpv.so.2 => /lib/x86_64-linux-gnu/libmpv.so.2

    Perfect! Ship it, right?

    Wrong. When I actually ran the application:

    Segmentation fault (core dumped)

    Thus began the real work.

    Challenge 1: The QtWebEngine Initialization Bug

    Symptom: Immediate segmentation fault when launching the application.

    First debugging attempt: Run with gdb, examine the stack trace:

    Program received signal SIGSEGV, Segmentation fault.
    0x00007ffff5a2b3c4 in QQmlApplicationEngine::QQmlApplicationEngine() ()

    The crash occurred during QQmlApplicationEngine construction. But why? The same code worked fine with bundled libraries.

    The investigation: After examining Qt5 WebEngine documentation and several failed attempts to reorganize the code, I discovered a critical initialization requirement buried in the QtWebEngine documentation:

    QtWebEngine::initialize() must be called before the QApplication constructor when using QML.

    The bundled library setup happened to satisfy this ordering by accident. With system libraries, the default main() function violated it:

    // WRONG - causes crashes
    int main(int argc, char *argv[]) {
        QApplication app(argc, argv);  // QApplication created first
        // QtWebEngine::initialize() never called!
        QQmlApplicationEngine engine;  // CRASH
    }

    The fix (patch 0007-add-qtwebengine-initialize-fix.patch):

    // CORRECT - initialize QtWebEngine before QApplication
    int main(int argc, char *argv[]) {
        QtWebEngine::initialize();     // CRITICAL: Must be first!
        QApplication app(argc, argv);
        QQmlApplicationEngine engine;  // Now works
    }

    Lesson: When replacing bundled libraries with system ones, initialization order assumptions may change. Always verify startup sequence requirements.

    Challenge 2: The SingleApplication Threading Nightmare

    Symptom: After fixing QtWebEngine initialization, the application launched but immediately crashed with:

    QObject: Cannot create children for a parent that is in a different thread.

    The culprit: System library libsingleapplication-dev version 3.3.4.

    Stremio needs single-instance behavior—when you launch it a second time, it should activate the existing window rather than start a new process. The upstream code used a bundled singleapplication library. The Debian system provides libsingleapplication-dev. Perfect replacement, right?

    Wrong again.

    The investigation: The system SingleApplication library sets up a threading context that conflicts with QQmlApplicationEngine. Specifically:

    1. System SingleApplication creates its IPC mechanism in a worker thread
    2. QQmlApplicationEngine expects to be created in the main thread
    3. Qt5’s threading model doesn’t allow cross-thread parent-child relationships for certain QML objects

    The bundled version used a different threading approach that happened to work with QML.

    The false starts: I tried:

    • Patching SingleApplication to use main thread (broke IPC)
    • Deferring QML engine creation (broke startup sequence)
    • Various Qt thread affinity hacks (broke other things)

    The solution: Write a custom CompatibleSingleApp class that provides identical functionality without threading conflicts:

    // compatible_singleapp.h
    class CompatibleSingleApp : public QApplication {
        Q_OBJECT
    public:
        CompatibleSingleApp(int &argc, char **argv);
        bool isPrimary() const;
        bool isSecondary() const;
    
    signals:
        void instanceStarted();
    
    private:
        QLocalServer *m_server;
        QString m_serverName;
        bool m_isPrimary;
    };

    Implementation highlights (patch 0008-add-compatible-singleapp-implementation.patch):

    CompatibleSingleApp::CompatibleSingleApp(int &argc, char **argv)
        : QApplication(argc, argv), m_isPrimary(false) {
    
        m_serverName = "stremio-" + QString(qgetenv("USER"));
    
        // Try to connect to existing instance
        QLocalSocket socket;
        socket.connectToServer(m_serverName);
    
        if (socket.waitForConnected(500)) {
            // Secondary instance - notify primary and exit
            m_isPrimary = false;
            socket.write("ACTIVATE");
            socket.waitForBytesWritten();
            return;
        }
    
        // Primary instance - create server
        m_isPrimary = true;
        m_server = new QLocalServer(this);
        m_server->listen(m_serverName);
    
        connect(m_server, &QLocalServer::newConnection, this, [this]() {
            QLocalSocket *client = m_server->nextPendingConnection();
            connect(client, &QLocalSocket::readyRead, [this, client]() {
                QByteArray data = client->readAll();
                if (data == "ACTIVATE") {
                    emit instanceStarted();
                }
                client->deleteLater();
            });
        });
    }

    Result: Perfect single-instance behavior using pure QApplication (no threading conflicts) with QLocalSocket/QLocalServer for IPC.

    Binary size: 424KB debug vs 293KB release—both using 100% system libraries.

    Key lesson: System libraries may have different implementation details (like threading models) even when providing the same API. Sometimes a custom minimal implementation is cleaner than patching around incompatibilities.

    Challenge 3: The Missing QML Modules

    Symptom: After fixing both initialization and threading issues, the application launched but showed a black screen with console errors:

    module "QtWebEngine" is not installed
    module "QtWebChannel" is not installed
    module "Qt.labs.platform" is not installed

    The problem: Qt5 QML modules are separate runtime packages in Debian, not automatically pulled in by qtdeclarative5-dev.

    The investigation: Stremio’s QML code imports numerous Qt modules:

    import QtQuick 2.12
    import QtQuick.Controls 2.12
    import QtWebEngine 1.10
    import QtWebChannel 1.0
    import Qt.labs.platform 1.1
    import Qt.labs.settings 1.0

    Each requires a separate Debian package.

    The solution: Comprehensive dependency mapping in debian/control:

    Depends: ${shlibs:Depends}, ${misc:Depends},
             qml-module-qtwebengine,
             qml-module-qtwebchannel,
             qml-module-qt-labs-platform,
             qml-module-qtquick-controls,
             qml-module-qtquick-dialogs,
             qml-module-qt-labs-settings,
             qml-module-qt-labs-folderlistmodel,
             qtbase5-dev-tools

    Lesson: When packaging Qt QML applications, trace every QML import statement to its corresponding Debian package. apt-file search is your friend:

    $ apt-file search QtWebEngine.qml
    qml-module-qtwebengine: /usr/lib/x86_64-linux-gnu/qt5/qml/QtWebEngine/...

    Challenge 4: The Streaming Server Mystery

    Symptom: GUI loads perfectly, but when trying to play media:

    Error while starting streaming server
    tcp: Connection to tcp://127.0.0.1:11470 failed: Connection refused

    The investigation: Stremio includes a Node.js server component (server.js) for streaming. The shell process log showed:

    TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
        at Object.join (node:path:1292:7)

    The root cause: Qt’s QProcess doesn’t inherit environment variables by default. The Node.js server expected HOME, USER, and PWD to be available, but they weren’t.

    The fix (patch 0011-fix-qprocess-environment-for-server-launch.patch):

    // stremioprocess.cpp
    void Process::start() {
        // Set up environment variables for Node.js server
        QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    
        if (!env.contains("HOME")) {
            env.insert("HOME",
                QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
        }
        if (!env.contains("USER")) {
            env.insert("USER", qgetenv("USER"));
        }
        if (!env.contains("PWD")) {
            env.insert("PWD", QDir::currentPath());
        }
    
        this->setProcessEnvironment(env);
        QProcess::start();
    }

    Result: Server starts successfully:

    hls executables located -> { ffmpeg: '/usr/bin/ffmpeg', ffsplit: null }
    Using app path -> /home/user/.stremio-server
    EngineFS server started at http://127.0.0.1:11470

    Lesson: When spawning processes from Qt applications, explicitly configure the environment. Don’t assume child processes inherit the parent’s environment variables.

    Challenge 5: Debian Packaging Structure Pitfalls

    Symptom: Package builds successfully, but files install to wrong locations or with wrong names.

    The problem: Misunderstanding debhelper’s .install file behavior.

    What I thought:

    # debian/stremio.install
    build/stremio usr/bin/stremio-bin    # Install as /usr/bin/stremio-bin

    What actually happened:

    /usr/bin/stremio-bin/stremio    # Created DIRECTORY, file inside!

    The revelation: In debhelper .install files:

    • Path ending with / → Install files INTO that directory using original names
    • Path WITHOUT / → Create directory with that name and install files inside

    The correct solution (actual implementation):

    # debian/stremio.install
    # Binary installed to /usr/libexec (FHS 3.0 compliance for helper executables)
    build/stremio usr/libexec/stremio/
    
    # Wrapper script becomes the primary user-facing command
    debian/stremio-wrapper usr/bin/
    
    # Desktop file for application menu integration
    debian/stremio.desktop usr/share/applications/
    
    # Application icons (multiple resolutions for different contexts)
    icons/smartcode-stremio_16.png usr/share/icons/hicolor/16x16/apps/
    icons/smartcode-stremio_64.png usr/share/icons/hicolor/64x64/apps/
    # ... (additional icon sizes)

    Why this structure?

    1. /usr/libexec/stremio/: Modern FHS 3.0 location for internal executables not meant to be called directly by users
    2. Wrapper script at /usr/bin/stremio: Sets environment variables (like QTWEBENGINE_DISABLE_SANDBOX=1) before launching the actual binary
    3. Trailing slashes: Install files INTO directories using original filenames—critical for correct placement

    Lesson: Read debhelper documentation carefully. Small syntax details (trailing slashes!) have big consequences. Modern Debian packaging also follows FHS 3.0 standards, placing helper binaries in /usr/libexec/ rather than /usr/bin/.

    The Meta-Lesson: Efficient Patch Development

    The technical challenges were difficult, but I made them harder through inefficient workflow. I created patches, tested them, found they failed on clean upstream, then reworked them—five times.

    The problem: I was testing patches against already-modified sources, not pristine upstream.

    Build System Strategy: Patch CMakeLists.txt First

    Critical principle: Always prioritize build system patches over source code modifications.

    When replacing bundled dependencies with system libraries, the first patches should target CMakeLists.txt:

    # Patch 0005-cmake-system-libraries-v4.4.169.patch
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(MPV REQUIRED mpv)
    find_package(Qt5 REQUIRED COMPONENTS Core Gui Qml Quick WebEngine DBus)
    find_package(OpenSSL REQUIRED)

    Why this matters: Smaller, focused patches that address build system integration separately from source code changes are easier to maintain and review.

    Build system preference: We used qmake to generate makefiles first (Stremio’s traditional build system), then ensured CMake compatibility. The stremio.pro file and release.makefile workflow took precedence for package builds.

    The Anti-Pattern

    1. Modify source files directly to fix issue
    2. Generate patches from modified state
    3. Try to apply patches to clean upstream
    4. Patches fail (missing context, wrong line numbers, missing dependencies)
    5. Repeat

    The Efficient Workflow I Should Have Used

    # 1. Start with clean upstream
    git checkout v4.4.169
    
    # 2. Create isolated test environment
    cp -r . /tmp/patch-test/
    cd /tmp/patch-test/
    
    # 3. Fix ONE issue, test, generate patch
    # (fix QtWebEngine initialization)
    mkdir build && cd build && cmake .. && make    # Test build
    cd .. && git diff > 0001-qtwebengine-init.patch
    
    # 4. Apply patch to clean upstream, fix next issue
    git checkout v4.4.169
    patch -p1 < 0001-qtwebengine-init.patch
    # (fix next issue)
    git diff > 0002-next-fix.patch
    
    # 5. Final validation: apply all patches to clean upstream
    git checkout v4.4.169
    for patch in *.patch; do
        patch -p1 < $patch || exit 1
    done
    mkdir build && cd build && cmake .. && make

    Dependency analysis checklist I wish I’d used from the start:

    ## Pre-Patch Analysis Template
    
    ### Files to Modify:
    - [ ] main.cpp - entry point changes
    - [ ] mainapplication.h - class definitions, includes
    - [ ] CMakeLists.txt - build system
    - [ ] compatible_singleapp.h/cpp - new files
    
    ### Dependency Chain:
    1. main.cpp includes → mainapplication.h
    2. mainapplication.h includes → singleapplication.h (to replace)
    3. CMakeLists.txt references → SingleApplication library
    4. Qt MOC will process → Q_OBJECT classes (check conflicts!)
    
    ### Build Test Plan:
    - [ ] Clean cmake build
    - [ ] ldd dependency verification
    - [ ] Runtime basic functionality

    Time saved if I’d done this from the start: ~70% reduction in patch development time.

    Key insight: Understand file dependencies and build system BEFORE making changes. Test patches against clean upstream at each step, not just at the end.

    The Complete Patch Set

    The final working solution consists of 11 patches:

    1. 0001-Fix-server.js-path-for-FHS-compliance.patch – Server location
    2. 0002-disable-server-download.patch – Use system Node.js
    3. 0004-minimal-qthelper-integration.patch – System Qt utilities
    4. 0005-cmake-system-libraries-v4.4.169.patch – MPV, OpenSSL integration
    5. 0007-add-qtwebengine-initialize-fix.patchCritical: QtWebEngine initialization
    6. 0008-add-compatible-singleapp-implementation.patchCritical: Custom single-instance
    7. 0009-remove-system-singleapplication-add-compatible.patch – Build integration
    8. 0010-fix-qmake-install-paths.patch – Install location fixes
    9. 0011-fix-qprocess-environment-for-server-launch.patchCritical: Server environment

    Validation Workflow

    The final validation workflow ensures patches work on clean upstream, using the GBP (git-buildpackage) import workflow for proper Debian package building:

    # Step 1: Create pristine test environment with GBP structure
    git clone --branch v4.4.169 https://github.com/Stremio/stremio-shell.git /tmp/validation
    cd /tmp/validation
    cp -r /path/to/debian .
    
    # Step 2: Apply all patches using quilt
    export QUILT_PATCHES=debian/patches
    quilt push -a
    
    # Step 3: Test local build first (fastest iteration)
    QT_DEFAULT_MAJOR_VERSION=5 dpkg-buildpackage -us -uc
    
    # Step 4: Verify dependencies
    ldd debian/stremio/usr/libexec/stremio/stremio | head -5
    # Should show: libQt5WebEngine.so.5, libcrypto.so.3, libmpv.so.2
    
    # Step 5: Test with pbuilder (clean chroot environment)
    sudo pbuilder update
    sudo pbuilder build ../*.dsc
    
    # Step 6: Test with sbuild (production-grade build)
    # WARNING: Qt5/WebEngine packages consume significant space
    # Typical requirement: 4-6GB build space (overlayfs in tmpfs)
    # Solution: Use machine with 16GB+ RAM or configure sbuild on disk
    
    sbuild -d unstable ../*.dsc
    # If sbuild fails with "No space left on device":
    # - Switch to larger machine (16GB+ RAM recommended)
    # - Or configure sbuild to use disk instead of tmpfs

    Build Environment Considerations

    Memory requirements for Qt5 applications:

    • dpkg-buildpackage: ~2GB RAM
    • pbuilder: ~4GB RAM
    • sbuild with overlayfs in tmpfs: 6-8GB RAM (Qt5WebEngine is memory-intensive)

    Our solution: After encountering space exhaustion on 8GB machines during sbuild, we migrated to a 32GB machine. This is typical for Qt5/WebEngine applications—always test sbuild capacity before committing to build infrastructure.

    Result: 293KB optimized binary, 100% system libraries, full functionality including streaming.

    Lessons for Other Packagers

    Technical Takeaways

    1. Initialization order matters: System libraries may have different startup requirements than bundled ones. Always verify initialization sequences.
    2. Threading models vary: Even libraries with identical APIs may use different threading approaches. Watch for cross-thread object creation errors.
    3. Environment variables aren’t automatic: QProcess and similar mechanisms need explicit environment setup.
    4. QML modules are separate packages: Trace every QML import to its Debian package dependency.
    5. Custom implementations beat complex patches: Sometimes writing 100 lines of clean code is better than a 500-line patch to an incompatible library.

    Process Takeaways

    1. Always test patches against clean upstream: Never generate patches from already-modified sources.
    2. Map dependencies before coding: Understand file relationships and build system before making changes.
    3. One fix, one patch, one test: Incremental development prevents cascading failures.
    4. Document assumptions: What works «by accident» with bundled libraries may fail with system ones.
    5. Validate completely: Test patches in isolated environments before declaring them «ready».

    Conclusion

    Packaging Stremio for Debian taught me far more than Qt5 internals and build system integration. It revealed how easily we fall into inefficient workflows when we don’t step back to examine our process.

    The technical achievement: A fully functional Debian package using 100% system libraries where the upstream used bundled dependencies—293KB binary, zero submodules, complete feature parity.

    The real achievement: Learning that the how of problem-solving matters as much as the what. Efficient patch development isn’t just about technical skill—it’s about disciplined workflow, systematic thinking, and honest self-assessment.

    Would I do anything differently? Absolutely. I’d use the validation workflow from day one, map dependencies before coding, and test each patch against clean upstream immediately.

    But would I have learned these lessons without making the mistakes? Probably not.

    Acknowledgments

    Thanks to the Stremio team for creating great software, the Debian community for maintaining high standards, my friend Arturo (a Debian Developer) that knowing my passion for Debian encouraged me to start working as a Debian Maintainer, and to every packager who has documented their struggles—your war stories make ours easier.


    Project Status (as of October 3, 2025)

    Note: This article documents the technical process and challenges. Package acceptance is pending Debian review. Status updates will be posted as the review process continues.


    This article is part of my journey toward becoming a Debian Developer. If you’re interested in Debian packaging or have questions about the technical details, feel free to reach out.

  • Suspender e Hibernar un Macbook pro con Debian Buster

    Suspender e Hibernar un Macbook pro con Debian Buster

    Tengo un Macbook pro con Debian GNU/Linux en el cual estaba teniendo problemas al hibernarlo y suspenderlo.

    El interfaz de red que tiene es:

    03:00.0 Network controller: Broadcom Limited BCM4360 802.11ac Wireless Network Adapter (rev 03)
    

    En este portátil he trasteado bastante reparticionando su disco duro, por lo que es probable que ello haya influido en modificar los identificadores de las particiones swap usadas al hibernar.

    Al hibernarlo:

    El arrancar de nuevo el ordenador era igual que si no lo hubiera hibernado antes.

    La solución estaba en modificar el archivo /etc/initramfs-tools/conf.d/resume
    y especificar correctamente el identificador UUID de la partición de swap a usar.

    Los identificadores pueden comprobarse en el directorio:

    /dev/disk/by-uuid/
    Ejemplo:
    1. Comprobar donde está la partición de espacio de intercambio (swap)

      $ sudo fdisk -l
      .
      /dev/sda3 131602432 165154815 33552384 16G Linux swap
      .

    2. Comprobar cual esl UUID de esa partición.

      $ ls -l /dev/disk/by-uuid/
      .
      lrwxrwxrwx 1 root root 10 Nov 25 14:39 db4290b0-56c2-499c-aa4a-8a4e932e9b23 -> ../../sda3
      .

    3.  Actualizar /etc/initramfs-tools/conf.d/resume con el UUID correcto.

      RESUME=UUID=db4290b0-56c2-499c-aa4a-8a4e932e9b23

    Fuente: https://lists.debian.org/debian-user/2017/07/msg01074.html
    
    

    Al suspenderlo:

    En este caso, el principal inconveniente que estaba teniendo era que al volver de la suspensión perdía las conexiones de redes, sea por cable ethernet o inalámbrica por wifi.
    Esto me estaba obligando a reiniciar el network-manager, y con frecuencia varias veces seguidas tras volver de una suspensión.

    Tras jugar con ajustes de energía en los paneles de control, los archivos de interfaces, systemd, etc…

    Al final, la solución estuvo en evitar conflictos entre varios gestores de red. En mi caso opté por eliminar el paquete wicd-daemon y dejar que network-manager se encargue de las conexiones.

     

  • Debian anuncia la fecha de la próxima publicación de Wheezy

     

    Si quieres organizar una fiesta en tu ciudad coincidiendo con la liberación de Wheezy, he aquí la página del wiki de Debian que viene al rescate:

    http://wiki.debian.org/ReleasePartyWheezy

  • Debian Women ofrece un tutorial para crear paquetes

     

     

     

    A continuación reproducimos la nota de prensa de Debian en castellano:

    ¿Eres un entusiasta de Debian y estas pensando en contribuir? Queremos guiarte en tus inicios.

    Estamos convencidos de que hay mucha gente ahí fuera que quiere involucrarse en el Software Libre pero no sabe por donde empezar. En Debian, la tarea más común que harás como colaborador será construir un paquete.

    El proyecto Debian Women, en colaboración con el proyecto OpenHatch, patrocinan un evento en el IRc para ayudar a la gente que quiere compilar su primer paquete desde el código fuente y aplicar su primer parche.

    El evento

    El sabado, 7 de Mayo, habrá dos sesiones en el canal #debian-women del servidor de IRC irc.debian.org para ayudar a la gente a construir paquetes por primera vez

    La primera sesión, aconsejada para aquellos que viven en Oceania, Asia, Africa, y Europa, tendrá lugar a las 11:00 UTC.

     

    La última sesión, aconsejada para aquellos que viven en América, tendrá lugar a las 22:00 UTC.

    Puedes encontrar cual es el tiempo para tu zona horaria utilizando este convertidor de zona horaria

    Se hallaran personas disponibles para responder dudas y para ayudar con cualquier dificultad que pudieran surgir durante el día.

    ¿A quién va dirigido?

    Este evento está pensando para cualquiera que quiera construir un paquete Debian por primera vez, es una tarea simple que no requiere conocimientos previos, solo una instalación funcional de Debian (o UBuntu, o cualquier sistema derivado de Debian). Queremos animar particularmente a las mujeres que quieran involucrarse, y dar los primeros pasos para contribuir en el Software Libre, pero todo el mundo es bienvenido.

    Sobre el IRC

    IRC (Internet Relay Chat) es un sistema de charlas en tiempo real con el que puedes entrar en contacto con otros miembros de la comunidad de Debian. Puedes conectar al IRC a través de diferentes clientes, entre ellos: xchat, pidgin, kconversation, etc…

     

    Sobre Debian Women

    El Proyecto Debian Women persigue equilibrar y diversificar el proyecto Debian animando a las mujeres interesadas a tomar parte en Debian.

    Sobre OpenHatch

    OpenHatch es una comunidad de software libre dirigida a ayudar a los recién llegados a desenvolverse en proyectos de software libre. Para conseguir este objetivo se utilizan eventos on-line y eventos de toma de contacto. Este evento se inspira en los eventos «Build It» de OpenHatch.

     

    Nota adicional:

    Este tutorial no es sobre crear paquetes nuevos en Debian. Para eso puedes mirar: http://wiki.debian.org/IntroDebianPackaging

    Actualización:

    Registro de la primera sesión:

    http://meetbot.debian.net/debian-women/2011/debian-women.2011-05-07-11.00.log.html

    Registro de la segunda sesión:

    http://meetbot.debian.net/debian-women/2011/debian-women.2011-05-07-22.02.log.html

  • Soporte para los clickpad en HP Pavillion DV7 4160ES

    Estos son los componentes que trae el susodicho portátil:

    # lspci
    00:00.0 Host bridge: Intel Corporation Core Processor DRAM Controller (rev 02)
    00:01.0 PCI bridge: Intel Corporation Core Processor PCI Express x16 Root Port (rev 02)
    00:02.0 VGA compatible controller: Intel Corporation Core Processor Integrated Graphics Controller (rev 02)
    00:16.0 Communication controller: Intel Corporation 5 Series/3400 Series Chipset HECI Controller (rev 06)
    00:1a.0 USB Controller: Intel Corporation 5 Series/3400 Series Chipset USB2 Enhanced Host Controller (rev 05)
    00:1b.0 Audio device: Intel Corporation 5 Series/3400 Series Chipset High Definition Audio (rev 05)
    00:1c.0 PCI bridge: Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 1 (rev 05)
    00:1c.1 PCI bridge: Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 2 (rev 05)
    00:1d.0 USB Controller: Intel Corporation 5 Series/3400 Series Chipset USB2 Enhanced Host Controller (rev 05)
    00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev a5)
    00:1f.0 ISA bridge: Intel Corporation Mobile 5 Series Chipset LPC Interface Controller (rev 05)
    00:1f.2 SATA controller: Intel Corporation 5 Series/3400 Series Chipset 4 port SATA AHCI Controller (rev 05)
    00:1f.3 SMBus: Intel Corporation 5 Series/3400 Series Chipset SMBus Controller (rev 05)
    00:1f.6 Signal processing controller: Intel Corporation 5 Series/3400 Series Chipset Thermal Subsystem (rev 05)
    01:00.0 VGA compatible controller: ATI Technologies Inc Manhattan [Mobility Radeon HD 5000 Series]
    01:00.1 Audio device: ATI Technologies Inc Manhattan HDMI Audio [Mobility Radeon HD 5000 Series]
    02:00.0 Network controller: Atheros Communications Inc. AR9285 Wireless Network Adapter (PCI-Express) (rev 01)
    03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 03)
    7f:00.0 Host bridge: Intel Corporation Core Processor QuickPath Architecture Generic Non-core Registers (rev 02)
    7f:00.1 Host bridge: Intel Corporation Core Processor QuickPath Architecture System Address Decoder (rev 02)
    7f:02.0 Host bridge: Intel Corporation Core Processor QPI Link 0 (rev 02)
    7f:02.1 Host bridge: Intel Corporation Core Processor QPI Physical 0 (rev 02)
    7f:02.2 Host bridge: Intel Corporation Core Processor Reserved (rev 02)
    7f:02.3 Host bridge: Intel Corporation Core Processor Reserved (rev 02)

    Haciendo apt-pinning en Debian instalo algunos paquetes de la rama unstable en Squeeze.

    Instalo la última versión del kernel:

    # apt-get install linux-headers-2.6.38-1-amd64
    # apt-get install linux-image-2.6.38-1-amd64

    Instalo las últimas versiones de los componentes de xorg de la rama unstable.
    (Todos los componentes hasta que no falte ninguna dependencia)

    # apt-get install -t unstable xserver-xorg-input-synaptics xorg xserver-xorg

    Veo que hay bugs relacionados en el bugtracker de Debian:
    http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=597082
    http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=572842

    En el primero de ellos se hace referencia a este parche y lo descargamos en /usr/src/99-clickpad.patch:
    http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=26;filename=99-clickpad.patch;att=1;bug=597082

    Bajamos los fuentes de Debian unstable para xserver-xorg-input-synaptics:

    # apt-get source -t unstable xserver-xorg-input-synaptics

    Bajamos tambien las dependencias para poder recompilarlo:

    # apt-get -t unstable build-dep xserver-xorg-input-synaptics

    Vamos al directorio donde se han descargado y aplicamos el parche que bajamos antes.
    (En nuestro caso se ha bajado la versión 1.4.0)

    # cd /usr/src/xserver-xorg-input-synaptics-1.4.0 
    # cat /usr/src/99-clickpad.patch |patch -p1

    Recompilamos el paquete con el parche ya incluido.

    # dpkg-buildpackage -b

    Instalamos el paquete:

    # sudo dpkg -i ../xserver-xorg-input-synaptics-*version*.deb

    (En mi caso: xserver-xorg-input-synaptics_1.4.0-1_amd64.deb)

    Sólo nos basta las X-window y el soporte mejora considerablemente. Aunque quedan bastantes funcionalidades que iremos viendo implementadas muy pronto por los desarrolladores del kernel y de Xorg.

    Y con esto y un bizcocho, este desarrollador puede desarrollar tranquilamente.

  • Conectar tu ordenador a Internet haciendo USB Tethering con Android.

    USB Tether Android con Linux

     

    Lo que nos hace falta es la aplicación para Android: AziLink app,  el programa «adb»  del Android SDK, y OpenVPN. Con éste metodo no se necesita «root» en el teléfono.

    Instalar openvpn.

    # apt-get install openvpn 

    Instalar el Android SDK para obtener el programa adb.

    # cd /usr/local/
    # wget http://dl.google.com/android/android-sdk_r10-linux_x86.tgz
    # tar xzvf android-sdk_r10-linux_86.tgz # ln -s android-sdk-linux_86/tools/adb /usr/local/bin/

    Notificar a udev  el USB vendor ID del teléfono. Esto se hace creando un fichero de reglas de udev. Cambia USERNAME por el nombre de tu usuario.

    El USB vendor ID de tu teléfono puedes saberlo, tecleando «lsusb» cuando hayas conectado el teléfono por el cable USB. En el caso del Spica es «04e8»

    /etc/udev/rules.d/51-android.rules

    SUBSYSTEM=="usb", ATTRS{idVendor}=="04e8", SYMLINK+="android_adb", MODE="0666", OWNER="USERNAME"

     

    # /etc/init.d/udev restart

    Habilitar la «Depuración de USB» en el teléfono en el menú Ajustes -> Aplicaciones -> Desarrollo -> Depuración de USB . Conectar ahora el cable USB.

    Comprobar que el teléfono ha sido reconocido

    $ adb devices

    Instalar AziLink en el teléfono a traves de adb:

    # cd /usr/local/bin/
    # wget http://azilink.googlecode.com/files/azilink-2.0.2.apk
    # wget http://azilink.googlecode.com/files/azilink.ovpn
    # adb install -r azilink-2.0.2.apk

    Crear una configuración de dns para la conexión.

    /etc/resolv.conf.azilink

    domain lan
    search lan
    nameserver 192.168.56.1

    Crear un shell script para arrancar adb y openvpn.

    /usr/local/bin/azilink.sh

    adb forward tcp:41927 tcp:41927
    sudo cp /etc/resolv.conf.azilink /etc/resolv.conf
    sudo openvpn --config /usr/local/bin/azilink.ovpn

    Convertir el script en ejecutable:

    # chmod +x /usr/local/bin/azilink.sh

    Dar acceso de sudo a tu usuario añadiendo la siguiente línea en /etc/sudoers, reemplazando USERNAME con tu login.

    USERNAME     ALL=(ALL)       ALL

     

    Despues de todo esto, sólo hay que desconectar cualquier otra conexión por cable o wifi que pudiera tener el ordenador y arrancar Azilink en el teléfono.  Ejecutar azilink.sh en el ordenador con tu usuario habitual.

     

    Fuente: http://idolinux.blogspot.com/2010/06/usb-tether-android-with-linux.html

  • Estar a la última en Debian mientras sigues con la rama estable

    Iremos al grano.

    Conceptos básicos:

    Debian mantiene varios repositorios o ramas de paquetes cada uno con sus propias versiones de paquetes.

    Los que nos interesan son:

    • oldstable
    • stable (actualmente: «squeeze»)
    • testing
    • unstable
    • experimental

     

    Existe otra rama: backports.   Los paquetes de «backports» son versiones de paquetes nuevos que han sido portados para la rama estable.

    Un sistema Debian recien instalado tiene «stable» como repositorio por defecto. Pero podemos instalar paquetes de otras ramas de manera sencilla.

    Comentarios

    Durante años, he tenido sistemas en unstable sin problemas.

    Actualmente lo que hago es que tener un sistema con repositorios de la rama «estable» y «backports», y de los que opcionalmente, de los paquetes que me interesa estar a la última, instalo de otras ramas.

    Configurar un sistema mixto con apt-pinning

    Apt-pinning lo que nos permite es tener diferentes ramas de Debian.

    Esto lo puedes configurar graficamente con el gestor de paquetes Synaptic o modificando estos ficheros, que al ser tan sencillo, optamos por eso.

    Fichero: /etc/apt/sources.list

    #########################STABLE########################################
    deb http://ftp.es.debian.org/debian/ squeeze non-free contrib main
    deb http://security.debian.org/ squeeze/updates non-free contrib main
    deb http://ftp.es.debian.org/debian/ squeeze-proposed-updates non-free contrib main
    ### Squeeze backports #####
    deb http://backports.debian.org/debian-backports squeeze-backports main contrib non-free
    #########################TESTING#########################################
    #deb http://ftp.es.debian.org/debian/ testing main contrib non-free 
    #########################UNSTABLE######################################## #deb http://ftp.es.debian.org/debian/ unstable main contrib non-free #########################EXPERIMENTAL#################################### #deb http://http.us.debian.org/debian/ experimental main contrib non-free

    Nota: El lector atento verá el carácter almohadilla # por delante de las ramas testing, unstable y experimental, esto es porque ahora mismo, no las estoy utilizando. El que lo necesite sólo tiene que habilitarlos, quitando la almohadilla #.

    Fichero: /etc/apt/preferences

    Package: *
    Pin: release a=squeeze-backports
    Pin-Priority: 900

    Package: *
    Pin: release a=squeeze
    Pin-Priority: 800

    Package: *
    Pin: release a=testing
    Pin-Priority: 700

    Package: *
    Pin: release a=unstable
    Pin-Priority: 600

    Package: *
    Pin: release a=experimental
    Pin-Priority: 500

    Con estas prioridades,cuando actualizamos el sistema se le da prioridad a los paquetes de stable (squeeze), de manera que «no se tienen en cuenta» las otras ramas a menos que explicitamente instalemos paquetes de otras ramas.

    Por ejemplo, para instalar un navegador como «midori», normalmente hacemos:

    apt-get install midori

    Ahora podemos hacer:

    apt-get install midori -t testing
    apt-get install midori -t unstable

     

    La primera sentencia instala midori de la rama testing, la segunda instala midori de la rama unstable.

    Comentarios Finales

    Tambien es útil saber que podemos comentar (deshabilitar) estos repositorios poniendo el carácter almohadilla # por delante del repositorio en /etc/apt/sources.list y habilitarlo cuando queramos quitando la almohadilla.

    Bueno, con esto y un bizcocho, queda demostrado que ese concepto raro llamado «apt-pinning» no es más que algo tan sencillo como tener varios repositorios disponibles e instalar paquetes de la rama que quieras.

    Algo que los obsesionados por estar a la última encontraran útil y sencillo

    Fuentes: http://www.esdebian.org/wiki/sistemas-mixtos

  • ¡Ya esta aquí!: Publicación de Debian 6.0 «Squeeze»

    de Fernando C. Estrada<fcestrada@fcestrada.com>
    responder a debian-users-spanish@lists.debian.org
    para debian-news-spanish@lists.debian.org
    fecha 6 de febrero de 2011 03:05
    asunto Publicación de Debian 6.0 «Squeeze»
    lista de distribución <debian-news-spanish.lists.debian.org>

    Después de 24 meses de desarrollo constante, el proyecto Debian se
    complace en anunciar su nueva versión estable 6.0 (nombre en clave
    `Squeeze’). Debian 6.0 es un sistema operativo libre y se presenta por
    primera vez en dos sabores, ya que junto con Debian GNU/Linux, en esta
    versión se ha introducido Debian/kFreeBSD como una `vista preliminar de
    la tecnología’.

    Debian 6.0 incluye los entornos de escritorio KDE, GNOME, Xfce y LXDE,
    así como todo tipo de aplicaciones de servidor. También ofrece
    compatibilidad con el estándar FHS v2.3 y el software desarrollado para
    la versión 3.2 de LSB.

    Debian se ejecuta en distintos tipos de sistemas que van desde
    computadores de bolsillo hasta supercomputadoras, pasando por
    prácticamente cualquier otro sistema intermedio. Debian GNU/Linux da
    soporte a un total de nueve arquitecturas: PCs de 32 bits / Intel IA-32
    (i386), PCs de 64 bits / Intel EM64T / x86-64 (amd64), PowerPC de
    Motorola/IBM (powerpc), SPARC de Sun/Oracle (sparc), MIPS (mips
    (big-endian) y mipsel (little-endian)), Itanium de Intel (ia64), S/390
    de IBM (s390), y ARM EABI (armel).

    Debian 6.0 `Squeeze’ incluye una versión preliminar de dos nuevas
    adaptaciones al núcleo del proyecto FreeBSD utilizando el conocido
    entorno de usuario Debian GNU: Debian GNU/kFreeBSD para arquitecturas
    de PCs de 32 bits (kfreebsd-i386) y PC de 64 bits (kfreebsd-amd64).
    Estas adaptaciones son las primeras en ser incluidas en una versión de
    Debian sin estar basadas en el núcleo de Linux. Hay muy buen soporte
    para aplicaciones de servidor y combina las características existentes
    de Debian basado en Linux con caracterí sticas únicas en el mundo BSD.
    Sin embargo, en esta versión estas adaptaciones son aún limitadas. Por
    ejemplo, algunas de las características avanzadas de escritorio aún no
    están soportadas.

    Otra novedad es el núcleo de Linux completamente libre. En esta versión
    el núcleo ya no contiene archivos problemáticos de firmware. Estos se
    han dividido en paquetes separados y se han movido fuera del archivo
    principal de Debian al área no libre («non-free») del archivo, la cual
    no está activada de manera predeterminada. De esta forma, los usuarios
    de Debian tienen la posibilidad de utilizar un sistema operativo
    completamente libre, aunque también pueden optar por utilizar archivos
    de firmware no libres en caso de requerirlos. Los archivos de firmware
    pueden cargarse durante la instalación a través del instalador si esto
    fuera necesario. También estarán disponibles en imágenes de CD
    especiales y como archivos comprimidos para utilizar la instalación
    desde USB. Hay más información disponible al respecto en la página del
    wiki del Firmware [1] de Debian.

    1: http://wiki.debian.org/Firmware

    Además, Debian 6.0 introduce un sistema de arranque basado en
    dependencias, por lo que el inicio del sistema ahora es más rápido y
    más robusto debido a la ejecución en paralelo de los programas de
    arranque y el seguimiento correcto de sus interdependencias. Algunos
    otros cambios hacen el uso de Debian en portátiles pequeños más cómodo,
    como por ejemplo, la introducción de KDE Plasma para Netbooks.

    Esta versión incluye una gran cantidad de paquetes de programas
    actualizados tal como:

    • el entorno de escritorio KDE 4.4.5
    • el entorno de escritorio GNOME 2.30
    • el entorno de escritorio Xfce 4.6
    • el entorno de escritorio LXDE 0.5.0
    • X.Org 7.5
    • OpenOffice.org 3.2.1
    • GIMP 2.6.11
    • Iceweasel 3.5.16 (una versión de Mozilla Firefox que no utiliza la
    marca registrada)
    • Icedove 3.0.11 (una versión de Mozilla Thunderbird que no utiliza
    la marca registrada)
    • PostgreSQL 8.4.6
    • MySQL 5.1.49
    • la Colección de compiladores de GNU 4.4.5
    • Linux 2.6.32
    • Apache 2.2.16
    • Samba 3.5.6
    • Python 2.6.6, 2.5.5 and 3.1.3
    • Perl 5.10.1
    • PHP 5.3.3
    • Asterisk 1.6.2.9
    • Nagios 3.2.3
    • el Hipervisor Xen 4.0.1 (con soporte tanto para dom0 como para
    domU)
    • OpenJDK 6b18
    • Tomcat 6.0.18
    • más de 29,000 paquetes de programas listos para usarse construidos
    a partir de 15.000 paquetes fuente).

    Debian 6.0 incluye cerca de 10,000 paquetes nuevos como el navegador
    Chromium, la solución de monitorización Icinga, la interfaz de usuario
    para administración de paquetes `Software Center’, el administrador de
    red wicd, las herramientas de contenedor de Linux lxc y el entorno para
    clústers Corosync.

    Con esta amplia selección de paquetes, Debian se mantiene fiel a su
    objetivo de ser el sistema operativo universal. Es un sistema que se
    puede utilizar para distintos casos como por ejemplo: sistemas de
    escritorio y netbooks; desde servidores de desarrollo hasta clústers;
    servidores de bases de datos, servidores web o de almacenamiento. Se ha
    hecho un gran esfuerzo para asegurar la calidad por medio de pruebas
    automáticas de instalación y actualización para todos los paquetes en
    el archivo de Debian, asegurando de esta forma que Debian 6.0 cumple
    las altas expectativas que tienen los usuarios de una versión estable
    de Debian. Es tan sólido como una roca y ha sido probado de manera
    rigurosa.

    A partir de Debian 6.0, las `Custom Debian Distributions’
    (Distribuciones Personalizadas de Debian) han cambiado su nombre y se
    llaman ahora `Debian Pure Blends’ [2]. Su cobertura se ha incrementado
    agregando Debian Accessibility [3], DebiChem [4], Debian EzGo [5],
    Debian GIS [6] y Debian Multimedia [7] a las ya existentes Debian Edu [8],
    Debian Med [9] y Debian Science [10] `pure blends’. Se puede consultar,
    el listado completo de todos los «blends» [11], incluyendo los paquetes
    que los usuarios nominen a ser incluidos para la siguiente publicación.

    2: http://blends.alioth.debian.org/
    3: http://www.debian.org/devel/debian-accessibility/
    4: http://debichem.alioth.debian.org/
    5: http://wiki.debian.org/DebianEzGo
    6: http://wiki.debian.org/DebianGis
    7: http://blends.alioth.debian.org/multimedia/tasks/index
    8: http://wiki.debian.org/DebianEdu
    9: http://www.debian.org/devel/debian-med/
    10: http://wiki.debian.org/DebianScience
    11: http://blends.alioth.debian.org/

    Puede instalarse Debian desde diversos medios como discos Blu-ray,
    DVDs, CDs, unidades USB o desde la red. GNOME es el escritorio
    predeterminado y por ello se incluye en el primer CD. Otros entornos de
    escritorio (como KDE, Xfce, o LXDE) pueden instalarse a través de dos
    imágenes de CD alternativas. También puede elegirse el entorno de
    escritorio deseado desde el menú de arranque de los CDs/DVDs. De nuevo,
    Debian 6.0 pone a disposición de los usuarios imágenes
    multi-arquitectura para CDs y DVDs las cuales soportan la instalación
    en varias arquitecturas desde un solo disco. La creación de un
    instalador de arranque a partir de USB se ha simplificado enormemente.
    Para mayor información lea la Guía de Instalación [12].

    12: http://www.debian.org/releases/squeeze/installmanual

    Además de los medios de instalación convencionales, Debian GNU/Linux
    también puede utilizarse sin necesidad de instalarlo. Las imágenes
    especiales utilizadas conocidas como imágenes en vivo («live») están
    disponibles para CDs, memorias USB y para arranque desde de red.
    Inicialmente, éstas se proporcionan únicamente para las arquitecturas
    amd64 e i386. También es posible utilizar estas imágenes para instalar
    Debian GNU/Linux.

    El proceso de instalación de Debian GNU/Linux 6.0 ha sido mejorado de
    varias formas, incluyendo una selección más fácil en la configuración
    del idioma y teclado, así  como en el particionado de volúmenes
    lógicos, RAID y sistemas cifrados. Se ha agregado soporte para los
    sistemas de archivos ext4 y Btrfs, y (en la arquitectura kFreeBSD) para
    el sistema de archivos Zettabyte (ZFS). El instalador de Debian GNU/
    Linux ha sido traducido a 70 idiomas.

    Las imágenes del instalador de Debian ya pueden descargarse mediante
    bittorrent [13] (método recomendado), jigdo [14] o HTTP [15]. Consulte
    Debian en CDs [16] para más información. Muy pronto también estarán
    disponibles los discos físicos en formato DVD, CD-ROM y Blu-ray por
    parte de diversos vendedores [17].

    13: http://www.debian.org/CD/torrent-cd/
    14: http://www.debian.org/CD/jigdo-cd/#which
    15: http://www.debian.org/CD/http-ftp/
    16: http://www.debian.org/CD/
    17: http://www.debian.org/CD//vendors

    La actualización a Debian GNU/Linux 6.0 desde la versión anterior,
    Debian GNU/Linux 5.0 (nombre en clave `Lenny’), se gestiona de forma
    automática a través de la aplicación para la administración de paquetes
    apt-get para la gran mayoría de las configuraciones, y hasta cierto
    punto, también por la aplicación para la administración de paquetes
    aptitude. Como siempre, los sistemas Debian GNU/Linux pueden
    actualizarse sin problemas y prácticamente sin tiempo de inactividad,
    aunque es ampliamente recomendable leer las Notas de Publicación [18] así
    como también la Guía de Instalación [19] para evitar posibles
    inconvenientes, ya que incluyen instrucciones detalladas relacionadas
    con la instalación y actualización. Las Notas de Publicación se
    seguirán mejorando y traduciendo a más idiomas en las semanas
    posteriores a la publicación de la versión.

    18: http://www.debian.org/releases/squeeze/releasenotes
    19: http://www.debian.org/releases/squeeze/installmanual

    Acerca de Debian
    —————-

    Debian es un sistema operativo libre desarrollado por miles de
    voluntarios de todo el mundo quienes colaboran a través de Internet.
    Los puntos fuertes del proyecto Debian son su base de voluntarios, su
    dedicación al Contrato Social de Debian, y su compromiso por ofrecer el
    mejor sistema operativo posible. Debian 6.0 es otro paso importante en
    esa dirección.

    Información de contacto
    ———————–

    Para más información, visite las páginas de Debian en http://www.debian.org/
    o envíe un correo electrónico a <press@debian.org>.

Creative Commons License
Except where otherwise noted, the content on this site is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.