Ultimamente ho ricevuto molte domande riguardo la containerizzazione degli ambienti per i test automatizzati quando si utilizzano sistemi di Integrazione Continua. Se non hai capito la maggior parte di quella frase non preoccuparti perché faremo un'immersione completa nei container, Docker, e come sfruttarli nel tuo ambiente embedded e nei test hardware in the loop.
Ci sono molti eccellenti articoli sui container, inclusi questo di Docker (uno dei motori di runtime per container più popolari in circolazione). I container negli ambienti di build (ad es. sistemi embedded) e negli ambienti di test (ad es. test hardware in the loop) ci danno la possibilità di astrarsi da tutta la complicata configurazione ogni volta che vogliamo avviare una nuova macchina. Questo non riguarda solo le nuove macchine di test ma anche l'espansione della nostra operazione nel cloud anche per la costruzione del firmware embedded.
Non importa di che dimensione sia l'operazione che stai gestendo oggi, molte aziende sfruttano il cloud per evitare di mantenere server fisici. Nei principi DevOps vogliamo sempre assicurarci che qualsiasi software scriviamo possa essere costruito ed eseguito ovunque, in qualsiasi momento, in qualsiasi luogo. Avviare continuamente nuove macchine nel cloud e installare software di compilazione, librerie e altri pacchetti software non è scalabile. Questo è, precisamente, il motivo per cui la containerizzazione è diventata così popolare. Possiamo prendere il nostro ambiente di build (o di runtime), impacchettarlo in una macchina virtuale molto leggera e consegnarlo a qualsiasi macchina per eseguirlo, sia che si tratti del cloud o del nostro computer personale.
Esploriamo come effettivamente creare e usare questi container nei tuoi progetti. Quando iniziamo a creare un'immagine container dobbiamo partire da un'immagine di base esistente. Nella maggior parte dei casi, qualche variante di un sistema operativo Linux, come Debian, Ubuntu o Alpine, sarà sufficiente. Una volta creato il tuo Dockerfile ti riferisci all'immagine così:
FROM ubuntu:latest
Questo indica che il sistema operativo di base sarà l'ultima immagine Docker di Ubuntu. Dopo di che dovremo installare qualsiasi libreria sia necessaria per il nostro ambiente di build o di test. In un esempio di repository, ho installato l'IDE Arduino usando il gestore di pacchetti Debian (Apt) e poi ho aggiunto altri strati installando anche i driver della scheda Arduino Sam. Eseguendo questo container in modalità privilegiata (o passando il punto di montaggio del volume al dispositivo) posso compilare e caricare uno sketch Arduino tramite linea di comando su una macchina nuovissima che contiene solo Docker (cioè nessun IDE o driver).
Possiamo fare lo stesso con le macchine che sono collegate ai nostri dispositivi in prova. In questo container Docker che ho preparato, installo tutte le dipendenze e il software necessario per far funzionare un dispositivo Analog Discovery 2. In teoria, posso avviare il container Docker su una macchina completamente nuova (che contiene solo Docker) e iniziare a comunicare con l'Analog Discovery 2 senza alcun problema. Con l'Analog Discovery 2 posso scrivere test per validare i miei ADC, DAC, o inviare comandi I2C/SPI a diversi chip sulla mia scheda (insieme a una miriade di altre capacità).
Ora, discutiamo di come i container possono migliorare i sistemi di Integrazione Continua per aumentare l'efficienza e la scalabilità. La vera magia si verifica quando iniziamo a utilizzare i container in congiunzione con i sistemi di Integrazione Continua (CI). Potremmo avere dozzine, se non centinaia di macchine di test fisiche o accesso a migliaia di macchine cloud per i nostri server di test e build. Per scalare praticamente, come menzionato sopra, non possiamo configurare ogni singola macchina man mano che vengono messe online. Fornire un container con ogni esecuzione CI ci dà non solo un modo sistematico e ripetibile di eseguire build e test, ma ci libera anche dall'avere a riconfigurare una macchina ogni volta che la portiamo online (che, nel cloud, avviene quasi ad ogni esecuzione CI). Sfruttando i container per le build embedded e i test su hardware fisico ci forniamo e forniamo alle nostre aziende un certo livello di scalabilità che le generazioni precedenti potevano solo sognare.
In questo articolo, abbiamo evidenziato il ruolo cruciale dei container nello sviluppo di sistemi embedded, specialmente per ambienti di build e test consistenti attraverso diversi tipi di infrastrutture. La loro integrazione con i sistemi di integrazione continua non solo semplifica lo sviluppo ma aumenta anche la scalabilità e l'affidabilità del prodotto. Con l'avanzamento della tecnologia dei container, la loro adozione diventerà sempre più importante per gli sviluppatori. Approfondisci e sperimenta con diverse configurazioni visitando alcuni repository di esempio su https://gitlab.com/docker-embedded.