バックアップをとろう(その2)

ちょっと長いけど、ここまでで出来上がったソース
backup.py

#!/usr/bin/python
# -*- coding:utf-8 -*-

import sys
from subprocess import call,Popen,PIPE
import os

def main():
    """
    文字列変数 partition 
    バックアップ対象となる論理ボリューム名や 物理パーティション名とし、
    実行時にコマンドラインから渡されるものをそのまま使用します
    """
    for partition in sys.argv[1:]:

       # どのパーティションを処理するのかを表示しておきます 
        print "[" + partition + "]"

        ###########################################################
        # 変数定義
        ###########################################################

        """
        bool変数 is_ROOT
        このプロセスの実行idが0ならTrue。そうでなければFalseとなる
        """
        is_ROOT = True
        if os.getuid() != 0:
            is_ROOT = False
 
        """
        文字列 mnt_root
        バックアップを取るパーティションをマウントする時のルート
        このプロセスを実行するユーザーのホームディレクトリとします
        """
        mnt_root = os.getenv('HOME')

        """
        文字列 source_volume
        バックアップ元となる論理ボリュームもしくは物理パーティション
        の名前を格納します
        """
        source_volume = "/dev/eltro/" + partition

        """
        文字列 dest_volume
        バックアップ先となる論理ボリュームもしくは物理パーティション
        の名前を格納します
        """
        dest_volume = "/dev/raid5/" + partition

        """
        文字列 source_mtpt 
        バックアップ元のマウントポイント
        """
        source_mtpt = mnt_root + "/src/" + partition

        """
        文字列 dest_mtpt 
        バックアップ先のマウントポイント
        """
        dest_mtpt = mnt_root + "/dst/" + partition

        #もし、source_mtpt,dest_mtptが存在しなければ、作成します
        for p in (source_mtpt,dest_mtpt):
            if os.path.exists(p) == False:
                os.makedirs(p)
        
        """
        リスト need_sudo
        プロセスIDが0以外の時に、sudoをつけて実行される必要の
        ある外部コマンドを格納するリスト
        """
        need_sudo = []
        
        ###########################################################
        # スクリプト内で使用する外部コマンドを定義します
        ###########################################################
        
        # mount
        # sudoが必要です
        mount_cmd = ["/bin/mount", "-v"]
        need_sudo.append(mount_cmd)

        # copy files
        # sudoは必ずしも必要ではないが、あった方がいいです
        rsync_cmd = ["/usr/bin/rsync","-av","--delete"]
        need_sudo.append(rsync_cmd)

        # umount
        # sudoが必要です
        umount_cmd = ["/bin/umount", "-v"]   
        need_sudo.append(umount_cmd)

        # chcp
        # sudoが必要です
        chcp_cmd = ["/usr/bin/chcp","ss",source_volume]
        need_sudo.append(chcp_cmd)

        # lscp
        # sudoは必要ありません
        lscp_cmd = ["/usr/bin/lscp","-r","-n1",source_volume]

        # 非rootユーザーがこのスクリプトを実行した場合に必要な処理をします
        if (is_ROOT == False):
            rsync_cmd.append("--dry-run")   # バックアップをしません
            for x in need_sudo:
                x.insert(0,"sudo")          # 先頭に"sudo"を挿入します


        ################################################################
        # 変数定義終了。ここから、実際の処理を記述していきます
        ################################################################

        # コピー先となるパーティションをマウントします
        call(mount_cmd + [dest_volume,dest_mtpt])

        # コピー元となるパーティションをマウントします
        # ファイルシステムや属性で処理が異なります
        if (partition == "boot"):
            """
            ブートパーティションは、fstabでnoauto指定してあるため、
            マウントしなければなりません
            """
            source_mtpt = "/boot"
            source_volume = "/dev/md1"
        else:
            """
            ここでは、home及びgentooのパーティションを処理すること
            を暗黙に仮定しています
            両パーティションともに、nilfs2ですので、nilfs2のsnapshot
            を作成して、それをコピー元として利用することにします
            """
            # 直近のチェックポイントを変数check_pointに格納します
            lscp_result = Popen(lscp_cmd,stdout=PIPE).communicate()[0]
            check_point = lscp_result.split()[7]
            
            # nilfs2のsnapshotを作成します
            call(chcp_cmd + [check_point])

            # snapshotをマウントする為のオプションを設定します
            mount_cmd.extend(["-t","nilfs2","-o","ro,cp="+check_point])

        # コピー元をマウントします
        call(mount_cmd + [source_volume,source_mtpt])

        # ファイルをコピーします
        call(rsync_cmd + [source_mtpt+"/",dest_mtpt])

        # 使用したパーティションをアンマウントします
        for p in (source_mtpt,dest_mtpt):
            call(umount_cmd + [p])

    # end for

# end main()

if __name__ == "__main__":
    main()