Remove leftover backup files
[time-slider.git] / usr / share / time-slider / lib / time_slider / setupgui.py~
diff --git a/usr/share/time-slider/lib/time_slider/setupgui.py~ b/usr/share/time-slider/lib/time_slider/setupgui.py~
deleted file mode 100755 (executable)
index b3a37b6..0000000
+++ /dev/null
@@ -1,1322 +0,0 @@
-#!/usr/bin/python2.6
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-import sys
-import os
-import subprocess
-import threading
-import util
-import smf
-from autosnapsmf import enable_default_schedules, disable_default_schedules
-
-from os.path import abspath, dirname, join, pardir
-sys.path.insert(0, join(dirname(__file__), pardir, "plugin"))
-import plugin
-sys.path.insert(0, join(dirname(__file__), pardir, "plugin", "rsync"))
-import rsyncsmf
-
-try:
-    import pygtk
-    pygtk.require("2.4")
-except:
-    pass
-try:
-    import gtk
-    import gtk.glade
-    gtk.gdk.threads_init()
-except:
-    sys.exit(1)
-
-import glib
-import gobject
-import gio
-import dbus
-import dbus.service
-import dbus.mainloop
-import dbus.mainloop.glib
-import dbussvc
-
-
-# This is the rough guess ratio used for rsync backup device size
-# vs. the total size of the pools it's expected to backup.
-RSYNCTARGETRATIO = 2
-
-# here we define the path constants so that other modules can use it.
-# this allows us to get access to the shared files without having to
-# know the actual location, we just use the location of the current
-# file and use paths relative to that.
-SHARED_FILES = os.path.abspath(os.path.join(os.path.dirname(__file__),
-                               os.path.pardir,
-                               os.path.pardir))
-LOCALE_PATH = os.path.join('/usr', 'share', 'locale')
-RESOURCE_PATH = os.path.join(SHARED_FILES, 'res')
-
-# the name of the gettext domain. because we have our translation files
-# not in a global folder this doesn't really matter, setting it to the
-# application name is a good idea tough.
-GETTEXT_DOMAIN = 'time-slider'
-
-# set up the glade gettext system and locales
-gtk.glade.bindtextdomain(GETTEXT_DOMAIN, LOCALE_PATH)
-gtk.glade.textdomain(GETTEXT_DOMAIN)
-
-import zfs
-from timeslidersmf import TimeSliderSMF
-from rbac import RBACprofile
-
-
-class FilesystemIntention:
-
-    def __init__(self, name, selected, inherited):
-        self.name = name
-        self.selected = selected
-        self.inherited = inherited
-
-    def __str__(self):
-        return_string = "Filesystem name: " + self.name + \
-                "\n\tSelected: " + str(self.selected) + \
-                "\n\tInherited: " + str(self.inherited)
-        return return_string
-
-    def __eq__(self, other):
-        if self.name != other.name:
-            return False
-        if self.inherited and other.inherited:
-            return True
-        elif not self.inherited and other.inherited:
-            return False
-        if (self.selected == other.selected) and \
-           (self.inherited == other.inherited):
-            return True
-        else:
-            return False
-
-class SetupManager:
-
-    def __init__(self, execpath):
-        self._execPath = execpath
-        self._datasets = zfs.Datasets()
-        self._xml = gtk.glade.XML("%s/../../glade/time-slider-setup.glade" \
-                                  % (os.path.dirname(__file__)))
-
-        # Tell dbus to use the gobject mainloop for async ops
-        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-        dbus.mainloop.glib.threads_init()
-
-        # Register a bus name with the system dbus daemon
-        systemBus = dbus.SystemBus()
-        busName = dbus.service.BusName("org.opensolaris.TimeSlider.config",
-                                       systemBus)
-        self._dbus = dbussvc.Config(systemBus,
-                                    '/org/opensolaris/TimeSlider/config')
-        # Used later to trigger a D-Bus notification of select configuration 
-        # changes made
-        self._configNotify = False
-
-        # These variables record the initial UI state which are used
-        # later to compare against the UI state when the OK or Cancel
-        # button is clicked and apply the minimum set of necessary 
-        # configuration changes. Prevents minor changes taking ages
-        # to be applied by the GUI.
-        self._initialEnabledState = None
-        self._initialRsyncState = None
-        self._initialRsyncTargetDir = None
-        self._initialCleanupLevel = None
-        self._initialCustomSelection = False
-        self._initialSnapStateDic = {}
-        self._initialRsyncStateDic = {}
-        self._initialFsIntentDic = {}
-        self._initialRsyncIntentDic = {}
-
-        # Currently selected rsync backup device via the GUI.
-        self._newRsyncTargetDir = None
-        # Used to store GUI filesystem selection state and the
-        # set of intended properties to apply to zfs filesystems.
-        self._snapStateDic = {}
-        self._rsyncStateDic = {}
-        self._fsIntentDic = {}
-        self._rsyncIntentDic = {}
-        # Dictionary that maps device ID numbers to zfs filesystem objects
-        self._fsDevices = {}
-
-        topLevel = self._xml.get_widget("toplevel")
-        self._pulseDialog = self._xml.get_widget("pulsedialog")
-        self._pulseDialog.set_transient_for(topLevel)
-        
-        # gio.VolumeMonitor reference
-        self._vm = gio.volume_monitor_get()
-        self._vm.connect("mount-added", self._mount_added)
-        self._vm.connect("mount-removed" , self._mount_removed)
-
-        self._fsListStore = gtk.ListStore(bool,
-                                         bool,
-                                         str,
-                                         str,
-                                         gobject.TYPE_PYOBJECT)
-        filesystems = self._datasets.list_filesystems()
-        for fsname,fsmountpoint in filesystems:
-            if (fsmountpoint == "legacy"):
-                mountpoint = _("Legacy")
-            else:
-                mountpoint = fsmountpoint
-            fs = zfs.Filesystem(fsname, fsmountpoint)
-            # Note that we don't deal with legacy mountpoints.
-            if fsmountpoint != "legacy" and fs.is_mounted():
-                self._fsDevices[os.stat(fsmountpoint).st_dev] = fs
-            snap = fs.get_auto_snap()
-            rsyncstr = fs.get_user_property(rsyncsmf.RSYNCFSTAG)
-            if rsyncstr == "true":
-                rsync = True
-            else:
-                rsync = False
-            # Rsync is only performed on snapshotted filesystems.
-            # So treat as False if rsync is set to true independently
-            self._fsListStore.append([snap, snap & rsync,
-                                     mountpoint, fs.name, fs])
-            self._initialSnapStateDic[fs.name] = snap
-            self._initialRsyncStateDic[fs.name] = snap & rsync
-        del filesystems
-
-        for fsname in self._initialSnapStateDic:
-                self._refine_filesys_actions(fsname,
-                                              self._initialSnapStateDic,
-                                              self._initialFsIntentDic)
-                self._refine_filesys_actions(fsname,
-                                              self._initialRsyncStateDic,
-                                              self._initialRsyncIntentDic)
-   
-        self._fsTreeView = self._xml.get_widget("fstreeview")
-        self._fsTreeView.set_sensitive(False)
-        self._fsTreeView.set_size_request(10, 200)
-
-        self._fsTreeView.set_model(self._fsListStore)
-
-        cell0 = gtk.CellRendererToggle()
-        cell1 = gtk.CellRendererToggle()
-        cell2 = gtk.CellRendererText()
-        cell3 = gtk.CellRendererText()
-        radioColumn = gtk.TreeViewColumn(_("Select"),
-                                             cell0, active=0)
-        self._fsTreeView.insert_column(radioColumn, 0)
-
-        self._rsyncRadioColumn = gtk.TreeViewColumn(_("Replicate"),
-                                                    cell1, active=1)
-        nameColumn = gtk.TreeViewColumn(_("Mount Point"),
-                                        cell2, text=2)
-        self._fsTreeView.insert_column(nameColumn, 2)
-        mountPointColumn = gtk.TreeViewColumn(_("File System Name"),
-                                              cell3, text=3)
-        self._fsTreeView.insert_column(mountPointColumn, 3)
-        cell0.connect('toggled', self._row_toggled)
-        cell1.connect('toggled', self._rsync_cell_toggled)
-        advancedBox = self._xml.get_widget("advancedbox")
-        advancedBox.connect('unmap', self._advancedbox_unmap)  
-
-        self._rsyncSMF = rsyncsmf.RsyncSMF("%s:rsync" \
-                                          %(plugin.PLUGINBASEFMRI))
-        state = self._rsyncSMF.get_service_state()
-        self._initialRsyncTargetDir = self._rsyncSMF.get_target_dir()
-        # Check for the default, unset value of "" from SMF.
-        if self._initialRsyncTargetDir == '""':
-            self._initialRsyncTargetDir = ''
-        self._newRsyncTargetDir = self._initialRsyncTargetDir
-        self._smfTargetKey = self._rsyncSMF.get_target_key()
-        self._newRsyncTargetSelected = False
-        sys,self._nodeName,rel,ver,arch = os.uname()
-
-        # Model columns:
-        # 0 Themed icon list (python list)
-        # 1 device root
-        # 2 volume name
-        # 3 Is gio.Mount device
-        # 4 Is separator (for comboBox separator rendering)
-        self._rsyncStore = gtk.ListStore(gobject.TYPE_PYOBJECT,
-                                         gobject.TYPE_STRING,
-                                         gobject.TYPE_STRING,
-                                         gobject.TYPE_BOOLEAN,
-                                         gobject.TYPE_BOOLEAN)
-        self._rsyncCombo = self._xml.get_widget("rsyncdevcombo")
-        mounts = self._vm.get_mounts()
-        for mount in mounts:
-            self._mount_added(self._vm, mount)
-        if len(mounts) > 0:
-            # Add a separator
-            self._rsyncStore.append((None, None, None, None, True))
-        del mounts
-
-        if len(self._newRsyncTargetDir) == 0:
-            self._rsyncStore.append((['folder'],
-                                    _("(None)"),
-                                    '',
-                                    False,
-                                    False))
-            # Add a separator
-            self._rsyncStore.append((None, None, None, None, True))
-        self._rsyncStore.append((None, _("Other..."), "Other", False, False))
-        self._iconCell = gtk.CellRendererPixbuf()
-        self._nameCell = gtk.CellRendererText()
-        self._rsyncCombo.clear()
-        self._rsyncCombo.pack_start(self._iconCell, False)
-        self._rsyncCombo.set_cell_data_func(self._iconCell,
-                                            self._icon_cell_render)
-        self._rsyncCombo.pack_end(self._nameCell)
-        self._rsyncCombo.set_attributes(self._nameCell, text=1)
-        self._rsyncCombo.set_row_separator_func(self._row_separator)
-        self._rsyncCombo.set_model(self._rsyncStore)
-        self._rsyncCombo.connect("changed", self._rsync_combo_changed)
-        # Force selection of currently configured device
-        self._rsync_dev_selected(self._newRsyncTargetDir)
-
-        # signal dictionary    
-        dic = {"on_ok_clicked" : self._on_ok_clicked,
-               "on_cancel_clicked" : gtk.main_quit,
-               "on_snapshotmanager_delete_event" : gtk.main_quit,
-               "on_enablebutton_toggled" : self._on_enablebutton_toggled,
-               "on_rsyncbutton_toggled" : self._on_rsyncbutton_toggled,
-               "on_defaultfsradio_toggled" : self._on_defaultfsradio_toggled,
-               "on_selectfsradio_toggled" : self._on_selectfsradio_toggled,
-               "on_deletesnapshots_clicked" : self._on_deletesnapshots_clicked}
-        self._xml.signal_autoconnect(dic)
-
-        if state != "disabled":
-            self._rsyncEnabled = True
-            self._xml.get_widget("rsyncbutton").set_active(True)
-            self._initialRsyncState = True
-        else:
-            self._rsyncEnabled = False
-            self._rsyncCombo.set_sensitive(False)
-            self._initialRsyncState = False
-
-        # Initialise SMF service instance state.
-        try:
-            self._sliderSMF = TimeSliderSMF()
-        except RuntimeError,message:
-            self._xml.get_widget("toplevel").set_sensitive(False)
-            dialog = gtk.MessageDialog(self._xml.get_widget("toplevel"),
-                                       0,
-                                       gtk.MESSAGE_ERROR,
-                                       gtk.BUTTONS_CLOSE,
-                                       _("Snapshot manager service error"))
-            dialog.format_secondary_text(_("The snapshot manager service does "
-                                         "not appear to be installed on this "
-                                         "system."
-                                         "\n\nSee the svcs(1) man page for more "
-                                         "information."
-                                         "\n\nDetails:\n%s")%(message))
-            dialog.set_icon_name("time-slider-setup")
-            dialog.run()
-            sys.exit(1)
-
-        if self._sliderSMF.svcstate == "disabled":
-            self._xml.get_widget("enablebutton").set_active(False)
-            self._initialEnabledState = False
-        elif self._sliderSMF.svcstate == "offline":
-            self._xml.get_widget("toplevel").set_sensitive(False)
-            errors = ''.join("%s\n" % (error) for error in \
-                self._sliderSMF.find_dependency_errors())
-            dialog = gtk.MessageDialog(self._xml.get_widget("toplevel"),
-                                        0,
-                                        gtk.MESSAGE_ERROR,
-                                        gtk.BUTTONS_CLOSE,
-                                        _("Snapshot manager service dependency error"))
-            dialog.format_secondary_text(_("The snapshot manager service has "
-                                            "been placed offline due to a dependency "
-                                            "problem. The following dependency problems "
-                                            "were found:\n\n%s\n\nRun \"svcs -xv\" from "
-                                            "a command prompt for more information about "
-                                            "these dependency problems.") % errors)
-            dialog.set_icon_name("time-slider-setup")
-            dialog.run()
-            sys.exit(1)
-        elif self._sliderSMF.svcstate == "maintenance":
-            self._xml.get_widget("toplevel").set_sensitive(False)
-            dialog = gtk.MessageDialog(self._xml.get_widget("toplevel"),
-                                        0,
-                                        gtk.MESSAGE_ERROR,
-                                        gtk.BUTTONS_CLOSE,
-                                        _("Snapshot manager service error"))
-            dialog.format_secondary_text(_("The snapshot manager service has "
-                                            "encountered a problem and has been "
-                                            "disabled until the problem is fixed."
-                                            "\n\nSee the svcs(1) man page for more "
-                                            "information."))
-            dialog.set_icon_name("time-slider-setup")
-            dialog.run()
-            sys.exit(1)
-        else:
-            # FIXME: Check transitional states 
-            self._xml.get_widget("enablebutton").set_active(True)
-            self._initialEnabledState = True
-
-
-        # Emit a toggled signal so that the initial GUI state is consistent
-        self._xml.get_widget("enablebutton").emit("toggled")
-        # Check the snapshotting policy (UserData (default), or Custom)
-        self._initialCustomSelection = self._sliderSMF.is_custom_selection()
-        if self._initialCustomSelection == True:
-            self._xml.get_widget("selectfsradio").set_active(True)
-            # Show the advanced controls so the user can see the
-            # customised configuration.
-            if self._sliderSMF.svcstate != "disabled":
-                self._xml.get_widget("expander").set_expanded(True)
-        else: # "false" or any other non "true" value
-            self._xml.get_widget("defaultfsradio").set_active(True)
-
-        # Set the cleanup threshhold value
-        spinButton = self._xml.get_widget("capspinbutton")
-        critLevel = self._sliderSMF.get_cleanup_level("critical")
-        warnLevel = self._sliderSMF.get_cleanup_level("warning")
-
-        # Force the warning level to something practical
-        # on the lower end, and make it no greater than the
-        # critical level specified in the SVC instance.
-        spinButton.set_range(70, critLevel)
-        self._initialCleanupLevel = warnLevel
-        if warnLevel > 70:
-            spinButton.set_value(warnLevel)
-        else:
-            spinButton.set_value(70)
-
-    def _icon_cell_render(self, celllayout, cell, model, iter):
-        iconList = self._rsyncStore.get_value(iter, 0)
-        if iconList != None:
-            gicon = gio.ThemedIcon(iconList)
-            cell.set_property("gicon", gicon)
-        else:
-            root = self._rsyncStore.get_value(iter, 2)
-            if root == "Other":
-                cell.set_property("gicon", None)
-
-    def _row_separator(self, model, iter):
-        return model.get_value(iter, 4)
-
-    def _mount_added(self, volume_monitor, mount):
-        icon = mount.get_icon()
-        iconList = icon.get_names()
-        if iconList == None:
-            iconList = ['drive-harddisk', 'drive']
-        root = mount.get_root()
-        path = root.get_path()
-        mountName = mount.get_name()
-        volume = mount.get_volume()
-        if volume == None:
-            volName = mount.get_name()
-            if volName == None:
-                volName = os.path.split(path)[1]
-        else:
-            volName = volume.get_name()
-
-        # Check to see if there is at least one gio.Mount device already
-        # in the ListStore. If not, then we also need to add a separator
-        # row.
-        iter = self._rsyncStore.get_iter_first()
-        if iter and self._rsyncStore.get_value(iter, 3) == False:
-            self._rsyncStore.insert(0, (None, None, None, None, True))
-        
-        self._rsyncStore.insert(0, (iconList, volName, path, True, False))
-        # If this happens to be the already configured backup device
-        # and the user hasn't tried to change device yet, auto select
-        # it.
-        if self._initialRsyncTargetDir == self._newRsyncTargetDir:
-            if self._validate_rsync_target(path) == True:
-                self._rsyncCombo.set_active(0)
-
-    def _mount_removed(self, volume_monitor, mount):
-        root = mount.get_root()
-        path = root.get_path()
-        iter = self._rsyncStore.get_iter_first()
-        mountIter = None
-        numMounts = 0
-        # Search gio.Mount devices
-        while iter != None and \
-            self._rsyncStore.get_value(iter, 3) == True:
-            numMounts += 1
-            compPath = self._rsyncStore.get_value(iter, 2)
-            if compPath == path:
-                mountIter = iter
-                break
-            else:
-                iter = self._rsyncStore.iter_next(iter)
-        if mountIter != None:
-            if numMounts == 1:
-                # Need to remove the separator also since
-                # there will be no more gio.Mount devices
-                # shown in the combo box
-                sepIter = self._rsyncStore.iter_next(mountIter)
-                if self._rsyncStore.get_value(sepIter, 4) == True:
-                    self._rsyncStore.remove(sepIter)                  
-            self._rsyncStore.remove(mountIter)
-            iter = self._rsyncStore.get_iter_first()
-            # Insert a custom folder if none exists already
-            if self._rsyncStore.get_value(iter, 2) == "Other":
-                path = self._initialRsyncTargetDir
-                length = len(path)
-                if length > 1:
-                    name = os.path.split(path)[1]
-                elif length == 1:
-                    name = path
-                else: # Indicates path is unset: ''
-                    name = _("(None)")
-                iter = self._rsyncStore.insert_before(iter,
-                                                      (None,
-                                                       None,
-                                                       None,
-                                                       None,
-                                                       True))
-                iter = self._rsyncStore.insert_before(iter,
-                                                      (['folder'],
-                                                       name,
-                                                       path,
-                                                       False,
-                                                       False))
-            self._rsyncCombo.set_active_iter(iter)
-
-    def _monitor_setup(self, pulseBar):
-        if self._enabler.isAlive() == True:
-            pulseBar.pulse()
-            return True
-        else:
-            gtk.main_quit()   
-
-    def _row_toggled(self, renderer, path):
-        model = self._fsTreeView.get_model()
-        iter = model.get_iter(path)
-        state = renderer.get_active()
-        if state == False:
-            self._fsListStore.set_value(iter, 0, True)
-        else:
-            self._fsListStore.set_value(iter, 0, False)
-            self._fsListStore.set_value(iter, 1, False)
-
-    def _rsync_cell_toggled(self, renderer, path):
-        model = self._fsTreeView.get_model()
-        iter = model.get_iter(path)
-        state = renderer.get_active()
-        rowstate = self._fsListStore.get_value(iter, 0)
-        if rowstate == True:
-            if state == False:
-                self._fsListStore.set_value(iter, 1, True)
-            else:
-                self._fsListStore.set_value(iter, 1, False)
-
-    def _rsync_config_error(self, msg):
-        topLevel = self._xml.get_widget("toplevel")
-        dialog = gtk.MessageDialog(topLevel,
-                                    0,
-                                    gtk.MESSAGE_ERROR,
-                                    gtk.BUTTONS_CLOSE,
-                                    _("Unsuitable Backup Location"))
-        dialog.format_secondary_text(msg)
-        dialog.set_icon_name("time-slider-setup")
-        dialog.run()
-        dialog.hide()
-        return
-
-    def _rsync_dev_selected(self, path):
-        iter = self._rsyncStore.get_iter_first()
-        while iter != None:
-            # Break out when we hit a non gio.Mount device
-            if self._rsyncStore.get_value(iter, 3) == False:
-                break
-            compPath = self._rsyncStore.get_value(iter, 2)
-            if compPath == path:
-                self._rsyncCombo.set_active_iter(iter)
-                self._newRsyncTargetDir = path
-                return
-            else:
-                iter = self._rsyncStore.iter_next(iter)
-
-        # Not one of the shortcut RMM devices, so it's
-        # some other path on the filesystem.
-        # iter may be pointing at a separator. Increment
-        # to next row iter if so.
-        if self._rsyncStore.get_value(iter, 4) == True:
-            iter = self._rsyncStore.iter_next(iter)
-
-        if iter != None:
-            if len(path) > 1:
-                name = os.path.split(path)[1]
-            elif len(path) == 1:
-                name = path
-            else: # Indicates path is unset: ''
-                name = _("(None)")
-            # Could be either the custom folder selection
-            # row or the  "Other" row if the custom row
-            # was not created. If "Other" then create the
-            # custom row and separator now at this position
-            if self._rsyncStore.get_value(iter, 2) == "Other":
-                iter = self._rsyncStore.insert_before(iter,
-                                                      (None,
-                                                       None,
-                                                       None,
-                                                       None,
-                                                       True))
-                iter = self._rsyncStore.insert_before(iter,
-                                                      (['folder'],
-                                                       name,
-                                                       path,
-                                                       False,
-                                                       False))
-            else:
-                self._rsyncStore.set(iter,
-                                     1, name,
-                                     2, path)
-            self._rsyncCombo.set_active_iter(iter)
-            self._newRsyncTargetDir = path
-
-    def _rsync_combo_changed(self, combobox):
-        newIter = combobox.get_active_iter()
-        if newIter != None:
-            root = self._rsyncStore.get_value(newIter, 2)
-            if root != "Other":
-                self._newRsyncTargetDir = root
-            else:
-                msg = _("Select A Back Up Device")
-                fileDialog = \
-                    gtk.FileChooserDialog(
-                        msg,
-                        self._xml.get_widget("toplevel"),
-                        gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
-                        (gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,
-                        gtk.STOCK_OK,gtk.RESPONSE_OK),
-                        None)
-                self._rsyncCombo.set_sensitive(False)
-                response = fileDialog.run()
-                fileDialog.hide()
-                if response == gtk.RESPONSE_OK:
-                    gFile = fileDialog.get_file()
-                    self._rsync_dev_selected(gFile.get_path())
-                else:
-                    self._rsync_dev_selected(self._newRsyncTargetDir)
-                self._rsyncCombo.set_sensitive(True)
-
-    def _rsync_size_warning(self, zpools, zpoolSize,
-                             rsyncTarget, targetSize):
-        # Using decimal "GB" instead of binary "GiB"
-        KB = 1000
-        MB = 1000 * KB
-        GB = 1000 * MB
-        TB = 1000 * GB
-
-        suggestedSize = RSYNCTARGETRATIO * zpoolSize
-        if suggestedSize > TB:
-            sizeStr = "%.1f TB" % round(suggestedSize / float(TB), 1)
-        elif suggestedSize > GB:
-            sizeStr = "%.1f GB" % round(suggestedSize / float(GB), 1)
-        else:
-            sizeStr = "%.1f MB" % round(suggestedSize / float(MB), 1)
-
-        if targetSize > TB:
-            targetStr = "%.1f TB" % round(targetSize / float(TB), 1)
-        elif targetSize > GB:
-            targetStr = "%.1f GB" % round(targetSize / float(GB), 1)
-        else:
-            targetStr = "%.1f MB" % round(targetSize / float(MB), 1)
-
-
-        msg = _("Time Slider suggests a device with a capacity of at "
-                "least <b>%s</b>.\n"
-                "The device: \'<b>%s</b>\'\nonly has <b>%s</b>\n"
-                "Do you want to use it anyway?") \
-                % (sizeStr, rsyncTarget, targetStr)
-
-        topLevel = self._xml.get_widget("toplevel")
-        dialog = gtk.MessageDialog(topLevel,
-                                   0,
-                                   gtk.MESSAGE_QUESTION,
-                                   gtk.BUTTONS_YES_NO,
-                                   _("Time Slider"))
-        dialog.set_default_response(gtk.RESPONSE_NO)
-        dialog.set_transient_for(topLevel)
-        dialog.set_markup(msg)
-        dialog.set_icon_name("time-slider-setup")
-
-        response = dialog.run()
-        dialog.hide()
-        if response == gtk.RESPONSE_YES:
-            return True
-        else:
-            return False
-
-    def _check_rsync_config(self):
-        """
-           Checks rsync configuration including, filesystem selection,
-           target directory validation and capacity checks.
-           Returns True if everything is OK, otherwise False.
-           Pops up blocking error dialogs to notify users of error
-           conditions before returning.
-        """
-        def _get_mount_point(path):
-            if os.path.ismount(path):
-                return path
-            else:
-                return _get_mount_point(abspath(join(path, pardir)))
-
-        if self._rsyncEnabled != True:
-            return True
-
-        if len(self._newRsyncTargetDir) == 0:
-            msg = _("No backup device was selected.\n"
-                    "Please select an empty device.")
-            self._rsync_config_error(msg)
-            return False
-        # There's little that can be done if the device is from a
-        # previous configuration and currently offline. So just 
-        # treat it as being OK based on the assumption that it was
-        # previously deemed to be OK.
-        if self._initialRsyncTargetDir == self._newRsyncTargetDir and \
-           not os.path.exists(self._newRsyncTargetDir):
-            return True
-        # Perform the required validation checks on the
-        # target directory.
-        newTargetDir = self._newRsyncTargetDir
-
-        # We require the whole device. So find the enclosing
-        # mount point and inspect from there.
-        targetMountPoint = abspath(_get_mount_point(newTargetDir))
-
-        # Check that it's writable.
-        f = None
-        testFile = os.path.join(targetMountPoint, ".ts-test")
-        try:
-            f = open(testFile, 'w')
-        except (OSError, IOError):
-            msg = _("\'%s\'\n"
-                    "is not writable. The backup device must "
-                    "be writable by the system administrator." 
-                    "\n\nPlease use a different device.") \
-                    % (targetMountPoint)
-            self._rsync_config_error(msg)
-            return False
-        f.close()
-
-        # Try to create a symlink. Rsync requires this to
-        # do incremental backups and to ensure it's posix like
-        # enough to correctly set file ownerships and perms.
-        os.chdir(targetMountPoint)
-        try:
-            os.link(testFile, ".ts-test-link")
-        except OSError:
-            msg = _("\'%s\'\n"
-                    "contains an incompatible file system. " 
-                    "The selected device must have a Unix "
-                    "style file system that supports file "
-                    "linking, such as UFS"
-                    "\n\nPlease use a different device.") \
-                    % (targetMountPoint)
-            self._rsync_config_error(msg)
-            return False
-        finally:
-            os.unlink(testFile)
-        os.unlink(".ts-test-link")
-
-        # Check that selected directory is either empty
-        # or already preconfigured as a backup target
-        sys,nodeName,rel,ver,arch = os.uname()
-        basePath = os.path.join(targetMountPoint,
-                                rsyncsmf.RSYNCDIRPREFIX)
-        nodePath = os.path.join(basePath,
-                                nodeName)
-        configPath = os.path.join(basePath,
-                                    rsyncsmf.RSYNCCONFIGFILE)
-        self._newRsyncTargetSelected = True
-        targetDirKey = None
-
-        contents = os.listdir(targetMountPoint)
-        os.chdir(targetMountPoint)
-
-        # The only other exception to an empty directory is
-        # "lost+found".
-        for item in contents:
-            if (item != rsyncsmf.RSYNCDIRPREFIX and \
-                item != "lost+found") or \
-               not os.path.isdir(item) or \
-               os.path.islink(item):
-                msg = _("\'%s\'\n is not an empty device.\n\n"
-                        "Please select an empty device.") \
-                        % (newTargetDir)
-                self._rsync_config_error(msg)
-                return False
-
-        # Validate existing directory structure
-        if os.path.exists(basePath):
-            # We only accept a pre-existing directory if
-            # 1. It has a config key that matches that stored by
-            #    the rsync plugin's SMF configuration
-            # 2. It has a single subfolder that matches the nodename
-            #    of this system,
-
-            # Check for previous config key
-            if os.path.exists(configPath):
-                f = open(configPath, 'r')
-                for line in f.readlines():
-                    key, val = line.strip().split('=')
-                    if key.strip() == "target_key":
-                        targetDirKey = val.strip()
-                        break
-
-            # Examine anything else in the directory
-            self._targetSelectionError = None
-            dirList = [d for d in os.listdir(basePath) if
-                        d != '.rsync-config']
-            os.chdir(basePath)
-            if len(dirList) > 0:
-                msg = _("\'%s\'\n is not an empty device.\n\n"
-                        "Please select an empty device.") \
-                        % (newTargetDir)
-                # No config key or > 1 directory:
-                # User specified a non empty directory.
-                if targetDirKey == None or len(dirList) > 1:
-                    self._rsync_config_error(msg)
-                    return False
-                # Make sure the single item is not a file or symlink.
-                elif os.path.islink(dirList[0]) or \
-                        os.path.isfile(dirList[0]):
-                    self._rsync_config_error(msg)
-                    return False
-                else:
-                    # Has 1 other item and a config key. Other
-                    # item must be a directory and must match the
-                    # system nodename and SMF's key value respectively
-                    # respectively
-                    if dirList[0] != nodeName and \
-                        targetDirKey != self._smfTargetKey:
-                        msg = _("\'%s\'\n"
-                                "is a Time Slider external backup device "
-                                "that is already in use by another system. "
-                                "Backup devices may not be shared between "
-                                "systems." 
-                                "\n\nPlease use a different device.") \
-                                % (newTargetDir)
-                        self._rsync_config_error(msg)                                
-                        return False
-                    else:
-                        if dirList[0] == nodeName and \
-                           targetDirKey != self._smfTargetKey:
-                            # Looks like a device that we previously used,
-                            # but discontinued using in favour of some other
-                            # device.
-                            msg = _("\'<b>%s</b>\' appears to be a a device "
-                                    "previously configured for use by this "
-                                    "system.\n\nDo you want resume use of "
-                                    "this device for backups?") \
-                                    % (newTargetDir)
-
-                            topLevel = self._xml.get_widget("toplevel")
-                            dialog = gtk.MessageDialog(topLevel,
-                                                       0,
-                                                       gtk.MESSAGE_QUESTION,
-                                                       gtk.BUTTONS_YES_NO,
-                                                       _("Time Slider"))
-                            dialog.set_default_response(gtk.RESPONSE_NO)
-                            dialog.set_transient_for(topLevel)
-                            dialog.set_markup(msg)
-                            dialog.set_icon_name("time-slider-setup")
-
-                            response = dialog.run()
-                            dialog.hide()
-                            if response == gtk.RESPONSE_NO:
-                                return False
-                        else:
-                            # Appears to be our own pre-configured directory.
-                            self._newRsyncTargetSelected = False
-
-        # Compare device ID against selected ZFS filesystems
-        # and their enclosing Zpools. The aim is to avoid
-        # a vicous circle caused by backing up snapshots onto
-        # the same pool the snapshots originate from
-        targetDev = os.stat(newTargetDir).st_dev
-        try:
-            fs = self._fsDevices[targetDev]
-            
-            # See if the filesystem itself is selected
-            # and/or any other fileystem on the pool is 
-            # selected.
-            fsEnabled = self._snapStateDic[fs.name]
-            if fsEnabled == True:
-                # Definitely can't use this since it's a
-                # snapshotted filesystem.
-                msg = _("\'%s\'\n"
-                        "belongs to the ZFS filesystem \'%s\' "
-                        "which is already selected for "
-                        "regular ZFS snaphots." 
-                        "\n\nPlease select a drive "
-                        "not already in use by "
-                        "Time Slider") \
-                        % (newTargetDir, fs.name)
-                self._rsync_config_error(msg)
-                return False
-            else:
-                # See if there is anything else on the pool being
-                # snapshotted
-                poolName = fs.name.split("/", 1)[0]
-                for name,mount in self._datasets.list_filesystems():
-                    if name.find(poolName) == 0:
-                        try:
-                            otherEnabled = self._snapStateDic[name]
-                            radioBtn = self._xml.get_widget("defaultfsradio")
-                            snapAll = radioBtn.get_active()
-                            if snapAll or otherEnabled:
-                                msg = _("\'%s\'\n"
-                                        "belongs to the ZFS pool \'%s\' "
-                                        "which is already being used "
-                                        "to store ZFS snaphots." 
-                                        "\n\nPlease select a drive "
-                                        "not already in use by "
-                                        "Time Slider") \
-                                        % (newTargetDir, poolName)
-                                self._rsync_config_error(msg)
-                                return False
-                        except KeyError:
-                            pass               
-        except KeyError:
-            # No match found - good.
-            pass
-
-
-        # Figure out if there's a reasonable amount of free space to
-        # store backups. This is a vague guess at best.
-        allPools = zfs.list_zpools()
-        snapPools = []
-        # FIXME -  this is for custom selection. There is a short
-        # circuit case for default (All) configuration. Don't forget
-        # to implement this short circuit.
-        for poolName in allPools:
-            try:
-                snapPools.index(poolName)
-            except ValueError:
-                pool = zfs.ZPool(poolName)
-                # FIXME - we should include volumes here but they
-                # can only be set from the command line, not via
-                # the GUI, so not crucial.
-                for fsName,mount in pool.list_filesystems():
-                    # Don't try to catch exception. The filesystems
-                    # are already populated in self._snapStateDic
-                    enabled = self._snapStateDic[fsName]
-                    if enabled == True:
-                        snapPools.append(poolName)
-                        break
-
-        sumPoolSize = 0
-        for poolName in snapPools:
-            pool = zfs.ZPool(poolName)
-            # Rough calcualation, but precise enough for
-            # estimation purposes
-            sumPoolSize += pool.get_used_size()
-            sumPoolSize += pool.get_available_size()
-
-
-        # Compare with available space on rsync target dir
-        targetAvail = util.get_available_size(targetMountPoint)
-        targetUsed = util.get_used_size(targetMountPoint)
-        targetSum = targetAvail + targetUsed
-
-        # Recommended Minimum:
-        # At least double the combined size of all pools with
-        # fileystems selected for backup. Variables include,
-        # frequency of data changes, how much efficiency rsync
-        # sacrifices compared to ZFS' block level diff tracking,
-        # whether compression and/or deduplication are enabled 
-        # on the source pool/fileystem.
-        # We don't try to make calculations based on individual
-        # filesystem selection as there are too many unpredictable
-        # variables to make an estimation of any practical use.
-        # Let the user figure that out for themselves.
-
-        # The most consistent measurement is to use the sum of
-        # available and used size on the target fileystem. We
-        # assume based on previous checks that the target device
-        # is only being used for rsync backups and therefore the
-        # used value consists of existing backups and is. Available
-        # space can be reduced for various reasons including the used
-        # value increasing or for nfs mounted zfs fileystems, other
-        # zfs filesystems on the containing pool using up more space.
-        
-
-        targetPoolRatio = targetSum/float(sumPoolSize)
-        if (targetPoolRatio < RSYNCTARGETRATIO):
-            response = self._rsync_size_warning(snapPools,
-                                                 sumPoolSize,
-                                                 targetMountPoint,
-                                                 targetSum)
-            if response == False:
-                return False
-
-        self._newRsyncTargetDir = targetMountPoint
-        return True
-
-    def _on_ok_clicked(self, widget):
-        # Make sure the dictionaries are empty.
-        self._fsIntentDic = {}
-        self._snapStateDic = {}
-        self._rsyncStateDic = {}
-        enabled = self._xml.get_widget("enablebutton").get_active()
-        self._rsyncEnabled = self._xml.get_widget("rsyncbutton").get_active()
-        if enabled == False:
-            if self._rsyncEnabled == False and \
-               self._initialRsyncState == True:
-                self._rsyncSMF.disable_service()
-            if self._initialEnabledState == True:
-                self._sliderSMF.disable_service()
-            # Ignore other changes to the snapshot/rsync configuration
-            # of filesystems. Just broadcast the change and exit.
-            self._configNotify = True
-            self.broadcast_changes()
-            gtk.main_quit()
-        else:
-            model = self._fsTreeView.get_model()
-            snapalldata = self._xml.get_widget("defaultfsradio").get_active()
-                
-            if snapalldata == True:
-                model.foreach(self._set_fs_selection_state, True)
-                if self._rsyncEnabled == True:
-                    model.foreach(self._set_rsync_selection_state, True)
-            else:
-                model.foreach(self._get_fs_selection_state)
-                model.foreach(self._get_rsync_selection_state)
-            for fsname in self._snapStateDic:
-                self._refine_filesys_actions(fsname,
-                                              self._snapStateDic,
-                                              self._fsIntentDic)
-                if self._rsyncEnabled == True:
-                    self._refine_filesys_actions(fsname,
-                                                  self._rsyncStateDic,
-                                                  self._rsyncIntentDic)
-            if self._rsyncEnabled and \
-               not self._check_rsync_config():
-                    return
-
-            self._pulseDialog.show()
-            self._enabler = EnableService(self)
-            self._enabler.start()
-            glib.timeout_add(100,
-                             self._monitor_setup,
-                             self._xml.get_widget("pulsebar"))
-
-    def _on_enablebutton_toggled(self, widget):
-        expander = self._xml.get_widget("expander")
-        enabled = widget.get_active()
-        self._xml.get_widget("filesysframe").set_sensitive(enabled)
-        expander.set_sensitive(enabled)
-        if (enabled == False):
-            expander.set_expanded(False)
-
-    def _on_rsyncbutton_toggled(self, widget):
-        self._rsyncEnabled = widget.get_active()
-        if self._rsyncEnabled == True:
-            self._fsTreeView.insert_column(self._rsyncRadioColumn, 1)
-            self._rsyncCombo.set_sensitive(True)
-        else:
-            self._fsTreeView.remove_column(self._rsyncRadioColumn)
-            self._rsyncCombo.set_sensitive(False)
-
-    def _on_defaultfsradio_toggled(self, widget):
-        if widget.get_active() == True:
-            self._xml.get_widget("fstreeview").set_sensitive(False)
-
-    def _on_selectfsradio_toggled(self, widget):
-       if widget.get_active() == True:
-            self._xml.get_widget("fstreeview").set_sensitive(True)
-
-    def _advancedbox_unmap(self, widget):
-        # Auto shrink the window by subtracting the frame's height
-        # requistion from the window's height requisition
-        myrequest = widget.size_request()
-        toplevel = self._xml.get_widget("toplevel")
-        toprequest = toplevel.size_request()
-        toplevel.resize(toprequest[0], toprequest[1] - myrequest[1])
-
-    def _get_fs_selection_state(self, model, path, iter):
-        fsname = self._fsListStore.get_value(iter, 3)    
-        enabled = self._fsListStore.get_value(iter, 0)
-        self._snapStateDic[fsname] = enabled
-
-    def _get_rsync_selection_state(self, model, path, iter):
-        fsname = self._fsListStore.get_value(iter, 3)
-        enabled = self._fsListStore.get_value(iter, 1)
-        self._rsyncStateDic[fsname] = enabled
-
-    def _set_fs_selection_state(self, model, path, iter, selected):
-        fsname = self._fsListStore.get_value(iter, 3)
-        self._snapStateDic[fsname] = selected
-
-    def _set_rsync_selection_state(self, model, path, iter, selected):
-        fsname = self._fsListStore.get_value(iter, 3)
-        self._rsyncStateDic[fsname] = selected
-
-    def _refine_filesys_actions(self, fsname, inputdic, actions):
-        selected = inputdic[fsname]
-        try:
-            fstag = actions[fsname]
-            # Found so we can skip over.
-        except KeyError:
-            # Need to check parent value to see if
-            # we should set explicitly or just inherit.
-            path = fsname.rsplit("/", 1)
-            parentName = path[0]
-            if parentName == fsname:
-                # Means this filesystem is the root of the pool
-                # so we need to set it explicitly.
-                actions[fsname] = \
-                    FilesystemIntention(fsname, selected, False)
-            else:
-                parentIntent = None
-                inherit = False
-                # Check if parent is already set and if so whether to
-                # inherit or override with a locally set property value.
-                try:
-                    # Parent has already been registered
-                    parentIntent = actions[parentName]
-                except:
-                    # Parent not yet set, so do that recursively to figure
-                    # out if we need to inherit or set a local property on
-                    # this child filesystem.
-                    self._refine_filesys_actions(parentName,
-                                                  inputdic,
-                                                  actions)
-                    parentIntent = actions[parentName]
-                if parentIntent.selected == selected:
-                    inherit = True
-                actions[fsname] = \
-                    FilesystemIntention(fsname, selected, inherit)
-
-    def _validate_rsync_target(self, path):
-        """
-            Tests path to see if it is the pre-configured
-            rsync backup device path.
-            Returns True on success, otherwise False
-        """
-        # FIXME - this is duplicate in applet.py and rsync-backup.py
-        # It should be moved into a shared module
-        if not os.path.exists(path):
-            return False
-        testDir = os.path.join(path,
-                                rsyncsmf.RSYNCDIRPREFIX,
-                                self._nodeName)
-        testKeyFile = os.path.join(path,
-                                    rsyncsmf.RSYNCDIRPREFIX,
-                                    rsyncsmf.RSYNCCONFIGFILE)
-        if os.path.exists(testDir) and \
-            os.path.exists(testKeyFile):
-            testKeyVal = None
-            f = open(testKeyFile, 'r')
-            for line in f.readlines():
-                key, val = line.strip().split('=')
-                if key.strip() == "target_key":
-                    targetKey = val.strip()
-                    break
-            f.close()
-            if targetKey == self._smfTargetKey:
-                return True
-        return False
-
-
-    def commit_filesystem_selection(self):
-        """
-        Commits the intended filesystem selection actions based on the
-        user's UI configuration to disk. Compares with initial startup
-        configuration and applies the minimum set of necessary changes.
-        """
-        for fsname,fsmountpoint in self._datasets.list_filesystems():
-            fs = zfs.Filesystem(fsname, fsmountpoint)
-            try:
-                initialIntent = self._initialFsIntentDic[fsname]
-                intent = self._fsIntentDic[fsname]
-                if intent == initialIntent:
-                    continue
-                fs.set_auto_snap(intent.selected, intent.inherited)
-
-            except KeyError:
-                pass
-
-    def commit_rsync_selection(self):
-        """
-        Commits the intended filesystem selection actions based on the
-        user's UI configuration to disk. Compares with initial startup
-        configuration and applies the minimum set of necessary changes.
-        """
-        for fsname,fsmountpoint in self._datasets.list_filesystems():
-            fs = zfs.Filesystem(fsname, fsmountpoint)
-            try:
-                initialIntent = self._initialRsyncIntentDic[fsname]
-                intent = self._rsyncIntentDic[fsname]
-                if intent == initialIntent:
-                    continue
-                if intent.inherited == True and \
-                    initialIntent.inherited == False:
-                    fs.unset_user_property(rsyncsmf.RSYNCFSTAG)
-                else:
-                    if intent.selected == True:
-                        value = "true"
-                    else:
-                        value = "false"
-                    fs.set_user_property(rsyncsmf.RSYNCFSTAG,
-                                         value)
-            except KeyError:
-                pass
-
-    def setup_rsync_config(self):
-        if self._rsyncEnabled == True:
-            if self._newRsyncTargetSelected == True:
-                sys,nodeName,rel,ver,arch = os.uname()
-                basePath = os.path.join(self._newRsyncTargetDir,
-                                        rsyncsmf.RSYNCDIRPREFIX,)
-                nodePath = os.path.join(basePath,
-                                        nodeName)
-                configPath = os.path.join(basePath,
-                                          rsyncsmf.RSYNCCONFIGFILE)
-                newKey = generate_random_key()
-                try:
-                    origmask = os.umask(0222)
-                    if not os.path.exists(nodePath):
-                        os.makedirs(nodePath, 0755)
-                    f = open(configPath, 'w')
-                    f.write("target_key=%s\n" % (newKey))
-                    f.close()
-                    os.umask(origmask)
-                except OSError as e:
-                    self._pulseDialog.hide()
-                    sys.stderr.write("Error configuring external " \
-                                     "backup device:\n" \
-                                     "%s\n\nReason:\n %s") \
-                                     % (self._newRsyncTargetDir, str(e))
-                    sys.exit(-1)
-                self._rsyncSMF.set_target_dir(self._newRsyncTargetDir)
-                self._rsyncSMF.set_target_key(newKey)
-                # Applet monitors rsyncTargetDir so make sure to notify it.
-                self._configNotify = True
-        return
-
-    def setup_services(self):
-        # Take care of the rsync plugin service first since time-slider
-        # will query it.
-        # Changes to rsync or time-slider SMF service State should be
-        # broadcast to let notification applet refresh.
-        if self._rsyncEnabled == True and \
-            self._initialRsyncState == False:
-            self._rsyncSMF.enable_service()
-            self._configNotify = True
-        elif self._rsyncEnabled == False and \
-            self._initialRsyncState == True:
-            self._rsyncSMF.disable_service()
-            self._configNotify = True
-        customSelection = self._xml.get_widget("selectfsradio").get_active()
-        if customSelection != self._initialCustomSelection:
-            self._sliderSMF.set_custom_selection(customSelection)
-        if self._initialEnabledState == False:
-            enable_default_schedules()
-            self._sliderSMF.enable_service()
-            self._configNotify = True
-
-    def set_cleanup_level(self):
-        """
-        Wrapper function to set the warning level cleanup threshold
-        value as a percentage of pool capacity.
-        """
-        level = self._xml.get_widget("capspinbutton").get_value_as_int()
-        if level != self._initialCleanupLevel:
-            self._sliderSMF.set_cleanup_level("warning", level)
-
-    def broadcast_changes(self):
-        """
-        Blunt instrument to notify D-Bus listeners such as notification
-        applet to rescan service configuration
-        """
-        if self._configNotify == False:
-            return
-        self._dbus.config_changed()
-
-    def _on_deletesnapshots_clicked(self, widget):
-        cmdpath = os.path.join(os.path.dirname(self._execPath), \
-                               "../lib/time-slider-delete")
-        p = subprocess.Popen(cmdpath, close_fds=True)
-
-
-class EnableService(threading.Thread):
-
-    def __init__(self, setupManager):
-        threading.Thread.__init__(self)
-        self._setupManager = setupManager
-
-    def run(self):
-        try:
-            # Set the service state last so that the ZFS filesystems
-            # are correctly tagged before the snapshot scripts check them
-            self._setupManager.commit_filesystem_selection()
-            self._setupManager.commit_rsync_selection()
-            self._setupManager.set_cleanup_level()
-            self._setupManager.setup_rsync_config()
-            self._setupManager.setup_services()
-            self._setupManager.broadcast_changes()
-        except RuntimeError, message:
-            sys.stderr.write(str(message))
-
-def generate_random_key(length=32):
-    """
-    Returns a 'length' byte character composed of random letters and
-    unsigned single digit integers. Used to create a random
-    signature key to identify pre-configured backup directories
-    for the rsync plugin
-    """
-    from string import letters, digits
-    from random import choice
-    return ''.join([choice(letters + digits) \
-              for i in range(length)])
-
-def main(argv):
-    rbacp = RBACprofile()
-    # The setup GUI needs to be run as root in order to ensure
-    # that the rsync backup target directory is accessible by
-    # root and to perform validation checks on it.
-    # This GUI can be launched with an euid of root in one of
-    # the following 3 ways;
-    # 0. Run by the superuser (root)
-    # 1. Run via gksu to allow a non priviliged user to authenticate
-    #    as the superuser (root)
-
-    if os.geteuid() == 0:
-        manager = SetupManager(argv)
-        gtk.gdk.threads_enter()
-        gtk.main()
-        gtk.gdk.threads_leave()
-    elif os.path.exists(argv) and os.path.exists("/usr/bin/gksu"):
-        # Run via gksu, which will prompt for the root password
-        os.unsetenv("DBUS_SESSION_BUS_ADDRESS")
-        os.execl("/usr/bin/gksu", "gksu", argv)
-        # Shouldn't reach this point
-        sys.exit(1)
-    else:
-        dialog = gtk.MessageDialog(None,
-                                   0,
-                                   gtk.MESSAGE_ERROR,
-                                   gtk.BUTTONS_CLOSE,
-                                   _("Insufficient Priviliges"))
-        dialog.format_secondary_text(_("The snapshot manager service requires "
-                                       "administrative privileges to run. "
-                                       "You have not been assigned the necessary"
-                                       "administrative priviliges."
-                                       "\n\nConsult your system administrator "))
-        dialog.set_icon_name("time-slider-setup")
-        dialog.run()
-        sys.exit(1)
-