зеркало из https://github.com/docker/compose-cli.git
Add exec.ts for an example of exec over gRPC
This commit is contained in:
Родитель
c34d016fdb
Коммит
71087c68be
|
@ -72,8 +72,7 @@ func getReader(t *testing.T, in []byte, errResult error) reader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAny(t *testing.T, data []byte) *any.Any {
|
func getAny(t *testing.T, in []byte) *any.Any {
|
||||||
in := []byte{104, 101, 108, 108, 111}
|
|
||||||
value, err := ptypes.MarshalAny(&streamsv1.BytesMessage{
|
value, err := ptypes.MarshalAny(&streamsv1.BytesMessage{
|
||||||
Type: streamsv1.IOStream_STDOUT,
|
Type: streamsv1.IOStream_STDOUT,
|
||||||
Value: in,
|
Value: in,
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
package proxy
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
|
|
||||||
v1 "github.com/docker/api/protos/containers/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
type streamWriter struct {
|
|
||||||
stream v1.Containers_LogsServer
|
|
||||||
}
|
|
||||||
|
|
||||||
func newStreamWriter(stream v1.Containers_LogsServer) io.Writer {
|
|
||||||
return &streamWriter{
|
|
||||||
stream: stream,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *streamWriter) Write(p []byte) (n int, err error) {
|
|
||||||
return len(p), w.stream.SendMsg(&v1.LogsResponse{
|
|
||||||
Logs: p,
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -3,8 +3,10 @@ node_modules/.bin/grpc_tools_node_protoc \
|
||||||
--grpc_out=generate_package_definition:./grpc \
|
--grpc_out=generate_package_definition:./grpc \
|
||||||
-I ../../protos/contexts/v1 \
|
-I ../../protos/contexts/v1 \
|
||||||
-I ../../protos/containers/v1 \
|
-I ../../protos/containers/v1 \
|
||||||
|
-I ../../protos/streams/v1 \
|
||||||
../../protos/contexts/v1/*.proto \
|
../../protos/contexts/v1/*.proto \
|
||||||
../../protos/containers/v1/*.proto
|
../../protos/containers/v1/*.proto \
|
||||||
|
../../protos/streams/v1/*.proto
|
||||||
|
|
||||||
# generate d.ts codes
|
# generate d.ts codes
|
||||||
protoc \
|
protoc \
|
||||||
|
@ -12,5 +14,7 @@ protoc \
|
||||||
--ts_out=generate_package_definition:./grpc \
|
--ts_out=generate_package_definition:./grpc \
|
||||||
-I ../../protos/contexts/v1 \
|
-I ../../protos/contexts/v1 \
|
||||||
-I ../../protos/containers/v1 \
|
-I ../../protos/containers/v1 \
|
||||||
|
-I ../../protos/streams/v1 \
|
||||||
../../protos/contexts/v1/*.proto \
|
../../protos/contexts/v1/*.proto \
|
||||||
../../protos/containers/v1/*.proto
|
../../protos/containers/v1/*.proto \
|
||||||
|
../../protos/streams/v1/*.proto
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
import * as grpc from "@grpc/grpc-js";
|
||||||
|
import * as readline from "readline";
|
||||||
|
import * as google_protobuf_any_pb from "google-protobuf/google/protobuf/any_pb.js";
|
||||||
|
|
||||||
|
import * as continersPb from "./grpc/containers_grpc_pb";
|
||||||
|
import { IContainersClient } from "./grpc/containers_grpc_pb";
|
||||||
|
import { ExecRequest, ExecResponse, LogsRequest } from "./grpc/containers_pb";
|
||||||
|
|
||||||
|
import * as streamsPb from "./grpc/streams_grpc_pb";
|
||||||
|
import { IStreamingClient } from "./grpc/streams_grpc_pb";
|
||||||
|
import { BytesMessage } from "./grpc/streams_pb";
|
||||||
|
|
||||||
|
let address = process.argv[3] || "unix:///tmp/backend.sock";
|
||||||
|
|
||||||
|
const ContainersServiceClient = grpc.makeClientConstructor(
|
||||||
|
continersPb["com.docker.api.protos.containers.v1.Containers"],
|
||||||
|
"ContainersClient"
|
||||||
|
);
|
||||||
|
|
||||||
|
const client = (new ContainersServiceClient(
|
||||||
|
address,
|
||||||
|
grpc.credentials.createInsecure()
|
||||||
|
) as unknown) as IContainersClient;
|
||||||
|
|
||||||
|
const StreamsServiceClient = grpc.makeClientConstructor(
|
||||||
|
streamsPb["com.docker.api.protos.streams.v1.Streaming"],
|
||||||
|
"StreamsClient"
|
||||||
|
);
|
||||||
|
|
||||||
|
let streamClient = (new StreamsServiceClient(
|
||||||
|
address,
|
||||||
|
grpc.credentials.createInsecure()
|
||||||
|
) as unknown) as IStreamingClient;
|
||||||
|
|
||||||
|
let backend = process.argv[2] || "moby";
|
||||||
|
let containerId = process.argv[3];
|
||||||
|
const meta = new grpc.Metadata();
|
||||||
|
meta.set("CONTEXT_KEY", backend);
|
||||||
|
|
||||||
|
// Get the stream
|
||||||
|
const stream = streamClient.newStream();
|
||||||
|
|
||||||
|
stream.on("metadata", (m: grpc.Metadata) => {
|
||||||
|
let req = new ExecRequest();
|
||||||
|
req.setCommand("/bin/bash");
|
||||||
|
req.setStreamId(m.get("id")[0] as string);
|
||||||
|
req.setId(containerId);
|
||||||
|
req.setTty(true);
|
||||||
|
|
||||||
|
client.exec(req, meta, (err: any, _: ExecResponse) => {
|
||||||
|
if (err != null) {
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
process.exit();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
readline.emitKeypressEvents(process.stdin);
|
||||||
|
process.stdin.setRawMode(true);
|
||||||
|
|
||||||
|
process.stdin.on("keypress", (str, key) => {
|
||||||
|
const mess = new BytesMessage();
|
||||||
|
const a = new Uint8Array(key.sequence.length);
|
||||||
|
for (let i = 0; i <= key.sequence.length; i++) {
|
||||||
|
a[i] = key.sequence.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mess.setValue(a);
|
||||||
|
|
||||||
|
const any = new google_protobuf_any_pb.Any();
|
||||||
|
any.pack(
|
||||||
|
mess.serializeBinary(),
|
||||||
|
"type.googleapis.com/com.docker.api.protos.streams.v1.BytesMessage"
|
||||||
|
);
|
||||||
|
stream.write(any);
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.on("data", (chunk: any) => {
|
||||||
|
const m = chunk.unpack(
|
||||||
|
BytesMessage.deserializeBinary,
|
||||||
|
"com.docker.api.protos.streams.v1.BytesMessage"
|
||||||
|
) as BytesMessage;
|
||||||
|
process.stdout.write(m.getValue());
|
||||||
|
});
|
|
@ -12,6 +12,7 @@
|
||||||
"grpc": "^1.24.2",
|
"grpc": "^1.24.2",
|
||||||
"grpc-tools": "^1.8.1",
|
"grpc-tools": "^1.8.1",
|
||||||
"grpc_tools_node_protoc_ts": "^3.0.0",
|
"grpc_tools_node_protoc_ts": "^3.0.0",
|
||||||
|
"readline": "^1.3.0",
|
||||||
"ts-node": "^8.9.1",
|
"ts-node": "^8.9.1",
|
||||||
"typescript": "^3.8.3"
|
"typescript": "^3.8.3"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
declare module "google-protobuf/google/protobuf/any_pb.js";
|
|
@ -1653,6 +1653,11 @@ readable-stream@^2.0.6, readable-stream@~2.3.6:
|
||||||
string_decoder "~1.1.1"
|
string_decoder "~1.1.1"
|
||||||
util-deprecate "~1.0.1"
|
util-deprecate "~1.0.1"
|
||||||
|
|
||||||
|
readline@^1.3.0:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/readline/-/readline-1.3.0.tgz#c580d77ef2cfc8752b132498060dc9793a7ac01c"
|
||||||
|
integrity sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw=
|
||||||
|
|
||||||
regex-not@^1.0.0, regex-not@^1.0.2:
|
regex-not@^1.0.0, regex-not@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c"
|
resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c"
|
||||||
|
|
Загрузка…
Ссылка в новой задаче