/** * 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)); }
/** * 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)); }
/** * 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)); }
/** * Update the version identifier stored in the gadgets.json file * * @param UpdateInfo $info * @param array $metaData */ public function updateJSON(UpdateInfo $info, array $metaData = []) { if (!empty($metaData['cabin'])) { $gadgetConfigFile = ROOT . '/Cabin/' . $metaData['cabin'] . '/config/gadgets.json'; } else { $gadgetConfigFile = ROOT . '/config/gadgets.json'; } $gadgetConfig = \Airship\loadJSON($gadgetConfigFile); foreach ($gadgetConfig as $i => $gadget) { if ($gadget['supplier'] === $info->getSupplierName()) { if ($gadget['name'] === $info->getPackageName()) { $gadgetConfig[$i]['version'] = $info->getVersion(); break; } } } \Airship\saveJSON($gadgetConfigFile, $gadgetConfig); }