emyl / vagrant-triggers

Allow the definition of arbitrary scripts that will run on the host before and/or after Vagrant commands.
MIT License
546 stars 35 forks source link

Trying to mysqldump on vagrant halt #51

Closed Twansparant closed 9 years ago

Twansparant commented 9 years ago

Hi there,

I'm trying to achieve a workflow similar to https://github.com/Varying-Vagrant-Vagrants/VVV/ where (if available) the database is imported from a synched folder on vagrant up and exported on vagrant halt, suspend and destroy.

VVV uses an external command from a specific directory /config/homebin/vagrant_halt which referes to another command db_backup in that same directory.

I'm trying to understand how these commands are recognized in their Vagrantfile, because when I try to run the command vagrant_halt in the halt trigger I get an error:

==> default: Running triggers before halt...
==> default: Executing command "vagrant ssh -c vagrant_halt"...
==> default: bash: vagrant_halt: command not found
==> default: Command execution finished.
The command "vagrant ssh -c 'vagrant_halt'" returned a failed exit code. The
error output is shown below:

bash: vagrant_halt: command not found

Which makes sense. So my first question is how can I run a command in the vagrant-triggers that's in a separate command file?

As a workaround I tried to run the db_backup lines directly in the vagrant-trigger like this:

if Vagrant.has_plugin? 'vagrant-triggers'
  config.trigger.before :halt, :stdout => true do
    wordpress_sites.each do |(name, site)|
      db_name  = site['env']['db_name']
      db_user  = site['env']['db_user']
      db_pass  = site['env']['db_password']
      info "Backing up #{db_name}"
      run "vagrant ssh -c mysqldump -u#{db_user} -p#{db_pass} #{db_name} > /srv/database/backups/#{db_name}.sql && echo 'Database #{db_name} backed up';"
    end
  end
else
  puts 'vagrant-triggers missing, please install the plugin:'
  puts 'vagrant plugin install vagrant-triggers'
end

Where db_name, db_user & db_pass are specified in a group_vars/development file. The loop and variables all work, but I keep on getting the following error when running vagrant halt:

==> default: Running triggers before halt...
==> default: Backing up example_dev
==> default: Executing command "vagrant ssh -c mysqldump -uusername -ppassword example_dev > /srv/database/backups/example_dev.sql && echo Database example_dev backed up;"...
==> default: An invalid option was specified. The help for this command
==> default: is available below.
==> default: 
==> default: Usage: vagrant ssh [options] [name] [-- extra ssh args]
==> default: 
==> default: Options:
==> default: 
==> default:     -c, --command COMMAND            Execute an SSH command directly
==> default:     -p, --plain                      Plain mode, leaves authentication up to user
==> default:     -h, --help                       Print this help
==> default: Command execution finished.
The command "vagrant ssh -c mysqldump -uusername -ppassword example_dev > /srv/database/backups/example_dev.sql && echo 'Database example_dev backed up';" returned a failed exit code. The
error output is shown below:

An invalid option was specified. The help for this command
is available below.

Usage: vagrant ssh [options] [name] [-- extra ssh args]

Options:

    -c, --command COMMAND            Execute an SSH command directly
    -p, --plain                      Plain mode, leaves authentication up to user
    -h, --help                       Print this help

What exactly is this invalid option that is specified? I tried running it without the -c flag but that makes no difference.

Thanks for your help!

hallman76 commented 9 years ago

Your second question re: invalid option looks like a quoting issue. The arguments you intend to pass to "mysqldump" are being passed to "vagrant ssh". Try:

run "vagrant ssh -c 'mysqldump -u#{db_user} -p#{db_pass} #{db_name} > /srv/database/backups/#{db_name}.sql'" 

Alternatively, use run_remote(). It's a helper method that vagrant-triggers exposes (see: issue #8).

emyl commented 9 years ago

I agree with @hallman76, run_remote should fit perfectly to your use case.