package main import ( "fmt" "io" "log" "path/filepath" "strings" "git.nevets.tech/Steven/ezconf" "github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-git/v5/storage/memory" ) func initClient() { err := loadDomainConfigs() if err != nil { log.Fatalf("Error loading domain configs: %v", err) } } func clientTick() { fmt.Println("Tick!") // Get local copy of domain configs mu.RLock() localDomainConfigs := make(map[string]*ezconf.Configuration, len(domainConfigs)) for k, v := range domainConfigs { localDomainConfigs[k] = v } mu.RUnlock() // Loop over all domain configs (domains) for domainStr, domainConfig := range localDomainConfigs { // Skip non-enabled domains if !domainConfig.GetAsBoolean("Domain.enabled") { continue } // Skip domains with up-to-date commit hashes // If the repo doesn't exist, we can't check for a remote commit, so stop the rest of the check repoExists := domainConfig.GetAsBoolean("Internal.repo_exists") if repoExists { localHash, err := getLocalCommitHash(domainStr) if err != nil { fmt.Printf("No local commit hash found for domain %s\n", domainStr) } gitSource, err := strToGitSource(config.GetAsString("Git.host")) if err != nil { fmt.Printf("Error getting git source for domain %s: %v\n", domainStr, err) continue } remoteHash, err := getRemoteCommitHash(domainStr, gitSource) if err != nil { fmt.Printf("Error getting remote commit hash for domain %s: %v\n", domainStr, err) } // If both hashes are blank (errored), break // If localHash equals remoteHash (local is up-to-date), skip if !(localHash == "" && remoteHash == "") && localHash == remoteHash { fmt.Printf("Domain %s is up to date. Skipping...\n", domainStr) continue } } gitWorkspace := &GitWorkspace{ Storage: memory.NewStorage(), FS: memfs.New(), } // Ex: https://git.example.com/Org/Repo-suffix.git // Clones repo and stores in gitWorkspace, skip if clone fails (doesn't exist?) repoUrl := config.GetAsString("Git.server") + "/" + config.GetAsString("Git.org_name") + "/" + domainStr + domainConfig.GetAsString("Repo.repo_suffix") + ".git" err := cloneRepo(repoUrl, gitWorkspace) if err != nil { fmt.Printf("Error cloning domain repo %s: %v\n", domainStr, err) continue } certsDir, err := getDomainCertsDirWConf(domainStr, domainConfig) if err != nil { fmt.Printf("Error getting certificates dir for domain %s: %v\n", domainStr, err) continue } // Get files in repo fileInfos, err := gitWorkspace.FS.ReadDir("/") if err != nil { fmt.Printf("Error reading directory in memFS on domain %s: %v\n", domainStr, err) continue } // Iterate over files, filtering by .crpt (encrypted) files in case other files were accidentally added for _, fileInfo := range fileInfos { if strings.HasSuffix(fileInfo.Name(), ".crpt") { filename, _ := strings.CutSuffix(fileInfo.Name(), ".crpt") file, err := gitWorkspace.FS.Open(fileInfo.Name()) if err != nil { fmt.Printf("Error opening file in memFS on domain %s: %v\n", domainStr, err) continue } fileBytes, err := io.ReadAll(file) if err != nil { fmt.Printf("Error reading file in memFS on domain %s: %v\n", domainStr, err) file.Close() continue } err = file.Close() if err != nil { fmt.Printf("Error closing file on domain %s: %v\n", domainStr, err) continue } err = DecryptFileFromBytes(domainConfig.GetAsString("Certificates.crypto_key"), fileBytes, filepath.Join(certsDir, filename), nil) if err != nil { fmt.Printf("Error decrypting file %s in domain %s: %v\n", filename, domainStr, err) continue } headRef, err := gitWorkspace.Repo.Head() if err != nil { fmt.Printf("Error getting head reference for domain %s: %v\n", domainStr, err) continue } err = writeCommitHash(headRef.Hash().String(), domainConfig) if err != nil { fmt.Printf("Error writing commit hash: %v\n", err) continue } } } } } func reloadClient() { fmt.Println("Reloading configs...") err := loadDomainConfigs() if err != nil { fmt.Printf("Error loading domain configs: %v\n", err) return } } func stopClient() { fmt.Println("Shutting down client") }