Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 197 additions & 0 deletions _unit-test/migrate-pgbouncer-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
#!/usr/bin/env bash

source _unit-test/_test_setup.sh
source install/dc-detect-version.sh

source install/ensure-files-from-examples.sh
cp $SENTRY_CONFIG_PY /tmp/sentry_conf_py
# Set the flag to apply automatic updates
export APPLY_AUTOMATIC_CONFIG_UPDATES=1

# Declare expected content
expected_db_config=$(
cat <<'EOF'
DATABASES = {
"default": {
"ENGINE": "sentry.db.postgres",
"NAME": "postgres",
"USER": "postgres",
"PASSWORD": "",
"HOST": "pgbouncer",
"PORT": "",
}
}
EOF
)

echo "Test 1 (pre 25.9.0 release)"
# Modify the `DATABASES = {` to the next `}` line, with:
# DATABASES = {
# "default": {
# "ENGINE": "sentry.db.postgres",
# "NAME": "postgres",
# "USER": "postgres",
# "PASSWORD": "",
# "HOST": "postgres",
# "PORT": "",
# }
# }

# Create the replacement text in a temp file
cat >/tmp/sentry_conf_py_db_config <<'EOF'
DATABASES = {
"default": {
"ENGINE": "sentry.db.postgres",
"NAME": "postgres",
"USER": "postgres",
"PASSWORD": "",
"HOST": "postgres",
"PORT": "",
}
}
EOF

# Replace the block
sed -i '/^DATABASES = {$/,/^}$/{
/^DATABASES = {$/r /tmp/sentry_conf_py_db_config
d
}' $SENTRY_CONFIG_PY

# Clean up
rm /tmp/sentry_conf_py_db_config

source install/migrate-pgbouncer.sh

# Extract actual content
actual_db_config=$(sed -n '/^DATABASES = {$/,/^}$/p' $SENTRY_CONFIG_PY)

# Compare
if [ "$actual_db_config" = "$expected_db_config" ]; then
echo "DATABASES section is correct"
else
echo "DATABASES section does not match"
echo "Expected:"
echo "$expected_db_config"
echo "Actual:"
echo "$actual_db_config"
exit 1
fi

# Reset the file
rm $SENTRY_CONFIG_PY
cp /tmp/sentry_conf_py $SENTRY_CONFIG_PY

echo "Test 2 (post 25.9.0 release)"
# Modify the `DATABASES = {` to the next `}` line, with:
# DATABASES = {
# "default": {
# "ENGINE": "sentry.db.postgres",
# "NAME": "postgres",
# "USER": "postgres",
# "PASSWORD": "",
# "HOST": "pgbouncer",
# "PORT": "",
# }
# }

# Create the replacement text in a temp file
cat >/tmp/sentry_conf_py_db_config <<'EOF'
DATABASES = {
"default": {
"ENGINE": "sentry.db.postgres",
"NAME": "postgres",
"USER": "postgres",
"PASSWORD": "",
"HOST": "pgbouncer",
"PORT": "",
}
}
EOF

# Replace the block
sed -i '/^DATABASES = {$/,/^}$/{
/^DATABASES = {$/r /tmp/sentry_conf_py_db_config
d
}' $SENTRY_CONFIG_PY

# Clean up
rm /tmp/sentry_conf_py_db_config

source install/migrate-pgbouncer.sh

# Extract actual content
actual_db_config=$(sed -n '/^DATABASES = {$/,/^}$/p' $SENTRY_CONFIG_PY)

# Compare
if [ "$actual_db_config" = "$expected_db_config" ]; then
echo "DATABASES section is correct"
else
echo "DATABASES section does not match"
echo "Expected:"
echo "$expected_db_config"
echo "Actual:"
echo "$actual_db_config"
exit 1
fi

# Reset the file
rm $SENTRY_CONFIG_PY
cp /tmp/sentry_conf_py $SENTRY_CONFIG_PY

echo "Test 3 (custom postgres config)"
# Modify the `DATABASES = {` to the next `}` line, with:
# DATABASES = {
# "default": {
# "ENGINE": "sentry.db.postgres",
# "NAME": "postgres",
# "USER": "sentry",
# "PASSWORD": "sentry",
# "HOST": "postgres.internal",
# "PORT": "5432",
# }
# }

# Create the replacement text in a temp file
cat >/tmp/sentry_conf_py_db_config <<'EOF'
DATABASES = {
"default": {
"ENGINE": "sentry.db.postgres",
"NAME": "postgres",
"USER": "sentry",
"PASSWORD": "sentry",
"HOST": "postgres.internal",
"PORT": "5432",
}
}
EOF

# Replace the block
sed -i '/^DATABASES = {$/,/^}$/{
/^DATABASES = {$/r /tmp/sentry_conf_py_db_config
d
}' $SENTRY_CONFIG_PY

# Clean up
rm /tmp/sentry_conf_py_db_config

source install/migrate-pgbouncer.sh

# Extract actual content
actual_db_config=$(sed -n '/^DATABASES = {$/,/^}$/p' $SENTRY_CONFIG_PY)

# THe file should NOT be modified
if [ "$actual_db_config" = "$expected_db_config" ]; then
echo "DATABASES section SHOULD NOT be modified"
echo "Expected:"
echo "$expected_db_config"
echo "Actual:"
echo "$actual_db_config"
exit 1
else
echo "DATABASES section is correct"
fi

# Remove the file
rm $SENTRY_CONFIG_PY /tmp/sentry_conf_py

report_success
82 changes: 82 additions & 0 deletions install/migrate-pgbouncer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
echo "${_group}Migrating Postgres config to PGBouncer..."
# If users has this EXACT configuration on their `sentry.conf.py` file:
# ```python
# DATABASES = {
# "default": {
# "ENGINE": "sentry.db.postgres",
# "NAME": "postgres",
# "USER": "postgres",
# "PASSWORD": "",
# "HOST": "postgres",
# "PORT": "",
# }
# }
# ```
# We need to migrate it to this configuration:
# ```python
# DATABASES = {
# "default": {
# "ENGINE": "sentry.db.postgres",
# "NAME": "postgres",
# "USER": "postgres",
# "PASSWORD": "",
# "HOST": "pgbouncer",
# "PORT": "",
# }
# }
# ```

if sed -n '/^DATABASES = {$/,/^}$/p' "$SENTRY_CONFIG_PY" | grep -q '"HOST": "postgres"'; then
Copy link
Member

Choose a reason for hiding this comment

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

I think we should either check SKIP_USER_CREATION, SKIP_USER_PROMPT env vars, check for an interactive TTY and/or add a SENTRY_NON_INTERACTIVE_INSTALL option to skip all prompts in a sane way.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've re-read the codebase, practically the existing SKIP_USER_PROMPT is SENTRY_NON_INTERACTIVE_INSTALL. I'll just add that.

apply_config_changes_pgbouncer=0
if [[ -z "${APPLY_AUTOMATIC_CONFIG_UPDATES:-}" ]]; then
echo
echo "We added PGBouncer to the default Compose stack, and to use that"
echo "you will need to modify your sentry.conf.py file contents."
echo "Do you want us to make this change automatically for you?"
echo

yn=""
until [ ! -z "$yn" ]; do
read -p "y or n? " yn
case $yn in
y | yes | 1)
export apply_config_changes_pgbouncer=1
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

FYI @BYK I made a change for this one, to not let it populate the global APPLY_AUTOMATIC_CONFIG_UPDATES. Hopefully this is the right approach.

Copy link
Member

Choose a reason for hiding this comment

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

Looks good to me. Not sure if you should be exporting it tho.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure about it either. Took the safest way about it.

echo
echo -n "Thank you."
;;
n | no | 0)
export apply_config_changes_pgbouncer=0
echo
echo -n "Alright, you will need to update your sentry.conf.py file manually before running 'docker compose up' or remove the $(pgbouncer) service if you don't want to use that."
;;
*) yn="" ;;
esac
done

echo
echo "To avoid this prompt in the future, use one of these flags:"
echo
echo " --apply-automatic-config-updates"
echo " --no-apply-automatic-config-updates"
echo
echo "or set the APPLY_AUTOMATIC_CONFIG_UPDATES environment variable:"
echo
echo " APPLY_AUTOMATIC_CONFIG_UPDATES=1 to apply automatic updates"
echo " APPLY_AUTOMATIC_CONFIG_UPDATES=0 to not apply automatic updates"
echo
sleep 5
fi

if [[ "$APPLY_AUTOMATIC_CONFIG_UPDATES" == 1 || "$apply_config_changes_pgbouncer" == 1 ]]; then
echo "Migrating $SENTRY_CONFIG_PY to use PGBouncer"
sed -i 's/"HOST": "postgres"/"HOST": "pgbouncer"/' "$SENTRY_CONFIG_PY"
echo "Migrated $SENTRY_CONFIG_PY to use PGBouncer"
fi
elif sed -n '/^DATABASES = {$/,/^}$/p' "$SENTRY_CONFIG_PY" | grep -q '"HOST": "pgbouncer"'; then
echo "Found pgbouncer in $SENTRY_CONFIG_PY, I'm assuming you're good! :)"
else
echo "⚠️ You don't have standard configuration for Postgres in $SENTRY_CONFIG_PY, skipping pgbouncer migration. I'm assuming you know what you're doing."
echo " For more information about PGBouncer, refer to https://github.com/getsentry/self-hosted/pull/3884"
fi

echo "${_endgroup}"
8 changes: 8 additions & 0 deletions install/parse-cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ Options:
self-hosted instance upstream to Sentry.
--container-engine-podman
Use podman as the container engine.
--apply-automatic-config-updates
Apply automatic config file updates.
--no-apply-automatic-config-updates
Do not apply automatic config file updates.
EOF
}

Expand All @@ -41,6 +45,7 @@ depwarn() {
if [ ! -z "${SKIP_USER_PROMPT:-}" ]; then
depwarn "SKIP_USER_PROMPT variable" "SKIP_USER_CREATION"
SKIP_USER_CREATION="${SKIP_USER_PROMPT}"
APPLY_AUTOMATIC_CONFIG_UPDATES="${SKIP_USER_PROMPT}"
Copy link
Member

Choose a reason for hiding this comment

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

Slightly nervous about this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Why

Copy link
Member

Choose a reason for hiding this comment

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

Because we will be trying the auto migration/config update without asking about it. Ideally this would be no action on non-interactive installs that said since you try to ensure it is unchanged, I'm fine. Just a little bit nervous in case we missed something.

fi

SKIP_USER_CREATION="${SKIP_USER_CREATION:-}"
Expand All @@ -49,6 +54,7 @@ SKIP_COMMIT_CHECK="${SKIP_COMMIT_CHECK:-}"
REPORT_SELF_HOSTED_ISSUES="${REPORT_SELF_HOSTED_ISSUES:-}"
SKIP_SSE42_REQUIREMENTS="${SKIP_SSE42_REQUIREMENTS:-}"
CONTAINER_ENGINE_PODMAN="${CONTAINER_ENGINE_PODMAN:-}"
APPLY_AUTOMATIC_CONFIG_UPDATES="${APPLY_AUTOMATIC_CONFIG_UPDATES:-}"

while (($#)); do
case "$1" in
Expand All @@ -71,6 +77,8 @@ while (($#)); do
--no-report-self-hosted-issues) REPORT_SELF_HOSTED_ISSUES=0 ;;
--skip-sse42-requirements) SKIP_SSE42_REQUIREMENTS=1 ;;
--container-engine-podman) CONTAINER_ENGINE_PODMAN=1 ;;
--apply-automatic-config-updates) APPLY_AUTOMATIC_CONFIG_UPDATES=1 ;;
--no-apply-automatic-config-updates) APPLY_AUTOMATIC_CONFIG_UPDATES=0 ;;
--) ;;
*)
echo "Unexpected argument: $1. Use --help for usage information."
Expand Down