github.com/kata-containers/tests@v0.0.0-20240307153542-772105b56064/integration/containerd/runk/runk-tests.sh (about)

     1  #!/bin/bash
     2  #
     3  # Copyright (c) 2022 Kata Contributors
     4  #
     5  # SPDX-License-Identifier: Apache-2.0
     6  #
     7  # This test will validate runk with containerd
     8  
     9  set -o errexit
    10  set -o nounset
    11  set -o pipefail
    12  set -o errtrace
    13  
    14  dir_path=$(dirname "$0")
    15  source /etc/os-release || source /usr/lib/os-release
    16  source "${dir_path}/../../../lib/common.bash"
    17  source "${dir_path}/../../../.ci/lib.sh"
    18  source "${dir_path}/../../../metrics/lib/common.bash"
    19  
    20  KATACONTAINERS_REPO=${katacontainers_repo:="github.com/kata-containers/kata-containers"}
    21  RUNK_SRC_PATH="${GOPATH}/src/${KATACONTAINERS_REPO}/src/tools/runk"
    22  RUNK_BIN_PATH="/usr/local/bin/runk"
    23  TEST_IMAGE="docker.io/library/busybox:latest"
    24  CONTAINER_ID="id1"
    25  PID_FILE="${CONTAINER_ID}.pid"
    26  WORK_DIR="$(mktemp -d --tmpdir runk.XXXXX)"
    27  
    28  setup() {
    29      # can't find cargo when make runk below, so we install rust to make runk build correctly
    30      "${dir_path}/../../../.ci/install_rust.sh" && source "$HOME/.cargo/env"
    31      echo "restart containerd service"
    32      sudo systemctl restart containerd
    33      echo "pull container image"
    34      check_images ${TEST_IMAGE}
    35  }
    36  
    37  install_runk() {
    38      echo "Install runk"
    39      pushd ${RUNK_SRC_PATH}
    40      make
    41      sudo make install
    42      popd
    43  }
    44  
    45  test_runk() {
    46      echo "start container with runk"
    47      # Bind mount ${WORK_DIR}:/tmp. Tests below will store files in this dir and check them when container is frozon.
    48      sudo ctr run --pid-file ${PID_FILE} --rm -d --runc-binary ${RUNK_BIN_PATH} --mount type=bind,src=${WORK_DIR},dst=/tmp,options=rbind:rw ${TEST_IMAGE} ${CONTAINER_ID}
    49      read CID PID STATUS <<< $(sudo ctr t ls | grep ${CONTAINER_ID})
    50      [ ${PID} == $(cat ${PID_FILE}) ] || die "pid is not consistent"
    51      [ ${STATUS} == "RUNNING" ] || die "container status is not RUNNING"
    52  
    53      echo "exec process in a container"
    54      sudo ctr t exec --exec-id id1 ${CONTAINER_ID} sh -c "echo hello > /tmp/foo"
    55      [ "hello" == "$(sudo ctr t exec --exec-id id1 ${CONTAINER_ID} cat /tmp/foo)" ] || die "exec process failed"
    56  
    57      echo "test ps command"
    58      sudo ctr t exec --detach --exec-id id1 ${CONTAINER_ID} sh
    59      # one line is the titles, and the other 2 lines are porcess info
    60      [ "3" == "$(sudo ctr t ps ${CONTAINER_ID} | wc -l)" ] || die "ps command failed"
    61  
    62      echo "test pause and resume"
    63      # The process outputs lines into /tmp/{CONTAINER_ID}, which can be read in host when it's frozon.
    64      sudo ctr t exec --detach --exec-id id2 ${CONTAINER_ID} sh -c "while true; do echo hello >> /tmp/${CONTAINER_ID}; sleep 0.1; done"
    65      # sleep for 1s to make sure the process outputs some lines
    66      sleep 1
    67      sudo ctr t pause ${CONTAINER_ID}
    68      [ "PAUSED" == "$(sudo ctr t ls | grep ${CONTAINER_ID} | grep -o PAUSED)" ] || die "status is not PAUSED"
    69      echo "container is paused"
    70      local TMP_FILE="${WORK_DIR}/${CONTAINER_ID}"
    71      local lines1=$(cat ${TMP_FILE} | wc -l)
    72      # sleep for a while and check the lines are not changed.
    73      sleep 1
    74      local lines2=$(cat ${TMP_FILE} | wc -l)
    75      [ ${lines1} == ${lines2} ] || die "paused container is still running"
    76      sudo ctr t resume ${CONTAINER_ID}
    77      [ "RUNNING" == "$(sudo ctr t ls | grep ${CONTAINER_ID} | grep -o RUNNING)" ] || die "status is not RUNNING"
    78      echo "container is resumed"
    79      # sleep for a while and check the lines are changed.
    80      sleep 1
    81      local lines3=$(cat ${TMP_FILE} | wc -l)
    82      [ ${lines2} -lt ${lines3} ] || die "resumed container is not running"
    83  
    84      echo "kill the container and poll until it is stopped"
    85      sudo ctr t kill --signal SIGKILL --all ${CONTAINER_ID}
    86      # poll for a while until the task receives signal and exit
    87      local cmd='[ "STOPPED" == "$(sudo ctr t ls | grep ${CONTAINER_ID} | awk "{print \$3}")" ]'
    88      waitForProcess 10 1 "${cmd}" || die "failed to kill task"
    89  
    90      echo "check the container is stopped"
    91      # there is only title line of ps command
    92      [ "1" == "$(sudo ctr t ps ${CONTAINER_ID} | wc -l)" ] || die "kill command failed"
    93  
    94      # High-level container runtimes such as containerd call the kill command with
    95      # --all option in order to terminate all processes inside the container
    96      # even if the container already is stopped. Hence, a low-level runtime
    97      # should allow kill --all regardless of the container state like runc.
    98      echo "test kill --all is allowed regardless of the container state"
    99      sudo ctr t kill --signal SIGKILL ${CONTAINER_ID} && die "kill should fail"
   100      sudo ctr t kill --signal SIGKILL --all ${CONTAINER_ID} || die "kill --all should not fail"
   101  
   102      echo "delete the container"
   103      sudo ctr t rm ${CONTAINER_ID} || die "failed to delete task"
   104      [ -z "$(sudo ctr t ls | grep ${CONTAINER_ID})" ] || die "failed to delete task"
   105      sudo ctr c rm ${CONTAINER_ID} || die "failed to delete container"
   106  }
   107  
   108  clean_up() {
   109      rm -f ${PID_FILE}
   110      rm -rf ${WORK_DIR}
   111  }
   112  
   113  setup
   114  install_runk
   115  test_runk
   116  clean_up