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"));
}
}
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;
}
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);
}
}
}
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);
}
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);
}
}
Aggregations