Import Error using pyarmor and the Torizon VSCode extension

Hey everyone! I wanted to ask if anyone here has tried using Pyarmor to obfuscate their python code and then deploy it to their board using the VSCode extension. I am able to obfuscate the code and run it locally with pyarmor, but once I try putting it on the board, I get the following error:

machinepulse-1  |     from .pyarmor_runtime import __pyarmor__
machinepulse-1  | ImportError: /home/torizon/app/src/distributed_python/pyarmor_runtime_000000/pyarmor_runtime.so: cannot open shared object file: No such file or directory
machinepulse-1  | Traceback (most recent call last):
machinepulse-1  |   File "/home/torizon/app/src/distributed_python/main.py", line 2, in <module>
machinepulse-1  |     from pyarmor_runtime_000000 import __pyarmor__
machinepulse-1  |   File "/home/torizon/app/src/distributed_python/pyarmor_runtime_000000/__init__.py", line 2, in <module>
machinepulse-1  |     from .pyarmor_runtime import __pyarmor__
machinepulse-1  | ImportError: /home/torizon/app/src/distributed_python/pyarmor_runtime_000000/pyarmor_runtime.so: cannot open shared object file: No such file or directory

When I go into my docker container to look at the files, I can clearly see this file is there and in the correct place. For further context, here is my dockerfile:

# ARGUMENTS --------------------------------------------------------------------
## Board architecture
ARG IMAGE_ARCH=
## Base container version
ARG BASE_VERSION=3.3.0-bookworm
## Directory of the application inside container
ARG APP_ROOT=

FROM --platform=linux/${IMAGE_ARCH} \
    torizon/debian:${BASE_VERSION} AS Deploy

ARG IMAGE_ARCH
ARG APP_ROOT

# Metadata label
LABEL org.opencontainers.image.description="test description."

# Install system-wide required packages
RUN apt-get -q -y update && \
    apt-get -q -y install \
    python3-minimal \
    python3-pip \
    python3-dbus \
    python3-venv \
    tzdata \
    network-manager \
    systemd \
    dbus \
    build-essential \ 
    libsqlcipher-dev \ 
    python3-dev \
    && apt-get clean && apt-get autoremove && \
    rm -rf /var/lib/apt/lists/*

# Additional installations for dependencies like msodbcsql
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        gnupg \
        g++ \
        unixodbc-dev \
        curl \
    && curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg \
    && curl https://packages.microsoft.com/config/debian/12/prod.list > /etc/apt/sources.list.d/mssql-release.list \
    && apt-get update \
    && ACCEPT_EULA=Y apt-get install -y --no-install-recommends msodbcsql18 \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Create a Python virtual environment
RUN python3 -m venv ${APP_ROOT}/.venv --system-site-packages

# Copy requirements file
COPY requirements-release.txt /requirements-release.txt

# Activate virtualenv and install pip packages, including PyArmor
# Install pip packages on venv with force flag to bypass system environment warning
RUN . ${APP_ROOT}/.venv/bin/activate && \
    pip3 install --upgrade pip && \
    pip3 install --break-system-packages pyarmor && \
    pip3 install -r requirements-release.txt && \
    rm requirements-release.txt


# Copy the entrypoint script and make it executable
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

# Copy the application source code to the container
COPY ./src ${APP_ROOT}/src

# Set the working directory
WORKDIR ${APP_ROOT}

# Set the environment variable
ENV APP_ROOT=${APP_ROOT}

# Set the entrypoint
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

# Activate the virtual environment and run the main script
CMD . ${APP_ROOT}/.venv/bin/activate && python3 src/distributed_python/main.py --no-sandbox

The dockerfile calls main.py, which it can clearly find. Here’s the beginning of main.py:

from pyarmor_runtime_000000 import __pyarmor__
__pyarmor__(__name__, __file__, b'PY000000\x00\x03\n\x00o\r\r\n\x80\x00\x01\x00\x08\x00\x00\x00\x04\x00\x00\x00@\x00\x00\x00x\x8c\x00\x00\x12\t\x04\x00B0-\xf9j\xa8I9G\x1cv\xafY0~\x01\x00\x00\x00\x00\x00\x00\x00\x00g\xc4M\x95+\xf1\x9c\x9b\xd7\x92\x92

pyarmor_runtime_00000 contains an init.py which is solely the following:

# Pyarmor 8.5.12 (trial), 000000, 2024-10-16T12:52:44.700199
from .pyarmor_runtime import __pyarmor__

Anyone have any suggestions to solve this import error? Thank you!

Hi, I’m the Toradex AI Assistant. The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


The error you’re encountering, ImportError: /home/torizon/app/src/distributed_python/pyarmor_runtime_000000/pyarmor_runtime.so: cannot open shared object file: No such file or directory, suggests that the shared object file pyarmor_runtime.so is not being found at runtime, even though you can see it in the correct location within the Docker container.

Here are a few suggestions to troubleshoot and potentially resolve this issue:

  1. Verify File Permissions: Ensure that the pyarmor_runtime.so file has the correct permissions set to be readable by the user running the Python script. You can check and modify permissions using chmod if necessary.

  2. Check Library Path: The issue might be related to the library path not being set correctly. You can try setting the LD_LIBRARY_PATH environment variable to include the directory containing pyarmor_runtime.so. You can do this in your Dockerfile by adding:

    ENV LD_LIBRARY_PATH=${APP_ROOT}/src/distributed_python/pyarmor_runtime_000000:$LD_LIBRARY_PATH
    
  3. Verify Virtual Environment: Ensure that the virtual environment is correctly activated when running the Python script. The CMD in your Dockerfile should activate the virtual environment before executing the script, which seems to be the case, but double-check that the path to the virtual environment is correct.

  4. Rebuild the Docker Image: Sometimes changes might not reflect due to caching. Try rebuilding the Docker image without cache using:

    docker build --no-cache -t your_image_name .
    
  5. Check for Architecture Compatibility: Ensure that the pyarmor_runtime.so file is compatible with the architecture of the Docker image you are using. If the file was compiled for a different architecture, it might not work.

  6. Debugging Output: Add some debugging output in your entrypoint script or Dockerfile to confirm that the file exists and is accessible at runtime. For example, you can add a line in your entrypoint.sh to list the contents of the directory:

    ls -l ${APP_ROOT}/src/distributed_python/pyarmor_runtime_000000
    

If none of these suggestions resolve the issue, you might need to delve deeper into the specifics of how Pyarmor is being used and ensure that all necessary files and dependencies are correctly included and accessible in the Docker environment.

Hey @jeatontenney,

edited*

I’m not familiar with pyarmor, but your error suggests that the program cannot find the pyarmor runtime. Can you verify that this runtime is included in 1) the container and 2) the ve has access to it.

-Eric

Hey @jeatontenney,

We’re you able to integrate pyarmor into your build?

-Eric

Hey @eric.tx !

Sorry to get back to you so late, other stuff has come up with the project, and we decided to move away for the time being with pyarmor, so I’ve not much time to test this further. When we get back around to it, I’ll be more responsive in this thread to try and figure out what’s going on.

Hey @jeatontenney,

Sound good. Thanks for the update.

-Eric