# ci_job.ps1
# This powershell scrip mimicks ros2/ci ci_job.xml.em
# This script uses a temporary dir
<#
.SYNOPSIS
Generates a ros2 container profiting from the OSRF continuous integration infrastructure. The idea is get updated and
out-of-the-box testing environment for trials.
.DESCRIPTION
The script mimicks the jenkins one provided by the OSRF in the ros2/ci github repo. Basically clones the repo in a
temporary location. Builds the dockerfile with the basic infrastructure required to build ros. Runs a ros2 module
devoted to build and test ros2 that profits from a python virtual environment.
.PARAMETER tagName
This is the name that will be used as base on container and image tag generation. It doesn't need to include os or build config references in it because those would be appended later.
.PARAMETER ubuntuDistro
This may be a valid ubuntu distro name for DockerFile use, for example: bionic or focal.
.PARAMETER ros2RepoUri
This is an uri to the repos file we want to use to download and build ros2. Usually a github raw reference.
.PARAMETER DebugBuild
This flag generates a debug build, that is, binaries keep symbolic data and safeguards.
.PARAMETER pkgsUpTo
This is a list of packages we want to build. In order to build them it's dependencies would be build also. Defaults to ros2run and demo_nodes_cpp.
.PARAMETER OpenContainer
This flag opens the generated container when the script finishes.
.PARAMETER imageName
Name we wish for the generated image.
.EXAMPLE
PS> .\ci_job ros2 focal -DebugBuild fastcdr
PS> .\ci_job ros2 focal fastcdr, fastrtps https://raw.githubusercontent.com/ros2/ros2/crystal/ros2.repos
PS> .\ci_job ros2 focal -pkgsUpTo ('fastcdr', 'fastrtps')
PS> .\ci_job ros2 focal -ros2RepoUri https://raw.githubusercontent.com/ros2/ros2/crystal/ros2.repos
.NOTES
In order to run ros2 examples:
- activate the python virtual environent by doing # . ./venv/bin/activate
- populate the environmental variables by sourcing the colcon script # . ./ws/install/local_setup.bash
#>
Param (
[Parameter(Mandatory=$true)]
[string]
# tagname for this image and container name. Ubuntu distro name will be appended as suffix. If -Debug then _debug will be appended as suffix.
$tagName,
[string]
# ubuntu distro name. Defaults to focal.
$ubuntuDistro = 'focal',
[Switch]
# use the flag -DebugBuild to generate a debug build.
$DebugBuild,
[Switch]
# after sucessfully commit the image open the container
$OpenContainer,
[string[]]
# setting this limits the number of packages build to those specified and its dependencies.
$pkgsUpTo = @("ros2run","demo_nodes_cpp"),
[string]
# ros2 repo uri. Allows to choose ros2 release or specific commit. Defaults to master.
$ros2RepoUri = 'https://raw.githubusercontent.com/ros2/ros2/master/ros2.repos',
[string]
# Generated image name. In order to push to DockerHub must match the user account name.
$imageName = 'miguelbarroeprosima'
)
# compose tag and continer name
$contName = "${tagName}_$ubuntuDistro$(if($DebugBuild) { '_debug' })"
$imageName = "${imageName}/ros2:$contName"
# first clean docker
docker container prune -f
docker container rm $contName
docker image prune -f
docker image rm ros2_batch_ci:$contName
docker image rm $imageName
# generate a temporary ancillary dir if there, we no longer use $PSScriptRoot
$ciroot = New-TemporaryFile
remove-item $ciroot
$ciroot = Join-Path $ciroot.Directory $ciroot.BaseName
mkdir $ciroot
# restore the DockerFile and entry_point script
cd $ciroot
git clone https://github.com/ros2/ci.git
$cachedir = Join-Path $ciroot .ccache
mkdir $cachedir
# determine arguments
# because of docker contrains we cannot use " within the environment variable. The reason is that we are going to pass this as argument to docker as an expression and powershell will surround it with ". Several nested " cannot be handled by docker.
$Env:CI_ARGS="$(if($DebugBuild){ '--cmake-build-type Debug' }) --do-venv --os linux --force-ansi-color --workspace-path /home/jenkins-agent/workspace/ci_linux --test-branch jacob/fix_unused_variabled_warn --ignore-rmw rmw_connext_cpp rmw_fastrtps_dynamic_cpp rmw_opensplice_cpp --repo-file-url $ros2RepoUri --isolated --colcon-mixin-url https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml --build-args --event-handlers console_cohesion+ console_package_list+ $(if($pkgsUpTo.Count -ne 0){ ,'--packages-up-to' + $pkgsUpTo -join ' ' }) --cmake-args -DINSTALL_EXAMPLES=OFF -DSECURITY=ON --test-args --event-handlers console_direct+ --executor sequential --retest-until-pass 2 --ctest-args -N"
# promote the DockerFile to Ubuntu:focal
$DockerFilePath = Join-Path $ciroot ci\linux_docker_resources\Dockerfile
(Get-Content $DockerFilePath) |
% { $_ -replace 'FROM \S+$', "FROM ubuntu:$ubuntuDistro" } |
Set-Content $DockerFilePath
# update the date into Dockerfile
(Get-Content $DockerFilePath) |
% { $_ -replace '@today_str', (Get-Date -Format "yyyy-MM-dd") } |
Set-Content $DockerFilePath
$EntryPointPath = Join-Path $ciroot ci\linux_docker_resources\entry_point.sh
# udpate the base path
(Get-Content $DockerFilePath) |
% { $_ -replace '@workdir', '/home/jenkins-agent/workspace/ci_linux' } |
Set-Content $DockerFilePath
(Get-Content $EntryPointPath) |
% { $_ -replace '@workdir', '/home/jenkins-agent/workspace/ci_linux' } |
Set-Content $EntryPointPath
# we cannot access the rti submodules thus we ignore them
(Get-Content $DockerFilePath) |
% { $_ -replace 'ADD rti', '#ADD rti' } |
Set-Content $DockerFilePath
# let's start by not executing any CMD or ENTRYPOINT but interactively
(Get-Content $DockerFilePath) |
% { $_ -replace '^CMD', '# CMD' } |
% { $_ -replace '^ENTRYPOINT', '# ENTRYPOINT' } |
Set-Content $DockerFilePath
# we will use docker exec to run the script
#Add-Content $DockerFilePath 'CMD python3 -u run_ros2_batch.py $CI_ARGS'
# Build DockerFile
docker build --build-arg UBUNTU_DISTRO=$ubuntuDistro --build-arg ROS1_DISTRO=noetic -t ros2_batch_ci:$contName $(Join-Path $ciroot ci\linux_docker_resources)
# Run the generated image this run builds ros2 on colcon but all sources and binaries end up in the volume mapping not into the
# ros2 container.
# The actual ci call uses a volume for the virtualenv but we cannot do that because the ros2 script creates hard-links
# (--system-site-packages) that cannot be copied between host and docker containers. Instead of using a volume we directly copy
# the gitrepos into the container
# docker network create -o com.docker.network.bridge.enable_icc=false isolated_network_$contName
docker create `
--privileged `
-e UID=1001 `
-e GID=1001 `
-e CCACHE_DIR=/home/rosbuild/.ccache `
-e CI_ARGS=$Env:CI_ARGS `
-i -t `
--name $contName `
ros2_batch_ci:$contName `
/bin/bash
# --net=isolated_network_$contName `
# -v (Join-String -InputObject ((Join-Path $ciroot ci\.ccache),'/home/rosbuild/.ccache') -Separator ':') `
# -v (Join-String -InputObject ((Join-Path $ciroot ci),'/home/jenkins-agent/workspace/ci_linux') -Separator ':') `
# The optimal way of generating an operational ros2 image would be filling all the run steps into the DockerFile but we
# cannot do this without breaking the ros2 ci infraestructure. As explained above we cannot use volumes because symbolic
# links do not travel well through docker boundaries. The next instruction will copy all ancillary files into the docker
docker cp (Join-Path $ciroot ci) ${contName}:/home/jenkins-agent/workspace
# Now we run the container
docker start $contName
# rename the ci workspace
docker exec -t -w /home/jenkins-agent/workspace $contName bash -c 'mv ci/* ci_linux'
# build ros2
docker exec -t $contName bash -c 'python3 -u run_ros2_batch.py $CI_ARGS'
# stop the container
docker stop $contName
# Now commit the container to an image
docker commit --change 'CMD /bin/bash' `
--author "$(whoami)" `
--message "$tagName on ubuntu $ubuntuDistro" $contName $imageName
# we recreate the container
docker container rm --force $contName
docker image rm ros2_batch_ci:$contName
# docker network rm isolated_network_$contName
if($OpenContainer)
{
docker run -ti --name $contName $imageName
}
else
{
docker create -ti --name $contName $imageName /bin/bash
}
# note that once inside the only python available is a virtual environment one. We must activate it running
# source /home/jenkins-agent/workspace/ci_linux/venv/bin/activate
Content type
Image
Digest
Size
1.8 GB
Last updated
over 6 years ago
docker pull miguelbarroeprosima/ros2:ros2_demo_focal