package hudson.plugins.swarm; import hudson.Plugin; import hudson.Util; import hudson.model.Descriptor.FormException; import hudson.model.Hudson; import hudson.model.Node; import hudson.security.ACL; import org.acegisecurity.context.SecurityContextHolder; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; import java.io.IOException; /** * Exposes an entry point to add a new swarm slave. * * @author Kohsuke Kawaguchi */ public class PluginImpl extends Plugin { /** * Adds a new swarm slave. */ public void doCreateSlave(StaplerRequest req, StaplerResponse rsp, @QueryParameter String name, @QueryParameter String description, @QueryParameter int executors, @QueryParameter String remoteFsRoot, @QueryParameter String labels, @QueryParameter String secret) throws IOException, FormException { // only allow nearby nodes to connect if(!UDPFragmentImpl.all().get(UDPFragmentImpl.class).secret.toString().equals(secret)) { rsp.setStatus(SC_FORBIDDEN); return; } // this is used by swarm clients that otherwise have no access to the system, // so bypass the regular security check, and only rely on secret. SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM); try { final Hudson hudson = Hudson.getInstance(); // try to make the name unique. Swarm clients are often repliated VMs, and they may have the same name. if(hudson.getNode(name)!=null) name = name+'-'+req.getRemoteAddr(); SwarmSlave slave = new SwarmSlave(name, "Swarm slave from "+req.getRemoteHost()+" : "+description, remoteFsRoot, String.valueOf(executors), "swarm "+Util.fixNull(labels)); // if this still results in a dupliate, so be it synchronized (hudson) { Node n = hudson.getNode(name); if(n!=null) hudson.removeNode(n); hudson.addNode(slave); } } catch (FormException e) { e.printStackTrace(); } finally { SecurityContextHolder.clearContext(); } } }