]> Git [git.vados.ru] :: Repos - Mikrotiks/ros.vados.ru.git/commitdiff
Autocommit in repo: ros.vados.ru, generated by owner: root, in 04:45:02 01.04.2026.
authorvados-dev <192440777+vados-dev@users.noreply.github.com>
Wed, 1 Apr 2026 01:45:02 +0000 (04:45 +0300)
committervados-dev <192440777+vados-dev@users.noreply.github.com>
Wed, 1 Apr 2026 01:45:02 +0000 (04:45 +0300)
html/AM-GlobalFunc.rsc

index cd5eb05fe1de23fa732813a283f3e5533752e4f8..19db87e3def3f5735793d867e5d3f13b1ac065e8 100644 (file)
@@ -17,9 +17,9 @@
 :global GlobalFuncReady false;
 
 # Git commit id & info, expected configuration version
-:global CommitId "main/198/2b3a8ea6";
+:global CommitId "main/199/b67d4fe3";
 :global CommitTAG "unknown";
-:global CommitInfo "Autocommit in repo: ros.vados.ru, generated by owner: root, in 04:40:02 01.04.2026.";
+:global CommitInfo "Autocommit in repo: ros.vados.ru, generated by owner: root, in 04:45:02 01.04.2026.";
 
 # The variables are received right here.
 :global GlobalConfVersion 138;
   :return $Return;
 }
 
-:set ScriptInstallUpdate do={ :onerror Err {
-  :local Scripts    [ :toarray $1 ];
-  :local NewComment [ :tostr   $2 ];
-  :global InitSetup;
-
-  :global ScriptUpdatesCRLF;
-  :global GlobalConfVersion;
-  :global Identity;
-  :global CertificateAvailable;
-  :global CheckSumsVerify;
-  :global GlobalScriptsUrl;
-  :global SumsDirAndFileName;
-  :global GlobalScriptsUrlSuffix;
-  :global EitherOr;
-  :global FetchUserAgentStr;
-  :global Grep;
-  :global IfThenElse;
-  :global LogPrint;
-  :global ParseKeyValueStore;
-  :global RequiredRouterOS;
-  :global SendNotification2;
-  :global SymbolForNotification;
-  :global ValidateSyntax;
-  :global CommentsInScripts;
-
-  :if ([ $CertificateAvailable "Root YE" "fetch" ] = false) do={
-    $LogPrint warning $0 ("Downloading certificate failed, trying without.");
-  }
-
-  :foreach Script in=$Scripts do={
-    :if ([ :len [ /system/script/find where name=$Script ] ] = 0) do={
-      $LogPrint info $0 ("Adding new script: " . $Script);
-      /system/script/add name=$Script owner=$Script source="#!rsc by Vados\n" comment=$NewComment;
-    }
-  }
-
-  :local GlobalConfVersionBefore $GlobalConfVersion;
-  :local ReloadGlobal false;
-  :local DeviceMode [ /system/device-mode/get ];
-
-  :if ($CheckSumsVerify = true) do={
-    :local CheckSums ({});
-     :do {
-     :local Url ($GlobalScriptsUrl . $SumsDirAndFileName . $GlobalScriptsUrlSuffix);
-      $LogPrint debug $0 ("Fetching checksums from url: " . $Url);
-      :set CheckSums [ :deserialize from=json ([ /tool/fetch check-certificate=yes-without-crl \
-        http-header-field=({ [ $FetchUserAgentStr $0 ] }) $Url output=user as-value ]->"data") ];
-    } on-error={ $LogPrint warning $0 ("Err = " . $Err); }
-    }
-
-  :foreach Script in=[ /system/script/find where source~"^#!rsc by Vados" ] do={
-    :local ScriptVal [ /system/script/get $Script ];
-    :local ScriptInfo [ $ParseKeyValueStore ($ScriptVal->"comment") ];
-    :local SourceNew;
-
-    :foreach Scheduler in=[ /system/scheduler/find where on-event~("\\b" . $ScriptVal->"name" . "\\b") ] do={
-      :local SchedulerVal [ /system/scheduler/get $Scheduler ];
-      :if ($ScriptVal->"policy" != $SchedulerVal->"policy") do={
-        $LogPrint warning $0 ("Policies differ for script '" . $ScriptVal->"name" . "' and its scheduler '" . $SchedulerVal->"name" . "'!");
-        }
-    }
-    :do {
-      :if ($ScriptInfo->"ignore" = true) do={
-        $LogPrint debug $0 ("Ignoring script '" . $ScriptVal->"name" . "', as requested.");
-        :error true;
-      }
-      :if ($CheckSumsVerify = true) do={
-        :local CheckSum ($CheckSums->($ScriptVal->"name"));
-        :if ([ :len ($ScriptInfo->"base-url") ] = 0 && [ :len ($ScriptInfo->"url-suffix") ] = 0 && \
-             [ :convert transform=md5 to=hex [ :tolf ($ScriptVal->"source") ] ] = $CheckSum) do={
-          $LogPrint debug $0 ("Checksum for script '" . $ScriptVal->"name" . "' matches, ignoring.");
-          :error true;
-        }
-      }
-      :if ([ :len ($ScriptInfo->"certificate") ] > 0) do={
-        :if ([ $CertificateAvailable ($ScriptInfo->"certificate") "fetch" ] = false) do={
-          $LogPrint warning $0 ("Downloading certificate failed, trying without.");
-        }
-      }
-      :onerror Err {
-        :local BaseUrl [ $EitherOr ($ScriptInfo->"base-url") $GlobalScriptsUrl ];
-        :local UrlSuffix [ $EitherOr ($ScriptInfo->"url-suffix") $GlobalScriptsUrlSuffix ];
-        :local Url ($BaseUrl . $ScriptVal->"name" . ".rsc" . $UrlSuffix);
-        $LogPrint warning $0 ("Fetching script '" . ($ScriptVal->"name") . "' from url: " . $Url);
-        :local Result [ /tool/fetch check-certificate=yes-without-crl \
-          http-header-field=({ [ $FetchUserAgentStr $0 ] }) $Url output=user as-value ];
-        :if ($Result->"status" = "finished") do={
-          :set SourceNew [ :tolf ($Result->"data") ];
-        } 
-      } do={
-        $LogPrint warning $0 ("Failed fetching script '" . $ScriptVal->"name" . "': " . $Err);
-        :if ($Err != "Fetch failed with status 404") do={
-          :error false;
-        }
-        :if ($ScriptVal->"source" = "#!rsc by Vados") do={
-          $LogPrint warning $0 ("Removing dummy. Typo on installation?");
-          /system/script/remove $Script;
-          :error false;
-        }
-        :if ($CheckSumsVerify = true) do={
-          :if ([ :len ($ScriptInfo->"base-url") ] = 0 && [ :len ($ScriptInfo->"url-suffix") ] = 0 && \
-               [ :len $CheckSum ] = 0) do={
-            $LogPrint warning $0 ("Added the script manually? Skip updates with 'ignore=true' in comment.");
-          }
-        }
-        :error false;
-      }
-
-      :if ([ :len $SourceNew ] = 0) do={
-        $LogPrint debug $0 ("No update for script '" . ($ScriptVal->"name") . "'.");
-        :error false;
-      }
-
-      :local SourceCRLF [ :tocrlf $SourceNew ];
-      :if ($InitSetup != true && (($ScriptVal->"name") != "AM-GlobalConfig" || ($ScriptVal->"name") != "AM-GlobalFunc")) do={
-        :if ($SourceNew = ($ScriptVal->"source") || $SourceCRLF = ($ScriptVal->"source")) do={
-          $LogPrint debug $0 ("Script '" .  ($ScriptVal->"name") . "' source did not change. End of lines set to CRLF.");
-          if ($ScriptUpdatesCRLF = false) do={
-            :put [ :tolf $SourceNew ];
-            $LogPrint debug $0 ("Script '" .  ($ScriptVal->"name") . "' source update end of lines to LF.");
-          }
-        :error false;
-        }
-      }
-
-      :if ([ :pick $SourceNew 0 14 ] != "#!rsc by Vados") do={
-        $LogPrint warning $0 ("Looks like new script '" . $ScriptVal->"name" . "' is not valid (missing shebang = '$shebang') Ignoring!");
-        :error false;
-      }
-
-      :if ($CommentsInScripts = true) do={
-         :local CommentLine [ $Grep $SourceNew ("\23 Script comment: ") ];
-         :if ([ :len $CommentLine ] = 0) do={
-           $LogPrint debug $0 ("The search in new script '" . ($ScriptVal->"name") . "' for comment in script body, is not found result Ignoring!");
-           :error false;
-         } else={
-           :if ([ :len ($ScriptVal->"comment")] = 0 || [ :len ($ScriptVal->"comment")] != [ :pick $CommentLine ([ :find $CommentLine ":"] + 2) [ :len $CommentLine] ]) do={
-             $LogPrint debug $0 ("Exsiting comment for script '" . ($ScriptVal->"name") . "' is '" . ($ScriptVal->"comment") . "'.");
-             :set ($ScriptVal->"comment") [ :pick $CommentLine ([ :find $CommentLine ":"] + 2) [ :len $CommentLine] ];
-             $LogPrint debug $0 ("New comment (" . ($ScriptVal->"comment") . ") for script '" . ($ScriptVal->"name") . "' has been added!");
-           } else={
-             $LogPrint debug $0 ("Comment for script '" . ($ScriptVal->"name") . "' did not change.");
-             :error false;
-           }
-         }   
-      }
-
-      :local RequiredROS ([ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires RouterOS, ") ] ]->version);
-      :if ([ $RequiredRouterOS $0 [ $EitherOr $RequiredROS "0.0" ] false ] = false) do={
-        $LogPrint warning $0 ("The script '" . ($ScriptVal->"name") . "' requires RouterOS " . \
-            $RequiredROS . ", which is not met by your installation. Ignoring!");
-        :error false;
-      }
-      :local RequiredDM [ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires device-mode, ") ] ];
-      :local MissingDM ({});
-      :foreach Feature,Value in=$RequiredDM do={
-        :if ([ :typeof ($DeviceMode->$Feature) ] = "bool" && ($DeviceMode->$Feature) = false) do={
-          :set MissingDM ($MissingDM, $Feature);
-        }
-      }
-      :if ([ :len $MissingDM ] > 0) do={
-        $LogPrint warning $0 ("The script '" . ($ScriptVal->"name") . "' requires disabled " . \
-            "device-mode features (" . [ :tostr $MissingDM ] . "). Ignoring!");
-        :error false;
-      }
-
-      :if ([ $ValidateSyntax $SourceNew ] = false) do={
-        $LogPrint warning $0 ("Syntax validation for script '" . ($ScriptVal->"name") . "' failed! Ignoring!");
-        :error false;
-      }
-      
-      :log info ("Updating script: " . ($ScriptVal->"name") . " Script comment: " . ($ScriptVal->"comment"));
-
-      /system/script/set owner=($ScriptVal->"name") comment=($ScriptVal->"comment") \
-          source=[ $IfThenElse ($ScriptUpdatesCRLF = true) $SourceCRLF $SourceNew ] $Script;
-      :if ($ScriptVal->"name" = "AM-GlobalConfig" || \
-           $ScriptVal->"name" = "AM-GlobalFunc" || \
-           $ScriptVal->"name" ~ ("^(AM-GlobalFunc\\.d|mod)/.")) do={
-        :set ReloadGlobal true;
-      }
-    } on-error={ }
-  }
-  :if ($ReloadGlobal = true) do={
-    $LogPrint info $0 ("Reloading global configuration and functions.");
-    :onerror Err {
-      :global InitSetup (a);
-      /system/script {run AM-GlobalConfig; run AM-GlobalFunc;};
-    } do={$LogPrint error $0 ("Reloading global configuration and functions failed! " . $Err)}
-  }
-  :if ($GlobalConfVersionBefore > $GlobalConfVersion) do={
-    $LogPrint warning $0 ("The configuration version decreased from " . \
-      $GlobalConfVersionBefore . " to " . $GlobalConfVersion . \
-      ". Installed an older version?");
-  }
-    :if ($GlobalConfVersionBefore < $GlobalConfVersion) do={
-    :global GlobalConfChanges;
-    :global GlobalConfMigration;
-    :local ChangeLogCode;
-    :if ([ :len $ChangeLogCode ] > 0) do={
-      :if ([ $ValidateSyntax $ChangeLogCode ] = true) do={
-        :onerror Err {
-          [ :parse $ChangeLogCode ];
-        } do={$LogPrint warning $0 ("The changelog failed to run: " . $Err)}
-      } else={$LogPrint warning $0 ("The changelog failed syntax validation!")}
-    }
-    :if ([ :len $GlobalConfMigration ] > 0) do={
-      :for I from=($GlobalConfVersionBefore + 1) to=$GlobalConfVersion do={
-        :local Migration ($GlobalConfMigration->[ :tostr $I ]);
-        :do {
-          :if ([ :typeof $Migration ] != "str") do={
-            $LogPrint debug $0 ("Migration code for change " . $I . " is not available.");
-            :error false;
-          }
-          :if ([ $ValidateSyntax $Migration ] = false) do={
-            $LogPrint warning $0 ("Migration code for change " . $I . " failed syntax validation!");
-            :error false}
-          $LogPrint info $0 ("Applying migration for change " . $I . ": " . $Migration);
-          :onerror Err {
-            [ :parse $Migration ];
-          } do={$LogPrint warning $0 ("Migration code for change " . $I . " failed to run: " . $Err)}
-        } on-error={ }
-      }
-    }
-    :local NotificationMessage ("The configuration version on " . $Identity . " increased " . \
-       "to " . $GlobalConfVersion . ", current configuration may need modification. " . \
-       "Please review and update global-config-overlay, then re-run global-config.");
-    $LogPrint info $0 ($NotificationMessage);
-    :if ([ :len $GlobalConfChanges ] > 0) do={
-      :set NotificationMessage ($NotificationMessage . "\n\nChanges:");
-      :for I from=($GlobalConfVersionBefore + 1) to=$GlobalConfVersion do={
-        :local Change ($GlobalConfChanges->[ :tostr $I ]);
-        :set NotificationMessage ($NotificationMessage . "\n " . \
-            [ $SymbolForNotification "pushpin" "*" ] . $Change);
-        $LogPrint info $0 ("Change " . $I . ": " . $Change);
-      }
-    } else={:set NotificationMessage ($NotificationMessage . "\n\nNews and changes are not available.")}
-
-    :set GlobalConfChanges;
-    :set GlobalConfMigration;
-  }
-} do={:global ExitOnError; $ExitOnError $0 $Err}
-}
-
 :set FetchUserAgentStr do={
   :local Caller [ :tostr $1 ];
   :global IfThenElse;
   :return $Return;
 }
 
+:set ScriptInstallUpdate do={ :onerror Err {
+  :local Scripts    [ :toarray $1 ];
+  :local NewComment [ :tostr   $2 ];
+  :global InitSetup;
+
+  :global CommitId;
+  :global ScriptUpdatesCRLF;
+  :global GlobalConfVersion;
+  :global Identity;
+  :global CertificateAvailable;
+  :global CheckSumsVerify;
+  :global GlobalScriptsUrl;
+  :global SumsDirAndFileName;
+  :global GlobalScriptsUrlSuffix;
+  :global EitherOr;
+  :global FetchUserAgentStr;
+  :global Grep;
+  :global IfThenElse;
+  :global LogPrint;
+  :global ParseKeyValueStore;
+  :global RequiredRouterOS;
+  :global SendNotification2;
+  :global SymbolForNotification;
+  :global ValidateSyntax;
+  :global CommentsInScripts;
+
+  :if ([ $CertificateAvailable "Root YE" "fetch" ] = false) do={
+    $LogPrint warning $0 ("Downloading certificate failed, trying without.");
+  }
+
+  :foreach Script in=$Scripts do={
+    :if ([ :len [ /system/script/find where name=$Script ] ] = 0) do={
+      $LogPrint info $0 ("Adding new script: " . $Script);
+      /system/script/add name=$Script owner=$Script source="#!rsc by Vados\n" comment=$NewComment;
+    }
+  }
+
+  :local GlobalConfVersionBefore $GlobalConfVersion;
+  :local ReloadGlobal false;
+  :local DeviceMode [ /system/device-mode/get ];
+
+  :if ($CheckSumsVerify = true) do={
+    :local CheckSums ({});
+     :do {
+     :local Url ($GlobalScriptsUrl . $SumsDirAndFileName . $GlobalScriptsUrlSuffix);
+      $LogPrint debug $0 ("Fetching checksums from url: " . $Url);
+      :set CheckSums [ :deserialize from=json ([ /tool/fetch check-certificate=yes-without-crl \
+        http-header-field=({ [ $FetchUserAgentStr $0 ] }) $Url output=user as-value ]->"data") ];
+    } on-error={ $LogPrint warning $0 ("Err = " . $Err); }
+    }
+
+  :foreach Script in=[ /system/script/find where source~"^#!rsc by Vados" ] do={
+    :local ScriptVal [ /system/script/get $Script ];
+    :local ScriptInfo [ $ParseKeyValueStore ($ScriptVal->"comment") ];
+    :local SourceNew;
+
+    :foreach Scheduler in=[ /system/scheduler/find where on-event~("\\b" . $ScriptVal->"name" . "\\b") ] do={
+      :local SchedulerVal [ /system/scheduler/get $Scheduler ];
+      :if ($ScriptVal->"policy" != $SchedulerVal->"policy") do={
+        $LogPrint warning $0 ("Policies differ for script '" . $ScriptVal->"name" . "' and its scheduler '" . $SchedulerVal->"name" . "'!");
+        }
+    }
+    :do {
+      :if ($ScriptInfo->"ignore" = true) do={
+        $LogPrint debug $0 ("Ignoring script '" . $ScriptVal->"name" . "', as requested.");
+        :error true;
+      }
+      :if ($CheckSumsVerify = true) do={
+        :local CheckSum ($CheckSums->($ScriptVal->"name"));
+        :if ([ :len ($ScriptInfo->"base-url") ] = 0 && [ :len ($ScriptInfo->"url-suffix") ] = 0 && \
+             [ :convert transform=md5 to=hex [ :tolf ($ScriptVal->"source") ] ] = $CheckSum) do={
+          $LogPrint debug $0 ("Checksum for script '" . $ScriptVal->"name" . "' matches, ignoring.");
+          :error true;
+        }
+      }
+      :if ([ :len ($ScriptInfo->"certificate") ] > 0) do={
+        :if ([ $CertificateAvailable ($ScriptInfo->"certificate") "fetch" ] = false) do={
+          $LogPrint warning $0 ("Downloading certificate failed, trying without.");
+        }
+      }
+      :onerror Err {
+        :local BaseUrl [ $EitherOr ($ScriptInfo->"base-url") $GlobalScriptsUrl ];
+        :local UrlSuffix [ $EitherOr ($ScriptInfo->"url-suffix") $GlobalScriptsUrlSuffix ];
+        :local Url ($BaseUrl . $ScriptVal->"name" . ".rsc" . $UrlSuffix);
+        $LogPrint warning $0 ("Fetching script '" . ($ScriptVal->"name") . "' from url: " . $Url);
+        :local Result [ /tool/fetch check-certificate=yes-without-crl \
+          http-header-field=({ [ $FetchUserAgentStr $0 ] }) $Url output=user as-value ];
+        :if ($Result->"status" = "finished") do={
+          :set SourceNew [ :tolf ($Result->"data") ];
+        } 
+      } do={
+        $LogPrint warning $0 ("Failed fetching script '" . $ScriptVal->"name" . "': " . $Err);
+        :if ($Err != "Fetch failed with status 404") do={
+          :error false;
+        }
+        :if ($ScriptVal->"source" = "#!rsc by Vados") do={
+          $LogPrint warning $0 ("Removing dummy. Typo on installation?");
+          /system/script/remove $Script;
+          :error false;
+        }
+        :if ($CheckSumsVerify = true) do={
+          :if ([ :len ($ScriptInfo->"base-url") ] = 0 && [ :len ($ScriptInfo->"url-suffix") ] = 0 && \
+               [ :len $CheckSum ] = 0) do={
+            $LogPrint warning $0 ("Added the script manually? Skip updates with 'ignore=true' in comment.");
+          }
+        }
+        :error false;
+      }
+
+      :if ([ :len $SourceNew ] = 0) do={
+        $LogPrint debug $0 ("No update for script '" . ($ScriptVal->"name") . "'.");
+        :error false;
+      }
+
+      :local SourceCRLF [ :tocrlf $SourceNew ];
+      :if ($InitSetup != true && (($ScriptVal->"name") != "AM-GlobalConfig" || ($ScriptVal->"name") != "AM-GlobalFunc")) do={
+        :if ($SourceNew = ($ScriptVal->"source") || $SourceCRLF = ($ScriptVal->"source")) do={
+          $LogPrint debug $0 ("Script '" .  ($ScriptVal->"name") . "' source did not change. End of lines set to CRLF.");
+          if ($ScriptUpdatesCRLF = false) do={
+            :put [ :tolf $SourceNew ];
+            $LogPrint debug $0 ("Script '" .  ($ScriptVal->"name") . "' source update end of lines to LF.");
+          }
+        :error false;
+        }
+      }
+
+      :if ([ :pick $SourceNew 0 14 ] != "#!rsc by Vados") do={
+        $LogPrint warning $0 ("Looks like new script '" . $ScriptVal->"name" . "' is not valid (missing shebang = '$shebang') Ignoring!");
+        :error false;
+      }
+
+      :if ($CommentsInScripts = true) do={
+         :local CommentLine [ $Grep $SourceNew ("\23 Script comment: ") ];
+         :if ([ :len $CommentLine ] = 0) do={
+           $LogPrint debug $0 ("The search in new script '" . ($ScriptVal->"name") . "' for comment in script body, is not found result Ignoring!");
+           :error false;
+         } else={
+           :if ([ :len ($ScriptVal->"comment")] = 0 || [ :len ($ScriptVal->"comment")] != [ :pick $CommentLine ([ :find $CommentLine ":"] + 2) [ :len $CommentLine] ]) do={
+             $LogPrint debug $0 ("Exsiting comment for script '" . ($ScriptVal->"name") . "' is '" . ($ScriptVal->"comment") . "'.");
+             :set ($ScriptVal->"comment") [ :pick $CommentLine ([ :find $CommentLine ":"] + 2) [ :len $CommentLine] ];
+             $LogPrint debug $0 ("New comment (" . ($ScriptVal->"comment") . ") for script '" . ($ScriptVal->"name") . "' has been added!");
+           } else={
+             $LogPrint debug $0 ("Comment for script '" . ($ScriptVal->"name") . "' did not change.");
+             :error false;
+           }
+         }   
+      }
+
+      :local RequiredROS ([ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires RouterOS, ") ] ]->version);
+      :if ([ $RequiredRouterOS $0 [ $EitherOr $RequiredROS "0.0" ] false ] = false) do={
+        $LogPrint warning $0 ("The script '" . ($ScriptVal->"name") . "' requires RouterOS " . \
+            $RequiredROS . ", which is not met by your installation. Ignoring!");
+        :error false;
+      }
+      :local RequiredDM [ $ParseKeyValueStore [ $Grep $SourceNew ("\23 requires device-mode, ") ] ];
+      :local MissingDM ({});
+      :foreach Feature,Value in=$RequiredDM do={
+        :if ([ :typeof ($DeviceMode->$Feature) ] = "bool" && ($DeviceMode->$Feature) = false) do={
+          :set MissingDM ($MissingDM, $Feature);
+        }
+      }
+      :if ([ :len $MissingDM ] > 0) do={
+        $LogPrint warning $0 ("The script '" . ($ScriptVal->"name") . "' requires disabled " . \
+            "device-mode features (" . [ :tostr $MissingDM ] . "). Ignoring!");
+        :error false;
+      }
+
+      :if ([ $ValidateSyntax $SourceNew ] = false) do={
+        $LogPrint warning $0 ("Syntax validation for script '" . ($ScriptVal->"name") . "' failed! Ignoring!");
+        :error false;
+      }
+      
+      :log info ("Updating script: " . ($ScriptVal->"name") . " Script comment: " . ($ScriptVal->"comment"));
+
+      /system/script/set owner=($ScriptVal->"name") comment=($ScriptVal->"comment") \
+          source=[ $IfThenElse ($ScriptUpdatesCRLF = true) $SourceCRLF $SourceNew ] $Script;
+      :if ($ScriptVal->"name" = "AM-GlobalConfig" || \
+           $ScriptVal->"name" = "AM-GlobalFunc" || \
+           $ScriptVal->"name" ~ ("^(AM-GlobalFunc\\.d|mod)/.")) do={
+        :set ReloadGlobal true;
+      }
+    } on-error={ }
+  }
+  :if ($ReloadGlobal = true) do={
+    $LogPrint info $0 ("Reloading global configuration and functions.");
+    :onerror Err {
+      :global InitSetup (a);
+      /system/script {run AM-GlobalConfig; run AM-GlobalFunc;};
+    } do={$LogPrint error $0 ("Reloading global configuration and functions failed! " . $Err)}
+  }
+  :if ($GlobalConfVersionBefore > $GlobalConfVersion) do={
+    $LogPrint warning $0 ("The configuration version decreased from " . \
+      $GlobalConfVersionBefore . " to " . $GlobalConfVersion . \
+      ". Installed an older version?");
+  }
+    :if ($GlobalConfVersionBefore < $GlobalConfVersion) do={
+    :global GlobalConfChanges;
+    :global GlobalConfMigration;
+    :local ChangeLogCode;
+    :if ([ :len $ChangeLogCode ] > 0) do={
+      :if ([ $ValidateSyntax $ChangeLogCode ] = true) do={
+        :onerror Err {
+          [ :parse $ChangeLogCode ];
+        } do={$LogPrint warning $0 ("The changelog failed to run: " . $Err)}
+      } else={$LogPrint warning $0 ("The changelog failed syntax validation!")}
+    }
+    :if ([ :len $GlobalConfMigration ] > 0) do={
+      :for I from=($GlobalConfVersionBefore + 1) to=$GlobalConfVersion do={
+        :local Migration ($GlobalConfMigration->[ :tostr $I ]);
+        :do {
+          :if ([ :typeof $Migration ] != "str") do={
+            $LogPrint debug $0 ("Migration code for change " . $I . " is not available.");
+            :error false;
+          }
+          :if ([ $ValidateSyntax $Migration ] = false) do={
+            $LogPrint warning $0 ("Migration code for change " . $I . " failed syntax validation!");
+            :error false}
+          $LogPrint info $0 ("Applying migration for change " . $I . ": " . $Migration);
+          :onerror Err {
+            [ :parse $Migration ];
+          } do={$LogPrint warning $0 ("Migration code for change " . $I . " failed to run: " . $Err)}
+        } on-error={ }
+      }
+    }
+    :local NotificationMessage ("The configuration version on " . $Identity . " increased " . \
+       "to " . $GlobalConfVersion . ", current configuration may need modification. " . \
+       "Please review and update global-config-overlay, then re-run global-config.");
+    $LogPrint info $0 ($NotificationMessage);
+    :if ([ :len $GlobalConfChanges ] > 0) do={
+      :set NotificationMessage ($NotificationMessage . "\n\nChanges:");
+      :for I from=($GlobalConfVersionBefore + 1) to=$GlobalConfVersion do={
+        :local Change ($GlobalConfChanges->[ :tostr $I ]);
+        :set NotificationMessage ($NotificationMessage . "\n " . \
+            [ $SymbolForNotification "pushpin" "*" ] . $Change);
+        $LogPrint info $0 ("Change " . $I . ": " . $Change);
+      }
+    } else={:set NotificationMessage ($NotificationMessage . "\n\nNews and changes are not available.")}
+
+    :set GlobalConfChanges;
+    :set GlobalConfMigration;
+  }
+} do={:global ExitOnError; $ExitOnError $0 $Err}
+}
+
 # Global Environment clear. Use: "$GlobalEnvRemove True;".
 :set GlobalEnvRemove do={
   :local doRmEnv [ :tostr $1 ];