バックアップをとろう(その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()