-
Notifications
You must be signed in to change notification settings - Fork 29
floware init script #295
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
base: develop
Are you sure you want to change the base?
floware init script #295
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| #!/bin/bash | ||
| set -e | ||
|
|
||
| export PATH="/app/.venv/bin:$PATH" | ||
|
|
||
| if [ "${FLOWARE_DB_CREATE}" = "true" ]; then | ||
| echo "Creating Floware database if not exists..." | ||
| python3 -c " | ||
| import psycopg2, os | ||
|
|
||
| host = os.environ['DB_HOST'] | ||
| user = os.environ['DB_USERNAME'] | ||
| password = os.environ['DB_PASSWORD'] | ||
| dbname = os.environ['DB_NAME'] | ||
|
|
||
| conn = psycopg2.connect(host=host, user=user, password=password, dbname='postgres') | ||
| conn.autocommit = True | ||
| cur = conn.cursor() | ||
| cur.execute(\"SELECT 1 FROM pg_database WHERE datname = %s\", (dbname,)) | ||
|
|
||
| if not cur.fetchone(): | ||
| cur.execute('CREATE DATABASE \"' + dbname.replace('\"', '\"\"') + '\"') | ||
| print('Database created') | ||
|
Comment on lines
+19
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: find . -name "floware-init.sh" -type fRepository: rootflo/wavefront Length of output: 104 🏁 Script executed: cat -n ./wavefront/server/scripts/floware-init.sh | head -40Repository: rootflo/wavefront Length of output: 1143 🏁 Script executed: python3 << 'PY'
import psycopg2
from psycopg2 import errors
# Check if DuplicateDatabase exists in psycopg2.errors
print("DuplicateDatabase available:", hasattr(errors, 'DuplicateDatabase'))
# Also check sql module availability
from psycopg2 import sql
print("sql.Identifier available:", hasattr(sql, 'Identifier'))
print("sql.SQL available:", hasattr(sql, 'SQL'))
# Verify the exception inheritance
if hasattr(errors, 'DuplicateDatabase'):
print("DuplicateDatabase base classes:", errors.DuplicateDatabase.__bases__)
PYRepository: rootflo/wavefront Length of output: 182 🌐 Web query:
💡 Result: The psycopg2.errors.DuplicateDatabase exception is a specific exception class provided by the psycopg2 library to handle the PostgreSQL SQLSTATE error 42P04 [1][2]. This error occurs when you attempt to execute a CREATE DATABASE statement for a database that already exists [1]. Because PostgreSQL does not support a native IF NOT EXISTS clause for CREATE DATABASE, this exception is commonly used to gracefully handle such attempts in application code [1][3]. Key details: - Module: psycopg2.errors [2][4] - PostgreSQL SQLSTATE: 42P04 [1][5] - Exception Hierarchy: It is a subclass of ProgrammingError [2][6]. Because it inherits from standard DB-API exception classes, catching the broader ProgrammingError will also catch DuplicateDatabase, ensuring backward compatibility with legacy code [7][4]. - Usage Example: import psycopg2 from psycopg2 import errors #... (connection setup) try: with conn.cursor as cur: cur.execute("CREATE DATABASE my_database") except errors.DuplicateDatabase: # Handle the case where the database already exists pass The exception is non-retriable, meaning the statement is immediately aborted, though the database connection remains open and usable [1]. Citations:
🌐 Web query:
💡 Result: The psycopg2.sql module provides utilities for generating dynamic SQL queries in a safe and convenient manner, specifically for parts of queries—such as table or column names—that cannot be parameterized using standard execute arguments [1][2]. sql.SQL The sql.SQL class represents a literal snippet of an SQL query. It is primarily used to create a template with {} placeholders into which variable parts (such as Identifiers or Literals) can be merged using the format method [1][3]. Key characteristics: - It acts as a Composable object [2]. - The string passed to SQL is not escaped, meaning it should contain only constant SQL code or template structures, never raw user-provided data [1][3]. - It supports join and format methods to build complex queries dynamically [1][3]. Example: query = sql.SQL("SELECT * FROM {}").format(sql.Identifier('my_table')) sql.Identifier The sql.Identifier class represents a PostgreSQL identifier, such as a table name or a column name. It ensures that the identifier is correctly escaped (e.g., by double-quoting) to prevent SQL injection and handle reserved keywords or special characters properly [1][4]. Key characteristics: - It can accept one or more strings to represent a qualified name (a dot-separated sequence of identifiers), such as schema.table [1][4][5]. - Since version 2.8, it supports passing multiple strings directly to the constructor [5][2]. Example: # Represents "schema"."table" table = sql.Identifier('schema', 'table') Together, these objects allow you to maintain query structure while safely injecting dynamic identifiers, keeping them separate from query parameters (which use %s placeholders) [1][5]. top_results: [1][4][5][3][2] Citations:
🌐 Web query:
💡 Result: PostgreSQL does not natively support an IF NOT EXISTS clause for the CREATE DATABASE statement [1][2][3]. As of June 2026, the official PostgreSQL documentation for the CREATE DATABASE command does not include this functionality [4][5][6]. Because CREATE DATABASE cannot be executed within a transaction block, you cannot simply wrap it in a standard PL/pgSQL DO block with exception handling to achieve this behavior directly [2]. However, you can simulate this functionality using one of the following approaches: 1. Using psql with \gexec: You can use the psql meta-command \gexec to conditionally execute the CREATE DATABASE command by checking the pg_database system catalog [2][3]: SELECT 'CREATE DATABASE my_database' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'my_database')\gexec 2. Using an external shell script: You can check for the database's existence via shell commands before attempting to create it [3]: psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'my_database'" | grep -q 1 || psql -U postgres -c "CREATE DATABASE my_database" 3. Using dblink (for internal procedural logic): If you need to perform this within a stored procedure, you can use the dblink extension to execute the command outside of the current transaction [2]: CREATE EXTENSION IF NOT EXISTS dblink; DO $$ BEGIN PERFORM dblink_exec('', 'CREATE DATABASE my_database'); EXCEPTION WHEN duplicate_database THEN RAISE NOTICE 'Database already exists, skipping.'; END $$; Citations:
Address the database creation race condition. Lines 19-23 implement a TOCTOU (time-of-check-time-of-use) vulnerability. Concurrent container startups can both see the database as missing; one will fail on Use try-except with Suggested patch-import psycopg2, os
+import psycopg2, os
+from psycopg2 import errors, sql
@@
-cur.execute(\"SELECT 1 FROM pg_database WHERE datname = %s\", (dbname,))
-
-if not cur.fetchone():
- cur.execute('CREATE DATABASE \"' + dbname.replace('\"', '\"\"') + '\"')
- print('Database created')
-else:
- print('Database already exists, skipping')
+try:
+ cur.execute(sql.SQL("CREATE DATABASE {}").format(sql.Identifier(dbname)))
+ print("Database created")
+except errors.DuplicateDatabase:
+ print("Database already exists, skipping")🤖 Prompt for AI Agents |
||
| else: | ||
| print('Database already exists, skipping') | ||
| conn.close() | ||
| " | ||
| else | ||
| echo "FLOWARE_DB_CREATE is not true, skipping database creation" | ||
| fi | ||
|
|
||
| cd /app/apps/floware/floware | ||
| exec uv run server.py | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: rootflo/wavefront
Length of output: 104
🏁 Script executed:
cat -n ./wavefront/server/scripts/floware-init.sh | head -30Repository: rootflo/wavefront
Length of output: 1070
🏁 Script executed:
Repository: rootflo/wavefront
Length of output: 451
🏁 Script executed:
rg "DB_PORT" -A 2 -B 2Repository: rootflo/wavefront
Length of output: 4821
🏁 Script executed:
rg "connect_timeout" -A 2 -B 2Repository: rootflo/wavefront
Length of output: 1829
🏁 Script executed:
Repository: rootflo/wavefront
Length of output: 448
Use
DB_PORTand a bounded connect timeout in the admin connection.The psycopg2.connect() call on line 16 is missing both
portandconnect_timeoutparameters. SinceDB_PORTis consumed by the runtime configuration across the codebase (alembic, celery workers, config.ini files), the init script will fail on non-5432 deployments. Additionally, without a boundedconnect_timeout, startup can hang indefinitely if there are network issues.Suggested patch
📝 Committable suggestion
🤖 Prompt for AI Agents