Skip to content

Commit c83a33a

Browse files
committed
Updating Debian packaging to more appropiately match proper Debian Packaging standards
1 parent 1e1dce8 commit c83a33a

File tree

9 files changed

+143
-22
lines changed

9 files changed

+143
-22
lines changed

.github/workflows/publish_docker.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646

4747
- name: Build package
4848
working-directory: panda/debian
49-
run: ./setup.sh Ubuntu ${{ matrix.ubuntu_version }}
49+
run: ./setup.sh Ubuntu ${{ matrix.ubuntu_version }} ${{ needs.create_release.outputs.v-version }}
5050

5151
- name: Upload wheel and debian packages to release
5252
uses: softprops/action-gh-release@v2

panda/debian/Dockerfile

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
ARG PACKAGE_VERSION=""
2+
13
# First run the main Dockerfile to build the base image and name it panda. Then we run here
24
# to generate a debian package
35

4-
FROM debian:buster-slim
6+
FROM debian:bookworm-slim
57

68
# Install necessary tools for packaging
79
RUN apt-get -qq update && \
@@ -12,15 +14,34 @@ RUN apt-get -qq update && \
1214
COPY --from=panda /tmp/base_dep.txt /tmp
1315
COPY --from=panda /tmp/build_dep.txt /tmp
1416

17+
# Copy libcapstone and libosi shared object files from panda
18+
RUN mkdir -p /package-root/usr/lib/x86_64-linux-gnu/
19+
COPY --from=panda /lib/libcapstone.so* /package-root/usr/lib/x86_64-linux-gnu/
20+
COPY --from=panda /lib/libosi.so /lib/libiohal.so /lib/liboffset.so /package-root/usr/lib/
21+
1522
# Set up /package-root with files from panda we'll package
16-
COPY --from=panda /usr/local/bin/panda* /usr/local/bin/libpanda* /usr/local/bin/qemu-img /package-root/usr/local/bin/
17-
COPY --from=panda /usr/local/etc/panda /package-root/usr/local/etc/panda
18-
COPY --from=panda /usr/local/lib/panda /package-root/usr/local/lib/panda
19-
COPY --from=panda /usr/local/share/panda /package-root/usr/local/share/panda
23+
COPY --from=panda /usr/local/bin/panda* /usr/local/bin/libpanda* /usr/local/bin/qemu-img /package-root/usr/bin/
24+
COPY --from=panda /usr/local/etc/panda /package-root/etc/panda/
25+
COPY --from=panda /usr/local/lib/panda /package-root/usr/lib/panda/
26+
COPY --from=panda /usr/local/share/panda /package-root/usr/share/panda/
27+
28+
# Copy documentation over, we should have a better Changelog if we go for official release?
29+
# COPY ./LICENSE /package-root/usr/share/doc/panda
30+
# COPY ./README.md /package-root/usr/share/doc/panda
2031

2132
# Create DEBIAN directory and control file
2233
COPY control /package-root/DEBIAN/control
2334

35+
# Generate MD5 checksums for all files and save to DEBIAN/md5sums
36+
RUN cd /package-root && \
37+
find . -type f ! -path './DEBIAN/*' -exec md5sum {} + | sed 's| \./| |' > /package-root/DEBIAN/md5sums
38+
39+
# Update control file with the correct version, and place installed size
40+
ARG PACKAGE_VERSION
41+
RUN INSTALLED_SIZE=$(du -sk /package-root | cut -f1) && \
42+
sed -i "s/^Installed-Size:.*/Installed-Size: ${INSTALLED_SIZE}/" /package-root/DEBIAN/control
43+
RUN sed -i "s/^Version:.*/Version: ${PACKAGE_VERSION}/" /package-root/DEBIAN/control
44+
2445
# Update control file with dependencies
2546
# Build time. We only select dependencies that are not commented out or blank
2647
RUN dependencies=$(grep '^[a-zA-Z]' /tmp/build_dep.txt | tr '\n' ',' | sed 's/,,\+/,/g'| sed 's/,$//') && \
@@ -30,6 +51,9 @@ RUN dependencies=$(grep '^[a-zA-Z]' /tmp/build_dep.txt | tr '\n' ',' | sed 's/,,
3051
RUN dependencies=$(grep '^[a-zA-Z]' /tmp/base_dep.txt | tr '\n' ',' | sed 's/,,\+/,/g' | sed 's/,$//') && \
3152
sed -i "s/DEPENDS_LIST/Depends: ipxe-qemu,${dependencies}/" /package-root/DEBIAN/control
3253

54+
# Add triggers script to run ldconfig after installation
55+
COPY triggers /package-root/DEBIAN/triggers
56+
3357
# Build the package
3458
RUN fakeroot dpkg-deb --build /package-root /pandare.deb
3559

panda/debian/control

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
Package: pandare
2-
Version: 3.1.0
3-
Architecture: all
2+
Source: MIT
3+
Version: <version-placeholder>
4+
Architecture: amd64
45
BUILD_DEPENDS_LIST
56
DEPENDS_LIST
6-
Maintainer: Andrew Fasano <[email protected]>
7+
Maintainer: Luke Craig <[email protected]>
8+
Installed-Size: <size-in-kb>
9+
Section: devel
10+
Priority: optional
11+
Multi-Arch: same
12+
Homepage: https://panda.re/
713
Description: dynamic analysis platform
814
Platform for Architecture Neutral Dynamic Analysis (PANDA) is a processor
915
emulator designed to support analyses of guest code. PANDA supports record-

panda/debian/setup.sh

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,35 +25,79 @@ if [[ $# -eq 1 ]]; then
2525
echo " To build a package for current Ubuntu version:"
2626
echo " $0"
2727
echo " To build a package for a specific OS/version (only Ubuntu supported for now):"
28-
echo " $0 <OS> <version>"
28+
echo " $0 <OS> <ubuntu-version> <tag-version>"
2929
exit 1
3030
fi
3131

3232
if [[ $# -eq 2 ]]; then
3333
version=$2
34-
3534
else
3635
version=$(lsb_release -r | awk '{print $2}')
3736
fi
3837

38+
if [[ $# -eq 3 ]]; then
39+
tag_version=$3
40+
else
41+
tag_version='v3.1.0'
42+
fi
43+
44+
# Remove leading 'v' if present, e. g. v1.5.1 -> 1.5.1
45+
if [[ "$tag_version" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
46+
tag_version=${tag_version:1}
47+
fi
48+
49+
# Check if the version follows the format X.Y.Z, e. g. 1.5.1 or 1.9.1
50+
if [[ ! "$tag_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
51+
echo "ERROR: Version must be in the format X.Y.Z, provided tag version: $tag_version"
52+
exit 1
53+
fi
54+
3955
# Check if the given version is supported
4056
if [[ ! -f "../dependencies/ubuntu_${version}_base.txt" ]]; then
4157
echo "ERROR: Ubuntu ${version} is not supported, no dependencies file found"
4258
exit 1
4359
fi
4460

61+
# Check if HTTP_PROXY and HTTPS_PROXY are set, if not set them to blank
62+
HTTP_PROXY="${HTTP_PROXY:-}"
63+
HTTPS_PROXY="${HTTPS_PROXY:-}"
64+
4565
# Build the installer to generate the wheel file
46-
DOCKER_BUILDKIT=1 docker build --target installer -t panda --build-arg BASE_IMAGE="ubuntu:${version}" ../..
66+
DOCKER_BUILDKIT=1 docker build \
67+
--target installer \
68+
-t panda_installer \
69+
--build-arg HTTP_PROXY="${HTTP_PROXY}" \
70+
--build-arg HTTPS_PROXY="${HTTPS_PROXY}" \
71+
--build-arg BASE_IMAGE="ubuntu:${version}" \
72+
../..
4773

4874
# Copy wheel file out of container to host
49-
# this also preserves wheel name, which is important as pip install WILL fail if you arbitarily change the generated wheel file name
50-
docker run --rm -v $(pwd):/out panda bash -c "cp /panda/panda/python/core/dist/*.whl /out"
75+
# This also preserves wheel name, which is important as pip install WILL fail if you arbitrarily change the generated wheel file name
76+
docker run --rm \
77+
-v $(pwd):/out \
78+
-e HTTP_PROXY="${HTTP_PROXY}" \
79+
-e HTTPS_PROXY="${HTTPS_PROXY}" \
80+
panda_installer \
81+
bash -c "cp /panda/panda/python/core/dist/*.whl /out"
5182

5283
# Finish building main panda container for the target ubuntu version
53-
DOCKER_BUILDKIT=1 docker build --target panda -t panda --build-arg BASE_IMAGE="ubuntu:${version}" ../..
84+
DOCKER_BUILDKIT=1 docker build \
85+
--cache-from panda_installer \
86+
--target panda \
87+
-t panda \
88+
--build-arg HTTP_PROXY="${HTTP_PROXY}" \
89+
--build-arg HTTPS_PROXY="${HTTPS_PROXY}" \
90+
--build-arg BASE_IMAGE="ubuntu:${version}" \
91+
../..
5492

5593
# Now build the packager container from that
56-
docker build -t packager .
94+
DOCKER_BUILDKIT=1 docker build \
95+
--cache-from panda \
96+
-t packager \
97+
--build-arg HTTP_PROXY="${HTTP_PROXY}" \
98+
--build-arg HTTPS_PROXY="${HTTPS_PROXY}" \
99+
--build-arg PACKAGE_VERSION="${tag_version}" \
100+
.
57101

58102
# Copy deb file out of container to host
59103
docker run --rm -v $(pwd):/out packager bash -c "cp /pandare.deb /out"

panda/debian/triggers

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Trigger ldconfig after install
2+
activate-noawait ldconfig

panda/plugins/osi_linux/osi_linux.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,13 @@ bool init_plugin(void *self) {
12411241
if (kconf_file != NULL) g_free(kconf_file);
12421242
const char* panda_dir = g_getenv("PANDA_DIR");
12431243
kconf_file = g_strdup_printf("%s%s", panda_dir, KERNEL_CONF);
1244+
LOG_INFO("Looking for kconf_file attempt %u: %s", 3, kconf_file);
1245+
kconffile_canon = realpath(kconf_file, NULL);
1246+
}
1247+
if (kconffile_canon == NULL) { // from /etc/panda/osi_linux (Debian package)
1248+
if (kconf_file != NULL) g_free(kconf_file);
1249+
kconf_file = g_build_filename("/etc", "panda", "osi_linux", "kernelinfo.conf", NULL);
1250+
LOG_INFO("Looking for kconf_file attempt %u: %s", 4, kconf_file);
12441251
kconffile_canon = realpath(kconf_file, NULL);
12451252
}
12461253

panda/python/core/pandare/panda.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ def get_plugin_path(self):
270270
if build_dir == "/usr/local/bin/":
271271
# Installed - use /usr/local/lib/panda/plugins
272272
self.plugin_path = f"/usr/local/lib/panda/{self.arch_name}"
273+
elif build_dir == "/usr/bin/":
274+
# Installed - use /usr/lib/panda/plugins
275+
self.plugin_path = f"/usr/lib/panda/{self.arch_name}"
273276
elif isdir(rel_dir):
274277
self.plugin_path = rel_dir
275278
else:

panda/python/core/pandare/utils.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ def _find_build_dir(arch_name, find_executable=False):
180180
Internal function to return the build directory for the specified architecture
181181
'''
182182

183+
debian_build = "/usr/bin/"
183184
system_build = "/usr/local/bin/"
184185
python_package = pjoin(*[dirname(__file__), "data"])
185186
local_build = realpath(pjoin(dirname(__file__), "../../../../build"))
@@ -190,9 +191,12 @@ def _find_build_dir(arch_name, find_executable=False):
190191
f"libpanda-{arch_name}.so"
191192

192193
# system path could have panda-system-X or libpanda-X.so. Others would have an arch_name - softmmu directory
193-
pot_paths = [system_build,
194-
pjoin(python_package, arch_dir),
195-
pjoin(local_build, arch_dir)]
194+
pot_paths = [
195+
system_build,
196+
debian_build,
197+
pjoin(python_package, arch_dir),
198+
pjoin(local_build, arch_dir)
199+
]
196200

197201
if find_executable and 'PATH' in environ:
198202
# If we're looking for the panda executable, also search the user's path

panda/src/callbacks.c

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
* See the COPYING file in the top-level directory.
1313
*
1414
PANDAENDCOMMENT */
15+
#include <stdio.h>
16+
#include <stdlib.h>
17+
#include <unistd.h>
1518
#include <stdint.h>
1619
#include <string.h>
1720
#include <dlfcn.h>
@@ -39,12 +42,25 @@ PANDAENDCOMMENT */
3942
#define LIBRARY_NAME "/libpanda-" TARGET_NAME ".so"
4043
#define PLUGIN_DIR "/" TARGET_NAME "-softmmu/panda/plugins/"
4144

42-
#define INSTALL_PLUGIN_DIR "/usr/local/lib/panda/"
43-
#define INSTALL_BIN_DIR "/usr/local/bin/" // libpanda-arch.so and panda-system-arch in here
45+
const char* INSTALL_PLUGIN_DIR;
46+
const char* INSTALL_BIN_DIR; // libpanda-arch.so and panda-system-arch in here
4447

4548
const gchar *panda_bool_true_strings[] = {"y", "yes", "true", "1", NULL};
4649
const gchar *panda_bool_false_strings[] = {"n", "no", "false", "0", NULL};
4750

51+
const char * panda_system_paths[] = {
52+
"/usr/bin/panda-system-aarch64",
53+
"/usr/bin/panda-system-arm",
54+
"/usr/bin/panda-system-i386",
55+
"/usr/bin/panda-system-mips",
56+
"/usr/bin/panda-system-mips64",
57+
"/usr/bin/panda-system-mips64el",
58+
"/usr/bin/panda-system-mipsel",
59+
"/usr/bin/panda-system-ppc",
60+
"/usr/bin/panda-system-x86_64",
61+
NULL
62+
};
63+
4864
#if 0
4965
###########################################################
5066
WARNING: This is all gloriously thread-unsafe!!!
@@ -153,6 +169,14 @@ static bool load_libpanda(void) {
153169
g_free((char *)panda_lib);
154170
}
155171

172+
INSTALL_BIN_DIR = "/usr/local/bin/";
173+
for (int i = 0; panda_system_paths[i] != NULL; i++) {
174+
if (access(panda_system_paths[i], F_OK) != -1) {
175+
INSTALL_BIN_DIR = "/usr/bin";
176+
break;
177+
}
178+
}
179+
156180
// Try standard install location
157181
panda_lib = g_strdup_printf("%s%s", INSTALL_BIN_DIR, LIBRARY_NAME);
158182
if (g_file_test(panda_lib, G_FILE_TEST_EXISTS)) {
@@ -347,7 +371,14 @@ char* resolve_file_from_plugin_directory(const char* file_name_fmt, const char*
347371
return plugin_path;
348372
}
349373
g_free(plugin_path);
350-
374+
375+
INSTALL_PLUGIN_DIR = "/usr/local/lib/panda/";
376+
for (int i = 0; panda_system_paths[i] != NULL; i++) {
377+
if (access(panda_system_paths[i], F_OK) != -1) {
378+
INSTALL_PLUGIN_DIR = "/usr/lib/panda";
379+
break;
380+
}
381+
}
351382

352383
// Third, check relative to the standard install location.
353384
plugin_path = attempt_normalize_path(

0 commit comments

Comments
 (0)