fixed wrong redirection after reboot (causing reboot loop)

clarified interpretation of blkid output
added missing success message to volume_format_fs
execute formatting in the background
mark busy devices as such
fixed a small bug in CryptoBoxRootActions
This commit is contained in:
lars 2006-12-06 16:25:52 +00:00
parent 873bd4ec85
commit f6ddb82f4c
26 changed files with 304 additions and 175 deletions

View File

@ -74,6 +74,7 @@ def checkIfPluginIsValid(plugin):
import imp
try:
x = imp.load_source("cbox_plugin",plugin)
#TODO: no wildcard catches, please!
except Exception:
return False
try:
@ -87,7 +88,7 @@ def checkIfPluginIsValid(plugin):
def checkIfEventScriptIsValid(plugin):
event_dir = os.path.dirname(plugin)
if os.path.exists(os.path.join(event_dir,EVENT_MARKER)):
if os.path.exists(os.path.join(event_dir, EVENT_MARKER)):
return True
else:
return False
@ -106,7 +107,7 @@ def call_plugin(args):
## check if the plugin is a python program, that is marked as a cryptobox plugin
if not checkIfPluginIsValid(plugin):
raise Exception, "the plugin (%s) is not a correctly marked python script" % plugin
args.insert(0,plugin)
args.insert(0, plugin)
proc = subprocess.Popen(
shell = False,
args = args)
@ -122,12 +123,12 @@ def call_event(args):
if not os.access(event, os.X_OK):
raise Exception, "could not find executable event script (%s)" % event
## check if the script is valid (the marker file must be in the same directory)
if not checkIfEventScriptIsValid(plugin):
raise Exception, "the event script (%s) does not reside in a directory with the marker file (%s) - this is not allowed due to abuse prevention" % (plugin,EVENT_MARKER)
if not checkIfEventScriptIsValid(event):
raise Exception, "the event script (%s) does not reside in a directory with the marker file (%s) - this is not allowed due to abuse prevention" % (event, EVENT_MARKER)
## check if the event (and its parents) are only writeable for root
if not checkIfFileIsSafe(event):
raise Exception, "the event (%s) is not safe - check its (and its parents') permissions" % event
args.insert(0,event)
args.insert(0, event)
proc = subprocess.Popen(
shell = False,
args = args)
@ -201,7 +202,7 @@ def run_cryptsetup(args):
cmd_args.append(action)
cmd_args.append(device)
elif action == "luksDelKey":
if len(cs_args) < 2: raise "WrongArguments", "missing arguments"
if len(args) < 2: raise "WrongArguments", "missing arguments"
device = args[0]; del args[0]
cmd_args.insert(-1, action)
cmd_args.insert(-1, device)
@ -361,7 +362,7 @@ def getUserInfo(user):
except TypeError:
# if a KeyError is raised again, then the supplied user was invalid
userinfo = pwd.getpwnam(user)
u_groups =[one_group.gr_gid
u_groups = [one_group.gr_gid
for one_group in grp.getgrall()
if userinfo.pw_name in one_group.gr_mem]
if not userinfo.pw_gid in u_groups: u_groups.append(userinfo.pw_gid)

View File

@ -76,11 +76,12 @@ Languages = en, de, sl, fr
[Programs]
cryptsetup = /sbin/cryptsetup
mkfs-data = /sbin/mkfs.ext3
mkfs = /sbin/mkfs
blkid = /sbin/blkid
blockdev = /sbin/blockdev
mount = /bin/mount
umount = /bin/umount
nice = /usr/bin/nice
super = /usr/bin/super
# this is the "program" name as defined in /etc/super.tab
CryptoBoxRootActions = CryptoBoxRootActions

View File

@ -1,17 +0,0 @@
[global]
server.socketPort = 8080
#server.environment = "production"
server.environment = "development"
server.logToScreen = True
server.log_tracebacks = True
server.threadPool = 1
server.reverseDNS = False
server.logFile = "cryptoboxwebserver.log"
[/favicon.ico]
static_filter.on = True
# TODO: use live-cd/live-cd-tree.d/var/www/favicon.ico
static_filter.file = "/usr/share/doc/python-cherrypy/cherrypy/favicon.ico"
[/test_stream]
stream_response = True

View File

@ -75,11 +75,12 @@ Languages = de, en, fr
[Programs]
cryptsetup = /sbin/cryptsetup
mkfs-data = /sbin/mkfs.ext3
mkfs = /sbin/mkfs
blkid = /sbin/blkid
blockdev = /sbin/blockdev
mount = /bin/mount
umount = /bin/umount
nice = /usr/bin/nice
super = /usr/bin/super
# this is the "program" name as defined in /etc/super.tab
CryptoBoxRootActions = CryptoBoxRootActions

7
debian/changelog vendored
View File

@ -1,3 +1,10 @@
cryptobox (0.2.52-1) unstable; urgency=low
* format partitions in background
* mark busy partitions
-- Lars Kruse <devel@sumpfralle.de> Wed, 6 Dec 2006 14:57:43 +0100
cryptobox (0.2.51-1) unstable; urgency=low
* favicon included

View File

@ -28,6 +28,7 @@ import os
import logging
import cryptobox.core.tools as cbxTools
import cryptobox.plugins.base
from cryptobox.core.exceptions import *
PARTTYPES = {
@ -228,7 +229,7 @@ class partition(cryptobox.plugins.base.CryptoBoxPlugin):
## breaks the flow (hanging process)
#self.cbox.reReadContainerList()
## write config data
self.cbox.prefs.mountPartition()
self.cbox.prefs.mount_partition()
self.cbox.prefs.write()
self.cbox.log.info("settings stored on config partition")
## return the result
@ -456,6 +457,26 @@ class partition(cryptobox.plugins.base.CryptoBoxPlugin):
def __format_one_partition(self, dev_name, fs_type):
"""Format a single partition
"""
import cryptobox.core.container
## first: retrieve UUID - it can be removed from the database afterwards
prev_name = [e.get_name() for e in self.cbox.get_container_list()
if e.get_device() == dev_name]
## call "mkfs"
try:
cont = cryptobox.core.container.CryptoBoxContainer(dev_name, self.cbox)
cont.create(cryptobox.core.container.CONTAINERTYPES["plain"], fs_type=fs_type)
except (CBInvalidType, CBCreateError, CBVolumeIsActive), err_msg:
self.cbox.log.warn(err_msg)
return False
## remove unused volume entry
if prev_name:
del self.cbox.prefs.volumes_db[prev_name[0]]
return True
def __old_format_one_partition(self, dev_name, fs_type):
"""Format a single partition
"""
## first: retrieve UUID - it can be removed from the database afterwards

View File

@ -22,7 +22,7 @@ __revision__ = "$Id"
import cryptobox.plugins.base
REDIRECT_DELAY = 180
REDIRECT_DELAY = 120
class shutdown(cryptobox.plugins.base.CryptoBoxPlugin):
@ -44,7 +44,7 @@ class shutdown(cryptobox.plugins.base.CryptoBoxPlugin):
elif type == "reboot":
if self.__do_shutdown("reboot"):
self.hdf["Data.Success"] = "Plugins.shutdown.Reboot"
self.hdf["Data.Redirect.URL"] = ""
self.hdf["Data.Redirect.URL"] = "/"
self.hdf["Data.Redirect.Delay"] = REDIRECT_DELAY
return "progress_reboot"
else:

View File

@ -31,8 +31,8 @@ AdviceMessage {
SuccessMessage {
FormatSuccess {
Title = Formatting successful
Text = The selected filesystem was successfully formatted.
Title = Formatting is running
Text = The selected filesystem is being formatted in the background. This may take some time (depending on the size of your disk).
}
}

View File

@ -40,7 +40,7 @@ class volume_format_fs(cryptobox.plugins.base.CryptoBoxPlugin):
def do_action(self, store=None, fs_type="windows", container_type="luks", crypto_password=None, crypto_password2=None, confirm=None):
if not fs_type in FSTYPES.keys():
self.cbox.info
self.cbox.log.info("invalid filesystem type choosen: %s" % str(fs_type))
return "format_volume"
self.hdf[self.hdf_prefix + "fs_type"] = fs_type
self.hdf[self.hdf_prefix + "container_type"] = container_type
@ -54,10 +54,10 @@ class volume_format_fs(cryptobox.plugins.base.CryptoBoxPlugin):
if container_type == "luks":
return "volume_format_luks"
elif container_type == "plain":
return self.__format_plain(fs_type)
return self.__format_plain(FSTYPES[fs_type])
elif store == "step2":
if container_type == "luks":
return self.__format_luks(fs_type, crypto_password, crypto_password2)
return self.__format_luks(FSTYPES[fs_type], crypto_password, crypto_password2)
else:
self.cbox.log.info("invalid input value for 'container_type': %s" % container_type)
return "volume_format"
@ -72,36 +72,10 @@ class volume_format_fs(cryptobox.plugins.base.CryptoBoxPlugin):
return "no status"
def __format_plain(self, fsType):
def __format_plain(self, fs_type):
try:
container = self.cbox.get_container(self.device)
container.create(cbx_container.CONTAINERTYPES["plain"])
except CBVolumeIsActive:
self.hdf["Data.Warning"] = "VolumeMayNotBeMounted"
self.cbox.log.info("initialization is not possible as long as the device (%s) is mounted" % self.device)
return None
except CBContainerError, errMsg:
self.hdf["Data.Warning"] = "Plugins.volume_format_fs.FormatFailed"
self.cbox.log.warn("initialization of device '%s' failed" % self.device)
self.cbox.log.warn("reason: %s" % errMsg)
return "volume_format"
else:
self.cbox.log.info("successfully initialized device '%s'" % self.device)
return None
def __format_luks(self, fsType, pw, pw2):
if not pw:
self.hdf["Data.Warning"] = "EmptyPassword"
self.cbox.log.warn("no crypto password was supplied for initialization of device '%s'" % self.device)
return "volume_format"
if pw != pw2:
self.hdf["Data.Warning"] = "DifferentPasswords"
self.cbox.log.warn("the crypto password was not repeated correctly for initialization of device '%s'" % self.device)
return "volume_format"
container = self.cbox.get_container(self.device)
try:
container.create(cbx_container.CONTAINERTYPES["luks"], pw)
container.create(cbx_container.CONTAINERTYPES["plain"], fs_type=fs_type)
except CBVolumeIsActive:
self.hdf["Data.Warning"] = "VolumeMayNotBeMounted"
self.cbox.log.info("initialization is not possible as long as the device (%s) is mounted" % self.device)
@ -114,5 +88,33 @@ class volume_format_fs(cryptobox.plugins.base.CryptoBoxPlugin):
else:
self.hdf["Data.Success"] = "Plugins.volume_format_fs.FormatSuccess"
self.cbox.log.info("successfully initialized device '%s'" % self.device)
return None
return { "plugin":"disks", "values":{} }
def __format_luks(self, fs_type, pw, pw2):
if not pw:
self.hdf["Data.Warning"] = "EmptyPassword"
self.cbox.log.warn("no crypto password was supplied for initialization of device '%s'" % self.device)
return "volume_format"
if pw != pw2:
self.hdf["Data.Warning"] = "DifferentPasswords"
self.cbox.log.warn("the crypto password was not repeated correctly for initialization of device '%s'" % self.device)
return "volume_format"
container = self.cbox.get_container(self.device)
try:
container.create(cbx_container.CONTAINERTYPES["luks"],
fs_type=fs_type, password=pw)
except CBVolumeIsActive:
self.hdf["Data.Warning"] = "VolumeMayNotBeMounted"
self.cbox.log.info("initialization is not possible as long as the device (%s) is mounted" % self.device)
return None
except CBContainerError, errMsg:
self.hdf["Data.Warning"] = "Plugins.volume_format_fs.FormatFailed"
self.cbox.log.warn("initialization of device '%s' failed" % self.device)
self.cbox.log.warn("reason: %s" % errMsg)
return "volume_format"
else:
self.hdf["Data.Success"] = "Plugins.volume_format_fs.FormatSuccess"
self.cbox.log.info("successfully initialized device '%s'" % self.device)
return { "plugin":"disks", "values":{} }

View File

@ -26,6 +26,7 @@ __revision__ = "$Id"
import subprocess
import os
import re
import time
from cryptobox.core.exceptions import *
@ -36,6 +37,10 @@ CONTAINERTYPES = {
"swap":3,
}
FSTYPES = {
"plain":["ext3", "ext2", "vfat", "reiserfs"],
"swap":["swap"]}
## we use this marker to make sure, that we do not remove a non-cryptobox directory
## below the mount directory
@ -46,10 +51,6 @@ class CryptoBoxContainer:
"""Manage a container of the CryptoBox
"""
__fsTypes = {
"plain":["ext3", "ext2", "vfat", "reiserfs"],
"swap":["swap"]}
__dmDir = "/dev/mapper"
@ -101,10 +102,10 @@ class CryptoBoxContainer:
raise CBVolumeIsActive("the container must not be active during renaming")
if not re.search(r'^[a-zA-Z0-9_\.\- ]+$', new_name):
raise CBInvalidName("the supplied new name contains illegal characters")
## check for another partitions with the same name
## check for another partition with the same name
if self.cbox.get_container_list(filter_name=new_name):
raise CBNameIsInUse("the supplied new name is already in use for anonther partition")
## maybe there a is an entry in the volumes database (but the partition is not active
## maybe there a is an entry in the volumes database (but the partition is not active)
try:
## remove possibly existing inactive database item
del self.cbox.prefs.volumes_db[new_name]
@ -182,23 +183,64 @@ class CryptoBoxContainer:
self.umount = self.__umount_plain
def create(self, cont_type, password=None):
def create(self, cont_type, password=None, fs_type="ext3"):
"""Format a container.
Also set a password for encrypted container.
"""
if not fs_type in FSTYPES["plain"]:
raise CBInvalidType("invalid filesystem type supplied: %s" % str(fs_type))
old_name = self.get_name()
if cont_type == CONTAINERTYPES["luks"]:
self.__create_luks(password)
self.__create_luks(password, fs_type)
elif cont_type == CONTAINERTYPES["plain"]:
self.__create_plain()
self.__create_plain(fs_type)
else:
raise CBInvalidType("invalid container type (%d) supplied" % (cont_type, ))
## no exception was raised during creation -> we can continue
## reset the properties (encryption state, ...) of the device
self.reset_object()
## restore the old name (must be after reset_object)
self.set_name(old_name)
try:
self.set_name(old_name)
except CBNameIsInUse:
## failure is okay
pass
def set_busy(self, new_state, time_limit=300):
"""Set the current busy state.
The timelimit is specified in seconds.
"""
if new_state:
self.cbox.busy_devices[self.device] = int(time.time() + time_limit)
else:
try:
if self.cbox.busy_devices[self.device]:
del self.cbox.busy_devices[self.device]
except KeyError:
pass
def is_busy(self):
"""Check the busy state of the container.
"""
if not self.cbox.busy_devices.has_key(self.device):
self.cbox.log.debug("no 'busy' attribute for '%s'" % self.get_name())
return False
## invalid value - can happen after saving and loading the database
if not isinstance(self.cbox.busy_devices[self.device], int):
self.cbox.log.debug("invalid 'busy' attribute for '%s'" % self.get_name())
del db_entry["busy"]
return False
if time.time() >= self.cbox.busy_devices[self.device]:
self.cbox.log.debug("expired 'busy' attribute for '%s'" % self.get_name())
del db_entry["busy"]
return False
## lock is still active
self.cbox.log.debug("active 'busy' attribute for '%s'" % self.get_name())
return True
def change_password(self, oldpw, newpw):
@ -362,9 +404,9 @@ class CryptoBoxContainer:
if self.__is_luks_partition():
return CONTAINERTYPES["luks"]
type_of_partition = self.__get_type_id_of_partition()
if type_of_partition in self.__fsTypes["plain"]:
if type_of_partition in FSTYPES["plain"]:
return CONTAINERTYPES["plain"]
if type_of_partition in self.__fsTypes["swap"]:
if type_of_partition in FSTYPES["swap"]:
return CONTAINERTYPES["swap"]
return CONTAINERTYPES["unused"]
@ -372,29 +414,28 @@ class CryptoBoxContainer:
def __get_type_id_of_partition(self):
"returns the type of the partition (see 'man blkid')"
devnull = None
try:
devnull = open(os.devnull, "w")
except IOError:
self.cbox.log.warn("Could not open %s" % (os.devnull, ))
proc = subprocess.Popen(
shell=False,
stdin=None,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
args=[self.cbox.prefs["Programs"]["blkid"],
shell = False,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
args = [ self.cbox.prefs["Programs"]["blkid"],
"-s", "TYPE",
"-o", "value",
"-c", os.devnull,
"-w", os.devnull,
self.device])
proc.wait()
output = proc.stdout.read().strip()
if proc.returncode != 0:
self.cbox.log.warn("retrieving of partition type via 'blkid' failed: %s" % \
(proc.stderr.read().strip(), ))
self.device ])
(stdout, stder) = proc.communicate()
if proc.returncode == 0:
## we found a uuid
return stdout.strip()
elif proc.returncode == 2:
## failed to find the attribute - no problem
return None
else:
## something strange happened
self.cbox.log.warn("retrieving of partition type via 'blkid' failed: %s" % \
(stderr.strip(), ))
return None
devnull.close()
return output
def __is_luks_partition(self):
@ -596,50 +637,63 @@ class CryptoBoxContainer:
self.cbox.send_event_notification("postumount", self.__get_event_args())
def __create_plain(self):
def __create_plain(self, fs_type="ext3"):
"make a plaintext partition"
import threading
if self.is_mounted():
raise CBVolumeIsActive("deactivate the partition before filesystem initialization")
devnull = None
try:
devnull = open(os.devnull, "w")
except IOError:
self.cbox.log.warn("Could not open %s" % (os.devnull, ))
proc = subprocess.Popen(
shell = False,
stdin = None,
stdout = devnull,
stderr = subprocess.PIPE,
args = [
self.cbox.prefs["Programs"]["mkfs-data"],
self.device])
proc.wait()
if proc.returncode != 0:
err_msg = "Could not create the filesystem: %s" % (proc.stderr.read().strip(), )
self.cbox.log.error(err_msg)
raise CBCreateError(err_msg)
devnull.close()
raise CBVolumeIsActive(
"deactivate the partition before filesystem initialization")
def format():
import os
old_name = self.get_name()
self.set_busy(True, 600)
self.cbox.log.debug("Turn the busy flag on: %s" % self.device)
## give the main thread a chance to continue
child_pid = os.fork()
if child_pid == 0:
proc = subprocess.Popen(
shell = False,
stdin = None,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
args = [
self.cbox.prefs["Programs"]["nice"],
self.cbox.prefs["Programs"]["mkfs"],
"-t", fs_type, self.device])
(stdout, sterr) = proc.communicate()
## for to allow error detection
if proc.returncode == 0:
time.sleep(5)
## skip cleanup stuff (as common for sys.exit)
os._exit(0)
else:
os.waitpid(child_pid, 0)
self.set_name(old_name)
self.set_busy(False)
self.cbox.log.debug("Turn the busy flag off: %s" % self.device)
bg_task = threading.Thread(target=format)
bg_task.start()
time.sleep(3)
## if the thread exited very fast, then it failed
if not bg_task.isAlive():
raise CBCreateError("Failed to initilize device: %s" % self.device)
def __create_luks(self, password):
def __create_luks(self, password, fs_type="ext3"):
"""Create a luks partition.
"""
import threading
if not password:
raise CBInvalidPassword("no password supplied for new luks mapping")
if self.is_mounted():
raise CBVolumeIsActive("deactivate the partition before filesystem initialization")
devnull = None
try:
devnull = open(os.devnull, "w")
except IOError:
self.cbox.log.warn("Could not open %s" % (os.devnull, ))
## remove any potential open luks mapping
self.__umount_luks()
## create the luks header
proc = subprocess.Popen(
shell = False,
stdin = subprocess.PIPE,
stdout = devnull,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
args = [
self.cbox.prefs["Programs"]["super"],
@ -660,7 +714,7 @@ class CryptoBoxContainer:
proc = subprocess.Popen(
shell = False,
stdin = subprocess.PIPE,
stdout = devnull,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
args = [
self.cbox.prefs["Programs"]["super"],
@ -676,24 +730,44 @@ class CryptoBoxContainer:
err_msg = "Could not open the new luks mapping: %s" % (errout.strip(), )
self.cbox.log.error(err_msg)
raise CBCreateError(err_msg)
## make the filesystem
proc = subprocess.Popen(
shell = False,
stdin = None,
stdout = devnull,
stderr = subprocess.PIPE,
args = [
self.cbox.prefs["Programs"]["mkfs-data"],
os.path.join(self.__dmDir, self.name)])
proc.wait()
## remove the mapping - for every exit status
self.__umount_luks()
if proc.returncode != 0:
err_msg = "Could not create the filesystem: %s" % (proc.stderr.read().strip(), )
self.cbox.log.error(err_msg)
## remove the luks mapping
raise CBCreateError(err_msg)
devnull.close()
def format_luks():
import os
old_name = self.get_name()
self.set_busy(True, 600)
self.cbox.log.debug("Turn the busy flag on: %s" % self.device)
child_pid = os.fork()
if child_pid == 0:
## make the filesystem
proc = subprocess.Popen(
shell = False,
stdin = None,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
args = [
self.cbox.prefs["Programs"]["nice"],
self.cbox.prefs["Programs"]["mkfs"],
"-t", fs_type,
os.path.join(self.__dmDir, self.name)])
(stdou, stderr) = proc.communicate()
## wait to allow error detection
if proc.returncode == 0:
time.sleep(5)
## skip cleanup stuff (as common for sys.exit)
os._exit(0)
else:
os.waitpid(child_pid, 0)
self.set_name(old_name)
self.set_busy(False)
self.cbox.log.debug("Turn the busy flag off: %s" % self.device)
## remove the mapping - for every exit status
self.__umount_luks()
bg_task = threading.Thread(target=format_luks)
bg_task.setDaemon(True)
bg_task.start()
time.sleep(3)
## if the thread exited very fast, then it failed
if not bg_task.isAlive():
raise CBCreateError("Failed to initilize device: %s" % self.device)
def __clean_mount_dirs(self):

View File

@ -46,6 +46,7 @@ class CryptoBox:
self.prefs = cbxSettings.CryptoBoxSettings(config_file)
self.__run_tests()
self.__containers = []
self.busy_devices = {}
self.reread_container_list()

View File

@ -455,7 +455,8 @@ Languages = list(min=1,default=list("en"))
[Programs]
cryptsetup = fileExecutable(default="/sbin/cryptsetup")
mkfs-data = fileExecutable(default="/sbin/mkfs.ext3")
mkfs = fileExecutable(default="/sbin/mkfs")
nice = fileExecutable(default="/usr/bin/nice")
blkid = fileExecutable(default="/sbin/blkid")
blockdev = fileExecutable(default="/sbin/blockdev")
mount = fileExecutable(default="/bin/mount")

View File

@ -191,6 +191,14 @@ class CryptoBoxPlugin:
return self.plugin_visibility
def reset(self):
"""Reinitialize the plugin.
This function should be called before every run
"""
self.hdf = {}
def get_test_class(self):
"""Return the unittest class of the feature.
"""

View File

@ -103,11 +103,13 @@ class WebInterfaceDataset(dict):
is_plain = (container.get_type() == \
cbxContainer.CONTAINERTYPES["plain"]) and 1 or 0
is_mounted = container.is_mounted() and 1 or 0
is_busy = container.is_busy() and 1 or 0
self["Data.CurrentDisk.device"] = container.get_device()
self["Data.CurrentDisk.name"] = container.get_name()
self["Data.CurrentDisk.encryption"] = is_encrypted
self["Data.CurrentDisk.plaintext"] = is_plain
self["Data.CurrentDisk.active"] = is_mounted
self["Data.CurrentDisk.busy"] = is_busy
self["Data.CurrentDisk.size"] = cbxTools.get_blockdevice_size_humanly(
container.get_device())
if is_mounted:
@ -133,10 +135,12 @@ class WebInterfaceDataset(dict):
is_plain = (container.get_type() == \
cbxContainer.CONTAINERTYPES["plain"]) and 1 or 0
is_mounted = container.is_mounted() and 1 or 0
is_busy = container.is_busy() and 1 or 0
self["Data.Disks.%d.device" % avail_counter] = container.get_device()
self["Data.Disks.%d.name" % avail_counter] = container.get_name()
self["Data.Disks.%d.encryption" % avail_counter] = is_encrypted
self["Data.Disks.%d.plaintext" % avail_counter] = is_plain
self["Data.Disks.%d.busy" % avail_counter] = is_busy
self["Data.Disks.%d.active" % avail_counter] = is_mounted
self["Data.Disks.%d.size" % avail_counter] = \
cbxTools.get_blockdevice_size_humanly(container.get_device())

View File

@ -252,28 +252,20 @@ class WebInterfaceSites:
""" returns a function that is suitable for handling a cherrypy
page request
"""
def handler(self, **args):
def handler(self, weblang="", device=None, redirect=None, message_keep=None, **args):
"""this function handles a cherrypy page request
"""
plugin.reset()
self.__reset_dataset()
self.__check_environment()
## set web interface language
try:
self.__set_web_lang(args["weblang"])
del args["weblang"]
except KeyError:
self.__set_web_lang("")
self.__set_web_lang(weblang)
## we always read the "device" setting - otherwise volume-plugin
## links would not work easily
## (see "volume_props" linking to "volume_format_fs")
## it will get ignored for non-volume plugins
try:
plugin.device = None
if self.__set_device(args["device"]):
plugin.device = args["device"]
del args["device"]
except KeyError:
plugin.device = None
plugin.device = None
if device and self.__set_device(device):
plugin.device = device
## check the device argument of volume plugins
if "volume" in plugin.plugin_capabilities:
## initialize the dataset of the selected device if necessary
@ -285,22 +277,18 @@ class WebInterfaceSites:
## check if there is a "redirect" setting - this will override
## the return value of the do_action function
## (e.g. useful for umount-before-format)
try:
if args["redirect"]:
override_next_template = { "plugin":args["redirect"] }
if "volume" in plugin.plugin_capabilities:
override_next_template["values"] = {"device":plugin.device}
del args["redirect"]
except KeyError:
override_next_template = None
override_next_template = None
if redirect:
override_next_template = { "plugin": redirect }
if "volume" in plugin.plugin_capabilities:
override_next_template["values"] = {"device":plugin.device}
## check for information to be kept after the last call
try:
keep_values = args["message_keep"]
del args["message_keep"]
for key, value in keep_values["dataset"].items():
if message_keep:
for (key, value) in message_keep["dataset"].items():
self.__dataset[key] = value
except KeyError:
keep_values = None
## check if the device is busy
if plugin.device and self.cbox.get_container(plugin.device).is_busy():
return self.__render("volume_busy")
## call the plugin handler
next_template = plugin.do_action(**args)
## for 'volume' plugins: reread the dataset of the current disk
@ -330,7 +318,7 @@ class WebInterfaceSites:
and self.__plugin_manager.get_plugin(next_template["plugin"]):
value_dict = dict(next_template["values"])
## force the current weblang attribute - otherwise it gets lost
value_dict["weblang"] = self.__dataset["Settings.Language"]
value_dict["weblang"] = self.lang_order[0]
## check for warnings/success messages, that should be kept
if "Data.Success" in plugin.hdf.keys() \
or "Data.Warning" in plugin.hdf.keys():
@ -354,7 +342,6 @@ class WebInterfaceSites:
@cherrypy.expose
@__request_auth
def test(self, weblang=""):
"""test authentication - this function may be safely removed
"""
@ -509,7 +496,10 @@ class WebInterfaceSites:
if key == "LINK":
return
try:
node.setValue("", translator.ugettext(node.value()))
#TODO: we should use unicode - or not?
#node.setValue("", translator.ugettext(node.value()))
## quite obscure: ugettext can handle None - gettext breaks instead
node.setValue("", str(translator.gettext(node.value())))
except UnicodeEncodeError, err_msg:
self.cbox.log.info(
"Failed unicode encoding for gettext: %s - %s" \

View File

@ -22,6 +22,17 @@ Button {
}
AdviceMessage {
VolumeIsBusy {
Title = Disk is busy
Text = This disk is currently busy. Please wait for a moment.
Link.Rel = /
Link.Text = Show all disks
}
}
WarningMessage {
AccessDenied {

View File

@ -119,15 +119,31 @@ def:show_volume_icon(volume) ?><?cs
# show the appropriate icon for the current state of the volume ?><?cs
if:volume.active ?><?cs
if:volume.encryption ?><?cs
set:filename='volume_active_crypto.gif' ?><?cs
if:volume.busy ?><?cs
set:filename='volume_active_crypto_busy.gif' ?><?cs
else ?><?cs
set:filename='volume_active_crypto.gif' ?><?cs
/if ?><?cs
else ?><?cs
set:filename='volume_active_plain.gif' ?><?cs
if:volume.busy ?><?cs
set:filename='volume_active_plain_busy.gif' ?><?cs
else ?><?cs
set:filename='volume_active_plain.gif' ?><?cs
/if ?><?cs
/if ?><?cs
else ?><?cs
if:volume.encryption ?><?cs
set:filename='volume_passive_crypto.gif' ?><?cs
if:volume.busy ?><?cs
set:filename='volume_passive_crypto_busy.gif' ?><?cs
else ?><?cs
set:filename='volume_passive_crypto.gif' ?><?cs
/if ?><?cs
else ?><?cs
set:filename='volume_passive_plain.gif' ?><?cs
if:volume.busy ?><?cs
set:filename='volume_passive_plain_busy.gif' ?><?cs
else ?><?cs
set:filename='volume_passive_plain.gif' ?><?cs
/if ?><?cs
/if ?><?cs
/if ?><img src="<?cs call:link('cryptobox-misc/' + filename,'','','','') ?>" alt="icon: volume" /><?cs
/def ?><?cs

8
templates/volume_busy.cs Normal file
View File

@ -0,0 +1,8 @@
<?cs # $Id$ ?>
<?cs # display a warning because of a busy volume ?>
<?cs call:handle_messages() ?>
<?cs call:hint('VolumeIsBusy') ?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB