package main import ( "crypto/sha256" "embed" "errors" "fmt" "os" "os/exec" "path/filepath" "strings" "time" "go.wit.com/lib/cobol" "go.wit.com/lib/config" "go.wit.com/lib/gui/prep" "go.wit.com/lib/gui/shell" "go.wit.com/lib/protobuf/zoopb" "go.wit.com/log" ) // sent via -ldflags var VERSION string var BUILDTIME string // used for shell auto completion var ARGNAME string = "mirrors" // todo: get this from $0 ? //go:embed resources/* var resources embed.FS func main() { me = new(mainType) me.sh = prep.Bash3(&argv) // add support for bash autocomplete with go-arg // read in protobuf file me.pb = zoopb.NewPackages() me.pb.Filename = "/home/mirrors/wit/mirrors.wit.com.pb" if err := me.pb.Load(); err != nil { if argv.Force { config.Save(me.pb) } else { me.sh.BadExit("no config found. use --force to create one", err) } } if me.pb.BaseDir != "/home/mirrors/wit" { me.pb.Filename = "/home/mirrors/wit/mirrors.wit.com.pb" me.pb.BaseDir = "/home/mirrors/wit" me.pb.Save() panic("missing /home/mirrors/wit as BaseDir") } if err := os.Chdir(me.pb.BaseDir); err != nil { me.sh.BadExit("no '"+me.pb.BaseDir+"' directory", err) } if !shell.IsDir("pool/") { me.sh.BadExit("no "+filepath.Join(me.pb.BaseDir, "pool")+" directory", errors.New("mount -a ? missing wit/pool/")) } if me.sh.Cmd == "" { // default behavior when no argv s := log.Sprintf("You have %d packages in %s", me.pb.Len(), me.pb.BaseDir) me.sh.GoodExit(s) } // default handling of argv subcommands var s string var err error if argv.Incoming != nil { s, err = doIncoming(me.pb) } if argv.Walk != nil { s, err = doWalk() } if argv.List != nil { s, err = doList() } if argv.Verify != nil { s, err = doVerify() } if argv.Update != nil { err = doDistro() } if argv.MakeDists != nil { s, err = doMakeDists() } if argv.Newest != nil { s, err = doNewest("amd64") } if err != nil { me.sh.BadExit(s, err) } me.sh.GoodExit(s) } // make a list of the newest .deb files func doNewest(arch string) (string, error) { log.Info("Processing dir", filepath.Join(me.pb.BaseDir, "pool")) newest := zoopb.NewPackages() for p := range me.pb.IterAll() { if p.Architecture != arch { continue } found := newest.FindByPackage(p.Package) if found == nil { // package is new log.Printf("%-20.20s %-20.20s %-80.80s\n", "new package", p.Package, p.Filename) newest.Clone(p) continue } curtime := p.Ctime.AsTime() newtime := found.Ctime.AsTime() durs := cobol.Since(p.Ctime) + " vs found " + cobol.Since(found.Ctime) if time.Since(curtime) > time.Since(newtime) { log.Printf("%-20.20s %-20.20s %-80.80s %s\n", "found is newer", p.Package, p.Filename, durs) } else { log.Printf("%-20.20s %-20.20s %-80.80s %s\n", "found is older", p.Package, p.Filename, durs) newest.Delete(found) newest.Clone(p) } } newest.SortPackage() var myshit string for p := range newest.IterAll() { controlfile, err := p.GetDebianControlFile() if err != nil { log.Info("make debInfo file error", err) panic("deb error") } log.Info(controlfile) myshit += controlfile + "\n" } fullname := "/home/mirrors/wit/first.Packages" if err := os.WriteFile(fullname, []byte(myshit), 0644); err != nil { return fullname, err } shell.RunVerbose([]string{"gzip", "-f", "-k", fullname}) shell.RunVerbose([]string{"bzip2", "-f", "-k", fullname}) allfiles, _ := FindFiles("dists/sid/main") for i, filename := range allfiles { log.Info(i, filename) } releasePath := filepath.Join("/home/mirrors/wit/dists/sid", "Release") rfile, _ := os.OpenFile(releasePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) fmt.Fprintf(rfile, "Origin: WIT.COM Debian Sid\n") fmt.Fprintf(rfile, "Label: WIT.COM Debian Sid\n") fmt.Fprintf(rfile, "Suite: sid\n") fmt.Fprintf(rfile, "Codename: sid\n") fmt.Fprintf(rfile, "Date: %s\n", time.Now().UTC().Format(time.RFC1123Z)) fmt.Fprintf(rfile, "Architectures: riscv64 amd64 arm64 all\n") fmt.Fprintf(rfile, "Components: main\n") fmt.Fprintf(rfile, "Description: Tooling for RiscV, Semiconductor Designs & Private Clouds\n") /* fmt.Fprintf(rfile, "MD5SUM:\n") for i, filename := range allfiles { log.Info(i, filename) fileBytes, _ := os.ReadFile(filename) sum := fmt.Sprintf("%x", md5.Sum(fileBytes)) // deprecated newfile := strings.TrimPrefix(filename, "dists/sid/") fmt.Fprintf(rfile, " %s %d %s\n", sum, len(fileBytes), newfile) } fmt.Fprintf(rfile, "SHA1:\n") for i, filename := range allfiles { log.Info(i, filename) fileBytes, _ := os.ReadFile(filename) sum := fmt.Sprintf("%x", sha1.Sum(fileBytes)) newfile := strings.TrimPrefix(filename, "dists/sid/") fmt.Fprintf(rfile, " %s %d %s\n", sum, len(fileBytes), newfile) } */ fmt.Fprintf(rfile, "SHA256:\n") for i, filename := range allfiles { log.Info(i, filename) fileBytes, _ := os.ReadFile(filename) sum := fmt.Sprintf("%x", sha256.Sum256(fileBytes)) newfile := strings.TrimPrefix(filename, "dists/sid/") fmt.Fprintf(rfile, " %s %d %s\n", sum, len(fileBytes), newfile) } // fmt.Fprintf(rfile, "SHA1:\n") // fmt.Fprintf(rfile, "SHA256:\n") rfile.Close() // Sign the file log.Println("Signing with GPG key:", gpgKeyID) distPath := "/home/mirrors/wit/dists/sid" // Create InRelease cmdClearSign := exec.Command("gpg", "--default-key", gpgKeyID, "--clearsign", "-o", filepath.Join(distPath, "InRelease"), releasePath) if err := runCommand(cmdClearSign); err != nil { log.Printf("failed to create InRelease: %v\n", err) } // Create Release.gpg cmdDetachedSign := exec.Command("gpg", "--default-key", gpgKeyID, "-abs", "-o", filepath.Join(distPath, "Release.gpg"), releasePath) if err := runCommand(cmdDetachedSign); err != nil { log.Printf("failed to create Release.gpg: %v\n", err) } /* var sum string switch name { case "MD5Sum": sum = fmt.Sprintf("%x", md5.Sum(fileBytes)) case "SHA1": sum = fmt.Sprintf("%x", sha1.Sum(fileBytes)) case "SHA256": // FIX 3: Use the correct sha256.Sum256 function. sum = fmt.Sprintf("%x", sha256.Sum256(fileBytes)) */ return "doNewest", nil }