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