/**
* 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.kickstart;
import com.redhat.rhn.common.conf.ConfigDefaults;
import com.redhat.rhn.common.db.datasource.DataResult;
import com.redhat.rhn.common.db.datasource.ModeFactory;
import com.redhat.rhn.common.db.datasource.SelectMode;
import com.redhat.rhn.common.validator.ValidatorError;
import com.redhat.rhn.domain.action.Action;
import com.redhat.rhn.domain.action.ActionFactory;
import com.redhat.rhn.domain.action.kickstart.KickstartGuestAction;
import com.redhat.rhn.domain.kickstart.KickstartData;
import com.redhat.rhn.domain.kickstart.KickstartFactory;
import com.redhat.rhn.domain.kickstart.KickstartSession;
import com.redhat.rhn.domain.kickstart.KickstartVirtualizationType;
import com.redhat.rhn.domain.server.Server;
import com.redhat.rhn.domain.user.User;
import com.redhat.rhn.frontend.dto.kickstart.KickstartDto;
import com.redhat.rhn.manager.action.ActionManager;
import com.redhat.rhn.manager.kickstart.cobbler.CobblerSystemCreateCommand;
import com.redhat.rhn.manager.kickstart.cobbler.CobblerVirtualSystemCommand;
import com.redhat.rhn.manager.kickstart.cobbler.CobblerXMLRPCHelper;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.cobbler.Profile;
import java.io.File;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.regex.Pattern;
/**
* Provides frequently used data for scheduling a kickstart
*
* @version $Rev $
*/
public class ProvisionVirtualInstanceCommand extends KickstartScheduleCommand {
private static Logger log = Logger.getLogger(ProvisionVirtualInstanceCommand.class);
public static final int MIN_NAME_SIZE = 4;
public static final int MAX_CPU = 32;
public static final String GUEST_NAME_REGEXP = "^[\\w\\-\\.\\_]+$";
private String guestName;
private Long memoryAllocation;
private Long virtualCpus;
private Long localStorage;
private String filePath;
private String virtBridge;
private String macAddress;
/**
* Constructor
* @param selectedServer server to kickstart
* @param userIn user performing the kickstart
*/
public ProvisionVirtualInstanceCommand(Long selectedServer, User userIn) {
super(selectedServer, null, (KickstartData)null, userIn, null, null);
this.setPackagesToInstall(new LinkedList());
}
/**
* Constructor to be used when you want to call the store()
* method.
*
* @param selectedServer server to kickstart
* @param ksid id of the KickstartData we are using
* @param userIn user performing the kickstart
* @param scheduleDateIn Date to schedule the KS.
* @param kickstartServerNameIn the name of the server who is kickstarting
* this machine
*/
public ProvisionVirtualInstanceCommand(Long selectedServer, Long ksid,
User userIn, Date scheduleDateIn, String kickstartServerNameIn) {
// We'll pass in the host server here, since the host server is the
// only one that exists.
this(selectedServer, KickstartFactory.
lookupKickstartDataByIdAndOrg(userIn.getOrg(), ksid),
userIn, scheduleDateIn, kickstartServerNameIn);
}
/**
* Constructor to be used when you want to call the store()
* method.
*
* @param selectedServer server to kickstart
* @param ksData the KickstartData we are using
* @param userIn user performing the kickstart
* @param scheduleDateIn Date to schedule the KS.
* @param kickstartServerNameIn the name of the server who is kickstarting
* this machine
*/
public ProvisionVirtualInstanceCommand(Long selectedServer,
KickstartData ksData,
User userIn, Date scheduleDateIn, String kickstartServerNameIn) {
// We'll pass in the host server here, since the host server is the
// only one that exists.
super(selectedServer, null, ksData, userIn, scheduleDateIn, kickstartServerNameIn);
}
/**
* Creates the Kickstart Sechdule command that works with a cobbler only
* kickstart where the host and the target may or may *not* be
* the same system. If the target system does not yet exist, selectedTargetServer
* should be null. To be used when you want to call the store() method.
*
* @param selectedServer server to host the kickstart
* @param label cobbler only profile label.
* @param userIn user performing the kickstart
* @param scheduleDateIn Date to schedule the KS.
* @param kickstartServerNameIn the name of the server who is serving the kickstart
* @return the created cobbler only profile aware kickstartScheduleCommand
*/
public static ProvisionVirtualInstanceCommand createCobblerScheduleCommand(
Long selectedServer,
String label,
User userIn,
Date scheduleDateIn,
String kickstartServerNameIn) {
ProvisionVirtualInstanceCommand cmd = new
ProvisionVirtualInstanceCommand(selectedServer,
(KickstartData) null, userIn, scheduleDateIn,
kickstartServerNameIn);
cmd.cobblerProfileLabel = label;
cmd.cobblerOnly = true;
return cmd;
}
/**
* @param prereqAction the prerequisite for this action
*
* @return Returns the rebootAction (if any) - null for virtual
* provisioning, since we don't want to reboot the host!
*/
@Override
public Action scheduleRebootAction(Action prereqAction) {
log.debug("** Skipping rebootAction - provisioning a virtual instance.");
return null;
}
@Override
protected SelectMode getMode() {
return ModeFactory.getMode("General_queries",
"virtual_kickstarts_channels_for_org");
}
@Override
protected CobblerSystemCreateCommand getCobblerSystemCreateCommand(User userIn,
Server serverIn, KickstartData ksdataIn, String mediaPath, String tokenList) {
return new CobblerVirtualSystemCommand(userIn, serverIn,
ksdataIn, mediaPath, tokenList, guestName);
}
@Override
protected CobblerSystemCreateCommand getCobblerSystemCreateCommand(User userIn,
Server serverIn, String cobblerProfileLabelIn) {
return new CobblerVirtualSystemCommand(userIn,
serverIn, cobblerProfileLabelIn);
}
/**
* @param prereqAction the prerequisite for this action
*
* @return Returns the KickstartGuestAction
*/
@Override
public Action scheduleKickstartAction(Action prereqAction) {
KickstartSession ksSession = getKickstartSession();
Long sessionId = (ksSession != null) ? ksSession.getId() : null;
//TODO -- It feels a little dirty to pass in this & this.getExtraOptions,
//but I don't know that I understand the implications of making getExtraOptions
//a public method.
KickstartGuestAction ksAction = ActionManager.scheduleKickstartGuestAction(this,
sessionId);
ksSession.setAction(ksAction);
ksAction.setPrerequisite(prereqAction);
ActionFactory.save(ksAction);
return ksAction;
}
/**
* This is a noop in the virtualization case - up2date isn't required
*
* @return Returns a ValidatorError if something goes wrong. ie, never
*/
@Override
protected ValidatorError validateUp2dateVersion() {
return null;
}
/**
* Returns the mac address
* @return the mac address
*/
public String getMacAddress() {
return this.macAddress;
}
/**
* Sets the mac address
* @param macAddressIn The mac address to set.
*/
public void setMacAddress(String macAddressIn) {
this.macAddress = macAddressIn;
}
/**
* @return Returns the guestName
*/
public String getGuestName() {
return this.guestName;
}
/**
* @param guestNameIn the guestName to set.
*/
public void setGuestName(String guestNameIn) {
this.guestName = guestNameIn;
}
/**
* @return Returns the memoryAllocation
*/
public Long getMemoryAllocation() {
return memoryAllocation;
}
/**
* @param memoryAllocationIn the memoryAllocation to set.
*/
public void setMemoryAllocation(Long memoryAllocationIn) {
this.memoryAllocation = memoryAllocationIn;
}
/**
* @return Returns the virtualCpus
*/
public Long getVirtualCpus() {
return virtualCpus;
}
/**
* @param virtualCpusIn the virtualCpus to set.
*/
public void setVirtualCpus(Long virtualCpusIn) {
this.virtualCpus = virtualCpusIn;
}
/**
* @return Returns the localStorage in GB
*/
public Long getLocalStorageSize() {
return localStorage;
}
/**
* @param localStorageIn the localStorage to set.
*/
public void setLocalStorageSize(Long localStorageIn) {
this.localStorage = localStorageIn;
}
/**
*
* {@inheritDoc}
*/
@Override
public DataResult<KickstartDto> getKickstartProfiles() {
DataResult<KickstartDto> result = super.getKickstartProfiles();
for (Iterator<KickstartDto> itr = result.iterator(); itr.hasNext();) {
KickstartDto dto = itr.next();
Profile prf = Profile.lookupById(
CobblerXMLRPCHelper.getConnection(this.getUser()), dto.getCobblerId());
if (prf != null) {
dto.setVirtBridge(prf.getVirtBridge());
dto.setVirtCpus(prf.getVirtCpus());
dto.setVirtMemory(prf.getVirtRam());
dto.setVirtSpace(prf.getVirtFileSize());
}
else {
itr.remove();
}
}
return result;
}
/**
* @return Returns the filePath.
*/
public String getFilePath() {
return filePath;
}
/**
* @param filePathIn The filePath to set.
*/
public void setFilePath(String filePathIn) {
this.filePath = filePathIn;
if (StringUtils.isBlank(filePath)) {
filePath = makeDefaultVirtPath(getGuestName(),
getKsdata().getKickstartDefaults().getVirtualizationType());
}
}
/**
* @return Returns the virtBridge.
*/
public String getVirtBridge() {
return virtBridge;
}
/**
* @param virtBridgeIn The virtBridge to set.
*/
public void setVirtBridge(String virtBridgeIn) {
this.virtBridge = virtBridgeIn;
}
/**
* Method to set up the default virt path where the guset will be stored
* based on the guest name.
* @param name the name of the guest
* @param type virtualization type to determine the virt paths
* its different for xen/kvm
* @return the virt path.
*/
public static String makeDefaultVirtPath(String name,
KickstartVirtualizationType type) {
File virtPathDir = ConfigDefaults.get().getVirtPath(
KickstartVirtualizationType.xenPV().equals(type) ||
KickstartVirtualizationType.xenFV().equals(type));
File virtPath = new File(virtPathDir, name.replace(' ', '-'));
return virtPath.getAbsolutePath();
}
/**
* {@inheritDoc}
*/
public ValidatorError doValidation() {
if (guestName.length() < MIN_NAME_SIZE) {
return new ValidatorError(
"frontend.actions.systems.virt.invalidguestnamelength",
MIN_NAME_SIZE);
}
Pattern pattern = Pattern.compile(GUEST_NAME_REGEXP, Pattern.CASE_INSENSITIVE);
if (!pattern.matcher(guestName).matches()) {
return new ValidatorError("frontend.actions.systems.virt.invalidregexp");
}
if (virtualCpus <= 0 || virtualCpus > ProvisionVirtualInstanceCommand.MAX_CPU) {
return new ValidatorError("frontend.actions.systems.virt.invalidcpuvalue",
MAX_CPU + 1);
}
return super.doValidation();
}
}