[V3] Add support for removing instances (#1270)

* [V3 Instance Setup] add a way of removing instances

* [V3 Launcher] add instance removal support to the launcher
This commit is contained in:
palmtree5 2018-01-28 18:56:28 -09:00 committed by Kowlin
parent de3a057e6e
commit 0c85e0fe22
3 changed files with 110 additions and 9 deletions

View File

@ -6,7 +6,7 @@ import sys
import argparse
import pkg_resources
from redbot.setup import basic_setup, load_existing_config
from redbot.setup import basic_setup, load_existing_config, remove_instance
if sys.platform == "linux":
import distro
@ -281,7 +281,8 @@ def main_menu():
print("3. Update Red")
print("4. Update Red (development version)")
print("5. Create Instance")
print("6. Debug information (use this if having issues with the launcher or bot)")
print("6. Remove Instance")
print("7. Debug information (use this if having issues with the launcher or bot)")
print("0. Exit")
choice = user_choice()
if choice == "1":
@ -318,6 +319,9 @@ def main_menu():
basic_setup()
wait()
elif choice == "6":
remove_instance()
wait()
elif choice == "7":
debug_info()
elif choice == "0":
break

View File

@ -1,15 +1,18 @@
#!/usr/bin/env python
import sys
import argparse
import os
import shutil
import sys
import tarfile
from copy import deepcopy
from datetime import datetime as dt
from pathlib import Path
import appdirs
from redbot.core.json_io import JsonIO
from redbot.core.data_manager import basic_config_default
from redbot.core.cli import confirm
from redbot.core.data_manager import basic_config_default
from redbot.core.json_io import JsonIO
config_dir = None
appdir = appdirs.AppDirs("Red-DiscordBot")
@ -28,6 +31,18 @@ except PermissionError:
config_file = config_dir / 'config.json'
def parse_cli_args():
parser = argparse.ArgumentParser(
description="Red - Discord Bot's instance manager (V3)"
)
parser.add_argument(
"--delete", "-d",
help="Interactively delete an instance",
action="store_true"
)
return parser.parse_known_args()
def load_existing_config():
if not config_file.exists():
return {}
@ -35,9 +50,12 @@ def load_existing_config():
return JsonIO(config_file)._load_json()
def save_config(name, data):
def save_config(name, data, remove=False):
config = load_existing_config()
config[name] = data
if remove and name in config:
config.pop(name)
else:
config[name] = data
JsonIO(config_file)._save_json(config)
@ -123,3 +141,82 @@ def basic_setup():
print()
print("Your basic configuration has been saved. Please run `redbot <name>` to"
" continue your setup process and to run the bot.")
def remove_instance():
instance_list = load_existing_config()
if not instance_list:
print("No instances have been set up!")
return
print(
"You have chosen to remove an instance. The following "
"is a list of instances that currently exist:\n"
)
for instance in instance_list.keys():
print("{}\n".format(instance))
print("Please select one of the above by entering its name")
selected = input("> ")
if selected not in instance_list.keys():
print("That isn't a valid instance!")
return
instance_data = instance_list[selected]
print(
"Would you like to make a backup of "
"the data for this instance (y/n)?"
)
yesno = input("> ")
if yesno.lower() == "y":
if instance_data["STORAGE_TYPE"] == "MongoDB":
raise NotImplementedError(
"Support for removing instances with MongoDB as the storage "
"is not implemented at this time due to backup support."
)
else:
print("Backing up the instance's data...")
backup_filename = "redv3-{}-{}.tar.gz".format(
selected, dt.utcnow().strftime("%Y-%m-%d %H:%M:%S")
)
pth = Path(instance_data["DATA_PATH"])
home = pth.home()
backup_file = home / backup_filename
os.chdir(str(pth.parent)) # str is used here because 3.5 support
with tarfile.open(str(backup_file), "w:gz") as tar:
tar.add(pth.stem) # add all files in that directory
print(
"A backup of {} has been made. It is at {}".format(
selected, backup_file
)
)
print("Removing the instance...")
shutil.rmtree(str(pth))
save_config(selected, {}, remove=True)
print("The instance has been removed")
return
elif yesno.lower() == "n":
print("Ok then")
return
else:
print("That's not a valid option!")
return
def main():
if args.delete:
try:
remove_instance()
except NotImplementedError as e:
print(str(e))
else:
basic_setup()
args, _ = parse_cli_args()
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("Exiting...")
else:
print("Exiting...")

View File

@ -108,7 +108,7 @@ setup(
entry_points={
'console_scripts': [
'redbot=redbot.__main__:main',
'redbot-setup=redbot.setup:basic_setup',
'redbot-setup=redbot.setup:main',
'redbot-launcher=redbot.launcher:main'
]
},