File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\lifecycle\Lifecycle.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 package hudson.lifecycle;
25
26 import hudson.ExtensionPoint;
27 import hudson.Functions;
28 import hudson.Util;
29 import jenkins.model.Jenkins;
30
31 import java.io.File;
32 import java.io.IOException;
33 import java.util.logging.Logger;
34 import java.util.logging.Level;
35
36 import org.apache.commons.io.FileUtils;
37
38 /**
39 * Provides the capability for starting/stopping/restarting/uninstalling Hudson.
40 *
41 * <p>
42 * The steps to perform these operations depend on how Hudson is launched,
43 * so the concrete instance of this method (which is VM-wide singleton) is discovered
44 * by looking up a FQCN from the system property "hudson.lifecycle".
45 *
46 * @author Kohsuke Kawaguchi
47 * @since 1.254
48 */
49 public abstract class Lifecycle implements ExtensionPoint {
50 private static Lifecycle INSTANCE = null;
51
52 /**
53 * Gets the singleton instance.
54 *
55 * @return never null
56 */
57 public synchronized static Lifecycle get() {
58 if(INSTANCE==null) {
59 Lifecycle instance;
60 String p = System.getProperty("hudson.lifecycle");
61 if(p!=null) {
62 try {
63 ClassLoader cl = Jenkins.getInstance().getPluginManager().uberClassLoader;
64 instance = (Lifecycle)cl.loadClass(p).newInstance();
65 } catch (InstantiationException e) {
66 InstantiationError x = new InstantiationError(e.getMessage());
67 x.initCause(e);
68 throw x;
69 } catch (IllegalAccessException e) {
70 IllegalAccessError x = new IllegalAccessError(e.getMessage());
71 x.initCause(e);
72 throw x;
73 } catch (ClassNotFoundException e) {
74 NoClassDefFoundError x = new NoClassDefFoundError(e.getMessage());
75 x.initCause(e);
76 throw x;
77 }
78 } else {
79 if(Functions.isWindows()) {
80 instance = new Lifecycle() {
81 @Override
82 public void verifyRestartable() throws RestartNotSupportedException {
83 throw new RestartNotSupportedException(
84 "Default Windows lifecycle does not support restart.");
85 }
86 };
87 } else if (System.getenv("SMF_FMRI")!=null && System.getenv("SMF_RESTARTER")!=null) {
88 // when we are run by Solaris SMF, these environment variables are set.
89 instance = new SolarisSMFLifecycle();
90 } else {
91 // if run on Unix, we can do restart
92 try {
93 instance = new UnixLifecycle();
94 } catch (final IOException e) {
95 LOGGER.log(Level.WARNING, "Failed to install embedded lifecycle implementation",e);
96 instance = new Lifecycle() {
97 @Override
98 public void verifyRestartable() throws RestartNotSupportedException {
99 throw new RestartNotSupportedException(
100 "Failed to install embedded lifecycle implementation, so cannot restart: " + e, e);
101 }
102 };
103 }
104 }
105 }
106 assert instance != null;
107 INSTANCE = instance;
108 }
109
110 return INSTANCE;
111 }
112
113 /**
114 * If the location of <tt>jenkins.war</tt> is known in this life cycle,
115 * return it location. Otherwise return null to indicate that it is unknown.
116 *
117 * <p>
118 * When a non-null value is returned, Hudson will offer an upgrade UI
119 * to a newer version.
120 */
121 public File getHudsonWar() {
122 String war = System.getProperty("executable-war");
123 if(war!=null && new File(war).exists())
124 return new File(war);
125 return null;
126 }
127
128 /**
129 * Replaces jenkins.war by the given file.
130 *
131 * <p>
132 * On some system, most notably Windows, a file being in use cannot be changed,
133 * so rewriting <tt>jenkins.war</tt> requires some special trick. Override this method
134 * to do so.
135 */
136 public void rewriteHudsonWar(File by) throws IOException {
137 File dest = getHudsonWar();
138 // this should be impossible given the canRewriteHudsonWar method,
139 // but let's be defensive
140 if(dest==null) throw new IOException("jenkins.war location is not known.");
141
142 // backing up the old jenkins.war before it gets lost due to upgrading
143 // (newly downloaded jenkins.war and 'backup' (jenkins.war.tmp) are the same files
144 // unless we are trying to rewrite jenkins.war by a backup itself
145 File bak = new File(dest.getPath() + ".bak");
146 if (!by.equals(bak))
147 FileUtils.copyFile(dest, bak);
148
149 FileUtils.copyFile(by, dest);
150 // we don't want to keep backup if we are downgrading
151 if (by.equals(bak)&&bak.exists())
152 bak.delete();
153 }
154
155 /**
156 * Can {@link #rewriteHudsonWar(File)} work?
157 */
158 public boolean canRewriteHudsonWar() {
159 // if we don't know where jenkins.war is, it's impossible to replace.
160 File f = getHudsonWar();
161 return f!=null && f.canWrite();
162 }
163
164 /**
165 * If this life cycle supports a restart of Hudson, do so.
166 * Otherwise, throw {@link UnsupportedOperationException},
167 * which is what the default implementation does.
168 *
169 * <p>
170 * The restart operation may happen synchronously (in which case
171 * this method will never return), or asynchronously (in which
172 * case this method will successfully return.)
173 *
174 * <p>
175 * Throw an exception if the operation fails unexpectedly.
176 */
177 public void restart() throws IOException, InterruptedException {
178 throw new UnsupportedOperationException();
179 }
180
181 /**
182 * Can the {@link #restart()} method restart Hudson?
183 *
184 * @throws RestartNotSupportedException
185 * If the restart is not supported, throw this exception and explain the cause.
186 */
187 public void verifyRestartable() throws RestartNotSupportedException {
188 // the rewriteHudsonWar method isn't overridden.
189 if (!Util.isOverridden(Lifecycle.class,getClass(), "restart"))
190 throw new RestartNotSupportedException("Restart is not supported in this running mode (" +
191 getClass().getName() + ").");
192 }
193
194 /**
195 * The same as {@link #verifyRestartable()} except the status is indicated by the return value,
196 * not by an exception.
197 */
198 public boolean canRestart() {
199 try {
200 verifyRestartable();
201 return true;
202 } catch (RestartNotSupportedException e) {
203 return false;
204 }
205 }
206
207 private static final Logger LOGGER = Logger.getLogger(Lifecycle.class.getName());
208 }
209