diff --git a/.dockerignore b/.dockerignore index c4ab83c6e..919a15e1c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,3 +2,8 @@ cmake-build* integration_tests/external* Dockerfile .dockerignore +.gitignore +.git +appimage/Dockerfile.part +appimage/export.sh +appimage/Makefile diff --git a/.gitignore b/.gitignore index c4fb154b5..82dd8837c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ docs/html-documentation-generated* integration_tests/external golang/pkg/client/version.go docs/internals/html +appimage/*.AppImage \ No newline at end of file diff --git a/appimage/Dockerfile.part b/appimage/Dockerfile.part new file mode 100644 index 000000000..a162f194f --- /dev/null +++ b/appimage/Dockerfile.part @@ -0,0 +1,18 @@ +# file is needed for appimagetool when its run with --appimage-extract-and-run +# binutil is needed for strip +RUN apt-get update && apt-get install -yqq --no-install-recommends python3-pip binutils file dietlibc-dev gcc musl musl-tools \ + && pip3 install --user exodus-bundler --no-warn-script-location \ + && /root/.local/bin/exodus --verbose --tarball --output=/tmp/pktvisor.tgz $(which pktvisord) $(which pktvisor-pcap) \ + && mkdir pktvisor \ + && tar --strip=1 -xf /tmp/pktvisor.tgz -C pktvisor/ \ + && strip --verbose --strip-debug pktvisor/data/* \ + && cp $(which pktvisor-cli) /pktvisor/bin/pktvisor-cli + +# get latest appimagetool +ADD https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage /bin/appimage-tool + +# add entrypoints and desktop things +COPY appimage/pktvisor /pktvisor + +# create appimage without fuse +RUN chmod +x /bin/appimage-tool /pktvisor/AppRun && appimage-tool --appimage-extract-and-run /pktvisor/ \ No newline at end of file diff --git a/appimage/Makefile b/appimage/Makefile new file mode 100644 index 000000000..085a7079c --- /dev/null +++ b/appimage/Makefile @@ -0,0 +1,17 @@ +DEV_IMAGE ?= ns1labs/pktvisor:latest + +# in dev mode we just use the latest image as the start point +ifneq ($(strip $(DEV_MODE)),) +DOCKERFILE_HEAD = <(echo "FROM $(DEV_IMAGE)") +else +DOCKERFILE_HEAD = docker/Dockerfile +endif + +pktvisor-x86_64.AppImage: SHELL:=/bin/bash #needed for the fd when DOCKERFILE_HEAD is in DEV_MODE +pktvisor-x86_64.AppImage: + ID=$$(cd .. && cat $(DOCKERFILE_HEAD) appimage/Dockerfile.part | docker build -q -f- .) ; \ + bash export.sh $$ID + +.PHONEY: clean +clean: + rm pktvisor-x86_64.AppImage \ No newline at end of file diff --git a/appimage/README.md b/appimage/README.md new file mode 100644 index 000000000..126ca1711 --- /dev/null +++ b/appimage/README.md @@ -0,0 +1,28 @@ +AppImage Packaging +================== + +Creates an AppImage that contains `pktvisord` `pktvisor-pcap` and `pktvisor-cli`. This implementation builds the AppImage in a docker using the assets generated by the docker [build](../docker). Because not all of the assets are statically linked we use [Exodus](https://github.com/intoli/exodus) to capture a minimal set of dependencies for the AppImage + + +## Build: +`make pktvisor-x86_64.AppImage` + +## Development: +Because the build can take a while you may want to build the appimage from the latest docker image on docker hub. To do this you can set the `DEV_MODE=` environment to anything. Like so: + +`DEV_MODE=t make pktvisor-x86_64.AppImage` + +You may also specify a custom image in dev mode by setting the env file `DEV_IMAGE=` to the image you wish to build on. Example: + +`DEV_IMAGE="ns1labs/pktvisor:develop" DEV_MODE=t make pktvisor-x86_64.AppImage` + + +## Usage: +To use the AppImage from the command line you can specify the binary you want to run as the first argument following the pattern: + +` +./pktvisor-x86_64.AppImage [pktvisord|pktvisor-pcap|pktvisor-cli] +` + +If you don't specify a binary, all args are passed to pktvisord by default. + diff --git a/appimage/export.sh b/appimage/export.sh new file mode 100644 index 000000000..00c27ff24 --- /dev/null +++ b/appimage/export.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +## +# Try to extract files from docker image as atomically as possible +# + +FILES=(pktvisor-x86_64.AppImage) + +die () { + echo "$@" >&2 + exit 1 +} + +# pass in image id as $1 +main () { + [[ $1 ]] || die "image name not specified" + + # make a trap that see the var + id= + cleanup() { + docker rm -v "$id" + } + + trap cleanup EXIT + + # make it + id=$(docker create $1) + [[ $? == 0 ]] || die "failed to create container for export" + + # take it + for file in "${FILES[@]}" ; do + docker cp "$id:$file" . + done +} + +main "$1" \ No newline at end of file diff --git a/appimage/pktvisor/AppRun b/appimage/pktvisor/AppRun new file mode 100644 index 000000000..a08924b64 --- /dev/null +++ b/appimage/pktvisor/AppRun @@ -0,0 +1,31 @@ +#!/bin/sh +set -x + +# borrowed from appimage directly +SELF=$(readlink -f "$0") +HERE=${SELF%/*} +export PATH="${HERE}/usr/bin/:${HERE}/usr/sbin/:${HERE}/usr/games/:${HERE}/bin/:${HERE}/sbin/${PATH:+:$PATH}" +export LD_LIBRARY_PATH="${HERE}/usr/lib/:${HERE}/usr/lib/i386-linux-gnu/:${HERE}/usr/lib/x86_64-linux-gnu/:${HERE}/usr/lib32/:${HERE}/usr/lib64/:${HERE}/lib/:${HERE}/lib/i386-linux-gnu/:${HERE}/lib/x86_64-linux-gnu/:${HERE}/lib32/:${HERE}/lib64/${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" +export PYTHONPATH="${HERE}/usr/share/pyshared/${PYTHONPATH:+:$PYTHONPATH}" +export XDG_DATA_DIRS="${HERE}/usr/share/${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}" +export PERLLIB="${HERE}/usr/share/perl5/:${HERE}/usr/lib/perl5/${PERLLIB:+:$PERLLIB}" +export GSETTINGS_SCHEMA_DIR="${HERE}/usr/share/glib-2.0/schemas/${GSETTINGS_SCHEMA_DIR:+:$GSETTINGS_SCHEMA_DIR}" +export QT_PLUGIN_PATH="${HERE}/usr/lib/qt4/plugins/:${HERE}/usr/lib/i386-linux-gnu/qt4/plugins/:${HERE}/usr/lib/x86_64-linux-gnu/qt4/plugins/:${HERE}/usr/lib32/qt4/plugins/:${HERE}/usr/lib64/qt4/plugins/:${HERE}/usr/lib/qt5/plugins/:${HERE}/usr/lib/i386-linux-gnu/qt5/plugins/:${HERE}/usr/lib/x86_64-linux-gnu/qt5/plugins/:${HERE}/usr/lib32/qt5/plugins/:${HERE}/usr/lib64/qt5/plugins/${QT_PLUGIN_PATH:+:$QT_PLUGIN_PATH}" + +# begin entrypoint +# default to pktvisord but allow first arg to specify binary +BINARY="$1" +case "$BINARY" in + pktvisor-cli) shift ;; + pktvisor-pcap) shift ;; + pktvisord) shift ;; + *) BINARY=pktvisord ;; +esac + +# not a terminal try to alert the user +if [ ! -t 1 ] ; then + xdg-open "file://${HERE}/TerminalEmulatorRequired.txt" + exit 1 +else + exec "${HERE}/bin/${BINARY}" "$@" +fi \ No newline at end of file diff --git a/appimage/pktvisor/TerminalEmulatorRequired.txt b/appimage/pktvisor/TerminalEmulatorRequired.txt new file mode 100644 index 000000000..f463044a7 --- /dev/null +++ b/appimage/pktvisor/TerminalEmulatorRequired.txt @@ -0,0 +1 @@ +This app needs to be run from a terminal to function correctly. See the docs at https://github.com/ns1/pktvisor for more details. \ No newline at end of file diff --git a/appimage/pktvisor/pktvisor.desktop b/appimage/pktvisor/pktvisor.desktop new file mode 100644 index 000000000..35a4e20b4 --- /dev/null +++ b/appimage/pktvisor/pktvisor.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Name=pktvisor +Terminal=true +Exec=AppRun +Icon=pktvisor +Type=Application +Categories=Utility; \ No newline at end of file diff --git a/appimage/pktvisor/pktvisor.png b/appimage/pktvisor/pktvisor.png new file mode 100644 index 000000000..b5a78ad08 Binary files /dev/null and b/appimage/pktvisor/pktvisor.png differ diff --git a/docker/Dockerfile b/docker/Dockerfile index ba8f74a0e..31046b12d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -23,6 +23,7 @@ RUN \ FROM golang:latest AS gobuild COPY golang/ /src/ WORKDIR /src/ +COPY --from=cppbuild /pktvisor-src/golang/pkg/client/version.go /src/pkg/client/version.go RUN go build -o pktvisor-cli cmd/pktvisor-cli/main.go FROM debian:bullseye-slim AS runtime