lundi 24 août 2015

Capistrano Deploy, access ActiveRecord

Okay,

I'm sorry if the title is not descriptive enough, but allow me to explain what I want to achieve:

  • I have a Rails 3 application
  • During my deploy, it needs to call pg_dump with the correct parameters to restore a backup
  • The task needs to be ran after the deploy is done but before the migrations.

The problem I have however, is that for this task, I would like to access Rails specific code, which is not working as Capistrano keeps throwing a lot of errors at me like gems not available or module not defined.

This is my Rake task:

namespace :deploy do
  namespace :rm do
    desc 'Backup the database'
    task :backup do

      # Generates the command to invoke the Rails runner
      # Used by the cfg method to execute the ActiveRecord configuration in the rails config.
      def runner
        dir = "#{fetch(:deploy_to)}/current"
        bundler = "#{SSHKit.config.command_map.prefix[:bundle].first} bundle exec"
        env = fetch(:rails_env)
        "cd #{dir}; #{bundler} rails r -e #{env}"
      end

      def cfg(name)
        env = fetch(:rails_env)
        command = "\"puts ActiveRecord::Base.configurations['#{env}']['#{name}']\""
        "#{runner} #{command}"
      end

      on roles(:db) do
        timestamp = Time.now.strftime('%Y%m%d%H%M%S')
        backups = File.expand_path(File.join(fetch(:deploy_to), '..', 'backups'))
        execute :mkdir, '-p', backups
        dump = "PGPASSWORD=`#{cfg('password')}` pg_dump -h `#{cfg'host')}` -U `#{cfg('username')}` `#{cfg('database')}`"
        fn = "#{timestamp}_#{fetch(:stage)}.sql.gz"
        path = File.join(backups, fn)
        execute "#{dump} | gzip > #{path}"
      end
    end
  end
end

In it's current form, it simply generates a string with the runner method and dumps that inside the cfg method.

I tried rewriting the runner method, but for some reason I keep getting the runner --help output from the remote server, but the command being generated in the output is correct, and works locally just fine.

We are using Ruby 2.2.2 and RVM on the remote server. Is it even possible to do what we are trying to construct together?

Aucun commentaire:

Enregistrer un commentaire