Search in sources :

Example 21 with Patch

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

the class LayerTestCase method patchLayer.

@Test
public void patchLayer() throws Exception {
    // add a layer
    // randomString();
    String layerName = "mylayer";
    installLayers(layerName);
    InstalledIdentity installedIdentity = loadInstalledIdentity();
    // build a one-off patch for the layer with 1 added module
    // and 1 add file
    String patchID = randomString();
    File patchDir = mkdir(tempDir, patchID);
    // randomString();
    String layerPatchId = "mylayerPatchID";
    String moduleName = randomString();
    ContentModification moduleAdded = ContentModificationUtils.addModule(patchDir, layerPatchId, moduleName);
    ContentModification fileAdded = ContentModificationUtils.addMisc(patchDir, patchID, "new file resource", "bin", "my-new-standalone.sh");
    Patch patch = PatchBuilder.create().setPatchId(patchID).oneOffPatchIdentity(installedIdentity.getIdentity().getName(), installedIdentity.getIdentity().getVersion()).getParent().oneOffPatchElement(layerPatchId, layerName, false).addContentModification(moduleAdded).getParent().addContentModification(fileAdded).build();
    createPatchXMLFile(patchDir, patch);
    File zippedPatch = createZippedPatchFile(patchDir, patchID);
    // apply patch
    PatchingResult result = executePatch(zippedPatch);
    assertPatchHasBeenApplied(result, patch);
    InstalledIdentity patchedInstalledIdentity = loadInstalledIdentity();
    assertInstallationIsPatched(patch, patchedInstalledIdentity.getIdentity().loadTargetInfo());
    assertFileExists(env.getInstalledImage().getJbossHome(), "bin", fileAdded.getItem().getName());
    DirectoryStructure layerDirStructure = installedIdentity.getLayers().get(0).loadTargetInfo().getDirectoryStructure();
    File modulesPatchDir = layerDirStructure.getModulePatchDirectory(layerPatchId);
    assertDirExists(modulesPatchDir);
    assertDefinedModule(modulesPatchDir, moduleName, moduleAdded.getItem().getContentHash());
}
Also used : PatchingResult(org.jboss.as.patching.tool.PatchingResult) TestUtils.randomString(org.jboss.as.patching.runner.TestUtils.randomString) IoUtils.newFile(org.jboss.as.patching.IoUtils.newFile) TestUtils.createPatchXMLFile(org.jboss.as.patching.runner.TestUtils.createPatchXMLFile) File(java.io.File) TestUtils.createZippedPatchFile(org.jboss.as.patching.runner.TestUtils.createZippedPatchFile) ContentModification(org.jboss.as.patching.metadata.ContentModification) Patch(org.jboss.as.patching.metadata.Patch) DirectoryStructure(org.jboss.as.patching.DirectoryStructure) Test(org.junit.Test)

Example 22 with Patch

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

the class IdentityPatchRunner method applyPatch.

/**
 * Apply a patch.
 *
 * @param patchId the patch id
 * @param patch   the patch metadata
 * @param context the patch context
 * @throws PatchingException
 * @throws IOException
 * @throws XMLStreamException
 */
private PatchingResult applyPatch(final String patchId, final Patch patch, final IdentityPatchContext context) throws PatchingException, IOException, XMLStreamException {
    final Identity identity = patch.getIdentity();
    final Patch.PatchType patchType = identity.getPatchType();
    final InstallationManager.InstallationModification modification = context.getModification();
    if (patchType == Patch.PatchType.CUMULATIVE) {
        // Invalidate all installed patches (one-off, cumulative) - we never need to invalidate the release base
        final List<String> invalidation = new ArrayList<String>(modification.getPatchIDs());
        if (!invalidation.isEmpty()) {
            try {
                // Before rolling back the one-off patches, validate that the state until that point is consistent
                validateRollbackState(invalidation.get(invalidation.size() - 1), modification.getUnmodifiedInstallationState());
            } catch (PatchingException e) {
                throw e;
            } catch (Exception e) {
                throw new PatchingException(e);
            }
            // Invalidate the installed patches first
            for (final String rollback : invalidation) {
                rollback(rollback, context);
            }
        }
    }
    // Add to installed patches list
    modification.addInstalledPatch(patchId);
    // Then apply the current patch
    for (final PatchElement element : patch.getElements()) {
        // Apply the content modifications
        final IdentityPatchContext.PatchEntry target = context.resolveForElement(element);
        final PatchElementProvider provider = element.getProvider();
        final Patch.PatchType elementPatchType = provider.getPatchType();
        final String elementPatchId = element.getId();
        // See if we can skip this element
        if (target.isApplied(elementPatchId)) {
            // This needs some further testing, maybe we need to compare our history with the patch if they are consistent
            throw PatchLogger.ROOT_LOGGER.alreadyApplied(elementPatchId);
        }
        // Check upgrade conditions
        checkUpgradeConditions(provider, target);
        apply(elementPatchId, element.getModifications(), target);
        target.apply(elementPatchId, elementPatchType);
    }
    // Apply the patch to the identity
    final IdentityPatchContext.PatchEntry identityEntry = context.getIdentityEntry();
    apply(patchId, patch.getModifications(), identityEntry);
    identityEntry.apply(patchId, patchType);
    // Port forward missing module changes
    if (patchType == Patch.PatchType.CUMULATIVE) {
        portForward(patch, context);
    }
    // We need the resulting version for rollback
    if (patchType == Patch.PatchType.CUMULATIVE) {
        final Identity.IdentityUpgrade upgrade = identity.forType(Patch.PatchType.CUMULATIVE, Identity.IdentityUpgrade.class);
        identityEntry.setResultingVersion(upgrade.getResultingVersion());
    }
    // Execute the tasks
    final IdentityApplyCallback callback = new IdentityApplyCallback(patch, identityEntry.getDirectoryStructure());
    try {
        return executeTasks(context, callback);
    } catch (Exception e) {
        context.cancel(callback);
        throw rethrowException(e);
    }
}
Also used : PatchingException(org.jboss.as.patching.PatchingException) PatchElementProvider(org.jboss.as.patching.metadata.PatchElementProvider) ArrayList(java.util.ArrayList) PatchElement(org.jboss.as.patching.metadata.PatchElement) XMLStreamException(javax.xml.stream.XMLStreamException) PatchingException(org.jboss.as.patching.PatchingException) IOException(java.io.IOException) InstallationManager(org.jboss.as.patching.installation.InstallationManager) Identity(org.jboss.as.patching.metadata.Identity) InstalledIdentity(org.jboss.as.patching.installation.InstalledIdentity) PatchType(org.jboss.as.patching.metadata.Patch.PatchType) Patch(org.jboss.as.patching.metadata.Patch) RollbackPatch(org.jboss.as.patching.metadata.RollbackPatch) PatchEntry(org.jboss.as.patching.runner.IdentityPatchContext.PatchEntry)

Example 23 with Patch

use of org.jboss.as.patching.metadata.Patch 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 24 with Patch

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

the class IdentityPatchRunner method portForward.

/**
 * Port forward missing module changes for each layer.
 *
 * @param patch   the current patch
 * @param context the patch context
 * @throws PatchingException
 * @throws IOException
 * @throws XMLStreamException
 */
void portForward(final Patch patch, IdentityPatchContext context) throws PatchingException, IOException, XMLStreamException {
    assert patch.getIdentity().getPatchType() == Patch.PatchType.CUMULATIVE;
    final PatchingHistory history = context.getHistory();
    for (final PatchElement element : patch.getElements()) {
        final PatchElementProvider provider = element.getProvider();
        final String name = provider.getName();
        final boolean addOn = provider.isAddOn();
        final IdentityPatchContext.PatchEntry target = context.resolveForElement(element);
        final String cumulativePatchID = target.getCumulativePatchID();
        if (Constants.BASE.equals(cumulativePatchID)) {
            reenableRolledBackInBase(target);
            continue;
        }
        boolean found = false;
        final PatchingHistory.Iterator iterator = history.iterator();
        while (iterator.hasNextCP()) {
            final PatchingHistory.Entry entry = iterator.nextCP();
            final String patchId = addOn ? entry.getAddOnPatches().get(name) : entry.getLayerPatches().get(name);
            if (patchId != null && patchId.equals(cumulativePatchID)) {
                final Patch original = loadPatchInformation(entry.getPatchId(), installedImage);
                for (final PatchElement originalElement : original.getElements()) {
                    if (name.equals(originalElement.getProvider().getName()) && addOn == originalElement.getProvider().isAddOn()) {
                        PatchingTasks.addMissingModifications(target, originalElement.getModifications(), ContentItemFilter.ALL_BUT_MISC);
                    }
                }
                // Record a loader to have access to the current modules
                final DirectoryStructure structure = target.getDirectoryStructure();
                final File modulesRoot = structure.getModulePatchDirectory(patchId);
                final File bundlesRoot = structure.getBundlesPatchDirectory(patchId);
                final PatchContentLoader loader = PatchContentLoader.create(null, bundlesRoot, modulesRoot);
                context.recordContentLoader(patchId, loader);
                found = true;
                break;
            }
        }
        if (!found) {
            throw PatchLogger.ROOT_LOGGER.patchNotFoundInHistory(cumulativePatchID);
        }
        reenableRolledBackInBase(target);
    }
}
Also used : PatchElementProvider(org.jboss.as.patching.metadata.PatchElementProvider) PatchElement(org.jboss.as.patching.metadata.PatchElement) Entry(org.jboss.as.patching.tool.PatchingHistory.Entry) Iterator(org.jboss.as.patching.tool.PatchingHistory.Iterator) PatchingHistory(org.jboss.as.patching.tool.PatchingHistory) Patch(org.jboss.as.patching.metadata.Patch) RollbackPatch(org.jboss.as.patching.metadata.RollbackPatch) File(java.io.File) PatchEntry(org.jboss.as.patching.runner.IdentityPatchContext.PatchEntry) DirectoryStructure(org.jboss.as.patching.DirectoryStructure)

Example 25 with Patch

use of org.jboss.as.patching.metadata.Patch 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)

Aggregations

Patch (org.jboss.as.patching.metadata.Patch)110 ContentModification (org.jboss.as.patching.metadata.ContentModification)94 File (java.io.File)93 Test (org.junit.Test)66 IoUtils.newFile (org.jboss.as.patching.IoUtils.newFile)60 PatchingTestUtil.createPatchXMLFile (org.jboss.as.test.patching.PatchingTestUtil.createPatchXMLFile)55 PatchingTestUtil.createZippedPatchFile (org.jboss.as.test.patching.PatchingTestUtil.createZippedPatchFile)52 PatchingTestUtil.randomString (org.jboss.as.test.patching.PatchingTestUtil.randomString)47 ProductConfig (org.jboss.as.version.ProductConfig)39 TestUtils.randomString (org.jboss.as.patching.runner.TestUtils.randomString)33 TestUtils.createPatchXMLFile (org.jboss.as.patching.runner.TestUtils.createPatchXMLFile)30 TestUtils.createZippedPatchFile (org.jboss.as.patching.runner.TestUtils.createZippedPatchFile)30 Module (org.jboss.as.test.patching.util.module.Module)29 PatchingResult (org.jboss.as.patching.tool.PatchingResult)24 PatchingTestUtil.readFile (org.jboss.as.test.patching.PatchingTestUtil.readFile)24 InstalledIdentity (org.jboss.as.patching.installation.InstalledIdentity)22 IOException (java.io.IOException)14 PatchBuilder (org.jboss.as.patching.metadata.PatchBuilder)14 PatchElement (org.jboss.as.patching.metadata.PatchElement)13 HashUtils.hashFile (org.jboss.as.patching.HashUtils.hashFile)12