mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
GUACAMOLE-374: Merge generalize Docker image to automatically map environment variables to properties.
This commit is contained in:
16
Dockerfile
16
Dockerfile
@@ -61,6 +61,9 @@ ENV \
|
||||
|
||||
# Add configuration scripts
|
||||
COPY guacamole-docker/bin/ /opt/guacamole/bin/
|
||||
COPY guacamole-docker/build.d/ /opt/guacamole/build.d/
|
||||
COPY guacamole-docker/entrypoint.d/ /opt/guacamole/entrypoint.d/
|
||||
COPY guacamole-docker/environment/ /opt/guacamole/environment/
|
||||
|
||||
# Copy source to container for sake of build
|
||||
COPY . "$BUILD_DIR"
|
||||
@@ -68,12 +71,14 @@ COPY . "$BUILD_DIR"
|
||||
# Run the build itself
|
||||
RUN /opt/guacamole/bin/build-guacamole.sh "$BUILD_DIR" /opt/guacamole
|
||||
|
||||
RUN rm -rf /opt/guacamole/build.d /opt/guacamole/bin/build-guacamole.sh
|
||||
|
||||
# For the runtime image, we start with the official Tomcat distribution
|
||||
FROM tomcat:${TOMCAT_VERSION}-${TOMCAT_JRE}
|
||||
|
||||
# Install XMLStarlet for server.xml alterations and unzip for LOGBACK_LEVEL case
|
||||
# Install XMLStarlet for server.xml alterations
|
||||
RUN apt-get update -qq \
|
||||
&& apt-get install -y xmlstarlet unzip\
|
||||
&& apt-get install -y xmlstarlet \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# This is where the build artifacts go in the runtime image
|
||||
@@ -91,6 +96,11 @@ RUN useradd --system --create-home --shell /usr/sbin/nologin --uid $UID --gid $G
|
||||
# Run with user guacamole
|
||||
USER guacamole
|
||||
|
||||
# Environment variable defaults
|
||||
ENV BAN_ENABLED=true \
|
||||
ENABLE_FILE_ENVIRONMENT_PROPERTIES=true \
|
||||
GUACAMOLE_HOME=/etc/guacamole
|
||||
|
||||
# Start Guacamole under Tomcat, listening on 0.0.0.0:8080
|
||||
EXPOSE 8080
|
||||
CMD ["/opt/guacamole/bin/start.sh" ]
|
||||
CMD ["/opt/guacamole/bin/entrypoint.sh" ]
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh -e
|
||||
#!/bin/bash -e
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
@@ -23,10 +23,15 @@
|
||||
##
|
||||
## Builds Guacamole, saving "guacamole.war" and all applicable extension .jars
|
||||
## using the guacamole-client source contained within the given directory.
|
||||
## Extension files will be grouped by their associated type, with all MySQL
|
||||
## files being placed within the "mysql/" subdirectory of the destination, all
|
||||
## PostgreSQL files being placed within the "postgresql/" subdirectory of the
|
||||
## destination, etc.
|
||||
## Extension files will be grouped by their associated type, identical to
|
||||
## extracting the .tar.gz files included with each Guacamole release except
|
||||
## that version numbers are stripped from directory and .jar file names.
|
||||
##
|
||||
## The build process is split across multiple scripts within the
|
||||
## /opt/guacamole/build.d directory. Additional steps may be added to the
|
||||
## build process by adding .sh scripts to this directory. Any such scripts MUST
|
||||
## be shell scripts ending with a ".sh" extension and MUST be written for bash
|
||||
## (the shell used by this entrypoint).
|
||||
##
|
||||
## @param BUILD_DIR
|
||||
## The directory which currently contains the guacamole-client source and
|
||||
@@ -39,164 +44,21 @@
|
||||
## extension type.
|
||||
##
|
||||
|
||||
##
|
||||
## The directory which currently contains the guacamole-client source and in
|
||||
## which the build should be performed.
|
||||
##
|
||||
BUILD_DIR="$1"
|
||||
|
||||
##
|
||||
## The directory to save guacamole.war within, along with all extension .jars.
|
||||
## Note that this script will create extension-specific subdirectories within
|
||||
## this directory, and files will thus be grouped by extension type.
|
||||
##
|
||||
DESTINATION="$2"
|
||||
|
||||
#
|
||||
# Create destination, if it does not yet exist
|
||||
#
|
||||
# Run all scripts within the "build.d" directory
|
||||
for SCRIPT in /opt/guacamole/build.d/*.sh; do
|
||||
source "$SCRIPT"
|
||||
done
|
||||
|
||||
mkdir -p "$DESTINATION"
|
||||
|
||||
#
|
||||
# Build guacamole.war and all extensions
|
||||
#
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
#
|
||||
# Run the maven build, applying any arbitrary provided maven arguments.
|
||||
#
|
||||
|
||||
mvn $MAVEN_ARGUMENTS package
|
||||
|
||||
#
|
||||
# Copy guacamole.war to destination
|
||||
#
|
||||
|
||||
cp guacamole/target/*.war "$DESTINATION/guacamole.war"
|
||||
|
||||
#
|
||||
# Copy JDBC auth extensions and SQL scripts
|
||||
#
|
||||
|
||||
tar -xzf extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-dist/target/*.tar.gz \
|
||||
-C "$DESTINATION" \
|
||||
--wildcards \
|
||||
--no-anchored \
|
||||
--strip-components=1 \
|
||||
"*.jar" \
|
||||
"*.sql"
|
||||
|
||||
#
|
||||
# Download MySQL JDBC driver
|
||||
#
|
||||
|
||||
echo "Downloading MySQL Connector/J ..."
|
||||
curl -L "https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-j-$MYSQL_JDBC_VERSION.tar.gz" | \
|
||||
tar -xz \
|
||||
-C "$DESTINATION/mysql/" \
|
||||
--wildcards \
|
||||
--no-anchored \
|
||||
--no-wildcards-match-slash \
|
||||
--strip-components=1 \
|
||||
"mysql-connector-*.jar"
|
||||
|
||||
#
|
||||
# Download PostgreSQL JDBC driver
|
||||
#
|
||||
|
||||
echo "Downloading PostgreSQL JDBC driver ..."
|
||||
curl -L "https://jdbc.postgresql.org/download/postgresql-$PGSQL_JDBC_VERSION.jar" \
|
||||
> "$DESTINATION/postgresql/postgresql-$PGSQL_JDBC_VERSION.jar"
|
||||
|
||||
#
|
||||
# Copy SSO auth extensions
|
||||
#
|
||||
|
||||
tar -xzf extensions/guacamole-auth-sso/modules/guacamole-auth-sso-dist/target/*.tar.gz \
|
||||
-C "$DESTINATION" \
|
||||
--wildcards \
|
||||
--no-anchored \
|
||||
--strip-components=1 \
|
||||
"*.jar"
|
||||
|
||||
#
|
||||
# Download SQL Server JDBC driver
|
||||
#
|
||||
|
||||
echo "Downloading SQL Server JDBC driver ..."
|
||||
curl -L "https://github.com/microsoft/mssql-jdbc/releases/download/v$MSSQL_JDBC_VERSION/mssql-jdbc-$MSSQL_JDBC_VERSION.jre8.jar" \
|
||||
> "$DESTINATION/sqlserver/mssql-jdbc-$MSSQL_JDBC_VERSION.jre8.jar" \
|
||||
|
||||
#
|
||||
# Copy LDAP auth extension and schema modifications
|
||||
#
|
||||
|
||||
mkdir -p "$DESTINATION/ldap"
|
||||
tar -xzf extensions/guacamole-auth-ldap/target/*.tar.gz \
|
||||
-C "$DESTINATION/ldap" \
|
||||
--wildcards \
|
||||
--no-anchored \
|
||||
--xform="s#.*/##" \
|
||||
"*.jar" \
|
||||
"*.ldif"
|
||||
|
||||
#
|
||||
# Copy Radius auth extension if it was build
|
||||
#
|
||||
|
||||
if [ -f extensions/guacamole-auth-radius/target/guacamole-auth-radius*.jar ]; then
|
||||
mkdir -p "$DESTINATION/radius"
|
||||
cp extensions/guacamole-auth-radius/target/guacamole-auth-radius*.jar "$DESTINATION/radius"
|
||||
fi
|
||||
|
||||
#
|
||||
# Copy TOTP auth extension if it was built
|
||||
#
|
||||
|
||||
if [ -f extensions/guacamole-auth-totp/target/guacamole-auth-totp*.jar ]; then
|
||||
mkdir -p "$DESTINATION/totp"
|
||||
cp extensions/guacamole-auth-totp/target/guacamole-auth-totp*.jar "$DESTINATION/totp"
|
||||
fi
|
||||
|
||||
#
|
||||
# Copy Duo auth extension if it was built
|
||||
#
|
||||
|
||||
if [ -f extensions/guacamole-auth-duo/target/*.tar.gz ]; then
|
||||
mkdir -p "$DESTINATION/duo"
|
||||
tar -xzf extensions/guacamole-auth-duo/target/*.tar.gz \
|
||||
-C "$DESTINATION/duo/" \
|
||||
--wildcards \
|
||||
--no-anchored \
|
||||
--no-wildcards-match-slash \
|
||||
--strip-components=1 \
|
||||
"*.jar"
|
||||
fi
|
||||
|
||||
#
|
||||
# Copy header auth extension if it was built
|
||||
#
|
||||
|
||||
if [ -f extensions/guacamole-auth-header/target/guacamole-auth-header*.jar ]; then
|
||||
mkdir -p "$DESTINATION/header"
|
||||
cp extensions/guacamole-auth-header/target/guacamole-auth-header*.jar "$DESTINATION/header"
|
||||
fi
|
||||
|
||||
#
|
||||
# Copy json auth extension if it was built
|
||||
#
|
||||
|
||||
if [ -f extensions/guacamole-auth-json/target/guacamole-auth-json*.jar ]; then
|
||||
mkdir -p "$DESTINATION/json"
|
||||
cp extensions/guacamole-auth-json/target/guacamole-auth-json*.jar "$DESTINATION/json"
|
||||
fi
|
||||
|
||||
#
|
||||
# Copy automatic brute-force banning auth extension if it was built
|
||||
#
|
||||
|
||||
if [ -f extensions/guacamole-auth-ban/target/guacamole-auth-ban*.jar ]; then
|
||||
mkdir -p "$DESTINATION/ban"
|
||||
cp extensions/guacamole-auth-ban/target/guacamole-auth-ban*.jar "$DESTINATION/ban"
|
||||
fi
|
||||
|
||||
#
|
||||
# Copy history recording storage extension if it was built
|
||||
#
|
||||
|
||||
if [ -f extensions/guacamole-history-recording-storage/target/guacamole-history-recording-storage*.jar ]; then
|
||||
mkdir -p "$DESTINATION/recordings"
|
||||
cp extensions/guacamole-history-recording-storage/target/guacamole-history-recording-storage*.jar "$DESTINATION/recordings"
|
||||
fi
|
||||
|
39
guacamole-docker/bin/entrypoint.sh
Executable file
39
guacamole-docker/bin/entrypoint.sh
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash -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 entrypoint.sh
|
||||
##
|
||||
## (Re-)configures the Apache Guacamole web application based on the values of
|
||||
## environment variables, deploys the web application beneath a bundled copy of
|
||||
## Apache Tomcat, and starts Tomcat.
|
||||
##
|
||||
## The startup process is split across multiple scripts within the
|
||||
## /opt/guacamole/entrypoint.d directory. Additional steps may be added to the
|
||||
## startup process by adding .sh scripts to this directory. Any such scripts
|
||||
## MUST be shell scripts ending with a ".sh" extension and MUST be written for
|
||||
## bash (the shell used by this entrypoint).
|
||||
##
|
||||
|
||||
# Run all scripts within the "entrypoint.d" directory
|
||||
for SCRIPT in /opt/guacamole/entrypoint.d/*.sh; do
|
||||
source "$SCRIPT"
|
||||
done
|
||||
|
File diff suppressed because it is too large
Load Diff
62
guacamole-docker/build.d/000-build-and-install-guacamole.sh
Normal file
62
guacamole-docker/build.d/000-build-and-install-guacamole.sh
Normal file
@@ -0,0 +1,62 @@
|
||||
#
|
||||
# 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 010-build-and-install-guacamole.sh
|
||||
##
|
||||
## Builds the Guacamole web application and all main extensions, installing the
|
||||
## resulting binaries to standard locations within the Docker image. After the
|
||||
## build and install process, the resulting binaries can be found beneath:
|
||||
##
|
||||
## /opt/guacamole/webapp:
|
||||
## The web application, "guacamole.war".
|
||||
##
|
||||
## /opt/guacamole/extensions:
|
||||
## All extensions, each within their own subdirectory and identical to the
|
||||
## result of extracting a released .tar.gz except that version numbers of been
|
||||
## stripped.
|
||||
##
|
||||
|
||||
#
|
||||
# Build guacamole.war and all extensions, applying any provided Maven build
|
||||
# arguments
|
||||
#
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
mvn $MAVEN_ARGUMENTS package
|
||||
|
||||
#
|
||||
# Copy built web application (guacamole.war) to destination location
|
||||
#
|
||||
|
||||
mkdir -p "$DESTINATION/webapp"
|
||||
cp guacamole/target/*.war "$DESTINATION/webapp/guacamole.war"
|
||||
|
||||
#
|
||||
# Extract all extensions to destination location, stripping version number
|
||||
# suffix from .jar files and top-level directory name
|
||||
#
|
||||
|
||||
mkdir -p "$DESTINATION/extensions"
|
||||
find extensions/ -path "**/target/*.tar.gz" -exec tar -xzf "{}" \
|
||||
-C "$DESTINATION/extensions" \
|
||||
--xform='s#^\([^/]*\)-[0-9]\+\.[0-9]\+\.[0-9]\+#\1#g' \
|
||||
--xform='s#-[0-9]\+\.[0-9]\+\.[0-9]\+\(\.jar$\)#\1#g' \
|
||||
";"
|
||||
|
118
guacamole-docker/build.d/010-map-guacamole-extensions.sh
Normal file
118
guacamole-docker/build.d/010-map-guacamole-extensions.sh
Normal file
@@ -0,0 +1,118 @@
|
||||
#
|
||||
# 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 020-map-guacamole-extensions.sh
|
||||
##
|
||||
## Maps all installed Guacamole extensions (built in a previous step) to their
|
||||
## corresponding environment variable prefixes, adding symbolic links so that
|
||||
## the changes to the contents of GUACAMOLE_HOME can be easily made by the
|
||||
## container's entrypoint based on which environment variables are set, without
|
||||
## requiring that the entrypoint be specifically aware of all supported
|
||||
## environment variables.
|
||||
##
|
||||
|
||||
##
|
||||
## Reads a mapping of Guacamole extension to environment variable prefix from
|
||||
## STDIN, creating a hierarchy of directories and symbolic links on the
|
||||
## filesystem that can be easily consumed by the container's entrypoint later.
|
||||
##
|
||||
## Each mapping consists of a single line with two values separated by
|
||||
## whitespace, where the first (leftmost) value is the path to the directory
|
||||
## containing the extension .jar file (relative to /opt/guacamole/extensions)
|
||||
## and the second (rightmost) value is the environment variable prefix used by
|
||||
## that extension. For readability, periods may be used in lieu of spaces.
|
||||
##
|
||||
## After mapping has occurred, the resulting mappings are located beneath
|
||||
## /opt/guacamole/environment. They consist of directories named after the
|
||||
## provided environment variable prefixes, where the contents of those
|
||||
## directories are subsets of the contents of GUACAMOLE_HOME that would need to
|
||||
## be added to the actual GUACAMOLE_HOME to enable that extension.
|
||||
##
|
||||
map_extensions() {
|
||||
|
||||
# Read through each provided path/prefix mapping pair
|
||||
mkdir -p "$DESTINATION/environment"
|
||||
tr . ' ' | while read -r EXT_PATH VAR_PREFIX; do
|
||||
|
||||
# Add mappings only for extensions that were actually built as part of
|
||||
# the build process (some extensions, like the RADIUS support, will
|
||||
# only be built if specific build arguments are provided)
|
||||
if [ -d "$DESTINATION/extensions/$EXT_PATH/" ]; then
|
||||
echo "Mapped: $EXT_PATH -> $VAR_PREFIX"
|
||||
mkdir -p "$DESTINATION/environment/$VAR_PREFIX/extensions"
|
||||
ln -s "$DESTINATION/extensions/$EXT_PATH"/*.jar "$DESTINATION/environment/$VAR_PREFIX/extensions/"
|
||||
else
|
||||
echo "Skipped: $EXT_PATH (not built)"
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# This section is a mapping of all bundled extensions to their corresponding
|
||||
# variable prefixes. Each line consists of a whitespace-separated pair of
|
||||
# extension path (the relative directory containing the .jar file) to that
|
||||
# extension's variable prefix. For readability, a period may be used in lieu of
|
||||
# a space.
|
||||
#
|
||||
# NOTES:
|
||||
#
|
||||
# (1) The actual variables used by each extension are not determined here, but
|
||||
# rather by the transformation of their configuration properties to variables
|
||||
# ("lowercase-with-dashes" to "UPPERCASE_WITH_UNDERSCORES"). The variable
|
||||
# prefixes listed here should be chosen to match the prefixes resulting from
|
||||
# that transformation of the extensions' properties.
|
||||
#
|
||||
# (2) The paths on the left side of this mapping are the paths of the extension
|
||||
# .jar files relative to the "/opt/guacamole/extensions" directory used by the
|
||||
# container to store extensions prior to use. They are identical to the paths
|
||||
# used by the distribution .tar.gz files provided with each Guacamole release,
|
||||
# except that the version numbers have been stripped from the top-level path.
|
||||
#
|
||||
# (3) The script processing this file uses these prefixes to define and process
|
||||
# an additional "ENABLED" variable (ie: "BAN_ENABLED", "TOTP_ENABLED", etc.)
|
||||
# that can be used to enable/disable an extension entirely regardless of the
|
||||
# presence/absence of other variables with the prefix. This allows extensions
|
||||
# that need no configuration to be easily enabled. It also allows extensions
|
||||
# that already have configuration present to be easily disabled without
|
||||
# requiring that all other configuration be removed.
|
||||
#
|
||||
map_extensions <<'EOF'
|
||||
guacamole-auth-ban..........................BAN_
|
||||
guacamole-auth-duo..........................DUO_
|
||||
guacamole-auth-header.......................HTTP_AUTH_
|
||||
guacamole-auth-jdbc/mysql...................MYSQL_
|
||||
guacamole-auth-jdbc/postgresql..............POSTGRESQL_
|
||||
guacamole-auth-jdbc/sqlserver...............SQLSERVER_
|
||||
guacamole-auth-json.........................JSON_
|
||||
guacamole-auth-ldap.........................LDAP_
|
||||
guacamole-auth-quickconnect.................QUICKCONNECT_
|
||||
guacamole-auth-radius.......................RADIUS_
|
||||
guacamole-auth-sso/cas......................CAS_
|
||||
guacamole-auth-sso/openid...................OPENID_
|
||||
guacamole-auth-sso/saml.....................SAML_
|
||||
guacamole-auth-sso/ssl......................SSL_
|
||||
guacamole-auth-totp.........................TOTP_
|
||||
guacamole-display-statistics................DISPLAY_STATISTICS_
|
||||
guacamole-history-recording-storage.........RECORDING_
|
||||
guacamole-vault/ksm.........................KSM_
|
||||
EOF
|
||||
|
99
guacamole-docker/build.d/020-download-drivers.sh
Normal file
99
guacamole-docker/build.d/020-download-drivers.sh
Normal file
@@ -0,0 +1,99 @@
|
||||
#
|
||||
# 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 030-download-drivers.sh
|
||||
##
|
||||
## Downloads all JDBC drivers required by the various supported databases. Each
|
||||
## downloaded driver is stored beneath /opt/guacamole/drivers, with symbolic
|
||||
## links added to the mappings beneath /opt/guacamole/environment to ensure any
|
||||
## required drivers are added to GUACAMOLE_HOME if necessary to support a
|
||||
## requested database.
|
||||
##
|
||||
|
||||
##
|
||||
## Downloads the JDBC driver at the given URL, storing the driver's .jar file
|
||||
## under the given name and environment variable prefix. The downloaded .jar
|
||||
## file is stored such that it is pulled into GUACAMOLE_HOME automatically if
|
||||
## environment variables with that prefix are used.
|
||||
##
|
||||
## If the URL is for a .tar.gz file and not a .jar file, the .jar will be
|
||||
## automatically extracted from the .tar.gz as it is downloaded.
|
||||
##
|
||||
## @param VAR_PREFIX
|
||||
## The environment variable prefix used by the extension that requires the
|
||||
## driver.
|
||||
##
|
||||
## @param URL
|
||||
## The URL that the driver should be downloaded from.
|
||||
##
|
||||
## @param DEST_JAR
|
||||
## The filename to assign to the downloaded .jar file. This is mainly
|
||||
## needed to ensure that the drivers bundled with the image have names that
|
||||
## are predictable and reliable enough that they can be consumed by
|
||||
## third-party use of this image.
|
||||
##
|
||||
download_driver() {
|
||||
|
||||
local VAR_PREFIX="$1"
|
||||
local URL="$2"
|
||||
local DEST_JAR="$3"
|
||||
|
||||
# Ensure primary destination path for .jar file exists
|
||||
local DEST_PATH="$DESTINATION/drivers/"
|
||||
mkdir -p "$DEST_PATH"
|
||||
|
||||
# Download requested .jar file, extracting from .tar.gz if necessary
|
||||
if [[ "$URL" == *.tar.gz ]]; then
|
||||
curl -L "$URL" | tar -xz \
|
||||
--wildcards \
|
||||
--no-anchored \
|
||||
--no-wildcards-match-slash \
|
||||
--to-stdout \
|
||||
"*.jar" > "$DEST_PATH/$DEST_JAR"
|
||||
else
|
||||
curl -L "$URL" > "$DEST_PATH/$DEST_JAR"
|
||||
fi
|
||||
|
||||
# Add any required link to ensure the .jar file is loaded along with the
|
||||
# extension that requires it
|
||||
mkdir -p "$DESTINATION/environment/$VAR_PREFIX/lib"
|
||||
ln -s "$DEST_PATH/$DEST_JAR" "$DESTINATION/environment/$VAR_PREFIX/lib/"
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# Download and link any required JDBC drivers
|
||||
#
|
||||
|
||||
# MySQL JDBC driver
|
||||
download_driver "MYSQL_" \
|
||||
"https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-j-$MYSQL_JDBC_VERSION.tar.gz" \
|
||||
"mysql-jdbc.jar"
|
||||
|
||||
# PostgreSQL JDBC driver
|
||||
download_driver "POSTGRESQL_" \
|
||||
"https://jdbc.postgresql.org/download/postgresql-$PGSQL_JDBC_VERSION.jar" \
|
||||
"postgresql-jdbc.jar"
|
||||
|
||||
# SQL Server JDBC driver
|
||||
download_driver "SQLSERVER_" \
|
||||
"https://github.com/microsoft/mssql-jdbc/releases/download/v$MSSQL_JDBC_VERSION/mssql-jdbc-$MSSQL_JDBC_VERSION.jre8.jar" \
|
||||
"mssql-jdbc.jar"
|
||||
|
47
guacamole-docker/build.d/999-verify-sanity.sh
Normal file
47
guacamole-docker/build.d/999-verify-sanity.sh
Normal file
@@ -0,0 +1,47 @@
|
||||
#
|
||||
# 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 999-verify-sanity.sh
|
||||
##
|
||||
## Performs sanity checks on the results of the build that verify the image
|
||||
## contains everything it is expected to contain, including all built
|
||||
## extensions. If symbolic links were not correctly constructed, or some built
|
||||
## extensions were not mapped to environment variable prefixes, this script
|
||||
## will log errors and fail the build.
|
||||
##
|
||||
|
||||
# Perform basic sanity checks that the symbolic links used to associated
|
||||
# environment variables with extensions/libraries have been correctly created,
|
||||
# bailing out if any problems are found.
|
||||
(
|
||||
|
||||
# Search for any broken symbolic links intended to map files for
|
||||
# environment variables
|
||||
find "$DESTINATION/environment/" -xtype l | sed 's/^/Broken link: /'
|
||||
|
||||
# Search for extensions that have not been mapped to any environment
|
||||
# variables at all
|
||||
comm -23 \
|
||||
<(find "$DESTINATION/extensions/" -name "*.jar" -exec realpath "{}" ";" | sort -u) \
|
||||
<(find "$DESTINATION/environment/" -path "**/extensions/*.jar" -exec realpath "{}" ";" | sort -u) \
|
||||
| sed 's/^/Unmapped extension: /'
|
||||
|
||||
) | sed 's/^/ERROR: /' | (! grep .) >&2 || exit 1
|
||||
|
116
guacamole-docker/entrypoint.d/000-migrate-legacy-variables.sh
Normal file
116
guacamole-docker/entrypoint.d/000-migrate-legacy-variables.sh
Normal file
@@ -0,0 +1,116 @@
|
||||
#
|
||||
# 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 000-migrate-legacy-variables.sh
|
||||
##
|
||||
## Checks for usage of any environment variables that were formerly supported
|
||||
## but are now deprecated, warning when any deprecated variables are
|
||||
## encountered. Until support for a deprecated variable is entirely removed,
|
||||
## the value provided for the deprecated variable is automatically assigned to
|
||||
## the currently-supported variable.
|
||||
##
|
||||
|
||||
##
|
||||
## Checks for usage of the given deprecated environment variable, automatically
|
||||
## assigning its value to the given currently-supported environment variable.
|
||||
## If usage of the deprecated variable is found, a warning is printed to
|
||||
## STDERR.
|
||||
##
|
||||
## @param LEGACY_VAR_NAME
|
||||
## The name of the environment variable that's deprecated.
|
||||
##
|
||||
## @param CURRENT_VAR_NAME
|
||||
## The name of the environment variable that is currently supported and
|
||||
## replaces the deprecated variable.
|
||||
##
|
||||
deprecate_variable() {
|
||||
|
||||
local LEGACY_VAR_NAME="$1"
|
||||
local CURRENT_VAR_NAME="$2"
|
||||
|
||||
if [ -n "${!LEGACY_VAR_NAME}" ]; then
|
||||
echo "WARNING: The \"$LEGACY_VAR_NAME\" environment variable has been deprecated in favor of \"$CURRENT_VAR_NAME\". Please migrate your configuration when possible, as support for the older name may be removed in future releases." >&2
|
||||
export "$CURRENT_VAR_NAME"="${!LEGACY_VAR_NAME}"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
##
|
||||
## Checks for usage of any environment variables using the given deprecated
|
||||
## prefix, automatically assigning their values to corresponding environment
|
||||
## variables having the given currently-supported prefix. If usage of the
|
||||
## deprecated prefix is found, a warning is printed to STDERR.
|
||||
##
|
||||
## @param LEGACY_VAR_PREFIX
|
||||
## The environment variable prefix that's deprecated.
|
||||
##
|
||||
## @param CURRENT_VAR_PREFIX
|
||||
## The environment variable prefix that is currently supported and
|
||||
## replaces the deprecated variable prefix.
|
||||
##
|
||||
deprecate_variable_prefix() {
|
||||
|
||||
local LEGACY_VAR_PREFIX="$1"
|
||||
local CURRENT_VAR_PREFIX="$2"
|
||||
|
||||
local LEGACY_VAR_NAME
|
||||
local CURRENT_VAR_NAME
|
||||
local HAS_LEGACY_VARIABLES=0
|
||||
|
||||
# Automatically reassign all "POSTGRES_*" variables to "POSTGRESQL_*"
|
||||
while read -r LEGACY_VAR_NAME; do
|
||||
HAS_LEGACY_VARIABLES=1
|
||||
CURRENT_VAR_NAME="$CURRENT_VAR_PREFIX${LEGACY_VAR_NAME#$LEGACY_VAR_PREFIX}"
|
||||
export "$CURRENT_VAR_NAME"="${!LEGACY_VAR_NAME}"
|
||||
unset "$LEGACY_VAR_NAME"
|
||||
done < <(awk 'BEGIN{for(v in ENVIRON) print v}' | grep "^$LEGACY_VAR_PREFIX")
|
||||
|
||||
if [ "$HAS_LEGACY_VARIABLES" = "1" ]; then
|
||||
echo "WARNING: The \"$LEGACY_VAR_PREFIX\" prefix for environment variables has been deprecated in favor of the \"$CURRENT_VAR_PREFIX\" prefix. Please migrate your configuration when possible, as support for the older prefix may be removed in future releases." >&2
|
||||
export "$CURRENT_VAR_NAME"="$LEGACY_VAR_NAME"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# The old "*_USER" style for configuring the user account to be used to access
|
||||
# the database is being replaced with "*_USERNAME" such that all environment
|
||||
# variables exactly correspond to the names of configuration properties from
|
||||
# guacamole.properties.
|
||||
deprecate_variable "MYSQL_USER" "MYSQL_USERNAME"
|
||||
deprecate_variable "POSTGRES_USER" "POSTGRESQL_USERNAME"
|
||||
deprecate_variable "SQLSERVER_USER" "SQLSERVER_USERNAME"
|
||||
|
||||
# The old "POSTGRES_" prefix for configuring usage of PostgreSQL is being
|
||||
# replaced with "POSTGRESQL_" such that all environment variables exactly
|
||||
# correspond to the names of configuration properties from
|
||||
# guacamole.properties.
|
||||
deprecate_variable_prefix "POSTGRES_" "POSTGRESQL_"
|
||||
|
||||
# The old "PROXY_*" names for attributes supported by RemoteIpValve are being
|
||||
# replaced with "REMOTE_IP_VALVE_*" attributes that more closely and
|
||||
# predictably match their attribute names
|
||||
deprecate_variable "PROXY_ALLOWED_IPS_REGEX" "REMOTE_IP_VALVE_INTERNAL_PROXIES"
|
||||
deprecate_variable "PROXY_IP_HEADER" "REMOTE_IP_VALVE_REMOTE_IP_HEADER"
|
||||
deprecate_variable "PROXY_PROTOCOL_HEADER" "REMOTE_IP_VALVE_PROTOCOL_HEADER"
|
||||
# NOTE: PROXY_BY_HEADER never worked as there is no "remoteIpProxiesHeader" attribute for RemoteIpValve
|
||||
|
||||
# The old "LOGBACK_LEVEL" environment variable has been replaced with
|
||||
# "LOG_LEVEL" for consistency with the guacd image
|
||||
deprecate_variable "LOGBACK_LEVEL" "LOG_LEVEL"
|
111
guacamole-docker/entrypoint.d/100-generate-guacamole-home.sh
Normal file
111
guacamole-docker/entrypoint.d/100-generate-guacamole-home.sh
Normal file
@@ -0,0 +1,111 @@
|
||||
#
|
||||
# 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 010-generate-guacamole-home.sh
|
||||
##
|
||||
## Automatically generates a temporary, skeleton GUACAMOLE_HOME to be used for
|
||||
## this run of the container. GUACAMOLE_HOMEs from previous runs are
|
||||
## automatically deleted prior to creating the new skeleton. A
|
||||
## randomly-generated temporary directory is used instead of a standard
|
||||
## directory like "/etc/guacamole" to allow users to use "/etc/guacamole" as a
|
||||
## basis for their own configuration.
|
||||
##
|
||||
|
||||
##
|
||||
## The directory to copy/link over as a basis for the GUACAMOLE_HOME actually
|
||||
## used by the Guacamole web application. Any configuration generated by this
|
||||
## container will be overlaid on top of this configuration. To achieve the
|
||||
## overlay, symbolic links will be created for all files inside and beneath
|
||||
## this directory. Only the guacamole.properties file will be copied instead of
|
||||
## using symbolic links (to ensure property generation performed by the
|
||||
## container does not potentially modify an external file).
|
||||
##
|
||||
GUACAMOLE_HOME_TEMPLATE="$GUACAMOLE_HOME"
|
||||
|
||||
##
|
||||
## Tests whether a given property is set within the guacamole.properties file
|
||||
## in GUACAMOLE_HOME.
|
||||
##
|
||||
## @param PROPERTY_NAME
|
||||
## The name of the property to check.
|
||||
##
|
||||
## @returns
|
||||
## Zero if the given property is set to any value within
|
||||
## guacamole.properties, non-zero otherwise.
|
||||
##
|
||||
is_property_set() {
|
||||
local PROPERTY_NAME="$1"
|
||||
grep "^[[:space:]]*$PROPERTY_NAME\>" "$GUACAMOLE_HOME/guacamole.properties" &> /dev/null
|
||||
}
|
||||
|
||||
#
|
||||
# Start with a fresh GUACAMOLE_HOME
|
||||
#
|
||||
|
||||
rm -rf /tmp/guacamole-home.*
|
||||
GUACAMOLE_HOME="`mktemp -p /tmp -d guacamole-home.XXXXXXXXXX`"
|
||||
mkdir -p "$GUACAMOLE_HOME/"{lib,extensions}
|
||||
|
||||
cat > "$GUACAMOLE_HOME/guacamole.properties" <<EOF
|
||||
# guacamole.properties - generated `date`
|
||||
EOF
|
||||
|
||||
#
|
||||
# Copy contents of provided GUACAMOLE_HOME template, if any
|
||||
#
|
||||
|
||||
if [ -e "$GUACAMOLE_HOME_TEMPLATE" ]; then
|
||||
|
||||
# Create links for any libraries provided in the template GUACAMOLE_HOME
|
||||
find "$GUACAMOLE_HOME_TEMPLATE/lib" -mindepth 1 -maxdepth 1 \
|
||||
-exec ln -sv "{}" "$GUACAMOLE_HOME/lib/" ";"
|
||||
|
||||
# Create links for any extensions provided in the template GUACAMOLE_HOME
|
||||
find "$GUACAMOLE_HOME_TEMPLATE/extensions" -mindepth 1 -maxdepth 1 \
|
||||
-exec ln -sv "{}" "$GUACAMOLE_HOME/extensions/" ";"
|
||||
|
||||
# Create links for all other files directly within the template
|
||||
# GUACAMOLE_HOME
|
||||
find "$GUACAMOLE_HOME_TEMPLATE" -mindepth 1 -maxdepth 1 \
|
||||
-name guacamole.properties -o -name lib -o -name extensions -prune \
|
||||
-o -exec ln -sv "{}" "$GUACAMOLE_HOME/" ";"
|
||||
|
||||
# Add any properties provided within template GUACAMOLE_HOME
|
||||
if [ -e "$GUACAMOLE_HOME_TEMPLATE/guacamole.properties" ]; then
|
||||
cat "$GUACAMOLE_HOME_TEMPLATE/guacamole.properties" >> "$GUACAMOLE_HOME/guacamole.properties"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# Enable reading of properties directly from environment variables unless
|
||||
# overridden
|
||||
if ! is_property_set "enable-environment-properties"; then
|
||||
cat >> "$GUACAMOLE_HOME/guacamole.properties" <<'EOF'
|
||||
#
|
||||
# NOTE: The following was automatically added by the container entrypoint to
|
||||
# allow all Guacamole configuration properties to be automatically read from
|
||||
# environment variables. If this is not desired, you can override this behavior
|
||||
# by specifying the "enable-environment-properties" variable yourself in your
|
||||
# own guacamole.properties file.
|
||||
#
|
||||
enable-environment-properties: true
|
||||
EOF
|
||||
fi
|
||||
|
@@ -0,0 +1,50 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
##
|
||||
## 500-generate-tomcat-catalina-base.sh
|
||||
##
|
||||
## Automcatically generates a fresh, temporary CATALINA_BASE for Apache Tomcat.
|
||||
## This allows Tomcat to run as a reduced-privilege user, and allows its
|
||||
## configuration to be dynamically generated by the container entrypoint at
|
||||
## startup.
|
||||
##
|
||||
|
||||
#
|
||||
# Start with a fresh CATALINA_BASE
|
||||
#
|
||||
|
||||
rm -rf /tmp/catalina-base.*
|
||||
export CATALINA_BASE="`mktemp -p /tmp -d catalina-base.XXXXXXXXXX`"
|
||||
|
||||
# User-only writable CATALINA_BASE
|
||||
for dir in logs temp webapps work; do
|
||||
mkdir -p $CATALINA_BASE/$dir
|
||||
done
|
||||
cp -R /usr/local/tomcat/conf $CATALINA_BASE
|
||||
|
||||
cat >> "$CATALINA_BASE/conf/catalina.properties" <<EOF
|
||||
|
||||
# Point Guacamole at automatically-generated, temporary GUACAMOLE_HOME
|
||||
guacamole.home=$GUACAMOLE_HOME
|
||||
EOF
|
||||
|
||||
# Install webapp
|
||||
ln -sf /opt/guacamole/webapp/guacamole.war $CATALINA_BASE/webapps/${WEBAPP_CONTEXT:-guacamole}.war
|
||||
|
88
guacamole-docker/entrypoint.d/700-configure-features.sh
Normal file
88
guacamole-docker/entrypoint.d/700-configure-features.sh
Normal file
@@ -0,0 +1,88 @@
|
||||
#
|
||||
# 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 800-configure-features.sh
|
||||
##
|
||||
## Automatically checks all environment variables currently set and performs
|
||||
## configuration tasks related to those variabels, including installing any
|
||||
## extensions and external libraries associated with those variables to
|
||||
## GUACAMOLE_HOME. Only environment variable prefixes are considered; this
|
||||
## script is not aware of whether an extension actually uses an environment
|
||||
## variable.
|
||||
##
|
||||
|
||||
##
|
||||
## Returns whether the feature associated with a particular environment
|
||||
## variable prefix has configuration values set. Only the presence of
|
||||
## environment variables having that prefix is checked. Features can also be
|
||||
## entirely enabled/disabled through setting the [PREFIX_]ENABLED variable to
|
||||
## true/false respectively, where "[PREFIX_]" is the specified environment
|
||||
## variable prefix (including trailing underscore).
|
||||
##
|
||||
## @param VAR_BASE
|
||||
## The environment variable prefix to check, including trailing underscore.
|
||||
##
|
||||
## @returns
|
||||
## Zero if the feature associated with the given environment variable
|
||||
## prefix is enabled, non-zero otherwise.
|
||||
##
|
||||
is_feature_enabled() {
|
||||
|
||||
local VAR_BASE="$1"
|
||||
|
||||
# Allow any feature to be explicitly enabled/disabled using a
|
||||
# [PREFIX_]ENABLED variable
|
||||
local ENABLED_VAR="${VAR_BASE}ENABLED"
|
||||
if [ "${!ENABLED_VAR}" = "true" ]; then
|
||||
return 0
|
||||
elif [ "${!ENABLED_VAR}" = "false" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Lacking an explicit request to enable/disable the feature, rely on
|
||||
# implicit enable/disable via presence of any other variables having the
|
||||
# given prefix
|
||||
awk 'BEGIN{for(v in ENVIRON) print v}' | grep "^${VAR_BASE}" > /dev/null
|
||||
|
||||
}
|
||||
|
||||
# Search environment for enabled extensions/features based on environment
|
||||
# variable prefixes
|
||||
for VAR_BASE in /opt/guacamole/environment/*; do
|
||||
|
||||
# Skip any directories without at least one corresponding environment
|
||||
# variable set
|
||||
is_feature_enabled "$(basename "$VAR_BASE")" || continue
|
||||
|
||||
# Execute any associated configuration script
|
||||
[ ! -e "$VAR_BASE/configure.sh" ] || source "$VAR_BASE/configure.sh"
|
||||
|
||||
# Add any required links for extensions/libraries associated with the
|
||||
# configured extension
|
||||
for SUBDIR in lib extensions; do
|
||||
if [ -d "$VAR_BASE/$SUBDIR" ]; then
|
||||
mkdir -p "$GUACAMOLE_HOME/$SUBDIR/"
|
||||
ln -s "$VAR_BASE/$SUBDIR"/* "$GUACAMOLE_HOME/$SUBDIR/"
|
||||
fi
|
||||
done
|
||||
|
||||
done
|
||||
|
30
guacamole-docker/entrypoint.d/999-start-tomcat.sh
Normal file
30
guacamole-docker/entrypoint.d/999-start-tomcat.sh
Normal file
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# 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 999-start-tomcat.sh
|
||||
##
|
||||
## Starts Tomcat. This script replaces the current process with the Tomcat
|
||||
## process and does not exit.
|
||||
##
|
||||
|
||||
# Start tomcat
|
||||
cd /usr/local/tomcat
|
||||
exec catalina.sh run
|
||||
|
61
guacamole-docker/environment/REMOTE_IP_VALVE_/configure.sh
Normal file
61
guacamole-docker/environment/REMOTE_IP_VALVE_/configure.sh
Normal file
@@ -0,0 +1,61 @@
|
||||
#
|
||||
# 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 REMOTE_IP_VALVE_/configure.sh
|
||||
##
|
||||
## Configures Tomcat to forward the IP addresses of clients behind a proxy if
|
||||
## the REMOTE_IP_VALVE_ENABLED environment variable is set to "true".
|
||||
##
|
||||
|
||||
##
|
||||
## Array of all xmlstarlet command-line options necessary to add the
|
||||
## RemoteIpValve attributes that correspond to various "REMOTE_IP_VALVE_*"
|
||||
## environment variables.
|
||||
##
|
||||
declare -a VALVE_ATTRIBUTES=( --type attr -n className -v org.apache.catalina.valves.RemoteIpValve )
|
||||
|
||||
# Translate all properties supported by RemoteIpValve into corresponding
|
||||
# environment variables
|
||||
for ATTRIBUTE in \
|
||||
remoteIpHeader \
|
||||
internalProxies \
|
||||
proxiesHeader \
|
||||
trustedProxies \
|
||||
protocolHeader \
|
||||
protocolHeaderHttpsValue \
|
||||
httpServerPort \
|
||||
httpsServerPort; do
|
||||
|
||||
VAR_NAME="REMOTE_IP_VALVE_$(echo "$ATTRIBUTE" | sed 's/\([a-z]\)\([A-Z]\)/\1_\2/g' | tr 'a-z' 'A-Z')"
|
||||
if [ -n "${!VAR_NAME}" ]; then
|
||||
VALVE_ATTRIBUTES+=( --type attr -n "$ATTRIBUTE" -v "${!VAR_NAME}" )
|
||||
else
|
||||
echo "Using default RemoteIpValve value for \"$ATTRIBUTE\" attribute."
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# Programmatically add requested RemoteIpValve entry
|
||||
xmlstarlet edit --inplace \
|
||||
--insert '/Server/Service/Engine/Host/*' --type elem -n Valve \
|
||||
--insert '/Server/Service/Engine/Host/Valve[not(@className)]' \
|
||||
"${VALVE_ATTRIBUTES[@]}" \
|
||||
"$CATALINA_BASE/conf/server.xml"
|
||||
|
@@ -20,6 +20,7 @@
|
||||
package org.apache.guacamole.properties;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
@@ -45,8 +46,10 @@ public abstract class EnumGuacamoleProperty<T extends Enum<T>> implements Guacam
|
||||
|
||||
/**
|
||||
* Defines the string value which should be accepted and parsed into the
|
||||
* annotated enum constant.
|
||||
* annotated enum constant. This annotation is repeatable, and each enum
|
||||
* constant may be associated with any any number of string values.
|
||||
*/
|
||||
@Repeatable(PropertyValues.class)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public static @interface PropertyValue {
|
||||
@@ -63,6 +66,29 @@ public abstract class EnumGuacamoleProperty<T extends Enum<T>> implements Guacam
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the string values which should be accepted and parsed into the
|
||||
* annotated enum constant. Each enum constant may be associated with any
|
||||
* any number of string values.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public static @interface PropertyValues {
|
||||
|
||||
/**
|
||||
* Returns the {@link PropertyValue} annotations that represent the
|
||||
* String values that should produce the annotated enum constant when
|
||||
* parsed.
|
||||
*
|
||||
* @return
|
||||
* The {@link PropertyValue} annotations that represent the String
|
||||
* values that should produce the annotated enum constant when
|
||||
* parsed.
|
||||
*/
|
||||
PropertyValue[] value();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping of valid property values to the corresponding enum constants
|
||||
* that those values parse to.
|
||||
@@ -103,7 +129,17 @@ public abstract class EnumGuacamoleProperty<T extends Enum<T>> implements Guacam
|
||||
+ "match declared values.", e);
|
||||
}
|
||||
|
||||
// Map enum constant only if PropertyValue annotation is present
|
||||
// Map enum constant only if one or more PropertyValue annotations
|
||||
// are present
|
||||
PropertyValues valuesAnnotation = field.getAnnotation(PropertyValues.class);
|
||||
if (valuesAnnotation != null) {
|
||||
for (PropertyValue valueAnnotation : valuesAnnotation.value())
|
||||
valueMapping.put(valueAnnotation.value(), value);
|
||||
}
|
||||
|
||||
// The PropertyValue annotation may appear as a separate, single
|
||||
// annotation, or as a multi-valued annotation via PropertyValues
|
||||
// (see above)
|
||||
PropertyValue valueAnnotation = field.getAnnotation(PropertyValue.class);
|
||||
if (valueAnnotation != null)
|
||||
valueMapping.put(valueAnnotation.value(), value);
|
||||
|
@@ -70,6 +70,7 @@ public class EnumGuacamolePropertyTest {
|
||||
* @see <a href="https://en.wikipedia.org/wiki/Tuna">Tuna (Wikipedia)</a>
|
||||
*/
|
||||
@PropertyValue("tuna")
|
||||
@PropertyValue("yellowfin")
|
||||
TUNA,
|
||||
|
||||
/**
|
||||
@@ -135,6 +136,7 @@ public class EnumGuacamolePropertyTest {
|
||||
assertEquals(Fish.TROUT, FAVORITE_FISH.parseValue("trout"));
|
||||
assertEquals(Fish.MACKEREL, FAVORITE_FISH.parseValue("mackerel"));
|
||||
assertEquals(Fish.TUNA, FAVORITE_FISH.parseValue("tuna"));
|
||||
assertEquals(Fish.TUNA, FAVORITE_FISH.parseValue("yellowfin"));
|
||||
assertEquals(Fish.SARDINE, FAVORITE_FISH.parseValue("sardine"));
|
||||
}
|
||||
|
||||
@@ -164,7 +166,7 @@ public class EnumGuacamolePropertyTest {
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue(message.contains("\"mackerel\", \"salmon\", \"sardine\", \"trout\", \"tuna\""));
|
||||
assertTrue(message.contains("\"mackerel\", \"salmon\", \"sardine\", \"trout\", \"tuna\", \"yellowfin\""));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -95,7 +95,7 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener
|
||||
|
||||
/**
|
||||
* A property that determines whether environment variables are evaluated
|
||||
* to override properties specified in guacamole.properties.
|
||||
* to supply properties not specified in guacamole.properties.
|
||||
*/
|
||||
private static final BooleanGuacamoleProperty ENABLE_ENVIRONMENT_PROPERTIES =
|
||||
new BooleanGuacamoleProperty() {
|
||||
@@ -105,6 +105,19 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A property that determines whether environment variables of the form
|
||||
* "*_FILE" are evaluated to supply properties not specified in
|
||||
* guacamole.properties nor in environment variables.
|
||||
*/
|
||||
private static final BooleanGuacamoleProperty ENABLE_FILE_ENVIRONMENT_PROPERTIES =
|
||||
new BooleanGuacamoleProperty() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "enable-file-environment-properties";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The Guacamole server environment.
|
||||
*/
|
||||
@@ -172,6 +185,23 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener
|
||||
logger.debug("Error reading \"{}\" property from guacamole.properties.", ENABLE_ENVIRONMENT_PROPERTIES.getName(), e);
|
||||
}
|
||||
|
||||
// For any values not defined in GUACAMOLE_HOME/guacamole.properties
|
||||
// nor in the system environment, read from files pointed to by
|
||||
// corresponding "*_FILE" variables in the system environment if
|
||||
// "enable-file-environment-properties" is set to "true"
|
||||
try {
|
||||
if (environment.getProperty(ENABLE_FILE_ENVIRONMENT_PROPERTIES, false)) {
|
||||
environment.addGuacamoleProperties(new SystemFileEnvironmentGuacamoleProperties());
|
||||
logger.info("Additional configuration parameters may be read "
|
||||
+ "from files pointed to by \"*_FILE\" environment "
|
||||
+ "variables.");
|
||||
}
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
logger.error("Unable to configure support for file environment properties: {}", e.getMessage());
|
||||
logger.debug("Error reading \"{}\" property from guacamole.properties.", ENABLE_FILE_ENVIRONMENT_PROPERTIES.getName(), e);
|
||||
}
|
||||
|
||||
// Now that at least the main guacamole.properties source of
|
||||
// configuration information is available, initialize the session map
|
||||
sessionMap = new HashTokenSessionMap(environment);
|
||||
@@ -210,13 +240,24 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener
|
||||
return current;
|
||||
|
||||
// Create new injector if necessary
|
||||
Injector injector = Guice.createInjector(Stage.PRODUCTION,
|
||||
new EnvironmentModule(environment),
|
||||
new LogModule(environment),
|
||||
new ExtensionModule(environment),
|
||||
new RESTServiceModule(sessionMap),
|
||||
new TunnelModule()
|
||||
);
|
||||
Injector injector =
|
||||
|
||||
// Ensure environment and logging are configured FIRST ...
|
||||
Guice.createInjector(Stage.PRODUCTION,
|
||||
new EnvironmentModule(environment),
|
||||
new LogModule(environment)
|
||||
)
|
||||
|
||||
// ... before attempting configuration of any other modules
|
||||
// (logging within the constructors of other modules may
|
||||
// otherwise default to including messages from the "debug"
|
||||
// level, regardless of how the application log level is
|
||||
// actually configured)
|
||||
.createChildInjector(
|
||||
new ExtensionModule(environment),
|
||||
new RESTServiceModule(sessionMap),
|
||||
new TunnelModule()
|
||||
);
|
||||
|
||||
return injector;
|
||||
|
||||
|
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.apache.guacamole.properties.GuacamoleProperties;
|
||||
import org.apache.guacamole.token.TokenName;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* GuacamoleProperties implementation which reads all properties from files
|
||||
* whose filenames are stored in environment variables. The name of the
|
||||
* environment variable corresponding to the filename is determined from the
|
||||
* original property using {@link TokenName#canonicalize(java.lang.String)}
|
||||
* with an additional "_FILE" suffix.
|
||||
*/
|
||||
public class SystemFileEnvironmentGuacamoleProperties implements GuacamoleProperties {
|
||||
|
||||
/**
|
||||
* Logger for this class.
|
||||
*/
|
||||
private static final Logger logger = LoggerFactory.getLogger(SystemFileEnvironmentGuacamoleProperties.class);
|
||||
|
||||
@Override
|
||||
public String getProperty(String name) {
|
||||
|
||||
String filename = System.getenv(TokenName.canonicalize(name) + "_FILE");
|
||||
if (filename != null) {
|
||||
try {
|
||||
return Files.asCharSource(new File(filename), StandardCharsets.UTF_8).read();
|
||||
}
|
||||
catch (IOException e) {
|
||||
logger.error("Property \"{}\" could not be read from file \"{}\": {}", name, filename, e.getMessage());
|
||||
logger.debug("Error reading property value from file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
163
guacamole/src/main/java/org/apache/guacamole/log/LogLevel.java
Normal file
163
guacamole/src/main/java/org/apache/guacamole/log/LogLevel.java
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole.log;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.apache.guacamole.properties.EnumGuacamoleProperty.PropertyValue;
|
||||
|
||||
/**
|
||||
* All log levels supported by the Apache Guacamole web application. Each log
|
||||
* level describes a different level of verbosity for the log messages included
|
||||
* in web application logs.
|
||||
*/
|
||||
public enum LogLevel {
|
||||
|
||||
/**
|
||||
* Errors that are fatal in the context of the operation being logged.
|
||||
*/
|
||||
@PropertyValue("error")
|
||||
ERROR("error"),
|
||||
|
||||
/**
|
||||
* Non-fatal conditions that may indicate the presence of a problem.
|
||||
*/
|
||||
@PropertyValue("warning")
|
||||
@PropertyValue("warn")
|
||||
WARNING("warning"),
|
||||
|
||||
/**
|
||||
* Informational messages of general interest to users or administrators.
|
||||
*/
|
||||
@PropertyValue("info")
|
||||
INFO("info"),
|
||||
|
||||
/**
|
||||
* Informational messages that are useful for debugging, but are generally
|
||||
* not useful to users or administrators. It is expected that debug-level
|
||||
* messages, while verbose, will not affect performance.
|
||||
*/
|
||||
@PropertyValue("debug")
|
||||
DEBUG("debug"),
|
||||
|
||||
/**
|
||||
* Informational messages that may be useful for debugging, but which are
|
||||
* so low-level that they may affect performance.
|
||||
*/
|
||||
@PropertyValue("trace")
|
||||
TRACE("trace");
|
||||
|
||||
/**
|
||||
* Format string whose sole format argument is a String containing the
|
||||
* name of the log level. As this configuration will be fed to Logback, the
|
||||
* name used must be a name acceptable by Logback.
|
||||
*/
|
||||
private static final String LOGBACK_XML_TEMPLATE =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
+ "<configuration>\n"
|
||||
+ "\n"
|
||||
+ " <!-- Default appender -->\n"
|
||||
+ " <appender name=\"GUAC-DEFAULT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n"
|
||||
+ " <encoder>\n"
|
||||
+ " <pattern>%%d{HH:mm:ss.SSS} [%%thread] %%-5level %%logger{36} - %%msg%%n</pattern>\n"
|
||||
+ " </encoder>\n"
|
||||
+ " </appender>\n"
|
||||
+ "\n"
|
||||
+ " <!-- Log at level defined with \"log-level\" property -->\n"
|
||||
+ " <root level=\"%s\">\n"
|
||||
+ " <appender-ref ref=\"GUAC-DEFAULT\" />\n"
|
||||
+ " </root>\n"
|
||||
+ "\n"
|
||||
+ "</configuration>\n";
|
||||
|
||||
/**
|
||||
* The name that should be used to refer to this log level in the context
|
||||
* of configuring Guacamole. This name should be both descriptive and
|
||||
* acceptable as the value of the "log-level" property.
|
||||
*/
|
||||
private final String canonicalName;
|
||||
|
||||
/**
|
||||
* The raw contents of the "logback.xml" that configures Logback to log
|
||||
* messages at this level, encoded as UTF-8.
|
||||
*/
|
||||
private final byte[] logbackConfig;
|
||||
|
||||
/**
|
||||
* Creates a new LogLevel with the given names. The pair of names provided
|
||||
* correspond to the name used within Guacamole's configuration and the
|
||||
* name used within Logback's configuration.
|
||||
*
|
||||
* @param canonicalName
|
||||
* The name that should be used for this log level when configuring
|
||||
* Guacamole to log at this level using the "log-level" property.
|
||||
*
|
||||
* @param logbackLogLevel
|
||||
* The name that would be provided to Logback to log at this level if
|
||||
* manually configuring Logback using "logback.xml".
|
||||
*/
|
||||
private LogLevel(String canonicalName, String logbackLogLevel) {
|
||||
this.canonicalName = canonicalName;
|
||||
this.logbackConfig = String.format(LOGBACK_XML_TEMPLATE, logbackLogLevel).getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new LogLevel with the given name. The provided name corresponds
|
||||
* to both the name used within Guacamole's configuration and the name used
|
||||
* within Logback's configuration.
|
||||
*
|
||||
* @param logLevel
|
||||
* The name that should be used for this log level when configuring
|
||||
* Guacamole to log at this level using the "log-level" property AND
|
||||
* when manually configuring Logback to log at this level using a
|
||||
* "logback.xml" configuration file.
|
||||
*/
|
||||
private LogLevel(String logLevel) {
|
||||
this(logLevel, logLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a name that may be used to refer to this log level when
|
||||
* configuring Guacamole using the "log-level" property.
|
||||
*
|
||||
* @return
|
||||
* A name that may be used to refer to this log level when
|
||||
* configuring Guacamole using the "log-level" property.
|
||||
*/
|
||||
public String getCanonicalName() {
|
||||
return canonicalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new InputStream that streams the contents of an XML
|
||||
* configuration file that can be provided to Logback to configure logging
|
||||
* at this log level.
|
||||
*
|
||||
* @return
|
||||
* A a new InputStream that streams the contents of an XML
|
||||
* configuration file that can be provided to Logback to configure
|
||||
* logging at this log level.
|
||||
*/
|
||||
public InputStream getLogbackConfiguration() {
|
||||
return new ByteArrayInputStream(logbackConfig);
|
||||
}
|
||||
|
||||
}
|
@@ -25,7 +25,13 @@ import ch.qos.logback.core.joran.spi.JoranException;
|
||||
import ch.qos.logback.core.util.StatusPrinter;
|
||||
import com.google.inject.AbstractModule;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.environment.Environment;
|
||||
import org.apache.guacamole.properties.EnumGuacamoleProperty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -44,6 +50,19 @@ public class LogModule extends AbstractModule {
|
||||
*/
|
||||
private final Environment environment;
|
||||
|
||||
/**
|
||||
* Property that specifies the highest level of verbosity that Guacamole
|
||||
* should use for the messages in its logs.
|
||||
*/
|
||||
private static final EnumGuacamoleProperty<LogLevel> LOG_LEVEL = new EnumGuacamoleProperty<LogLevel>(LogLevel.class) {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "log-level";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new LogModule which uses the given environment to determine
|
||||
* the logging configuration.
|
||||
@@ -54,26 +73,57 @@ public class LogModule extends AbstractModule {
|
||||
public LogModule(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an InputStream that streams the contents of the "logback.xml"
|
||||
* file that Logback should read to configure logging to Guacamole. If the
|
||||
* user provided their own "logback.xml" within GUACAMOLE_HOME, this will
|
||||
* be an InputStream that reads the contents of that file. The required
|
||||
* "logback.xml" will otherwise be dynamically generated based on the value
|
||||
* of the "log-level" property.
|
||||
*
|
||||
* @return
|
||||
* An InputStream that streams the contents of the "logback.xml" file
|
||||
* that Logback should read to configure logging to Guacamole.
|
||||
*/
|
||||
private InputStream getLogbackConfiguration() {
|
||||
|
||||
// Check for custom logback.xml
|
||||
File logbackFile = new File(environment.getGuacamoleHome(), "logback.xml");
|
||||
if (logbackFile.exists()) {
|
||||
try {
|
||||
logger.info("Loading logback configuration from \"{}\".", logbackFile);
|
||||
return new FileInputStream(logbackFile);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
logger.info("Logback configuration could not be read "
|
||||
+ "from \"{}\": {}", logbackFile, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Default to generating an internal logback.xml based on a simple
|
||||
// "log-level" property
|
||||
LogLevel level;
|
||||
try {
|
||||
level = environment.getProperty(LOG_LEVEL, LogLevel.INFO);
|
||||
logger.info("Logging will be at the \"{}\" level.", level.getCanonicalName());
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
level = LogLevel.INFO;
|
||||
logger.error("Falling back to \"{}\" log level: {}", level.getCanonicalName(), e.getMessage());
|
||||
}
|
||||
|
||||
return level.getLogbackConfiguration();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
||||
// Only load logback configuration if GUACAMOLE_HOME exists
|
||||
File guacamoleHome = environment.getGuacamoleHome();
|
||||
if (!guacamoleHome.isDirectory())
|
||||
return;
|
||||
try (InputStream logbackConfiguration = getLogbackConfiguration()) {
|
||||
|
||||
// Check for custom logback.xml
|
||||
File logbackConfiguration = new File(guacamoleHome, "logback.xml");
|
||||
if (!logbackConfiguration.exists())
|
||||
return;
|
||||
|
||||
logger.info("Loading logback configuration from \"{}\".", logbackConfiguration);
|
||||
|
||||
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||
context.reset();
|
||||
|
||||
try {
|
||||
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||
context.reset();
|
||||
|
||||
// Initialize logback
|
||||
JoranConfigurator configurator = new JoranConfigurator();
|
||||
@@ -86,7 +136,11 @@ public class LogModule extends AbstractModule {
|
||||
}
|
||||
catch (JoranException e) {
|
||||
logger.error("Initialization of logback failed: {}", e.getMessage());
|
||||
logger.debug("Unable to load logback configuration..", e);
|
||||
logger.debug("Unable to load logback configuration.", e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
logger.warn("Logback configuration file could not be cleanly closed: {}", e.getMessage());
|
||||
logger.debug("Failed to close logback configuration file.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<configuration>
|
||||
|
||||
<!-- Default appender -->
|
||||
<appender name="GUAC-DEFAULT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Log at INFO level -->
|
||||
<root level="info">
|
||||
<appender-ref ref="GUAC-DEFAULT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
Reference in New Issue
Block a user