You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2017/06/29 08:10:01 UTC

karaf git commit: [KARAF-5123] Executing feature:repo-remove can leave karaf in an invalid state

Repository: karaf
Updated Branches:
  refs/heads/karaf-4.1.x 35c58aac6 -> 06df1bb41


[KARAF-5123] Executing feature:repo-remove can leave karaf in an invalid state

Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/06df1bb4
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/06df1bb4
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/06df1bb4

Branch: refs/heads/karaf-4.1.x
Commit: 06df1bb417388885b59ceba805a09caea1754abe
Parents: 35c58aa
Author: Guillaume Nodet <gn...@apache.org>
Authored: Thu Jun 29 10:09:50 2017 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Thu Jun 29 10:09:50 2017 +0200

----------------------------------------------------------------------
 .../internal/service/FeaturesServiceImpl.java   | 38 +++++++++++++++++---
 1 file changed, 34 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/06df1bb4/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
index 19598bc..780b895 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
@@ -22,9 +22,11 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Deque;
 import java.util.Dictionary;
 import java.util.EnumSet;
 import java.util.Enumeration;
@@ -505,14 +507,28 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
             return;
         }
 
-        Set<String> features = new HashSet<>();
+        Set<Repository> repos;
+        Set<String> features;
         synchronized (lock) {
-            for (Feature feature : repo.getFeatures()) {
-                if (isRequired(feature)) {
-                    features.add(feature.getId());
+            repos = getRepositoryClosure(repo);
+            List<Repository> required = new ArrayList<>();
+            for (String r : state.repositories) {
+                required.add(repositoryCache.get(r));
+            }
+            required.remove(repo);
+            for (Repository rep : required) {
+                repos.removeAll(getRepositoryClosure(rep));
+            }
+            features = new HashSet<>();
+            for (Repository tranRepo : repos) {
+                for (Feature f : tranRepo.getFeatures()) {
+                    if (isRequired(f)) {
+                        features.add(f.getId());
+                    }
                 }
             }
         }
+
         if (!features.isEmpty()) {
             if (uninstall) {
                 uninstallFeatures(features, EnumSet.noneOf(Option.class));
@@ -544,6 +560,20 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
         callListeners(new RepositoryEvent(repo, RepositoryEvent.EventType.RepositoryRemoved, false));
     }
 
+    private Set<Repository> getRepositoryClosure(Repository repo) throws Exception {
+        Set<Repository> closure = new HashSet<>();
+        Deque<Repository> remaining = new ArrayDeque<>(Collections.singleton(repo));
+        while (!remaining.isEmpty()) {
+            Repository rep = remaining.removeFirst();
+            if (closure.add(rep)) {
+                for (URI uri : rep.getRepositories()) {
+                    remaining.add(this.repositoryCache.get(uri.toString()));
+                }
+            }
+        }
+        return closure;
+    }
+
     @Override
     public void restoreRepository(URI uri) throws Exception {
         throw new UnsupportedOperationException();