From d6510360d03118ffaf37967678fa35c5bf412da5 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 8 Feb 2018 16:29:07 -0800 Subject: [PATCH] GUACAMOLE-407: Dynamically derive runtime dependencies. --- Dockerfile | 68 ++++------------ src/guacd-docker/bin/link-freerdp-plugins.sh | 86 ++++++++++++++++++++ src/guacd-docker/bin/list-dependencies.sh | 48 +++++++++++ 3 files changed, 152 insertions(+), 50 deletions(-) create mode 100755 src/guacd-docker/bin/link-freerdp-plugins.sh create mode 100755 src/guacd-docker/bin/list-dependencies.sh diff --git a/Dockerfile b/Dockerfile index e2e632d6..79c884f7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -61,13 +61,20 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* # Add configuration scripts -COPY src/guacd-docker/bin /opt/guacd/bin/ +COPY src/guacd-docker/bin "${PREFIX_DIR}/bin/" # Copy source to container for sake of build COPY . "$BUILD_DIR" # Build guacamole-server from local source -RUN /opt/guacd/bin/build-guacd.sh "$BUILD_DIR" "$PREFIX_DIR" +RUN ${PREFIX_DIR}/bin/build-guacd.sh "$BUILD_DIR" "$PREFIX_DIR" + +# Record the packages of all runtime library dependencies +RUN ${PREFIX_DIR}/bin/list-dependencies.sh \ + ${PREFIX_DIR}/sbin/guacd \ + ${PREFIX_DIR}/lib/libguac-client-*.so \ + ${PREFIX_DIR}/lib/freerdp/guac*.so \ + > ${PREFIX_DIR}/DEPENDENCIES # Use same Ubuntu as the base for the runtime image FROM ubuntu:${UBUNTU_VERSION} @@ -85,62 +92,23 @@ ENV GUACD_LOG_LEVEL=info ARG RUNTIME_DEPENDENCIES=" \ ghostscript \ - libcairo2 \ + libfreerdp-plugins-standard \ fonts-liberation \ fonts-dejavu \ - libfreerdp-cache1.1 \ - libfreerdp-client1.1 \ - libfreerdp-codec1.1 \ - libfreerdp-common1.1.0 \ - libfreerdp-core1.1 \ - libfreerdp-crypto1.1 \ - libfreerdp-locale1.1 \ - libfreerdp-primitives1.1 \ - libfreerdp-plugins-standard \ - libfreerdp-utils1.1 \ - libjpeg-turbo8 \ - libossp-uuid16 \ - libpango1.0 \ - libpulse0 \ - libssh2-1 \ - libssl1.0.0 \ - libtelnet2 \ - libvncclient1 \ - libwebp5 \ - libwinpr-crt0.1 \ - libwinpr-dsparse0.1 \ - libwinpr-environment0.1 \ - libwinpr-file0.1 \ - libwinpr-handle0.1 \ - libwinpr-heap0.1 \ - libwinpr-input0.1 \ - libwinpr-interlocked0.1 \ - libwinpr-library0.1 \ - libwinpr-path0.1 \ - libwinpr-pool0.1 \ - libwinpr-registry0.1 \ - libwinpr-rpc0.1 \ - libwinpr-sspi0.1 \ - libwinpr-synch0.1 \ - libwinpr-sysinfo0.1 \ - libwinpr-thread0.1 \ - libwinpr-utils0.1 \ xfonts-terminus" -# Bring runtime environment up to date and install runtime dependencies -RUN apt-get update && \ - apt-get install -y $RUNTIME_DEPENDENCIES && \ - rm -rf /var/lib/apt/lists/* - # Copy build artifacts into this stage COPY --from=builder ${PREFIX_DIR} ${PREFIX_DIR} +# Bring runtime environment up to date and install runtime dependencies +RUN apt-get update && \ + apt-get install -y $RUNTIME_DEPENDENCIES && \ + apt-get install -y $(cat "${PREFIX_DIR}"/DEPENDENCIES) && \ + rm -rf /var/lib/apt/lists/* + # Link FreeRDP plugins into proper path -RUN FREERDP_DIR=$(dirname \ - $(dpkg-query -L libfreerdp-client1.1 | grep 'libfreerdp.*\.so' | head -n1)) && \ - FREERDP_PLUGIN_DIR="${FREERDP_DIR}/freerdp" && \ - mkdir -p "$FREERDP_PLUGIN_DIR" && \ - ln -s "$PREFIX_DIR"/lib/freerdp/*.so "$FREERDP_PLUGIN_DIR" +RUN ${PREFIX_DIR}/bin/link-freerdp-plugins.sh \ + ${PREFIX_DIR}/lib/freerdp/guac*.so # Expose the default listener port EXPOSE 4822 diff --git a/src/guacd-docker/bin/link-freerdp-plugins.sh b/src/guacd-docker/bin/link-freerdp-plugins.sh new file mode 100755 index 00000000..332d4c0f --- /dev/null +++ b/src/guacd-docker/bin/link-freerdp-plugins.sh @@ -0,0 +1,86 @@ +#!/bin/sh -e +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +## +## @fn link-freerdp-plugins.sh +## +## Automatically creates any required symbolic links for the proper loading of +## the given FreeRDP plugins. If a given plugin is already in the correct +## directory, no link is created for that plugin. +## +## @param ... +## The FreeRDP plugins to add links for. +## + +## +## Given the full path to a FreeRDP plugin, locates the base directory of the +## associated FreeRDP installation (where the FreeRDP library .so files are +## located), printing the result to STDOUT. If the directory cannot be +## determined, an error is printed. +## +## @param PLUGIN_FILE +## The full path to the FreeRDP plugin to check. +## +where_is_freerdp() { + + PLUGIN_FILE="$1" + + # Determine the location of all libfreerdp* libraries explicitly linked + # to given file + PATHS="$(ldd "$PLUGIN_FILE" \ + | awk '/=>/{print $(NF-1)}' \ + | grep 'libfreerdp' \ + | xargs -r dirname \ + | xargs -r realpath \ + | sort -u)" + + # Verify that exactly one location was found + if [ "$(echo "$PATHS" | wc -l)" != 1 ]; then + echo "$1: Unable to locate FreeRDP install location." >&2 + return 1 + fi + + echo "$PATHS" + +} + +# +# Create symbolic links as necessary to include all given plugins within the +# search path of FreeRDP +# + +while [ -n "$1" ]; do + + # Determine correct install location for FreeRDP plugins + FREERDP_DIR="$(where_is_freerdp "$1")" + FREERDP_PLUGIN_DIR="${FREERDP_DIR}/freerdp" + + # Add symbolic link if necessary + if [ ! -e "$FREERDP_PLUGIN_DIR/$(basename "$1")" ]; then + mkdir -p "$FREERDP_PLUGIN_DIR" + ln -s "$1" "$FREERDP_PLUGIN_DIR" + else + echo "$1: Already in correct directory." >&2 + fi + + shift + +done + diff --git a/src/guacd-docker/bin/list-dependencies.sh b/src/guacd-docker/bin/list-dependencies.sh new file mode 100755 index 00000000..090185e4 --- /dev/null +++ b/src/guacd-docker/bin/list-dependencies.sh @@ -0,0 +1,48 @@ +#!/bin/sh -e +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +## +## @fn list-dependencies.sh +## +## Lists the Debian/Ubuntu package names for all library dependencies of the +## given binaries. Each package is only listed once, even if multiple binaries +## provided by the same package are given. +## +## @param ... +## The full paths to all binaries being checked. +## + +while [ -n "$1" ]; do + + # For all non-Guacamole library dependencies + ldd "$1" | grep -v 'libguac' | awk '/=>/{print $(NF-1)}' \ + | while read LIBRARY; do + + # Determine the Debian package which is associated with that + # library, if any + dpkg-query -S "$LIBRARY" 2> /dev/null || true + + done + + # Next binary + shift + +done | cut -f1 -d: | sort -u +