added gray disc icon for unitialized volumes

simple partitioning interface finished
order in navigation bar changed
ignore extended partitions (in container list)
master
lars 17 years ago
parent 665d18bdbd
commit 1c8db28989

@ -113,10 +113,10 @@ class CryptoBoxProps(CryptoBox):
def __init__(self, config_file=None):
'''read config and fill class variables'''
CryptoBox.__init__(self, config_file)
self.__reReadContainerList()
self.reReadContainerList()
def __reReadContainerList(self):
def reReadContainerList(self):
self.containers = []
for device in CryptoBoxTools.getAvailablePartitions():
if self.isDeviceAllowed(device):

@ -18,7 +18,8 @@ def getAvailablePartitions():
if (len(p_details) == 4):
"the following code prevents double entries like /dev/hda and /dev/hda1"
(p_major, p_minor, p_size, p_device) = p_details
if re.search('^[0-9]*$', p_major) and re.search('^[0-9]*$', p_minor):
## ignore lines with: invalid minor/major or extend partitions (size=1)
if re.search('^[0-9]*$', p_major) and re.search('^[0-9]*$', p_minor) and (p_size != "1"):
p_parent = re.sub('[1-9]?[0-9]$', '', p_device)
if p_parent == p_device:
if [e for e in ret_list if re.search('^' + p_parent + '[1-9]?[0-9]$', e)]:

@ -14,6 +14,7 @@ class WebInterfaceDataset(dict):
self.cbox = cbox
self.__setConfigValues()
self.__setCryptoBoxState()
def setPluginState(self, plugins):
@ -41,18 +42,7 @@ class WebInterfaceDataset(dict):
self["Data.CurrentDisk.capacity.percent"] = percent
def __setConfigValues(self):
self["Settings.TemplateDir"] = os.path.abspath(self.prefs["Locations"]["TemplateDir"])
self["Settings.LanguageDir"] = os.path.abspath(self.prefs["Locations"]["LangDir"])
self["Settings.DocDir"] = os.path.abspath(self.prefs["Locations"]["DocDir"])
self["Settings.Stylesheet"] = self.prefs["WebSettings"]["Stylesheet"]
self["Settings.Language"] = self.prefs["WebSettings"]["Language"]
self["Settings.DocLang"] = self.prefs["WebSettings"]["DocLanguage"]
self["Settings.PluginDir"] = self.prefs["Locations"]["PluginDir"]
def __setCryptoBoxState(self):
self["Data.Version"] = self.cbox.VERSION
def setContainersState(self):
avail_counter = 0
active_counter = 0
for container in self.cbox.getContainerList():
@ -67,6 +57,20 @@ class WebInterfaceDataset(dict):
if isMounted: active_counter += 1
avail_counter += 1
self["Data.activeDisksCount"] = active_counter
def __setConfigValues(self):
self["Settings.TemplateDir"] = os.path.abspath(self.prefs["Locations"]["TemplateDir"])
self["Settings.LanguageDir"] = os.path.abspath(self.prefs["Locations"]["LangDir"])
self["Settings.DocDir"] = os.path.abspath(self.prefs["Locations"]["DocDir"])
self["Settings.Stylesheet"] = self.prefs["WebSettings"]["Stylesheet"]
self["Settings.Language"] = self.prefs["WebSettings"]["Language"]
self["Settings.DocLang"] = self.prefs["WebSettings"]["DocLanguage"]
self["Settings.PluginDir"] = self.prefs["Locations"]["PluginDir"]
def __setCryptoBoxState(self):
self["Data.Version"] = self.cbox.VERSION
for lang in self.cbox.getAvailableLanguages():
self["Data.Languages." + lang] = self.__getLanguageName(lang)
## TODO: open issues: Data.Config.AdminPasswordIsSet

@ -34,6 +34,10 @@ class WebInterfaceSites:
def __resetDataset(self):
"""this method has to be called at the beginning of every "site" action
important: only at the beginning of an action (to not loose information)
important: for _every_ "site" action (cherrypy is stateful)
"""
self.dataset = WebInterfaceDataset.WebInterfaceDataset(self.cbox, self.prefs)
@ -144,8 +148,6 @@ class WebInterfaceSites:
self.dataset["Data.Warning"] = "SetVolumeNameFailed"
else:
self.log.info("successfully renamed volume '%s' to '%s'" % (device, volume_name))
# reread the dataset
self.__resetDataset()
self.dataset.setCurrentDiskState(device)
else:
self.dataset["Data.Warning"] = "InvalidVolumeName"
@ -188,8 +190,6 @@ class WebInterfaceSites:
self.log.warn("failed to mount the device (%s)" % device)
else:
self.log.info("successfully mounted the container (%s)" % device)
# reread the dataset
self.__resetDataset()
self.dataset.setCurrentDiskState(device)
else:
if self.cbox.getContainerList():
@ -264,7 +264,6 @@ class WebInterfaceSites:
else:
self.log.info("successfully initialized device '%s'" % device)
# reread the dataset
self.__resetDataset()
self.dataset.setCurrentDiskState(device)
return self.__render("show_volume")
else:
@ -274,8 +273,9 @@ class WebInterfaceSites:
return self.__render("show_status")
def test(self):
def test(self, weblang=""):
self.__resetDataset()
self.__setWebLang(weblang)
return "test passed"
@ -306,7 +306,6 @@ class WebInterfaceSites:
else:
self.log.info("successfully unmounted the container (%s)" % device)
# reread the dataset
self.__resetDataset()
self.dataset.setCurrentDiskState(device)
else:
if self.cbox.getContainerList():
@ -455,6 +454,9 @@ class WebInterfaceSites:
## add the current state of the plugins to the hdf dataset
self.dataset.setPluginState(self.pluginList)
## update the container information
self.dataset.setContainersState()
hdf = neo_util.HDF()
hdf.readFile(hdf_path)
self.log.debug(self.dataset)

@ -8,10 +8,9 @@ Lang {
Top = Die CryptoBox
Slogan = ... und 1984 war gestern!
Init = Initialisierung der CryptoBox
Mount = Aktivierung der Crypto-Daten
Umount = Deaktivierung der Crypto-Daten
Mount = Aktivierung des Containers
Umount = Deaktivierung des Containers
Config = Konfiguration der CryptoBox
Log = Protokoll der CryptoBox
System = System
Status = Status der CryptoBox
Volume = Eigenschaften von
@ -31,7 +30,6 @@ Lang {
PartitionInfo = Derzeitige Partitionierung der Festplatte:
IPAddress = Netzwerk-Adresse (IP) der CryptoBox:
TimeOut = Zeitabschaltung des Crypto-Dateisystems (in Minuten):
EmptyLog = Das Logbuch der CryptoBox ist leer.
SelectLanguage = Spracheinstellung:
RedirectNote = Klicke hier, falls dein Browser die automatische Weiterleitung nicht unterstützt.
ProjectHomePage = Projekt-Seite
@ -54,12 +52,11 @@ Lang {
DoInit = Initialisierung
SaveConfig = Speichere Konfiguration
Update = Aktualisieren
Mount = Crypto-Daten aktivieren
Umount = Crypto-Daten deaktivieren
Mount = Container aktivieren
Umount = Container deaktivieren
Config = Einstellungen
PowerOff = ausschalten
ReBoot = neu starten
Protocol = Protokoll anzeigen
Documentation = Hilfe
Status = Status
System = System

@ -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!
}
SuccessMessage {
Partitioned {
Title = Partitioning complete
Text = The disk was partitioned successfully.
}
}
WarningMessage {
InvalidInput {
Title = Invalid input
Text = You entered an invalid value.
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>
<?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") ?>
<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 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" />

@ -1,25 +1,11 @@
<?cs # $Id$ ?>
<?cs # mounting possible? ?>
<?cs if:((Data.Status.Config == 1) && (Data.Status.InitRunning == 0)) ?>
<!-- TODO: remove the following lines, as soon as we completely switched to the volume-based user interface
<?cs if:subcount(Data.Disks.passive) > 0 ?>
<a href="<?cs call:link('mount_ask','','','','') ?>" title="<?cs var:html_escape(Lang.Text.DoMount) ?>"><?cs var:html_escape(Lang.Button.Mount) ?></a><?cs /if ?>
<?cs if:Data.activeDisksCount > 0 ?>
<a href="<?cs call:link('umount_ask','','','','') ?>" title="<?cs var:html_escape(Lang.Text.DoUmount) ?>"><?cs var:html_escape(Lang.Button.Umount) ?></a><?cs /if ?>
-->
<?cs # status ?>
<a href="<?cs call:link('status','','','','') ?>" title="<?cs var:html_escape(Lang.Button.Status) ?>"><?cs var:html_escape(Lang.Button.Status) ?></a>
<a href="<?cs if:subcount(Data.Disks) > 1
?><?cs call:link('show_status','','','','')
?><?cs else
?><?cs call:link('show_volume','device',Data.Disks.0.device,'','')
?><?cs /if
?>" title="<?cs var:html_escape(Lang.Button.Status) ?>"><?cs var:html_escape(Lang.Button.Status) ?></a>
<?cs /if ?>
<?cs # system ?>
<a href="<?cs call:link('system','','','','') ?>" title="<?cs var:html_escape(Lang.Button.System) ?>"><?cs var:html_escape(Lang.Button.System) ?></a>
<?cs # manual ?>
<a href="<?cs call:link('doc','','','','') ?>" title="<?cs var:html_escape(Lang.Button.Documentation) ?>"><?cs var:html_escape(Lang.Button.Documentation) ?></a>
<a href="<?cs call:link('status','','','','') ?>" title="<?cs var:html_escape(Lang.Button.Status) ?>"><?cs var:html_escape(Lang.Button.Status) ?></a>
<a href="<?cs call:link('system','','','','') ?>" title="<?cs var:html_escape(Lang.Button.System) ?>"><?cs var:html_escape(Lang.Button.System) ?></a>

@ -6,7 +6,9 @@
<a href="<?cs call:link('show_volume','device',Data.Disks[index].device,'','') ?>" title="<?cs
var:Data.Disks[index].name ?>">
<?cs # the "div" is the container for the background image ?>
<div class="<?cs if:Data.Disks[index].active ?>active<?cs else ?>passive<?cs /if ?><?cs
<div class="<?cs if:Data.Disks[index].active ?>active<?cs
elif:Data.Disks[index].encryption || Data.Disks[index].plaintext ?>passive<?cs
else ?>void<?cs /if ?><?cs
if:Data.Disks[index].device == Data.CurrentDisk.device ?> current<?cs /if ?>">
<p><?cs var:Data.Disks[index].name ?></p>
</div>

@ -319,6 +319,10 @@ button:hover {
background-image: url(disc_green.png);
}
#volumes div.void {
background-image: url(disc_gray.png);
}
#volumes div.current {
border-style: dashed;
border-width: 2px;
@ -422,3 +426,14 @@ button:hover {
color: #909090;
margin-top: 0px;
}
// TODO: move this to the plugin "partition" (inline include with cs)
#words div.partition {
text-align: center;
align: center;
}
table.partition tr td{
text-align: center
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Loading…
Cancel
Save