Search in sources :

Example 1 with RollbackPatch

use of org.jboss.as.patching.metadata.RollbackPatch in project wildfly-core by wildfly.

the class IdentityPatchRunner method loadRollbackInformation.

static RollbackPatch loadRollbackInformation(final String patchId, final InstalledImage installedImage) throws PatchingException, IOException, XMLStreamException {
    final File historyDir = installedImage.getPatchHistoryDir(patchId);
    final File patchXml = new File(historyDir, Constants.ROLLBACK_XML);
    return (RollbackPatch) PatchXml.parse(patchXml).resolvePatch(null, null);
}
Also used : RollbackPatch(org.jboss.as.patching.metadata.RollbackPatch) File(java.io.File)

Example 2 with RollbackPatch

use of org.jboss.as.patching.metadata.RollbackPatch in project wildfly-core by wildfly.

the class IdentityPatchRunner method reenableNotOverridenModules.

void reenableNotOverridenModules(final RollbackPatch patch, IdentityPatchContext context) throws PatchingException, IOException, XMLStreamException {
    assert patch.getIdentity().getPatchType() == Patch.PatchType.CUMULATIVE;
    final Iterator historyIterator = context.getHistory().iterator(patch.getIdentityState().getIdentity().loadTargetInfo());
    if (!historyIterator.hasNext()) {
        return;
    }
    final List<PatchElement> elements = patch.getElements();
    final Map<String, List<PatchElement>> layerPatches = new HashMap<String, List<PatchElement>>(elements.size());
    final Map<String, List<PatchElement>> addonPatches = new HashMap<String, List<PatchElement>>(elements.size());
    for (PatchElement e : elements) {
        if (e.getProvider().isAddOn()) {
            addonPatches.put(e.getProvider().getName(), Collections.<PatchElement>emptyList());
        } else {
            layerPatches.put(e.getProvider().getName(), Collections.<PatchElement>emptyList());
        }
    }
    Patch prevCP = null;
    while (historyIterator.hasNext()) {
        final Entry entry = historyIterator.next();
        if (entry.getType() == PatchType.CUMULATIVE) {
            prevCP = entry.getMetadata();
            break;
        }
        final Patch oneOff = entry.getMetadata();
        for (PatchElement oneOffElement : oneOff.getElements()) {
            final Map<String, List<PatchElement>> providerPatches;
            if (oneOffElement.getProvider().isAddOn()) {
                providerPatches = addonPatches;
            } else {
                providerPatches = layerPatches;
            }
            List<PatchElement> patches = providerPatches.get(oneOffElement.getProvider().getName());
            if (patches != null) {
                switch(patches.size()) {
                    case 0:
                        providerPatches.put(oneOffElement.getProvider().getName(), Collections.singletonList(oneOffElement));
                        break;
                    case 1:
                        patches = new ArrayList<PatchElement>(patches);
                        providerPatches.put(oneOffElement.getProvider().getName(), patches);
                    default:
                        patches.add(oneOffElement);
                }
            }
        }
    }
    Set<ModuleItem> cpElementModules;
    Set<ModuleItem> reenabledModules = Collections.emptySet();
    for (PatchElement e : elements) {
        final List<PatchElement> patches;
        if (e.getProvider().isAddOn()) {
            patches = addonPatches.get(e.getProvider().getName());
        } else {
            patches = layerPatches.get(e.getProvider().getName());
        }
        if (patches.isEmpty()) {
            continue;
        }
        cpElementModules = null;
        final PatchEntry rollbackEntry = context.resolveForElement(e);
        for (PatchElement oneOff : patches) {
            for (ContentModification mod : oneOff.getModifications()) {
                if (mod.getItem().getContentType() != ContentType.MODULE) {
                    continue;
                }
                final ModuleItem module = (ModuleItem) mod.getItem();
                if (rollbackEntry.get(new Location(module)) != null) {
                    continue;
                }
                if (reenabledModules.contains(module)) {
                    continue;
                }
                final File modulePath = PatchContentLoader.getModulePath(rollbackEntry.getDirectoryStructure().getModulePatchDirectory(oneOff.getId()), module);
                rollbackEntry.invalidateRoot(modulePath);
                if (reenabledModules.isEmpty()) {
                    reenabledModules = new HashSet<ModuleItem>();
                }
                reenabledModules.add(module);
                if (prevCP == null) {
                    rollbackEntry.disableBaseModule(module);
                } else {
                    if (cpElementModules == null) {
                        for (PatchElement cpE : prevCP.getElements()) {
                            if (cpE.getProvider().getName().equals(e.getProvider().getName()) && cpE.getProvider().getLayerType().equals(e.getProvider().getLayerType())) {
                                cpElementModules = new HashSet<ModuleItem>(cpE.getModifications().size());
                                for (ContentModification cpMod : cpE.getModifications()) {
                                    if (cpMod.getItem().getContentType() == ContentType.MODULE) {
                                        cpElementModules.add(cpMod.getItem(ModuleItem.class));
                                    }
                                }
                                break;
                            }
                        }
                    }
                    if (cpElementModules != null && !cpElementModules.contains(module)) {
                        rollbackEntry.disableBaseModule(module);
                    }
                }
            }
        }
    }
}
Also used : PatchEntry(org.jboss.as.patching.runner.IdentityPatchContext.PatchEntry) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) PatchElement(org.jboss.as.patching.metadata.PatchElement) ModuleItem(org.jboss.as.patching.metadata.ModuleItem) Entry(org.jboss.as.patching.tool.PatchingHistory.Entry) PatchEntry(org.jboss.as.patching.runner.IdentityPatchContext.PatchEntry) Iterator(org.jboss.as.patching.tool.PatchingHistory.Iterator) ArrayList(java.util.ArrayList) List(java.util.List) Patch(org.jboss.as.patching.metadata.Patch) RollbackPatch(org.jboss.as.patching.metadata.RollbackPatch) ContentModification(org.jboss.as.patching.metadata.ContentModification) File(java.io.File)

Example 3 with RollbackPatch

use of org.jboss.as.patching.metadata.RollbackPatch in project wildfly-core by wildfly.

the class IdentityPatchContext method finalize.

/**
 * Finalize the patch.
 *
 * @param callback the finalize callback
 * @return the result
 * @throws Exception
 */
protected PatchingResult finalize(final FinalizeCallback callback) throws Exception {
    assert state == State.NEW;
    final Patch original = callback.getPatch();
    final Patch.PatchType patchType = original.getIdentity().getPatchType();
    final String patchId;
    if (patchType == Patch.PatchType.CUMULATIVE) {
        patchId = modification.getCumulativePatchID();
    } else {
        patchId = original.getPatchId();
    }
    try {
        // The processed patch, based on the recorded changes
        final Patch processedPatch = createProcessedPatch(original);
        // The rollback containing all the recorded rollback actions
        final RollbackPatch rollbackPatch = createRollbackPatch(patchId, patchType);
        callback.finishPatch(processedPatch, rollbackPatch, this);
    } catch (Exception e) {
        if (undoChanges()) {
            callback.operationCancelled(this);
        }
        throw e;
    }
    state = State.PREPARED;
    return new PatchingResult() {

        @Override
        public String getPatchId() {
            return original.getPatchId();
        }

        @Override
        public PatchInfo getPatchInfo() {
            return new PatchInfo() {

                @Override
                public String getVersion() {
                    return identityEntry.getResultingVersion();
                }

                @Override
                public String getCumulativePatchID() {
                    return identityEntry.delegate.getModifiedState().getCumulativePatchID();
                }

                @Override
                public List<String> getPatchIDs() {
                    return identityEntry.delegate.getModifiedState().getPatchIDs();
                }
            };
        }

        @Override
        public void commit() {
            if (state == State.PREPARED) {
                complete(modification, callback);
            } else {
                undoChanges();
                throw new IllegalStateException();
            }
        }

        @Override
        public void rollback() {
            if (undoChanges()) {
                try {
                    callback.operationCancelled(IdentityPatchContext.this);
                } finally {
                    modification.cancel();
                }
            }
        }
    };
}
Also used : PatchInfo(org.jboss.as.patching.PatchInfo) PatchingResult(org.jboss.as.patching.tool.PatchingResult) RollbackPatch(org.jboss.as.patching.metadata.RollbackPatch) Patch(org.jboss.as.patching.metadata.Patch) RollbackPatch(org.jboss.as.patching.metadata.RollbackPatch) XMLStreamException(javax.xml.stream.XMLStreamException) PatchingException(org.jboss.as.patching.PatchingException) IOException(java.io.IOException)

Example 4 with RollbackPatch

use of org.jboss.as.patching.metadata.RollbackPatch in project wildfly-core by wildfly.

the class IdentityPatchRunner method rollback.

/**
 * Rollback a patch.
 *
 * @param patchID the patch id
 * @param context the patch context
 * @throws PatchingException
 */
private void rollback(final String patchID, final IdentityPatchContext context) throws PatchingException {
    try {
        // Load the patch history
        final PatchingTaskContext.Mode mode = context.getMode();
        final Patch originalPatch = loadPatchInformation(patchID, installedImage);
        final RollbackPatch rollbackPatch = loadRollbackInformation(patchID, installedImage);
        final Patch.PatchType patchType = rollbackPatch.getIdentity().getPatchType();
        final InstalledIdentity history = rollbackPatch.getIdentityState();
        // Process originals by type first
        final LinkedHashMap<String, PatchElement> originalLayers = new LinkedHashMap<String, PatchElement>();
        final LinkedHashMap<String, PatchElement> originalAddOns = new LinkedHashMap<String, PatchElement>();
        for (final PatchElement patchElement : originalPatch.getElements()) {
            final PatchElementProvider provider = patchElement.getProvider();
            final String layerName = provider.getName();
            final LayerType layerType = provider.getLayerType();
            final Map<String, PatchElement> originals;
            switch(layerType) {
                case Layer:
                    originals = originalLayers;
                    break;
                case AddOn:
                    originals = originalAddOns;
                    break;
                default:
                    throw new IllegalStateException();
            }
            if (!originals.containsKey(layerName)) {
                originals.put(layerName, patchElement);
            } else {
                throw PatchLogger.ROOT_LOGGER.installationDuplicateLayer(layerType.toString(), layerName);
            }
        }
        // Process the rollback xml
        for (final PatchElement patchElement : rollbackPatch.getElements()) {
            final String elementPatchId = patchElement.getId();
            final PatchElementProvider provider = patchElement.getProvider();
            final String layerName = provider.getName();
            final LayerType layerType = provider.getLayerType();
            final LinkedHashMap<String, PatchElement> originals;
            switch(layerType) {
                case Layer:
                    originals = originalLayers;
                    break;
                case AddOn:
                    originals = originalAddOns;
                    break;
                default:
                    throw new IllegalStateException();
            }
            final PatchElement original = originals.remove(layerName);
            if (original == null) {
                throw PatchLogger.ROOT_LOGGER.noSuchLayer(layerName);
            }
            final IdentityPatchContext.PatchEntry entry = context.resolveForElement(patchElement);
            // Create the rollback
            PatchingTasks.rollback(elementPatchId, original.getModifications(), patchElement.getModifications(), entry, ContentItemFilter.ALL_BUT_MISC, mode);
            entry.rollback(original.getId());
            // We need to restore the previous state
            final Patch.PatchType elementPatchType = provider.getPatchType();
            final PatchableTarget.TargetInfo info;
            if (layerType == LayerType.AddOn) {
                info = history.getAddOn(layerName).loadTargetInfo();
            } else {
                info = history.getLayer(layerName).loadTargetInfo();
            }
            if (mode == ROLLBACK) {
                restoreFromHistory(entry, elementPatchId, elementPatchType, info);
            }
        }
        if (!originalLayers.isEmpty() || !originalAddOns.isEmpty()) {
            throw PatchLogger.ROOT_LOGGER.invalidRollbackInformation();
        }
        // Rollback the patch
        final IdentityPatchContext.PatchEntry identity = context.getIdentityEntry();
        PatchingTasks.rollback(patchID, originalPatch.getModifications(), rollbackPatch.getModifications(), identity, ContentItemFilter.MISC_ONLY, mode);
        identity.rollback(patchID);
        // Restore previous state
        if (mode == ROLLBACK) {
            final PatchableTarget.TargetInfo identityHistory = history.getIdentity().loadTargetInfo();
            restoreFromHistory(identity, rollbackPatch.getPatchId(), patchType, identityHistory);
            if (patchType == Patch.PatchType.CUMULATIVE) {
                reenableNotOverridenModules(rollbackPatch, context);
            }
        }
        if (patchType == Patch.PatchType.CUMULATIVE) {
            final Identity.IdentityUpgrade upgrade = rollbackPatch.getIdentity().forType(Patch.PatchType.CUMULATIVE, Identity.IdentityUpgrade.class);
            identity.setResultingVersion(upgrade.getResultingVersion());
        }
    } catch (Exception e) {
        throw rethrowException(e);
    }
}
Also used : InstalledIdentity(org.jboss.as.patching.installation.InstalledIdentity) PatchableTarget(org.jboss.as.patching.installation.PatchableTarget) PatchElementProvider(org.jboss.as.patching.metadata.PatchElementProvider) RollbackPatch(org.jboss.as.patching.metadata.RollbackPatch) PatchElement(org.jboss.as.patching.metadata.PatchElement) XMLStreamException(javax.xml.stream.XMLStreamException) PatchingException(org.jboss.as.patching.PatchingException) IOException(java.io.IOException) LinkedHashMap(java.util.LinkedHashMap) LayerType(org.jboss.as.patching.metadata.LayerType) PatchType(org.jboss.as.patching.metadata.Patch.PatchType) Identity(org.jboss.as.patching.metadata.Identity) InstalledIdentity(org.jboss.as.patching.installation.InstalledIdentity) Patch(org.jboss.as.patching.metadata.Patch) RollbackPatch(org.jboss.as.patching.metadata.RollbackPatch) PatchEntry(org.jboss.as.patching.runner.IdentityPatchContext.PatchEntry)

Example 5 with RollbackPatch

use of org.jboss.as.patching.metadata.RollbackPatch in project wildfly-core by wildfly.

the class RollbackTargetArtifact method process.

@Override
public boolean process(PatchingXmlArtifact.XmlArtifactState<RollbackPatch> parent, PatchingArtifactProcessor processor) {
    final RollbackPatch patch = parent.getPatch();
    final PatchingArtifacts.PatchID patchID = processor.getParentArtifact(PatchingArtifacts.HISTORY_RECORD);
    final InstalledIdentity identity = patch.getIdentityState();
    processor.getValidationContext().setCurrentPatchIdentity(identity);
    final State state = new State(identity, patchID);
    if (identity == null) {
        processor.getValidationContext().getErrorHandler().addMissing(PatchingArtifacts.ROLLBACK_TARGET, state);
        return false;
    } else {
        return processor.process(this, state);
    }
}
Also used : InstalledIdentity(org.jboss.as.patching.installation.InstalledIdentity) RollbackPatch(org.jboss.as.patching.metadata.RollbackPatch)

Aggregations

RollbackPatch (org.jboss.as.patching.metadata.RollbackPatch)6 Patch (org.jboss.as.patching.metadata.Patch)4 InstalledIdentity (org.jboss.as.patching.installation.InstalledIdentity)3 PatchElement (org.jboss.as.patching.metadata.PatchElement)3 File (java.io.File)2 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 LinkedHashMap (java.util.LinkedHashMap)2 XMLStreamException (javax.xml.stream.XMLStreamException)2 PatchingException (org.jboss.as.patching.PatchingException)2 ContentModification (org.jboss.as.patching.metadata.ContentModification)2 PatchEntry (org.jboss.as.patching.runner.IdentityPatchContext.PatchEntry)2 HashMap (java.util.HashMap)1 List (java.util.List)1 PatchInfo (org.jboss.as.patching.PatchInfo)1 PatchableTarget (org.jboss.as.patching.installation.PatchableTarget)1 Identity (org.jboss.as.patching.metadata.Identity)1 LayerType (org.jboss.as.patching.metadata.LayerType)1 ModuleItem (org.jboss.as.patching.metadata.ModuleItem)1 PatchType (org.jboss.as.patching.metadata.Patch.PatchType)1