Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ DOCKER_PREFIX := ${LIB_NAME}
DOCKER_TAG := ${DOCKER_PREFIX}-yocto-builder
DOCKER_SUSE_TAG := ${DOCKER_PREFIX}-open-suse-env
DOCKER_PYTHON_TAG := ${DOCKER_PREFIX}-analyzer
DOCKER_YOCTO_VM_TAG := ${DOCKER_PREFIX}-yocto-vm
DOCKER_SUSE_VM_TAG := ${DOCKER_PREFIX}-suse-vm
DOCKER_BUILD_VOLUME := ${DOCKER_PREFIX}-yocto-build
DOCKER_DOWNLOADS_VOLUME := ${DOCKER_PREFIX}-yocto-downloads
DOCKER_SSTATE_VOLUME := ${DOCKER_PREFIX}-yocto-sstate
Expand Down
3 changes: 3 additions & 0 deletions conf/packages.conf
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ IMAGE_INSTALL:append = " \
jq \
json-c \
kbd \
kernel-devsrc \
kmod \
ldconfig \
less \
Expand Down Expand Up @@ -92,6 +93,7 @@ IMAGE_INSTALL:append = " \
libusb1 \
libxcrypt \
libxml2 \
linux-libc-headers \
libyaml \
logrotate \
lshw \
Expand Down Expand Up @@ -140,6 +142,7 @@ IMAGE_INSTALL:append = " \
python3-setuptools \
readline \
rpm \
ruby \
rsync \
rsyslog \
screen \
Expand Down
51 changes: 48 additions & 3 deletions docker/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,34 @@ services:
BUILD_DIR: ${BUILD_DIR}
POKY_DIR: ${POKY_DIR}
OS_IMAGE: ${OS_IMAGE}
VM_RAM: ${QEMU_VM_RAM}
USER: ${USER}
GROUP: ${GROUP}

imgtests-yocto-vm:
build:
dockerfile: docker/vm-yocto.dockerfile
args:
USER: ${USER}
GROUP: ${GROUP}
PASSWORD: ${PASSWORD}
POKY_DIR: ${POKY_DIR}
image: ${DOCKER_YOCTO_VM_TAG}
privileged: true
devices:
- /dev/kvm
volumes:
- ${DOCKER_BUILD_VOLUME}:${BUILD_DIR}
- ${DOCKER_DOWNLOADS_VOLUME}:${POKY_DIR}/downloads
- ${DOCKER_SSTATE_VOLUME}:${POKY_DIR}/sstate-cache
- ${HOST_CONF_PATH}/local.conf:${BUILD_DIR}/conf/local.conf
- ${HOST_CONF_PATH}/packages.conf:${BUILD_DIR}/conf/packages.conf
- ${HOST_CONF_PATH}/added_packages.conf:${BUILD_DIR}/conf/added_packages.conf
- ${HOST_LAYERS_PATH}/meta-image-tests:${POKY_DIR}/meta-image-tests
- ${HOST_SCRIPTS_PATH}/add-layers.sh:${POKY_DIR}/add-layers.sh
environment:
BUILD_DIR: ${BUILD_DIR}
POKY_DIR: ${POKY_DIR}
OS_IMAGE: ${OS_IMAGE}
CPUS: ${CPUS}
USER: ${USER}
GROUP: ${GROUP}
Expand All @@ -37,6 +64,9 @@ services:
networks:
yocto-network:
ipv4_address: ${YOCTO_ADDRESS}
depends_on:
imgtests-yocto:
condition: service_completed_successfully

imgtests-suse-156:
build:
Expand All @@ -51,13 +81,28 @@ services:
environment:
S_USER: ${S_USER}
PASSWORD: ${PASSWORD}
VM_RAM: ${QEMU_VM_RAM}
CPUS: ${CPUS}
networks:
- yocto-network

imgtests-suse-vm:
build:
dockerfile: docker/vm-suse.dockerfile
args:
USER: ${USER}
image: ${DOCKER_SUSE_VM_TAG}
privileged: true
devices:
- /dev/kvm
volumes:
- ${DOCKER_OPENSUSE_VOLUME}:${SUSE_DIR}
environment:
SSH_QEMU_PORT: ${SSH_TO_QEMU_PORT}
SSH_SUSE_PORT: ${SSH_SUSE_PORT_156}
SUSE_NE_PORT: ${SUSE_156_NE_PORT}
DEFAULT_NE_PORT: ${DEFAULT_NE_PORT}
IPERF3_PORT: ${IPERF3_PORT}
VM_RAM: ${QEMU_VM_RAM}
CPUS: ${CPUS}
ports:
- ${SSH_SUSE_PORT_156}:${SSH_SUSE_PORT_156}
networks:
Expand Down
6 changes: 4 additions & 2 deletions docker/image_builder.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ RUN groupadd -g 510 ${GROUP} && \
echo "${USER}:${PASSWORD}" | chpasswd

USER ${USER}

RUN mkdir --parents ${POKY_DIR} && \
git clone --depth 1 -b walnascar --recurse-submodules https://git.yoctoproject.org/poky ${POKY_DIR}

WORKDIR ${POKY_DIR}

COPY --chown=${USER}:${GROUP} layers ${POKY_DIR}
COPY --chown=${USER}:${GROUP} scripts/entrypoint.sh ${POKY_DIR}/
COPY --chown=${USER}:${GROUP} scripts/cmd_yocto.sh ${POKY_DIR}/
COPY --chown=${USER}:${GROUP} scripts/entrypoint.sh ${POKY_DIR}
COPY --chown=${USER}:${GROUP} scripts/cmd_yocto.sh ${POKY_DIR}

ENTRYPOINT ["/home/user/poky/entrypoint.sh"]
3 changes: 0 additions & 3 deletions docker/open-suse.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ ENV DEBIAN_FRONTEND=noninteractive \

RUN apt-get update && \
apt-get install -y --no-install-recommends \
qemu-system \
qemu-utils \
qemu-user-static \
cloud-init \
cloud-image-utils \
wget \
Expand Down
19 changes: 19 additions & 0 deletions docker/vm-suse.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM ubuntu:24.04

ARG USER

ENV DEBIAN_FRONTEND=noninteractive \
SUSE_DIR=/home/${USER}/suse

RUN apt-get update && \
apt-get install -y --no-install-recommends \
qemu-system \
qemu-utils \
qemu-user-static

WORKDIR ${SUSE_DIR}

COPY scripts/opensuse/start-vm.sh /start-vm.sh
RUN chmod +x /start-vm.sh

ENTRYPOINT ["/start-vm.sh"]
38 changes: 38 additions & 0 deletions docker/vm-yocto.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
FROM ubuntu:22.04

ARG USER
ARG GROUP
ARG PASSWORD
ARG POKY_DIR

ENV DEBIAN_FRONTEND=noninteractive \
LANG=en_US.UTF-8

RUN apt-get update && \
apt-get install -y --no-install-recommends \
sudo wget git locales chrpath cpio diffstat gawk \
zstd liblz4-tool python3 python3-pip tar gcc make \
bzip2 file g++ patch python3-pexpect python3-git \
python3-jinja2 python3-subunit screen \
libtirpc-dev libtirpc3 pkg-config \
qemu qemu-system-x86 qemu-utils \
openssh-server && \
rm -rf /var/lib/apt/lists/* && \
locale-gen en_US.UTF-8

RUN groupadd -g 510 ${GROUP} && \
groupadd -g 993 kvm && \
useradd -rm -d /home/${USER} -s /bin/bash -g ${GROUP} -u 1010 -G sudo,kvm ${USER} && \
echo "${USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/${USER} && \
echo "${USER}:${PASSWORD}" | chpasswd

USER ${USER}

RUN git clone --depth 1 -b walnascar --recurse-submodules https://git.yoctoproject.org/poky ${POKY_DIR}

WORKDIR ${POKY_DIR}

COPY --chown=${USER}:${GROUP} layers ${POKY_DIR}
COPY --chown=${USER}:${GROUP} scripts/start-vm-yocto.sh ${POKY_DIR}

ENTRYPOINT ["/home/user/poky/start-vm-yocto.sh"]
15 changes: 15 additions & 0 deletions docs/methodology/failure_emulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@
* Проводить различные манипуляции с сетевыми пакетами, в т.ч. вызывать потерю пакетов, дублировать их, повреждать, блокировать;
* Делать порт недоступным;
* Вносить изменения в работу DNS.
* Пример создания сетевой задержки 100 мс на интерфейсе `eth0` (реализован в `scripts/fault-injection/chaosblade_vm.sh`):
```
# Создать эксперимент: задержка 100 мс, автоматическое завершение через 30 с
sudo blade create network delay --time 100 --interface eth0 --timeout 30

# Проверить статус и, при необходимости, завершить вручную
sudo blade status <experiment-id>
sudo blade destroy <experiment-id>
```
- [tc](https://man7.org/linux/man-pages/man8/tc.8.html) - утилита для управления трафиком. Для эмуляции сетевых сбоев используется `tc netem`. Как и `chaosblade` позволяет создавать задержки, потери, дубликации, неправильный порядок пакетов. Пример: добавление задержки 100 мс: ```sudo tc qdisc add dev eth0 root netem delay 100ms```

### Диски и файловые системы
Expand All @@ -32,6 +41,9 @@
+ ```# krfctl -p 100``` - установить вероятность ошибки равной 1%
+ ```# krfctl -P io``` - для указания группы системных вызовов, которые должны завершаться с ошибкой (в данном случае, все, связанные с вводом/выводом)
+ ```$ krfexec <command> [args]``` - для запуска программы через `krfexec`

Пример использования `krf` реализован в `scripts/fault-injection/krf_vm.sh`

- [epbfault](https://github.com/trailofbits/ebpfault) - утилита для внедрения ошибок в системные вызовы, работающая на основе eBPF. Удобна в использовании, так как позволяет задать в конфигурационном файле системные вызовы, в которых будет симулироваться ошибка, вощвращаемое значение и вероятность возврата этого значения. Пример конфигурационного файла:
```
{
Expand Down Expand Up @@ -68,6 +80,9 @@

Использование:
```ebpfault --config /path/to/config.json --exec /path/to/program arg1 arg2```

Пример использования `ebpfault` реализован в `scripts/fault-injection/ebpfault_vm.sh`

- Аналогично `ebpfault` можно писать свои тесты с использованием `kprobes` и `bpf`. Для этого подходит функция `bpf_override_return()`, позволяющая перезаписывать код возврата функций.

Кроме того, некоторые рассмотренные инструменты, можно использовать и для других целей. Так, chaosblade можно также использовать для эмуляции сбоев файловой подсистемы, процессора, дисков.
Expand Down
7 changes: 7 additions & 0 deletions docs/utilities/benchmarking/general/chaosblade.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,10 @@ blade status --type create --flag-filter "timeout=10"
]
}
```

6. Создать эксперимент с сетевой задержкой. Например, 100 мс на интерфейсе `eth0` с автоматическим завершением через 30 секунд:
```
blade create network delay --time 100 --interface eth0 --timeout 30
```

Задержку можно комбинировать с другими параметрами: `--offset` (jitter в мс), `--destination-ip`, `--exclude-ip`. Получение статуса и завершение эксперимента выполняются командами `blade status <experiment-id>` и `blade destroy <experiment-id>`. Реализация примера есть в скриптах `scripts/fault-injection/chaosblade.sh` и `scripts/fault-injection/chaosblade_vm.sh`.
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAIL_IO_TIMEOUT=y
CONFIG_FAIL_FUTEX=y
CONFIG_BPF_KPROBE_OVERRIDE=y
4 changes: 0 additions & 4 deletions scripts/cmd_yocto.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,3 @@ set -e
cd "${POKY_DIR}"
./add-layers.sh
bitbake "${OS_IMAGE}"
ROOTFS_IMAGE="${POKY_DIR}/build/tmp/deploy/images/qemux86-64/${OS_IMAGE}-qemux86-64.rootfs.ext4.qcow2"

QB_SLIRP_OPT="-netdev user,id=net0,hostfwd=tcp::8080-:80,hostfwd=tcp::${SSH_QEMU_PORT}-:${SSH_TO_QEMU_PORT},hostfwd=tcp::${YOCTO_NE_PORT}-:${DEFAULT_NE_PORT},hostfwd=tcp:0.0.0.0:${IPERF3_PORT}-:${IPERF3_PORT},hostfwd=udp:0.0.0.0:${IPERF3_PORT}-:${IPERF3_PORT}" \
runqemu qemux86-64 slirp nographic "${ROOTFS_IMAGE}" qemuparams="-monitor tcp:0.0.0.0:4444,server,nowait -smp ${CPUS}"
85 changes: 85 additions & 0 deletions scripts/fault-injection/chaosblade.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/bin/bash

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

source "${SCRIPT_DIR}/common.sh"

CHAOSBLADE_VERSION="${CHAOSBLADE_VERSION:-1.8.0}"
CPU_PERCENT="${CHAOSBLADE_CPU_PERCENT:-20}"
TIMEOUT="${CHAOSBLADE_TIMEOUT_SEC:-30}"
NET_DELAY_MS="${CHAOSBLADE_NETWORK_DELAY_MS:-}"
INTERFACE="${CHAOSBLADE_INTERFACE:-eth0}"

IDS=()

cleanup() {
local id
for id in "${IDS[@]}"; do
run "$id" <<<"sudo /opt/chaosblade/blade destroy $id" || warn "Failed to destroy $id"
done
}
trap cleanup EXIT

install_chao() {
has blade && { info "chaosblade already installed on ${TARGET}"; return; }
[[ "$TARGET" == yocto ]] && die "not installed on ${TARGET}; add the chaosblade to the poky image"
info "Installing chaosblade v${CHAOSBLADE_VERSION} on ${TARGET}..."
run "$CHAOSBLADE_VERSION" <<'EOF' || die "Failed to install chaosblade"
set -euo pipefail
v=$1
d=$(mktemp -d)
trap 'rm -rf "$d"' EXIT
cd "$d"
sudo zypper -n install --no-recommends wget tar
wget -q "https://github.com/chaosblade-io/chaosblade/releases/download/v${v}/chaosblade-${v}-linux_amd64.tar.gz"
tar -xzf "chaosblade-${v}-linux_amd64.tar.gz"
mkdir -p /opt/chaosblade
cp -r "chaosblade-${v}-linux_amd64"/. /opt/chaosblade/
chmod 755 /opt/chaosblade/blade
ln -sf /opt/chaosblade/blade /usr/local/bin/blade
EOF
}

create_exp() {
local out id
out=$(run "$@" <<'EOF'
set -euo pipefail
sudo /opt/chaosblade/blade check os "$1" "$2" > /dev/null 2>&1 || true
sudo /opt/chaosblade/blade create "$1" "$2" "${@:3}"
EOF
) || return 1
id=$(printf '%s\n' "$out" | grep -o '"result":"[^"]*"' | head -1 | sed 's/"result":"\([^"]*\)"/\1/') || return 1
[[ -n "$id" ]] || return 1
printf '%s' "$id"
}

show() { run "$1" <<<'sudo /opt/chaosblade/blade status "$1"'; }
destroy() { run "$1" <<<"sudo /opt/chaosblade/blade destroy $1" || warn "Failed to destroy $1"; }

main() {
install_chao

cpu=$(create_exp cpu fullload --cpu-percent "$CPU_PERCENT" --timeout "$TIMEOUT") ||
die "Failed to create CPU experiment"
IDS+=("$cpu")
show "$cpu"
info "Running CPU experiment for 5s..."
sleep 5

if [[ -n "$NET_DELAY_MS" ]]; then
if net=$(create_exp network delay --time "$NET_DELAY_MS" --interface "$INTERFACE" --timeout "$TIMEOUT"); then
IDS+=("$net")
show "$net"
info "Running network experiment for 5s..."
sleep 5
destroy "$net"
else
warn "Skipping network experiment"
fi
fi

destroy "$cpu"
show "$cpu"
info "Done."
}
main "$@"
Loading
Loading