summaryrefslogtreecommitdiffstats
path: root/vespaclient/src/perl/lib/Yahoo/Vespa/Bin/GetNodeState.pm
blob: 1e82c05db0a7915345d55e271204a198db6d72fd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

package Yahoo::Vespa::Bin::GetNodeState;

use strict;
use warnings;
use Yahoo::Vespa::ArgParser;
use Yahoo::Vespa::ClusterController;
use Yahoo::Vespa::ConsoleOutput;
use Yahoo::Vespa::ContentNodeSelection;
use Yahoo::Vespa::Utils;

BEGIN {
    use base 'Exporter';
    our @EXPORT = qw(
        getNodeState
    );
}

our $resultdesc;
our %cluster_states;

return 1;

# Run the get node state tool
sub getNodeState { # (Command line arguments)
    my ($argsref) = @_;
    &handleCommandLine($argsref);
    detectClusterController();
    &showSettings();
    &showNodeStates();
}

# Parse command line arguments
sub handleCommandLine { # (Command line arguments)
    my ($args) = @_;
    $resultdesc = <<EOS;
Shows the various states of one or more nodes in a Vespa Storage cluster.
There exist three different type of node states. They are:

  Unit state      - The state of the node seen from the cluster controller.
  User state      - The state we want the node to be in. By default up. Can be
                    set by administrators or by cluster controller when it
                    detects nodes that are behaving badly.
  Generated state - The state of a given node in the current cluster state.
                    This is the state all the other nodes know about. This
                    state is a product of the other two states and cluster
                    controller logic to keep the cluster stable.
EOS
    $resultdesc =~ s/\s*\n(\S.)/ $1/gs;
    chomp $resultdesc;
    my $description = <<EOS;
Retrieve the state of one or more storage services from the fleet controller.
Will list the state of the locally running services, possibly restricted to
less by options.

$resultdesc

EOS
    $description =~ s/(\S)\n(\S)/$1 $2/gs;
    chomp $description;

    setProgramDescription($description);
    Yahoo::Vespa::ContentNodeSelection::registerCommandLineArguments();
    Yahoo::Vespa::VespaModel::registerCommandLineArguments();
    handleCommandLineArguments($args);
}

# Show what settings this tool is running with (if verbosity is high enough)
sub showSettings { # ()
    &Yahoo::Vespa::ClusterController::showSettings();
    &Yahoo::Vespa::ContentNodeSelection::showSettings();
}

# Print all state we want to show for this request
sub showNodeStates { # ()
    printInfo $resultdesc . "\n";
    Yahoo::Vespa::ContentNodeSelection::visit(\&showNodeStateForNode);
}

# Get the node state from cluster controller, unless already cached
sub getStateForNode { # (Type, Index, Cluster)
    my ($type, $index, $cluster) = @_;
    if (!exists $cluster_states{$cluster}) {
        $cluster_states{$cluster} = getContentClusterState($cluster);
    }
    return $cluster_states{$cluster}->$type->{$index};
}

# Print all states for a given node
sub showNodeStateForNode { # (Service, Index, NodeState, Model, ClusterName)
    my ($info) = @_;
    my ($cluster, $type, $index) = (
            $$info{'cluster'}, $$info{'type'}, $$info{'index'});
    printResult "\n$cluster/$type.$index:\n";
    my $nodestate = &getStateForNode($type, $index, $cluster);
    printState('Unit', $nodestate->unit);
    printState('Generated', $nodestate->generated);
    printState('User', $nodestate->user);
}

# Print the value of a single state type for a node
sub printState { # (State name, State)
    my ($name, $state) = @_;
    if (!defined $state) {
        printResult $name . ": UNKNOWN\n";
    } else {
        my $msg = $name . ": ";
        if ($state->state ne 'up') {
            $msg .= COLOR_ERR;
        }
        $msg .= $state->state;
        if ($state->state ne 'up') {
            $msg .= COLOR_RESET;
        }
        $msg .= ": " . $state->reason . "\n";
        printResult $msg;
    }
}