@Override protected PatchableTarget getProvider(final String name, final InstalledIdentity identity) throws OperationFailedException { final AddOn target = identity.getAddOn(name); if (target == null) { throw new OperationFailedException(PatchLogger.ROOT_LOGGER.noSuchLayer(name).getLocalizedMessage()); } return target; } }
protected static InstalledIdentity copy(InstalledIdentity original) throws IOException { final InstalledIdentityImpl copy = new InstalledIdentityImpl(original.getIdentity(), original.getAllInstalledPatches(), original.getInstalledImage()); for (final Layer layer : original.getLayers()) { copy.putLayer(layer.getName(), new LayerInfo(layer.getName(), layer.loadTargetInfo(), layer.getDirectoryStructure())); } for (final AddOn addOn : original.getAddOns()) { copy.putAddOn(addOn.getName(), new LayerInfo(addOn.getName(), addOn.loadTargetInfo(), addOn.getDirectoryStructure())); } return copy; }
@Override protected Layer getProvider(final String name, final InstalledIdentity identity) throws OperationFailedException { final Layer target = identity.getLayer(name); if (target == null) { throw new OperationFailedException(PatchLogger.ROOT_LOGGER.noSuchLayer(name).getLocalizedMessage()); } return target; } }
/** * Load the layers based on the default setup. * * @param jbossHome the jboss home directory * @param productConfig the product config * @param repoRoots the repository roots * @return the available layers * @throws IOException */ public static InstalledIdentity load(final File jbossHome, final ProductConfig productConfig, final File... repoRoots) throws IOException { final InstalledImage installedImage = installedImage(jbossHome); return load(installedImage, productConfig, Arrays.<File>asList(repoRoots), Collections.<File>emptyList()); }
static void writeInstallation(final XMLExtendedStreamWriter writer, final InstalledIdentity identity) throws XMLStreamException { writer.writeStartElement(Element.INSTALLATION.name); // identity writeTargetInfo(writer, Element.IDENTITY, identity.getIdentity()); // layers for (final Layer layer : identity.getLayers()) { writeTargetInfo(writer, Element.LAYER, layer); } // addons for (final AddOn addOn : identity.getAddOns()) { writeTargetInfo(writer, Element.ADD_ON, addOn); } writer.writeEndElement(); }
/** * Load the installation state based on the identity * * @param installedIdentity the installed identity * @return the installation state * @throws IOException */ protected static InstallationModificationImpl.InstallationState load(final InstalledIdentity installedIdentity) throws IOException { final InstallationModificationImpl.InstallationState state = new InstallationModificationImpl.InstallationState(); for (final Layer layer : installedIdentity.getLayers()) { state.putLayer(layer); } for (final AddOn addOn : installedIdentity.getAddOns()) { state.putAddOn(addOn); } return state; }
switch(target) { case LAYER: dirStructure = originalIdentity.getLayer(name).getDirectoryStructure(); break; case ADD_ON: dirStructure = originalIdentity.getAddOn(name).getDirectoryStructure(); break; default: dirStructure = originalIdentity.getIdentity().getDirectoryStructure();
final InstalledIdentity original = copy(this); final Identity identity = original.getIdentity(); final PatchableTarget.TargetInfo identityInfo = identity.loadTargetInfo(); final InstallationModificationImpl.InstallationState state = load(this); return new InstallationModificationImpl(identityInfo, identity.getName(), identity.getVersion(), this.getAllInstalledPatches(), state) {
private static void assertExistsOnDisk(IteratorImpl i, String id) throws NoSuchElementException { final File historyDir = i.mgr.getInstalledImage().getPatchHistoryDir(id); if(!historyDir.exists()) { throw new NoSuchElementException(PatchLogger.ROOT_LOGGER.noPatchHistory(historyDir.getAbsolutePath())); } // TODO parsed xml can be cached final File rollbackXml = new File(historyDir, "rollback.xml"); if(!rollbackXml.exists()) { throw new NoSuchElementException(PatchLogger.ROOT_LOGGER.patchIsMissingFile(rollbackXml.getAbsolutePath())); } try { PatchXml.parse(rollbackXml); } catch (Exception e) { throw new NoSuchElementException(PatchLogger.ROOT_LOGGER.fileIsNotReadable(rollbackXml.getAbsolutePath() + ": " + e.getLocalizedMessage())); } final File patchXml = new File(historyDir, "patch.xml"); if(!patchXml.exists()) { throw new NoSuchElementException(PatchLogger.ROOT_LOGGER.patchIsMissingFile(patchXml.getAbsolutePath())); } final Patch patchMetaData; try { patchMetaData = PatchXml.parse(patchXml).resolvePatch(i.mgr.getIdentity().getName(), i.mgr.getIdentity().getVersion()); } catch (Exception e) { throw new NoSuchElementException(PatchLogger.ROOT_LOGGER.fileIsNotReadable(patchXml.getAbsolutePath() + ": " + e.getLocalizedMessage())); } if(i.excludeAgedOut && isAgedOut(i.mgr, patchMetaData)) { throw new NoSuchElementException("Patch " + patchMetaData.getPatchId() + " was aged out"); } }
.oneOffPatchIdentity(installedIdentity.getIdentity().getName(), installedIdentity.getIdentity().getVersion()) .getParent() .oneOffPatchElement(addOnPatchID, addOnName, true) InstalledIdentity patchedInstalledIdentity = InstalledIdentity.load(env.getInstalledImage().getJbossHome(), productConfig, env.getInstalledImage().getModulesDir()); assertInstallationIsPatched(patch, patchedInstalledIdentity.getIdentity().loadTargetInfo()); assertFileExists(env.getInstalledImage().getJbossHome(), "bin", fileAdded.getItem().getName()); DirectoryStructure addOnStructure = installedIdentity.getAddOns().iterator().next().loadTargetInfo().getDirectoryStructure(); File modulesPatchDir = addOnStructure.getModulePatchDirectory(addOnPatchID); assertDirExists(modulesPatchDir);
info = installedIdentity.getIdentity().loadTargetInfo(); } catch (IOException e) { throw new IllegalStateException(PatchLogger.ROOT_LOGGER.failedToLoadInfo(installedIdentity.getIdentity().getName()), e); final Layer layer = installedIdentity.getLayer(layerName); if (layer == null) { final File patchHistoryDir = installedIdentity.getInstalledImage().getPatchHistoryDir(entry.getPatchId()); if (patchHistoryDir.exists()) { ops.add(new DeleteOp(patchHistoryDir, HISTORY_FILTER));
PatchableTarget.TargetInfo identityInfo = installedIdentity.getIdentity().loadTargetInfo(); assertEquals(BASE, identityInfo.getCumulativePatchID()); assertTrue(identityInfo.getPatchIDs().isEmpty()); .oneOffPatchIdentity(installedIdentity.getIdentity().getName(), installedIdentity.getIdentity().getVersion()) .getParent() .oneOffPatchElement(layerPatchId, layerName, false) File zippedPatch = createZippedPatchFile(patchDir, patchID); Identity identityBeforePatch = loadInstalledIdentity().getIdentity(); assertPatchHasBeenApplied(patchResult, patch); InstalledIdentity patchedInstalledIdentity = InstalledIdentity.load(env.getInstalledImage().getJbossHome(), productConfig, env.getInstalledImage().getModulesDir()); assertInstallationIsPatched(patch, patchedInstalledIdentity.getIdentity().loadTargetInfo()); assertFileExists(env.getInstalledImage().getJbossHome(), "bin", fileAdded.getItem().getName()); DirectoryStructure layerDirStructure = patchedInstalledIdentity.getLayers().get(0).loadTargetInfo().getDirectoryStructure(); File modulesPatchDir = layerDirStructure.getModulePatchDirectory(layerPatchId); assertDirExists(modulesPatchDir); assertPatchHasBeenRolledBack(rollbackResult, identityBeforePatch); InstalledIdentity rolledBackInstalledIdentity = InstalledIdentity.load(env.getInstalledImage().getJbossHome(), productConfig, env.getInstalledImage().getModulesDir()); PatchingAssert.assertFileDoesNotExist(env.getInstalledImage().getJbossHome(), "bin", fileAdded.getItem().getName()); if (File.separatorChar != '\\') { assertDirDoesNotExist(rolledBackInstalledIdentity.getLayers().get(0).loadTargetInfo().getDirectoryStructure().getModulePatchDirectory(layerPatchId));
private static boolean isAgedOut(InstalledIdentity installedIdentity, final Patch metadata) { for (PatchElement pe : metadata.getElements()) { final PatchElementProvider peProvider = pe.getProvider(); final PatchableTarget layer = peProvider.isAddOn() ? installedIdentity.getAddOn(peProvider.getName()) : installedIdentity.getLayer(peProvider.getName()); if (layer == null) { // if an identity is missing a layer that means either it was re-configured and the layer // was removed // or the layer in the patch is optional and may be missing on the disk // we haven't had this case yet, not sure how critical this is to terminate the process of // cleaning up throw new IllegalStateException(PatchLogger.ROOT_LOGGER.layerNotFound(peProvider.getName())); } final File patchDir = layer.getDirectoryStructure().getModulePatchDirectory(pe.getId()); if (!patchDir.exists()) { return true; } } return false; }
@Override public List<String> getPatchStreams() throws PatchingException { final List<InstalledIdentity> installedIdentities = manager.getInstalledIdentities(); if(installedIdentities.size() == 1) { return Collections.singletonList(installedIdentities.get(0).getIdentity().getName()); } final List<String> result = new ArrayList<String>(installedIdentities.size()); for(InstalledIdentity ii : installedIdentities) { result.add(ii.getIdentity().getName()); } return result; }
@Override public PatchingResult rollback(final String streamName, final String patchId, final ContentVerificationPolicy contentPolicy, final boolean rollbackTo, final boolean resetConfiguration) throws PatchingException { InstalledIdentity targetIdentity = null; if (streamName == null) { for (InstalledIdentity identity : manager.getInstalledIdentities()) { if (identity.getAllInstalledPatches().contains(patchId)) { if (targetIdentity != null) { throw new PatchingException(PatchLogger.ROOT_LOGGER.patchIdFoundInMoreThanOneStream(patchId, targetIdentity.getIdentity().getName(), identity.getIdentity().getName())); } targetIdentity = identity; } } if(targetIdentity == null) { throw PatchLogger.ROOT_LOGGER.patchNotFoundInHistory(patchId); } } else { targetIdentity = manager.getInstalledIdentity(streamName, null); } // Rollback the patch final InstallationManager.InstallationModification modification = targetIdentity.modifyInstallation(runner); try { return runner.rollbackPatch(patchId, contentPolicy, rollbackTo, resetConfiguration, modification); } catch (Exception e) { modification.cancel(); throw rethrowException(e); } }
@Test public void installedLayer() throws Exception { String layerName = randomString(); installLayers(layerName); TestUtils.tree(env.getInstalledImage().getJbossHome()); InstalledIdentity installedIdentity = loadInstalledIdentity(); Identity identity = installedIdentity.getIdentity(); assertEquals(productConfig.getProductName(), identity.getName()); assertEquals(productConfig.resolveVersion(), identity.getVersion()); List<Layer> layers = installedIdentity.getLayers(); assertEquals(2, layers.size()); Layer layer = layers.get(0); assertEquals(layerName, layer.getName()); assertEquals(BASE, layers.get(1).getName()); // base layer is always appended PatchableTarget.TargetInfo targetInfo = layer.loadTargetInfo(); assertEquals(BASE, targetInfo.getCumulativePatchID()); assertTrue(targetInfo.getPatchIDs().isEmpty()); DirectoryStructure directoryStructure = targetInfo.getDirectoryStructure(); assertEquals(newFile(env.getModuleRoot(), "system", "layers", layerName), directoryStructure.getModuleRoot()); assertNull(directoryStructure.getBundleRepositoryRoot()); }
@Override protected Collection<? extends PatchableTarget> getChildTargets(InstalledIdentity identity) { return identity.getLayers(); } }
@Override public String getAppliedAt() { if(appliedAt == null) { final File patchHistoryDir = i.mgr.getInstalledImage().getPatchHistoryDir(entryPatchId); if(patchHistoryDir.exists()) { try { appliedAt = getAppliedAt(patchHistoryDir); } catch (PatchingException e) { } } } return appliedAt; }
@Test public void testWrongModuleContent() throws Exception { final PatchingTestBuilder builder = createDefaultBuilder(); // Add some random content ContentModificationUtils.addModule(builder.getRoot(), "base-patch-001", "test.module", randomString()); // Override the hash with a wrong one final ModuleItem item = new ModuleItem("test.module", "main", WRONG_HASH); final ContentModification wrongModification = new ContentModification(item, IoUtils.NO_CONTENT, ModificationType.ADD); final PatchingTestStepBuilder step1 = builder.createStepBuilder(); step1.oneOffPatchIdentity(PRODUCT_VERSION) .setPatchId("oo1") .oneOffPatchElement("base-patch-001", "base", false) .addContentModification(wrongModification) .getParent() .addFileWithRandomContent(null, "test", "content"); // try { apply(step1); Assert.fail("should have failed"); } catch (PatchingException e) { Assert.assertFalse(builder.hasFile("test", "content")); final InstalledIdentity identity = loadInstallationManager().getDefaultIdentity(); final PatchableTarget base = identity.getLayer("base"); Assert.assertFalse(base.getDirectoryStructure().getModulePatchDirectory("base-patch-001").exists()); Assert.assertFalse(identity.getInstalledImage().getPatchHistoryDir("oo1").exists()); } }
private void prepareCP3(final InstalledIdentity installedIdentity) throws IOException, Exception { final String cp3ID = "CP3"; final File cp3Dir = mkdir(tempDir, cp3ID); cp3StandaloneModified = ContentModificationUtils.modifyMisc(cp3Dir, cp3ID, "updated by cp3", standaloneSh, "bin", standaloneSh.getName()); cp3BaseModuleModified = ContentModificationUtils.modifyModule(cp3Dir, baseCP3ID, moduleName, cp2BaseModuleModified.getItem().getContentHash(), "cp3 content"); // cp3BaseModule2Added = ContentModificationUtils.addModule(cp3Dir, baseCP3ID, moduleName + "2"); the patchgen tool // would generate an update instead final File absentModuleXml = IoUtils.newFile(installedIdentity.getLayer("base").loadTargetInfo() .getDirectoryStructure().getModulePatchDirectory(baseCP2ID), "org", "jboss", "test2", "main", "module.xml"); cp3BaseModule2Added = ContentModificationUtils.modifyModule(cp3Dir, baseCP3ID, moduleName + "2", HashUtils.hashFile(absentModuleXml), "cp3 content"); final ContentModification cp3AddedByCP1RemovedByCP3Removed = ContentModificationUtils.removeMisc(addedByCP1RemovedByCP3, "bin", addedByCP1RemovedByCP3.getName()); cp3 = PatchBuilder.create() .setPatchId(cp3ID) .setDescription(randomString()) .upgradeIdentity(installedIdentity.getIdentity().getName(), productConfig.getProductVersion() + "_CP2", productConfig.getProductVersion() + "_CP3") .getParent() .upgradeElement(baseCP3ID, BASE, false) .addContentModification(cp3BaseModuleModified) .addContentModification(cp3BaseModule2Added) .getParent() .addContentModification(cp3StandaloneModified) .addContentModification(cp3AddedByCP1RemovedByCP3Removed) .build(); createPatchXMLFile(cp3Dir, cp3); cp3Zip = createZippedPatchFile(cp3Dir, cp3ID); }