Skip to content

Commit

Permalink
docker: Use only native Python API, set only necessary variables (OSG…
Browse files Browse the repository at this point in the history
…eo#3819)

- Rewrite `testdata/test_grass_session.py`, replacing the `pip install grass-session` approach by native solution (now fully functional).
- Fix Ubuntu ARG handling.
- Remove unneeded environmental variables from images (setting GISBASE without the rest of variables may be harmful because internal mechanisms use it to determine if there is an existing session or not).
- Update tests for all Dockerfiles.

Co-authored-by: Vaclav Petras <wenzeslaus@gmail.com>
  • Loading branch information
neteler and wenzeslaus authored Jun 15, 2024
1 parent ef6bae8 commit 9f7ecdc
Show file tree
Hide file tree
Showing 13 changed files with 130 additions and 98 deletions.
59 changes: 41 additions & 18 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ ARG GRASS_RUN_PACKAGES="build-essential \
ncurses-bin \
pdal \
proj-data \
python-is-python3 \
python3 \
python3-dev \
python3-venv \
Expand All @@ -82,6 +83,7 @@ ARG GRASS_RUN_PACKAGES="build-essential \
zip \
zlib1g \
"
ENV GRASS_RUN_PACKAGES=${GRASS_RUN_PACKAGES}

# Define build packages
ARG GRASS_BUILD_PACKAGES="cmake \
Expand All @@ -101,6 +103,7 @@ ARG GRASS_BUILD_PACKAGES="cmake \
mesa-common-dev \
zlib1g-dev \
"
ENV GRASS_BUILD_PACKAGES=${GRASS_BUILD_PACKAGES}

ARG GRASS_CONFIG="--with-cxx \
--enable-largefile \
Expand All @@ -126,7 +129,6 @@ ARG GRASS_CONFIG="--with-cxx \

ARG GRASS_PYTHON_PACKAGES="pip \
setuptools \
grass-session \
python-dateutil \
python-magic \
numpy \
Expand All @@ -135,12 +137,13 @@ ARG GRASS_PYTHON_PACKAGES="pip \
matplotlib \
psycopg2 \
"
ENV GRASS_PYTHON_PACKAGES=${GRASS_PYTHON_PACKAGES}


FROM common_start as grass_without_gui

ARG GRASS_CONFIG="${GRASS_CONFIG} --without-opengl"

ENV GRASS_CONFIG=${GRASS_CONFIG}

FROM common_start as grass_with_gui

Expand Down Expand Up @@ -244,12 +247,12 @@ RUN apt-get update \
RUN (echo "Install Python" \
&& wget https://bootstrap.pypa.io/pip/get-pip.py \
# && apt-get install -y python3-ensurepip \
&& python3 get-pip.py \
&& python get-pip.py \
# && python3 -m ensurepip --upgrade \
&& rm -r get-pip.py \
&& mkdir -p /src/site-packages \
&& cd /src \
&& python3 -m pip install --no-cache-dir -t /src/site-packages --upgrade \
&& python -m pip install --no-cache-dir -t /src/site-packages --upgrade \
$GRASS_PYTHON_PACKAGES \
&& rm -r /root/.cache \
&& rm -rf /tmp/pip-* \
Expand All @@ -265,13 +268,12 @@ WORKDIR /src/grass_build
ENV MYCFLAGS "-O2 -std=gnu99 -m64"
ENV MYLDFLAGS "-s"
# CXX stuff:
#ENV LD_LIBRARY_PATH "/usr/local/lib"
ENV LD_LIBRARY_PATH "/usr/local/lib"
ENV LDFLAGS "$MYLDFLAGS"
ENV CFLAGS "$MYCFLAGS"
ENV CXXFLAGS "$MYCXXFLAGS"

# Configure compile and install GRASS GIS
ENV GRASS_PYTHON=/usr/bin/python3
ENV NUMTHREADS=4
RUN make distclean || echo "nothing to clean"
RUN ./configure $GRASS_CONFIG \
Expand Down Expand Up @@ -301,18 +303,13 @@ FROM grass_gis as grass_gis_final

# GRASS GIS specific
# allow work with MAPSETs that are not owned by current user
# add GRASS GIS envs for python usage
ENV GRASSBIN="/usr/local/bin/grass" \
GRASS_SKIP_MAPSET_OWNER_CHECK=1 \
ENV GRASS_SKIP_MAPSET_OWNER_CHECK=1 \
SHELL="/bin/bash" \
# https://proj.org/usage/environmentvars.html#envvar-PROJ_NETWORK
PROJ_NETWORK=ON \
# GRASSBIN=grass \
LC_ALL="en_US.UTF-8" \
GISBASE="/usr/local/grass/" \
GRASSBIN="/usr/local/bin/grass" \
PYTHONPATH="${PYTHONPATH}:/usr/local/grass/etc/python/" \
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/grass/lib" \
PYTHONPATH="/usr/local/grass/etc/python/:${PYTHONPATH}" \
LD_LIBRARY_PATH="/usr/local/grass/lib:$LD_LIBRARY_PATH" \
GDAL_DRIVER_PATH="/usr/lib/gdalplugins"

# Copy GRASS GIS from build image
Expand All @@ -323,11 +320,37 @@ COPY --link --from=build /usr/lib/gdalplugins /usr/lib/gdalplugins
# COPY --link --from=datum_grids /tmp/cdn.proj.org/*.tif /usr/share/proj/

# Create generic GRASS GIS lib name regardless of version number
RUN ln -sf /usr/local/grass85 /usr/local/grass \
&& ldconfig /etc/ld.so.conf.d
RUN ln -sf /usr/local/grass85 /usr/local/grass

# show GRASS GIS, PROJ, GDAL etc versions
RUN grass --tmp-project EPSG:4326 --exec g.version -rge && \
pdal --version && \
python --version

# Reduce the image size
RUN apt-get autoremove -y
RUN apt-get clean -y
RUN rm -r /src/grass_build/.git

# Data workdir
WORKDIR /scripts

# enable GRASS GIS Python session support
## grass --config python-path
ENV PYTHONPATH "/usr/local/grass/etc/python:${PYTHONPATH}"
# enable GRASS GIS ctypes imports
## grass --config path
ENV LD_LIBRARY_PATH "/usr/local/grass/lib:$LD_LIBRARY_PATH"

WORKDIR /tmp
COPY docker/testdata/simple.laz .
WORKDIR /scripts
COPY docker/testdata/test_grass_session.py .
## run GRASS GIS python session and scan the test LAZ file
RUN python /scripts/test_grass_session.py
RUN rm -rf /tmp/grasstest_epsg_25832
# test LAZ file
RUN grass --tmp-project EPSG:25832 --exec r.in.pdal input="/tmp/simple.laz" output="count_1" method="n" resolution=1 -g
WORKDIR /grassdb
VOLUME /grassdb

CMD ["bash", "-c", "$GRASSBIN", "--version"]
CMD ["$GRASSBIN", "--version"]
20 changes: 9 additions & 11 deletions docker/alpine/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,10 @@ FROM common as grass

# GRASS GIS specific
# allow work with MAPSETs that are not owned by current user
ENV GRASSBIN="/usr/local/bin/grass" \
GRASS_SKIP_MAPSET_OWNER_CHECK=1 \
ENV GRASS_SKIP_MAPSET_OWNER_CHECK=1 \
SHELL="/bin/bash" \
# https://proj.org/usage/environmentvars.html#envvar-PROJ_NETWORK
PROJ_NETWORK=ON \
GRASSBIN=grass \
LC_ALL="en_US.UTF-8" \
PYTHONPATH="/usr/local/grass/etc/python:$PYTHONPATH"

Expand All @@ -206,20 +204,20 @@ COPY --from=build /usr/local/grass* /usr/local/grass/
COPY --from=build /usr/lib/gdalplugins/*_GRASS.so /usr/lib/gdalplugins/
# run simple LAZ test
COPY docker/testdata/simple.laz /tmp/
COPY docker/testdata/test_grass_python.py docker/alpine/grass_tests.sh /scripts/
COPY docker/testdata/test_grass_python.py /scripts/
COPY docker/testdata/test_grass_python.py docker/testdata/test_grass_session.py docker/alpine/grass_tests.sh /scripts/

# install external Python API
# run GRASS GIS python session and scan the test LAZ file; some cleanup
# also show installed version
RUN ln -sf /usr/local/grass $(grass --config path); \
# run some tests and cleanup
$SHELL /scripts/grass_tests.sh \
rm -rf /tmp/grasstest_epsg_25832; \
$SHELL /scripts/grass_tests.sh; \
python /scripts/test_grass_session.py && rm -rf /tmp/grasstest_epsg_25832; \
grass --tmp-project EPSG:25832 --exec r.in.pdal input="/tmp/simple.laz" output="count_1" method="n" resolution=1 -g \
&& rm -f /scripts/grass_tests.sh /tmp/simple.laz /scripts/test_grass_python.py; \
# delete unused packages
apk del --no-cache gettext pdal-dev; \
# show installed version
grass --tmp-project XY --exec g.version -rge \
&& pdal --version \
&& python3 --version
&& python --version

# Data workdir
WORKDIR /grassdb
Expand Down
3 changes: 1 addition & 2 deletions docker/alpine/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# Docker GRASS GIS (alpine linux)

Dockerfile with an [Alpine Linux](https://www.alpinelinux.org/) image with
[GRASS GIS](https://grass.osgeo.org/), [PDAL](https://pdal.io) support and
[grass-session](https://github.com/zarch/grass-session/).
[GRASS GIS](https://grass.osgeo.org/), [PDAL](https://pdal.io) support.

Download size of this image is only approximately 80 MB.

Expand Down
2 changes: 1 addition & 1 deletion docker/alpine/grass_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# add dependency
apk add --no-cache py3-scikit-learn

# Test grass-session:
# Test grass-session
/usr/bin/python3 /scripts/test_grass_session.py
# Test PDAL
grass --tmp-project EPSG:25832 --exec r.in.pdal input="/tmp/simple.laz" output="count_1" method="n" resolution=1 -g
Expand Down
25 changes: 12 additions & 13 deletions docker/debian/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ RUN apt-get update && apt-get upgrade -y && \
netcdf-bin \
proj-bin \
proj-data \
python-is-python3 \
python3 \
python3-dateutil \
python3-dev \
Expand Down Expand Up @@ -148,7 +149,6 @@ ENV CFLAGS "$MYCFLAGS"
ENV CXXFLAGS "$MYCXXFLAGS"

# Configure compile and install GRASS GIS
ENV GRASS_PYTHON=/usr/bin/python3
ENV NUMTHREADS=4
RUN make distclean || echo "nothing to clean"
RUN /src/grass_build/configure \
Expand Down Expand Up @@ -197,7 +197,7 @@ RUN ln -sf /usr/local/grass85 /usr/local/grass
# show GRASS GIS, PROJ, GDAL etc versions
RUN grass --tmp-project EPSG:4326 --exec g.version -rge && \
pdal --version && \
python3 --version
python --version

# Reduce the image size
RUN apt-get autoremove -y
Expand All @@ -206,24 +206,23 @@ RUN rm -r /src/grass_build/.git

WORKDIR /scripts

# install external GRASS GIS session Python API
RUN pip3 install grass-session --break-system-packages

# add GRASS GIS envs for python usage
ENV GISBASE "/usr/local/grass/"
ENV GRASSBIN "/usr/local/bin/grass"
ENV PYTHONPATH "${PYTHONPATH}:$GISBASE/etc/python/"
ENV LD_LIBRARY_PATH "$LD_LIBRARY_PATH:$GISBASE/lib"
# enable GRASS GIS Python session support
## grass --config python-path
ENV PYTHONPATH "/usr/local/grass/etc/python:${PYTHONPATH}"
# enable GRASS GIS ctypes imports
## grass --config path
ENV LD_LIBRARY_PATH "/usr/local/grass/lib:$LD_LIBRARY_PATH"

WORKDIR /tmp
COPY docker/testdata/simple.laz .
WORKDIR /scripts
COPY docker/testdata/test_grass_session.py .
## just scan the LAZ file
# Not yet ready for GRASS GIS 8:
#RUN /usr/bin/python3 /scripts/test_grass_session.py
## run GRASS GIS python session and scan the test LAZ file
RUN python /scripts/test_grass_session.py
RUN rm -rf /tmp/grasstest_epsg_25832
# test LAZ file
RUN grass --tmp-project EPSG:25832 --exec r.in.pdal input="/tmp/simple.laz" output="count_1" method="n" resolution=1 -g

WORKDIR /grassdb
VOLUME /grassdb
CMD ["$GRASSBIN", "--version"]
3 changes: 1 addition & 2 deletions docker/debian/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# Docker GRASS GIS (Debian Linux)

Dockerfile with an [Debian Linux](https://www.debian.org/) image with
[GRASS GIS](https://grass.osgeo.org/), [PDAL](https://pdal.io) support and
[grass-session](https://github.com/zarch/grass-session/).
[GRASS GIS](https://grass.osgeo.org/), [PDAL](https://pdal.io) support.

Download size of this image is of approximately 2.6 GB.

Expand Down
20 changes: 9 additions & 11 deletions docker/testdata/test_grass_session.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
# Import GRASS Python bindings
# https://github.com/zarch/grass-session
# pip install grass-session
# Import GRASS GIS Python bindings (requires 8.4+) and test r.in.pdal

# PYTHONPATH=$(grass --config python-path) python

from grass_session import Session
import grass.script as gs

# full path to new project
project = "/tmp/grasstest_epsg_25832"
gs.create_project(project, epsg="25832")

# hint: do not use ~ as an alias for HOME
with Session(
# run in PERMANENT mapset after creation of location "test"
gisdb="/grassdata/",
location="test",
create_opts="EPSG:25832",
):
print("grass-session: tests for PROJ, GDAL, PDAL, GRASS GIS")
with gs.setup.init(project):
print("GRASS GIS session: tests for PROJ, GDAL, PDAL, GRASS GIS")
print(gs.parse_command("g.gisenv", flags="s"))

# simple test: just scan the LAZ file
Expand Down
Loading

0 comments on commit 9f7ecdc

Please sign in to comment.