2017-10-05 20:38:24 +03:00
|
|
|
#!/bin/bash
|
2020-09-17 17:05:33 +00:00
|
|
|
|
2017-10-05 20:38:24 +03:00
|
|
|
set -x -e -o pipefail
|
|
|
|
|
2020-08-14 08:37:25 +00:00
|
|
|
./apt-install \
|
2017-10-05 20:38:24 +03:00
|
|
|
apt-transport-https \
|
|
|
|
ca-certificates \
|
|
|
|
curl \
|
|
|
|
software-properties-common
|
|
|
|
|
|
|
|
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
|
|
|
|
|
|
|
|
add-apt-repository \
|
|
|
|
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
|
|
|
|
$(lsb_release -cs) \
|
2019-01-01 23:06:38 -08:00
|
|
|
stable test"
|
2017-10-05 20:38:24 +03:00
|
|
|
|
2020-08-14 08:37:25 +00:00
|
|
|
./apt-install docker-ce
|
2017-10-05 20:38:24 +03:00
|
|
|
|
2022-04-12 16:40:31 -07:00
|
|
|
# shellcheck source=/dev/null
|
2019-12-20 17:50:37 +01:00
|
|
|
. /etc/lsb-release
|
|
|
|
|
2022-08-05 22:00:16 +01:00
|
|
|
# docker checkpoint and restore is an experimental feature
|
2022-08-05 21:44:11 +01:00
|
|
|
echo '{ "experimental": true }' > /etc/docker/daemon.json
|
2022-08-05 22:00:16 +01:00
|
|
|
service docker restart
|
2017-10-05 20:38:24 +03:00
|
|
|
|
2021-02-03 23:48:26 +00:00
|
|
|
CRIU_LOG='/criu.log'
|
|
|
|
mkdir -p /etc/criu
|
|
|
|
echo "log-file=$CRIU_LOG" > /etc/criu/runc.conf
|
|
|
|
|
2020-11-03 10:18:02 +00:00
|
|
|
export SKIP_CI_TEST=1
|
2017-10-05 20:38:24 +03:00
|
|
|
|
2020-11-03 10:18:02 +00:00
|
|
|
./run-ci-tests.sh
|
2017-10-05 20:38:24 +03:00
|
|
|
|
|
|
|
cd ../../
|
|
|
|
|
2017-10-05 23:17:05 +03:00
|
|
|
make install
|
2017-10-05 20:38:24 +03:00
|
|
|
|
|
|
|
docker info
|
|
|
|
|
|
|
|
criu --version
|
|
|
|
|
2021-07-30 07:24:13 +01:00
|
|
|
run_container () {
|
|
|
|
docker run \
|
|
|
|
--tmpfs /tmp \
|
|
|
|
--tmpfs /run \
|
|
|
|
--read-only \
|
|
|
|
--name cr \
|
|
|
|
--health-cmd='sleep 1' \
|
|
|
|
--health-interval=1s \
|
|
|
|
-d \
|
|
|
|
alpine \
|
|
|
|
/bin/sh -c 'i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done'
|
|
|
|
}
|
|
|
|
|
|
|
|
wait_running () {
|
|
|
|
until [ "$(docker inspect -f '{{.State.Running}}' cr)" = "true" ]; do
|
|
|
|
sleep 1;
|
|
|
|
done;
|
|
|
|
}
|
|
|
|
|
|
|
|
wait_healthy () {
|
|
|
|
until [ "$(docker inspect -f '{{.State.Health.Status}}' cr)" = "healthy" ]; do
|
|
|
|
sleep 1;
|
|
|
|
done;
|
|
|
|
}
|
|
|
|
|
|
|
|
checkpoint_container () {
|
|
|
|
CHECKPOINT_NAME=$1
|
|
|
|
|
|
|
|
docker checkpoint create cr "$CHECKPOINT_NAME" &&
|
|
|
|
(docker exec cr true >> /dev/null 2>&1 && exit 1 || exit 0) &&
|
|
|
|
# wait for container to stop
|
|
|
|
docker wait cr
|
|
|
|
}
|
|
|
|
|
2022-08-11 09:51:34 +01:00
|
|
|
print_logs () {
|
2020-09-17 17:05:33 +00:00
|
|
|
cat "$(grep log 'log file:' | sed 's/log file:\s*//')" || true
|
2017-10-05 20:38:24 +03:00
|
|
|
docker logs cr || true
|
2021-02-03 23:48:26 +00:00
|
|
|
cat $CRIU_LOG || true
|
2017-10-05 20:38:24 +03:00
|
|
|
dmesg
|
|
|
|
docker ps
|
|
|
|
exit 1
|
2022-08-11 09:51:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
declare -i max_restore_container_tries=3
|
|
|
|
current_iteration=
|
|
|
|
|
|
|
|
restore_container () {
|
|
|
|
CHECKPOINT_NAME=$1
|
|
|
|
|
|
|
|
docker start --checkpoint "$CHECKPOINT_NAME" cr 2>&1 | tee log || {
|
|
|
|
# FIXME: There is a race condition in docker/containerd that causes
|
|
|
|
# docker to occasionally fail when starting a container from a
|
|
|
|
# checkpoint immediately after the checkpoint has been created.
|
|
|
|
# https://github.com/moby/moby/issues/42900
|
|
|
|
if [ "$current_iteration" -gt "$max_restore_container_tries" ]; then
|
|
|
|
print_logs
|
|
|
|
fi
|
|
|
|
grep -Eq '^Error response from daemon: failed to upload checkpoint to containerd: commit failed: content sha256:.*: already exists$' log && {
|
|
|
|
((current_iteration+=1))
|
|
|
|
echo "Retry container restore: $current_iteration"
|
|
|
|
sleep 1;
|
|
|
|
restore_container "$CHECKPOINT_NAME"
|
|
|
|
} ||
|
|
|
|
print_logs
|
|
|
|
} && current_iteration=0
|
2021-07-30 07:24:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Scenario: Create multiple containers and checkpoint and restore them once
|
|
|
|
for i in $(seq 10); do
|
|
|
|
run_container
|
|
|
|
wait_running
|
|
|
|
|
|
|
|
docker ps
|
|
|
|
checkpoint_container checkpoint
|
|
|
|
|
|
|
|
docker ps
|
|
|
|
restore_container checkpoint
|
|
|
|
|
2017-10-05 20:38:24 +03:00
|
|
|
docker ps
|
2021-07-30 07:24:13 +01:00
|
|
|
docker rm -f cr
|
2017-10-05 20:38:24 +03:00
|
|
|
done
|
|
|
|
|
2021-07-30 07:24:13 +01:00
|
|
|
# Scenario: Create container and checkpoint and restore it multiple times
|
|
|
|
run_container
|
|
|
|
wait_running
|
|
|
|
|
|
|
|
for i in $(seq 5); do
|
|
|
|
docker ps
|
|
|
|
checkpoint_container checkpoint"${i}"
|
|
|
|
|
|
|
|
docker ps
|
|
|
|
restore_container checkpoint"${i}"
|
|
|
|
|
|
|
|
# Wait for healthy state before creating another checkpoint
|
|
|
|
wait_healthy
|
|
|
|
done
|