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