blob: 95d5c86b17adecbed176da13d6727279ef46c66c [file] [log] [blame]
Thomas Vachuskaf9c84362015-04-15 11:20:45 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onlab.stc;
17
18import java.io.BufferedReader;
19import java.io.File;
20import java.io.IOException;
21import java.io.InputStream;
22import java.io.InputStreamReader;
23import java.io.PrintWriter;
24
Thomas Vachuska4bfccd542015-05-30 00:35:25 -070025import static java.lang.String.format;
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070026import static org.onlab.stc.Coordinator.print;
27
28/**
29 * Manages execution of the specified step or a group.
30 */
31class StepProcessor implements Runnable {
32
33 private static final int FAIL = -1;
34
35 static String launcher = "stc-launcher ";
36
37 private final Step step;
38 private final boolean skip;
39 private final File logDir;
40
41 private Process process;
42 private StepProcessListener delegate;
43
44 /**
45 * Creates a process monitor.
46 *
47 * @param step step or group to be executed
48 * @param skip indicates the process should not actually execute
49 * @param logDir directory where step process log should be stored
50 * @param delegate process lifecycle listener
51 */
52 StepProcessor(Step step, boolean skip, File logDir, StepProcessListener delegate) {
53 this.step = step;
54 this.skip = skip;
55 this.logDir = logDir;
56 this.delegate = delegate;
57 }
58
59 @Override
60 public void run() {
61 int code = FAIL;
62 delegate.onStart(step);
63 if (!skip) {
64 code = execute();
65 }
66 delegate.onCompletion(step, code);
67 }
68
69 /**
70 * Executes the step process.
71 *
72 * @return exit code
73 */
74 private int execute() {
Thomas Vachuska4bfccd542015-05-30 00:35:25 -070075 try (PrintWriter pw = new PrintWriter(logFile())) {
76 process = Runtime.getRuntime().exec(command());
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070077 processOutput(pw);
78
79 // Wait for the process to complete and get its exit code.
80 if (process.isAlive()) {
81 process.waitFor();
82 }
83 return process.exitValue();
84
85 } catch (IOException e) {
86 print("Unable to run step %s using command %s", step.name(), step.command());
87 } catch (InterruptedException e) {
88 print("Step %s interrupted", step.name());
89 }
90 return FAIL;
91 }
92
93 /**
Thomas Vachuska4bfccd542015-05-30 00:35:25 -070094 * Returns ready-to-run command for the step.
95 *
96 * @return command to execute
97 */
98 private String command() {
99 return format("%s %s %s %s", launcher,
100 step.env() != null ? step.env() : "-",
101 step.cwd() != null ? step.cwd() : "-",
102 step.command());
103 }
104
105 /**
Thomas Vachuskaf9c84362015-04-15 11:20:45 -0700106 * Captures output of the step process.
107 *
108 * @param pw print writer to send output to
109 * @throws IOException if unable to read output or write logs
110 */
111 private void processOutput(PrintWriter pw) throws IOException {
112 InputStream out = process.getInputStream();
113 BufferedReader br = new BufferedReader(new InputStreamReader(out));
114
115 // Slurp its combined stderr/stdout
116 String line;
117 while ((line = br.readLine()) != null) {
118 pw.println(line);
119 delegate.onOutput(step, line);
120 }
121 }
122
123 /**
Thomas Vachuska4bfccd542015-05-30 00:35:25 -0700124 * Returns the log file for the step output.
Thomas Vachuskaf9c84362015-04-15 11:20:45 -0700125 *
Thomas Vachuskaf9c84362015-04-15 11:20:45 -0700126 * @return log file
127 */
Thomas Vachuska4bfccd542015-05-30 00:35:25 -0700128 private File logFile() {
Thomas Vachuskaf9c84362015-04-15 11:20:45 -0700129 return new File(logDir, step.name() + ".log");
130 }
131
132}