Add commands (#2)

* Add remote command execution

* Add tests for environment variables and resize

* Fix tab spacing, add newlines

* Remove extra newline

* Add fork
This commit is contained in:
Kyle Carberry
2019-01-12 13:44:29 -06:00
parent a06854a937
commit d61873e8da
16 changed files with 744 additions and 109 deletions

View File

@@ -3,29 +3,29 @@ import "command.proto";
import "node.proto";
message ClientMessage {
oneof msg {
// command.proto
NewSessionMessage new_session = 1;
ShutdownSessionMessage shutdown_session = 2;
WriteToSessionMessage write_to_session = 3;
CloseSessionInputMessage close_session_input = 4;
ResizeSessionTTYMessage resize_session_tty = 5;
// node.proto
NewEvalMessage new_eval = 6;
}
oneof msg {
// command.proto
NewSessionMessage new_session = 1;
ShutdownSessionMessage shutdown_session = 2;
WriteToSessionMessage write_to_session = 3;
CloseSessionInputMessage close_session_input = 4;
ResizeSessionTTYMessage resize_session_tty = 5;
// node.proto
NewEvalMessage new_eval = 6;
}
}
message ServerMessage {
oneof msg {
// command.proto
NewSessionFailureMessage new_session_failure = 1;
SessionDoneMessage session_done = 2;
SessionOutputMessage session_output = 3;
// node.proto
EvalFailedMessage eval_failed = 4;
EvalDoneMessage eval_done = 5;
}
}
oneof msg {
// command.proto
NewSessionFailureMessage new_session_failure = 1;
SessionDoneMessage session_done = 2;
SessionOutputMessage session_output = 3;
IdentifySessionMessage identify_session = 4;
// node.proto
EvalFailedMessage eval_failed = 5;
EvalDoneMessage eval_done = 6;
}
}

View File

@@ -84,6 +84,11 @@ export class ServerMessage extends jspb.Message {
getSessionOutput(): command_pb.SessionOutputMessage | undefined;
setSessionOutput(value?: command_pb.SessionOutputMessage): void;
hasIdentifySession(): boolean;
clearIdentifySession(): void;
getIdentifySession(): command_pb.IdentifySessionMessage | undefined;
setIdentifySession(value?: command_pb.IdentifySessionMessage): void;
hasEvalFailed(): boolean;
clearEvalFailed(): void;
getEvalFailed(): node_pb.EvalFailedMessage | undefined;
@@ -110,6 +115,7 @@ export namespace ServerMessage {
newSessionFailure?: command_pb.NewSessionFailureMessage.AsObject,
sessionDone?: command_pb.SessionDoneMessage.AsObject,
sessionOutput?: command_pb.SessionOutputMessage.AsObject,
identifySession?: command_pb.IdentifySessionMessage.AsObject,
evalFailed?: node_pb.EvalFailedMessage.AsObject,
evalDone?: node_pb.EvalDoneMessage.AsObject,
}
@@ -119,8 +125,9 @@ export namespace ServerMessage {
NEW_SESSION_FAILURE = 1,
SESSION_DONE = 2,
SESSION_OUTPUT = 3,
EVAL_FAILED = 4,
EVAL_DONE = 5,
IDENTIFY_SESSION = 4,
EVAL_FAILED = 5,
EVAL_DONE = 6,
}
}

View File

@@ -465,7 +465,7 @@ if (goog.DEBUG && !COMPILED) {
* @private {!Array<!Array<number>>}
* @const
*/
proto.ServerMessage.oneofGroups_ = [[1,2,3,4,5]];
proto.ServerMessage.oneofGroups_ = [[1,2,3,4,5,6]];
/**
* @enum {number}
@@ -475,8 +475,9 @@ proto.ServerMessage.MsgCase = {
NEW_SESSION_FAILURE: 1,
SESSION_DONE: 2,
SESSION_OUTPUT: 3,
EVAL_FAILED: 4,
EVAL_DONE: 5
IDENTIFY_SESSION: 4,
EVAL_FAILED: 5,
EVAL_DONE: 6
};
/**
@@ -517,6 +518,7 @@ proto.ServerMessage.toObject = function(includeInstance, msg) {
newSessionFailure: (f = msg.getNewSessionFailure()) && command_pb.NewSessionFailureMessage.toObject(includeInstance, f),
sessionDone: (f = msg.getSessionDone()) && command_pb.SessionDoneMessage.toObject(includeInstance, f),
sessionOutput: (f = msg.getSessionOutput()) && command_pb.SessionOutputMessage.toObject(includeInstance, f),
identifySession: (f = msg.getIdentifySession()) && command_pb.IdentifySessionMessage.toObject(includeInstance, f),
evalFailed: (f = msg.getEvalFailed()) && node_pb.EvalFailedMessage.toObject(includeInstance, f),
evalDone: (f = msg.getEvalDone()) && node_pb.EvalDoneMessage.toObject(includeInstance, f)
};
@@ -571,11 +573,16 @@ proto.ServerMessage.deserializeBinaryFromReader = function(msg, reader) {
msg.setSessionOutput(value);
break;
case 4:
var value = new command_pb.IdentifySessionMessage;
reader.readMessage(value,command_pb.IdentifySessionMessage.deserializeBinaryFromReader);
msg.setIdentifySession(value);
break;
case 5:
var value = new node_pb.EvalFailedMessage;
reader.readMessage(value,node_pb.EvalFailedMessage.deserializeBinaryFromReader);
msg.setEvalFailed(value);
break;
case 5:
case 6:
var value = new node_pb.EvalDoneMessage;
reader.readMessage(value,node_pb.EvalDoneMessage.deserializeBinaryFromReader);
msg.setEvalDone(value);
@@ -642,18 +649,26 @@ proto.ServerMessage.prototype.serializeBinaryToWriter = function (writer) {
command_pb.SessionOutputMessage.serializeBinaryToWriter
);
}
f = this.getEvalFailed();
f = this.getIdentifySession();
if (f != null) {
writer.writeMessage(
4,
f,
command_pb.IdentifySessionMessage.serializeBinaryToWriter
);
}
f = this.getEvalFailed();
if (f != null) {
writer.writeMessage(
5,
f,
node_pb.EvalFailedMessage.serializeBinaryToWriter
);
}
f = this.getEvalDone();
if (f != null) {
writer.writeMessage(
5,
6,
f,
node_pb.EvalDoneMessage.serializeBinaryToWriter
);
@@ -761,18 +776,48 @@ proto.ServerMessage.prototype.hasSessionOutput = function() {
/**
* optional EvalFailedMessage eval_failed = 4;
* optional IdentifySessionMessage identify_session = 4;
* @return {proto.IdentifySessionMessage}
*/
proto.ServerMessage.prototype.getIdentifySession = function() {
return /** @type{proto.IdentifySessionMessage} */ (
jspb.Message.getWrapperField(this, command_pb.IdentifySessionMessage, 4));
};
/** @param {proto.IdentifySessionMessage|undefined} value */
proto.ServerMessage.prototype.setIdentifySession = function(value) {
jspb.Message.setOneofWrapperField(this, 4, proto.ServerMessage.oneofGroups_[0], value);
};
proto.ServerMessage.prototype.clearIdentifySession = function() {
this.setIdentifySession(undefined);
};
/**
* Returns whether this field is set.
* @return{!boolean}
*/
proto.ServerMessage.prototype.hasIdentifySession = function() {
return jspb.Message.getField(this, 4) != null;
};
/**
* optional EvalFailedMessage eval_failed = 5;
* @return {proto.EvalFailedMessage}
*/
proto.ServerMessage.prototype.getEvalFailed = function() {
return /** @type{proto.EvalFailedMessage} */ (
jspb.Message.getWrapperField(this, node_pb.EvalFailedMessage, 4));
jspb.Message.getWrapperField(this, node_pb.EvalFailedMessage, 5));
};
/** @param {proto.EvalFailedMessage|undefined} value */
proto.ServerMessage.prototype.setEvalFailed = function(value) {
jspb.Message.setOneofWrapperField(this, 4, proto.ServerMessage.oneofGroups_[0], value);
jspb.Message.setOneofWrapperField(this, 5, proto.ServerMessage.oneofGroups_[0], value);
};
@@ -786,23 +831,23 @@ proto.ServerMessage.prototype.clearEvalFailed = function() {
* @return{!boolean}
*/
proto.ServerMessage.prototype.hasEvalFailed = function() {
return jspb.Message.getField(this, 4) != null;
return jspb.Message.getField(this, 5) != null;
};
/**
* optional EvalDoneMessage eval_done = 5;
* optional EvalDoneMessage eval_done = 6;
* @return {proto.EvalDoneMessage}
*/
proto.ServerMessage.prototype.getEvalDone = function() {
return /** @type{proto.EvalDoneMessage} */ (
jspb.Message.getWrapperField(this, node_pb.EvalDoneMessage, 5));
jspb.Message.getWrapperField(this, node_pb.EvalDoneMessage, 6));
};
/** @param {proto.EvalDoneMessage|undefined} value */
proto.ServerMessage.prototype.setEvalDone = function(value) {
jspb.Message.setOneofWrapperField(this, 5, proto.ServerMessage.oneofGroups_[0], value);
jspb.Message.setOneofWrapperField(this, 6, proto.ServerMessage.oneofGroups_[0], value);
};
@@ -816,7 +861,7 @@ proto.ServerMessage.prototype.clearEvalDone = function() {
* @return{!boolean}
*/
proto.ServerMessage.prototype.hasEvalDone = function() {
return jspb.Message.getField(this, 5) != null;
return jspb.Message.getField(this, 6) != null;
};

View File

@@ -6,70 +6,73 @@ syntax = "proto3";
// If env is provided, the environment variables will be set.
// If tty_dimensions is included, we will spawn a tty for the command using the given dimensions.
message NewSessionMessage {
uint64 id = 1;
string command = 2;
repeated string args = 3;
map<string, string> env = 4;
TTYDimensions tty_dimensions = 5;
uint64 id = 1;
string command = 2;
repeated string args = 3;
map<string, string> env = 4;
string cwd = 5;
TTYDimensions tty_dimensions = 6;
bool is_fork = 7;
}
// Sent when starting a session failed.
message NewSessionFailureMessage {
uint64 id = 1;
enum Reason {
Prohibited = 0;
ResourceShortage = 1;
}
Reason reason = 2;
string message = 3;
uint64 id = 1;
enum Reason {
Prohibited = 0;
ResourceShortage = 1;
}
Reason reason = 2;
string message = 3;
}
// Sent when a session has completed
message SessionDoneMessage {
uint64 id = 1;
int64 exit_status = 2;
uint64 id = 1;
int64 exit_status = 2;
}
// Identifies a session with a PID.
message IdentifySessionMessage {
uint64 id = 1;
uint64 pid = 2;
uint64 id = 1;
uint64 pid = 2;
}
// Writes data to a session.
message WriteToSessionMessage {
uint64 id = 1;
bytes data = 2;
uint64 id = 1;
bytes data = 2;
}
// Resizes the TTY of the session identified by the id.
// The connection will be closed if a TTY was not requested when the session was created.
message ResizeSessionTTYMessage {
uint64 id = 1;
TTYDimensions tty_dimensions = 2;
uint64 id = 1;
TTYDimensions tty_dimensions = 2;
}
// CloseSessionInputMessage closes the stdin of the session by the ID.
message CloseSessionInputMessage {
uint64 id = 1;
uint64 id = 1;
}
message ShutdownSessionMessage {
uint64 id = 1;
uint64 id = 1;
string signal = 2;
}
// SessionOutputMessage carries data read from the stdout or stderr of the session identified by the id.
message SessionOutputMessage {
uint64 id = 1;
enum FD {
Stdout = 0;
Stderr = 1;
}
FD fd = 2;
bytes data = 3;
uint64 id = 1;
enum FD {
Stdout = 0;
Stderr = 1;
}
FD fd = 2;
bytes data = 3;
}
message TTYDimensions {
uint32 height = 1;
uint32 width = 2;
}
uint32 height = 1;
uint32 width = 2;
}

View File

@@ -17,11 +17,17 @@ export class NewSessionMessage extends jspb.Message {
getEnvMap(): jspb.Map<string, string>;
clearEnvMap(): void;
getCwd(): string;
setCwd(value: string): void;
hasTtyDimensions(): boolean;
clearTtyDimensions(): void;
getTtyDimensions(): TTYDimensions | undefined;
setTtyDimensions(value?: TTYDimensions): void;
getIsFork(): boolean;
setIsFork(value: boolean): void;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): NewSessionMessage.AsObject;
static toObject(includeInstance: boolean, msg: NewSessionMessage): NewSessionMessage.AsObject;
@@ -38,7 +44,9 @@ export namespace NewSessionMessage {
command: string,
argsList: Array<string>,
envMap: Array<[string, string]>,
cwd: string,
ttyDimensions?: TTYDimensions.AsObject,
isFork: boolean,
}
}
@@ -199,6 +207,9 @@ export class ShutdownSessionMessage extends jspb.Message {
getId(): number;
setId(value: number): void;
getSignal(): string;
setSignal(value: string): void;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): ShutdownSessionMessage.AsObject;
static toObject(includeInstance: boolean, msg: ShutdownSessionMessage): ShutdownSessionMessage.AsObject;
@@ -212,6 +223,7 @@ export class ShutdownSessionMessage extends jspb.Message {
export namespace ShutdownSessionMessage {
export type AsObject = {
id: number,
signal: string,
}
}

View File

@@ -78,7 +78,9 @@ proto.NewSessionMessage.toObject = function(includeInstance, msg) {
command: msg.getCommand(),
argsList: jspb.Message.getField(msg, 3),
envMap: (f = msg.getEnvMap(true)) ? f.toArray() : [],
ttyDimensions: (f = msg.getTtyDimensions()) && proto.TTYDimensions.toObject(includeInstance, f)
cwd: msg.getCwd(),
ttyDimensions: (f = msg.getTtyDimensions()) && proto.TTYDimensions.toObject(includeInstance, f),
isFork: msg.getIsFork()
};
if (includeInstance) {
@@ -135,10 +137,18 @@ proto.NewSessionMessage.deserializeBinaryFromReader = function(msg, reader) {
});
break;
case 5:
var value = /** @type {string} */ (reader.readString());
msg.setCwd(value);
break;
case 6:
var value = new proto.TTYDimensions;
reader.readMessage(value,proto.TTYDimensions.deserializeBinaryFromReader);
msg.setTtyDimensions(value);
break;
case 7:
var value = /** @type {boolean} */ (reader.readBool());
msg.setIsFork(value);
break;
default:
reader.skipField();
break;
@@ -202,14 +212,28 @@ proto.NewSessionMessage.prototype.serializeBinaryToWriter = function (writer) {
if (f && f.getLength() > 0) {
f.serializeBinary(4, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeString);
}
f = this.getCwd();
if (f.length > 0) {
writer.writeString(
5,
f
);
}
f = this.getTtyDimensions();
if (f != null) {
writer.writeMessage(
5,
6,
f,
proto.TTYDimensions.serializeBinaryToWriter
);
}
f = this.getIsFork();
if (f) {
writer.writeBool(
7,
f
);
}
};
@@ -288,18 +312,33 @@ proto.NewSessionMessage.prototype.getEnvMap = function(opt_noLazyCreate) {
/**
* optional TTYDimensions tty_dimensions = 5;
* optional string cwd = 5;
* @return {string}
*/
proto.NewSessionMessage.prototype.getCwd = function() {
return /** @type {string} */ (jspb.Message.getFieldProto3(this, 5, ""));
};
/** @param {string} value */
proto.NewSessionMessage.prototype.setCwd = function(value) {
jspb.Message.setField(this, 5, value);
};
/**
* optional TTYDimensions tty_dimensions = 6;
* @return {proto.TTYDimensions}
*/
proto.NewSessionMessage.prototype.getTtyDimensions = function() {
return /** @type{proto.TTYDimensions} */ (
jspb.Message.getWrapperField(this, proto.TTYDimensions, 5));
jspb.Message.getWrapperField(this, proto.TTYDimensions, 6));
};
/** @param {proto.TTYDimensions|undefined} value */
proto.NewSessionMessage.prototype.setTtyDimensions = function(value) {
jspb.Message.setWrapperField(this, 5, value);
jspb.Message.setWrapperField(this, 6, value);
};
@@ -313,7 +352,24 @@ proto.NewSessionMessage.prototype.clearTtyDimensions = function() {
* @return{!boolean}
*/
proto.NewSessionMessage.prototype.hasTtyDimensions = function() {
return jspb.Message.getField(this, 5) != null;
return jspb.Message.getField(this, 6) != null;
};
/**
* optional bool is_fork = 7;
* Note that Boolean fields may be set to 0/1 when serialized from a Java server.
* You should avoid comparisons like {@code val === true/false} in those cases.
* @return {boolean}
*/
proto.NewSessionMessage.prototype.getIsFork = function() {
return /** @type {boolean} */ (jspb.Message.getFieldProto3(this, 7, false));
};
/** @param {boolean} value */
proto.NewSessionMessage.prototype.setIsFork = function(value) {
jspb.Message.setField(this, 7, value);
};
@@ -1528,7 +1584,8 @@ proto.ShutdownSessionMessage.prototype.toObject = function(opt_includeInstance)
*/
proto.ShutdownSessionMessage.toObject = function(includeInstance, msg) {
var f, obj = {
id: msg.getId()
id: msg.getId(),
signal: msg.getSignal()
};
if (includeInstance) {
@@ -1569,6 +1626,10 @@ proto.ShutdownSessionMessage.deserializeBinaryFromReader = function(msg, reader)
var value = /** @type {number} */ (reader.readUint64());
msg.setId(value);
break;
case 2:
var value = /** @type {string} */ (reader.readString());
msg.setSignal(value);
break;
default:
reader.skipField();
break;
@@ -1614,6 +1675,13 @@ proto.ShutdownSessionMessage.prototype.serializeBinaryToWriter = function (write
f
);
}
f = this.getSignal();
if (f.length > 0) {
writer.writeString(
2,
f
);
}
};
@@ -1641,6 +1709,21 @@ proto.ShutdownSessionMessage.prototype.setId = function(value) {
};
/**
* optional string signal = 2;
* @return {string}
*/
proto.ShutdownSessionMessage.prototype.getSignal = function() {
return /** @type {string} */ (jspb.Message.getFieldProto3(this, 2, ""));
};
/** @param {string} value */
proto.ShutdownSessionMessage.prototype.setSignal = function(value) {
jspb.Message.setField(this, 2, value);
};
/**
* Generated by JsPbCodeGenerator.

View File

@@ -1,36 +1,36 @@
syntax = "proto3";
message TypedValue {
enum Type {
String = 0;
Number = 1;
Object = 2;
Boolean = 3;
}
Type type = 1;
string value = 2;
enum Type {
String = 0;
Number = 1;
Object = 2;
Boolean = 3;
}
Type type = 1;
string value = 2;
}
message NewEvalMessage {
uint64 id = 1;
string function = 2;
repeated string args = 3;
// Timeout in ms
uint32 timeout = 4;
uint64 id = 1;
string function = 2;
repeated string args = 3;
// Timeout in ms
uint32 timeout = 4;
}
message EvalFailedMessage {
uint64 id = 1;
enum Reason {
Timeout = 0;
Exception = 1;
Conflict = 2;
}
Reason reason = 2;
string message = 3;
uint64 id = 1;
enum Reason {
Timeout = 0;
Exception = 1;
Conflict = 2;
}
Reason reason = 2;
string message = 3;
}
message EvalDoneMessage {
uint64 id = 1;
TypedValue response = 2;
uint64 id = 1;
TypedValue response = 2;
}