Commit e04eec47 authored by Leonardo Menezes's avatar Leonardo Menezes
Browse files

support relocate shard

parent d2281c4c
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -84,4 +84,15 @@ class ClusterOverviewController extends BaseController {
    }
  }

  def relocateShard = process { (request, client) =>
    val index = request.get("index")
    val shard = request.getInt("shard")
    val from = request.get("from")
    val to = request.get("to")
    val server = ElasticServer(request.host, request.authentication)
    client.relocateShard(shard, index, from, to, server).map { response =>
      Status(response.status)(response.body)
    }
  }

}
+20 −0
Original line number Diff line number Diff line
@@ -118,6 +118,26 @@ trait ElasticClient {
    execute(s"${target.host}$path", "GET", None, target.authentication)
  }

  def relocateShard(shard: Int, index: String, from: String, to: String, target: ElasticServer) = {
    val path = "/_cluster/reroute"
    val commands =
      s"""
         |{
         |  "commands": [
         |    {
         |      "move": {
         |        "shard": $shard,
         |        "index": \"$index\",
         |        "from_node": \"$from\",
         |        "to_node": \"$to\"
         |      }
         |    }
         |  ]
         |}
       """.stripMargin
    execute(s"${target.host}$path", "POST", Some(commands), target.authentication)
  }

  def getIndexRecovery(index: String, target: ElasticServer) = {
    val path = s"/$index/_recovery?active_only=true&human=true"
    execute(s"${target.host}$path", "GET", None, target.authentication)
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ POST /overview/clear_indices_cache @controllers.ClusterOvervi
POST        /overview/refresh_indices                 @controllers.ClusterOverviewController.refreshIndex
POST        /overview/delete_indices                  @controllers.ClusterOverviewController.deleteIndex
POST        /overview/get_shard_stats                 @controllers.ClusterOverviewController.getShardStats
POST        /overview/relocate_shard                  @controllers.ClusterOverviewController.relocateShard

# Navbar module
POST        /navbar                                   @controllers.NavbarController.index
+2 −0
Original line number Diff line number Diff line
@@ -35,8 +35,10 @@ table.shard-map { table-layout: fixed; }
.shard-started { border: 2px solid #1AC98E; color: #1AC98E; }
.shard-initializing { border: 1px solid #1CA8DD; color: #1CA8DD; }
.shard-relocated { border: 1px solid #9F85FF; color: #9F85FF; }
.shard-relocating { border: 1px solid #9F85FF; color: #9F85FF; }
.shard-recovering { border: 1px solid #E4D836; color: #E4D836; }
.shard-unassigned { border: 1px solid #8B8F95; color: #8B8F95; }
.shard-spot { border: 1px dashed; opacity: 0.7; padding-top: 2px; }
.shard-replica { border: 1px dashed; opacity: 0.7; }
.row-condensed { margin-right: -.1875rem !important; margin-left: -.1875rem !important; }
.col-condensed { margin-left: 0px; margin-right: 0px; padding-left: 2px !important; padding-right: 2px !important; }
+63 −1
Original line number Diff line number Diff line
@@ -684,7 +684,6 @@ angular.module('cerebro').controller('OverviewController', ['$scope', '$http',
    $scope.initializing_shards = 0;
    $scope.closed_indices = 0;
    $scope.special_indices = 0;
    $scope.expandedView = false;
    $scope.shardAllocation = true;

    $scope.indices_filter = new IndexFilter('', true, false, true, true, 0);
@@ -940,6 +939,44 @@ angular.module('cerebro').controller('OverviewController', ['$scope', '$http',
      $location.path('index_settings').search('index', index);
    };

    $scope.select = function(shard) {
      $scope.relocatingShard = shard;
    };

    $scope.relocateShard = function(node) {
      var shard = $scope.relocatingShard;
      DataService.relocateShard(shard.shard, shard.index, shard.node, node.id,
        function(response) {
          $scope.relocatingShard = undefined;
          RefreshService.refresh();
          AlertService.info('Relocation successfully started', response);
        },
        function(error) {
          AlertService.error('Error while starting relocation', error);
        }
      );
    };

    $scope.canReceiveShard = function(index, node) {
      var shard = $scope.relocatingShard;
      if (shard && index) { // in case num indices < num columns
        if (shard.node !== node.id && shard.index === index.name) {
          var shards = index.shards[node.id];
          if (shards) {
            var sameShard = function(s) {
              return s.shard === shard.shard;
            };
            if (shards.filter(sameShard).length === 0) {
              return true;
            }
          } else {
            return true;
          }
        }
      }
      return false;
    };

  }]);

angular.module('cerebro').controller('RepositoriesController', ['$scope',
@@ -2069,6 +2106,26 @@ angular.module('cerebro').directive('ngPlainInclude', function() {
  };
});

angular.module('cerebro').directive('ngShard', function() {
  return {
    scope: true,
    link: function(scope) {
      var shard = scope.shard;
      scope.state = shard.state.toLowerCase();
      scope.replica = !shard.primary && shard.node;
      scope.id = shard.shard + '_' + shard.node + '_' + shard.index;
      scope.clazz = scope.replica ? 'shard-replica' : '';
      scope.equal = function(other) {
        return other && shard.index === other.index &&
          shard.node === other.node && shard.shard === other.shard;
      };
    },
    templateUrl: function() {
      return 'overview/shard.html';
    }
  };
});

angular.module('cerebro').factory('AceEditorService', function() {

  this.init = function(name) {
@@ -2349,6 +2406,11 @@ angular.module('cerebro').factory('DataService', ['$rootScope', '$timeout',
      request('/overview/get_shard_stats', data, success, error);
    };

    this.relocateShard = function(shard, index, from, to, success, error) {
      var data = {shard: shard, index: index, from: from, to: to};
      request('/overview/relocate_shard', data, success, error);
    };

    // ---------- Create index ----------
    this.createIndex = function(index, metadata, success, error) {
      var data = {index: index, metadata: metadata};
Loading