use of io.fabric8.maven.docker.config.CopyConfiguration.Entry in project fabric8 by jboss-fuse.
the class Logs method newInstance.
public static LogEvent newInstance(PaxLoggingEvent event) {
LogEvent answer = new LogEvent();
try {
answer.setLevel(toString(event.getLevel()));
} catch (NoClassDefFoundError error) {
// ENTESB-2234, KARAF-3350: Ignore NoClassDefFoundError exceptions
// Those exceptions may happen if the underlying pax-logging service
// bundle has been refreshed somehow.
answer.setLevel("LOG");
}
answer.setMessage(event.getMessage());
answer.setLogger(event.getLoggerName());
answer.setTimestamp(new Date(event.getTimeStamp()));
answer.setThread(event.getThreadName());
answer.setException(addMavenCoord(event.getThrowableStrRep()));
Map eventProperties = event.getProperties();
if (eventProperties != null && eventProperties.size() > 0) {
Map<String, String> properties = new HashMap<String, String>();
Set<Map.Entry> set = eventProperties.entrySet();
for (Map.Entry entry : set) {
Object key = entry.getKey();
Object value = entry.getValue();
if (key != null && value != null) {
properties.put(toString(key), toString(value));
}
}
MavenCoordinates.addMavenCoord(properties);
answer.setProperties(properties);
}
// event.getFQNOfLoggerClass()
try {
PaxLocationInfo locationInformation = event.getLocationInformation();
if (locationInformation != null) {
answer.setClassName(locationInformation.getClassName());
answer.setFileName(locationInformation.getFileName());
answer.setMethodName(locationInformation.getMethodName());
answer.setLineNumber(locationInformation.getLineNumber());
}
} catch (NoClassDefFoundError error) {
// ENTESB-2234, KARAF-3350: Ignore NoClassDefFoundError exceptions
}
return answer;
}
use of io.fabric8.maven.docker.config.CopyConfiguration.Entry in project fabric8 by jboss-fuse.
the class GitPatchManagementServiceImpl method handleConflict.
private void handleConflict(File patchDirectory, Git fork, boolean preferNew, String cpPrefix, boolean performBackup, String choose, String backup, boolean rollback) throws GitAPIException, IOException {
Map<String, IndexDiff.StageState> conflicts = fork.status().call().getConflictingStageState();
DirCache cache = fork.getRepository().readDirCache();
// path -> [oursObjectId, baseObjectId, theirsObjectId]
Map<String, ObjectId[]> threeWayMerge = new HashMap<>();
// collect conflicts info
for (int i = 0; i < cache.getEntryCount(); i++) {
DirCacheEntry entry = cache.getEntry(i);
if (entry.getStage() == DirCacheEntry.STAGE_0) {
continue;
}
if (!threeWayMerge.containsKey(entry.getPathString())) {
threeWayMerge.put(entry.getPathString(), new ObjectId[] { null, null, null });
}
if (entry.getStage() == DirCacheEntry.STAGE_1) {
// base
threeWayMerge.get(entry.getPathString())[1] = entry.getObjectId();
}
if (entry.getStage() == DirCacheEntry.STAGE_2) {
// ours
threeWayMerge.get(entry.getPathString())[0] = entry.getObjectId();
}
if (entry.getStage() == DirCacheEntry.STAGE_3) {
// theirs
threeWayMerge.get(entry.getPathString())[2] = entry.getObjectId();
}
}
// resolve conflicts
ObjectReader objectReader = fork.getRepository().newObjectReader();
for (Map.Entry<String, ObjectId[]> entry : threeWayMerge.entrySet()) {
if (entry.getKey().equals("patch-info.txt")) {
fork.rm().addFilepattern(entry.getKey()).call();
continue;
}
Resolver resolver = conflictResolver.getResolver(entry.getKey());
// resolved version - either by custom resolved or using automatic algorithm
String resolved = null;
if (resolver != null && entry.getValue()[0] != null && entry.getValue()[2] != null) {
// custom conflict resolution (don't expect DELETED_BY_X kind of conflict, only BOTH_MODIFIED)
String message = String.format(" - %s (%s): %s", entry.getKey(), conflicts.get(entry.getKey()), "Using " + resolver.getClass().getName() + " to resolve the conflict");
Activator.log2(LogService.LOG_INFO, message);
// when doing custom resolution of conflict, we know that both user and patch has changed the file
// in non-mergeable way.
// If there was no resolver, we simply check what to choose by "preferNew" flag
// But because we have custom resolver, we use "preferNew" flag to check which STAGE points to patch'
// version and we select this patch' version of conflicting file as less important file inside
// custom resolver
File base = null, first = null, second = null;
try {
ObjectLoader loader = null;
if (entry.getValue()[1] != null) {
base = new File(fork.getRepository().getWorkTree(), entry.getKey() + ".1");
loader = objectReader.open(entry.getValue()[1]);
try (FileOutputStream fos = new FileOutputStream(base)) {
loader.copyTo(fos);
}
}
// if preferNew == true (P patch) then "first" file (less important) will be file
// provided by patch ("theirs", STAGE_3)
first = new File(fork.getRepository().getWorkTree(), entry.getKey() + ".2");
loader = objectReader.open(entry.getValue()[preferNew ? 2 : 0]);
try (FileOutputStream fos = new FileOutputStream(first)) {
loader.copyTo(fos);
}
// "second", more important file will be user change
second = new File(fork.getRepository().getWorkTree(), entry.getKey() + ".3");
loader = objectReader.open(entry.getValue()[preferNew ? 0 : 2]);
try (FileOutputStream fos = new FileOutputStream(second)) {
loader.copyTo(fos);
}
// resolvers treat patch change as less important - user lines overwrite patch lines
if (resolver instanceof PropertiesFileResolver) {
// TODO: use options from patch:install / patch:fabric-install command
// by default we use a file that comes from patch and we may add property changes
// from user
// in R patch, preferNew == false, because patch comes first
// in P patch, preferNew == true, because patch comes last
// in R patch + fabric mode, preferNew == true, because we *merge* patch branch into version
// branch
boolean useFirstChangeAsBase = true;
if (entry.getKey().startsWith("etc/")) {
// as base
if (rollback) {
useFirstChangeAsBase = true;
} else {
useFirstChangeAsBase = false;
}
}
resolved = ((ResolverEx) resolver).resolve(first, base, second, useFirstChangeAsBase, rollback);
} else {
resolved = resolver.resolve(first, base, second);
}
if (resolved != null) {
FileUtils.write(new File(fork.getRepository().getWorkTree(), entry.getKey()), resolved);
fork.add().addFilepattern(entry.getKey()).call();
}
} finally {
if (base != null) {
base.delete();
}
if (first != null) {
first.delete();
}
if (second != null) {
second.delete();
}
}
}
if (resolved == null) {
// automatic conflict resolution
String message = String.format(" - %s (%s): Choosing %s", entry.getKey(), conflicts.get(entry.getKey()), choose);
ObjectLoader loader = null;
ObjectLoader loaderForBackup = null;
// longer code, but more readable then series of elvis operators (?:)
if (preferNew) {
switch(conflicts.get(entry.getKey())) {
case BOTH_ADDED:
case BOTH_MODIFIED:
loader = objectReader.open(entry.getValue()[2]);
loaderForBackup = objectReader.open(entry.getValue()[0]);
break;
case BOTH_DELETED:
break;
case DELETED_BY_THEM:
// ENTESB-6003: special case: when R patch removes something and we've modified it
// let's preserve our version
message = String.format(" - %s (%s): Keeping custom change", entry.getKey(), conflicts.get(entry.getKey()));
loader = objectReader.open(entry.getValue()[0]);
break;
case DELETED_BY_US:
loader = objectReader.open(entry.getValue()[2]);
break;
}
} else {
switch(conflicts.get(entry.getKey())) {
case BOTH_ADDED:
case BOTH_MODIFIED:
loader = objectReader.open(entry.getValue()[0]);
loaderForBackup = objectReader.open(entry.getValue()[2]);
break;
case DELETED_BY_THEM:
loader = objectReader.open(entry.getValue()[0]);
break;
case BOTH_DELETED:
case DELETED_BY_US:
break;
}
}
Activator.log2(LogService.LOG_WARNING, message);
if (loader != null) {
try (FileOutputStream fos = new FileOutputStream(new File(fork.getRepository().getWorkTree(), entry.getKey()))) {
loader.copyTo(fos);
}
fork.add().addFilepattern(entry.getKey()).call();
} else {
fork.rm().addFilepattern(entry.getKey()).call();
}
if (performBackup) {
// the other entry should be backed up
if (loaderForBackup != null) {
File target = new File(patchDirectory.getParent(), patchDirectory.getName() + ".backup");
if (isStandaloneChild()) {
target = new File(patchDirectory.getParent(), patchDirectory.getName() + "." + System.getProperty("karaf.name") + ".backup");
}
if (cpPrefix != null) {
target = new File(target, cpPrefix);
}
File file = new File(target, entry.getKey());
message = String.format("Backing up %s to \"%s\"", backup, file.getCanonicalPath());
Activator.log2(LogService.LOG_DEBUG, message);
file.getParentFile().mkdirs();
try (FileOutputStream fos = new FileOutputStream(file)) {
loaderForBackup.copyTo(fos);
}
}
}
}
}
}
use of io.fabric8.maven.docker.config.CopyConfiguration.Entry in project fabric8 by jboss-fuse.
the class GitPatchManagementServiceImpl method unzipKarafAdminJar.
/**
* Unzips <code>bin</code> and <code>etc</code> from org.apache.karaf.admin.core.
* @param artifact
* @param targetDirectory
* @throws IOException
*/
private void unzipKarafAdminJar(File artifact, File targetDirectory) throws IOException {
ZipFile zf = new ZipFile(artifact);
String prefix = "org/apache/karaf/admin/";
try {
for (Enumeration<ZipArchiveEntry> e = zf.getEntries(); e.hasMoreElements(); ) {
ZipArchiveEntry entry = e.nextElement();
String name = entry.getName();
if (!name.startsWith(prefix)) {
continue;
}
name = name.substring(prefix.length());
if (!name.startsWith("bin") && !name.startsWith("etc")) {
continue;
}
// flags from karaf.admin.core
// see: org.apache.karaf.admin.internal.AdminServiceImpl.createInstance()
boolean windows = System.getProperty("os.name").startsWith("Win");
boolean cygwin = windows && new File(System.getProperty("karaf.home"), "bin/admin").exists();
if (!entry.isDirectory() && !entry.isUnixSymlink()) {
if (windows && !cygwin) {
if (name.startsWith("bin/") && !name.endsWith(".bat")) {
continue;
}
} else {
if (name.startsWith("bin/") && name.endsWith(".bat")) {
continue;
}
}
File file = new File(targetDirectory, name);
file.getParentFile().mkdirs();
FileOutputStream output = new EOLFixingFileOutputStream(targetDirectory, file);
IOUtils.copyLarge(zf.getInputStream(entry), output);
IOUtils.closeQuietly(output);
if (Files.getFileAttributeView(file.toPath(), PosixFileAttributeView.class) != null) {
if (name.startsWith("bin/") && !name.endsWith(".bat")) {
Files.setPosixFilePermissions(file.toPath(), getPermissionsFromUnixMode(file, 0775));
}
}
}
}
} finally {
if (zf != null) {
zf.close();
}
}
}
use of io.fabric8.maven.docker.config.CopyConfiguration.Entry in project fabric8 by jboss-fuse.
the class ServiceImpl method install.
/**
* <p>Main installation method. Installing a patch in non-fabric mode is a matter of correct merge (cherry-pick, merge,
* rebase) of patch branch into <code>master</code> branch.</p>
* <p>Static changes are handled by git, runtime changes (bundles, features) are handled depending on patch type:<ul>
* <li>Rollup: clear OSGi bundle cache, reinstall features that were installed after restart</li>
* <li>Non-Rollup: update bundles, generate overrides.properties and update scripts to reference new versions</li>
* </ul></p>
* <p>For Rollup patches we don't update bundles - we clear the bundle cache instead.</p>
* @param patches
* @param simulate
* @param synchronous
* @return
*/
private Map<String, PatchResult> install(final Collection<Patch> patches, final boolean simulate, boolean synchronous) {
PatchKind kind = checkConsistency(patches);
checkPrerequisites(patches);
checkStandaloneChild(patches);
// checkFabric();
String transaction = null;
try {
// Compute individual patch results (patchId -> Result)
final Map<String, PatchResult> results = new LinkedHashMap<String, PatchResult>();
// current state of the framework
Bundle[] allBundles = bundleContext.getBundles();
// bundle -> url to update the bundle from (used for non-rollup patch)
final Map<Bundle, String> bundleUpdateLocations = new HashMap<>();
/* A "key" is name + "update'able version". Such version is current version with micro version == 0 */
// [symbolic name|updateable-version] -> newest update for the bundle out of all installed patches
final Map<String, BundleUpdate> updatesForBundleKeys = new LinkedHashMap<>();
// [feature name|updateable-version] -> newest update for the feature out of all installed patches
final Map<String, FeatureUpdate> updatesForFeatureKeys = new LinkedHashMap<>();
// symbolic name -> version -> location
final BundleVersionHistory history = createBundleVersionHistory();
// beginning installation transaction = creating of temporary branch in git
transaction = this.patchManagement.beginInstallation(kind);
// bundles from etc/startup.properties + felix.framework = all bundles not managed by features
// these bundles will be treated in special way
// symbolic name -> Bundle
final Map<String, Bundle> coreBundles = helper.getCoreBundles(allBundles);
// runtime info is prepared to apply runtime changes and static info is prepared to update KARAF_HOME files
for (Patch patch : patches) {
List<FeatureUpdate> featureUpdatesInThisPatch = null;
if (kind == PatchKind.ROLLUP) {
// list of feature updates for the current patch
featureUpdatesInThisPatch = featureUpdatesInPatch(patch, updatesForFeatureKeys, kind);
helper.sortFeatureUpdates(featureUpdatesInThisPatch);
}
// list of bundle updates for the current patch - for ROLLUP patch, we minimize the list of bundles
// to "restore" (install after clearing data/cache) by not including bundles that are
// already updated as part of fueatures update
List<BundleUpdate> bundleUpdatesInThisPatch = bundleUpdatesInPatch(patch, allBundles, bundleUpdateLocations, history, updatesForBundleKeys, kind, coreBundles, featureUpdatesInThisPatch);
// each patch may change files, we're not updating the main files yet - it'll be done when
// install transaction is committed
patchManagement.install(transaction, patch, bundleUpdatesInThisPatch);
// each patch may ship a migrator
if (!simulate) {
installMigratorBundle(patch);
}
// prepare patch result before doing runtime changes
PatchResult result = null;
if (patch.getResult() != null) {
result = patch.getResult();
if (patchManagement.isStandaloneChild()) {
// ENTESB-5120: "result" is actually a result of patch installation in root container
// we need dedicated result for admin:create based child container
PatchResult childResult = new PatchResult(patch.getPatchData(), simulate, System.currentTimeMillis(), bundleUpdatesInThisPatch, featureUpdatesInThisPatch, result);
result.addChildResult(System.getProperty("karaf.name"), childResult);
}
} else {
result = new PatchResult(patch.getPatchData(), simulate, System.currentTimeMillis(), bundleUpdatesInThisPatch, featureUpdatesInThisPatch);
}
result.getKarafBases().add(String.format("%s | %s", System.getProperty("karaf.name"), System.getProperty("karaf.base")));
results.put(patch.getPatchData().getId(), result);
}
// One special case
if (kind == PatchKind.NON_ROLLUP) {
// for rollup patch, this bundle will be installed from scratch
for (Map.Entry<Bundle, String> entry : bundleUpdateLocations.entrySet()) {
Bundle bundle = entry.getKey();
if (bundle.getSymbolicName() != null && "org.ops4j.pax.url.mvn".equals(stripSymbolicName(bundle.getSymbolicName()))) {
// handle this bundle specially - update it here
URL location = new URL(entry.getValue());
System.out.printf("Special update of bundle \"%s\" from \"%s\"%n", bundle.getSymbolicName(), location);
if (!simulate) {
BundleUtils.update(bundle, location);
bundle.start();
}
// replace location - to be stored in result
bundleUpdateLocations.put(bundle, location.toString());
}
}
}
Presentation.displayFeatureUpdates(updatesForFeatureKeys.values(), true);
// effectively, we will update all the bundles from this list - even if some bundles will be "updated"
// as part of feature installation
Presentation.displayBundleUpdates(updatesForBundleKeys.values(), true);
// then required repositories, features and bundles will be reinstalled
if (kind == PatchKind.ROLLUP) {
if (!simulate) {
if (patches.size() == 1) {
Patch patch = patches.iterator().next();
PatchResult result = results.get(patch.getPatchData().getId());
patch.setResult(result);
// single shot
if (patchManagement.isStandaloneChild()) {
backupService.backupDataFiles(result.getChildPatches().get(System.getProperty("karaf.name")), Pending.ROLLUP_INSTALLATION);
} else {
backupService.backupDataFiles(result, Pending.ROLLUP_INSTALLATION);
}
for (Bundle b : coreBundles.values()) {
if (b.getSymbolicName() != null && Utils.stripSymbolicName(b.getSymbolicName()).equals("org.apache.felix.fileinstall")) {
b.stop(Bundle.STOP_TRANSIENT);
break;
}
}
// update KARAF_HOME
patchManagement.commitInstallation(transaction);
if (patchManagement.isStandaloneChild()) {
result.getChildPatches().get(System.getProperty("karaf.name")).setPending(Pending.ROLLUP_INSTALLATION);
} else {
result.setPending(Pending.ROLLUP_INSTALLATION);
}
result.store();
// Some updates need a full JVM restart.
if (isJvmRestartNeeded(results)) {
boolean handlesFullRestart = Boolean.getBoolean("karaf.restart.jvm.supported");
if (handlesFullRestart) {
System.out.println("Rollup patch " + patch.getPatchData().getId() + " installed. Restarting Karaf..");
System.setProperty("karaf.restart.jvm", "true");
} else {
System.out.println("Rollup patch " + patch.getPatchData().getId() + " installed. 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();
Thread.currentThread().setContextClassLoader(bundleContext.getBundle(0l).adapt(BundleWiring.class).getClassLoader());
bundleContext.getBundle(0l).stop();
}
} else {
System.out.println("Simulation only - no files and runtime data will be modified.");
patchManagement.rollbackInstallation(transaction);
}
return results;
}
// update KARAF_HOME
if (!simulate) {
patchManagement.commitInstallation(transaction);
} else {
patchManagement.rollbackInstallation(transaction);
}
if (!simulate) {
Runnable task = new Runnable() {
@Override
public void run() {
try {
// update bundles
applyChanges(bundleUpdateLocations);
// persist results of all installed patches
for (Patch patch : patches) {
PatchResult result = results.get(patch.getPatchData().getId());
patch.setResult(result);
result.store();
}
} catch (Exception e) {
e.printStackTrace(System.err);
System.err.flush();
}
}
};
if (synchronous) {
task.run();
} else {
new Thread(task).start();
}
} else {
System.out.println("Simulation only - no files and runtime data will be modified.");
}
return results;
} catch (Exception e) {
e.printStackTrace(System.err);
System.err.flush();
if (transaction != null && patchManagement != null) {
patchManagement.rollbackInstallation(transaction);
}
throw new PatchException(e.getMessage(), e);
} finally {
System.out.flush();
}
}
use of io.fabric8.maven.docker.config.CopyConfiguration.Entry in project fabric8 by jboss-fuse.
the class Utils method unpack.
/**
* Unpacks a ZIP file to targetDirectory
* @param zipFile
* @param targetDirectory
* @param skipInitialDirectories how many levels of a path to skip when unpacking (like skipping base directory inside ZIP)
* @throws IOException
*/
public static void unpack(File zipFile, File targetDirectory, int skipInitialDirectories) throws IOException {
ZipFile zf = new ZipFile(zipFile);
try {
for (Enumeration<ZipArchiveEntry> e = zf.getEntries(); e.hasMoreElements(); ) {
ZipArchiveEntry entry = e.nextElement();
String name = entry.getName();
int skip = skipInitialDirectories;
while (skip-- > 0) {
name = name.substring(name.indexOf('/') + 1);
}
if (entry.isDirectory()) {
new File(targetDirectory, name).mkdirs();
} else /*if (!entry.isUnixSymlink())*/
{
File file = new File(targetDirectory, name);
file.getParentFile().mkdirs();
FileOutputStream output = new EOLFixingFileOutputStream(targetDirectory, file);
IOUtils.copyLarge(zf.getInputStream(entry), output);
IOUtils.closeQuietly(output);
if (Files.getFileAttributeView(file.toPath(), PosixFileAttributeView.class) != null) {
Files.setPosixFilePermissions(file.toPath(), getPermissionsFromUnixMode(file, entry.getUnixMode()));
}
}
}
} finally {
zf.close();
}
}
Aggregations