package hudson.model; import com.thoughtworks.xstream.XStream; import groovy.lang.GroovyShell; import hudson.security.BasicAuthenticationFilter; import hudson.FeedAdapter; import hudson.FilePath; import hudson.Functions; import hudson.Launcher; import hudson.Launcher.LocalLauncher; import hudson.Plugin; import hudson.PluginManager; import hudson.PluginWrapper; import hudson.TcpSlaveAgentListener; import hudson.Util; import static hudson.Util.fixEmpty; import hudson.XmlFile; import hudson.model.Descriptor.FormException; import hudson.model.listeners.ItemListener; import hudson.model.listeners.JobListener; import hudson.model.listeners.JobListener.JobListenerAdapter; import hudson.model.listeners.SCMListener; import hudson.remoting.LocalChannel; import hudson.remoting.VirtualChannel; import hudson.scm.CVSSCM; import hudson.scm.RepositoryBrowser; import hudson.scm.RepositoryBrowsers; import hudson.scm.SCM; import hudson.scm.SCMDescriptor; import hudson.scm.SCMS; import hudson.search.CollectionSearchIndex; import hudson.search.SearchIndexBuilder; import hudson.tasks.BuildStep; import hudson.tasks.BuildWrapper; import hudson.tasks.BuildWrappers; import hudson.tasks.Builder; import hudson.tasks.DynamicLabeler; import hudson.tasks.LabelFinder; import hudson.tasks.Mailer; import hudson.tasks.Publisher; import hudson.triggers.Trigger; import hudson.triggers.TriggerDescriptor; import hudson.triggers.Triggers; import hudson.util.ClockDifference; import hudson.util.CopyOnWriteList; import hudson.util.CopyOnWriteMap; import hudson.util.DaemonThreadFactory; import hudson.util.FormFieldValidator; import hudson.util.HudsonIsLoading; import hudson.util.MultipartFormDataParser; import hudson.util.XStream2; import hudson.widgets.Widget; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.export.Exported; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.Stack; import java.util.StringTokenizer; import java.util.TreeSet; import java.util.Vector; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; import java.util.regex.Pattern; /** * Root object of the system. * * @author Kohsuke Kawaguchi */ public final class Hudson extends View implements ItemGroup, Node { private transient final Queue queue = new Queue(); /** * {@link Computer}s in this Hudson system. Read-only. */ private transient final Map computers = new CopyOnWriteMap.Hash(); /** * Number of executors of the master node. */ private int numExecutors = 2; /** * False to enable anyone to do anything. */ private boolean useSecurity = false; /** * Message displayed in the top page. */ private String systemMessage; /** * Root directory of the system. */ public transient final File root; /** * All {@link Item}s keyed by their {@link Item#getName() name}s. */ /*package*/ transient final Map items = new CopyOnWriteMap.Tree(); /** * The sole instance. */ private static Hudson theInstance; private transient boolean isQuietingDown; private transient boolean terminating; private List jdks = new ArrayList(); /** * Widgets on Hudson. */ private transient final List widgets = new CopyOnWriteArrayList(); private transient volatile DependencyGraph dependencyGraph = DependencyGraph.EMPTY; /** * Set of installed cluster nodes. * * We use this field with copy-on-write semantics. * This field has mutable list (to keep the serialization look clean), * but it shall never be modified. Only new completely populated slave * list can be set here. */ private volatile List slaves; /** * Quiet period. * * This is {@link Integer} so that we can initialize it to '5' for upgrading users. */ /*package*/ Integer quietPeriod; /** * {@link ListView}s. */ private List views; // can't initialize it eagerly for backward compatibility private transient final FingerprintMap fingerprintMap = new FingerprintMap(); /** * Loaded plugins. */ public transient final PluginManager pluginManager; public transient volatile TcpSlaveAgentListener tcpSlaveAgentListener; /** * List of registered {@link JobListener}s. */ private transient final CopyOnWriteList itemListeners = new CopyOnWriteList(); /** * List of registered {@link SCMListener}s. */ private transient final CopyOnWriteList scmListeners = new CopyOnWriteList(); /** * TCP slave agent port. * 0 for random, -1 to disable. */ private int slaveAgentPort =0; /** * Once plugin is uploaded, this flag becomes true. * This is used to report a message that Hudson needs to be restarted * for new plugins to take effect. */ private transient boolean pluginUploaded =false; /** * All labels known to Hudson. This allows us to reuse the same label instances * as much as possible, even though that's not a strict requirement. */ private transient final ConcurrentHashMap labels = new ConcurrentHashMap(); private transient Set