Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add strict SQL mode to allow d2-cloner to stop execution on error during cloning process #136

Open
wants to merge 15 commits into
base: development
Choose a base branch
from
3 changes: 3 additions & 0 deletions src/d2_docker/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ def main():
args = parser.parse_args()
utils.logger.setLevel(args.log_level.upper())


Copy link
Contributor

@tokland tokland Feb 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra blank line

if getattr(args, "strict_sql", False) and not args.run_sql:
parser.error("--strict-sql requires --run-sql to be set")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot do args checking of some specific command (start) in the main cli.

The check should be done in the "run" function of start.py.

if not getattr(args, "func", None):
parser.print_usage()
return 1
Expand Down
9 changes: 8 additions & 1 deletion src/d2_docker/commands/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def setup(parser):
parser.add_argument("--tomcat-server-xml", metavar="FILE", help=server_xml_help)
parser.add_argument("--dhis-conf", metavar="FILE", help=dhis_conf_help)
parser.add_argument("--run-sql", metavar="DIRECTORY", help="Run .sql[.gz] files in directory")
parser.add_argument("--strict-sql", action="store_true", default=False, help="Stop the sql script on first fail and show in the log")
parser.add_argument("--debug-port", metavar="PORT", help="Expose DHIS2 core debug port")
parser.add_argument("--db-port", metavar="PORT", help="Expose DB Postgres port")
parser.add_argument(
Expand Down Expand Up @@ -93,6 +94,11 @@ def start(args):
)

deploy_path = "/" + re.sub("^/*", "", args.deploy_path) if args.deploy_path else ""
post_strict_sql_dir = None
post_sql_dir = args.run_sql
if args.run_sql and args.strict_sql:
post_strict_sql_dir = post_sql_dir
post_sql_dir = None

with utils.stop_docker_on_interrupt(image_name, core_image):
utils.run_docker_compose(
Expand All @@ -102,7 +108,8 @@ def start(args):
bind_ip=args.bind_ip,
core_image=core_image,
load_from_data=override_containers,
post_sql_dir=args.run_sql,
post_sql_dir=post_sql_dir,
post_strict_sql_dir=post_strict_sql_dir,
Copy link
Contributor

@tokland tokland Feb 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of passing a new sql_dir param, we could pass the boolean flag so the script knows if the mode is "strict" or not. This would greatly simplify dhis2-core-start.sh (and support all kind of files, not only sql)

debug_port=args.debug_port,
db_port=args.db_port,
scripts_dir=args.run_scripts,
Expand Down
17 changes: 15 additions & 2 deletions src/d2_docker/config/dhis2-core-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ export PGPASSWORD="dhis"

dhis2_url="http://localhost:8080/$DEPLOY_PATH"
dhis2_url_with_auth="http://$DHIS2_AUTH@localhost:8080/$DEPLOY_PATH"
psql_cmd="psql -v ON_ERROR_STOP=0 --quiet -h db -U dhis dhis2"
psql_base_cmd="psql --quiet -h db -U dhis dhis2"
psql_cmd="$psql_base_cmd -v ON_ERROR_STOP=0"
psql_strict_cmd="$psql_base_cmd -v ON_ERROR_STOP=1"
pgrestore_cmd="pg_restore -h db -U dhis -d dhis2"
configdir="/config"
homedir="/dhis2-home-files"
scripts_dir="/data/scripts"
root_db_path="/data/db"
post_db_path="/data/db/post"
post_strict_db_path="/data/db/post_strict_sql"
source_apps_path="/data/apps"
source_documents_path="/data/document"
source_datavalues_path="/data/dataValue"
Expand All @@ -50,12 +53,22 @@ run_sql_files() {
echo "Load SQL (compressed): $path"
zcat "$path" | $psql_cmd || true
done

find "$base_db_path" -type f \( -name '*.sql' \) |
sort | while read -r path; do
echo "Load SQL: $path"
$psql_cmd <"$path" || true
done
find "$post_strict_db_path" -type f \( -name '*.sql' \) |
sort | while read -r path; do
echo "Load SQL: $path"
$psql_strict_cmd <"$path"
exit_code=$?
echo "Exit code of psql: $exit_code"
if [[ $exit_code -ne 0 ]]; then
echo "Error detected while executing SQL file: $path"
fi
true
done
}

run_pre_scripts() {
Expand Down
1 change: 1 addition & 0 deletions src/d2_docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ services:
- "${TOMCAT_SERVER}:/config/override/tomcat/server.xml"
- "${SCRIPTS_DIR}:/data/scripts"
- "${POST_SQL_DIR}:/data/db/post"
- "${POST_STRICT_SQL_DIR}:/data/db/post_strict_sql"
- "/etc/timezone:/etc/timezone:ro"
- "/etc/localtime:/etc/localtime:ro"
environment:
Expand Down
4 changes: 4 additions & 0 deletions src/d2_docker/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ def run_docker_compose(
port=None,
load_from_data=True,
post_sql_dir=None,
post_strict_sql_dir=None,
debug_port=None,
db_port=None,
bind_ip=None,
Expand All @@ -274,6 +275,7 @@ def run_docker_compose(
project_name = get_project_name(final_image_name)
core_image_name = core_image or get_core_image_name(data_image)
post_sql_dir_abs = get_absdir_for_docker_volume(post_sql_dir)
post_strict_sql_dir_abs= get_absdir_for_docker_volume(post_strict_sql_dir)
scripts_dir_abs = get_absdir_for_docker_volume(scripts_dir)

env_pairs = [
Expand All @@ -285,6 +287,8 @@ def run_docker_compose(
("LOAD_FROM_DATA", "yes" if load_from_data else "no"),
# Set default values for directory, required by docker-compose volumes section
("POST_SQL_DIR", post_sql_dir_abs),
("POST_STRICT_SQL_DIR", post_strict_sql_dir_abs),

("SCRIPTS_DIR", scripts_dir_abs),
("DEPLOY_PATH", deploy_path or ""),
("JAVA_OPTS", java_opts or ""),
Expand Down