Beispiel #1
0
// systemctlUnitFileStatus checks whether or not the given unit file has the
// given status: static | enabled | disabled
func systemctlUnitFileStatus(parameters []string) (exitCode int, exitMessage string) {
	// getUnitFilesWithStatuses returns a pair of string slices that hold
	// the name of unit files with their current statuses.
	getUnitFilesWithStatuses := func() (units []string, statuses []string) {
		cmd := exec.Command("systemctl", "--no-pager", "list-unit-files")
		units = wrkutils.CommandColumnNoHeader(0, cmd)
		cmd = exec.Command("systemctl", "--no-pager", "list-unit-files")
		statuses = wrkutils.CommandColumnNoHeader(1, cmd)
		// last two are empty line and junk statistics we don't care about
		msg := fmt.Sprint(cmd.Args) + " didn't output enough lines"
		wrkutils.IndexError(msg, 2, units)
		wrkutils.IndexError(msg, 2, statuses)
		return units[:len(units)-2], statuses[:len(statuses)-2]
	}
	unit := parameters[0]
	status := parameters[1]
	units, statuses := getUnitFilesWithStatuses()
	var actualStatus string
	// TODO check if unit could be found at all
	for i, un := range units {
		if un == unit {
			actualStatus = statuses[i]
			if actualStatus == status {
				return 0, ""
			}
		}
	}
	msg := "Unit didn't have status"
	return wrkutils.GenericError(msg, status, []string{actualStatus})
}
Beispiel #2
0
// 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
}
Beispiel #3
0
// 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)
}
Beispiel #4
0
// temp parses the output of lm_sensors and determines if Core 0 (all cores) are
// over a certain threshold as specified in the JSON.
func temp(parameters []string) (exitCode int, exitMessage string) {
	// TODO: check for negative, outrageously high temperatures
	// allCoreTemps returns the temperature of each core
	allCoreTemps := func() (temps []int) {
		cmd := exec.Command("sensors")
		out, err := cmd.CombinedOutput()
		outstr := string(out)
		wrkutils.ExecError(cmd, outstr, err)
		restr := `Core\s\d+:\s+[\+\-](?P<temp>\d+)\.*\d*°C`
		re := regexp.MustCompile(restr)
		for _, line := range regexp.MustCompile(`\n+`).Split(outstr, -1) {
			if re.MatchString(line) {
				// submatch captures only the integer part of the temperature
				matchDict := wrkutils.SubmatchMap(re, line)
				if _, ok := matchDict["temp"]; !ok {
					log.WithFields(log.Fields{
						"regexp":    re.String(),
						"matchDict": matchDict,
						"output":    outstr,
					}).Fatal("Couldn't find any temperatures in `sensors` output")
				}
				tempInt64, err := strconv.ParseInt(matchDict["temp"], 10, 64)
				if err != nil {
					log.WithFields(log.Fields{
						"regexp":    re.String(),
						"matchDict": matchDict,
						"output":    outstr,
						"error":     err.Error(),
					}).Fatal("Couldn't parse integer from `sensors` output")
				}
				temps = append(temps, int(tempInt64))
			}
		}
		return temps
	}
	// getCoreTemp returns an integer temperature for a certain core
	getCoreTemp := func(core int) (temp int) {
		temps := allCoreTemps()
		wrkutils.IndexError("No such core available", core, temps)
		return temps[core]
	}
	max := wrkutils.ParseMyInt(parameters[0])
	temp := getCoreTemp(0)
	if temp < max {
		return 0, ""
	}
	msg := "Core temp exceeds defined maximum"
	return wrkutils.GenericError(msg, max, []string{fmt.Sprint(temp)})
}
Beispiel #5
0
// getTimers returns of all the timers under the UNIT column of
// `systemctl list-timers`
func getTimers(all bool) []string {
	cmd := exec.Command("systemctl", "list-timers")
	if all {
		cmd = exec.Command("systemctl", "list-timers", "--all")
	}
	out, err := cmd.CombinedOutput()
	outstr := string(out)
	wrkutils.ExecError(cmd, outstr, err)
	// last three lines are junk
	lines := tabular.Lines(outstr)
	msg := fmt.Sprint(cmd.Args) + " didn't output enough lines"
	wrkutils.IndexError(msg, 3, lines)
	table := tabular.SeparateOnAlignment(tabular.Unlines(lines[:len(lines)-3]))
	column := tabular.GetColumnByHeader("UNIT", table)
	return column
}
Beispiel #6
0
// pacmanIgnore checks to see whether a given package is in /etc/pacman.conf's
// IgnorePkg setting
func pacmanIgnore(parameters []string) (exitCode int, exitMessage string) {
	pkg := parameters[0]
	path := "/etc/pacman.conf"
	data := wrkutils.FileToString(path)
	re := regexp.MustCompile(`[^#]IgnorePkg\s+=\s+.+`)
	find := re.FindString(data)
	var packages []string
	if find != "" {
		spl := strings.Split(find, " ")
		wrkutils.IndexError("Not enough lines in "+path, 2, spl)
		packages = spl[2:] // first two are "IgnorePkg" and "="
		if tabular.StrIn(pkg, packages) {
			return 0, ""
		}
	}
	msg := "Couldn't find package in IgnorePkg"
	return wrkutils.GenericError(msg, pkg, packages)
}
Beispiel #7
0
// gatewayInterface checks that the default gateway is using a specified interface
func gatewayInterface(parameters []string) (exitCode int, exitMessage string) {
	// getGatewayInterface returns the interface that the default gateway is
	// operating on
	getGatewayInterface := func() (iface string) {
		ips := routingTableColumn("Gateway")
		names := routingTableColumn("Iface")
		for i, ip := range ips {
			if ip != "0.0.0.0" {
				msg := "Fewer names in kernel routing table than IPs"
				wrkutils.IndexError(msg, i, names)
				return names[i] // interface name
			}
		}
		return ""
	}
	name := parameters[0]
	iface := getGatewayInterface()
	if name == iface {
		return 0, ""
	}
	msg := "Default gateway does not operate on interface"
	return wrkutils.GenericError(msg, name, []string{iface})
}