Search in sources :

Example 6 with BundleUpdate

use of io.fabric8.patch.management.BundleUpdate 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)

Example 7 with BundleUpdate

use of io.fabric8.patch.management.BundleUpdate in project fabric8 by jboss-fuse.

the class ServiceImplTest method testVersionHistory.

@Test
public void testVersionHistory() {
    // the same bundle has been patched twice
    Patch patch1 = new Patch(new PatchData("patch1", "First patch", null, null, null, null, null), null);
    patch1.setResult(new PatchResult(patch1.getPatchData(), true, System.currentTimeMillis(), new LinkedList<io.fabric8.patch.management.BundleUpdate>(), null));
    patch1.getResult().getBundleUpdates().add(new BundleUpdate("my-bsn", "1.1.0", "mvn:groupId/my-bsn/1.1.0", "1.0.0", "mvn:groupId/my-bsn/1.0.0"));
    Patch patch2 = new Patch(new PatchData("patch2", "Second patch", null, null, null, null, null), null);
    patch2.setResult(new PatchResult(patch1.getPatchData(), true, System.currentTimeMillis(), new LinkedList<io.fabric8.patch.management.BundleUpdate>(), null));
    patch2.getResult().getBundleUpdates().add(new BundleUpdate("my-bsn;directive1=true", "1.2.0", "mvn:groupId/my-bsn/1.2.0", "1.1.0", "mvn:groupId/my-bsn/1.1.0"));
    Map<String, Patch> patches = new HashMap<String, Patch>();
    patches.put("patch1", patch1);
    patches.put("patch2", patch2);
    // the version history should return the correct URL, even when bundle.getLocation() does not
    ServiceImpl.BundleVersionHistory history = new ServiceImpl.BundleVersionHistory(patches);
    assertEquals("Should return version from patch result instead of the original location", "mvn:groupId/my-bsn/1.2.0", history.getLocation(createMockBundle("my-bsn", "1.2.0", "mvn:groupId/my-bsn/1.0.0")));
    assertEquals("Should return version from patch result instead of the original location", "mvn:groupId/my-bsn/1.1.0", history.getLocation(createMockBundle("my-bsn", "1.1.0", "mvn:groupId/my-bsn/1.0.0")));
    assertEquals("Should return original bundle location if no maching version is found in the history", "mvn:groupId/my-bsn/1.0.0", history.getLocation(createMockBundle("my-bsn", "1.0.0", "mvn:groupId/my-bsn/1.0.0")));
    assertEquals("Should return original bundle location if no maching version is found in the history", "mvn:groupId/my-bsn/0.9.0", history.getLocation(createMockBundle("my-bsn", "0.9.0", "mvn:groupId/my-bsn/0.9.0")));
}
Also used : PatchData(io.fabric8.patch.management.PatchData) HashMap(java.util.HashMap) GitPatchManagementServiceImpl(io.fabric8.patch.management.impl.GitPatchManagementServiceImpl) LinkedList(java.util.LinkedList) PatchResult(io.fabric8.patch.management.PatchResult) Patch(io.fabric8.patch.management.Patch) BundleUpdate(io.fabric8.patch.management.BundleUpdate) Test(org.junit.Test)

Example 8 with BundleUpdate

use of io.fabric8.patch.management.BundleUpdate in project fabric8 by jboss-fuse.

the class ServiceImplTest method bundleUpdatesInPatch.

@Test
public void bundleUpdatesInPatch() throws Exception {
    BundleContext context = EasyMock.createMock(BundleContext.class);
    Bundle bundle0 = createMock(Bundle.class);
    expect(bundle0.getBundleContext()).andReturn(context);
    replay(bundle0);
    expect(context.getProperty("karaf.home")).andReturn("target/bundleUpdatesInPatch").anyTimes();
    expect(context.getProperty("karaf.base")).andReturn("target/bundleUpdatesInPatch").anyTimes();
    expect(context.getProperty("karaf.data")).andReturn("target/bundleUpdatesInPatch/data").anyTimes();
    expect(context.getProperty("karaf.name")).andReturn("root").anyTimes();
    expect(context.getProperty("karaf.instances")).andReturn("instances").anyTimes();
    expect(context.getProperty("karaf.default.repository")).andReturn("system");
    expect(context.getProperty("fuse.patch.location")).andReturn(null);
    expect(context.getBundle(0)).andReturn(bundle0);
    replay(context);
    ServiceImpl service = new ServiceImpl();
    Method m = service.getClass().getDeclaredMethod("bundleUpdatesInPatch", Patch.class, Bundle[].class, Map.class, ServiceImpl.BundleVersionHistory.class, Map.class, PatchKind.class, Map.class, List.class);
    m.setAccessible(true);
    Field f = service.getClass().getDeclaredField("helper");
    f.setAccessible(true);
    f.set(service, new OSGiPatchHelper(new File("target/bundleUpdatesInPatch"), context) {

        @Override
        public String[] getBundleIdentity(String url) throws IOException {
            Artifact a = Utils.mvnurlToArtifact(url, false);
            return new String[] { a.getArtifactId(), a.getVersion() };
        }
    });
    PatchData pd = new PatchData("patch-x");
    // for these two, bundle.getLocation() will return matching location
    pd.getBundles().add("mvn:io.fabric8/pax-romana/1.0.1");
    pd.getBundles().add("mvn:io.fabric8/pax-hellenica/1.0.1/jar");
    // for these two, bundle.getLocation() will return non-matching location
    pd.getBundles().add("mvn:io.fabric8/pax-bohemia/1.0.1");
    pd.getBundles().add("mvn:io.fabric8/pax-pomerania/1.0.1/jar");
    // for these two, bundle.getLocation() will return matching location
    pd.getBundles().add("mvn:io.fabric8/pax-avaria/1.0.1/jar/uber");
    pd.getBundles().add("mvn:io.fabric8/pax-mazovia/1.0.1//uber");
    // for these two, bundle.getLocation() will return non-matching location
    pd.getBundles().add("mvn:io.fabric8/pax-novgorod/1.0.1/jar/uber");
    pd.getBundles().add("mvn:io.fabric8/pax-castile/1.0.1//uber");
    f = pd.getClass().getDeclaredField("versionRanges");
    f.setAccessible(true);
    f.set(pd, new HashMap<>());
    Patch patch = new Patch(pd, null);
    Bundle[] bundles = new Bundle[8];
    bundles[0] = bundle("mvn:io.fabric8/pax-romana/1.0.0");
    bundles[1] = bundle("mvn:io.fabric8/pax-hellenica/1.0.0/jar");
    bundles[2] = bundle("mvn:io.fabric8/pax-bohemia/1.0.0/jar");
    bundles[3] = bundle("mvn:io.fabric8/pax-pomerania/1.0.0");
    bundles[4] = bundle("mvn:io.fabric8/pax-avaria/1.0.0/jar/uber");
    bundles[5] = bundle("mvn:io.fabric8/pax-mazovia/1.0.0//uber");
    bundles[6] = bundle("mvn:io.fabric8/pax-novgorod/1.0.0//uber");
    bundles[7] = bundle("mvn:io.fabric8/pax-castile/1.0.0/jar/uber");
    Object _list = m.invoke(service, patch, bundles, new HashMap<>(), new ServiceImpl.BundleVersionHistory(new HashMap<String, Patch>()), new HashMap<>(), PatchKind.NON_ROLLUP, new HashMap<>(), null);
    List<BundleUpdate> list = (List<BundleUpdate>) _list;
    assertThat(list.size(), equalTo(8));
    assertThat(list.get(0).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-romana/1.0.0"));
    assertThat(list.get(1).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-hellenica/1.0.0/jar"));
    assertThat(list.get(2).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-bohemia/1.0.0/jar"));
    assertThat(list.get(3).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-pomerania/1.0.0"));
    assertThat(list.get(4).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-avaria/1.0.0/jar/uber"));
    assertThat(list.get(5).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-mazovia/1.0.0//uber"));
    assertThat(list.get(6).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-novgorod/1.0.0//uber"));
    assertThat(list.get(7).getPreviousLocation(), equalTo("mvn:io.fabric8/pax-castile/1.0.0/jar/uber"));
    assertThat(list.get(0).getNewLocation(), equalTo("mvn:io.fabric8/pax-romana/1.0.1"));
    assertThat(list.get(1).getNewLocation(), equalTo("mvn:io.fabric8/pax-hellenica/1.0.1/jar"));
    assertThat(list.get(2).getNewLocation(), equalTo("mvn:io.fabric8/pax-bohemia/1.0.1"));
    assertThat(list.get(3).getNewLocation(), equalTo("mvn:io.fabric8/pax-pomerania/1.0.1/jar"));
    assertThat(list.get(4).getNewLocation(), equalTo("mvn:io.fabric8/pax-avaria/1.0.1/jar/uber"));
    assertThat(list.get(5).getNewLocation(), equalTo("mvn:io.fabric8/pax-mazovia/1.0.1//uber"));
    assertThat(list.get(6).getNewLocation(), equalTo("mvn:io.fabric8/pax-novgorod/1.0.1/jar/uber"));
    assertThat(list.get(7).getNewLocation(), equalTo("mvn:io.fabric8/pax-castile/1.0.1//uber"));
    // ---
    Repository repository = createMock(Repository.class);
    File tmp = new File("target/bundleUpdatesInPatch/" + UUID.randomUUID().toString());
    tmp.mkdirs();
    File startupProperties = new File(tmp, "etc/startup.properties");
    FileUtils.copyFile(new File("src/test/resources/uber-startup.properties"), startupProperties);
    expect(repository.getWorkTree()).andReturn(tmp).anyTimes();
    replay(repository);
    Git fork = createMock(Git.class);
    expect(fork.getRepository()).andReturn(repository).anyTimes();
    replay(fork);
    GitPatchManagementServiceImpl gitPatchManagementService = new GitPatchManagementServiceImpl(context);
    m = gitPatchManagementService.getClass().getDeclaredMethod("updateFileReferences", Git.class, PatchData.class, List.class);
    m.setAccessible(true);
    m.invoke(gitPatchManagementService, fork, pd, list);
    try (FileReader reader = new FileReader(startupProperties)) {
        Properties startup = new Properties();
        startup.load(reader);
        assertTrue(startup.containsKey("io/fabric8/pax-romana/1.0.1/pax-romana-1.0.1.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-hellenica/1.0.1/pax-hellenica-1.0.1.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-bohemia/1.0.1/pax-bohemia-1.0.1.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-pomerania/1.0.1/pax-pomerania-1.0.1.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-avaria/1.0.1/pax-avaria-1.0.1-uber.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-mazovia/1.0.1/pax-mazovia-1.0.1-uber.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-novgorod/1.0.1/pax-novgorod-1.0.1-uber.jar"));
        assertTrue(startup.containsKey("io/fabric8/pax-castile/1.0.1/pax-castile-1.0.1-uber.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-romana/1.0.0/pax-romana-1.0.0.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-hellenica/1.0.0/pax-hellenica-1.0.0.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-bohemia/1.0.0/pax-bohemia-1.0.0.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-pomerania/1.0.0/pax-pomerania-1.0.0.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-avaria/1.0.0/pax-avaria-1.0.0-uber.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-mazovia/1.0.0/pax-mazovia-1.0.0-uber.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-novgorod/1.0.0/pax-novgorod-1.0.0-uber.jar"));
        assertFalse(startup.containsKey("io/fabric8/pax-castile/1.0.0/pax-castile-1.0.0-uber.jar"));
    }
}
Also used : HashMap(java.util.HashMap) Properties(java.util.Properties) Field(java.lang.reflect.Field) List(java.util.List) LinkedList(java.util.LinkedList) FileReader(java.io.FileReader) BundleUpdate(io.fabric8.patch.management.BundleUpdate) PatchData(io.fabric8.patch.management.PatchData) Bundle(org.osgi.framework.Bundle) GitPatchManagementServiceImpl(io.fabric8.patch.management.impl.GitPatchManagementServiceImpl) Method(java.lang.reflect.Method) IOException(java.io.IOException) Artifact(io.fabric8.patch.management.Artifact) GitPatchRepository(io.fabric8.patch.management.impl.GitPatchRepository) Repository(org.eclipse.jgit.lib.Repository) Git(org.eclipse.jgit.api.Git) GitPatchManagementServiceImpl(io.fabric8.patch.management.impl.GitPatchManagementServiceImpl) JarFile(java.util.jar.JarFile) File(java.io.File) Patch(io.fabric8.patch.management.Patch) BundleContext(org.osgi.framework.BundleContext) Test(org.junit.Test)

Example 9 with BundleUpdate

use of io.fabric8.patch.management.BundleUpdate in project fabric8 by jboss-fuse.

the class Presentation method displayBundleUpdates.

/**
 * Displays a table with installed (<code>install == true</code>) or rolledback bundles
 * @param updatesForBundleKeys
 * @param install is this displayed during patch install (<code>true</code>) or rollback (<code>false</code>)
 */
public static void displayBundleUpdates(Collection<BundleUpdate> updatesForBundleKeys, boolean install) {
    int l1 = "[symbolic name]".length();
    int l2 = "[version]".length();
    int l3 = install ? "[new location]".length() : "[previous location]".length();
    // updates
    int tu = 0;
    // updates as part of features
    int tuf = 0;
    // reinstalls
    int tk = 0;
    // reinstalls as part of features
    int tkf = 0;
    Map<String, BundleUpdate> map = new TreeMap<>();
    for (BundleUpdate be : updatesForBundleKeys) {
        String sn = be.getSymbolicName() == null ? "" : stripSymbolicName(be.getSymbolicName());
        if (sn.length() > l1) {
            l1 = sn.length();
        }
        if (install) {
            String version = be.getPreviousVersion() == null ? "<update>" : be.getPreviousVersion();
            if (version.length() > l2) {
                l2 = version.length();
            }
        } else {
            String version = be.getNewVersion() == null ? be.getPreviousVersion() : be.getNewVersion();
            if (version.length() > l2) {
                l2 = version.length();
            }
        }
        if (install) {
            String newLocation = be.getNewLocation() == null ? "<reinstall>" : be.getNewLocation();
            if (newLocation.length() > l3) {
                l3 = newLocation.length();
            }
        } else {
            String previousLocation = be.getPreviousLocation();
            if (previousLocation.length() > l3) {
                l3 = previousLocation.length();
            }
        }
        if (be.getNewLocation() != null) {
            if (be.isIndependent()) {
                tu++;
            } else {
                tuf++;
            }
        } else {
            if (be.isIndependent()) {
                tk++;
            } else {
                tkf++;
            }
        }
        map.put(be.getSymbolicName(), be);
    }
    if (tu > 0) {
        System.out.printf("========== Bundles to %s (%d):%n", install ? "update" : "downgrade", tu);
        System.out.printf("%-" + l1 + "s   %-" + l2 + "s   %-" + l3 + "s%n", "[symbolic name]", "[version]", install ? "[new location]" : "[previous location]");
        for (Map.Entry<String, BundleUpdate> e : map.entrySet()) {
            BundleUpdate be = e.getValue();
            if (be.isIndependent() && be.getNewLocation() != null) {
                System.out.printf("%-" + l1 + "s   %-" + l2 + "s   %-" + l3 + "s%n", be.getSymbolicName() == null ? "" : stripSymbolicName(be.getSymbolicName()), install ? (be.getPreviousVersion() == null ? "<update>" : be.getPreviousVersion()) : be.getNewVersion(), install ? be.getNewLocation() : be.getPreviousLocation());
            }
        }
    }
    if (tuf > 0) {
        System.out.printf("========== Bundles to %s as part of features or core bundles (%d):%n", install ? "update" : "downgrade", tuf);
        System.out.printf("%-" + l1 + "s   %-" + l2 + "s   %-" + l3 + "s%n", "[symbolic name]", "[version]", install ? "[new location]" : "[previous location]");
        for (Map.Entry<String, BundleUpdate> e : map.entrySet()) {
            BundleUpdate be = e.getValue();
            if (!be.isIndependent() && be.getNewLocation() != null) {
                System.out.printf("%-" + l1 + "s   %-" + l2 + "s   %-" + l3 + "s%n", be.getSymbolicName() == null ? "" : stripSymbolicName(be.getSymbolicName()), install ? be.getPreviousVersion() : be.getNewVersion(), install ? be.getNewLocation() : be.getPreviousLocation());
            }
        }
    }
    if (tk > 0) {
        System.out.printf("========== Bundles to reinstall (%d):%n", tk);
        System.out.printf("%-" + l1 + "s   %-" + l2 + "s   %-" + l3 + "s%n", "[symbolic name]", "[version]", "[location]");
        for (Map.Entry<String, BundleUpdate> e : map.entrySet()) {
            BundleUpdate be = e.getValue();
            if (be.isIndependent() && be.getNewLocation() == null) {
                System.out.printf("%-" + l1 + "s   %-" + l2 + "s   %-" + l3 + "s%n", be.getSymbolicName() == null ? "" : stripSymbolicName(be.getSymbolicName()), be.getPreviousVersion(), be.getPreviousLocation());
            }
        }
    }
    if (tkf > 0) {
        System.out.printf("========== Bundles to reinstall as part of features or core bundles (%d):%n", tkf);
        System.out.printf("%-" + l1 + "s   %-" + l2 + "s   %-" + l3 + "s%n", "[symbolic name]", "[version]", "[location]");
        for (Map.Entry<String, BundleUpdate> e : map.entrySet()) {
            BundleUpdate be = e.getValue();
            if (!be.isIndependent() && be.getNewLocation() == null) {
                System.out.printf("%-" + l1 + "s   %-" + l2 + "s   %-" + l3 + "s%n", be.getSymbolicName() == null ? "" : stripSymbolicName(be.getSymbolicName()), be.getPreviousVersion(), be.getPreviousLocation());
            }
        }
    }
    System.out.flush();
}
Also used : TreeMap(java.util.TreeMap) TreeMap(java.util.TreeMap) Map(java.util.Map) BundleUpdate(io.fabric8.patch.management.BundleUpdate)

Example 10 with BundleUpdate

use of io.fabric8.patch.management.BundleUpdate in project fabric8 by jboss-fuse.

the class FileBackupService method backupDataFiles.

/**
 * Invoked just before Framework is restarted and data/cache directory is removed. We copy existing data
 * directories for current bundles and record for which bundle$$version it is used.
 * @param result used to create backup directories.
 * @param pending
 * @throws IOException
 */
@Override
public void backupDataFiles(PatchResult result, Pending pending) throws IOException {
    Map<String, Bundle> bundlesWithData = new HashMap<>();
    // bundle.getDataFile("xxx") creates data dir if it didn't exist - it's not what we want
    String storageLocation = systemContext.getProperty("org.osgi.framework.storage");
    if (storageLocation == null) {
        Activator.log(LogService.LOG_INFO, "Can't determine \"org.osgi.framework.storage\" property value");
        return;
    }
    File cacheDir = new File(storageLocation);
    if (!cacheDir.isDirectory()) {
        return;
    }
    for (Bundle b : systemContext.getBundles()) {
        if (b.getSymbolicName() != null) {
            String sn = Utils.stripSymbolicName(b.getSymbolicName());
            if ("org.apache.karaf.features.core".equals(sn)) {
                // we start with fresh features service state
                continue;
            }
            // a bit of knowledge of how Felix works below...
            File dataDir = new File(cacheDir, "bundle" + b.getBundleId() + "/data");
            if (dataDir.isDirectory()) {
                String key = String.format("%s$$%s", sn, b.getVersion().toString());
                bundlesWithData.put(key, b);
            }
        }
    }
    // this property file will be used to map full symbolicName$$version to a location where bundle data
    // is stored - the data must be restored both during R patch installation and rollback
    Properties properties = new Properties();
    String dirName = result.getPatchData().getId() + ".datafiles";
    if (result.getParent() != null) {
        dirName = result.getPatchData().getId() + "." + System.getProperty("karaf.name") + ".datafiles";
    }
    File dataBackupDir = new File(result.getPatchData().getPatchLocation(), dirName);
    String prefix = pending == Pending.ROLLUP_INSTALLATION ? "install" : "rollback";
    for (BundleUpdate update : result.getBundleUpdates()) {
        // same update for both updated and reinstalled bundle
        String key = String.format("%s$$%s", update.getSymbolicName(), pending == Pending.ROLLUP_INSTALLATION ? update.getPreviousVersion() : (update.getNewVersion() == null ? update.getPreviousVersion() : update.getNewVersion()));
        if (bundlesWithData.containsKey(key)) {
            File dataFileBackupDir = new File(dataBackupDir, prefix + "/" + key + "/data");
            dataFileBackupDir.mkdirs();
            final Bundle b = bundlesWithData.get(key);
            FileUtils.copyDirectory(b.getDataFile(""), dataFileBackupDir, new FileFilter() {

                @Override
                public boolean accept(File pathname) {
                    return pathname.isDirectory() || !b.getSymbolicName().equals("org.apache.felix.configadmin") || pathname.getName().endsWith(".config");
                }
            });
            properties.setProperty(key, key);
            properties.setProperty(String.format("%s$$%s", update.getSymbolicName(), update.getPreviousVersion()), key);
            if (update.getNewVersion() != null) {
                properties.setProperty(String.format("%s$$%s", update.getSymbolicName(), update.getNewVersion()), key);
            }
        }
    }
    FileOutputStream propsFile = new FileOutputStream(new File(dataBackupDir, "backup-" + prefix + ".properties"));
    properties.store(propsFile, "Data files to restore after \"" + result.getPatchData().getId() + "\" " + (pending == Pending.ROLLUP_INSTALLATION ? "installation" : "rollback"));
    propsFile.close();
}
Also used : HashMap(java.util.HashMap) Bundle(org.osgi.framework.Bundle) FileOutputStream(java.io.FileOutputStream) Properties(java.util.Properties) FileFilter(java.io.FileFilter) File(java.io.File) BundleUpdate(io.fabric8.patch.management.BundleUpdate)

Aggregations

BundleUpdate (io.fabric8.patch.management.BundleUpdate)16 File (java.io.File)14 LinkedList (java.util.LinkedList)11 Test (org.junit.Test)9 HashMap (java.util.HashMap)7 PatchResult (io.fabric8.patch.management.PatchResult)6 Bundle (org.osgi.framework.Bundle)6 IOException (java.io.IOException)5 Git (org.eclipse.jgit.api.Git)5 Patch (io.fabric8.patch.management.Patch)4 PatchData (io.fabric8.patch.management.PatchData)4 PatchException (io.fabric8.patch.management.PatchException)4 GitPatchManagementServiceImpl (io.fabric8.patch.management.impl.GitPatchManagementServiceImpl)4 Map (java.util.Map)4 Properties (java.util.Properties)4 FeatureUpdate (io.fabric8.patch.management.FeatureUpdate)3 GitPatchRepository (io.fabric8.patch.management.impl.GitPatchRepository)3 URISyntaxException (java.net.URISyntaxException)3 LinkedHashMap (java.util.LinkedHashMap)3 Artifact (io.fabric8.patch.management.Artifact)2