Search in sources :

Example 11 with Patch

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

the class GitPatchManagementServiceImpl method updateOverrides.

/**
 * <p>Updates existing <code>etc/overrides.properties</code> after installing single {@link PatchKind#NON_ROLLUP}
 * patch.</p>
 * @param workTree
 * @param patchData
 */
private void updateOverrides(File workTree, PatchData patchData) throws IOException {
    File overrides = new File(workTree, "etc/overrides.properties");
    List<String> currentOverrides = overrides.isFile() ? FileUtils.readLines(overrides) : new LinkedList<String>();
    for (String bundle : patchData.getBundles()) {
        Artifact artifact = mvnurlToArtifact(bundle, true);
        if (artifact == null) {
            continue;
        }
        // Compute patch bundle version and range
        VersionRange range;
        Version oVer = Utils.getOsgiVersion(artifact.getVersion());
        String vr = patchData.getVersionRange(bundle);
        String override;
        if (vr != null && !vr.isEmpty()) {
            override = bundle + ";range=" + vr;
            range = new VersionRange(vr);
        } else {
            override = bundle;
            Version v1 = new Version(oVer.getMajor(), oVer.getMinor(), 0);
            Version v2 = new Version(oVer.getMajor(), oVer.getMinor() + 1, 0);
            range = new VersionRange(VersionRange.LEFT_CLOSED, v1, v2, VersionRange.RIGHT_OPEN);
        }
        // Process overrides.properties
        boolean matching = false;
        boolean added = false;
        for (int i = 0; i < currentOverrides.size(); i++) {
            String line = currentOverrides.get(i).trim();
            if (!line.isEmpty() && !line.startsWith("#")) {
                Artifact overrideArtifact = mvnurlToArtifact(line, true);
                if (overrideArtifact != null) {
                    Version ver = Utils.getOsgiVersion(overrideArtifact.getVersion());
                    if (isSameButVersion(artifact, overrideArtifact) && range.includes(ver)) {
                        matching = true;
                        if (ver.compareTo(oVer) < 0) {
                            // Replace old override with the new one
                            currentOverrides.set(i, override);
                            added = true;
                        }
                    }
                }
            }
        }
        // If there was not matching bundles, add it
        if (!matching) {
            currentOverrides.add(override);
        }
    }
    FileUtils.writeLines(overrides, currentOverrides, IOUtils.LINE_SEPARATOR_UNIX);
}
Also used : Version(org.osgi.framework.Version) Artifact.isSameButVersion(io.fabric8.patch.management.Artifact.isSameButVersion) VersionRange(org.osgi.framework.VersionRange) ZipFile(org.apache.commons.compress.archivers.zip.ZipFile) File(java.io.File) Artifact(io.fabric8.patch.management.Artifact)

Example 12 with Patch

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

the class GitPatchManagementServiceImpl method commitInstallation.

@Override
public void commitInstallation(String transaction) {
    transactionIsValid(transaction, null);
    Git fork = pendingTransactions.get(transaction);
    try {
        switch(pendingTransactionsTypes.get(transaction)) {
            case ROLLUP:
                {
                    // hard reset of main patch branch to point to transaction branch + apply changes to ${karaf.home}
                    gitPatchRepository.checkout(fork).setName(gitPatchRepository.getMainBranchName()).call();
                    // before we reset main patch branch to originate from new baseline, let's find previous baseline
                    RevTag baseline = gitPatchRepository.findCurrentBaseline(fork);
                    RevCommit c1 = new RevWalk(fork.getRepository()).parseCommit(fork.getRepository().resolve(baseline.getTagName() + "^{commit}"));
                    // hard reset of main patch branch - to point to other branch, originating from new baseline
                    fork.reset().setMode(ResetCommand.ResetType.HARD).setRef(transaction).call();
                    gitPatchRepository.push(fork);
                    RevCommit c2 = new RevWalk(fork.getRepository()).parseCommit(fork.getRepository().resolve("HEAD"));
                    // apply changes from single range of commits
                    // applyChanges(fork, c1, c2);
                    applyChanges(fork, false);
                    break;
                }
            case NON_ROLLUP:
                {
                    // fast forward merge of main patch branch with transaction branch
                    gitPatchRepository.checkout(fork).setName(gitPatchRepository.getMainBranchName()).call();
                    // current version of ${karaf.home}
                    RevCommit c1 = new RevWalk(fork.getRepository()).parseCommit(fork.getRepository().resolve("HEAD"));
                    // fast forward over patch-installation branch - possibly over more than 1 commit
                    fork.merge().setFastForward(MergeCommand.FastForwardMode.FF_ONLY).include(fork.getRepository().resolve(transaction)).call();
                    gitPatchRepository.push(fork);
                    // apply a change from commits of all installed patches
                    RevCommit c2 = new RevWalk(fork.getRepository()).parseCommit(fork.getRepository().resolve("HEAD"));
                    applyChanges(fork, c1, c2);
                    // applyChanges(fork);
                    break;
                }
        }
        gitPatchRepository.push(fork);
    } catch (GitAPIException | IOException e) {
        throw new PatchException(e.getMessage(), e);
    } finally {
        gitPatchRepository.closeRepository(fork, true);
    }
    pendingTransactions.remove(transaction);
    pendingTransactionsTypes.remove(transaction);
}
Also used : GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) Git(org.eclipse.jgit.api.Git) RevTag(org.eclipse.jgit.revwalk.RevTag) IOException(java.io.IOException) PatchException(io.fabric8.patch.management.PatchException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 13 with Patch

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

the class GitPatchManagementServiceImpl method checkPendingPatches.

@Override
public void checkPendingPatches() {
    File[] pendingPatches = patchesDir.listFiles(new FileFilter() {

        @Override
        public boolean accept(File pathname) {
            return pathname.exists() && pathname.getName().endsWith(".pending");
        }
    });
    if (pendingPatches == null || pendingPatches.length == 0) {
        return;
    }
    final String dataCache = systemContext.getProperty("org.osgi.framework.storage");
    for (File pending : pendingPatches) {
        try {
            Pending what = Pending.valueOf(FileUtils.readFileToString(pending));
            final String prefix = what == Pending.ROLLUP_INSTALLATION ? "install" : "rollback";
            String name = pending.getName().replaceFirst("\\.pending$", "");
            if (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()) {
                Activator.log(LogService.LOG_INFO, "Ignoring patch result file: " + patchFile.getName());
                continue;
            }
            PatchData patchData = PatchData.load(new FileInputStream(patchFile));
            Patch patch = loadPatch(new PatchDetailsRequest(patchData.getId()));
            String dataFilesName = patchData.getId() + ".datafiles";
            if (isStandaloneChild()) {
                dataFilesName = patchData.getId() + "." + System.getProperty("karaf.name") + ".datafiles";
            }
            final File dataFilesBackupDir = new File(pending.getParentFile(), dataFilesName);
            final Properties backupProperties = new Properties();
            FileInputStream inStream = new FileInputStream(new File(dataFilesBackupDir, "backup-" + prefix + ".properties"));
            backupProperties.load(inStream);
            IOUtils.closeQuietly(inStream);
            // maybe one of those bundles has data directory to restore?
            for (Bundle b : systemContext.getBundles()) {
                if (b.getSymbolicName() != null) {
                    String key = String.format("%s$$%s", stripSymbolicName(b.getSymbolicName()), b.getVersion().toString());
                    if (backupProperties.containsKey(key)) {
                        String backupDirName = backupProperties.getProperty(key);
                        File backupDir = new File(dataFilesBackupDir, prefix + "/" + backupDirName + "/data");
                        restoreDataDirectory(dataCache, b, backupDir);
                        // we no longer want to restore this dir
                        backupProperties.remove(key);
                    }
                }
            }
            // 2. We can however have more bundle data backups - we'll restore them after each bundle
            // is INSTALLED and we'll use listener for this
            BundleListener bundleListener = new SynchronousBundleListener() {

                @Override
                public void bundleChanged(BundleEvent event) {
                    Bundle b = event.getBundle();
                    if (event.getType() == BundleEvent.INSTALLED && b.getSymbolicName() != null) {
                        String key = String.format("%s$$%s", stripSymbolicName(b.getSymbolicName()), b.getVersion().toString());
                        if (backupProperties.containsKey(key)) {
                            String backupDirName = backupProperties.getProperty(key);
                            File backupDir = new File(dataFilesBackupDir, prefix + "/" + backupDirName + "/data");
                            restoreDataDirectory(dataCache, b, backupDir);
                        }
                    }
                }
            };
            systemContext.addBundleListener(bundleListener);
            pendingPatchesListeners.put(patchData.getId(), bundleListener);
        } catch (Exception e) {
            Activator.log(LogService.LOG_ERROR, null, e.getMessage(), e, true);
        }
    }
}
Also used : PatchData(io.fabric8.patch.management.PatchData) Bundle(org.osgi.framework.Bundle) Properties(java.util.Properties) PatchDetailsRequest(io.fabric8.patch.management.PatchDetailsRequest) FileInputStream(java.io.FileInputStream) PatchException(io.fabric8.patch.management.PatchException) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) BundleEvent(org.osgi.framework.BundleEvent) BundleListener(org.osgi.framework.BundleListener) SynchronousBundleListener(org.osgi.framework.SynchronousBundleListener) FileFilter(java.io.FileFilter) ZipFile(org.apache.commons.compress.archivers.zip.ZipFile) File(java.io.File) ManagedPatch(io.fabric8.patch.management.ManagedPatch) Patch(io.fabric8.patch.management.Patch) Pending(io.fabric8.patch.management.Pending) SynchronousBundleListener(org.osgi.framework.SynchronousBundleListener)

Example 14 with Patch

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

the class GitPatchManagementServiceImpl method loadPatch.

@Override
public Patch loadPatch(PatchDetailsRequest request) throws PatchException {
    File descriptor = new File(patchesDir, request.getPatchId() + ".patch");
    try {
        Patch patch = loadPatch(descriptor, true);
        if (patch == null) {
            return null;
        }
        Git repo = gitPatchRepository.findOrCreateMainGitRepository();
        List<DiffEntry> diff = null;
        if (request.isFiles() || request.isDiff()) {
            // fetch the information from git
            ObjectId commitId = repo.getRepository().resolve(patch.getManagedPatch().getCommitId());
            RevCommit commit = new RevWalk(repo.getRepository()).parseCommit(commitId);
            diff = gitPatchRepository.diff(repo, commit.getParent(0), commit);
        }
        if (request.isBundles()) {
        // it's already in PatchData
        }
        if (request.isFiles() && diff != null) {
            for (DiffEntry de : diff) {
                DiffEntry.ChangeType ct = de.getChangeType();
                String newPath = de.getNewPath();
                String oldPath = de.getOldPath();
                switch(ct) {
                    case ADD:
                        patch.getManagedPatch().getFilesAdded().add(newPath);
                        break;
                    case MODIFY:
                        patch.getManagedPatch().getFilesModified().add(newPath);
                        break;
                    case DELETE:
                        patch.getManagedPatch().getFilesRemoved().add(oldPath);
                        break;
                }
            }
        }
        if (request.isDiff() && diff != null) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            DiffFormatter formatter = new DiffFormatter(baos);
            formatter.setContext(4);
            formatter.setRepository(repo.getRepository());
            for (DiffEntry de : diff) {
                formatter.format(de);
            }
            formatter.flush();
            patch.getManagedPatch().setUnifiedDiff(new String(baos.toByteArray(), "UTF-8"));
        }
        return patch;
    } catch (IOException | GitAPIException e) {
        throw new PatchException(e.getMessage(), e);
    }
}
Also used : ObjectId(org.eclipse.jgit.lib.ObjectId) ByteArrayOutputStream(org.apache.commons.io.output.ByteArrayOutputStream) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) Git(org.eclipse.jgit.api.Git) PatchException(io.fabric8.patch.management.PatchException) DiffFormatter(org.eclipse.jgit.diff.DiffFormatter) ZipFile(org.apache.commons.compress.archivers.zip.ZipFile) File(java.io.File) ManagedPatch(io.fabric8.patch.management.ManagedPatch) Patch(io.fabric8.patch.management.Patch) DiffEntry(org.eclipse.jgit.diff.DiffEntry) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 15 with Patch

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

the class GitPatchManagementServiceImpl method loadPatch.

/**
 * Retrieves patch information from existing file
 * @param patchDescriptor existing file with patch descriptor (<code>*.patch</code> file)
 * @param details whether the returned {@link Patch} should contain {@link ManagedPatch} information
 * @return
 * @throws IOException
 */
private Patch loadPatch(File patchDescriptor, boolean details) throws IOException {
    Patch p = new Patch();
    if (!patchDescriptor.exists() || !patchDescriptor.isFile()) {
        return null;
    }
    PatchData data = PatchData.load(new FileInputStream(patchDescriptor));
    p.setPatchData(data);
    File patchDirectory = new File(patchesDir, FilenameUtils.getBaseName(patchDescriptor.getName()));
    if (patchDirectory.exists() && patchDirectory.isDirectory()) {
        // not every descriptor downloaded may be a ZIP file, not every patch has content
        data.setPatchDirectory(patchDirectory);
    }
    data.setPatchLocation(patchesDir);
    File resultFile = new File(patchesDir, FilenameUtils.getBaseName(patchDescriptor.getName()) + ".patch.result");
    if (resultFile.exists() && resultFile.isFile()) {
        PatchResult result = PatchResult.load(data, new FileInputStream(resultFile));
        p.setResult(result);
    }
    if (details) {
        ManagedPatch mp = gitPatchRepository.getManagedPatch(data.getId());
        p.setManagedPatch(mp);
    }
    return p;
}
Also used : ManagedPatch(io.fabric8.patch.management.ManagedPatch) PatchData(io.fabric8.patch.management.PatchData) PatchResult(io.fabric8.patch.management.PatchResult) ManagedPatch(io.fabric8.patch.management.ManagedPatch) Patch(io.fabric8.patch.management.Patch) ZipFile(org.apache.commons.compress.archivers.zip.ZipFile) File(java.io.File) FileInputStream(java.io.FileInputStream)

Aggregations

File (java.io.File)54 Test (org.junit.Test)43 Git (org.eclipse.jgit.api.Git)35 PatchException (io.fabric8.patch.management.PatchException)34 Patch (io.fabric8.patch.management.Patch)30 IOException (java.io.IOException)28 GitPatchManagementServiceImpl (io.fabric8.patch.management.impl.GitPatchManagementServiceImpl)27 GitPatchRepository (io.fabric8.patch.management.impl.GitPatchRepository)26 HashMap (java.util.HashMap)18 RevCommit (org.eclipse.jgit.revwalk.RevCommit)18 LinkedList (java.util.LinkedList)17 ZipFile (org.apache.commons.compress.archivers.zip.ZipFile)17 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)17 ObjectId (org.eclipse.jgit.lib.ObjectId)17 Bundle (org.osgi.framework.Bundle)17 Version (org.osgi.framework.Version)15 PatchResult (io.fabric8.patch.management.PatchResult)13 BundleUpdate (io.fabric8.patch.management.BundleUpdate)11 PatchData (io.fabric8.patch.management.PatchData)11 ArrayList (java.util.ArrayList)11