From a60d93ce03dfc14808f71e6c6fc8c01a768d9b8e Mon Sep 17 00:00:00 2001 From: Vadim Troshchinskiy Date: Mon, 13 Jan 2025 09:54:40 +0100 Subject: [PATCH] Reorder and fix for ogrepository reorganization Still needs a bit of improvement to deal with the case of not being on the same machine as ogadmin --- installer/README.md | 10 +- installer/opengnsys_git_installer.py | 134 ++++++++++++++++----------- 2 files changed, 85 insertions(+), 59 deletions(-) diff --git a/installer/README.md b/installer/README.md index bd3f8bd..9f7d012 100644 --- a/installer/README.md +++ b/installer/README.md @@ -16,13 +16,17 @@ Para instalar dependencias de python se usa el modulo venv (https://docs.python. El sistema de Git accede al ogrepository por SSH. Para funcionar, necesita que el oglive tenga una clave de SSH, y que el ogrepository la acepte. -El instalador de Git puede realizar los cambios requeridos, con: +El instalador de Git puede realizar los cambios requeridos, extrayendo una clave de SSH de un oglive e instalándola en Forgejo, con: - ./opengnsys_git_installer.py --set-ssh-key + ./opengnsys_git_installer.py --extract-ssh-key-from-initrd O para hacerlo contra un oglive especifico: - ./opengnsys_git_installer.py --set-ssh-key --oglive 1 # numero de oglive + ./opengnsys_git_installer.py --extract-ssh-key-from-initrd --oglive 1 # numero de oglive + +O contra un archivo de initrd directamente: + + ./opengnsys_git_installer.py --extract-ssh-key-from-initrd --initrd-file /home/user/initrd.img Ejecutar este comando agrega la clave de SSH a Forgejo automáticamente. diff --git a/installer/opengnsys_git_installer.py b/installer/opengnsys_git_installer.py index 6c631aa..43d60c3 100755 --- a/installer/opengnsys_git_installer.py +++ b/installer/opengnsys_git_installer.py @@ -30,7 +30,7 @@ import hashlib import datetime #FORGEJO_VERSION="8.0.3" -FORGEJO_VERSION="9.0.0" +FORGEJO_VERSION="9.0.3" FORGEJO_URL=f"https://codeberg.org/forgejo/forgejo/releases/download/v{FORGEJO_VERSION}/forgejo-{FORGEJO_VERSION}-linux-amd64" @@ -147,6 +147,7 @@ class OpengnsysGitInstaller: for kp in self.key_paths: self.key_paths_dict[kp] = 1 + os.environ["PATH"] += os.pathsep + os.path.join(self.base_path, "bin") self.oglive = Oglive() @@ -294,7 +295,7 @@ class OpengnsysGitInstaller: raise TimeoutError("Timed out waiting for connection!") - def add_ssh_key_from_squashfs(self, oglive_num = None): + def add_ssh_key_from_squashfs(self, oglive_num = None, squashfs_file = None): if oglive_num is None: self.__logger.info("Using default oglive") @@ -305,31 +306,35 @@ class OpengnsysGitInstaller: oglive_client = self.oglive.get_clients()[str(oglive_num)] self.__logger.info("Oglive is %s", oglive_client) - keys = installer.extract_ssh_keys(oglive_num = oglive_num) + keys = installer.extract_ssh_keys_from_squashfs(oglive_num = oglive_num, squashfs_file=squashfs_file) for k in keys: timestamp = '{:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now()) installer.add_forgejo_sshkey(k, f"Key for {oglive_client} ({timestamp})") - def extract_ssh_keys(self, oglive_num = None): + def extract_ssh_keys_from_squashfs(self, oglive_num = None, squashfs_file = None): public_keys = [] squashfs = "ogclient.sqfs" - tftp_dir = os.path.join(self.base_path, "tftpboot") + if squashfs_file is None: + tftp_dir = os.path.join(self.base_path, "tftpboot") - if oglive_num is None: - self.__logger.info("Reading from default oglive") - oglive_num = self.oglive.get_default() + if oglive_num is None: + self.__logger.info("Reading from default oglive") + oglive_num = self.oglive.get_default() + else: + self.__logger.info("Reading from oglive %i", oglive_num) + + oglive_client = self.oglive.get_clients()[str(oglive_num)] + self.__logger.info("Oglive is %s", oglive_client) + + client_squashfs_path = os.path.join(tftp_dir, oglive_client, squashfs) else: - self.__logger.info("Reading from oglive %i", oglive_num) - - oglive_client = self.oglive.get_clients()[str(oglive_num)] - self.__logger.info("Oglive is %s", oglive_client) - - client_squashfs_path = os.path.join(tftp_dir, oglive_client, squashfs) + self.__logger.info("Using specified squashfs file %s", squashfs_file) + client_squashfs_path = squashfs_file self.__logger.info("Mounting %s", client_squashfs_path) mount_tempdir = tempfile.TemporaryDirectory() @@ -352,37 +357,50 @@ class OpengnsysGitInstaller: return public_keys - def _extract_ssh_key_from_initrd(self): + def extract_ssh_key_from_initrd(self, oglive_number = None, initrd_file = None): public_key="" INITRD = "oginitrd.img" - tftp_dir = os.path.join(self.base_path, "tftpboot") - default_num = self.oglive.get_default() - default_client = self.oglive.get_clients()[default_num] - client_initrd_path = os.path.join(tftp_dir, default_client, INITRD) + self.__logger.debug("Extracting ssh key from initrd") - #self.temp_dir = self._get_tempdir() + if initrd_file is None: + self.__logger.debug("Looking for initrd file") + tftp_dir = os.path.join(self.base_path, "tftpboot") + if oglive_number is None: + oglive_number = self.oglive.get_default() + + oglive_client = self.oglive.get_clients()[oglive_number] + client_initrd_path = os.path.join(tftp_dir, oglive_client, INITRD) + + self.__logger.debug("Found at %s", client_initrd_path) + else: + self.__logger.debug("Using provided initrd file %s", initrd_file) + client_initrd_path = initrd_file if self.usesshkey: with open(self.usesshkey, 'r') as f: public_key = f.read().strip() else: + self.__logger.debug("Extracting key from %s", client_initrd_path) + if os.path.isfile(client_initrd_path): #os.makedirs(temp_dir, exist_ok=True) #os.chdir(self.temp_dir.name) - self.__logger.debug("Descomprimiendo %s", client_initrd_path) + self.__logger.debug("Uncompressing %s", client_initrd_path) public_key = None with libarchive.file_reader(client_initrd_path) as initrd: for file in initrd: - self.__logger.debug("Archivo: %s", file) + self.__logger.debug("File: %s", file) pathname = file.pathname; if pathname.startswith("./"): pathname = pathname[2:] if pathname in self.key_paths_dict: + self.__logger.info("Found key %s, extracting", pathname) + data = bytearray() for block in file.get_blocks(): data = data + block @@ -390,9 +408,12 @@ class OpengnsysGitInstaller: break else: - print(f"No se encuentra la imagen de initrd {client_initrd_path}") + print(f"Failed to find initrd at {client_initrd_path}") exit(2) + if not public_key: + self.__logger.warning("Failed to find a SSH key") + return public_key def set_ssh_key_in_initrd(self, client_num = None): @@ -534,7 +555,26 @@ class OpengnsysGitInstaller: self.add_forgejo_sshkey(oglive_public_key, f"Key for {ogclient} ({timestamp})") - def install(self): + + + def verify_requirements(self): + self.__logger.info("verify_requirements()") + + # Control básico de errores. + self.__logger.debug("Comprobando euid") + if os.geteuid() != 0: + raise RequirementException("Sólo ejecutable por root") + + if not os.path.exists("/etc/debian_version"): + raise RequirementException("Instalación sólo soportada en Debian y Ubuntu") + + + MIN_PYTHON = (3, 8) + if sys.version_info < MIN_PYTHON: + raise RequirementException(f"Python %s.%s mínimo requerido.\n" % MIN_PYTHON) + + + def install_dependencies(self): """Instalar Ejecuta todo el proceso de instalación incluyendo: @@ -551,31 +591,10 @@ class OpengnsysGitInstaller: """ self.__logger.info("install()") - ogdir_images = os.path.join(self.base_path, "images") - ENGINECFG = os.path.join(self.base_path, "client/etc/engine.cfg") - os.environ["PATH"] += os.pathsep + os.path.join(self.base_path, "bin") - tftp_dir = os.path.join(self.base_path, "tftpboot") - INITRD = "oginitrd.img" - self.temp_dir = self._get_tempdir() - SSHUSER = "opengnsys" + self.verify_requirements() - - # Control básico de errores. - self.__logger.debug("Comprobando euid") - if os.geteuid() != 0: - raise RequirementException("Sólo ejecutable por root") - - if not os.path.exists("/etc/debian_version"): - raise RequirementException("Instalación sólo soportada en Debian y Ubuntu") - - - MIN_PYTHON = (3, 8) - if sys.version_info < MIN_PYTHON: - raise RequirementException(f"Python %s.%s mínimo requerido.\n" % MIN_PYTHON) - - - self.__logger.debug("Instalando dependencias") + self.__logger.debug("Installing dependencies") subprocess.run(["apt-get", "install", "-y", "git"], check=True) def _install_template(self, template, destination, keysvalues): @@ -604,7 +623,8 @@ class OpengnsysGitInstaller: - bin_path = os.path.join(self.base_path, "bin", "forgejo") + opengnsys_bin_path = os.path.join(self.base_path, "bin") + bin_path = os.path.join(opengnsys_bin_path, "forgejo") conf_dir_path = os.path.join(self.base_path, "etc", "forgejo") @@ -626,6 +646,8 @@ class OpengnsysGitInstaller: subprocess.run(["systemctl", "stop", "opengnsys-forgejo"], check=False) self.__logger.debug("Downloading from %s into %s", FORGEJO_URL, bin_path) + pathlib.Path(opengnsys_bin_path).mkdir(parents=True, exist_ok=True) + urllib.request.urlretrieve(FORGEJO_URL, bin_path) os.chmod(bin_path, 0o755) @@ -716,11 +738,6 @@ class OpengnsysGitInstaller: token_file.write(token) - ssh_key = self._extract_ssh_key_from_initrd() - - self.add_forgejo_sshkey(ssh_key, "Default key") - - def add_forgejo_repo(self, repository_name, description = ""): token = "" with open(os.path.join(self.base_path, "etc", "ogGitApiToken.cfg"), "r", encoding='utf-8') as token_file: @@ -830,6 +847,9 @@ if __name__ == '__main__': parser.add_argument('--set-ssh-key', action='store_true', help="Read SSH key from oglive squashfs and set it in Forgejo") parser.add_argument('--extract-ssh-key-from-initrd', action='store_true', help="Extract SSH key from oglive initrd (obsolete)") + parser.add_argument('--initrd-file', metavar="FILE", help="Initrd file to extract SSH key from") + parser.add_argument('--squashfs-file', metavar="FILE", help="Squashfs file to extract SSH key from") + parser.add_argument('--set-ssh-key-in-initrd', action='store_true', help="Configure SSH key in oglive (obsolete)") parser.add_argument('--oglive', type=int, metavar='NUM', help = "Do SSH key manipulation on this oglive") parser.add_argument('--quiet', action='store_true', help="Quiet console output") @@ -860,23 +880,25 @@ if __name__ == '__main__': elif args.test_createuser: installer.set_ssh_user_group("oggit2", "oggit2") elif args.extract_ssh_key: - keys = installer.extract_ssh_keys(oglive_num = args.oglive) + keys = installer.extract_ssh_keys_from_squashfs(oglive_num = args.oglive) print(f"{keys}") elif args.extract_ssh_key_from_initrd: - key = installer._extract_ssh_key_from_initrd() + key = installer.extract_ssh_key_from_initrd(oglive_number = args.oglive, initrd_file = args.initrd_file) print(f"{key}") elif args.set_ssh_key: installer.add_ssh_key_from_squashfs(oglive_num=args.oglive) elif args.set_ssh_key_in_initrd: installer.set_ssh_key_in_initrd() else: - installer.install() + installer.install_dependencies() installer.install_forgejo() installer.add_forgejo_repo("windows", "Windows") installer.add_forgejo_repo("linux", "Linux") installer.add_forgejo_repo("mac", "Mac") + installer.add_ssh_key_from_squashfs(oglive_num = args.oglive, squashfs_file=args.squashfs_file) + except RequirementException as req: show_error(f"Requisito para la instalación no satisfecho: {req.message}") exit(1)