/*
* RHQ Management Platform
* Copyright (C) 2005-2012 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation, and/or the GNU Lesser
* General Public License, version 2.1, also as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License and the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.rhq.plugins.platform;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.transfer.ContentResponseResult;
import org.rhq.core.domain.content.transfer.DeployIndividualPackageResponse;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
import org.rhq.core.domain.content.transfer.RemoveIndividualPackageResponse;
import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.core.domain.measurement.MeasurementDataTrait;
import org.rhq.core.domain.measurement.MeasurementReport;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.pluginapi.content.ContentContext;
import org.rhq.core.pluginapi.content.ContentFacet;
import org.rhq.core.pluginapi.content.ContentServices;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.plugins.platform.content.RpmPackageDiscoveryDelegate;
import org.rhq.plugins.platform.content.yum.PluginContext;
import org.rhq.plugins.platform.content.yum.YumContext;
import org.rhq.plugins.platform.content.yum.YumProxy;
import org.rhq.plugins.platform.content.yum.YumServer;
public class LinuxPlatformComponent extends PosixPlatformComponent implements ContentFacet {
// the prefix for all distro trait names
private static final String DISTRO_TRAIT_NAME_PREFIX = "distro.";
// trait metric names
private static final String TRAIT_DISTRO_NAME = DISTRO_TRAIT_NAME_PREFIX + "name";
private static final String TRAIT_DISTRO_VERSION = DISTRO_TRAIT_NAME_PREFIX + "version";
private final Log log = LogFactory.getLog(LinuxPlatformComponent.class);
private YumServer yumServer;
private YumProxy yumProxy;
private boolean enableContentDiscovery = false;
private boolean enableInternalYumServer = false;
@Override
public void start(ResourceContext context) {
super.start(context);
Configuration pluginConfiguration = context.getPluginConfiguration();
PropertySimple contentProp = pluginConfiguration.getSimple("enableContentDiscovery");
if (contentProp != null) {
Boolean bool = contentProp.getBooleanValue();
this.enableContentDiscovery = (bool != null) ? bool.booleanValue() : false;
} else {
this.enableContentDiscovery = false;
}
PropertySimple yumProp = pluginConfiguration.getSimple("enableInternalYumServer");
if (yumProp != null) {
Boolean bool = yumProp.getBooleanValue();
this.enableInternalYumServer = (bool != null) ? bool.booleanValue() : false;
} else {
this.enableInternalYumServer = false;
}
if (this.enableContentDiscovery) {
RpmPackageDiscoveryDelegate.setSystemInfo(this.resourceContext.getSystemInformation());
RpmPackageDiscoveryDelegate.checkExecutables();
//DebPackageDiscoveryDelegate.setSystemInfo(this.resourceContext.getSystemInformation());
//DebPackageDiscoveryDelegate.checkExecutables();
}
startWithContentContext(context.getContentContext());
return;
}
@Override
public void stop() {
if (yumServer != null) {
try {
yumServer.halt();
} catch (Exception e) {
log.warn("Failed to shutdown the yum server.", e);
}
}
super.stop();
}
private void startWithContentContext(ContentContext context) {
if (this.enableInternalYumServer) {
yumServer = new YumServer();
yumProxy = new YumProxy();
int port = yumPort();
log.debug("yum port=[" + port + "]");
try {
YumContext yumContext = new PluginContext(port, this.resourceContext, context);
yumServer.start(yumContext);
yumProxy.init(this.resourceContext);
} catch (Exception e) {
log.error("Failed to start yum server.", e);
}
} else {
log.info("Internal yum server is disabled.");
}
return;
}
public Set<ResourcePackageDetails> discoverDeployedPackages(PackageType type) {
Set<ResourcePackageDetails> detailsSet = new HashSet<ResourcePackageDetails>();
if (this.enableContentDiscovery) {
if (type.getName().equals("rpm")) {
try {
detailsSet = RpmPackageDiscoveryDelegate.discoverPackages(type);
} catch (IOException e) {
log.error("Error while trying to discover RPMs", e);
}
}
}
return detailsSet;
}
public List<DeployPackageStep> generateInstallationSteps(ResourcePackageDetails packageDetails) {
return null;
}
public DeployPackagesResponse deployPackages(Set<ResourcePackageDetails> packages, ContentServices contentServices) {
if (!this.enableInternalYumServer) {
throw new UnsupportedOperationException("Internal yum server is disabled - this operation is a no-op.");
}
try {
DeployPackagesResponse result = new DeployPackagesResponse(ContentResponseResult.SUCCESS);
List<String> pkgs = new ArrayList<String>();
for (ResourcePackageDetails p : packages) {
String pkgInfo = p.getName();
String version = p.getVersion();
if ((version != null) && (!"".equals(version))) {
pkgInfo = pkgInfo + "-" + version;
}
log.info("Adding <" + pkgInfo + "> to list of packages to deploy, original package object was: " + p);
pkgs.add(pkgInfo);
result
.addPackageResponse(new DeployIndividualPackageResponse(p.getKey(), ContentResponseResult.SUCCESS));
}
yumProxy.install(pkgs);
return result;
} catch (Exception e) {
log.error("Install packages failed", e);
}
return new DeployPackagesResponse(ContentResponseResult.FAILURE);
}
public RemovePackagesResponse removePackages(Set<ResourcePackageDetails> packages) {
if (!this.enableInternalYumServer) {
throw new UnsupportedOperationException("Internal yum server is disabled - this operation is a no-op.");
}
try {
RemovePackagesResponse result = new RemovePackagesResponse(ContentResponseResult.SUCCESS);
List<String> pkgs = new ArrayList<String>();
for (ResourcePackageDetails p : packages) {
pkgs.add(p.getName());
result
.addPackageResponse(new RemoveIndividualPackageResponse(p.getKey(), ContentResponseResult.SUCCESS));
}
yumProxy.remove(pkgs);
return result;
} catch (Exception e) {
log.error("Remove packages failed", e);
}
return new RemovePackagesResponse(ContentResponseResult.FAILURE);
}
public InputStream retrievePackageBits(ResourcePackageDetails packageDetails) {
return null;
}
@Override
public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metricRequests) {
super.getValues(report, metricRequests);
for (MeasurementScheduleRequest metricRequest : metricRequests) {
if (metricRequest.getName().startsWith(DISTRO_TRAIT_NAME_PREFIX)) {
report.addData(getDistroTrait(metricRequest));
}
}
}
@Override
public OperationResult invokeOperation(String name, Configuration parameters) throws Exception {
if ("cleanYumMetadataCache".equals(name)) {
if (!this.enableInternalYumServer) {
throw new UnsupportedOperationException("Internal yum server is disabled - this operation is a no-op.");
}
log.info("Cleaning yum metadata...");
yumServer.cleanMetadata();
yumProxy.cleanMetadata();
return new OperationResult();
}
return super.invokeOperation(name, parameters);
}
private MeasurementDataTrait getDistroTrait(MeasurementScheduleRequest metricRequest) {
MeasurementDataTrait trait = new MeasurementDataTrait(metricRequest, "?");
if (metricRequest.getName().equals(TRAIT_DISTRO_NAME)) {
trait.setValue(LinuxDistroInfo.getInstance().getName());
} else if (metricRequest.getName().equals(TRAIT_DISTRO_VERSION)) {
trait.setValue(LinuxDistroInfo.getInstance().getVersion());
} else {
log.error("Being asked to collect an unknown Linux distro trait: " + metricRequest.getName());
}
return trait;
}
private int yumPort() {
PropertySimple p = this.resourceContext.getPluginConfiguration().getSimple("yumPort");
return ((p != null) ? p.getIntegerValue() : 9080);
}
}