summaryrefslogtreecommitdiffstats
path: root/vespaclient/src/perl/lib/Yahoo/Vespa/ContentNodeSelection.pm
blob: d15fd4a75dfc3dcd9b17648d653f6b08a15778b9 (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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#
# This module implements a way to select a subset of nodes from a Vespa
# application.
#

package Yahoo::Vespa::ContentNodeSelection;

use strict;
use warnings;
use Yahoo::Vespa::ArgParser;
use Yahoo::Vespa::ConsoleOutput;
use Yahoo::Vespa::Utils;
use Yahoo::Vespa::VespaModel;

BEGIN { # - Declare exports and dependency aliases for module
    use base 'Exporter';
    our @EXPORT = qw(
        NO_LOCALHOST_CONSTRAINT
        CLUSTER_ONLY_LIMITATION
    );
        # Package aliases
    *VespaModel:: = *Yahoo::Vespa::VespaModel:: ;
}

my $CLUSTER;
my $NODE_TYPE;
my $INDEX;
my $FORCE = 0;
our $LOCALHOST;

use constant NO_LOCALHOST_CONSTRAINT => 1;
use constant CLUSTER_ONLY_LIMITATION => 2;

return 1;

######################## Externally usable functions #######################

sub registerCommandLineArguments { # (Flags)
    my ($flags) = @_;
    if (!defined $flags) { $flags = 0; }
    if (($flags & NO_LOCALHOST_CONSTRAINT) == 0) {
        $LOCALHOST = getHostname();
    } else {
        $LOCALHOST = undef;
    }
    if (($flags & CLUSTER_ONLY_LIMITATION) == 0) {
        setOptionHeader("Node selection options. By default, nodes running "
                      . "locally will be selected:");
    }
    setStringOption(
            ['c', 'cluster'],
            \$CLUSTER,
            'Cluster name of cluster to query. '
          . 'If unspecified, and vespa is installed on current node, '
          . 'information will be attempted auto-extracted');
    setFlagOption(
        ['f', 'force'],
        \$FORCE,
        'Force the execution of a dangerous command.');
    if (($flags & CLUSTER_ONLY_LIMITATION) == 0) {
        setStringOption(
                ['t', 'type'],
                \$NODE_TYPE,
                'Node type to query. This can either be \'storage\' or '
              . '\'distributor\'. If not specified, the operation will show '
              . 'state for all types.');
        setIntegerOption(
                ['i', 'index'],
                \$INDEX,
                'The node index to show state for. If not specified, all nodes '
              . 'found running on this host will be shown.');
    }
}
sub visit { # (Callback)
    my ($callback) = @_;
    printDebug "Visiting selected services: "
            . "Cluster " . (defined $CLUSTER ? $CLUSTER : 'undef')
            . " node type " . (defined $NODE_TYPE ? $NODE_TYPE : 'undef')
            . " index " . (defined $INDEX ? $INDEX : 'undef')
            . " localhost only ? " . ($LOCALHOST ? "true" : "false") . "\n";
    VespaModel::visitServices(sub {
        my ($info) = @_;
        $$info{'type'} = &convertType($$info{'type'});
        if (!&validType($$info{'type'})) { return; }
        if (defined $CLUSTER && $CLUSTER ne $$info{'cluster'}) { return; }
        if (defined $NODE_TYPE && $NODE_TYPE ne $$info{'type'}) { return; }
        if (defined $INDEX && $INDEX ne $$info{'index'}) { return; }
        if (!defined $INDEX && defined $LOCALHOST
            && $LOCALHOST ne $$info{'host'})
        {
            return;
        }
       # printResult "Ok $$info{'cluster'} $$info{'type'} $$info{'index'}\n";
        &$callback($info);
    });
}
sub showSettings { # ()
    printDebug "Visiting selected services: "
            . "Cluster " . (defined $CLUSTER ? $CLUSTER : 'undef')
            . " node type " . (defined $NODE_TYPE ? $NODE_TYPE : 'undef')
            . " index " . (defined $INDEX ? $INDEX : 'undef')
            . " localhost only ? " . ($LOCALHOST ? "true" : "false") . "\n";
}

sub validateCommandLineArguments { # (WantedState)
    my ($wanted_state) = @_;

    if (defined $NODE_TYPE) {
        if ($NODE_TYPE !~ /^(distributor|storage)$/) {
            printWarning "Invalid value '$NODE_TYPE' given for node type.\n";
            return 0;
        }
    }

    if (!$FORCE &&
        (!defined $NODE_TYPE || $NODE_TYPE eq "distributor") &&
        $wanted_state eq "maintenance") {
        printWarning "Setting the distributor to maintenance mode may have "
            . "severe consequences for feeding!\n"
            . "Please specify -t storage to only set the storage node to "
            . "maintenance mode, or -f to override this error.\n";
        return 0;
    }

    printDebug "Command line arguments validates ok\n";
    return 1;
}

############## Utility functions - Not intended for external use #############

sub validType { # (ServiceType) -> Bool
    my ($type) = @_;
    return $type =~ /^(?:distributor|storage)$/;
}
sub convertType { # (ServiceType) -> Bool
    my ($type) = @_;
    if ($type eq 'storagenode') { return 'storage'; }
    return $type;
}