mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-29 06:50:10 +01:00
NM-ci wants to install a lot of packages when running the first test. In particular, NM-ci has no nice script that lists all the dependencies, so it's not immediately clear which packages are required. Still, install some of those packages so that they are already present when running the first NM-ci test.
633 lines
16 KiB
Bash
Executable file
633 lines
16 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.
|
|
# Create a symlink ./.git/NetworkManager-ci, to also bind-mount the CI directory.
|
|
#
|
|
# Currently NM-ci requires a working eth1.
|
|
# Hence call `nm-env-prepare.sh --prefix eth -i 1 && nmcli device connect eth1` before
|
|
# running a CI test.
|
|
###############################################################################
|
|
|
|
BASE_IMAGE="${BASE_IMAGE:-fedora:latest}"
|
|
|
|
BASEDIR_NM="$(readlink -f "$(dirname "$(readlink -f "$0")")/../..")"
|
|
BASEDIR="$BASEDIR_NM/contrib/scripts/nm-in-container.d"
|
|
|
|
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|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"
|
|
}
|
|
|
|
bind_files() {
|
|
VARIABLE_NAME="$1"
|
|
|
|
ARR=()
|
|
H=~
|
|
|
|
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"
|
|
|
|
cp "$BASEDIR_NM/contrib/scripts/NM-log" "$BASEDIR/data-NM-log"
|
|
CLEANUP_FILES+=( "$BASEDIR/data-NM-log" )
|
|
|
|
cat <<EOF | tmp_file "$BASEDIR/data-motd"
|
|
*** nm-in-container:
|
|
|
|
find NetworkManager bind mounted at $BASEDIR_NM
|
|
run \`nm-env-prepare.sh setup --idx 1\` to setup test interfaces
|
|
|
|
Coredumps: coredumps are not namespaced, so by default they will
|
|
be sent to coredumpctl of the outer host, which has no idea where
|
|
to get the debugging symbols from. A possible workaround is setting
|
|
|
|
$ echo '/tmp/core.%e.%p' | sudo tee /proc/sys/kernel/core_pattern
|
|
|
|
so that core dumps get written to file. Afterwards, restore with
|
|
|
|
echo '|/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h' | sudo tee /proc/sys/kernel/core_pattern
|
|
|
|
from /usr/lib/sysctl.d/50-coredump.conf.
|
|
|
|
For example, configure NetworkManager with
|
|
\$ ./configure \\
|
|
--enable-address-sanitizer=no \\
|
|
--enable-compile-warnings=yes \\
|
|
--enable-concheck \\
|
|
--enable-config-plugin-ibft=yes \\
|
|
--enable-gtk-doc \\
|
|
--enable-ifcfg-rh=yes \\
|
|
--enable-ifcfg-suse \\
|
|
--enable-ifnet \\
|
|
--enable-ifupdown=yes \\
|
|
--enable-introspection \\
|
|
--enable-json-validation=yes \\
|
|
--enable-maintainer-mode \\
|
|
--enable-more-logging \\
|
|
--enable-more-warnings=error \\
|
|
--enable-ovs=yes \\
|
|
--enable-polkit=yes \\
|
|
--enable-teamdctl=yes \\
|
|
--enable-undefined-sanitizer=no \\
|
|
--enable-vala=yes \\
|
|
--enable-wimax \\
|
|
--localstatedir=/var \\
|
|
--prefix=/opt/test \\
|
|
--sysconfdir=/etc \\
|
|
--with-config-dhcp-default=internal \\
|
|
--with-config-dns-rc-manager-default=auto \\
|
|
--with-consolekit=yes \\
|
|
--with-consolekit=yes \\
|
|
--with-crypto=nss \\
|
|
--with-dhclient=yes \\
|
|
--with-dhcpcanon=yes \\
|
|
--with-dhcpcd=yes \\
|
|
--with-iwd=yes \\
|
|
--with-libnm-glib=yes \\
|
|
--with-modem-manager-1 \\
|
|
--with-netconfig=/bin/nowhere/netconfig \\
|
|
--with-nm-cloud-setup=yes \\
|
|
--with-nmcli=yes \\
|
|
--with-nmtui=yes \\
|
|
--with-ofono=yes \\
|
|
--with-resolvconf=/bin/nowhere/resolvconf \\
|
|
--with-session-tracking=systemd \\
|
|
--with-suspend-resume=systemd \\
|
|
--with-systemd-logind=yes \\
|
|
--with-valgrind=yes \\
|
|
--enable-tests="\${NM_BUILD_TESTS:-yes}" \\
|
|
--with-more-asserts="\${NM_BUILD_MORE_ASSERTS:-1000}" \\
|
|
"\${NM_CONFIGURE_OTPS[@]}"
|
|
Test with:
|
|
\$ systemctl stop NetworkManager; /opt/test/sbin/NetworkManager --debug 2>&1 | tee -a /tmp/nm-log.txt
|
|
|
|
Or better, configure with \`contrib/fedora/rpm/configure-for-system.sh\`,
|
|
subsequent \`make && make install\` will overwrite your system's NetworkManager,
|
|
and you can test it with \`systemctl daemon-reload ; systemctl restart NetworkManager\`.
|
|
|
|
Run NM-ci tests after creating eth1 with
|
|
\`nm-env-prepare.sh --prefix eth -i 1 && nmcli device connect eth1\`.
|
|
EOF
|
|
|
|
cat <<EOF | tmp_file "$BASEDIR/data-bashrc.my"
|
|
alias m="make -j 8"
|
|
alias n="ninja -C build"
|
|
|
|
alias l='ls -l --color=auto'
|
|
|
|
ulimit -c unlimited
|
|
|
|
export G_DEBUG=fatal-warnings
|
|
|
|
unset DEBUGINFOD_URLS
|
|
|
|
Clean() {
|
|
systemctl stop NetworkManager
|
|
rm -i -rf /run/NetworkManager
|
|
nm-env-prepare.sh
|
|
}
|
|
|
|
Cat-Timestamp() {
|
|
while IFS=$'\n' read line; do
|
|
printf "[%s]: %s\n" "$(date '+%s.%N')" "$line"
|
|
done
|
|
}
|
|
|
|
Journald-clear() {
|
|
rm -rf /var/log/journal/????????????????????????????????/*
|
|
systemctl restart systemd-journald
|
|
}
|
|
|
|
nm_run_gdb() {
|
|
systemctl stop NetworkManager.service
|
|
gdb --args "\${1:-/opt/test/sbin/NetworkManager}" --debug
|
|
}
|
|
|
|
nm_run_normal() {
|
|
systemctl stop NetworkManager.service
|
|
"\${1:-/opt/test/sbin/NetworkManager}" --debug 2>&1 | tee /tmp/nm-log.txt
|
|
}
|
|
|
|
. /usr/share/git-core/contrib/completion/git-prompt.sh
|
|
PS1="\[\\033[01;36m\]\u@\h\[\\033[00m\]:\\t:\[\\033[01;34m\]\w\\\$(__git_ps1 \\" \[\\033[01;36m\](%s)\[\\033[00m\]\\")\[\\033[00m\]\$ "
|
|
export GIT_PS1_SHOWDIRTYSTATE=1
|
|
|
|
if test "\$SHOW_MOTD" != 0; then
|
|
cat /etc/motd
|
|
export SHOW_MOTD=0
|
|
fi
|
|
EOF
|
|
|
|
cat <<EOF | tmp_file "$BASEDIR/data-90-my.conf"
|
|
[main]
|
|
no-auto-default=*
|
|
debug=RLIMIT_CORE,fatal-warnings
|
|
|
|
[logging]
|
|
level=TRACE
|
|
domains=ALL,VPN_PLUGIN:TRACE
|
|
|
|
[device-managed-0]
|
|
match-device=interface-name:d_*,interface-name:tap*
|
|
managed=0
|
|
|
|
[device-managed-1]
|
|
match-device=interface-name:net*,interface-name:eth*
|
|
managed=1
|
|
EOF
|
|
|
|
cat <<EOF | tmp_file "$BASEDIR/data-95-user.conf"
|
|
EOF
|
|
|
|
cat <<EOF | tmp_file "$BASEDIR/data-bash_history" 600
|
|
NM-log
|
|
NM-log /tmp/nm-log.txt
|
|
behave -f html --stop -t ipv4_method_static_with_IP ./features/scenarios/ipv4.feature
|
|
behave -f html --stop ./features/scenarios/vrf.feature
|
|
cd $BASEDIR_NM
|
|
for i in {1..9}; do nm-env-prepare.sh --prefix eth -i \$i; done
|
|
Journald-clear
|
|
journalctl | NM-log
|
|
journalctl --since '3 min ago' | NM-log
|
|
m
|
|
make
|
|
make install
|
|
n
|
|
nm-env-prepare.sh
|
|
nm-env-prepare.sh --prefix eth -i 1
|
|
nm-env-prepare.sh --prefix eth -i 1 && nmcli device connect eth1
|
|
nm_run_gdb
|
|
nm_run_normal
|
|
gdb /usr/sbin/NetworkManager /tmp/core.NetworkManager.
|
|
nmcli connection add type pppoe con-name ppp-net1 ifname ppp-net1 pppoe.parent net1 service isp username test password networkmanager autoconnect no
|
|
nmcli device connect eth1
|
|
systemctl stop NetworkManager; /opt/test/sbin/NetworkManager --debug 2>&1 | tee -a ./nm-log.txt
|
|
systemctl stop NetworkManager; gdb -ex run --args /opt/test/sbin/NetworkManager --debug
|
|
systemctl stop NetworkManager
|
|
systemctl daemon-reload ; systemctl restart NetworkManager
|
|
systemctl status NetworkManager
|
|
EOF
|
|
|
|
cat <<EOF | tmp_file "$BASEDIR/data-gdbinit"
|
|
set history save
|
|
set history filename ~/.gdb_history
|
|
EOF
|
|
|
|
cat <<EOF | tmp_file "$BASEDIR/data-gdb_history" 600
|
|
run
|
|
run --debug 2>&1 | tee /tmp/nm-log.txt
|
|
EOF
|
|
|
|
cat <<EOF | tmp_file "$BASEDIR/data-behaverc" 600
|
|
[behave.formatters]
|
|
html = behave_html_formatter:HTMLFormatter
|
|
EOF
|
|
|
|
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 \\
|
|
ModemManager-devel \\
|
|
ModemManager-glib-devel \\
|
|
NetworkManager \\
|
|
audit-libs-devel \\
|
|
bash-completion \\
|
|
bind-utils \\
|
|
bluez-libs-devel \\
|
|
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 \\
|
|
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/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 \\
|
|
gdb \\
|
|
gdb \\
|
|
git \\
|
|
hostapd \\
|
|
iproute-tc \\
|
|
ipsec-tools \\
|
|
iputils \\
|
|
iscsi-initiator-utils \\
|
|
iw \\
|
|
ldns \\
|
|
libreswan \\
|
|
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 \$(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
|
|
|
|
COPY data-NM-log "/usr/bin/NM-log"
|
|
COPY data-nm-env-prepare.sh "/usr/bin/nm-env-prepare.sh"
|
|
COPY data-_nm-in-container-setup.sh "/usr/bin/_nm-in-container-setup.sh"
|
|
COPY data-etc-rc.local "/etc/rc.d/rc.local"
|
|
COPY data-motd /etc/motd
|
|
COPY data-bashrc.my /etc/bashrc.my
|
|
COPY data-90-my.conf /etc/NetworkManager/conf.d/90-my.conf
|
|
COPY data-95-user.conf /etc/NetworkManager/conf.d/95-user.conf
|
|
COPY data-bash_history /root/.bash_history
|
|
COPY data-gdbinit /root/.gdbinit
|
|
COPY data-gdb_history /root/.gdb_history
|
|
COPY data-behaverc /root/.behaverc
|
|
|
|
RUN systemctl enable NetworkManager
|
|
|
|
# Generate a stable machine id.
|
|
RUN echo "10001000100010001000100010001000" > /etc/machine-id
|
|
|
|
# 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 rm -rf /etc/NetworkManager/system-connections/*
|
|
|
|
RUN echo -e '\n. /etc/bashrc.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/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"
|
|
else
|
|
bind_files BIND_FILES
|
|
|
|
BIND_NM_CI=()
|
|
if [ -d "$BASEDIR_NM/.git/NetworkManager-ci" ] ; then
|
|
DIR="$(readlink -f "$BASEDIR_NM/.git/NetworkManager-ci")"
|
|
BIND_NM_CI=(-v "$DIR:$DIR")
|
|
fi
|
|
|
|
podman run --privileged \
|
|
--name "$CONTAINER_NAME_NAME" \
|
|
-d \
|
|
-v "$BASEDIR_NM:$BASEDIR_NM" \
|
|
"${BIND_NM_CI[@]}" \
|
|
"${BIND_FILES[@]}" \
|
|
"$CONTAINER_NAME_REPOSITORY:$CONTAINER_NAME_TAG"
|
|
fi
|
|
}
|
|
|
|
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_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|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 "${#EXTRA_ARGS[@]}" != 0 ; then
|
|
die "Extra arguments are only allowed with exec command"
|
|
fi
|
|
|
|
###############################################################################
|
|
|
|
do_$CMD "${EXTRA_ARGS[@]}"
|