]> git.proxmox.com Git - pve-ha-manager.git/blob - pve-ha-manager
introduce new HA::Manger class
[pve-ha-manager.git] / pve-ha-manager
1 #!/usr/bin/perl
2
3 use lib '.';
4
5 use strict;
6 use warnings;
7
8 use PVE::Tools;
9 use PVE::HA::SimEnv;
10 use PVE::HA::Manager;
11
12 my $statusdir = "/var/tmp/pve-ha-manager";
13
14 mkdir $statusdir;
15
16 my $haenv = PVE::HA::SimEnv->new($statusdir, 'node1');
17
18 my $status;
19
20 sub set_local_status {
21 my ($new_status) = @_;
22
23 return if $status eq $new_status;
24
25 $haenv->log('info', "manager status change $status => $new_status");
26
27 $status = $new_status;
28
29 $haenv->write_local_status($status);
30 }
31
32 sub get_manager_lock {
33
34 my $count = 0;
35 for (;;) {
36 return 1 if $haenv->get_ha_manager_lock();
37 last if ++$count > 5;
38 $haenv->sleep(1);
39 }
40
41 return 0;
42 }
43
44 sub sleep_until {
45 my ($end_time) = @_;
46
47 for (;;) {
48 my $cur_time = $haenv->get_time();
49 return if $cur_time >= $end_time;
50 $haenv->sleep($end_time - $cur_time);
51 }
52 }
53
54 if (!$haenv->manager_status_exists()) {
55 $haenv->log('info', "HA is not enabled");
56 exit(0);
57 }
58
59 $status = $haenv->read_local_status() || 'wait_for_quorum';
60
61 # can happen after crash?
62 if ($status eq 'master') {
63 set_local_status('recover');
64 } else {
65 set_local_status('wait_for_quorum');
66 }
67
68 $haenv->log('info', "starting simulation environment (status = $status)");
69
70 my $manager = PVE::HA::Manager->new($haenv);
71
72 eval {
73
74 for (;;) {
75
76 $haenv->loop_start_hook();
77
78 if ($status eq 'recover') {
79
80 $haenv->log('info', "waiting for 5 seconds");
81 $haenv->sleep(5);
82
83 set_local_status('wait_for_quorum');
84
85 } elsif ($status eq 'wait_for_quorum') {
86
87 $haenv->sleep(5);
88
89 if ($haenv->quorate()) {
90 if (get_manager_lock()) {
91 set_local_status('master');
92 } else {
93 set_local_status('slave');
94 }
95 }
96
97 } elsif ($status eq 'master') {
98
99 my $startime = $haenv->get_time();
100
101 my $max_time = 10;
102
103
104 # do work (max_time seconds)
105 eval {
106 # fixme: set alert timer
107 $manager->manage();
108 };
109 if (my $err = $@) {
110
111 # fixme: cleanup?
112 $haenv->log('err', "got unexpected error - $err");
113 set_local_status('error');
114
115 } else {
116 sleep_until($startime + $max_time);
117 }
118
119 if (!get_manager_lock()) {
120 if ($haenv->quorate()) {
121 set_local_status('slave');
122 } else {
123 set_local_status('wait_for_quorum');
124 # set_local_status('lost_quorum');
125 }
126 }
127 } elsif ($status eq 'slave') {
128
129 $haenv->sleep(5);
130
131 if ($haenv->quorate()) {
132 if (get_manager_lock()) {
133 set_local_status('master');
134 }
135 } else {
136 set_local_status('wait_for_quorum');
137 }
138
139 } elsif ($status eq 'error') {
140 die "stopping due to errors\n";
141 } elsif ($status eq 'lost_quorum') {
142 die "lost_quorum\n";
143 } elsif ($status eq 'halt') {
144 die "halt\n";
145 } else {
146 die "got unexpected status '$status'\n";
147 }
148
149 $haenv->loop_end_hook();
150 }
151 };
152 if (my $err = $@) {
153 $haenv->log('err', "exit now (status = $status) - $err ");
154 } else {
155 $haenv->log('info', "exit simulation environment (status = $status)");
156 }
157
158 exit(0);
159