Search in sources :

Example 86 with Version

use of io.fabric8.kubernetes.model.annotation.Version in project fabric8 by jboss-fuse.

the class GitPatchManagementServiceImpl method mergeProfileChanges.

@Override
public void mergeProfileChanges(Patch patch, File gitRepository, String versionBranch, String patchBranch) {
    Git git = null;
    try {
        git = Git.open(gitRepository);
        // merge version branch with patch branch - no fast forward, so we have nice named commit
        git.checkout().setCreateBranch(false).setName(versionBranch).call();
        MergeResult result = git.merge().setFastForward(MergeCommand.FastForwardMode.NO_FF).include(git.getRepository().resolve(patchBranch)).setCommit(false).call();
        boolean commit = true;
        if (result.getMergeStatus() == MergeResult.MergeStatus.CONFLICTING) {
            handleMergeConflict(git, result, versionBranch, patchBranch);
        } else if (result.getMergeStatus() != MergeResult.MergeStatus.MERGED_NOT_COMMITTED) {
            commit = false;
            Activator.log2(LogService.LOG_ERROR, "Can't merge version branch \"" + versionBranch + "\" with" + " patch branch \"" + patchBranch + "\". Resetting the branch.");
            git.reset().setMode(ResetCommand.ResetType.HARD).call();
        }
    // if (commit) {
    // git.commit()
    // .setMessage("Installing rollup patch \"" + patch.getPatchData().getId() + "\"")
    // .call();
    // }
    } catch (Exception e) {
        throw new PatchException(e.getMessage(), e);
    } finally {
        if (git != null) {
            try {
                git.branchDelete().setBranchNames(patchBranch).setForce(true).call();
            } catch (GitAPIException e) {
                Activator.log2(LogService.LOG_ERROR, e.getMessage());
            }
            gitPatchRepository.closeRepository(git, false);
        }
    }
}
Also used : GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) Git(org.eclipse.jgit.api.Git) MergeResult(org.eclipse.jgit.api.MergeResult) PatchException(io.fabric8.patch.management.PatchException) PatchException(io.fabric8.patch.management.PatchException) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException)

Example 87 with Version

use of io.fabric8.kubernetes.model.annotation.Version in project fabric8 by jboss-fuse.

the class GitPatchManagementServiceIT method rollbackInstalledRollupPatch.

@Test
public void rollbackInstalledRollupPatch() throws IOException, GitAPIException {
    freshKarafStandaloneDistro();
    GitPatchRepository repository = patchManagement();
    PatchManagement management = (PatchManagement) pm;
    preparePatchZip("src/test/resources/content/patch1", "target/karaf/patches/source/patch-1.zip", false);
    preparePatchZip("src/test/resources/content/patch4", "target/karaf/patches/source/patch-4.zip", false);
    List<PatchData> patches = management.fetchPatches(new File("target/karaf/patches/source/patch-1.zip").toURI().toURL());
    Patch patch1 = management.trackPatch(patches.get(0));
    patches = management.fetchPatches(new File("target/karaf/patches/source/patch-4.zip").toURI().toURL());
    Patch patch4 = management.trackPatch(patches.get(0));
    Git fork = repository.cloneRepository(repository.findOrCreateMainGitRepository(), true);
    ObjectId master1 = fork.getRepository().resolve(GitPatchRepository.HISTORY_BRANCH);
    String tx = management.beginInstallation(PatchKind.ROLLUP);
    management.install(tx, patch4, null);
    management.commitInstallation(tx);
    // install P patch to check if rolling back rollup patch will remove P patch's tag
    tx = management.beginInstallation(PatchKind.NON_ROLLUP);
    management.install(tx, patch1, null);
    management.commitInstallation(tx);
    fork = repository.cloneRepository(repository.findOrCreateMainGitRepository(), true);
    assertTrue(repository.containsTag(fork, "patch-my-patch-1"));
    management.rollback(patch4.getPatchData());
    repository.closeRepository(fork, true);
    fork = repository.cloneRepository(repository.findOrCreateMainGitRepository(), true);
    ObjectId master2 = fork.getRepository().resolve(GitPatchRepository.HISTORY_BRANCH);
    assertThat(master1, not(equalTo(master2)));
    assertThat(fork.tagList().call().size(), equalTo(2));
    assertTrue(repository.containsTag(fork, "patch-management"));
    assertTrue(repository.containsTag(fork, "baseline-6.2.0"));
    assertFalse("When rolling back rollup patch, newer P patches' tags should be removed", repository.containsTag(fork, "patch-my-patch-1"));
    assertThat(repository.findCurrentBaseline(fork).getTagName(), equalTo("baseline-6.2.0"));
// TODO: There should be version restored from backed up conflict
// but we've changed the way rolledback R patch handled - we copy entire WC after rollback
// String binStart = FileUtils.readFileToString(new File(karafHome, "bin/start"));
// assertTrue("bin/start should be at previous version",
// binStart.contains("echo \"This is user's change\""));
}
Also used : Git(org.eclipse.jgit.api.Git) ObjectId(org.eclipse.jgit.lib.ObjectId) GitPatchRepository(io.fabric8.patch.management.impl.GitPatchRepository) File(java.io.File) Test(org.junit.Test)

Example 88 with Version

use of io.fabric8.kubernetes.model.annotation.Version in project fabric8 by jboss-fuse.

the class ServiceImpl method rollback.

@Override
public void rollback(final Patch patch, boolean simulate, boolean force) throws PatchException {
    final PatchResult result = !patchManagement.isStandaloneChild() ? patch.getResult() : patch.getResult().getChildPatches().get(System.getProperty("karaf.name"));
    if (result == null) {
        throw new PatchException("Patch " + patch.getPatchData().getId() + " is not installed");
    }
    if (patch.getPatchData().isRollupPatch()) {
        // we already have the "state" (feature repositories, features, bundles and their states, datafiles
        // and start-level info) stored in *.result file
        Presentation.displayFeatureUpdates(result.getFeatureUpdates(), false);
        Presentation.displayBundleUpdates(result.getBundleUpdates(), false);
        try {
            if (!simulate) {
                // let's backup data files before configadmin detects changes to etc/* files.
                backupService.backupDataFiles(result, Pending.ROLLUP_ROLLBACK);
                for (Bundle b : this.bundleContext.getBundles()) {
                    if (b.getSymbolicName() != null && Utils.stripSymbolicName(b.getSymbolicName()).equals("org.apache.felix.fileinstall")) {
                        b.stop(Bundle.STOP_TRANSIENT);
                        break;
                    }
                }
                patchManagement.rollback(patch.getPatchData());
                result.setPending(Pending.ROLLUP_ROLLBACK);
                if (patchManagement.isStandaloneChild()) {
                    result.getParent().store();
                } else {
                    result.store();
                }
                if (isJvmRestartNeeded(result)) {
                    boolean handlesFullRestart = Boolean.getBoolean("karaf.restart.jvm.supported");
                    if (handlesFullRestart) {
                        System.out.println("Rollup patch " + patch.getPatchData().getId() + " rolled back. Restarting Karaf..");
                        System.setProperty("karaf.restart.jvm", "true");
                    } else {
                        System.out.println("Rollup patch " + patch.getPatchData().getId() + " rolled back. Shutting down Karaf, please restart...");
                    }
                } else {
                    // We don't need a JVM restart, so lets just do a OSGi framework restart
                    System.setProperty("karaf.restart", "true");
                }
                File karafData = new File(bundleContext.getProperty("karaf.data"));
                File cleanCache = new File(karafData, "clean_cache");
                cleanCache.createNewFile();
                bundleContext.getBundle(0l).stop();
                // stop/shutdown occurs on another thread
                return;
            } else {
                System.out.println("Simulation only - no files and runtime data will be modified.");
                return;
            }
        } catch (Exception e) {
            e.printStackTrace(System.err);
            System.err.flush();
            throw new PatchException(e.getMessage(), e);
        }
    }
    // continue with NON_ROLLUP patch
    // current state of the framework
    Bundle[] allBundles = bundleContext.getBundles();
    // check if all the bundles that were updated in patch are available (installed)
    List<BundleUpdate> badUpdates = new ArrayList<BundleUpdate>();
    for (BundleUpdate update : result.getBundleUpdates()) {
        boolean found = false;
        Version v = Version.parseVersion(update.getNewVersion() == null ? update.getPreviousVersion() : update.getNewVersion());
        for (Bundle bundle : allBundles) {
            if (bundle.getSymbolicName() == null || update.getSymbolicName() == null) {
                continue;
            }
            if (stripSymbolicName(bundle.getSymbolicName()).equals(stripSymbolicName(update.getSymbolicName())) && bundle.getVersion().equals(v)) {
                found = true;
                break;
            }
        }
        if (!found) {
            badUpdates.add(update);
        }
    }
    if (!badUpdates.isEmpty() && !force) {
        StringBuilder sb = new StringBuilder();
        sb.append("Unable to rollback patch ").append(patch.getPatchData().getId()).append(" because of the following missing bundles:\n");
        for (BundleUpdate up : badUpdates) {
            String version = up.getNewVersion() == null ? up.getPreviousVersion() : up.getNewVersion();
            sb.append(" - ").append(up.getSymbolicName()).append("/").append(version).append("\n");
        }
        throw new PatchException(sb.toString());
    }
    if (!simulate) {
        // bundle -> old location of the bundle to downgrade from
        final Map<Bundle, String> toUpdate = new HashMap<Bundle, String>();
        for (BundleUpdate update : result.getBundleUpdates()) {
            Version v = Version.parseVersion(update.getNewVersion() == null ? update.getPreviousVersion() : update.getNewVersion());
            for (Bundle bundle : allBundles) {
                if (bundle.getSymbolicName() == null || update.getSymbolicName() == null) {
                    continue;
                }
                if (stripSymbolicName(bundle.getSymbolicName()).equals(stripSymbolicName(update.getSymbolicName())) && bundle.getVersion().equals(v)) {
                    toUpdate.put(bundle, update.getPreviousLocation());
                }
            }
        }
        final boolean isStandaloneChild = patchManagement.isStandaloneChild();
        patchManagement.rollback(patch.getPatchData());
        Executors.newSingleThreadExecutor().execute(new Runnable() {

            @Override
            public void run() {
                try {
                    applyChanges(toUpdate);
                } catch (Exception e) {
                    throw new PatchException("Unable to rollback patch " + patch.getPatchData().getId() + ": " + e.getMessage(), e);
                }
                patch.setResult(null);
                File file = new File(patchDir, result.getPatchData().getId() + ".patch.result");
                if (isStandaloneChild) {
                    file = new File(patchDir, result.getPatchData().getId() + "." + System.getProperty("karaf.name") + ".patch.result");
                }
                file.delete();
            }
        });
    }
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Bundle(org.osgi.framework.Bundle) ArrayList(java.util.ArrayList) URISyntaxException(java.net.URISyntaxException) PatchException(io.fabric8.patch.management.PatchException) BundleException(org.osgi.framework.BundleException) IOException(java.io.IOException) Version(org.osgi.framework.Version) PatchResult(io.fabric8.patch.management.PatchResult) PatchException(io.fabric8.patch.management.PatchException) File(java.io.File) BundleUpdate(io.fabric8.patch.management.BundleUpdate)

Example 89 with Version

use of io.fabric8.kubernetes.model.annotation.Version in project fabric8 by jboss-fuse.

the class ServiceImpl method bundleUpdatesInPatch.

/**
 * Returns a list of {@link BundleUpdate} for single patch, taking into account already discovered updates
 * @param patch
 * @param allBundles
 * @param bundleUpdateLocations out parameter that gathers update locations for bundles across patches
 * @param history
 * @param updatesForBundleKeys
 * @param kind
 * @param coreBundles
 * @param featureUpdatesInThisPatch
 * @return
 * @throws IOException
 */
private List<BundleUpdate> bundleUpdatesInPatch(Patch patch, Bundle[] allBundles, Map<Bundle, String> bundleUpdateLocations, BundleVersionHistory history, Map<String, BundleUpdate> updatesForBundleKeys, PatchKind kind, Map<String, Bundle> coreBundles, List<FeatureUpdate> featureUpdatesInThisPatch) throws Exception {
    List<BundleUpdate> updatesInThisPatch = new LinkedList<>();
    // for ROLLUP patch we can check which bundles AREN'T updated by this patch - we have to reinstall them
    // at the same version as existing one. "no update" means "require install after clearing cache"
    // Initially all bundles need update. If we find an update in patch, we remove a key from this map
    Map<String, Bundle> updateNotRequired = new LinkedHashMap<>();
    // // let's keep {symbolic name -> list of versions} mapping
    // MultiMap<String, Version> allBundleVersions = new MultiMap<>();
    // bundle location -> bundle key (symbolic name|updateable version)
    Map<String, String> locationsOfBundleKeys = new HashMap<>();
    for (Bundle b : allBundles) {
        if (b.getSymbolicName() == null) {
            continue;
        }
        Version v = b.getVersion();
        Version updateableVersion = new Version(v.getMajor(), v.getMinor(), 0);
        String key = String.format("%s|%s", stripSymbolicName(b.getSymbolicName()), updateableVersion.toString());
        // symbolic name, differing at micro version only
        if (!coreBundles.containsKey(stripSymbolicName(b.getSymbolicName()))) {
            updateNotRequired.put(key, b);
        } else {
            // let's key core (etc/startup.properties) bundles by symbolic name only - there should be only
            // one version of symbolic name
            updateNotRequired.put(stripSymbolicName(b.getSymbolicName()), b);
        }
        // allBundleVersions.put(stripSymbolicName(b.getSymbolicName()), b.getVersion());
        String location = b.getLocation();
        if (location != null && location.startsWith("mvn:") && location.contains("//")) {
            // special case for mvn:org.ops4j.pax.url/pax-url-wrap/2.4.7//uber
            location = location.replace("//", "/jar/");
        }
        locationsOfBundleKeys.put(location, key);
    }
    // let's prepare a set of bundle keys that are part of features that will be updated/reinstalled - those
    // bundle keys don't have to be reinstalled separately
    Set<String> bundleKeysFromFeatures = new HashSet<>();
    if (featureUpdatesInThisPatch != null) {
        for (FeatureUpdate featureUpdate : featureUpdatesInThisPatch) {
            if (featureUpdate.getName() != null) {
                // this is either installation or update of single feature
                String fName = featureUpdate.getName();
                String fVersion = featureUpdate.getPreviousVersion();
                Feature f = featuresService.getFeature(fName, fVersion);
                for (BundleInfo bundleInfo : f.getBundles()) {
                    if (/*!bundleInfo.isDependency() && */
                    locationsOfBundleKeys.containsKey(bundleInfo.getLocation())) {
                        bundleKeysFromFeatures.add(locationsOfBundleKeys.get(bundleInfo.getLocation()));
                    }
                }
                for (Conditional cond : f.getConditional()) {
                    for (BundleInfo bundleInfo : cond.getBundles()) {
                        if (/*!bundleInfo.isDependency() && */
                        locationsOfBundleKeys.containsKey(bundleInfo.getLocation())) {
                            bundleKeysFromFeatures.add(locationsOfBundleKeys.get(bundleInfo.getLocation()));
                        }
                    }
                }
            }
        }
    }
    for (String newLocation : patch.getPatchData().getBundles()) {
        // [symbolicName, version] of the new bundle
        String[] symbolicNameVersion = helper.getBundleIdentity(newLocation);
        if (symbolicNameVersion == null || symbolicNameVersion[0] == null) {
            continue;
        }
        String sn = stripSymbolicName(symbolicNameVersion[0]);
        String vr = symbolicNameVersion[1];
        Version newVersion = VersionTable.getVersion(vr);
        Version updateableVersion = new Version(newVersion.getMajor(), newVersion.getMinor(), 0);
        // this bundle update from a patch may be applied only to relevant bundle|updateable-version, not to
        // *every* bundle with exact symbolic name
        String key = null;
        if (!coreBundles.containsKey(sn)) {
            key = String.format("%s|%s", sn, updateableVersion.toString());
        } else {
            key = sn;
        }
        // if existing bundle is within this range, update is possible
        VersionRange range = getUpdateableRange(patch, newLocation, newVersion);
        if (coreBundles.containsKey(sn)) {
            // so we lower down the lowest possible version of core bundle that we can update
            if (range == null) {
                range = new VersionRange(false, Version.emptyVersion, newVersion, true);
            } else {
                range = new VersionRange(false, Version.emptyVersion, range.getCeiling(), true);
            }
        } else if (range != null) {
            // if range is specified on non core bundle, the key should be different - updateable
            // version should be taken from range
            key = String.format("%s|%s", sn, range.getFloor().toString());
        }
        Bundle bundle = updateNotRequired.get(key);
        if (bundle == null && coreBundles.containsKey(sn)) {
            bundle = updateNotRequired.get(sn);
        }
        if (bundle == null || range == null) {
            // this patch ships a bundle that can't be used as an update for ANY currently installed bundle
            if (kind == PatchKind.NON_ROLLUP) {
                // which is strange, because non rollup patches should update existing bundles...
                if (range == null) {
                    System.err.printf("Skipping bundle %s - unable to process bundle without a version range configuration%n", newLocation);
                } else {
                // range is fine, we simply didn't find installed bundle at all - bundle from patch
                // will be stored in ${karaf.default.repository}, but not used as an update
                }
            }
            continue;
        }
        Version oldVersion = bundle.getVersion();
        if (range.contains(oldVersion)) {
            String oldLocation = history.getLocation(bundle);
            if ("org.ops4j.pax.url.mvn".equals(sn)) {
                Artifact artifact = Utils.mvnurlToArtifact(newLocation, true);
                if (artifact != null) {
                    URL location = new File(repository, String.format("org/ops4j/pax/url/pax-url-aether/%1$s/pax-url-aether-%1$s.jar", artifact.getVersion())).toURI().toURL();
                    newLocation = location.toString();
                }
            }
            int startLevel = bundle.adapt(BundleStartLevel.class).getStartLevel();
            int state = bundle.getState();
            BundleUpdate update = new BundleUpdate(sn, newVersion.toString(), newLocation, oldVersion.toString(), oldLocation, startLevel, state);
            if (bundleKeysFromFeatures.contains(key) || coreBundles.containsKey(sn)) {
                update.setIndependent(false);
            }
            updatesInThisPatch.add(update);
            updateNotRequired.remove(key);
            if (coreBundles.containsKey(sn)) {
                updateNotRequired.remove(sn);
            }
            // Merge result
            BundleUpdate oldUpdate = updatesForBundleKeys.get(key);
            if (oldUpdate != null) {
                Version upv = null;
                if (oldUpdate.getNewVersion() != null) {
                    upv = VersionTable.getVersion(oldUpdate.getNewVersion());
                }
                if (upv == null || upv.compareTo(newVersion) < 0) {
                    // other patch contains newer update for a bundle
                    updatesForBundleKeys.put(key, update);
                    bundleUpdateLocations.put(bundle, newLocation);
                }
            } else {
                // this is the first update of the bundle
                updatesForBundleKeys.put(key, update);
                bundleUpdateLocations.put(bundle, newLocation);
            }
        }
    }
    if (kind == PatchKind.ROLLUP) {
        // user features) and we have (at least try) to install them after restart.
        for (Bundle b : updateNotRequired.values()) {
            if (b.getSymbolicName() == null) {
                continue;
            }
            String symbolicName = stripSymbolicName(b.getSymbolicName());
            Version v = b.getVersion();
            Version updateableVersion = new Version(v.getMajor(), v.getMinor(), 0);
            String key = String.format("%s|%s", symbolicName, updateableVersion.toString());
            int startLevel = b.adapt(BundleStartLevel.class).getStartLevel();
            int state = b.getState();
            BundleUpdate update = new BundleUpdate(symbolicName, null, null, v.toString(), history.getLocation(b), startLevel, state);
            if (bundleKeysFromFeatures.contains(key) || coreBundles.containsKey(symbolicName)) {
                // we don't have to install it separately
                update.setIndependent(false);
            }
            updatesInThisPatch.add(update);
            updatesForBundleKeys.put(key, update);
        }
    }
    return updatesInThisPatch;
}
Also used : BundleStartLevel(org.osgi.framework.startlevel.BundleStartLevel) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Bundle(org.osgi.framework.Bundle) Conditional(org.apache.karaf.features.Conditional) VersionRange(org.apache.felix.utils.version.VersionRange) Feature(org.apache.karaf.features.Feature) LinkedList(java.util.LinkedList) Utils.mvnurlToArtifact(io.fabric8.patch.management.Utils.mvnurlToArtifact) Artifact(io.fabric8.patch.management.Artifact) URL(java.net.URL) LinkedHashMap(java.util.LinkedHashMap) BundleInfo(org.apache.karaf.features.BundleInfo) Version(org.osgi.framework.Version) File(java.io.File) BundleUpdate(io.fabric8.patch.management.BundleUpdate) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) FeatureUpdate(io.fabric8.patch.management.FeatureUpdate)

Example 90 with Version

use of io.fabric8.kubernetes.model.annotation.Version in project fabric8 by jboss-fuse.

the class ServiceImpl method install.

/**
 * <p>Main installation method. Installing a patch in non-fabric mode is a matter of correct merge (cherry-pick, merge,
 * rebase) of patch branch into <code>master</code> branch.</p>
 * <p>Static changes are handled by git, runtime changes (bundles, features) are handled depending on patch type:<ul>
 *     <li>Rollup: clear OSGi bundle cache, reinstall features that were installed after restart</li>
 *     <li>Non-Rollup: update bundles, generate overrides.properties and update scripts to reference new versions</li>
 * </ul></p>
 * <p>For Rollup patches we don't update bundles - we clear the bundle cache instead.</p>
 * @param patches
 * @param simulate
 * @param synchronous
 * @return
 */
private Map<String, PatchResult> install(final Collection<Patch> patches, final boolean simulate, boolean synchronous) {
    PatchKind kind = checkConsistency(patches);
    checkPrerequisites(patches);
    checkStandaloneChild(patches);
    // checkFabric();
    String transaction = null;
    try {
        // Compute individual patch results (patchId -> Result)
        final Map<String, PatchResult> results = new LinkedHashMap<String, PatchResult>();
        // current state of the framework
        Bundle[] allBundles = bundleContext.getBundles();
        // bundle -> url to update the bundle from (used for non-rollup patch)
        final Map<Bundle, String> bundleUpdateLocations = new HashMap<>();
        /* A "key" is name + "update'able version". Such version is current version with micro version == 0 */
        // [symbolic name|updateable-version] -> newest update for the bundle out of all installed patches
        final Map<String, BundleUpdate> updatesForBundleKeys = new LinkedHashMap<>();
        // [feature name|updateable-version] -> newest update for the feature out of all installed patches
        final Map<String, FeatureUpdate> updatesForFeatureKeys = new LinkedHashMap<>();
        // symbolic name -> version -> location
        final BundleVersionHistory history = createBundleVersionHistory();
        // beginning installation transaction = creating of temporary branch in git
        transaction = this.patchManagement.beginInstallation(kind);
        // bundles from etc/startup.properties + felix.framework = all bundles not managed by features
        // these bundles will be treated in special way
        // symbolic name -> Bundle
        final Map<String, Bundle> coreBundles = helper.getCoreBundles(allBundles);
        // runtime info is prepared to apply runtime changes and static info is prepared to update KARAF_HOME files
        for (Patch patch : patches) {
            List<FeatureUpdate> featureUpdatesInThisPatch = null;
            if (kind == PatchKind.ROLLUP) {
                // list of feature updates for the current patch
                featureUpdatesInThisPatch = featureUpdatesInPatch(patch, updatesForFeatureKeys, kind);
                helper.sortFeatureUpdates(featureUpdatesInThisPatch);
            }
            // list of bundle updates for the current patch - for ROLLUP patch, we minimize the list of bundles
            // to "restore" (install after clearing data/cache) by not including bundles that are
            // already updated as part of fueatures update
            List<BundleUpdate> bundleUpdatesInThisPatch = bundleUpdatesInPatch(patch, allBundles, bundleUpdateLocations, history, updatesForBundleKeys, kind, coreBundles, featureUpdatesInThisPatch);
            // each patch may change files, we're not updating the main files yet - it'll be done when
            // install transaction is committed
            patchManagement.install(transaction, patch, bundleUpdatesInThisPatch);
            // each patch may ship a migrator
            if (!simulate) {
                installMigratorBundle(patch);
            }
            // prepare patch result before doing runtime changes
            PatchResult result = null;
            if (patch.getResult() != null) {
                result = patch.getResult();
                if (patchManagement.isStandaloneChild()) {
                    // ENTESB-5120: "result" is actually a result of patch installation in root container
                    // we need dedicated result for admin:create based child container
                    PatchResult childResult = new PatchResult(patch.getPatchData(), simulate, System.currentTimeMillis(), bundleUpdatesInThisPatch, featureUpdatesInThisPatch, result);
                    result.addChildResult(System.getProperty("karaf.name"), childResult);
                }
            } else {
                result = new PatchResult(patch.getPatchData(), simulate, System.currentTimeMillis(), bundleUpdatesInThisPatch, featureUpdatesInThisPatch);
            }
            result.getKarafBases().add(String.format("%s | %s", System.getProperty("karaf.name"), System.getProperty("karaf.base")));
            results.put(patch.getPatchData().getId(), result);
        }
        // One special case
        if (kind == PatchKind.NON_ROLLUP) {
            // for rollup patch, this bundle will be installed from scratch
            for (Map.Entry<Bundle, String> entry : bundleUpdateLocations.entrySet()) {
                Bundle bundle = entry.getKey();
                if (bundle.getSymbolicName() != null && "org.ops4j.pax.url.mvn".equals(stripSymbolicName(bundle.getSymbolicName()))) {
                    // handle this bundle specially - update it here
                    URL location = new URL(entry.getValue());
                    System.out.printf("Special update of bundle \"%s\" from \"%s\"%n", bundle.getSymbolicName(), location);
                    if (!simulate) {
                        BundleUtils.update(bundle, location);
                        bundle.start();
                    }
                    // replace location - to be stored in result
                    bundleUpdateLocations.put(bundle, location.toString());
                }
            }
        }
        Presentation.displayFeatureUpdates(updatesForFeatureKeys.values(), true);
        // effectively, we will update all the bundles from this list - even if some bundles will be "updated"
        // as part of feature installation
        Presentation.displayBundleUpdates(updatesForBundleKeys.values(), true);
        // then required repositories, features and bundles will be reinstalled
        if (kind == PatchKind.ROLLUP) {
            if (!simulate) {
                if (patches.size() == 1) {
                    Patch patch = patches.iterator().next();
                    PatchResult result = results.get(patch.getPatchData().getId());
                    patch.setResult(result);
                    // single shot
                    if (patchManagement.isStandaloneChild()) {
                        backupService.backupDataFiles(result.getChildPatches().get(System.getProperty("karaf.name")), Pending.ROLLUP_INSTALLATION);
                    } else {
                        backupService.backupDataFiles(result, Pending.ROLLUP_INSTALLATION);
                    }
                    for (Bundle b : coreBundles.values()) {
                        if (b.getSymbolicName() != null && Utils.stripSymbolicName(b.getSymbolicName()).equals("org.apache.felix.fileinstall")) {
                            b.stop(Bundle.STOP_TRANSIENT);
                            break;
                        }
                    }
                    // update KARAF_HOME
                    patchManagement.commitInstallation(transaction);
                    if (patchManagement.isStandaloneChild()) {
                        result.getChildPatches().get(System.getProperty("karaf.name")).setPending(Pending.ROLLUP_INSTALLATION);
                    } else {
                        result.setPending(Pending.ROLLUP_INSTALLATION);
                    }
                    result.store();
                    // Some updates need a full JVM restart.
                    if (isJvmRestartNeeded(results)) {
                        boolean handlesFullRestart = Boolean.getBoolean("karaf.restart.jvm.supported");
                        if (handlesFullRestart) {
                            System.out.println("Rollup patch " + patch.getPatchData().getId() + " installed. Restarting Karaf..");
                            System.setProperty("karaf.restart.jvm", "true");
                        } else {
                            System.out.println("Rollup patch " + patch.getPatchData().getId() + " installed. Shutting down Karaf, please restart...");
                        }
                    } else {
                        // We don't need a JVM restart, so lets just do a OSGi framework restart
                        System.setProperty("karaf.restart", "true");
                    }
                    File karafData = new File(bundleContext.getProperty("karaf.data"));
                    File cleanCache = new File(karafData, "clean_cache");
                    cleanCache.createNewFile();
                    Thread.currentThread().setContextClassLoader(bundleContext.getBundle(0l).adapt(BundleWiring.class).getClassLoader());
                    bundleContext.getBundle(0l).stop();
                }
            } else {
                System.out.println("Simulation only - no files and runtime data will be modified.");
                patchManagement.rollbackInstallation(transaction);
            }
            return results;
        }
        // update KARAF_HOME
        if (!simulate) {
            patchManagement.commitInstallation(transaction);
        } else {
            patchManagement.rollbackInstallation(transaction);
        }
        if (!simulate) {
            Runnable task = new Runnable() {

                @Override
                public void run() {
                    try {
                        // update bundles
                        applyChanges(bundleUpdateLocations);
                        // persist results of all installed patches
                        for (Patch patch : patches) {
                            PatchResult result = results.get(patch.getPatchData().getId());
                            patch.setResult(result);
                            result.store();
                        }
                    } catch (Exception e) {
                        e.printStackTrace(System.err);
                        System.err.flush();
                    }
                }
            };
            if (synchronous) {
                task.run();
            } else {
                new Thread(task).start();
            }
        } else {
            System.out.println("Simulation only - no files and runtime data will be modified.");
        }
        return results;
    } catch (Exception e) {
        e.printStackTrace(System.err);
        System.err.flush();
        if (transaction != null && patchManagement != null) {
            patchManagement.rollbackInstallation(transaction);
        }
        throw new PatchException(e.getMessage(), e);
    } finally {
        System.out.flush();
    }
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) PatchKind(io.fabric8.patch.management.PatchKind) URL(java.net.URL) LinkedHashMap(java.util.LinkedHashMap) BundleUpdate(io.fabric8.patch.management.BundleUpdate) FeatureUpdate(io.fabric8.patch.management.FeatureUpdate) Bundle(org.osgi.framework.Bundle) URISyntaxException(java.net.URISyntaxException) PatchException(io.fabric8.patch.management.PatchException) BundleException(org.osgi.framework.BundleException) IOException(java.io.IOException) PatchResult(io.fabric8.patch.management.PatchResult) PatchException(io.fabric8.patch.management.PatchException) Patch(io.fabric8.patch.management.Patch) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) File(java.io.File)

Aggregations

Map (java.util.Map)87 Version (io.fabric8.api.Version)74 Profile (io.fabric8.api.Profile)70 Test (org.junit.jupiter.api.Test)66 ArrayList (java.util.ArrayList)63 IOException (java.io.IOException)62 File (java.io.File)61 HashMap (java.util.HashMap)61 Vertx (io.vertx.core.Vertx)58 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)57 Test (org.junit.Test)55 Checkpoint (io.vertx.junit5.Checkpoint)54 VertxExtension (io.vertx.junit5.VertxExtension)54 VertxTestContext (io.vertx.junit5.VertxTestContext)54 ExtendWith (org.junit.jupiter.api.extension.ExtendWith)54 KubernetesClient (io.fabric8.kubernetes.client.KubernetesClient)52 Reconciliation (io.strimzi.operator.common.Reconciliation)50 BeforeAll (org.junit.jupiter.api.BeforeAll)48 Collections (java.util.Collections)46 CoreMatchers.is (org.hamcrest.CoreMatchers.is)46