Я не совсем Ruby, но мне удалось заставить Chef импортировать большой файл .sql
, используя инструмент командной строки mysql
. Задачи, которые мне нужно было решить:
- Импорт файла
.sql
в диапазоне сотен МБ (YMMV, если вам нужны ГБ или ТБ)
- Идемпотентность - запускать импорт можно только в том случае, если файл
.sql
изменился
- Не передавать учетные данные в MySQL в качестве параметров команды (из соображений безопасности)
Сначала я создал .my.cnf
шаблон файла для передачи учетных данных:
шаблоны / по умолчанию / .my.cnf.erb
[client]
host=<%= @host %>
user=<%= @user %>
password="<%= @password %>"
Затем я добавил в свой рецепт ресурс, который будет заполнять шаблон:
Рецепты / импорт-db.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
. Если импортируемый файл .sql
не из надежного источника, вам нужно будет запустить mysql
как пользователь с ограниченными правами и подключиться к 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, которая будет восстановлена.)