1 package hudson.model; 2 3 import hudson.EnvVars; 4 import hudson.remoting.Callable; 5 import hudson.remoting.VirtualChannel; 6 import hudson.util.DaemonThreadFactory; 7 import hudson.util.RunList; 8 import org.kohsuke.stapler.StaplerRequest; 9 import org.kohsuke.stapler.StaplerResponse; 10 11 import javax.servlet.ServletException ; 12 import java.io.IOException ; 13 import java.util.ArrayList ; 14 import java.util.List ; 15 import java.util.Map ; 16 import java.util.TreeMap ; 17 import java.util.Collections ; 18 import java.util.concurrent.ExecutorService ; 19 import java.util.concurrent.Executors ; 20 21 44 public abstract class Computer implements ModelObject { 45 private final List<Executor> executors = new ArrayList <Executor>(); 46 47 private int numExecutors; 48 49 52 private boolean temporarilyOffline; 53 54 58 protected String nodeName; 59 60 public Computer(Node node) { 61 assert node.getNumExecutors()!=0 : "Computer created with 0 executors"; 62 setNode(node); 63 } 64 65 71 public abstract VirtualChannel getChannel(); 72 73 76 public abstract void doLaunchSlaveAgent( StaplerRequest req, StaplerResponse rsp ) throws IOException , ServletException ; 77 78 85 public int getNumExecutors() { 87 return numExecutors; 88 } 89 90 93 public Node getNode() { 94 if(nodeName==null) 95 return Hudson.getInstance(); 96 return Hudson.getInstance().getSlave(nodeName); 97 } 98 99 public boolean isOffline() { 100 return temporarilyOffline || getChannel()==null; 101 } 102 103 106 public boolean isJnlpAgent() { 107 return false; 108 } 109 110 123 public boolean isTemporarilyOffline() { 124 return temporarilyOffline; 125 } 126 127 public void setTemporarilyOffline(boolean temporarilyOffline) { 128 this.temporarilyOffline = temporarilyOffline; 129 Hudson.getInstance().getQueue().scheduleMaintenance(); 130 } 131 132 public String getIcon() { 133 if(isOffline()) 134 return "computer-x.gif"; 135 else 136 return "computer.gif"; 137 } 138 139 public String getDisplayName() { 140 return nodeName; 141 } 142 143 public String getUrl() { 144 return "computer/"+getDisplayName()+"/"; 145 } 146 147 150 public List<Project> getTiedJobs() { 151 List<Project> r = new ArrayList <Project>(); 152 for( Project p : Hudson.getInstance().getProjects() ) { 153 if(p.getAssignedNode()==getNode()) 154 r.add(p); 155 } 156 return r; 157 } 158 159 163 protected void setNode(Node node) { 164 assert node!=null; 165 if(node instanceof Slave) 166 this.nodeName = node.getNodeName(); 167 else 168 this.nodeName = null; 169 170 setNumExecutors(node.getNumExecutors()); 171 } 172 173 176 protected void kill() { 177 setNumExecutors(0); 178 } 179 180 private synchronized void setNumExecutors(int n) { 181 this.numExecutors = n; 182 183 for( Executor e : executors ) 185 if(e.getCurrentBuild()==null) 186 e.interrupt(); 187 188 while(executors.size()<numExecutors) 190 executors.add(new Executor(this)); 191 } 192 193 196 public synchronized int countIdle() { 197 int n = 0; 198 for (Executor e : executors) { 199 if(e.isIdle()) 200 n++; 201 } 202 return n; 203 } 204 205 208 public synchronized List<Executor> getExecutors() { 209 return new ArrayList <Executor>(executors); 210 } 211 212 215 synchronized void removeExecutor(Executor e) { 216 executors.remove(e); 217 if(executors.isEmpty()) 218 Hudson.getInstance().removeComputer(this); 219 } 220 221 224 public synchronized void interrupt() { 225 for (Executor e : executors) { 226 e.interrupt(); 227 } 228 } 229 230 234 public Map <Object ,Object > getSystemProperties() throws IOException , InterruptedException { 235 return getChannel().call(new GetSystemProperties()); 236 } 237 238 private static final class GetSystemProperties implements Callable<Map <Object ,Object >,RuntimeException > { 239 public Map <Object ,Object > call() { 240 return new TreeMap <Object ,Object >(System.getProperties()); 241 } 242 private static final long serialVersionUID = 1L; 243 } 244 245 249 public Map <String ,String > getEnvVars() throws IOException , InterruptedException { 250 VirtualChannel channel = getChannel(); 251 if(channel==null) 252 return Collections.singletonMap("N/A","N/A"); 253 return channel.call(new GetEnvVars()); 254 } 255 256 private static final class GetEnvVars implements Callable<Map <String ,String >,RuntimeException > { 257 public Map <String ,String > call() { 258 return new TreeMap <String ,String >(EnvVars.masterEnvVars); 259 } 260 private static final long serialVersionUID = 1L; 261 } 262 263 264 public static final ExecutorService threadPoolForRemoting = Executors.newCachedThreadPool(new DaemonThreadFactory()); 265 266 public void doRssAll( StaplerRequest req, StaplerResponse rsp ) throws IOException , ServletException { 272 rss(req, rsp, " all builds", new RunList(getTiedJobs())); 273 } 274 public void doRssFailed( StaplerRequest req, StaplerResponse rsp ) throws IOException , ServletException { 275 rss(req, rsp, " failed builds", new RunList(getTiedJobs()).failureOnly()); 276 } 277 private void rss(StaplerRequest req, StaplerResponse rsp, String suffix, RunList runs) throws IOException , ServletException { 278 RSS.forwardToRss(getDisplayName()+ suffix, getUrl(), 279 runs.newBuilds(), Run.FEED_ADAPTER, req, rsp ); 280 } 281 282 public void doToggleOffline( StaplerRequest req, StaplerResponse rsp ) throws IOException , ServletException { 283 if(!Hudson.adminCheck(req,rsp)) 284 return; 285 286 setTemporarilyOffline(!temporarilyOffline); 287 rsp.forwardToPreviousPage(req); 288 } 289 } 290 | Popular Tags |