diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index d9daa99..e6f3ee7 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.tar *.tar.gz -.idea \ No newline at end of file +.idea +.vscode +__pycharm__ \ No newline at end of file diff --git a/man b/man index 1fc1718..6771db7 100755 --- a/man +++ b/man @@ -1,220 +1,3 @@ #!/bin/sh -PROJECT_NAME=${PROJECT_NAME:-neo} -LIST=docker-compose.*.yml -SAVEFILE=$HOME/.local/faulty/$PROJECT_NAME.save -PROFILES="" - -alias dc="docker-compose -p $PROJECT_NAME" -# alias dc="echo docker-compose -p $PROJECT_NAME" - -alias _p="printf \"%s\"" -default() { - fopts="" - for f in $LIST; do - fopts="$fopts -f $f" - done - profopts="" - for p in $PROFILES; do - profopts="$profopts --profile $p" - done - dc $fopts $profopts $* -} - -safe_env_load() { - # $1 = file - # $2 = var - # get env var from regex instead of inclusion - [ ! -f $1 ] && fatal "file doesn't exist" - [ ! -r $1 ] && fatal "file not readable" - res=$(grep -E "^$2=" $1 | sed -E "s/^$2=\"(.*)\"/\1/") - [ -z "$res" ] && fatal "var not found" - _p $res -} - -write_savefile() { - [ -d $(dirname $1) ] || mkdir -p $(dirname $1}) - echo -n "LIST=\"" > $1 - for li in $LIST; do - echo -n " $li" >> $1 - done - echo "\"" >> $1 - echo -n "PROFILES=\"" >> $1 - for p in $PROFILES; do - echo -n " $p" >> $1 - done - echo "\"" >> $1 -} - -load_savefile() { - [ "$1" == "/dev/null" ] && return - [ ! -f $1 ] && return - LIST=$(safe_env_load $1 LIST) - PROFILES=$(save_env_load $1 PROFILES) -} - -fatal() { - echo "FATAL: $@" - exit 1 -} - -includechain=0 -handleFallthrough() { - cmd=${1:-}; shift - case $cmd in - delete-project-files|dpf) - [ -n "$1" ] || fatal "no directory specified" - [ -d /srv/$1 ] || fatal "directory doesn't exist" - ls /srv/$1 - printf "Are you sure? (y/n) [n]: " - read answer - [ "$answer" = "y" ] && sudo rm -rf /srv/$1 || fatal "cancelled" - ;; - - -p) # add profile - PROFILES="$PROFILES $1"; shift - handleFallthrough $@ - ;; - - -i) #include - if [ $includechain -eq 0 ]; then - LIST="docker-compose.$1.yml" - includechain=1 - else - LIST="$LIST docker-compose.$1.yml" - fi - shift - handleFallthrough $@ - ;; - - -x) #exclude - LIST=$(echo $LIST | sed "s/docker-compose.$1.yml/ /") - shift - handleFallthrough $@ - ;; - - make:*) - WHAT=`echo $cmd | cut -c6-` - case $WHAT in - dc|docker-compose) - [ -n "$1" ] || fatal "no name specified" - FILE="docker-compose.$1.yml" - [ -f $FILE ] && fatal "file exists" - echo -e "version: '2.2'\n" > $FILE - echo -e "services: \n" >> $FILE - ;; - backup) - [ -n "$1" ] || fatal "no name specified" - FILE="$1.tar.gz" - [ -f $FILE ] && fatal "file exists" - tar cvf $FILE /srv . - ;; - *) fatal "not supported" ;; - esac - ;; - - setup:*|s:*) - WHAT=`echo $cmd | cut -c8-` - case $WHAT in - ports) sudo ./utils/setup-ports.sh up ./utils/rulelist.rules ;; - def) sudo ./utils/setup.sh ;; - all|a) - sudo ./utils/setup.sh - sudo ./utils/setup-ports.sh up ./utils/rulelist.rules - ;; - *) fatal "not supported" ;; - esac - ;; - - --save) # save behaviour - handleFallthrough $@ - write_savefile $SAVEFILE - ;; - - # preference - logs) default logs --tail=20 -f $@ ;; - up) default up -d $@ ;; - upr) default up -d --remove-orphans $@ ;; - - --help|-h) - __() { - colsep="$1" - cmd="$2" - desc="$3" - aliases="$4" - printf "%s %-20s %s %-64s %s %-40s %s \n" "$colsep" "$cmd" "$colsep" "$desc" "$colsep" "$aliases" "$colsep" - } - _hr() { - repchar() { - printf "%$1s" | tr " " "$2" - } - __ "*" ${1:-$(repchar 20 -)} ${2:-$(repchar 64 -)} ${3:-$(repchar 40 -)} - } - _r() { - __ "|" "$1" "$2" "$3" - } - _hr - _r $0 Description Aliases - _hr - _hr "Flags" " " " " - _hr - _r "-x" "Excludes a docker-compose file from the list." " " - _r "-i" "Includes a docker-compose file from the list." " " - _hr - _hr "Commands" " " " " - _hr - _r "dpf" "Delete project files." "delete-project-files " - _r "setup:ports" "Setup ports." "setup:ports" - _r "setup:def" "Setup default." "setup:def" - _r "setup:all" "Setup all." "setup:all" - _r "make:dc " "Make docker-compose file." "make:docker-compose " - _r "make:backup " "Make backup file." "tar cvf .tar.gz /srv" - _hr - _hr "Commands/aliases" "(shortcuts)" " " - _hr - _r "up" "Bring up services. (-d)" "$0 default up -d" - _r "upr" "Bring up services and remove orphans." "$0 default up -d --remove-orphans" - _r "logs" "View logs and follow with a tail of 20." "$0 default logs --tail=20 -f" - _hr - _r "default" "fallback to the main docker-compose command with fileopts." "docker-compose" - _hr - ;; - - debug) - load_savefile $SAVEFILE - _() { - eval "echo -n \"$1=\"; echo \$$1" - } - _ SAVEFILE - _ LIST - for i in $LIST; do - echo $i - done - return - ;; - default) default $@ ;; - *|'') default $cmd $@ ;; - esac -} - -main() { - case $1 in - --ignore-save) - SAVEFILE=/dev/null - shift 1 - ;; - --set-save) - SAVEFILE=$2 - shift 2 - main $@; exit 0 - ;; - --del-save) - rm $SAVEFILE - shift - ;; - esac - load_savefile $SAVEFILE - handleFallthrough $@ -} - -main $@ \ No newline at end of file +python utils/manager/main.py $@ \ No newline at end of file diff --git a/utils/manager/main.py b/utils/manager/main.py new file mode 100644 index 0000000..9c99821 --- /dev/null +++ b/utils/manager/main.py @@ -0,0 +1,97 @@ +import glob +import os +import argparse +from savefile import SaveFile + +# Spaghetti code to replace the shell script + +PROJECT_NAME = os.environ.get("PROJECT_NAME", "neo") + +files = glob.glob("docker-compose.*.yml") + +def setup_handler(what: str): + types = { + "def": lambda: os.system("sh ./utils/setup.sh"), + "ports": lambda: os.system("sh ./utils/setup-ports.sh ./utils/rulelist.rules") + }.get(what, lambda: print("Invalid setup type")) + + +def dc(cmd: str): + fopts = "" + for f in files: + fopts += f"-f {f} " + # print(f"docker-compose {fopts}{cmd}") + os.system(f"docker-compose -p {PROJECT_NAME} {fopts} {cmd}") + + +def main(): + global files + ap = argparse.ArgumentParser() + + ap.add_argument("--savefile", help="The savefile to use", + default=os.path.expanduser("~/.local/faulty/neo.save")) + ap.add_argument("--del-savefile", help="Delete the savefile", + action="store_true") + ap.add_argument("--ignore-savefile", help="Ignore the savefile", + action="store_true") + + # -x, --exclude: e.g. -x this -x that + ap.add_argument("-x", "--exclude", help="Exclude a file from the list", + action="append", default=[]) + # -i, --include: e.g. -i this -i that + ap.add_argument("-i", "--include", help="Include a file from the list", + action="append", default=[]) + + ap.add_argument('--save', help="Save the list of files to the savefile", action="store_true") + + ap.add_argument('action', help="The action to perform on the files", + nargs="?", default="up") + ap.add_argument('args', help="Extra arguments for the action", + nargs=argparse.REMAINDER) + + args = ap.parse_args() + + if args.del_savefile: + os.remove(args.savefile) + return + + if not args.ignore_savefile: + savefile = SaveFile(args.savefile) + else: + savefile = SaveFile(os.path.expanduser("~/.local/faulty/neo.save")) + + # load the savefile + if not args.ignore_savefile: + files = savefile.get("files", files) + + if len(args.include) > 0: + files = [] + for i in args.include: + files.append(f"docker-compose.{i}.yml") + + if len(args.exclude) > 0: + for i in args.exclude: + files.remove(f"docker-compose.{i}.yml") + + if args.save: + savefile["files"] = files + return + + def handle_aliases(fnlist: dict, name: str): + return fnlist.get(name, lambda: print("does not exist")) + + fnlist = { + "up": lambda: dc(f"up -d {' '.join(args.args)}"), + "upr": lambda: dc(f"up -d --build {' '.join(args.args)}"), + "logs": lambda: dc(f"logs --tail=20 -f {' '.join(args.args)}"), + "setup": lambda: setup_handler(args.args[0]), + "delete-project-files": lambda: os.system(f"sudo rm -rf /srv/{args.args[0]}"), + + "dpf": lambda: handle_aliases(fnlist, "delete-project-files")() + } + + fnlist.get(args.action, lambda: dc(f"{args.action} {' '.join(args.args)}"))() + + +if __name__ == "__main__": + main() diff --git a/utils/manager/savefile.py b/utils/manager/savefile.py new file mode 100644 index 0000000..96a36d4 --- /dev/null +++ b/utils/manager/savefile.py @@ -0,0 +1,28 @@ +import json +import os + + +class SaveFile(dict): + def __init__(self, file: str) -> None: + super().__init__() + self.path: str = file + _dir = os.path.dirname(self.path) + if not os.path.exists(_dir): + os.makedirs(_dir) + if os.path.exists(self.path): + with open(self.path) as f: + self.update(json.loads(f.read())) + else: + self.save() + + def save(self): + with open(self.path, 'a+') as f: + f.write(json.dumps(self, indent=1)) + + def __getitem__(self, key): + return super().__getitem__(key) + + def __setitem__(self, key, value): + super().__setitem__(key, value) + self.save() +