/** * Copyright (c) 2009--2012 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.tree; import com.redhat.rhn.common.hibernate.HibernateFactory; import com.redhat.rhn.common.validator.ValidatorError; import com.redhat.rhn.common.validator.ValidatorException; import com.redhat.rhn.domain.channel.Channel; import com.redhat.rhn.domain.channel.ChannelFactory; import com.redhat.rhn.domain.kickstart.KickstartData; import com.redhat.rhn.domain.kickstart.KickstartFactory; import com.redhat.rhn.domain.kickstart.KickstartInstallType; import com.redhat.rhn.domain.kickstart.KickstartableTree; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.frontend.dto.PackageListItem; import com.redhat.rhn.manager.BasePersistOperation; import com.redhat.rhn.manager.kickstart.cobbler.CobblerCommand; import com.redhat.rhn.manager.kickstart.cobbler.CobblerXMLRPCHelper; import org.cobbler.Distro; import org.cobbler.XmlRpcException; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * BaseTreeEditCommand * @version $Rev$ */ public abstract class BaseTreeEditOperation extends BasePersistOperation { private static final String INVALID_INITRD = "kickstart.tree.invalidinitrd"; private static final String INVALID_KERNEL = "kickstart.tree.invalidkernel"; protected KickstartableTree tree; private static final String EMPTY_STRING = ""; public static final String KICKSTART_CAPABILITY = "rhn.kickstart.boot_image"; private String postKernelOptions = ""; private String kernelOptions = ""; /** * Constructor * @param userIn to associate with cmd. */ public BaseTreeEditOperation(User userIn) { this.user = userIn; } /** * Constructor for use when looking up by label * @param treeLabel to lookup * @param userIn who owns the tree */ public BaseTreeEditOperation(String treeLabel, User userIn) { this(userIn); this.tree = KickstartFactory. lookupKickstartTreeByLabel(treeLabel, userIn.getOrg()); } /** * {@inheritDoc} */ public ValidatorError store() { if (!this.validateLabel()) { HibernateFactory.getSession().evict(this.tree); return new ValidatorError("kickstart.tree.invalidlabel"); } try { validateBasePath(); } catch (ValidatorException ve) { return ve.getResult().getErrors().get(0); } KickstartFactory.saveKickstartableTree(this.tree); // Sync to cobbler try { CobblerCommand command = getCobblerCommand(); command.store(); Distro distro = Distro.lookupById(CobblerXMLRPCHelper.getConnection( this.getUser()), tree.getCobblerId()); Distro xenDistro = Distro.lookupById(CobblerXMLRPCHelper.getConnection( this.getUser()), tree.getCobblerXenId()); Map kOpts = distro.getKernelOptions(); distro.setKernelOptions(getKernelOptions()); distro.setKernelPostOptions(getPostKernelOptions()); distro.save(); if (xenDistro != null) { xenDistro.setKernelOptions(getKernelOptions()); xenDistro.setKernelPostOptions(getPostKernelOptions()); xenDistro.save(); } } catch (XmlRpcException xe) { HibernateFactory.rollbackTransaction(); if (xe.getCause().getMessage().contains("kernel not found")) { return new ValidatorError(INVALID_KERNEL, this.tree.getKernelPath()); } else if (xe.getCause().getMessage().contains("initrd not found")) { return new ValidatorError(INVALID_INITRD, this.tree.getInitrdPath()); } else { throw new RuntimeException(xe.getCause()); } } catch (Exception e) { HibernateFactory.rollbackTransaction(); String message = e.getMessage(); if (message != null && message.contains("kernel not found")) { return new ValidatorError(INVALID_KERNEL, this.tree.getKernelPath()); } else if (message != null && message.contains("initrd not found")) { return new ValidatorError(INVALID_INITRD, this.tree.getInitrdPath()); } else { throw new RuntimeException(e); } } return null; } /** * Validate the label to make sure: * * "The Distribution Label field should contain only letters, numbers, hyphens, * periods, and underscores. It must also be at least 4 characters long." * * @return boolean if its valid or not */ public boolean validateLabel() { String regEx = "^([-_0-9A-Za-z@.]{1,255})$"; Pattern pattern = Pattern.compile(regEx); Matcher matcher = pattern.matcher(this.getTree().getLabel()); return matcher.matches(); } /** * Ensures that the base path is correctly setup.. * As in the initrd and kernel structures are setup correctly. * @throws ValidatorException if those paths don;t exist */ public void validateBasePath() throws ValidatorException { getTree().getInitrdPath(); getTree().getKernelPath(); } /** * @return Returns the tree. */ public KickstartableTree getTree() { return tree; } /** * Set the Install type for this Kickstart * @param typeIn to set on this KickstartableTree */ public void setInstallType(KickstartInstallType typeIn) { this.tree.setInstallType(typeIn); } /** * Set the label on the tree * @param labelIn to set */ public void setLabel(String labelIn) { this.tree.setLabel(labelIn); } /** * Set the location of the tree * @param url to set. */ public void setBasePath(String url) { this.tree.setBasePath(url); } /** * Set the Channel for this tree * @param channelIn to set */ public void setChannel(Channel channelIn) { this.tree.setChannel(channelIn); } /** * Replace legacy package names with empty string for each PackageListItem * in the provided list. * @param packageListItems List of PackageListItems to be modified in place. */ private void replaceLegacyPackageNames(List packageListItems) { // munge the list of auto kickstarts for (Iterator itr = packageListItems.iterator(); itr.hasNext();) { PackageListItem pli = (PackageListItem)itr.next(); pli.setName(pli.getName().replaceFirst( KickstartData.LEGACY_KICKSTART_PACKAGE_NAME, EMPTY_STRING)); } } /** * Return all channels available for creating kickstartable trees. * @return list of channels */ public List<Channel> getKickstartableTreeChannels() { return ChannelFactory.getKickstartableTreeChannels(user.getOrg()); } /** * Get the CobblerCommand class associated with this operation. * Determines which Command we should execute when calling store() * * @return CobblerCommand instance. */ protected abstract CobblerCommand getCobblerCommand(); /** * @return Returns the postKernelOptions. */ public String getPostKernelOptions() { return postKernelOptions; } /** * @param postKernelOptionsIn The postKernelOptions to set. */ public void setPostKernelOptions(String postKernelOptionsIn) { postKernelOptions = postKernelOptionsIn; } /** * @return Returns the kernelOptions. */ public String getKernelOptions() { return kernelOptions; } /** * @param kernelOptionsIn The kernelOptions to set. */ public void setKernelOptions(String kernelOptionsIn) { kernelOptions = kernelOptionsIn; } }