/** * Copyright (c) 2009--2015 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.domain.kickstart; import com.redhat.rhn.common.conf.ConfigDefaults; import com.redhat.rhn.common.util.StringUtil; import com.redhat.rhn.common.validator.ValidatorException; import com.redhat.rhn.domain.BaseDomainHelper; import com.redhat.rhn.domain.channel.Channel; import com.redhat.rhn.domain.org.Org; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.manager.kickstart.cobbler.CobblerCommand; import com.redhat.rhn.manager.kickstart.cobbler.CobblerXMLRPCHelper; import org.apache.commons.lang.StringUtils; import org.cobbler.CobblerConnection; import org.cobbler.Distro; import java.io.File; import java.util.Arrays; import java.util.Date; /** * KickstartableTree * @version $Rev$ */ public class KickstartableTree extends BaseDomainHelper { private static final String INVALID_INITRD = "kickstart.tree.invalidinitrd"; private static final String INVALID_KERNEL = "kickstart.tree.invalidkernel"; private String basePath; private Channel channel; private Long id; private KickstartInstallType installType; private String label; private Date lastModified; private String cobblerId; private String cobblerXenId; private Org org; private KickstartTreeType treeType; /** * @return Returns the basePath. */ public String getBasePath() { return basePath; } /** * @param b The basePath to set. */ public void setBasePath(String b) { this.basePath = b; } /** * @return Returns the channel. */ public Channel getChannel() { return channel; } /** * @param c The channel to set. */ public void setChannel(Channel c) { this.channel = c; } /** * @return Returns the id. */ public Long getId() { return id; } /** * @param i The id to set. */ public void setId(Long i) { this.id = i; } /** * @return Returns the installType. */ public KickstartInstallType getInstallType() { return installType; } /** * @param i The installType to set. */ public void setInstallType(KickstartInstallType i) { this.installType = i; } /** * @return Returns the label. */ public String getLabel() { return label; } /** * @param l The label to set. */ public void setLabel(String l) { this.label = l; } /** * @return Returns the lastModified. */ public Date getLastModified() { return lastModified; } /** * @param l The lastModified to set. */ public void setLastModified(Date l) { this.lastModified = l; } /** * @return Returns the orgId. */ public Long getOrgId() { if (isRhnTree()) { return null; } return getOrg().getId(); } /** * @return Returns the org. */ public Org getOrg() { return org; } /** * @param o The org to set. */ public void setOrg(Org o) { this.org = o; } /** * @return Returns the treeType. */ public KickstartTreeType getTreeType() { return treeType; } /** * @param t The treeType to set. */ public void setTreeType(KickstartTreeType t) { this.treeType = t; } /** * Check to see if this tree is 'owned' by RHN. * @return boolean if this tree is owned or not by RHN */ public boolean isRhnTree() { return this.org == null; } /** * Get the default download location for this KickstartableTree. * * eg: /rhn/kickstart/ks-rhel-i386-as-4 * * NOTE: the default path does not include a host. * We append the host if it starts with a '/' * * @return String url */ public String getDefaultDownloadLocation() { if (this.getBasePath() != null) { if (basePathIsUrl()) { return this.getBasePath(); } String defaultLocation = "/ks/dist/"; if (this.getOrg() != null) { defaultLocation += "org/" + this.getOrgId() + "/"; } defaultLocation += this.getLabel(); return defaultLocation; } return ""; } /** * Check if the tree's base path is a fully qualified URL or just a relative path. * * @return True if base path is a URL. */ public boolean basePathIsUrl() { String defaultLocation = this.getBasePath().toLowerCase(); return (defaultLocation.startsWith("http://") || defaultLocation.startsWith("ftp://")); } /** * @return the cobblerDistroName */ public String getCobblerDistroName() { return CobblerCommand.makeCobblerName(getLabel(), getOrg()); } /** * @return the cobblerDistroName */ public String getCobblerXenDistroName() { String sep = ConfigDefaults.get().getCobblerNameSeparator(); return CobblerCommand.makeCobblerName(getLabel() + sep + "xen", getOrg()); } /** * Basically returns the actual basepath * we need this method because the * database stores rhn/.... as basepath for redhat channels * and actual path for non redhat channels... * @return the actual basepath. */ public String getAbsolutePath() { if (isRhnTree()) { //redhat channel append the mount point to //base path... return ConfigDefaults.get().getKickstartMountPoint() + getBasePath(); } //its a base channel return the return getBasePath(); } /** * Returns default kernel path * @return default kernel path */ public String getDefaultKernelPath() { String arch = this.getChannel().getChannelArch().getLabel(); if (arch.equals("channel-s390") || arch.endsWith("channel-s390x")) { return StringUtil.addPath(getAbsolutePath(), "/images/kernel.img"); } else if (arch.startsWith("channel-ppc")) { return StringUtil.addPath(getAbsolutePath(), "/ppc/ppc64/vmlinuz"); } else if (this.installType.isSUSE()) { return StringUtil.addPath(getAbsolutePath(), "/boot/" + this.getChannel().getChannelArch().getName() + "/loader/linux"); } else { return StringUtil.addPath(getAbsolutePath(), "/images/pxeboot/vmlinuz"); } } /** * Returns valid kernel path or throws an exception * @return valid kernel path */ public String getKernelPath() { String defaultPath = getDefaultKernelPath(); if (pathExists(defaultPath)) { return defaultPath; } ValidatorException.raiseException(INVALID_KERNEL, defaultPath); // we'll never get here, just a compiler required line return ""; } /** * Returns default initrd paths * @return default initrd paths */ public String[] getDefaultInitrdPath() { String arch = this.getChannel().getChannelArch().getLabel(); if (arch.equals("channel-s390") || arch.endsWith("channel-s390x")) { return new String[] { StringUtil.addPath(getAbsolutePath(), "/images/initrd.img")}; } else if (arch.startsWith("channel-ppc")) { return new String[] { StringUtil.addPath(getAbsolutePath(), "/ppc/ppc64/ramdisk.image.gz"), StringUtil.addPath(getAbsolutePath(), "/ppc/ppc64/initrd.img")}; } else if (this.installType.isSUSE()) { return new String[] {StringUtil.addPath(getAbsolutePath(), "/boot/" + this.getChannel().getChannelArch().getName() + "/loader/initrd")}; } else { return new String[] { StringUtil.addPath(getAbsolutePath(), "/images/pxeboot/initrd.img")}; } } /** * Returns valid Initrd path or throws an exception * @return the Initrd path */ public String getInitrdPath() { String[] defaultPaths = getDefaultInitrdPath(); for (String initrdPath : defaultPaths) { if (pathExists(initrdPath)) { return initrdPath; } } ValidatorException.raiseException(INVALID_INITRD, StringUtil.join(", ", Arrays.asList(defaultPaths))); // we'll never get here, just a compiler required line return ""; } /** * Returns the kernel path for the xen kernel * includes the mount point * its an absolute path. * @return the kernel path */ public String getKernelXenPath() { return StringUtil.addPath(getAbsolutePath(), "/images/xen/vmlinuz"); } /** * Returns the Initrd path for the xen kernel * includes the mount point * its an absolute path. * @return the Initrd path */ public String getInitrdXenPath() { return StringUtil.addPath(getAbsolutePath(), "/images/xen/initrd.img"); } /** * @return Returns the cobblerId. */ public String getCobblerId() { return cobblerId; } /** * @param cobblerIdIn The cobblerId to set. */ public void setCobblerId(String cobblerIdIn) { this.cobblerId = cobblerIdIn; } /** * Gets the cobblerXenId, which is the cobbler id corresponding to the * cobbler distro that is pointing to Xen PV boot images instead of regular * boot images (yes this sucks) * @return Returns the cobblerXenId. */ public String getCobblerXenId() { return cobblerXenId; } /** * @param cobblerXenIdIn The cobblerXenId to set. */ public void setCobblerXenId(String cobblerXenIdIn) { this.cobblerXenId = cobblerXenIdIn; } /** * Check to see if the selected tree support xen paravirt * @return true if it can, false otherwise */ public boolean doesParaVirt() { File kernel = new File(this.getKernelXenPath()); return kernel.exists(); } /** * Returns the cobbler object associated to * to this tree. * @param user the user object needed for connection, * enter null if you want to use the * automated connection as provided by * taskomatic. * @return the Distro associated to this tree */ public Distro getCobblerObject(User user) { if (StringUtils.isBlank(getCobblerId())) { return null; } CobblerConnection con; if (user == null) { con = CobblerXMLRPCHelper.getAutomatedConnection(); } else { con = CobblerXMLRPCHelper.getConnection(user); } return Distro.lookupById(con, getCobblerId()); } private boolean pathExists(String path) { return new File(path).exists(); } /** * Returns true if both the kernel path and initrd paths exist * and cobbler id is not null for this distribution. * @return true if this is a valid distro. */ public boolean isValid() { return !StringUtils.isBlank(getCobblerId()) && isPathsValid(); } /** * are the paths valid for kernel and initrd * @return true if valid */ public boolean isPathsValid() { try { getInitrdPath(); getKernelPath(); return true; } catch (ValidatorException e) { return false; } } }