使用Ruby / Chef Recipe for Vagrant导入Mysql数据库

我正在编写一个自动设置开发环境的厨师脚本。 我可以创建一个数据库并授予权限,但我试图找到一种方法将mysql转储文件导入刚刚创建的数据库。

我授予访问权限的代码是

ruby_block "Execute grants" do block do require 'rubygems' Gem.clear_paths require 'mysql' m = Mysql.new('localhost', "root", node[:mysql][:server_root_password]) m.query("GRANT ALL ON *.* TO 'root'@'10.0.0.1' IDENTIFIED BY '#{node[:mysql][:server_root_password]}'") m.query('FLUSH PRIVILEGES') end end 

我希望我能够执行以下查询#m.query("-u root -p root db_name < /project/db/import.sql")

但只是给了我一个错误。

我没有做太多的Ruby,所以很难弄明白。 谁知道我怎么做到这一点?

如果它是文件路径错误,并且您正在使用chef solo,请尝试使用solo.rb中指定的路径,例如:

 /tmp/chef-solo/site-cookbooks/path_to_file.sql 

作为一般说明,考虑使用数据库cookbook进行mysql用户和数据库管理任务。 一旦设置了必要的cookbook依赖项,就可以将这样的代码放入主配方的default.rb中

 # externalize conection info in a ruby hash mysql_connection_info = { :host => "localhost", :username => 'root', :password => node['mysql']['server_root_password'] } # drop if exists, then create a mysql database named DB_NAME mysql_database 'DB_NAME' do connection mysql_connection_info action [:drop, :create] end # query a database from a sql script on disk mysql_database "DB_NAME" do connection mysql_connection_info sql { ::File.open("/tmp/chef-solo/site-cookbooks/main/path/to/sql_script.sql").read } action :query end #or import from a dump file mysql_database "DB_NAME" do connection mysql_connection_info sql "source /tmp/chef-solo/site-cookbooks/main/path/to/sql_dump.sql;" end 

没有测试过最后一个,因为在chef目录中存储数据库文件确实减慢了速度。

另请参见:将SQL文件导入mysql

您可以从MySQL命令行客户端创建备份,但不能从SQL查询中创建备份。 您需要从shell执行命令。 我相信execute资源可能会为您解决问题:

http://wiki.opscode.com/display/chef/Resources#Resources-Execute

我不是一个真正的Ruby人,但我设法让Chef通过利用mysql命令行工具导入一个大的.sql文件。 我需要解决的挑战:

  • 导入100 MB范围内的.sql文件(如果需要GB或TB,则为YMMV)
  • Idempotentcy – 仅在.sql文件发生更改时才运行导入
  • 不将凭据作为命令参数传递给MySQL(安全问题)

首先,我创建了一个.my.cnf文件模板来传递凭据:

模板/默认/ .my.cnf.erb

 [client] host=<%= @host %> user=<%= @user %> password="<%= @password %>" 

然后我在我的配方中添加了一个资源来填充模板:

食谱/importdb.rb

 template '/root/.my.cnf' do mode 0600 variables({ :host => 'localhost', :user => 'root', :password => node[:your_cookbook][:db][:root_password], }) end 

(其中node[:your_cookbook][:db][:root_password]是包含MySQL root密码的属性)

安全注意 :为简单起见,我以root用户身份进行导入。 如果要导入的.sql文件不是来自受信任的源,则需要以受限用户身份运行mysql ,并使用只能访问相关数据库的有限db用户连接到MySQL。

最后,我在实际执行导入的配方中添加了另一个资源:

 backup_sql = '/path/to/the/db-backup.sql' db_last_modified = "/etc/db-#{node[:your_cookbook][:db][:name]}.lastmodified" execute 'restore backup' do command "mysql #{node[:your_cookbook][:db][:name]} <'#{backup_sql}' && touch '#{db_last_modified}'" not_if { FileUtils.uptodate?(db_last_modified, [backup_sql]) } end 

(其中node[:your_cookbook][:db][:name]是要恢复的MySQL数据库的名称。)