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

Mysql cli #353

Merged
merged 14 commits into from
Mar 21, 2019
Merged

Mysql cli #353

merged 14 commits into from
Mar 21, 2019

Conversation

smacker
Copy link
Contributor

@smacker smacker commented Mar 19, 2019

Fix: #154
Fix: #278

Most probably it fixes some other issue but they need to be tested with this patch.

It currently uses mysql image and separate container to run client. When src-d/gitbase#733 is fixed & released we can switch to using that image. Or we can use some other client such as mysqlsh.

It will be also possible to refactor it without starting separate container but attaching to gitbase one.
Most probably it should be very little change.

@smacker smacker requested a review from a team March 19, 2019 14:57
@smacker
Copy link
Contributor Author

smacker commented Mar 19, 2019

go mod check has failed 🤦‍♀️ Please don't mind it now, I'll figure how to fix it and push it later.

@smacker
Copy link
Contributor Author

smacker commented Mar 19, 2019

Okay. I was able to fix it only by updating go to 1.12.1 locally, removing local cache, removing go.sum, removing vendor. Missing any of this was producing a different result 🤦‍♀️

Copy link
Contributor

@carlosms carlosms left a comment

Choose a reason for hiding this comment

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

I've tested it a bit and works great for the normal usage.
Pushing the limits a bit I found these problems:

  • I cannot use the up arrow to use the latest command, or ctrl+R to search the history
  • If I exit the client with exit the mysql container is stopped, but not if I exit with ctrl+C

Then, there is the missing parts to put this new component at the same level as the other components:

  • It does not appear in the srcd components list output
  • It is not included in other commands, like srcd prune --with-images. Which I'm not sure if it should... if engine installed the mysql image then yes, it should be pruned. But you may have that image before using engine 🤔

I guess you didn't include the new component in components list and other commands because we will eventually use the mysql client from the gitbase image.
But we may have to do an engine release before gitbase does a new release. Ideally I think we should have our master ready to release at any moment.

What do you think? should we make this new component a "first class" component before merging? or keep this PR open until gitbase includes the mysql client?

// Might have to pull some images
ctx, cancel := context.WithTimeout(context.Background(), 1440*time.Minute)
defer cancel()
func installMysqlCli(client api.EngineClient) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick, but since the function also starts gitbase, I would either change the function name, or do the gitbase start outside of the function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

do you think installMysqlCliWithDeps is a good name for it?
I do everything in 1 function because this way I'm able to use defer and print log message only once.

Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense to bundle it in one function. I guess what seemed a bit strange to me is here:

if err := installMysqlCli(client); err != nil {
	fatal(err, "could not install mysql client")
}

connReady := logAfterTimeoutWithSpinner("waiting for gitbase to be ready", 5*time.Second, 0)
err = ensureConnReady(client)
connReady()
if err != nil {
	fatal(err, "could not connect to gitbase")
}

It reads like you install the mysql client, and then you check the connectivity to gitbase. Maybe this function should be called startGitbaseWithClient?

Honestly it's a small nickpick, leave as it is if you think it's ok.

Copy link
Contributor Author

@smacker smacker Mar 20, 2019

Choose a reason for hiding this comment

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

startGitbaseWithClient is a good name. Applied in: src-d/sourced-ce@9542724

also, I changed the signature so the function doesn't return an error anymore. I did it to make error handling for gitbase & mysql-cli consistent.

}
defer resp.Close()
defer func() {
err := docker.RemoveContainer(components.MysqlCli.Name)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why you remove the container? Isn't it better to remove it only on srcd stop?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that is a very good question. I did it for a reason for sure. But I don't remember this reason anymore... 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ahhh. because the container wasn't presented in the components list and stop wasn't stopping it. After the recent change, I think I don't need to remove it anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ooops. No. We still need it. To show help & mysql > with current implementation.
It's possible to run new mysql command in the same container each time but it would require more changes. Do you want me to do it in this PR?

Copy link
Contributor

Choose a reason for hiding this comment

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

No I'd consider it as an improvement, thanks for the clarification!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now I remember the original reason. I looked at how web client works. It removes container on exit. So I did the same for cli client.

(moved this comment from a wrong thread)

@smacker
Copy link
Contributor Author

smacker commented Mar 20, 2019

I cannot use the up arrow to use the latest command, or ctrl+R to search the history

that is interesting. Thanks! It works in the client itself. Need to investigate more why it doesn't work using current attach. Though this PR already solves many problems. Maybe we can fix it in sequential pr. (I'm not sure how hard it will be to fix lacking features)

If I exit the client with exit the mysql container is stopped, but not if I exit with ctrl+C

I'll fix it. Should be simple.

It does not appear in the srcd components list output
It is not included in other commands, like srcd prune --with-images. Which I'm not sure if it should... if engine installed the mysql image then yes, it should be pruned. But you may have that image before using engine 🤔

I'll fix it. Should be simple.

@se7entyse7en
Copy link
Contributor

BTW well done! 👏 and also to @carlosms for pushing the limits!

@smacker
Copy link
Contributor Author

smacker commented Mar 20, 2019

Update:

  • add client into components list -> done
  • consistent behavior for Ctrl-C & exit
  • fix for Ctrl-D (discovered myself)

Pending:

  • now, after adding it to components list it's possible to keep container running, though it would require adding Exec command to docker. Shouldn't be very difficult but most probably quite many changes
  • fix special keys like "Ctrl-R" and arrow-up. Right now I have no idea why they don't work, need to investigate

Do you guys want me to implement pending things in this PR or in sequential ones? (imo this pr is big enough already and pending things are more features than bugs)

@se7entyse7en
Copy link
Contributor

imo this pr is big enough already

yup, I agree. I'd close this and open issues for the pending things.

@se7entyse7en
Copy link
Contributor

Just one thing. Could you make more clear whether we want to give priority to the input from piping or from args? What I mean is that we could move the reading of args just before checking if the stdin is a pipe. So something like this:

		var query string
		if len(args) == 1 {
			query = strings.TrimSpace(args[0])
		} else {
			fi, _ := os.Stdin.Stat()
			if (fi.Mode() & os.ModeCharDevice) == 0 {
				fmt.Println("b")
				b, err := ioutil.ReadAll(os.Stdin)
				if err != nil {
					fatal(err, "could not read input")
				}

				query = string(b)
			}
		}

or like this:

		fi, _ := os.Stdin.Stat()
		if (fi.Mode() & os.ModeCharDevice) == 0 {
			fmt.Println("b")
			b, err := ioutil.ReadAll(os.Stdin)
			if err != nil {
				fatal(err, "could not read input")
			}

			query = string(b)
		} else if len(args) == 1 {
			query = strings.TrimSpace(args[0])
		}

depending on to which we want to give priority. We could also move it in a separate function to make the flow of the code easier to read.

defer stopMysqlClient()

// in case of Ctrl-C or kill defer wouldn't work
ch := make(chan os.Signal, 1)
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we could unify this with the logic in attachStdio? I was thinking about sending nil (or an error identifying the signal) to ouputDone or inputDone when one of the two signals arrive.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we can't put this logic into attachStdio because we need to handle signal correctly for the case when we don't attach stdin too. Example: you run select * from files which takes a lot of time, Ctrl-C should stop the query and remove container correctly. Instead of writing additional code for this case we can handle it using this function in both cases with or without stdin.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok! gonna approved then! thank!

@smacker
Copy link
Contributor Author

smacker commented Mar 21, 2019

Imo priority for arg or stdin doesn't matter. Mixing them would work weird anyway. For example how mysql-cli itself works with it:

root@2a07b9ea86ca:/# echo "select 2" | mysql -h srcd-cli-gitbase -e "select 1"
1
1

It prefers arguments over stdin but changes output format to -B one.

I changed to if/else to make it more clear but I disagree about moving it to function. I think we should improve it later by really piping stdin to mysql-cli instead of overriding the query. (but as I mentioned in the comment it would change current output)

@@ -519,3 +519,52 @@ func GetLogs(ctx context.Context, containerID string) (io.ReadCloser, error) {

return reader, err
}

func Attach(ctx context.Context, config *container.Config, host *container.HostConfig, name string) (*types.HijackedResponse, chan int64, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

By Attach it sounds like this command should be used like docker attach, over a running container. So you call Start and then Attach.

But this method already starts the container.
I guess you need to it this way for the attach config settings. Is there a way to attach to a running container? I think it would be more clear.
It not, I would consider changing the method name. StartAttach? And documenting what it does.

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 command actually works as docker run -it. The difference from normal docker attach is that it attaches BEFORE starting the container. So you have all the output of the container.
You can try with docker by running docker run mysql mysql -e "select * from files" and then docker attach. You will get only part of the output since the moment you attached.

I don't see any use case when engine would need attach to a running container. So I named it just Attach not AttachRun or StartAttach. But I don't mind to rename it if you prefer so.

Later we can implement exec that actually attaches to a running container and runs a command. It should be very similar code. (most probably reuse parts of this function). Though for exec we need image that runs something as pid 1 and doesn't exit. Like new gitbase. For the current image run is a better fit.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the explanation. Attaching before starting the container is a very good reason to keep it like it's now 👍.

Maybe we could add comment explaining that it's similar to run -it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
Signed-off-by: Maxim Sukharev <max@smacker.ru>
@smacker
Copy link
Contributor Author

smacker commented Mar 21, 2019

rebased on master due to conflicts

@smacker smacker merged commit c7cdeee into src-d:master Mar 21, 2019
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.

running a query fails with srcd sql but not with srcd web sql Improve/replace srcd sql client
3 participants