diff --git a/Makefile b/Makefile index a89f8afb..3df44c3d 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ build: ## Build the Gotenberg's Docker image -t $(DOCKER_REGISTRY)/$(DOCKER_REPOSITORY):$(GOTENBERG_VERSION) \ -f $(DOCKERFILE) $(DOCKER_BUILD_CONTEXT) +TZ=UTC GOTENBERG_HIDE_BANNER=false GOTENBERG_GRACEFUL_SHUTDOWN_DURATION=30s GOTENBERG_BUILD_DEBUG_DATA=true @@ -86,6 +87,7 @@ run: ## Start a Gotenberg container -p $(API_PORT):$(API_PORT) \ -e GOTENBERG_API_BASIC_AUTH_USERNAME=$(GOTENBERG_API_BASIC_AUTH_USERNAME) \ -e GOTENBERG_API_BASIC_AUTH_PASSWORD=$(GOTENBERG_API_BASIC_AUTH_PASSWORD) \ + -e TZ=$(TZ) \ $(DOCKER_REGISTRY)/$(DOCKER_REPOSITORY):$(GOTENBERG_VERSION) \ gotenberg \ --gotenberg-hide-banner=$(GOTENBERG_HIDE_BANNER) \ diff --git a/build/Dockerfile b/build/Dockerfile index 85e77749..d213e310 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -79,6 +79,9 @@ RUN jlink \ # ---------------------------------------------- FROM debian:13-slim AS base-image-stage +ARG TIMEZONE=UTC +ENV TZ=$TIMEZONE + COPY --from=custom-jre-stage /custom-jre /opt/java ENV PATH="/opt/java/bin:${PATH}" diff --git a/pkg/gotenberg/debug.go b/pkg/gotenberg/debug.go index 9a83a699..d79e183e 100644 --- a/pkg/gotenberg/debug.go +++ b/pkg/gotenberg/debug.go @@ -4,6 +4,7 @@ import ( "runtime" "sort" "sync" + "time" flag "github.com/spf13/pflag" ) @@ -11,6 +12,7 @@ import ( // DebugInfo gathers data for debugging. type DebugInfo struct { Version string `json:"version"` + Timezone string `json:"timezone"` Architecture string `json:"architecture"` Modules []string `json:"modules"` ModulesAdditionalData map[string]map[string]interface{} `json:"modules_additional_data"` @@ -24,6 +26,7 @@ func BuildDebug(ctx *Context) { debug = &DebugInfo{ Version: Version, + Timezone: time.Now().Location().String(), Architecture: runtime.GOARCH, Modules: make([]string, len(ctx.moduleInstances)), ModulesAdditionalData: make(map[string]map[string]interface{}), diff --git a/pkg/gotenberg/debug_test.go b/pkg/gotenberg/debug_test.go index 5c50fde5..c31466ce 100644 --- a/pkg/gotenberg/debug_test.go +++ b/pkg/gotenberg/debug_test.go @@ -13,6 +13,8 @@ func TestBuildDebug(t *testing.T) { t.Errorf("Debug() should return empty debug data") } + t.Setenv("TZ", "UTC") + fs := flag.NewFlagSet("gotenberg", flag.ExitOnError) fs.String("foo", "bar", "Set foo") ctx := NewContext(ParsedFlags{ @@ -51,6 +53,7 @@ func TestBuildDebug(t *testing.T) { expect := DebugInfo{ Version: Version, + Timezone: "UTC", Architecture: runtime.GOARCH, Modules: []string{ "bar", diff --git a/test/integration/features/debug.feature b/test/integration/features/debug.feature index 033810a3..6a4dce55 100644 --- a/test/integration/features/debug.feature +++ b/test/integration/features/debug.feature @@ -16,6 +16,126 @@ Feature: /debug """ { "version": "{version}", + "timezone": "UTC", + "architecture": "ignore", + "modules": [ + "api", + "chromium", + "exiftool", + "libreoffice", + "libreoffice-api", + "libreoffice-pdfengine", + "logging", + "pdfcpu", + "pdfengines", + "pdftk", + "prometheus", + "qpdf", + "webhook" + ], + "modules_additional_data": { + "chromium": { + "version": "ignore" + }, + "exiftool": { + "version": "ignore" + }, + "libreoffice-api": { + "version": "ignore" + }, + "pdfcpu": { + "version": "ignore" + }, + "pdftk": { + "version": "ignore" + }, + "qpdf": { + "version": "ignore" + } + }, + "flags": { + "api-bind-ip": "", + "api-body-limit": "", + "api-disable-download-from": "false", + "api-disable-health-check-logging": "false", + "api-download-from-allow-list": "", + "api-download-from-deny-list": "", + "api-download-from-max-retry": "4", + "api-enable-basic-auth": "false", + "api-enable-debug-route": "true", + "api-port": "3000", + "api-port-from-env": "", + "api-root-path": "/", + "api-start-timeout": "30s", + "api-timeout": "30s", + "api-tls-cert-file": "", + "api-tls-key-file": "", + "api-trace-header": "Gotenberg-Trace", + "chromium-allow-file-access-from-files": "false", + "chromium-allow-insecure-localhost": "false", + "chromium-allow-list": "", + "chromium-auto-start": "false", + "chromium-clear-cache": "false", + "chromium-clear-cookies": "false", + "chromium-deny-list": "^file:(?!//\\/tmp/).*", + "chromium-disable-javascript": "false", + "chromium-disable-routes": "false", + "chromium-disable-web-security": "false", + "chromium-host-resolver-rules": "", + "chromium-ignore-certificate-errors": "false", + "chromium-incognito": "false", + "chromium-max-queue-size": "0", + "chromium-proxy-server": "", + "chromium-restart-after": "10", + "chromium-start-timeout": "20s", + "gotenberg-build-debug-data": "true", + "gotenberg-graceful-shutdown-duration": "30s", + "libreoffice-auto-start": "false", + "libreoffice-disable-routes": "false", + "libreoffice-max-queue-size": "0", + "libreoffice-restart-after": "10", + "libreoffice-start-timeout": "20s", + "log-fields-prefix": "", + "log-format": "auto", + "log-level": "info", + "pdfengines-convert-engines": "[libreoffice-pdfengine]", + "pdfengines-disable-routes": "false", + "pdfengines-engines": "[]", + "pdfengines-flatten-engines": "[qpdf]", + "pdfengines-merge-engines": "[qpdf,pdfcpu,pdftk]", + "pdfengines-read-metadata-engines": "[exiftool]", + "pdfengines-split-engines": "[pdfcpu,qpdf,pdftk]", + "pdfengines-write-metadata-engines": "[exiftool]", + "prometheus-collect-interval": "1s", + "prometheus-disable-collect": "false", + "prometheus-disable-route-logging": "false", + "prometheus-namespace": "gotenberg", + "prometheus-metrics-path": "/prometheus/metrics", + "webhook-allow-list": "", + "webhook-client-timeout": "30s", + "webhook-deny-list": "", + "webhook-disable": "false", + "webhook-error-allow-list": "", + "webhook-error-deny-list": "", + "webhook-max-retry": "4", + "webhook-retry-max-wait": "30s", + "webhook-retry-min-wait": "1s" + } + } + """ + + Scenario: GET /debug (Environment based timezone) + Given I have a Gotenberg container with the following environment variable(s): + | API_ENABLE_DEBUG_ROUTE | true | + | TZ | America/New_York | + When I make a "GET" request to Gotenberg at the "/debug" endpoint + Then the response status code should be 200 + Then the response header "Content-Type" should be "application/json" + Then the response body should match JSON: + """ + { + "version": "{version}", + "timezone": "America/New_York", "architecture": "ignore", "modules": [ "api", @@ -134,6 +254,7 @@ Feature: /debug """ { "version": "", + "timezone": "", "architecture": "", "modules": null, "modules_additional_data": null, diff --git a/test/integration/testdata/header-footer-html/header.html b/test/integration/testdata/header-footer-html/header.html index f9501f91..45a2e1e8 100644 --- a/test/integration/testdata/header-footer-html/header.html +++ b/test/integration/testdata/header-footer-html/header.html @@ -8,6 +8,7 @@
+