Merge branch 'websocket'
This commit is contained in:
commit
07bd09473c
|
|
@ -9,8 +9,8 @@ message Action {
|
||||||
string title = 2;
|
string title = 2;
|
||||||
string icon = 3;
|
string icon = 3;
|
||||||
bool canExec = 4;
|
bool canExec = 4;
|
||||||
|
|
||||||
repeated ActionArgument arguments = 5;
|
repeated ActionArgument arguments = 5;
|
||||||
|
bool popupOnStart = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ActionArgument {
|
message ActionArgument {
|
||||||
|
|
@ -55,13 +55,13 @@ message StartActionArgument {
|
||||||
}
|
}
|
||||||
|
|
||||||
message StartActionResponse {
|
message StartActionResponse {
|
||||||
LogEntry logEntry = 1;
|
string executionUuid = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetLogsRequest{};
|
message GetLogsRequest{};
|
||||||
|
|
||||||
message LogEntry {
|
message LogEntry {
|
||||||
string datetime = 1;
|
string datetimeStarted = 1;
|
||||||
string actionTitle = 2;
|
string actionTitle = 2;
|
||||||
string stdout = 3;
|
string stdout = 3;
|
||||||
string stderr = 4;
|
string stderr = 4;
|
||||||
|
|
@ -71,6 +71,8 @@ message LogEntry {
|
||||||
string userClass = 8;
|
string userClass = 8;
|
||||||
string actionIcon = 9;
|
string actionIcon = 9;
|
||||||
repeated string tags = 10;
|
repeated string tags = 10;
|
||||||
|
string executionUuid = 11;
|
||||||
|
string datetimeFinished = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetLogsResponse {
|
message GetLogsResponse {
|
||||||
|
|
@ -87,6 +89,14 @@ message ValidateArgumentTypeResponse {
|
||||||
string description = 2;
|
string description = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message WatchExecutionRequest {
|
||||||
|
string executionUuid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WatchExecutionUpdate {
|
||||||
|
string update = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message WhoAmIRequest {}
|
message WhoAmIRequest {}
|
||||||
|
|
||||||
message WhoAmIResponse {
|
message WhoAmIResponse {
|
||||||
|
|
@ -113,6 +123,13 @@ service OliveTinApi {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpc WatchExecution(WatchExecutionRequest) returns (stream WatchExecutionUpdate) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
post: "/api/WatchExecution"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
rpc GetLogs(GetLogsRequest) returns (GetLogsResponse) {
|
rpc GetLogs(GetLogsRequest) returns (GetLogsResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
get: "/api/GetLogs"
|
get: "/api/GetLogs"
|
||||||
|
|
|
||||||
1
go.mod
1
go.mod
|
|
@ -20,6 +20,7 @@ require (
|
||||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0
|
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0
|
||||||
google.golang.org/protobuf v1.31.0
|
google.golang.org/protobuf v1.31.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
|
nhooyr.io/websocket v1.8.7
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
|
||||||
41
go.sum
41
go.sum
|
|
@ -94,6 +94,10 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4
|
||||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||||
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
|
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
|
||||||
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
|
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
|
||||||
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
|
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||||
|
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||||
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
|
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
|
||||||
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
github.com/go-critic/go-critic v0.8.2 h1:mekhZ9jw5NBEj3I8o/EywXw5zBfGAJuMo4VVVjtxF80=
|
github.com/go-critic/go-critic v0.8.2 h1:mekhZ9jw5NBEj3I8o/EywXw5zBfGAJuMo4VVVjtxF80=
|
||||||
|
|
@ -106,6 +110,13 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
|
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||||
|
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||||
|
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||||
|
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||||
|
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
|
||||||
|
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||||
github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8=
|
github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8=
|
||||||
github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU=
|
github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU=
|
||||||
github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s=
|
github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s=
|
||||||
|
|
@ -124,6 +135,12 @@ github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQi
|
||||||
github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ=
|
github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ=
|
||||||
github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus=
|
github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus=
|
||||||
github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=
|
github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=
|
||||||
|
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
|
||||||
|
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||||
|
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
|
||||||
|
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||||
|
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
|
||||||
|
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||||
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
|
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
|
||||||
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||||
|
|
@ -177,6 +194,7 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ=
|
github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ=
|
||||||
github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
|
github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
|
|
@ -200,6 +218,8 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||||
|
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||||
|
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2 h1:dygLcbEBA+t/P7ck6a8AkXv6juQ4cK0RHBoh32jxhHM=
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2 h1:dygLcbEBA+t/P7ck6a8AkXv6juQ4cK0RHBoh32jxhHM=
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2/go.mod h1:Ap9RLCIJVtgQg1/BBgVEfypOAySvvlcpcVQkSzJCH4Y=
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2/go.mod h1:Ap9RLCIJVtgQg1/BBgVEfypOAySvvlcpcVQkSzJCH4Y=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
|
@ -214,10 +234,13 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf
|
||||||
github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 h1:2uT3aivO7NVpUPGcQX7RbHijHMyWix/yCnIrCWc+5co=
|
github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 h1:2uT3aivO7NVpUPGcQX7RbHijHMyWix/yCnIrCWc+5co=
|
||||||
github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw=
|
github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw=
|
||||||
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
|
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
|
||||||
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||||
|
|
@ -228,14 +251,22 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||||
|
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
|
|
@ -289,6 +320,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
|
@ -301,6 +333,10 @@ github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8
|
||||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||||
github.com/tetratelabs/wazero v1.4.0 h1:9/MirYvmkJ/zSUOygKY/ia3t+e+RqIZXKbylIby1WYk=
|
github.com/tetratelabs/wazero v1.4.0 h1:9/MirYvmkJ/zSUOygKY/ia3t+e+RqIZXKbylIby1WYk=
|
||||||
github.com/tetratelabs/wazero v1.4.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
|
github.com/tetratelabs/wazero v1.4.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
|
||||||
|
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||||
|
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||||
|
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||||
|
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||||
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
|
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
|
||||||
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
|
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
|
@ -446,6 +482,7 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|
@ -654,6 +691,8 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||||
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
@ -665,6 +704,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
|
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
|
||||||
|
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,10 @@ func getMetdataKeyOrEmpty(md metadata.MD, key string) string {
|
||||||
func UserFromContext(ctx context.Context, cfg *config.Config) *AuthenticatedUser {
|
func UserFromContext(ctx context.Context, cfg *config.Config) *AuthenticatedUser {
|
||||||
md, ok := metadata.FromIncomingContext(ctx)
|
md, ok := metadata.FromIncomingContext(ctx)
|
||||||
|
|
||||||
ret := &AuthenticatedUser{}
|
ret := &AuthenticatedUser{
|
||||||
|
Username: "guest",
|
||||||
|
Usergroup: "guest",
|
||||||
|
}
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
ret.Username = getMetdataKeyOrEmpty(md, "username")
|
ret.Username = getMetdataKeyOrEmpty(md, "username")
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ type Action struct {
|
||||||
ExecOnStartup bool
|
ExecOnStartup bool
|
||||||
ExecOnCron []string
|
ExecOnCron []string
|
||||||
Arguments []ActionArgument
|
Arguments []ActionArgument
|
||||||
|
PopupOnStart bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionArgument objects appear on Actions.
|
// ActionArgument objects appear on Actions.
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@ import (
|
||||||
pb "github.com/OliveTin/OliveTin/gen/grpc"
|
pb "github.com/OliveTin/OliveTin/gen/grpc"
|
||||||
acl "github.com/OliveTin/OliveTin/internal/acl"
|
acl "github.com/OliveTin/OliveTin/internal/acl"
|
||||||
config "github.com/OliveTin/OliveTin/internal/config"
|
config "github.com/OliveTin/OliveTin/internal/config"
|
||||||
|
"github.com/google/uuid"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"io"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -24,18 +26,22 @@ type ExecutionRequest struct {
|
||||||
AuthenticatedUser *acl.AuthenticatedUser
|
AuthenticatedUser *acl.AuthenticatedUser
|
||||||
logEntry *InternalLogEntry
|
logEntry *InternalLogEntry
|
||||||
finalParsedCommand string
|
finalParsedCommand string
|
||||||
|
uuid string
|
||||||
}
|
}
|
||||||
|
|
||||||
// InternalLogEntry objects are created by an Executor, and represent the final
|
// InternalLogEntry objects are created by an Executor, and represent the final
|
||||||
// state of execution (even if the command is not executed). It's designed to be
|
// state of execution (even if the command is not executed). It's designed to be
|
||||||
// easily serializable.
|
// easily serializable.
|
||||||
type InternalLogEntry struct {
|
type InternalLogEntry struct {
|
||||||
Datetime string
|
DatetimeStarted string
|
||||||
Stdout string
|
DatetimeFinished string
|
||||||
Stderr string
|
Stdout string
|
||||||
TimedOut bool
|
Stderr string
|
||||||
ExitCode int32
|
StdoutBuffer io.ReadCloser
|
||||||
Tags []string
|
StderrBuffer io.ReadCloser
|
||||||
|
TimedOut bool
|
||||||
|
ExitCode int32
|
||||||
|
Tags []string
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The following two properties are obviously on Action normally, but it's useful
|
The following two properties are obviously on Action normally, but it's useful
|
||||||
|
|
@ -44,6 +50,9 @@ type InternalLogEntry struct {
|
||||||
*/
|
*/
|
||||||
ActionTitle string
|
ActionTitle string
|
||||||
ActionIcon string
|
ActionIcon string
|
||||||
|
|
||||||
|
ExecutionStarted bool
|
||||||
|
ExecutionCompleted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type executorStepFunc func(*ExecutionRequest) bool
|
type executorStepFunc func(*ExecutionRequest) bool
|
||||||
|
|
@ -51,46 +60,17 @@ type executorStepFunc func(*ExecutionRequest) bool
|
||||||
// Executor represents a helper class for executing commands. It's main method
|
// Executor represents a helper class for executing commands. It's main method
|
||||||
// is ExecRequest
|
// is ExecRequest
|
||||||
type Executor struct {
|
type Executor struct {
|
||||||
Logs []InternalLogEntry
|
Logs map[string]*InternalLogEntry
|
||||||
|
|
||||||
chainOfCommand []executorStepFunc
|
chainOfCommand []executorStepFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecRequest processes an ExecutionRequest
|
|
||||||
func (e *Executor) ExecRequest(req *ExecutionRequest) *pb.StartActionResponse {
|
|
||||||
req.logEntry = &InternalLogEntry{
|
|
||||||
Datetime: time.Now().Format("2006-01-02 15:04:05"),
|
|
||||||
ActionTitle: req.ActionName,
|
|
||||||
Stdout: "",
|
|
||||||
Stderr: "",
|
|
||||||
ExitCode: -1337, // If an Action is not actually executed, this is the default exit code.
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, step := range e.chainOfCommand {
|
|
||||||
if !step(req) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e.Logs = append(e.Logs, *req.logEntry)
|
|
||||||
|
|
||||||
return &pb.StartActionResponse{
|
|
||||||
LogEntry: &pb.LogEntry{
|
|
||||||
ActionTitle: req.logEntry.ActionTitle,
|
|
||||||
ActionIcon: req.logEntry.ActionIcon,
|
|
||||||
Datetime: req.logEntry.Datetime,
|
|
||||||
Stderr: req.logEntry.Stderr,
|
|
||||||
Stdout: req.logEntry.Stdout,
|
|
||||||
TimedOut: req.logEntry.TimedOut,
|
|
||||||
ExitCode: req.logEntry.ExitCode,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultExecutor returns an Executor, with a sensible "chain of command" for
|
// DefaultExecutor returns an Executor, with a sensible "chain of command" for
|
||||||
// executing actions.
|
// executing actions.
|
||||||
func DefaultExecutor() *Executor {
|
func DefaultExecutor() *Executor {
|
||||||
e := Executor{}
|
e := Executor{}
|
||||||
|
e.Logs = make(map[string]*InternalLogEntry)
|
||||||
|
|
||||||
e.chainOfCommand = []executorStepFunc{
|
e.chainOfCommand = []executorStepFunc{
|
||||||
stepFindAction,
|
stepFindAction,
|
||||||
stepACLCheck,
|
stepACLCheck,
|
||||||
|
|
@ -103,6 +83,36 @@ func DefaultExecutor() *Executor {
|
||||||
return &e
|
return &e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecRequest processes an ExecutionRequest
|
||||||
|
func (e *Executor) ExecRequest(req *ExecutionRequest) *pb.StartActionResponse {
|
||||||
|
req.uuid = uuid.New().String()
|
||||||
|
req.logEntry = &InternalLogEntry{
|
||||||
|
DatetimeStarted: time.Now().Format("2006-01-02 15:04:05"),
|
||||||
|
ActionTitle: req.ActionName,
|
||||||
|
Stdout: "",
|
||||||
|
Stderr: "",
|
||||||
|
ExitCode: -1337, // If an Action is not actually executed, this is the default exit code.
|
||||||
|
ExecutionStarted: false,
|
||||||
|
ExecutionCompleted: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Logs[req.uuid] = req.logEntry
|
||||||
|
|
||||||
|
go e.execChain(req)
|
||||||
|
|
||||||
|
return &pb.StartActionResponse{
|
||||||
|
ExecutionUuid: req.uuid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Executor) execChain(req *ExecutionRequest) {
|
||||||
|
for _, step := range e.chainOfCommand {
|
||||||
|
if !step(req) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func stepFindAction(req *ExecutionRequest) bool {
|
func stepFindAction(req *ExecutionRequest) bool {
|
||||||
actualAction := req.Cfg.FindAction(req.ActionName)
|
actualAction := req.Cfg.FindAction(req.ActionName)
|
||||||
|
|
||||||
|
|
@ -181,9 +191,19 @@ func stepExec(req *ExecutionRequest) bool {
|
||||||
cmd := wrapCommandInShell(ctx, req.finalParsedCommand)
|
cmd := wrapCommandInShell(ctx, req.finalParsedCommand)
|
||||||
cmd.Stdout = &stdout
|
cmd.Stdout = &stdout
|
||||||
cmd.Stderr = &stderr
|
cmd.Stderr = &stderr
|
||||||
|
req.logEntry.StdoutBuffer, _ = cmd.StdoutPipe()
|
||||||
|
req.logEntry.StderrBuffer, _ = cmd.StderrPipe()
|
||||||
|
|
||||||
runerr := cmd.Run()
|
req.logEntry.ExecutionStarted = true
|
||||||
|
|
||||||
|
runerr := cmd.Start()
|
||||||
|
|
||||||
|
cmd.Wait()
|
||||||
|
|
||||||
|
//req.logEntry.Stdout = req.logEntry.StdoutBuffer.String()
|
||||||
|
//req.logEntry.Stderr = req.logEntry.StderrBuffer.String()
|
||||||
|
|
||||||
|
req.logEntry.ExecutionCompleted = true
|
||||||
req.logEntry.ExitCode = int32(cmd.ProcessState.ExitCode())
|
req.logEntry.ExitCode = int32(cmd.ProcessState.ExitCode())
|
||||||
req.logEntry.Stdout = stdout.String()
|
req.logEntry.Stdout = stdout.String()
|
||||||
req.logEntry.Stderr = stderr.String()
|
req.logEntry.Stderr = stderr.String()
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
acl "github.com/OliveTin/OliveTin/internal/acl"
|
acl "github.com/OliveTin/OliveTin/internal/acl"
|
||||||
|
|
@ -43,6 +44,32 @@ func (api *oliveTinAPI) StartAction(ctx ctx.Context, req *pb.StartActionRequest)
|
||||||
return api.executor.ExecRequest(&execReq), nil
|
return api.executor.ExecRequest(&execReq), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *oliveTinAPI) WatchExecution(req *pb.WatchExecutionRequest, srv pb.OliveTinApi_WatchExecutionServer) error {
|
||||||
|
log.Infof("Watch")
|
||||||
|
|
||||||
|
if logEntry, ok := api.executor.Logs[req.ExecutionUuid]; !ok {
|
||||||
|
log.Errorf("Execution not found: %v", req.ExecutionUuid)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
if logEntry.ExecutionStarted {
|
||||||
|
for !logEntry.ExecutionCompleted {
|
||||||
|
tmp := make([]byte, 256)
|
||||||
|
|
||||||
|
red, err := io.ReadAtLeast(logEntry.StdoutBuffer, tmp, 1)
|
||||||
|
|
||||||
|
log.Infof("%v %v", red, err)
|
||||||
|
|
||||||
|
srv.Send(&pb.WatchExecutionUpdate{
|
||||||
|
Update: string(tmp),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (api *oliveTinAPI) GetDashboardComponents(ctx ctx.Context, req *pb.GetDashboardComponentsRequest) (*pb.GetDashboardComponentsResponse, error) {
|
func (api *oliveTinAPI) GetDashboardComponents(ctx ctx.Context, req *pb.GetDashboardComponentsRequest) (*pb.GetDashboardComponentsResponse, error) {
|
||||||
user := acl.UserFromContext(ctx, cfg)
|
user := acl.UserFromContext(ctx, cfg)
|
||||||
|
|
||||||
|
|
@ -62,16 +89,18 @@ func (api *oliveTinAPI) GetLogs(ctx ctx.Context, req *pb.GetLogsRequest) (*pb.Ge
|
||||||
|
|
||||||
// TODO Limit to 10 entries or something to prevent browser lag.
|
// TODO Limit to 10 entries or something to prevent browser lag.
|
||||||
|
|
||||||
for _, logEntry := range api.executor.Logs {
|
for uuid, logEntry := range api.executor.Logs {
|
||||||
ret.Logs = append(ret.Logs, &pb.LogEntry{
|
ret.Logs = append(ret.Logs, &pb.LogEntry{
|
||||||
ActionTitle: logEntry.ActionTitle,
|
ActionTitle: logEntry.ActionTitle,
|
||||||
ActionIcon: logEntry.ActionIcon,
|
ActionIcon: logEntry.ActionIcon,
|
||||||
Datetime: logEntry.Datetime,
|
DatetimeStarted: logEntry.DatetimeStarted,
|
||||||
Stdout: logEntry.Stdout,
|
DatetimeFinished: logEntry.DatetimeFinished,
|
||||||
Stderr: logEntry.Stderr,
|
Stdout: logEntry.Stdout,
|
||||||
TimedOut: logEntry.TimedOut,
|
Stderr: logEntry.Stderr,
|
||||||
ExitCode: logEntry.ExitCode,
|
TimedOut: logEntry.TimedOut,
|
||||||
Tags: logEntry.Tags,
|
ExitCode: logEntry.ExitCode,
|
||||||
|
Tags: logEntry.Tags,
|
||||||
|
ExecutionUuid: uuid,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,11 @@ func actionsCfgToPb(cfgActions []config.Action, user *acl.AuthenticatedUser) *pb
|
||||||
|
|
||||||
func actionCfgToPb(action config.Action, user *acl.AuthenticatedUser) *pb.Action {
|
func actionCfgToPb(action config.Action, user *acl.AuthenticatedUser) *pb.Action {
|
||||||
btn := pb.Action{
|
btn := pb.Action{
|
||||||
Id: fmt.Sprintf("%x", md5.Sum([]byte(action.Title))),
|
Id: fmt.Sprintf("%x", md5.Sum([]byte(action.Title))),
|
||||||
Title: action.Title,
|
Title: action.Title,
|
||||||
Icon: action.Icon,
|
Icon: action.Icon,
|
||||||
CanExec: acl.IsAllowedExec(cfg, user, &action),
|
CanExec: acl.IsAllowedExec(cfg, user, &action),
|
||||||
|
PopupOnStart: action.PopupOnStart,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cfgArg := range action.Arguments {
|
for _, cfgArg := range action.Arguments {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StartSingleHTTPFrontend will create a reverse proxy that proxies the API
|
// StartSingleHTTPFrontend will create a reverse proxy that proxies the API
|
||||||
|
|
@ -37,8 +38,12 @@ func StartSingleHTTPFrontend(cfg *config.Config) {
|
||||||
})
|
})
|
||||||
|
|
||||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Debugf("ui req: %q", r.URL)
|
if strings.Contains(r.Header.Get("Connection"), "Upgrade") {
|
||||||
webuiProxy.ServeHTTP(w, r)
|
handleWebsocket(w, r)
|
||||||
|
} else {
|
||||||
|
log.Debugf("ui req: %q", r.URL)
|
||||||
|
webuiProxy.ServeHTTP(w, r)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package httpservers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"net/http"
|
||||||
|
"nhooyr.io/websocket"
|
||||||
|
"nhooyr.io/websocket/wsjson"
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
func handleWebsocket(w http.ResponseWriter, r *http.Request) bool {
|
||||||
|
c, err := websocket.Accept(w, r, nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Websocket issue: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
defer c.Close(websocket.StatusInternalError, "Goodbye")
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(r.Context(), time.Second*10)
|
||||||
|
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
var v interface{}
|
||||||
|
|
||||||
|
err = wsjson.Read(ctx, c, v)
|
||||||
|
|
||||||
|
log.Printf("recv: %v", v)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Websocket issue: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
c.Close(websocket.StatusNormalClosure, "")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
@ -4,11 +4,14 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
config "github.com/OliveTin/OliveTin/internal/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetWebuiDir(t *testing.T) {
|
func TestGetWebuiDir(t *testing.T) {
|
||||||
os.Chdir("../../") // go test sets the cwd to "httpservers" by default
|
os.Chdir("../../") // go test sets the cwd to "httpservers" by default
|
||||||
|
|
||||||
|
cfg = config.DefaultConfig();
|
||||||
|
|
||||||
dir := findWebuiDir()
|
dir := findWebuiDir()
|
||||||
|
|
||||||
assert.Equal(t, "./webui", dir, "Finding the webui dir")
|
assert.Equal(t, "./webui", dir, "Finding the webui dir")
|
||||||
|
|
|
||||||
|
|
@ -146,5 +146,6 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type = "module" src = "main.js"></script>
|
<script type = "module" src = "main.js"></script>
|
||||||
|
<script type = "module" src = "js/websocket.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
export function setupWebsocket () {
|
||||||
|
window.websocketAvailable = false
|
||||||
|
|
||||||
|
let proto = 'ws:'
|
||||||
|
|
||||||
|
if (window.location.protocol === 'https:') {
|
||||||
|
proto = 'wss:'
|
||||||
|
}
|
||||||
|
|
||||||
|
const websocketConnectionUrl = proto + window.location.host + '/websocket'
|
||||||
|
const ws = window.ws = new WebSocket(websocketConnectionUrl)
|
||||||
|
|
||||||
|
ws.addEventListener('open', websocketOnOpen)
|
||||||
|
ws.addEventListener('message', websocketOnMessage)
|
||||||
|
ws.addEventListener('error', websocketOnError)
|
||||||
|
ws.addEventListener('close', websocketOnClose)
|
||||||
|
}
|
||||||
|
|
||||||
|
function websocketOnOpen (evt) {
|
||||||
|
window.websocketAvailable = true
|
||||||
|
console.log('open')
|
||||||
|
|
||||||
|
const foo = '{}'
|
||||||
|
|
||||||
|
ws.send(foo)
|
||||||
|
}
|
||||||
|
|
||||||
|
function websocketOnMessage (msg) {
|
||||||
|
console.log(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
function websocketOnError (err) {
|
||||||
|
window.websocketAvailable = false
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
function websocketOnClose () {
|
||||||
|
window.websocketAvailable = false
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
import { marshalActionButtonsJsonToHtml, marshalLogsJsonToHtml } from './js/marshaller.js'
|
import { marshalActionButtonsJsonToHtml, marshalLogsJsonToHtml } from './js/marshaller.js'
|
||||||
|
import { setupWebsocket } from './js/websocket.js'
|
||||||
|
|
||||||
function showSection (name) {
|
function showSection (name) {
|
||||||
for (const otherName of ['Actions', 'Logs']) {
|
for (const otherName of ['Actions', 'Logs']) {
|
||||||
|
|
@ -75,6 +76,8 @@ function processWebuiSettingsJson (settings) {
|
||||||
function main () {
|
function main () {
|
||||||
setupSections()
|
setupSections()
|
||||||
|
|
||||||
|
setupWebsocket()
|
||||||
|
|
||||||
window.fetch('webUiSettings.json').then(res => {
|
window.fetch('webUiSettings.json').then(res => {
|
||||||
return res.json()
|
return res.json()
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue