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  }