/*
* Copyright (c) 2013 Technische Universitat Wien (TUW), Distributed Systems Group. http://dsg.tuwien.ac.at
*
* This work was partially supported by the European Commission in terms of the CELAR FP7 project (FP7-ICT-2011-8 #317790), http://www.celarcloud.eu/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package at.ac.tuwien.dsg.cloud.salsa.pioneer.utils;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
public class SystemFunctions {
static org.slf4j.Logger logger = PioneerConfiguration.logger;
private final static File envFileGlobal = new File("/etc/environment");
// write to a /etc/profile.d and the /etc/environment
// the format is metric=value;metric2=value2
public static void writeSystemVariable(String keyAndValue) {
try {
String[] pairs=keyAndValue.split(";");
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(envFileGlobal.getPath(), true)));
for (String s:pairs){
out.println(s +"\n");
}
out.flush();
out.close();
} catch (IOException e) {
logger.error("Could not write in config file. Error: " + e);
}
}
public static String getEth0IPAddress() {
// copy the getEth0IPv4 to /tmp and execute it, return the value
URL inputUrl = SystemFunctions.class.getResource("/scripts/getEth0IPv4.sh");
File dest = new File("/tmp/getEth0IPv4.sh");
try {
FileUtils.copyURLToFile(inputUrl, dest);
} catch (IOException ex) {
ex.printStackTrace();
}
return executeCommandGetFirstLineOutput("/bin/bash /tmp/getEth0IPv4.sh", "/tmp", null);
}
/**
* Run a command and wait, return the first line of the output
*
* @param cmd The command to run
* @param workingDir The folder where the command is run
* @param executeFrom For logging message to the center of where to execute the command.
* @return
*/
public static String executeCommandGetFirstLineOutput(String cmd, String workingDir, String executeFrom) {
logger.debug("Execute command: " + cmd);
if (workingDir == null) {
workingDir = "/tmp";
}
String[] splitStr = cmd.split("\\s+");
ProcessBuilder pb = new ProcessBuilder(splitStr);
pb.directory(new File(workingDir));
pb = pb.redirectErrorStream(true); // this is important to redirect the error stream to output stream, prevent blocking with long output
Map<String, String> env = pb.environment();
String path = env.get("PATH");
path = path + File.pathSeparator + "/usr/bin:/usr/sbin";
logger.debug("PATH to execute command: " + pb.environment().get("PATH"));
env.put("PATH", path);
try {
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String output = reader.readLine();
String line;
while ((line = reader.readLine()) != null) {
logger.debug(line);
}
p.waitFor();
while ((line = reader.readLine()) != null) {
logger.debug(line + "[buffered]");
}
logger.debug("Execute Command output: " + output.trim());
p.getInputStream().close();
if (p.exitValue() == 0) {
logger.debug("Command exit 0, result: " + output.trim());
return output.trim();
} else {
logger.debug("Command return non zero code: " + p.exitValue());
return null;
}
} catch (InterruptedException | IOException e1) {
logger.error("Error when execute command. Error: " + e1);
e1.printStackTrace();
}
return null;
}
public static int executeCommandGetReturnCode(String cmd, String workingDir, String executeFrom) {
// try {
// String[] splitStr = cmd.split("\\s+");
// ManagedProcessBuilder builder = new ManagedProcessBuilder(new File(splitStr[0]));
// if (splitStr.length>1){
// for(String s: splitStr){
// builder.addArgument(s);
// }
// }
//// ManagedProcessBuilder builder = new ManagedProcessBuilder(cmd);
// builder.setWorkingDirectory(new File(workingDir));
//
// String path = builder.getEnvironment().get("PATH");
// if (path == null){
// path="/usr/bin:/usr/sbin";
// } else {
// path = path + File.pathSeparator + "/usr/bin:/usr/sbin";
// }
// builder.getEnvironment().put("PATH", path);
// ManagedProcess p = builder.build();
//
// p.start();
// p.waitForExit();
// return p.exitValue();
return executeCommandGetReturnCode(cmd, workingDir, executeFrom, 0);
// } catch (ManagedProcessException ex) {
// logger.error("error when execute command: {}, error: {}, cause: {}", cmd, ex.getMessage(), ex.getCause());
//
// ex.printStackTrace();
// return 1;
// }
}
public static int executeCommandGetReturnCode(String cmd, String workingDir, String executeFrom, long timeout) {
logger.debug("Execute command: " + cmd);
if (workingDir == null) {
workingDir = "/tmp";
}
try {
String[] splitStr = cmd.split("\\s+");
ProcessBuilder pb = new ProcessBuilder(splitStr);
pb.directory(new File(workingDir));
pb = pb.redirectErrorStream(true); // this is important to redirect the error stream to output stream, prevent blocking with long output
Map<String, String> env = pb.environment();
String path = env.get("PATH");
path = path + File.pathSeparator + "/usr/bin:/usr/sbin";
//logger.debug("PATH to execute command: " + pb.environment().get("PATH"));
env.put("PATH", path);
Process p = pb.start();
logger.debug("Process started: " + cmd);
// InputStream is = p.getInputStream();
// int c;
// while ((c = is.read()) != -1) {
// System.out.print((char) c);
// }
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
logger.debug(line);
}
// StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), System.out);
// StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), System.out);
//
// errorGobbler.start();
// outputGobbler.start();
int returnCode = -1;
if (timeout == 0) {
p.waitFor();
returnCode = p.exitValue();
} else {
boolean finished = p.waitFor(timeout, TimeUnit.SECONDS);
if (finished) {
returnCode = p.exitValue();
} else {
logger.error("Command " + cmd + " is blocked and interrupted after " + timeout + " seconds");
}
}
while ((line = reader.readLine()) != null) {
logger.debug(line + "[buffered]");
}
// errorGobbler.join(); // Handle condition where the
// outputGobbler.join(); // process ends before the threads finish
logger.debug("Execute command done: " + cmd + ". Get return code: " + returnCode);
return returnCode;
} catch (InterruptedException | IOException e1) {
logger.error("Error when execute command. Error: " + e1);
e1.printStackTrace();
} catch (Exception e) {
logger.error("Unknown error when execute command: " + e.getMessage());
e.printStackTrace();
}
return -1;
}
static class StreamGobbler extends Thread {
InputStream is;
PrintStream os;
StreamGobbler(InputStream is, PrintStream os) {
this.is = is;
this.os = os;
}
@Override
public void run() {
try {
int c;
while ((c = is.read()) != -1) {
os.print((char) c);
}
} catch (IOException x) {
x.printStackTrace();
}
}
}
}