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

Cluster read only #100

Merged
merged 1 commit into from
Aug 28, 2018
Merged

Cluster read only #100

merged 1 commit into from
Aug 28, 2018

Conversation

MerceaOtniel
Copy link
Contributor

No description provided.

@MerceaOtniel MerceaOtniel force-pushed the clusterReadOnly branch 2 times, most recently from c494ae2 to 5dc3a76 Compare August 17, 2018 09:02
}

if node.ReadOnly == true {
isReadOnly = isReadOnly && true
Copy link
Contributor

Choose a reason for hiding this comment

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

Write it just once and above if statement. And use logical OR because using AND it will not work.

isReadOnly = isReadOnly && !node.ReadOnly

}

}
glog.Infof("\n---------- displaying the array/checking if every value is the same---------------\n")
Copy link
Contributor

Choose a reason for hiding this comment

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

No need of debugging logging anymore.

f.updateNodeCondition(host, api.NodeConditionMaster, core.ConditionFalse)
}
if err == nil {
root = append(root, master)
Copy link
Contributor

Choose a reason for hiding this comment

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

rename it to masterForNode

}

if len(getMasterForNode(insts)) != 0 {
masterHostName, check := verifyMasterArray(getMasterForNode(insts))
Copy link
Contributor

Choose a reason for hiding this comment

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

you can merge those two functions, you will always use them like this verifyMasterArray(getMasterForNode(insts)) so you can make just one function:

func determinMasterFor(inst []orc.Instace) (string, err)


}

if len(getMasterForNode(insts)) != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

no need for this check

func (f *cFactory) setMasterWritable(masterHostName string, insts []orc.Instance) {
master, err := getInstance(masterHostName, insts)

if err == nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

if err != nil {
  glog.Errorf("Get instance error:%s", err)
  return
}

@@ -30,6 +30,9 @@ type Interface interface {

AuditRecovery(cluster string) ([]TopologyRecovery, error)
AckRecovery(id int64, commnet string) error

SetHostWritable(host string, port int) error
Copy link
Contributor

Choose a reason for hiding this comment

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

You can use as parameter InstanceKey because instance key has both host and port

f.updateNodeCondition(masterHostName, api.NodeConditionMaster, core.ConditionFalse)
}

f.setMasterWritable(masterHostName, insts)
Copy link
Contributor

Choose a reason for hiding this comment

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

move this function call at line 48 after updateStatusFromOrc call

}

func (f *cFactory) setMasterWritable(masterHostName string, insts []orc.Instance) {
master, err := getInstance(masterHostName, insts)
Copy link
Contributor

Choose a reason for hiding this comment

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

you can compute masterHostName using determinMasterFor and don't need to pass it as parameter. See see the next comments.

@MerceaOtniel MerceaOtniel force-pushed the clusterReadOnly branch 3 times, most recently from 6e78f63 to eebc592 Compare August 21, 2018 10:59
if err == nil {
f.updateNodeCondition(masterHostName, api.NodeConditionMaster, core.ConditionTrue)
} else {
f.updateNodeCondition(masterHostName, api.NodeConditionMaster, core.ConditionFalse)
Copy link
Contributor

Choose a reason for hiding this comment

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

if there is an error then what value masterHostName will have?

Copy link
Contributor

Choose a reason for hiding this comment

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

else statement can be deleted or better log the error

f.updateNodeCondition(masterHostName, api.NodeConditionMaster, core.ConditionFalse)
}

err = f.setMasterWritable(masterHostName, insts)
Copy link
Contributor

Choose a reason for hiding this comment

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

This code should be moved in SyncOrchestratorStatus function near to updateStatusFromOrc call.

}

func (f *cFactory) setMasterWritable(masterHostName string, insts []orc.Instance) error {
master, err := getInstance(masterHostName, insts)
Copy link
Contributor

Choose a reason for hiding this comment

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

Get master here with determineMasterFor.

Also in this function you have to make sure that only one node is writable!

Copy link
Contributor

Choose a reason for hiding this comment

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

Make sure that failover works as expected, by manually testing.

Test case:

  • create a cluster 2 nodes
  • delete pod 0
  • check node:0 -> read only and node:1 -> writable (cluster status)

Copy link
Contributor

Choose a reason for hiding this comment

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

Test case 2:

  • create cluster 3 nodes
  • make node:1 comaster
  • check status

@MerceaOtniel MerceaOtniel force-pushed the clusterReadOnly branch 3 times, most recently from a4b9f6d to cc95119 Compare August 24, 2018 07:15
query = "SET GLOBAL SUPER_READ_ONLY = 1"
}

query = "SET GLOBAL SUPER_READ_ONLY = 1"
Copy link
Contributor

Choose a reason for hiding this comment

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

query := "SET GLOBAL SUPER_READ_ONLY = 1"

@@ -107,6 +107,8 @@ type ClusterSpec struct {
// QueryLimits represents limits for a query
// +optional
QueryLimits *QueryLimits `json:"queryLimits,omitempty"`

ReadOnly bool `json:"readOnly,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a description here


func (f *cFactory) updateNodesReadOnlyFlagInOrc(insts []orc.Instance) error {
master, err := determineMasterFor(insts)

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's treat the error here, the code will be much more clearly.

master, err := determineMasterFor(insts)
if err != nil {
    // if no master determined then set the cluster in read only.
    for _, inst := range insts {
        f.putNodeInMaintenance(inst)
        f.setInstReadOnly(inst)
    }
}

} else {
f.updateNodeCondition(host, api.NodeConditionReadOnly, core.ConditionFalse)
}

Copy link
Contributor

Choose a reason for hiding this comment

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

to many new lines.

}

master, err := determineMasterFor(insts)
if err == nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

if err != nil {
    glog.Errorf("Error acquiring master name %s", err)
}
f.updateNodeCondition(master.Key.Hostname, api.NodeConditionMaster, core.ConditionTrue)
....

"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/tools/record"
"testing"
"time"
Copy link
Contributor

Choose a reason for hiding this comment

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

the time and testing should be in the first group of imports, then in the second group external imports and finally the third group should be local imports.

@@ -99,6 +98,8 @@ var _ = Describe("Mysql cluster reconcilation", func() {
Ω(rec.Events).Should(Receive(&event))
Expect(event).To(ContainSubstring("ReplicationStopped"))
Ω(rec.Events).Should(Receive(&event))
Expect(event).To(ContainSubstring("DemoteMaster"))
Ω(rec.Events).Should(Receive(&event))
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's replace all Ω with Expect. Ω is hard to type.

@@ -65,6 +65,38 @@ func (o *FakeOrc) AddInstance(cluster, host string, master bool, sls int64, slav
o.Clusters[cluster] = []Instance{inst}
}

func (o *FakeOrc) AddInstanceInTopology(cluster, host string, port int, master bool, sls int64, slaveR, upToDate bool, masterKey string, masterPort int, coMaster bool) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I propose that, lets return a pointer to newly created Instance so you can easily modify instance so you don't need to pass that much parameters to this function.

And also you can use AddInstance function from above.

func (o *FakeOrc) AddInstance(cluster, host string, master bool, sls int64, slaveR, upToDate bool) *Instance

By keeping the old parameters you don't have to modify old tests. The new test will lock like:

inst := orcClient.AddInstanceInTopology("asd.default", "foo122-mysql-0",
					3306, false, -1, false, true)
inst.MasterKey = InstanceKey{Hostname: "foo122-mysql-5", Port: 3305}
inst.IsCoMaster = true


func (o *FakeOrc) SetHostWritable(key InstanceKey) error {

var check bool = false
Copy link
Contributor

Choose a reason for hiding this comment

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

check := false


}

func (o *orchestrator) EndMaintenance(key InstanceKey, owner, reason string) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't use owner and reason params.

@MerceaOtniel MerceaOtniel force-pushed the clusterReadOnly branch 6 times, most recently from 13dd266 to 0b714ea Compare August 28, 2018 10:00
}

// tests if the cluster is in orchestrator and is properly configured
func testClusterRegistrationInOrchestrator(f *framework.Framework, cluster *api.MysqlCluster, ClusterReadOnly bool) {
Copy link
Contributor

Choose a reason for hiding this comment

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

use lower letter for ClusterReadOnly param

}

return nil

Copy link
Contributor

Choose a reason for hiding this comment

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

empty line

}
o.Clusters[cluster] = []Instance{inst}

for _, inst1 := range o.Clusters[cluster] {
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need to iterate over any more.
Also you can create inst in the first place as pointer and to return the address:

inst := &Instance{
...

return inst


_, err := determineMasterFor(insts)
Expect(err).ToNot(BeNil())

Copy link
Contributor

Choose a reason for hiding this comment

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

empty line


_, err := determineMasterFor(insts)
Expect(err).ToNot(BeNil())

Copy link
Contributor

Choose a reason for hiding this comment

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

empty line


_, err := determineMasterFor(insts)
Expect(err).To(BeNil())

Copy link
Contributor

Choose a reason for hiding this comment

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

empty line


Expect(cluster.Status.Nodes[0].GetCondition(api.NodeConditionMaster).Status).To(
Equal(core.ConditionTrue))

orcClient.RemoveInstance("asd.default", cluster.GetPodHostname(0))
Ω(factory.SyncOrchestratorStatus(ctx)).Should(Succeed())
Expect(factory.SyncOrchestratorStatus(ctx)).Should(Succeed())

Expect(cluster.Status.Nodes[0].GetCondition(api.NodeConditionMaster).Status).To(
Equal(core.ConditionUnknown))

Copy link
Contributor

Choose a reason for hiding this comment

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

empty line

fakeOrc "github.com/presslabs/mysql-operator/pkg/util/orchestrator/fake"
tutil "github.com/presslabs/mysql-operator/pkg/util/test"
core "k8s.io/api/core/v1"
Copy link
Contributor

Choose a reason for hiding this comment

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

external imports should be in the second group of imports.
First is go imports, second is external imports and third are the local imports(imports from project)

@MerceaOtniel MerceaOtniel merged commit 7524d2d into master Aug 28, 2018
@calind calind deleted the clusterReadOnly branch September 12, 2018 11:25
chapsuk pushed a commit to chapsuk/mysql-operator that referenced this pull request Oct 16, 2023
…use this is probably the default behavior that users of vtop want. (bitpoke#100)

Signed-off-by: Peter Farr <Peter@PrismaPhonic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants