Dokuwiki è un potente wiki opensource che permette di editare, far versioning di documenti e caricare file e immagini, anch'essi sottoposti a controllo di versione.
Il controllo di versione funziona in modo trasparente se si utilizza l'interfaccia web di dokuwiki, ma supponiamo di avere dei file che vengono generati sul server che ospita la vostra istanza dokuwiki, e supponiamo di volerli rendere disponibili come media all'interno di dokuwiki stesso, con il controllo di versione.
Dokuwiki non offre nessuno strumento nativo per questo tipo di esigenza ma, con un po' di reverse engineering di come funziona il sistema di versioning di dokuwiki è possibile realizzare tale istanza, ovvero copiare localmente un file all'interno della struttura media di dokuwiki, mantenendone il versioning (potendo quindi ripristinare versioni precedenti, qualora lo si rendesse necessario).
Prima di entrare nella modalità operativa occorre spiegare un attimo come funziona dokuwiki e il suo sistema di versioning. Dokuwiki è un sistema che funziona senza database, quindi tutta la logica di funzionamento è presente all'interno di directory e files nella struttura dell'istanza di dokuwiki.
Supponiamo di voler mantenere aggiornato, con controllo di versione, il file logs.zip creato da uno script sul server stesso che monta l'istanza di dokuwiki. Supponiamo di mantenere il file logs.zip all'interno del contenitore generale media.
Se si fa l'upload da interfaccia web del file logs.zip, quello che avviene a livello di filesystem è che il file viene salvato nella directory <path_dokuwiki>/data/media
. Se il file viene sostituito da una versione più recente, il media manager compie queste azioni:
- Calcola la data di ultima modifica in timestamp unix del file logs.zip originale
- Sposta il file logs.zip originale nella directory
<path_dokuwiki>/data/media_attic
e lo rinomina come logs.<unix_timestamp_ultima_modifica>.zip
- Aggiunge al file
<path_dokuwiki>/data/media_meta/logs.zip.changes
una riga, la cui sintassi viene descritta più avanti, che mantiene le informazioni per il versioning
- Copia il nuovo file logs.zip in
<path_dokuwiki>/data/media
Volendo fare "l'upload" del file logs.zip dall'interno del server stesso occorre quindi simulare le operazioni svolte dal media manager di dokuwiki.
La sintassi dei file con estensione .changes
, che sono responsabili del mantenimento di versione, è la seguente; per ogni nuova versione del file caricata viene aggiunta una riga contenente le seguenti informazioni, separate da tabulazione:
- tempo di ultima modifica in unix timestamp del nuovo file
- ip di origine
- Flag di creazione/modifica
- path del file in notazione namespace
- utente che ha fatto la modifica
- riga "creata" se creazione
- dimensione del file in byte
Usando uno script bash è possibile eseguire tutte le operazioni e i calcoli necessari, in particolare:
- tempo di ultima modifica in unix timestamp del nuovo file
stat -c %Y
- ip di origine
127.0.0.1
- Flag di creazione/modifica
C oppure E
- path del file in notazione namespace
logs.zip
- utente che ha fatto la modifica (il proprio utente dokuwiki va bene)
- riga "creata" se creazione
- dimensione del file in byte
ls -l file| awk '{print $5}'
Un ipotetico script in bash, quindi, conterrebbe le seguenti righe:
fileupd="<path>/logs.zip"
lastmod=$(stat -c %Y $fileupd)
fileupdsize=$(ls -l $fileupd| awk '{print $5}'
echo "$lastmod 127.0.0.1 E logs.zip mydoku-user $fileupdsize >> <path_dokuwiki>/data/media_meta/logs.zip
Nello stesso script dovrebbe comparire anche la linea relativa allo spostamento e alla rinomina della vecchia versione del file logs.zip all'interno della directory <path_dokuwiki>/data/media_attic
:
mv <path_dokuwiki>/media/logs.zip <path_dokuwiki>/media_attic/logs.$(stat -c %Y <path_dokuwiki>/media/logs.zip).zip
Infine, resta da copiare il nuovo file logs.zip all'interno della directory media e sistemarne i permessi perché sia leggibile all'utente che esegue l'istanza web (per Debian/Ubuntu, ad esempio, è l'utente www-data
mv $fileupd <path_dokuwiki>/media/
chown www-data:www-data <path_dokuwiki>/media/logs.zip
Per rendere il tutto automatico è possibile sfruttare naturalmente cron/anacron, così da far eseguire lo script senza necessità di interazione.