From 2cbdd1cc627c892cb8afe75917ed6333a335769b Mon Sep 17 00:00:00 2001 From: shlomi-noach Date: Wed, 25 Nov 2015 13:11:46 +0100 Subject: [PATCH] "relocate" uses further heuristics for binlog servers, simplifying another scenario web: - modal dialog does not support "begin/end-maintenance" any more. Instead, it now supports "begin/end-downtime", with implied owner, with duration --- build.sh | 2 +- go/http/api.go | 18 +++++++++++++- go/inst/instance_topology.go | 6 +++++ resources/public/css/orchestrator.css | 5 ++++ resources/public/js/audit-recovery.js | 2 +- resources/public/js/orchestrator.js | 36 +++++++++++---------------- resources/templates/layout.tmpl | 29 +++++++++++++-------- 7 files changed, 63 insertions(+), 35 deletions(-) diff --git a/build.sh b/build.sh index 3283518d..94eaadc6 100755 --- a/build.sh +++ b/build.sh @@ -6,7 +6,7 @@ # set -e -RELEASE_VERSION="1.4.544" +RELEASE_VERSION="1.4.546" TOPDIR=/tmp/orchestrator-release export RELEASE_VERSION TOPDIR diff --git a/go/http/api.go b/go/http/api.go index 7d1a022e..67ff0555 100644 --- a/go/http/api.go +++ b/go/http/api.go @@ -27,6 +27,8 @@ import ( "github.com/martini-contrib/auth" "github.com/martini-contrib/render" + "github.com/outbrain/golib/util" + "github.com/outbrain/orchestrator/go/agent" "github.com/outbrain/orchestrator/go/config" "github.com/outbrain/orchestrator/go/inst" @@ -260,7 +262,20 @@ func (this *HttpAPI) BeginDowntime(params martini.Params, r render.Render, req * r.JSON(200, &APIResponse{Code: ERROR, Message: err.Error()}) return } - err = inst.BeginDowntime(&instanceKey, params["owner"], params["reason"], 0) + + var durationSeconds int = 0 + if params["duration"] != "" { + durationSeconds, err = util.SimpleTimeToSeconds(params["duration"]) + if durationSeconds < 0 { + err = fmt.Errorf("Duration value must be non-negative. Given value: %d", durationSeconds) + } + if err != nil { + r.JSON(200, &APIResponse{Code: ERROR, Message: err.Error()}) + return + } + } + + err = inst.BeginDowntime(&instanceKey, params["owner"], params["reason"], uint(durationSeconds)) if err != nil { r.JSON(200, &APIResponse{Code: ERROR, Message: err.Error(), Details: instanceKey}) @@ -2166,6 +2181,7 @@ func (this *HttpAPI) RegisterRequests(m *martini.ClassicMartini) { m.Get("/api/end-maintenance/:host/:port", this.EndMaintenanceByInstanceKey) m.Get("/api/end-maintenance/:maintenanceKey", this.EndMaintenance) m.Get("/api/begin-downtime/:host/:port/:owner/:reason", this.BeginDowntime) + m.Get("/api/begin-downtime/:host/:port/:owner/:reason/:duration", this.BeginDowntime) m.Get("/api/end-downtime/:host/:port", this.EndDowntime) // Recovery: diff --git a/go/inst/instance_topology.go b/go/inst/instance_topology.go index 9f36d028..1c1711bc 100644 --- a/go/inst/instance_topology.go +++ b/go/inst/instance_topology.go @@ -2320,6 +2320,11 @@ func relocateBelowInternal(instance, other *Instance) (*Instance, error) { return Repoint(&instance.Key, &instanceMaster.MasterKey, GTIDHintDeny) } if other.IsBinlogServer() { + if instanceMaster.IsBinlogServer() && InstancesAreSiblings(instanceMaster, other) { + // Special case: this is a binlog server family; we move under the uncle, in one single step + return Repoint(&instance.Key, &other.Key, GTIDHintDeny) + } + // Relocate to its master, then repoint to the binlog server otherMaster, found, err := ReadInstance(&other.MasterKey) if err != nil || !found { @@ -2328,6 +2333,7 @@ func relocateBelowInternal(instance, other *Instance) (*Instance, error) { if !other.IsLastCheckValid { return instance, log.Errorf("Binlog server %+v is not reachable. It would take two steps to relocate %+v below it, and I won't even do the first step.", other.Key, instance.Key) } + log.Debugf("Relocating to a binlog server; will first attempt to relocate to the binlog server's master: %+v, and then repoint down", otherMaster.Key) if _, err := relocateBelowInternal(instance, otherMaster); err != nil { return instance, err diff --git a/resources/public/css/orchestrator.css b/resources/public/css/orchestrator.css index 9c0b2401..d4b3124e 100644 --- a/resources/public/css/orchestrator.css +++ b/resources/public/css/orchestrator.css @@ -337,6 +337,11 @@ body { padding: 5px 9px; } +#node_modal [data-panel-type=begin-downtime] .btn { + width: auto; + display: inline-block; +} + #modalDataAttributesTable tbody tr td { padding: 3px; } diff --git a/resources/public/js/audit-recovery.js b/resources/public/js/audit-recovery.js index b0174b3e..d36f6647 100644 --- a/resources/public/js/audit-recovery.js +++ b/resources/public/js/audit-recovery.js @@ -124,7 +124,7 @@ $(document).ready(function () { var recoveryId = $(event.target).attr("data-recovery-id"); bootbox.prompt({ title: "Acknowledge recovery", - value: "comment", + placeholder: "comment", callback: function (result) { if (result !== null) { showLoader(); diff --git a/resources/public/js/orchestrator.js b/resources/public/js/orchestrator.js index 93dbbb16..ee12e10d 100644 --- a/resources/public/js/orchestrator.js +++ b/resources/public/js/orchestrator.js @@ -231,12 +231,6 @@ function openNodeModal(node) { $('#modalDataAttributesTable').html(""); addNodeModalDataAttribute("Last seen", node.LastSeenTimestamp+ " ("+node.SecondsSinceLastSeen.Int64+"s ago)"); - if (node.IsDowntimed) { - var td = addNodeModalDataAttribute("Downtime", node.DowntimeOwner+': '+node.DowntimeReason+' ('+node.DowntimeEndTimestamp+')'); - $('#node_modal [data-btn=end-downtime]').appendTo(td.find("div")); - } else { - $('#node_modal [data-btn=end-downtime]').appendTo(hiddenZone); - } if (node.UnresolvedHostname) { addNodeModalDataAttribute("Unresolved hostname", node.UnresolvedHostname); } @@ -330,19 +324,17 @@ function openNodeModal(node) { $('#node_modal [data-btn]').unbind("click"); - $('#node_modal button[data-btn=begin-maintenance]').click(function() { - if (!$("#beginMaintenanceOwner").val()) { + $("#beginDowntimeOwner").val(getUserId()); + $('#node_modal button[data-btn=begin-downtime]').click(function() { + if (!$("#beginDowntimeOwner").val()) { return addModalAlert("You must fill the owner field"); } - if (!$("#beginMaintenanceReason").val()) { + if (!$("#beginDowntimeReason").val()) { return addModalAlert("You must fill the reason field"); } - var uri = "/api/begin-maintenance/"+node.Key.Hostname+"/"+node.Key.Port + "/" + $("#beginMaintenanceOwner").val() + "/" + $("#beginMaintenanceReason").val(); + var uri = "/api/begin-downtime/"+node.Key.Hostname+"/"+node.Key.Port + "/" + $("#beginDowntimeOwner").val() + "/" + $("#beginDowntimeReason").val() + "/" + $("#beginDowntimeDuration").val(); apiCommand(uri); }); - $('#node_modal button[data-btn=end-maintenance]').click(function(){ - apiCommand("/api/end-maintenance/"+node.Key.Hostname+"/"+node.Key.Port); - }); $('#node_modal button[data-btn=refresh-instance]').click(function(){ apiCommand("/api/refresh/"+node.Key.Hostname+"/"+node.Key.Port, "refresh"); }); @@ -427,17 +419,17 @@ function openNodeModal(node) { apiCommand("/api/move-equivalent/"+node.Key.Hostname+"/"+node.Key.Port+"/"+targetHostname+"/"+targetPort); }); - if (node.inMaintenance) { - $('#node_modal [data-panel-type=maintenance]').html("In maintenance"); - $('#node_modal [data-description=maintenance-status]').html( - "Started " + node.maintenanceEntry.BeginTimestamp + " by "+node.maintenanceEntry.Owner + ".
Reason: "+node.maintenanceEntry.Reason + if (node.IsDowntimed) { + $('#node_modal [data-panel-type=downtime]').html("Downtimed by "+node.DowntimeOwner+" until "+node.DowntimeEndTimestamp); + $('#node_modal [data-description=downtime-status]').html( + node.DowntimeReason ); - $('#node_modal [data-panel-type=begin-maintenance]').hide(); - $('#node_modal [data-panel-type=end-maintenance]').show(); + $('#node_modal [data-panel-type=begin-downtime]').hide(); + $('#node_modal [data-panel-type=end-downtime]').show(); } else { - $('#node_modal [data-panel-type=maintenance]').html("Maintenance"); - $('#node_modal [data-panel-type=begin-maintenance]').show(); - $('#node_modal [data-panel-type=end-maintenance]').hide(); + $('#node_modal [data-panel-type=downtime]').html("Downtime"); + $('#node_modal [data-panel-type=begin-downtime]').show(); + $('#node_modal [data-panel-type=end-downtime]').hide(); } $('#node_modal button[data-btn=skip-query]').hide(); $('#node_modal button[data-btn=start-slave]').hide(); diff --git a/resources/templates/layout.tmpl b/resources/templates/layout.tmpl index 81765680..29eb3277 100644 --- a/resources/templates/layout.tmpl +++ b/resources/templates/layout.tmpl @@ -152,22 +152,31 @@