added gray disc icon for unitialized volumes
simple partitioning interface finished order in navigation bar changed ignore extended partitions (in container list)
This commit is contained in:
parent
665d18bdbd
commit
1c8db28989
16 changed files with 243 additions and 97 deletions
|
@ -6,9 +6,9 @@ Title.Partition = Disk partitions
|
|||
|
||||
Button {
|
||||
SelectDevice = Repartition disk
|
||||
AddPartition = Add another partition
|
||||
Back = Back
|
||||
SavePartitions = Save changes
|
||||
AddPartition = Add
|
||||
DelPartition = Remove
|
||||
SavePartitions = Write new partition table
|
||||
AbortPartitions = Cancel
|
||||
}
|
||||
|
||||
|
@ -20,14 +20,33 @@ Text {
|
|||
Ext3 = Ext3
|
||||
Reiser = Reiser
|
||||
}
|
||||
PartNum = Id
|
||||
PartType = Type
|
||||
Size = Size (MB)
|
||||
SelectDevice = Choose a disk for partitioning
|
||||
NoDevicesAvailable = No suitable disks found - please check your configuration and hardware setup.
|
||||
WarningMessage = If you continue, you will destroy all data on the choosen disk. Please be careful!
|
||||
}
|
||||
|
||||
|
||||
WarningMessage {
|
||||
InvalidInput {
|
||||
Title = Invalid input
|
||||
Text = You entered an invalid value.
|
||||
SuccessMessage {
|
||||
Partitioned {
|
||||
Title = Partitioning complete
|
||||
Text = The disk was partitioned successfully.
|
||||
}
|
||||
}
|
||||
|
||||
WarningMessage {
|
||||
NoDisksAvailable {
|
||||
Title = No disks found
|
||||
Text = No suitable disks found - please check your configuration and hardware setup.
|
||||
}
|
||||
|
||||
PartitioningFailed {
|
||||
Title = Partitioning failed
|
||||
Text = The partitioning of the device failed for some reason - sorry!
|
||||
}
|
||||
|
||||
DiskIsBusy {
|
||||
Title = This disk is busy
|
||||
Text = Please deactivate all containers of this disk before partitioning.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,15 +28,24 @@ def doAction(hdf, cbox, **args):
|
|||
|
||||
|
||||
def getStatus(cbox):
|
||||
#return "%d.%d.%d.%d" % __getCurrentIP(cbox)
|
||||
return "TODO"
|
||||
|
||||
|
||||
def __isDeviceValid(device, cbox):
|
||||
## TODO: also check for "is device busy" add output a warning
|
||||
if not cbox.isDeviceAllowed(device):
|
||||
return False
|
||||
if not device in CryptoBoxTools.getParentBlockDevices():
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def __isDeviceBusy(device, cbox):
|
||||
"""check if the device (or one of its partitions) is mounted"""
|
||||
for c in cbox.getContainerList():
|
||||
if re.match(device + "\d*$", c.getDevice()):
|
||||
if c.isMounted(): return True
|
||||
return False
|
||||
|
||||
|
||||
def __actionSelectDevice(hdf, cbox, args):
|
||||
|
@ -48,6 +57,9 @@ def __actionSelectDevice(hdf, cbox, args):
|
|||
hdf["Data.Plugins.partition.BlockDevices.%d" % counter] = a
|
||||
cbox.log.debug("found a suitable block device: %s" % a)
|
||||
counter += 1
|
||||
## there is no disk available
|
||||
if not block_devices:
|
||||
hdf["Data.Warning"] = "Plugins.partition.NoDisksAvailable"
|
||||
return "select_device"
|
||||
|
||||
|
||||
|
@ -56,8 +68,10 @@ def __actionAddPartition(hdf, cbox, args):
|
|||
device = args["block_device"]
|
||||
except KeyError:
|
||||
return __actionSelectDevice(hdf, cbox, args)
|
||||
#FIXME: the following check should obviuosly get reversed
|
||||
if __isDeviceValid(device, cbox): return __actionSelectDevice(hdf, cbox, args)
|
||||
if not __isDeviceValid(device, cbox): return __actionSelectDevice(hdf, cbox, args)
|
||||
if __isDeviceBusy(device, cbox):
|
||||
hdf["Data.Warning"] = "Plugins.partition.DiskIsBusy"
|
||||
return __actionSelectDevice(hdf, cbox, args)
|
||||
size = __getDeviceSize(device)
|
||||
hdf["Data.Plugins.partition.Device"] = device
|
||||
hdf["Data.Plugins.partition.Device.Size"] = size
|
||||
|
@ -69,18 +83,49 @@ def __actionAddPartition(hdf, cbox, args):
|
|||
def __actionDelPartition(hdf, cbox, args):
|
||||
try:
|
||||
device = args["block_device"]
|
||||
except KeyError:
|
||||
part_num = int(args["del_num"])
|
||||
except (TypeError,KeyError):
|
||||
return __actionSelectDevice(hdf, cbox, args)
|
||||
if not __isDeviceValid(device, cbox): return __actionSelectDevice(hdf, cbox, args)
|
||||
if __isDeviceBusy(device, cbox):
|
||||
hdf["Data.Warning"] = "Plugins.partition.DiskIsBusy"
|
||||
return __actionSelectDevice(hdf, cbox, args)
|
||||
#FIXME: the following check should obviuosly get reversed
|
||||
if __isDeviceValid(device, cbox): return __actionSelectDevice(hdf, cbox, args)
|
||||
size = __getDeviceSize(device)
|
||||
hdf["Data.Plugins.partition.Device"] = device
|
||||
hdf["Data.Plugins.partition.Device.Size"] = size
|
||||
parts = __getPartitionsFromArgs(args, size)
|
||||
__setPartitionData(hdf, parts[:-1], size)
|
||||
## valid partition number to be deleted?
|
||||
if part_num < len(parts):
|
||||
del parts[part_num]
|
||||
else:
|
||||
return __actionSelectDevice(hdf, cbox, args)
|
||||
__setPartitionData(hdf, parts, size)
|
||||
return "set_partitions"
|
||||
|
||||
|
||||
def __actionFinish(hdf, cbox, args):
|
||||
try:
|
||||
device = args["block_device"]
|
||||
except KeyError:
|
||||
return __actionSelectDevice(hdf, cbox, args)
|
||||
if not __isDeviceValid(device, cbox): return __actionSelectDevice(hdf, cbox, args)
|
||||
if __isDeviceBusy(device, cbox):
|
||||
hdf["Data.Warning"] = "Plugins.partition.DiskIsBusy"
|
||||
return __actionSelectDevice(hdf, cbox, args)
|
||||
size = __getDeviceSize(device)
|
||||
parts = __getPartitionsFromArgs(args, size)
|
||||
if parts:
|
||||
if not __runFDisk(cbox, device, parts):
|
||||
hdf["Data.Warning"] = "Plugins.partition.PartitioningFailed"
|
||||
return __actionAddPartition(hdf, cbox, args)
|
||||
else:
|
||||
hdf["Data.Success"] = "Plugins.partition.Partitioned"
|
||||
cbox.reReadContainerList()
|
||||
return "form_system"
|
||||
else:
|
||||
return __actionSelectDevice(hdf, cbox, args)
|
||||
|
||||
|
||||
def __setPartitionData(hdf, parts, size):
|
||||
availSize = size
|
||||
i = 0
|
||||
|
@ -126,8 +171,41 @@ def __getDeviceSize(device):
|
|||
elements = f.split()
|
||||
if len(elements) != 4: continue
|
||||
if (int(elements[0]) == major) and (int(elements[1]) == minor):
|
||||
return int(elements[2])
|
||||
return int(elements[2])/1024
|
||||
except ValueError:
|
||||
pass
|
||||
return 0
|
||||
|
||||
|
||||
def __runFDisk(cbox, device, parts):
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = 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"),
|
||||
"partition",
|
||||
device])
|
||||
import logging
|
||||
logger = logging.getLogger("CryptoBox")
|
||||
for line in __getSFDiskLayout(parts): proc.stdin.write(line + "\n")
|
||||
(output, error) = proc.communicate()
|
||||
if error: logger.debug("partitioning failed: %s" % error)
|
||||
return proc.returncode == 0
|
||||
|
||||
|
||||
def __getSFDiskLayout(paramParts):
|
||||
parts = paramParts[:]
|
||||
## first a primary partition
|
||||
yield ",%d,%s,*" % (parts[0]["size"], PartTypes[parts[0]["type"]])
|
||||
del parts[0]
|
||||
if not parts: return
|
||||
yield ",,E" # extended container for the rest
|
||||
yield ";" # empty partition in main table
|
||||
yield ";" # another empty partition in main table
|
||||
while parts:
|
||||
yield ",%d,%s" % (parts[0]["size"], PartTypes[parts[0]["type"]])
|
||||
del parts[0]
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
#!/usr/bin/env python2.4
|
||||
|
||||
#TODO: add netmask and gateway
|
||||
|
||||
## necessary: otherwise CryptoBoxRootActions.py will refuse to execute this script
|
||||
PLUGIN_TYPE = "cryptobox"
|
||||
|
||||
SFDISK_BIN = "/sbin/sfdisk"
|
||||
|
||||
import subprocess
|
||||
import re
|
||||
|
@ -12,22 +11,39 @@ import sys
|
|||
import os
|
||||
|
||||
|
||||
def __partitionDevice(device):
|
||||
## do not use the "-q" flag, as this spoils the exit code of sfdisk (seems to be a bug)
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
args = [
|
||||
SFDISK_BIN,
|
||||
"-uM",
|
||||
device])
|
||||
proc.communicate()
|
||||
return proc.returncode == 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = sys.argv[1:]
|
||||
|
||||
self_bin =sys.argv[0]
|
||||
|
||||
if len(args) > 1:
|
||||
if len(args) > 2:
|
||||
sys.stderr.write("%s: too many arguments (%s)\n" % (self_bin, args))
|
||||
sys.exit(1)
|
||||
|
||||
if len(args) == 0:
|
||||
sys.stderr.write("%s: no argument supplied\n" % self_bin)
|
||||
sys.exit(1)
|
||||
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
args = [IFCONFIG_BIN, IFACE, args[0]])
|
||||
proc.communicate()
|
||||
sys.exit(proc.returncode)
|
||||
|
||||
if args[0] == "partition":
|
||||
if len(args) < 2:
|
||||
sys.stderr.write("%s: not enough arguments (%s)\n" % (self_bin, args))
|
||||
sys.exit(1)
|
||||
if __partitionDevice(args[1]):
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(1)
|
||||
else:
|
||||
sys.exit(1)
|
||||
|
||||
|
|
|
@ -13,15 +13,17 @@
|
|||
<?cs /each ?>
|
||||
</select></p>
|
||||
|
||||
<p class="note">
|
||||
<?cs var:html_escape(Lang.Plugins.partition.Text.WarningMessage) ?>
|
||||
</p>
|
||||
|
||||
<input type="hidden" name="step" value="add_partition" />
|
||||
|
||||
<button type="submit"><?cs var:html_escape(Lang.Plugins.partition.Button.SelectDevice) ?></button>
|
||||
|
||||
</form>
|
||||
|
||||
<?cs else ?>
|
||||
|
||||
<p><?cs var:html_escape(Lang.Plugins.partition.Text.NoDevicesAvailable) ?></p>
|
||||
|
||||
<?cs /if ?>
|
||||
|
||||
<?cs # a warning will be displayed if there are no disks available ?>
|
||||
|
||||
|
|
|
@ -2,32 +2,56 @@
|
|||
|
||||
<h1><?cs var:html_escape(Lang.Plugins.partition.Title.Partition) ?></h1>
|
||||
|
||||
<p> <?cs loop: x = #0, subcount(Data.Plugins.partition.Parts)-1, #1 ?>
|
||||
<p><?cs var:x ?> - <?cs var:Data.Plugins.partition.Parts[x].Size ?> - <?cs var:Data.Plugins.partition.Parts[x].Type ?></p><?cs
|
||||
/loop ?></p>
|
||||
<div align="center">
|
||||
<table class="partition">
|
||||
<tr>
|
||||
<th><?cs var:html_escape(Lang.Plugins.partition.Text.PartNum) ?></th>
|
||||
<th><?cs var:html_escape(Lang.Plugins.partition.Text.Size) ?></th>
|
||||
<th><?cs var:html_escape(Lang.Plugins.partition.Text.PartType) ?></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
<?cs if:Data.Plugins.partition.availSize ?>
|
||||
<?cs call:print_form_header("plugins/partition") ?>
|
||||
<?cs include:Settings.PluginDir + "/partition/current_partition_info.cs" ?><?cs
|
||||
|
||||
# new partition input if space is available ?><?cs
|
||||
set: x = subcount(Data.Plugins.partition.Parts) ?>
|
||||
<p><?cs var:x ?> - <input type="text" name="part<?cs var:x ?>_size" value="<?cs var:Data.Plugins.partition.availSize ?>" /> - <select name="part<?cs var:x ?>_type" size="0"><?cs each: t = Data.Plugins.partition.Types ?><option><?cs var:t ?></option><?cs /each ?></select></p>
|
||||
|
||||
<input type="hidden" name="step" value="add_partition" />
|
||||
<button type="submit"><?cs var:html_escape(Lang.Plugins.partition.Button.AddPartition) ?></button>
|
||||
</form>
|
||||
<?cs /if ?>
|
||||
|
||||
<?cs if:subcount(Data.Plugins.partition.Parts) > 0 ?>
|
||||
<?cs call:print_form_header("plugins/partition") ?>
|
||||
<?cs loop: x = #0, subcount(Data.Plugins.partition.Parts)-1, #1 ?>
|
||||
<tr>
|
||||
<td><?cs var:x ?></td>
|
||||
<td><?cs var:Data.Plugins.partition.Parts[x].Size ?></td>
|
||||
<td><?cs var:Data.Plugins.partition.Parts[x].Type ?></td>
|
||||
<td>
|
||||
<?cs call:print_form_header("plugins/partition") ?>
|
||||
<?cs include:Settings.PluginDir + "/partition/current_partition_info.cs" ?>
|
||||
<input type="hidden" name="step" value="del_partition" />
|
||||
<button type="submit"><?cs var:html_escape(Lang.Plugins.partition.Button.Back) ?></button>
|
||||
<input type="hidden" name="del_num" value="<?cs var:x ?>" />
|
||||
<button type="submit"><?cs var:html_escape(Lang.Plugins.partition.Button.DelPartition) ?></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?cs /loop ?></p>
|
||||
|
||||
<?cs # new partition input if space is available ?>
|
||||
<?cs if:Data.Plugins.partition.availSize > 0 ?>
|
||||
<tr>
|
||||
<?cs call:print_form_header("plugins/partition") ?>
|
||||
<?cs include:Settings.PluginDir + "/partition/current_partition_info.cs" ?>
|
||||
<input type="hidden" name="step" value="add_partition" />
|
||||
<?cs set: x = subcount(Data.Plugins.partition.Parts) ?>
|
||||
<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><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>
|
||||
<button type="submit"><?cs var:html_escape(Lang.Plugins.partition.Button.AddPartition) ?></button>
|
||||
</td>
|
||||
</form>
|
||||
</tr>
|
||||
<?cs /if ?>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<?cs if:subcount(Data.Plugins.partition.Parts) > 0 ?>
|
||||
<p class="note">
|
||||
<?cs var:html_escape(Lang.Plugins.partition.Text.WarningMessage) ?>
|
||||
</p>
|
||||
|
||||
<?cs call:print_form_header("plugins/partition") ?>
|
||||
<?cs include:Settings.PluginDir + "/partition/current_partition_info.cs" ?>
|
||||
<input type="hidden" name="step" value="finish" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue