// returns a column of the routing table as a slice of strings func routingTableColumn(name string) []string { cmd := exec.Command("route", "-n") out := wrkutils.CommandOutput(cmd) table := tabular.ProbabalisticSplit(out) if len(table) < 1 { log.WithFields(log.Fields{ "column": name, "table": "\n" + tabular.ToString(table), }).Fatal("Routing table was not available or not properly parsed") } finalTable := table[1:] // has extra line before headers return tabular.GetColumnByHeader(name, finalTable) }
// systemctlSock is an abstraction of systemctlSockPath and systemctlSockUnit, // it reads from `systemctl list-sockets` and sees if the value is in the // appropriate column. func systemctlSock(value string, column string) (exitCode int, exitMessage string) { outstr := wrkutils.CommandOutput(exec.Command("systemctl", "list-sockets")) lines := tabular.Lines(outstr) msg := "systemctl list-sockers didn't output enough rows" wrkutils.IndexError(msg, len(lines)-4, lines) unlines := tabular.Unlines(lines[:len(lines)-4]) table := tabular.SeparateOnAlignment(unlines) values := tabular.GetColumnByHeader(column, table) if tabular.StrIn(value, values) { return 0, "" } return wrkutils.GenericError("Socket not found", value, values) }
// systemctlService checks to see if a service has a givens status // status: active | loaded func systemctlService(service string, activeOrLoaded string) (exitCode int, exitMessage string) { // cmd depends on whether we're checking active or loaded cmd := exec.Command("systemctl", "show", "-p", "ActiveState", service) if activeOrLoaded == "loaded" { cmd = exec.Command("systemctl", "show", "-p", "LoadState", service) } outString := wrkutils.CommandOutput(cmd) contained := "ActiveState=active" if activeOrLoaded == "loaded" { contained = "LoadState=loaded" } if strings.Contains(outString, contained) { return 0, "" } msg := "Service not " + activeOrLoaded return wrkutils.GenericError(msg, service, []string{outString}) }
// getYumRepos constructs Repos from the yum.conf file at path. Gives non-zero // Names, Fullnames, and URLs. func getYumRepos() (repos []repo) { // safeAccess allows access w/o fear of a panic into a slice of strings safeAccess := func(slc []string, index int) string { // catch runtime panic defer func() { if err := recover(); err != nil { msg := "safeAccess: Please report this error" wrkutils.IndexError(msg, index, slc) } }() // invoke inside defer if len(slc) > index { return slc[index] } return "" } // get and parse output of `yum repolist` cmd := exec.Command("yum", "repolist") outstr := wrkutils.CommandOutput(cmd) slc := tabular.ProbabalisticSplit(outstr) ids := tabular.GetColumnNoHeader(0, slc) // TODO use columnbyheader here wrkutils.IndexError("getYumRepos", 2, ids) ids = ids[:len(ids)-2] names := tabular.GetColumnNoHeader(1, slc) // TODO and here statuses := tabular.GetColumnNoHeader(2, slc) // TODO and here if len(ids) != len(names) || len(names) != len(statuses) { log.WithFields(log.Fields{ "names": len(names), "ids": len(ids), "statuses": len(statuses), }).Warn("Could not fetch complete metadata for every repo.") } // Construct repos for i := range ids { name := safeAccess(names, i) id := safeAccess(ids, i) status := safeAccess(statuses, i) repo := repo{Name: name, ID: id, Status: status} repos = append(repos, repo) } return repos }
// getSwapOrMemory returns output from `free`, it is an abstraction of // getSwap and getMemory. inputs: status: free | used | total // swapOrMem: memory | swap, units: b | kb | mb | gb | tb // TODO: support kib/gib style units, with proper transformations. func getSwapOrMemory(status string, swapOrMem string, units string) int { statusToColumn := map[string]int{ "total": 1, "used": 2, "free": 3, } unitsToFlag := map[string]string{ "b": "--bytes", "kb": "--kilo", "mb": "--mega", "gb": "--giga", "tb": "--tera", } typeToRow := map[string]int{ "memory": 0, "swap": 1, } // check to see that our keys are really in our dict if _, ok := statusToColumn[status]; !ok { log.WithFields(log.Fields{ "status": status, "expected": []string{"total", "used", "free"}, }).Fatal("Internal error: invalid status in getSwapOrMemory") } else if _, ok := unitsToFlag[units]; !ok { log.WithFields(log.Fields{ "units": units, "expected": []string{"b", "kb", "mb", "gb", "tb"}, }).Fatal("Internal error: invalid units in getSwapOrMemory") } else if _, ok := typeToRow[swapOrMem]; !ok { log.WithFields(log.Fields{ "option": swapOrMem, "expected": []string{"memory", "swap"}, }).Fatal("Internal error: invalid option in getSwapOrMemory") } // execute free and return the appropriate output cmd := exec.Command("free", unitsToFlag[units]) outStr := wrkutils.CommandOutput(cmd) table := tabular.ProbabalisticSplit(outStr) column := tabular.GetColumnByHeader(status, table) row := typeToRow[swapOrMem] // check for errors in output of `free` if column == nil { log.WithFields(log.Fields{ "header": status, "table": "\n" + tabular.ToString(table), }).Fatal("Free column was empty") } if row >= len(column) { log.WithFields(log.Fields{ "output": outStr, "column": column, "row": row, }).Fatal("`free` didn't output enough rows") } toReturn, err := strconv.ParseInt(column[row], 10, 64) if err != nil { log.WithFields(log.Fields{ "cell": column[row], "error": err.Error(), "output": outStr, }).Fatal("Couldn't parse output of `free` as an int") } return int(toReturn) }