github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/internal/operator/nodeagent/dep/package-manager-installed.go (about) 1 package dep 2 3 import ( 4 "bufio" 5 "fmt" 6 "io" 7 "os/exec" 8 "strings" 9 ) 10 11 func (p *PackageManager) debbasedInstalled() error { 12 return p.listAndParse(exec.Command("apt", "list", "--installed"), "Listing...", false, func(line string) (string, string, error) { 13 parts := strings.Split(line, "/") 14 if len(parts) < 2 { 15 return "", "", fmt.Errorf(`splitting line "%s" by a forward slash failed`, line) 16 } 17 18 versionParts := strings.Fields(parts[1]) 19 if len(versionParts) < 2 { 20 return "", "", fmt.Errorf(`splitting "%s" (the part after the forward slash) by empty characters failed`, parts[1]) 21 } 22 23 return parts[0], versionParts[1], nil 24 }) 25 } 26 27 func (p *PackageManager) rembasedInstalled(filter []string) error { 28 return p.listAndParse(exec.Command("rpm", append([]string{"-q", "--queryformat", "%{NAME} %{VERSION}-%{RELEASE}\n"}, filter...)...), "", true, func(line string) (string, string, error) { 29 parts := strings.Fields(line) 30 if len(parts) < 2 { 31 return "", "", fmt.Errorf(`splitting line "%s" empty characters failed`, line) 32 } 33 34 return parts[0], parts[1], nil 35 }) 36 } 37 38 func (p *PackageManager) listAndParse(listCommand *exec.Cmd, afterLineContaining string, ignoreError bool, parse func(line string) (string, string, error)) error { 39 40 p.installed = make(map[string][]string) 41 if p.monitor.IsVerbose() { 42 fmt.Println(strings.Join(listCommand.Args, " ")) 43 } 44 45 stdout, err := listCommand.StdoutPipe() 46 if err != nil { 47 return fmt.Errorf("getting stdout pipe for list command failed: %w", err) 48 } 49 bufferedReader := bufio.NewReader(stdout) 50 51 err = listCommand.Start() 52 if err != nil { 53 return fmt.Errorf("listing packages failed: %w", err) 54 } 55 56 doParse := afterLineContaining == "" 57 for err == nil { 58 var line string 59 line, err = bufferedReader.ReadString('\n') 60 if p.monitor.IsVerbose() { 61 fmt.Println(line) 62 } 63 64 if !doParse && strings.Contains(line, afterLineContaining) { 65 doParse = true 66 continue 67 } 68 69 if !doParse { 70 continue 71 } 72 73 pkg, version, _ := parse(line) 74 p.installed[pkg] = append(p.installed[pkg], version) 75 p.monitor.WithFields(map[string]interface{}{ 76 "package": pkg, 77 "version": version, 78 }).Debug("Found installed package") 79 } 80 81 if err == io.EOF { 82 err = nil 83 } 84 85 if waitErr := listCommand.Wait(); waitErr != nil && !ignoreError { 86 return fmt.Errorf("waiting for list packages command failed: %w", waitErr) 87 } 88 89 if err != nil { 90 return fmt.Errorf("reading and parsing installed packages failed: %w", err) 91 } 92 return nil 93 }