package buckets import ( "errors" "idun/pkg/storage" "time" ) type Config struct { Unlimit int `yaml:"unlimit"` Hourly int `yaml:"hourly"` Daily int `yaml:"daily"` Weekly int `yaml:"weekly"` Monthly int `yaml:"monthly"` } func InsertFilesInBuckets(buckets *[]Bucket, files []storage.File) error { for _, f := range files { for _, b := range *buckets { err := b.AddFile(f) if err != nil { if errors.Is(err, storage.ErrFileNotInBucketTime) { continue } return err } break } } return nil } func GenerateBuckets(fromTime time.Time, config Config, location *time.Location) ([]Bucket, error) { end := fromTime plan := []Bucket{} //Unlimit Bucket for the current hour untilStart := time.Date(fromTime.Year(), fromTime.Month(), fromTime.Day(), fromTime.Hour(), 0, 0, 0, location) unlimitBucket := UnlimitBucket{ start: untilStart, end: fromTime, } end = untilStart plan = append(plan, &unlimitBucket) //Todo: Make just one unlimit bucket for the complete time //Unlimit Buckets for i := 0; i < config.Unlimit; i++ { unlimitBucket := UnlimitBucket{ start: end.Add(-1 * time.Hour), end: end.Add(-1), } end = end.Add(-1 * time.Hour) plan = append(plan, &unlimitBucket) } //Hour Buckets for i := 0; i < config.Hourly; i++ { timebucket := TimeBucket{ start: end.Add(-1 * time.Hour), end: end.Add(-1), } end = end.Add(-1 * time.Hour) plan = append(plan, &timebucket) } //Hour Backups until middnight, if dayly, weekly or monthly is active if config.Daily > 0 || config.Weekly > 0 || config.Monthly > 0 { for { timebucket := TimeBucket{ start: end.Add(-1 * time.Hour), end: end.Add(-1), } end = end.Add(-1 * time.Hour) plan = append(plan, &timebucket) if end.Hour() == 0 { break } } } //Daily for i := 0; i < config.Daily; i++ { timebucket := TimeBucket{ start: end.Add(-24 * time.Hour), end: end.Add(-1), } end = end.Add(-24 * time.Hour) plan = append(plan, &timebucket) } //Daily Backups until (inc) monday, if weekly or monthly backups ar active if config.Weekly > 0 || config.Monthly > 0 { for { timebucket := TimeBucket{ start: end.Add(-24 * time.Hour), end: end.Add(-1), } end = end.Add(-24 * time.Hour) plan = append(plan, &timebucket) if end.Weekday() == time.Monday { break } } } //Weekly for i := 0; i < config.Weekly; i++ { timebucket := TimeBucket{ start: end.Add(-24 * 7 * time.Hour), end: end.Add(-1), } end = end.Add(-24 * 7 * time.Hour) plan = append(plan, &timebucket) } //Daily Backups until (inc) monday, if weekly or monthly backups ar active if config.Monthly > 0 { for { lastrun := false start := end.Add(-24 * 7 * time.Hour) if start.Month() != end.Month() { start = time.Date(end.Year(), end.Month(), 1, 0, 0, 0, 0, location) lastrun = true } timebucket := TimeBucket{ start: start, end: end.Add(-1), } end = start plan = append(plan, &timebucket) if lastrun { break } } } //Monthly for i := 0; i < config.Monthly; i++ { timebucket := TimeBucket{ start: end.AddDate(0, -1, 0), end: end.Add(-1), } end = end.AddDate(0, -1, 0) plan = append(plan, &timebucket) } //Add Delete all Backups older than the last plan deleteBucket := DeleteBucket{ start: time.Time{}, end: end.Add(-1), } plan = append(plan, &deleteBucket) return plan, nil }