]> git.proxmox.com Git - pve-ha-manager.git/blob - src/PVE/CLI/ha_manager.pm
f4873693f019aa26c05870676db297c38d4a649d
[pve-ha-manager.git] / src / PVE / CLI / ha_manager.pm
1 package PVE::CLI::ha_manager;
2
3 use strict;
4 use warnings;
5
6 use PVE::INotify;
7 use JSON;
8
9 use PVE::JSONSchema qw(get_standard_option);
10 use PVE::CLIHandler;
11 use PVE::Cluster;
12 use PVE::Tools qw(extract_param);
13 use PVE::RPCEnvironment;
14
15 use PVE::HA::Config; # needed for bash completion in PVE::HA::Tools!
16 use PVE::HA::Env::PVE2;
17 use PVE::HA::Tools;
18 use PVE::API2::HA::Resources;
19 use PVE::API2::HA::Groups;
20 use PVE::API2::HA::Status;
21
22 use base qw(PVE::CLIHandler);
23
24 my $nodename = PVE::INotify::nodename();
25
26 my $timestamp_to_status = sub {
27 my ($ctime, $timestamp) = @_;
28
29 my $tdiff = $ctime - $timestamp;
30 if ($tdiff > 30) {
31 return "old timestamp - dead?";
32 } elsif ($tdiff < -2) {
33 return "detected time drift!";
34 } else {
35 return "active";
36 }
37 };
38
39 sub setup_environment {
40 PVE::RPCEnvironment->setup_default_cli_env();
41 }
42
43 __PACKAGE__->register_method ({
44 name => 'status',
45 path => 'status',
46 method => 'GET',
47 description => "Display HA manger status.",
48 parameters => {
49 additionalProperties => 0,
50 properties => {
51 verbose => {
52 description => "Verbose output. Include complete CRM and LRM status (JSON).",
53 type => 'boolean',
54 default => 0,
55 optional => 1,
56 }
57 },
58 },
59 returns => { type => 'null' },
60 code => sub {
61 my ($param) = @_;
62
63 my $res = PVE::API2::HA::Status->status({});
64 foreach my $e (@$res) {
65 print "$e->{type} $e->{status}\n";
66 }
67
68 if ($param->{verbose}) {
69 print "full cluster state:\n";
70 my $data = PVE::API2::HA::Status->manager_status({});
71 print to_json($data, { pretty => 1, canonical => 1} );
72 }
73
74 return undef;
75 }});
76
77 __PACKAGE__->register_method ({
78 name => 'stop',
79 path => 'stop',
80 method => 'POST',
81 description => "Request the service to be stopped.",
82 permissions => {
83 check => ['perm', '/', [ 'Sys.Console' ]],
84 },
85 parameters => {
86 additionalProperties => 0,
87 properties => {
88 sid => get_standard_option('pve-ha-resource-or-vm-id', {
89 completion => \&PVE::HA::Tools::complete_sid
90 }),
91 timeout => {
92 description => "Timeout in seconds. If set to 0 a hard stop will be performed.",
93 type => 'integer',
94 minimum => 0,
95 },
96 },
97 },
98 returns => { type => 'null' },
99 code => sub {
100 my ($param) = @_;
101
102 my $sid = PVE::HA::Config::parse_sid(extract_param($param, 'sid'));
103
104 PVE::HA::Config::service_is_ha_managed($sid);
105
106 PVE::API2::HA::Resources::check_service_state($sid);
107
108 PVE::HA::Config::queue_crm_commands("stop $sid $param->{timeout}");
109
110 return undef;
111 }});
112
113 our $cmddef = {
114 status => [ __PACKAGE__, 'status'],
115 config => [ 'PVE::API2::HA::Resources', 'index', [], {}, sub {
116 my $res = shift;
117 foreach my $rec (sort { $a->{sid} cmp $b->{sid} } @$res) {
118 my ($type, $name) = split(':', $rec->{sid}, 2);
119 print "$type:$name\n";
120 foreach my $k (sort keys %$rec) {
121 next if $k eq 'digest' || $k eq 'sid' ||
122 $k eq 'type' || $k eq 'errors';
123 print "\t$k $rec->{$k}\n";
124 }
125 if (my $errors = $rec->{errors}) {
126 foreach my $p (keys %$errors) {
127 warn "error: property '$p' - $errors->{$p}\n";
128 }
129 }
130 print "\n";
131 }}],
132 groupconfig => [ 'PVE::API2::HA::Groups', 'index', [], {}, sub {
133 my $res = shift;
134 foreach my $rec (sort { $a->{group} cmp $b->{group} } @$res) {
135 print "group: $rec->{group}\n";
136 foreach my $k (sort keys %$rec) {
137 next if $k eq 'digest' || $k eq 'group' ||
138 $k eq 'type';
139 print "\t$k $rec->{$k}\n";
140 }
141 print "\n";
142 }}],
143 groupadd => [ "PVE::API2::HA::Groups", 'create', ['group'] ],
144 groupremove => [ "PVE::API2::HA::Groups", 'delete', ['group'] ],
145 groupset => [ "PVE::API2::HA::Groups", 'update', ['group'] ],
146
147 add => [ "PVE::API2::HA::Resources", 'create', ['sid'] ],
148 remove => [ "PVE::API2::HA::Resources", 'delete', ['sid'] ],
149 set => [ "PVE::API2::HA::Resources", 'update', ['sid'] ],
150
151 migrate => { alias => 'crm-command migrate' },
152 relocate => { alias => 'crm-command relocate' },
153
154 'crm-command' => {
155 migrate => [ "PVE::API2::HA::Resources", 'migrate', ['sid', 'node'] ],
156 relocate => [ "PVE::API2::HA::Resources", 'relocate', ['sid', 'node'] ],
157 stop => [ __PACKAGE__, 'stop', ['sid', 'timeout'] ],
158 }
159
160 };
161
162 1;