/** * Copyright (c) 2013 SUSE LLC * * 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.kickstart.cobbler; import com.redhat.rhn.common.validator.ValidatorError; import com.redhat.rhn.domain.server.Server; import com.redhat.rhn.domain.user.User; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.cobbler.CobblerConnection; import org.cobbler.Image; import org.cobbler.SystemRecord; import org.cobbler.XmlRpcException; import java.io.IOException; /** * Changes power management settings for a server. */ public class CobblerPowerSettingsUpdateCommand extends CobblerCommand { /** * Name of the dummy image that can be created to use power management on * systems that do not have an existing Cobbler profile. */ public static final String POWER_MANAGEMENT_DUMMY_NAME = "dummy_for_power_management"; /** The log. */ private static Logger log = Logger.getLogger(CobblerPowerSettingsUpdateCommand.class); /** The server to update. */ private Server server; /** The new power management scheme. */ private String powerType; /** The new power management IP address or hostname. */ private String powerAddress; /** The new power management username. */ private String powerUsername; /** The new power management password. */ private String powerPassword; /** The new power management id. */ private String powerId; /** * Standard constructor. Empty parameters strings can be used to leave * existing values untouched. * @param userIn the user running this command * @param serverIn the server to update * @param powerTypeIn the new power management scheme * @param powerAddressIn the new power management IP address or hostname * @param powerUsernameIn the new power management username * @param powerPasswordIn the new power management password * @param powerIdIn the new power management id */ public CobblerPowerSettingsUpdateCommand(User userIn, Server serverIn, String powerTypeIn, String powerAddressIn, String powerUsernameIn, String powerPasswordIn, String powerIdIn) { super(userIn); server = serverIn; powerType = powerTypeIn; powerAddress = powerAddressIn; powerUsername = powerUsernameIn; powerPassword = powerPasswordIn; powerId = powerIdIn; } /** * Clears server's power settings * @return any errors */ public ValidatorError removeSystemProfile() { Long sid = server.getId(); SystemRecord systemRecord = getSystemRecordForSystem(); if (systemRecord != null) { systemRecord.remove(); log.debug("Cobbler system profile removed for system " + sid); } return null; } private SystemRecord getSystemRecordForSystem() { CobblerConnection connection = getCobblerConnection(); SystemRecord systemRecord = null; // is there an existing record? if so, use it String cobblerId = server.getCobblerId(); if (!StringUtils.isEmpty(cobblerId)) { systemRecord = SystemRecord.lookupById(connection, cobblerId); } return systemRecord; } /** * Updates a server's power settings. Creates a Cobbler system profile if it * does not exist. * @return any errors */ @Override public ValidatorError store() { Long sid = server.getId(); SystemRecord systemRecord = getSystemRecordForSystem(); if (systemRecord == null) { log.debug("No Cobbler system record found for system " + sid); try { CobblerConnection connection = getCobblerConnection(); Image image = createDummyImage(connection); systemRecord = SystemRecord.create(connection, CobblerSystemCreateCommand.getCobblerSystemRecordName(server), image); systemRecord.enableNetboot(false); server.setCobblerId(systemRecord.getId()); } catch (IOException e) { log.error("Could not create temporary file for Cobbler image"); return new ValidatorError("kickstart.powermanagement.cannot_create_file"); } } try { log.debug("Setting Cobbler parameters for system " + sid); if (powerType != null && !powerType.equals("") && !powerType.equals(systemRecord.getPowerType())) { systemRecord.setPowerType(powerType); } if (powerAddress != null && !powerAddress.equals(systemRecord.getPowerAddress())) { systemRecord.setPowerAddress(powerAddress); } if (powerUsername != null && !powerUsername.equals(systemRecord.getPowerUsername())) { systemRecord.setPowerUsername(powerUsername); } if (powerPassword != null && !powerPassword.equals(systemRecord.getPowerPassword())) { systemRecord.setPowerPassword(powerPassword); } if (powerId != null && !powerId.equals(systemRecord.getPowerId())) { systemRecord.setPowerId(powerId); } systemRecord.save(); log.debug("Settings saved for system " + sid); } catch (XmlRpcException e) { Throwable cause = e.getCause(); if (cause != null) { String message = cause.getMessage(); if (message != null && message.contains("power type must be one of")) { log.error("Unsupported Cobbler power type " + powerType); return new ValidatorError( "kickstart.powermanagement.unsupported_power_type"); } if (message != null && message.contains( "Invalid characters found in input")) { log.error(message); return new ValidatorError("kickstart.powermanagement.invalid_chars"); } } throw e; } return null; } /** * HACK: create a dummy image to be able to add non-netbooting system * profile to Cobbler in case one has not already been defined for * Kickstart. That is, support Cobbler power management features even with * systems that do not need PXE booting. * @param connection the connection * @return the image * @throws IOException Signals that an I/O exception has occurred. */ private Image createDummyImage(CobblerConnection connection) throws IOException { Image image = Image.lookupByName(connection, POWER_MANAGEMENT_DUMMY_NAME); if (image == null) { log.debug("Creating Cobbler dummy image"); // any existing readable filename is accepted by Cobbler String tempFile = "/dev/null"; image = Image.create(connection, POWER_MANAGEMENT_DUMMY_NAME, Image.TYPE_ISO, tempFile); image.save(); log.debug("Cobbler dummy image saved"); } return image; } }