I'm not a Ruby guy, but I managed to get the chef to import a large .sql
file using the mysql
command-line tool. The tasks that I need to solve:
- Import
.sql
file into 100 MB ranges (YMMV if you need GB or TB) - Idempotentcy - only import if
.sql
file .sql
changed - Do not pass MySQL credentials as command parameters (security issue)
First, I created a .my.cnf
file .my.cnf
for transferring credentials:
Templates / default /.my.cnf.erb
[client] host=<%= @host %> user=<%= @user %> password="<%= @password %>"
Then I added a resource to my recipe that would populate the template:
Recipes / Import-db.rb
template '/root/.my.cnf' do mode 0600 variables({ :host => 'localhost', :user => 'root', :password => node[:your_cookbook][:db][:root_password], }) end
(Where node[:your_cookbook][:db][:root_password]
is the attribute containing the MySQL administrator password)
Safety note . For simplicity, I am importing as a root
. If the .sql
file you want to import is not from a reliable source, you want to start mysql
as a limited user and connect to MySQL with a limited user db, which has access only to the corresponding database.
Finally, I added another resource to the recipe that actually imports:
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
(Where node[:your_cookbook][:db][:name]
is the name of the MySQL database to be restored.)
Michael kropat
source share