/** * 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.domain.kickstart; import com.redhat.rhn.common.conf.ConfigDefaults; import com.redhat.rhn.common.hibernate.HibernateFactory; import com.redhat.rhn.common.util.MD5Crypt; import com.redhat.rhn.common.util.SHA256Crypt; import com.redhat.rhn.common.util.StringUtil; import com.redhat.rhn.domain.channel.Channel; import com.redhat.rhn.domain.common.FileList; import com.redhat.rhn.domain.kickstart.crypto.CryptoKey; import com.redhat.rhn.domain.org.Org; import com.redhat.rhn.domain.rhnpackage.PackageName; import com.redhat.rhn.domain.token.ActivationKey; import com.redhat.rhn.domain.token.ActivationKeyFactory; import com.redhat.rhn.domain.token.Token; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.frontend.action.kickstart.KickstartTreeUpdateType; import com.redhat.rhn.manager.kickstart.KickstartFormatter; import com.redhat.rhn.manager.kickstart.cobbler.CobblerCommand; import com.redhat.rhn.manager.kickstart.cobbler.CobblerXMLRPCHelper; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.cobbler.CobblerConnection; import org.cobbler.Profile; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * KickstartData - Class representation of the table RhnKSData. * @version $Rev: 1 $ */ public class KickstartData { private Long id; protected String kickstartType; private Org org; private String label; private String comments; private Boolean active; private Boolean postLog; private Boolean preLog; private Boolean ksCfg; private Date created; private Date modified; private boolean isOrgDefault; private String kernelParams; private Boolean nonChrootPost; private Boolean verboseUp2date; private String cobblerId; private byte[] partitionData; private Set<CryptoKey> cryptoKeys; private Set<Channel> childChannels; private Set<Token> defaultRegTokens; private Set<FileList> preserveFileLists; private Set<KickstartPackage> ksPackages = new HashSet<KickstartPackage>(); private Collection<KickstartCommand> commands = new LinkedHashSet<KickstartCommand>(); private Set<KickstartIpRange> ips; // rhnKickstartIpRange private Set<KickstartScript> scripts; // rhnKickstartScript private KickstartDefaults kickstartDefaults; private boolean noBase; private boolean ignoreMissing; private String updateType; private static final Pattern URL_REGEX = Pattern.compile("--url\\s*(\\S+)", Pattern.CASE_INSENSITIVE); public static final String LEGACY_KICKSTART_PACKAGE_NAME = "auto-kickstart-"; public static final String WIZARD_DIR = "wizard"; public static final String RAW_DIR = "upload"; public static final String SELINUX_MODE_COMMAND = "selinux"; public static final String TYPE_WIZARD = "wizard"; public static final String TYPE_RAW = "raw"; private static String[] advancedOptions = {"partitions", "raids", "logvols", "volgroups", "include", "repo", "custom", "custom_partition"}; private static final List<String> ADANCED_OPTIONS = Arrays.asList(advancedOptions); /** * Initializes properties. */ public KickstartData() { cryptoKeys = new HashSet<CryptoKey>(); defaultRegTokens = new HashSet<Token>(); preserveFileLists = new HashSet<FileList>(); ksPackages = new TreeSet<KickstartPackage>(); commands = new LinkedHashSet<KickstartCommand>(); ips = new HashSet<KickstartIpRange>(); scripts = new HashSet<KickstartScript>(); postLog = false; preLog = false; ksCfg = false; verboseUp2date = false; nonChrootPost = false; childChannels = new HashSet<Channel>(); kickstartType = TYPE_WIZARD; noBase = false; ignoreMissing = false; setUpdateType(KickstartTreeUpdateType.NONE.getType()); } /** * Logger for this class */ private static Logger logger = Logger .getLogger(KickstartData.class); /** * Getter for id * @return Long to get */ public Long getId() { return this.id; } /** * Setter for id * @param idIn to set */ public void setId(Long idIn) { this.id = idIn; } /** * Associates the KS with an Org. * @param orgIn Org to be associated to this KS. */ public void setOrg(Org orgIn) { org = orgIn; } /** * Getter for org * @return org to get */ public Org getOrg() { return org; } /** * Getter for label * @return String to get */ public String getLabel() { return this.label; } /** * Setter for label * @param labelIn to set */ public void setLabel(String labelIn) { this.label = labelIn; } /** * Getter for comments * @return String to get */ public String getComments() { return this.comments; } /** * Setter for comments * @param commentsIn to set */ public void setComments(String commentsIn) { this.comments = commentsIn; } /** * Getter for active * @return String to get */ public Boolean isActive() { return this.active; } /** * Getter for active * @return String to get */ public boolean getActive() { return isActive(); } /** * Setter for active * @param activeIn to set */ public void setActive(Boolean activeIn) { this.active = activeIn; } /** * Getter for created * @return Date to get */ public Date getCreated() { return this.created; } /** * Setter for created * @param createdIn to set */ public void setCreated(Date createdIn) { this.created = createdIn; } /** * Getter for modified * @return Date to get */ public Date getModified() { return this.modified; } /** * Setter for modified * @param modifiedIn to set */ public void setModified(Date modifiedIn) { this.modified = modifiedIn; } /** * Getter for isOrgDefault * @return String to get */ public Boolean isOrgDefault() { return getIsOrgDefault(); } /** * Getter for isOrgDefault * @return String to get */ protected boolean getIsOrgDefault() { return this.isOrgDefault; } /** * Setter for isOrgDefault * @param isDefault to set */ protected void setIsOrgDefault(boolean isDefault) { this.isOrgDefault = isDefault; } /** * Setter for isOrgDefault * @param isDefault to set */ public void setOrgDefault(boolean isDefault) { // We actually want to set the orgdefault if (!isOrgDefault() && isDefault) { KickstartData existingDefault = KickstartFactory. lookupOrgDefault(getOrg()); if (existingDefault != null) { existingDefault.setIsOrgDefault(Boolean.FALSE); KickstartFactory.saveKickstartData(existingDefault); } } setIsOrgDefault(isDefault); } /** * Getter for kernelParams * @return String to get */ public String getKernelParams() { return this.kernelParams; } /** * Setter for kernelParams * @param kernelParamsIn to set */ public void setKernelParams(String kernelParamsIn) { this.kernelParams = kernelParamsIn; } /** * @return the cryptoKeys */ public Set<CryptoKey> getCryptoKeys() { return cryptoKeys; } /** * @param cryptoKeysIn The cryptoKeys to set. */ public void setCryptoKeys(Set<CryptoKey> cryptoKeysIn) { this.cryptoKeys = cryptoKeysIn; } /** * Add a CryptoKey to this kickstart * @param key to add */ public void addCryptoKey(CryptoKey key) { this.cryptoKeys.add(key); } /** * Remove a crypto key from the set. * @param key to remove. */ public void removeCryptoKey(CryptoKey key) { this.cryptoKeys.remove(key); } /** * @return the childChannels */ public Set<Channel> getChildChannels() { return childChannels; } /** * @param childChannelsIn childChannels to set. */ public void setChildChannels(Set<Channel> childChannelsIn) { this.childChannels = childChannelsIn; } /** * Add a ChildChannel to this kickstart * @param childChnl to add */ public void addChildChannel(Channel childChnl) { if (this.childChannels == null) { this.childChannels = new HashSet<Channel>(); } this.childChannels.add(childChnl); } /** * Remove a child Channel from the set. * @param childChnl to remove. */ public void removeChildChannel(Channel childChnl) { this.childChannels.remove(childChnl); } /** * Adds an Token object to default. * Note that an ActivationKey is almost the same as a Token. Sorry. * @param key Token to add */ public void addDefaultRegToken(Token key) { defaultRegTokens.add(key); } /** * Getter for defaultRegTokens * @return Returns the packageLists. */ public Set<Token> getDefaultRegTokens() { return defaultRegTokens; } /** * Setter for defaultRegTokens * @param p The packageLists to set. */ public void setDefaultRegTokens(Set<Token> p) { this.defaultRegTokens = p; } /** * Gets the value of preserveFileLists * * @return the value of preserveFileLists */ public Set<FileList> getPreserveFileLists() { return this.preserveFileLists; } /** * Sets the value of preserveFileLists * * @param preserveFileListsIn set of FileList objects to assign to * this.preserveFileLists */ public void setPreserveFileLists(Set<FileList> preserveFileListsIn) { this.preserveFileLists = preserveFileListsIn; } /** * Adds a PreserveFileList object to preserveFileLists * @param fileList preserveFileList to add */ public void addPreserveFileList(FileList fileList) { preserveFileLists.add(fileList); } /** * Remove a file list from the set. * @param fileList to remove. */ public void removePreserveFileList(FileList fileList) { this.preserveFileLists.remove(fileList); } /** * Adds a KickstartPackage object to ksPackages. * @param kp KickstartPackage to add */ public void addKsPackage(KickstartPackage kp) { kp.setPosition((long)ksPackages.size()); if (this.ksPackages.add(kp)) { // save to collection KickstartFactory.savePackage(kp); // save to DB } } /** * Removes a KickstartPackage object from ksPackages. * @param kp KickstartPackage to remove */ public void removeKsPackage(KickstartPackage kp) { this.ksPackages.remove(kp); } /** * Getter for ksPackages * @return Returns the ksPackages. */ public Set<KickstartPackage> getKsPackages() { return ksPackages; } /** * Setter for ksPackages * @param p The KickstartPackage set to set. */ public void setKsPackages(Set<KickstartPackage> p) { this.ksPackages = p; } /** * Clear all ksPackages */ public void clearKsPackages() { for (Iterator<KickstartPackage> iter = ksPackages.iterator(); iter.hasNext();) { // remove from DB KickstartFactory.removePackage(iter.next()); // remove from collection iter.remove(); } } /** * * @param pName Package name to check if Kickstart Data contains * @return if package name is in this kickstart data */ public boolean hasKsPackage(PackageName pName) { for (KickstartPackage pack : ksPackages) { if (pName.equals(pack.getPackageName())) { return true; } } return false; } /** * Get the KickstartScript of type "pre" * @return KickstartScript used by the Pre section. Null if not used */ public KickstartScript getPreKickstartScript() { return lookupScriptByType(KickstartScript.TYPE_PRE); } /** * Get the KickstartScript of type "post" * @return KickstartScript used by the post section. Null if not used */ public KickstartScript getPostKickstartScript() { return lookupScriptByType(KickstartScript.TYPE_POST); } private KickstartScript lookupScriptByType(String typeIn) { if (this.getScripts() != null && this.getScripts().size() > 0) { Iterator<KickstartScript> i = this.getScripts().iterator(); while (i.hasNext()) { KickstartScript kss = i.next(); if (kss.getScriptType().equals(typeIn)) { return kss; } } } return null; } /** * Getter for commands * @return Returns commands */ public Collection<KickstartCommand> getCommands() { return this.commands; } /** * Convenience method to detect if command is set * @param commandName Command name * @return true if found, otherwise false */ public boolean hasCommand(String commandName) { boolean retval = false; if (this.commands != null && this.commands.size() > 0) { for (Iterator<KickstartCommand> iter = this.commands.iterator(); iter.hasNext();) { KickstartCommand cmd = iter.next(); if (cmd.getCommandName().getName().equals(label)) { retval = true; break; } } } return retval; } /** * Convenience method to remove commands by name * @param commandName Command name * @param removeFirst if true only stop at first instance, otherwise remove all */ public void removeCommand(String commandName, boolean removeFirst) { if (this.commands != null && this.commands.size() > 0) { for (Iterator<KickstartCommand> iter = this.commands.iterator(); iter.hasNext();) { KickstartCommand cmd = iter.next(); if (cmd.getCommandName().getName().equals(commandName)) { iter.remove(); if (removeFirst) { break; } } } } } /** * Convenience method to find a command by name stopping at the first match * @param commandName Command name * @return command if found, otherwise null */ public KickstartCommand getCommand(String commandName) { KickstartCommand retval = null; if (this.commands != null && this.commands.size() > 0) { for (Iterator<KickstartCommand> iter = this.commands.iterator(); iter.hasNext();) { KickstartCommand cmd = iter.next(); if (cmd.getCommandName().getName().equals(commandName)) { retval = cmd; break; } } } return retval; } /** * Setter for commands * @param c The Command List to set. */ public void setCommands(Collection<KickstartCommand> c) { this.commands = c; } /** * Convenience method to remove all commands */ public void removeCommands() { if (this.commands != null && this.commands.size() > 0) { this.commands.clear(); } } private Set<KickstartCommand> getCommandSubset(String name) { Set<KickstartCommand> retval = new LinkedHashSet<KickstartCommand>(); if (this.commands != null && this.commands.size() > 0) { for (Iterator<KickstartCommand> iter = this.commands.iterator(); iter.hasNext();) { KickstartCommand cmd = iter.next(); logger.debug("getCommandSubset : working with: " + cmd.getCommandName().getName()); if (cmd.getCommandName().getName().equals(name)) { logger.debug("getCommandSubset : name equals, returning"); retval.add(cmd); } } } logger.debug("getCommandSubset : returning: " + retval); return Collections.unmodifiableSet(retval); } /** * @return Returns the repos. */ public Set <KickstartCommand> getRepos() { return getCommandSubset("repo"); } /** * Updates the repos commands associated to this ks data. * @param repoCommands the repos to update */ public void setRepos(Collection<KickstartCommand> repoCommands) { replaceSet(getRepos(), repoCommands); } /** * @return Returns the repos. */ public Set<RepoInfo> getRepoInfos() { Set <KickstartCommand> repoCommands = getRepos(); Set <RepoInfo> info = new HashSet<RepoInfo>(); for (KickstartCommand cmd : repoCommands) { info.add(RepoInfo.parse(cmd)); } return info; } /** * Updates the repos commands associated to this ks data. * @param repos the repos to update **/ public void setRepoInfos(Collection<RepoInfo> repos) { Set <KickstartCommand> repoCommands = new HashSet<KickstartCommand>(); for (RepoInfo repo : repos) { KickstartCommand cmd = KickstartFactory.createKickstartCommand(this, "repo"); repo.setArgumentsIn(cmd); repoCommands.add(cmd); } setRepos(repoCommands); } /** * @return Returns the customOptions. */ public LinkedHashSet<KickstartCommand> getCustomOptions() { return new LinkedHashSet<KickstartCommand>(getCommandSubset("custom")); } /** * remove old custom options and replace with new * @param customIn to replace old with. */ public void setCustomOptions(Collection<KickstartCommand> customIn) { replaceSet(this.getCustomOptions(), customIn); } /** * remove old options and replace with new * @param optionsIn to replace old with. */ public void setOptions(Collection<KickstartCommand> optionsIn) { replaceSet(this.getOptions(), optionsIn); } private void replaceSet(Collection<KickstartCommand> oldSet, Collection<KickstartCommand> newSet) { logger.debug("replaceSet co.pre: " + this.getCustomOptions()); this.commands.removeAll(oldSet); logger.debug("replaceSet co.post: " + this.getCustomOptions()); this.commands.addAll(newSet); logger.debug("replaceSet co.done: " + this.getCustomOptions()); } /** * Getter for command options * @return Returns Kickstartcommand options */ public Set<KickstartCommand> getOptions() { // 'partitions', 'raids', 'logvols', 'volgroups', 'include', 'repo', 'custom' logger.debug("returning all commands except: " + ADANCED_OPTIONS); Set<KickstartCommand> retval = new HashSet<KickstartCommand>(); if (this.commands != null && this.commands.size() > 0) { for (Iterator<KickstartCommand> iter = this.commands.iterator(); iter.hasNext();) { KickstartCommand cmd = iter.next(); logger.debug("working with: " + cmd.getCommandName().getName()); if (!ADANCED_OPTIONS.contains(cmd.getCommandName().getName())) { logger.debug("not contained within filtered list. adding to retval"); retval.add(cmd); } } } logger.debug("returning: " + retval); return Collections.unmodifiableSet(retval); } /** * @return the download url suffix */ public String getUrl() { for (KickstartCommand c : getOptions()) { String a = c.getArguments(); if (c.getCommandName().getName().equals("url") && a != null) { Matcher match = URL_REGEX.matcher(a); if (match.find()) { return match.group(1); } } } return ""; } /** * * @param kd KickstartDefaults to set */ public void setKickstartDefaults(KickstartDefaults kd) { this.kickstartDefaults = kd; } /** * * @return the Kickstart Defaults assoc w/this Kickstart */ public KickstartDefaults getKickstartDefaults() { return this.kickstartDefaults; } /** * Conv method * @return Install Type for Kickstart */ public KickstartInstallType getInstallType() { if (this.getTree() != null) { return getTree().getInstallType(); } return null; } /** * @return if this kickstart profile is rhel installer type */ public boolean isRhel() { if (getInstallType() != null) { return getInstallType().isRhel(); } return false; } /** * @return if this kickstart profile is rhel 7 installer type */ public boolean isRhel7() { if (getInstallType() != null) { return getInstallType().isRhel7(); } return false; } /** * @return if this kickstart profile is rhel 5 installer type */ public boolean isRhel5() { if (getInstallType() != null) { return getInstallType().isRhel5(); } return false; } /** * @return if this kickstart profile is rhel 7 installer type or greater (for rhel8) */ public boolean isRhel7OrGreater() { if (getInstallType() != null) { return (getInstallType().isRhel7OrGreater() || getInstallType().isFedora()); } return false; } /** * @return if this kickstart profile is rhel 6 installer type or greater (for rhel7) */ public boolean isRhel6OrGreater() { if (getInstallType() != null) { return (getInstallType().isRhel6OrGreater() || getInstallType().isFedora()); } return false; } /** * @return if this kickstart profile is rhel 5 installer type or greater (for rhel6) */ public boolean isRhel5OrGreater() { if (getInstallType() != null) { return (getInstallType().isRhel5OrGreater() || getInstallType().isFedora()); } return false; } /** * * @return if this kickstart profile is RHEL 5 or less */ public boolean isRHEL5OrLess() { if (getInstallType() != null) { return (getInstallType().isRhel5() || !this.isRhel5OrGreater()); } return false; } /** * returns true if this is a fedora kickstart * @return if this is a fedora kickstart or not */ public boolean isFedora() { if (getInstallType() != null) { return getInstallType().isFedora(); } return false; } /** * returns true if this is a generic kickstart * as in non rhel and non fedora. * @return if this is a generic kickstart or not */ public boolean isGeneric() { if (getInstallType() != null) { return getInstallType().isGeneric(); } return false; } /** * returns true if this is a SUSE autoinstallation * @return if this is a SUSE autoinstallation or not */ public boolean isSUSE() { if (getInstallType() != null) { return getInstallType().isSUSE(); } return false; } /** * @return if this kickstart profile is rhel 4 installer type */ public boolean isRhel4() { if (getInstallType() != null) { return getInstallType().isRhel4(); } return false; } /** * @return if this kickstart profile is rhel 3 installer type */ public boolean isRhel3() { if (getInstallType() != null) { return getInstallType().isRhel3(); } return false; } /** * * @return if this kickstart profile is rhel 2 installer type */ public boolean isRhel2() { if (getInstallType() != null) { return getInstallType().isRhel2(); } return false; } /** * * @return Set of IpRanges for Kickstart */ public Set<KickstartIpRange> getIps() { return ips; } /** * * @param ipsIn Set of IPRanges to set */ public void setIps(Set<KickstartIpRange> ipsIn) { this.ips = ipsIn; } /** * * @param ipIn KickstartIpRange to add */ public void addIpRange(KickstartIpRange ipIn) { ips.add(ipIn); } /** * Convenience method to get the KickstartableTree object * @return KickstartableTree object associated with this KSData. */ public KickstartableTree getTree() { if (this.getKickstartDefaults() != null) { return this.getKickstartDefaults().getKstree(); } return null; } /** * Setter for KickstartableTree object * @param kstreeIn the KickstartableTree to set */ public void setTree(KickstartableTree kstreeIn) { this.getKickstartDefaults().setKstree(kstreeIn); } /** * @return the scripts */ public Set<KickstartScript> getScripts() { return scripts; } /** * @param scriptsIn The scripts to set. */ public void setScripts(Set<KickstartScript> scriptsIn) { this.scripts = scriptsIn; } /** * Add a KickstartScript to the KickstartData * @param ksIn to add */ public void addScript(KickstartScript ksIn) { // The ordering goes: Pre scripts and post (chroot) scripts have // positive positions, post nochroot scripts have negative // positions where the most negative script is run right before // Red Hat's scripts. The user can adjust these default positions // later, but this allows us to preserve previous behavor where // adding a nochroot post script added it right before Red Hat's // post scripts and adding a post (chroot) script added it as the // last script that runs. if (ksIn.getScriptType().equals(KickstartScript.TYPE_POST) && !ksIn.thisScriptIsChroot()) { Long minPosition = 0L; for (KickstartScript script : scripts) { if (script.getPosition() < minPosition) { minPosition = script.getPosition(); } } ksIn.setPosition(minPosition - 1); } else { Long maxPosition = 0L; for (KickstartScript script : scripts) { if (script.getPosition() > maxPosition) { maxPosition = script.getPosition(); } } ksIn.setPosition(maxPosition + 1); } ksIn.setKsdata(this); scripts.add(ksIn); } /** * Remove a KickstartScript from this Profile. * @param ksIn to remove. */ public void removeScript(KickstartScript ksIn) { scripts.remove(ksIn); } /** * Is ELILO required for this kickstart profile? * We base this off of the channel arch, because IA64 systems * require elilo * @return boolean - required, or not */ public boolean getEliloRequired() { return this.getKickstartDefaults().getKstree().getChannel() .getChannelArch().getLabel().equals("channel-ia64"); } /** * Get the bootloader type * * @return String: lilo or grub */ public String getBootloaderType() { KickstartCommand bootloaderCommand = this.getCommand("bootloader"); if (bootloaderCommand == null || bootloaderCommand.getArguments() == null) { return "grub"; } String regEx = ".*--useLilo.*"; Pattern pattern = Pattern.compile(regEx); Matcher matcher = pattern.matcher(bootloaderCommand.getArguments()); if (matcher.matches()) { return "lilo"; } return "grub"; } /** * Changes the bootloader * @param type either "grub" or "lilo" * @return true if changed, false otherwise */ public boolean changeBootloaderType(String type) { boolean retval = false; KickstartCommand bootloaderCommand = this.getCommand("bootloader"); if (bootloaderCommand != null) { retval = true; bootloaderCommand.setArguments( bootloaderCommand.getArguments().replaceAll( "--useLilo", "").trim()); if (type.equalsIgnoreCase("lilo")) { bootloaderCommand.setArguments(bootloaderCommand.getArguments() + " --useLilo"); } } return retval; } /** * Convenience method to get the Channel associated with this profile * KickstartData -> KickstartDefault -> KickstartTree -> Channel * @return Channel object associated with this KickstartData */ public Channel getChannel() { if (this.kickstartDefaults != null) { if (this.kickstartDefaults.getKstree() != null) { return this.kickstartDefaults.getKstree().getChannel(); } } return null; } /** * Get the timezone - just the timezone, not the --utc or other args * * @return String: The timezone (like "Asia/Qatar") */ public String getTimezone() { KickstartCommand tzCommand = this.getCommand("timezone"); // my @args = grep { not /--/ } split / /, $tzCommand; // return @args ? $args[0] : ""; if (tzCommand == null || tzCommand.getArguments() == null) { return ""; } List<String> tokens = StringUtil.stringToList(tzCommand.getArguments()); Iterator<String> iter = tokens.iterator(); while (iter.hasNext()) { String token = iter.next(); if (!token.startsWith("--")) { return token; } } return null; } /** * Will the system hardware clock use UTC * * @return Boolean Are we using UTC? */ public Boolean isUsingUtc() { KickstartCommand tzCommand = this.getCommand("timezone"); if (tzCommand == null || tzCommand.getArguments() == null) { return Boolean.FALSE; } List<String> tokens = StringUtil.stringToList(tzCommand.getArguments()); Iterator<String> iter = tokens.iterator(); while (iter.hasNext()) { String token = iter.next(); if (token.equals("--utc")) { return Boolean.TRUE; } } return Boolean.FALSE; } /** * Copy this KickstartData into a new one. NOTE: We don't clone * the following sub-objects: * * KickstartIpRange * * NOTE: We also don't clone isOrgDefault. * * @param user who is doing the cloning * @param newLabel to set on the cloned object * @return KickstartData that is cloned. */ public KickstartData deepCopy(User user, String newLabel) { KickstartData cloned = new KickstartData(); updateCloneDetails(cloned, user, newLabel); return cloned; } protected void updateCloneDetails(KickstartData cloned, User user, String newLabel) { cloned.setLabel(newLabel); cloned.setActive(this.isActive()); cloned.setPostLog(this.getPostLog()); cloned.setPreLog(this.getPreLog()); cloned.setKsCfg(this.getKsCfg()); cloned.setComments(this.getComments()); cloned.setNonChrootPost(this.getNonChrootPost()); cloned.setVerboseUp2date(this.getVerboseUp2date()); cloned.setOrg(this.getOrg()); cloned.setChildChannels(new HashSet<Channel>(this.getChildChannels())); cloned.setPartitionData(getPartitionData()); copyKickstartCommands(getCommands(), cloned); // Gotta remember to create a new HashSet with // the other objects. Otherwise hibernate will // complain that you are using the same collection // in two objects. if (this.getCryptoKeys() != null) { cloned.setCryptoKeys(new HashSet<CryptoKey>(this.getCryptoKeys())); } // NOTE: Make sure we *DONT* clone isOrgDefault cloned.setIsOrgDefault(Boolean.FALSE); cloned.setKernelParams(this.getKernelParams()); if (this.getKickstartDefaults() != null) { cloned.setKickstartDefaults(this.getKickstartDefaults().deepCopy(cloned)); } cloned.setOrg(this.getOrg()); if (this.getKsPackages() != null) { for (KickstartPackage kp : this.getKsPackages()) { cloned.getKsPackages().add(kp.deepCopy(cloned)); } } if (this.getPreserveFileLists() != null) { cloned.setPreserveFileLists(new HashSet<FileList>(this.getPreserveFileLists())); } if (this.getScripts() != null) { Iterator<KickstartScript> i = this.getScripts().iterator(); while (i.hasNext()) { KickstartScript kss = i.next(); KickstartScript ksscloned = kss.deepCopy(cloned); cloned.getScripts().add(ksscloned); } } //copy all of the non-session related kickstarts Set<Token> newTokens = new HashSet<Token>(); if (this.getDefaultRegTokens() != null) { for (Token tok : this.getDefaultRegTokens()) { ActivationKey key = ActivationKeyFactory.lookupByToken(tok); if (key == null || key.getKickstartSession() == null) { newTokens.add(tok); } } } cloned.setDefaultRegTokens(newTokens); cloned.setNoBase(this.getNoBase()); cloned.setIgnoreMissing(this.getIgnoreMissing()); } // Helper method to copy KickstartCommands private static void copyKickstartCommands(Collection<KickstartCommand> commands, KickstartData cloned) { if (commands != null) { Iterator<KickstartCommand> i = commands.iterator(); while (i.hasNext()) { KickstartCommand cmd = i.next(); KickstartCommand clonedCmd = cmd.deepCopy(cloned); cloned.addCommand(clonedCmd); } } } /** * Add a kickstartCommand object * @param clonedCmd The kickstartCommand to add */ public void addCommand(KickstartCommand clonedCmd) { commands.add(clonedCmd); } /** * Util method to determine if we are RHEL3/2.1 * @return boolean if this KickstartData is using RHEL2.1 or RHEL3 */ public boolean isLegacyKickstart() { if (this.getTree() != null && this.getTree().getInstallType() != null) { String installType = this.getTree().getInstallType().getLabel(); return (installType.equals(KickstartInstallType.RHEL_21) || installType.equals(KickstartInstallType.RHEL_3)); } return false; } /** * Bean wrapper so we can call isLegacyKickstart() from JSTL * @return boolean if this KickstartData is using RHEL2.1 or RHEL3 */ public boolean getLegacyKickstart() { return isLegacyKickstart(); } /** * Get the name of the kickstart package this KS will use. * @return String kickstart package like auto-kickstart-ks-rhel-i386-as-4 */ public String getKickstartPackageName() { return ConfigDefaults.get().getKickstartPackageName(); } /** * @return Returns if the post scripts should be logged. */ public Boolean getPostLog() { return postLog; } /** * @return Returns if the pre scripts should be logged. */ public Boolean getPreLog() { return preLog; } /** * @return Returns if we should copy ks.cfg and %include'd fragments to /root */ public Boolean getKsCfg() { return ksCfg; } /** * @param postLogIn The postLog to set. */ public void setPostLog(Boolean postLogIn) { this.postLog = postLogIn; } /** * @param preLogIn The preLog to set. */ public void setPreLog(Boolean preLogIn) { this.preLog = preLogIn; } /** * @param ksCfgIn The ksCfg to set. */ public void setKsCfg(Boolean ksCfgIn) { this.ksCfg = ksCfgIn; } /** * Returns the SE Linux mode associated to this kickstart profile * @return the se linux mode or the default SE Liunx mode (i.e. enforcing).. */ public SELinuxMode getSELinuxMode() { KickstartCommand cmd = getCommand(SELINUX_MODE_COMMAND); if (cmd != null) { String args = cmd.getArguments(); if (!StringUtils.isBlank(args)) { if (args.endsWith(SELinuxMode.PERMISSIVE.getValue())) { return SELinuxMode.PERMISSIVE; } else if (args.endsWith(SELinuxMode.ENFORCING.getValue())) { return SELinuxMode.ENFORCING; } else if (args.endsWith(SELinuxMode.DISABLED.getValue())) { return SELinuxMode.DISABLED; } } } return SELinuxMode.ENFORCING; } /** * True if config management is enabled in this profile.. * @return True if config management is enabled in this profile.. */ public boolean isConfigManageable() { return getKickstartDefaults() != null && getKickstartDefaults().getCfgManagementFlag(); } /** * True if remote command flag is enabled in this profile.. * @return True if remote command flag is enabled in this profile.. */ public boolean isRemoteCommandable() { return getKickstartDefaults() != null && getKickstartDefaults().getRemoteCommandFlag(); } /** * @return the cobblerName */ public String getCobblerFileName() { if (getCobblerId() != null) { Profile prof = Profile.lookupById( CobblerXMLRPCHelper.getConnection( ConfigDefaults.get().getCobblerAutomatedUser()), getCobblerId()); if (prof != null && !StringUtils.isBlank(prof.getKickstart())) { return prof.getKickstart(); } } return null; } /** * Build std kickstart cfg template path * @return ks cfg template path */ public String buildCobblerFileName() { if (isRawData()) { return CobblerCommand.makeCobblerFileName(RAW_DIR + "/" + getLabel(), getOrg()); } return CobblerCommand.makeCobblerFileName(WIZARD_DIR + "/" + getLabel(), getOrg()); } /** * @return Returns if up2date/yum should be verbose */ public Boolean getVerboseUp2date() { return this.verboseUp2date; } /** * @param verboseup2dateIn The verboseup2date to set. */ public void setVerboseUp2date(Boolean verboseup2dateIn) { this.verboseUp2date = verboseup2dateIn; } /** * @return Returns if nonchroot post script is to be logged */ public Boolean getNonChrootPost() { return this.nonChrootPost; } /** * @param nonchrootpostIn The nonchrootpost to set. */ public void setNonChrootPost(Boolean nonchrootpostIn) { this.nonChrootPost = nonchrootpostIn; } /** * Returns true if this is a * raw mode data . * @return true or false. */ public boolean isRawData() { return false; } /** * Return the string containing the kickstart file * @param host the kickstart host * @param session the kickstart session, * can be null if the data * is not part of a session * @return String containing kickstart file */ public String getFileData(String host, KickstartSession session) { KickstartFormatter formatter = new KickstartFormatter(host, this, session); return formatter.getFileData(); } /** * @return Returns the cobblerId. */ public String getCobblerId() { return cobblerId; } /** * @param cobblerIdIn The cobblerId to set. */ public void setCobblerId(String cobblerIdIn) { this.cobblerId = cobblerIdIn; } /** * @return the kickstartType */ protected String getKickstartType() { return kickstartType; } /** * @param kickstartTypeIn the kickstartType to set */ protected void setKickstartType(String kickstartTypeIn) { this.kickstartType = kickstartTypeIn; } /** * @return Returns true if the base package group should be left off */ public boolean getNoBase() { return noBase; } /** * @param noBaseIn the noBase to set */ public void setNoBase(Boolean noBaseIn) { this.noBase = noBaseIn; } /** * @return Returns true if we should ignore missing packages */ public boolean getIgnoreMissing() { return ignoreMissing; } /** * @param ignoreMissingIn the ignoreMissing to set */ public void setIgnoreMissing(Boolean ignoreMissingIn) { this.ignoreMissing = ignoreMissingIn; } /** * Get the default virt bridge for this KickstartData object. * * @return String virt bridge (xenbr0, virbr0) */ public String getDefaultVirtBridge() { if (this.getKickstartDefaults().getVirtualizationType().getLabel() .equals(KickstartVirtualizationType.KVM_FULLYVIRT)) { return ConfigDefaults.get().getDefaultKVMVirtBridge(); } return ConfigDefaults.get().getDefaultXenVirtBridge(); } /** * Returns the cobbler object associated to * to this profile. * @param user the user object needed for connection, * enter null if you want to use the * automated connection as provided by * taskomatic. * @return the Profile associated to this ks data */ public Profile getCobblerObject(User user) { if (StringUtils.isBlank(getCobblerId())) { return null; } CobblerConnection con; if (user == null) { con = CobblerXMLRPCHelper.getAutomatedConnection(); } else { con = CobblerXMLRPCHelper.getConnection(user); } return Profile.lookupById(con, getCobblerId()); } /** * Gets the Registration Type (i.e. the code that determines if * the ks script needs to generate a reactivation key or not) * @param user the user object needed to load the profile from cobbler * @return the registration type */ public RegistrationType getRegistrationType(User user) { Profile prof = getCobblerObject(null); if (prof == null) { return RegistrationType.getDefault(); } return RegistrationType.find((String)prof.getKsMeta().get( RegistrationType.COBBLER_VAR)); } /** * Sets the registration type * @param type the refgistration type * @param user the user needed to load the profile form cobbler */ public void setRegistrationType(RegistrationType type, User user) { Profile prof = getCobblerObject(user); Map<String, Object> meta = prof.getKsMeta(); meta.put(RegistrationType.COBBLER_VAR, type.getType()); prof.setKsMeta(meta); prof.save(); } /** * Method to determine if the profile * is valid or if it needs to be corrected. * @return true if the profile is synced to cobbler * and the distro it hosts is valid. */ public boolean isValid() { return !StringUtils.isBlank(getCobblerId()) && getTree().isValid(); } /** * @return Returns the partitionData. */ protected byte[] getPartitionDataBinary() { return partitionData; } /** * @param partitionDataIn The partitionData to set. */ protected void setPartitionDataBinary(byte[] partitionDataIn) { partitionData = partitionDataIn; } /** * Get the partition data as string * @return partition data as string */ public String getPartitionData() { return HibernateFactory.getByteArrayContents(getPartitionDataBinary()); } /** * Set the partition data * @param data the partition info */ public void setPartitionData(String data) { setPartitionDataBinary(HibernateFactory.stringToByteArray(data)); } /** * get the update type * @return the update type */ public String getUpdateType() { return this.updateType; } /** * get the update type * @return the update type */ public KickstartTreeUpdateType getRealUpdateType() { return KickstartTreeUpdateType.find(this.updateType); } /** * Set the update type * Hibernate wigs out if this is called "setUpdateType", which is should be * @param updateTypeIn the update type to set */ public void setUpdateType(String updateTypeIn) { this.updateType = updateTypeIn; } /** * Set the update type * Hibernate wigs out if this is called "setUpdateType", which is should be * @param updateTypeIn the update type to set */ public void setRealUpdateType(KickstartTreeUpdateType updateTypeIn) { this.updateType = updateTypeIn.getType(); } /** * Return the default args to the auth command for this ksdata * @return default auth args */ public String defaultAuthArgs() { if (this.isRHEL5OrLess()) { return "--enablemd5 --enableshadow"; } return "--enableshadow --passalgo=sha256"; } /** * Encrypt the password with whichever algorithm is appropriate for this ksdata * @param password the password to encrypt * @return the encrypted password */ public String encryptPassword(String password) { if (this.isRHEL5OrLess()) { return MD5Crypt.crypt(password); } return SHA256Crypt.crypt(password); } }