Encapsulates an update file (.phar or .zip)
Beispiel #1
0
 /**
  * Install the new version
  *
  * If we get to this point:
  *
  * 1. We know the signature is signed by the supplier.
  * 2. The hash was checked into Keyggdrasil, which
  *    was independently vouched for by our peers.
  *
  * @param UpdateInfo $info (part of definition but not used here)
  * @param UpdateFile $file
  * @throws CouldNotUpdate
  * @throws MotifZipFailed
  */
 protected function install(UpdateInfo $info, UpdateFile $file)
 {
     if (!$file->hashMatches($info->getChecksum())) {
         throw new CouldNotUpdate(\__('Checksum mismatched'));
     }
     // Let's open the update package:
     $path = $file->getPath();
     $zip = new \ZipArchive();
     $res = $zip->open($path);
     if ($res !== true) {
         throw new MotifZipFailed(\__("ZIP Error: %s", "default", $res));
     }
     $dir = \implode(DIRECTORY_SEPARATOR, [ROOT, 'Motifs', $this->supplier->getName(), $this->name]);
     // Extract the new files to the current directory
     if (!$zip->extractTo($dir)) {
         throw new CouldNotUpdate();
     }
     // Make sure we update the version info. in the DB cache:
     $this->updateDBRecord('Motif', $info);
     self::$continuumLogger->store(LogLevel::INFO, 'Motif update installed', $this->getLogContext($info, $file));
 }
Beispiel #2
0
 /**
  * Install an updated version of a cabin
  *
  * If we get to this point:
  *
  * 1. We know the signature is signed by the supplier.
  * 2. The hash was checked into Keyggdrasil, which
  *    was independently vouched for by our peers.
  *
  * @param UpdateInfo $info
  * @param UpdateFile $file
  * @throws CouldNotUpdate
  */
 protected function install(UpdateInfo $info, UpdateFile $file)
 {
     if (!$file->hashMatches($info->getChecksum())) {
         throw new CouldNotUpdate(\__('Checksum mismatched'));
     }
     $path = $file->getPath();
     $this->log('Begin Cabin updater', LogLevel::DEBUG, ['path' => $path, 'supplier' => $info->getSupplierName(), 'name' => $info->getPackageName()]);
     $updater = new \Phar($path, \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME);
     $updater->setAlias($this->pharAlias);
     $ns = $this->makeNamespace($info->getSupplierName(), $info->getPackageName());
     // We need to do this while we're replacing files.
     $this->bringCabinDown($ns);
     $oldMetadata = \Airship\loadJSON(ROOT . '/Cabin/' . $ns . '/manifest.json');
     // Overwrite files
     $updater->extractTo(ROOT . '/Cabin/' . $ns, null, true);
     // Run the update trigger.
     Sandbox::safeInclude('phar://' . $this->pharAlias . '/update_trigger.php', $oldMetadata);
     // Free up the updater alias
     $garbageAlias = Base64UrlSafe::encode(\random_bytes(33)) . '.phar';
     $updater->setAlias($garbageAlias);
     unset($updater);
     // Now bring it back up.
     $this->bringCabinBackUp($ns);
     // Make sure we update the version info. in the DB cache:
     $this->updateDBRecord('Cabin', $info);
     $this->log('Conclude Cabin updater', LogLevel::DEBUG, ['path' => $path, 'supplier' => $info->getSupplierName(), 'name' => $info->getPackageName()]);
     self::$continuumLogger->store(LogLevel::INFO, 'Cabin update installed', $this->getLogContext($info, $file));
 }
Beispiel #3
0
 /**
  * Let's install the automatic update.
  *
  * If we get to this point:
  *
  * 1. We know the signature is signed by
  *    Paragon Initiative Enterprises, LLC.
  * 2. The hash was checked into Keyggdrasil, which
  *    was independently vouched for by our peers.
  *
  * @param UpdateInfo $info
  * @param UpdateFile $file
  * @throws CouldNotUpdate
  */
 protected function install(UpdateInfo $info, UpdateFile $file)
 {
     if (!$file->hashMatches($info->getChecksum())) {
         throw new CouldNotUpdate(\__('Checksum mismatched'));
     }
     // Let's open the update package:
     $path = $file->getPath();
     $updater = new \Phar($path, \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME);
     $updater->setAlias($this->pharAlias);
     $metadata = $updater->getMetadata();
     // We need to do this while we're replacing files.
     $this->bringSiteDown();
     if (isset($metadata['files'])) {
         foreach ($metadata['files'] as $fileName) {
             $this->replaceFile($fileName);
         }
     }
     if (isset($metadata['autoRun'])) {
         foreach ($metadata['autoRun'] as $autoRun) {
             $this->autoRunScript($autoRun);
         }
     }
     // If we included composer.lock, we need to install the dependencies.
     if (\in_array('composer.lock', $metadata['files'])) {
         $composers = ['/usr/bin/composer', '/usr/bin/composer.phar', \dirname(ROOT) . '/composer', \dirname(ROOT) . '/composer.phar'];
         $composerUpdated = false;
         foreach ($composers as $composer) {
             if (\file_exists($composer)) {
                 $dir = \getcwd();
                 \chdir(\dirname(ROOT));
                 \shell_exec("{$composer} install");
                 \chdir($dir);
                 $composerUpdated = true;
                 break;
             }
         }
         if (!$composerUpdated) {
             self::$continuumLogger->store(LogLevel::INFO, 'Could not update dependencies. Please run Composer manually.', $this->getLogContext($info, $file));
         }
     }
     // Free up the updater alias
     $garbageAlias = Base64UrlSafe::encode(\random_bytes(63)) . '.phar';
     $updater->setAlias($garbageAlias);
     unset($updater);
     // Now bring it back up.
     $this->bringSiteBackUp();
     self::$continuumLogger->store(LogLevel::INFO, 'CMS Airship core update installed', $this->getLogContext($info, $file));
 }
Beispiel #4
0
 /**
  * We just need to replace the Phar
  *
  * If we get to this point:
  *
  * 1. We know the signature is signed by the supplier.
  * 2. The hash was checked into Keyggdrasil, which
  *    was independently vouched for by our peers.
  *
  * @param UpdateInfo $info
  * @param UpdateFile $file
  * @throws CouldNotUpdate
  */
 protected function install(UpdateInfo $info, UpdateFile $file)
 {
     if (!$file->hashMatches($info->getChecksum())) {
         throw new CouldNotUpdate(\__('Checksum mismatched'));
     }
     // Create a backup of the old Gadget:
     \rename($this->filePath, $this->filePath . '.backup');
     \rename($file->getPath(), $this->filePath);
     $this->log('Begin install process', LogLevel::DEBUG, ['path' => $file->getPath(), 'hash' => $file->getHash(), 'version' => $file->getVersion(), 'size' => $file->getSize()]);
     // Get metadata from the old version of this Gadget:
     $oldAlias = Base64UrlSafe::encode(\random_bytes(48)) . '.phar';
     $oldGadget = new \Phar($this->filePath, \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME);
     $oldGadget->setAlias($oldAlias);
     $oldMetadata = $oldGadget->getMetadata();
     unset($oldGadget);
     unset($oldAlias);
     // Let's open the update package:
     $newGadget = new \Phar($this->filePath, \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME, $this->pharAlias);
     $newGadget->setAlias($this->pharAlias);
     $metaData = $newGadget->getMetadata();
     // We need to do this while we're replacing files.
     $this->bringSiteDown();
     Sandbox::safeRequire('phar://' . $this->pharAlias . '/update_trigger.php', $oldMetadata);
     // Free up the updater alias
     $garbageAlias = Base64UrlSafe::encode(\random_bytes(48)) . '.phar';
     $newGadget->setAlias($garbageAlias);
     unset($newGadget);
     // Now bring it back up.
     $this->bringSiteBackUp();
     // Make sure we update the version info. in the DB cache:
     $this->updateDBRecord('Gadget', $info);
     if ($metaData) {
         $this->updateJSON($info, $metaData);
     }
     self::$continuumLogger->store(LogLevel::INFO, 'Gadget update installed', $this->getLogContext($info, $file));
 }