Skip to content

Commit

Permalink
Merge pull request #216 from fromanirh/warning-machinery
Browse files Browse the repository at this point in the history
warning: support new option to override default
  • Loading branch information
jaypipes authored Feb 2, 2021
2 parents 981ba60 + 6527efc commit 38a8f62
Show file tree
Hide file tree
Showing 26 changed files with 163 additions and 73 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,26 @@ $ GHW_DISABLE_WARNINGS=1 ghwc memory
memory (24GB physical, 24GB usable)
```

You can disable warning programmatically using the `WithDisableWarnings` option:

```go

import (
"github.com/jaypipes/ghw"
)

mem, err := ghw.Memory(ghw.WithDisableWarnings())
```

`WithDisableWarnings` is a alias for the `WithNullAlerter` option, which in turn
leverages the more general `Alerter` feature of ghw.

You may supply a `Alerter` to ghw to redirect all the warnings there, like
logger objects (see for example golang's stdlib `log.Logger`).
`Alerter` is in fact the minimal logging interface `ghw needs.
To learn more, please check the `option.Alerter` interface and the `ghw.WithAlerter()`
function.

### Memory

Information about the host computer's memory can be retrieved using the
Expand Down
8 changes: 6 additions & 2 deletions alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ import (
type WithOption = option.Option

var (
WithChroot = option.WithChroot
WithSnapshot = option.WithSnapshot
WithChroot = option.WithChroot
WithSnapshot = option.WithSnapshot
WithAlterter = option.WithAlerter
WithNullAlterter = option.WithNullAlerter
// match the existing environ variable to minimize surprises
WithDisableWarnings = option.WithNullAlerter
)

type SnapshotOptions = option.SnapshotOptions
Expand Down
10 changes: 8 additions & 2 deletions host.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ package ghw
import (
"fmt"

"github.com/jaypipes/ghw/pkg/context"

"github.com/jaypipes/ghw/pkg/baseboard"
"github.com/jaypipes/ghw/pkg/bios"
"github.com/jaypipes/ghw/pkg/block"
Expand All @@ -26,6 +28,7 @@ import (
// HostInfo is a wrapper struct containing information about the host system's
// memory, block storage, CPU, etc
type HostInfo struct {
ctx *context.Context
Memory *memory.Info `json:"memory"`
Block *block.Info `json:"block"`
CPU *cpu.Info `json:"cpu"`
Expand All @@ -42,6 +45,8 @@ type HostInfo struct {
// Host returns a pointer to a HostInfo struct that contains fields with
// information about the host system's CPU, memory, network devices, etc
func Host(opts ...*WithOption) (*HostInfo, error) {
ctx := context.New(opts...)

memInfo, err := memory.New(opts...)
if err != nil {
return nil, err
Expand Down Expand Up @@ -87,6 +92,7 @@ func Host(opts ...*WithOption) (*HostInfo, error) {
return nil, err
}
return &HostInfo{
ctx: ctx,
CPU: cpuInfo,
Memory: memInfo,
Block: blockInfo,
Expand Down Expand Up @@ -123,11 +129,11 @@ func (info *HostInfo) String() string {
// YAMLString returns a string with the host information formatted as YAML
// under a top-level "host:" key
func (i *HostInfo) YAMLString() string {
return marshal.SafeYAML(i)
return marshal.SafeYAML(i.ctx, i)
}

// JSONString returns a string with the host information formatted as JSON
// under a top-level "host:" key
func (i *HostInfo) JSONString(indent bool) string {
return marshal.SafeJSON(i, indent)
return marshal.SafeJSON(i.ctx, i, indent)
}
4 changes: 2 additions & 2 deletions pkg/baseboard/baseboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ type baseboardPrinter struct {
// YAMLString returns a string with the baseboard information formatted as YAML
// under a top-level "dmi:" key
func (info *Info) YAMLString() string {
return marshal.SafeYAML(baseboardPrinter{info})
return marshal.SafeYAML(info.ctx, baseboardPrinter{info})
}

// JSONString returns a string with the baseboard information formatted as JSON
// under a top-level "baseboard:" key
func (info *Info) JSONString(indent bool) string {
return marshal.SafeJSON(baseboardPrinter{info}, indent)
return marshal.SafeJSON(info.ctx, baseboardPrinter{info}, indent)
}
4 changes: 2 additions & 2 deletions pkg/bios/bios.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ type biosPrinter struct {
// YAMLString returns a string with the BIOS information formatted as YAML
// under a top-level "dmi:" key
func (info *Info) YAMLString() string {
return marshal.SafeYAML(biosPrinter{info})
return marshal.SafeYAML(info.ctx, biosPrinter{info})
}

// JSONString returns a string with the BIOS information formatted as JSON
// under a top-level "bios:" key
func (info *Info) JSONString(indent bool) string {
return marshal.SafeJSON(biosPrinter{info}, indent)
return marshal.SafeJSON(info.ctx, biosPrinter{info}, indent)
}
4 changes: 2 additions & 2 deletions pkg/block/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,11 @@ type blockPrinter struct {
// YAMLString returns a string with the block information formatted as YAML
// under a top-level "block:" key
func (i *Info) YAMLString() string {
return marshal.SafeYAML(blockPrinter{i})
return marshal.SafeYAML(i.ctx, blockPrinter{i})
}

// JSONString returns a string with the block information formatted as JSON
// under a top-level "block:" key
func (i *Info) JSONString(indent bool) string {
return marshal.SafeJSON(blockPrinter{i}, indent)
return marshal.SafeJSON(i.ctx, blockPrinter{i}, indent)
}
25 changes: 13 additions & 12 deletions pkg/block/block_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"strconv"
"strings"

"github.com/jaypipes/ghw/pkg/context"
"github.com/jaypipes/ghw/pkg/linuxpath"
"github.com/jaypipes/ghw/pkg/util"
)
Expand All @@ -25,7 +26,7 @@ const (

func (i *Info) load() error {
paths := linuxpath.New(i.ctx)
i.Disks = disks(paths)
i.Disks = disks(i.ctx, paths)
var tpb uint64
for _, d := range i.Disks {
tpb += d.SizeBytes
Expand Down Expand Up @@ -179,12 +180,12 @@ func diskWWN(paths *linuxpath.Paths, disk string) string {
// but just the name. In other words, "sda", not "/dev/sda" and "nvme0n1" not
// "/dev/nvme0n1") and returns a slice of pointers to Partition structs
// representing the partitions in that disk
func diskPartitions(paths *linuxpath.Paths, disk string) []*Partition {
func diskPartitions(ctx *context.Context, paths *linuxpath.Paths, disk string) []*Partition {
out := make([]*Partition, 0)
path := filepath.Join(paths.SysBlock, disk)
files, err := ioutil.ReadDir(path)
if err != nil {
util.Warn("failed to read disk partitions: %s\n", err)
ctx.Warn("failed to read disk partitions: %s\n", err)
return out
}
for _, file := range files {
Expand All @@ -194,7 +195,7 @@ func diskPartitions(paths *linuxpath.Paths, disk string) []*Partition {
}
size := partitionSizeBytes(paths, disk, fname)
mp, pt, ro := partitionInfo(paths, fname)
du := diskPartUUID(fname)
du := diskPartUUID(ctx, fname)
p := &Partition{
Name: fname,
SizeBytes: size,
Expand All @@ -208,7 +209,7 @@ func diskPartitions(paths *linuxpath.Paths, disk string) []*Partition {
return out
}

func diskPartUUID(part string) string {
func diskPartUUID(ctx *context.Context, part string) string {
if !strings.HasPrefix(part, "/dev") {
part = "/dev/" + part
}
Expand All @@ -220,7 +221,7 @@ func diskPartUUID(part string) string {
}
out, err := exec.Command(args[0], args[1:]...).Output()
if err != nil {
util.Warn("failed to read disk partuuid of %s : %s\n", part, err.Error())
ctx.Warn("failed to read disk partuuid of %s : %s\n", part, err.Error())
return ""
}

Expand All @@ -230,7 +231,7 @@ func diskPartUUID(part string) string {

parts := strings.Split(string(out), "PARTUUID=")
if len(parts) != 2 {
util.Warn("failed to parse the partuuid of %s\n", part)
ctx.Warn("failed to parse the partuuid of %s\n", part)
return ""
}

Expand All @@ -250,7 +251,7 @@ func diskIsRemovable(paths *linuxpath.Paths, disk string) bool {
return false
}

func disks(paths *linuxpath.Paths) []*Disk {
func disks(ctx *context.Context, paths *linuxpath.Paths) []*Disk {
// In Linux, we could use the fdisk, lshw or blockdev commands to list disk
// information, however all of these utilities require root privileges to
// run. We can get all of this information by examining the /sys/block
Expand All @@ -269,7 +270,7 @@ func disks(paths *linuxpath.Paths) []*Disk {
driveType, storageController := diskTypes(dname)
// TODO(jaypipes): Move this into diskTypes() once abstracting
// diskIsRotational for ease of unit testing
if !diskIsRotational(paths, dname) {
if !diskIsRotational(ctx, paths, dname) {
driveType = DRIVE_TYPE_SSD
}
size := diskSizeBytes(paths, dname)
Expand Down Expand Up @@ -297,7 +298,7 @@ func disks(paths *linuxpath.Paths) []*Disk {
WWN: wwn,
}

parts := diskPartitions(paths, dname)
parts := diskPartitions(ctx, paths, dname)
// Map this Disk object into the Partition...
for _, part := range parts {
part.Disk = d
Expand Down Expand Up @@ -348,9 +349,9 @@ func diskTypes(dname string) (
return driveType, storageController
}

func diskIsRotational(paths *linuxpath.Paths, devName string) bool {
func diskIsRotational(ctx *context.Context, paths *linuxpath.Paths, devName string) bool {
path := filepath.Join(paths.SysBlock, devName, "queue", "rotational")
contents := util.SafeIntFromFile(path)
contents := util.SafeIntFromFile(ctx, path)
return contents == 1
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/chassis/chassis.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,11 @@ type chassisPrinter struct {
// YAMLString returns a string with the chassis information formatted as YAML
// under a top-level "dmi:" key
func (info *Info) YAMLString() string {
return marshal.SafeYAML(chassisPrinter{info})
return marshal.SafeYAML(info.ctx, chassisPrinter{info})
}

// JSONString returns a string with the chassis information formatted as JSON
// under a top-level "chassis:" key
func (info *Info) JSONString(indent bool) string {
return marshal.SafeJSON(chassisPrinter{info}, indent)
return marshal.SafeJSON(info.ctx, chassisPrinter{info}, indent)
}
11 changes: 11 additions & 0 deletions pkg/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ type Context struct {
SnapshotPath string
SnapshotRoot string
SnapshotExclusive bool
alert option.Alerter
}

// New returns a Context struct pointer that has had various options set on it
func New(opts ...*option.Option) *Context {
merged := option.Merge(opts...)
ctx := &Context{
alert: option.EnvOrDefaultAlerter(),
Chroot: *merged.Chroot,
}

Expand All @@ -35,6 +37,11 @@ func New(opts ...*option.Option) *Context {
}
ctx.SnapshotExclusive = merged.Snapshot.Exclusive
}

if merged.Alerter != nil {
ctx.alert = merged.Alerter
}

return ctx
}

Expand Down Expand Up @@ -104,3 +111,7 @@ func (ctx *Context) Teardown() error {
}
return snapshot.Cleanup(ctx.SnapshotRoot)
}

func (ctx *Context) Warn(msg string, args ...interface{}) {
ctx.alert.Printf("WARNING: "+msg, args...)
}
4 changes: 2 additions & 2 deletions pkg/cpu/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,11 @@ type cpuPrinter struct {
// YAMLString returns a string with the cpu information formatted as YAML
// under a top-level "cpu:" key
func (i *Info) YAMLString() string {
return marshal.SafeYAML(cpuPrinter{i})
return marshal.SafeYAML(i.ctx, cpuPrinter{i})
}

// JSONString returns a string with the cpu information formatted as JSON
// under a top-level "cpu:" key
func (i *Info) JSONString(indent bool) string {
return marshal.SafeJSON(cpuPrinter{i}, indent)
return marshal.SafeJSON(i.ctx, cpuPrinter{i}, indent)
}
2 changes: 1 addition & 1 deletion pkg/cpu/cpu_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ func CoresForNode(ctx *context.Context, nodeID int) ([]*ProcessorCore, error) {
continue
}
coreIDPath := filepath.Join(cpuPath, "topology", "core_id")
coreID := util.SafeIntFromFile(coreIDPath)
coreID := util.SafeIntFromFile(ctx, coreIDPath)
core := findCoreByID(coreID)
core.LogicalProcessors = append(
core.LogicalProcessors,
Expand Down
4 changes: 2 additions & 2 deletions pkg/gpu/gpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ type gpuPrinter struct {
// YAMLString returns a string with the gpu information formatted as YAML
// under a top-level "gpu:" key
func (i *Info) YAMLString() string {
return marshal.SafeYAML(gpuPrinter{i})
return marshal.SafeYAML(i.ctx, gpuPrinter{i})
}

// JSONString returns a string with the gpu information formatted as JSON
// under a top-level "gpu:" key
func (i *Info) JSONString(indent bool) string {
return marshal.SafeJSON(gpuPrinter{i}, indent)
return marshal.SafeJSON(i.ctx, gpuPrinter{i}, indent)
}
4 changes: 2 additions & 2 deletions pkg/gpu/gpu_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (i *Info) load() error {
paths := linuxpath.New(i.ctx)
links, err := ioutil.ReadDir(paths.SysClassDRM)
if err != nil {
util.Warn(_WARN_NO_SYS_CLASS_DRM)
i.ctx.Warn(_WARN_NO_SYS_CLASS_DRM)
return nil
}
cards := make([]*GraphicsCard, 0)
Expand Down Expand Up @@ -139,7 +139,7 @@ func gpuFillNUMANodes(ctx *context.Context, cards []*GraphicsCard) {
"device",
"numa_node",
)
nodeIdx := util.SafeIntFromFile(fpath)
nodeIdx := util.SafeIntFromFile(ctx, fpath)
if nodeIdx == -1 {
continue
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/linuxdmi/dmi_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func Item(ctx *context.Context, value string) string {

b, err := ioutil.ReadFile(path)
if err != nil {
util.Warn("Unable to read %s: %s\n", value, err)
ctx.Warn("Unable to read %s: %s\n", value, err)
return util.UNKNOWN
}

Expand Down
12 changes: 6 additions & 6 deletions pkg/marshal/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ import (
"encoding/json"

"github.com/ghodss/yaml"
"github.com/jaypipes/ghw/pkg/util"
"github.com/jaypipes/ghw/pkg/context"
)

// safeYAML returns a string after marshalling the supplied parameter into YAML
func SafeYAML(p interface{}) string {
func SafeYAML(ctx *context.Context, p interface{}) string {
b, err := json.Marshal(p)
if err != nil {
util.Warn("error marshalling JSON: %s", err)
ctx.Warn("error marshalling JSON: %s", err)
return ""
}
yb, err := yaml.JSONToYAML(b)
if err != nil {
util.Warn("error converting JSON to YAML: %s", err)
ctx.Warn("error converting JSON to YAML: %s", err)
return ""
}
return string(yb)
Expand All @@ -31,7 +31,7 @@ func SafeYAML(p interface{}) string {
// safeJSON returns a string after marshalling the supplied parameter into
// JSON. Accepts an optional argument to trigger pretty/indented formatting of
// the JSON string
func SafeJSON(p interface{}, indent bool) string {
func SafeJSON(ctx *context.Context, p interface{}, indent bool) string {
var b []byte
var err error
if !indent {
Expand All @@ -40,7 +40,7 @@ func SafeJSON(p interface{}, indent bool) string {
b, err = json.MarshalIndent(&p, "", " ")
}
if err != nil {
util.Warn("error marshalling JSON: %s", err)
ctx.Warn("error marshalling JSON: %s", err)
return ""
}
return string(b)
Expand Down
Loading

0 comments on commit 38a8f62

Please sign in to comment.