package hudson.plugins.pxe; import hudson.Util; import hudson.util.VariableResolver; import org.apache.commons.io.IOUtils; import org.apache.commons.jexl.ExpressionFactory; import org.apache.commons.jexl.context.HashMapContext; import org.jvnet.hudson.tftpd.Data; import org.kohsuke.loopy.FileEntry; import org.kohsuke.loopy.iso9660.ISO9660FileSystem; import org.kohsuke.stapler.StaplerResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Locale; import java.util.TimeZone; public abstract class LinuxBootConfiguration extends IsoBasedBootConfiguration { protected LinuxBootConfiguration(File iso) { super(iso); } /** * Directs the user to the OS specific submenu. */ public String getPxeLinuxConfigFragment() throws IOException { return String.format("LABEL %1$s\n" + " MENU LABEL %2$s\n" + " KERNEL vesamenu.c32\n" + " APPEND %1$s/menu.txt \n", getId(), getRelease()); } /** * Serves menu.txt by replacing variables. */ public Data tftp(String fileName) throws IOException { if(fileName.equals("menu.txt")) { // pxelinux boot menu String template = IOUtils.toString(getResourceAsStream("menu.txt")); return Data.from(Util.replaceMacro(template,createResolver())); } // look them up in the ISO file ISO9660FileSystem fs = new ISO9660FileSystem(iso,false); FileEntry dir = getTftpIsoMountDir(fs); if(dir!=null) { FileEntry f = dir.get(fileName); if(f!=null) return new FileEntryData(f); } return null; } /** * Directory inside the ISO file that gets "mounted" to TFTP. Used normally to serve * kernel and initrd. * * @return * null if no directory from ISO is mount to tftp. */ protected abstract FileEntry getTftpIsoMountDir(ISO9660FileSystem fs) throws IOException; /** * Creates a variable resolver that looks up properties on this class. */ protected VariableResolver<String> createResolver() { final HashMapContext context = new HashMapContext(); context.put("it", this); // these are commonly used values context.put("timeZone", TimeZone.getDefault().getID()); context.put("locale", Locale.getDefault().toString()); return new VariableResolver<String>() { public String resolve(String name) { try { if (context.containsKey(name)) return context.get(name).toString(); Object o = ExpressionFactory.createExpression("it." + name).evaluate(context); if(o==null) return ""; return String.valueOf(o); } catch (Exception e) { throw new Error(e); // tunneling. this must indicate a programming error } } }; } /** * Serves the static text resource after expanding macro variables. */ protected void serveMacroExpandedResource(StaplerResponse rsp, String resourceName) throws IOException { rsp.setContentType("text/plain"); rsp.getWriter().println( Util.replaceMacro(IOUtils.toString(getResourceAsStream(resourceName)), createResolver())); } }