diff options
| author | Jeff Carr <[email protected]> | 2025-10-07 09:01:45 -0500 |
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2025-10-07 09:01:45 -0500 |
| commit | e9e0dd856c77ad3c2f54a53a3ca0eef23f69ede1 (patch) | |
| tree | f1f5bc8001b64f5527c3f84b318e4a99c7678340 | |
| parent | f46ce34f817930945fd5de53a8cdf4a10b62bded (diff) | |
new package
| -rw-r--r-- | apt.go | 28 | ||||
| -rw-r--r-- | distro.go | 61 | ||||
| -rw-r--r-- | hw.go | 33 | ||||
| -rw-r--r-- | init.go | 47 | ||||
| -rw-r--r-- | old/apt.go | 39 | ||||
| -rw-r--r-- | old/apt_darwin.go | 11 | ||||
| -rw-r--r-- | old/apt_windows.go | 11 | ||||
| -rw-r--r-- | update.go | 118 | ||||
| -rw-r--r-- | wit.go | 135 |
9 files changed, 483 insertions, 0 deletions
@@ -4,8 +4,11 @@ package debian import ( + "fmt" + "github.com/go-cmd/cmd" "go.wit.com/lib/fhelp" + "go.wit.com/lib/protobuf/zoopb" "go.wit.com/log" ) @@ -53,3 +56,28 @@ func AptUpdate() error { } return nil } + +// init the installed package list +func initPackages(me *zoopb.Machine) { + // Get the list of installed packages for the detected distro + newP, err := getPackageList(me.Distro) + if err != nil { + fmt.Println("Error:", err) + return + } + + if me.Packages == nil { + me.Packages = new(zoopb.Packages) + } + + // Print the installed packages and their versions + for pkg, version := range newP { + new1 := new(zoopb.Package) + new1.Name = pkg + new1.Version = version + me.Packages.Append(new1) + // log.Info("added", new1.Name, "failed") + } + + getMemory(me) +} diff --git a/distro.go b/distro.go new file mode 100644 index 0000000..a912e2f --- /dev/null +++ b/distro.go @@ -0,0 +1,61 @@ +// Copyright 2024 WIT.COM Inc. + +package debian + +// simple stab at making a human readable distro name +// this is for displaying in a table in the zookeeper app +// it's just so you can easily see what machines in your grid are +// doing what + +import ( + "bufio" + "fmt" + "os" + "runtime" + "strings" +) + +func initDistro() string { + switch runtime.GOOS { + case "windows": + return "windows" + case "macos": + return "macos" + case "linux": + // Detect the Linux distribution + distro := detectDistro() + if distro == "" { + fmt.Println("Unable to detect Linux distribution.") + distro = "fixme" + } + + fmt.Printf("Detected distribution: %s\n", distro) + return distro + default: + return runtime.GOOS + } +} + +// detectDistro returns the Linux distribution name (if possible) +func detectDistro() string { + // Check if we're on Linux + + // Try to read /etc/os-release to determine the distro + file, err := os.Open("/etc/os-release") + if err != nil { + return "" + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "ID=") { + parts := strings.SplitN(line, "=", 2) + if len(parts) == 2 { + return strings.Trim(parts[1], `"`) + } + } + } + return "" +} @@ -0,0 +1,33 @@ +package debian + +import ( + "fmt" + "runtime" + + "go.wit.com/lib/protobuf/zoopb" + "golang.org/x/sys/unix" +) + +// init the installed package list +func getMemory(me *zoopb.Machine) { + // Get number of CPUs + numCPUs := runtime.NumCPU() + + // Get total system memory + var sysInfo unix.Sysinfo_t + err := unix.Sysinfo(&sysInfo) + if err != nil { + fmt.Println("Error getting system info:", err) + return + } + + // Convert memory from bytes to GB + m := float64(sysInfo.Totalram) * float64(sysInfo.Unit) + me.Memory = int64(m) + me.Cpus = int64(numCPUs) + + // totalMemGB := float64(sysInfo.Totalram) * float64(sysInfo.Unit) / (1024 * 1024 * 1024) + // Print results + // fmt.Printf("Total Memory: %.2f GB\n", totalMemGB) + // fmt.Printf("Number of CPUs: %d\n", numCPUs) +} @@ -0,0 +1,47 @@ +package debian + +import ( + "os" + + "go.wit.com/lib/config" + "go.wit.com/lib/protobuf/zoopb" + "go.wit.com/log" +) + +// sent via -ldflags +var VERSION string +var BUILDTIME string + +/* +func (m *zoopb.Machine) SinceLastUpdate() time.Duration { + age := m.Laststamp.AsTime() + return time.Since(age) +} +*/ + +func InitMachine() (*zoopb.Machine, string) { + var fullname string + var err error + m := new(zoopb.Machine) + if fullname, err = config.LoadPB(m, "forge", "machine"); err != nil { + log.Info("zoopb.ConfigLoad() failed", err) + } + hostname, _ := os.Hostname() + m.Hostname = hostname + m.Distro = detectDistro() + m.Packages = zoopb.NewPackages() + initPackages(m) + + InitWitMirrors(m) + config.SavePB(m, fullname) + + return m, fullname +} + +func InitDaemon() *zoopb.Machine { + m := new(zoopb.Machine) + m.Load() + InitWitMirrors(m) + m.Save() + return m +} diff --git a/old/apt.go b/old/apt.go new file mode 100644 index 0000000..4b9018b --- /dev/null +++ b/old/apt.go @@ -0,0 +1,39 @@ +package zoopb + +import ( + "fmt" +) + +// init the installed package list +func initPackages(me *Machine) { + // Get the list of installed packages for the detected distro + newP, err := getPackageList(me.Distro) + if err != nil { + fmt.Println("Error:", err) + return + } + + if me.Packages == nil { + me.Packages = new(Packages) + } + + // Print the installed packages and their versions + for pkg, version := range newP { + new1 := new(Package) + new1.Name = pkg + new1.Version = version + me.Packages.Append(new1) + // log.Info("added", new1.Name, "failed") + } + + me.getMemory() +} + +/* +func (me *Machine) addNew(name string, version string) { + new1 := new(Package) + new1.Name = name + new1.Version = version + me.Packages.Append(new1) +} +*/ diff --git a/old/apt_darwin.go b/old/apt_darwin.go new file mode 100644 index 0000000..0fc8e0f --- /dev/null +++ b/old/apt_darwin.go @@ -0,0 +1,11 @@ +package zoopb + +import ( + "go.wit.com/log" +) + +// getPackageList returns the list of installed packages based on the distro +func getPackageList(distro string) (map[string]string, error) { + log.Info("zoopb: have not done macos yet, skipping okay") + return nil, nil +} diff --git a/old/apt_windows.go b/old/apt_windows.go new file mode 100644 index 0000000..feec104 --- /dev/null +++ b/old/apt_windows.go @@ -0,0 +1,11 @@ +package zoopb + +import ( + "go.wit.com/log" +) + +// getPackageList returns the list of installed packages based on the distro +func getPackageList(distro string) (map[string]string, error) { + log.Info("zoopb: have not done windows yet, skipping okay") + return nil, nil +} diff --git a/update.go b/update.go new file mode 100644 index 0000000..0033447 --- /dev/null +++ b/update.go @@ -0,0 +1,118 @@ +package debian + +import ( + "bufio" + "fmt" + "os/exec" + "strings" + + "go.wit.com/lib/protobuf/zoopb" + "go.wit.com/log" +) + +// getPackageList returns the list of installed packages based on the distro +func getPackageList(distro string) (map[string]string, error) { + var cmd *exec.Cmd + + // Run the appropriate command based on the detected distribution + switch distro { + case "ubuntu", "debian": + return dpkgQuery() + case "fedora", "centos", "rhel": + cmd = exec.Command("rpm", "-qa") + case "arch", "manjaro": + cmd = exec.Command("pacman", "-Q") + default: + return nil, fmt.Errorf("unsupported distribution: %s", distro) + } + + // Capture the command's output + output, err := cmd.CombinedOutput() + if err != nil { + return nil, fmt.Errorf("error running command: %v", err) + } + + // todo: Split the output into lines and return + lines := strings.Split(string(output), "\n") + log.Info("output had", len(lines), "lines") + return nil, nil +} + +func dpkgQuery() (map[string]string, error) { + // Run the dpkg-query command to list installed packages and versions + cmd := exec.Command("dpkg-query", "-W", "-f=${Package} ${Version}\n") + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, err + } + + // Start the command execution + if err := cmd.Start(); err != nil { + return nil, err + } + defer cmd.Wait() + + // Create a map to store package names and versions + installedPackages := make(map[string]string) + + // Use a scanner to read the output of the command line by line + scanner := bufio.NewScanner(stdout) + for scanner.Scan() { + line := scanner.Text() + // Split each line into package name and version + parts := strings.SplitN(line, " ", 2) + if len(parts) == 2 { + packageName := parts[0] + version := parts[1] + installedPackages[packageName] = version + } + } + + // Return the map with package names and versions + return installedPackages, scanner.Err() +} + +/* +func (me *Machine) UpdatePackages() string { + log.Info("fixme. broken after move to autogenpb") + return "" +} +*/ + +func UpdatePackages(me *zoopb.Machine) string { + // Get the list of installed packages for the detected distro + newP, err := getPackageList(me.Distro) + if err != nil { + fmt.Println("Error:", err) + return fmt.Sprintln("getPackageList()", err) + } + + var newCounter, changeCounter int + // Print the installed packages and their versions + for pname, version := range newP { + found := me.Packages.FindByName(pname) + if found == nil { + log.Info("adding new", pname, version) + new1 := new(zoopb.Package) + new1.Name = pname + new1.Version = version + me.Packages.Append(new1) + newCounter += 1 + } else { + found.Version = version + // panic("redo this. broken after autogenpb. was never right anyway") + //if me.Packages.Update(found) { + // changeCounter += 1 + //} + } + } + + footer := fmt.Sprintf("%s has distro %s with %d packages installed", me.Hostname, me.Distro, me.Packages.Len()) + if changeCounter != 0 { + footer += fmt.Sprintf(" (%d changed)", changeCounter) + } + if newCounter != 0 { + footer += fmt.Sprintf(" (%d new)", newCounter) + } + return footer +} @@ -0,0 +1,135 @@ +package debian + +import ( + "bufio" + "os" + "strings" + + "go.wit.com/lib/fhelp" + "go.wit.com/lib/protobuf/zoopb" +) + +// obviously a hack at this point +// read the package list file from mirrors.wit.com +func InitWitMirrors(m *zoopb.Machine) error { + m.Wit = zoopb.NewPackages() + err := scanPackageListFile(m, "/var/lib/apt/lists/mirrors.wit.com_wit_dists_sid_main_binary-amd64_Packages") + return err +} + +// adds the package if the name isn't there +// if it's newer, remove the old package and use the new one +func AddIfNewer(all *zoopb.Packages, p *zoopb.Package) { + check := all.FindByName(p.Name) + if check == nil { + all.Append(p) + return + } + v1, _ := fhelp.NewDebVersion(check.Version) + v2, _ := fhelp.NewDebVersion(p.Version) + if v1.Equal(v2) { + // log.Info("do nothing", v1, v2) + return + } + if v1.LessThan(v2) { + // log.Info("removing", v1, "using", v2) + all.Delete(check) + all.Append(p) + } else { + // log.Info("keeping", v1, "got:", v2) + } +} + +// breaks up the apt list file into sections +// then sends each section to be processed +// and added to zoopb.Machine.Wit +func scanPackageListFile(m *zoopb.Machine, filename string) error { + file, err := os.Open(filename) + if err != nil { + return err + } + defer file.Close() + scanner := bufio.NewScanner(file) + var debInfo string + for scanner.Scan() { + line := scanner.Text() + if line == "" { + p := parsePackageInfo(debInfo) + AddIfNewer(m.Wit, p) + debInfo = "" + } + debInfo += line + "\n" + } + p := parsePackageInfo(debInfo) + m.Wit.Append(p) + return nil +} + +/* +func (m *Machine) addPackage(name string, version string, filename string) { + if name == "" { + return + } + // log.Info("addPackage:", name, version, filename) + var deb *DebPackage + var ok bool + deb, ok = allp[name] + if !ok { + deb = NewPackage() + deb.name.SetLabel(name) + allp[name] = deb + } + newversion := new(Version) + newversion.v = version + newversion.file = filename + deb.versions = append(deb.versions, newversion) +} +*/ + +// parses dpkg -s foo.deb +func parsePackageInfo(lines string) *zoopb.Package { + var name string + var version string + var filename string + var gopath string + + for _, line := range strings.Split(lines, "\n") { + if line == "" { + continue + } + if strings.HasPrefix(line, " ") { + // these are usually Description: lines + continue + } + if strings.HasPrefix(line, "#") { + // skip comment lines. (probably doesn't happen in debian list files + continue + } + line = strings.TrimSpace(line) + parts := strings.Split(line, " ") + if len(parts) < 2 { + continue + } + if parts[0] == "Package:" { + name = parts[1] + } + if parts[0] == "Version:" { + version = parts[1] + } + if parts[0] == "Filename:" { + filename = strings.Join(parts[1:], " ") + } + if parts[0] == "GoPath:" { + gopath = parts[1] + } + } + + p := zoopb.Package{ + Name: name, + Version: version, + PkgName: filename, + SrcPath: gopath, + } + + return &p +} |
