/**
* 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));
}