1 /**
2 *
3 * Copyright 2004 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.geronimo.gbuild.agent;
18
19 import org.codehaus.plexus.logging.AbstractLogEnabled;
20 import org.codehaus.plexus.util.cli.CommandLineException;
21 import org.codehaus.plexus.util.cli.CommandLineUtils;
22 import org.codehaus.plexus.util.cli.Commandline;
23
24 import java.io.File;
25 import java.util.Map;
26 import java.util.List;
27 import java.util.ArrayList;
28
29 /**
30 * @version $Rev$ $Date$
31 */
32 public class KillProcessesExtension extends AbstractLogEnabled implements BuildAgentExtension {
33
34 /**
35 * @plexus.requirement
36 */
37 private BuildActivityNotifier notifier;
38
39 private String regex;
40
41 public void preProcess(Map build) {
42 }
43
44 public void postProcess(Map build, Map results) {
45 boolean isWindows = System.getProperty("os.name").startsWith("Windows");
46
47 if (isWindows){
48 return;
49 }
50
51 String[] ids = null;
52
53 List pids = null;
54 try {
55 pids = findProcessIds(regex);
56 } catch (Exception e) {
57 getLogger().warn("Failed to get a list of running processes. ", e);
58 return;
59 }
60
61 String processes = "";
62 for (int i = 0; i < pids.size(); i++) {
63 String pid = (String) pids.get(i);
64 processes += pid +", ";
65 }
66
67 processes = processes.replaceAll(", $","");
68
69 if (pids.size() > 0){
70
71 String message = "Found " + pids.size()+ " processes matching \""+regex+"\" (" + processes + ").";
72
73 results.put("header.hung-processes", processes);
74 getLogger().info(message);
75 notifier.sendNotification(build, message);
76
77 try {
78 killProcesses(pids);
79 } catch (Exception e) {
80 getLogger().error("Unable to kill "+pids.size()+" processes matching \""+regex+"\" (" + processes + ").", e);
81 }
82
83 } else {
84 getLogger().debug("No processes found matching \""+regex+"\".");
85 }
86 }
87
88 public static void killProcesses(List pids) throws Exception {
89 ExecResult res = exec("kill", (String[]) pids.toArray(new String[]{}));
90 if (res.exitCode != 0){
91 throw new IllegalStateException("Command returned error exit code " + res.exitCode + ".");
92 }
93 }
94
95 public static List findProcessIds(String regex) throws Exception {
96 ExecResult res = exec("sh", new String[]{"-c","\"ps ax\""});
97 if (res.exitCode != 0){
98 throw new IllegalStateException("Command returned error exit code " + res.exitCode + ".");
99 }
100 String stdout = res.getStdout();
101 String[] lines = stdout.split("[\n\r]");
102 List list = new ArrayList();
103 for (int i = 0; i < lines.length; i++) {
104 String line = lines[i];
105 if (line.matches(regex)){
106 line = line.replaceFirst(" *","");
107 String pid = line.split(" +")[0];
108 list.add(pid);
109 }
110 }
111 return list;
112 }
113
114 public static class ExecResult {
115 private final int exitCode;
116 private final String stdout;
117 private final String stderr;
118
119 public ExecResult(int exitCode, String stdout, String stderr) {
120 this.exitCode = exitCode;
121 this.stdout = stdout;
122 this.stderr = stderr;
123 }
124
125 public int getExitCode() {
126 return exitCode;
127 }
128
129 public String getStdout() {
130 return stdout;
131 }
132
133 public String getStderr() {
134 return stderr;
135 }
136 }
137
138 public static ExecResult exec(String cmd, String[] arguments) throws CommandLineException {
139 Commandline commandline = new Commandline();
140 commandline.setExecutable(cmd);
141 commandline.setWorkingDirectory(new File(".").getAbsolutePath());
142
143 for (int i = 0; i < arguments.length; i++) {
144 commandline.createArgument().setLine(arguments[i]);
145 }
146
147 CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
148 CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
149 int exitCode = CommandLineUtils.executeCommandLine(commandline, stdout, stderr);
150 return new ExecResult(exitCode, stdout.getOutput(), stderr.getOutput());
151 }
152
153 }