diff --git a/examples/compose/vttablet-up.sh b/examples/compose/vttablet-up.sh index 91a3c1870e5..efdb0f4d498 100755 --- a/examples/compose/vttablet-up.sh +++ b/examples/compose/vttablet-up.sh @@ -36,6 +36,13 @@ if [ -d $VTDATAROOT/$tablet_dir ]; then action='start' fi +export KEYSPACE=$keyspace +export SHARD=$shard +export TABLET_ID=$alias +export TABLET_DIR=$tablet_dir +export MYSQL_PORT=3306 +export TABLET_TYPE=$tablet_role + $VTROOT/bin/mysqlctl \ -log_dir $VTDATAROOT/tmp \ -tablet_uid $uid \ diff --git a/examples/local/vttablet-up.sh b/examples/local/vttablet-up.sh index 893621345ef..fc7d40a9764 100755 --- a/examples/local/vttablet-up.sh +++ b/examples/local/vttablet-up.sh @@ -64,6 +64,19 @@ for uid_index in $uids; do printf -v alias '%s-%010d' $cell $uid printf -v tablet_dir 'vt_%010d' $uid + export KEYSPACE=$keyspace + export SHARD=$shard + export TABLET_ID=$alias + export TABLET_DIR=$tablet_dir + export MYSQL_PORT=$mysql_port + + tablet_type=replica + if [[ $uid_index -gt 2 ]]; then + tablet_type=rdonly + fi + + export TABLET_TYPE=$tablet_type + echo "Starting MySQL for tablet $alias..." action="init -init_db_sql_file $init_db_sql_file" if [ -d $VTDATAROOT/$tablet_dir ]; then diff --git a/go/vt/hook/hook.go b/go/vt/hook/hook.go index c2844b3f362..db65ef497ae 100644 --- a/go/vt/hook/hook.go +++ b/go/vt/hook/hook.go @@ -85,6 +85,11 @@ func NewSimpleHook(name string) *Hook { return &Hook{Name: name} } +// NewHookWithEnv returns a Hook object with the provided name, params and ExtraEnv. +func NewHookWithEnv(name string, params []string, env map[string]string) *Hook { + return &Hook{Name: name, Parameters: params, ExtraEnv: env} +} + // findHook trie to locate the hook, and returns the exec.Cmd for it. func (hook *Hook) findHook() (*exec.Cmd, int, error) { // Check the hook path. diff --git a/go/vt/mysqlctl/mycnf_test.go b/go/vt/mysqlctl/mycnf_test.go index 082ea5ecc3c..5bc438c3c84 100644 --- a/go/vt/mysqlctl/mycnf_test.go +++ b/go/vt/mysqlctl/mycnf_test.go @@ -23,7 +23,9 @@ import ( "strings" "testing" + "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/env" + "vitess.io/vitess/go/vt/servenv" ) var MycnfPath = "/tmp/my.cnf" @@ -76,3 +78,82 @@ func TestMycnf(t *testing.T) { t.Errorf("mycnf.ServerID = %v, want %v", got, want) } } + +// Run this test if any changes are made to hook handling / make_mycnf hook +// other tests fail if we keep the hook around +// 1. ln -snf $VTTOP/test/vthook-make_mycnf $VTROOT/vthook/make_mycnf +// 2. Remove "No" prefix from func name +// 3. go test +// 4. \rm $VTROOT/vthook/make_mycnf +// 5. Add No Prefix back + +func NoTestMycnfHook(t *testing.T) { + os.Setenv("MYSQL_FLAVOR", "MariaDB") + uid := uint32(11111) + cnf := NewMycnf(uid, 6802) + // Assigning ServerID to be different from tablet UID to make sure that there are no + // assumptions in the code that those IDs are the same. + cnf.ServerID = 22222 + + // expect these in the output my.cnf + os.Setenv("KEYSPACE", "test-messagedb") + os.Setenv("SHARD", "0") + os.Setenv("TABLET_TYPE", "MASTER") + os.Setenv("TABLET_ID", "11111") + os.Setenv("TABLET_DIR", TabletDir(uid)) + os.Setenv("MYSQL_PORT", "15306") + // this is not being passed, so it should be nil + os.Setenv("MY_VAR", "myvalue") + + dbcfgs, err := dbconfigs.Init(cnf.SocketFile) + mysqld := NewMysqld(dbcfgs) + servenv.OnClose(mysqld.Close) + + err = mysqld.InitConfig(cnf) + if err != nil { + t.Errorf("err: %v", err) + } + _, err = ioutil.ReadFile(cnf.path) + if err != nil { + t.Errorf("failed reading, err %v", err) + return + } + mycnf := NewMycnf(uid, 0) + mycnf.path = cnf.path + mycnf, err = ReadMycnf(mycnf) + if err != nil { + t.Errorf("failed reading, err %v", err) + } else { + t.Logf("socket file %v", mycnf.SocketFile) + } + // Tablet UID should be 11111, which determines tablet/data dir. + if got, want := mycnf.DataDir, "/vt_0000011111/"; !strings.Contains(got, want) { + t.Errorf("mycnf.DataDir = %v, want *%v*", got, want) + } + // MySQL server-id should be 22222, different from Tablet UID. + if got, want := mycnf.ServerID, uint32(22222); got != want { + t.Errorf("mycnf.ServerID = %v, want %v", got, want) + } + // check that the env variables we set were passed correctly to the hook + if got, want := mycnf.lookup("KEYSPACE"), "test-messagedb"; got != want { + t.Errorf("Error passing env %v, got %v, want %v", "KEYSPACE", got, want) + } + if got, want := mycnf.lookup("SHARD"), "0"; got != want { + t.Errorf("Error passing env %v, got %v, want %v", "SHARD", got, want) + } + if got, want := mycnf.lookup("TABLET_TYPE"), "MASTER"; got != want { + t.Errorf("Error passing env %v, got %v, want %v", "TABLET_TYPE", got, want) + } + if got, want := mycnf.lookup("TABLET_ID"), "11111"; got != want { + t.Errorf("Error passing env %v, got %v, want %v", "TABLET_ID", got, want) + } + if got, want := mycnf.lookup("TABLET_DIR"), "/vt_0000011111"; !strings.Contains(got, want) { + t.Errorf("Error passing env %v, got %v, want %v", "TABLET_DIR", got, want) + } + if got, want := mycnf.lookup("MYSQL_PORT"), "15306"; got != want { + t.Errorf("Error passing env %v, got %v, want %v", "MYSQL_PORT", got, want) + } + if got := mycnf.lookup("MY_VAR"); got != "" { + t.Errorf("Unexpected env %v set to %v", "MY_VAR", got) + } +} diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index c754d0cafd7..03a3b10eea4 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -595,7 +595,13 @@ func (mysqld *Mysqld) initConfig(root string, cnf *Mycnf, outFile string) error var err error var configData string - switch hr := hook.NewSimpleHook("make_mycnf").Execute(); hr.ExitStatus { + env := make(map[string]string) + envVars := []string{"KEYSPACE", "SHARD", "TABLET_TYPE", "TABLET_ID", "TABLET_DIR", "MYSQL_PORT"} + for _, v := range envVars { + env[v] = os.Getenv(v) + } + + switch hr := hook.NewHookWithEnv("make_mycnf", nil, env).Execute(); hr.ExitStatus { case hook.HOOK_DOES_NOT_EXIST: log.Infof("make_mycnf hook doesn't exist, reading template files") configData, err = cnf.makeMycnf(getMycnfTemplates(root)) diff --git a/test/vthook-make_mycnf b/test/vthook-make_mycnf new file mode 100755 index 00000000000..9755abc56ae --- /dev/null +++ b/test/vthook-make_mycnf @@ -0,0 +1,27 @@ +#!/bin/bash + +# Copyright 2018 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# this script creates a dummy my.cnf which won't actually work +echo "KEYSPACE=""$KEYSPACE" +echo "SHARD=""$SHARD" +echo "TABLET_TYPE=""$TABLET_TYPE" +echo "TABLET_ID=""$TABLET_ID" +echo "TABLET_DIR=""$TABLET_DIR" +echo "MYSQL_PORT=""$MYSQL_PORT" + +echo "server-id = 22222" +echo "datadir = /vt/vtdataroot/vt_0000011111/data" +echo "port = 6802"