Node.java 8.7 KB
Newer Older
K
kohsuke 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * The MIT License
 * 
 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe, Stephen Connolly
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
K
kohsuke 已提交
24 25
package hudson.model;

K
kohsuke 已提交
26
import hudson.ExtensionPoint;
27
import hudson.FilePath;
28
import hudson.FileSystemProvisioner;
29 30
import hudson.Launcher;
import hudson.node_monitors.NodeMonitor;
31
import hudson.remoting.VirtualChannel;
32
import hudson.security.ACL;
K
kohsuke 已提交
33
import hudson.security.AccessControlled;
34
import hudson.security.Permission;
K
kohsuke 已提交
35
import hudson.slaves.NodeDescriptor;
36 37
import hudson.slaves.NodeProperty;
import hudson.slaves.NodePropertyDescriptor;
38
import hudson.util.ClockDifference;
39
import hudson.util.DescribableList;
K
kohsuke 已提交
40
import hudson.util.EnumConverter;
K
kohsuke 已提交
41

K
kohsuke 已提交
42
import java.io.IOException;
K
kohsuke 已提交
43
import java.util.Set;
K
kohsuke 已提交
44
import java.util.List;
45

46
import org.kohsuke.stapler.Stapler;
K
kohsuke 已提交
47 48
import org.kohsuke.stapler.export.ExportedBean;
import org.kohsuke.stapler.export.Exported;
49

K
kohsuke 已提交
50
/**
K
kohsuke 已提交
51 52 53 54
 * Base type of Hudson slaves (although in practice, you probably extend {@link Slave} to define a new slave type.)
 *
 * <p>
 * As a special case, {@link Hudson} extends from here.
K
kohsuke 已提交
55 56
 *
 * @author Kohsuke Kawaguchi
K
kohsuke 已提交
57
 * @see NodeMonitor
K
kohsuke 已提交
58
 * @see NodeDescriptor
K
kohsuke 已提交
59
 */
K
kohsuke 已提交
60
@ExportedBean
61
public abstract class Node extends AbstractModelObject implements Describable<Node>, ExtensionPoint, AccessControlled {
62 63 64 65 66
    /**
     * Newly copied slaves get this flag set, so that Hudson doesn't try to start this node until its configuration
     * is saved once.
     */
    protected volatile transient boolean holdOffLaunchUntilSave;
67

68 69 70 71 72 73 74 75
    public String getDisplayName() {
        return getNodeName(); // default implementation
    }

    public String getSearchUrl() {
        return "computer/"+getNodeName();
    }

76 77 78 79
    public boolean isHoldOffLaunchUntilSave() {
        return holdOffLaunchUntilSave;
    }

K
kohsuke 已提交
80
    /**
K
kohsuke 已提交
81
     * Name of this node.
K
kohsuke 已提交
82 83 84 85
     *
     * @return
     *      "" if this is master
     */
K
kohsuke 已提交
86
    @Exported(visibility=999)
87
    public abstract String getNodeName();
K
kohsuke 已提交
88

K
kohsuke 已提交
89 90 91 92 93 94 95 96 97 98
    /**
     * When the user clones a {@link Node}, Hudson uses this method to change the node name right after
     * the cloned {@link Node} object is instantiated.
     *
     * <p>
     * This method is never used for any other purpose, and as such for all practical intents and purposes,
     * the node name should be treated like immutable.
     *
     * @deprecated to indicate that this method isn't really meant to be called by random code.
     */
99
    public abstract void setNodeName(String name);
K
kohsuke 已提交
100

K
kohsuke 已提交
101 102 103
    /**
     * Human-readable description of this node.
     */
K
kohsuke 已提交
104
    @Exported
105
    public abstract String getNodeDescription();
K
kohsuke 已提交
106 107 108

    /**
     * Returns a {@link Launcher} for executing programs on this node.
K
kohsuke 已提交
109 110 111
     *
     * <p>
     * The callee must call {@link Launcher#decorateFor(Node)} before returning to complete the decoration. 
K
kohsuke 已提交
112
     */
113
    public abstract Launcher createLauncher(TaskListener listener);
K
kohsuke 已提交
114 115 116 117 118 119 120

    /**
     * Returns the number of {@link Executor}s.
     *
     * This may be different from <code>getExecutors().size()</code>
     * because it takes time to adjust the number of executors.
     */
K
kohsuke 已提交
121
    @Exported
122
    public abstract int getNumExecutors();
K
kohsuke 已提交
123 124

    /**
125
     * Returns {@link Mode#EXCLUSIVE} if this node is only available
K
kohsuke 已提交
126 127 128
     * for those jobs that exclusively specifies this node
     * as the assigned node.
     */
K
kohsuke 已提交
129
    @Exported
130
    public abstract Mode getMode();
K
kohsuke 已提交
131

132 133 134 135
    /**
     * Gets the corresponding {@link Computer} object.
     *
     * @return
K
kohsuke 已提交
136 137
     *      this method can return null if there's no {@link Computer} object for this node,
     *      such as when this node has no executors at all.
138
     */
139 140 141
    public final Computer toComputer() {
        return Hudson.getInstance().getComputer(this);
    }
142

K
kohsuke 已提交
143 144 145 146
    /**
     * Creates a new {@link Computer} object that acts as the UI peer of this {@link Node}.
     * Nobody but {@link Hudson#updateComputerList()} should call this method.
     */
147
    protected abstract Computer createComputer();
K
kohsuke 已提交
148

149 150 151 152
    /**
     * Returns the possibly empty set of labels that are assigned to this node,
     * including the automatic {@link #getSelfLabel() self label}.
     */
K
kohsuke 已提交
153
    @Exported
154
    public abstract Set<Label> getAssignedLabels();
155

K
kohsuke 已提交
156 157 158 159 160 161
    /**
     * The same as {@link #getAssignedLabels()} but returns labels as a single text.
     * Mainly for form binding.
     */
    public abstract String getLabelString();

162
    /*
163 164 165
     * Returns the possibly empty set of labels that it has been determined as supported by this node.
     * @see hudson.tasks.LabelFinder
     */
166
    public abstract Set<Label> getDynamicLabels();
167

168 169 170
    /**
     * Gets the special label that represents this node itself.
     */
171 172 173
    public Label getSelfLabel() {
        return Hudson.getInstance().getLabel(getNodeName());
    }
174

175 176 177 178 179 180
    /**
     * Returns a "workspace" directory for the given {@link TopLevelItem}.
     *
     * <p>
     * Workspace directory is usually used for keeping out the checked out
     * source code, but it can be used for anything.
K
kohsuke 已提交
181 182 183
     *
     * @return
     *      null if this node is not connected hence the path is not available
184
     */
K
kohsuke 已提交
185
    // TODO: should this be modified now that getWorkspace is moved from AbstractProject to AbstractBuild?
186
    public abstract FilePath getWorkspaceFor(TopLevelItem item);
187

K
kohsuke 已提交
188 189 190 191 192 193 194 195 196 197 198
    /**
     * Gets the root directory of this node.
     *
     * <p>
     * Hudson always owns a directory on every node. This method
     * returns that.
     *
     * @return
     *      null if the node is offline and hence the {@link FilePath}
     *      object is not available.
     */
199
    public abstract FilePath getRootPath();
K
kohsuke 已提交
200

201 202 203
    /**
     * Gets the {@link FilePath} on this node.
     */
204 205 206 207 208 209 210 211
    public FilePath createPath(String absolutePath) {
        Computer computer = toComputer();
        if (computer==null) return null; // offline
        VirtualChannel ch = computer.getChannel();
        if(ch==null)    return null;    // offline
        return new FilePath(ch,absolutePath);
    }

212 213 214 215 216
    public FileSystemProvisioner getFileSystemProvisioner() {
        // TODO: make this configurable or auto-detectable or something else
        return FileSystemProvisioner.DEFAULT;
    }

217 218 219
    /**
     * Gets the {@link NodeProperty} instances configured for this {@link Node}.
     */
220
    public abstract DescribableList<NodeProperty<?>, NodePropertyDescriptor> getNodeProperties();
221

K
kohsuke 已提交
222 223 224 225
    // used in the Jelly script to expose descriptors
    public List<NodePropertyDescriptor> getNodePropertyDescriptors() {
        return NodeProperty.for_(this);
    }
226
    
227 228 229 230 231 232 233 234 235 236 237
    public ACL getACL() {
        return Hudson.getInstance().getAuthorizationStrategy().getACL(this);
    }
    
    public final void checkPermission(Permission permission) {
        getACL().checkPermission(permission);
    }

    public final boolean hasPermission(Permission permission) {
        return getACL().hasPermission(permission);
    }
238

239
    public abstract NodeDescriptor getDescriptor();
K
kohsuke 已提交
240

K
kohsuke 已提交
241 242 243 244
    /**
     * Estimates the clock difference with this slave.
     *
     * @return
245
     *      always non-null.
K
kohsuke 已提交
246 247 248
     * @throws InterruptedException
     *      if the operation is aborted.
     */
249
    public abstract ClockDifference getClockDifference() throws IOException, InterruptedException;
K
kohsuke 已提交
250

K
kohsuke 已提交
251 252 253
    /**
     * Constants that control how Hudson allocates jobs to slaves.
     */
K
kohsuke 已提交
254
    public enum Mode {
S
sogabe 已提交
255 256
        NORMAL(Messages.Node_Mode_NORMAL()),
        EXCLUSIVE(Messages.Node_Mode_EXCLUSIVE());
K
kohsuke 已提交
257 258 259 260 261 262 263 264 265 266 267 268 269 270

        private final String description;

        public String getDescription() {
            return description;
        }

        public String getName() {
            return name();
        }

        Mode(String description) {
            this.description = description;
        }
K
kohsuke 已提交
271 272

        static {
273
            Stapler.CONVERT_UTILS.register(new EnumConverter(), Mode.class);
274 275
        }
    }
276

K
kohsuke 已提交
277
}