1. 증분 백업 버그 수정
2. 일반 백업 해쉬 비교 추가
This commit is contained in:
@@ -1,2 +1,5 @@
|
|||||||
# simple_backup
|
# simple_backup
|
||||||
|
## build
|
||||||
|
```sh
|
||||||
|
$ go build -o backup git.lhk.o-r.kr/freerer2/simple_backup/cmd
|
||||||
|
```
|
||||||
@@ -230,7 +230,7 @@ func main() {
|
|||||||
mode = backup.CompareHash
|
mode = backup.CompareHash
|
||||||
}
|
}
|
||||||
|
|
||||||
backupOpts := backup.BackupOptions{
|
backupOpts := backup.Options{
|
||||||
DryRun: opts.DryRun,
|
DryRun: opts.DryRun,
|
||||||
Verbose: opts.Verbose,
|
Verbose: opts.Verbose,
|
||||||
Force: opts.Force,
|
Force: opts.Force,
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ type Progress struct {
|
|||||||
|
|
||||||
type ProgressCallback func(Progress)
|
type ProgressCallback func(Progress)
|
||||||
|
|
||||||
type BackupOptions struct {
|
type Options struct {
|
||||||
DryRun bool
|
DryRun bool
|
||||||
Verbose bool
|
Verbose bool
|
||||||
Force bool
|
Force bool
|
||||||
@@ -42,24 +42,24 @@ type BackupOptions struct {
|
|||||||
dirCache *path.DirCache
|
dirCache *path.DirCache
|
||||||
}
|
}
|
||||||
|
|
||||||
type BackupMeta struct {
|
type Meta struct {
|
||||||
LastBackup time.Time `json:"lastBackup"`
|
LastBackup time.Time `json:"lastBackup"`
|
||||||
Files map[string]string `json:"files"` // 파일 경로 -> 해시 또는 수정 시간
|
Files map[string]string `json:"files"` // 파일 경로 -> 해시 또는 수정 시간
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadBackupMeta(dst string) (*BackupMeta, error) {
|
func loadBackupMeta(src string) (*Meta, error) {
|
||||||
metaPath := filepath.Join(dst, constants.MetaFileName)
|
metaPath := filepath.Join(src, constants.MetaFileName)
|
||||||
data, err := os.ReadFile(metaPath)
|
data, err := os.ReadFile(metaPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return &BackupMeta{
|
return &Meta{
|
||||||
Files: make(map[string]string),
|
Files: make(map[string]string),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("메타 파일을 읽을 수 없습니다: %w", err)
|
return nil, fmt.Errorf("메타 파일을 읽을 수 없습니다: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var meta BackupMeta
|
var meta Meta
|
||||||
if err := json.Unmarshal(data, &meta); err != nil {
|
if err := json.Unmarshal(data, &meta); err != nil {
|
||||||
return nil, fmt.Errorf("메타 파일을 파싱할 수 없습니다: %w", err)
|
return nil, fmt.Errorf("메타 파일을 파싱할 수 없습니다: %w", err)
|
||||||
}
|
}
|
||||||
@@ -70,8 +70,8 @@ func loadBackupMeta(dst string) (*BackupMeta, error) {
|
|||||||
return &meta, nil
|
return &meta, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveBackupMeta(dst string, meta *BackupMeta) error {
|
func saveBackupMeta(src string, meta *Meta) error {
|
||||||
metaPath := filepath.Join(dst, constants.MetaFileName)
|
metaPath := filepath.Join(src, constants.MetaFileName)
|
||||||
data, err := json.MarshalIndent(meta, "", " ")
|
data, err := json.MarshalIndent(meta, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("메타 데이터를 직렬화할 수 없습니다: %w", err)
|
return fmt.Errorf("메타 데이터를 직렬화할 수 없습니다: %w", err)
|
||||||
@@ -104,7 +104,7 @@ func calculateFileHash(path string) (string, error) {
|
|||||||
return fmt.Sprintf("%x", h.Sum(nil)), nil
|
return fmt.Sprintf("%x", h.Sum(nil)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunBackup(ctx context.Context, src, dst string, opts BackupOptions) error {
|
func RunBackup(ctx context.Context, src, dst string, opts Options) error {
|
||||||
if opts.dirCache == nil {
|
if opts.dirCache == nil {
|
||||||
opts.dirCache = path.NewDirCache()
|
opts.dirCache = path.NewDirCache()
|
||||||
}
|
}
|
||||||
@@ -118,10 +118,10 @@ func RunBackup(ctx context.Context, src, dst string, opts BackupOptions) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 증분 백업을 위한 메타데이터 로드
|
// 증분 백업을 위한 메타데이터 로드
|
||||||
var meta *BackupMeta
|
var meta *Meta
|
||||||
var err error
|
var err error
|
||||||
if opts.Incremental {
|
if opts.Incremental {
|
||||||
meta, err = loadBackupMeta(dst)
|
meta, err = loadBackupMeta(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -236,10 +236,26 @@ func RunBackup(ctx context.Context, src, dst string, opts BackupOptions) error {
|
|||||||
return fmt.Errorf("원본 파일 정보를 읽을 수 없습니다: %w", err)
|
return fmt.Errorf("원본 파일 정보를 읽을 수 없습니다: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch opts.CompareMode {
|
||||||
|
case CompareTime:
|
||||||
if srcInfo.Size() == dstInfo.Size() && srcInfo.ModTime().Equal(dstInfo.ModTime()) {
|
if srcInfo.Size() == dstInfo.Size() && srcInfo.ModTime().Equal(dstInfo.ModTime()) {
|
||||||
opts.Logger.Printf("건너뜀 (동일): %s\n", relPath)
|
opts.Logger.Printf("건너뜀 (시간 동일): %s\n", relPath)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
case CompareHash:
|
||||||
|
srcHash, err := calculateFileHash(srcPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("원본 파일 해시를 계산할 수 없습니다: %w", err)
|
||||||
|
}
|
||||||
|
dstHash, err := calculateFileHash(dstPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("대상 파일 해시를 계산할 수 없습니다: %w", err)
|
||||||
|
}
|
||||||
|
if srcHash == dstHash {
|
||||||
|
opts.Logger.Printf("건너뜀 (해시 동일): %s\n", relPath)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +270,7 @@ func RunBackup(ctx context.Context, src, dst string, opts BackupOptions) error {
|
|||||||
// 증분 백업 메타데이터 저장
|
// 증분 백업 메타데이터 저장
|
||||||
if opts.Incremental && !opts.DryRun {
|
if opts.Incremental && !opts.DryRun {
|
||||||
meta.LastBackup = time.Now()
|
meta.LastBackup = time.Now()
|
||||||
if err := saveBackupMeta(dst, meta); err != nil {
|
if err := saveBackupMeta(src, meta); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user