Permalink
Browse files

2010-05-14 Niall Power - <niall.power@oracle.com>

        * etc/dbus-1/system.d/time-slider.conf:
          Add service and policy definitions for TimSlider.config
          service.

        * usr/share/time-slider/lib/plugin/rsync/backup.py:
          Deal with backup device being mounted under variable
          removable media mount points if not found in it's expected
          location. Find and validate alternate mount points.

        * usr/share/time-slider/lib/time_slider/applet.py:
          Refactored to allow more modular notification management.
          Improved rsync device monitoring by implementing both gio.File
          and gio.Volume monitors so we can track mounting/unmounting of
          static mounts like nfs/zfs and variable mount points for
          hotpluggable devices. Validate rsync target is correct using
          SMF configuration key. Listen to TimeSlider.Config D-Bus events
          and refresh configuration when D-Bus notification is received.
          Add menu item to enable launching of setup GUI from the applet.

        * usr/share/time-slider/lib/time_slider/dbussvc.py:
          Add class and method definition for TimeSlider Config service
          notifications.

        * usr/share/time-slider/lib/time_slider/setupgui.py:
          Register with system D-Bus and send notification of changes
          to time-slider and rsync plugin services so the applet can
          refresh.
  • Loading branch information...
1 parent e2ffe8a commit 14650af81e1e147e99826d9adc41c699d5ada76b @NiallPower NiallPower committed May 13, 2010
View
@@ -1,3 +1,33 @@
+2010-05-14 Niall Power - <niall.power@oracle.com>
+
+ * etc/dbus-1/system.d/time-slider.conf:
+ Add service and policy definitions for TimSlider.config
+ service.
+
+ * usr/share/time-slider/lib/plugin/rsync/backup.py:
+ Deal with backup device being mounted under variable
+ removable media mount points if not found in it's expected
+ location. Find and validate alternate mount points.
+
+ * usr/share/time-slider/lib/time_slider/applet.py:
+ Refactored to allow more modular notification management.
+ Improved rsync device monitoring by implementing both gio.File
+ and gio.Volume monitors so we can track mounting/unmounting of
+ static mounts like nfs/zfs and variable mount points for
+ hotpluggable devices. Validate rsync target is correct using
+ SMF configuration key. Listen to TimeSlider.Config D-Bus events
+ and refresh configuration when D-Bus notification is received.
+ Add menu item to enable launching of setup GUI from the applet.
+
+ * usr/share/time-slider/lib/time_slider/dbussvc.py:
+ Add class and method definition for TimeSlider Config service
+ notifications.
+
+ * usr/share/time-slider/lib/time_slider/setupgui.py:
+ Register with system D-Bus and send notification of changes
+ to time-slider and rsync plugin services so the applet can
+ refresh.
+
2010-05-13 Niall Power - <niall.power@oracle.com>
* usr/share/time-slider/lib/plugin/rsync/backup.py:
@@ -19,6 +19,14 @@
<allow own="org.opensolaris.TimeSlider.plugin.rsync"/>
</policy>
+ <!-- Only root or user zfssnap can own the config service -->
+ <policy user="zfssnap">
+ <allow own="org.opensolaris.TimeSlider.config"/>
+ </policy>
+ <policy user="root">
+ <allow own="org.opensolaris.TimeSlider.config"/>
+ </policy>
+
<!-- Allow anyone to invoke methods on time-sliderd -->
<policy context="default">
<allow send_destination="org.opensolaris.TimeSlider"/>
@@ -31,4 +39,10 @@
<allow receive_sender="org.opensolaris.TimeSlider.plugin.rsync"/>
</policy>
+ <!-- Allow anyone to invoke methods on the config service -->
+ <policy context="default">
+ <allow send_destination="org.opensolaris.TimeSlider.config"/>
+ <allow receive_sender="org.opensolaris.TimeSlider.config"/>
+ </policy>
+
</busconfig>
@@ -32,6 +32,7 @@
import math
import syslog
import gobject
+import gio
import dbus
import shutil
import copy
@@ -255,22 +256,20 @@ def __init__(self, fmri, dbus, mainLoop=None):
"<rsync/cleanup_threshold>: %d." \
"Using default value of 95%" \
% (self._cleanupThreshold))
- # Determine the rsync backup dir. This is the target dir
- # defined by the SMF instance plus the "TIMESLIDER/<nodename>"
- # suffix
- self._rsyncBaseDir = self._smfInst.get_target_dir()
- sys,nodeName,rel,ver,arch = os.uname()
- self._rsyncDir = os.path.join(self._rsyncBaseDir,
- rsyncsmf.RSYNCDIRPREFIX,
- nodeName)
- self._keyFile = os.path.join(self._rsyncBaseDir,
- rsyncsmf.RSYNCDIRPREFIX,
- rsyncsmf.RSYNCCONFIGFILE)
+
+ # Base variables for backup device. Will be initialised
+ # later in _find_backup_device()
self._smfTargetKey = self._smfInst.get_target_key()
+ sys,self._nodeName,rel,ver,arch = os.uname()
+ self._rsyncBaseDir = None
+ self._rsyncDir = None
+ self._keyFile = None
+
tsSMF = timeslidersmf.TimeSliderSMF()
self._labelSeparator = tsSMF.get_separator()
del tsSMF
-
+ # Finally go look for the backup device
+ self._find_backup_device()
def empty_trash_folders(self):
trashDirs = []
@@ -412,6 +411,73 @@ def _discover_backups(self):
insort(self._backups, [long(mtime), os.path.abspath(d)])
self._backupTimes[dirName][d] = mtime
+ def _find_backup_device(self):
+ # Determine the rsync backup dir. This is the target dir
+ # defined by the SMF instance plus the "TIMESLIDER/<nodename>"
+ # suffix. Try finding it at the preconfigured path first,
+ # then failing that, scan removable media mounts, in case it
+ # got remounted under a different path than at setup time.
+ self._rsyncBaseDir = None
+ path = self._smfInst.get_target_dir()
+ if self._validate_rsync_target(path) == True:
+ self._rsyncBaseDir = path
+ util.debug("Backup target device online: %s" % (path),
+ self._verbose)
+ else:
+ util.debug("Backup target device not mounted at: %s" \
+ "Scanning removable devices.." \
+ % (path),
+ self._verbose)
+ volMonitor = gio.volume_monitor_get()
+ mounts = volMonitor.get_mounts()
+ for mount in mounts:
+ root = mount.get_root()
+ path = root.get_path()
+ if self._validate_rsync_target(path) == True:
+ util.debug("Located backup target device at: %s" \
+ % (path),
+ self._verbose)
+ self._rsyncBaseDir = path
+
+ if self._rsyncBaseDir != None:
+ self._rsyncDir = os.path.join(self._rsyncBaseDir,
+ rsyncsmf.RSYNCDIRPREFIX,
+ self._nodeName)
+ self._keyFile = os.path.join(self._rsyncBaseDir,
+ rsyncsmf.RSYNCDIRPREFIX,
+ rsyncsmf.RSYNCCONFIGFILE)
+
+
+ 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 the applet and 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 _find_deleteable_backups(self, timestamp):
"""
Returns a list of backup directory paths that are older than
@@ -585,42 +651,19 @@ def _recover_space(self, deleteables):
def backup_snapshot(self):
# First, check to see if the rsync destination
# directory is accessible.
- try:
- os.stat(self._rsyncDir)
- except OSError:
- util.debug("Backup target directory is not " \
+
+ if self._rsyncBaseDir == None:
+ util.debug("Backup target device is not " \
"accessible right now: %s" \
- % (self._rsyncDir),
+ % (self._smfInst.get_target_dir()),
self._verbose)
self._bus.rsync_unsynced(len(self._pendingList))
if self._mainLoop:
self._mainLoop.quit()
sys.exit(0)
- # Check its config key matches what's recorded in SMF
- try:
- os.stat(self._keyFile)
- except OSError:
- util.debug("Backup target directory has no" \
- "configuration file. Possibly wrong " \
- "or misconfigured device: %s" \
- % (self._keyFile),
- self._verbose)
- self._bus.rsync_unsynced(len(self._pendingList))
- if self._mainLoop:
- self._mainLoop.quit()
- sys.exit(0)
-
- targetKey = None
- f = open(self._keyFile, '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:
+ # Extra paranoia
+ if self._validate_rsync_target(self._rsyncBaseDir) == False:
util.debug("Backup target directory does not " \
"have a matching configuration key. " \
"Possibly old or wrong device: %s" \
Oops, something went wrong.

0 comments on commit 14650af

Please sign in to comment.