Het stagingprobleem van drupal

Posted by: 
Dominique De Cooman

Ik heb dit probleem al meermaals tegengekomen. We hebben reeds vanuit verschillende omgevingen gewerkt: een productie, een ontwikkeling en een integratie omgeving. Deze klassieke stappenopeenvolging bij software ontwikkeling noemt men upstream van productie tot ontwikkeling en downstream van ontwikkeling tot productie.

Upstream
In het upstream proces worden nieuwe aangemaakte gebruikers, inhoude en gebruikersconfiguraties overgezet. Dit wordt in de meeste gevallen gedaan door het transfereren van database dumps. Bij sommige gevallen echter kan het gebeuren dat de database te groot is om alles in een stuk over te zetten. Als je bijvoorbeeld 3,5 miljoen nodes in je database steken hebt wil je niet het hele ding gaan downloaden...

De Oplossing
Als je alleen de gebruikersconfiguraties wilt van een productie omgeving (bijvoorbeeld http://drupal.org/project/homebox instellingen) een mogelijke oplossing is om gebruik te maken van de http://drupal.org/project/backup_migrate module. Hiermee kan je zelf selecteren welke tabellen er moeten worden geëxporteerd. Op die manier voer je enkel die tabellen uit die configuraties bevatten.
Hoewel dit een meer geavanceerde kennis van drupal vereist (omdat je moet weten welke de juist tabellen zijn om te exporteren) is het een gemakkelijke te herhalen methode doordat je de selectie tabel kan opslaan.
Je kan deze module automatiseren door gebruik te maken van cron en het heeft ook enkele drush commando's klaar zodat het een snelle manier is om upstream sites up to date te houden.
Wanneer je enkel nieuwe aangemaakte inhoud, drupal configuraties of views, maak dan gebruik van de http://drupal.org/project/deploy module. Deze video legt hierover alles uit http://www.youtube.com/watch?v=7PjwT0HWHxw

Downstream
Het downstream proces dat de nieuwe code en instellingen in het ontwikkelingsketen inbrengt is een probleem in Drupal. Je hebt de grove manier, waarbij je database dumps transfereert. Dit is echter niet zo'n goed idee wanneer je site constant wordt geupdate. Een mogelijke variatie hierop zou de werkwijze kunnen zijn die hierboven werd besproken, waarbij enkel de tabellen worden overgezet die instellingen bevatten inzake backup en migratie. Je komt echter al snel in de problemen van zodra je begint met het installeren van modules die reageren op inhoud.
Een eenvoudig voorbeeldje is een nieuw veld in een content type. Dit verander de content type tabel. Ook is het zo dat alles database overdrachtgerelateerd slechte rollback mogelijkheden en change logging heeft. Het verrichten van database transfers tesamen met het manueel updaten van zaken is een update strategie dat wel uit de oertijd lijkt weggeplukt...

Om dit probleem toch ietwat eleganter op te lossen is het beter een systeem te installeren dat gebruik maakt van volgende drie verschillende componenten:

Features
De module http://drupal.org/project/features heeft als sterkte om datastructuren te exporteren dat in de database voorkomt als code. Dit is handig omdat je veranderingen in de version control kan nagaan en je zo wijzigingen kan herzien. Dit kan echt wel een 'verlosssende' module zijn MAAR hoe er rekening mee dat het niet alle datastructuren ondersteunt. Het onderstuent menu's, permissies, inhoud types, views, displays, regels, ... (lees de project pagina voor meer) Gebruik dus feautures voor de datastructuren die het ondersteunt. Hopelijk zullen alle datastructuren in drupal worden ondersteund. Dit enkel is nodig opdat Drupal's staging probleem zou kunnen worden opgelost.
Hoe werkt het? Installeer het, creëer één of meer features, exporteer deze en wanneer je updates in je datastructuur hebt zullen deze worden getoond.
Gebruik drush fu [name-feature] om deze te updaten, voeg deze to aan jouw repository. Wanneer nu de svn up on downstream omgevingen gebeurt zal jouw site gebruikmaken van deze nieuwe datastructuren.

Deploy
Je herkent deze van hierboven, gebruik het als je inhoud hebt ontwikkeld. Een rollback systeem is geïnstalleerd, dus om terug te gaan moet je de gecreërde inhoud manueel verwijderen. De reden waarom ik er geen gebruik van maak voor het transfereren van instellingen, views en dergelijk is omdat er geen rollback functie is.

Hook update
Gebruik http://api.drupal.org/api/function/hook_update_N/6 wanneer veranderingen niet kunnen worden gedaan door de twee vorige.
Een voorbeeld hiervan is een custom of contrib datastructuur dat in de database zit en dat niet kan worden geëxporteerd voor instellingen of deploy. Als je een rollback wenst zal je het zelf moeten schrijven met een extra hook_update. Hopelijk hoef je dit niet al te vaak te doen :)

Hook update wordt ook gebruikt voor omgevingsspecifieke updates. Bijvoorbeeld, je wil niet dat devel mogelijk is bij productie.
In settings.php configureer je een omgevingsvariabele. Omdat settings.php verschillend is in iedere omgeving configureer je zodat Drupal weet om welke omgeving het gaat. Een voorbeeld van productie in settings.php.

<?php
$conf
['environment'] = 'production';
?>

In hook_update maak je nu:

<?php
function module_update_6001() {
  if (
variable_get('environment''dev') == 'production') {
    
module_disable(array('devel'));
  }

  return array();
}
?>

Conclusie
Het belangrijkste is elke keer je de database verandert, om de gewoonte te kweken om deze veranderingen in de code te brengen. Gebruik maken van bovenstaande strategie zal meer tijd vragen wanneer er meer hook updates nodig zijn. Het zal zelf meer tijd vragen wanneer er rollback aanwezig zijn. Maar het zal je ook meer controle geven.

Het komt dus neer op een afweging tussen enerzijds meer controle en anderzijds meer ontwikkelingstijd. Het zou voor iedereen duidelijk moeten zijn -van client, project manager tot ontwikkelaar en maintainer- dat het installeren en onderhouden van deze workflow in een project veel tijd vraagt.

Toekomst
De echte oplossing voor dit probleem ligt in het gebrek aan steun vanuit de core. Een core systeem dat alle datastructuren registreet en een stage inhoudsmarkering zouden moeten worden uitgewerkt. Dit systeem zou in staat moeten zijn om verbinding te maken met alle soorten omgevingen en om de status van de inhoud en structuren te tonen. In dit geval zouden releases kunnen worden gepland, uitgevoerd, teruggeroepen, logged etc
Dan natuurlijk kunnen alle contrib modules bijdragende structuren integreren met dit core systeem :)

Momenteel lijkt het dat dergelijk systeem nog niet voor direct zal zijn. Ik geloof echter dat features dichter komen aan te leunen voor configuraties en datastructuren en deploy dichter zal komen aan te leunen bij inhoud. Ik vrees dat we het moet hook update zullen moeten uitroeien voor de volgende jaren.

Reactie toevoegen