Parted y Python: pyparted

Python

Supongo que muchos de vosotros conoceréis libparted, la librería que hay debajo de los programas de particionado típicos de GNU. Muchos de vosotros conocéis también Python, si juntamos estas dos cosas tenemos que hacer programitas que manejen el particionado del disco va a estar al alcance de cualquiera. Llegados a este punto, no sobra decir que: NO me responsabilizo de los daños que pueda causar el uso de esta receta, yo lo he probado con un disco flash y me ha funcionado sin problemas. Quien quiera garantías... que las pague Sticking out tongue.

Instalación

Pues lamentablemente hay que compilar e instalar... no es muy complicado, pero bueno... empecemos por descargarnos los fuentes del modulo de python, los encontramos en http://dcantrel.fedorapeople.org/pyparted/. Hay que tener en cuenta una cosa, a fecha de hoy (4 de diciembre de 2007) en Debian Unstable la versión de libgparted-dev empaquetada es la antiquísima 1.7, lo cual nos obliga a usar una versión del módulo antigua: la 1.8.5. Esto es un poco rollo, pero por lo menos no tenemos que instalar y configurar libgparted entera. No he probado versiones más nuevas del módulo de python, salvo la versión 1.8.9 que compilaba pero luego no funcionaba.
Descargados los fuentes nos tenemos que instalar ciertas cosillas:
# apt-get install libparted-dev uuid-dev

Si ahora intentáis compilar no os va a funcionar porque el módulo está pensado para el libparted de fedora, que tiene algunos "maquillajes" que, se supone, vienen en los libparted más nuevos (realmente la 1.7 de Debian es antiquísima), nosotros cambiaremos lo siguiente (abrid como admins el archivo /usr/include/parted/disk.h):

typedef enum {
        PED_PARTITION_NORMAL            = 0x00,
        PED_PARTITION_LOGICAL           = 0x01,
        PED_PARTITION_EXTENDED          = 0x02,
        PED_PARTITION_FREESPACE         = 0x04,
        PED_PARTITION_METADATA          = 0x08
} PedPartitionType;

Lo cambiaremos por:

typedef enum {
        PED_PARTITION_NORMAL            = 0x00,
        PED_PARTITION_LOGICAL           = 0x01,
        PED_PARTITION_EXTENDED          = 0x02,
        PED_PARTITION_FREESPACE         = 0x04,
        PED_PARTITION_METADATA          = 0x08,
        PED_PARTITION_PROTECTED         = 0x10
} PedPartitionType;

...y ahora sí, a compilar:
:~$ unp pyparted-1.8.1.tar.gz
~$ cd pyparted-1.8.1
~/pyparted-1.8.1$ ./configure
~/pyparted-1.8.1$ make && sudo make install

Ejemplos de uso

Para probar el módulo vamos a usar ipython, si no lo tenéis ya sabéis: apt-get o aptitude. Y una cosa más: hay que ejecutarlo en modo superusuario porque si no no podréis abrir los dispositivos de escritura. En los ejemplos vamos a usar un pendrive direccionado en /dev/sda. TENED CUIDADO POR SI VUESTRO DISCO PRINCIPAL ES SATA QUE ENTONCES SERÁ /dev/sda. Si queréis hacer las pruebas con un pendrive comprobad con dmesg el nombre del dispositivo. Y una cosa más: si gnome os automonta la unidad, debéis desmontarla primero.

Al tajo, ejecutamos ipython:

$ sudo ipython
Total number of aliases: 15
Python 2.4.4 (#2, Aug 16 2007, 02:03:40)
Type "copyright", "credits" or "license" for more information.
IPython 0.8.1 -- An enhanced Interactive Python.
? -> Introduction to IPython's features.
%magic -> Information about IPython's 'magic' % functions.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.
In [1]:

y ahora abrimos la unidad, para ello debemos crear un PedDevice que gestione el dispositivo y con el PedDevice podremos crear un PedDisk que es el objeto que nos permitirá gestionar las particiones, lo haremos todo de una:
In [1]:import parted
In [2]:myDisk = parted.PedDisk.new(parted.PedDevice.get('/dev/sda'))

Para acceder al dispositivo (por ejemplo para obligar a realizar un open(), un close() o un sync()) podemos usar el atributo de clase dev:
In [3]:myDisk.dev.open()

A lo que vamos: leer la información de las particiones. Podemos ver cuántas particiones tenemos y luego recorrer una a una la lista. Hasta lo que creo, no hay un iterador bonico para ello, supongo que en versiones más nuevas ya estará añadido.
In [4]:myDisk.get_last_partition_num()
Out[4]:1
In [5]:partition = myDisk.get_partition(1)
In [6]:partition.type_name
Out[6]:'primary'
In [7]:geometria = partition.geom
In [8]:geom2 = geometria.duplicate()
In [9]:print geometria.start, geometria.end
19 63359

Ahora vamos a hacer cosas divertidas, OJO QUE ESTO ES PELIGROSO, empezamos borrando TODAS las particiones:
In [10]:myDisk.delete_all()
In [11]:print myDisk.get_partition(1).geom.start
---------------------------------------------------------------------------
parted.error Traceback (most recent call last)
/home/tobias/pyparted-1.7.3/<ipython console>
error: partition not found

Ahora, para crear una partición, necesitamos: un tipo (primaria, secundaria, etc.), un sector inicial y una longitud. Esta partición va dentro de unos límites, que pueden ser el disco físico o una partición extendida, esos límites los definimos al añadir la partición al disco, pero no al crearla:

In [12]:myPartition=myDisk.partition_new(parted.PARTITION_PRIMARY,None,1,4000)

El None es el filesystem que llevará la partición, podemos establecerlo en la creación, o a posteriori (como el resto de parámetros):

In [13]:myFs = parted.file_system_type_get('fat32')
In [14]:myPartition.set_system(myFs)

Ahora añadimos la partición al disco, dentro de unos límites, es este caso es todo el disco físico:

In [14]:entireDisk = parted.PedDevice.get('/dev/sda').constraint_any()
In [15]:myDisk.add_partition(myPartition, entireDisk)
In [16]:myDisk.commit()
Out[16]:1

Ese 1 indica que todo ha ido bien, ahora podemos comprobar con fdisk los destrozos causados Sticking out tongue...

Usando el completion de ipython podemos encontrar muchos métodos interesantes para cálculo de sectores físicos/lógicos, maximización de particiones, etc. De todas formas os puede ser útil la API de libparted. Para haceros una idea. Por último sólo aclarar que esta receta no va sobre un programa para crear/borrar particiones, para eso tenemos gparted, aquí sólo hemos explicado un poquillo cómo usar los métodos del módulo pyparted por si queréis hacer programillas y tal... Eye-wink

Enlaces

Ya están por la receta... Sticking out tongue

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de oscarah

Muy chula

Muy chula la receta. Ya se me están ocurriendo utilidades varias... ¡muchas gracias! Eye-wink

________________________________________________
La "S" de "CRySoL" es de "Software" no de "Salsa-rosa".
La "L" de "CRySoL" es de "Libre" no de "Linux".

"aviso: la dereferencia de punteros de tipo castigado romperá las reglas de alias estricto" --GCC 4.3.1

Imagen de david.villa

como por ejemplo

como por ejemplo el partitiontable_inspector?

No soy portavoz de ningún colectivo, grupo o facción. Mi opinión es personal e intransferible.

Imagen de oscarah

jajajaja

a veces me das miedo... Sticking out tongue

PD: con cairo seguro que queda chulísimo!
________________________________________________
La "S" de "CRySoL" es de "Software" no de "Salsa-rosa".
La "L" de "CRySoL" es de "Libre" no de "Linux".

"aviso: la dereferencia de punteros de tipo castigado romperá las reglas de alias estricto" --GCC 4.3.1