diff options
author | crupest <crupest@outlook.com> | 2024-11-11 01:12:29 +0800 |
---|---|---|
committer | Yuqian Yang <crupest@crupest.life> | 2024-12-18 18:31:27 +0800 |
commit | aaa855e3839130a79193f38969f07763f2773c5d (patch) | |
tree | e4cb238df4588f4633d9c1190136895865d51a98 /tools/cru-py/crupest/aio.py | |
parent | 95da3ade5bfa6ef39923cd3fc2a551ad983c1537 (diff) | |
download | crupest-aaa855e3839130a79193f38969f07763f2773c5d.tar.gz crupest-aaa855e3839130a79193f38969f07763f2773c5d.tar.bz2 crupest-aaa855e3839130a79193f38969f07763f2773c5d.zip |
HALF WORK: 2024.11.27
Diffstat (limited to 'tools/cru-py/crupest/aio.py')
-rw-r--r-- | tools/cru-py/crupest/aio.py | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/tools/cru-py/crupest/aio.py b/tools/cru-py/crupest/aio.py new file mode 100644 index 0000000..0a26146 --- /dev/null +++ b/tools/cru-py/crupest/aio.py @@ -0,0 +1,319 @@ +#!/usr/bin/env python3 + +try: + import rich + import jsonschema + import cryptography +except ImportError: + print("Some necessary crupest can't be imported. Please run `pip install -r requirements.txt` to install them.") + exit(1) + +from os.path import * +import argparse +import subprocess +from rich.prompt import Confirm +from install_docker import * +from path import * +from nginx import * +from config import * +from check import * +from backup import * +from download_tools import * +from test import * +from dns import * +from setup import * + +from tui import console + + +parser = argparse.ArgumentParser( + description="Crupest server all-in-one setup script. Have fun play with it!") +parser.add_argument("--no-hello", action="store_true", + default=False, help="Do not print hello message.") +parser.add_argument("--no-bye-bye", action="store_true", + default=False, help="Do not print bye-bye message.") + +parser.add_argument("--no-check-python-version", action="store_true", + default=False, help="Do not check python version.") +parser.add_argument("--no-check-system", action="store_true", + default=False, help="Do not check system type.") +parser.add_argument("-y", "--yes", action="store_true", + default=False, help="Yes to all confirmation.") + +subparsers = parser.add_subparsers(dest="action") + +setup_parser = subparsers.add_parser( + "setup", help="Do everything necessary to setup the server.") + +print_path_parser = subparsers.add_parser( + "print-path", help="Print the paths of all related files and dirs.") + +download_tools_parser = subparsers.add_parser( + "download-tools", help="Download some extra tools to manage the server.") + +list_domain_parser = subparsers.add_parser( + "list-domain", help="Misc things about domains.") + +nginx_parser = subparsers.add_parser( + "nginx", help="Generate nginx config.") + +certbot_parser = subparsers.add_parser( + "certbot", help="Get some common certbot commands.") + +certbot_command_group = certbot_parser.add_mutually_exclusive_group() + +certbot_command_group.add_argument( + "-C", "--create", action="store_true", default=False, help="Only print the command for 'create' action.") +certbot_command_group.add_argument( + "-E", "--expand", action="store_true", default=False, help="Only print the command for 'expand' action.") +certbot_command_group.add_argument( + "-R", "--renew", action="store_true", default=False, help="Only print the command for 'renew' action.") + +certbot_parser.add_argument( + "-t", "--test", action="store_true", default=False, help="Make the commands for test use.") + +clear_parser = subparsers.add_parser( + "clear", help="Delete existing data so you can make a fresh start.") +clear_parser.add_argument("-D", "--include-data-dir", action="store_true", + default=False, help="Also delete the data directory.") + +install_docker_parser = subparsers.add_parser( + "install-docker", help="Install docker and docker-compose.") + +backup_parser = subparsers.add_parser( + "backup", help="Backup related things." +) + +backup_subparsers = backup_parser.add_subparsers(dest="backup_action") +backup_restore_parser = backup_subparsers.add_parser( + "restore", help="Restore data from url.") +backup_restore_parser.add_argument( + "restore_url", help="Restore archive url. Can be local path or http/https.") +backup_backup_parser = backup_subparsers.add_parser( + "backup", help="Backup data to specified path.") +backup_backup_parser.add_argument( + "backup_path", nargs="?", help="Backup path. Can be empty for a timestamp as name. Must be local path.") + +docker_parser = subparsers.add_parser("docker", help="Docker related things.") +docker_subparsers = docker_parser.add_subparsers(dest="docker_action") +docker_subparsers.add_parser("up", help="Run docker compose up -d.") +docker_subparsers.add_parser("down", help="Run docker compose down.") +docker_subparsers.add_parser( + "prune", help="Run docker system prune -a -f.") + +test_parser = subparsers.add_parser("test", help="Test things.") +test_parser.add_argument( + "test_action", help="Test action.", choices=["crupest-api"]) + +dns_parser = subparsers.add_parser("dns", help="Generate dns zone.") + +dns_parser.add_argument("-i", "--ip", help="IP address of the server.") + +git_update_parser = subparsers.add_parser( + "git-update", help="Update git submodules.") + +update_blog_parser = subparsers.add_parser( + "update-blog", help="Update and regenerate blog.") + +up_parser = subparsers.add_parser( + "up", help="Do something necessary and then docker compose up.") + +down_parser = subparsers.add_parser( + "down", help="Do something necessary and then docker compose down.") + +args = parser.parse_args() + +if args.yes: + old_ask = Confirm.ask + + def new_ask(prompt, *args, console=console, default=None, **kwargs): + default_text = "" + if default is not None: + default_text = "(y)" if default else "(n)" + text = f"[prompt]{prompt}[/] [prompt.choices]\\[y/n][/] [prompt.default]{default_text}[/]" + console.print(text) + return True + + Confirm.ask = new_ask + +if (args.action == "certbot" and (args.create or args.renew or args.expand)) or (args.action == "dns" and args.ip is not None): + args.no_hello = True + args.no_bye_bye = True + + +if not args.no_check_python_version: + if check_python_version(): + console.print("This script works well on python 3.10. Otherwise you may encounter some problems. But I would like to improve some rational compatibility.", style="yellow") + +if not args.no_check_system: + if not check_ubuntu(): + console.print("This script works well on Ubuntu 22.04. Otherwise you may encounter some problems. But I would like to improve some rational compatibility.", style="yellow") + + +if not args.no_hello: + console.print("Nice to see you! :waving_hand:", style="cyan") + + +def check_domain_is_defined(): + try: + return get_domain() + except Exception as e: + console.print(e.args[0], style="red") + raise e + + +def git_update(): + def do_it(): + subprocess.run(["git", "pull"], check=True) + run_in_project_dir(do_it) + + +def update_blog(): + def do_it(): + subprocess.run(["docker", "compose", "exec", + "crupest-blog", "/scripts/update.bash"], check=True) + run_in_project_dir(do_it) + + +def docker_compose_up(): + def do_docker_compose_up(): + subprocess.run(["docker", "compose", "up", "-d"], check=True) + run_in_dir(project_abs_path, do_docker_compose_up) + + +def docker_compose_down(): + def do_docker_compose_down(): + subprocess.run( + ["docker", "compose", "down"], check=True) + run_in_dir(project_abs_path, do_docker_compose_down) + + +action = args.action + + +def run(): + match action: + case "install-docker": + install_docker() + console.print( + "Succeeded to install docker. Please re-login to take effect.", style="green") + + case "docker": + docker_action = args.docker_action + + match docker_action: + case "up": + docker_compose_up() + case "down": + docker_compose_down() + case "prune": + to_do = Confirm.ask( + "[yellow]Are you sure to prune docker?[/]", console=console) + if to_do: + subprocess.run( + ["docker", "system", "prune", "-a", "-f"], check=True) + case _: + raise ValueError("Unknown docker action.") + + case "backup": + backup_action = args.backup_action + match backup_action: + case "backup": + backup_backup(args.backup_path, console) + console.print("Succeeded to restore data.", style="green") + case "restore": + backup_restore(args.restore_path, console) + console.print("Succeeded to backup data.", style="green") + + case 'print-path': + console.print("Project path =", project_dir) + console.print("Project absolute path =", project_abs_path) + console.print("Data path =", data_dir) + + case "download-tools": + download_tools(console) + + case "list-domain": + domain = check_domain_is_defined() + domains = list_domains(domain) + for domain in domains: + console.print(domain) + + case "nginx": + raise Exception("This command is deprecated.") + + case "certbot": + domain = check_domain_is_defined() + is_test = args.test + if args.create: + console.print(certbot_command_gen(domain, "create", + test=is_test), soft_wrap=True, highlight=False) + elif args.expand: + console.print(certbot_command_gen(domain, "expand", + test=is_test), soft_wrap=True, highlight=False) + elif args.renew: + console.print(certbot_command_gen(domain, "renew", + test=is_test), soft_wrap=True, highlight=False) + else: + console.print( + "Here is some commands you can use to do certbot related work.") + if is_test: + console.print( + "Note you specified --test, so the commands are for test use.", style="yellow") + console.print( + "To create certs for init (standalone):", style="cyan") + console.print(certbot_command_gen( + domain, 'create', test=is_test), soft_wrap=True) + console.print("To expand certs (nginx):", style="cyan") + console.print(certbot_command_gen( + domain, 'create', test=is_test), soft_wrap=True) + console.print( + "To renew certs previously created (nginx):", style="cyan") + console.print(certbot_command_gen( + domain, 'renew', test=is_test), soft_wrap=True) + case "test": + match args.test_action: + case "crupest-api": + test_crupest_api(console) + case _: + console.print("Test action invalid.", style="red") + + case "dns": + domain = check_domain_is_defined() + if domain is not None: + if args.ip is None: + ip = Prompt.ask( + "Please enter your server ip", console=console) + else: + ip = args.ip + console.print(generate_dns_zone_with_dkim( + domain, ip), soft_wrap=True, highlight=False) + + case "git-update": + git_update() + + case "update-blog": + update_blog() + + case "up": + git_update() + template_generate(console) + docker_compose_up() + + case "down": + docker_compose_down() + + case "clear": + clear(console, args.include_data_dir) + + case _: + template_generate(console) + if Confirm.ask( + "By the way, would you like to download some scripts to do some extra setup like creating email user?", console=console, default=True): + download_tools(console) + + +run() + +if not args.no_bye_bye: + console.print(":beers: All done! Bye bye!", style="green") |