mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-15 12:34:55 +00:00
84ede1c380
- If ".git/nm-in-container-host" exists, bind mount all of "/" to "/Host". - also honor all ".git/nm-data-link-*" files for additional directories to bind mount. - as before, honor ".git/NetworkManager-ci" symlink. Note that directories also get symlinked from "/". Like "/NetworkManager-ci" which symlinks links to the bind mount location.
521 lines
13 KiB
Bash
Executable file
521 lines
13 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
set -e
|
|
|
|
###############################################################################
|
|
# Script to create a podman container for testing NetworkManager.
|
|
#
|
|
# Commands:
|
|
# - build: build a new image, named "$CONTAINER_NAME_REPOSITORY:$CONTAINER_NAME_TAG" ("nm:nm").
|
|
# - run: start the container and tag it "$CONTAINER_NAME_NAME" ("nm").
|
|
# - exec: run bash inside the container (this is the default).
|
|
# - journal|j: print the journal from inside the container.
|
|
# - stop: stop the container.
|
|
# - reset: stop and delete the container.
|
|
# - clean: stop and delete the container and the image.
|
|
#
|
|
# Options:
|
|
# --no-cleanup: don't delete the CONTAINERFILE and other artifacts
|
|
# --stop: only has effect with "run". It will stop the container afterwards.
|
|
# -- [EXTRA_ARGS]:
|
|
# - with command "exec", provide a command and arguments to run in the container.
|
|
# Defaults to "bash".
|
|
# - with command "journal", additional arguments that are passed to journalctl.
|
|
#
|
|
# It bind mounts the current working directory inside the container.
|
|
# You can run `make install` and run tests.
|
|
# There is a script nm-env-prepare.sh to generate a net1 interface for testing.
|
|
#
|
|
# This will bind-mount the NetworkManager working tree inside the container (and symlink
|
|
# from /NetworkManager). Create a file ".git/nm-in-container-host" to bind mount the host's
|
|
# "/" to "/Host".
|
|
#
|
|
# Create a symlink ./.git/NetworkManager-ci, to also bind-mount the CI directory.
|
|
# Create additional symlinks ./.git/nm-guest-link-*, to bind mount additional
|
|
# directories.
|
|
#
|
|
# Currently NM-ci requires a working eth1.
|
|
# Hence call `nm-env-prepare.sh --prefix eth -i 1 && sleep 1 && nmcli device connect eth1` before
|
|
# running a CI test.
|
|
###############################################################################
|
|
|
|
if [ -z "$BASE_IMAGE" ]; then
|
|
if grep -q "^ID=fedora$" /etc/os-release 2>/dev/null ; then
|
|
BASE_IMAGE="$(sed -n 's/^VERSION_ID=\([0-9]\+\)$/fedora:\1/p' /etc/os-release)"
|
|
fi
|
|
fi
|
|
if [ -z "$BASE_IMAGE" ]; then
|
|
BASE_IMAGE=fedora:latest
|
|
fi
|
|
|
|
BASEDIR_NM="$(readlink -f "$(dirname "$(readlink -f "$0")")/..")"
|
|
BASEDIR_DATA="$BASEDIR_NM/tools/nm-guest-data"
|
|
|
|
SYMLINK_NAME=()
|
|
SYMLINK_TARGET=()
|
|
for d in $(ls -1d "$BASEDIR_NM/.git/NetworkManager-ci" "$BASEDIR_NM/.git/nm-guest-link-"* 2>/dev/null) ; do
|
|
NAME="${d##*/}"
|
|
NAME="${NAME##nm-guest-link-}"
|
|
TARGET="$(readlink -f "$d")"
|
|
test -e "$TARGET"
|
|
SYMLINK_NAME+=("$NAME")
|
|
SYMLINK_TARGET+=("$TARGET")
|
|
done
|
|
|
|
CONTAINER_NAME_REPOSITORY=${CONTAINER_NAME_REPOSITORY:-nm}
|
|
CONTAINER_NAME_TAG=${CONTAINER_NAME_TAG:-nm}
|
|
CONTAINER_NAME_NAME=${CONTAINER_NAME_NAME:-nm}
|
|
|
|
EXEC_ENV=()
|
|
|
|
###############################################################################
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
$0: build|run|exec|stop|reset|reexec|clean|journal [--no-cleanup] [--stop] [-- EXTRA_ARGS]
|
|
EOF
|
|
echo
|
|
awk '/^####*$/{ if(on) exit; on=1} { if (on) { if (on==2) print(substr($0,3)); on=2; } }' "$BASH_SOURCE"
|
|
echo
|
|
}
|
|
|
|
###############################################################################
|
|
|
|
die() {
|
|
(
|
|
echo -n -e "\033[31m"
|
|
printf "%s" "$*"
|
|
echo -e "\033[0m"
|
|
) >&2
|
|
exit 1
|
|
}
|
|
|
|
###############################################################################
|
|
|
|
CLEANUP_FILES=()
|
|
DO_CLEANUP=1
|
|
cleanup() {
|
|
test "$DO_CLEANUP" = 1 || return 0
|
|
for f in "${CLEANUP_FILES[@]}" ; do
|
|
rm -rf "$f"
|
|
done
|
|
}
|
|
|
|
trap cleanup EXIT
|
|
|
|
###############################################################################
|
|
|
|
tmp_file() {
|
|
cat > "$1"
|
|
CLEANUP_FILES+=( "$1" )
|
|
test -z "$2" || chmod "$2" "$1"
|
|
}
|
|
|
|
gen_file() {
|
|
local PERMS
|
|
[[ $1 =~ bin-* ]] && PERMS=755 || PERMS=644
|
|
sed "s|{{BASEDIR_NM}}|$BASEDIR_NM|g" "$BASEDIR_DATA/$1.in" \
|
|
| tmp_file "$BASEDIR_DATA/data-$1" $PERMS
|
|
}
|
|
|
|
bind_files() {
|
|
VARIABLE_NAME="$1"
|
|
|
|
ARR=()
|
|
H=~
|
|
|
|
ARR+=( -v "$BASEDIR_NM:$BASEDIR_NM" )
|
|
|
|
if [ -e "$BASEDIR_NM/.git/nm-in-container-host" ] ; then
|
|
ARR+=( -v /:/Host )
|
|
fi
|
|
|
|
for i in $(seq 1 ${#SYMLINK_TARGET[@]}) ; do
|
|
j=$((i - 1))
|
|
ARR+=( -v "${SYMLINK_TARGET[$j]}:${SYMLINK_TARGET[$j]}" )
|
|
done
|
|
|
|
for f in ~/.gitconfig* ~/.vim* ; do
|
|
test -e "$f" || continue
|
|
f2="${f#$H/}"
|
|
[[ "$f2" = .viminf* ]] && continue
|
|
[[ "$f2" = *.tmp ]] && continue
|
|
[[ "$f2" = *~ ]] && continue
|
|
f2="/root/$f2"
|
|
ARR+=( -v "$f:$f2" )
|
|
done
|
|
|
|
eval "$VARIABLE_NAME=( \"\${ARR[@]}\" )"
|
|
}
|
|
|
|
create_dockerfile() {
|
|
|
|
local CONTAINERFILE="$1"
|
|
local BASE_IMAGE="$2"
|
|
local GEN_FILES="bin-nm-env-prepare.sh bin-nm-deploy.sh bin-_nm-in-container-setup.sh
|
|
etc-rc.local etc-motd-container etc-bashrc.my etc-bashrc-motd.my nm-90-my.conf
|
|
nm-95-user.conf home-bash_history home-gdbinit home-gdb_history home-behaverc
|
|
systemd-20-nm.override"
|
|
|
|
cp "$BASEDIR_NM/contrib/scripts/NM-log" "$BASEDIR_DATA/data-bin-NM-log"
|
|
CLEANUP_FILES+=( "$BASEDIR_DATA/data-NM-log" )
|
|
|
|
for f in $GEN_FILES; do
|
|
gen_file "$f"
|
|
done
|
|
chmod 755 "$BASEDIR_DATA/data-etc-rc.local"
|
|
|
|
RUN_LN_BASEDIR_NM=
|
|
if [ -n "$BASEDIR_NM" -a "$BASEDIR_NM" != "/NetworkManager" ] ; then
|
|
RUN_LN_BASEDIR_NM="RUN ln -snf \"$BASEDIR_NM\" /NetworkManager"
|
|
fi
|
|
|
|
RUN_LN_SYMLINK_CMDS=""
|
|
for i in $(seq 1 ${#SYMLINK_NAME[@]}) ; do
|
|
j=$((i - 1))
|
|
if [ -d "${SYMLINK_TARGET[$j]}" ] ; then
|
|
RUN_LN_SYMLINK_CMDS="$RUN_LN_SYMLINK_CMDS"$'\n'"RUN ln -snf \"${SYMLINK_TARGET[$j]}\" \"/${SYMLINK_NAME[$j]}\""
|
|
fi
|
|
done
|
|
|
|
cat <<EOF | tmp_file "$CONTAINERFILE"
|
|
FROM $BASE_IMAGE
|
|
|
|
ENTRYPOINT ["/sbin/init"]
|
|
|
|
RUN sed -i 's/^tsflags=.*/tsflags=/' /etc/dnf/dnf.conf
|
|
|
|
RUN dnf install -y \\
|
|
--skip-broken \\
|
|
\\
|
|
/usr/bin/python \\
|
|
/usr/sbin/ausearch \\
|
|
ModemManager-devel \\
|
|
ModemManager-glib-devel \\
|
|
NetworkManager \\
|
|
audit-libs-devel \\
|
|
bash-completion \\
|
|
bind-utils \\
|
|
black \\
|
|
bluez-libs-devel \\
|
|
ccache \\
|
|
clang \\
|
|
clang-tools-extra \\
|
|
cscope \\
|
|
dbus-devel \\
|
|
dbus-x11 \\
|
|
dhclient \\
|
|
dnsmasq \\
|
|
firewalld-filesystem \\
|
|
gcc-c++ \\
|
|
gdb \\
|
|
gettext-devel \\
|
|
git \\
|
|
glib2-doc \\
|
|
glibc-langpack-pl \\
|
|
gnutls-devel \\
|
|
gobject-introspection-devel \\
|
|
gtk-doc \\
|
|
intltool \\
|
|
iproute \\
|
|
iproute-tc \\
|
|
iptables \\
|
|
jansson-devel \\
|
|
libasan \\
|
|
libcurl-devel \\
|
|
libndp-devel \\
|
|
libpsl-devel \\
|
|
libselinux-devel \\
|
|
libtool \\
|
|
libubsan \\
|
|
libuuid-devel \\
|
|
make \\
|
|
meson \\
|
|
mlocate \\
|
|
mobile-broadband-provider-info-devel \\
|
|
newt-devel \\
|
|
nispor \\
|
|
nmstate \\
|
|
nss-devel \\
|
|
polkit-devel \\
|
|
ppp \\
|
|
ppp-devel \\
|
|
procps \\
|
|
python3-behave \\
|
|
python3-black \\
|
|
python3-dbus \\
|
|
python3-devel \\
|
|
python3-gobject \\
|
|
python3-pexpect \\
|
|
python3-pip \\
|
|
python3-pyte \\
|
|
python3-pyyaml \\
|
|
qt-devel \\
|
|
radvd \\
|
|
readline-devel \\
|
|
rp-pppoe \\
|
|
rpm-build \\
|
|
strace \\
|
|
systemd \\
|
|
systemd-devel \\
|
|
tcpdump \\
|
|
teamd-devel \\
|
|
vala \\
|
|
vala-devel \\
|
|
valgrind \\
|
|
vim \\
|
|
which \\
|
|
\\
|
|
'dbus*' \\
|
|
'openvswitch2*' \\
|
|
/usr/bin/pytest \\
|
|
/usr/bin/debuginfo-install \\
|
|
NetworkManager-openvpn \\
|
|
NetworkManager-pptp \\
|
|
NetworkManager-strongswan \\
|
|
NetworkManager-vpnc \\
|
|
NetworkManager-ovs \\
|
|
NetworkManager-wifi \\
|
|
NetworkManager-team \\
|
|
NetworkManager-ppp \\
|
|
cryptsetup \\
|
|
dhcp-client \\
|
|
dhcp-relay \\
|
|
dhcp-server \\
|
|
dnsmasq \\
|
|
dracut-network \\
|
|
ethtool \\
|
|
firewalld \\
|
|
gcc \\
|
|
git \\
|
|
hostapd \\
|
|
iproute-tc \\
|
|
ipsec-tools \\
|
|
iputils \\
|
|
iscsi-initiator-utils \\
|
|
iw \\
|
|
ldns \\
|
|
libreswan \\
|
|
libselinux-utils \\
|
|
libyaml-devel \\
|
|
logrotate \\
|
|
lvm2 \\
|
|
mdadm \\
|
|
net-tools \\
|
|
nfs-utils \\
|
|
nmap-ncat \\
|
|
nss-tools \\
|
|
openvpn \\
|
|
perl-IO-Pty-Easy \\
|
|
perl-IO-Tty \\
|
|
psmisc \\
|
|
python3-dbus \\
|
|
python3-gobject \\
|
|
python3-netaddr \\
|
|
qemu-kvm \\
|
|
radvd \\
|
|
rp-pppoe \\
|
|
scsi-target-utils \\
|
|
tcpdump \\
|
|
tcpreplay \\
|
|
tuned \\
|
|
wireguard-tools \\
|
|
wireshark-cli
|
|
|
|
RUN dnf debuginfo-install --skip-broken NetworkManager \$(ldd /usr/sbin/NetworkManager | sed -n 's/.* => \\(.*\\) (0x[0-9A-Fa-f]*)$/\1/p' | xargs -n1 readlink -f) -y
|
|
|
|
RUN dnf clean all
|
|
|
|
RUN pip3 install --user behave_html_formatter || true
|
|
|
|
RUN mkdir -p /etc/systemd/system/NetworkManager.service.d
|
|
|
|
COPY data-bin-NM-log "/usr/bin/NM-log"
|
|
COPY data-bin-nm-env-prepare.sh "/usr/bin/nm-env-prepare.sh"
|
|
COPY data-bin-nm-deploy.sh "/usr/bin/nm-deploy.sh"
|
|
COPY data-bin-_nm-in-container-setup.sh "/usr/bin/_nm-in-container-setup.sh"
|
|
COPY data-etc-rc.local "/etc/rc.d/rc.local"
|
|
COPY data-etc-motd-container /etc/motd
|
|
COPY data-etc-bashrc.my /etc/bashrc.my
|
|
COPY data-etc-bashrc-motd.my /etc/bashrc-motd.my
|
|
COPY data-nm-90-my.conf /etc/NetworkManager/conf.d/90-my.conf
|
|
COPY data-nm-95-user.conf /etc/NetworkManager/conf.d/95-user.conf
|
|
COPY data-home-bash_history /root/.bash_history
|
|
COPY data-home-gdbinit /root/.gdbinit
|
|
COPY data-home-gdb_history /root/.gdb_history
|
|
COPY data-home-behaverc /root/.behaverc
|
|
COPY data-systemd-20-nm.override /etc/systemd/system/NetworkManager.service.d/20-nm.override
|
|
|
|
RUN systemctl enable NetworkManager
|
|
|
|
# Generate a stable machine id.
|
|
RUN echo "10001000100010001000100010001000" > /etc/machine-id
|
|
|
|
RUN echo -e "# Default from the container image\nnameserver 8.8.8.8" > /etc/resolv.conf
|
|
|
|
# Generate a fixed (version 1) secret key.
|
|
RUN mkdir -p /var/lib/NetworkManager
|
|
RUN chmod 700 /var/lib/NetworkManager
|
|
RUN echo -n "nm-in-container-secret-key" > /var/lib/NetworkManager/secret_key
|
|
RUN chmod 600 /var/lib/NetworkManager/secret_key
|
|
|
|
RUN sed 's/.*RateLimitBurst=.*/RateLimitBurst=0/' /etc/systemd/journald.conf -i
|
|
|
|
$RUN_LN_BASEDIR_NM
|
|
$RUN_LN_SYMLINK_CMDS
|
|
|
|
RUN rm -rf /etc/NetworkManager/system-connections/*
|
|
|
|
RUN echo -e '\n. /etc/bashrc.my\n' >> /etc/bashrc
|
|
RUN echo -e '\n. /etc/bashrc-motd.my\n' >> /etc/bashrc
|
|
|
|
RUN updatedb
|
|
EOF
|
|
}
|
|
|
|
###############################################################################
|
|
|
|
container_image_exists() {
|
|
podman image exists "$1" || return 1
|
|
}
|
|
|
|
container_exists() {
|
|
podman container exists "$1" || return 1
|
|
}
|
|
|
|
container_is_running() {
|
|
test "$(podman ps --format "{{.ID}} {{.Names}}" | sed -n "s/ $1\$/\0/p")" != "" || return 1
|
|
}
|
|
|
|
###############################################################################
|
|
|
|
do_reset() {
|
|
podman stop "$CONTAINER_NAME_NAME" || :
|
|
podman rm "$CONTAINER_NAME_NAME" || :
|
|
}
|
|
|
|
do_clean() {
|
|
do_reset
|
|
podman rmi "$CONTAINER_NAME_REPOSITORY:$CONTAINER_NAME_TAG" || :
|
|
}
|
|
|
|
do_build() {
|
|
container_image_exists "$CONTAINER_NAME_REPOSITORY:$CONTAINER_NAME_TAG" && return 0
|
|
|
|
CONTAINERFILE="$BASEDIR_DATA/containerfile"
|
|
create_dockerfile "$CONTAINERFILE" "$BASE_IMAGE"
|
|
podman build --squash-all --tag "$CONTAINER_NAME_REPOSITORY:$CONTAINER_NAME_TAG" -f "$CONTAINERFILE"
|
|
}
|
|
|
|
do_run() {
|
|
do_build
|
|
|
|
if container_is_running "$CONTAINER_NAME_NAME" ; then
|
|
return 0
|
|
fi
|
|
|
|
if container_exists "$CONTAINER_NAME_NAME" ; then
|
|
podman start "$CONTAINER_NAME_NAME"
|
|
return 0
|
|
fi
|
|
|
|
bind_files BIND_FILES
|
|
|
|
podman run --privileged \
|
|
--name "$CONTAINER_NAME_NAME" \
|
|
--dns=none \
|
|
--no-hosts \
|
|
-d \
|
|
"${BIND_FILES[@]}" \
|
|
"$CONTAINER_NAME_REPOSITORY:$CONTAINER_NAME_TAG"
|
|
}
|
|
|
|
do_exec() {
|
|
do_run
|
|
|
|
local e
|
|
local EXTRA_ARGS=("$@")
|
|
if [ "${#EXTRA_ARGS[@]}" = 0 ]; then
|
|
EXTRA_ARGS=('bash')
|
|
fi
|
|
|
|
local ENV=()
|
|
for e in "${EXEC_ENV[@]}" ; do
|
|
ENV+=(-e "$e")
|
|
done
|
|
|
|
podman exec "${ENV[@]}" --workdir "$BASEDIR_NM" -it "$CONTAINER_NAME_NAME" "${EXTRA_ARGS[@]}"
|
|
|
|
if [ "$DO_STOP" = 1 ]; then
|
|
do_stop
|
|
fi
|
|
}
|
|
|
|
do_reexec() {
|
|
do_reset
|
|
do_exec "$@"
|
|
}
|
|
|
|
do_journal() {
|
|
EXEC_ENV+=( "SYSTEMD_COLORS=0" )
|
|
do_exec "journalctl" --no-pager "$@"
|
|
}
|
|
|
|
do_stop() {
|
|
container_is_running "$CONTAINER_NAME_NAME" || return 0
|
|
podman stop "$CONTAINER_NAME_NAME"
|
|
}
|
|
|
|
###############################################################################
|
|
|
|
DO_STOP=0
|
|
CMD=exec
|
|
EXTRA_ARGS=()
|
|
for (( i=1 ; i<="$#" ; )) ; do
|
|
c="${@:$i:1}"
|
|
i=$((i+1))
|
|
case "$c" in
|
|
--no-cleanup)
|
|
DO_CLEANUP=0
|
|
;;
|
|
--stop)
|
|
DO_STOP=1
|
|
;;
|
|
j)
|
|
CMD=journal
|
|
;;
|
|
build|run|exec|stop|reset|reexec|clean|journal)
|
|
CMD=$c
|
|
;;
|
|
--)
|
|
EXTRA_ARGS=( "${@:$i}" )
|
|
break
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
if [ "$CMD" = "journal" ]; then
|
|
EXTRA_ARGS=( "${@:$((i-1))}" )
|
|
break;
|
|
else
|
|
usage
|
|
die "invalid argument: $c"
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
|
|
###############################################################################
|
|
|
|
test "$UID" != 0 || die "cannot run as root"
|
|
|
|
if test "$CMD" != exec -a "$CMD" != journal -a "$CMD" != reexec -a "${#EXTRA_ARGS[@]}" != 0 ; then
|
|
die "Extra arguments are only allowed with exec|journal|reexec command"
|
|
fi
|
|
|
|
###############################################################################
|
|
|
|
do_$CMD "${EXTRA_ARGS[@]}"
|