Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add exec-agent #2163

Merged
merged 1 commit into from
Dec 8, 2016
Merged

Add exec-agent #2163

merged 1 commit into from
Dec 8, 2016

Conversation

voievodin
Copy link
Contributor

@voievodin voievodin commented Aug 18, 2016

What does this PR do?

Adds a golang based implementation of exec-agent(machine-agent described in #1943).
The main goal of the exec-agent is to reduce API instance load by putting commands execution/output streaming/logs management on the side of machines.

Exec-agent consist of two main parts

  • che-websocket-terminal(copied from che-lib)
  • Commands execution/logs streaming

Available API:

Exec-agent is deployed in a couple with terminal and can be accessed via the same host and port.

Go dependencies are managed by Godep, so the PR contains vendor sources as well.

@skabashnyuk, @garagatyi, @akorneta, @tolusha check this out

@voievodin voievodin added the status/code-review This issue has a pull request posted for it and is awaiting code review completion by the community. label Aug 18, 2016
@voievodin voievodin self-assigned this Aug 18, 2016
@codenvy-ci
Copy link

Build # 143 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/143/ to view the results.

@benoitf
Copy link
Contributor

benoitf commented Aug 18, 2016

question:

is that clients will still be able to use
/api/workspace/<workspace-id>/machine/<machine-id>/command
(few days ago it was changed as it was /api/machine/machine-id/command)

or it means clients will require to be changed to call ws-agent REST-API directly ?

@@ -17,7 +17,6 @@ test-output/

# Compiled source #
###################
*.com
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need .com files ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no we don't but we need to keep vendor/github.com directory

Copy link
Contributor

@benoitf benoitf Aug 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(to authorize directories with *com)
!*.com/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'll fix it thank you

@voievodin
Copy link
Contributor Author

voievodin commented Aug 18, 2016

@benoitf check this out there are several issues which describe the process of moving from current approach to a new one, but as a result i think yes the clients will have to use exec-agent's API

@codenvy-ci
Copy link

Build # 153 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/153/ to view the results.

@@ -0,0 +1,3 @@
logs/
exec-agent
g

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add new line in the end of file. Also is the rule g really needed?

@garagatyi
Copy link

Please rebase on tom of master

@@ -0,0 +1,39 @@
// Moved from term/server.go

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment needed?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need license headers on all new files

@codenvy-ci
Copy link

Build # 401 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/401/ to view the results.

@codenvy-ci
Copy link

@codenvy-ci
Copy link

@codenvy-ci
Copy link

@codenvy-ci
Copy link

Build # 524 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/524/ to view the results.

@codenvy-ci
Copy link

Build # 571 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/571/ to view the results.

@codenvy-ci
Copy link

Build # 572 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/572/ to view the results.

@codenvy-ci
Copy link

Build # 578 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/578/ to view the results.

@codenvy-ci
Copy link

Build # 579 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/579/ to view the results.

@codenvy-ci
Copy link

Build # 580 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/580/ to view the results.

if tokenParam == "" {
return rest.Unauthorized(errors.New("Authentication failed: missing 'token' query parameter"))
}
req, err := http.NewRequest("GET", ApiEndpoint+"/machine/token/user/"+tokenParam, nil)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think spaces near plus signs would be more standart syntax, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

golang fmt formats it in this way

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@voievodin
Copy link
Contributor Author

Waiting for CQ

Copy link

@garagatyi garagatyi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is huge amount of work and it looks really awesome. I'm eager to see it merged.
I'm still reviewing but please consider my my comments. Maybe some of them are dummy, sorry if so.

xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>${item}</id>
<includeBaseDirectory>true</includeBaseDirectory>
<baseDirectory>terminal</baseDirectory>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename this one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, i haven't changed it yet because:

  • executable name should be also changed
  • agent name should be also changed

i think that the most suitable name is exec-agent but it is another, not really small bunch of work which i think should be done separately

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

- `channel`(optional) - the id of the channel which should be subscribed to the process events
- `types`(optional) - works only in couple with specified `channel`, defines
the events which will be sent by the process to the `channel`. Several values may be specified,
e.g. `channel=channel-1&types=stderr,stdout`. Possible type values:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you describe default behavior here


```json
{
"pid": 1,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a description in the docs that this is not a real PID but our API ID of a process?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, i thought it was obvious from the process.start method, which goes first in the doc and contains both nativePid and pid at the same time. But i can add a small description to the documentation about response data.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, please add


_GET /process_

- `all`(optional) - if `true` then all the processes including _dead_ ones will be returned(respecting paging ofc), otherwise if `all` is `false`, or not specified or invalid then only _alive_ processes will be returned

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if you say otherwise you can omit ifallisfalse, or not specified or invalid


- __name__ - the name of the command
- __commandLine__ - command line to execute
- __type__(optional) - command type

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we describe in this doc that it is not used in any way by the API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who knows, we don't use it right now but we may use it in future, so i would probably let it as it is

"id": "0x12345",
"params": {
"pid": 2,
"eventTypes": "stdout,stderr",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if channel is not subscribed to one(or all) of the event types?

"id": "0x12345",
"result": {
"pid": 2,
"text": "Successfully unsubscribed"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How error response looks like? How it differs from success response?

_POST /process_

- `channel`(optional) - the id of the channel which should be subscribed to the process events
- `types`(optional) - works only in couple with specified `channel`, defines

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In other places docs states comma separated types, maybe this one should do the same?

"id": "0x12345",
"params": {
"pid": 2,
"eventTypes": "process_status"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How error response looks like?
How it differs from success response?
What if channel is not subscribed to one(or all) of the event types?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i will document error responses as well

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you


##### Response

For the command `printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10`, the result will look like

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is response limited in size? Is it chunked with websocket protocol? Does it have paging? Does it show only logs produced before this request got to the server?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request section for this response covers your questions.

Does it show only logs produced before this request got to the server?

It will use logs [first logged message, time.Now()] where time.Now is a time when server receives request

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. And what about size of response in bytes, is it limited? Does websocket protocol handle that somehow?

@codenvy-ci
Copy link

xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>${item}</id>
<includeBaseDirectory>true</includeBaseDirectory>
<baseDirectory>terminal</baseDirectory>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

if tokenParam == "" {
return rest.Unauthorized(errors.New("Authentication failed: missing 'token' query parameter"))
}
req, err := http.NewRequest("GET", ApiEndpoint+"/machine/token/user/"+tokenParam, nil)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok


```json
{
"pid": 1,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, please add

"id": "0x12345",
"params": {
"pid": 2,
"eventTypes": "process_status"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you


##### Response

For the command `printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10`, the result will look like

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. And what about size of response in bytes, is it limited? Does websocket protocol handle that somehow?

```


#### Get process logs

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix heading please

flag.BoolVar(&auth.Enabled, "enable-auth", false, "Whether authenticate on workspace master or not")
flag.StringVar(&auth.ApiEndpoint,
"auth-api-endpoint",
os.Getenv("CHE_API_ENDPOINT"),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this env var was recently renamed to CHE_API. Please also rename --auth-api-endpoint parameter

flag.StringVar(&auth.ApiEndpoint,
"auth-api-endpoint",
os.Getenv("CHE_API_ENDPOINT"),
"Auth api-endpoint, by default 'CHEAPI-ENDPOINT' environment variable is used for this")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix description of default value

"Auth api-endpoint, by default 'CHEAPI-ENDPOINT' environment variable is used for this")

// Process configuration
flag.IntVar(&process.CleanupPeriodInMinutes, "process-cleanup-period", 2, "How often processs cleanup will happen(in minutes)")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use ENV var to set all of the params? It is getting popular after refactoring of Che CLI

// Process configuration
flag.IntVar(&process.CleanupPeriodInMinutes, "process-cleanup-period", 2, "How often processs cleanup will happen(in minutes)")
flag.IntVar(&process.CleanupThresholdInMinutes,
"process-lifetime",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is more process cleanup than lifetime

@codenvy-ci
Copy link

}

serverAddress string
staticFlag string

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why these variables are called flags? usually that term is used with boolean variables

// Server configuration
flag.StringVar(&serverAddress, "addr", ":9000", "IP:PORT or :PORT the address to start the server on")
flag.StringVar(&staticFlag, "static", "./static/", "path to static content")
flag.StringVar(&pathFlag, "path", "", "Path of the pty server. Go regexp syntax is suported.")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this whole path to pty or just prefix?

flag.Parse()

// print configuration
fmt.Println("Exec-agent configuration")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think code can be cleaner if you split it into methods print summary, normalize base path, cleanup resources, setup routes, etc

<artifactId>license-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>*.*</exclude>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we need to exclude all the files from license header check?

Copy link
Contributor Author

@voievodin voievodin Nov 29, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is temporary solution, i will remove it and handle go files as well

for _, t := range strings.Split(types, ",") {
switch strings.ToLower(strings.TrimSpace(t)) {
case "stderr":
mask |= StderrBit

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this code is in common file, then maybe it would be a good idea to put these constants here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is rather webscoket & rest apis commons, i will rename it to service_commons.go
in accordance to rest_service.go, ws_service.go names

@@ -0,0 +1,114 @@
package process_test

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does maven run these tests on its test phase?

Copy link
Contributor Author

@voievodin voievodin Nov 29, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, i am going to add tests phase

//
// Request.
// It's a message from the physical websocket connection client to the exec-agent server.
// Request(in it's origin form) is considered is considered to be unidirectional.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo - is considered is used twice

@Inject
public TerminalAgentLauncherImpl(@Named("che.agent.dev.max_start_time_ms") long agentMaxStartTimeMs,
@Named("che.agent.dev.ping_delay_ms") long agentPingDelayMs) {
@Named("che.agent.dev.ping_delay_ms") long agentPingDelayMs,
@Named("machine.terminal_agent.run_command") String runCommand) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is exec agent and this property is new, maybe we can call it as exec agent run command?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, it may be confusing for people, as long as executable is named che-websocket-terminal and agent name is terminal, the command should be named appropriately.

@codenvy-ci
Copy link

Build # 1157 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/1157/ to view the results.

@codenvy-ci
Copy link

@codenvy-ci
Copy link

@voievodin voievodin force-pushed the exec-agent branch 2 times, most recently from 19a4927 to a34f616 Compare December 1, 2016 16:55
@codenvy-ci
Copy link

Build # 1194 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/1194/ to view the results.

@voievodin
Copy link
Contributor Author

Gorilla mux was replaced with httprouter, waiting for CQ

@codenvy-ci
Copy link

@codenvy-ci
Copy link

@codenvy-ci
Copy link

@codenvy-ci
Copy link

Build # 1222 - FAILED

Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/1222/ to view the results.

@codenvy-ci
Copy link

@codenvy-ci
Copy link

@voievodin voievodin deleted the exec-agent branch January 17, 2017 08:23
JPinkney pushed a commit to JPinkney/che that referenced this pull request Aug 17, 2017
@benoitf benoitf removed the status/code-review This issue has a pull request posted for it and is awaiting code review completion by the community. label Nov 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants