: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 ];