2015-03-18 9 views
5

Ho un libro di cucina dello Chef, con più ricette, che installa un servizio. Il modo in cui lo chef-cliente funziona, converge ogni 15 minuti (o qualche altro intervallo regolare). In questo momento il primo passo del mio ricettario è quello di interrompere il servizio, quindi il servizio si fermerà ogni 15 minuti, ma voglio davvero evitarlo. Il problema è che il servizio deve essere fermato per alcuni passaggi da eseguire.Con Chef, come eseguire "risorsa 1" prima di "risorsa 2", condizionale all'esecuzione di "risorsa 2"?

Se solo avessi una o due condizioni nelle risorse mie ricette, si potrebbe semplicemente fare:

condition1 = ... # some true/false values 
condition2 = ... # 

service myservice do 
    only_if { condition1 or condition2 } 
    action :stop 
end 

resource1 do 
    only_if { condition1 } 
end 

resource2 do 
    only_if { condition2 } 
end 

Ma, come ho una dozzina di condizioni, in molteplici ricette, diventa poco elegante. C'è un modo per fare ciò che fa questo pseudocodice?

service_resource = service myservice do 
    # somehow don't execute this right now, but wait for 
    # signal from resource1 or resource2 
    action :stop 
end 

resource1 do 
    make sure service_resource executed first 
    only_if { condition1 } 
end 

resource2 do 
    make sure service_resource executed first 
    only_if { condition2 } 
end 

Se ci fosse qualche "Notifica: prima di" meccanismo Chef (invece di esempio "avvisa: subito"), ho potuto utilizzare questo, ma non ho trovato nulla del genere. Qualche idea?

EDIT:

Dopo pensando a questo un po ', un altro modo di farlo, ancora non perfetto, ma meglio, sarebbe sfruttando la fase di compilazione dello Chef definendo un singolo attributo che è sovrascritto. In questo modo, almeno, non dobbiamo mantenere tutte le condizioni in un unico posto.

# in an "attributes" file: 
default["stop_service"] = false 

# in some recipe: 
service myservice do 
    action :stop 
    only_if { node["stop_service"] } 
end 

# ... later, or in some other recipe file 
condition1 = ... # true/false 
if condition1 
    # I think this executes before the only_if of the "service" resource 
    override["stop_service"] = true 
end 

resource1 do 
    only_if { condition1 } 
end 
+1

La maggior parte dei servizi su sistemi operativi UNIX può avere la loro configurazione (o anche codice, purché il gestore di pacchetti locale sostituisca i file creando nuovi inode anziché riscrivere gli inode esistenti per avere nuovi contenuti) aggiornato dal vivo, motivo per cui questo non è È un problema comune: la maggior parte delle volte, non è necessario arrestare un servizio prima che avvenga la riconfigurazione o l'aggiornamento. –

+0

@CharlesDuffy Alla fine forse è quello su cui farò affidamento, ma quello che ho scritto è in realtà una semplificazione: abbiamo un sacco di servizi, e non sono sicuro che tutti possano cambiare la configurazione durante l'esecuzione. Penso che almeno uno di loro ricarica automaticamente la sua configurazione, quindi potrebbe ricaricare mentre sono state applicate solo modifiche parziali.Anche per alcune ricette aggiungiamo/sostituiamo in file esistenti, quindi in questi casi non stiamo usando nuovi inode (se ho capito correttamente cosa intendevi). – fsdj

+1

Dipende esattamente da come funziona la funzionalità append/replace: le implementazioni sicure (quando i dati aggiunti sono più che compatibili in un syscall o quando sono necessarie modifiche sul posto), si scrive un file temporaneo nella stessa directory e rinominandolo sulla destinazione. Ma sì, ha senso che tu voglia fare un riavvio (o un SIGSTOP e SIGCONT, se supportato) attorno alle modifiche di configurazione se vuoi che quelle modifiche siano atomiche, che vengano modificati più file e che venga implementato il comportamento di ricarica automatica. –

risposta

3

Cosa vorrei fare:

fase la configurazione in un luogo "messa in scena", se questo cambiamento, avvisa stop, copiare i file, avviare il servizio.

Qualcosa lungo la linea:

service "my_service" do 
    action :nothing 
end 

template "/staging/conf1" do 
    [... usual attributes ...] 
    notifies :stop,"service[my_service]",:immediately 
end 

template "/staging/conf2" do 
    [... usual attributes ...] 
    notifies :stop,"service[my_service]",:immediately 
end 

remote_file "/opt/my_service/etc/conf1" do 
    source "/staging/conf1" 
    notifies :start,"service[my_service]" # delayed here to allow all conf files to be updated. 
end 

remote_file "/opt/my_service/etc/conf2" do 
    source "/staging/conf2" 
    notifies :start,"service[my_service]" # delayed here to allow all conf files to be updated. 
end 

Il mio gusto personnal va a ciclo su file/template definizione hash per questo tipo di opzione con le stesse risorse come:

node['my_namespace']['conf_files']['conf1'] = "template1" 
node['my_namespace']['conf_files']['conf2'] = "template2" 

e poi loop over con

node['my_namespace']['conf_files'].each do |cfgfile,tmplname| 
    template "/staging/#{cfgfile}" do 
    source tmplname 
    notifies :stop,"service[my_service]",:immediately 
    end 

    remote_file "/opt/my_service/etc/#{cfgfile}" do 
    source "/staging/#{cfgfile}" 
    notifies :start,"service[my_service]" 
    end 
end 

Per casi d'uso più complessi, è possibile utilizzare un hash anche di un singolo valore

Se sono coinvolte più di 2 risorse (eseguendo comandi specifici per il file conf per convalidarlo prima di sostituire quello attuale, ecc.) potrebbe essere adatta una definizione.

Un altro potrebbe essere quello di eseguire tutti i lavori di staging nello load_current_resource di un LWRP, ma potrei andare troppo lontano per il caso d'uso descritto.

+0

Grazie a @Tensibai. Potrebbe funzionare per alcuni tipi di risorse, penso, ma influenza davvero la struttura delle ricette. Sto cercando di evitare cambiamenti così grandi e di mantenere le ricette il più "naturali" possibili, motivo per cui sto cercando qualcosa come "notifiche: prima" (che richiederebbe un po 'di magia con la "coda di risorse dello chef" ... ma se non è nel quadro, non c'è molto da fare). – fsdj

+1

@fsdj Bene il caso è stato discusso [Qui] (https://tickets.opscode.com/browse/CHEF-2421) con alcune prove su di esso. I commenti sul PR collegato nel biglietto dicono il motivo per cui non è in chef in realtà. – Tensibai

+0

Oh wow è esattamente quello che intendevo. Quindi sì, immagino che non sia davvero fattibile in Chef per il momento ("senza un grande refactoring", come dice la PR). Un "dipende" tra le risorse sarebbe stato ancora migliore (per evitare di eseguire il passaggio precedente più volte, come qualcuno menzionato). Grazie mille, eviterete ulteriori scavi inutili. – fsdj

Problemi correlati