package hudson.plugins.pxe;
import hudson.DescriptorExtensionList;
import static hudson.Functions.defaulted;
import hudson.model.Describable;
import hudson.model.Hudson;
import hudson.model.AbstractModelObject;
import org.jvnet.hudson.tftpd.Data;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import java.io.IOException;
import java.io.InputStream;
/**
* Configuration of a bootable operating system.
*
* <p>
* Say "Ubuntu 2008.10 + such and such preseed config".
*
* <p>
* These objects are bound to URL as <tt>"/pxe/configuration/{@linkplain #getId() ID}/"</tt>
*
* @author Kohsuke Kawaguchi
*/
public abstract class BootConfiguration extends AbstractModelObject implements Describable<BootConfiguration> {
/**
* Computed by {@link PXE#doConfigSubmit(StaplerRequest, StaplerResponse)}.
*/
/*package almost final*/ String id;
/**
* Returns a unique ID that distinguishes {@link BootConfiguration}s among other siblings.
*
* For serving dynamic data from TFTP, it's often useful to have an unique ID per {@link BootConfiguration}.
* This method provides that.
*/
public String getId() {
return id;
}
/**
* Returns the string that becomes the seed of the {@link #getId()}. The ID
* is in turn used for HTTP URLs and TFTP file names, so this method should
* return something stable and not entirely illegible. But avoid unsafe characters like spaces, '/', etc.
* A good example would be "OpenSolaris2008.11" or "Ubuntu8.10".
*
* <p>
* Several {@link BootConfiguration}s can return the same ID seed, and {@link #getId()} handles
* those situations correctly.
*/
protected abstract String getIdSeed();
public final String getSearchUrl() {
return "configuration/"+getId();
}
public final String getUrl() {
return getSearchUrl();
}
/**
* Gets the absolute URL to this {@link BootConfiguration}.
*
* @return
* String like "http://foobar/path/to/hudson/pxe/configuration/me" without trailing '/'.
*/
public final String getAbsoluteUrl() {
return defaulted(PXE.ROOT_URL,Hudson.getInstance().getRootUrl())+"pxe/"+getUrl();
}
public BootConfigurationDescriptor getDescriptor() {
return (BootConfigurationDescriptor) Hudson.getInstance().getDescriptor(getClass());
}
/**
* Convenience method to load a resource from the same place as Jelly views are loaded.
*/
protected InputStream getResourceAsStream(String fileName) {
for(Class c=getClass(); c!=null; c=c.getSuperclass()) {
InputStream s = c.getClassLoader().getResourceAsStream(c.getName().replace('.', '/') + '/' + fileName);
if(s!=null) return s;
}
return null; // not found
}
/**
* Serves data from TFTP.
*
* <p>
* This mechanism is useful when you need to generate the data to be served on the fly.
* Static resources can be more easily served by simply placing them as resources
* under /tftp.
*
* <p>
* The TFTP file namespace is divided for each {@link BootConfiguration}s as
* <tt>/{@linkplain #getId() ID}/...</tt> to avoid collisions between different configurations.
*
* @param fileName
* Relative path within the space designated for this boot configuration. For example,
* if the client requests "foo/bar/zot" and the ID of this configuration is "foo", this
* parameter will be "bar/zot".
* @return
* null if no such file exists, as far as this plugin is concerned.
* The PXE plugin will continue to search other {@link BootConfiguration}s to
* see if anyone understands it.
* @throws IOException
* If a problem occurs. The PXE plugin will abort the search and the download will fail.
*/
public Data tftp(String fileName) throws IOException {
return null;
}
/**
* Called before the {@link BootConfiguration} instances are let go because of the reconfiguration.
* This is a good place to clean up background threads, etc.
*/
protected void shutdown() throws IOException {
}
/**
* Returns the fragment to be merged into <tt>pxelinux.cfg/default</tt>.
*/
public abstract String getPxeLinuxConfigFragment() throws IOException;
/**
* Returns all the registered {@link BootConfigurationDescriptor}s.
*/
public static DescriptorExtensionList<BootConfiguration, BootConfigurationDescriptor> all() {
return Hudson.getInstance().getDescriptorList(BootConfiguration.class);
}
}