Skip to content
Browse files

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.
  • Loading branch information...
1 parent d8201d4 commit 203b4321597f3c4507672a32c2ae84728c63473c @mudrd8mz mudrd8mz committed Mar 14, 2013
Showing with 90 additions and 6 deletions.
  1. +74 −6 mdeploy.php
  2. +16 −0 mdeploytest.php
View
80 mdeploy.php
@@ -775,7 +775,53 @@ public function execute() {
$this->done();
} 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.
@@ -1126,18 +1172,36 @@ protected function move_directory_source_precheck($source) {
}
/**
- * 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
* @return bool
*/
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;
}
- $result = mkdir($target, 02777) && rmdir($target);
+ $result = mkdir($path, 02777) && rmdir($path);
return $result;
}
@@ -1273,7 +1337,9 @@ protected function unzip_plugin($ziplocation, $plugintyperoot, $expectedlocation
$result = $zip->open($ziplocation);
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');
}
@@ -1292,7 +1358,9 @@ protected function unzip_plugin($ziplocation, $plugintyperoot, $expectedlocation
if (!$zip->extractTo($plugintyperoot)) {
$zip->close();
$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');
}
View
16 mdeploytest.php
@@ -106,6 +106,13 @@ public function move_directory($source, $target, $keepsourceroot = false) {
public function remove_directory($path, $keeppathroot = false) {
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 @@ public function test_moving_and_removing_directories() {
$this->assertTrue($worker->remove_directory($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.
+ }
}

0 comments on commit 203b432

Please sign in to comment.
Something went wrong with that request. Please try again.