2011-09-26 18 views
9

Sto provando a configurare Capistrano per eseguire la stessa operazione su due server diversi, ognuno con credenziali diverse. Mi piacerebbe fare qualcosa simili a:Come posso accedere alle opzioni specifiche del server in Capistrano?

namespace :deploy do 
    role :db, "192.168.1.1", :credentials => "db1.yml" 
    role :db, "192.168.1.1", :credentials => "db2.yml" 

    task :mytask, :roles => :db do 
    credentials = YAML.load_file(something) 
    ... 

è possibile? Cosa devo sostituire con something con, per accedere alla configurazione attuale del server?

risposta

12

OK, ho finalmente avuto un po 'di tempo per risolvere questo. Speriamo che qualcun altro trovi utile questa risposta. Ecco come ho finalmente risolto il problema:

role :db, "db1" ,{ :credentials => 'db1-credentials'}      
role :db, "db2" ,{ :credentials => 'db2-credentials'}      
role :db, "db3" 

namespace :stackoverflow do 

    # Don't run this task on host that don't have credentials defined 
    task :default, {:role => :db, :except => {:credentials => nil } } do 
    servers = find_servers_for_task(current_task) 
    servers.each do |server| 
     credentials = server.options[:credentials] 

     puts credentials # actual task 

    end 
    end 
end 

Vedo ora che io possa aver dichiarato la questione in un modo confuso - è perché non avevo capito, questo compito vengono eseguiti contemporaneamente.

Questo infatti eseguirà l'attività (qui puts credentials) una volta per ciascun server, che era quello che stavo cercando di fare.

uscita:

$ cap stackoverflow 
    * executing `stackoverflow' 
db1-credentials 
db2-credentials 

E 'una buona idea quella di aggiungere un filtro a un'attività in modo che non verrà eseguito se il server non dispone di credenziali.

Detto questo, far sì che tutti i membri del team mantengano le credenziali attuali (e per ragioni di sicurezza non in versione) su tutti i server si è rivelato troppo complicato (vanificando così l'idea di utilizzare Capistrano). Ora invece di mantenere la configurazione esterna sui dischi degli utenti, manterrò i dati sui server interessati (principalmente sotto forma di script eseguibili con tutte le credenziali nascoste all'interno).Come questo:

task :dump {:role => :db} do 
    run "/root/dump_db.sh | gzip > /tmp/dump.sql.gz" 
    download "/tmp/dump.sql.gz", "somewhere" 
end 
+2

Ho cercato come fare 'find_servers_for_task (current_task)' per ore. Grazie mille. – aceofspades

1

È possibile utilizzare capistrano in configurazione multi-ambiente.

È possibile richiedere Capistrano gemma più stadi che nel file di deploy.rb come -

require 'capistrano/ext/multistage' 

Per questo si lavora è necessario gemma Capistrano-ext pure. Dopo questo, è possibile impostare due ambienti come -

set :stages, %w(staging production) 
set :default_stage, "staging" 

Dopo di che, all'interno del vostro deploy/production.rb e distribuire file/staging.rb, è possibile utilizzare le configurazioni che si differenziano sia per il server. Tutte le configurazioni comuni andranno nel file deploy.rb.

+0

Non è quello che sto cercando. Sto già usando capistrano multistage. Voglio avere due server database definiti per una singola fase (ad esempio database primario e secondario, e ho bisogno di scaricare il database di staging in entrambi). – Barnaba

+0

Vedendo come è possibile chiamare l'attività di una fase da un'altra fase immagino sia un'opzione valida (potrei creare stage 'generali' che chiamano attività di altri stadi, ognuno contenente un server DB e la sua configurazione). – Barnaba

3

Sto lavorando a questo problema al momento. La funzione 'parallela' non ti dà l'opportunità di modificare la riga di comando che viene eseguita, ma ti dà la possibilità di avere linee di comando alternative a seconda delle opzioni del server. Sto pensando di fare una patch di scimmia sulla funzione replace-placeholders in command.rb. Solo avere $ CAPISTRANO: HOST $ come opzione sembra molto limitante. Mi chiedo quanto il caos sarebbe stato causato da solo facendo il seguente:

module Capistrano 
    module Command 
     class Tree 
      def replace_placeholders(command, channel) 
       server = channel[:server] 
       command.eval(command) 
      end 
     end 
    end 
end 

In teoria ora si potrebbe fare questo:

role :whatever, "myserver.com", :special_feature => "foo" 

run "do-something #{server.options[:special_feature]}" 

il codice potrebbe sopra necessita di alcuni lavori.

+0

Qualunque stato/problema GitHub relativo a Capistrano per questa funzione? È oltre utile quando si desidera avere configurazioni di opzioni del server (come "quanti processi di lavoro voglio eseguire"). – ghayes

1

Se si desidera veramente utilizzare le opzioni del server su comandi remoti è ancora possibile utilizzare find_servers_for_task senza patch è:

server 'server-one', :db, :credentials => 'cred1.yml' 
server 'server-two', :db, :credentials => 'cred2.yml' 

namespace :stackoverflow do 
    task :default, :roles => :db do 
    find_servers_for_task(current_task).each do |server| 
     run "start_your_db -C#{server.options[:credentials]}", :hosts => server.name 
    end 
    end 
end 

Ma la :hosts sul comando run è essenziale, come i comandi Capistrano verrà eseguito in parallelo e senza eseguire due comandi su ciascun server in questo esempio.

Problemi correlati