]> git.proxmox.com Git - pve-ha-manager.git/blob - src/ha-manager
ha-manager: improve status output
[pve-ha-manager.git] / src / ha-manager
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5 use Data::Dumper;
6
7 use PVE::INotify;
8 use JSON;
9
10 use PVE::JSONSchema qw(get_standard_option);
11 use PVE::CLIHandler;
12 use PVE::Cluster;
13
14 use PVE::HA::Tools;
15 use PVE::API2::HA::Resources;
16 use PVE::API2::HA::Groups;
17 use PVE::HA::Env::PVE2;
18
19 use base qw(PVE::CLIHandler);
20
21 $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
22 $ENV{LC_ALL} = 'C';
23
24 die "please run as root\n" if $> != 0;
25
26 my $nodename = PVE::INotify::nodename();
27
28 __PACKAGE__->register_method ({
29 name => 'enable',
30 path => 'enable',
31 method => 'POST',
32 description => "Enable a HA resource.",
33 parameters => {
34 additionalProperties => 0,
35 properties => {
36 sid => get_standard_option('pve-ha-resource-id'),
37 },
38 },
39 returns => { type => 'null' },
40 code => sub {
41 my ($param) = @_;
42
43 # delete state (default is 'enabled')
44 PVE::API2::HA::Resources->update({ sid => $param->{sid}, delete => 'state' });
45
46 return undef;
47 }});
48
49 __PACKAGE__->register_method ({
50 name => 'disable',
51 path => 'disable',
52 method => 'POST',
53 description => "Disable a HA resource.",
54 parameters => {
55 additionalProperties => 0,
56 properties => {
57 sid => get_standard_option('pve-ha-resource-id'),
58 },
59 },
60 returns => { type => 'null' },
61 code => sub {
62 my ($param) = @_;
63
64 PVE::API2::HA::Resources->update({ sid => $param->{sid}, state => 'disabled' });
65
66 return undef;
67 }});
68
69 my $timestamp_to_status = sub {
70 my ($ctime, $timestamp) = @_;
71
72 my $tdiff = $ctime - $timestamp;
73 if ($tdiff > 30) {
74 return "old timestamp - dead?";
75 } elsif ($tdiff < -2) {
76 return "detected time drift!";
77 } else {
78 return "active";
79 }
80 };
81
82 __PACKAGE__->register_method ({
83 name => 'status',
84 path => 'status',
85 method => 'GET',
86 description => "Display HA manger status.",
87 parameters => {
88 additionalProperties => 0,
89 properties => {},
90 },
91 returns => { type => 'null' },
92 code => sub {
93 my ($param) = @_;
94
95 PVE::Cluster::check_cfs_quorum();
96
97 my $haenv = PVE::HA::Env::PVE2->new($nodename);
98
99 my $status = $haenv->read_manager_status();
100
101 my $ctime = $haenv->get_time();
102
103 my $master = $status->{master_node};
104 my $status_str = &$timestamp_to_status($ctime, $status->{timestamp});
105
106 print "master_node: $master ($status_str)\n";
107 my $time_str = localtime($status->{timestamp});
108 print "last_update: $time_str\n";
109
110 foreach my $node (sort keys %{$status->{node_status}}) {
111 my $d = $status->{node_status}->{node};
112 my $lrm_status = $haenv->read_lrm_status($node);
113 if (!$lrm_status->{timestamp}) {
114 print "lrm_status: $node (unable to read lrm status)\n";
115 } else {
116 $status_str = &$timestamp_to_status($ctime, $lrm_status->{timestamp});
117 my $time_str = localtime($lrm_status->{timestamp});
118 print "lrm_status: $node ($status_str, $time_str)\n";
119 }
120 }
121
122 print "manager_status:\n";
123 print to_json($status, { pretty => 1, canonical => 1} );
124
125 return undef;
126 }});
127
128 my $cmddef = {
129 enable => [ __PACKAGE__, 'enable', ['sid']],
130 disable => [ __PACKAGE__, 'disable', ['sid']],
131 status => [ __PACKAGE__, 'status'],
132 config => [ 'PVE::API2::HA::Resources', 'index', [], {}, sub {
133 my $res = shift;
134 foreach my $rec (sort { $a->{sid} cmp $b->{sid} } @$res) {
135 my ($type, $name) = split(':', $rec->{sid}, 2);
136 print "$type:$name\n";
137 foreach my $k (sort keys %$rec) {
138 next if $k eq 'digest' || $k eq 'sid' ||
139 $k eq 'type';
140 print "\t$k $rec->{$k}\n";
141 }
142 print "\n";
143 }}],
144 groups => [ 'PVE::API2::HA::Groups', 'index', [], {}, sub {
145 my $res = shift;
146 foreach my $rec (sort { $a->{group} cmp $b->{group} } @$res) {
147 print "group: $rec->{group}\n";
148 foreach my $k (sort keys %$rec) {
149 next if $k eq 'digest' || $k eq 'group' ||
150 $k eq 'type';
151 print "\t$k $rec->{$k}\n";
152 }
153 print "\n";
154 }}],
155 add => [ "PVE::API2::HA::Resources", 'create', ['sid'] ],
156 remove => [ "PVE::API2::HA::Resources", 'delete', ['sid'] ],
157 set => [ "PVE::API2::HA::Resources", 'update', ['sid'] ],
158
159 migrate => [ "PVE::API2::HA::Resources", 'migrate', ['sid', 'node'] ],
160 relocate => [ "PVE::API2::HA::Resources", 'relocate', ['sid', 'node'] ],
161
162 };
163
164 my $cmd = shift;
165
166 if ($cmd && $cmd ne 'printmanpod' && $cmd ne 'verifyapi') {
167 PVE::Cluster::check_cfs_is_mounted();
168 PVE::Cluster::cfs_update();
169 }
170
171 PVE::CLIHandler::handle_cmd($cmddef, "ha-manager", $cmd, \@ARGV, undef, $0);
172
173 exit 0;
174
175 __END__
176
177 =head1 NAME
178
179 pvecm - Proxmox VE HA Command Line Interface
180
181 =head1 SYNOPSIS
182
183 =include synopsis
184
185 =head1 DESCRIPTION
186
187 ha-manager is a program to manage the HA configuration.
188
189 =include pve_copyright
190
191