Skip to content

Commit

Permalink
enable setting backup interval to minutes or hours (default remains h…
Browse files Browse the repository at this point in the history
…ours).
  • Loading branch information
jonhadfield committed Aug 25, 2023
1 parent dcfda1f commit 65cd28f
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 46 deletions.
64 changes: 42 additions & 22 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,18 +103,27 @@ func init() {
func getBackupInterval() int {
backupIntervalEnv := os.Getenv(envGitBackupInterval)

var backupInterval int

var intervalConversionErr error

if backupIntervalEnv != "" {
backupInterval, intervalConversionErr = strconv.Atoi(backupIntervalEnv)
if intervalConversionErr != nil {
logger.Fatalf("%s must be a number.", envGitBackupInterval)
hours, isHour := isInt(backupIntervalEnv)

switch {
case isHour:
// an int represents hours
return hours * 60
case strings.HasSuffix(backupIntervalEnv, "h"):
// a string ending in h represents hours
hours, isHour = isInt(backupIntervalEnv[:len(backupIntervalEnv)-1])
if isHour {
return hours * 60
}
case strings.HasSuffix(backupIntervalEnv, "m"):
// a string ending in m represents minutes
minutes, isMinute := isInt(backupIntervalEnv[:len(backupIntervalEnv)-1])
if isMinute {
return minutes
}
}

return backupInterval
return 0
}

func getLogLevel() int {
Expand Down Expand Up @@ -219,10 +228,6 @@ func displayStartupConfig() {
logger.Printf("root backup directory: %s", backupDIR)
}

if backupInterval := os.Getenv(envGitBackupInterval); backupInterval != "" {
logger.Printf("git backup interval: %s hours", backupInterval)
}

// output github config
if ghToken := os.Getenv(envGitHubToken); ghToken != "" {
if ghOrgs := strings.ToLower(os.Getenv(envGitHubOrgs)); ghOrgs != "" {
Expand Down Expand Up @@ -335,14 +340,9 @@ func run() error {
backupInterval := getBackupInterval()

if backupInterval != 0 {
hourOutput := "hour"
if backupInterval > 1 {
hourOutput = "hours"
}
logger.Printf("scheduling to run every %s", formatIntervalDuration(backupInterval))

logger.Printf("scheduling to run every %d %s", backupInterval, hourOutput)

_, err = scheduler.Every(int(time.Duration(backupInterval))).Hours().Run(execProviderBackups)
_, err = scheduler.Every(int(time.Duration(backupInterval))).Minutes().Run(execProviderBackups)
if err != nil {
return errors.Wrapf(err, "scheduler failed")
}
Expand All @@ -355,6 +355,18 @@ func run() error {
return nil
}

func formatIntervalDuration(m int) string {
if m == 0 {
return ""
}

if m%60 == 0 {
return fmt.Sprintf("%dh", m/60)
}

return time.Duration(int64(m) * int64(time.Minute)).String()
}

func getOrgsListFromEnvVar(envVar string) []string {
orgsList := os.Getenv(envVar)

Expand Down Expand Up @@ -477,12 +489,12 @@ func execProviderBackups() {
logger.Println("backups complete")

if backupInterval := getBackupInterval(); backupInterval > 0 {
nextBackupTime := startTime.Add(time.Duration(backupInterval) * time.Hour)
nextBackupTime := startTime.Add(time.Duration(backupInterval) * time.Minute)
if nextBackupTime.Before(time.Now()) {
logger.Fatal("error: backup took longer than scheduled interval")
}

logger.Printf("next run scheduled for: %v", nextBackupTime)
logger.Printf("next run scheduled for: %s", nextBackupTime.Format("2006-01-02 15:04:05 -0700 MST"))
}
}

Expand Down Expand Up @@ -527,3 +539,11 @@ func getBackupsToRetain(envVar string) int {

return backupsToKeep
}

func isInt(i string) (int, bool) {
if val, err := strconv.Atoi(i); err == nil {
return val, true
}

return 0, false
}
104 changes: 80 additions & 24 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,13 @@ func TestGiteaRepositoryBackup(t *testing.T) {
require.NoError(t, run())
}

func TestFormatIntervalDuration(t *testing.T) {
require.Equal(t, "", formatIntervalDuration(0))
require.Equal(t, "1h", formatIntervalDuration(60))
require.Equal(t, "1h1m0s", formatIntervalDuration(61))
require.Equal(t, "3m0s", formatIntervalDuration(3))
}

func TestGiteaOrgsRepositoryBackup(t *testing.T) {
if os.Getenv(envGiteaToken) == "" {
t.Skipf("Skipping Gitea test as %s is missing", envGiteaToken)
Expand All @@ -405,45 +412,72 @@ func TestGiteaOrgsRepositoryBackup(t *testing.T) {

defer resetBackups()

unsetEnvVarsExcept([]string{envGitBackupDir, envGiteaToken, envGiteaAPIURL, envGiteaOrgs})
unsetEnvVarsExcept([]string{envGitBackupDir, envGiteaToken, envGiteaAPIURL})

for _, org := range []string{"soba-org-two", "*"} {
require.NoError(t, os.Setenv(envGiteaOrgs, org))

require.NoError(t, run())

require.DirExists(t, path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-two"))
entriesOrgOne, err := os.ReadDir(path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-one"))
require.NoError(t, err)
entriesOrgTwo, err := os.ReadDir(path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-two"))
require.NoError(t, err)
switch org {
case "soba-org-two":
require.DirExists(t, path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-two"))
require.NoDirExists(t, path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-one"))
entriesOrgTwo, err := os.ReadDir(path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-two"))
require.NoError(t, err)

require.Len(t, entriesOrgTwo, 2)
require.Len(t, entriesOrgTwo, 2)

var foundOne, foundTwo, foundThree bool
var foundOne, foundTwo bool

for _, entry := range entriesOrgOne {
if strings.HasPrefix(entry.Name(), "soba-org-one-repo-one") {
foundThree = true
for _, entry := range entriesOrgTwo {
if strings.HasPrefix(entry.Name(), "soba-org-two-repo-one") {
foundOne = true
}

if strings.HasPrefix(entry.Name(), "soba-org-two-repo-two") {
foundTwo = true
}
}
}

for _, entry := range entriesOrgTwo {
if strings.HasPrefix(entry.Name(), "soba-org-two-repo-one") {
foundOne = true
require.True(t, foundOne)
require.True(t, foundTwo)

resetBackups()
case "*":
require.DirExists(t, path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-two"))
require.DirExists(t, path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-one"))
entriesOrgOne, err := os.ReadDir(path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-one"))
require.NoError(t, err)
entriesOrgTwo, err := os.ReadDir(path.Join(os.Getenv(envGitBackupDir), "gitea.lessknown.co.uk", "soba-org-two"))
require.NoError(t, err)

require.Len(t, entriesOrgOne, 1)
require.Len(t, entriesOrgTwo, 2)

var foundOne, foundTwo, foundThree bool

for _, entry := range entriesOrgOne {
if strings.HasPrefix(entry.Name(), "soba-org-one-repo-one") {
foundThree = true
}
}

if strings.HasPrefix(entry.Name(), "soba-org-two-repo-two") {
foundTwo = true
for _, entry := range entriesOrgTwo {
if strings.HasPrefix(entry.Name(), "soba-org-two-repo-one") {
foundOne = true
}

if strings.HasPrefix(entry.Name(), "soba-org-two-repo-two") {
foundTwo = true
}
}
}

switch org {
case "soba-org-two":
require.True(t, foundOne && foundTwo)
require.False(t, foundThree)
case "*":
require.True(t, foundOne && foundTwo && foundThree)
require.True(t, foundOne)
require.True(t, foundTwo)
require.True(t, foundThree)

resetBackups()
}

resetBackups()
Expand Down Expand Up @@ -617,3 +651,25 @@ func TestGithubRepositoryBackupWithWildcardOrgsAndPersonal(t *testing.T) {
require.Regexp(t, regexp.MustCompile(`^repo[0,1]\.\d{14}\.bundle$`), entries[0].Name())
}
}

func TestGetBackupInterval(t *testing.T) {
_ = os.Setenv(envGitBackupInterval, "1h")

require.Equal(t, 60, getBackupInterval())

_ = os.Setenv(envGitBackupInterval, "1")

require.Equal(t, 60, getBackupInterval())

_ = os.Setenv(envGitBackupInterval, "100h")

require.Equal(t, 6000, getBackupInterval())

_ = os.Setenv(envGitBackupInterval, "100m")

require.Equal(t, 100, getBackupInterval())

_ = os.Setenv(envGitBackupInterval, "0")

require.Equal(t, 0, getBackupInterval())
}

0 comments on commit 65cd28f

Please sign in to comment.