Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

t3c to use package metadata if rpm db is unhealthy #7652

Merged
merged 10 commits into from
Jul 26, 2023
69 changes: 57 additions & 12 deletions cache-config/t3c-apply/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -81,6 +82,7 @@
SvcManagement SvcManagement
Retries int
ReverseProxyDisable bool
RpmDBOk bool
SkipOSCheck bool
UseStrategies t3cutil.UseStrategiesFlag
TOInsecure bool
Expand Down Expand Up @@ -188,6 +190,29 @@
return info.IsDir(), info
}

const RpmDir = "/var/lib/rpm"
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved

// verifies the rpm database files. if there is any database corruption
// it will return false
func VerifyRpmDB() bool {
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
exclude := regexp.MustCompile(`(^\.|^__)`)
dbFiles, err := os.ReadDir(RpmDir)
if err != nil {
return false
}
for _, file := range dbFiles {
if exclude.Match([]byte(file.Name())) {
continue

Check warning on line 205 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L197-L205

Added lines #L197 - L205 were not covered by tests
}
cmd := exec.Command("/usr/lib/rpm/rpmdb_verify", RpmDir+"/"+file.Name())
err := cmd.Run()
if err != nil || cmd.ProcessState.ExitCode() > 0 {
return false
}

Check warning on line 211 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L207-L211

Added lines #L207 - L211 were not covered by tests
}
return true

Check warning on line 213 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L213

Added line #L213 was not covered by tests
}

// derives the ATS Installation directory from
// the rpm config file list.
func GetTSPackageHome() string {
Expand Down Expand Up @@ -322,10 +347,11 @@
// so we want to log what flags the mode set here, to aid debugging.
// But we can't do that until the loggers are initialized.
modeLogStrs := []string{}
fatalLogStrs := []string{}

Check warning on line 350 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L350

Added line #L350 was not covered by tests
if getopt.IsSet(runModeFlagName) {
runMode := t3cutil.StrToMode(*runModePtr)
if runMode == t3cutil.ModeInvalid {
return Cfg{}, errors.New(*runModePtr + " is an invalid mode.")
fatalLogStrs = append(fatalLogStrs, *runModePtr+" is an invalid mode.")

Check warning on line 354 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L354

Added line #L354 was not covered by tests
}
modeLogStrs = append(modeLogStrs, "t3c-apply is running in "+runMode.String()+" mode")
switch runMode {
Expand Down Expand Up @@ -411,7 +437,7 @@
}

if *verbosePtr > 2 {
return Cfg{}, errors.New("Too many verbose options. The maximum log verbosity level is 2 (-vv or --verbose=2) for errors (0), warnings (1), and info (2)")
fatalLogStrs = append(fatalLogStrs, "Too many verbose options. The maximum log verbosity level is 2 (-vv or --verbose=2) for errors (0), warnings (1), and info (2)")

Check warning on line 440 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L440

Added line #L440 was not covered by tests
}

var cacheHostName string
Expand All @@ -420,7 +446,7 @@
} else {
cacheHostName, err = os.Hostname()
if err != nil {
return Cfg{}, errors.New("Could not get the hostname from the O.S., please supply a hostname: " + err.Error())
fatalLogStrs = append(fatalLogStrs, "Could not get the hostname from the O.S., please supply a hostname: "+err.Error())

Check warning on line 449 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L449

Added line #L449 was not covered by tests
}
// strings.Split always returns a slice with at least 1 element, so we don't need a len check
cacheHostName = strings.Split(cacheHostName, ".")[0]
Expand All @@ -429,7 +455,7 @@
useGit := StrToUseGitFlag(*useGitStr)

if useGit == UseGitInvalid {
return Cfg{}, errors.New("Invalid git flag '" + *useGitStr + "'. Valid options are yes, no, auto.")
fatalLogStrs = append(fatalLogStrs, "Invalid git flag '"+*useGitStr+"'. Valid options are yes, no, auto.")

Check warning on line 458 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L458

Added line #L458 was not covered by tests
}

retries := *retriesPtr
Expand Down Expand Up @@ -471,6 +497,17 @@
os.Setenv("TO_PASS", toPass)
}

rpmDBisOk := VerifyRpmDB()

if *installPackagesPtr && !rpmDBisOk {
if t3cutil.StrToMode(*runModePtr) == t3cutil.ModeBadAss {
fatalLogStrs = append(fatalLogStrs, "RPM database check failed unable to install packages cannot continue in badass mode")
} else {
fatalLogStrs = append(fatalLogStrs, "RPM database check failed unable to install packages cannot continue")
}

Check warning on line 507 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L500-L507

Added lines #L500 - L507 were not covered by tests
}

toInfoLog = append(toInfoLog, fmt.Sprintf("rpm database is ok: %v", rpmDBisOk))

Check warning on line 510 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L510

Added line #L510 was not covered by tests
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
// set TSHome
var tsHome = ""
if *tsHomePtr != "" {
Expand All @@ -481,13 +518,13 @@
tsHome = os.Getenv("TS_HOME") // check for the environment variable.
if tsHome != "" {
toInfoLog = append(toInfoLog, fmt.Sprintf("set TSHome from TS_HOME environment variable '%s'\n", TSHome))
} else { // finally check using the config file listing from the rpm package.
} else if rpmDBisOk { // check using the config file listing from the rpm package if rpmdb is ok.

Check warning on line 521 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L521

Added line #L521 was not covered by tests
tsHome = GetTSPackageHome()
if tsHome != "" {
toInfoLog = append(toInfoLog, fmt.Sprintf("set TSHome from the RPM config file list '%s'\n", TSHome))
} else {
toInfoLog = append(toInfoLog, fmt.Sprintf("no override for TSHome was found, using the configured default: '%s'\n", TSHome))
}
} else if tsHome == "" {
toInfoLog = append(toInfoLog, fmt.Sprintf("no override for TSHome was found, using the configured default: '%s'\n", TSHome))

Check warning on line 527 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L526-L527

Added lines #L526 - L527 were not covered by tests
}
}

Expand All @@ -503,23 +540,23 @@
if *useLocalATSVersionPtr {
atsVersionStr, err = GetATSVersionStr(tsHome)
if err != nil {
return Cfg{}, errors.New("getting local ATS version: " + err.Error())
fatalLogStrs = append(fatalLogStrs, "getting local ATS version: "+err.Error())

Check warning on line 543 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L543

Added line #L543 was not covered by tests
}
}
toInfoLog = append(toInfoLog, fmt.Sprintf("ATSVersionStr: '%s'\n", atsVersionStr))

usageStr := "basic usage: t3c-apply --traffic-ops-url=myurl --traffic-ops-user=myuser --traffic-ops-password=mypass --cache-host-name=my-cache"
if strings.TrimSpace(toURL) == "" {
return Cfg{}, errors.New("Missing required argument --traffic-ops-url or TO_URL environment variable. " + usageStr)
fatalLogStrs = append(fatalLogStrs, "Missing required argument --traffic-ops-url or TO_URL environment variable. "+usageStr)

Check warning on line 550 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L550

Added line #L550 was not covered by tests
}
if strings.TrimSpace(toUser) == "" {
return Cfg{}, errors.New("Missing required argument --traffic-ops-user or TO_USER environment variable. " + usageStr)
fatalLogStrs = append(fatalLogStrs, "Missing required argument --traffic-ops-user or TO_USER environment variable. "+usageStr)

Check warning on line 553 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L553

Added line #L553 was not covered by tests
}
if strings.TrimSpace(toPass) == "" {
return Cfg{}, errors.New("Missing required argument --traffic-ops-password or TO_PASS environment variable. " + usageStr)
fatalLogStrs = append(fatalLogStrs, "Missing required argument --traffic-ops-password or TO_PASS environment variable. "+usageStr)

Check warning on line 556 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L556

Added line #L556 was not covered by tests
}
if strings.TrimSpace(cacheHostName) == "" {
return Cfg{}, errors.New("Missing required argument --cache-host-name. " + usageStr)
fatalLogStrs = append(fatalLogStrs, "Missing required argument --cache-host-name. "+usageStr)

Check warning on line 559 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L559

Added line #L559 was not covered by tests
}

toURLParsed, err := url.Parse(toURL)
Expand All @@ -540,6 +577,7 @@
CacheHostName: cacheHostName,
SvcManagement: svcManagement,
Retries: retries,
RpmDBOk: rpmDBisOk,

Check warning on line 580 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L580

Added line #L580 was not covered by tests
ReverseProxyDisable: reverseProxyDisable,
SkipOSCheck: skipOsCheck,
UseStrategies: useStrategies,
Expand Down Expand Up @@ -580,6 +618,13 @@
return Cfg{}, errors.New("Initializing loggers: " + err.Error() + "\n")
}

if len(fatalLogStrs) > 0 {
for _, str := range fatalLogStrs {
str = strings.TrimSpace(str)
log.Warnln(str)
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
}
return Cfg{}, errors.New("fatal error has occurerd")

Check warning on line 626 in cache-config/t3c-apply/config/config.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/config/config.go#L621-L626

Added lines #L621 - L626 were not covered by tests
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
}
for _, str := range modeLogStrs {
str = strings.TrimSpace(str)
if str == "" {
Expand Down
10 changes: 6 additions & 4 deletions cache-config/t3c-apply/t3c-apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
Expand Down Expand Up @@ -94,8 +93,8 @@
var lock util.FileLock
cfg, err := config.GetCfg(Version, GitRevision)
if err != nil {
fmt.Println(err)
fmt.Println(FailureExitMsg)
log.Infoln(err)
log.Errorln(FailureExitMsg)

Check warning on line 97 in cache-config/t3c-apply/t3c-apply.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/t3c-apply.go#L96-L97

Added lines #L96 - L97 were not covered by tests
return ExitCodeConfigError
} else if cfg == (config.Cfg{}) { // user used the --help option
return ExitCodeSuccess
Expand Down Expand Up @@ -261,7 +260,7 @@
// make sure we got the data necessary to check packages
log.Infoln("======== Didn't get all files, no package processing needed or possible ========")
metaData.InstalledPackages = oldMetaData.InstalledPackages
} else {
} else if cfg.RpmDBOk {

Check warning on line 263 in cache-config/t3c-apply/t3c-apply.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/t3c-apply.go#L263

Added line #L263 was not covered by tests
log.Infoln("======== Start processing packages ========")
err = trops.ProcessPackages()
if err != nil {
Expand All @@ -276,6 +275,9 @@
log.Errorf("Error verifying system services: %s\n", err.Error())
return GitCommitAndExit(ExitCodeServicesError, FailureExitMsg, cfg, metaData, oldMetaData)
}
} else {
log.Infoln("======== RPM DB checks failed, package processing not possible, using installed packages from metadata if available========")
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
trops.ProcessPackagesWithMetaData(oldMetaData.InstalledPackages)

Check warning on line 280 in cache-config/t3c-apply/t3c-apply.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/t3c-apply.go#L278-L280

Added lines #L278 - L280 were not covered by tests
}

log.Debugf("Preparing to fetch the config files for %s, files: %s, syncdsUpdate: %s\n", cfg.CacheHostName, cfg.Files, syncdsUpdate)
Expand Down
45 changes: 44 additions & 1 deletion cache-config/t3c-apply/torequest/torequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,10 +587,14 @@
func (r *TrafficOpsReq) IsPackageInstalled(name string) bool {
for k, v := range r.Pkgs {
if strings.HasPrefix(k, name) {
log.Infof("Found in cache for '%v'", k)
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
return v
}
}

if !r.Cfg.RpmDBOk {
log.Warnf("RPM DB is corrupted cannot run IsPackageInstalled for '%v' and package metadata is unavailable", name)
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
return false
}
log.Infof("IsPackageInstalled '%v' not found in cache, querying rpm", name)
pkgArr, err := util.PackageInfo("pkg-query", name)
if err != nil {
Expand Down Expand Up @@ -1030,6 +1034,45 @@
return nil
}

func pkgMetaDataToMap(pmd []string) map[string]bool {
pkgMap := map[string]bool{}
for _, pkg := range pmd {
pkgMap[pkg] = true
}
return pkgMap

Check warning on line 1042 in cache-config/t3c-apply/torequest/torequest.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/torequest/torequest.go#L1037-L1042

Added lines #L1037 - L1042 were not covered by tests
}

func pkgMatch(pkgMetaData []string, pk string) bool {
for _, pkg := range pkgMetaData {
if ok := strings.Contains(pk, pkg); ok {
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
return true
}

Check warning on line 1049 in cache-config/t3c-apply/torequest/torequest.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/torequest/torequest.go#L1045-L1049

Added lines #L1045 - L1049 were not covered by tests
}
return false

Check warning on line 1051 in cache-config/t3c-apply/torequest/torequest.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/torequest/torequest.go#L1051

Added line #L1051 was not covered by tests

}

func (r *TrafficOpsReq) ProcessPackagesWithMetaData(packageMetaData []string) error {
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
pkgs, err := getPackages(r.Cfg)
pkgMdataMap := pkgMetaDataToMap(packageMetaData)
if err != nil {
return errors.New("getting packages: " + err.Error())
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
}
for _, pkg := range pkgs {
fullPackage := pkg.Name + "-" + pkg.Version
if pkgMdataMap[fullPackage] {
log.Infof("package %v is assumed to be installed according to metadata file", fullPackage)
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
r.Pkgs[fullPackage] = true
} else if pkgMatch(packageMetaData, pkg.Name) {
log.Infof("package %v is assumed to be installed according to metadata, but doesn't match traffic ops pkg", fullPackage)
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
r.Pkgs[fullPackage] = true
} else {
log.Infof("package %v does not appear to be installed.", pkg.Name+"-"+pkg.Version)
jpappa200 marked this conversation as resolved.
Show resolved Hide resolved
}

Check warning on line 1071 in cache-config/t3c-apply/torequest/torequest.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/torequest/torequest.go#L1055-L1071

Added lines #L1055 - L1071 were not covered by tests
}
return nil

Check warning on line 1073 in cache-config/t3c-apply/torequest/torequest.go

View check run for this annotation

Codecov / codecov/patch

cache-config/t3c-apply/torequest/torequest.go#L1073

Added line #L1073 was not covered by tests
}

func (r *TrafficOpsReq) RevalidateWhileSleeping(metaData *t3cutil.ApplyMetaData) (UpdateStatus, error) {
updateStatus, err := r.CheckRevalidateState(true)
if err != nil {
Expand Down
Loading