1 | import os |
---|
2 | import re |
---|
3 | import subprocess |
---|
4 | import shutil |
---|
5 | import sys |
---|
6 | import platform |
---|
7 | |
---|
8 | from engine.FileSystemLib import * |
---|
9 | from engine.SystemLib import * |
---|
10 | from engine.DiskLib import * |
---|
11 | |
---|
12 | def ogCreateCache(ndisk=1, npart=4, partsize=None): |
---|
13 | """ |
---|
14 | Define la caché local, por defecto en partición 4 del disco 1. |
---|
15 | |
---|
16 | :param ndisk: número de disco donde crear la caché, por defecto es 1. |
---|
17 | :param npart: número de partición (opcional, 4 por defecto). |
---|
18 | :param partsize: tamaño de la partición en KB. |
---|
19 | :raises ValueError: Si el formato de los parámetros es incorrecto. |
---|
20 | :raises RuntimeError: Si ocurre un error durante la creación de la caché. |
---|
21 | """ |
---|
22 | |
---|
23 | if partsize is None: |
---|
24 | raise ValueError("El tamaño de la partición debe especificarse.") |
---|
25 | |
---|
26 | # Verifica si las herramientas necesarias están instaladas |
---|
27 | required_tools = ["sfdisk", "parted", "awk", "sed"] |
---|
28 | for tool in required_tools: |
---|
29 | if not shutil.which(tool): |
---|
30 | raise RuntimeError(f"La herramienta {tool} no está instalada.") |
---|
31 | |
---|
32 | # Preparar los comandos para crear la caché |
---|
33 | disk = f"/dev/sd{chr(96 + ndisk)}" |
---|
34 | size_in_sectors = partsize * 2 # Asumiendo 512B por sector |
---|
35 | |
---|
36 | try: |
---|
37 | # Lógica simplificada para crear la caché en la partición |
---|
38 | subprocess.run(["parted", disk, "mkpart", "primary", str(npart), str(partsize)], check=True) |
---|
39 | except subprocess.CalledProcessError as e: |
---|
40 | raise RuntimeError(f"Error al crear la caché: {e}") |
---|
41 | |
---|
42 | def ogDeleteCache(): |
---|
43 | """ |
---|
44 | Borra la partición utilizada para caché. |
---|
45 | |
---|
46 | :raises RuntimeError: Si ocurre un error durante la eliminación de la partición de caché. |
---|
47 | """ |
---|
48 | cachepart = ogFindCache() |
---|
49 | if cachepart is None: |
---|
50 | raise RuntimeError("No se encontró la partición de caché.") |
---|
51 | |
---|
52 | disk = f"/dev/sd{chr(96 + int(cachepart))}" |
---|
53 | try: |
---|
54 | subprocess.run(["parted", disk, "rm", cachepart], check=True) |
---|
55 | except subprocess.CalledProcessError as e: |
---|
56 | raise RuntimeError(f"Error al borrar la partición de caché: {e}") |
---|
57 | |
---|
58 | def ogFindCache(): |
---|
59 | """ |
---|
60 | Encuentra la partición que se usa como caché. |
---|
61 | |
---|
62 | :return: El nombre de la partición de caché si se encuentra, de lo contrario None. |
---|
63 | """ |
---|
64 | try: |
---|
65 | for disk in [f"/dev/sd{chr(97 + i)}" for i in range(26)]: # /dev/sda to /dev/sdz |
---|
66 | result = subprocess.run(["sfdisk", "-d", disk], capture_output=True, text=True, check=True) |
---|
67 | if "CA00" in result.stdout: |
---|
68 | cachepart = [line.split()[0] for line in result.stdout.splitlines() if "CA00" in line][0] |
---|
69 | return cachepart |
---|
70 | except subprocess.CalledProcessError: |
---|
71 | return None |
---|
72 | |
---|
73 | return None |
---|
74 | |
---|
75 | def ogFormatCache(): |
---|
76 | """ |
---|
77 | Formatea la partición de caché. |
---|
78 | |
---|
79 | :raises RuntimeError: Si ocurre un error durante el formateo de la partición. |
---|
80 | """ |
---|
81 | # Si se solicita, mostrar ayuda. |
---|
82 | if len(sys.argv) > 1 and sys.argv[1] == "help": |
---|
83 | ogHelp("ogFormatCache", "ogFormatCache") |
---|
84 | return |
---|
85 | |
---|
86 | # Error si no hay definida partición de caché. |
---|
87 | cachepart = ogFindCache() |
---|
88 | if cachepart is None: |
---|
89 | ogRaiseError(OG_ERR_PARTITION, MSG_NOCACHE) |
---|
90 | return |
---|
91 | |
---|
92 | disk = ogDiskToDev(cachepart) |
---|
93 | |
---|
94 | # Formatear sistema de ficheros. |
---|
95 | ogUnmountCache() |
---|
96 | options = "extent,large_file" |
---|
97 | if re.match("^5", platform.release()): |
---|
98 | options += ",uninit_bg,^metadata_csum,^64bit" |
---|
99 | try: |
---|
100 | subprocess.run(["mkfs.ext4", "-q", "-F", disk, "-L", "CACHE", "-O", options], check=True) |
---|
101 | except subprocess.CalledProcessError as e: |
---|
102 | raise RuntimeError(f"Error al formatear la partición de caché: {e}") |
---|
103 | |
---|
104 | # Crear estructura básica. |
---|
105 | mntdir = ogMountCache() |
---|
106 | os.makedirs(os.path.join(mntdir, OGIMG), exist_ok=True) |
---|
107 | |
---|
108 | # Incluir kernel e Initrd del ogLive |
---|
109 | updateBootCache() |
---|
110 | |
---|
111 | def ogGetCacheSize(): |
---|
112 | """ |
---|
113 | Obtiene el tamaño de la partición de caché. |
---|
114 | |
---|
115 | :return: Tamaño de la partición de caché en kilobytes. |
---|
116 | :raises RuntimeError: Si ocurre un error al obtener el tamaño de la partición de caché. |
---|
117 | """ |
---|
118 | # Si se solicita, mostrar ayuda. |
---|
119 | if len(sys.argv) > 1 and sys.argv[1] == "help": |
---|
120 | ogHelp("ogGetCacheSize", "help", "ogGetCacheSize") |
---|
121 | |
---|
122 | # Error si no se encuentra partición de caché. |
---|
123 | cachepart = ogFindCache() |
---|
124 | if cachepart is None: |
---|
125 | raise RuntimeError(MSG_NOCACHE) |
---|
126 | |
---|
127 | # Devuelve tamaño de la partición de caché. |
---|
128 | return ogGetPartitionSize(cachepart) |
---|
129 | |
---|
130 | def ogGetCacheSpace(): |
---|
131 | """ |
---|
132 | Obtiene el espacio libre en la partición de caché en kilobytes. |
---|
133 | |
---|
134 | :return: Espacio libre en kilobytes. |
---|
135 | :raises RuntimeError: Si ocurre un error al obtener el espacio libre. |
---|
136 | """ |
---|
137 | # Si se solicita, mostrar ayuda. |
---|
138 | if len(sys.argv) > 1 and sys.argv[1] == "help": |
---|
139 | ogHelp("ogGetCacheSpace", "help", "ogGetCacheSpace") |
---|
140 | |
---|
141 | # Error si no se encuentra partición de caché. |
---|
142 | cachepart = ogFindCache() |
---|
143 | if cachepart is None: |
---|
144 | raise RuntimeError(MSG_NOCACHE) |
---|
145 | |
---|
146 | # Obtener el tamaño del disco y el número de sectores. |
---|
147 | disk = ogDiskToDev(cachepart) |
---|
148 | try: |
---|
149 | result = subprocess.run(["sfdisk", "-g", disk], capture_output=True, text=True, check=True) |
---|
150 | output = result.stdout |
---|
151 | sectors_per_cylinder = int(output.splitlines()[1].split()[1]) |
---|
152 | total_sectors = int(output.splitlines()[1].split()[0]) * sectors_per_cylinder - 1 |
---|
153 | except subprocess.CalledProcessError as e: |
---|
154 | raise RuntimeError(f"Error al obtener el espacio libre: {e}") |
---|
155 | |
---|
156 | # Obtener el último sector de la partición 3. |
---|
157 | try: |
---|
158 | result = subprocess.run(["sfdisk", "-uS", "-l", disk], capture_output=True, text=True, check=True) |
---|
159 | output = result.stdout |
---|
160 | end_sector_part3 = int([line.split()[2] for line in output.splitlines() if cachepart + "3" in line][0]) |
---|
161 | except subprocess.CalledProcessError as e: |
---|
162 | raise RuntimeError(f"Error al obtener el espacio libre: {e}") |
---|
163 | |
---|
164 | # Calcular el espacio libre en kilobytes. |
---|
165 | if end_sector_part3 > total_sectors // 2: |
---|
166 | free_space_kb = (total_sectors - end_sector_part3) // 2 |
---|
167 | else: |
---|
168 | free_space_kb = total_sectors // 4 |
---|
169 | |
---|
170 | return free_space_kb |
---|
171 | |
---|
172 | def ogMountCache(): |
---|
173 | """ |
---|
174 | Monta la partición de caché en el directorio /mnt/sda4. |
---|
175 | |
---|
176 | :raises RuntimeError: Si ocurre un error durante el montaje de la partición de caché. |
---|
177 | """ |
---|
178 | # Si se solicita, mostrar ayuda. |
---|
179 | if len(sys.argv) > 1 and sys.argv[1] == "help": |
---|
180 | ogHelp("ogMountCache", "help", "ogMountCache") |
---|
181 | |
---|
182 | # Montar la partición de caché en /mnt/sda4. |
---|
183 | try: |
---|
184 | subprocess.run(["mount", ogFindCache(), "/mnt/sda4"], check=True) |
---|
185 | except subprocess.CalledProcessError as e: |
---|
186 | raise RuntimeError(f"Error al montar la partición de caché: {e}") |
---|
187 | |
---|
188 | def ogUnmountCache(): |
---|
189 | """ |
---|
190 | Desmonta la partición de caché. |
---|
191 | |
---|
192 | :raises RuntimeError: Si ocurre un error durante el desmontaje de la partición de caché. |
---|
193 | """ |
---|
194 | # Si se solicita, mostrar ayuda. |
---|
195 | if len(sys.argv) > 1 and sys.argv[1] == "help": |
---|
196 | ogHelp("ogUnmountCache", "help", "ogUnmountCache") |
---|
197 | |
---|
198 | # Obtener la partición de caché. |
---|
199 | cachepart = ogFindCache() |
---|
200 | if cachepart is None: |
---|
201 | raise RuntimeError("No se encontró la partición de caché.") |
---|
202 | |
---|
203 | # Desmontar la partición de caché. |
---|
204 | try: |
---|
205 | subprocess.run(["umount", cachepart], check=True) |
---|
206 | except subprocess.CalledProcessError as e: |
---|
207 | raise RuntimeError(f"Error al desmontar la partición de caché: {e}") |
---|
208 | |
---|
209 | # Eliminar el enlace simbólico de /mnt/ParticiónCache. |
---|
210 | os.remove(f"/mnt/{cachepart}") |
---|