// Make this external, since these transitions need to be forced from time to time. func ChangeType(ts topo.Server, tabletAlias topo.TabletAlias, newType topo.TabletType, runHooks bool) error { tablet, err := ts.GetTablet(tabletAlias) if err != nil { return err } if !topo.IsTrivialTypeChange(tablet.Type, newType) || !topo.IsValidTypeChange(tablet.Type, newType) { return fmt.Errorf("cannot change tablet type %v -> %v %v", tablet.Type, newType, tabletAlias) } if runHooks { // Only run the preflight_serving_type hook when // transitioning from non-serving to serving. if !topo.IsServingType(tablet.Type) && topo.IsServingType(newType) { if err := hook.NewSimpleHook("preflight_serving_type").ExecuteOptional(); err != nil { return err } } } tablet.Type = newType if newType == topo.TYPE_IDLE { if tablet.Parent.Uid == topo.NO_TABLET { // With a master the node cannot be set to idle unless we have already removed all of // the derived paths. The global replication path is a good indication that this has // been resolved. children, err := ts.GetReplicationPaths(tablet.Keyspace, tablet.Shard, tablet.ReplicationPath()) if err != nil && err != topo.ErrNoNode { return err } if err == nil && len(children) > 0 { return fmt.Errorf("cannot change tablet type %v -> %v - reparent action has not finished %v", tablet.Type, newType, tabletAlias) } } tablet.Parent = topo.TabletAlias{} tablet.Keyspace = "" tablet.Shard = "" tablet.KeyRange = key.KeyRange{} } return topo.UpdateTablet(ts, tablet) }
func CheckReplicationPaths(t *testing.T, ts topo.Server) { if _, err := ts.GetReplicationPaths("test_keyspace", "-10", "/"); err != topo.ErrNoNode { t.Errorf("GetReplicationPaths(bad shard): %v", err) } if err := ts.CreateKeyspace("test_keyspace"); err != nil { t.Errorf("CreateKeyspace: %v", err) } if err := topo.CreateShard(ts, "test_keyspace", "-10"); err != nil { t.Errorf("CreateShard: %v", err) } if paths, err := ts.GetReplicationPaths("test_keyspace", "-10", "/"); err != nil || len(paths) != 0 { t.Errorf("GetReplicationPaths(empty shard): %v, %v", err, paths) } if _, err := ts.GetReplicationPaths("test_keyspace", "-10", "/666"); err != topo.ErrNoNode { t.Errorf("GetReplicationPaths(non-existing path): %v", err) } if err := ts.CreateReplicationPath("test_keyspace", "-10", "/cell-0000000001"); err != nil { t.Errorf("CreateReplicationPath: %v", err) } if err := ts.CreateReplicationPath("test_keyspace", "-10", "/cell-0000000001"); err != topo.ErrNodeExists { t.Errorf("CreateReplicationPath(again): %v", err) } if paths, err := ts.GetReplicationPaths("test_keyspace", "-10", "/"); err != nil || len(paths) != 1 || paths[0].String() != "cell-0000000001" { t.Errorf("GetReplicationPaths(root): %v, %v", err, paths) } if err := ts.CreateReplicationPath("test_keyspace", "-10", "/cell-0000000001/cell-0000000002"); err != nil { t.Errorf("CreateReplicationPath(2): %v", err) } if err := ts.CreateReplicationPath("test_keyspace", "-10", "/cell-0000000001/cell-0000000003"); err != nil { t.Errorf("CreateReplicationPath(3): %v", err) } if paths, err := ts.GetReplicationPaths("test_keyspace", "-10", "/cell-0000000001"); err != nil || len(paths) != 2 || paths[0].String() != "cell-0000000002" || paths[1].String() != "cell-0000000003" { t.Errorf("GetReplicationPaths(master): %v, %v", err, paths) } if err := ts.DeleteReplicationPath("test_keyspace", "-10", "/cell-0000000001"); err != topo.ErrNotEmpty { t.Errorf("DeleteReplicationPath(master with slaves): %v", err) } if err := ts.DeleteReplicationPath("test_keyspace", "-10", "/cell-0000000001/cell-0000000002"); err != nil { t.Errorf("DeleteReplicationPath(slave1): %v", err) } if paths, err := ts.GetReplicationPaths("test_keyspace", "-10", "/cell-0000000001"); err != nil || len(paths) != 1 || paths[0].String() != "cell-0000000003" { t.Errorf("GetReplicationPaths(master): %v, %v", err, paths) } if err := ts.DeleteReplicationPath("test_keyspace", "-10", "/cell-0000000001/cell-0000000003"); err != nil { t.Errorf("DeleteReplicationPath(slave2): %v", err) } if paths, err := ts.GetReplicationPaths("test_keyspace", "-10", "/cell-0000000001"); err != nil || len(paths) != 0 { t.Errorf("GetReplicationPaths(master): %v, %v", err, paths) } if err := ts.DeleteReplicationPath("test_keyspace", "-10", "/cell-0000000001"); err != nil { t.Errorf("DeleteReplicationPath(master): %v", err) } if paths, err := ts.GetReplicationPaths("test_keyspace", "-10", "/"); err != nil || len(paths) != 0 { t.Errorf("GetReplicationPaths(root): %v, %v", err, paths) } }