1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
#! /bin/sh
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
# PASST - Plug A Simple Socket Transport
# for qemu/UNIX domain socket mode
#
# PASTA - Pack A Subtle Tap Abstraction
# for network namespace/tap device mode
#
# test/lib/context - Run commands in different contexts (host, guest, namespace etc.)
#
# Copyright Red Hat
# Author: David Gibson <david@gibson.dropbear.id.au>
NSTOOL="${BASEPATH}/nstool"
# context_setup_common() - Create outline of a new context
# $1: Context name
context_setup_common() {
__name="$1"
__log="${LOGDIR}/context_${__name}.log"
echo -n "${__name}$ " > "${__log}"
}
# context_setup_host() - Create a new context for running commands on the host
# $1: Context name
context_setup_host() {
__name="$1"
__enter="${STATESETUP}/context_${__name}.enter"
context_setup_common "${__name}"
echo sh -c > "${__enter}"
}
# context_setup_nstool() - Create a new context for running commands with nstool exec
# $1: Context name
# $2: nstool control socket
context_setup_nstool() {
__name="$1"
__sock="$2"
__enter="${STATESETUP}/context_${__name}.enter"
# Wait for the ns to be ready
${NSTOOL} info -w "${__sock}" > /dev/null
context_setup_common "${__name}"
echo "${NSTOOL} exec ${__sock} -- sh -c" > "${__enter}"
}
# context_setup_guest() - Create a new context for running commands in a guest
# $1: Context name
# $2: CID to use for vsock
context_setup_guest() {
__name="$1"
__cid="$2"
__enter="${STATESETUP}/context_${__name}.enter"
__ssh="${STATESETUP}/context_${__name}.ssh"
context_setup_common "${__name}"
cat > "${__ssh}" <<EOF
Host ${__name}
User root
UserKnownHostsFile ${STATESETUP}/context_${__name}.hosts
StrictHostKeyChecking no
IdentityFile ${BASEPATH}/guest-key
IdentityAgent none
ProxyCommand socat - VSOCK-CONNECT:${__cid}:22
EOF
echo "ssh -F ${__ssh} ${__name}" > "${__enter}"
# Wait for the guest to be booted and accepting connections
wait_for ssh -F "${__ssh}" "${__name}" :
}
# context_teardown() - Remove a context (leave log files intact)
# $1: Context name
context_teardown() {
__name="$1"
__prefix="${STATESETUP}/context_${__name}"
rm -f "${__prefix}.enter" "${__prefix}.ssh" "${__prefix}.hosts"
}
# context_exists() - Test if a context currently exists
# $1: Context name
context_exists() {
__name="$1"
__enter="${STATESETUP}/context_${__name}.enter"
[ -f "${__enter}" ]
}
# context_run() - Run a shell command in a context, and wait for it to finish
# $1: Context name
# $*: Command to start
context_run() {
__name="$1"
__log="${LOGDIR}/context_${__name}.log"
__enter="${STATESETUP}/context_${__name}.enter"
__stdout="$(mktemp -u "${STATESETUP}/context_${__name}.stdout.XXXXXXXX")"
__stderr="$(mktemp -u "${STATESETUP}/context_${__name}.stderr.XXXXXXXX")"
shift
echo "$*" >> "${__log}"
mkfifo "${__stdout}" "${__stderr}"
tee -a "${__log}" < "${__stdout}" &
tee -a "${__log}" < "${__stderr}" >&2 &
$(cat ${__enter}) "$*" >> "${__stdout}" 2>> "${__stderr}"
rc=$?
rm "${__stdout}" "${__stderr}"
[ ${DEBUG} -eq 1 ] && echo "[Exit code: $rc]" >> "${__log}"
echo -n "${__name}$ " >> "${__log}"
return $rc
}
# context_run_bg() - Start a shell command in a context
# $1: Context name
# $*: Command to start
context_run_bg() {
__name="$1"
__pidfile="${STATESETUP}/context_${__name}.pid"
context_run "$@" &
echo $! > "${__pidfile}"
}
# context_wait() - Wait for background command in a context to complete
# $1: Context name
# Returns the status of the completed command
context_wait() {
__name="$1"
__pidfile="${STATESETUP}/context_${__name}.pid"
__pid=$(cat "${__pidfile}")
rm "${__pidfile}"
wait ${__pid}
}
|