From a987c1e9aed4b14e0b12100f35408ebababd7dee Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Fri, 16 Dec 2022 17:32:45 +0530 Subject: [PATCH] style: chmod+x, format, space -> tabs --- easy-install.py | 535 ++++++++++++++++++++++++------------------------ 1 file changed, 266 insertions(+), 269 deletions(-) mode change 100644 => 100755 easy-install.py diff --git a/easy-install.py b/easy-install.py old mode 100644 new mode 100755 index 6faf5c13..82fc1738 --- a/easy-install.py +++ b/easy-install.py @@ -1,94 +1,95 @@ #!/usr/bin/env python3 + import argparse -import subprocess +import logging import os +import platform +import subprocess import sys import time import urllib.request -import logging -import platform -from shutil import which, unpack_archive, move -from hashlib import sha224 +from shutil import move, unpack_archive, which from typing import Dict logging.basicConfig( - filename="easy-install.log", - filemode="w", - format="%(asctime)s - %(levelname)s - %(message)s", - level=logging.INFO, + filename="easy-install.log", + filemode="w", + format="%(asctime)s - %(levelname)s - %(message)s", + level=logging.INFO, ) def cprint(*args, level: int = 1): - """ - logs colorful messages - level = 1 : RED - level = 2 : GREEN - level = 3 : YELLOW + """ + logs colorful messages + level = 1 : RED + level = 2 : GREEN + level = 3 : YELLOW - default level = 1 - """ - CRED = "\033[31m" - CGRN = "\33[92m" - CYLW = "\33[93m" - reset = "\033[0m" - message = " ".join(map(str, args)) - if level == 1: - print(CRED, message, reset) - if level == 2: - print(CGRN, message, reset) - if level == 3: - print(CYLW, message, reset) + default level = 1 + """ + CRED = "\033[31m" + CGRN = "\33[92m" + CYLW = "\33[93m" + reset = "\033[0m" + message = " ".join(map(str, args)) + if level == 1: + print(CRED, message, reset) + if level == 2: + print(CGRN, message, reset) + if level == 3: + print(CYLW, message, reset) def clone_frappe_docker_repo() -> None: - try: - urllib.request.urlretrieve( - "https://github.com/frappe/frappe_docker/archive/refs/heads/main.zip", - "frappe_docker.zip", - ) - logging.info("Downloaded frappe_docker zip file from GitHub") - unpack_archive( - "frappe_docker.zip", "." - ) # Unzipping the frappe_docker.zip creates a folder "frappe_docker-main" - move("frappe_docker-main", "frappe_docker") - logging.info("Unzipped and Renamed frappe_docker") - os.remove("frappe_docker.zip") - logging.info("Removed the downloaded zip file") - except Exception as e: - logging.error("Download and unzip failed", exc_info=True) - cprint("\nCloning frappe_docker Failed\n\n", "[ERROR]: ", e, level=1) + try: + urllib.request.urlretrieve( + "https://github.com/frappe/frappe_docker/archive/refs/heads/main.zip", + "frappe_docker.zip", + ) + logging.info("Downloaded frappe_docker zip file from GitHub") + unpack_archive( + "frappe_docker.zip", "." + ) # Unzipping the frappe_docker.zip creates a folder "frappe_docker-main" + move("frappe_docker-main", "frappe_docker") + logging.info("Unzipped and Renamed frappe_docker") + os.remove("frappe_docker.zip") + logging.info("Removed the downloaded zip file") + except Exception as e: + logging.error("Download and unzip failed", exc_info=True) + cprint("\nCloning frappe_docker Failed\n\n", "[ERROR]: ", e, level=1) -def get_from_env(dir,file) -> Dict: - env_vars ={} - with open(os.path.join(dir,file)) as f: - for line in f: - if line.startswith('#') or not line.strip(): - continue - key, value = line.strip().split('=', 1) - env_vars[key] = value - return env_vars + +def get_from_env(dir, file) -> Dict: + env_vars = {} + with open(os.path.join(dir, file)) as f: + for line in f: + if line.startswith("#") or not line.strip(): + continue + key, value = line.strip().split("=", 1) + env_vars[key] = value + return env_vars def write_to_env(wd: str, site: str, db_pass: str, admin_pass: str, email: str) -> None: - site_name = site or "" - example_env = get_from_env(wd,"example.env") - with open(os.path.join(wd, ".env"), "w") as f: - f.writelines( - [ - f"FRAPPE_VERSION={example_env['FRAPPE_VERSION']}\n", # Defaults to latest version of Frappe - f"ERPNEXT_VERSION={example_env['ERPNEXT_VERSION']}\n", # defaults to latest version of ERPNext - f"DB_PASSWORD={db_pass}\n", - "DB_HOST=db\n", - "DB_PORT=3306\n", - "REDIS_CACHE=redis-cache:6379\n", - "REDIS_QUEUE=redis-queue:6379\n", - "REDIS_SOCKETIO=redis-socketio:6379\n", - f"LETSENCRYPT_EMAIL={email}\n", - f"FRAPPE_SITE_NAME_HEADER={site_name}\n", - f"SITE_ADMIN_PASS={admin_pass}", - ] - ) + site_name = site or "" + example_env = get_from_env(wd, "example.env") + with open(os.path.join(wd, ".env"), "w") as f: + f.writelines( + [ + f"FRAPPE_VERSION={example_env['FRAPPE_VERSION']}\n", # Defaults to latest version of Frappe + f"ERPNEXT_VERSION={example_env['ERPNEXT_VERSION']}\n", # defaults to latest version of ERPNext + f"DB_PASSWORD={db_pass}\n", + "DB_HOST=db\n", + "DB_PORT=3306\n", + "REDIS_CACHE=redis-cache:6379\n", + "REDIS_QUEUE=redis-queue:6379\n", + "REDIS_SOCKETIO=redis-socketio:6379\n", + f"LETSENCRYPT_EMAIL={email}\n", + f"FRAPPE_SITE_NAME_HEADER={site_name}\n", + f"SITE_ADMIN_PASS={admin_pass}", + ] + ) def generate_pass(length: int = 12) -> str: @@ -103,221 +104,217 @@ def generate_pass(length: int = 12) -> str: def check_repo_exists() -> bool: - return os.path.exists(os.path.join(os.getcwd(), "frappe_docker")) + return os.path.exists(os.path.join(os.getcwd(), "frappe_docker")) def setup_prod(project: str, sitename: str, email: str) -> None: - if check_repo_exists(): - compose_file_name = os.path.join( - os.path.expanduser("~"), f"{project}-compose.yml" - ) - docker_repo_path = os.path.join(os.getcwd(), "frappe_docker") - cprint( - "\nPlease refer to .example.env file in the frappe_docker folder to know which keys to set\n\n", - level=3, - ) - admin_pass = "" - db_pass = "" - with open(compose_file_name, "w") as f: - # Writing to compose file - if not os.path.exists(os.path.join(docker_repo_path, ".env")): - admin_pass = generate_pass() - db_pass = generate_pass(9) - write_to_env(docker_repo_path, sitename, db_pass, admin_pass, email) - cprint( - "\nA .env file is generated with basic configs. Please edit it to fit to your needs \n", - level=3, - ) - with open( - os.path.join(os.path.expanduser("~"), "passwords.txt"), "w" - ) as en: - en.writelines(f"ADMINISTRATOR_PASSWORD={admin_pass}\n") - en.writelines(f"MARIADB_ROOT_PASSWORD={db_pass}\n") - else: - env = get_from_env(docker_repo_path,".env") - admin_pass = env['SITE_ADMIN_PASS'] - db_pass = env['DB_PASSWORD'] - try: - # TODO: Include flags for non-https and non-erpnext installation - subprocess.run( - [ - which("docker"), - "compose", - "--project-name", - project, - "-f", - "compose.yaml", - "-f", - "overrides/compose.mariadb.yaml", - "-f", - "overrides/compose.redis.yaml", - # "-f", "overrides/compose.noproxy.yaml", TODO: Add support for local proxying without HTTPs - "-f", - "overrides/compose.erpnext.yaml", - "-f", - "overrides/compose.https.yaml", - "--env-file", - ".env", - "config", - ], - cwd=docker_repo_path, - stdout=f, - check=True, - ) + if check_repo_exists(): + compose_file_name = os.path.join(os.path.expanduser("~"), f"{project}-compose.yml") + docker_repo_path = os.path.join(os.getcwd(), "frappe_docker") + cprint( + "\nPlease refer to .example.env file in the frappe_docker folder to know which keys to set\n\n", + level=3, + ) + admin_pass = "" + db_pass = "" + with open(compose_file_name, "w") as f: + # Writing to compose file + if not os.path.exists(os.path.join(docker_repo_path, ".env")): + admin_pass = generate_pass() + db_pass = generate_pass(9) + write_to_env(docker_repo_path, sitename, db_pass, admin_pass, email) + cprint( + "\nA .env file is generated with basic configs. Please edit it to fit to your needs \n", + level=3, + ) + with open(os.path.join(os.path.expanduser("~"), "passwords.txt"), "w") as en: + en.writelines(f"ADMINISTRATOR_PASSWORD={admin_pass}\n") + en.writelines(f"MARIADB_ROOT_PASSWORD={db_pass}\n") + else: + env = get_from_env(docker_repo_path, ".env") + admin_pass = env["SITE_ADMIN_PASS"] + db_pass = env["DB_PASSWORD"] + try: + # TODO: Include flags for non-https and non-erpnext installation + subprocess.run( + [ + which("docker"), + "compose", + "--project-name", + project, + "-f", + "compose.yaml", + "-f", + "overrides/compose.mariadb.yaml", + "-f", + "overrides/compose.redis.yaml", + # "-f", "overrides/compose.noproxy.yaml", TODO: Add support for local proxying without HTTPs + "-f", + "overrides/compose.erpnext.yaml", + "-f", + "overrides/compose.https.yaml", + "--env-file", + ".env", + "config", + ], + cwd=docker_repo_path, + stdout=f, + check=True, + ) - except Exception as e: - logging.error("Docker Compose generation failed", exc_info=True) - cprint("\nGenerating Compose File failed\n") - sys.exit(1) - try: - # Starting with generated compose file - subprocess.run( - [ - which("docker"), - "compose", - "-p", - project, - "-f", - compose_file_name, - "up", - "-d", - ], - check=True, - ) - logging.info(f"Docker Compose file generated at ~/{project}-compose.yml") + except Exception: + logging.error("Docker Compose generation failed", exc_info=True) + cprint("\nGenerating Compose File failed\n") + sys.exit(1) + try: + # Starting with generated compose file + subprocess.run( + [ + which("docker"), + "compose", + "-p", + project, + "-f", + compose_file_name, + "up", + "-d", + ], + check=True, + ) + logging.info(f"Docker Compose file generated at ~/{project}-compose.yml") - except Exception as e: - logging.error("Prod docker-compose failed", exc_info=True) - cprint(" Docker Compose failed, please check the container logs\n", e) - sys.exit(1) + except Exception as e: + logging.error("Prod docker-compose failed", exc_info=True) + cprint(" Docker Compose failed, please check the container logs\n", e) + sys.exit(1) - cprint(f"\nCreating site: {sitename} \n", level=3) + cprint(f"\nCreating site: {sitename} \n", level=3) - try: - subprocess.run( - [ - which("docker"), - "compose", - "-p", - project, - "exec", - "backend", - "bench", - "new-site", - sitename, - "--db-root-password", - db_pass, - "--admin-password", - admin_pass, - "--install-app", - "erpnext", - "--set-default" - ], - check=True, - ) - logging.info("New site creation completed") - except Exception as e: - logging.error("Bench site creation failed", exc_info=True) - cprint("Bench Site creation failed\n", e) - sys.exit(1) - else: - install_docker() - clone_frappe_docker_repo() - setup_prod(project, sitename, email) # Recursive + try: + subprocess.run( + [ + which("docker"), + "compose", + "-p", + project, + "exec", + "backend", + "bench", + "new-site", + sitename, + "--db-root-password", + db_pass, + "--admin-password", + admin_pass, + "--install-app", + "erpnext", + "--set-default", + ], + check=True, + ) + logging.info("New site creation completed") + except Exception as e: + logging.error("Bench site creation failed", exc_info=True) + cprint("Bench Site creation failed\n", e) + sys.exit(1) + else: + install_docker() + clone_frappe_docker_repo() + setup_prod(project, sitename, email) # Recursive def setup_dev_instance(project: str): - if check_repo_exists(): - try: - subprocess.run( - [ - "docker", - "compose", - "-f", - "devcontainer-example/docker-compose.yml", - "--project-name", - project, - "up", - "-d", - ], - cwd=os.path.join(os.getcwd(), "frappe_docker"), - check=True, - ) - cprint( - "Please go through the Development Documentation: https://github.com/frappe/frappe_docker/tree/main/development to fully complete the setup.", - level=2, - ) - logging.info("Development Setup completed") - except Exception as e: - logging.error("Dev Environment setup failed", exc_info=True) - cprint("Setting Up Development Environment Failed\n", e) - else: - install_docker() - clone_frappe_docker_repo() - setup_dev_instance(project) # Recursion on goes brrrr + if check_repo_exists(): + try: + subprocess.run( + [ + "docker", + "compose", + "-f", + "devcontainer-example/docker-compose.yml", + "--project-name", + project, + "up", + "-d", + ], + cwd=os.path.join(os.getcwd(), "frappe_docker"), + check=True, + ) + cprint( + "Please go through the Development Documentation: https://github.com/frappe/frappe_docker/tree/main/development to fully complete the setup.", + level=2, + ) + logging.info("Development Setup completed") + except Exception as e: + logging.error("Dev Environment setup failed", exc_info=True) + cprint("Setting Up Development Environment Failed\n", e) + else: + install_docker() + clone_frappe_docker_repo() + setup_dev_instance(project) # Recursion on goes brrrr def install_docker(): - if which("docker") is not None: - return - cprint("Docker is not installed, Installing Docker...", level=3) - logging.info("Docker not found, installing Docker") - if platform.system() == "Darwin" or platform.system() == "Windows": - print( - f""" + if which("docker") is not None: + return + cprint("Docker is not installed, Installing Docker...", level=3) + logging.info("Docker not found, installing Docker") + if platform.system() == "Darwin" or platform.system() == "Windows": + print( + f""" This script doesn't install Docker on {"Mac" if platform.system()=="Darwin" else "Windows"}. Please go through the Docker Installation docs for your system and run this script again""" - ) - logging.debug("Docker setup failed due to platform is not Linux") - sys.exit(1) - try: - ps = subprocess.run( - ["curl", "-fsSL", "https://get.docker.com"], - capture_output=True, - check=True, - ) - subprocess.run(["/bin/bash"], input=ps.stdout, capture_output=True) - subprocess.run( - ["sudo", "usermod", "-aG", "docker", str(os.getenv("USER"))], check=True - ) - cprint("Waiting Docker to start", level=3) - time.sleep(10) - subprocess.run(["sudo", "systemctl", "restart", "docker.service"], check=True) - except Exception as e: - logging.error("Installing Docker failed", exc_info=True) - cprint("Failed to Install Docker\n", e) - cprint("\n Try Installing Docker Manually and re-run this script again\n") - sys.exit(1) + ) + logging.debug("Docker setup failed due to platform is not Linux") + sys.exit(1) + try: + ps = subprocess.run( + ["curl", "-fsSL", "https://get.docker.com"], + capture_output=True, + check=True, + ) + subprocess.run(["/bin/bash"], input=ps.stdout, capture_output=True) + subprocess.run( + ["sudo", "usermod", "-aG", "docker", str(os.getenv("USER"))], check=True + ) + cprint("Waiting Docker to start", level=3) + time.sleep(10) + subprocess.run(["sudo", "systemctl", "restart", "docker.service"], check=True) + except Exception as e: + logging.error("Installing Docker failed", exc_info=True) + cprint("Failed to Install Docker\n", e) + cprint("\n Try Installing Docker Manually and re-run this script again\n") + sys.exit(1) if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Install Frappe with Docker") - parser.add_argument( - "-p", "--prod", help="Setup Production System", action="store_true" - ) - parser.add_argument( - "-d", "--dev", help="Setup Development System", action="store_true" - ) - parser.add_argument( - "-s", - "--sitename", - help="The Site Name for your production site", - default="site1.local", - ) - parser.add_argument("-n", "--project", help="Project Name", default="frappe") - parser.add_argument( - "--email", help="Add email for the SSL.", required="--prod" in sys.argv - ) - args = parser.parse_args() - if args.dev: - cprint("\nSetting Up Development Instance\n", level=2) - logging.info("Running Development Setup") - setup_dev_instance(args.project) - elif args.prod: - cprint("\nSetting Up Production Instance\n", level=2) - logging.info("Running Production Setup") - if "example.com" in args.email: - cprint("Emails with example.com not acceptable", level=1) - sys.exit(1) - setup_prod(args.project, args.sitename, args.email) \ No newline at end of file + parser = argparse.ArgumentParser(description="Install Frappe with Docker") + parser.add_argument( + "-p", "--prod", help="Setup Production System", action="store_true" + ) + parser.add_argument( + "-d", "--dev", help="Setup Development System", action="store_true" + ) + parser.add_argument( + "-s", + "--sitename", + help="The Site Name for your production site", + default="site1.local", + ) + parser.add_argument("-n", "--project", help="Project Name", default="frappe") + parser.add_argument( + "--email", help="Add email for the SSL.", required="--prod" in sys.argv + ) + args = parser.parse_args() + if args.dev: + cprint("\nSetting Up Development Instance\n", level=2) + logging.info("Running Development Setup") + setup_dev_instance(args.project) + elif args.prod: + cprint("\nSetting Up Production Instance\n", level=2) + logging.info("Running Production Setup") + if "example.com" in args.email: + cprint("Emails with example.com not acceptable", level=1) + sys.exit(1) + setup_prod(args.project, args.sitename, args.email)