コード例 #1
0
ファイル: util.go プロジェクト: marsmensch/blobstash
func Restore(con *glacier.Connection, db *DB, vault string) (err error) {
	var wg sync.WaitGroup
	go handleClose(db)
	jobs := []string{}
	kvs := make(chan *KeyValue)
	go db.Iter(kvs, "archive:", "archive:\xff", 0)
	errch := make(chan error)
	go func() {
		select {
		case cerr := <-errch:
			if cerr != nil {
				panic(cerr)
			}
		}
	}()
	for kv := range kvs {
		archive := &glacier.Archive{}
		if err := json.Unmarshal([]byte(kv.Value), archive); err != nil {
			return err
		}
		var jobId string
		statusKey := fmt.Sprintf("job:%v", kv.Key)
		jobId, err = db.Get(statusKey)
		if err != nil {
			return err
		}
		if jobId == "" {
			jobId, err = con.InitiateRetrievalJob(vault, archive.ArchiveId, "", "")
			if err != nil {
				return err
			}
			if err := db.Set(statusKey, jobId); err != nil {
				return err
			}
			log.Printf("Initiated a new job for archive retrieval %v", archive.ArchiveId)
		}
		wg.Add(1)
		go func(archive *glacier.Archive, jobId string) {
			if err := RestoreArchive(con, vault, jobId, filepath.Base(archive.ArchiveDescription), &wg); err != nil {
				errch <- err
			}
		}(archive, jobId)
		jobs = append(jobs, jobId)
	}
	if len(jobs) == 0 {
		log.Printf("Error: no archive in local DB, maybe sync is not done yet?")
		db.Close()
		os.Exit(1)
	}
	log.Printf("Waiting for %v jobs to complete, you can safely CTRL+C and resume this process", len(jobs))
	wg.Wait()
	defer close(errch)
	log.Printf("Restore done, %v archives restored", len(jobs))
	return nil
}