func (s *TestSuite) TestFailMoveBelow(c *C) { clearTestMaintenance() _, _ = inst.ExecInstance(&slave2Key, `set global binlog_format:='ROW'`) _, err := inst.MoveBelow(&slave1Key, &slave2Key) _, _ = inst.ExecInstance(&slave2Key, `set global binlog_format:='STATEMENT'`) c.Assert(err, Not(IsNil)) }
func (s *TestSuite) TestFailMoveBelowUponMaintenance(c *C) { clearTestMaintenance() _, _ = inst.ReadTopologyInstance(&slave1Key) k, err := inst.BeginMaintenance(&slave1Key, "unittest", "TestBeginEndMaintenance") c.Assert(err, IsNil) _, err = inst.MoveBelow(&slave1Key, &slave2Key) c.Assert(err, Not(IsNil)) err = inst.EndMaintenance(k) c.Assert(err, IsNil) }
func (s *TestSuite) TestFailMoveBelowUponOtherSlaveStopped(c *C) { clearTestMaintenance() slave1, _ := inst.ReadTopologyInstance(&slave1Key) c.Assert(slave1.SlaveRunning(), Equals, true) slave1, _ = inst.StopSlaveNicely(&slave1.Key) c.Assert(slave1.SlaveRunning(), Equals, false) _, err := inst.MoveBelow(&slave2Key, &slave1Key) c.Assert(err, Not(IsNil)) _, _ = inst.StartSlave(&slave1.Key) }
func (s *TestSuite) TestMoveBelowAndBack(c *C) { clearTestMaintenance() // become child slave1, err := inst.MoveBelow(&slave1Key, &slave2Key) c.Assert(err, IsNil) c.Assert(slave1.MasterKey.Equals(&slave2Key), Equals, true) c.Assert(slave1.SlaveRunning(), Equals, true) // And back; keep topology intact slave1, _ = inst.MoveUp(&slave1Key) slave2, _ := inst.ReadTopologyInstance(&slave2Key) c.Assert(inst.InstancesAreSiblings(slave1, slave2), Equals, true) c.Assert(slave1.SlaveRunning(), Equals, true) }
// MoveBelow attempts to move an instance below its supposed sibling func (this *HttpAPI) MoveBelow(params martini.Params, r render.Render) { instanceKey, err := this.getInstanceKey(params["host"], params["port"]) if err != nil { r.JSON(200, &APIResponse{Code: ERROR, Message: err.Error()}) return } siblingKey, err := this.getInstanceKey(params["siblingHost"], params["siblingPort"]) if err != nil { r.JSON(200, &APIResponse{Code: ERROR, Message: err.Error()}) return } instance, err := inst.MoveBelow(&instanceKey, &siblingKey) if err != nil { r.JSON(200, &APIResponse{Code: ERROR, Message: err.Error()}) return } r.JSON(200, &APIResponse{Code: OK, Message: fmt.Sprintf("Instance %+v moved below %+v", instanceKey, siblingKey), Details: instance}) }
func (s *TestSuite) TestMoveBelowAndBackComplex(c *C) { clearTestMaintenance() // become child slave1, _ := inst.MoveBelow(&slave1Key, &slave2Key) c.Assert(slave1.MasterKey.Equals(&slave2Key), Equals, true) c.Assert(slave1.SlaveRunning(), Equals, true) // Now let's have fun. Stop slave2 (which is now parent of slave1), execute queries on master, // move s1 back under master, start all, verify queries. _, err := inst.StopSlave(&slave2Key) c.Assert(err, IsNil) randValue := rand.Int() _, err = inst.ExecInstance(&masterKey, `replace into orchestrator_test.test_table (name, value) values ('TestMoveBelowAndBackComplex', ?)`, randValue) c.Assert(err, IsNil) master, err := inst.ReadTopologyInstance(&masterKey) c.Assert(err, IsNil) // And back; keep topology intact slave1, err = inst.MoveUp(&slave1Key) c.Assert(err, IsNil) _, err = inst.MasterPosWait(&slave1Key, &master.SelfBinlogCoordinates) c.Assert(err, IsNil) slave2, err := inst.ReadTopologyInstance(&slave2Key) c.Assert(err, IsNil) _, err = inst.MasterPosWait(&slave2Key, &master.SelfBinlogCoordinates) c.Assert(err, IsNil) // Now check for value! var value1, value2 int inst.ScanInstanceRow(&slave1Key, `select value from orchestrator_test.test_table where name='TestMoveBelowAndBackComplex'`, &value1) inst.ScanInstanceRow(&slave2Key, `select value from orchestrator_test.test_table where name='TestMoveBelowAndBackComplex'`, &value2) c.Assert(inst.InstancesAreSiblings(slave1, slave2), Equals, true) c.Assert(value1, Equals, randValue) c.Assert(value2, Equals, randValue) }
// Cli initiates a command line interface, executing requested command. func Cli(command string, instance string, sibling string, owner string, reason string) { instanceKey, err := inst.ParseInstanceKey(instance) if err != nil { instanceKey = nil } siblingKey, err := inst.ParseInstanceKey(sibling) if err != nil { siblingKey = nil } if len(owner) == 0 { // get os username as owner usr, err := user.Current() if err != nil { log.Fatale(err) } owner = usr.Username } if len(command) == 0 { log.Fatal("expected command (-c) (discover|forget|continuous|move-up|move-below|begin-maintenance|end-maintenance|clusters|topology|resolve)") } switch command { case "move-up": { if instanceKey == nil { log.Fatal("Cannot deduce instance:", instance) } _, err := inst.MoveUp(instanceKey) if err != nil { log.Errore(err) } } case "move-below": { if instanceKey == nil { log.Fatal("Cannot deduce instance:", instance) } if siblingKey == nil { log.Fatal("Cannot deduce sibling:", sibling) } _, err := inst.MoveBelow(instanceKey, siblingKey) if err != nil { log.Errore(err) } } case "discover": { if instanceKey == nil { log.Fatal("Cannot deduce instance:", instance) } orchestrator.StartDiscovery(*instanceKey) } case "forget": { if instanceKey == nil { log.Fatal("Cannot deduce instance:", instance) } inst.ForgetInstance(instanceKey) } case "begin-maintenance": { if instanceKey == nil { log.Fatal("Cannot deduce instance:", instance) } if owner == "" { log.Fatal("--owner option required") } if reason == "" { log.Fatal("--reason option required") } maintenanceKey, err := inst.BeginMaintenance(instanceKey, owner, reason) if err == nil { log.Infof("Maintenance key: %+v", maintenanceKey) } if err != nil { log.Errore(err) } } case "end-maintenance": { if instanceKey == nil { log.Fatal("Cannot deduce instance:", instance) } err := inst.EndMaintenanceByInstanceKey(instanceKey) if err != nil { log.Errore(err) } } case "clusters": { clusters, err := inst.ReadClusters() if err != nil { log.Errore(err) } else { fmt.Println(strings.Join(clusters, "\n")) } } case "topology": { if instanceKey == nil { log.Fatal("Cannot deduce instance:", instance) } output, err := inst.AsciiTopology(instance) if err != nil { log.Errore(err) } else { fmt.Println(output) } } case "continuous": { orchestrator.ContinuousDiscovery() } case "resolve": { if instanceKey == nil { log.Fatal("Cannot deduce instance:", instance) } if conn, err := net.Dial("tcp", instanceKey.DisplayString()); err == nil { conn.Close() } else { log.Fatale(err) } fmt.Println(instanceKey.DisplayString()) } default: log.Fatal("Unknown command:", command) } }