Debugging
Disclaimer
This document collects information on how to go about debugging an openDesk deployment.
It will be extended over time as we deal with debugging cases.
We for sure do not want to reinvent the wheel, so we might link to external sources that contain helpful information where available.
You should never enable the debug option in production environments! By looking up debug.enabled in the
deployment, you will find the various places changes are applied when enabling debugging. So, outside of
development and test environments, you should use them thoughtfully and carefully if needed.
Enable debugging
Check the openDesk debug.yaml.gotmpl and configure it for your deployment
debug:
enabled: trueThis will result in:
- setting most component’s log level to debug
- making the Keycloak admin console available by default at
https://id.<your_domain>/admin/ - ingress for
http://minio-console.<your_domain>being configured
When enabling debug mode and updating your deployment, you must manually delete all jobs before updating. In debug mode, we keep the jobs, and some job fields are immutable, leading to a deployment failure.
All containers should write their log output to STDOUT; if you find (valuable) logs inside a container which were not in STDOUT, please let us know!
Adding containers to a pod for debugging purposes
During testing or development, you may need to execute tools, browse, or even change things in the filesystem of another container.
This can be a challenge the more security-hardened the container images are because there are no debugging tools available, and sometimes, there is not even a shell.
Adding a container to a Pod can ease the pain.
Below are some brief notes on debugging openDesk by adding debug containers. Of course, there are many more detailed resources out there.
Adding a container to a pod/deployment - Dev/Test only
You can add a container by editing and updating an existing deployment, which is quite comfortable with tools like Lens.
- Select the container you want to use as a debugging container; in the example below, it is
registry.opencode.de/bmi/opendesk/components/platform-development/images/opendesk-debugging-image:latest. - Ensure the
shareProcessNamespaceoption is enabled for the Pod. - Reference the selected container within the
containersarray of the deployment. - If you want to access another container’s filesystem, ensure both containers’ user/group settings match.
- Save & update the deployment.
The following example can be used to debug the openDesk-Nextcloud-PHP container; if you want to modify files, remember to set readOnlyRootFilesystem to true on the PHP container.
shareProcessNamespace: true
containers:
- name: debugging
image: registry.opencode.de/bmi/opendesk/components/platform-development/images/opendesk-debugging-image:latest
command: ["/bin/bash", "-c", "while true; do echo 'This is a temporary container for debugging'; sleep 5 ; done"]
securityContext:
capabilities:
drop:
- ALL
privileged: false
runAsUser: 65532
runAsGroup: 65532
runAsNonRoot: true
readOnlyRootFilesystem: false
allowPrivilegeEscalation: false
seccompProfile:
type: RuntimeDefault- After the deployment has been reloaded, open the shell of the debugging container.
- When you’ve succeeded, you will see the processes of both/all containers in the Pod when executing
ps aux. - To access other containers’ filesystems, select the PID of a process from the other container and do a
cd /proc/<selected_process_id>/root.
Temporary/ephemeral containers
An interesting read from which we picked most of the details below from: https://iximiuz.com/en/posts/kubernetes-ephemeral-containers/
Sometimes, you do not want to add a container permanently to your existing deployment. In that case, you could use ephemeral containers.
For the commands further down this section, we need to set some environment variables first:
NAMESPACE: The namespace in which the Pod you want to inspect is running.DEPLOYMENT_NAME: The deployment’s name responsible for spawning the Pod you want to inspect within the aforementioned namespace.POD_NAME: The name of the Pod you want to inspect within the aforementioned namespace.EPH_CONTAINER_NAME: The name of your debugging container, “debugging” seems obvious.DEBUG_IMAGE: The image you want to use for debugging purposes.
export NAMESPACE=my_test_deployment
export DEPLOYMENT_NAME=opendesk-nextcloud-php
export POD_NAME=opendesk-nextcloud-php-6686d47cfb-7642f
export EPH_CONTAINER_NAME=debugging
export DEBUG_IMAGE=registry.opencode.de/bmi/opendesk/components/platform-development/images/opendesk-debugging-image:latestYou still need to ensure that your deployment supports process namespace sharing:
kubectl -n ${NAMESPACE} patch deployment ${DEPLOYMENT_NAME} --patch '
spec:
template:
spec:
shareProcessNamespace: true'Now, you can add the ephemeral container with:
kubectl -n ${NAMESPACE} debug -it --attach=false -c ${EPH_CONTAINER_NAME} --image={DEBUG_IMAGE} ${POD_NAME}and open its interactive terminal with
kubectl -n ${NAMESPACE} attach -it -c ${EPH_CONTAINER_NAME} ${POD_NAME}Components
Helmfile
When refactoring the Helmfile structure, you want to ensure that there are no unintended edits by executing e.g. diff and
comparing the output of Helmfile from before and after the change by calling:
helmfile template -e dev >output_to_compare.yamlMariaDB
When using the openDesk bundled MariaDB, you can explore the database(s) using the MariaDB interactive terminal from the Pod’s command line: mariadb -u root -p. On the password prompt, provide the value for MARIADB_ROOT_PASSWORD which can be found in the Pod’s environment.
While you will find all the details for the CLI tool in the MariaDB documentation, some commonly used commands are:
help: Get help on the psql command setshow databases: Lists all databasesuse <databasename>: Connect to<databasename>show tables: Lists tables within the currently connected databasequit: Quit the client
Nextcloud
occ is the CLI for Nextcloud; all the details can be found in the upstream documentation.
You can run occ commands in the opendesk-nextcloud-aio pod like this: php /var/www/html/occ config:list
OpenProject
OpenProject is a Ruby on Rails application. Therefore, you can make use of the Rails console from the Pod’s command line bundle exec rails console
and run debug code like this:
uri = URI('https://nextcloud.url/apps/integration_openproject/check-config')
Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https') do |http|
request = Net::HTTP::Get.new uri
response = http.request request # Net::HTTPResponse object
endPostgreSQL
Using the openDesk bundled PostgreSQL, you can explore database(s) using the PostgreSQL interactive terminal from the Pod’s command line: psql -U postgres.
While you will find all details about the cli tool psql in the PostgreSQL documentation, some commonly used commands are:
\?: Get help on the psql command set\l: Lists all databases\c <databasename>: Connect to<databasename>\dt: List (describe) tables within the currently connected database\q: Quit the client
Open-Xchange
OX App Suite
Applying global config changes for debugging
You have two ways of applying config changes e.g. to enable debug relevant settings. In the examples below we will enable com.openexchange.imap.debugLog.enabled assuming the given property is not set anywhere else yet.
- Especially in environments where the core-mw Pods are scaled it is recommended to use customizatzions (see
customizations.yaml.gotmplfor reference) and to redeploy the OX App Suite component. Due to the rolling upgrade feature this should not cause downtime for users.
core-mw:
properties:
com.openexchange.imap.debugLog.enabled: "true"- When just dealing with a single core-mw Pod:
echo com.openexchange.imap.debugLog.enabled=true >> /opt/open-xchange/etc/additional.properties
/opt/open-xchange/sbin/reloadconfigurationUsing config cascade
OX App Suite allows some settings that can set globally also to be defined using a finer granularity down to the user level using the so call config cascade.
The example below requires the related setting to be available on the global level e.g. with value "false" to
be able to set in on a “lower” level, like the user.
Find more details in the upstream documentation.
Using the same setting from the previous section but now setting it just for a specific user:
/opt/open-xchange/sbin/changeuser -A $MASTER_ADMIN_USER -P $MASTER_ADMIN_PW -c <contextId> -i <userId> --config/com.openexchange.imap.debugLog.enabled=trueFor deactivation on the given user run:
/opt/open-xchange/sbin/changeuser -A $MASTER_ADMIN_USER -P $MASTER_ADMIN_PW -c <contextId> -i <userId> --remove-config/com.openexchange.imap.debugLog.enabledOX Dovecot
When it comes to debugging Dovecot some commands come in handy:
- Get the configuration in a standard (comparable) format and secrets removed:
doveconf -n - Get the log output with focus on errors only:
doveadm log errors - Looking into specific user mailbox activities:
doveadm dump /var/lib/dovecot/<UUID_2CHARS>/<UUID>/mdbox/dovecot.mailbox.log- When running openDesk CE the use
/srv/mail/instead of/var/lib/dovecot
- When running openDesk CE the use
- Listing a users mailbox:
doveadm mailbox list -u <EMAIL_ADDRESS>
Example for getting log output for specific events:
event_exporter log {
format = json
format_args = time-rfc3339
transport = log
}
metric imap_command_unsubscribe {
exporter = log
filter = event=imap_command_finished AND cmd_name=UNSUBSCRIBE
}Nubus
Provisioning
This section should provide an overview on the Nubus Provisioning API in addition to the available upstream documentation.
As of openDesk 1.13 the provisioning is used for Nubus internal use cases e.g. the self-service except for OX App Suite provisioning of objects like users and groups.
A core element of Nubus Provisioning is the messagaging system NATS.
Below is a simplified representation of the end-to-end flow for an data object starting from the creation of using the UDM REST API until the object is getting persisted in the OX App Suite.
- HTTP Client: Send UDM API Request.
udm-rest-api-*: Processes the request writing the resulting object into the LDAP.ldap-server-primary-0: LDAP as the actual identity data store.ldap-notifier-0: Monitors changes to LDAP objects and makes them available to other components that implement a so-called listener.provisioning-udm-listener-0: Receives the events from the notifier and generates NATS stream entries containting directory objects.provisioning-nats-0:stream:ldap-producer
provisioning-udm-transformer-*: Processes the directory objects and transforms them into UDM objects.provisioning-nats-0:stream:incoming
provisioning-dispatcher-*: Dispatches all objects into all registered consumer streams. The consumer filters for its relevant events.provisioning-nats-0:stream:ox-connector
provisioning-api-*: The service for consumers to retrieve their stream messages through.ox-connector-0: The consumer retrieves the objects from its own stream through the Provisioning API, filters for the relevant ones and sends API requests to OX App Suite SOAP API.open-xchange-core-mw-groupware-*: OX App Suite Pod receiving the API calls. Whentechnical.oxAppSuite.provisioning.dedicatedCoreMwPodis set totruethe Pod name isopen-xchange-core-mw-admin-*.- OX App Suite MariaDB schema(s): Persistent storage for all received objects.
The Pod provisioning-prefill-*: Provides the consumer with information about directory objects that already exist in the directory at the time of registration.
For interaction with NATS it is convenient to have the NATS Box container available in the provisioning-nats Pod to execute nats CLI commands.
Check technical.yaml.gotmpl for details of the following setting:
technical:
nubus:
provisioning:
nats:
natsBox:
enabled: trueAt good start is to check the NATS stream status using the following command, followed by more detailed looks at the key-value store:
nats stream ls --user=admin --password=${NATS_PASSWORD}
nats kv ls --user=admin --password=${NATS_PASSWORD}
nats kv ls --user=admin --password=${NATS_PASSWORD} SUBSCRIPTIONS
nats kv get --user=admin --password=${NATS_PASSWORD} SUBSCRIPTIONS ox-connectorKeycloak
Setting the log level
Keycloak is the gateway to integrate other authentication management systems or applications. It is undesirable to enable debug mode for the whole platform if you just need to look into Keycloak.
Enabling debugging mode for Keycloak can easily be achieved in two steps:
- Updating the value for
KC_LOG_LEVELin the related configmapums-keycloak.
export NAMESPACE=<your_namespace>
export CONFIGMAP_NAME=ums-keycloak
kubectl patch -n ${NAMESPACE} configmap ${CONFIGMAP_NAME} --type merge -p '{"data":{"KC_LOG_LEVEL":"DEBUG"}}'- Restart the Keycloak Pod(s).
Because the ums-keycloak-extensions-handler is sending frequent requests (one per second) to Keycloak for
retrieval of the Keycloak event history, you might want to stop/remove the deployment while
debugging/analysing Keycloak to not get your debug output spammed by these requests.
While you can set the standard log levels like INFO, DEBUG, TRACE etc. you can also set class specific
logs by comma separating the details in the KC_LOG_LEVEL environment variable like
e.g. INFO,org.keycloak.protocol.oidc.endpoints:TRACE. The example sets the overall loglevel to INFO but
provides trace logs for org.keycloak.protocol.oidc.endpoints.
Accessing the Keycloak admin console
Deployments set to debug.enable: true expose the Keycloak admin console at http://id.<your_opendesk_domain>/admin/. This can also be achieved by updating the Ingress ums-keycloak-extensions-proxy with an additional path that allows access to /admin/.
The admin console login is using the default Keycloak admin account kcadmin and the password from the secret ums-opendesk-keycloak-credentials.