/**
* Copyright (c) 2009--2014 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package com.redhat.rhn.manager.satellite;
import com.redhat.rhn.common.conf.Config;
import com.redhat.rhn.common.conf.ConfigDefaults;
import com.redhat.rhn.common.validator.ValidatorError;
import com.redhat.rhn.domain.user.User;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
/**
* ConfigureSatelliteCommand
* @version $Rev$
*/
public class ConfigureSatelliteCommand extends BaseConfigureCommand
implements SatelliteConfigurator {
/**
* Logger for this class
*/
private static Logger logger = Logger.
getLogger(ConfigureSatelliteCommand.class);
private final List<String> keysToBeUpdated;
/**
* Create a new ConfigureSatelliteCommand class with the
* user requesting the config.
* @param userIn who wants to config the sat.
*/
public ConfigureSatelliteCommand(User userIn) {
super(userIn);
this.keysToBeUpdated = new LinkedList<String>();
}
/**
* Get the formatted String array of command line arguments to execute
* when we call out to the system utility to store the config.
* @param configFilePath path to config file to update
* @param optionMap Map of key/value pairs to update local config with.
* @param removals List of keys that will be removed
* Note that they have preference over the updated keys
* @return String[] array of arguments.
*/
public String[] getCommandArguments(String configFilePath,
Map<String, String> optionMap, List<String> removals) {
boolean anythingChanged = false;
if (logger.isDebugEnabled()) {
logger.debug("getCommandArguments(String configFilePath=" +
configFilePath + ", Iterator keyIterator=" + optionMap +
") - start");
}
List<String> argList = new LinkedList<String>();
argList.add("/usr/bin/sudo");
argList.add("/usr/bin/rhn-config-satellite.pl");
argList.add("--target=" + configFilePath);
for (String key : optionMap.keySet()) {
StringBuilder sb = new StringBuilder();
sb.append("--option=");
sb.append(key);
sb.append("=");
String val = optionMap.get(key);
// We don't want to put the actual string 'null'
// in rhn.conf. See bz: 189600
if (StringUtils.isEmpty(val)) {
sb.append("");
}
else {
sb.append(val);
}
argList.add(sb.toString());
anythingChanged = true;
}
for (String key : removals) {
StringBuilder sb = new StringBuilder();
sb.append("--remove=");
sb.append(key);
argList.add(sb.toString());
anythingChanged = true;
}
argList.add("2>&1");
argList.add(">");
argList.add("/dev/null");
String[] returnStringArray = argList.toArray(new String[0]);
if (logger.isDebugEnabled()) {
logger.debug("getCommandArguments(String, Iterator) - end - return value=" +
returnStringArray);
}
return (anythingChanged ? returnStringArray : null);
}
/**
* Get the formatted String array of command line arguments to execute
* when we call out to the system utility to store the config.
* @return String[] array of arguments.
*/
public String[] getCommandArguments() {
Map<String, String> optionMap = new HashMap<String, String>();
List<String> removals = new LinkedList<String>();
for (String key : getKeysToBeUpdated()) {
if (Config.get().containsKey(key)) {
optionMap.put(key, Config.get().getString(key));
}
else {
removals.add(key);
}
}
return getCommandArguments(Config.getDefaultConfigFilePath(),
optionMap, removals);
}
/**
* Store the Configuration to the filesystem
* @return ValidatorError
*/
public ValidatorError[] storeConfiguration() {
if (logger.isDebugEnabled()) {
logger.debug("storeConfiguration() - start");
}
Executor e = getExecutor();
if (keysToBeUpdated.contains(ConfigDefaults.JABBER_SERVER)) {
// if hostname changes, we must update
// osa-dispatcher.server_jabber as well
this.updateString("osa-dispatcher.jabber_server",
ConfigDefaults.get().getHostname());
}
if (keysToBeUpdated.contains(ConfigDefaults.MOUNT_POINT)) {
this.updateString(ConfigDefaults.KICKSTART_MOUNT_POINT,
Config.get().getString(ConfigDefaults.MOUNT_POINT));
}
if (keysToBeUpdated.contains(ConfigDefaults.DISCONNECTED) &&
!Config.get().getBoolean(ConfigDefaults.DISCONNECTED)) {
//if there isn't already a value set for the satellite parent (We don't want to
// overwrite a custom value.)
if (Config.get().getString(ConfigDefaults.SATELLITE_PARENT) == null ||
Config.get().getString(ConfigDefaults.SATELLITE_PARENT).length() == 0) {
this.updateString(ConfigDefaults.SATELLITE_PARENT,
ConfigDefaults.DEFAULT_SAT_PARENT);
}
}
String[] commandArguments = getCommandArguments();
if (commandArguments != null) {
int exitcode = e.execute(commandArguments);
if (exitcode != 0) {
ValidatorError[] retval = new ValidatorError[1];
retval[0] = new ValidatorError("config.storeconfig.error",
Integer.toString(exitcode));
if (logger.isDebugEnabled()) {
logger.debug("storeConfiguration() - end - return value=" + retval);
}
return retval;
}
}
this.keysToBeUpdated.clear();
if (logger.isDebugEnabled()) {
logger.debug("storeConfiguration() - end - return value=" + null);
}
return null;
}
/**
* Update a configuration value for this satellite. This tracks
* the values that are actually changed.
* @param configKey key to the Config value you want to set
* @param newValue you want to set
*/
public void updateBoolean(String configKey, Boolean newValue) {
if (logger.isDebugEnabled()) {
logger.debug("updateBoolean(String configKey=" + configKey +
", Boolean newValue=" + newValue + ") - start");
}
if (newValue == null) {
// If its true we are changing the value
if (Config.get().getBoolean(configKey)) {
Config.get().setBoolean(configKey, Boolean.FALSE.toString());
keysToBeUpdated.add(configKey);
}
}
else {
if (Config.get().getBoolean(configKey) != newValue.booleanValue()) {
Config.get().setBoolean(configKey, newValue.toString());
keysToBeUpdated.add(configKey);
}
}
if (logger.isDebugEnabled()) {
logger.debug("updateBoolean(String, Boolean) - end");
}
}
/**
* Update a String config
* @param configKey to the value
* @param newValue to set
*/
public void updateString(String configKey, String newValue) {
if (logger.isDebugEnabled()) {
logger.debug("updateString(String configKey=" + configKey +
", String newValue=" + newValue + ") - start");
}
if (Config.get().getString(configKey) == null ||
!Config.get().getString(configKey).equals(newValue)) {
keysToBeUpdated.add(configKey);
Config.get().setString(configKey, newValue);
}
if (logger.isDebugEnabled()) {
logger.debug("updateString(String, String) - end");
}
}
/**
* Remove a configuration entry
* @param configKey to the value
*/
public void remove(String configKey) {
if (logger.isDebugEnabled()) {
logger.debug("remove(String configKey=" + configKey + ") - start");
}
if (Config.get().getString(configKey) != null) {
keysToBeUpdated.add(configKey);
Config.get().remove(configKey);
}
if (logger.isDebugEnabled()) {
logger.debug("remove(String) - end");
}
}
/**
* Get the list of configuration values that need to be written out
* to the persistence mechanism.
* @return List of String values of to the keys to be written.
*/
public List<String> getKeysToBeUpdated() {
return keysToBeUpdated;
}
/**
* Clear the set of configuration changes from the Command.
*/
public void clearUpdates() {
if (logger.isDebugEnabled()) {
logger.debug("clearUpdates() - start");
}
this.keysToBeUpdated.clear();
if (logger.isDebugEnabled()) {
logger.debug("clearUpdates() - end");
}
}
}