Files
CyberPanel/install/mysqlUtilities.py

163 lines
6.9 KiB
Python
Raw Normal View History

2025-08-01 14:56:30 +05:00
import subprocess, shlex
import install
import time
class mysqlUtilities:
@staticmethod
def createDatabase(dbname, dbuser, dbpassword, publicip):
2025-09-28 02:00:25 +05:00
"""
Create database and user with improved error handling and validation
"""
import logging
# Validate input parameters
if not dbname or not dbuser or not dbpassword:
logging.InstallLog.writeToFile(f"ERROR: Missing required parameters - dbname: {dbname}, dbuser: {dbuser}, password: {'SET' if dbpassword else 'EMPTY'}")
return 0
logging.InstallLog.writeToFile(f"Creating database '{dbname}' and user '{dbuser}' with password length: {len(dbpassword)}")
2025-08-01 14:56:30 +05:00
try:
2025-09-28 02:00:25 +05:00
# Step 1: Create database
createDB = "CREATE DATABASE IF NOT EXISTS " + dbname
2025-08-01 14:56:30 +05:00
try:
from json import loads
mysqlData = loads(open("/etc/cyberpanel/mysqlPassword", 'r').read())
initCommand = 'mariadb -h %s --port %s -u %s -p%s -e "' % (mysqlData['mysqlhost'], mysqlData['mysqlport'], mysqlData['mysqluser'], mysqlData['mysqlpassword'])
remote = 1
2025-09-28 02:00:25 +05:00
logging.InstallLog.writeToFile("Using remote MySQL configuration")
2025-08-01 14:56:30 +05:00
except:
passFile = "/etc/cyberpanel/mysqlPassword"
f = open(passFile)
data = f.read()
password = data.split('\n', 1)[0]
initCommand = 'mariadb -u root -p' + password + ' -e "'
remote = 0
2025-09-28 02:00:25 +05:00
logging.InstallLog.writeToFile("Using local MySQL configuration")
2025-08-01 14:56:30 +05:00
command = initCommand + createDB + '"'
2025-09-28 02:00:25 +05:00
logging.InstallLog.writeToFile(f"Executing database creation: CREATE DATABASE IF NOT EXISTS {dbname}")
2025-08-01 14:56:30 +05:00
if install.preFlightsChecks.debug:
print(command)
time.sleep(10)
cmd = shlex.split(command)
res = subprocess.call(cmd)
2025-09-28 02:00:25 +05:00
if res != 0:
logging.InstallLog.writeToFile(f"ERROR: Database creation failed with return code: {res}")
2025-08-01 14:56:30 +05:00
return 0
2025-09-28 02:00:25 +05:00
else:
logging.InstallLog.writeToFile(f"✓ Database '{dbname}' created successfully")
2025-08-01 14:56:30 +05:00
2025-09-28 02:00:25 +05:00
# Step 2: Create user (drop first if exists to avoid conflicts)
2025-08-01 14:56:30 +05:00
if remote:
2025-09-28 02:00:25 +05:00
dropUser = f"DROP USER IF EXISTS '{dbuser}'@'{publicip}'"
createUser = f"CREATE USER '{dbuser}'@'{publicip}' IDENTIFIED BY '{dbpassword}'"
host = publicip
2025-08-01 14:56:30 +05:00
else:
2025-09-28 02:00:25 +05:00
dropUser = f"DROP USER IF EXISTS '{dbuser}'@'localhost'"
createUser = f"CREATE USER '{dbuser}'@'localhost' IDENTIFIED BY '{dbpassword}'"
host = 'localhost'
# Drop user if exists
command = initCommand + dropUser + '"'
logging.InstallLog.writeToFile(f"Dropping existing user '{dbuser}'@'{host}' if exists")
if install.preFlightsChecks.debug:
print(command)
time.sleep(10)
2025-08-01 14:56:30 +05:00
2025-09-28 02:00:25 +05:00
cmd = shlex.split(command)
subprocess.call(cmd) # Ignore return code for DROP USER IF EXISTS
# Create user
2025-08-01 14:56:30 +05:00
command = initCommand + createUser + '"'
2025-09-28 02:00:25 +05:00
logging.InstallLog.writeToFile(f"Creating user '{dbuser}'@'{host}' with password")
2025-08-01 14:56:30 +05:00
if install.preFlightsChecks.debug:
print(command)
time.sleep(10)
cmd = shlex.split(command)
res = subprocess.call(cmd)
2025-09-28 02:00:25 +05:00
if res != 0:
logging.InstallLog.writeToFile(f"ERROR: User creation failed with return code: {res}")
2025-08-01 14:56:30 +05:00
return 0
else:
2025-09-28 02:00:25 +05:00
logging.InstallLog.writeToFile(f"✓ User '{dbuser}'@'{host}' created successfully")
2025-08-01 14:56:30 +05:00
2025-09-28 02:00:25 +05:00
# Step 3: Handle special cases and grant privileges
2025-08-01 14:56:30 +05:00
if remote:
2025-09-28 02:00:25 +05:00
### DigitalOcean MySQL compatibility
2025-08-01 14:56:30 +05:00
if mysqlData['mysqlhost'].find('ondigitalocean') > -1:
2025-09-28 02:00:25 +05:00
alterUserPassword = f"ALTER USER '{dbuser}'@'{publicip}' IDENTIFIED WITH mysql_native_password BY '{dbpassword}'"
2025-08-01 14:56:30 +05:00
command = initCommand + alterUserPassword + '"'
2025-09-28 02:00:25 +05:00
logging.InstallLog.writeToFile(f"Applying DigitalOcean MySQL compatibility for '{dbuser}'@'{publicip}'")
2025-08-01 14:56:30 +05:00
if install.preFlightsChecks.debug:
print(command)
time.sleep(10)
cmd = shlex.split(command)
2025-09-28 02:00:25 +05:00
res = subprocess.call(cmd)
2025-08-01 14:56:30 +05:00
2025-09-28 02:00:25 +05:00
if res != 0:
logging.InstallLog.writeToFile(f"WARNING: DigitalOcean ALTER USER failed with return code: {res}")
2025-08-01 14:56:30 +05:00
2025-09-28 02:00:25 +05:00
## RDS vs Standard MySQL permissions
2025-08-01 14:56:30 +05:00
if mysqlData['mysqlhost'].find('rds.amazon') == -1:
2025-09-28 02:00:25 +05:00
grantPrivileges = f"GRANT ALL PRIVILEGES ON {dbname}.* TO '{dbuser}'@'{publicip}'"
2025-08-01 14:56:30 +05:00
else:
2025-09-28 02:00:25 +05:00
grantPrivileges = f"GRANT INDEX, DROP, UPDATE, ALTER, CREATE, SELECT, INSERT, DELETE ON {dbname}.* TO '{dbuser}'@'{publicip}'"
host = publicip
2025-08-01 14:56:30 +05:00
else:
2025-09-28 02:00:25 +05:00
grantPrivileges = f"GRANT ALL PRIVILEGES ON {dbname}.* TO '{dbuser}'@'localhost'"
host = 'localhost'
2025-08-01 14:56:30 +05:00
2025-09-28 02:00:25 +05:00
# Grant privileges
command = initCommand + grantPrivileges + '"'
logging.InstallLog.writeToFile(f"Granting privileges on database '{dbname}' to user '{dbuser}'@'{host}'")
2025-08-01 14:56:30 +05:00
if install.preFlightsChecks.debug:
print(command)
time.sleep(10)
cmd = shlex.split(command)
res = subprocess.call(cmd)
2025-09-28 02:00:25 +05:00
if res != 0:
logging.InstallLog.writeToFile(f"ERROR: Grant privileges failed with return code: {res}")
2025-08-01 14:56:30 +05:00
return 0
2025-09-28 02:00:25 +05:00
else:
logging.InstallLog.writeToFile(f"✓ Privileges granted successfully")
# Step 4: Flush privileges
flushCommand = initCommand + "FLUSH PRIVILEGES" + '"'
logging.InstallLog.writeToFile("Flushing MySQL privileges")
2025-08-01 14:56:30 +05:00
2025-09-28 02:00:25 +05:00
cmd = shlex.split(flushCommand)
res = subprocess.call(cmd)
if res != 0:
logging.InstallLog.writeToFile(f"WARNING: FLUSH PRIVILEGES failed with return code: {res}")
else:
logging.InstallLog.writeToFile("✓ Privileges flushed successfully")
logging.InstallLog.writeToFile(f"✅ Database '{dbname}' and user '{dbuser}' created successfully!")
2025-08-01 14:56:30 +05:00
return 1
2025-09-28 02:00:25 +05:00
2025-08-01 14:56:30 +05:00
except BaseException as msg:
2025-09-28 02:00:25 +05:00
logging.InstallLog.writeToFile(f"❌ CRITICAL ERROR in createDatabase: {str(msg)}")
import traceback
logging.InstallLog.writeToFile(f"Full traceback: {traceback.format_exc()}")
2025-08-01 14:56:30 +05:00
return 0