Compare commits
	
		
			No commits in common. "d4ce9c3ee39737105a334f4a613d416a846dab32" and "09baf6d1e85573feca8d23191ec2169b4c3a6a36" have entirely different histories. 
		
	
	
		
			d4ce9c3ee3
			...
			09baf6d1e8
		
	
		
							
								
								
									
										101
									
								
								api/gitapi.py
								
								
								
								
							
							
						
						
									
										101
									
								
								api/gitapi.py
								
								
								
								
							|  | @ -77,7 +77,7 @@ REPOSITORIES_BASE_PATH = "/opt/opengnsys/ogrepository/oggit/git/oggit/" | |||
| 
 | ||||
| start_time = time.time() | ||||
| tasks = {} | ||||
| tasks_max = 1024 | ||||
| 
 | ||||
| 
 | ||||
| # Create an instance of the Flask class | ||||
| app = Flask(__name__) | ||||
|  | @ -93,24 +93,6 @@ executor = Executor(app) | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| def add_task(future): | ||||
|     task_id = uuid.uuid4().hex | ||||
|     task_data = { | ||||
|         "future" : future, | ||||
|         "start_time" : time.time() | ||||
|     } | ||||
| 
 | ||||
|     while len(tasks) >= tasks_max: | ||||
|         oldest_task_id = min(tasks, key=lambda k: tasks[k]['start_time']) | ||||
|         task = tasks[task_id]["future"] | ||||
|         if task.running(): | ||||
|             log.error("Cancelling still running task %s, maximum task limit of %i reached", task_id, tasks_max) | ||||
|             task.cancel() | ||||
| 
 | ||||
|         del tasks[oldest_task_id] | ||||
| 
 | ||||
|     tasks[task_id] = task_data | ||||
|     return task_id | ||||
| 
 | ||||
| def do_repo_backup(repo, params): | ||||
|     """ | ||||
|  | @ -128,10 +110,7 @@ def do_repo_backup(repo, params): | |||
|         bool: True if the backup was successful. | ||||
|     """ | ||||
| 
 | ||||
|     git_repo_path = f"{REPOSITORIES_BASE_PATH}/{repo}.git" | ||||
|     git_repo = git.Repo(git_repo_path) | ||||
|     git_repo.git.config('--global', '--add', 'safe.directory', git_repo_path) | ||||
| 
 | ||||
|     gitrepo = git.Repo(f"{REPOSITORIES_BASE_PATH}/{repo}.git") | ||||
| 
 | ||||
|     ssh = paramiko.SSHClient() | ||||
|     ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) | ||||
|  | @ -141,7 +120,7 @@ def do_repo_backup(repo, params): | |||
| 
 | ||||
| 
 | ||||
|     with sftp.file(params["filename"], mode='wb+') as remote_file: | ||||
|         git_repo.archive(remote_file, format="tar.gz") | ||||
|         gitrepo.archive(remote_file, format="tar.gz") | ||||
| 
 | ||||
| 
 | ||||
|     return True | ||||
|  | @ -160,16 +139,13 @@ def do_repo_sync(repo, params): | |||
|             - "remote_ref" (str): The name of the remote reference. | ||||
|             - "summary" (str): A summary of the push operation for the reference. | ||||
|     """ | ||||
|     git_repo_path = f"{REPOSITORIES_BASE_PATH}/{repo}.git" | ||||
|     git_repo = git.Repo(git_repo_path) | ||||
|     git_repo.git.config('--global', '--add', 'safe.directory', git_repo_path) | ||||
| 
 | ||||
|     gitrepo = git.Repo(f"{REPOSITORIES_BASE_PATH}/{repo}.git") | ||||
| 
 | ||||
|     # Recreate the remote every time, it might change | ||||
|     if "backup" in git_repo.remotes: | ||||
|         git_repo.delete_remote("backup") | ||||
|     if "backup" in gitrepo.remotes: | ||||
|         gitrepo.delete_remote("backup") | ||||
| 
 | ||||
|     backup_repo = git_repo.create_remote("backup", params["remote_repository"]) | ||||
|     backup_repo = gitrepo.create_remote("backup", params["remote_repository"]) | ||||
|     pushed_references = backup_repo.push("*:*") | ||||
|     results = [] | ||||
| 
 | ||||
|  | @ -189,11 +165,11 @@ def do_repo_gc(repo): | |||
|     Returns: | ||||
|         bool: True if the garbage collection command was executed successfully. | ||||
|     """ | ||||
|     git_repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git") | ||||
|     git_repo = git.Repo(git_repo_path) | ||||
|     git_repo.git.config('--global', '--add', 'safe.directory', git_repo_path) | ||||
|     gitrepo = git.Repo(f"{REPOSITORIES_BASE_PATH}/{repo}.git") | ||||
| 
 | ||||
|     gitrepo.git.gc() | ||||
|     return True | ||||
| 
 | ||||
|     git_repo.git.gc() | ||||
| 
 | ||||
| @app.errorhandler(HTTPException) | ||||
| def handle_exception(e): | ||||
|  | @ -303,7 +279,6 @@ class GitRepositories(Resource): | |||
|         data = request.json | ||||
| 
 | ||||
|         if data is None: | ||||
|             log.error("Can't create repository, JSON post data missing") | ||||
|             return {"error" : "Parameters missing"}, 400 | ||||
| 
 | ||||
|         repo = data["name"] | ||||
|  | @ -350,16 +325,15 @@ class GitRepoSync(Resource): | |||
|         data = request.json | ||||
| 
 | ||||
|         if data is None: | ||||
|             log.error("Can't create repository, JSON post data missing") | ||||
|             return {"error" : "Parameters missing"}, 400 | ||||
| 
 | ||||
|         if not "remote_repository" in data: | ||||
|             log.error("Can't create repository, parameter 'remote_repository' missing") | ||||
|             return {"error" : "Parameter 'remote_repository' missing"}, 400 | ||||
| 
 | ||||
| 
 | ||||
|         future = executor.submit(do_repo_sync, repo, data) | ||||
|         task_id = add_task(future) | ||||
|         task_id = str(uuid.uuid4()) | ||||
|         tasks[task_id] = future | ||||
| 
 | ||||
|         log.info("Starting synchronization of repository %s, task %s", repo, task_id, extra = {"repository" : repo, "task_id" : task_id}) | ||||
|         return {"status": "started", "task_id" : task_id}, 200 | ||||
|  | @ -399,7 +373,6 @@ class GitRepoBackup(Resource): | |||
| 
 | ||||
|         data = request.json | ||||
|         if data is None: | ||||
|             log.error("Can't create repository, JSON post data missing") | ||||
|             return {"error" : "Parameters missing"}, 400 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -408,7 +381,8 @@ class GitRepoBackup(Resource): | |||
| 
 | ||||
| 
 | ||||
|         future = executor.submit(do_repo_backup, repo, data) | ||||
|         task_id = add_task(future) | ||||
|         task_id = str(uuid.uuid4()) | ||||
|         tasks[task_id] = future | ||||
| 
 | ||||
|         log.info("Starting backup of repository %s, task %s", repo, task_id, extra = {"repository" : repo, "task_id" : task_id}) | ||||
|         return {"status": "started", "task_id" : task_id}, 200 | ||||
|  | @ -437,7 +411,8 @@ class GitRepoCompact(Resource): | |||
|             return {"error": "Repository not found"}, 404 | ||||
| 
 | ||||
|         future = executor.submit(do_repo_gc, repo) | ||||
|         task_id = add_task(future) | ||||
|         task_id = str(uuid.uuid4()) | ||||
|         tasks[task_id] = future | ||||
| 
 | ||||
|         log.info("Starting compaction of repository %s, task %s", repo, task_id, extra = {"repository" : repo, "task_id" : task_id}) | ||||
|         return {"status": "started", "task_id" : task_id}, 200 | ||||
|  | @ -462,7 +437,7 @@ class GitTaskStatus(Resource): | |||
|             log.error("Task %s was not found", task_id, extra = {"task_id" : task_id}) | ||||
|             return {"error": "Task not found"}, 404 | ||||
| 
 | ||||
|         future  = tasks[task_id]["future"] | ||||
|         future  = tasks[task_id] | ||||
| 
 | ||||
|         try: | ||||
|             if future.done(): | ||||
|  | @ -531,8 +506,6 @@ class GitRepoBranches(Resource): | |||
|             return {"error": "Repository not found"}, 404 | ||||
| 
 | ||||
|         git_repo = git.Repo(repo_path) | ||||
|         git_repo.git.config('--global', '--add', 'safe.directory', repo_path) | ||||
| 
 | ||||
| 
 | ||||
|         branches = [] | ||||
|         for branch in git_repo.branches: | ||||
|  | @ -543,36 +516,7 @@ class GitRepoBranches(Resource): | |||
|             "branches": branches | ||||
|         } | ||||
| 
 | ||||
| @git_ns.route('/repositories/<repo>/branches/<branch>') | ||||
| class GitRepoBranchesDeleter(Resource): | ||||
|     def delete(self, repo, branch): | ||||
|         """Delete a given branch in a given repository | ||||
| 
 | ||||
|         Args: | ||||
|             repo (str): The name of the repository. | ||||
| 
 | ||||
|         Returns: | ||||
|             Response: A JSON response containing a list of branch names or an error message if the repository is not found. | ||||
|             - 200: A JSON object with a "status" key containing "deleted" | ||||
|             - 404: A JSON object with an "error" key containing the message "Repository not found" or "Branch not found" | ||||
|         """ | ||||
| 
 | ||||
|         repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git") | ||||
|         if not os.path.isdir(repo_path): | ||||
|             log.error("Can't get branches of repository repository %s, not found. Looked in %s", repo, repo_path, extra = {"repository" : repo, "path" : repo_path }) | ||||
|             return {"error": "Repository not found"}, 404 | ||||
| 
 | ||||
|         git_repo = git.Repo(repo_path) | ||||
|         git_repo.git.config('--global', '--add', 'safe.directory', repo_path) | ||||
| 
 | ||||
| 
 | ||||
|         if not branch in git_repo.branches: | ||||
|             log.error("Can't delete branch %s, not found in repository %s", branch, repo, extra = {"repository" : repo, "branch" : branch}) | ||||
|             return {"error": "Branch not found"}, 404 | ||||
| 
 | ||||
|         git_repo.delete_head(branch) | ||||
|         log.info("Branch %s of repository %s deleted", branch, repo, extra = {"repository" : repo, "branch" : branch}) | ||||
|         return {"status": "deleted"}, 200 | ||||
| 
 | ||||
| 
 | ||||
| @git_ns.route('/health') | ||||
|  | @ -613,15 +557,6 @@ class GitStatus(Resource): | |||
|             "active_tasks" : len(tasks) | ||||
|         } | ||||
| 
 | ||||
| @app.after_request | ||||
| def after_request(response): | ||||
|     log.info("Request from %s: %s %s %s %s", request.remote_addr, request.method, request.scheme, request.full_path, response.status, | ||||
|              extra = {"remote_addr" : request.remote_addr, "method" : request.method, "scheme" : request.scheme, "full_path" : request.full_path, "status" : response.status}) | ||||
| 
 | ||||
|     if debug_enabled: | ||||
|         log.debug("Response: %s", response.data, extra = {"response" : response.data}) | ||||
| 
 | ||||
|     return response | ||||
| 
 | ||||
| api.add_namespace(git_ns) | ||||
| 
 | ||||
|  |  | |||
|  | @ -248,6 +248,10 @@ class OpengnsysGitInstaller: | |||
|         """Ignorar requisito de clave de ssh para el instalador""" | ||||
|         self.ignoresshkey = value | ||||
| 
 | ||||
|     def set_usesshkey(self, value): | ||||
|         """Usar clave de ssh especificada""" | ||||
|         self.usesshkey = value | ||||
| 
 | ||||
|     def set_basepath(self, value): | ||||
|         """Establece ruta base de OpenGnsys | ||||
|         Valor por defecto: /opt/opengnsys | ||||
|  | @ -474,33 +478,38 @@ class OpengnsysGitInstaller: | |||
|             self.__logger.debug("Using provided initrd file %s", initrd_file) | ||||
|             client_initrd_path = initrd_file | ||||
| 
 | ||||
|         self.__logger.debug("Extracting key from %s", client_initrd_path) | ||||
|         if self.usesshkey: | ||||
|             with open(self.usesshkey, 'r') as f: | ||||
|                 public_key = f.read().strip() | ||||
| 
 | ||||
|         if os.path.isfile(client_initrd_path): | ||||
|             #os.makedirs(temp_dir, exist_ok=True) | ||||
|             #os.chdir(self.temp_dir.name) | ||||
|             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("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 | ||||
|                         public_key = data.decode('utf-8').strip() | ||||
| 
 | ||||
|                         break | ||||
|         else: | ||||
|             print(f"Failed to find initrd at {client_initrd_path}") | ||||
|             exit(2) | ||||
|             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("Uncompressing %s", client_initrd_path) | ||||
|                 public_key = None | ||||
|                 with libarchive.file_reader(client_initrd_path) as initrd: | ||||
|                     for file in initrd: | ||||
|                         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 | ||||
|                             public_key = data.decode('utf-8').strip() | ||||
| 
 | ||||
|                             break | ||||
|             else: | ||||
|                 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") | ||||
|  | @ -952,7 +961,7 @@ if __name__ == '__main__': | |||
| 
 | ||||
|     parser.add_argument('--testmode', action='store_true', help="Modo de prueba") | ||||
|     parser.add_argument('--ignoresshkey', action='store_true', help="Ignorar clave de SSH") | ||||
|     parser.add_argument('--use-ssh-key', metavar="FILE", type=str, help="Add the SSH key from the specified file") | ||||
|     parser.add_argument('--usesshkey', type=str, help="Usar clave SSH especificada") | ||||
|     parser.add_argument('--test-createuser', action='store_true') | ||||
|     parser.add_argument('--extract-ssh-key', action='store_true', help="Extract SSH key from oglive squashfs") | ||||
|     parser.add_argument('--set-ssh-key', action='store_true', help="Read SSH key from oglive squashfs and set it in Forgejo") | ||||
|  | @ -984,6 +993,7 @@ if __name__ == '__main__': | |||
|     installer = OpengnsysGitInstaller() | ||||
|     installer.set_testmode(args.testmode) | ||||
|     installer.set_ignoresshkey(args.ignoresshkey) | ||||
|     installer.set_usesshkey(args.usesshkey) | ||||
| 
 | ||||
|     logger.debug("Inicio de instalación") | ||||
| 
 | ||||
|  | @ -1002,13 +1012,6 @@ if __name__ == '__main__': | |||
|             print(f"{key}") | ||||
|         elif args.set_ssh_key: | ||||
|             installer.add_ssh_key_from_squashfs(oglive_num=args.oglive, squashfs_file=args.squashfs_file, oglive_file = args.oglive_file or args.oglive_url) | ||||
|         elif args.use_ssh_key: | ||||
|             with open(args.use_ssh_key, 'r', encoding='utf-8') as ssh_key_file: | ||||
|                 ssh_key_data = ssh_key_file.read().strip() | ||||
|                 (keytype, keydata, description) = ssh_key_data.split(" ", 2) | ||||
| 
 | ||||
|                 installer.add_forgejo_sshkey(f"{keytype} {keydata}", description) | ||||
| 
 | ||||
|         elif args.set_ssh_key_in_initrd: | ||||
|             installer.set_ssh_key_in_initrd() | ||||
|         elif args.get_image_paths: | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue