| 1 |
<?php
|
| 2 |
|
| 3 |
function drush_provision_mysql_pre_provision_backup($url = NULL) {
|
| 4 |
# set the umask to 077 so that the dump itself is generated so it's non-readable by the webserver
|
| 5 |
umask(0077);
|
| 6 |
drush_log("Generating mysql dump for $url.", 'backup');
|
| 7 |
# mixed copy-paste of drush_shell_exec and provision_shell_exec
|
| 8 |
$cmd = sprintf("mysqldump --defaults-file=/dev/fd/3 -rsites/%s/database.sql %s", escapeshellcmd($url), escapeshellcmd(drush_get_option('db_name')));
|
| 9 |
drush_log($cmd);
|
| 10 |
if (drush_get_context('DRUSH_VERBOSE') || drush_get_context('DRUSH_SIMULATE')) {
|
| 11 |
drush_print('Executing: ' . $cmd, $indent);
|
| 12 |
}
|
| 13 |
|
| 14 |
if (drush_get_context('DRUSH_SIMULATE')) {
|
| 15 |
return true;
|
| 16 |
}
|
| 17 |
|
| 18 |
# pipe handling code
|
| 19 |
# we go through all this trouble to hide the password from the commandline, it's the most secure way (apart from writing a temporary file, which would create conflicts in parallel runs)
|
| 20 |
$mycnf = sprintf('[client]
|
| 21 |
host=%s
|
| 22 |
user=%s
|
| 23 |
password=%s
|
| 24 |
', drush_get_option('db_host'), drush_get_option('db_user'), drush_get_option('db_passwd'));
|
| 25 |
|
| 26 |
$descriptorspec = array(
|
| 27 |
// 0 => array("pipe", "r"), // this would be stdin, but we don't need to input into mysqldump
|
| 28 |
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
|
| 29 |
2 => array("pipe", "w"), // stderr is a file to write to
|
| 30 |
3 => array("pipe", "r"), // fd3 is our special file descriptor where we pass credentials
|
| 31 |
);
|
| 32 |
|
| 33 |
$process = proc_open($cmd, $descriptorspec, $pipes);
|
| 34 |
|
| 35 |
$output = array();
|
| 36 |
if (is_resource($process)) {
|
| 37 |
fwrite($pipes[3], $mycnf);
|
| 38 |
fclose($pipes[3]);
|
| 39 |
|
| 40 |
$output = array_filter(array_merge(explode("\n", stream_get_contents($pipes[1])), explode("\n", stream_get_contents($pipes[2]))));
|
| 41 |
// "It is important that you close any pipes before calling
|
| 42 |
// proc_close in order to avoid a deadlock"
|
| 43 |
fclose($pipes[1]);
|
| 44 |
fclose($pipes[2]);
|
| 45 |
$return_value = proc_close($process);
|
| 46 |
} else {
|
| 47 |
// XXX: failed to execute? unsure when this happens
|
| 48 |
$return_value = -1;
|
| 49 |
}
|
| 50 |
|
| 51 |
# resuming drush_exec copy/paste
|
| 52 |
$indent = 0;
|
| 53 |
|
| 54 |
_drush_shell_exec_output_set($output);
|
| 55 |
|
| 56 |
if (drush_get_context('DRUSH_VERBOSE')) {
|
| 57 |
foreach ($output as $line) {
|
| 58 |
drush_print($line, $indent + 2);
|
| 59 |
}
|
| 60 |
}
|
| 61 |
|
| 62 |
$result = ($return_value == 0);
|
| 63 |
if (!$result && !drush_get_option('force', false)) {
|
| 64 |
drush_set_error('PROVISION_BACKUP_FAILED', dt("Could not generate database backup from mysqldump"));
|
| 65 |
}
|
| 66 |
# reset the umask to normal permissions
|
| 67 |
umask(0022);
|
| 68 |
}
|
| 69 |
|
| 70 |
function drush_provision_mysql_pre_provision_backup_rollback($url = NULL) {
|
| 71 |
provision_path("unlink", drush_get_option('sites_path') . "/$url/database.sql", TRUE, dt("Deleted mysql dump from sites directory"),
|
| 72 |
dt("Could not delete mysql dump from sites directory"));
|
| 73 |
}
|
| 74 |
|
| 75 |
function drush_provision_mysql_post_provision_backup($url = NULL) {
|
| 76 |
drush_provision_mysql_pre_provision_backup_rollback($url);
|
| 77 |
}
|
| 78 |
|