func ActionNodeToJson(n *ActionNode) string { result := jscfg.ToJson(n) + "\n" if n.args == nil { result += "{}\n" } else { result += jscfg.ToJson(n.args) + "\n" } if n.reply == nil { result += "{}\n" } else { result += jscfg.ToJson(n.reply) + "\n" } return result }
func (zkts *Server) UpdateKeyspace(ki *topo.KeyspaceInfo) error { keyspacePath := path.Join(globalKeyspacesPath, ki.KeyspaceName()) data := jscfg.ToJson(ki.Keyspace) _, err := zkts.zconn.Set(keyspacePath, data, -1) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { // The code should be: // err = topo.ErrNoNode // Temporary code until we have Keyspace object // everywhere: _, err = zkts.zconn.Create(keyspacePath, data, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { // the directory doesn't even exist err = topo.ErrNoNode } return err } event.Dispatch(&events.KeyspaceChange{ KeyspaceInfo: *ki, Status: "updated (had to create Keyspace object)", }) return nil } return err } event.Dispatch(&events.KeyspaceChange{ KeyspaceInfo: *ki, Status: "updated", }) return nil }
func (zkts *Server) UpdateShardReplicationFields(cell, keyspace, shard string, update func(*topo.ShardReplication) error) error { // create the parent directory to be sure it's here zkDir := path.Join("/zk", cell, "vt", "replication", keyspace) if _, err := zk.CreateRecursive(zkts.zconn, zkDir, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)); err != nil && !zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { return err } // now update the data zkPath := shardReplicationPath(cell, keyspace, shard) f := func(oldValue string, oldStat zk.Stat) (string, error) { sr := &topo.ShardReplication{} if oldValue != "" { if err := json.Unmarshal([]byte(oldValue), sr); err != nil { return "", err } } if err := update(sr); err != nil { return "", err } return jscfg.ToJson(sr), nil } err := zkts.zconn.RetryChange(zkPath, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return err } return nil }
func (zkts *Server) CreateShard(keyspace, shard string, value *topo.Shard) error { shardPath := path.Join(globalKeyspacesPath, keyspace, "shards", shard) pathList := []string{ shardPath, path.Join(shardPath, "action"), path.Join(shardPath, "actionlog"), } alreadyExists := false for i, zkPath := range pathList { c := "" if i == 0 { c = jscfg.ToJson(value) } _, err := zk.CreateRecursive(zkts.zconn, zkPath, c, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { alreadyExists = true } else { return fmt.Errorf("error creating shard: %v %v", zkPath, err) } } } if alreadyExists { return topo.ErrNodeExists } return nil }
func (zkts *Server) updateTabletEndpoint(oldValue string, oldStat zk.Stat, addr *topo.VtnsAddr) (newValue string, err error) { if oldStat == nil { // The incoming object doesn't exist - we haven't been placed in the serving // graph yet, so don't update. Assume the next process that rebuilds the graph // will get the updated tablet location. return "", skipUpdateErr } var addrs *topo.VtnsAddrs if oldValue != "" { addrs, err = topo.NewVtnsAddrs(oldValue, oldStat.Version()) if err != nil { return } foundTablet := false for i, entry := range addrs.Entries { if entry.Uid == addr.Uid { foundTablet = true if !topo.VtnsAddrEquality(&entry, addr) { addrs.Entries[i] = *addr } break } } if !foundTablet { addrs.Entries = append(addrs.Entries, *addr) } } else { addrs = topo.NewAddrs() addrs.Entries = append(addrs.Entries, *addr) } return jscfg.ToJson(addrs), nil }
func (zkts *Server) UpdateTabletFields(tabletAlias topo.TabletAlias, update func(*topo.Tablet) error) error { zkTabletPath := TabletPathForAlias(tabletAlias) f := func(oldValue string, oldStat zk.Stat) (string, error) { if oldValue == "" { return "", fmt.Errorf("no data for tablet addr update: %v", tabletAlias) } tablet, err := topo.TabletFromJson(oldValue) if err != nil { return "", err } if err := update(tablet); err != nil { return "", err } return jscfg.ToJson(tablet), nil } err := zkts.zconn.RetryChange(zkTabletPath, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return err } return nil }
func (zkts *Server) CreateKeyspace(keyspace string, value *topo.Keyspace) error { keyspacePath := path.Join(globalKeyspacesPath, keyspace) pathList := []string{ keyspacePath, path.Join(keyspacePath, "action"), path.Join(keyspacePath, "actionlog"), path.Join(keyspacePath, "shards"), } alreadyExists := false for i, zkPath := range pathList { c := "" if i == 0 { c = jscfg.ToJson(value) } _, err := zk.CreateRecursive(zkts.zconn, zkPath, c, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { alreadyExists = true } else { return fmt.Errorf("error creating keyspace: %v %v", zkPath, err) } } } if alreadyExists { return topo.ErrNodeExists } event.Dispatch(&events.KeyspaceChange{ KeyspaceInfo: *topo.NewKeyspaceInfo(keyspace, value), Status: "created", }) return nil }
func main() { dbConfigsFile, dbCredentialsFile := dbconfigs.RegisterCommonFlags() flag.Parse() relog.Info("started vtaction %v", os.Args) rpc.HandleHTTP() jsonrpc.ServeHTTP() jsonrpc.ServeRPC() bsonrpc.ServeHTTP() bsonrpc.ServeRPC() logFile, err := os.OpenFile(*logFilename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0666) if err != nil { relog.Fatal("Can't open log file: %v", err) } relog.SetOutput(logFile) relog.SetPrefix(fmt.Sprintf("vtaction [%v] ", os.Getpid())) if err := relog.SetLevelByName(*logLevel); err != nil { relog.Fatal("%v", err) } relog.HijackLog(nil) relog.HijackStdio(logFile, logFile) mycnf, mycnfErr := mysqlctl.ReadMycnf(*mycnfFile) if mycnfErr != nil { relog.Fatal("mycnf read failed: %v", mycnfErr) } relog.Debug("mycnf: %v", jscfg.ToJson(mycnf)) dbcfgs, cfErr := dbconfigs.Init(mycnf.SocketFile, *dbConfigsFile, *dbCredentialsFile) if err != nil { relog.Fatal("%s", cfErr) } mysqld := mysqlctl.NewMysqld(mycnf, dbcfgs.Dba, dbcfgs.Repl) topoServer := topo.GetServer() defer topo.CloseServers() actor := tabletmanager.NewTabletActor(mysqld, topoServer) // we delegate out startup to the micromanagement server so these actions // will occur after we have obtained our socket. bindAddr := fmt.Sprintf(":%v", *port) httpServer := &http.Server{Addr: bindAddr} go func() { if err := httpServer.ListenAndServe(); err != nil { relog.Error("httpServer.ListenAndServe err: %v", err) } }() actionErr := actor.HandleAction(*actionNode, *action, *actionGuid, *force) if actionErr != nil { relog.Fatal("action error: %v", actionErr) } relog.Info("finished vtaction %v", os.Args) }
func (zkts *Server) UpdateSrvKeyspace(cell, keyspace string, srvKeyspace *topo.SrvKeyspace) error { path := zkPathForVtKeyspace(cell, keyspace) data := jscfg.ToJson(srvKeyspace) _, err := zkts.zconn.Set(path, data, -1) if zookeeper.IsError(err, zookeeper.ZNONODE) { _, err = zk.CreateRecursive(zkts.zconn, path, data, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) } return err }
func (zkts *Server) UpdateShard(si *topo.ShardInfo) error { shardPath := path.Join(globalKeyspacesPath, si.Keyspace(), "shards", si.ShardName()) _, err := zkts.zconn.Set(shardPath, jscfg.ToJson(si.Shard), -1) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } } return err }
func (zkts *Server) UpdateKeyspace(ki *topo.KeyspaceInfo) error { keyspacePath := path.Join(globalKeyspacesPath, ki.KeyspaceName()) _, err := zkts.zconn.Set(keyspacePath, jscfg.ToJson(ki.Keyspace), -1) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { // The code should be: // err = topo.ErrNoNode // Temporary code until we have Keyspace object // everywhere: _, err = zkts.zconn.Create(keyspacePath, jscfg.ToJson(ki.Keyspace), 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { // the directory doesn't even exist err = topo.ErrNoNode } } } } return err }
func (zkts *Server) CreateShardReplication(cell, keyspace, shard string, sr *topo.ShardReplication) error { data := jscfg.ToJson(sr) zkPath := shardReplicationPath(cell, keyspace, shard) _, err := zk.CreateRecursive(zkts.zconn, zkPath, data, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { err = topo.ErrNodeExists } return err } return nil }
func (zkts *Server) UpdateSrvTabletType(cell, keyspace, shard string, tabletType topo.TabletType, addrs *topo.VtnsAddrs) error { path := zkPathForVtName(cell, keyspace, shard, tabletType) data := jscfg.ToJson(addrs) _, err := zk.CreateRecursive(zkts.zconn, path, data, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { // Node already exists - just stomp away. Multiple writers shouldn't be here. // We use RetryChange here because it won't update the node unnecessarily. f := func(oldValue string, oldStat zk.Stat) (string, error) { return data, nil } err = zkts.zconn.RetryChange(path, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) } } return err }
func (zkts *Server) UpdateShard(si *topo.ShardInfo) error { shardPath := path.Join(globalKeyspacesPath, si.Keyspace(), "shards", si.ShardName()) _, err := zkts.zconn.Set(shardPath, jscfg.ToJson(si.Shard), -1) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return err } event.Dispatch(&events.ShardChange{ ShardInfo: *si, Status: "updated", }) return nil }
func TestExtraFieldsJson(t *testing.T) { swra := &SlaveWasRestartedArgs{ Parent: topo.TabletAlias{ Uid: 1, Cell: "aa", }, } data := jscfg.ToJson(swra) output := &slaveWasRestartedTestArgs{} decoder := json.NewDecoder(strings.NewReader(data)) err := decoder.Decode(output) if err != nil { t.Errorf("Cannot re-decode struct without field: %v", err) } }
func (zkts *Server) UpdateShard(si *topo.ShardInfo, existingVersion int64) (int64, error) { shardPath := path.Join(globalKeyspacesPath, si.Keyspace(), "shards", si.ShardName()) stat, err := zkts.zconn.Set(shardPath, jscfg.ToJson(si.Shard), int(existingVersion)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return -1, err } event.Dispatch(&events.ShardChange{ ShardInfo: *si, Status: "updated", }) return int64(stat.Version()), nil }
func main() { dbconfigs.RegisterFlags() mysqlctl.RegisterFlags() flag.Parse() servenv.Init() defer servenv.Close() log.Infof("started vtaction %v", os.Args) servenv.ServeRPC() mycnf, mycnfErr := mysqlctl.NewMycnfFromFlags(0) if mycnfErr != nil { log.Fatalf("mycnf read failed: %v", mycnfErr) } log.V(6).Infof("mycnf: %v", jscfg.ToJson(mycnf)) dbcfgs, cfErr := dbconfigs.Init(mycnf.SocketFile) if cfErr != nil { log.Fatalf("%s", cfErr) } mysqld := mysqlctl.NewMysqld("Dba", mycnf, &dbcfgs.Dba, &dbcfgs.Repl) defer mysqld.Close() topoServer := topo.GetServer() defer topo.CloseServers() actor := actor.NewTabletActor(mysqld, mysqld, topoServer, topo.TabletAlias{}) // we delegate out startup to the micromanagement server so these actions // will occur after we have obtained our socket. bindAddr := fmt.Sprintf(":%v", *servenv.Port) httpServer := &http.Server{Addr: bindAddr} go func() { if err := httpServer.ListenAndServe(); err != nil { log.Errorf("httpServer.ListenAndServe err: %v", err) } }() actionErr := actor.HandleAction(*actionNode, *action, *actionGuid, *force) if actionErr != nil { log.Fatalf("action error: %v", actionErr) } log.Infof("finished vtaction %v", os.Args) }
func (zkts *Server) UpdateKeyspace(ki *topo.KeyspaceInfo, existingVersion int64) (int64, error) { keyspacePath := path.Join(globalKeyspacesPath, ki.KeyspaceName()) data := jscfg.ToJson(ki.Keyspace) stat, err := zkts.zconn.Set(keyspacePath, data, int(existingVersion)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return -1, err } event.Dispatch(&events.KeyspaceChange{ KeyspaceInfo: *ki, Status: "updated", }) return int64(stat.Version()), nil }
func TestMissingFieldsJson(t *testing.T) { swra := &slaveWasRestartedTestArgs{ Parent: topo.TabletAlias{ Uid: 1, Cell: "aa", }, ExpectedMasterAddr: "a1", ExpectedMasterIpAddr: "i1", ScrapStragglers: true, } data := jscfg.ToJson(swra) output := &SlaveWasRestartedArgs{} decoder := json.NewDecoder(strings.NewReader(data)) err := decoder.Decode(output) if err != nil { t.Errorf("Cannot re-decode struct without field: %v", err) } }
func (zkts *Server) updateTabletEndpoint(oldValue string, oldStat zk.Stat, addr *topo.EndPoint) (newValue string, err error) { if oldStat == nil { // The incoming object doesn't exist - we haven't been placed in the serving // graph yet, so don't update. Assume the next process that rebuilds the graph // will get the updated tablet location. return "", skipUpdateErr } var addrs *topo.EndPoints if oldValue != "" { addrs = &topo.EndPoints{} if len(oldValue) > 0 { if err := json.Unmarshal([]byte(oldValue), addrs); err != nil { return "", fmt.Errorf("EndPoints unmarshal failed: %v %v", oldValue, err) } } foundTablet := false for i, entry := range addrs.Entries { if entry.Uid == addr.Uid { foundTablet = true if !topo.EndPointEquality(&entry, addr) { addrs.Entries[i] = *addr } break } } if !foundTablet { addrs.Entries = append(addrs.Entries, *addr) } } else { addrs = topo.NewEndPoints() addrs.Entries = append(addrs.Entries, *addr) } return jscfg.ToJson(addrs), nil }
func (zkts *Server) UpdateShardReplicationFields(cell, keyspace, shard string, update func(*topo.ShardReplication) error) error { zkPath := shardReplicationPath(cell, keyspace, shard) f := func(oldValue string, oldStat zk.Stat) (string, error) { sr := &topo.ShardReplication{} if oldValue != "" { if err := json.Unmarshal([]byte(oldValue), sr); err != nil { return "", err } } if err := update(sr); err != nil { return "", err } return jscfg.ToJson(sr), nil } err := zkts.zconn.RetryChange(zkPath, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return err } return nil }
func (zkts *Server) UpdateTabletFields(tabletAlias topo.TabletAlias, update func(*topo.Tablet) error) error { // Store the last tablet value so we can log it if the change succeeds. var lastTablet *topo.Tablet zkTabletPath := TabletPathForAlias(tabletAlias) f := func(oldValue string, oldStat zk.Stat) (string, error) { if oldValue == "" { return "", fmt.Errorf("no data for tablet addr update: %v", tabletAlias) } tablet, err := tabletFromJson(oldValue) if err != nil { return "", err } if err := update(tablet); err != nil { return "", err } lastTablet = tablet return jscfg.ToJson(tablet), nil } err := zkts.zconn.RetryChange(zkTabletPath, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return err } if lastTablet != nil { event.Dispatch(&events.TabletChange{ Tablet: *lastTablet, Status: "updated", }) } return nil }
func (zkts *Server) UpdateSrvKeyspace(cell, keyspace string, srvKeyspace *topo.SrvKeyspace) error { path := zkPathForVtKeyspace(cell, keyspace) data := jscfg.ToJson(srvKeyspace) _, err := zkts.zconn.Set(path, data, -1) return err }
func (scr *SchemaChangeResult) String() string { return jscfg.ToJson(scr) }
func WriteAddrs(zconn zk.Conn, zkPath string, addrs *LegacyZknsAddrs) error { data := jscfg.ToJson(addrs) _, err := zk.CreateOrUpdate(zconn, zkPath, data, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), true) return err }
func (zkts *Server) UpdateSrvShard(cell, keyspace, shard string, srvShard *topo.SrvShard) error { path := zkPathForVtShard(cell, keyspace, shard) data := jscfg.ToJson(srvShard) _, err := zkts.zconn.Set(path, data, -1) return err }
func (tablet *Tablet) Json() string { return jscfg.ToJson(tablet) }
func (shard *Shard) Json() string { return jscfg.ToJson(shard) }
func (sd *SchemaDefinition) String() string { return jscfg.ToJson(sd) }
func (hr *HookResult) String() string { return jscfg.ToJson(hr) }