<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/bborbe/backup/config"
	"github.com/bborbe/backup/dto"
	"github.com/bborbe/backup/service"
	"github.com/bborbe/backup/util"
	"github.com/bborbe/log"
	"io"
	"os"
	"sort"
	"syscall"
)

const LOCK_NAME = "/var/run/backup_clean.lock"

var logger = log.DefaultLogger

func main() {
	logLevelPtr := flag.Int("loglevel", config.DEFAULT_LOG_LEVEL, "int")
	rootdirPtr := flag.String("rootdir", config.DEFAULT_ROOT_DIR, "string")
	hostPtr := flag.String("host", config.DEFAULT_HOST, "string")
	flag.Parse()
	logger.SetLevelThreshold(*logLevelPtr)
	logger.Debugf("set log level to %s", log.LogLevelToString(*logLevelPtr))

	writer := os.Stdout
	logger.Debugf("use backup dir %s", *rootdirPtr)
	backupService := service.NewBackupService(*rootdirPtr)
	err := do(writer, backupService, *hostPtr, LOCK_NAME)
	if err != nil {
		logger.Fatal(err)
		os.Exit(1)
	}
}

func do(writer io.Writer, backupService service.BackupService, hostname string, lockName string) error {
	var err error
	var hosts []dto.Host
	err = lock(lockName)
	if err != nil {
		return err
	}
	defer unlock(lockName)
	logger.Debug("start")
	if hostname == config.DEFAULT_HOST {
		hosts, err = backupService.ListHosts()
		if err != nil {
			return err
		}
	} else {
		host, err := backupService.GetHost(hostname)
		if err != nil {
			return err
		}
		hosts = []dto.Host{host}
	}
	sort.Sort(util.HostByDate(hosts))
	for _, host := range hosts {
		err := backupService.Cleanup(host)
		if err != nil {
			return err
		}
		fmt.Fprintf(writer, "%s cleaned\n", host.GetName())
	}
	logger.Debug("done")
	return nil
}

func lock(name string) error {
	logger.Debugf("try lock %s", name)
	var err error
	var file *os.File
	file, err = os.Create(name)
	if err != nil {
		return err
	}
	file, err = os.OpenFile(name, os.O_APPEND, 0666)
	if err != nil {
		return err
	}
	err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX)
	if err != nil {
		return err
	}
	logger.Debugf("locked %s", name)
	return file.Close()
}

func unlock(name string) error {
	logger.Debugf("try unlock %s", name)
	var err error
	var file *os.File
	file, err = os.OpenFile(name, os.O_APPEND, 0666)
	if err != nil {
		return err
	}
	err = syscall.Flock(int(file.Fd()), syscall.LOCK_UN)
	if err != nil {
		return err
	}<commit_msg>fix locking<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/bborbe/backup/config"
	"github.com/bborbe/backup/dto"
	"github.com/bborbe/backup/service"
	"github.com/bborbe/backup/util"
	"github.com/bborbe/log"
	"io"
	"os"
	"sort"
	"syscall"
)

const LOCK_NAME = "/var/run/backup_clean.lock"

var logger = log.DefaultLogger

func main() {
	logLevelPtr := flag.Int("loglevel", config.DEFAULT_LOG_LEVEL, "int")
	rootdirPtr := flag.String("rootdir", config.DEFAULT_ROOT_DIR, "string")
	hostPtr := flag.String("host", config.DEFAULT_HOST, "string")
	flag.Parse()
	logger.SetLevelThreshold(*logLevelPtr)
	logger.Debugf("set log level to %s", log.LogLevelToString(*logLevelPtr))

	writer := os.Stdout
	logger.Debugf("use backup dir %s", *rootdirPtr)
	backupService := service.NewBackupService(*rootdirPtr)
	err := do(writer, backupService, *hostPtr, LOCK_NAME)
	if err != nil {
		logger.Fatal(err)
		os.Exit(1)
	}
}

func do(writer io.Writer, backupService service.BackupService, hostname string, lockName string) error {
	var err error
	var hosts []dto.Host
	err = lock(lockName)
	if err != nil {
		return err
	}
	defer unlock(lockName)
	logger.Debug("start")
	if hostname == config.DEFAULT_HOST {
		hosts, err = backupService.ListHosts()
		if err != nil {
			return err
		}
	} else {
		host, err := backupService.GetHost(hostname)
		if err != nil {
			return err
		}
		hosts = []dto.Host{host}
	}
	sort.Sort(util.HostByDate(hosts))
	for _, host := range hosts {
		err := backupService.Cleanup(host)
		if err != nil {
			return err
		}
		fmt.Fprintf(writer, "%s cleaned\n", host.GetName())
	}
	logger.Debug("done")
	return nil
}

func lock(name string) error {
	logger.Debugf("try lock %s", name)
	var err error
	var file *os.File
	file, _ = os.Open(name)
	if file == nil {
		file, err = os.Create(name)
		if err != nil {
			return err
		}
	}
	err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX)
	if err != nil {
		return err
	}
	logger.Debugf("locked %s", name)
	return file.Close()
}

func unlock(name string) error {
	logger.Debugf("try unlock %s", name)
	var err error
	var file *os.File
	file, err = os.Open(name)
	if err != nil {
		return err
	}
	err = syscall.Flock(int(file.Fd()), syscall.LOCK_UN)
	if err != nil {
		return err
	}
{'fraction_non_alphanumeric': 0.14850615114235502, 'fraction_numerical': 0.0021968365553602814, 'mean_word_length': 4.003296703296703, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3087431', 'n_tokens_mistral': 1814, 'n_tokens_neox': 1728, 'n_words': 404}