use of io.fabric8.patch.management.Pending in project fabric8 by jboss-fuse.
the class DeploymentAgent method doUpdate.
public boolean doUpdate(Dictionary<String, ?> props) throws Exception {
if (props == null || Boolean.parseBoolean((String) props.get("disabled"))) {
return false;
}
final Hashtable<String, String> properties = new Hashtable<>();
for (Enumeration e = props.keys(); e.hasMoreElements(); ) {
Object key = e.nextElement();
Object val = props.get(key);
if (!"service.pid".equals(key) && !FeatureConfigInstaller.FABRIC_ZOOKEEPER_PID.equals(key)) {
properties.put(key.toString(), val.toString());
}
}
updateStatus("analyzing", null);
// Building configuration
curatorCompleteService.waitForService(TimeUnit.SECONDS.toMillis(30));
String httpUrl;
List<URI> mavenRepoURIs;
// force reading of updated informations from ZK
if (!fabricService.isEmpty()) {
updateMavenRepositoryConfiguration(fabricService.getService());
}
try {
fabricServiceOperations.lock();
// no one will change the members now
httpUrl = this.httpUrl;
mavenRepoURIs = this.mavenRepoURIs;
} finally {
fabricServiceOperations.unlock();
}
addMavenProxies(properties, httpUrl, mavenRepoURIs);
final MavenResolver resolver = MavenResolvers.createMavenResolver(properties, "org.ops4j.pax.url.mvn");
final DownloadManager manager = DownloadManagers.createDownloadManager(resolver, getDownloadExecutor());
manager.addListener(new DownloadCallback() {
@Override
public void downloaded(StreamProvider provider) throws Exception {
int pending = manager.pending();
updateStatus(pending > 0 ? "downloading (" + pending + " pending)" : "downloading", null);
}
});
// Update framework, libs, system and config props
final Object lock = new Object();
final AtomicBoolean restart = new AtomicBoolean();
final Set<String> libsToRemove = new HashSet<>(managedLibs.keySet());
final Set<String> endorsedLibsToRemove = new HashSet<>(managedEndorsedLibs.keySet());
final Set<String> extensionLibsToRemove = new HashSet<>(managedExtensionLibs.keySet());
final Set<String> sysPropsToRemove = new HashSet<>(managedSysProps.keySet());
final Set<String> configPropsToRemove = new HashSet<>(managedConfigProps.keySet());
final Set<String> etcsToRemove = new HashSet<>(managedEtcs.keySet());
final Properties configProps = new Properties(new File(KARAF_BASE + File.separator + "etc" + File.separator + "config.properties"));
final Properties systemProps = new Properties(new File(KARAF_BASE + File.separator + "etc" + File.separator + "system.properties"));
Downloader downloader = manager.createDownloader();
for (String key : properties.keySet()) {
if (key.equals("framework")) {
String url = properties.get(key);
if (!url.startsWith("mvn:")) {
throw new IllegalArgumentException("Framework url must use the mvn: protocol");
}
downloader.download(url, new DownloadCallback() {
@Override
public void downloaded(StreamProvider provider) throws Exception {
File file = provider.getFile();
String path = file.getPath();
if (path.startsWith(KARAF_HOME)) {
path = path.substring(KARAF_HOME.length() + 1);
}
synchronized (lock) {
if (!path.equals(configProps.get("karaf.framework.felix"))) {
configProps.put("karaf.framework", "felix");
configProps.put("karaf.framework.felix", path);
restart.set(true);
}
}
}
});
} else if (key.startsWith("config.")) {
String k = key.substring("config.".length());
String v = properties.get(key);
synchronized (lock) {
managedConfigProps.put(k, v);
configPropsToRemove.remove(k);
if (!v.equals(configProps.get(k))) {
configProps.put(k, v);
restart.set(true);
}
}
} else if (key.startsWith("system.")) {
String k = key.substring("system.".length());
synchronized (lock) {
String v = properties.get(key);
managedSysProps.put(k, v);
sysPropsToRemove.remove(k);
if (!v.equals(systemProps.get(k))) {
systemProps.put(k, v);
restart.set(true);
}
}
} else if (key.startsWith("lib.")) {
String value = properties.get(key);
downloader.download(value, new DownloadCallback() {
@Override
public void downloaded(StreamProvider provider) throws Exception {
File libFile = provider.getFile();
String libName = libFile.getName();
Long checksum = ChecksumUtils.checksum(libFile);
boolean update;
synchronized (lock) {
managedLibs.put(libName, "true");
libsToRemove.remove(libName);
update = !Long.toString(checksum).equals(libChecksums.getProperty(libName));
}
if (update) {
Files.copy(libFile, new File(LIB_PATH, libName));
restart.set(true);
}
}
});
} else if (key.startsWith("endorsed.")) {
String value = properties.get(key);
downloader.download(value, new DownloadCallback() {
@Override
public void downloaded(StreamProvider provider) throws Exception {
File libFile = provider.getFile();
String libName = libFile.getName();
Long checksum = ChecksumUtils.checksum(new FileInputStream(libFile));
boolean update;
synchronized (lock) {
managedEndorsedLibs.put(libName, "true");
endorsedLibsToRemove.remove(libName);
update = !Long.toString(checksum).equals(endorsedChecksums.getProperty(libName));
}
if (update) {
Files.copy(libFile, new File(LIB_ENDORSED_PATH, libName));
restart.set(true);
}
}
});
} else if (key.startsWith("extension.")) {
String value = properties.get(key);
downloader.download(value, new DownloadCallback() {
@Override
public void downloaded(StreamProvider provider) throws Exception {
File libFile = provider.getFile();
String libName = libFile.getName();
Long checksum = ChecksumUtils.checksum(libFile);
boolean update;
synchronized (lock) {
managedExtensionLibs.put(libName, "true");
extensionLibsToRemove.remove(libName);
update = !Long.toString(checksum).equals(extensionChecksums.getProperty(libName));
}
if (update) {
Files.copy(libFile, new File(LIB_EXT_PATH, libName));
restart.set(true);
}
}
});
} else if (key.startsWith("etc.")) {
String value = properties.get(key);
downloader.download(value, new DownloadCallback() {
@Override
public void downloaded(StreamProvider provider) throws Exception {
File etcFile = provider.getFile();
String etcName = etcFile.getName();
Long checksum = ChecksumUtils.checksum(new FileInputStream(etcFile));
boolean update;
synchronized (lock) {
managedEtcs.put(etcName, "true");
etcsToRemove.remove(etcName);
update = !Long.toString(checksum).equals(etcChecksums.getProperty(etcName));
}
if (update) {
Files.copy(etcFile, new File(KARAF_ETC, etcName));
}
}
});
}
}
downloader.await();
// Remove unused libs, system & config properties
for (String sysProp : sysPropsToRemove) {
systemProps.remove(sysProp);
managedSysProps.remove(sysProp);
System.clearProperty(sysProp);
restart.set(true);
}
for (String configProp : configPropsToRemove) {
configProps.remove(configProp);
managedConfigProps.remove(configProp);
restart.set(true);
}
for (String lib : libsToRemove) {
File libFile = new File(LIB_PATH, lib);
libFile.delete();
libChecksums.remove(lib);
managedLibs.remove(lib);
restart.set(true);
}
for (String lib : endorsedLibsToRemove) {
File libFile = new File(LIB_ENDORSED_PATH, lib);
libFile.delete();
endorsedChecksums.remove(lib);
managedEndorsedLibs.remove(lib);
restart.set(true);
}
for (String lib : extensionLibsToRemove) {
File libFile = new File(LIB_EXT_PATH, lib);
libFile.delete();
extensionChecksums.remove(lib);
managedExtensionLibs.remove(lib);
restart.set(true);
}
for (String etc : etcsToRemove) {
File etcFile = new File(KARAF_ETC, etc);
etcFile.delete();
etcChecksums.remove(etc);
managedEtcs.remove(etc);
}
libChecksums.save();
endorsedChecksums.save();
extensionChecksums.save();
etcChecksums.save();
managedLibs.save();
managedEndorsedLibs.save();
managedExtensionLibs.save();
managedConfigProps.save();
managedSysProps.save();
managedEtcs.save();
if (restart.get()) {
updateStatus("restarting", null);
configProps.save();
systemProps.save();
System.setProperty("karaf.restart", "true");
bundleContext.getBundle(0).stop();
return false;
}
FeatureConfigInstaller configInstaller = null;
ServiceReference configAdminServiceReference = bundleContext.getServiceReference(ConfigurationAdmin.class.getName());
if (configAdminServiceReference != null) {
ConfigurationAdmin configAdmin = (ConfigurationAdmin) bundleContext.getService(configAdminServiceReference);
configInstaller = new FeatureConfigInstaller(bundleContext, configAdmin, manager);
}
int bundleStartTimeout = Constants.BUNDLE_START_TIMEOUT;
String overriddenTimeout = properties.get(Constants.BUNDLE_START_TIMEOUT_PID_KEY);
try {
if (overriddenTimeout != null)
bundleStartTimeout = Integer.parseInt(overriddenTimeout);
} catch (Exception e) {
LOGGER.warn("Failed to set {} value: [{}], applying default value: {}", Constants.BUNDLE_START_TIMEOUT_PID_KEY, overriddenTimeout, Constants.BUNDLE_START_TIMEOUT);
}
Agent agent = new Agent(bundleContext.getBundle(), systemBundleContext, manager, configInstaller, null, DEFAULT_FEATURE_RESOLUTION_RANGE, DEFAULT_BUNDLE_UPDATE_RANGE, DEFAULT_UPDATE_SNAPSHOTS, bundleContext.getDataFile(STATE_FILE), bundleStartTimeout) {
@Override
public void updateStatus(String status) {
DeploymentAgent.this.updateStatus(status, null, false);
}
@Override
public void updateStatus(String status, boolean force) {
DeploymentAgent.this.updateStatus(status, null, force);
}
@Override
protected void saveState(State newState) throws IOException {
super.saveState(newState);
DeploymentAgent.this.state.replace(newState);
}
@Override
protected void provisionList(Set<Resource> resources) {
DeploymentAgent.this.provisionList = resources;
}
@Override
protected boolean done(boolean agentStarted, List<String> urls) {
if (agentStarted) {
// let's do patch-management "last touch" only if new agent wasn't started.
return true;
}
// agent finished provisioning, we can call back to low level patch management
ServiceReference<PatchManagement> srPm = systemBundleContext.getServiceReference(PatchManagement.class);
ServiceReference<FabricService> srFs = systemBundleContext.getServiceReference(FabricService.class);
if (srPm != null && srFs != null) {
PatchManagement pm = systemBundleContext.getService(srPm);
FabricService fs = systemBundleContext.getService(srFs);
if (pm != null && fs != null) {
LOGGER.info("Validating baseline information");
this.updateStatus("validating baseline information", true);
Profile profile = fs.getCurrentContainer().getOverlayProfile();
Map<String, String> versions = profile.getConfiguration("io.fabric8.version");
File localRepository = resolver.getLocalRepository();
if (pm.alignTo(versions, urls, localRepository, new PatchSynchronization())) {
this.updateStatus("requires full restart", true);
// let's reuse the same flag
restart.set(true);
return false;
}
if (handleRestartJvmFlag(profile, restart)) {
return false;
}
}
}
return true;
}
};
agent.setDeploymentAgentId(deploymentAgentId);
agent.provision(getPrefixedProperties(properties, "repository."), getPrefixedProperties(properties, "feature."), getPrefixedProperties(properties, "bundle."), getPrefixedProperties(properties, "req."), getPrefixedProperties(properties, "override."), getPrefixedProperties(properties, "optional."), getMetadata(properties, "metadata#"));
if (restart.get()) {
// prevent updating status to "success"
return false;
}
return true;
}
use of io.fabric8.patch.management.Pending in project fabric8 by jboss-fuse.
the class GitMasterListener method updateMasterUrl.
/**
* Updates the git master url, if needed.
*/
private void updateMasterUrl(Group<GitNode> group) {
GitNode master = group.master();
String masterUrl = master != null ? master.getUrl() : null;
try {
if (masterUrl != null) {
GitService gitservice = gitService.get();
String substitutedUrl = getSubstitutedData(curator.get(), masterUrl);
if (!Strings.isNotBlank(substitutedUrl)) {
LOGGER.warn("Could not render git master URL {}.", masterUrl);
}
// Catch any possible issue indicating that the URL is invalid.
if (!FabricValidations.isURIValid(substitutedUrl)) {
LOGGER.warn("Not changing master Git URL to \"" + substitutedUrl + "\". There may be pending ZK connection shutdown.");
} else {
gitservice.notifyRemoteChanged(substitutedUrl);
}
}
} catch (Exception e) {
LOGGER.error("Failed to point origin to the new master.", e);
}
}
use of io.fabric8.patch.management.Pending in project fabric8 by jboss-fuse.
the class FileBackupService method backupDataFiles.
/**
* Invoked just before Framework is restarted and data/cache directory is removed. We copy existing data
* directories for current bundles and record for which bundle$$version it is used.
* @param result used to create backup directories.
* @param pending
* @throws IOException
*/
@Override
public void backupDataFiles(PatchResult result, Pending pending) throws IOException {
Map<String, Bundle> bundlesWithData = new HashMap<>();
// bundle.getDataFile("xxx") creates data dir if it didn't exist - it's not what we want
String storageLocation = systemContext.getProperty("org.osgi.framework.storage");
if (storageLocation == null) {
Activator.log(LogService.LOG_INFO, "Can't determine \"org.osgi.framework.storage\" property value");
return;
}
File cacheDir = new File(storageLocation);
if (!cacheDir.isDirectory()) {
return;
}
for (Bundle b : systemContext.getBundles()) {
if (b.getSymbolicName() != null) {
String sn = Utils.stripSymbolicName(b.getSymbolicName());
if ("org.apache.karaf.features.core".equals(sn)) {
// we start with fresh features service state
continue;
}
// a bit of knowledge of how Felix works below...
File dataDir = new File(cacheDir, "bundle" + b.getBundleId() + "/data");
if (dataDir.isDirectory()) {
String key = String.format("%s$$%s", sn, b.getVersion().toString());
bundlesWithData.put(key, b);
}
}
}
// this property file will be used to map full symbolicName$$version to a location where bundle data
// is stored - the data must be restored both during R patch installation and rollback
Properties properties = new Properties();
String dirName = result.getPatchData().getId() + ".datafiles";
if (result.getParent() != null) {
dirName = result.getPatchData().getId() + "." + System.getProperty("karaf.name") + ".datafiles";
}
File dataBackupDir = new File(result.getPatchData().getPatchLocation(), dirName);
String prefix = pending == Pending.ROLLUP_INSTALLATION ? "install" : "rollback";
for (BundleUpdate update : result.getBundleUpdates()) {
// same update for both updated and reinstalled bundle
String key = String.format("%s$$%s", update.getSymbolicName(), pending == Pending.ROLLUP_INSTALLATION ? update.getPreviousVersion() : (update.getNewVersion() == null ? update.getPreviousVersion() : update.getNewVersion()));
if (bundlesWithData.containsKey(key)) {
File dataFileBackupDir = new File(dataBackupDir, prefix + "/" + key + "/data");
dataFileBackupDir.mkdirs();
final Bundle b = bundlesWithData.get(key);
FileUtils.copyDirectory(b.getDataFile(""), dataFileBackupDir, new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory() || !b.getSymbolicName().equals("org.apache.felix.configadmin") || pathname.getName().endsWith(".config");
}
});
properties.setProperty(key, key);
properties.setProperty(String.format("%s$$%s", update.getSymbolicName(), update.getPreviousVersion()), key);
if (update.getNewVersion() != null) {
properties.setProperty(String.format("%s$$%s", update.getSymbolicName(), update.getNewVersion()), key);
}
}
}
FileOutputStream propsFile = new FileOutputStream(new File(dataBackupDir, "backup-" + prefix + ".properties"));
properties.store(propsFile, "Data files to restore after \"" + result.getPatchData().getId() + "\" " + (pending == Pending.ROLLUP_INSTALLATION ? "installation" : "rollback"));
propsFile.close();
}
use of io.fabric8.patch.management.Pending in project fabric8 by jboss-fuse.
the class ServiceImpl method resumePendingPatchTasks.
/**
* Upon startup (activation), we check if there are any *.patch.pending files. if yes, we're finishing the
* installation
*/
private void resumePendingPatchTasks() throws IOException {
File[] pendingPatches = patchDir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.exists() && pathname.getName().endsWith(".pending");
}
});
if (pendingPatches == null || pendingPatches.length == 0) {
return;
}
for (File pending : pendingPatches) {
Pending what = Pending.valueOf(FileUtils.readFileToString(pending));
String name = pending.getName().replaceFirst("\\.pending$", "");
if (patchManagement.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()) {
System.out.println("Ignoring patch result file: " + patchFile.getName());
continue;
}
PatchData patchData = PatchData.load(new FileInputStream(patchFile));
Patch patch = patchManagement.loadPatch(new PatchDetailsRequest(patchData.getId()));
System.out.printf("Resume %s of %spatch \"%s\"%n", what == Pending.ROLLUP_INSTALLATION ? "installation" : "rollback", patch.getPatchData().isRollupPatch() ? "rollup " : "", patch.getPatchData().getId());
PatchResult result = patch.getResult();
if (patchManagement.isStandaloneChild()) {
result = result.getChildPatches().get(System.getProperty("karaf.name"));
if (result == null) {
System.out.println("Ignoring patch result file: " + patchFile.getName());
continue;
}
}
// feature time
Set<String> newRepositories = new LinkedHashSet<>();
Set<String> features = new LinkedHashSet<>();
for (FeatureUpdate featureUpdate : result.getFeatureUpdates()) {
if (featureUpdate.getName() == null && featureUpdate.getPreviousRepository() != null) {
// feature was not shipped by patch
newRepositories.add(featureUpdate.getPreviousRepository());
} else if (featureUpdate.getNewRepository() == null) {
// feature was not changed by patch
newRepositories.add(featureUpdate.getPreviousRepository());
features.add(String.format("%s|%s", featureUpdate.getName(), featureUpdate.getPreviousVersion()));
} else {
// feature was shipped by patch
if (what == Pending.ROLLUP_INSTALLATION) {
newRepositories.add(featureUpdate.getNewRepository());
features.add(String.format("%s|%s", featureUpdate.getName(), featureUpdate.getNewVersion()));
} else {
newRepositories.add(featureUpdate.getPreviousRepository());
features.add(String.format("%s|%s", featureUpdate.getName(), featureUpdate.getPreviousVersion()));
}
}
}
for (String repo : newRepositories) {
System.out.println("Restoring feature repository: " + repo);
try {
featuresService.addRepository(URI.create(repo));
} catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace(System.err);
System.err.flush();
}
}
for (String f : features) {
String[] fv = f.split("\\|");
System.out.printf("Restoring feature %s/%s%n", fv[0], fv[1]);
try {
featuresService.installFeature(fv[0], fv[1]);
} catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace(System.err);
System.err.flush();
}
}
for (BundleUpdate update : result.getBundleUpdates()) {
if (!update.isIndependent()) {
continue;
}
String location = null;
if (update.getNewVersion() == null) {
System.out.printf("Restoring bundle %s from %s%n", update.getSymbolicName(), update.getPreviousLocation());
location = update.getPreviousLocation();
} else {
if (what == Pending.ROLLUP_INSTALLATION) {
System.out.printf("Updating bundle %s from %s%n", update.getSymbolicName(), update.getNewLocation());
location = update.getNewLocation();
} else {
System.out.printf("Downgrading bundle %s from %s%n", update.getSymbolicName(), update.getPreviousLocation());
location = update.getPreviousLocation();
}
}
try {
Bundle b = bundleContext.installBundle(location);
if (update.getStartLevel() > -1) {
b.adapt(BundleStartLevel.class).setStartLevel(update.getStartLevel());
}
switch(update.getState()) {
// ?
case Bundle.UNINSTALLED:
case Bundle.INSTALLED:
case Bundle.STARTING:
case Bundle.STOPPING:
break;
case Bundle.RESOLVED:
// ?bundleContext.getBundle(0L).adapt(org.osgi.framework.wiring.FrameworkWiring.class).resolveBundles(...);
break;
case Bundle.ACTIVE:
b.start();
break;
}
} catch (BundleException e) {
System.err.println(" - " + e.getMessage());
// e.printStackTrace(System.err);
System.err.flush();
}
}
pending.delete();
System.out.printf("%spatch \"%s\" %s successfully%n", patch.getPatchData().isRollupPatch() ? "Rollup " : "", patchData.getId(), what == Pending.ROLLUP_INSTALLATION ? "installed" : "rolled back");
if (what == Pending.ROLLUP_ROLLBACK) {
List<String> bases = patch.getResult().getKarafBases();
for (Iterator<String> iterator = bases.iterator(); iterator.hasNext(); ) {
String s = iterator.next();
if (s.startsWith(System.getProperty("karaf.name"))) {
iterator.remove();
}
}
result.setPending(null);
patch.getResult().store();
if (patch.getResult().getKarafBases().size() == 0) {
File file = new File(patchDir, patchData.getId() + ".patch.result");
file.delete();
}
if (patchManagement.isStandaloneChild()) {
File file = new File(patchDir, patchData.getId() + "." + System.getProperty("karaf.name") + ".patch.result");
if (file.isFile()) {
file.delete();
}
}
}
}
}
use of io.fabric8.patch.management.Pending in project zalenium by zalando.
the class KubernetesContainerClient method getRunningContainers.
@Override
public int getRunningContainers(String image) {
PodList list = client.pods().withLabels(createdByZaleniumMap).list();
logger.debug("Pods in the list " + list.getItems().size());
int count = 0;
for (Pod pod : list.getItems()) {
String phase = pod.getStatus().getPhase();
if ("Running".equalsIgnoreCase(phase) || "Pending".equalsIgnoreCase(phase)) {
count++;
}
}
return count;
}
Aggregations