package hudson.plugins.pxe;
import hudson.Extension;
import hudson.Util;
import static hudson.util.FormValidation.error;
import org.jvnet.hudson.tftpd.Data;
import org.kohsuke.loopy.FileEntry;
import org.kohsuke.loopy.iso9660.ISO9660FileSystem;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerResponse;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Map;
import java.util.TreeMap;
import java.util.Arrays;
/**
* RedHat/Fedora boot configuration.
*
* @author Kohsuke Kawaguchi
*/
public class RedHatBootConfiguration extends LinuxBootConfiguration {
public final String additionalPackages;
public final String password;
@DataBoundConstructor
public RedHatBootConfiguration(File iso, String password, String additionalPackages) {
super(iso);
if(Util.fixEmptyAndTrim(password)==null) password="hudson";
if(!password.startsWith("$1$"))
password = Crypt.cryptMD5("abcdefgh",password);
this.password = password;
this.additionalPackages = Util.fixEmptyAndTrim(additionalPackages);
}
protected String getIdSeed() {
return getRelease().replaceAll("[ ()]","");
}
/**
* The root directory that we expose to TFTP.
*/
protected FileEntry getTftpIsoMountDir(ISO9660FileSystem fs) throws IOException {
return fs.get("/images/pxeboot");
}
/**
* Serves menu.txt by replacing variables.
*/
public Data tftp(String fileName) throws IOException {
if(fileName.equals("splash.jpg")) {
ISO9660FileSystem fs = new ISO9660FileSystem(iso,false);
return new FileEntryData(fs.grab("/isolinux/splash.jpg"));
}
return super.tftp(fileName);
}
/**
* Serves the kickstart file
*/
public void doKickstart(StaplerResponse rsp) throws IOException {
serveMacroExpandedResource(rsp,"kickstart.txt");
}
/**
* Package list formatted in the kickstart format.
*/
public String getPackageList() {
// returning empty line breaks CentOS, so return something harmless
if(additionalPackages==null) return "# no additional packages";
return Util.join(Arrays.asList(additionalPackages.split(" +")),"\n");
}
@Extension
public static class DescriptorImpl extends IsoBasedBootConfigurationDescriptor {
public String getDisplayName() {
return "RedHat/Fedora";
}
/**
* This returns string like "Fedora 10"
*
* TODO: where can we get the architecture information?
*/
protected String getReleaseInfo(File iso) throws IOException {
ISO9660FileSystem fs=null;
try {
try {
fs = new ISO9660FileSystem(iso,false);
} catch (IOException e) {
LOGGER.log(Level.INFO,iso+" isn't an ISO file?",e);
throw error(iso+" doesn't look like an ISO file");
}
FileEntry info = fs.get("/.treeinfo");
if(info==null)
throw error(iso+" doesn't look like a RedHat/Fedora CD/DVD image");
/* On Fedora 10 DVD, this file contains:
[general]
family = Fedora
timestamp = 1227142151.33
variant = Fedora
totaldiscs = 1
version = 10
discnum = 1
packagedir =
arch = i386
On CentOS, this entry was:
[general]
family = CentOS
timestamp = 1237646605.22
totaldiscs = 1
version = 5.3
discnum = 1
packagedir = CentOS
arch = i386
*/
Map<String,String> section = new TreeMap<String,String>();
BufferedReader r = new BufferedReader(new InputStreamReader(info.read()));
try {
String line;
while((line=r.readLine())!=null) {
if(line.contains(" = ")) {
String[] tokens = line.split("=");
section.put(tokens[0].trim(),tokens[1].trim());
}
}
if(!section.containsKey("family") || !section.containsKey("version") || !section.containsKey("arch"))
throw error(iso+" doesn't contain the name entry in media.repo");
// should be something like "CentOS 5.3 (i386)"
return Util.join(Arrays.asList(
section.get("family"),section.get("version"),"("+section.get("arch")+")")," ");
} finally {
r.close();
}
} finally {
if(fs!=null)
fs.close();
}
}
}
private static final Logger LOGGER = Logger.getLogger(RedHatBootConfiguration.class.getName());
}