Search in sources :

Example 31 with Start

use of io.fabric8.arquillian.kubernetes.event.Start 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 32 with Start

use of io.fabric8.arquillian.kubernetes.event.Start in project fabric8 by jboss-fuse.

the class AbstractPatchIntegrationTest method rollback.

// Rollback a patch and wait for rollback to complete
protected void rollback(String name) throws Exception {
    Patch patch = service.getPatch(name);
    service.rollback(patch, false, false);
    long start = System.currentTimeMillis();
    while (patch.isInstalled() && System.currentTimeMillis() - start < TIMEOUT) {
        Thread.sleep(100);
    }
    if (patch.isInstalled()) {
        fail(String.format("Patch '%s' did not roll back within %s ms", name, TIMEOUT));
    }
}
Also used : Patch(io.fabric8.patch.management.Patch)

Example 33 with Start

use of io.fabric8.arquillian.kubernetes.event.Start in project fabric8 by jboss-fuse.

the class AbstractPatchIntegrationTest method install.

// Install a patch and wait for installation to complete
protected void install(String name) throws Exception {
    Patch patch = service.getPatch(name);
    service.install(patch, false, false);
    long start = System.currentTimeMillis();
    while (!patch.isInstalled() && System.currentTimeMillis() - start < TIMEOUT) {
        Thread.sleep(100);
    }
    if (!patch.isInstalled()) {
        fail(String.format("Patch '%s' did not installed within %s ms", name, TIMEOUT));
    }
}
Also used : Patch(io.fabric8.patch.management.Patch)

Example 34 with Start

use of io.fabric8.arquillian.kubernetes.event.Start in project fabric8 by jboss-fuse.

the class ServiceFactoryTest method testDiscoveryOnRestartCurator.

@Test
public void testDiscoveryOnRestartCurator() throws Exception {
    underTest = new ActiveMQServiceFactory();
    underTest.curator = curator;
    Properties props = new Properties();
    props.put("config", "amq.xml");
    props.put("broker-name", "amq");
    props.put("group", "amq");
    props.put("connectors", "openwire");
    props.put("openwire-port", "0");
    props.put("container.ip", "localhost");
    underTest.updated("b", props);
    final AtomicReference<CuratorFramework> curatorFrameworkAtomicReference = new AtomicReference<>(curator);
    OsgiFabricDiscoveryAgent osgiFabricDiscoveryAgent = new OsgiFabricDiscoveryAgent(new BundleContext() {

        @Override
        public String getProperty(String s) {
            return null;
        }

        @Override
        public Bundle getBundle() {
            return null;
        }

        @Override
        public Bundle installBundle(String s, InputStream inputStream) throws BundleException {
            return null;
        }

        @Override
        public Bundle installBundle(String s) throws BundleException {
            return null;
        }

        @Override
        public Bundle getBundle(long l) {
            return null;
        }

        @Override
        public Bundle[] getBundles() {
            return new Bundle[0];
        }

        @Override
        public void addServiceListener(ServiceListener serviceListener, String s) throws InvalidSyntaxException {
        }

        @Override
        public void addServiceListener(ServiceListener serviceListener) {
        }

        @Override
        public void removeServiceListener(ServiceListener serviceListener) {
        }

        @Override
        public void addBundleListener(BundleListener bundleListener) {
        }

        @Override
        public void removeBundleListener(BundleListener bundleListener) {
        }

        @Override
        public void addFrameworkListener(FrameworkListener frameworkListener) {
        }

        @Override
        public void removeFrameworkListener(FrameworkListener frameworkListener) {
        }

        @Override
        public ServiceRegistration<?> registerService(String[] strings, Object o, Dictionary<String, ?> dictionary) {
            return null;
        }

        @Override
        public ServiceRegistration<?> registerService(String s, Object o, Dictionary<String, ?> dictionary) {
            return null;
        }

        @Override
        public <S> ServiceRegistration<S> registerService(Class<S> aClass, S s, Dictionary<String, ?> dictionary) {
            return null;
        }

        @Override
        public ServiceReference<?>[] getServiceReferences(String s, String s1) throws InvalidSyntaxException {
            return new ServiceReference<?>[0];
        }

        @Override
        public ServiceReference<?>[] getAllServiceReferences(String s, String s1) throws InvalidSyntaxException {
            return new ServiceReference<?>[0];
        }

        @Override
        public ServiceReference<?> getServiceReference(String s) {
            return null;
        }

        @Override
        public <S> ServiceReference<S> getServiceReference(Class<S> aClass) {
            return null;
        }

        @Override
        public <S> Collection<ServiceReference<S>> getServiceReferences(Class<S> aClass, String s) throws InvalidSyntaxException {
            return null;
        }

        @Override
        public <S> S getService(ServiceReference<S> serviceReference) {
            return (S) curatorFrameworkAtomicReference.get();
        }

        @Override
        public boolean ungetService(ServiceReference<?> serviceReference) {
            return false;
        }

        @Override
        public File getDataFile(String s) {
            return null;
        }

        @Override
        public Filter createFilter(String s) throws InvalidSyntaxException {
            return null;
        }

        @Override
        public Bundle getBundle(String s) {
            return null;
        }
    });
    final LinkedBlockingQueue<DiscoveryEvent> discoveryEvents = new LinkedBlockingQueue<DiscoveryEvent>(10);
    osgiFabricDiscoveryAgent.setDiscoveryListener(new DiscoveryListener() {

        @Override
        public void onServiceAdd(DiscoveryEvent discoveryEvent) {
            discoveryEvents.offer(discoveryEvent);
        }

        @Override
        public void onServiceRemove(DiscoveryEvent discoveryEvent) {
        }
    });
    // will call into dummy bundle and get curator
    osgiFabricDiscoveryAgent.addingService(null);
    osgiFabricDiscoveryAgent.setGroupName("amq");
    osgiFabricDiscoveryAgent.start();
    DiscoveryEvent event = discoveryEvents.poll(5, TimeUnit.SECONDS);
    LOG.info("event: " + event);
    assertNotNull("got added service", event);
    underTest.deleted("b");
    // swap curator ref
    CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder().connectString("localhost:" + zkPort).sessionTimeoutMs(15000).retryPolicy(new RetryNTimes(5000, 1000));
    curator = builder.build();
    LOG.debug("Starting new curator " + curator);
    curator.start();
    curatorFrameworkAtomicReference.get().close();
    curatorFrameworkAtomicReference.set(curator);
    // will call into dummy bundle and get new curator ref
    osgiFabricDiscoveryAgent.addingService(null);
    // start broker again
    underTest.curator = curator;
    underTest.updated("b", props);
    event = discoveryEvents.poll(5, TimeUnit.SECONDS);
    LOG.info("new event: " + event);
    assertNotNull("got newly added service", event);
    underTest.deleted("b");
}
Also used : CuratorFrameworkFactory(org.apache.curator.framework.CuratorFrameworkFactory) DiscoveryEvent(org.apache.activemq.command.DiscoveryEvent) Properties(java.util.Properties) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) CuratorFramework(org.apache.curator.framework.CuratorFramework) RetryNTimes(org.apache.curator.retry.RetryNTimes) InputStream(java.io.InputStream) AtomicReference(java.util.concurrent.atomic.AtomicReference) OsgiFabricDiscoveryAgent(io.fabric8.mq.fabric.discovery.OsgiFabricDiscoveryAgent) Collection(java.util.Collection) File(java.io.File) DiscoveryListener(org.apache.activemq.transport.discovery.DiscoveryListener) Test(org.junit.Test)

Example 35 with Start

use of io.fabric8.arquillian.kubernetes.event.Start in project fabric8 by jboss-fuse.

the class GitPatchManagementServiceIT method installRollupPatch.

@Test
public void installRollupPatch() throws IOException, GitAPIException {
    freshKarafStandaloneDistro();
    GitPatchRepository repository = patchManagement();
    PatchManagement management = (PatchManagement) pm;
    Git fork = repository.cloneRepository(repository.findOrCreateMainGitRepository(), true);
    repository.prepareCommit(fork, "artificial change, not treated as user change (could be a patch)").call();
    repository.prepareCommit(fork, "artificial change, not treated as user change").call();
    // no changes, but commit
    ((GitPatchManagementServiceImpl) pm).applyUserChanges(fork);
    FileUtils.write(new File(karafHome, "bin/start"), "echo \"another user change\"\n", true);
    // conflicting change, but commit
    ((GitPatchManagementServiceImpl) pm).applyUserChanges(fork);
    FileUtils.write(new File(karafHome, "bin/test"), "echo \"another user change\"\n");
    // non-conflicting
    ((GitPatchManagementServiceImpl) pm).applyUserChanges(fork);
    repository.closeRepository(fork, true);
    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-4.zip").toURI().toURL());
    Patch patch = management.trackPatch(patches.get(0));
    String tx = management.beginInstallation(PatchKind.ROLLUP);
    management.install(tx, patch, null);
    @SuppressWarnings("unchecked") Map<String, Git> transactions = (Map<String, Git>) getField(management, "pendingTransactions");
    assertThat(transactions.size(), equalTo(1));
    fork = transactions.values().iterator().next();
    ObjectId since = fork.getRepository().resolve("baseline-6.2.0^{commit}");
    ObjectId to = fork.getRepository().resolve(tx);
    Iterable<RevCommit> commits = fork.log().addRange(since, to).call();
    // only one "user change", because we had two conflicts with new baseline - they were resolved
    // by picking what already comes from rollup patch ("ours"):
    /*
         * Problem with applying the change 657f11c4b65bb7893a2b82f888bb9731a6d5f7d0:
         *  - bin/start: BOTH_MODIFIED
         * Choosing "ours" change
         * Problem with applying the change d9272b97582582f4b056f7170130ec91fc21aeac:
         *  - bin/start: BOTH_MODIFIED
         * Choosing "ours" change
         */
    List<String> commitList = Arrays.asList("[PATCH] Apply user changes", "[PATCH] Apply user changes", "[PATCH] Apply user changes", "[PATCH] Rollup patch patch-4 - resetting etc/overrides.properties", "[PATCH] Installing rollup patch patch-4");
    int n = 0;
    for (RevCommit c : commits) {
        String msg = c.getShortMessage();
        assertThat(msg, equalTo(commitList.get(n++)));
    }
    assertThat(n, equalTo(commitList.size()));
    assertThat(fork.tagList().call().size(), equalTo(3));
    assertTrue(repository.containsTag(fork, "patch-management"));
    assertTrue(repository.containsTag(fork, "baseline-6.2.0"));
    assertTrue(repository.containsTag(fork, "baseline-6.2.0.redhat-002"));
}
Also used : ObjectId(org.eclipse.jgit.lib.ObjectId) GitPatchRepository(io.fabric8.patch.management.impl.GitPatchRepository) Git(org.eclipse.jgit.api.Git) GitPatchManagementServiceImpl(io.fabric8.patch.management.impl.GitPatchManagementServiceImpl) File(java.io.File) Map(java.util.Map) RevCommit(org.eclipse.jgit.revwalk.RevCommit) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)25 IOException (java.io.IOException)24 File (java.io.File)18 HashMap (java.util.HashMap)15 Map (java.util.Map)10 Git (org.eclipse.jgit.api.Git)10 GitPatchRepository (io.fabric8.patch.management.impl.GitPatchRepository)8 ArrayList (java.util.ArrayList)8 Bundle (org.osgi.framework.Bundle)8 PatchException (io.fabric8.patch.management.PatchException)7 URISyntaxException (java.net.URISyntaxException)7 BundleException (org.osgi.framework.BundleException)7 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)6 CuratorFramework (org.apache.curator.framework.CuratorFramework)6 Container (io.fabric8.api.Container)5 CreateContainerMetadata (io.fabric8.api.CreateContainerMetadata)5 FabricService (io.fabric8.api.FabricService)5 GitPatchManagementServiceImpl (io.fabric8.patch.management.impl.GitPatchManagementServiceImpl)5 MalformedURLException (java.net.MalformedURLException)5 URI (java.net.URI)5