qdumpfs 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +22 -16
- data/lib/qdumpfs.rb +36 -111
- data/lib/qdumpfs/option.rb +2 -1
- data/lib/qdumpfs/version.rb +4 -3
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: bc8d8dec60fe04598e9dd5bea8528f5299a7cbb7ee0f0432c3b6d46488917edf
         | 
| 4 | 
            +
              data.tar.gz: '029dffccca2865524f208d28f2ebe2f63b2de465e0a5f08de93c597156fd48a9'
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 9c393b76dddd9978adf5dfc77cfb25f3c14bfb9b1aca0767228b8b4c70fdf11206f4a35c9e0f5098b1c7ba1e3b113dc8f51de3ad14b48d39fe1dff8dd21309f1
         | 
| 7 | 
            +
              data.tar.gz: 054605d2b4f91e2c0fdbd0518614b81a9f04f0ba378f0d92c5aba28c59456ae88c40dfb156579295c10130c248fc314197bd03398f18435cd1e0596696f444f2
         | 
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,13 +1,14 @@ | |
| 1 1 | 
             
            # Qdumpfs
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 3 | 
            +
            pdumpfsの個人的改良版です。
         | 
| 4 4 |  | 
| 5 | 
            -
             | 
| 5 | 
            +
            Gem化して最近のバージョンのバージョンのRubyに対応。コマンドの拡張などを行っています。
         | 
| 6 6 |  | 
| 7 | 
            -
             | 
| 7 | 
            +
            ## インストール
         | 
| 8 8 |  | 
| 9 | 
            -
             | 
| 9 | 
            +
            gem install qdumpfs
         | 
| 10 10 |  | 
| 11 | 
            +
            ## 使用方法
         | 
| 11 12 |  | 
| 12 13 | 
             
            ```
         | 
| 13 14 | 
             
            Usage: qdumpfs [options] <source> <dest>
         | 
| @@ -19,48 +20,53 @@ Options | |
| 19 20 | 
             
                -e, --exclude=PATTERN            exclude files/directories matching PATTERN
         | 
| 20 21 | 
             
                -s, --exclude-by-size=SIZE       exclude files larger than SIZE
         | 
| 21 22 | 
             
                -w, --exclude-by-glob=GLOB       exclude files matching GLOB
         | 
| 22 | 
            -
                -c, --command=COMMAND            backup|sync|list|expire|verify| | 
| 23 | 
            +
                -c, --command=COMMAND            backup|sync|list|expire|verify|delete
         | 
| 23 24 | 
             
                -l, --limit=HOURS                limit hours
         | 
| 24 25 | 
             
                -k, --keep=KEEPARG               ex: --keep 100Y12M12W30D (100years, 12months, 12weeks, 30days, default)
         | 
| 25 26 | 
             
            ```
         | 
| 26 27 |  | 
| 27 | 
            -
            ##  | 
| 28 | 
            +
            ## 実行例
         | 
| 29 | 
            +
             | 
| 30 | 
            +
             | 
| 31 | 
            +
            バックアップを実行する場合。
         | 
| 28 32 |  | 
| 29 | 
            -
            Backup your home directory, run the following command.
         | 
| 30 33 | 
             
            ```
         | 
| 31 34 | 
             
            qdumpfs /home/foo /backup
         | 
| 32 35 | 
             
            ```
         | 
| 33 36 |  | 
| 34 | 
            -
             | 
| 37 | 
            +
            "--command backup"オプションを明示することもできます。
         | 
| 38 | 
            +
             | 
| 35 39 | 
             
            ```
         | 
| 36 40 | 
             
            qdumpfs --command=backup /home/foo /backup
         | 
| 37 41 | 
             
            ```
         | 
| 38 42 |  | 
| 39 | 
            -
             | 
| 43 | 
            +
            "--command sync"でバックアップフォルダを同期できます。
         | 
| 40 44 | 
             
            ```
         | 
| 41 45 | 
             
            qdumpfs --command=sync /backup1 /backup2
         | 
| 42 46 | 
             
            ```
         | 
| 43 47 |  | 
| 44 | 
            -
             | 
| 48 | 
            +
            バックアップフォルダの同期には膨大な時間が必要な場合があるため、実行時間を制限できます。以下は例えば1時間に制限する場合です。
         | 
| 45 49 | 
             
            ```
         | 
| 46 50 | 
             
            qdumpfs --command=sync --limit=1 /backup1 /backup2
         | 
| 47 51 | 
             
            ```
         | 
| 48 52 |  | 
| 49 | 
            -
             | 
| 53 | 
            +
            バックアップフォルダの同期で、1時間でかつ"100Y12M12W30D"を保存する場合のオプションです。
         | 
| 50 54 | 
             
            ```
         | 
| 51 | 
            -
            qdumpfs --command=sync --limit=1 --keep=5Y6M7W10D  | 
| 55 | 
            +
            qdumpfs --command=sync --limit=1 --keep=5Y6M7W10D backup1 /backup2
         | 
| 52 56 | 
             
            ```
         | 
| 53 57 |  | 
| 54 | 
            -
             | 
| 58 | 
            +
            "--command expire"で、"--keep="パターンに該当しないバックアップを削除できます。
         | 
| 55 59 | 
             
            ```
         | 
| 56 | 
            -
            qdumpfs --command=expire --limit=1 --keep=5Y6M7W10D  | 
| 60 | 
            +
            qdumpfs --command=expire --limit=1 --keep=5Y6M7W10D backup1 /backup2
         | 
| 57 61 | 
             
            ```
         | 
| 58 62 |  | 
| 63 | 
            +
            "--command delete"で、バックアップに存在する指定したパスを削除できます(間違えてバックアップした内容を削除したい場合などに使用)。
         | 
| 64 | 
            +
            ```
         | 
| 65 | 
            +
            qdumpfs --command=delete --delete-dir=backup1 --limit=1  r:/backup2
         | 
| 66 | 
            +
            ```
         | 
| 59 67 |  | 
| 60 68 | 
             
            ## License
         | 
| 61 69 |  | 
| 62 70 | 
             
            qdumpfs is a free software with ABSOLUTELY NO WARRANTY under the terms of the GNU General Public License version 2.
         | 
| 63 71 |  | 
| 64 72 |  | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
    
        data/lib/qdumpfs.rb
    CHANGED
    
    | @@ -45,6 +45,9 @@ module Qdumpfs | |
| 45 45 | 
             
                  opt.on('--delete-to=YYYYMMDD', 'delete backup to YYYY/MM/DD') {|v|
         | 
| 46 46 | 
             
                    opts[:delete_to] = Date.parse(v)
         | 
| 47 47 | 
             
                  }
         | 
| 48 | 
            +
                  opt.on('--delete-dir=DIRS', 'relative path from the snapshot root of the backup. ex: --delete-dir=foo,home/bar') {|v|
         | 
| 49 | 
            +
                    opts[:delete_dirs] = v.split(/,/)
         | 
| 50 | 
            +
                  }      
         | 
| 48 51 | 
             
                  opt.on('--backup-at=YYYYMMDD', 'backup at YYYY/MM/DD') {|v|
         | 
| 49 52 | 
             
                    opts[:backup_at] = Date.parse(v)
         | 
| 50 53 | 
             
                  }
         | 
| @@ -85,8 +88,6 @@ module Qdumpfs | |
| 85 88 | 
             
                    verify
         | 
| 86 89 | 
             
                  elsif @opt.cmd == 'delete'
         | 
| 87 90 | 
             
                    delete('delete')
         | 
| 88 | 
            -
            #      elsif @opt.cmd == 'test'
         | 
| 89 | 
            -
            #        test
         | 
| 90 91 | 
             
                  else
         | 
| 91 92 | 
             
                    raise RuntimeError, "unknown command: #{@opt.cmd}"
         | 
| 92 93 | 
             
                  end
         | 
| @@ -149,29 +150,6 @@ module Qdumpfs | |
| 149 150 | 
             
                  return src_count, dst_count
         | 
| 150 151 | 
             
                end
         | 
| 151 152 |  | 
| 152 | 
            -
            #    def get_snapshots(target_dir)
         | 
| 153 | 
            -
            #      # 指定したディレクトリに含まれるバックアップフォルダ(日付つき)を全て取得
         | 
| 154 | 
            -
            #      dd   = "[0-9][0-9]"
         | 
| 155 | 
            -
            #      dddd = dd + dd
         | 
| 156 | 
            -
            #      # FIXME: Y10K problem.
         | 
| 157 | 
            -
            #      dirs = []
         | 
| 158 | 
            -
            #      glob_path = File.join(target_dir, dddd, dd, dd)
         | 
| 159 | 
            -
            #      Dir.glob(glob_path).sort.find {|dir|
         | 
| 160 | 
            -
            #        day, month, year = File.split_all(dir).reverse.map {|x| x.to_i }
         | 
| 161 | 
            -
            #        path = diro
         | 
| 162 | 
            -
            #        if File.directory?(path) and Date.valid_date?(year, month, day) and
         | 
| 163 | 
            -
            #          dirs << path
         | 
| 164 | 
            -
            #        end
         | 
| 165 | 
            -
            #      }
         | 
| 166 | 
            -
            #      dirs
         | 
| 167 | 
            -
            #    end
         | 
| 168 | 
            -
             | 
| 169 | 
            -
            #    def get_snapshot_date(snapshot)
         | 
| 170 | 
            -
            #      # バックアップディレクトリのパス(日付つき)から日付を取得して返す
         | 
| 171 | 
            -
            #      day, month, year = File.split_all(snapshot).reverse.map {|x| x.to_i }
         | 
| 172 | 
            -
            #      Time.new(year, month, day)
         | 
| 173 | 
            -
            #    end
         | 
| 174 | 
            -
                
         | 
| 175 153 | 
             
                def update_snapshot(src, latest, today)
         | 
| 176 154 | 
             
                  # バックアップの差分コピーを実行
         | 
| 177 155 | 
             
                  # src: コピー元ディレクトリ ex) i:/from/home
         | 
| @@ -457,9 +435,7 @@ module Qdumpfs | |
| 457 435 |  | 
| 458 436 | 
             
                def delete(cmd)
         | 
| 459 437 | 
             
                  @opt.validate_directories(1)
         | 
| 460 | 
            -
                  
         | 
| 461 438 | 
             
                  start_time = Time.now
         | 
| 462 | 
            -
            p @opt.limit_sec      
         | 
| 463 439 | 
             
                  limit_time = start_time + (@opt.limit_sec)
         | 
| 464 440 | 
             
                  log("##### #{cmd} delete-from=#{@opt.delete_from} delete-to=#{@opt.delete_to} start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
         | 
| 465 441 | 
             
                  @opt.dirs.each do |target_dir|
         | 
| @@ -482,6 +458,29 @@ p @opt.limit_sec | |
| 482 458 | 
             
                  log("##### #{cmd} end #####")
         | 
| 483 459 | 
             
                end
         | 
| 484 460 |  | 
| 461 | 
            +
                def rm_dir(path)
         | 
| 462 | 
            +
                  can_delete = true
         | 
| 463 | 
            +
                  if @opt.dry_run
         | 
| 464 | 
            +
                    can_delete = false
         | 
| 465 | 
            +
                  elsif !FileTest.directory?(path)
         | 
| 466 | 
            +
                    can_delete = false
         | 
| 467 | 
            +
                  end
         | 
| 468 | 
            +
                  msg = can_delete ? "...ok..." : "...ng..."
         | 
| 469 | 
            +
                  print "Deleting #{path} #{msg}"
         | 
| 470 | 
            +
             | 
| 471 | 
            +
                  return unless can_delete
         | 
| 472 | 
            +
             | 
| 473 | 
            +
                  #それ以外は日付バックアップディレクトリ全体を削除
         | 
| 474 | 
            +
                  if windows?
         | 
| 475 | 
            +
                    # Windowsの場合
         | 
| 476 | 
            +
                    win_backup_path = to_win_path(path)
         | 
| 477 | 
            +
                    system("rmdir /S /Q #{win_backup_path}")
         | 
| 478 | 
            +
                  else
         | 
| 479 | 
            +
                    # Linux/macOSの場合
         | 
| 480 | 
            +
                    system("rm -rf #{path}")
         | 
| 481 | 
            +
                  end
         | 
| 482 | 
            +
                end
         | 
| 483 | 
            +
             | 
| 485 484 | 
             
                def delete_target_dir(cmd, target_dir)
         | 
| 486 485 | 
             
                  target_dir = to_unix_path(target_dir)
         | 
| 487 486 | 
             
                  puts "<<<<< Target dir: #{target_dir} >>>>>"
         | 
| @@ -494,40 +493,20 @@ p @opt.limit_sec | |
| 494 493 | 
             
                  else
         | 
| 495 494 | 
             
                    raise RuntimeError, "unknown command: #{cmd}"
         | 
| 496 495 | 
             
                  end
         | 
| 497 | 
            -
             | 
| 498 | 
            -
            #      p @opt.keep_year
         | 
| 499 | 
            -
            #      p @opt.keep_month
         | 
| 500 | 
            -
            #      p @opt.keep_day
         | 
| 501 | 
            -
                  
         | 
| 496 | 
            +
                
         | 
| 502 497 | 
             
                  snapshots.each do |snapshot|
         | 
| 503 498 | 
             
                    next if snapshot.keep
         | 
| 504 499 | 
             
                    t_start = Time.now
         | 
| 505 | 
            -
             | 
| 506 | 
            -
             | 
| 507 | 
            -
             | 
| 508 | 
            -
                       | 
| 509 | 
            -
             | 
| 510 | 
            -
             | 
| 511 | 
            -
                      
         | 
| 512 | 
            -
                      if windows?
         | 
| 513 | 
            -
                        # Windowsの場合
         | 
| 514 | 
            -
                        win_backup_path = to_win_path(snapshot.path)
         | 
| 515 | 
            -
                        
         | 
| 516 | 
            -
            #            byenow = "byenow"
         | 
| 517 | 
            -
            #            if which(byenow)
         | 
| 518 | 
            -
            #              print " bynow"
         | 
| 519 | 
            -
            #              system("byenow -y --delete-ntapi --one-liner #{snapshot.path}")
         | 
| 520 | 
            -
            #            else
         | 
| 521 | 
            -
            #              print " pass1"
         | 
| 522 | 
            -
            #              system("del /F /S /Q #{win_backup_path} > nul")
         | 
| 523 | 
            -
            #              print " pass2"
         | 
| 524 | 
            -
            #              system("rmdir /S /Q #{win_backup_path}")
         | 
| 525 | 
            -
                        #            end
         | 
| 526 | 
            -
                        system("rmdir /S /Q #{win_backup_path}")
         | 
| 527 | 
            -
                      else
         | 
| 528 | 
            -
                        # Linux/macOSの場合
         | 
| 529 | 
            -
                        system("rm -rf #{snapshot.path}")
         | 
| 500 | 
            +
             | 
| 501 | 
            +
                    if @opt.delete_dirs.size > 0
         | 
| 502 | 
            +
                      #削除するディレクトリが指定されている場合日付バックアップディレクトリの下そのディレクトリを削除
         | 
| 503 | 
            +
                      @opt.delete_dirs.each do |delete_dir|
         | 
| 504 | 
            +
                        delete_path = File.join(snapshot.path, delete_dir)
         | 
| 505 | 
            +
                        rm_dir(delete_path)
         | 
| 530 506 | 
             
                      end
         | 
| 507 | 
            +
                    else
         | 
| 508 | 
            +
                      #それ以外はバックアップディレクトリ全体が対象
         | 
| 509 | 
            +
                      rm_dir(snapshot.path)
         | 
| 531 510 | 
             
                    end
         | 
| 532 511 |  | 
| 533 512 | 
             
                    t_end = Time.now
         | 
| @@ -551,60 +530,6 @@ p @opt.limit_sec | |
| 551 530 | 
             
                  end      
         | 
| 552 531 | 
             
                end
         | 
| 553 532 |  | 
| 554 | 
            -
                # def delete
         | 
| 555 | 
            -
                #   @opt.validate_directories(1)
         | 
| 556 | 
            -
                  
         | 
| 557 | 
            -
                #   start_time = Time.now
         | 
| 558 | 
            -
                #   limit_time = start_time + (@opt.limit_sec)      
         | 
| 559 | 
            -
                #   log("##### delete start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
         | 
| 560 | 
            -
                #   @opt.dirs.each do |target_dir|
         | 
| 561 | 
            -
                #     target_start = Time.now
         | 
| 562 | 
            -
                #     delete_target_dir(target_dir)
         | 
| 563 | 
            -
                #     target_end = Time.now
         | 
| 564 | 
            -
                    
         | 
| 565 | 
            -
                #     # 次回expireにかかる時間を最終expire時間の半分と予想
         | 
| 566 | 
            -
                #     next_expire = (target_end - target_start) / 2
         | 
| 567 | 
            -
                    
         | 
| 568 | 
            -
                #     cur_time = Time.now
         | 
| 569 | 
            -
                #     in_imit = (cur_time + next_expire) < limit_time
         | 
| 570 | 
            -
                    
         | 
| 571 | 
            -
                #     log("## cur_time=#{fmt(cur_time)} + next_expire=#{next_expire} <  limit_time=#{fmt(limit_time)} in_limit=#{in_limit} ## ")
         | 
| 572 | 
            -
                #     unless in_limit
         | 
| 573 | 
            -
                #       break
         | 
| 574 | 
            -
                #     end
         | 
| 575 | 
            -
                #   end        
         | 
| 576 | 
            -
                #   log("##### delete end #####")
         | 
| 577 | 
            -
                # end
         | 
| 578 | 
            -
             | 
| 579 | 
            -
                # def delete_target_dir(target_dir)
         | 
| 580 | 
            -
                #   target_dir = to_unix_path(target_dir)
         | 
| 581 | 
            -
                #   puts "<<<<< Target dir: #{target_dir} >>>>>"
         | 
| 582 | 
            -
                  
         | 
| 583 | 
            -
                #   snapshots = BackupDir.scan_backup_dirs(target_dir)
         | 
| 584 | 
            -
                #   @opt.detect_delete_dirs(snapshots)
         | 
| 585 | 
            -
             | 
| 586 | 
            -
                #   snapshots.each do |snapshot|
         | 
| 587 | 
            -
                #     next if snapshot.keep
         | 
| 588 | 
            -
                #     t_start = Time.now
         | 
| 589 | 
            -
                #     print "Deleting #{snapshot.path} ..."
         | 
| 590 | 
            -
                   
         | 
| 591 | 
            -
                #     unless @opt.dry_run
         | 
| 592 | 
            -
                #       if windows?
         | 
| 593 | 
            -
                #         # Windowsの場合
         | 
| 594 | 
            -
                #         win_backup_path = to_win_path(snapshot.path)
         | 
| 595 | 
            -
                #         system("rmdir /S /Q #{win_backup_path}")
         | 
| 596 | 
            -
                #       else
         | 
| 597 | 
            -
                #         # Linux/macOSの場合
         | 
| 598 | 
            -
                #         system("rm -rf #{snapshot.path}")
         | 
| 599 | 
            -
                #       end
         | 
| 600 | 
            -
                #     end
         | 
| 601 | 
            -
                #   end
         | 
| 602 | 
            -
             | 
| 603 | 
            -
                #   t_end = Time.now
         | 
| 604 | 
            -
                #   diff = (t_end - t_start).to_i
         | 
| 605 | 
            -
                #   diff_hours = diff / 3600
         | 
| 606 | 
            -
                #   puts " done[#{diff} seconds = #{diff_hours} hours]." 
         | 
| 607 | 
            -
                # end
         | 
| 608 533 |  | 
| 609 534 | 
             
              end
         | 
| 610 535 |  | 
    
        data/lib/qdumpfs/option.rb
    CHANGED
    
    | @@ -141,6 +141,7 @@ module Qdumpfs | |
| 141 141 | 
             
                  @keep_day = $1.to_i if keep =~ /(\d+)D/
         | 
| 142 142 | 
             
                  @delete_from = @opts[:delete_from]
         | 
| 143 143 | 
             
                  @delete_to = @opts[:delete_to]
         | 
| 144 | 
            +
                  @delete_dirs = @opts[:delete_dirs]
         | 
| 144 145 | 
             
                  @backup_at = @opts[:backup_at]
         | 
| 145 146 | 
             
                  @today = Date.today
         | 
| 146 147 | 
             
                end
         | 
| @@ -148,7 +149,7 @@ module Qdumpfs | |
| 148 149 | 
             
                attr_reader :keep_year, :keep_month, :keep_week, :keep_day
         | 
| 149 150 | 
             
                attr_reader :logdir, :logpath, :verifypath
         | 
| 150 151 | 
             
                attr_reader :logger, :matcher, :reporter, :interval_proc
         | 
| 151 | 
            -
                attr_reader :delete_from, :delete_to, :backup_at
         | 
| 152 | 
            +
                attr_reader :delete_from, :delete_to, :delete_dirs, :backup_at
         | 
| 152 153 |  | 
| 153 154 | 
             
                def report(type, filename)
         | 
| 154 155 | 
             
                  if @opts[:v]
         | 
    
        data/lib/qdumpfs/version.rb
    CHANGED
    
    | @@ -1,3 +1,4 @@ | |
| 1 | 
            -
            module Qdumpfs
         | 
| 2 | 
            -
              VERSION = "0. | 
| 3 | 
            -
            end
         | 
| 1 | 
            +
            module Qdumpfs
         | 
| 2 | 
            +
              VERSION = "0.8.0"
         | 
| 3 | 
            +
            end  
         | 
| 4 | 
            +
              
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: qdumpfs
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.8.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - src
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2021- | 
| 11 | 
            +
            date: 2021-02-22 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         |