Compare commits

...

11 Commits

Author SHA1 Message Date
7a9c1db489 fix: use configurable root credentials for dbinit job via values.yaml
dbInit.mysqlUser and dbInit.mysqlPasswordKey are now configurable in
values.yaml. Defaults to root/mysql-root-password since SQL migrations
need SUPER privilege for triggers with DEFINER=root@%.

App (hades-service) still connects as hades_user — only the migration
job uses root.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 14:17:52 +05:30
ffb6b84b3c fix: revert database.username to hades_user (Backstage overrides this value)
The values.yaml database.username has no effect when Backstage deploys
with mysql.enabled=false — Backstage passes the username from the UI.
The shared MySQL init SQL needs to create hades_user separately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 14:09:06 +05:30
91b0f32c79 fix: use correct external DB username and allow dbinit for shared MySQL
- Change database.username from "hades_user" to "mysql_user" to match
  the shared MySQL user created by Backstage environment provisioning
- Remove mysql.enabled=true condition from dbinit job so SQL migrations
  run against external/shared MySQL databases too

Without these fixes, deploying hades with mysql.enabled=false (Backstage
shared MySQL) causes access denied because hades_user doesn't exist in
the shared MySQL, and dbinit is skipped so no tables are created.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 14:00:13 +05:30
e7e5e77af3 fix: mount config at /etc/onlinesales/config/hadesV2 for hadesV3
HadesV3 reads config from hardcoded path /etc/onlinesales/config/hadesV2/
but chart only mounted at /etc/onlinesales/config/hades/. App fell back
to image defaults with is_app_ip_enabled=true.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 14:44:45 +05:30
c525455841 fix: disable IP validation for test-framework environments
Set is_app_ip_enabled to false so hades endpoints are accessible
without IP whitelist restrictions in test environments.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 12:31:09 +05:30
7ede16d79e fix: add hades.read/write.hibernate.cfg.xml configurable from values
App expects separate read/write hibernate configs at
/etc/onlinesales/db/hadesV2/. Added both files in values-local.yaml
with templated DB creds. Changed configmap to use tpl for rendering.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:23:17 +05:30
ca2e78769e fix: run container as root to fix Tomcat directory permission errors
Test-framework pods need write access to Tomcat dirs like webapps,
conf/Catalina, work. Running as root (user 0) permanently fixes this.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 17:20:08 +05:30
4a8d031c87 fix: add configurable tomcatWritableDirs for non-root pod support
hadesV3 runs as non-root user (1000) and can't write to Tomcat dirs.
Added tomcatWritableDirs config to mount emptyDir volumes at paths
like /usr/local/tomcat/conf/Catalina and /usr/local/tomcat/work.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 17:02:47 +05:30
57314032c3 fix: skip dbinit job when using external DB
When mysql.enabled=false (external DB), data already exists.
Running migrations would be destructive, so dbinit now only
runs when internal MySQL subchart is enabled.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 16:46:23 +05:30
53d86cd48b fix: use configurable db username in dbinit job instead of hardcoded root
Root user doesn't have access on external DB. Now uses the same
database username helper as the main deployment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 16:40:49 +05:30
e7899972e2 fix: make config mountPaths configurable to resolve path mismatch
App looks for config at /etc/onlinesales/db/hadesV2/ but was only
mounted at /etc/onlinesales/config/hades/. Now mountPaths is a list
in values.yaml so both paths can be served.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 16:31:56 +05:30
5 changed files with 117 additions and 14 deletions

View File

@ -6,8 +6,9 @@ metadata:
labels:
{{- include "hades.labels" . | nindent 4 }}
data:
{{- with .Values.config.files }}
{{- toYaml . | nindent 2 }}
{{- range $filename, $content := .Values.config.files }}
{{ $filename }}: |
{{- tpl $content $ | nindent 4 }}
{{- end }}
hibernate.cfg.xml: |
<?xml version='1.0' encoding='utf-8'?>

View File

@ -142,21 +142,29 @@ spec:
value: "false"
- name: HIBERNATE_HBM2DDL_AUTO
value: "validate"
{{- if or .Values.config.enabled .Values.allhosts.enabled }}
{{- if or .Values.config.enabled .Values.allhosts.enabled .Values.tomcatWritableDirs.enabled }}
volumeMounts:
{{- if .Values.config.enabled }}
{{- range .Values.config.mountPaths }}
- name: config
mountPath: /etc/onlinesales/config/hades
mountPath: {{ . }}
readOnly: true
{{- end }}
{{- end }}
{{- if .Values.allhosts.enabled }}
- name: allhosts
mountPath: /etc/onlinesales/config/allhosts/allhosts.tsv
subPath: allhosts.tsv
readOnly: true
{{- end }}
{{- if .Values.tomcatWritableDirs.enabled }}
{{- range $i, $path := .Values.tomcatWritableDirs.paths }}
- name: tomcat-writable-{{ $i }}
mountPath: {{ $path }}
{{- end }}
{{- if or .Values.config.enabled .Values.allhosts.enabled }}
{{- end }}
{{- end }}
{{- if or .Values.config.enabled .Values.allhosts.enabled .Values.tomcatWritableDirs.enabled }}
volumes:
{{- if .Values.config.enabled }}
- name: config
@ -168,6 +176,12 @@ spec:
configMap:
name: {{ include "hades.fullname" . }}-allhosts
{{- end }}
{{- if .Values.tomcatWritableDirs.enabled }}
{{- range $i, $path := .Values.tomcatWritableDirs.paths }}
- name: tomcat-writable-{{ $i }}
emptyDir: {}
{{- end }}
{{- end }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:

View File

@ -50,12 +50,12 @@ spec:
- name: MYSQL_DATABASE
value: {{ include "hades.databaseName" . | quote }}
- name: MYSQL_USER
value: "root"
value: {{ .Values.dbInit.mysqlUser | default "root" | quote }}
- name: MYSQL_PWD
valueFrom:
secretKeyRef:
name: {{ include "hades.databaseSecretName" . }}
key: mysql-root-password
key: {{ .Values.dbInit.mysqlPasswordKey | default "mysql-root-password" }}
command:
- /bin/bash
- -c
@ -72,7 +72,7 @@ spec:
# Test connection
echo "Testing database connection..."
if ! mysql -h"${MYSQL_HOST}" -P"${MYSQL_PORT}" -u"root" -e "SELECT 1" "${MYSQL_DATABASE}" &> /dev/null; then
if ! mysql -h"${MYSQL_HOST}" -P"${MYSQL_PORT}" -u"${MYSQL_USER}" -e "SELECT 1" "${MYSQL_DATABASE}" &> /dev/null; then
echo "ERROR: Cannot connect to database"
exit 1
fi
@ -94,7 +94,7 @@ spec:
echo -n "Applying $filename... "
if mysql -h"${MYSQL_HOST}" -P"${MYSQL_PORT}" -u"root" "${MYSQL_DATABASE}" < "$sql_file" 2>/tmp/migration_error.log; then
if mysql -h"${MYSQL_HOST}" -P"${MYSQL_PORT}" -u"${MYSQL_USER}" "${MYSQL_DATABASE}" < "$sql_file" 2>/tmp/migration_error.log; then
echo "✓ SUCCESS"
SUCCESS=$((SUCCESS + 1))
else

View File

@ -107,13 +107,17 @@ allhosts:
# Configuration files for local development
config:
enabled: true
mountPaths:
- /etc/onlinesales/config/hades
- /etc/onlinesales/config/hadesV2
- /etc/onlinesales/db/hadesV2
files:
hades.cfg: |
{
test: {
logConfig: "/etc/onlinesales/config/hades/log.cfg",
hades_hibernate_config_read: "/etc/onlinesales/config/hades/hibernate.cfg.xml",
hades_hibernate_config_write: "/etc/onlinesales/config/hades/hibernate.cfg.xml",
hades_hibernate_config_read: "/etc/onlinesales/db/hadesV2/hades.read.hibernate.cfg.xml",
hades_hibernate_config_write: "/etc/onlinesales/db/hadesV2/hades.write.hibernate.cfg.xml",
rest_accessor_config_file: "/etc/onlinesales/config/hades/restAccessor.cfg",
forgot_password_email_config_file: "/etc/onlinesales/config/hades/forgotPasswordEmailSender.cfg",
activation_email_config_file: "/etc/onlinesales/config/hades/activationEmailConfigFile.cfg",
@ -122,7 +126,7 @@ config:
stats_logging_config: "/etc/onlinesales/config/hades/statsLogging.cfg",
sms_sender_lib_config: "/etc/onlinesales/config/hades/smsSenderLib.cfg",
context_key: "/etc/onlinesales/config/hades/contextKey.cfg",
is_app_ip_enabled: "true",
is_app_ip_enabled: "false",
firebase_admin_sdk_config: "/etc/onlinesales/config/hades/firebaseAdminConfig.cfg",
firebase_data_url: "https://os-login-656b5.firebaseio.com",
failed_events_file: "/tmp/hades_failed_events.err",
@ -290,6 +294,81 @@ config:
}
}
hades.read.hibernate.cfg.xml: |
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://{{ include "hades.databaseHost" . }}:{{ include "hades.databasePort" . }}/{{ include "hades.databaseName" . }}?useUnicode=true&amp;characterEncoding=UTF-8&amp;autoReconnect=true&amp;</property>
<property name="connection.username">{{ include "hades.databaseUsername" . }}</property>
<property name="connection.password">{{ .Values.database.password | default .Values.mysql.mysqlPassword | default "local-mysql-pass" }}</property>
<property name="connection.pool_size">1</property>
<property name="dialect">ai.osmos.dblib.CustomMySQL8DialectUtf8mb4</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="show_sql">false</property>
<property name="use_keying_service">false</property>
<property name="use_credential_store">false</property>
<property name="connection.isolation">2</property>
<property name="connection.autocommit">true</property>
<property name="connection.useUnicode">true</property>
<property name="connection.characterEncoding">UTF-8</property>
<property name="c3p0.acquire_increment">10</property>
<property name="c3p0.idle_test_period">3600</property>
<property name="c3p0.max_size">30</property>
<property name="c3p0.max_statements">0</property>
<property name="c3p0.min_size">10</property>
<property name="c3p0.timeout">3605</property>
<property name="hibernate.c3p0.preferredTestQuery">select 1;</property>
<property name="hibernate.globally_quoted_identifiers">true</property>
</session-factory>
</hibernate-configuration>
hades.write.hibernate.cfg.xml: |
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://{{ include "hades.databaseHost" . }}:{{ include "hades.databasePort" . }}/{{ include "hades.databaseName" . }}?useUnicode=true&amp;characterEncoding=UTF-8&amp;autoReconnect=true&amp;</property>
<property name="connection.username">{{ include "hades.databaseUsername" . }}</property>
<property name="connection.password">{{ .Values.database.password | default .Values.mysql.mysqlPassword | default "local-mysql-pass" }}</property>
<property name="connection.pool_size">1</property>
<property name="dialect">ai.osmos.dblib.CustomMySQL8DialectUtf8mb4</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="show_sql">false</property>
<property name="use_keying_service">false</property>
<property name="use_credential_store">false</property>
<property name="connection.isolation">2</property>
<property name="connection.autocommit">true</property>
<property name="connection.useUnicode">true</property>
<property name="connection.characterEncoding">UTF-8</property>
<property name="c3p0.acquire_increment">10</property>
<property name="c3p0.idle_test_period">3600</property>
<property name="c3p0.max_size">30</property>
<property name="c3p0.max_statements">0</property>
<property name="c3p0.min_size">10</property>
<property name="c3p0.timeout">3605</property>
<property name="hibernate.c3p0.preferredTestQuery">select 1;</property>
<property name="hibernate.globally_quoted_identifiers">true</property>
</session-factory>
</hibernate-configuration>
# Tomcat writable directories (emptyDir mounts for non-root pods)
tomcatWritableDirs:
enabled: true
paths:
- /usr/local/tomcat/conf/Catalina
- /usr/local/tomcat/work
# Hibernate configuration options (hibernate.cfg.xml is now generated dynamically)
hibernate:
connectionPoolSize: 10

View File

@ -36,8 +36,8 @@ securityContext:
drop:
- ALL
readOnlyRootFilesystem: false
runAsNonRoot: true
runAsUser: 1000
runAsNonRoot: false
runAsUser: 0
service:
type: ClusterIP
@ -166,10 +166,14 @@ mysql:
# Automatically runs all SQL migration files from sql/ directory in alphabetical order
dbInit:
enabled: true
mysqlUser: "root"
mysqlPasswordKey: "mysql-root-password"
# ConfigMap for application configuration files
config:
enabled: true
mountPaths:
- /etc/onlinesales/config/hades
# Add your configuration files here
# files:
# hades.cfg: |
@ -188,6 +192,11 @@ hibernate:
connectionPoolSize: 10
showSql: "true"
# Tomcat writable directories (emptyDir mounts for non-root pods)
tomcatWritableDirs:
enabled: false
paths: []
nodeSelector: {}
tolerations: []