-
Notifications
You must be signed in to change notification settings - Fork 0
/
AptAutoUpgrade.php
180 lines (141 loc) · 4.99 KB
/
AptAutoUpgrade.php
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
<?php
use Pebble\SMTP;
use Pebble\Service\ConfigService;
use Pebble\Service\LogService;
use Pebble\ExceptionTrace;
use Pebble\Special;
use Diversen\Cli\Utils as CliUtils;
use function Safe\touch;
use function Safe\unlink;
class AptAutoUpgrade
{
private $config;
private $smtp;
private $send_to;
private $cli_utils;
protected $lock_file = './restart.lock';
public function __construct()
{
$this->config = (new ConfigService())->getConfig();
$this->smtp = new SMTP($this->config->getSection('SMTP'));
$this->send_to = $this->config->get('SMTP.DefaultTo');
$this->cli_utils = new CliUtils();
$this->log = (new LogService())->getLog();
date_default_timezone_set($this->config->get('App.timezone'));
}
public function get_hostname()
{
$res = $this->cli_utils->execSilent('hostname');
if ($res) {
throw new Exception('Could not get server hostname');
}
return $this->cli_utils->getStdout();
}
function parse_apt_check(string $apt_output)
{
$output_ary = explode(";", $apt_output); // 3;0
if ($output_ary[0] === '0' && $output_ary[1] === '0') {
return false;
}
return true;
}
function has_updates()
{
$command = "/usr/lib/update-notifier/apt-check";
$res = $this->cli_utils->execSilent($command);
if ($res) {
throw new Exception($this->cli_utils->getStderr());
}
// Without any error the apt-check message is available in stderr
// It has the form "3;3" "security update;non security updates"
$apt_output = $this->cli_utils->getStderr();
if ($this->parse_apt_check($apt_output)) {
return true;
}
return false;
}
function upgrade()
{
$command = "apt-get upgrade --with-new-pkgs -y";
$res = $this->cli_utils->execSilent($command);
if ($res) {
throw new Exception($this->cli_utils->getStderr());
}
}
function needs_restart()
{
if (file_exists('/var/run/reboot-required')) {
return true;
}
}
function should_auto_restart()
{
if ($this->needs_restart() && $this->config->get('App.restart')) {
return true;
}
}
function send_mail(string $subject, string $message)
{
// Fail silently on mail errros
try {
$message .= "Mail sent: " . $this->get_datetime();
$this->smtp->send($this->send_to, $subject, $message, nl2br($message));
} catch (Exception $e) {
$this->log->error($e->getMessage());
}
}
function restart()
{
$res = $this->cli_utils->execSilent('/sbin/shutdown -r +1');
if ($res) {
throw new Exception($this->cli_utils->getStderr());
}
}
public function get_datetime()
{
return date('Y-m-d H:i:s');
}
public function run()
{
try {
$server_name = $this->get_hostname();
// Check if server has been restarted
if (file_exists($this->lock_file)) {
$subject = "Server ($server_name) restarted with success";
$message = "Server ($server_name) was restarted. \n\n";
unlink($this->lock_file);
$this->log->notice('Removed lock file (restart success): ' . $this->lock_file);
$this->send_mail($subject, $message);
}
if ($this->has_updates()) {
$this->log->notice('Server should be upgraded. Will now try to upgrade');
$this->upgrade();
$this->log->notice('Server upgraded');
$subject = "Server ($server_name) upgraded with success";
$message = "Server ($server_name) was upgraded.\n\n";
if ($this->needs_restart()) {
$message .= "The server needs to be restarted\n\n";
if ($this->should_auto_restart()) {
$message .= "Server will try to restart automatically\n\n";
} else {
$message .= "You will need to restart the server manually\n\n";
}
}
$this->send_mail($subject, $message);
if ($this->should_auto_restart()) {
touch($this->lock_file);
$this->restart();
$this->log->notice('Server restarting in one minut');
}
}
exit(0);
} catch (Exception $e) {
$this->log->error($e->getMessage(), ['exception' => ExceptionTrace::get($e)]);
$subject = "Server ($server_name) upgrade failed";
$message = "There was an error while trying to upgrade the server:\n\n";
$message .= Special::encodeStr(ExceptionTrace::get($e)) . "\n\n";
$this->send_mail($subject, $message);
exit(1);
}
}
}