2011-09-26 22 views
9

Tôi đang cố định cấu hình Capistrano để thực hiện tác vụ tương tự trên hai máy chủ khác nhau, mỗi máy chủ có các thông tin đăng nhập khác nhau. Tôi muốn làm điều gì đó tương tự như:Làm thế nào tôi có thể truy cập các tùy chọn máy chủ cụ thể trong 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) 
    ... 

Điều đó có thể? Tôi nên thay thế something bằng cách nào, để truy cập cấu hình máy chủ hiện tại?

Trả lời

12

OK, cuối cùng tôi đã có thời gian để giải quyết vấn đề này. Hy vọng rằng ai đó sẽ tìm thấy câu trả lời này hữu ích. Đây là cách tôi cuối cùng đã giải quyết được vấn đề:

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 

Tôi thấy rằng tôi có thể đã nêu câu hỏi theo cách khó hiểu - đó là vì tôi chưa hiểu, nhiệm vụ đó được chạy đồng thời.

Điều này thực tế sẽ thực hiện tác vụ (ở đây puts credentials) một lần cho mỗi máy chủ, đó là những gì tôi đã cố gắng thực hiện.

Output:

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

Đó là một ý tưởng tốt để thêm một bộ lọc để một công việc vì vậy nó sẽ không chạy nếu máy chủ không có thông tin. Điều đó đang được nói, khiến mọi người trong nhóm duy trì thông tin đăng nhập hiện tại (và vì lý do bảo mật không được phiên bản) cho tất cả các máy chủ hóa ra là quá phức tạp (do đó đánh bại ý tưởng sử dụng Capistrano). Bây giờ thay vì giữ cấu hình bên ngoài trên các đĩa của người dùng, tôi sẽ giữ dữ liệu trên các máy chủ bị ảnh hưởng (chủ yếu ở dạng các kịch bản chạy được với tất cả các thông tin ẩn bên trong).Như thế này:

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

Tôi đã tìm kiếm cách thực hiện 'find_servers_for_task (current_task)' trong nhiều giờ. Cảm ơn nhiều. – aceofspades

1

Bạn có thể sử dụng capistrano trong cài đặt đa môi trường.

Bạn có thể yêu cầu đá quý nhiều tầng capistrano rằng trong tập tin deploy.rb như -

require 'capistrano/ext/multistage' 

Đối với điều này bạn làm việc bạn cần phải đá quý capistrano-ext là tốt. Sau đó, bạn có thể thiết lập hai môi trường như -

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

Sau đó, bên trong triển khai của bạn/production.rb và triển khai/file staging.rb, bạn có thể sử dụng các cấu hình mà là khác nhau cho cả máy chủ. Tất cả các cấu hình phổ biến sẽ đi vào bên trong tệp deploy.rb.

+0

Đó không phải là những gì tôi đang tìm kiếm. Tôi đã sử dụng multistage capistrano. Tôi muốn có hai máy chủ cơ sở dữ liệu được xác định cho một giai đoạn duy nhất (ví dụ: cơ sở dữ liệu chính và cơ sở dữ liệu phụ, và tôi cần phải kết xuất cơ sở dữ liệu dàn dựng vào cả hai). – Barnaba

+0

Xem cách thực hiện nhiệm vụ của một giai đoạn từ một giai đoạn khác, tôi đoán đó là lựa chọn khả thi (tôi có thể tạo giai đoạn 'chung' gọi các nhiệm vụ của các giai đoạn khác, mỗi nhiệm vụ chứa một máy chủ db và cấu hình của nó). – Barnaba

3

Tôi đang khắc phục sự cố này vào lúc này. Hàm 'song song' không cho bạn cơ hội sửa đổi dòng lệnh đang được thực thi, nhưng nó cho bạn khả năng có các dòng lệnh thay thế tùy thuộc vào các tùy chọn máy chủ. Tôi đang nghĩ về việc làm một miếng vá khỉ trên hàm thay thế chỗ dành sẵn trong command.rb. Chỉ có $ CAPISTRANO: HOST $ là một tùy chọn có vẻ rất hạn chế. Tôi tự hỏi có bao nhiêu hỗn loạn sẽ được gây ra bởi chỉ cách làm như sau:

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

Về lý thuyết, bây giờ bạn có thể làm điều này:

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

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

Mã sức trên cần một số công việc.

+0

Bất kỳ trạng thái/vấn đề GitHub nào liên quan đến Capistrano cho tính năng này? Nó rất hữu ích khi bạn muốn có cấu hình tùy chọn máy chủ (chẳng hạn như "có bao nhiêu quy trình công nhân tôi muốn chạy"). – ghayes

1

Nếu bạn thực sự muốn sử dụng tùy chọn của máy chủ trên các lệnh từ xa mà bạn vẫn có thể sử dụng find_servers_for_task mà không vá nó:

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 

Nhưng :hosts trên lệnh run là điều cần thiết, như lệnh Capistrano sẽ thực hiện song song và không có nó sẽ thực hiện hai lệnh trên mỗi máy chủ trong ví dụ này.

Các vấn đề liên quan