aboutsummaryrefslogtreecommitdiffstats
path: root/check-routeros-update
blob: 3d4f14a25ac5ed853acd8cf15dfeebf5d5402cfd (plain) (blame)
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
#!rsc by RouterOS
# RouterOS script: check-routeros-update
# Copyright (c) 2013-2022 Christian Hesse <mail@eworm.de>
# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md
#
# check for RouterOS update, send notification and/or install
# https://git.eworm.de/cgit/routeros-scripts/about/doc/check-routeros-update.md

:local 0 "check-routeros-update";
:global GlobalFunctionsReady;
:while ($GlobalFunctionsReady != true) do={ :delay 500ms; }

:global Identity;
:global SafeUpdateNeighbor;
:global SafeUpdateOnCap;
:global SafeUpdatePatch;
:global SafeUpdateUrl;
:global SentRouterosUpdateNotification;

:global DeviceInfo;
:global LogPrintExit2;
:global ScriptFromTerminal;
:global ScriptLock;
:global SendNotification2;
:global SymbolForNotification;
:global VersionToNum;
:global WaitFullyConnected;

:local DoUpdate do={
  :if ([ :len [ /system/script/find where name="packages-update" ] ] > 0) do={
    /system/script/run packages-update;
  } else={
    /system/package/update/install without-paging;
  }
  :error "Waiting for system to reboot.";
}

$ScriptLock $0;

$WaitFullyConnected;

:if ([ :len [ /system/package/find where name="wireless" disabled=no ] ] > 0) do={
  :if ([ /interface/wireless/cap/get enabled ] = true && \
       [ /caps-man/manager/get enabled ] = false && \
       $SafeUpdateOnCap != true) do={
    $LogPrintExit2 error $0 ("System is managed by CAPsMAN, not checking for RouterOS version.") true;
  }
}

:if ([ :len [ /system/scheduler/find where name="reboot-for-update" ] ] > 0) do={
  :error "A reboot for update is already scheduled.";
}

$LogPrintExit2 debug $0 ("Checking for updates...") false;
/system/package/update/check-for-updates without-paging as-value;
:local Update [ /system/package/update/get ];

:if ([ :len ($Update->"latest-version") ] = 0) do={
  $LogPrintExit2 info $0 ("An empty string is not a valid version.") true;
}

:if ([ $ScriptFromTerminal $0 ] = true && ($Update->"installed-version") = ($Update->"latest-version")) do={
  $LogPrintExit2 info $0 ("System is already up to date.") true;
}

:local NumInstalled [ $VersionToNum ($Update->"installed-version") ];
:local NumLatest [ $VersionToNum ($Update->"latest-version") ];
:local Link ("https://mikrotik.com/download/changelogs/" . $Update->"channel" . "-release-tree");

:if ($NumInstalled < $NumLatest) do={
  :if ($SafeUpdatePatch = true && ($NumInstalled & 0xffff0000) = ($NumLatest & 0xffff0000)) do={
    $LogPrintExit2 info $0 ("Version " . $Update->"latest-version" . " is a patch release, updating...") false;
    $SendNotification2 ({ origin=$0; \
      subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update"); \
      message=("Version " . $Update->"latest-version" . " is a patch update for " . $Update->"channel" . \
        ", updating on " . $Identity . "..."); link=$Link; silent=true });
    $DoUpdate;
  }

  :if ($SafeUpdateNeighbor = true && [ :len [ /ip/neighbor/find where \
       version=($Update->"latest-version" . " (" . $Update->"channel" . ")") ] ] > 0) do={
    $LogPrintExit2 info $0 ("Seen a neighbor running version " . $Update->"latest-version" . ", updating...") false;
    $SendNotification2 ({ origin=$0; \
      subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update"); \
      message=("Seen a neighbor running version " . $Update->"latest-version" . " from " . $Update->"channel" . \
        ", updating on " . $Identity . "..."); link=$Link; silent=true });
    $DoUpdate;
  }

  :if ([ :len $SafeUpdateUrl ] > 0) do={
    :local Result;
    :do {
      :set Result [ /tool/fetch check-certificate=yes-without-crl \
          ($SafeUpdateUrl . $Update->"channel" . "?installed=" . $Update->"installed-version" . \
          "&latest=" . $Update->"latest-version") output=user as-value ];
    } on-error={
      $LogPrintExit2 warning $0 ("Failed receiving safe version for " . $Update->"channel" . ".") false;
    }
    :if ($Result->"status" = "finished" && $Result->"data" = $Update->"latest-version") do={
      $LogPrintExit2 info $0 ("Version " . $Update->"latest-version" . " is considered safe, updating...") false;
      $SendNotification2 ({ origin=$0; \
        subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update"); \
        message=("Version " . $Update->"latest-version" . " is considered safe for " . $Update->"channel" . \
          ", updating on " . $Identity . "..."); link=$Link; silent=true });
      $DoUpdate;
    }
  }

  :if ([ $ScriptFromTerminal $0 ] = true) do={
    :put ("Do you want to install RouterOS version " . $Update->"latest-version" . "? [y/N]");
    :if (([ /terminal/inkey timeout=60 ] % 32) = 25) do={
      $DoUpdate;
    } else={
      :put "Canceled...";
    }
  }

  :if ($SentRouterosUpdateNotification = $Update->"latest-version") do={
    $LogPrintExit2 info $0 ("Already sent the RouterOS update notification for version " . \
        $Update->"latest-version" . ".") true;
  }

  $SendNotification2 ({ origin=$0; \
    subject=([ $SymbolForNotification "sparkles" ] . "RouterOS update"); \
    message=("A new RouterOS version " . ($Update->"latest-version") . \
      " is available for " . $Identity . ".\n\n" . \
      [ $DeviceInfo ]); link=$Link; silent=true });
  :set SentRouterosUpdateNotification ($Update->"latest-version");
}

:if ($NumInstalled > $NumLatest) do={
  :if ($SentRouterosUpdateNotification = $Update->"latest-version") do={
    $LogPrintExit2 info $0 ("Already sent the RouterOS downgrade notification for version " . \
        $Update->"latest-version" . ".") true;
  }

  $SendNotification2 ({ origin=$0; \
    subject=([ $SymbolForNotification "warning-sign" ] . "RouterOS version"); \
    message=("A different RouterOS version " . ($Update->"latest-version") . \
      " is available for " . $Identity . ", but it is a downgrade.\n\n" . \
      [ $DeviceInfo ]); link=$Link; silent=true });
  $LogPrintExit2 info $0 ("A different RouterOS version " . ($Update->"latest-version") . \
    " is available for downgrade.") false;
  :set SentRouterosUpdateNotification ($Update->"latest-version");
}