예제 #1
0
 Map<String, Patch> load() {
   Map<String, Patch> patches = new HashMap<String, Patch>();
   for (File file : patchDir.listFiles()) {
     if (file.exists() && file.getName().endsWith(".patch")) {
       try {
         Patch patch = load(file);
         patches.put(patch.getId(), patch);
       } catch (IOException e) {
         e.printStackTrace();
       }
     }
   }
   return patches;
 }
예제 #2
0
  Map<String, Result> install(
      final Collection<Patch> patches, boolean simulate, boolean synchronous) {
    try {
      // Compute individual patch results
      final Map<String, Result> results = new LinkedHashMap<String, Result>();
      final Map<Bundle, String> toUpdate = new HashMap<Bundle, String>();
      Map<String, BundleUpdate> allUpdates = new HashMap<String, BundleUpdate>();
      for (Patch patch : patches) {
        String startup =
            readFully(new File(System.getProperty("karaf.base"), "etc/startup.properties"));
        String overrides =
            readFully(new File(System.getProperty("karaf.base"), "etc/overrides.properties"));
        List<BundleUpdate> updates = new ArrayList<BundleUpdate>();
        Bundle[] allBundles = bundleContext.getBundles();
        for (String url : patch.getBundles()) {
          JarInputStream jis = new JarInputStream(new URL(url).openStream());
          jis.close();
          Manifest manifest = jis.getManifest();
          Attributes att = manifest != null ? manifest.getMainAttributes() : null;
          String sn = att != null ? att.getValue(Constants.BUNDLE_SYMBOLICNAME) : null;
          String vr = att != null ? att.getValue(Constants.BUNDLE_VERSION) : null;
          if (sn == null || vr == null) {
            continue;
          }
          Version v = VersionTable.getVersion(vr);

          VersionRange range = null;

          if (patch.getVersionRange(url) == null) {
            // default version range starts with x.y.0 as the lower bound
            Version lower = new Version(v.getMajor(), v.getMinor(), 0);

            // We can't really upgrade with versions such as 2.1.0
            if (v.compareTo(lower) > 0) {
              range = new VersionRange(false, lower, v, true);
            }
          } else {
            range = new VersionRange(patch.getVersionRange(url));
          }

          if (range != null) {
            for (Bundle bundle : allBundles) {
              Version oldV = bundle.getVersion();
              if (bundle.getBundleId() != 0
                  && stripSymbolicName(sn).equals(stripSymbolicName(bundle.getSymbolicName()))
                  && range.contains(oldV)) {
                String location = bundle.getLocation();
                BundleUpdate update =
                    new BundleUpdateImpl(sn, v.toString(), url, oldV.toString(), location);
                updates.add(update);
                // Merge result
                BundleUpdate oldUpdate = allUpdates.get(sn);
                if (oldUpdate != null) {
                  Version upv = VersionTable.getVersion(oldUpdate.getNewVersion());
                  if (upv.compareTo(v) < 0) {
                    allUpdates.put(sn, update);
                    toUpdate.put(bundle, url);
                  }
                } else {
                  toUpdate.put(bundle, url);
                }
              }
            }
          } else {
            System.err.printf(
                "Skipping bundle %s - unable to process bundle without a version range configuration%n",
                url);
          }
        }
        if (!simulate) {
          new Offline(new File(System.getProperty("karaf.base")))
              .applyConfigChanges(((PatchImpl) patch).getPatch());
        }
        Result result =
            new ResultImpl(
                patch, simulate, System.currentTimeMillis(), updates, startup, overrides);
        results.put(patch.getId(), result);
      }
      // Apply results
      System.out.println("Bundles to update:");
      for (Map.Entry<Bundle, String> e : toUpdate.entrySet()) {
        System.out.println(
            "    "
                + e.getKey().getSymbolicName()
                + "/"
                + e.getKey().getVersion().toString()
                + " with "
                + e.getValue());
      }
      if (simulate) {
        System.out.println("Running simulation only - no bundles are being updated at this time");
      } else {
        System.out.println(
            "Installation will begin.  The connection may be lost or the console restarted.");
      }
      System.out.flush();
      if (!simulate) {
        Thread thread =
            new Thread() {
              public void run() {
                try {
                  applyChanges(toUpdate);
                  for (Patch patch : patches) {
                    Result result = results.get(patch.getId());
                    ((PatchImpl) patch).setResult(result);
                    saveResult(result);
                  }
                } catch (Exception e) {
                  e.printStackTrace(System.err);
                  System.err.flush();
                }
              }
            };
        if (synchronous) {
          thread.run();
        } else {
          thread.start();
        }
      }
      return results;
    } catch (Exception e) {
      throw new PatchException(e);
    }
  }
예제 #3
0
 Result install(Patch patch, boolean simulate, boolean synchronous) {
   Map<String, Result> results = install(Collections.singleton(patch), simulate, synchronous);
   return results.get(patch.getId());
 }
예제 #4
0
  void rollback(Patch patch, boolean force) throws PatchException {
    Result result = patch.getResult();
    if (result == null) {
      throw new PatchException("Patch " + patch.getId() + " is not installed");
    }
    Bundle[] allBundles = bundleContext.getBundles();
    List<BundleUpdate> badUpdates = new ArrayList<BundleUpdate>();
    for (BundleUpdate update : result.getUpdates()) {
      boolean found = false;
      Version v = Version.parseVersion(update.getNewVersion());
      for (Bundle bundle : allBundles) {
        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.getId())
          .append(" because of the following missing bundles:\n");
      for (BundleUpdate up : badUpdates) {
        sb.append("\t")
            .append(up.getSymbolicName())
            .append("/")
            .append(up.getNewVersion())
            .append("\n");
      }
      throw new PatchException(sb.toString());
    }

    Map<Bundle, String> toUpdate = new HashMap<Bundle, String>();
    for (BundleUpdate update : result.getUpdates()) {
      Version v = Version.parseVersion(update.getNewVersion());
      for (Bundle bundle : allBundles) {
        if (stripSymbolicName(bundle.getSymbolicName())
                .equals(stripSymbolicName(update.getSymbolicName()))
            && bundle.getVersion().equals(v)) {
          toUpdate.put(bundle, update.getPreviousLocation());
        }
      }
    }
    try {
      applyChanges(toUpdate);
      writeFully(
          new File(System.getProperty("karaf.base"), "etc/startup.properties"),
          ((ResultImpl) result).getStartup());
      writeFully(
          new File(System.getProperty("karaf.base"), "etc/overrides.properties"),
          ((ResultImpl) result).getOverrides());
    } catch (Exception e) {
      throw new PatchException(
          "Unable to rollback patch " + patch.getId() + ": " + e.getMessage(), e);
    }
    ((PatchImpl) patch).setResult(null);
    File file = new File(patchDir, result.getPatch().getId() + ".patch.result");
    file.delete();
  }
예제 #5
0
 @Override
 public Iterable<Patch> download(URL url) {
   try {
     File file = new File(patchDir, Long.toString(System.currentTimeMillis()) + ".patch.tmp");
     // Copy file
     InputStream is = null;
     OutputStream os = null;
     try {
       is = url.openStream();
       os = new FileOutputStream(file);
       copy(is, os);
     } finally {
       close(is, os);
     }
     // Patch file
     List<Patch> patches = new ArrayList<Patch>();
     // Try to unzip
     ZipFile zipFile = null;
     try {
       zipFile = new ZipFile(file);
     } catch (IOException e) {
     }
     if (zipFile != null) {
       File localRepoPath = new File(System.getProperty("karaf.base"), "system");
       Enumeration<? extends ZipEntry> entries = zipFile.entries();
       while (entries.hasMoreElements()) {
         ZipEntry entry = entries.nextElement();
         if (!entry.isDirectory()) {
           String entryName = entry.getName();
           if (entryName.startsWith("repository/")) {
             String fileName = entryName.substring("repository/".length());
             File f = new File(localRepoPath, fileName);
             if (!f.isFile()) {
               f.getParentFile().mkdirs();
               InputStream fis = zipFile.getInputStream(entry);
               FileOutputStream fos = new FileOutputStream(f);
               try {
                 copy(fis, fos);
               } finally {
                 close(fis, fos);
               }
             }
           } else if (entryName.endsWith(".patch") && !entryName.contains("/")) {
             File f = new File(patchDir, entryName);
             if (!f.isFile()) {
               InputStream fis = zipFile.getInputStream(entry);
               FileOutputStream fos = new FileOutputStream(f);
               try {
                 copy(fis, fos);
               } finally {
                 close(fis, fos);
               }
             }
             Patch patch = load(f);
             f.renameTo(new File(patchDir, patch.getId() + ".patch"));
             patches.add(patch);
           }
         }
       }
       close(zipFile);
       file.delete();
     }
     // If the file is not a zip/jar, assume it's a single patch file
     else {
       Patch patch = load(file);
       file.renameTo(new File(patchDir, patch.getId() + ".patch"));
       patches.add(patch);
     }
     return patches;
   } catch (Exception e) {
     throw new PatchException("Unable to download patch from url " + url, e);
   }
 }