diff --git a/CHANGELOG.md b/CHANGELOG.md index 64a3837..3cc668f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.7.7] - 2025-10-22 + +### Fixed + +- gitlib: save and restore symlink info +- gitlib: support nvme disks +- netlib: fix getting net info + ## [1.7.6] - 2025-10-16 ### Fixed diff --git a/ogclient/lib/python3/FileSystemLib.py b/ogclient/lib/python3/FileSystemLib.py index 306f449..87e136f 100644 --- a/ogclient/lib/python3/FileSystemLib.py +++ b/ogclient/lib/python3/FileSystemLib.py @@ -664,7 +664,7 @@ def ogReduceFs (disk, par): extrasize = 0 retval = 1 while retval != 0 and size+extrasize < maxsize: - nr = subprocess.run (['ntfsresize', '-fns', str(size), PART], capture_output=True, text=True) + nr = subprocess.run (['ntfsresize', '--no-progress-bar', '-fns', str(size), PART], capture_output=True, text=True) for l in nr.stdout.splitlines(): if 'Needed relocations' not in l: continue extrasize = int ((int (l.split()[3])*1.1/1024+1)*1024) diff --git a/ogclient/lib/python3/GitLib/__init__.py b/ogclient/lib/python3/GitLib/__init__.py index 5c8e068..0aae3a2 100755 --- a/ogclient/lib/python3/GitLib/__init__.py +++ b/ogclient/lib/python3/GitLib/__init__.py @@ -647,6 +647,15 @@ class OpengnsysGitLibrary: return results + def _getfattr(self, file_type, path, path_rel, fd): + getfattr_out = subprocess.run (['getfattr', '--no-dereference', '--encoding', 'hex', '--name', 'system.ntfs_reparse_data', path], capture_output=True, text=True).stdout + if getfattr_out: + reparse_data = re.search ('ntfs_reparse_data=(0x[0-9a-fA-F]*)', getfattr_out).groups()[0] + fd.write(json.dumps({"file" : path_rel, "type" : file_type, "reparse_data" : reparse_data}) + "\n") + else: + self.logger.warning (f'{path}: symlink with no reparse data') + + def _create_metadata(self, path, initial_creation=False): """Calculate metadata for a filesystem @@ -719,6 +728,7 @@ class OpengnsysGitLibrary: renamed_file = open(os.path.join(meta_dir, "renamed.jsonl.new"), "w", encoding='utf-8') filesystems_file = open(os.path.join(meta_dir, "filesystems.json.new"), "w", encoding='utf-8') partitions_file = open(os.path.join(meta_dir, "partitions.json.new"), "w", encoding='utf-8') + symlinks_file = open(os.path.join(meta_dir, "symlinks.jsonl.new"), "w", encoding='utf-8') partitions_file.write(self.disk.get_disk_json_data(self.fs.find_device(mountpoint=path))) @@ -919,9 +929,11 @@ class OpengnsysGitLibrary: # Git falla al encontrarse con archivos especiales como dispositivos. De momento debemos # eliminarlos. os.unlink(full_path) + if os.path.islink(full_path): #self.logger.debug(f"Symlink: {full_path_rel}") return_data['symlinks'].append(full_path_rel) + self._getfattr ("file", full_path, full_path_rel, symlinks_file) if os.path.isfile(full_path) and file in self.rename_list and root != path: # Process this last so that all the metadata references the real names. @@ -955,6 +967,9 @@ class OpengnsysGitLibrary: os.rename(full_path, renamed_dir_path) + if os.path.islink(full_path): + self._getfattr ("dir", full_path, full_path_rel, symlinks_file) + if not ntfs and os.path.isdir(full_path) and not os.path.islink(full_path): stat_data = os.stat(full_path) @@ -996,6 +1011,7 @@ class OpengnsysGitLibrary: filesystems_file.close() metadata_file.close() partitions_file.close() + symlinks_file.close() os.rename(os.path.join(meta_dir, "empty_directories.jsonl.new"), os.path.join(meta_dir, "empty_directories.jsonl")) os.rename(os.path.join(meta_dir, "special_files.jsonl.new"), os.path.join(meta_dir, "special_files.jsonl")) @@ -1006,6 +1022,7 @@ class OpengnsysGitLibrary: os.rename(os.path.join(meta_dir, "filesystems.json.new"), os.path.join(meta_dir, "filesystems.json")) os.rename(os.path.join(meta_dir, "metadata.json.new"), os.path.join(meta_dir, "metadata.json")) os.rename(os.path.join(meta_dir, "partitions.json.new"), os.path.join(meta_dir, "partitions.json")) + os.rename(os.path.join(meta_dir, "symlinks.jsonl.new"), os.path.join(meta_dir, "symlinks.jsonl")) self.logger.debug("Processing pending NTFS secaudits...") @@ -1613,6 +1630,33 @@ class OpengnsysGitLibrary: if self.fs.filesystem_type(mountpoint = destination_dir) == "ntfs": self._ntfs_restore_secaudit(destination_dir) + self.logger.info("Processing symlinks.jsonl") + meta_dir = os.path.join(destination_dir, ".opengnsys-metadata") + with open(os.path.join(meta_dir, "symlinks.jsonl"), "r", encoding='utf-8') as symlinks_file: + for line in symlinks_file: + if line.isspace(): + self.logger.debug("Empty line, skipping") + continue + symlink_data = json.loads(line) + symlink_file = symlink_data['file'] + symlink_type = symlink_data['type'] + symlink_reparse_data = symlink_data['reparse_data'] + full_path = os.path.join(destination_dir,symlink_file) + if os.path.islink (full_path): + rp = os.path.realpath (full_path) + if not os.path.exists (full_path): continue ## broken symlink but that's fine + ## islink and exists: that's how it should be + continue + self.logger.info(f'({full_path}): not a symlink, restoring ntfs reparse data...') + os.unlink (full_path) + if 'dir' == symlink_type: os.mkdir (full_path) + else: open (full_path, 'w').close() + p = subprocess.run (['setfattr', '--no-dereference', '--value', symlink_reparse_data, '--name', 'system.ntfs_reparse_data', full_path], capture_output=True, text=True) + if p.returncode or p.stderr: + self.logger.warning(f'setfattr rc ({p.returncode}) out ({p.stdout}) err ({p.stderr})') + else: + self.logger.debug(f'setfattr rc ({p.returncode}) out ({p.stdout}) err ({p.stderr})') + if repo_is_efi: self._efi_install(root_directory=destination_dir) else: diff --git a/ogclient/lib/python3/GitLib/disk.py b/ogclient/lib/python3/GitLib/disk.py index 09b3881..c667205 100644 --- a/ogclient/lib/python3/GitLib/disk.py +++ b/ogclient/lib/python3/GitLib/disk.py @@ -22,7 +22,7 @@ class DiskLibrary: [base_device, partno] """ - r = re.compile("^(.*?)(\\d+)$") + r = re.compile("^(.*?)p?(\\d+)$") m = r.match(device) disk = m.group(1) partno = int(m.group(2)) diff --git a/ogclient/lib/python3/NetLib.py b/ogclient/lib/python3/NetLib.py index 8ab03d8..9f5407d 100644 --- a/ogclient/lib/python3/NetLib.py +++ b/ogclient/lib/python3/NetLib.py @@ -143,6 +143,7 @@ def ogGetIpAddress(): ipasj = json.loads (ipas) addresses = [] for e in ipasj: + if 'ifname' not in e: continue if 'lo' == e['ifname']: continue if 'addr_info' not in e: continue addrs = e['addr_info']