in integration_test/agents/agents.go [432:482]
func checkPackages(ctx context.Context, logger *log.Logger, vm *gce.VM, pkgs []string, installed bool) error {
errPrefix := ""
if installed {
errPrefix = "not "
}
if gce.IsWindows(vm.ImageSpec) {
output, err := gce.RunRemotely(ctx, logger, vm, "googet installed")
if err != nil {
return err
}
for _, pkg := range pkgs {
// Look for the package name in the output. \b means word boundary.
expr := `\b` + pkg + `\b`
re, err := regexp.Compile(expr)
if err != nil {
return fmt.Errorf("regexp %q failed to compile: %v", expr, err)
}
if m := re.FindString(output.Stdout); (m == "") == installed {
return fmt.Errorf("package %q was unexpectedly %sinstalled", pkg, errPrefix)
}
}
// Success: the expected set of packages was found in the output of "googet installed".
return nil
}
for _, pkg := range pkgs {
cmd := ""
if IsRPMBased(vm.ImageSpec) {
cmd = fmt.Sprintf("rpm --query %s", pkg)
if !installed {
cmd = "! " + cmd
}
} else if strings.HasPrefix(vm.ImageSpec, "debian-cloud") ||
strings.HasPrefix(vm.ImageSpec, "ubuntu-os-cloud") {
// dpkg's package states are documented in "man 1 dpkg".
// "config-files" means that the package is not installed but its config files
// are still on the system. Accepting both that and "not-installed" is more
// future-proof than just accepting "config-files".
cmd = fmt.Sprintf(
`(dpkg-query --show '--showformat=${db:Status-Status}' %s || echo 'not-installed') | grep --extended-regexp '(not-installed)|(config-files)'`, pkg)
if installed {
cmd = "! (" + cmd + ")"
}
} else {
return fmt.Errorf("checkPackages() does not support image spec: %s", vm.ImageSpec)
}
if _, err := gce.RunRemotely(ctx, logger, vm, cmd); err != nil {
return fmt.Errorf("command could not be run or %q was unexpectedly %sinstalled. err: %v", pkg, errPrefix, err)
}
}
return nil
}