mirror of
https://github.com/beeyev/Mikrotik-RouterOS-automatic-backup-and-update.git
synced 2025-07-15 08:24:37 +02:00
Refactor OS version and channel retrieval functions for improved clarity and error handling
This commit is contained in:
parent
d1b3e45468
commit
e2439c15f7
1 changed files with 126 additions and 47 deletions
173
v3.rsc
173
v3.rsc
|
@ -75,24 +75,45 @@
|
||||||
#:log info "$SMP Script Mode: `$scriptMode`, forceBackup: `$forceBackup`"
|
#:log info "$SMP Script Mode: `$scriptMode`, forceBackup: `$forceBackup`"
|
||||||
|
|
||||||
############### vvvvvvvvv FUNCTIONS vvvvvvvvv ###############
|
############### vvvvvvvvv FUNCTIONS vvvvvvvvv ###############
|
||||||
# Function: FuncGetInstalledOsChannel
|
|
||||||
|
# Function: FuncGetRunningOsVersion
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
# Returns installed RouterOS channel (stable, long-term, testing, development)
|
# Returns currently running RouterOS version
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
# :put [$FuncGetInstalledOsChannel] # Output: stable
|
# :put [$FuncGetRunningOsVersion] # Output: 6.48.1
|
||||||
:local FuncGetInstalledOsChannel do={
|
:local FuncGetRunningOsVersion do={
|
||||||
:local installedOsAndChannel [/system resource get version]
|
:local runningOsAndChannel [/system resource get version]
|
||||||
:local errorMessage "Bkp&Upd: Could not extract installed OS channel from version string: `$installedOsAndChannel`. Script stopped."
|
|
||||||
|
:local spacePos [:find $runningOsAndChannel " "]
|
||||||
|
if ([:len $spacePos] = 0) do={
|
||||||
|
:log error "Bkp&Upd: Could not extract installed OS version string: `$runningOsAndChannel`. Script stopped."
|
||||||
|
:error "Bkp&Upd: script stopped due to an error. Please check logs for more details."
|
||||||
|
}
|
||||||
|
|
||||||
|
:local versionOnly [:pick $runningOsAndChannel 0 $spacePos]
|
||||||
|
|
||||||
|
:return $versionOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function: FuncGetRunningOsChannel
|
||||||
|
# ----------------------------
|
||||||
|
# Returns currently running RouterOS channel (stable, long-term, testing, development)
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# :put [$FuncGetRunningOsChannel] # Output: stable
|
||||||
|
:local FuncGetRunningOsChannel do={
|
||||||
|
:local runningOsAndChannel [/system resource get version]
|
||||||
|
:local errorMessage "Bkp&Upd: Could not extract installed OS channel from version string: `$runningOsAndChannel`. Script stopped."
|
||||||
:local exitErrorMessage "Bkp&Upd: script stopped due to an error. Please check logs for more details."
|
:local exitErrorMessage "Bkp&Upd: script stopped due to an error. Please check logs for more details."
|
||||||
|
|
||||||
:local open [:find $installedOsAndChannel "("]
|
:local open [:find $runningOsAndChannel "("]
|
||||||
if ([:len $open] = 0) do={
|
if ([:len $open] = 0) do={
|
||||||
:log error ($errorMessage . " (1)")
|
:log error ($errorMessage . " (1)")
|
||||||
:error $exitErrorMessage
|
:error $exitErrorMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
:local rest [:pick $installedOsAndChannel ($open+1) [:len $installedOsAndChannel]]
|
:local rest [:pick $runningOsAndChannel ($open+1) [:len $runningOsAndChannel]]
|
||||||
|
|
||||||
:local close [:find $rest ")"]
|
:local close [:find $rest ")"]
|
||||||
if ([:len $close] = 0) do={
|
if ([:len $close] = 0) do={
|
||||||
|
@ -266,10 +287,10 @@ if ($scriptMode = "osupdate" and $installOnlyPatchUpdates=true) do={
|
||||||
:error $exitErrorMessage
|
:error $exitErrorMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
:local susInstalledOsChannel [$FuncGetInstalledOsChannel]
|
:local susRunningOsChannel [$FuncGetRunningOsChannel]
|
||||||
|
|
||||||
if ($susInstalledOsChannel != "stable" and $susInstalledOsChannel != "long-term") do={
|
if ($susRunningOsChannel != "stable" and $susRunningOsChannel != "long-term") do={
|
||||||
:log error ("$SMP Script is set to install only patch updates, but the installed RouterOS version is not from `stable` or `long-term` channel: `$susInstalledOsChannel`. Script stopped.")
|
:log error ("$SMP Script is set to install only patch updates, but the installed RouterOS version is not from `stable` or `long-term` channel: `$susRunningOsChannel`. Script stopped.")
|
||||||
:error $exitErrorMessage
|
:error $exitErrorMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,27 +331,37 @@ if ($scriptMode = "osupdate" and $installOnlyPatchUpdates=true) do={
|
||||||
:set isCloudHostedRouter true;
|
:set isCloudHostedRouter true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
:local deviceIdentityName [/system identity get name];
|
||||||
|
:local deviceIdentityNameShort [:pick $deviceIdentityName 0 18]
|
||||||
|
|
||||||
:local deviceRbModel "CloudHostedRouter";
|
:local deviceRbModel "CloudHostedRouter";
|
||||||
:local deviceRbSerialNumber "--";
|
:local deviceRbSerialNumber "--"
|
||||||
:local deviceRbCurrentFw "--";
|
:local deviceRbCurrentFw "--"
|
||||||
:local deviceRbUpgradeFw "--";
|
:local deviceRbUpgradeFw "--"
|
||||||
|
|
||||||
:if ($isCloudHostedRouter = false) do={
|
:if ($isCloudHostedRouter = false) do={
|
||||||
:set deviceRbModel [/system routerboard get model];
|
:set deviceRbModel [/system routerboard get model]
|
||||||
:set deviceRbSerialNumber [/system routerboard get serial-number];
|
:set deviceRbSerialNumber [/system routerboard get serial-number]
|
||||||
:set deviceRbCurrentFw [/system routerboard get current-firmware];
|
:set deviceRbCurrentFw [/system routerboard get current-firmware]
|
||||||
:set deviceRbUpgradeFw [/system routerboard get upgrade-firmware];
|
:set deviceRbUpgradeFw [/system routerboard get upgrade-firmware]
|
||||||
};
|
};
|
||||||
|
|
||||||
:local installedOsChannel [$FuncGetInstalledOsChannel]
|
:local runningOsChannel [$FuncGetRunningOsChannel]
|
||||||
:local deviceOsVerAndChannelInstalled [/system resource get version]
|
:local runningOsVersion [$FuncGetRunningOsVersion]
|
||||||
|
:local deviceOsVerAndChannelRunning [/system resource get version]
|
||||||
|
|
||||||
:local backupNameTemplate "v$deviceOsVerInstalled_$installedOsChannel_$currentDateTime";
|
:local backupNameTemplate "v$runningOsVersion_$runningOsChannel_$currentDateTime"
|
||||||
:local backupNameBeforeUpdate "backup_before_update_$backupNameTemplate";
|
:local backupNameBeforeUpdate "backup_before_update_$backupNameTemplate"
|
||||||
:local backupNameAfterUpdate "backup_after_update_$backupNameTemplate";
|
:local backupNameAfterUpdate "backup_after_update_$backupNameTemplate"
|
||||||
|
|
||||||
## Email body template
|
## Email body template
|
||||||
|
|
||||||
|
:local mailSubject "$SMP Device - $deviceIdentityNameShort."
|
||||||
|
:local mailBody ""
|
||||||
|
|
||||||
|
:local mailBodyCopyright "\r\n\r\nMikrotik RouterOS automatic backup & update (ver. $scriptVersion) \r\nhttps://github.com/beeyev/Mikrotik-RouterOS-automatic-backup-and-update"
|
||||||
|
:local changelogUrl "Check RouterOS changelog: https://mikrotik.com/download/changelogs/"
|
||||||
|
|
||||||
:local mailBodyDeviceInfo ""
|
:local mailBodyDeviceInfo ""
|
||||||
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\n\nDevice information")
|
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\n\nDevice information")
|
||||||
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\n---------------------")
|
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\n---------------------")
|
||||||
|
@ -338,54 +369,102 @@ if ($scriptMode = "osupdate" and $installOnlyPatchUpdates=true) do={
|
||||||
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nModel: $deviceRbModel")
|
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nModel: $deviceRbModel")
|
||||||
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nBoard: $deviceBoardName")
|
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nBoard: $deviceBoardName")
|
||||||
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nSerial number: $deviceRbSerialNumber")
|
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nSerial number: $deviceRbSerialNumber")
|
||||||
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nRouterOS version: v$deviceOsVerAndChannelInstalled")
|
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nRouterOS version: v$deviceOsVerAndChannelRunning")
|
||||||
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nBuild time: $[/system resource get build-time]")
|
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nBuild time: $[/system resource get build-time]")
|
||||||
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nRouterboard FW: $deviceRbCurrentFw")
|
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nRouterboard FW: $deviceRbCurrentFw")
|
||||||
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nDate time: $rawDate $rawTime")
|
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nDate time: $rawDate $rawTime")
|
||||||
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nUptime: $[/system resource get uptime]")
|
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nUptime: $[/system resource get uptime]")
|
||||||
|
# IP address will be appended later if needed
|
||||||
|
|
||||||
:local mailAttachments [:toarray ""];
|
:local mailAttachments [:toarray ""]
|
||||||
|
|
||||||
|
|
||||||
|
## IP address detection & anonymous statistics collection
|
||||||
|
:if ($updateStep = 1 or $updateStep = 3) do={
|
||||||
|
:if ($updateStep = 3) do={
|
||||||
|
:log info ("$SMP Waiting for one minute before continuing to the final step.")
|
||||||
|
:delay 1m
|
||||||
|
}
|
||||||
|
# default values, to be set later
|
||||||
|
:local publicIpAddress "not-detected"
|
||||||
|
:local telemetryDataQuery ""
|
||||||
|
|
||||||
|
:if ($detectPublicIpAddress = true or $allowAnonymousStatisticsCollection = true) do={
|
||||||
|
:if ($allowAnonymousStatisticsCollection = true) do={
|
||||||
|
:set telemetryDataQuery ("\?mode=" . $scriptMode . "&osver=" . $deviceOsVerInst . "&model=" . $deviceRbModel. "&step=" . $updateStep)
|
||||||
|
}
|
||||||
|
|
||||||
|
:do {:set publicIpAddress ([/tool fetch http-method="get" url=($ipAddressDetectServiceDefault . $telemetryDataQuery) output=user as-value]->"data")} on-error={
|
||||||
|
:if ($detectPublicIpAddress = true) do={
|
||||||
|
:log warning "$SMP Could not detect public IP address using default detection service: `$ipAddressDetectServiceDefault`"
|
||||||
|
:log warning "$SMP Trying to detect public IP using fallback detection service: `$ipAddressDetectServiceFallback`"
|
||||||
|
:do {
|
||||||
|
:set publicIpAddress ([/tool fetch http-method="get" url=$ipAddressDetectServiceFallback output=user as-value]->"data")
|
||||||
|
} on-error={
|
||||||
|
:log warning "$SMP Could not detect public IP address using fallback detection service: `$ipAddressDetectServiceFallback`"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:set publicIpAddress ([:pick $publicIpAddress 0 15])
|
||||||
|
|
||||||
|
:if ($detectPublicIpAddress = true) do={
|
||||||
|
# truncate IP to max 15 characters (basic safety)
|
||||||
|
:set mailBodyDeviceInfo ($mailBodyDeviceInfo . "\nPublic IP address: $publicIpAddress")
|
||||||
|
:log info "$SMP Public IP address detected: `$publicIpAddress`"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
## STEP ONE: Creating backups, checking for new RouterOs version and sending email with backups,
|
## STEP ONE: Creating backups, checking for new RouterOs version and sending email with backups,
|
||||||
## Steps 2 and 3 are fired only if script is set to automatically update device and if a new RouterOs version is available.
|
## Steps 2 and 3 are fired only if script is set to automatically update device and if a new RouterOs version is available.
|
||||||
:if ($updateStep = 1) do={
|
:if ($updateStep = 1) do={
|
||||||
:log info ("$SMP Performing the first step.")
|
:log info ("$SMP Performing the first step.")
|
||||||
|
|
||||||
:local deviceOsVerAvailable "0.0.0"
|
:local routerOsVersionAvailable "0.0.0"
|
||||||
:local packageUpdateStatus "undefined"
|
|
||||||
:local isNewOsUpdateAvailable false
|
:local isNewOsUpdateAvailable false
|
||||||
:local isLatestOsAlreadyInstalled true
|
:local isLatestOsAlreadyInstalled true
|
||||||
:local isOsNeedsToBeUpdated false
|
:local isOsNeedsToBeUpdated false
|
||||||
|
|
||||||
# Checking for new RouterOS version
|
# Checking for new RouterOS version
|
||||||
if ($scriptMode = "osupdate" or $scriptMode = "osnotify") do={
|
if ($scriptMode = "osupdate" or $scriptMode = "osnotify") do={
|
||||||
log info ("$SMP Setting update channel to `$updateChannel`")
|
log info ("$SMP Setting update channel to `$updateChannel`")
|
||||||
/system package update set channel=$updateChannel
|
/system package update set channel=$updateChannel
|
||||||
log info ("$SMP Checking for new RouterOS version. Current installed version is: `$deviceOsVerInstalled`")
|
log info ("$SMP Checking for new RouterOS version. Current installed version is: `$runningOsVersion`")
|
||||||
/system package update check-for-updates
|
/system package update check-for-updates
|
||||||
|
|
||||||
# Wait for 5 seconds to allow the system to check for updates
|
# Wait for 5 seconds to allow the system to check for updates
|
||||||
:delay 5s;
|
:delay 5s;
|
||||||
|
|
||||||
:set deviceOsVerAvailable [/system package update get latest-version]
|
:local packageUpdateStatus "undefined"
|
||||||
:set packageUpdateStatus [/system package update get status]
|
|
||||||
|
|
||||||
if ($packageUpdateStatus = "New version is available") do={
|
:set routerOsVersionAvailable [/system package update get latest-version]
|
||||||
:log info ("$SMP New RouterOS version is available: `$deviceOsVerAvailable`")
|
:set packageUpdateStatus [/system package update get status]
|
||||||
:set isNewOsUpdateAvailable true
|
|
||||||
:set isLatestOsAlreadyInstalled false
|
if ($packageUpdateStatus = "New version is available") do={
|
||||||
|
:log info ("$SMP New RouterOS version is available: `$routerOsVersionAvailable`")
|
||||||
|
:set isNewOsUpdateAvailable true
|
||||||
|
:set isLatestOsAlreadyInstalled false
|
||||||
|
} else={
|
||||||
|
if ($packageUpdateStatus = "System is already up to date") do={
|
||||||
|
:log info ("$SMP No new RouterOS version is available, this device is already up to date: `$runningOsVersion`")
|
||||||
} else={
|
} else={
|
||||||
if ($packageUpdateStatus = "System is already up to date") do={
|
:log error ("$SMP Failed to check for new RouterOS version. Package check status: `$packageUpdateStatus`")
|
||||||
:log info ("$SMP No new RouterOS version is available, this device is already up to date: `$deviceOsVerInstalled`")
|
|
||||||
} else={
|
|
||||||
:log error ("$SMP Failed to check for new RouterOS version. Package check status: `$packageUpdateStatus`")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# TODO Check for minor version updates
|
|
||||||
if ($scriptMode = "osupdate" and $isNewOsUpdateAvailable = true) do={
|
if ($scriptMode = "osupdate" and $isNewOsUpdateAvailable = true) do={
|
||||||
:set isOsNeedsToBeUpdated true
|
if ($installOnlyPatchUpdates = true) do={
|
||||||
|
:if ([$FuncIsPatchUpdateOnly $runningOsVersion $routerOsVersionAvailable] = false) do={
|
||||||
|
:log info ("$SMP New RouterOS version is available, but it is not a patch update. Current version: `$runningOsVersion`, new version: `$routerOsVersionAvailable`.")
|
||||||
|
:set isOsNeedsToBeUpdated true
|
||||||
|
} else={
|
||||||
|
:log info ("$SMP New RouterOS version is available and it is a patch update. Current version: `$runningOsVersion`, new version: `$routerOsVersionAvailable`.")
|
||||||
|
}
|
||||||
|
} else={
|
||||||
|
:set isOsNeedsToBeUpdated true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue