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: Refactor out usage of servenv #14732

Merged

Conversation

dbussink
Copy link
Contributor

@dbussink dbussink commented Dec 8, 2023

The servenv package is something that is use for server environments like vtgate, vttablet etc. But the go/mysql package should really be independent code for things like the MySQL protocol bits.

This change refactors things so that go/mysql doesn't depend anymore on servenv. This makes it easier to be used as a library for example.

The remaining bits here are in collations, which is something to tackle separately as it's very invasive.

Related Issue(s)

Part of #14717

Checklist

  • "Backport to:" labels have been added if this change should be back-ported
  • Tests were added or are not required
  • Did the new or modified tests pass consistently locally and on the CI
  • Documentation was added or is not required

Copy link
Contributor

vitess-bot bot commented Dec 8, 2023

Review Checklist

Hello reviewers! 👋 Please follow this checklist when reviewing this Pull Request.

General

  • Ensure that the Pull Request has a descriptive title.
  • Ensure there is a link to an issue (except for internal cleanup and flaky test fixes), new features should have an RFC that documents use cases and test cases.

Tests

  • Bug fixes should have at least one unit or end-to-end test, enhancement and new features should have a sufficient number of tests.

Documentation

  • Apply the release notes (needs details) label if users need to know about this change.
  • New features should be documented.
  • There should be some code comments as to why things are implemented the way they are.
  • There should be a comment at the top of each new or modified test to explain what the test does.

New flags

  • Is this flag really necessary?
  • Flag names must be clear and intuitive, use dashes (-), and have a clear help text.

If a workflow is added or modified:

  • Each item in Jobs should be named in order to mark it as required.
  • If the workflow needs to be marked as required, the maintainer team must be notified.

Backward compatibility

  • Protobuf changes should be wire-compatible.
  • Changes to _vt tables and RPCs need to be backward compatible.
  • RPC changes should be compatible with vitess-operator
  • If a flag is removed, then it should also be removed from vitess-operator and arewefastyet, if used there.
  • vtctl command output order should be stable and awk-able.

@vitess-bot vitess-bot bot added NeedsDescriptionUpdate The description is not clear or comprehensive enough, and needs work NeedsIssue A linked issue is missing for this Pull Request NeedsWebsiteDocsUpdate What it says labels Dec 8, 2023
@github-actions github-actions bot added this to the v19.0.0 milestone Dec 8, 2023
vtgate.RegisterPluginInitializer(func() { mysql.InitAuthServerClientCert() })
servenv.OnParseFor("vtgate", func(fs *pflag.FlagSet) {
fs.StringVar(&clientcertAuthMethod, "mysql_clientcert_auth_method", string(mysql.MysqlClearPassword), "client-side authentication method to use. Supported values: mysql_clear_password, dialog.")
})
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 one and others still have the same flags, but now moved into vtgate which I think is a better place anyway to have them set up.

fs.StringVar(&mysqlAuthServerStaticFile, "mysql_auth_server_static_file", "", "JSON File to read the users/passwords from.")
fs.StringVar(&mysqlAuthServerStaticString, "mysql_auth_server_static_string", "", "JSON representation of the users/passwords config.")
fs.DurationVar(&mysqlAuthServerStaticReloadInterval, "mysql_auth_static_reload_interval", 0, "Ticker to reload credentials")
fs.DurationVar(&mysqlServerFlushDelay, "mysql_server_flush_delay", mysqlServerFlushDelay, "Delay after which buffered response will be flushed to the client.")
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 flag was in a very wrong place. It was in the auth plugin, but it's a MySQL protocol config flag! It was moved to the vtgate mysql plugin server instead which seems much more appropriate.

@@ -263,6 +263,8 @@ func getHostPort(t *testing.T, a net.Addr) (string, int) {
return host, port
}

const mysqlVersion = "8.0.30-Vitess"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only used for testing here, so better to just copy a static value than depending on the whole servenv.

Copy link
Contributor

Choose a reason for hiding this comment

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

there are a few places i saw where you missed using this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ajm188 I'll fix up the ones I missed, but it can't be used in all cases, since this is in the test file only. That's deliberate so it doesn't get used accidentally.

@@ -97,6 +99,7 @@ func registerPluginFlags(fs *pflag.FlagSet) {
fs.DurationVar(&mysqlQueryTimeout, "mysql_server_query_timeout", mysqlQueryTimeout, "mysql query timeout")
fs.BoolVar(&mysqlConnBufferPooling, "mysql-server-pool-conn-read-buffers", mysqlConnBufferPooling, "If set, the server will pool incoming connection read buffers")
fs.DurationVar(&mysqlKeepAlivePeriod, "mysql-server-keepalive-period", mysqlKeepAlivePeriod, "TCP period between keep-alives")
fs.DurationVar(&mysqlServerFlushDelay, "mysql_server_flush_delay", mysqlServerFlushDelay, "Delay after which buffered response will be flushed to the client.")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It has underscores since this moves the flag to its appropriate location.

Copy link
Contributor

Choose a reason for hiding this comment

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

we can also define a new flag and fs.MarkDeprecated this one to support both

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'd like to keep it this way. Dunno if we have a generic plan to do this? Since I wouldn't want to do it just for a one off flag then which only happens due to a refactor that for most end users is not really relevant anyway.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah let's not do a one-off flag rename/deprecation. We should tackle all of them together.

@@ -1470,12 +1472,10 @@ func TestParseConnAttrs(t *testing.T) {
}

func TestServerFlush(t *testing.T) {
defer func(saved time.Duration) { mysqlServerFlushDelay = saved }(mysqlServerFlushDelay)
mysqlServerFlushDelay = 10 * time.Millisecond
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 removes global state modification which is a great win imho.

@dbussink dbussink removed NeedsDescriptionUpdate The description is not clear or comprehensive enough, and needs work NeedsWebsiteDocsUpdate What it says NeedsIssue A linked issue is missing for this Pull Request labels Dec 8, 2023
The servenv package is something that is use for server environments
like vtgate, vttablet etc. But the go/mysql package should really be
independent code for things like the MySQL protocol bits.

This change refactors things so that go/mysql doesn't depend anymore on
servenv. This makes it easier to be used as a library for example.

The remaining bits here are in collations, which is something to tackle
separately as it's very invasive.

Signed-off-by: Dirkjan Bussink <[email protected]>
@dbussink dbussink force-pushed the dbussink/refactor-mysql-servenv-usage branch from a84ee7a to 1e8b3b3 Compare December 8, 2023 15:20
vtgate.RegisterPluginInitializer(func() { ldapauthserver.Init() })
Main.Flags().StringVar(&ldapAuthConfigFile, "mysql_ldap_auth_config_file", "", "JSON File from which to read LDAP server config.")
Main.Flags().StringVar(&ldapAuthConfigString, "mysql_ldap_auth_config_string", "", "JSON representation of LDAP server config.")
Main.Flags().StringVar(&ldapAuthMethod, "mysql_ldap_auth_method", string(mysql.MysqlClearPassword), "client-side authentication method to use. Supported values: mysql_clear_password, dialog.")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ajm188 Had to use Main.Flags() here since the on parse callbacks don't work as it's too late since cli.go inits first, but dunno if this is the right fix then? Or if there's another way?

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, that's what we're currently doing? https://github.com/vitessio/vitess/blob/main/go/cmd/vtgate/cli/cli.go#L187-L189 i'm not sure if that answers your question

Copy link
Contributor

@ajm188 ajm188 left a comment

Choose a reason for hiding this comment

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

looking good! few small things but lgtm after those

vtgate.RegisterPluginInitializer(func() { ldapauthserver.Init() })
Main.Flags().StringVar(&ldapAuthConfigFile, "mysql_ldap_auth_config_file", "", "JSON File from which to read LDAP server config.")
Main.Flags().StringVar(&ldapAuthConfigString, "mysql_ldap_auth_config_string", "", "JSON representation of LDAP server config.")
Main.Flags().StringVar(&ldapAuthMethod, "mysql_ldap_auth_method", string(mysql.MysqlClearPassword), "client-side authentication method to use. Supported values: mysql_clear_password, dialog.")
Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, that's what we're currently doing? https://github.com/vitessio/vitess/blob/main/go/cmd/vtgate/cli/cli.go#L187-L189 i'm not sure if that answers your question

go/mysql/conn.go Show resolved Hide resolved
go/mysql/fakesqldb/server.go Show resolved Hide resolved
@@ -327,7 +327,7 @@ func FuzzTLSServer(data []byte) int {
Password: "password1",
}}
defer authServer.close()
l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false)
l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, 0, "8.0.30-Vitess")
Copy link
Contributor

Choose a reason for hiding this comment

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

and here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same here, this one can't use it as it's not in the test file(s).

@@ -263,6 +263,8 @@ func getHostPort(t *testing.T, a net.Addr) (string, int) {
return host, port
}

const mysqlVersion = "8.0.30-Vitess"
Copy link
Contributor

Choose a reason for hiding this comment

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

there are a few places i saw where you missed using this

@@ -97,6 +99,7 @@ func registerPluginFlags(fs *pflag.FlagSet) {
fs.DurationVar(&mysqlQueryTimeout, "mysql_server_query_timeout", mysqlQueryTimeout, "mysql query timeout")
fs.BoolVar(&mysqlConnBufferPooling, "mysql-server-pool-conn-read-buffers", mysqlConnBufferPooling, "If set, the server will pool incoming connection read buffers")
fs.DurationVar(&mysqlKeepAlivePeriod, "mysql-server-keepalive-period", mysqlKeepAlivePeriod, "TCP period between keep-alives")
fs.DurationVar(&mysqlServerFlushDelay, "mysql_server_flush_delay", mysqlServerFlushDelay, "Delay after which buffered response will be flushed to the client.")
Copy link
Contributor

Choose a reason for hiding this comment

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

we can also define a new flag and fs.MarkDeprecated this one to support both

@@ -348,7 +348,7 @@ func TestGracefulShutdown(t *testing.T) {

vh := newVtgateHandler(&VTGate{executor: executor, timings: timings, rowsReturned: rowsReturned, rowsAffected: rowsAffected})
th := &testHandler{}
listener, err := mysql.NewListener("tcp", "127.0.0.1:", mysql.NewAuthServerNone(), th, 0, 0, false, false, 0)
listener, err := mysql.NewListener("tcp", "127.0.0.1:", mysql.NewAuthServerNone(), th, 0, 0, false, false, 0, 0, "8.0.30-Vitess")
Copy link
Contributor

Choose a reason for hiding this comment

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

missed one here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not an exposed constant, so it can't be used here. I can turn these two into their own constant? I thought about it and didn't know if it was worth it for 2 or not then.

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah tests-only seems fine this way

@@ -378,7 +378,7 @@ func TestGracefulShutdownWithTransaction(t *testing.T) {

vh := newVtgateHandler(&VTGate{executor: executor, timings: timings, rowsReturned: rowsReturned, rowsAffected: rowsAffected})
th := &testHandler{}
listener, err := mysql.NewListener("tcp", "127.0.0.1:", mysql.NewAuthServerNone(), th, 0, 0, false, false, 0)
listener, err := mysql.NewListener("tcp", "127.0.0.1:", mysql.NewAuthServerNone(), th, 0, 0, false, false, 0, 0, "8.0.30-Vitess")
Copy link
Contributor

Choose a reason for hiding this comment

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

and here

Copy link
Collaborator

@vmg vmg left a comment

Choose a reason for hiding this comment

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

Looks good overall. Not looking forward to fixing collations.

@@ -80,7 +51,7 @@ type AuthServerVault struct {
}

// InitAuthServerVault - entrypoint for initialization of Vault AuthServer implementation
func InitAuthServerVault() {
func InitAuthServerVault(vaultAddr string, vaultTimeout time.Duration, vaultCACert, vaultPath string, vaultCacheTTL time.Duration, vaultTokenFile, vaultRoleID, vaultRoleSecretIDFile, vaultRoleMountPoint string) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

These are quite a few args. Maybe enough that we should construct a struct out of them.

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 thought about that, but we already use the whole list one call site down as well. So I don't consider it to really be anything significantly worse than before.

@dbussink dbussink merged commit ab1ba2e into vitessio:main Dec 8, 2023
116 checks passed
@dbussink dbussink deleted the dbussink/refactor-mysql-servenv-usage branch December 8, 2023 20:50
ejortegau pushed a commit to slackhq/vitess that referenced this pull request Dec 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: General Changes throughout the code base Type: Internal Cleanup
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants