#!/usr/bin/env python3 import platform import os, sys import subprocess import shutil import fileinput # By default, install the virtual environment AND the database INSTALL_VENV = True INSTALL_DB = True VENV = "venv_py3_pyros" SQL_DATABASE = "pyros" SQL_DATABASE_TEST = "pyros_test" SQL_USER = "pyros" SQL_PSWD = "DjangoPyros" MYSQL_EXE_PATH = "" REQUIREMENTS = 'REQUIREMENTS.txt' #REQUIREMENTS = 'REQUIREMENTS_36.txt' #REQUIREMENTS = 'REQUIREMENTS_37.txt' END_OF_LINE = '\n\n' VENV_BIN = '/bin/' WINDOWS = False # -------------------------------------------- # --- Modified values for Windows # -------------------------------------------- if (platform.system() == "Windows"): WINDOWS = True REQUIREMENTS = 'REQUIREMENTS_WINDOWS.txt' #REQUIREMENTS = 'REQUIREMENTS_WINDOWS_36.txt' END_OF_LINE = "\r\n\r\n" VENV_BIN = '\\Scripts\\' #MYSQL_EXE_PATH = "C:/Program Files (x86)/MySQL/MySQL Server 5.0/bin/" #question = "Enter the path of the MySQL server if it is not the following name (" + MYSQL_EXE_PATH + "): " #res = input(question) #if res!="": # MYSQL_EXE_PATH = res VENV_PIP = VENV + VENV_BIN+'pip' VENV_PYTHON = VENV + VENV_BIN+'python' class Colors: if WINDOWS: ERROR = '' END = '' LOG_BLUE = '' else: ERROR = '\033[91m' END = '\033[0m' LOG_BLUE = '\033[94m' # GLOBAL_PYTHON = 'python3' GLOBAL_PYTHON = os.path.split(sys.executable)[-1] print(Colors.LOG_BLUE + "Python executable is " + GLOBAL_PYTHON + Colors.END) ##if platform.dist()[0] == "centos": print("centos platform") def replacePatternInFile(pattern, replace, file_path): try: with fileinput.FileInput(file_path, inplace=True, backup='.bak') as file: for line in file: print(line.replace(pattern, replace), end='') except: sys.stderr.write(Colors.ERROR + "ERROR !: replacement in file failed !" + Colors.END + "\r\n") return 1 return 0 def install_dependency_ubuntu(command, mode): ''' Install dependency then check the return code ''' old = command if (mode == 'i'): command = 'apt-get install ' + command elif (mode == 'u'): command = 'apt-get update' elif (mode == 'a'): command = 'add-apt-repository ' + command process = subprocess.Popen(command, shell=True) process.wait() if process.returncode != 0: sys.stderr.write(Colors.ERROR + "ERROR !: installation of " + old + " failed !" + Colors.END + "\r\n") def install_required_ubuntu(): install_dependency_ubuntu("update", 'u') install_dependency_ubuntu("python-lxml", 'i') install_dependency_ubuntu("libxml2-dev", 'i') install_dependency_ubuntu("libxslt-dev", 'i') install_dependency_ubuntu("zlib1g-dev", 'i') install_dependency_ubuntu("update", 'u') install_dependency_ubuntu("rabbitmq-server", 'i') #install_dependency_ubuntu("libmysqlclient-dev", 'i') def install_dependency_centos(command, mode): old = command if (mode == 'i'): command = 'yum -y install ' + command elif (mode == 'u'): command = 'yum update ' + command process = subprocess.Popen(command, shell=True) process.wait() if process.returncode != 0: sys.stderr.write(Colors.ERROR + "ERROR !: installation of " + old + " failed !" + Colors.END + "\r\n") def install_required_centos(): install_dependency_centos("yum", 'u') install_dependency_centos("kernel", 'u') install_dependency_centos("", 'u') install_dependency_centos("libxml2", 'i') install_dependency_centos("libxslt libxslt-2", 'i') install_dependency_centos("libxslt-devel libxml2-devel", 'i') install_dependency_centos("rabbitmq-server", 'i') install_dependency_centos("mariadb-server", 'i') install_dependency_centos("mariadb", 'i') install_dependency_centos("mariadb-devel", 'i') process = subprocess.Popen("systemctl start mariadb.service", shell=True) process.wait() if process.returncode != 0: sys.stderr.write(Colors.ERROR + "ERROR !" + Colors.END + "\r\n") process = subprocess.Popen("systemctl enable mariadb.service", shell=True) process.wait() if process.returncode != 0: sys.stderr.write(Colors.ERROR + "ERROR !" + Colors.END + "\r\n") process = subprocess.Popen("mysql_secure_installation", shell=True) process.wait() if process.returncode != 0: sys.stderr.write(Colors.ERROR + "ERROR !" + Colors.END + "\r\n") def install_required(): # Checking if user is sudo then install the needed dependencies # Find the linux distribution and call the related function distribution = platform.dist() if not 'SUDO_UID' in os.environ.keys(): sys.stderr.write("Super user rights are needed to install prerequisites\r\n") exit(1) if distribution[0] == "Ubuntu" or distribution[0] == "Debian": install_required_ubuntu() elif distribution[0] == "centos": install_required_centos() else: print("Requirements are made for Ubuntu, Debian and CentOS only") exit(1) def venv_pip_install(package_name:str, options:str=''): os.system(VENV_PIP + ' install ' + options + ' ' + package_name) def install_venv(venv:str): # -------------------------------------------- # --- Be aware not to create virtual environment in case of user root # -------------------------------------------- if 'SUDO_UID' in os.environ.keys(): answer = input( "You are about to install your virtualenv only for root, this is discouraged, are you sure ? (Y/N) If you are not sure, relaunch the script without super user privileges\n") while (answer != 'Y' and answer != 'y' and answer != 'n' and answer != 'N'): answer = input( "You are about to install your virtualenv only for root, this is discouraged, are you sure ? (Y/N) \n") if (answer not in ['y', 'Y']): exit(1) # -------------------------------------------- # --- Create the (private) venv directory to put in files for virtual environment # -------------------------------------------- if (os.path.basename(os.getcwd()) != "venv"): if not(os.path.isdir("../venv")): print(Colors.LOG_BLUE + "-----------------------------Creating \'venv\' directory-----------------------------" + Colors.END) os.mkdir("../venv") # -------------------------------------------- # --- Deleting if already exist then creating the venv # -------------------------------------------- #print(Colors.LOG_BLUE + "-----------------------------cd venv-----------------------------" + Colors.END) os.chdir("../venv/") while True: try: if (os.path.isdir(venv)): print(Colors.LOG_BLUE + "-----------------------------Deleting existing venv-----------------------------" + Colors.END) shutil.rmtree(venv) break # Exception on Windows WinError 145 : Cannot remove folder because files in folder not yet removed... except Exception as e: #print(e) continue # -------------------------------------------- # --- Reinstall the virtual environment (from ../venv/) # -------------------------------------------- print(Colors.LOG_BLUE + "-----------------------------Creating venv " + venv + "-----------------------------"+END_OF_LINE + Colors.END) os.system(GLOBAL_PYTHON+" -m venv " + venv) print(Colors.LOG_BLUE + "-----------------------------Upgrade pip, wheel, and setuptools" + "-----------------------------"+END_OF_LINE + Colors.END) # Upgrade pip os.system(VENV_PYTHON + ' -m pip install --upgrade pip') ''' if (platform.system() == "Windows"): os.system(venv + '\Scripts\python -m pip install --upgrade pip') else: # Linux os.system(venv + '/bin/python -m pip install --upgrade pip') ''' # Pip upgrade wheel and setuptools venv_pip_install('wheel', '--upgrade') #os.system(VENV_PIP+' install --upgrade wheel') venv_pip_install('setuptools', '--upgrade') #os.system(VENV_PIP+' install --upgrade setuptools') # Pip install required packages from REQUIREMENTS file print() print(Colors.LOG_BLUE + "-----------------------------Installing python packages via pip-----------------------------" + Colors.END) venv_pip_install('../install/'+REQUIREMENTS, '-r') #os.system(VENV_PIP+' install -r ../install' + os.sep + REQUIREMENTS) #print(Colors.LOG_BLUE + "-----------------------------cd ../install-----------------------------" + Colors.END) os.chdir("../install") if WINDOWS: ## moving voeventparse in site-packages directory try: site_packages = "..\\venv\\"+VENV+"\\Lib\\site-packages\\" if (not os.path.isdir(site_packages + "voevent_parse-0.9.5.dist-info") and not os.path.isdir(site_packages + "voeventparse")): print(Colors.LOG_BLUE + "\r\n\r\n-----------------------------Copying the voevent library in Lib/site-packages-----------------------------" + Colors.END) cmdline = "xcopy /i /y windows\\voeventparse " + site_packages + "voeventparse" process = subprocess.Popen(cmdline) process.wait() if (process.returncode != 0): raise Exception process = subprocess.Popen("xcopy /i /y windows\\voevent_parse-0.9.5.dist-info " + site_packages + "voevent_parse-0.9.5.dist-info") process.wait() if (process.returncode != 0): raise Exception print(Colors.LOG_BLUE + "\r\n-----------------------------library successfully copied-----------------------------" + Colors.END) except Exception as e: print(Colors.ERROR + "ERROR while Copying the voevent library in Lib/site-packages" + Colors.END) ; #, file=stderr) return False return 0 def install_database(venv): print(Colors.LOG_BLUE + END_OF_LINE+"-----------------------------Launching mysql to create database and create and grant user pyros-----------------------------" + Colors.END) # -------------------------------------------- # --- Determine the MySQL version # -------------------------------------------- output = subprocess.check_output("mysql --version", shell=True) # output is something like: "mysql Ver 15.1 Distrib 10.0.20-MariaDB, for Linux (x86_64) using EditLine wrapper" tmp = (str(output).split()[4]).split('.') sql_version = float(tmp[0]+'.'+tmp[1]) print(Colors.LOG_BLUE + "MySQL version is " + str(sql_version) + Colors.END) # -------------------------------------------- # --- Prepare the SQL query to create and initialize the pyros database if needed # -------------------------------------------- if sql_version < 5.5: #sql_query = "drop database "+SQL_DATABASE+" ; CREATE DATABASE "+SQL_DATABASE+"; drop database "+SQL_DATABASE_TEST+" ; CREATE DATABASE "+SQL_DATABASE_TEST+"; CREATE USER "+SQL_USER+" ; GRANT USAGE ON *.* TO '"+SQL_USER+"'@'localhost' IDENTIFIED BY '"+SQL_PSWD+"' WITH GRANT OPTION; DROP USER '"+SQL_USER+"'@'localhost'; GRANT ALL ON "+SQL_DATABASE+".* TO '"+SQL_USER+"'@'localhost' IDENTIFIED BY '"+SQL_PSWD+"'; GRANT ALL PRIVILEGES ON "+SQL_DATABASE+".* TO '"+SQL_USER+"'@'localhost' IDENTIFIED BY '"+SQL_PSWD+"' WITH GRANT OPTION; GRANT ALL PRIVILEGES ON "+SQL_DATABASE_TEST+".* TO "+SQL_USER+"@localhost IDENTIFIED BY '"+SQL_PSWD+"' WITH GRANT OPTION;" sql_query = "" sql_query += "drop database "+SQL_DATABASE+" ; CREATE DATABASE "+SQL_DATABASE+"; " sql_query += "drop database "+SQL_DATABASE_TEST+" ; CREATE DATABASE "+SQL_DATABASE_TEST+"; " sql_query += "CREATE USER "+SQL_USER+" ; GRANT USAGE ON *.* TO '"+SQL_USER+"'@'localhost' IDENTIFIED BY '"+SQL_PSWD+"' WITH GRANT OPTION; " sql_query += "DROP USER '"+SQL_USER+"'@'localhost'; " sql_query += "GRANT ALL ON "+SQL_DATABASE+".* TO '"+SQL_USER+"'@'localhost' IDENTIFIED BY '"+SQL_PSWD+"'; " sql_query += "GRANT ALL PRIVILEGES ON "+SQL_DATABASE+".* TO '"+SQL_USER+"'@'localhost' IDENTIFIED BY '"+SQL_PSWD+"' WITH GRANT OPTION; " sql_query += "GRANT ALL PRIVILEGES ON "+SQL_DATABASE_TEST+".* TO "+SQL_USER+"@localhost IDENTIFIED BY '"+SQL_PSWD+"' WITH GRANT OPTION; " else: # (EP 18/6/19, tout refait) sql_query = \ "CREATE DATABASE IF NOT EXISTS " + SQL_DATABASE +"; " +\ "CREATE DATABASE IF NOT EXISTS " + SQL_DATABASE_TEST +"; " if sql_version >= 5.7: sql_create_user = "CREATE USER IF NOT EXISTS "+SQL_USER+"; " else: # 5.5 <= version < 5.7 # Si user n'existe pas => est créé ; Si user existe => pas d'erreur ; DONC ok dans les 2 cas sql_create_user = "GRANT ALL ON "+SQL_DATABASE+".* TO '"+SQL_USER+"'@'localhost' IDENTIFIED BY '"+SQL_PSWD+"'; " sql_query += sql_create_user # Ne marche pas si l'utilisateur existe déjà => erreur #"CREATE USER "+SQL_USER+"; " +\ ''' # (EP) AVANT, y avait tout ça..., vraiment utile ? "GRANT USAGE ON *.* TO '"+SQL_USER+"'; " +\ "DROP USER '"+SQL_USER+"'; " +\ "GRANT ALL ON "+SQL_DATABASE+".* TO '"+SQL_USER+"'@'localhost' IDENTIFIED BY '"+SQL_PSWD+"'; " +\ "GRANT ALL ON "+SQL_DATABASE_TEST+".* TO '"+SQL_USER+"'@'localhost'; " +\ "GRANT ALL PRIVILEGES ON "+SQL_DATABASE_TEST+".* TO '"+SQL_USER+"'@'localhost'; " +\ "GRANT ALL ON "+SQL_DATABASE_TEST+".* TO '"+SQL_USER+"'@'localhost' IDENTIFIED BY '"+SQL_PSWD+"' ;" # J'ai simplifié comme ça : ''' sql_query += \ "GRANT ALL ON "+SQL_DATABASE_TEST+".* TO '"+SQL_USER+"'@'localhost' IDENTIFIED BY '"+SQL_PSWD+"' ;" # NEWER MYSQL: # OLDER MYSQL: Try this instead for OLDER mysql (works on CentOS 6.4 and Centos 7.5 with mysql 5.5): #req = "drop database pyros; CREATE DATABASE pyros; drop database pyros_test ; CREATE DATABASE pyros_test; drop user 'pyros'@'localhost' ; CREATE USER pyros; GRANT USAGE ON *.* TO 'pyros'; DROP USER 'pyros'; GRANT ALL ON pyros.* TO 'pyros'@'localhost' IDENTIFIED BY 'DjangoPyros'; GRANT ALL ON test_pyros.* TO 'pyros'@'localhost'; GRANT ALL PRIVILEGES ON test_pyros_test.* TO 'pyros'@'localhost'; GRANT ALL ON pyros_test.* TO 'pyros'@'localhost' IDENTIFIED BY 'DjangoPyros'" #req = "drop database pyros ; CREATE DATABASE pyros; drop database pyros_test ; CREATE DATABASE pyros_test; DROP USER 'pyros'@'localhost' ; GRANT USAGE ON *.* TO 'pyros'@'localhost' IDENTIFIED BY 'DjangoPyros' WITH GRANT OPTION; DROP USER 'pyros'@'localhost'; GRANT ALL ON pyros.* TO 'pyros'@'localhost' IDENTIFIED BY 'DjangoPyros'; GRANT ALL PRIVILEGES ON pyros.* TO 'pyros'@'localhost' IDENTIFIED BY 'DjangoPyros' WITH GRANT OPTION; GRANT ALL PRIVILEGES ON pyros_test.* TO pyros@localhost IDENTIFIED BY 'DjangoPyros' WITH GRANT OPTION;" # (EP) ok for CENTOS 7 I suppose (but not for CentOS 6): #req_centos = "CREATE DATABASE IF NOT EXISTS pyros; CREATE DATABASE IF NOT EXISTS pyros_test; GRANT USAGE ON *.* TO 'pyros'@'localhost' IDENTIFIED BY 'DjangoPyros' WITH GRANT OPTION; DROP USER 'pyros'@'localhost'; GRANT ALL ON pyros.* TO 'pyros'@'localhost' IDENTIFIED BY 'DjangoPyros'; GRANT ALL PRIVILEGES ON pyros.* TO 'pyros'@'localhost' IDENTIFIED BY 'DjangoPyros' WITH GRANT OPTION; GRANT ALL PRIVILEGES ON pyros_test.* TO pyros@localhost IDENTIFIED BY 'DjangoPyros' WITH GRANT OPTION;" # --- Prepare the SQL query to create and initialize the pyros database if needed #if platform.dist()[0] == "centos": # req = sql_query #mysql_call_root = '"' + MYSQL_EXE_PATH + 'mysql" -u root -p' mysql_call_root = 'mysql -u root -p' mysql_call_pyros = "\"" + MYSQL_EXE_PATH+ "mysql\" -u "+SQL_USER+" -p" # -------------------------------------------- # --- Creating database and creating and granting user pyros # -------------------------------------------- user_ros_is_created = True if sql_version<5.5: print(Colors.LOG_BLUE +"------------------ Check if the user pyros exists in MYSQL (type the pyros password) -----------------------------" + Colors.END) # --- We are testing if user pyros already exists in the database process = subprocess.Popen("echo quit |" + mysql_call_pyros, shell=True) process.wait() if (process.returncode == 0): user_ros_is_created = False if user_ros_is_created: # --- The user pyros must be created in the database print(Colors.LOG_BLUE +"-----------------------------Please enter your MYSQL root password-----------------------------" + Colors.END) #process = subprocess.Popen("echo \"" + sql_query + "\" |"+ mysql_call_root, shell=True) sql_cmd = 'echo "' + sql_query + '" | '+ mysql_call_root print("Executing sql cmd: ", sql_cmd) process = subprocess.Popen(sql_cmd, shell=True) process.wait() if (process.returncode != 0): sys.stderr.write(Colors.ERROR + "ERROR !: db configuration failed !" + Colors.END + "\r\n") return -1 print(Colors.LOG_BLUE + END_OF_LINE+"-----------------------------Database created and user pyros successfully created and granted-----------------------------" + Colors.END) # -------------------------------------------- # --- Replacing pattern in settings.py to use mysql # -------------------------------------------- print(Colors.LOG_BLUE + "-----------------------------setting MYSQL = True in settings-----------------------------" + Colors.END) replacePatternInFile("MYSQL = False", "MYSQL = True", os.path.normpath("../src/core/pyros_django/pyros/settings.py")) #print(Colors.LOG_BLUE + "\r\n-----------------------------cd ..-----------------------------" + Colors.END) os.chdir("..") # -------------------------------------------- # --- Executing migrations # -------------------------------------------- print(Colors.LOG_BLUE + "\r\n\r\n-----------------------------Migrate : executing pyros.py init_database-----------------------------" + Colors.END) #TODO: from venv !!! try: #os.system(GLOBAL_PYTHON+" pyros.py init_database") os.system(GLOBAL_PYTHON+" pyros.py initdb") ''' process = subprocess.Popen(GLOBAL_PYTHON + " pyros.py init_database" , shell=True) process.wait() ''' except Exception as e: print("Exception ", e) print(Colors.ERROR + "Error while initializing database :" + Colors.END) return -1 print(Colors.LOG_BLUE + "\r\n\r\n-----------------------------Install successfull !-----------------------------" + Colors.END) return 0 def _help(): print( "Welcome in the installation script of the pyros venv.\t\nPlease launch it from the install directory of pyros.\n\tIf you're on Ubuntu Debian or CentOS:\n\tlaunch it with sudo and <--prerequisites> or <-p> to install the prerequisites.\n\t-->sudo ./test_install.py -p\n\n\tFor the python packages launch it from the install directory of pyros without sudo and without parameter\n\t-->./test_install.py") if __name__ == '__main__': if (len(sys.argv) > 1): if sys.argv[1] == "--prerequisites" or sys.argv[1] == "-p": install_required() else: _help() elif len(sys.argv) == 1: if INSTALL_VENV: install_venv(VENV) if INSTALL_DB: install_database(VENV) else: _help()