Re: python (parted) question
[ Please CC replies, I'm not subscribed to either list ]
[ d-python: this is a restatement of my previous question. Hope its ]
[ clearer this time. ]
I posed this question several days ago and received no response. mdz
(correctly) nudged me with a cluestick by telling me that perhaps I should
be more specific in describing my problem. So here goes... I'm no python
hacker, so maybe I'm missing something obvious.
I have attached part of a script (python_parted). It is intended to
partition a disk drive. I have edited out much of the script before and
after the problem section (such as reading in config files, etc) so that
the size is manageable, if you want the complete script refer to the
'autoinstall' package in Debian unstable. (I believe the included section
completely describes the problem.) I have also attached the partition.py
module which is loaded by this script. All other modules should be
standard... available from either the python or python-parted packages
in
Debian unstable.
My problem occurs at line 101 of python_parted, that reads:
drvnewpart = drvdisk.get_partition(drvpartnum)
The get_partition function is defined by the parted module, and always
returns 'None' when I call it. I have stepped through line-by-line and
every other value appears to be correct up to that point.
get_partition is as follows:
def get_partition(self, num):
"""Returns the partition numbered num.
"""
r = _parted.disk_get_partition(self._o, num)
if r:
return Partition(self, None, None, None, None, r)
else:
return None
and the corresponding C call which accesses libparted:
static PyObject *
disk_get_partition(PyObject *self, PyObject *args)
{
PyPartedObject *o;
int num;
if (!PyArg_ParseTuple(args, "Oi", &o, &num))
return NULL;
return PyPartedObject_new("PedPartition",
ped_disk_get_partition((PedDisk *)o->obj,
num));
}
This same code worked with libparted1.4, and broke at the 1.6 upgrade.
I'm not sure if the problem is in libparted, python-parted, or user-error.
I'm perfectly willing to accept the latter, but I hope to find a solution
anyway. :)
Is anyone else out there even using python-parted? There doesn't seem to
be much info about it...
Thanks,
--
Paul Telford | 1024D/431B38BA | pxt@debian.org | paul@droflet.net
C903 0E85 9AF5 1B80 6A5F F169 D7E9 4363 431B 38BA
#!/usr/bin/python -i
import sys
import os
import popen2
import stat
import traceback
import signal
import string
import time
import copy
import parted
# Arch-specific modules
import partition
try:
drvlist = []
parted.init()
parted.device_probe_all()
print "Examining drives..."
try:
drvinstlist = [parted.get_devices()[0]]
except:
print "No available drives found!"
killsystem()
bootdrv = ""
for drv in drvinstlist:
if not bootdrv:
bootdrv = drv.get_path()
drvdisk = drv.disk_open()
if drvdisk is not None:
partlist = drvdisk.get_part_list()
isdata = 0
for part in partlist:
if part.get_type() != parted.PARTITION_FREESPACE:
isdata = 1
drvdisk.close()
# Partition and format drive.
for drv in drvinstlist:
print "Partitioning drive %s..." % drv.get_path()
drvobj = partition.Partition(drv)
drvsectors = drv.get_length()
drvobj.create_partition_table()
partabssect = 0
# for reference, partcfg at this point looks like:
# [['ext2', '80%', '/', ['primary']], ['swap', '256M', 'swap', ['primary']]]
for partinfo in partcfg:
if partinfo[2] == "/":
rootpart = partinfo
partsizetype = string.upper(partinfo[1][-1])
if partsizetype == "M":
partsize = string.atoi(partinfo[1][:-1])
partsect = int(float(partsize) * 1024 * 1024 / parted.SECTOR_SIZE)
partabssect = partabssect + partsect
elif partsizetype != "%":
raise RuntimeError, "invalid partition size specifier"
partremsect = drvsectors - partabssect - curpartend
for (partfs, partsizestr, partmount, parthints) in partcfg:
print "Creating %s partition for %s..." % (partfs, partmount)
partsizetype = string.upper(partsizestr[-1])
partsize = string.atoi(partsizestr[:-1])
if partfs == "swap":
partfs = "linux-swap"
partfstype = parted.file_system_type_get(partfs)
if partsizetype == "%":
partsect = int(partremsect * (float(partsize) / 100))
else:
partsect = int(float(partsize) * 1024 * 1024 / parted.SECTOR_SIZE)
partdevice = drvobj.create_partition(curpartend,
curpartend + partsect - 1,
partfstype, parthints)
mountlist.append([partdevice, partmount, partfs])
curpartend = curpartend + partsect
drvobj.commit_changes()
drvdisk = drv.disk_open()
for (partdevice, partmount, partfs) in mountlist:
print "Creating %s file system on %s..." % (partfs, partdevice)
drvpartnumstr = partdevice[-2:]
if drvpartnumstr[0] not in string.digits:
drvpartnumstr = drvpartnumstr[1]
drvpartnum = string.atoi(drvpartnumstr)
partfstype = parted.file_system_type_get(partfs)
drvnewpart = drvdisk.get_partition(drvpartnum)
parted.FileSystem(drvnewpart.get_geom(), partfstype).close()
drvdisk.close()
drv.close()
# Since we're done with partitioning, we can call this now. This
# ensures that the partition table is reread by the system. It's
# important not to call parted for anything after this.
parted.done()
# Autoinstaller partition code for MS-DOS style partitions.
# Copyright (c) 2001 Progeny Linux Systems, Inc.
# Written by Jeff Licquia.
# This module assumes that the parted subsystem has already been
# initialized fully; it simply stands in for certain calls that may be
# different for different partition types.
# from python-parted package
import parted
class Partition:
def __init__(self, drive):
self.drive = drive
self.disk = None
self.primarynum = 0
self.extnum = 0
self.isext = 0
def get_freespace(self):
if self.disk is None:
self.disk = self.drive.disk_open()
if self.disk is not None:
freelist = []
partlist = self.disk.get_part_list()
for part in partlist:
partnum = part.get_num()
if part.get_type() == parted.PED_PARTITION_PRIMARY:
self.primarynum = partnum + 1
elif part.get_type() == parted.PED_PARTITION_EXTENDED:
self.extnum = partnum + 1
elif part.get_type() == parted.PED_PARTITION_LOGICAL:
self.isext = 1
elif part.get_type() == parted.PED_PARTITION_FREESPACE:
freelist.append([part.get_geom().get_start(),
part.get_geom().get_end()])
if not self.primarynum:
if self.isext:
self.primarynum = 2
else:
self.primarynum = 1
if not self.extnum:
self.extnum = 5
return freelist
else:
return None
def create_partition_table(self):
self.primarynum = 1
self.extnum = 5
self.isext = 0
self.disk = self.drive.disk_create(parted.disk_type_get("msdos"))
return self.get_freespace()
def create_partition(self, start, end, type, hints):
drvsectors = self.drive.get_length()
if self.disk is None:
self.disk = self.drive.disk_open()
if self.disk is None:
raise RuntimeError, "drive has no partition table"
if "primary" in hints:
if self.primarynum > 4:
raise RuntimeError, "out of primary partitions"
if self.isext:
raise RuntimeError, "cannot create primary partition after extended partition"
partnum = self.primarynum
self.primarynum = self.primarynum + 1
parttypecode = parted.PED_PARTITION_PRIMARY
else:
if not self.isext:
if self.primarynum > 4:
raise RuntimeError, "out of slots for extended partition"
self.disk.add_partition(
parted.Partition(self.disk,
parted.PED_PARTITION_EXTENDED,
None, start, drvsectors - 1))
self.primarynum = self.primarynum + 1
self.isext = 1
partnum = self.extnum
self.extnum = self.extnum + 1
parttypecode = parted.PED_PARTITION_LOGICAL
drvnewpart = parted.Partition(self.disk, parttypecode, type,
start, end)
self.disk.add_partition(drvnewpart)
partdevice = "%s%d" % (self.drive.get_path(), partnum)
return partdevice
def commit_changes(self):
if self.disk is not None:
self.disk.write()
self.disk.close()
self.disk = None
self.drive.sync()
Reply to: