mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 21:49:15 +01:00
MDL-38493 Make mdeploy.php able to install new plugin
The patch implements the second mode of the mdeploy.php script. If --install option is passed, the given package is downloaded, verified and deployed to the requested location.
This commit is contained in:
parent
d8201d49d8
commit
203b432159
80
mdeploy.php
80
mdeploy.php
@ -775,7 +775,53 @@ class worker extends singleton_pattern {
|
|||||||
$this->done();
|
$this->done();
|
||||||
|
|
||||||
} else if ($this->input->get_option('install')) {
|
} else if ($this->input->get_option('install')) {
|
||||||
// Installing a new plugin not implemented yet.
|
$this->log('Plugin installation requested');
|
||||||
|
|
||||||
|
$plugintyperoot = $this->input->get_option('typeroot');
|
||||||
|
$pluginname = $this->input->get_option('name');
|
||||||
|
$source = $this->input->get_option('package');
|
||||||
|
$md5remote = $this->input->get_option('md5');
|
||||||
|
|
||||||
|
// Check if the plugin location if available for us.
|
||||||
|
$pluginlocation = $plugintyperoot.'/'.$pluginname;
|
||||||
|
|
||||||
|
$this->log('New plugin code location: '.$pluginlocation);
|
||||||
|
|
||||||
|
if (file_exists($pluginlocation)) {
|
||||||
|
throw new filesystem_exception('Unable to prepare the plugin location (directory already exists)');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->create_directory_precheck($pluginlocation)) {
|
||||||
|
throw new filesystem_exception('Unable to prepare the plugin location (cannot create new directory)');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the ZIP file into a temporary location.
|
||||||
|
$target = $this->target_location($source);
|
||||||
|
$this->log('Downloading package '.$source);
|
||||||
|
|
||||||
|
if ($this->download_file($source, $target)) {
|
||||||
|
$this->log('Package downloaded into '.$target);
|
||||||
|
} else {
|
||||||
|
$this->log('cURL error ' . $this->curlerrno . ' ' . $this->curlerror);
|
||||||
|
$this->log('Unable to download the file');
|
||||||
|
throw new download_file_exception('Unable to download the package');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare MD5 checksum of the ZIP file
|
||||||
|
$md5local = md5_file($target);
|
||||||
|
|
||||||
|
if ($md5local !== $md5remote) {
|
||||||
|
$this->log('MD5 checksum failed. Expected: '.$md5remote.' Got: '.$md5local);
|
||||||
|
throw new checksum_exception('MD5 checksum failed');
|
||||||
|
}
|
||||||
|
$this->log('MD5 checksum ok');
|
||||||
|
|
||||||
|
// Unzip the plugin package file into the plugin location.
|
||||||
|
$this->unzip_plugin($target, $plugintyperoot, $pluginlocation, false);
|
||||||
|
$this->log('Package successfully extracted');
|
||||||
|
|
||||||
|
// Redirect to the given URL (in HTTP) or exit (in CLI).
|
||||||
|
$this->done();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print help in CLI by default.
|
// Print help in CLI by default.
|
||||||
@ -1126,18 +1172,36 @@ class worker extends singleton_pattern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks to see if a source foldr could be safely moved into the given new location
|
* Checks to see if a source folder could be safely moved into the given new location
|
||||||
*
|
*
|
||||||
* @param string $destination full path to the new expected location of a folder
|
* @param string $destination full path to the new expected location of a folder
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function move_directory_target_precheck($target) {
|
protected function move_directory_target_precheck($target) {
|
||||||
|
|
||||||
if (file_exists($target)) {
|
// Check if the target folder does not exist yet, can be created
|
||||||
|
// and removed again.
|
||||||
|
$result = $this->create_directory_precheck($target);
|
||||||
|
|
||||||
|
// At the moment, it seems to be enough to check. We may want to add
|
||||||
|
// more steps in the future.
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure the given directory can be created (and removed)
|
||||||
|
*
|
||||||
|
* @param string $path full path to the folder
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function create_directory_precheck($path) {
|
||||||
|
|
||||||
|
if (file_exists($path)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = mkdir($target, 02777) && rmdir($target);
|
$result = mkdir($path, 02777) && rmdir($path);
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
@ -1273,7 +1337,9 @@ class worker extends singleton_pattern {
|
|||||||
$result = $zip->open($ziplocation);
|
$result = $zip->open($ziplocation);
|
||||||
|
|
||||||
if ($result !== true) {
|
if ($result !== true) {
|
||||||
$this->move_directory($backuplocation, $expectedlocation);
|
if ($backuplocation !== false) {
|
||||||
|
$this->move_directory($backuplocation, $expectedlocation);
|
||||||
|
}
|
||||||
throw new zip_exception('Unable to open the zip package');
|
throw new zip_exception('Unable to open the zip package');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1292,7 +1358,9 @@ class worker extends singleton_pattern {
|
|||||||
if (!$zip->extractTo($plugintyperoot)) {
|
if (!$zip->extractTo($plugintyperoot)) {
|
||||||
$zip->close();
|
$zip->close();
|
||||||
$this->remove_directory($expectedlocation, true); // just in case something was created
|
$this->remove_directory($expectedlocation, true); // just in case something was created
|
||||||
$this->move_directory_into($backuplocation, $expectedlocation);
|
if ($backuplocation !== false) {
|
||||||
|
$this->move_directory_into($backuplocation, $expectedlocation);
|
||||||
|
}
|
||||||
throw new zip_exception('Unable to extract the zip package');
|
throw new zip_exception('Unable to extract the zip package');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +106,13 @@ class testable_worker extends worker {
|
|||||||
public function remove_directory($path, $keeppathroot = false) {
|
public function remove_directory($path, $keeppathroot = false) {
|
||||||
return parent::remove_directory($path, $keeppathroot);
|
return parent::remove_directory($path, $keeppathroot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to the protected method.
|
||||||
|
*/
|
||||||
|
public function create_directory_precheck($path) {
|
||||||
|
return parent::create_directory_precheck($path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -284,4 +291,13 @@ class mdeploytest extends PHPUnit_Framework_TestCase {
|
|||||||
$this->assertTrue($worker->remove_directory($root.'/c'));
|
$this->assertTrue($worker->remove_directory($root.'/c'));
|
||||||
$this->assertFalse(is_dir($root.'/c'));
|
$this->assertFalse(is_dir($root.'/c'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_create_directory_precheck() {
|
||||||
|
$worker = testable_worker::instance();
|
||||||
|
|
||||||
|
$root = sys_get_temp_dir().'/'.uniqid('mdeploytest', true);
|
||||||
|
$this->assertFalse(file_exists($root));
|
||||||
|
$this->assertTrue($worker->create_directory_precheck($root));
|
||||||
|
$this->assertFalse(file_exists($root)); // The precheck is supposed to remove it again.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user