Search in sources :

Example 21 with Patch

use of org.jboss.fuse.patch.management.Patch in project fuse-karaf by jboss-fuse.

the class PatchServiceImpl method resumePendingPatchTasks.

/**
 * Upon startup (activation), we check if there are any *.patch.pending files. if yes, we're finishing the
 * installation
 */
private void resumePendingPatchTasks() {
    LOG.info("Performing \"resume pending patch tasks\"");
    try {
        File[] pendingPatches = patchDir.listFiles(pathname -> pathname.exists() && pathname.getName().endsWith(".pending"));
        if (pendingPatches == null || pendingPatches.length == 0) {
            return;
        }
        for (File pending : pendingPatches) {
            Pending what = Pending.valueOf(FileUtils.readFileToString(pending, "UTF-8"));
            String name = pending.getName().replaceFirst("\\.pending$", "");
            if (patchManagement.isStandaloneChild()) {
                if (name.endsWith("." + System.getProperty("karaf.name") + ".patch")) {
                    name = name.replaceFirst("\\." + System.getProperty("karaf.name"), "");
                } else {
                    continue;
                }
            }
            File patchFile = new File(pending.getParentFile(), name);
            if (!patchFile.isFile()) {
                System.out.println("Ignoring patch result file: " + patchFile.getName());
                continue;
            }
            PatchData patchData = PatchData.load(new FileInputStream(patchFile));
            Patch patch = patchManagement.loadPatch(new PatchDetailsRequest(patchData.getId()));
            System.out.printf("Resume %s of %spatch \"%s\"%n", what == Pending.ROLLUP_INSTALLATION ? "installation" : "rollback", patch.getPatchData().isRollupPatch() ? "rollup " : "", patch.getPatchData().getId());
            PatchResult result = patch.getResult();
            if (patchManagement.isStandaloneChild()) {
                result = result.getChildPatches().get(System.getProperty("karaf.name"));
                if (result == null) {
                    System.out.println("Ignoring patch result file: " + patchFile.getName());
                    continue;
                }
            }
            // feature time
            Set<String> newRepositories = new LinkedHashSet<>();
            Set<String> features = new LinkedHashSet<>();
            for (FeatureUpdate featureUpdate : result.getFeatureUpdates()) {
                if (featureUpdate.getName() == null && featureUpdate.getPreviousRepository() != null) {
                    // feature was not shipped by patch
                    newRepositories.add(featureUpdate.getPreviousRepository());
                } else if (featureUpdate.getNewRepository() == null) {
                    // feature was not changed by patch
                    newRepositories.add(featureUpdate.getPreviousRepository());
                    features.add(String.format("%s|%s", featureUpdate.getName(), featureUpdate.getPreviousVersion()));
                } else {
                    // feature was shipped by patch
                    if (what == Pending.ROLLUP_INSTALLATION) {
                        newRepositories.add(featureUpdate.getNewRepository());
                        features.add(String.format("%s|%s", featureUpdate.getName(), featureUpdate.getNewVersion()));
                    } else {
                        newRepositories.add(featureUpdate.getPreviousRepository());
                        features.add(String.format("%s|%s", featureUpdate.getName(), featureUpdate.getPreviousVersion()));
                    }
                }
            }
            System.out.println("Restoring feature repositories");
            for (String repo : newRepositories) {
                try {
                    URI repositoryUri = URI.create(repo);
                    if (featuresService.getRepository(repositoryUri) == null) {
                        System.out.println("Restoring feature repository: " + repo);
                        featuresService.addRepository(repositoryUri);
                    }
                } catch (Exception e) {
                    System.err.println(e.getMessage());
                    e.printStackTrace(System.err);
                    System.err.flush();
                }
            }
            Set<String> installedFeatures = null;
            try {
                installedFeatures = Arrays.stream(featuresService.listInstalledFeatures()).map(f -> String.format("%s|%s", f.getName(), f.getVersion())).collect(Collectors.toSet());
            } catch (Exception e) {
                System.err.println(e.getMessage());
                e.printStackTrace(System.err);
                System.err.flush();
            }
            EnumSet<FeaturesService.Option> options = EnumSet.noneOf(FeaturesService.Option.class);
            Set<String> toInstall = new LinkedHashSet<>();
            System.out.println("Restoring features");
            for (String f : features) {
                if (installedFeatures == null || !installedFeatures.contains(f)) {
                    String[] fv = f.split("\\|");
                    String fid = String.format("%s/%s", fv[0], fv[1]);
                    System.out.printf("Restoring feature %s%n", fid);
                    toInstall.add(fid);
                }
            }
            try {
                if (!toInstall.isEmpty()) {
                    featuresService.installFeatures(toInstall, options);
                }
                System.out.println("Refreshing features service");
                featuresService.refreshFeatures(options);
            } catch (Exception e) {
                System.err.println(e.getMessage());
                e.printStackTrace(System.err);
                System.err.flush();
            }
            for (BundleUpdate update : result.getBundleUpdates()) {
                if (!update.isIndependent()) {
                    continue;
                }
                String location = null;
                if (update.getNewVersion() == null) {
                    System.out.printf("Restoring bundle %s from %s%n", update.getSymbolicName(), update.getPreviousLocation());
                    location = update.getPreviousLocation();
                } else {
                    if (what == Pending.ROLLUP_INSTALLATION) {
                        System.out.printf("Updating bundle %s from %s%n", update.getSymbolicName(), update.getNewLocation());
                        location = update.getNewLocation();
                    } else {
                        System.out.printf("Downgrading bundle %s from %s%n", update.getSymbolicName(), update.getPreviousLocation());
                        location = update.getPreviousLocation();
                    }
                }
                try {
                    Bundle b = bundleContext.installBundle(location);
                    if (update.getStartLevel() > -1) {
                        b.adapt(BundleStartLevel.class).setStartLevel(update.getStartLevel());
                    }
                    switch(update.getState()) {
                        // ?
                        case Bundle.UNINSTALLED:
                        case Bundle.INSTALLED:
                        case Bundle.STARTING:
                        case Bundle.STOPPING:
                            break;
                        case Bundle.RESOLVED:
                            // ?bundleContext.getBundle(0L).adapt(org.osgi.framework.wiring.FrameworkWiring.class).resolveBundles(...);
                            break;
                        case Bundle.ACTIVE:
                            b.start();
                            break;
                    }
                } catch (BundleException e) {
                    System.err.println(" - " + e.getMessage());
                    // e.printStackTrace(System.err);
                    System.err.flush();
                }
            }
            pending.delete();
            System.out.printf("%spatch \"%s\" %s successfully%n", patch.getPatchData().isRollupPatch() ? "Rollup " : "", patchData.getId(), what == Pending.ROLLUP_INSTALLATION ? "installed" : "rolled back");
            if (what == Pending.ROLLUP_INSTALLATION) {
                System.out.printf("Summary of patch %s:%n", patch.getPatchData().getId());
                PatchReport report = patch.getResult().getReport();
                System.out.printf(" - Bundles updated: %d%n", report.getUpdatedBundles());
                System.out.printf(" - Features updated: %d%n", report.getUpdatedFeatures());
                System.out.printf(" - Features overriden: %d%n", report.getOverridenFeatures());
                System.out.printf("Detailed report: %s%n", new File(patch.getPatchData().getPatchLocation(), patch.getPatchData().getId() + ".patch.result.html").getCanonicalPath());
                System.out.flush();
            }
            if (what == Pending.ROLLUP_ROLLBACK) {
                List<String> bases = patch.getResult().getKarafBases();
                bases.removeIf(s -> s.startsWith(System.getProperty("karaf.name")));
                result.setPending(null);
                patch.getResult().store();
                if (patch.getResult().getKarafBases().size() == 0) {
                    File file = new File(patchDir, patchData.getId() + ".patch.result");
                    file.delete();
                }
                if (patchManagement.isStandaloneChild()) {
                    File file = new File(patchDir, patchData.getId() + "." + System.getProperty("karaf.name") + ".patch.result");
                    if (file.isFile()) {
                        file.delete();
                    }
                }
            }
        }
    } catch (IOException e) {
        LOG.error("Error resuming a patch: " + e.getMessage(), e);
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) BundleStartLevel(org.osgi.framework.startlevel.BundleStartLevel) PatchDetailsRequest(org.jboss.fuse.patch.management.PatchDetailsRequest) URI(java.net.URI) FeaturesService(org.apache.karaf.features.FeaturesService) BundleException(org.osgi.framework.BundleException) BundleUpdate(org.jboss.fuse.patch.management.BundleUpdate) FeatureUpdate(org.jboss.fuse.patch.management.FeatureUpdate) PatchData(org.jboss.fuse.patch.management.PatchData) Bundle(org.osgi.framework.Bundle) PatchReport(org.jboss.fuse.patch.management.PatchReport) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) URISyntaxException(java.net.URISyntaxException) PatchException(org.jboss.fuse.patch.management.PatchException) BundleException(org.osgi.framework.BundleException) IOException(java.io.IOException) PatchResult(org.jboss.fuse.patch.management.PatchResult) File(java.io.File) Patch(org.jboss.fuse.patch.management.Patch) Pending(org.jboss.fuse.patch.management.Pending)

Example 22 with Patch

use of org.jboss.fuse.patch.management.Patch in project fuse-karaf by jboss-fuse.

the class PatchServiceImpl method checkStandaloneChild.

/**
 * Check if this is installation in @{link {@link org.jboss.fuse.patch.management.EnvType#STANDALONE_CHILD}}
 * - in this case the patch has to be installed in root first
 * @param patches
 */
private void checkStandaloneChild(Collection<Patch> patches) {
    if (patchManagement.isStandaloneChild()) {
        for (Patch patch : patches) {
            if (patch.getResult() == null) {
                throw new PatchException(String.format("Patch '%s' should be installed in parent container first", patch.getPatchData().getId()));
            } else {
                List<String> bases = patch.getResult().getKarafBases();
                boolean isInstalledInRoot = false;
                for (String base : bases) {
                    String[] coords = base.split("\\s*\\|\\s*");
                    if (coords.length == 2 && coords[1].trim().equals(System.getProperty("karaf.home"))) {
                        isInstalledInRoot = true;
                    }
                }
                if (!isInstalledInRoot) {
                    throw new PatchException(String.format("Patch '%s' should be installed in parent container first", patch.getPatchData().getId()));
                }
            }
        }
    }
}
Also used : PatchException(org.jboss.fuse.patch.management.PatchException) Patch(org.jboss.fuse.patch.management.Patch)

Example 23 with Patch

use of org.jboss.fuse.patch.management.Patch in project fuse-karaf by jboss-fuse.

the class PatchServiceImpl method download.

@Override
public Iterable<Patch> download(URL url) {
    if ("file".equals(url.getProtocol())) {
        // ENTESB-4992: prevent adding non existing files or directories
        try {
            if (!new File(url.toURI()).isFile()) {
                throw new PatchException("Path " + url.getPath() + " doesn't exist or is not a file");
            }
        } catch (URISyntaxException e) {
            throw new PatchException(e.getMessage(), e);
        }
    }
    try {
        List<PatchData> patchesData = patchManagement.fetchPatches(url);
        List<Patch> patches = new ArrayList<>(patchesData.size());
        for (PatchData patchData : patchesData) {
            Patch patch = patchManagement.trackPatch(patchData);
            patches.add(patch);
        }
        return patches;
    } catch (PatchException e) {
        throw e;
    } catch (Exception e) {
        throw new PatchException("Unable to download patch from url " + url, e);
    }
}
Also used : PatchData(org.jboss.fuse.patch.management.PatchData) ArrayList(java.util.ArrayList) PatchException(org.jboss.fuse.patch.management.PatchException) URISyntaxException(java.net.URISyntaxException) File(java.io.File) Patch(org.jboss.fuse.patch.management.Patch) URISyntaxException(java.net.URISyntaxException) PatchException(org.jboss.fuse.patch.management.PatchException) BundleException(org.osgi.framework.BundleException) IOException(java.io.IOException)

Example 24 with Patch

use of org.jboss.fuse.patch.management.Patch in project fuse-karaf by jboss-fuse.

the class PatchServiceImpl method cliInstall.

/**
 * Used by the patch client when executing the script in the console
 * @param ids
 */
public void cliInstall(String[] ids) {
    final List<Patch> patches = new ArrayList<Patch>();
    for (String id : ids) {
        Patch patch = getPatch(id);
        if (patch == null) {
            throw new IllegalArgumentException("Unknown patch: " + id);
        }
        patches.add(patch);
    }
    install(patches, false, false);
}
Also used : ArrayList(java.util.ArrayList) Patch(org.jboss.fuse.patch.management.Patch)

Example 25 with Patch

use of org.jboss.fuse.patch.management.Patch in project fuse-karaf by jboss-fuse.

the class PatchServiceImplTest method testPatchWithVersionRanges.

@Test
public void testPatchWithVersionRanges() throws Exception {
    ComponentContext componentContext = mock(ComponentContext.class);
    BundleContext bundleContext = mock(BundleContext.class);
    Bundle sysBundle = mock(Bundle.class);
    BundleContext sysBundleContext = mock(BundleContext.class);
    Bundle bundle = mock(Bundle.class);
    Bundle bundle2 = mock(Bundle.class);
    FrameworkWiring wiring = mock(FrameworkWiring.class);
    GitPatchRepository repository = mock(GitPatchRepository.class);
    // 
    // Create a new service, download a patch
    // 
    when(componentContext.getBundleContext()).thenReturn(bundleContext);
    when(bundleContext.getBundle(0)).thenReturn(sysBundle);
    when(sysBundle.getBundleContext()).thenReturn(sysBundleContext);
    when(sysBundleContext.getProperty(PatchService.PATCH_LOCATION)).thenReturn(storage.toString());
    when(repository.getManagedPatch(anyString())).thenReturn(null);
    when(repository.findOrCreateMainGitRepository()).thenReturn(null);
    when(sysBundleContext.getProperty("karaf.default.repository")).thenReturn("system");
    when(sysBundleContext.getProperty("karaf.home")).thenReturn(karaf.getCanonicalPath());
    when(sysBundleContext.getProperty("karaf.base")).thenReturn(karaf.getCanonicalPath());
    when(sysBundleContext.getProperty("karaf.name")).thenReturn("root");
    when(sysBundleContext.getProperty("karaf.instances")).thenReturn(karaf.getCanonicalPath() + "/instances");
    when(sysBundleContext.getProperty("karaf.data")).thenReturn(karaf.getCanonicalPath() + "/data");
    when(sysBundleContext.getProperty("karaf.etc")).thenReturn(karaf.getCanonicalPath() + "/etc");
    PatchManagement pm = mockManagementService(bundleContext);
    ((GitPatchManagementServiceImpl) pm).setGitPatchRepository(repository);
    PatchServiceImpl service = new PatchServiceImpl();
    setField(service, "patchManagement", pm);
    service.activate(componentContext);
    Iterable<Patch> patches = service.download(patch140.toURI().toURL());
    assertNotNull(patches);
    Iterator<Patch> it = patches.iterator();
    assertTrue(it.hasNext());
    Patch patch = it.next();
    assertNotNull(patch);
    assertEquals("patch-1.4.0", patch.getPatchData().getId());
    assertNotNull(patch.getPatchData().getBundles());
    assertEquals(1, patch.getPatchData().getBundles().size());
    Iterator<String> itb = patch.getPatchData().getBundles().iterator();
    assertEquals("mvn:foo/my-bsn/1.4.0", itb.next());
    assertNull(patch.getResult());
    // 
    // Simulate the patch
    // 
    when(sysBundleContext.getBundles()).thenReturn(new Bundle[] { bundle });
    when(sysBundleContext.getServiceReference("io.fabric8.api.FabricService")).thenReturn(null);
    when(bundle.getSymbolicName()).thenReturn("my-bsn");
    when(bundle.getVersion()).thenReturn(new Version("1.3.1"));
    when(bundle.getLocation()).thenReturn("location");
    when(bundle.getBundleId()).thenReturn(123L);
    BundleStartLevel bsl = mock(BundleStartLevel.class);
    when(bsl.getStartLevel()).thenReturn(30);
    when(bundle.adapt(BundleStartLevel.class)).thenReturn(bsl);
    when(bundle.getState()).thenReturn(1);
    when(sysBundleContext.getProperty("karaf.default.repository")).thenReturn("system");
    PatchResult result = service.install(patch, true);
    assertNotNull(result);
    assertEquals(1, result.getBundleUpdates().size());
    assertTrue(result.isSimulation());
}
Also used : BundleStartLevel(org.osgi.framework.startlevel.BundleStartLevel) ComponentContext(org.osgi.service.component.ComponentContext) Bundle(org.osgi.framework.Bundle) GitPatchRepository(org.jboss.fuse.patch.management.impl.GitPatchRepository) FrameworkWiring(org.osgi.framework.wiring.FrameworkWiring) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) GitPatchManagementServiceImpl(org.jboss.fuse.patch.management.impl.GitPatchManagementServiceImpl) Version(org.osgi.framework.Version) PatchManagement(org.jboss.fuse.patch.management.PatchManagement) PatchResult(org.jboss.fuse.patch.management.PatchResult) Patch(org.jboss.fuse.patch.management.Patch) BundleContext(org.osgi.framework.BundleContext) Test(org.junit.Test)

Aggregations

Patch (org.jboss.fuse.patch.management.Patch)33 PatchException (org.jboss.fuse.patch.management.PatchException)20 IOException (java.io.IOException)12 PatchResult (org.jboss.fuse.patch.management.PatchResult)11 File (java.io.File)10 ManagedPatch (org.jboss.fuse.patch.management.ManagedPatch)9 PatchData (org.jboss.fuse.patch.management.PatchData)9 Test (org.junit.Test)9 LinkedList (java.util.LinkedList)7 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)7 PatchDetailsRequest (org.jboss.fuse.patch.management.PatchDetailsRequest)7 HashMap (java.util.HashMap)6 BundleUpdate (org.jboss.fuse.patch.management.BundleUpdate)6 Bundle (org.osgi.framework.Bundle)6 ZipFile (org.apache.commons.compress.archivers.zip.ZipFile)5 RevCommit (org.eclipse.jgit.revwalk.RevCommit)5 RevWalk (org.eclipse.jgit.revwalk.RevWalk)5 GitPatchManagementServiceImpl (org.jboss.fuse.patch.management.impl.GitPatchManagementServiceImpl)5 FileInputStream (java.io.FileInputStream)4 ArrayList (java.util.ArrayList)4