idun/pkg/buckets/calculator.go

158 lines
3.4 KiB
Go

package buckets
import (
"errors"
"idun/pkg/storage"
"time"
)
type Config struct {
Unlimit int `yaml:"unlimit"`
Hourly int `yaml:"hourly"`
Daily int `yaml:"dayly"`
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
}