diff options
Diffstat (limited to 'global-functions')
-rw-r--r-- | global-functions | 136 |
1 files changed, 133 insertions, 3 deletions
diff --git a/global-functions b/global-functions index 3187036..1aa64d2 100644 --- a/global-functions +++ b/global-functions @@ -6,7 +6,7 @@ # global functions # expected configuration version -:global ExpectedConfigVersion 13; +:global ExpectedConfigVersion 14; # global variables not to be changed by user :global GlobalFunctionsReady false; @@ -378,13 +378,143 @@ :set ScriptInstallUpdate do={ :local Scripts [ :toarray $1 ]; + :global ExpectedConfigVersion; + :global GlobalConfigVersion; + :global Identity; + :global IDonate; + :global ScriptUpdatesBaseUrl; + :global ScriptUpdatesFetch; + :global ScriptUpdatesIgnore; + :global ScriptUpdatesUrlSuffix; + :global SentConfigChangesNotification; + + :global LogPrintExit; + :global SendNotification; + :foreach Script in=$Scripts do={ :if ([ / system script print count-only where name=$Script ] = 0) do={ - :log info ("Adding new script: " . $Script); + $LogPrintExit info ("Adding new script: " . $Script) false; / system script add name=$Script source="#!rsc"; } } - / system script run script-updates; + + :foreach Script in=[ / system script find where source~"^#!rsc" or source="" ] do={ + :local Ignore 0; + :local ScriptVal [ / system script get $Script ]; + :local ScriptFile [ / file find where name=("script-updates/" . $ScriptVal->"name") ]; + :local SourceNew; + :if ([ :len $ScriptFile ] > 0) do={ + :set SourceNew [ / file get $ScriptFile content ]; + / file remove $ScriptFile; + } + + :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={ + $LogPrintExit warning ("Policies differ for script " . $ScriptVal->"name" . \ + " and its scheduler " . $SchedulerVal->"name" . "!") false; + } + :if ($SchedulerVal->"name" != "global-scripts" && \ + $SchedulerVal->"start-time" = "startup" && \ + $SchedulerVal->"interval" = 0s && \ + !(($SchedulerVal->"on-event") ~ "\\brun global-wait\\b")) do={ + $LogPrintExit warning ("Scheduler " . $SchedulerVal->"name" . " starts on startup, " . \ + "without waiting for global-functions. Run 'global-wait' to avoid race conditions!") false; + } + } + + :if ([ :len $SourceNew ] = 0 && $ScriptUpdatesFetch = true) do={ + :foreach IgnoreLoop in=$ScriptUpdatesIgnore do={ + :if ($IgnoreLoop = $ScriptVal->"name") do={ :set Ignore 1; } + } + + :if ($Ignore = 0) do={ + $LogPrintExit debug ("Fetching script from url: " . $ScriptVal->"name") false; + :do { + :local Result [ / tool fetch check-certificate=yes-without-crl \ + ($ScriptUpdatesBaseUrl . $ScriptVal->"name" . $ScriptUpdatesUrlSuffix) \ + output=user as-value ]; + :if ($Result->"status" = "finished") do={ + :set SourceNew ($Result->"data"); + } + } on-error={ + $LogPrintExit warning ("Failed fetching " . $ScriptVal->"name") false; + } + } + } + + :if ([ :len $SourceNew ] > 0) do={ + :if ([ :pick $SourceNew 0 5 ] = "#!rsc") do={ + :if ($SourceNew != $ScriptVal->"source") do={ + :local DontRequirePermissions \ + ($SourceNew~"\n# requires: dont-require-permissions=yes\n"); + $LogPrintExit info ("Updating script: " . $ScriptVal->"name") false; + / system script set owner=($ScriptVal->"name") source=$SourceNew \ + dont-require-permissions=$DontRequirePermissions $Script; + :if ($ScriptVal->"name" = "global-config" && \ + [ / system script print count-only where name="global-config-overlay" ] > 0) do={ + / system script { run global-config; run global-config-overlay; } + } + :if ($ScriptVal->"name" = "global-functions") do={ + / system script run global-functions; + } + } else={ + $LogPrintExit debug ("Script " . $ScriptVal->"name" . " did not change.") false; + } + } else={ + $LogPrintExit warning ("Looks like new script " . $ScriptVal->"name" . " is not valid. Ignoring!") false; + } + } else={ + $LogPrintExit debug ("No update for script " . $ScriptVal->"name" . ".") false; + } + } + + :if ($SentConfigChangesNotification!=$ExpectedConfigVersion && \ + $GlobalConfigVersion < $ExpectedConfigVersion) do={ + :global GlobalConfigChanges; + :local ChangeLogCode; + :local ConfigScript "global-config"; + :if ([ /system script print count-only where name="global-config-overlay" ] > 0) do={ + :set ConfigScript "global-config-overlay"; + } + :local NotificationMessage ("Current configuration on " . $Identity . \ + " is out of date. Please update " . $ConfigScript . ", then increase " . \ + "\$GlobalConfigVersion (currently " . $GlobalConfigVersion . \ + ") to " . $ExpectedConfigVersion . " and re-run " . $ConfigScript . "."); + + $LogPrintExit debug ("Fetching changelog.") false; + :do { + :local Result [ / tool fetch check-certificate=yes-without-crl \ + ($ScriptUpdatesBaseUrl . "global-config.changes" . $ScriptUpdatesUrlSuffix) \ + output=user as-value ]; + :if ($Result->"status" = "finished") do={ + :set ChangeLogCode ($Result->"data"); + } + :set NotificationMessage ($NotificationMessage . "\n\nChanges:"); + [ :parse $ChangeLogCode ]; + :for I from=($GlobalConfigVersion + 1) to=$ExpectedConfigVersion do={ + :set NotificationMessage ($NotificationMessage . \ + "\n * " . $GlobalConfigChanges->[ :tostr $I ]); + } + :set GlobalConfigChanges; + } on-error={ + $LogPrintExit warning ("Failed fetching changes!") false; + :set NotificationMessage ($NotificationMessage . \ + "\n\nChanges are not available."); + } + + :if ($IDonate != true) do={ + :set NotificationMessage ($NotificationMessage . \ + "\n\n==== donation hint ====\n" . \ + "This project is developed in private spare time and usage is " . \ + "free of charge for you. If you like the scripts and think this is " . \ + "of value for you or your business please consider a donation:\n" . \ + "https://git.eworm.de/cgit/routeros-scripts/about/#donate"); + } + + $SendNotification "Configuration warning!" $NotificationMessage; + :set SentConfigChangesNotification $ExpectedConfigVersion; + } } # lock script against multiple invocation |