aboutsummaryrefslogtreecommitdiff
path: root/python/cru/service/_gen_cmd.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/cru/service/_gen_cmd.py')
-rw-r--r--python/cru/service/_gen_cmd.py200
1 files changed, 200 insertions, 0 deletions
diff --git a/python/cru/service/_gen_cmd.py b/python/cru/service/_gen_cmd.py
new file mode 100644
index 0000000..f51d65f
--- /dev/null
+++ b/python/cru/service/_gen_cmd.py
@@ -0,0 +1,200 @@
+from dataclasses import dataclass, replace
+from typing import TypeAlias
+
+from ._base import AppCommandFeatureProvider
+from ._nginx import NginxManager
+
+_Str_Or_Cmd_List: TypeAlias = str | list["_Cmd"]
+
+
+@dataclass
+class _Cmd:
+ name: str
+ desc: str
+ cmd: _Str_Or_Cmd_List
+
+ def clean(self) -> "_Cmd":
+ if isinstance(self.cmd, list):
+ return replace(
+ self,
+ cmd=[cmd.clean() for cmd in self.cmd],
+ )
+ elif isinstance(self.cmd, str):
+ return replace(self, cmd=self.cmd.strip())
+ else:
+ raise ValueError("Unexpected type for cmd.")
+
+ def generate_text(
+ self,
+ info_only: bool,
+ *,
+ parent: str | None = None,
+ ) -> str:
+ if parent is None:
+ tag = "COMMAND"
+ long_name = self.name
+ indent = ""
+ else:
+ tag = "SUBCOMMAND"
+ long_name = f"{parent}.{self.name}"
+ indent = " "
+
+ if info_only:
+ return f"{indent}[{long_name}]: {self.desc}"
+
+ text = f"--- {tag}[{long_name}]: {self.desc}"
+ if isinstance(self.cmd, str):
+ text += "\n" + self.cmd
+ elif isinstance(self.cmd, list):
+ for sub in self.cmd:
+ text += "\n" * 2 + sub.generate_text(info_only, parent=self.name)
+ else:
+ raise ValueError("Unexpected type for cmd.")
+
+ lines: list[str] = []
+ for line in text.splitlines():
+ if len(line) == 0:
+ lines.append("")
+ else:
+ lines.append(indent + line)
+ text = "\n".join(lines)
+
+ return text
+
+
+_docker_uninstall = _Cmd(
+ "uninstall",
+ "uninstall apt docker",
+ """
+for pkg in docker.io docker-doc docker-compose \
+podman-docker containerd runc; \
+do sudo apt-get remove $pkg; done
+""",
+)
+
+_docker_apt_certs = _Cmd(
+ "apt-certs",
+ "prepare apt certs",
+ """
+sudo apt-get update
+sudo apt-get install ca-certificates curl
+sudo install -m 0755 -d /etc/apt/keyrings
+""",
+)
+
+_docker_docker_certs = _Cmd(
+ "docker-certs",
+ "add docker certs",
+ """
+sudo curl -fsSL https://download.docker.com/linux/debian/gpg \
+-o /etc/apt/keyrings/docker.asc
+sudo chmod a+r /etc/apt/keyrings/docker.asc
+""",
+)
+
+_docker_apt_repo = _Cmd(
+ "apt-repo",
+ "add docker apt repo",
+ """
+echo \\
+ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
+https://download.docker.com/linux/debian \\
+ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \\
+ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
+""",
+)
+
+_docker_install = _Cmd(
+ "install",
+ "update apt and install docker",
+ """
+sudo apt-get update
+sudo apt-get install docker-ce docker-ce-cli containerd.io \
+docker-buildx-plugin docker-compose-plugin
+""",
+)
+
+_docker_setup = _Cmd(
+ "setup",
+ "setup system for docker",
+ """
+sudo systemctl enable docker
+sudo systemctl start docker
+sudo groupadd -f docker
+sudo usermod -aG docker $USER
+# Remember to log out and log back in for the group changes to take effect
+""",
+)
+
+_docker = _Cmd(
+ "install-docker",
+ "install docker for a fresh new system",
+ [
+ _docker_uninstall,
+ _docker_apt_certs,
+ _docker_docker_certs,
+ _docker_apt_repo,
+ _docker_install,
+ _docker_setup,
+ ],
+)
+
+_update_blog = _Cmd(
+ "update-blog",
+ "re-generate blog pages",
+ """
+docker exec -it blog /scripts/update.bash
+""",
+)
+
+_git_user = _Cmd(
+ "git-user",
+ "add/set git server user and password",
+ """
+docker run -it --rm -v "$ps_file:/user-info" httpd htpasswd "/user-info" [username]
+""",
+)
+
+
+class GenCmdProvider(AppCommandFeatureProvider):
+ def __init__(self) -> None:
+ super().__init__("gen-cmd-provider")
+ self._cmds: dict[str, _Cmd] = {}
+ self._register_cmds(_docker, _update_blog, _git_user)
+
+ def _register_cmd(self, cmd: "_Cmd"):
+ self._cmds[cmd.name] = cmd.clean()
+
+ def _register_cmds(self, *cmds: "_Cmd"):
+ for c in cmds:
+ self._register_cmd(c)
+
+ def setup(self):
+ pass
+
+ def get_command_info(self):
+ return ("gen-cmd", "Get commands of running external cli tools.")
+
+ def setup_arg_parser(self, arg_parser):
+ subparsers = arg_parser.add_subparsers(
+ dest="gen_cmd", metavar="GEN_CMD_COMMAND"
+ )
+ certbot_parser = subparsers.add_parser("certbot", help="print certbot commands")
+ certbot_parser.add_argument(
+ "-t", "--test", action="store_true", help="run certbot in test mode"
+ )
+ for cmd in self._cmds.values():
+ subparsers.add_parser(cmd.name, help=cmd.desc)
+
+ def _print_cmd(self, name: str):
+ print(self._cmds[name].generate_text(False))
+
+ def run_command(self, args):
+ if args.gen_cmd is None or args.gen_cmd == "list":
+ print("[certbot]: certbot ssl cert commands")
+ for cmd in self._cmds.values():
+ print(cmd.generate_text(True))
+ elif args.gen_cmd == "certbot":
+ self.app.get_feature(NginxManager).print_all_certbot_commands(args.test)
+ else:
+ self._print_cmd(args.gen_cmd)