166 lines
4.2 KiB
Go
166 lines
4.2 KiB
Go
package sync
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"git.csclub.uwaterloo.ca/public/merlin/config"
|
|
)
|
|
|
|
// jobs to complete before repo sync command should be run
|
|
// when done is false: status can be ignored and sync command should continue
|
|
// when done is true: sync should exit with status
|
|
func preRepoSync(repo *config.Repo) (status int, done bool) {
|
|
status = config.SUCCESS
|
|
done = false
|
|
|
|
// clear the rsync log file
|
|
if repo.RsyncLogFile != "" {
|
|
err := os.Truncate(repo.RsyncLogFile, 0)
|
|
if err != nil {
|
|
status = config.FAILURE
|
|
repo.Logger.Error("Error while trying to clear logfile: " + repo.RepoLogFile)
|
|
}
|
|
}
|
|
|
|
if repo.TraceHost != "" {
|
|
if status, done = checkIfRepoSyncNeeded(repo); done {
|
|
|
|
// run alternative jobs if a full sync will not be done
|
|
if exit := noRepoSyncNeeded(repo); exit != config.SUCCESS {
|
|
status = exit
|
|
}
|
|
return
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// check if the repo should be synced by comparing their trace file with our own
|
|
// returns the exit status of the command used to retrieve the repo's trace file
|
|
// returns true for done if and only if no errors occur and it is confirmed that
|
|
// the trace files are the same or that a termination signal was given
|
|
// (csc-sync-debian will always sync so done in its case will always be false)
|
|
func checkIfRepoSyncNeeded(repo *config.Repo) (status int, done bool) {
|
|
status = config.FAILURE
|
|
done = false
|
|
|
|
if repo.DryRun {
|
|
repo.Logger.Debug("dry running so assuming that trace file was changed")
|
|
return config.SUCCESS, false
|
|
}
|
|
|
|
repo.Logger.Debug("Retrieving the repo's trace file")
|
|
|
|
temp, err := os.CreateTemp("/tmp", "merlin-"+repo.Name+"-trace-*")
|
|
if err != nil {
|
|
repo.Logger.Error(err.Error())
|
|
return
|
|
}
|
|
temp.Close()
|
|
defer os.Remove(temp.Name())
|
|
|
|
// get the trace command to copy the last update file
|
|
var cmd []string
|
|
switch repo.SyncType {
|
|
case "csc-sync-archlinux":
|
|
cmd = cscTraceArchLinux(repo, temp.Name())
|
|
case "csc-sync-debian":
|
|
cmd = cscTraceDebian(repo, temp.Name())
|
|
default:
|
|
repo.Logger.Error("Trace files are not implemented for sync type '" + repo.SyncType + "'")
|
|
return
|
|
}
|
|
|
|
status = spawnProcessAndWait(repo, cmd)
|
|
if status != config.SUCCESS {
|
|
if status == config.TERMINATED {
|
|
done = true
|
|
}
|
|
return
|
|
}
|
|
|
|
repo.Logger.Debug("Comparing the repo's trace file with our own")
|
|
|
|
// diff returns true if files are the same (if files are the same then sync is done)
|
|
switch repo.SyncType {
|
|
case "csc-sync-archlinux":
|
|
done = cscTraceArchLinuxDiff(repo, temp.Name())
|
|
case "csc-sync-debian":
|
|
done = cscTraceDebianDiff(repo, temp.Name())
|
|
}
|
|
|
|
if done {
|
|
repo.Logger.Info("trace file for " + repo.RsyncHost + " unchanged")
|
|
|
|
// debian syncs even when trace file is unchanged
|
|
if repo.SyncType == "csc-sync-debian" {
|
|
done = false
|
|
}
|
|
return
|
|
}
|
|
|
|
repo.Logger.Debug("trace file changes found; will attempt to sync")
|
|
return
|
|
}
|
|
|
|
// jobs to do when a full sync will not be run
|
|
func noRepoSyncNeeded(repo *config.Repo) (status int) {
|
|
status = config.SUCCESS
|
|
|
|
var args []string
|
|
switch repo.SyncType {
|
|
case "csc-sync-archlinux":
|
|
args = cscTraceArchLinuxUpdate(repo)
|
|
}
|
|
|
|
status = spawnProcessAndWait(repo, args)
|
|
return
|
|
}
|
|
|
|
func cscTraceArchLinux(repo *config.Repo, newTime string) []string {
|
|
args := []string{
|
|
"curl",
|
|
"--interface", config.Conf.IPv4Address,
|
|
"-s", repo.TraceHost,
|
|
"-o", newTime,
|
|
}
|
|
|
|
return args
|
|
}
|
|
|
|
func cscTraceDebian(repo *config.Repo, newTime string) []string {
|
|
args := []string{
|
|
"nice", "rsync", "-tv", "--quiet",
|
|
"-4", "--address=" + config.Conf.IPv4Address,
|
|
repo.RsyncHost + "::" + filepath.Join(repo.RsyncDir, "project/trace", repo.TraceHost),
|
|
newTime,
|
|
}
|
|
|
|
return args
|
|
}
|
|
|
|
func cscTraceArchLinuxDiff(repo *config.Repo, newTime string) bool {
|
|
return diffFileContent(repo, newTime, filepath.Join(buildDownloadDir(repo), "lastupdate"))
|
|
}
|
|
|
|
func cscTraceDebianDiff(repo *config.Repo, newTime string) bool {
|
|
return diffFileTime(repo, newTime, filepath.Join(buildDownloadDir(repo), "project/trace", repo.TraceHost))
|
|
}
|
|
|
|
func cscTraceArchLinuxUpdate(repo *config.Repo) (args []string) {
|
|
rsyncDir := repo.RsyncDir
|
|
localDir := repo.LocalDir
|
|
|
|
repo.RsyncDir = repo.RsyncDir + "/lastsync"
|
|
repo.LocalDir = repo.LocalDir + "/lastsync"
|
|
|
|
args = cscSyncArchLinux(repo)
|
|
|
|
repo.RsyncDir = rsyncDir
|
|
repo.LocalDir = localDir
|
|
|
|
return args
|
|
}
|