/** * Restore the configuration. Depending on reset-configuration this is going to replace the * original files with the backup, otherwise it will create a restored-configuration folder the * configuration directories. * * <p>TODO log a warning if the restored configuration files are different from the current one? * or should we check that before rolling back the patch to give the user a chance to save the * changes * * @param rollingBackPatchID the patch id * @param resetConfiguration whether to override the configuration files or not * @throws IOException for any error */ void restoreConfiguration(final String rollingBackPatchID, final boolean resetConfiguration) throws IOException { final File backupConfigurationDir = new File(installedImage.getPatchHistoryDir(rollingBackPatchID), Constants.CONFIGURATION); final File ba = new File(backupConfigurationDir, Constants.APP_CLIENT); final File bd = new File(backupConfigurationDir, Constants.DOMAIN); final File bs = new File(backupConfigurationDir, Constants.STANDALONE); final String configuration; if (resetConfiguration) { configuration = Constants.CONFIGURATION; } else { configuration = Constants.CONFIGURATION + File.separator + Constants.RESTORED_CONFIGURATION; } if (ba.exists()) { final File a = new File(installedImage.getAppClientDir(), configuration); backupDirectory(ba, a); } if (bd.exists()) { final File d = new File(installedImage.getDomainDir(), configuration); backupDirectory(bd, d); } if (bs.exists()) { final File s = new File(installedImage.getStandaloneDir(), configuration); backupDirectory(bs, s); } }
/** * Add a rollback loader for a give patch. * * @param patchId the patch id. * @param target the patchable target * @throws XMLStreamException * @throws IOException */ private void recordRollbackLoader(final String patchId, PatchableTarget.TargetInfo target) { // setup the content loader paths final DirectoryStructure structure = target.getDirectoryStructure(); final InstalledImage image = structure.getInstalledImage(); final File historyDir = image.getPatchHistoryDir(patchId); final File miscRoot = new File(historyDir, PatchContentLoader.MISC); final File modulesRoot = structure.getModulePatchDirectory(patchId); final File bundlesRoot = structure.getBundlesPatchDirectory(patchId); final PatchContentLoader loader = PatchContentLoader.create(miscRoot, bundlesRoot, modulesRoot); // recordContentLoader(patchId, loader); }
IdentityPatchContext( final File backup, final PatchContentProvider contentProvider, final ContentVerificationPolicy contentPolicy, final InstallationManager.InstallationModification modification, final PatchingTaskContext.Mode mode, final InstalledImage installedImage) { this.miscTargetRoot = installedImage.getJbossHome(); this.mode = mode; this.contentProvider = contentProvider; this.contentPolicy = contentPolicy; this.modification = modification; this.installedImage = installedImage; this.history = PatchingHistory.Factory.getHistory(modification.getUnmodifiedInstallationState()); if (backup != null) { this.miscBackup = new File(backup, PatchContentLoader.MISC); this.configBackup = new File(backup, Constants.CONFIGURATION); } else { this.miscBackup = null; // This will trigger a failure when the root is actually needed this.configBackup = null; } this.identityEntry = new PatchEntry(modification, null); }
/** * Backup the current configuration as part of the patch history. * * @throws IOException for any error */ void backupConfiguration() throws IOException { final String configuration = Constants.CONFIGURATION; final File a = new File(installedImage.getAppClientDir(), configuration); final File d = new File(installedImage.getDomainDir(), configuration); final File s = new File(installedImage.getStandaloneDir(), configuration); if (a.exists()) { final File ab = new File(configBackup, Constants.APP_CLIENT); backupDirectory(a, ab); } if (d.exists()) { final File db = new File(configBackup, Constants.DOMAIN); backupDirectory(d, db); } if (s.exists()) { final File sb = new File(configBackup, Constants.STANDALONE); backupDirectory(s, sb); } }
/** * Complete the current operation and persist the current state to the disk. This will also * trigger the invalidation of outdated modules. * * @param modification the current modification * @param callback the completion callback */ private void complete( final InstallationManager.InstallationModification modification, final FinalizeCallback callback) { final List<File> processed = new ArrayList<File>(); try { try { // Update the state to invalidate and process module resources if (stateUpdater.compareAndSet(this, State.PREPARED, State.INVALIDATE) && mode == PatchingTaskContext.Mode.APPLY) { // Only invalidate modules when applying patches; on rollback files are immediately // restored for (final File invalidation : moduleInvalidations) { processed.add(invalidation); PatchModuleInvalidationUtils.processFile(invalidation, mode); } } modification.complete(); callback.completed(this); state = State.COMPLETED; } catch (Exception e) { this.moduleInvalidations.clear(); this.moduleInvalidations.addAll(processed); throw new RuntimeException(e); } } finally { if (state != State.COMPLETED) { try { modification.cancel(); } finally { try { undoChanges(); } finally { callback.operationCancelled(this); } } } else { try { if (checkForGarbageOnRestart) { final File cleanupMarker = new File(installedImage.getInstallationMetadata(), "cleanup-patching-dirs"); cleanupMarker.createNewFile(); } } catch (IOException e) { PatchLogger.ROOT_LOGGER.infof(e, "failed to create cleanup marker"); } } } }