UX tweaks, better output request behaviour
This commit is contained in:
parent
88e745346e
commit
55b77789c3
7 changed files with 62 additions and 43 deletions
|
|
@ -54,8 +54,8 @@ public class JobServClient {
|
||||||
try {
|
try {
|
||||||
return Integer.parseInt(this.programArgs[index]);
|
return Integer.parseInt(this.programArgs[index]);
|
||||||
|
|
||||||
} catch (InputMismatchException e) {
|
} catch (NumberFormatException e) {
|
||||||
System.out.println(this.programArgs[index] + " is not a valid int, much less a valid pid");
|
System.out.println(this.programArgs[index] + " is not a valid integer");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,9 +69,9 @@ public class JobServClient {
|
||||||
System.out.println("... new (command)\n"+
|
System.out.println("... new (command)\n"+
|
||||||
"Starts a new process on the server\n"+
|
"Starts a new process on the server\n"+
|
||||||
"example: ./client key.pem cert.crt ca.crt localhost 8448 new echo hello world!\n\n"+
|
"example: ./client key.pem cert.crt ca.crt localhost 8448 new echo hello world!\n\n"+
|
||||||
"... output (pid)\n"+
|
"... output (pid) (lines)\n"+
|
||||||
"Garners output from process on server\n"+
|
"Garners (lines) lines of output from process (pid) on server\n"+
|
||||||
"example: ./client key.pem cert.crt ca.crt localhost 8448 output 0\n\n"+
|
"example: ./client key.pem cert.crt ca.crt localhost 8448 output 0 5\n\n"+
|
||||||
"... status (pid)\n"+
|
"... status (pid)\n"+
|
||||||
"Returns whether process on server is running"+
|
"Returns whether process on server is running"+
|
||||||
"example: ./client key.pem cert.crt ca.crt localhost 8448 status 0\n\n"+
|
"example: ./client key.pem cert.crt ca.crt localhost 8448 status 0\n\n"+
|
||||||
|
|
@ -88,11 +88,6 @@ public class JobServClient {
|
||||||
* makes a new process
|
* makes a new process
|
||||||
*/
|
*/
|
||||||
public void makeNewProcess() {
|
public void makeNewProcess() {
|
||||||
if (this.programArgs.length < 6) {
|
|
||||||
System.out.println("Improper formatting, try client --help");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String command = "";
|
String command = "";
|
||||||
for (int token = 6; token < this.programArgs.length; token++) {
|
for (int token = 6; token < this.programArgs.length; token++) {
|
||||||
command += " " + this.programArgs[token];
|
command += " " + this.programArgs[token];
|
||||||
|
|
@ -121,12 +116,18 @@ public class JobServClient {
|
||||||
* gets output from a process
|
* gets output from a process
|
||||||
*/
|
*/
|
||||||
public void getOutput() {
|
public void getOutput() {
|
||||||
|
if (this.programArgs.length < 8) {
|
||||||
|
System.out.println("Improper formatting, need a lines and a pid argument.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int candidatePid = this.getPidArg(6);
|
int candidatePid = this.getPidArg(6);
|
||||||
|
int lines = this.getPidArg(7);
|
||||||
if (candidatePid < 0) {
|
if (candidatePid < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String processOutput = this.api.getProcessOutput(candidatePid);
|
String processOutput = this.api.getProcessOutput(candidatePid, lines);
|
||||||
System.out.println(processOutput);
|
System.out.println(processOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,11 +63,12 @@ class JobServClientAPIConnector {
|
||||||
* sends the server a request for output from the process identified by 'pid'
|
* sends the server a request for output from the process identified by 'pid'
|
||||||
* returns process output as string
|
* returns process output as string
|
||||||
*/
|
*/
|
||||||
public String getProcessOutput(int pid) {
|
public String getProcessOutput(int pid, int lines) {
|
||||||
logger.info("[+] requesting output");
|
logger.info("[+] requesting output");
|
||||||
|
|
||||||
PIDMessage request = PIDMessage.newBuilder()
|
OutputRequestMessage request = OutputRequestMessage.newBuilder()
|
||||||
.setPid(pid)
|
.setPid(pid)
|
||||||
|
.setLines(lines)
|
||||||
.build();
|
.build();
|
||||||
OutputMessage response;
|
OutputMessage response;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,11 @@
|
||||||
|
|
||||||
package JobServ;
|
package JobServ;
|
||||||
|
|
||||||
import java.util.Scanner;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ProcessController
|
* ProcessController
|
||||||
|
|
@ -28,7 +29,8 @@ class ProcessController {
|
||||||
// interactive processes (out of scope for initial API)
|
// interactive processes (out of scope for initial API)
|
||||||
private OutputStream output;
|
private OutputStream output;
|
||||||
private InputStream input;
|
private InputStream input;
|
||||||
private Scanner outputScanner;
|
private InputStreamReader inputIntermediateStream;
|
||||||
|
private BufferedReader reader;
|
||||||
|
|
||||||
private Process process;
|
private Process process;
|
||||||
|
|
||||||
|
|
@ -46,8 +48,8 @@ class ProcessController {
|
||||||
this.process = Runtime.getRuntime().exec(command);
|
this.process = Runtime.getRuntime().exec(command);
|
||||||
this.output = this.process.getOutputStream();
|
this.output = this.process.getOutputStream();
|
||||||
this.input = this.process.getInputStream();
|
this.input = this.process.getInputStream();
|
||||||
this.outputScanner = new Scanner(this.input);
|
this.inputIntermediateStream = new InputStreamReader(this.input);
|
||||||
this.outputScanner.useDelimiter("\\A");
|
this.reader = new BufferedReader(this.inputIntermediateStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -61,9 +63,6 @@ class ProcessController {
|
||||||
/*
|
/*
|
||||||
* getStatus()
|
* getStatus()
|
||||||
* returns whether or not the process is running
|
* returns whether or not the process is running
|
||||||
* this isnt a very direct way of getting the information
|
|
||||||
* The alternative is to use reflection to get into the private UNIXProcess class
|
|
||||||
* for the PID and to check that against 'ps' or a similar command
|
|
||||||
*
|
*
|
||||||
* TODO: (for future release) return thread state
|
* TODO: (for future release) return thread state
|
||||||
*/
|
*/
|
||||||
|
|
@ -85,7 +84,7 @@ class ProcessController {
|
||||||
* returns the exit code of the process
|
* returns the exit code of the process
|
||||||
* 256 if process is still running
|
* 256 if process is still running
|
||||||
* 257 if process was killed manually and no longer exists
|
* 257 if process was killed manually and no longer exists
|
||||||
* (unix/posix defines an exit code as a uint8, so 256 is fair game)
|
* (unix/posix defines an exit code as a uint8, so 256+ is fair game)
|
||||||
*/
|
*/
|
||||||
public int getReturn() {
|
public int getReturn() {
|
||||||
if (this.killedManually) {
|
if (this.killedManually) {
|
||||||
|
|
@ -103,17 +102,23 @@ class ProcessController {
|
||||||
* getOutput()
|
* getOutput()
|
||||||
* gets output from process
|
* gets output from process
|
||||||
*/
|
*/
|
||||||
public String getOutput() {
|
public String getOutput(int lines) {
|
||||||
if (this.killedManually) {
|
String output = "";
|
||||||
return "";
|
for (int i = 0; i < lines; i++) {
|
||||||
|
String newLine = null;
|
||||||
|
try {
|
||||||
|
newLine = reader.readLine();
|
||||||
|
} catch (IOException e) {
|
||||||
|
newLine = "[-] SERVER: error reading process output: " + e.getMessage();
|
||||||
|
} finally {
|
||||||
|
if (newLine != null) {
|
||||||
|
output += newLine + "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String out = "";
|
|
||||||
while(outputScanner.hasNext()) {
|
|
||||||
out += outputScanner.next();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -121,15 +126,20 @@ class ProcessController {
|
||||||
* Cleans up resources and destroys process
|
* Cleans up resources and destroys process
|
||||||
*/
|
*/
|
||||||
public void kill() {
|
public void kill() {
|
||||||
|
if (this.killedManually) {
|
||||||
|
System.err.println("[~] Tried to kill already killed process");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.input.close();
|
this.input.close();
|
||||||
this.output.close();
|
this.output.close();
|
||||||
this.outputScanner.close();
|
this.inputIntermediateStream.close();
|
||||||
|
this.reader.close();
|
||||||
this.process.destroy();
|
this.process.destroy();
|
||||||
} catch (IOException e) {
|
|
||||||
// streams already closed
|
|
||||||
}
|
|
||||||
|
|
||||||
this.killedManually = true;
|
this.killedManually = true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("[-] Killing process failed: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ class ProcessManager {
|
||||||
* returns output of process 'pid'
|
* returns output of process 'pid'
|
||||||
* or returns description of error
|
* or returns description of error
|
||||||
*/
|
*/
|
||||||
public String getProcessOutput(int pid) {
|
public String getProcessOutput(int pid, int lines) {
|
||||||
try {
|
try {
|
||||||
if(!this.getLock(pid)) {
|
if(!this.getLock(pid)) {
|
||||||
return "[-] SERVER: Process not found";
|
return "[-] SERVER: Process not found";
|
||||||
|
|
@ -152,7 +152,7 @@ class ProcessManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessController candidate = this.processMap.get(pid);
|
ProcessController candidate = this.processMap.get(pid);
|
||||||
String output = candidate.getOutput();
|
String output = candidate.getOutput(lines);
|
||||||
this.releaseLock(pid);
|
this.releaseLock(pid);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,10 +47,11 @@ class ShellServerService extends ShellServerGrpc.ShellServerImplBase {
|
||||||
* implements api endpoint as defined in jobserv.proto
|
* implements api endpoint as defined in jobserv.proto
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void getOutput(PIDMessage request,
|
public void getOutput(OutputRequestMessage request,
|
||||||
StreamObserver<OutputMessage> responder) {
|
StreamObserver<OutputMessage> responder) {
|
||||||
|
|
||||||
String output = manager.getProcessOutput(request.getPid());
|
String output = manager.getProcessOutput(request.getPid(),
|
||||||
|
request.getLines());
|
||||||
|
|
||||||
OutputMessage reply = OutputMessage.newBuilder()
|
OutputMessage reply = OutputMessage.newBuilder()
|
||||||
.setOutput(output)
|
.setOutput(output)
|
||||||
|
|
@ -67,7 +68,8 @@ class ShellServerService extends ShellServerGrpc.ShellServerImplBase {
|
||||||
public void newJob(NewJobMessage request,
|
public void newJob(NewJobMessage request,
|
||||||
StreamObserver<PIDMessage> responder) {
|
StreamObserver<PIDMessage> responder) {
|
||||||
|
|
||||||
int newPid = manager.newProcess(request.getCommand());
|
String command = request.getCommand();
|
||||||
|
int newPid = manager.newProcess(command);
|
||||||
|
|
||||||
PIDMessage reply = PIDMessage.newBuilder()
|
PIDMessage reply = PIDMessage.newBuilder()
|
||||||
.setPid(newPid)
|
.setPid(newPid)
|
||||||
|
|
@ -101,7 +103,7 @@ class ShellServerService extends ShellServerGrpc.ShellServerImplBase {
|
||||||
public void killJob(PIDMessage request,
|
public void killJob(PIDMessage request,
|
||||||
StreamObserver<StatusMessage> responder) {
|
StreamObserver<StatusMessage> responder) {
|
||||||
|
|
||||||
int status = manager.getProcessStatus(request.getPid());
|
int status = manager.killProcess(request.getPid());
|
||||||
|
|
||||||
StatusMessage reply = StatusMessage.newBuilder()
|
StatusMessage reply = StatusMessage.newBuilder()
|
||||||
.setProcessStatus(status)
|
.setProcessStatus(status)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ package JobServ;
|
||||||
service ShellServer {
|
service ShellServer {
|
||||||
rpc getStatus (PIDMessage) returns (StatusMessage) {}
|
rpc getStatus (PIDMessage) returns (StatusMessage) {}
|
||||||
rpc getReturn (PIDMessage) returns (ReturnMessage) {}
|
rpc getReturn (PIDMessage) returns (ReturnMessage) {}
|
||||||
rpc getOutput (PIDMessage) returns (OutputMessage) {}
|
rpc getOutput (OutputRequestMessage) returns (OutputMessage) {}
|
||||||
rpc killJob (PIDMessage) returns (StatusMessage) {}
|
rpc killJob (PIDMessage) returns (StatusMessage) {}
|
||||||
rpc newJob (NewJobMessage) returns (PIDMessage) {}
|
rpc newJob (NewJobMessage) returns (PIDMessage) {}
|
||||||
}
|
}
|
||||||
|
|
@ -23,6 +23,11 @@ message ReturnMessage {
|
||||||
int32 ProcessReturnCode = 1;
|
int32 ProcessReturnCode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message OutputRequestMessage {
|
||||||
|
int32 Pid = 1;
|
||||||
|
int32 Lines = 2;
|
||||||
|
}
|
||||||
|
|
||||||
message OutputMessage {
|
message OutputMessage {
|
||||||
string Output = 1;
|
string Output = 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ public class ProcessManagerTest {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
String out = manager.getProcessOutput(pid);
|
String out = manager.getProcessOutput(pid, 2);
|
||||||
assertEquals("test\n", out); // calls string.equals()
|
assertEquals("test\n", out); // calls string.equals()
|
||||||
|
|
||||||
manager.shutdown();
|
manager.shutdown();
|
||||||
|
|
@ -159,7 +159,7 @@ public class ProcessManagerTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void getUnknownOutputTest() {
|
public void getUnknownOutputTest() {
|
||||||
String out = manager.getProcessOutput(532);
|
String out = manager.getProcessOutput(532, 10);
|
||||||
assertEquals("[-] SERVER: Process not found", out);
|
assertEquals("[-] SERVER: Process not found", out);
|
||||||
manager.shutdown();
|
manager.shutdown();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue