Search in sources :

Example 1 with PatchException

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

the class PatchServiceImplTest method testCheckRequirementsMultiplePatches.

@Test
public void testCheckRequirementsMultiplePatches() throws IOException {
    Collection<PatchServiceImpl.PatchDescriptor> patches = new LinkedList<PatchServiceImpl.PatchDescriptor>();
    patches.add(getPatchDescriptor("test3.patch"));
    patches.add(getPatchDescriptor("test4.patch"));
    Version version = buildVersion("1.1").withProfiles("karaf", "default", "patch-prereq4a", "patch-prereq3").done();
    try {
        PatchServiceImpl.checkRequirements(version, patches);
        fail("Patch should not have passed requirements check - required patch is missing");
    } catch (PatchException e) {
        assertTrue(e.getMessage().toLowerCase().contains("required patch 'prereq4b' is missing"));
    }
}
Also used : Version(io.fabric8.api.Version) PatchException(io.fabric8.api.PatchException) LinkedList(java.util.LinkedList) Test(org.junit.Test)

Example 2 with PatchException

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

the class GitPatchManagementServiceImpl method listPatches.

@Override
public List<Patch> listPatches(boolean details) throws PatchException {
    List<Patch> patches = new LinkedList<>();
    File[] patchDescriptors = patchesDir.listFiles(new FilenameFilter() {

        @Override
        public boolean accept(File dir, String name) {
            return name.endsWith(".patch") && new File(dir, name).isFile();
        }
    });
    try {
        for (File pd : patchDescriptors) {
            Patch p = loadPatch(pd, details);
            patches.add(p);
        }
    } catch (IOException e) {
        throw new PatchException(e.getMessage(), e);
    }
    return patches;
}
Also used : FilenameFilter(java.io.FilenameFilter) IOException(java.io.IOException) PatchException(io.fabric8.patch.management.PatchException) ManagedPatch(io.fabric8.patch.management.ManagedPatch) Patch(io.fabric8.patch.management.Patch) ZipFile(org.apache.commons.compress.archivers.zip.ZipFile) File(java.io.File) LinkedList(java.util.LinkedList)

Example 3 with PatchException

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

the class GitPatchManagementServiceImpl method trackPatch.

/**
 * <p>This method turns static information about a patch into managed patch - i.e., patch added to git
 * repository.</p>
 *
 * <p>Such patch has its own branch ready to be merged (when patch is installed). Before installation we can verify
 * the patch,
 * examine the content, check the differences, conflicts and perform simulation (merge to temporary branch created
 * from main patch branch)</p>
 *
 * <p>The strategy is as follows:<ul>
 *     <li><em>main patch branch</em> in git repository tracks all changes (from baselines, patch-management
 *     system, patches and user changes)</li>
 *     <li>Initially there are 3 commits: baseline, patch-management bundle installation in etc/startup.properties,
 *     initial user changes</li>
 *     <li>We always <strong>tag the baseline commit</strong></li>
 *     <li>User changes may be applied each time Framework is restarted</li>
 *     <li>When we add a patch, we create <em>named branch</em> from the <strong>latest baseline</strong></li>
 *     <li>When we install a patch, we <strong>merge</strong> the patch branch with the <em>main patch branch</em>
 *     (that may contain additional user changes)</li>
 *     <li>When patch ZIP contains new baseline distribution, after merging patch branch, we tag the merge commit
 *     in <em>main patch branch</em> branch as new baseline</li>
 *     <li>Branches for new patches will then be created from new baseline commit</li>
 * </ul></p>
 * @param patchData
 * @return
 */
@Override
public Patch trackPatch(PatchData patchData) throws PatchException {
    try {
        awaitInitialization();
    } catch (InterruptedException e) {
        throw new PatchException("Patch management system is not ready yet");
    }
    Git fork = null;
    try {
        Git mainRepository = gitPatchRepository.findOrCreateMainGitRepository();
        // prepare single fork for all the below operations
        fork = gitPatchRepository.cloneRepository(mainRepository, true);
        // 1. find current baseline
        RevTag latestBaseline = gitPatchRepository.findCurrentBaseline(fork);
        if (latestBaseline == null) {
            throw new PatchException("Can't find baseline distribution tracked in patch management. Is patch management initialized?");
        }
        // the commit from the patch should be available from main patch branch
        RevCommit commit = new RevWalk(fork.getRepository()).parseCommit(latestBaseline.getObject());
        // create dedicated branch for this patch. We'll immediately add patch content there so we can examine the
        // changes from the latest baseline
        gitPatchRepository.checkout(fork).setCreateBranch(true).setName("patch-" + patchData.getId()).setStartPoint(commit).call();
        // copy patch resources (but not maven artifacts from system/ or repository/) to working copy
        if (patchData.getPatchDirectory() != null) {
            boolean removeTargetDir = patchData.isRollupPatch();
            copyManagedDirectories(patchData.getPatchDirectory(), fork.getRepository().getWorkTree(), removeTargetDir, false, false);
        }
        // add the changes
        fork.add().addFilepattern(".").call();
        // remove the deletes (without touching specially-managed etc/overrides.properties)
        for (String missing : fork.status().call().getMissing()) {
            if (!"etc/overrides.properties".equals(missing)) {
                fork.rm().addFilepattern(missing).call();
            }
        }
        // record information about other "patches" included in added patch (e.g., Fuse patch
        // may contain patches to admin:create based containers in standalone mode)
        StringWriter sw = new StringWriter();
        sw.append("# tags for patches included in \"").append(patchData.getId()).append("\"\n");
        for (String bundle : patchData.getBundles()) {
            // containers that want to patch:install patches added in root containers
            if (bundle.contains("mvn:org.apache.karaf.admin/org.apache.karaf.admin.core/")) {
                Artifact a = Utils.mvnurlToArtifact(bundle, true);
                if (a != null) {
                    sw.append(String.format(EnvType.STANDALONE_CHILD.getBaselineTagFormat(), a.getVersion())).append("\n");
                }
                break;
            }
        }
        FileUtils.write(new File(fork.getRepository().getWorkTree(), "patch-info.txt"), sw.toString());
        fork.add().addFilepattern(".").call();
        // commit the changes (patch vs. baseline) to patch branch
        gitPatchRepository.prepareCommit(fork, String.format("[PATCH] Tracking patch %s", patchData.getId())).call();
        // push the patch branch
        gitPatchRepository.push(fork, "patch-" + patchData.getId());
        // track other kinds of baselines found in the patch
        if (env.isFabric()) {
            trackBaselinesForRootContainer(fork);
            trackBaselinesForChildContainers(fork);
            trackBaselinesForSSHContainers(fork);
        } else {
            // for admin:create child containers
            trackBaselinesForChildContainers(fork);
        }
        return new Patch(patchData, gitPatchRepository.getManagedPatch(patchData.getId()));
    } catch (IOException | GitAPIException e) {
        throw new PatchException(e.getMessage(), e);
    } finally {
        if (fork != null) {
            gitPatchRepository.closeRepository(fork, true);
        }
    }
}
Also used : RevTag(org.eclipse.jgit.revwalk.RevTag) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) Artifact(io.fabric8.patch.management.Artifact) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) Git(org.eclipse.jgit.api.Git) StringWriter(java.io.StringWriter) PatchException(io.fabric8.patch.management.PatchException) ZipFile(org.apache.commons.compress.archivers.zip.ZipFile) File(java.io.File) ManagedPatch(io.fabric8.patch.management.ManagedPatch) Patch(io.fabric8.patch.management.Patch) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 4 with PatchException

use of io.fabric8.patch.management.PatchException 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 5 with PatchException

use of io.fabric8.patch.management.PatchException 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)

Aggregations

PatchException (io.fabric8.patch.management.PatchException)30 IOException (java.io.IOException)19 File (java.io.File)15 Patch (io.fabric8.patch.management.Patch)14 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)11 ZipFile (org.apache.commons.compress.archivers.zip.ZipFile)10 Git (org.eclipse.jgit.api.Git)10 LinkedList (java.util.LinkedList)9 Test (org.junit.Test)9 ArrayList (java.util.ArrayList)7 GitPatchManagementServiceImpl (io.fabric8.patch.management.impl.GitPatchManagementServiceImpl)6 URISyntaxException (java.net.URISyntaxException)6 HashMap (java.util.HashMap)6 RevCommit (org.eclipse.jgit.revwalk.RevCommit)6 PatchResult (io.fabric8.patch.management.PatchResult)5 FileInputStream (java.io.FileInputStream)5 FileNotFoundException (java.io.FileNotFoundException)5 BundleException (org.osgi.framework.BundleException)5 ManagedPatch (io.fabric8.patch.management.ManagedPatch)4 URL (java.net.URL)4