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

chore: create appsmith schema for postgres #36591

Merged
merged 20 commits into from
Sep 30, 2024

Conversation

AnaghHegde
Copy link
Member

@AnaghHegde AnaghHegde commented Sep 27, 2024

Description

The current state is default schema or public schema. This schema is accessible by default when user connects to the pg database. Hence create appsmith schema for Appsmith server to use. This is to avoid anyone accidentally modifying the appsmith data.

Automation

/ok-to-test tags="@tag.Sanity"

🔍 Cypress test results

Warning

Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/11111681323
Commit: 32f91e8
Cypress dashboard.
Tags: @tag.Sanity
Spec:
It seems like no tests ran 😔. We are not able to recognize it, please check workflow here.


Tue, 01 Oct 2024 02:47:18 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced a script to initialize the PostgreSQL database schema for Appsmith.
    • Added utilities for managing PostgreSQL database connections, including availability checks and parameter extraction.
    • Enhanced scripts for managing PostgreSQL connections and initialization.
    • Improved environment configuration for PostgreSQL database connections, including automatic password generation for local setups.
    • Updated JDBC URL handling to include schema parameters for PostgreSQL connections.
    • Added support for proxy configuration in the application setup.
  • Bug Fixes

    • Improved error handling and connection retry mechanisms for PostgreSQL setup.
  • Documentation

    • Updated comments and logging for better clarity on database operations.

Copy link
Contributor

coderabbitai bot commented Sep 27, 2024

Walkthrough

The changes introduce new shell scripts focused on PostgreSQL database initialization and connection management within Appsmith. The pg-default-schema.sh script is responsible for creating the database schema, while pg-utils.sh provides utility functions for checking PostgreSQL availability and extracting connection parameters. Additionally, the run-java.sh script has been updated to utilize these functionalities, improving the overall management of PostgreSQL connections.

Changes

Files Change Summary
deploy/docker/fs/opt/appsmith/pg-default-schema.sh Introduced a script to initialize the PostgreSQL schema, including validation of the database URL and connection attempts.
deploy/docker/fs/opt/appsmith/pg-utils.sh Added functions for checking PostgreSQL availability and extracting database parameters from a connection string.
deploy/docker/fs/opt/appsmith/run-java.sh Modified to source pg-utils.sh, check PostgreSQL mode, and run the schema initialization script in the background.
deploy/docker/fs/opt/appsmith/entrypoint.sh Enhanced init_env_file to manage database credentials based on the APPSMITH_DB_URL.
deploy/docker/fs/opt/appsmith/templates/docker.env.sh Renamed MONGO_PASSWORD to DB_PASSWORD for consistency in environment variable usage.
app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CommonDBConfig.java Updated JDBC URL construction to append currentSchema=appsmith to the query parameters.
app/server/appsmith-server/src/test/java/com/appsmith/server/configurations/CommonDBConfigTest.java Adjusted test cases to reflect the new JDBC URL format including the currentSchema parameter.

Possibly related PRs

Suggested labels

Task, Move to Postgres, DB Infrastructure Pod

Suggested reviewers

  • sharat87
  • mohanarpit
  • pratapaprasanna

In the land of code where functions play,
New scripts emerge to brighten the day.
With PostgreSQL now in command,
Initialization goes as planned.
So let’s celebrate this splendid feat,
With joyful cheers, our work's complete! 🎉


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@AnaghHegde AnaghHegde added the ok-to-test Required label for CI label Sep 27, 2024
@github-actions github-actions bot added the skip-changelog Adding this label to a PR prevents it from being listed in the changelog label Sep 27, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Outside diff range and nitpick comments (2)
deploy/docker/fs/opt/appsmith/pg-default-schema.sh (1)

42-50: Consider adding retry logic for schema creation

If the schema creation fails due to transient issues, it would be helpful to implement retry logic. Retrying a few times before exiting can make the script more robust against temporary network issues or database locks.

deploy/docker/fs/opt/appsmith/pg-utils.sh (1)

22-22: Enhance clarity in log message

In line 22, the log message uses "e.g." twice, which can be redundant and may affect readability. Let's refine the message for better clarity.

Suggested change:

- tlog "PostgreSQL host '$PG_DB_HOST' is rejecting connections e.g. due to being in recovery mode or not accepting connections eg. connections maxed out."
+ tlog "PostgreSQL host '$PG_DB_HOST' is rejecting connections, possibly due to being in recovery mode or connections being maxed out."
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b1ed82d and d89a596.

📒 Files selected for processing (3)
  • deploy/docker/fs/opt/appsmith/pg-default-schema.sh (1 hunks)
  • deploy/docker/fs/opt/appsmith/pg-utils.sh (1 hunks)
  • deploy/docker/fs/opt/appsmith/run-java.sh (3 hunks)
🧰 Additional context used
🪛 Shellcheck
deploy/docker/fs/opt/appsmith/pg-utils.sh

[warning] 65-80: Quote this to prevent word splitting.

(SC2046)

🔇 Additional comments (3)
deploy/docker/fs/opt/appsmith/run-java.sh (1)

3-4: Excellent inclusion of the PostgreSQL utilities script

By sourcing pg-utils.sh, you're ensuring that all the necessary PostgreSQL functions are available for use in this script. This promotes modularity and reusability, which are important principles in scripting.

deploy/docker/fs/opt/appsmith/pg-utils.sh (2)

3-48: Well-structured function for PostgreSQL availability check

The waitForPostgresAvailability function is thoughtfully designed, covering various PostgreSQL status codes and incorporating a robust retry mechanism. Excellent work in ensuring the application waits appropriately for the database to become ready before proceeding.


61-88: Consider potential issues with spaces or special characters in connection parameters

If any of the connection parameters (username, password, hostname, database name) contain spaces or special characters, the current parsing approach may fail. It's advisable to handle such cases to make your script more robust.

You can test this by using a connection string with spaces in the credentials:

🧰 Tools
🪛 Shellcheck

[warning] 65-80: Quote this to prevent word splitting.

(SC2046)

deploy/docker/fs/opt/appsmith/pg-default-schema.sh Outdated Show resolved Hide resolved
deploy/docker/fs/opt/appsmith/pg-default-schema.sh Outdated Show resolved Hide resolved
deploy/docker/fs/opt/appsmith/run-java.sh Outdated Show resolved Hide resolved
deploy/docker/fs/opt/appsmith/run-java.sh Outdated Show resolved Hide resolved
deploy/docker/fs/opt/appsmith/pg-utils.sh Outdated Show resolved Hide resolved
@AnaghHegde
Copy link
Member Author

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11070738411.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 36591.
recreate: .

Copy link

Deploy-Preview-URL: https://ce-36591.dp.appsmith.com

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Outside diff range and nitpick comments (4)
deploy/docker/fs/opt/appsmith/templates/docker.env.sh (3)

66-66: Good job updating the database connection string!

Students, notice how we've correctly updated our MongoDB connection string to use the new DB_PASSWORD variable. This ensures our application can still connect to the database after our variable renaming exercise.

However, I have a little homework for you: Consider using environment variables for the hostname and port as well. This would make our configuration even more flexible for different deployment scenarios. What do you think about that?

Here's an example of how you could further improve this line:

-APPSMITH_DB_URL=mongodb://$MONGO_USER:$DB_PASSWORD@localhost:27017/appsmith
+APPSMITH_DB_URL=mongodb://$MONGO_USER:$DB_PASSWORD@$DB_HOST:$DB_PORT/appsmith

Don't forget to define DB_HOST and DB_PORT variables at the beginning of the script!


67-67: Excellent addition of the PostgreSQL connection string!

Class, this is a perfect example of forward-thinking in our code. By adding this commented-out PostgreSQL connection string, we're preparing our application to work with different database systems. It's like having a backup plan – always a smart move!

However, I have a small suggestion to make this even better. For consistency with our MongoDB string, let's use the $MONGO_USER variable here too, instead of hardcoding 'appsmith'. This way, we maintain flexibility in our user configuration across different database systems.

Here's a small improvement we could make:

-#APPSMITH_DB_URL=postgresql://appsmith:$DB_PASSWORD@localhost:5432/postgres
+#APPSMITH_DB_URL=postgresql://$MONGO_USER:$DB_PASSWORD@localhost:5432/postgres

Remember, consistency is key in coding, just like in your homework assignments!


69-69: Well done on updating the MongoDB password variable!

Class, observe how we've correctly updated the APPSMITH_MONGODB_PASSWORD to use our new DB_PASSWORD variable. This ensures that our MongoDB configuration remains consistent with our earlier changes.

However, I have a thought-provoking question for you: Given that we're now supporting multiple database types, should we consider renaming this variable to something more generic? This could help avoid confusion if we switch to a different database system in the future.

Here's a suggestion to ponder:

-APPSMITH_MONGODB_PASSWORD=$DB_PASSWORD
+APPSMITH_DB_PASSWORD=$DB_PASSWORD

What do you think about this change? How might it impact our application's flexibility and maintainability? Let's discuss!

deploy/docker/fs/opt/appsmith/entrypoint.sh (1)

95-95: Ensure Consistent Definition of Database User

The DB_USER variable is set to "appsmith":

DB_USER="appsmith"

Confirm that this username aligns with the expected database user elsewhere in your configuration to maintain consistency.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 1edfc6f and 1413b1e.

📒 Files selected for processing (2)
  • deploy/docker/fs/opt/appsmith/entrypoint.sh (2 hunks)
  • deploy/docker/fs/opt/appsmith/templates/docker.env.sh (2 hunks)
🔇 Additional comments (3)
deploy/docker/fs/opt/appsmith/templates/docker.env.sh (2)

5-5: Excellent work on generalizing the database password variable!

Class, let's take a moment to appreciate this change. By renaming MONGO_PASSWORD to DB_PASSWORD, we're making our code more flexible. This allows us to potentially use different types of databases in the future, not just MongoDB. It's like having a universal key that can open many doors!


Line range hint 1-95: Excellent work on adapting the environment configuration for multiple databases!

Class, let's recap what we've learned from this code review:

  1. We've successfully generalized our database configuration, making it easier to switch between MongoDB and PostgreSQL.
  2. The changes are consistent and well-thought-out, showing good attention to detail.
  3. We've identified a few areas where we can further improve flexibility and consistency.

Remember, in the world of software development, adaptability is key. By making these changes, we're preparing our application for future growth and different deployment scenarios.

For your next assignment, I want you to think about other parts of the application that might need similar updates to support multiple database types. How can we ensure our entire system is as flexible as this configuration file?

Keep up the great work!

deploy/docker/fs/opt/appsmith/entrypoint.sh (1)

96-96: Use Secure Password Generation

While openssl rand is effective, specifying the length in bytes might not result in the desired number of characters. The command:

DB_PASSWORD=$(openssl rand -base64 12)  # Generate a random password

Ensure that the generated password meets your security requirements regarding length and complexity. You might want to increase the length parameter to generate a longer password.

deploy/docker/fs/opt/appsmith/entrypoint.sh Outdated Show resolved Hide resolved
deploy/docker/fs/opt/appsmith/entrypoint.sh Outdated Show resolved Hide resolved
deploy/docker/fs/opt/appsmith/entrypoint.sh Outdated Show resolved Hide resolved
deploy/docker/fs/opt/appsmith/entrypoint.sh Outdated Show resolved Hide resolved
deploy/docker/fs/opt/appsmith/entrypoint.sh Outdated Show resolved Hide resolved
@AnaghHegde
Copy link
Member Author

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11071132873.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 36591.
recreate: .

Copy link

Deploy-Preview-URL: https://ce-36591.dp.appsmith.com

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CommonDBConfig.java (1)

71-84: Excellent work on improving the URL construction, students!

Your new logic for handling query parameters is a significant improvement. Let's break it down for the class:

  1. You check if the URL already has query parameters.
  2. If parameters exist, you append the currentSchema=appsmith to the existing query string.
  3. If no parameters exist, you add currentSchema=appsmith as the first parameter.

This approach ensures that the currentSchema is always set without overwriting existing parameters. Well done!

However, to make your code even more readable for your classmates, consider extracting the URL format strings into constants. Here's a little homework for you:

private static final String URL_FORMAT_WITH_QUERY = "%s%s://%s:%s%s?%s&currentSchema=appsmith";
private static final String URL_FORMAT_WITHOUT_QUERY = "%s%s://%s:%s%s?currentSchema=appsmith";

// Then use these constants in your String.format calls

This small change will make your code easier to maintain and understand. Remember, clear code is happy code!

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 1413b1e and cb4a295.

📒 Files selected for processing (1)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CommonDBConfig.java (1 hunks)
🔇 Additional comments (1)
app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/CommonDBConfig.java (1)

68-69: Good job clarifying the default port comment, class!

You've done well in updating the comment to specify that 5432 is the standard PostgreSQL port. This kind of clarity is important for your fellow students who might be new to database configurations.

Copy link

Failed server tests

  • com.appsmith.server.configurations.CommonDBConfigTest#testExtractAndSaveJdbcParams_validDbUrlWithUsernameAndPassword
  • com.appsmith.server.configurations.CommonDBConfigTest#testExtractAndSaveJdbcParams_validDbUrlWithoutUsernameAndPassword
  • com.appsmith.server.solutions.CreateDBTablePageSolutionTests#createPageWithInvalidApplicationIdTest

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
app/server/appsmith-server/src/test/java/com/appsmith/server/configurations/CommonDBConfigTest.java (1)

35-35: Good job on covering different scenarios, class!

I'm impressed that you've consistently applied the "?currentSchema=appsmith" addition across different test cases, including this one without username and password. This demonstrates attention to detail and thorough testing practices.

However, to make your test suite even more comprehensive, consider adding one more test case:

@Test
public void testExtractAndSaveJdbcParams_validDbUrlWithUsernamePasswordAndExistingQueryParams() {
    CommonDBConfig commonDBConfig = new CommonDBConfig();
    String dbUrl = "postgresql://postgres:password@localhost:5432/postgres?sslmode=require";
    DataSourceProperties ds = commonDBConfig.extractJdbcProperties(dbUrl);
    assertEquals("postgres", ds.getUsername());
    assertEquals("password", ds.getPassword());
    assertEquals("jdbc:postgresql://localhost:5432/postgres?sslmode=require&currentSchema=appsmith", ds.getUrl());
}

This additional test will ensure that the currentSchema parameter is correctly appended when other query parameters already exist in the URL. Remember, in software development, it's always better to be thorough!

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between cb4a295 and 833832d.

📒 Files selected for processing (1)
  • app/server/appsmith-server/src/test/java/com/appsmith/server/configurations/CommonDBConfigTest.java (2 hunks)
🔇 Additional comments (2)
app/server/appsmith-server/src/test/java/com/appsmith/server/configurations/CommonDBConfigTest.java (2)

19-19: Well done, class! Let's examine this change.

The addition of "?currentSchema=appsmith" to the expected JDBC URL is a smart move. It ensures that our Appsmith application will use a specific schema when connecting to PostgreSQL. This change will help maintain consistency across different environments and prevent potential conflicts with other schemas.


25-25: Excellent work on consistency, students!

I'm pleased to see that you've applied the same "?currentSchema=appsmith" addition to this test case as well. It's crucial to maintain consistency across different scenarios. By testing with a non-standard port (1234), you're demonstrating good test coverage. Remember, thorough testing is the foundation of robust software!

Copy link
Contributor

@abhvsn abhvsn left a comment

Choose a reason for hiding this comment

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

Added few comments for clarification. Also I didn't find the create user commend which is required to execute the create schema command. How did we test this change?

deploy/docker/fs/opt/appsmith/entrypoint.sh Outdated Show resolved Hide resolved
deploy/docker/fs/opt/appsmith/entrypoint.sh Show resolved Hide resolved
# Check if the DB_HOST is local (localhost or 127.0.0.1)
if [[ "$PG_DB_HOST" == "localhost" || "$PG_DB_HOST" == "127.0.0.1" ]]; then
echo "Local PostgreSQL detected, switching to postgres user."
PGPASSWORD=$PG_DB_PASSWORD su - postgres -c "psql -h $PG_DB_HOST -p $PG_DB_PORT -U $PG_DB_USER -d $PG_DB_NAME -c 'CREATE SCHEMA IF NOT EXISTS appsmith;'"
Copy link
Contributor

Choose a reason for hiding this comment

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

We are su to postgres and then again passing the user via -U, have we tested this change?

@AnaghHegde
Copy link
Member Author

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11105610023.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 36591.
recreate: .

Copy link

Deploy-Preview-URL: https://ce-36591.dp.appsmith.com

@AnaghHegde
Copy link
Member Author

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/11109372703.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 36591.
recreate: .

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (1)
deploy/docker/fs/opt/appsmith/run-java.sh (1)

Attention to Detail Needed on pg-default-schema.sh Invocation 🛠️

Excellent progress on enhancing error handling! However, we've identified that pg-default-schema.sh is not being invoked anywhere in the current scripts. This omission could potentially reintroduce the race conditions we aimed to resolve with init_pg_db.

Action Items:

  • Confirm Invocation: Verify if pg-default-schema.sh is invoked elsewhere in the codebase or if its responsibilities have been relocated.
  • Reintegrate if Necessary: If it's required, ensure that pg-default-schema.sh is properly called within run-java.sh or the appropriate initialization scripts to prevent race conditions.

Let's make sure our setup is as reliable as our intentions! 👍

🔗 Analysis chain

Line range hint 28-39: Let's revisit some previous lessons, class!

We had some excellent feedback in our last review that we should address:

  1. Error Handling: We need to ensure our PostgreSQL functions (extract_postgres_db_params, waitForPostgresAvailability, and init_pg_db) handle errors gracefully. Remember, proper error handling is like wearing a safety helmet – it protects us from unexpected bumps!

  2. Race Conditions: The addition of init_pg_db is a step in the right direction to address potential race conditions. However, we should verify that this indeed solves the issue with pg-default-schema.sh.

Let's check the implementation of these functions to ensure they include proper error handling:

This will help us ensure our functions are handling errors properly and provide meaningful error messages.

To verify the resolution of the race condition issue:

This will show us where pg-default-schema.sh is being executed in relation to our PostgreSQL initialization steps.


Great job addressing the initial concerns! 🏆 Let's dive a bit deeper to ensure everything is shipshape:

  1. Error Handling:
    Let's make sure that all PostgreSQL-related functions (extract_postgres_db_params, waitForPostgresAvailability, and init_pg_db) are equipped with comprehensive error handling. This ensures our script doesn't stumble unexpectedly.

  2. Race Conditions:
    Since pg-default-schema.sh isn't being called in run-java.sh, we need to confirm if it's handled elsewhere or if additional steps are needed to prevent race conditions.

To thoroughly verify these aspects, let's run a couple more checks:

[/run_scripts]

Let's gather these results to ensure our script is as robust as it can be!

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check error handling in PostgreSQL-related functions

grep -n -A 10 "extract_postgres_db_params()" deploy/docker/fs/opt/appsmith/pg-utils.sh
echo "---"
grep -n -A 10 "waitForPostgresAvailability()" deploy/docker/fs/opt/appsmith/pg-utils.sh
echo "---"
grep -n -A 10 "init_pg_db()" deploy/docker/fs/opt/appsmith/pg-utils.sh

Length of output: 1636


Script:

#!/bin/bash
# Description: Check the execution order of pg-default-schema.sh

grep -n "pg-default-schema.sh" deploy/docker/fs/opt/appsmith/run-java.sh

Length of output: 72


Script:

#!/bin/bash
# Description: Check error handling in extract_postgres_db_params and waitForPostgresAvailability functions

grep -n -A 10 "extract_postgres_db_params()" deploy/docker/fs/opt/appsmith/pg-utils.sh
echo "---"
grep -n -A 10 "waitForPostgresAvailability()" deploy/docker/fs/opt/appsmith/pg-utils.sh

Length of output: 1029


Script:

#!/bin/bash
# Description: Search for any invocation of pg-default-schema.sh in the codebase

rg "pg-default-schema.sh"

Length of output: 25

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 43089a6 and 14a0f35.

📒 Files selected for processing (2)
  • deploy/docker/fs/opt/appsmith/pg-utils.sh (1 hunks)
  • deploy/docker/fs/opt/appsmith/run-java.sh (1 hunks)
🔇 Additional comments (4)
deploy/docker/fs/opt/appsmith/run-java.sh (3)

Line range hint 18-70: Excellent work on improving our proxy configuration, class!

I'm impressed with the enhancements made to our proxy handling. Let's review the key improvements:

  1. The match-proxy-url function: This is a great example of modular programming. It extracts proxy details from environment variables, making our code more readable and maintainable.

  2. Separate handling for HTTP and HTTPS proxies: This allows for more flexible configurations.

  3. Setting NO_PROXY to an empty string if not defined: This is a thoughtful addition that prevents potential issues down the line.

  4. Adding proxy settings to extra_args: This ensures that our Java application will use the configured proxy settings.

Remember, class, clear and modular code like this makes our lives as developers much easier in the long run!


Line range hint 1-93: Class, let's summarize our lesson for today!

We've made some excellent progress with our run-java.sh script. Here's what we've learned:

  1. Database Initialization: We've added the init_pg_db function, which is a great step towards ensuring our PostgreSQL database is properly set up before our application starts.

  2. Proxy Configuration: Our proxy handling has improved significantly. We now have a more robust and flexible system for configuring HTTP and HTTPS proxies.

  3. Error Handling: While we've made improvements, we still need to ensure all our PostgreSQL-related functions have proper error handling. Remember, good error handling is like a good explanation – it helps us understand what went wrong and how to fix it!

  4. Race Conditions: We've taken steps to address potential race conditions, but we should verify that our changes have fully resolved the issue.

For homework, I'd like you all to review the error handling in our PostgreSQL functions and think about how we can make it even better. Remember, in programming as in life, it's not just about getting things right – it's about being prepared for when things go wrong!


39-39: Class, let's examine the new addition to our script!

I see we've introduced a new function call init_pg_db here. This is an excellent step towards proper database initialization. However, we must ensure that this function is well-defined and handles potential errors gracefully.

Remember, class, in programming as in life, it's important to be prepared for all scenarios. Let's make sure this function:

  1. Initializes the PostgreSQL database correctly
  2. Handles any potential errors that may occur during initialization
  3. Provides clear feedback or logging for troubleshooting purposes

To ensure our init_pg_db function is properly implemented, let's take a look at its definition:

#!/bin/bash
# Description: Check the implementation of init_pg_db function

grep -n -A 10 "init_pg_db()" deploy/docker/fs/opt/appsmith/pg-utils.sh

This will help us understand how the function is implemented and if it addresses our concerns about error handling and logging.

deploy/docker/fs/opt/appsmith/pg-utils.sh (1)

90-139: Class, let's summarize our review of the new init_pg_db function.

Overall, you've done a commendable job in creating this function to initialize the PostgreSQL database and schema for Appsmith. The structure is logical, and it handles both local and remote database scenarios.

However, as we've discussed, there are several areas for improvement:

  1. Enhance URL validation and host type determination.
  2. Implement better security practices, especially in handling user credentials.
  3. Improve error handling throughout the function.
  4. Add more robust verification steps.

These changes will make the function more secure, reliable, and maintainable. Remember, in database management, we must always prioritize data integrity and security.

Keep up the good work, and don't forget to apply these lessons in your future coding assignments!

Comment on lines 101 to 123
# Check if the database exists
DB_CHECK=$(psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "postgres" -tAc "SELECT 1 FROM pg_database WHERE datname='$PG_DB_NAME'")

if [ "$DB_CHECK" != "1" ]; then
echo "Database $PG_DB_NAME does not exist. Creating database..."
psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "postgres" -c "CREATE DATABASE $PG_DB_NAME;"
else
echo "Database $PG_DB_NAME already exists."
fi

# Check if the schema exists
SCHEMA_CHECK=$(psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -tAc "SELECT 1 FROM information_schema.schemata WHERE schema_name='appsmith'")

# Create schema and user if not exists
if [ "$SCHEMA_CHECK" != "1" ]; then
echo "Schema 'appsmith' does not exist. Creating schema..."
psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE SCHEMA appsmith;"

echo "Creating user '$PG_DB_USER' with password "
psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE USER '$PG_DB_USER' WITH PASSWORD '$PG_DB_PASSWORD';"
else
echo "Schema 'appsmith' already exists."
fi
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Now, let's turn our attention to the local database and schema creation, class.

You've done a good job structuring the database and schema creation logic. However, there are a few points we need to address:

  1. Excellent use of conditional checks before creating the database and schema!

  2. Be cautious about potential SQL injection in the database name. Let's sanitize it:

    PG_DB_NAME=$(echo "$PG_DB_NAME" | sed 's/[^a-zA-Z0-9_]//g')
  3. There's a syntax error in the user creation SQL. The username should not be in single quotes. Let's fix that:

    psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE USER $PG_DB_USER WITH PASSWORD '$PG_DB_PASSWORD';"
  4. It's generally not a good practice to log passwords, even partially. Let's remove that from the echo statement on line 119.

  5. Consider adding error handling for each psql command to ensure the script exits if any operation fails.

Remember, class, security and error handling are crucial in database management scripts!

Copy link

Deploy-Preview-URL: https://ce-36591.dp.appsmith.com

Copy link

Failed server tests

  • com.appsmith.server.solutions.ce.ActionExecutionSolutionCETest#testWidgetSuggestionAfterExecutionWithArrayOfStringsDropDownWidget

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 14a0f35 and d38ca4d.

📒 Files selected for processing (2)
  • deploy/docker/fs/opt/appsmith/entrypoint.sh (2 hunks)
  • deploy/docker/fs/opt/appsmith/pg-utils.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • deploy/docker/fs/opt/appsmith/entrypoint.sh

deploy/docker/fs/opt/appsmith/pg-utils.sh Show resolved Hide resolved
deploy/docker/fs/opt/appsmith/pg-utils.sh Show resolved Hide resolved
Comment on lines 111 to 123
# Check if the schema exists
SCHEMA_CHECK=$(psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -tAc "SELECT 1 FROM information_schema.schemata WHERE schema_name='appsmith'")

# Create schema and user if not exists
if [ "$SCHEMA_CHECK" != "1" ]; then
echo "Creating user '$PG_DB_USER' with password "
psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE USER \"$PG_DB_USER\" WITH PASSWORD '$PG_DB_PASSWORD';"

echo "Schema 'appsmith' does not exist. Creating schema..."
psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE SCHEMA appsmith;"
else
echo "Schema 'appsmith' already exists."
fi
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Let's examine the schema and user creation, class.

You've made a good start here, but there are several areas we need to improve:

  1. In the user creation SQL, the username should not be in quotes. Let's fix that:

    psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE USER $PG_DB_USER WITH PASSWORD '$PG_DB_PASSWORD';"
  2. We need to add error handling for both schema and user creation:

    if ! psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE SCHEMA appsmith;"; then
        echo "Failed to create schema 'appsmith'. Please check your permissions and try again."
        exit 1
    fi
    
    if ! psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE USER $PG_DB_USER WITH PASSWORD '$PG_DB_PASSWORD';"; then
        echo "Failed to create user $PG_DB_USER. Please check your permissions and try again."
        exit 1
    fi
  3. It's not a good practice to log passwords, even partially. Let's remove that from the echo statement:

    echo "Creating user '$PG_DB_USER'"

Remember, class, security and error handling are paramount in database management!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d38ca4d and 32f91e8.

📒 Files selected for processing (1)
  • deploy/docker/fs/opt/appsmith/pg-utils.sh (1 hunks)

Comment on lines +94 to +99
# Check if APPSMITH_DB_URL is a PostgreSQL URL
if [[ -n "$APPSMITH_DB_URL" && "$APPSMITH_DB_URL" == postgres*://* ]]; then
echo "APPSMITH_DB_URL is a valid PostgreSQL URL."

# Check if the DB_HOST is local (localhost or 127.0.0.1)
if [[ "$PG_DB_HOST" == "localhost" || "$PG_DB_HOST" == "127.0.0.1" ]]; then
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Class, let's examine the URL validation and host determination.

Good effort on validating the APPSMITH_DB_URL! However, we can improve this section:

  1. The condition "$APPSMITH_DB_URL" == postgres*://* might not catch all valid PostgreSQL URLs. Let's use a more robust regex pattern.
  2. Our local host check is incomplete. We should include all possible local addresses.

Here's a suggested improvement:

if [[ -n "$APPSMITH_DB_URL" && "$APPSMITH_DB_URL" =~ ^postgres(ql)?:// ]]; then
    echo "APPSMITH_DB_URL is a valid PostgreSQL URL."

    if [[ "$PG_DB_HOST" == "localhost" || "$PG_DB_HOST" == "127.0.0.1" || "$PG_DB_HOST" == "::1" ]]; then
        echo "Local PostgreSQL instance detected."
    else
        echo "Remote PostgreSQL instance detected."
    fi
else
    echo "Invalid or missing PostgreSQL URL."
    exit 1
fi

This change will catch more valid PostgreSQL URLs and include the IPv6 localhost address. Remember, students, attention to detail is crucial in database management!

Comment on lines +101 to +121
# Check if the database exists
DB_CHECK=$(psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "postgres" -tAc "SELECT 1 FROM pg_database WHERE datname='$PG_DB_NAME'")

if [ "$DB_CHECK" != "1" ]; then
echo "Database $PG_DB_NAME does not exist. Creating database..."
psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "postgres" -c "CREATE DATABASE $PG_DB_NAME;"
else
echo "Database $PG_DB_NAME already exists."
fi

# Check if the schema exists
SCHEMA_CHECK=$(psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -tAc "SELECT 1 FROM information_schema.schemata WHERE schema_name='appsmith'")

# Create schema and user if not exists
if [ "$SCHEMA_CHECK" != "1" ]; then
echo "Creating user '$PG_DB_USER' with password "
psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE USER \"$PG_DB_USER\" WITH PASSWORD '$PG_DB_PASSWORD';"

echo "Schema 'appsmith' does not exist. Creating schema..."
psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE SCHEMA appsmith;"
fi
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Now, let's turn our attention to the local database and schema creation, class.

You've done a good job structuring the database and schema creation logic. However, there are a few points we need to address:

  1. Excellent use of conditional checks before creating the database and schema!

  2. Be cautious about potential SQL injection in the database name. Let's sanitize it:

    PG_DB_NAME=$(echo "$PG_DB_NAME" | sed 's/[^a-zA-Z0-9_]//g')
  3. There's a syntax error in the user creation SQL. The username should not be in double quotes. Let's fix that:

    psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U postgres -d "$PG_DB_NAME" -c "CREATE USER $PG_DB_USER WITH PASSWORD '$PG_DB_PASSWORD';"
  4. It's generally not a good practice to log passwords, even partially. Let's remove that from the echo statement on line 116.

  5. Consider adding error handling for each psql command to ensure the script exits if any operation fails.

Remember, class, security and error handling are crucial in database management scripts!

Comment on lines +122 to +125
else
echo "Remote PostgreSQL detected, running as current user."
PGPASSWORD=$PG_DB_PASSWORD psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U "$PG_DB_USER" -d "$PG_DB_NAME" -c "CREATE SCHEMA IF NOT EXISTS appsmith;"
fi
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Now, let's examine the remote host schema creation, students.

While this section is concise, there are a few important points we need to address:

  1. Using PGPASSWORD in the command line is not the most secure method. However, for scripts, it's acceptable. Just ensure this script is only accessible to authorized users.

  2. We're missing error handling here. Let's add some:

    if ! PGPASSWORD=$PG_DB_PASSWORD psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U "$PG_DB_USER" -d "$PG_DB_NAME" -c "CREATE SCHEMA IF NOT EXISTS appsmith;"; then
        echo "Failed to create schema 'appsmith' on remote host."
        exit 1
    fi
  3. Consider using a connection timeout to prevent the script from hanging indefinitely:

    PGCONNECT_TIMEOUT=10 PGPASSWORD=$PG_DB_PASSWORD psql ...

Remember, class, always think about error handling and timeouts when dealing with remote connections!

Comment on lines +127 to +135
# Check if the schema creation was successful
if [ $? -eq 0 ]; then
echo "Schema 'appsmith' created or already exists."
else
echo "Failed to create schema 'appsmith'."
exit 1
fi
echo "PostgreSQL initialization completed."
fi
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Finally, let's review the schema creation verification, class.

This section shows good attention to error handling, but we can make it even better:

  1. The success message could be more specific. Instead of just saying the schema exists, let's confirm it:

    if psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U "$PG_DB_USER" -d "$PG_DB_NAME" -tAc "SELECT 1 FROM information_schema.schemata WHERE schema_name='appsmith'" | grep -q 1; then
        echo "Successfully confirmed the existence of schema 'appsmith'."
    else
        echo "Failed to confirm the existence of schema 'appsmith'. Please check the database manually."
        exit 1
    fi
  2. Let's add a final check to ensure the user has the necessary permissions:

    if psql -h "$PG_DB_HOST" -p "$PG_DB_PORT" -U "$PG_DB_USER" -d "$PG_DB_NAME" -tAc "SELECT has_schema_privilege('$PG_DB_USER', 'appsmith', 'usage')" | grep -q t; then
        echo "User '$PG_DB_USER' has the necessary permissions on schema 'appsmith'."
    else
        echo "Warning: User '$PG_DB_USER' may not have the necessary permissions on schema 'appsmith'."
    fi

Remember, students, thorough verification and clear error messages are key to maintaining a robust system!

@abhvsn abhvsn merged commit bb11bf5 into release Sep 30, 2024
22 checks passed
@abhvsn abhvsn deleted the chore/add-schema-creation-for-postgres branch September 30, 2024 18:12
AnaghHegde added a commit that referenced this pull request Sep 30, 2024
## Description

The current state is default schema or public schema. This schema is
accessible by default when user connects to the pg database. Hence
create `appsmith` schema for Appsmith server to use. This is to avoid
anyone accidentally modifying the appsmith data.

## Automation

/ok-to-test tags="@tag.Sanity"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!IMPORTANT]
> 🟣 🟣 🟣 Your tests are running.
> Tests running at:
<https://github.com/appsmithorg/appsmith/actions/runs/11111681323>
> Commit: 32f91e8
> Workflow: `PR Automation test suite`
> Tags: `@tag.Sanity`
> Spec: ``
> <hr>Mon, 30 Sep 2024 18:08:23 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
- Introduced a script to initialize the PostgreSQL database schema for
Appsmith.
- Added utilities for managing PostgreSQL database connections,
including availability checks and parameter extraction.
- Enhanced scripts for managing PostgreSQL connections and
initialization.
- Improved environment configuration for PostgreSQL database
connections, including automatic password generation for local setups.
- Updated JDBC URL handling to include schema parameters for PostgreSQL
connections.
	- Added support for proxy configuration in the application setup.

- **Bug Fixes**
- Improved error handling and connection retry mechanisms for PostgreSQL
setup.

- **Documentation**
- Updated comments and logging for better clarity on database
operations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Abhijeet <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ok-to-test Required label for CI skip-changelog Adding this label to a PR prevents it from being listed in the changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants