-
-
Save tcminh1987/6f9597d9879d796aebb4ae54eb502623 to your computer and use it in GitHub Desktop.
:local containerToUpdate | |
:set $containerToUpdate "name-of-container" | |
:local containerVeth | |
:set $containerVeth "container-veth-interface" | |
:local containerImage | |
:set $containerImage "org/image:tag" | |
:local containerEnvlist | |
:set $containerEnvlist "name-of-envlist" | |
:local containerMounts | |
:set %containerMounts "name-of-mount" | |
# Stop Container | |
/container/stop [find where comment~$containerToUpdate] | |
# Wait for container(s) to stop | |
:while ( [/container print count-only where comment~$containerToUpdate status=stopping] > 0) do={ :delay 1 } | |
# Remove old Container(s) | |
/container/remove [find where comment~$containerToUpdate] | |
# short delay | |
:delay 3 | |
# create new container | |
/container/add interface=$containerVeth remote-image=$containerImage mounts=$containerMounts envlist=$containerEnvlist start-on-boot=yes logging=yes comment=$containerToUpdate | |
:delay 1 | |
# Wait for new container to be ready | |
:while ( [/container print count-only where comment~$containerToUpdate status=extracting] > 0 ) do { :delay 1 } | |
# Start the new container | |
/container/start [find where comment~$containerToUpdate] |
:local contComment "<CONTAINER_COMMENT>"
:local logPrefix "Container update: "
:local abortWithMessage do={
:log error "$($logPrefix)Error - $1"
:error $1
}
/container
:local contId [find where comment=$contComment]
:if ($contId = "") do={ $abortWithMessage ("container $contComment not found, aborting") logPrefix=$logPrefix }
:local contStatus ([get $contId]->"status")
:if ($contStatus = "extracting") do={ $abortWithMessage ("container $contComment is extracting, aborting") logPrefix=$logPrefix }
:log info "$($logPrefix)Container $contComment update started"
:local contStarted false
:if ($contStatus != "stopped") do={
:if ($contStatus = "running") do={
:log warn "$($logPrefix)Container $contComment is running, stopping container"
:set contStarted true
stop $contId
}
:local stopTimeoutSec 120
:local sec 0
:while (([get $contId]->"status") != "stopped" && $sec <= $stopTimeoutSec) do={
:delay 1
:set sec ($sec + 1)
}
:if ($sec > $stopTimeoutSec) do={ $abortWithMessage ("container $contComment stop timed out, aborting") logPrefix=$logPrefix }
:log info "$($logPrefix)Container $contComment stopped"
}
:local cont [get $contId]
remove $contId
:delay 5
after ROS upgrade check below if something has changed
------------------------------------------------------
validAddArgs - array of container add command argument names which are named exact as config property names
:local validAddArgs ( "cmd", "comment", "dns", "domain-name", "entrypoint", "envlist", "hostname", "interface", "logging", "mounts", "root-dir", "start-on-boot", "workdir" )
replaceArgs - key-value array for mapping container add command argument name from different config property name, where key is config property name and value is argument name
:local replaceArgs { "tag"="remote-image" }
addCmd - ROS CLI container add command
:local addCmd "/container add"
-----------------------------------------------------
:local escapeStr do={
:local strLen [:len $1]
:local escStr ""
:for i from=0 to=($strLen - 1) do={
:local chr [:pick $1 $i ($i + 1)]
:if ($chr = "\$") do={ :set escStr "$escStr\\\$" } else={
:if ($chr = "\\") do={ :set escStr "$escStr\\\\" } else={
:if ($chr = "\"") do={ :set escStr "$escStr\\\"" } else={
:set escStr "$escStr$chr"
}
}
}
}
:return ""$escStr""
}
:local arrayToStr do={
:local arrLen [:len $1]
:local strArr "("
:for i from=0 to=($arrLen - 1) do={
:local item [:pick $1 $i]
:if ([:len $strArr] > 1) do={ :set $strArr "$strArr," }
:if ([:typeof $item] = "str") do={
:set $strArr "$strArr$([$escapeStr $item])"
} else={
:set $strArr "$strArr$item"
}
}
:return "$strArr)"
}
:local escapeValue do={
:if ([:typeof $1] = "str") do={ :return [$escapeStr $1] }
:if ([:typeof $1] = "array") do={ :return [$arrayToStr $1 escapeStr=$escapeStr] }
:if ([:typeof $1] = "bool") do={:if ($1) do={ :return "yes" } else={ :return "no" }}
:return $1
}
:foreach k,v in=$cont do={
:if ([:len $v] != 0) do={
:if ([:find $validAddArgs $k] >= 0) do={
:set addCmd "$addCmd
} else={
:local rk ($replaceArgs->"$k")
:if ([:typeof $rk] != "nothing") do={ :set addCmd "$addCmd
}
}
}
:execute "$addCmd" as-string
:set contId [find where comment=$contComment]
:if ($contId = "") do={ $abortWithMessage ("unable to add container $contComment, check add command: $addCmd") logPrefix=$logPrefix }
rise if not enough (30min) on slow network or device
:local extrTimeoutSec 1800
:local sec 0
:while (([get $contId]->"status") = "extracting" && $sec <= $extrTimeoutSec) do={
:delay 1
:set sec ($sec + 1)
}
:if ($sec > $extrTimeoutSec) do={ $abortWithMessage ("container $contComment extract wait timed out, something is failed or slower than expected") logPrefix=$logPrefix }
:if ($contStarted) do={ start $contId }
:log info "$($logPrefix)Container $contComment update finished"
:local contComment "<CONTAINER_COMMENT>"
:local logPrefix "Container update: "
:local abortWithMessage do={
:log error "$($logPrefix)Error - $1"
:error $1
}
/container
:local contId [find where comment=$contComment]
:if ($contId = "") do={ $abortWithMessage ("container $contComment not found, aborting") logPrefix=$logPrefix }
:local contStatus ([get $contId]->"status")
:if ($contStatus = "extracting") do={ $abortWithMessage ("container $contComment is extracting, aborting") logPrefix=$logPrefix }
:log info "$($logPrefix)Container $contComment update started"
:local contStarted false
:if ($contStatus != "stopped") do={
:if ($contStatus = "running") do={
:log warn "$($logPrefix)Container $contComment is running, stopping container"
:set contStarted true
stop $contId
}
:local stopTimeoutSec 120
:local sec 0
:while (([get $contId]->"status") != "stopped" && $sec <= $stopTimeoutSec) do={
:delay 1
:set sec ($sec + 1)
}
:if ($sec > $stopTimeoutSec) do={ $abortWithMessage ("container $contComment stop timed out, aborting") logPrefix=$logPrefix }
:log info "$($logPrefix)Container $contComment stopped"
}
:local cont [get $contId]
remove $contId
:delay 5
after ROS upgrade check below if something has changed
------------------------------------------------------
validAddArgs - array of container add command argument names which are named exact as config property names
:local validAddArgs ( "cmd", "comment", "dns", "domain-name", "entrypoint", "envlist", "hostname", "interface", "logging", "mounts", "root-dir", "start-on-boot", "workdir" )
replaceArgs - key-value array for mapping container add command argument name from different config property name, where key is config property name and value is argument name
:local replaceArgs { "tag"="remote-image" }
addCmd - ROS CLI container add command
:local addCmd "/container add"
-----------------------------------------------------
:local escapeStr do={
:local strLen [:len $1]
:local escStr ""
:for i from=0 to=($strLen - 1) do={
:local chr [:pick $1 $i ($i + 1)]
}
:return ""$escStr""
}
:local arrayToStr do={
:local arrLen [:len $1]
:local strArr "("
:for i from=0 to=($arrLen - 1) do={
:local item [:pick $1 $i]
}
:return "$strArr)"
}
:local escapeValue do={
:if ([:typeof $1] = "str") do={ :return [$escapeStr $1] }
:if ([:typeof $1] = "array") do={ :return [$arrayToStr $1 escapeStr=$escapeStr] }
:if ([:typeof $1] = "bool") do={:if ($1) do={ :return "yes" } else={ :return "no" }}
:return $1
}
:foreach k,v in=$cont do={$k=$ ([$escapeValue $v escapeStr=$escapeStr arrayToStr=$arrayToStr])"$rk=$ ([$escapeValue $v escapeStr=$escapeStr arrayToStr=$arrayToStr])" }
:if ([:len $v] != 0) do={
:if ([:find $validAddArgs $k] >= 0) do={
:set addCmd "$addCmd
} else={
:local rk ($replaceArgs->"$k")
:if ([:typeof $rk] != "nothing") do={ :set addCmd "$addCmd
}
}
}
:execute "$addCmd" as-string
:set contId [find where comment=$contComment]
:if ($contId = "") do={ $abortWithMessage ("unable to add container $contComment, check add command: $addCmd") logPrefix=$logPrefix }
rise if not enough (30min) on slow network or device
:local extrTimeoutSec 1800
:local sec 0
:while (([get $contId]->"status") = "extracting" && $sec <= $extrTimeoutSec) do={
:delay 1
:set sec ($sec + 1)
}
:if ($sec > $extrTimeoutSec) do={ $abortWithMessage ("container $contComment extract wait timed out, something is failed or slower than expected") logPrefix=$logPrefix }
:if ($contStarted) do={ start $contId }
:log info "$($logPrefix)Container $contComment update finished"