add (possible) config partition to 'partition' plugin
This commit is contained in:
parent
1c8db28989
commit
3cc64e84f3
9 changed files with 257 additions and 48 deletions
|
@ -100,7 +100,6 @@ class CryptoBox:
|
||||||
self.log.info(string)
|
self.log.info(string)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# RFC: why should CryptoBoxProps inherit CryptoBox? [l]
|
# RFC: why should CryptoBoxProps inherit CryptoBox? [l]
|
||||||
# RFC: shouldn't we move all useful functions of CryptoBoxProps to CryptoBox? [l]
|
# RFC: shouldn't we move all useful functions of CryptoBoxProps to CryptoBox? [l]
|
||||||
class CryptoBoxProps(CryptoBox):
|
class CryptoBoxProps(CryptoBox):
|
||||||
|
@ -119,12 +118,27 @@ class CryptoBoxProps(CryptoBox):
|
||||||
def reReadContainerList(self):
|
def reReadContainerList(self):
|
||||||
self.containers = []
|
self.containers = []
|
||||||
for device in CryptoBoxTools.getAvailablePartitions():
|
for device in CryptoBoxTools.getAvailablePartitions():
|
||||||
if self.isDeviceAllowed(device):
|
if self.isDeviceAllowed(device) and not self.isConfigPartition(device):
|
||||||
self.containers.append(CryptoBoxContainer.CryptoBoxContainer(device, self))
|
self.containers.append(CryptoBoxContainer.CryptoBoxContainer(device, self))
|
||||||
## sort by container name
|
## sort by container name
|
||||||
self.containers.sort(cmp = lambda x,y: x.getName() < y.getName() and -1 or 1)
|
self.containers.sort(cmp = lambda x,y: x.getName() < y.getName() and -1 or 1)
|
||||||
|
|
||||||
|
|
||||||
|
def isConfigPartition(self, device):
|
||||||
|
import subprocess
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
shell = False,
|
||||||
|
stdout = subprocess.PIPE,
|
||||||
|
args = [
|
||||||
|
self.prefs["Programs"]["blkid"],
|
||||||
|
"-c", os.path.devnull,
|
||||||
|
"-o", "value",
|
||||||
|
"-s", "LABEL",
|
||||||
|
device])
|
||||||
|
(output, error) = proc.communicate()
|
||||||
|
return output.strip() == self.prefs["Main"]["ConfigVolumeLabel"]
|
||||||
|
|
||||||
|
|
||||||
def isDeviceAllowed(self, devicename):
|
def isDeviceAllowed(self, devicename):
|
||||||
"check if a device is white-listed for being used as cryptobox containers"
|
"check if a device is white-listed for being used as cryptobox containers"
|
||||||
import types
|
import types
|
||||||
|
|
|
@ -164,6 +164,7 @@ class CryptoBoxSettings:
|
||||||
AllowedDevices = list(min=1)
|
AllowedDevices = list(min=1)
|
||||||
DefaultVolumePrefix = string(min=1)
|
DefaultVolumePrefix = string(min=1)
|
||||||
DefaultCipher = string(default="aes-cbc-essiv:sha256")
|
DefaultCipher = string(default="aes-cbc-essiv:sha256")
|
||||||
|
ConfigVolumeLabel = string(min=1,default="cbox_config")
|
||||||
|
|
||||||
[Locations]
|
[Locations]
|
||||||
MountParentDir = directoryExists(default="/var/cache/cryptobox/mnt")
|
MountParentDir = directoryExists(default="/var/cache/cryptobox/mnt")
|
||||||
|
@ -186,7 +187,6 @@ DocLanguage = string(min=1, default="en")
|
||||||
[Programs]
|
[Programs]
|
||||||
cryptsetup = fileExecutable(default="/sbin/cryptsetup")
|
cryptsetup = fileExecutable(default="/sbin/cryptsetup")
|
||||||
mkfs-data = fileExecutable(default="/sbin/mkfs.ext3")
|
mkfs-data = fileExecutable(default="/sbin/mkfs.ext3")
|
||||||
mkfs-config = fileExecutable(default="/sbin/mkfs.ext2")
|
|
||||||
blkid = fileExecutable(default="/sbin/blkid")
|
blkid = fileExecutable(default="/sbin/blkid")
|
||||||
mount = fileExecutable(default="/bin/mount")
|
mount = fileExecutable(default="/bin/mount")
|
||||||
umount = fileExecutable(default="/bin/umount")
|
umount = fileExecutable(default="/bin/umount")
|
||||||
|
|
|
@ -4,12 +4,16 @@
|
||||||
# beware: .e.g "/dev/hd" grants access to _all_ harddisks
|
# beware: .e.g "/dev/hd" grants access to _all_ harddisks
|
||||||
AllowedDevices = /dev/loop
|
AllowedDevices = /dev/loop
|
||||||
|
|
||||||
|
|
||||||
# the default name prefix of not unnamed containers
|
# the default name prefix of not unnamed containers
|
||||||
DefaultVolumePrefix = "Data "
|
DefaultVolumePrefix = "Data "
|
||||||
|
|
||||||
# which cipher should cryptsetup-luks use?
|
# which cipher should cryptsetup-luks use?
|
||||||
DefaultCipher = aes-cbc-essiv:sha256
|
DefaultCipher = aes-cbc-essiv:sha256
|
||||||
|
|
||||||
|
# label of the configuration partition (you should never change this)
|
||||||
|
ConfigVolumeLabel = cbox_config
|
||||||
|
|
||||||
|
|
||||||
[Locations]
|
[Locations]
|
||||||
# where should we mount volumes?
|
# where should we mount volumes?
|
||||||
|
@ -70,7 +74,6 @@ DocLanguage = de
|
||||||
[Programs]
|
[Programs]
|
||||||
cryptsetup = /sbin/cryptsetup
|
cryptsetup = /sbin/cryptsetup
|
||||||
mkfs-data = /sbin/mkfs.ext3
|
mkfs-data = /sbin/mkfs.ext3
|
||||||
mkfs-config = /sbin/mkfs.ext2
|
|
||||||
blkid = /sbin/blkid
|
blkid = /sbin/blkid
|
||||||
mount = /bin/mount
|
mount = /bin/mount
|
||||||
umount = /bin/umount
|
umount = /bin/umount
|
||||||
|
|
|
@ -5,4 +5,7 @@
|
||||||
|
|
||||||
<input type="hidden" name="block_device" value="<?cs var:html_escape(Data.Plugins.partition.Device) ?>" />
|
<input type="hidden" name="block_device" value="<?cs var:html_escape(Data.Plugins.partition.Device) ?>" />
|
||||||
|
|
||||||
|
<?cs if:Data.Plugins.partition.CreateConfigPartition ?>
|
||||||
|
<input type="hidden" name="create_config_partition" value="1" />
|
||||||
|
<?cs /if ?>
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,23 @@ WarningMessage {
|
||||||
Text = The partitioning of the device failed for some reason - sorry!
|
Text = The partitioning of the device failed for some reason - sorry!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FormattingFailed {
|
||||||
|
Title = Formatting failed
|
||||||
|
Text = The formatting of the filesystems of the device failed - sorry!
|
||||||
|
}
|
||||||
|
|
||||||
DiskIsBusy {
|
DiskIsBusy {
|
||||||
Title = This disk is busy
|
Title = This disk is busy
|
||||||
Text = Please deactivate all containers of this disk before partitioning.
|
Text = Please deactivate all containers of this disk before partitioning.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PartitionTooBig {
|
||||||
|
Title = Invalid size
|
||||||
|
Text = The container size you entered exceeded the available size of the disk.
|
||||||
|
}
|
||||||
|
|
||||||
|
PartitionTooSmall {
|
||||||
|
Title = Invalid size
|
||||||
|
Text = The minimum size of a container is 10 megabytes.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
import re
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import imp
|
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
import CryptoBoxTools
|
import CryptoBoxTools
|
||||||
|
|
||||||
PartTypes = {
|
PartTypes = {
|
||||||
"linux" : "L",
|
"windows" : ["0xC", "vfat"],
|
||||||
"windows" : "0xC"}
|
"linux" : ["L", "ext3"]}
|
||||||
|
|
||||||
|
ConfigPartition = {
|
||||||
|
"size" : 5, # size of configuration partition (if necessary) in MB
|
||||||
|
"type" : "L",
|
||||||
|
"fs" : "ext2"}
|
||||||
|
|
||||||
logger = logging.getLogger("CryptoBox")
|
logger = logging.getLogger("CryptoBox")
|
||||||
|
|
||||||
|
|
||||||
def doAction(hdf, cbox, **args):
|
def doAction(hdf, cbox, **args):
|
||||||
try:
|
try:
|
||||||
step = args["step"]
|
step = args["step"]
|
||||||
|
@ -32,7 +36,6 @@ def getStatus(cbox):
|
||||||
|
|
||||||
|
|
||||||
def __isDeviceValid(device, cbox):
|
def __isDeviceValid(device, cbox):
|
||||||
## TODO: also check for "is device busy" add output a warning
|
|
||||||
if not cbox.isDeviceAllowed(device):
|
if not cbox.isDeviceAllowed(device):
|
||||||
return False
|
return False
|
||||||
if not device in CryptoBoxTools.getParentBlockDevices():
|
if not device in CryptoBoxTools.getParentBlockDevices():
|
||||||
|
@ -42,6 +45,8 @@ def __isDeviceValid(device, cbox):
|
||||||
|
|
||||||
def __isDeviceBusy(device, cbox):
|
def __isDeviceBusy(device, cbox):
|
||||||
"""check if the device (or one of its partitions) is mounted"""
|
"""check if the device (or one of its partitions) is mounted"""
|
||||||
|
# TODO: the config partition is ignored, as it is not part of the container list - that is not good
|
||||||
|
import re
|
||||||
for c in cbox.getContainerList():
|
for c in cbox.getContainerList():
|
||||||
if re.match(device + "\d*$", c.getDevice()):
|
if re.match(device + "\d*$", c.getDevice()):
|
||||||
if c.isMounted(): return True
|
if c.isMounted(): return True
|
||||||
|
@ -57,6 +62,8 @@ def __actionSelectDevice(hdf, cbox, args):
|
||||||
hdf["Data.Plugins.partition.BlockDevices.%d" % counter] = a
|
hdf["Data.Plugins.partition.BlockDevices.%d" % counter] = a
|
||||||
cbox.log.debug("found a suitable block device: %s" % a)
|
cbox.log.debug("found a suitable block device: %s" % a)
|
||||||
counter += 1
|
counter += 1
|
||||||
|
if __withConfigPartition(args):
|
||||||
|
hdf["Data.Plugins.partition.CreateConfigPartition"] = "1"
|
||||||
## there is no disk available
|
## there is no disk available
|
||||||
if not block_devices:
|
if not block_devices:
|
||||||
hdf["Data.Warning"] = "Plugins.partition.NoDisksAvailable"
|
hdf["Data.Warning"] = "Plugins.partition.NoDisksAvailable"
|
||||||
|
@ -72,11 +79,11 @@ def __actionAddPartition(hdf, cbox, args):
|
||||||
if __isDeviceBusy(device, cbox):
|
if __isDeviceBusy(device, cbox):
|
||||||
hdf["Data.Warning"] = "Plugins.partition.DiskIsBusy"
|
hdf["Data.Warning"] = "Plugins.partition.DiskIsBusy"
|
||||||
return __actionSelectDevice(hdf, cbox, args)
|
return __actionSelectDevice(hdf, cbox, args)
|
||||||
size = __getDeviceSize(device)
|
size = __getAvailableDeviceSize(device, __withConfigPartition(args))
|
||||||
hdf["Data.Plugins.partition.Device"] = device
|
hdf["Data.Plugins.partition.Device"] = device
|
||||||
hdf["Data.Plugins.partition.Device.Size"] = size
|
hdf["Data.Plugins.partition.Device.Size"] = size
|
||||||
parts = __getPartitionsFromArgs(args, size)
|
parts = __getPartitionsFromArgs(hdf, args, size)
|
||||||
__setPartitionData(hdf, parts, size)
|
__setPartitionData(hdf, parts, size, __withConfigPartition(args))
|
||||||
return "set_partitions"
|
return "set_partitions"
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,16 +97,16 @@ def __actionDelPartition(hdf, cbox, args):
|
||||||
if __isDeviceBusy(device, cbox):
|
if __isDeviceBusy(device, cbox):
|
||||||
hdf["Data.Warning"] = "Plugins.partition.DiskIsBusy"
|
hdf["Data.Warning"] = "Plugins.partition.DiskIsBusy"
|
||||||
return __actionSelectDevice(hdf, cbox, args)
|
return __actionSelectDevice(hdf, cbox, args)
|
||||||
size = __getDeviceSize(device)
|
size = __getAvailableDeviceSize(device, __withConfigPartition(args))
|
||||||
hdf["Data.Plugins.partition.Device"] = device
|
hdf["Data.Plugins.partition.Device"] = device
|
||||||
hdf["Data.Plugins.partition.Device.Size"] = size
|
hdf["Data.Plugins.partition.Device.Size"] = size
|
||||||
parts = __getPartitionsFromArgs(args, size)
|
parts = __getPartitionsFromArgs(hdf, args, size)
|
||||||
## valid partition number to be deleted?
|
## valid partition number to be deleted?
|
||||||
if part_num < len(parts):
|
if part_num < len(parts):
|
||||||
del parts[part_num]
|
del parts[part_num]
|
||||||
else:
|
else:
|
||||||
return __actionSelectDevice(hdf, cbox, args)
|
return __actionSelectDevice(hdf, cbox, args)
|
||||||
__setPartitionData(hdf, parts, size)
|
__setPartitionData(hdf, parts, size, __withConfigPartition(args))
|
||||||
return "set_partitions"
|
return "set_partitions"
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,21 +119,24 @@ def __actionFinish(hdf, cbox, args):
|
||||||
if __isDeviceBusy(device, cbox):
|
if __isDeviceBusy(device, cbox):
|
||||||
hdf["Data.Warning"] = "Plugins.partition.DiskIsBusy"
|
hdf["Data.Warning"] = "Plugins.partition.DiskIsBusy"
|
||||||
return __actionSelectDevice(hdf, cbox, args)
|
return __actionSelectDevice(hdf, cbox, args)
|
||||||
size = __getDeviceSize(device)
|
size = __getAvailableDeviceSize(device, __withConfigPartition(args))
|
||||||
parts = __getPartitionsFromArgs(args, size)
|
parts = __getPartitionsFromArgs(hdf, args, size)
|
||||||
if parts:
|
if parts:
|
||||||
if not __runFDisk(cbox, device, parts):
|
if not __runFDisk(cbox, device, parts, __withConfigPartition(args)):
|
||||||
hdf["Data.Warning"] = "Plugins.partition.PartitioningFailed"
|
hdf["Data.Warning"] = "Plugins.partition.PartitioningFailed"
|
||||||
return __actionAddPartition(hdf, cbox, args)
|
return __actionAddPartition(hdf, cbox, args)
|
||||||
else:
|
else:
|
||||||
hdf["Data.Success"] = "Plugins.partition.Partitioned"
|
if __formatPartitions(cbox, device, parts, __withConfigPartition(args)):
|
||||||
|
hdf["Data.Success"] = "Plugins.partition.Partitioned"
|
||||||
|
else:
|
||||||
|
hdf["Data.Warning"] = "Plugins.partition.FormattingFailed"
|
||||||
cbox.reReadContainerList()
|
cbox.reReadContainerList()
|
||||||
return "form_system"
|
return "form_system"
|
||||||
else:
|
else:
|
||||||
return __actionSelectDevice(hdf, cbox, args)
|
return __actionSelectDevice(hdf, cbox, args)
|
||||||
|
|
||||||
|
|
||||||
def __setPartitionData(hdf, parts, size):
|
def __setPartitionData(hdf, parts, size, withConfigPartition):
|
||||||
availSize = size
|
availSize = size
|
||||||
i = 0
|
i = 0
|
||||||
for part in parts:
|
for part in parts:
|
||||||
|
@ -136,11 +146,13 @@ def __setPartitionData(hdf, parts, size):
|
||||||
availSize -= part["size"]
|
availSize -= part["size"]
|
||||||
i += 1
|
i += 1
|
||||||
hdf["Data.Plugins.partition.availSize"] = availSize
|
hdf["Data.Plugins.partition.availSize"] = availSize
|
||||||
|
if withConfigPartition:
|
||||||
|
hdf["Data.Plugins.partition.CreateConfigPartition"] = "1"
|
||||||
for t in PartTypes.keys():
|
for t in PartTypes.keys():
|
||||||
hdf["Data.Plugins.partition.Types.%s" % t] = t
|
hdf["Data.Plugins.partition.Types.%s" % t] = t
|
||||||
|
|
||||||
|
|
||||||
def __getPartitionsFromArgs(args, maxSize):
|
def __getPartitionsFromArgs(hdf, args, maxSize):
|
||||||
parts = []
|
parts = []
|
||||||
done = False
|
done = False
|
||||||
availSize = maxSize
|
availSize = maxSize
|
||||||
|
@ -150,8 +162,12 @@ def __getPartitionsFromArgs(args, maxSize):
|
||||||
try:
|
try:
|
||||||
size = int(args["part%d_size" % i])
|
size = int(args["part%d_size" % i])
|
||||||
partType = args["part%d_type" % i]
|
partType = args["part%d_type" % i]
|
||||||
if int(size) > availSize: continue
|
if int(size) > availSize:
|
||||||
if int(size) <= 0: continue
|
hdf["Data.Warning"] = "Plugins.partition.PartitionTooBig"
|
||||||
|
continue
|
||||||
|
if int(size) < 10:
|
||||||
|
hdf["Data.Warning"] = "Plugins.partition.PartitionTooSmall"
|
||||||
|
continue
|
||||||
if not partType in PartTypes.keys(): continue
|
if not partType in PartTypes.keys(): continue
|
||||||
parts.append({"size":size, "type":partType})
|
parts.append({"size":size, "type":partType})
|
||||||
availSize -= size
|
availSize -= size
|
||||||
|
@ -162,7 +178,9 @@ def __getPartitionsFromArgs(args, maxSize):
|
||||||
return parts
|
return parts
|
||||||
|
|
||||||
|
|
||||||
def __getDeviceSize(device):
|
def __getAvailableDeviceSize(device, withConfigPartition):
|
||||||
|
"""calculate the available size (MB) of the device
|
||||||
|
also consider a (possible) configuration partition"""
|
||||||
rdev = os.stat(device).st_rdev
|
rdev = os.stat(device).st_rdev
|
||||||
minor = os.minor(rdev)
|
minor = os.minor(rdev)
|
||||||
major = os.major(rdev)
|
major = os.major(rdev)
|
||||||
|
@ -171,16 +189,34 @@ def __getDeviceSize(device):
|
||||||
elements = f.split()
|
elements = f.split()
|
||||||
if len(elements) != 4: continue
|
if len(elements) != 4: continue
|
||||||
if (int(elements[0]) == major) and (int(elements[1]) == minor):
|
if (int(elements[0]) == major) and (int(elements[1]) == minor):
|
||||||
return int(elements[2])/1024
|
deviceSize = int(elements[2])/1024
|
||||||
|
if withConfigPartition: deviceSize -= ConfigPartition["size"]
|
||||||
|
return deviceSize
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def __runFDisk(cbox, device, parts):
|
def __withConfigPartition(args):
|
||||||
|
try:
|
||||||
|
if args["create_config_partition"]:
|
||||||
|
createConfig = True
|
||||||
|
else:
|
||||||
|
createConfig = False
|
||||||
|
except KeyError:
|
||||||
|
createConfig = False
|
||||||
|
return createConfig
|
||||||
|
|
||||||
|
|
||||||
|
def __runFDisk(cbox, device, parts, withConfigPartition):
|
||||||
|
## check if the device is completely filled (to avoid some empty last blocks)
|
||||||
|
avail_size = __getAvailableDeviceSize(device, withConfigPartition)
|
||||||
|
for d in parts: avail_size -= d["size"]
|
||||||
|
isFilled = avail_size == 0
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.Popen(
|
||||||
shell = False,
|
shell = False,
|
||||||
stdin = subprocess.PIPE,
|
stdin = subprocess.PIPE,
|
||||||
|
stdout = subprocess.PIPE,
|
||||||
stderr = subprocess.PIPE,
|
stderr = subprocess.PIPE,
|
||||||
args = [
|
args = [
|
||||||
cbox.prefs["Programs"]["super"],
|
cbox.prefs["Programs"]["super"],
|
||||||
|
@ -189,23 +225,123 @@ def __runFDisk(cbox, device, parts):
|
||||||
os.path.join(os.path.dirname(__file__), "root_action.py"),
|
os.path.join(os.path.dirname(__file__), "root_action.py"),
|
||||||
"partition",
|
"partition",
|
||||||
device])
|
device])
|
||||||
import logging
|
for line in __getSFDiskLayout(parts, withConfigPartition, isFilled):
|
||||||
logger = logging.getLogger("CryptoBox")
|
proc.stdin.write(line + "\n")
|
||||||
for line in __getSFDiskLayout(parts): proc.stdin.write(line + "\n")
|
|
||||||
(output, error) = proc.communicate()
|
(output, error) = proc.communicate()
|
||||||
if error: logger.debug("partitioning failed: %s" % error)
|
if proc.returncode != 0: logger.debug("partitioning failed: %s" % error)
|
||||||
return proc.returncode == 0
|
return proc.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
def __getSFDiskLayout(paramParts):
|
def __getSFDiskLayout(paramParts, withConfigPartition, isFilled):
|
||||||
parts = paramParts[:]
|
parts = paramParts[:]
|
||||||
## first a primary partition
|
## first a (possible) configuration partition - so it will be reusable
|
||||||
yield ",%d,%s,*" % (parts[0]["size"], PartTypes[parts[0]["type"]])
|
if withConfigPartition:
|
||||||
|
## fill the main table (including a config partition)
|
||||||
|
yield ",%d,%s" % (ConfigPartition["size"], ConfigPartition["type"])
|
||||||
|
## one primary partition
|
||||||
|
yield ",%d,%s,*" % (parts[0]["size"], PartTypes[parts[0]["type"]][0])
|
||||||
del parts[0]
|
del parts[0]
|
||||||
|
## no extended partition, if there is only one disk
|
||||||
if not parts: return
|
if not parts: return
|
||||||
yield ",,E" # extended container for the rest
|
## an extended container for the rest
|
||||||
yield ";" # empty partition in main table
|
yield ",,E"
|
||||||
yield ";" # another empty partition in main table
|
## an empty partition in main table
|
||||||
|
yield ";"
|
||||||
|
## maybe another empty partition if there is no config partition
|
||||||
|
if not withConfigPartition: yield ";"
|
||||||
while parts:
|
while parts:
|
||||||
yield ",%d,%s" % (parts[0]["size"], PartTypes[parts[0]["type"]])
|
if isFilled and (len(parts) == 1):
|
||||||
|
yield ",,%s" % (PartTypes[parts[0]["type"]][0],)
|
||||||
|
else:
|
||||||
|
yield ",%d,%s" % (parts[0]["size"], PartTypes[parts[0]["type"]][0])
|
||||||
del parts[0]
|
del parts[0]
|
||||||
|
|
||||||
|
|
||||||
|
def __formatPartitions(cbox, device, paramParts, withConfigPartition):
|
||||||
|
success = True
|
||||||
|
parts = paramParts[:]
|
||||||
|
part_num = 1
|
||||||
|
## maybe a config partition?
|
||||||
|
if withConfigPartition:
|
||||||
|
dev_name = device + str(part_num)
|
||||||
|
logger.info("formatting config partition (%s)" % dev_name)
|
||||||
|
if __formatOnePartition(cbox, dev_name, ConfigPartition["fs"]):
|
||||||
|
__setLabelOfPartition(cbox, dev_name, cbox.prefs["Main"]["ConfigVolumeLabel"])
|
||||||
|
else:
|
||||||
|
success = False
|
||||||
|
part_num += 1
|
||||||
|
## the first data partition
|
||||||
|
dev_name = device + str(part_num)
|
||||||
|
partType = PartTypes[parts[0]["type"]][1]
|
||||||
|
logger.info("formatting partition (%s) as '%s'" % (dev_name, partType))
|
||||||
|
if not __formatOnePartition(cbox, dev_name, partType):
|
||||||
|
success = False
|
||||||
|
del parts[0]
|
||||||
|
## other data partitions
|
||||||
|
part_num = 5
|
||||||
|
while parts:
|
||||||
|
dev_name = device + str(part_num)
|
||||||
|
partType = PartTypes[parts[0]["type"]][1]
|
||||||
|
logger.info("formatting partition (%s) as '%s'" % (dev_name, partType))
|
||||||
|
if not __formatOnePartition(cbox, dev_name, partType):
|
||||||
|
success = False
|
||||||
|
part_num += 1
|
||||||
|
del parts[0]
|
||||||
|
return success
|
||||||
|
|
||||||
|
|
||||||
|
def __formatOnePartition(cbox, dev_name, type):
|
||||||
|
import time, sys
|
||||||
|
child_pid = os.fork()
|
||||||
|
## we run formatting as a parallel thread
|
||||||
|
## TODO: the parent thread still waits for the last child - that is not good for big harddisks
|
||||||
|
if child_pid == 0:
|
||||||
|
## we are the child process
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
shell = False,
|
||||||
|
stdout = subprocess.PIPE,
|
||||||
|
stderr = subprocess.PIPE,
|
||||||
|
args = [
|
||||||
|
cbox.prefs["Programs"]["super"],
|
||||||
|
cbox.prefs["Programs"]["CryptoBoxRootActions"],
|
||||||
|
"plugin",
|
||||||
|
os.path.join(os.path.dirname(__file__), "root_action.py"),
|
||||||
|
"format",
|
||||||
|
dev_name,
|
||||||
|
type])
|
||||||
|
(output, error) = proc.communicate()
|
||||||
|
if proc.returncode != 0:
|
||||||
|
logger.warn("failed to create filesystem on %s: %s" % (dev_name, error))
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
time.sleep(1)
|
||||||
|
(pid, exit_state) = os.waitpid(child_pid, os.WNOHANG)
|
||||||
|
if ((pid == 0) and (exit_state == 0)) \
|
||||||
|
or ((pid == child_pid) and (exit_state == 0)):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def __setLabelOfPartition(cbox, dev_name, label):
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
shell = False,
|
||||||
|
stdout = subprocess.PIPE,
|
||||||
|
stderr = subprocess.PIPE,
|
||||||
|
args = [
|
||||||
|
cbox.prefs["Programs"]["super"],
|
||||||
|
cbox.prefs["Programs"]["CryptoBoxRootActions"],
|
||||||
|
"plugin",
|
||||||
|
os.path.join(os.path.dirname(__file__), "root_action.py"),
|
||||||
|
"label",
|
||||||
|
dev_name,
|
||||||
|
label])
|
||||||
|
(output, error) = proc.communicate()
|
||||||
|
if proc.returncode == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.warn("failed to create filesystem on %s: %s" % (device + str(part_num), error))
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
PLUGIN_TYPE = "cryptobox"
|
PLUGIN_TYPE = "cryptobox"
|
||||||
|
|
||||||
SFDISK_BIN = "/sbin/sfdisk"
|
SFDISK_BIN = "/sbin/sfdisk"
|
||||||
|
MKFS_BIN = "/sbin/mkfs"
|
||||||
|
LABEL_BIN = "/sbin/e2label"
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import re
|
import re
|
||||||
|
@ -23,27 +25,55 @@ def __partitionDevice(device):
|
||||||
return proc.returncode == 0
|
return proc.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
|
def __formatPartition(device, type):
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
shell = False,
|
||||||
|
args = [
|
||||||
|
MKFS_BIN,
|
||||||
|
"-t", type,
|
||||||
|
device])
|
||||||
|
proc.communicate()
|
||||||
|
return proc.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
|
def __labelPartition(device, label):
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
shell = False,
|
||||||
|
args = [
|
||||||
|
LABEL_BIN,
|
||||||
|
device,
|
||||||
|
label])
|
||||||
|
proc.communicate()
|
||||||
|
return proc.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
args = sys.argv[1:]
|
args = sys.argv[1:]
|
||||||
|
|
||||||
self_bin =sys.argv[0]
|
self_bin =sys.argv[0]
|
||||||
|
|
||||||
if len(args) > 2:
|
|
||||||
sys.stderr.write("%s: too many arguments (%s)\n" % (self_bin, args))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if len(args) == 0:
|
if len(args) == 0:
|
||||||
sys.stderr.write("%s: no argument supplied\n" % self_bin)
|
sys.stderr.write("%s: no argument supplied\n" % self_bin)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if args[0] == "partition":
|
try:
|
||||||
if len(args) < 2:
|
if args[0] == "partition":
|
||||||
sys.stderr.write("%s: not enough arguments (%s)\n" % (self_bin, args))
|
if len(args) != 2: raise "InvalidArgNum"
|
||||||
|
result = __partitionDevice(args[1])
|
||||||
|
elif args[0] == "format":
|
||||||
|
if len(args) != 3: raise "InvalidArgNum"
|
||||||
|
result = __formatPartition(args[1], args[2])
|
||||||
|
elif args[0] == "label":
|
||||||
|
if len(args) != 3: raise "InvalidArgNum"
|
||||||
|
result = __labelPartition(args[1], args[2])
|
||||||
|
else:
|
||||||
|
sys.stderr.write("%s: invalid action (%s)\n" % (self_bin, args[0]))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
if __partitionDevice(args[1]):
|
if result:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
else:
|
else:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
except "InvalidArgNum":
|
||||||
|
sys.stderr.write("%s: invalid number of arguments (%s)\n" % (self_bin, args))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,13 @@
|
||||||
<?cs /each ?>
|
<?cs /each ?>
|
||||||
</select></p>
|
</select></p>
|
||||||
|
|
||||||
|
<p><label for="create_config_partition">Create configuration partition?</label><input type="checkbox" name="create_config_partition" value="1" id="create_config_partition" /></p>
|
||||||
|
<!--
|
||||||
|
<?cs if:Data.Plugins.partition.CreateConfigPartition ?>
|
||||||
|
<input type="hidden" name="create_config_partition" value="1" />
|
||||||
|
<?cs /if ?>
|
||||||
|
-->
|
||||||
|
|
||||||
<p class="note">
|
<p class="note">
|
||||||
<?cs var:html_escape(Lang.Plugins.partition.Text.WarningMessage) ?>
|
<?cs var:html_escape(Lang.Plugins.partition.Text.WarningMessage) ?>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -36,7 +36,8 @@
|
||||||
<?cs set: x = subcount(Data.Plugins.partition.Parts) ?>
|
<?cs set: x = subcount(Data.Plugins.partition.Parts) ?>
|
||||||
<td><?cs var:x ?></td>
|
<td><?cs var:x ?></td>
|
||||||
<td><input type="text" name="part<?cs var:x ?>_size" size="8" value="<?cs var:Data.Plugins.partition.availSize ?>" /></td>
|
<td><input type="text" name="part<?cs var:x ?>_size" size="8" value="<?cs var:Data.Plugins.partition.availSize ?>" /></td>
|
||||||
<td><select name="part<?cs var:x ?>_type" size="0"><?cs each: t = Data.Plugins.partition.Types ?><option><?cs var:t ?></option><?cs /each ?></select></td>
|
<td><select name="part<?cs var:x ?>_type" size="0"><?cs each: t = Data.Plugins.partition.Types ?><option <?cs if:t == "windows" ?>selected="selected"<?cs /if ?>><?cs var:t ?></option>
|
||||||
|
<?cs /each ?></select></td>
|
||||||
<td>
|
<td>
|
||||||
<button type="submit"><?cs var:html_escape(Lang.Plugins.partition.Button.AddPartition) ?></button>
|
<button type="submit"><?cs var:html_escape(Lang.Plugins.partition.Button.AddPartition) ?></button>
|
||||||
</td>
|
</td>
|
||||||
|
|
Loading…
Reference in a new issue