Skip to content

Commit

Permalink
"relocate" uses further heuristics for binlog servers, simplifying
Browse files Browse the repository at this point in the history
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
  • Loading branch information
shlomi-noach committed Nov 25, 2015
1 parent d1a66f9 commit 2cbdd1c
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 35 deletions.
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#
set -e

RELEASE_VERSION="1.4.544"
RELEASE_VERSION="1.4.546"
TOPDIR=/tmp/orchestrator-release
export RELEASE_VERSION TOPDIR

Expand Down
18 changes: 17 additions & 1 deletion go/http/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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})
Expand Down Expand Up @@ -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:
Expand Down
6 changes: 6 additions & 0 deletions go/inst/instance_topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand Down
5 changes: 5 additions & 0 deletions resources/public/css/orchestrator.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion resources/public/js/audit-recovery.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
36 changes: 14 additions & 22 deletions resources/public/js/orchestrator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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");
});
Expand Down Expand Up @@ -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 + ".<br/>Reason: "+node.maintenanceEntry.Reason
if (node.IsDowntimed) {
$('#node_modal [data-panel-type=downtime]').html("Downtimed by <strong>"+node.DowntimeOwner+"</strong> 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();
Expand Down
29 changes: 19 additions & 10 deletions resources/templates/layout.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -152,22 +152,31 @@
</div>
<div class="modal-body">
<div class="panel panel-info">
<div class="panel-heading" data-panel-type="maintenance"></div>
<div class="panel-heading" data-panel-type="downtime"></div>
<div class="panel-body">
<div class="" data-panel-type="begin-maintenance">
<div class="" data-panel-type="begin-downtime">
<form class="form-inline" role="form">
<input type="text" class="form-control input-sm" id="beginMaintenanceOwner" placeholder="owner name" />
<input type="text" class="form-control input-sm" id="beginMaintenanceReason" placeholder="reason" />
<button type="button" class="btn btn-info pull-right" data-btn="begin-maintenance">
<span class="glyphicon glyphicon-wrench"></span> Begin maintenance
<input type="text" class="form-control input-sm" id="beginDowntimeOwner" placeholder="owner name" />
<input type="text" class="form-control input-sm" id="beginDowntimeReason" placeholder="reason" />
<select class="form-control input-sm" id="beginDowntimeDuration">
<option value="10m">10m</option>
<option value="30m">30m</option>
<option value="1h">1h</option>
<option value="4h">4h</option>
<option value="24h">24h</option>
<option value="2d">2d</option>
<option value="7d">7d</option>
</select>
<button type="button" class="btn btn-info pull-right" data-btn="begin-downtime">
<span class="glyphicon glyphicon-volume-off"></span> Begin downtime
</button>
</form>
</div>
<div class="" data-panel-type="end-maintenance">
<div class="pull-left" data-description="maintenance-status">
<div class="" data-panel-type="end-downtime">
<div class="pull-left" data-description="downtime-status">
</div>
<button type="button" class="btn btn-default pull-right" data-btn="end-maintenance">
<span class="glyphicon glyphicon-wrench"></span> End maintenance
<button type="button" class="btn btn-default pull-right" data-btn="end-downtime">
<span class="glyphicon glyphicon-volume-up"></span> End downtime
</button>
</div>
</div>
Expand Down

0 comments on commit 2cbdd1c

Please sign in to comment.