pvl/backup/lvm.py
author Tero Marttila <tero.marttila@aalto.fi>
Mon, 28 Jul 2014 13:14:53 +0300
changeset 80 b332d99f988e
parent 69 468704db09c4
permissions -rw-r--r--
update for pvl.args; fixing -c/command and --config option dupliates
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
"""
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
    Simple /sbin/lvm wrapper for handling snapshots.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
"""
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
from pvl.backup.invoke import invoke, optargs, InvokeError
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
import contextlib
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
import os.path
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
import logging
42
43e27a3e9efe pvlbackup-rsync-wrapper: add --snapshot-size / --snapshot-wait opts
Tero Marttila <terom@paivola.fi>
parents: 29
diff changeset
    10
import time
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
log = logging.getLogger('pvl.backup.lvm')
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
42
43e27a3e9efe pvlbackup-rsync-wrapper: add --snapshot-size / --snapshot-wait opts
Tero Marttila <terom@paivola.fi>
parents: 29
diff changeset
    14
# default snapshot size
43e27a3e9efe pvlbackup-rsync-wrapper: add --snapshot-size / --snapshot-wait opts
Tero Marttila <terom@paivola.fi>
parents: 29
diff changeset
    15
LVM_SNAPSHOT_SIZE   = '5G'
43e27a3e9efe pvlbackup-rsync-wrapper: add --snapshot-size / --snapshot-wait opts
Tero Marttila <terom@paivola.fi>
parents: 29
diff changeset
    16
43e27a3e9efe pvlbackup-rsync-wrapper: add --snapshot-size / --snapshot-wait opts
Tero Marttila <terom@paivola.fi>
parents: 29
diff changeset
    17
# number of seconds to wait for lvm snapshot to settle after unmount..
43e27a3e9efe pvlbackup-rsync-wrapper: add --snapshot-size / --snapshot-wait opts
Tero Marttila <terom@paivola.fi>
parents: 29
diff changeset
    18
LVM_SNAPSHOT_WAIT   = 5
43e27a3e9efe pvlbackup-rsync-wrapper: add --snapshot-size / --snapshot-wait opts
Tero Marttila <terom@paivola.fi>
parents: 29
diff changeset
    19
61
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
    20
# number of times to retry removal, due to lvm/udev bug..
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
    21
LVM_SNAPSHOT_RETRY  = 5
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
    22
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
class LVMError (Exception) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
    pass
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    26
class LVM (object) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
    """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
        LVM VolumeGroup
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
    """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
    # path to lvm2 binary
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
    LVM = '/sbin/lvm'
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    33
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    34
    
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    35
    # VG name
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    36
    name = None
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    37
69
468704db09c4 pvl.backup.mount/lvm: implement optional sudo invoke
Tero Marttila <terom@paivola.fi>
parents: 61
diff changeset
    38
    def __init__ (self, name, sudo=None) :
468704db09c4 pvl.backup.mount/lvm: implement optional sudo invoke
Tero Marttila <terom@paivola.fi>
parents: 61
diff changeset
    39
        """
468704db09c4 pvl.backup.mount/lvm: implement optional sudo invoke
Tero Marttila <terom@paivola.fi>
parents: 61
diff changeset
    40
            name    - VG name
468704db09c4 pvl.backup.mount/lvm: implement optional sudo invoke
Tero Marttila <terom@paivola.fi>
parents: 61
diff changeset
    41
            sudo    - invoke sudo
468704db09c4 pvl.backup.mount/lvm: implement optional sudo invoke
Tero Marttila <terom@paivola.fi>
parents: 61
diff changeset
    42
        """
468704db09c4 pvl.backup.mount/lvm: implement optional sudo invoke
Tero Marttila <terom@paivola.fi>
parents: 61
diff changeset
    43
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
        self.name = name
69
468704db09c4 pvl.backup.mount/lvm: implement optional sudo invoke
Tero Marttila <terom@paivola.fi>
parents: 61
diff changeset
    45
        self.sudo = sudo
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
    def lv_name (self, lv) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
            vg/lv name.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
        return '{vg}/{lv}'.format(vg=self.name, lv=lv)
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    53
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    54
    def lv_path (self, lv) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
            /dev/vg/lv path.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    59
        return '/dev/{vg}/{lv}'.format(vg=self.name, lv=lv)
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
    def command (self, cmd, *args, **opts) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
            Invoke a command with options/arguments, given via Python arguments/keyword arguments
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
        
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
        log.debug("{cmd} {opts} {args}".format(cmd=cmd, args=args, opts=opts))
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    68
        # invoke
69
468704db09c4 pvl.backup.mount/lvm: implement optional sudo invoke
Tero Marttila <terom@paivola.fi>
parents: 61
diff changeset
    69
        invoke(self.LVM, [cmd] + optargs(*args, **opts), sudo=self.sudo)
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
    def volume (self, name) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
            Return an LVMVolume for given named LV.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
        return LVMVolume(self, name)
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
    @contextlib.contextmanager
61
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
    79
    def snapshot (self, base, wait=LVM_SNAPSHOT_WAIT, retry=LVM_SNAPSHOT_RETRY, **opts) :
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    80
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
            A Context Manager for handling an LVMSnapshot.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
            See LVMSnapshot.create()
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
            with lvm.snapshot(lv) as snapshot : ...
42
43e27a3e9efe pvlbackup-rsync-wrapper: add --snapshot-size / --snapshot-wait opts
Tero Marttila <terom@paivola.fi>
parents: 29
diff changeset
    86
43e27a3e9efe pvlbackup-rsync-wrapper: add --snapshot-size / --snapshot-wait opts
Tero Marttila <terom@paivola.fi>
parents: 29
diff changeset
    87
                wait        - wait given interval for the snapshot device to settle before unmounting it
61
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
    88
                retry       - retry removal given number of times
42
43e27a3e9efe pvlbackup-rsync-wrapper: add --snapshot-size / --snapshot-wait opts
Tero Marttila <terom@paivola.fi>
parents: 29
diff changeset
    89
                **opts      - LVMSnapshot.create() options (e.g. size)
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    91
61
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
    92
        log.debug("creating snapshot from {base}: wait={wait}, retry={retry} {opts}".format(base=base, wait=wait, retry=retry, opts=opts))
42
43e27a3e9efe pvlbackup-rsync-wrapper: add --snapshot-size / --snapshot-wait opts
Tero Marttila <terom@paivola.fi>
parents: 29
diff changeset
    93
        snapshot = LVMSnapshot.create(self, base, **opts)
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
        try :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    96
            log.debug("got: {0}".format(snapshot))
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
            yield snapshot
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
        finally:
61
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   100
            # XXX: there's some common udev bug with removing lvm snapshots
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   101
            #       https://bugzilla.redhat.com/show_bug.cgi?id=577798
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   102
            #       http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=618016
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   103
            #       possibly fixed in lvm2 2.02.86?
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   104
            # try to just patiently wait for it to settle down... then retry... if this isn't enough, we need some dmremove magic?
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   105
            while True :
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   106
                # wait..
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   107
                if wait :
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   108
                    log.debug("%s: cleanup: waiting %.2f seconds for snapshot volume to settle...", snapshot, wait)
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   109
                    time.sleep(wait)
29
5abd153d78eb lvm: try and workaround an umount -> lvremove udev timing bug with a time.sleep(1)
Tero Marttila <terom@paivola.fi>
parents: 10
diff changeset
   110
61
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   111
                # lvremove
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   112
                try :
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   113
                    log.debug("%s: cleanup", snapshot)
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   114
                    snapshot.close()
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   115
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   116
                except InvokeError as ex :
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   117
                    if ex.exit != 5 :
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   118
                        # lvremove sez "Can't remove open logical volume ..." -> exit(5);
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   119
                        raise
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   120
                    
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   121
                    # retry counter?
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   122
                    if retry :
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   123
                        log.warn("%s: cleanup: lvremove failed, retrying...", snapshot)
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   124
                        retry -= 1
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   125
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   126
                        # retry
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   127
                        continue
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   128
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   129
                    else :
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   130
                        # failed
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   131
                        log.error("%s: cleanup: lvremove failed, aborting...", snapshot)
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   132
                        raise
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   133
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   134
                else :
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   135
                    # done
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   136
                    break
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   137
10
724a90bd77b5 fixup __str__s
Tero Marttila <terom@paivola.fi>
parents: 5
diff changeset
   138
    def __str__ (self) :
724a90bd77b5 fixup __str__s
Tero Marttila <terom@paivola.fi>
parents: 5
diff changeset
   139
        return self.name
724a90bd77b5 fixup __str__s
Tero Marttila <terom@paivola.fi>
parents: 5
diff changeset
   140
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   141
    def __repr__ (self) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   142
        return "LVM(name={name})".format(name=repr(self.name))
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   143
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   144
class LVMVolume (object) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   145
    """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   146
        LVM Logical Volume.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   147
    """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   148
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   149
    # VG
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   150
    lvm = None
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   151
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   152
    # name
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   153
    name = None
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   154
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   155
    def __init__ (self, lvm, name) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   156
        self.lvm = lvm
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   157
        self.name = name
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   158
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   159
    @property
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   160
    def lvm_path (self) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   161
        return self.lvm.lv_name(self.name)
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   162
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   163
    @property
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   164
    def dev_path (self) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   165
        return self.lvm.lv_path(self.name)
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   166
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   167
    def verify_exists (self) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   168
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   169
            Verify that the LV exists.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   170
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   171
            Raises an LVMError otherwise.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   172
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   173
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   174
        # lvdisplay
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   175
        try :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   176
            self.lvm.command('lvs', self.lvm_path)
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   177
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   178
        except InvokeError :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   179
            raise LVMError("Unable to lvdisplay LV: {path}".format(path=self.lvm_path))
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   180
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   181
        # dev
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   182
        if not self.test_dev() :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   183
            raise LVMError("LV dev does not exist: {path}".format(path=self.dev_path))
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   184
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   185
    def verify_missing (self) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   186
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   187
            Verify that the LV does NOT exist.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   188
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   189
            Raises an LVMError otherwise.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   190
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   191
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   192
        if self.test_dev() :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   193
            raise Exception("LV already exists: {path}".format(path=self.dev_path))
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   194
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   195
    def test_dev (self) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   196
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   197
            Tests for existance of device file, returning True/False.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   198
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   199
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   200
        return os.path.exists(self.dev_path)
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   201
10
724a90bd77b5 fixup __str__s
Tero Marttila <terom@paivola.fi>
parents: 5
diff changeset
   202
    def __str__ (self) :
724a90bd77b5 fixup __str__s
Tero Marttila <terom@paivola.fi>
parents: 5
diff changeset
   203
        return self.lvm_path
724a90bd77b5 fixup __str__s
Tero Marttila <terom@paivola.fi>
parents: 5
diff changeset
   204
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   205
    def __repr__ (self) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   206
        return "LVMVolume(lvm={lvm}, name={name})".format(
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   207
                lvm     = repr(self.lvm),
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   208
                name    = repr(self.name),
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   209
        )
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   210
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   211
class LVMSnapshot (LVMVolume) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   212
    """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   213
        LVM snapshot
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   214
    """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   215
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   216
    # base lv
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   217
    base = None
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   218
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   219
    @classmethod
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   220
    def create (cls, lvm, base, tag, size=LVM_SNAPSHOT_SIZE) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   221
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   222
            Create a new LVM snapshot of the given LV.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   223
            
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   224
            Returns a (snapshot_name, dev_path) tuple.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   225
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   226
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   227
        # snapshot name
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   228
        name = '{name}-{tag}'.format(name=base.name, tag=tag)
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   229
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   230
        # snapshot instance
42
43e27a3e9efe pvlbackup-rsync-wrapper: add --snapshot-size / --snapshot-wait opts
Tero Marttila <terom@paivola.fi>
parents: 29
diff changeset
   231
        snapshot = cls(lvm, base, name, size=size)
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   232
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   233
        ## verify
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   234
        # base should exist
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   235
        base.verify_exists()
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   236
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   237
        # snapshot should not
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   238
        snapshot.verify_missing()
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   239
        
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   240
        ## create
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   241
        snapshot.open()
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   242
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   243
        # verify
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   244
        if not snapshot.test_dev() :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   245
            raise LVMError("Failed to find new snapshot LV device: {path}".format(path=snapshot.dev_path))
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   246
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   247
        # yay
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   248
        return snapshot
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   249
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   250
    def __init__ (self, lvm, base, name, size=LVM_SNAPSHOT_SIZE) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   251
        LVMVolume.__init__(self, lvm, name)
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   252
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   253
        self.base = base
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   254
        self.size = size
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   255
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   256
    def open (self) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   257
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   258
            Create snapshot volume.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   259
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   260
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   261
        # create
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   262
        self.lvm.command('lvcreate', self.base.lvm_path, snapshot=True, name=self.name, size=self.size)
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   263
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   264
    def close (self) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   265
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   266
            Remove snapshot volume.
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   267
        """
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   268
61
4fdf70cbc9b0 pvl.backup.lvm: snapshot: retry removal if fails with exit == 5 ("Can't remove open logical volume ...")
Tero Marttila <terom@paivola.fi>
parents: 42
diff changeset
   269
        # don't typo me!
5
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   270
        self.lvm.command('lvremove', '-f', self.lvm_path)
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   271
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   272
    def __repr__ (self) :
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   273
        return "LVMSnapshot(lvm={lvm}, base={base}, name={name})".format(
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   274
                lvm     = str(self.lvm),
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   275
                base    = str(self.base),
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   276
                name    = repr(self.name),
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   277
        )
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   278
23371d26fdd0 split up into pvl.backup package
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   279