use of io.fabric8.api.PatchException in project fabric8 by jboss-fuse.
the class GitPatchManagementServiceImpl method mergeProfileChanges.
@Override
public void mergeProfileChanges(Patch patch, File gitRepository, String versionBranch, String patchBranch) {
Git git = null;
try {
git = Git.open(gitRepository);
// merge version branch with patch branch - no fast forward, so we have nice named commit
git.checkout().setCreateBranch(false).setName(versionBranch).call();
MergeResult result = git.merge().setFastForward(MergeCommand.FastForwardMode.NO_FF).include(git.getRepository().resolve(patchBranch)).setCommit(false).call();
boolean commit = true;
if (result.getMergeStatus() == MergeResult.MergeStatus.CONFLICTING) {
handleMergeConflict(git, result, versionBranch, patchBranch);
} else if (result.getMergeStatus() != MergeResult.MergeStatus.MERGED_NOT_COMMITTED) {
commit = false;
Activator.log2(LogService.LOG_ERROR, "Can't merge version branch \"" + versionBranch + "\" with" + " patch branch \"" + patchBranch + "\". Resetting the branch.");
git.reset().setMode(ResetCommand.ResetType.HARD).call();
}
// if (commit) {
// git.commit()
// .setMessage("Installing rollup patch \"" + patch.getPatchData().getId() + "\"")
// .call();
// }
} catch (Exception e) {
throw new PatchException(e.getMessage(), e);
} finally {
if (git != null) {
try {
git.branchDelete().setBranchNames(patchBranch).setForce(true).call();
} catch (GitAPIException e) {
Activator.log2(LogService.LOG_ERROR, e.getMessage());
}
gitPatchRepository.closeRepository(git, false);
}
}
}
use of io.fabric8.api.PatchException in project fabric8 by jboss-fuse.
the class GitPatchManagementServiceImpl method beginInstallation.
@Override
public String beginInstallation(PatchKind kind) {
String tx = null;
try {
Git fork = gitPatchRepository.cloneRepository(gitPatchRepository.findOrCreateMainGitRepository(), true);
Ref installationBranch = null;
// let's pick up latest user changes
applyUserChanges(fork);
switch(kind) {
case ROLLUP:
// create temporary branch from the current baseline - rollup patch installation is a rebase
// of existing user changes on top of new baseline
RevTag currentBaseline = gitPatchRepository.findCurrentBaseline(fork);
installationBranch = gitPatchRepository.checkout(fork).setName(String.format("patch-install-%s", GitPatchRepository.TS.format(new Date()))).setCreateBranch(true).setStartPoint(currentBaseline.getTagName() + "^{commit}").call();
break;
case NON_ROLLUP:
// create temporary branch from main-patch-branch/HEAD - non-rollup patch installation is cherry-pick
// of non-rollup patch commit over existing user changes - we can fast forward when finished
installationBranch = gitPatchRepository.checkout(fork).setName(String.format("patch-install-%s", GitPatchRepository.TS.format(new Date()))).setCreateBranch(true).setStartPoint(gitPatchRepository.getMainBranchName()).call();
break;
}
pendingTransactionsTypes.put(installationBranch.getName(), kind);
pendingTransactions.put(installationBranch.getName(), fork);
return installationBranch.getName();
} catch (IOException | GitAPIException e) {
if (tx != null) {
pendingTransactions.remove(tx);
pendingTransactionsTypes.remove(tx);
}
throw new PatchException(e.getMessage(), e);
}
}
use of io.fabric8.api.PatchException in project fabric8 by jboss-fuse.
the class GitPatchManagementServiceIT method initializationPerformedNoFuseVersion.
@Test
public void initializationPerformedNoFuseVersion() throws IOException, GitAPIException {
pm = new GitPatchManagementServiceImpl(bundleContext);
pm.start();
try {
pm.ensurePatchManagementInitialized();
fail("Should fail, because versions can't be determined");
} catch (PatchException e) {
assertTrue(e.getMessage().contains("Can't find"));
}
}
use of io.fabric8.api.PatchException in project fabric8 by jboss-fuse.
the class ServiceImpl method activate.
@Activate
void activate(ComponentContext componentContext) throws IOException {
// Use system bundle' bundle context to avoid running into
// "Invalid BundleContext" exceptions when updating bundles
this.bundleContext = componentContext.getBundleContext().getBundle(0).getBundleContext();
String dir = this.bundleContext.getProperty(NEW_PATCH_LOCATION);
if (dir != null) {
patchDir = new File(dir);
} else {
dir = this.bundleContext.getProperty(PATCH_LOCATION);
if (dir != null) {
patchDir = new File(dir);
} else {
if (patchManagement.isStandaloneChild()) {
patchDir = new File(System.getProperty("karaf.home"), "patches");
}
if (patchDir == null) {
// only now fallback to datafile of system bundle
patchDir = this.bundleContext.getDataFile("patches");
}
}
}
if (!patchDir.isDirectory()) {
patchDir.mkdirs();
if (!patchDir.isDirectory()) {
throw new PatchException("Unable to create patch folder");
}
}
this.karafHome = new File(bundleContext.getProperty("karaf.home"));
this.repository = new File(bundleContext.getProperty("karaf.default.repository"));
helper = new OSGiPatchHelper(karafHome, bundleContext);
load(true);
resumePendingPatchTasks();
}
use of io.fabric8.api.PatchException in project fabric8 by jboss-fuse.
the class ServiceImpl method rollback.
@Override
public void rollback(final Patch patch, boolean simulate, boolean force) throws PatchException {
final PatchResult result = !patchManagement.isStandaloneChild() ? patch.getResult() : patch.getResult().getChildPatches().get(System.getProperty("karaf.name"));
if (result == null) {
throw new PatchException("Patch " + patch.getPatchData().getId() + " is not installed");
}
if (patch.getPatchData().isRollupPatch()) {
// we already have the "state" (feature repositories, features, bundles and their states, datafiles
// and start-level info) stored in *.result file
Presentation.displayFeatureUpdates(result.getFeatureUpdates(), false);
Presentation.displayBundleUpdates(result.getBundleUpdates(), false);
try {
if (!simulate) {
// let's backup data files before configadmin detects changes to etc/* files.
backupService.backupDataFiles(result, Pending.ROLLUP_ROLLBACK);
for (Bundle b : this.bundleContext.getBundles()) {
if (b.getSymbolicName() != null && Utils.stripSymbolicName(b.getSymbolicName()).equals("org.apache.felix.fileinstall")) {
b.stop(Bundle.STOP_TRANSIENT);
break;
}
}
patchManagement.rollback(patch.getPatchData());
result.setPending(Pending.ROLLUP_ROLLBACK);
if (patchManagement.isStandaloneChild()) {
result.getParent().store();
} else {
result.store();
}
if (isJvmRestartNeeded(result)) {
boolean handlesFullRestart = Boolean.getBoolean("karaf.restart.jvm.supported");
if (handlesFullRestart) {
System.out.println("Rollup patch " + patch.getPatchData().getId() + " rolled back. Restarting Karaf..");
System.setProperty("karaf.restart.jvm", "true");
} else {
System.out.println("Rollup patch " + patch.getPatchData().getId() + " rolled back. Shutting down Karaf, please restart...");
}
} else {
// We don't need a JVM restart, so lets just do a OSGi framework restart
System.setProperty("karaf.restart", "true");
}
File karafData = new File(bundleContext.getProperty("karaf.data"));
File cleanCache = new File(karafData, "clean_cache");
cleanCache.createNewFile();
bundleContext.getBundle(0l).stop();
// stop/shutdown occurs on another thread
return;
} else {
System.out.println("Simulation only - no files and runtime data will be modified.");
return;
}
} catch (Exception e) {
e.printStackTrace(System.err);
System.err.flush();
throw new PatchException(e.getMessage(), e);
}
}
// continue with NON_ROLLUP patch
// current state of the framework
Bundle[] allBundles = bundleContext.getBundles();
// check if all the bundles that were updated in patch are available (installed)
List<BundleUpdate> badUpdates = new ArrayList<BundleUpdate>();
for (BundleUpdate update : result.getBundleUpdates()) {
boolean found = false;
Version v = Version.parseVersion(update.getNewVersion() == null ? update.getPreviousVersion() : update.getNewVersion());
for (Bundle bundle : allBundles) {
if (bundle.getSymbolicName() == null || update.getSymbolicName() == null) {
continue;
}
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.getPatchData().getId()).append(" because of the following missing bundles:\n");
for (BundleUpdate up : badUpdates) {
String version = up.getNewVersion() == null ? up.getPreviousVersion() : up.getNewVersion();
sb.append(" - ").append(up.getSymbolicName()).append("/").append(version).append("\n");
}
throw new PatchException(sb.toString());
}
if (!simulate) {
// bundle -> old location of the bundle to downgrade from
final Map<Bundle, String> toUpdate = new HashMap<Bundle, String>();
for (BundleUpdate update : result.getBundleUpdates()) {
Version v = Version.parseVersion(update.getNewVersion() == null ? update.getPreviousVersion() : update.getNewVersion());
for (Bundle bundle : allBundles) {
if (bundle.getSymbolicName() == null || update.getSymbolicName() == null) {
continue;
}
if (stripSymbolicName(bundle.getSymbolicName()).equals(stripSymbolicName(update.getSymbolicName())) && bundle.getVersion().equals(v)) {
toUpdate.put(bundle, update.getPreviousLocation());
}
}
}
final boolean isStandaloneChild = patchManagement.isStandaloneChild();
patchManagement.rollback(patch.getPatchData());
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
try {
applyChanges(toUpdate);
} catch (Exception e) {
throw new PatchException("Unable to rollback patch " + patch.getPatchData().getId() + ": " + e.getMessage(), e);
}
patch.setResult(null);
File file = new File(patchDir, result.getPatchData().getId() + ".patch.result");
if (isStandaloneChild) {
file = new File(patchDir, result.getPatchData().getId() + "." + System.getProperty("karaf.name") + ".patch.result");
}
file.delete();
}
});
}
}
Aggregations