-
Notifications
You must be signed in to change notification settings - Fork 182
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is the first step in actually overhauling the ghw library's context package and moving to a more standard `context.Context` usage. In order to standardize the context usage, we needed to change the way that the ghw-snapshot functionality worked to manually construct a `pkg/context.Context` and call `pkg/context.Context:Do()` while reading the snapshot tarball. In order to do that, I created a new `ghw-snapshot read` command that accepts a single argument to the snapshot tarball path to read: ``` ➜ ghw git:(overhaul-snapshot) ✗ GHW_DISABLE_WARNINGS=1 go run cmd/ghw-snapshot/main.go read testdata/snapshots/linux-amd64-intel-xeon-L5640.tar.gz block storage (8 disks, 723GB physical storage) cpu (2 physical packages, 12 cores, 24 hardware threads) gpu (0 graphics cards) memory (66GB physical, 63GB usable) net (0 NICs) topology NUMA (2 nodes) chassis type=unknown vendor=unknown version=unknown bios vendor=unknown version=unknown baseboard vendor=unknown version=unknown product=unknown product family=unknown name=unknown vendor=unknown sku=unknown version=unknown PCI (82 devices) ➜ ghw git:(overhaul-snapshot) ✗ GHW_DISABLE_WARNINGS=1 go run cmd/ghw-snapshot/main.go read testdata/snapshots/linux-amd64-amd-ryzen-1600.tar.gz block storage (8 disks, 3TB physical storage) cpu (1 physical package, 6 cores, 12 hardware threads) gpu (1 graphics card) memory (32GB physical, 32GB usable) net (4 NICs) topology NUMA (0 nodes) chassis type=unknown vendor=unknown version=unknown bios vendor=unknown version=unknown baseboard vendor=unknown version=unknown product=unknown product family=unknown name=unknown vendor=unknown sku=unknown version=unknown PCI (43 devices) ``` A followup series of patches will make the aforementioned changes to `pkg/context` and remove the `pkg/context.Context:Do()` method and put that entirely in the `cmd/ghw-snapshot/command/read.go` file which is the only place we actually use it. Signed-off-by: Jay Pipes <jaypipes@gmail.com>
- Loading branch information
Showing
4 changed files
with
193 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// | ||
// Use and distribution licensed under the Apache license version 2. | ||
// | ||
// See the COPYING file in the root project directory for full text. | ||
// | ||
|
||
package command | ||
|
||
import ( | ||
"crypto/md5" | ||
"fmt" | ||
"io" | ||
"os" | ||
"runtime" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/jaypipes/ghw/pkg/snapshot" | ||
) | ||
|
||
var ( | ||
// output filepath to save snapshot to | ||
outPath string | ||
) | ||
|
||
var createCmd = &cobra.Command{ | ||
Use: "create", | ||
Short: "Creates a new ghw snapshot", | ||
RunE: doCreate, | ||
} | ||
|
||
// doCreate creates a ghw snapshot | ||
func doCreate(cmd *cobra.Command, args []string) error { | ||
scratchDir, err := os.MkdirTemp("", "ghw-snapshot") | ||
if err != nil { | ||
return err | ||
} | ||
defer os.RemoveAll(scratchDir) | ||
|
||
snapshot.SetTraceFunction(trace) | ||
if err = snapshot.CloneTreeInto(scratchDir); err != nil { | ||
return err | ||
} | ||
|
||
if outPath == "" { | ||
outPath, err = defaultOutPath() | ||
if err != nil { | ||
return err | ||
} | ||
trace("using default output filepath %s\n", outPath) | ||
} | ||
|
||
return snapshot.PackFrom(outPath, scratchDir) | ||
} | ||
|
||
func systemFingerprint() (string, error) { | ||
hn, err := os.Hostname() | ||
if err != nil { | ||
return "unknown", err | ||
} | ||
m := md5.New() | ||
_, err = io.WriteString(m, hn) | ||
if err != nil { | ||
return "unknown", err | ||
} | ||
return fmt.Sprintf("%x", m.Sum(nil)), nil | ||
} | ||
|
||
func defaultOutPath() (string, error) { | ||
fp, err := systemFingerprint() | ||
if err != nil { | ||
return "unknown", err | ||
} | ||
return fmt.Sprintf("%s-%s-%s.tar.gz", runtime.GOOS, runtime.GOARCH, fp), nil | ||
} | ||
|
||
func init() { | ||
createCmd.PersistentFlags().StringVarP( | ||
&outPath, | ||
"out", "o", | ||
outPath, | ||
"Path to place snapshot. Defaults to file in current directory with name $OS-$ARCH-$HASHSYSTEMNAME.tar.gz", | ||
) | ||
rootCmd.AddCommand(createCmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// | ||
// Use and distribution licensed under the Apache license version 2. | ||
// | ||
// See the COPYING file in the root project directory for full text. | ||
// | ||
|
||
package command | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/jaypipes/ghw" | ||
ghwcontext "github.com/jaypipes/ghw/pkg/context" | ||
) | ||
|
||
var readCmd = &cobra.Command{ | ||
Use: "read", | ||
Short: "Reads a new ghw snapshot", | ||
RunE: doRead, | ||
} | ||
|
||
// doRead reads a ghw snapshot from the input snapshot path argument | ||
func doRead(cmd *cobra.Command, args []string) error { | ||
if len(args) != 1 { | ||
return errors.New("supply a single argument with the filepath to the snapshot you wish to read") | ||
} | ||
inPath := args[0] | ||
if _, err := os.Stat(inPath); err != nil { | ||
return err | ||
} | ||
os.Setenv("GHW_SNAPSHOT_PATH", inPath) | ||
ctx := ghwcontext.New() | ||
|
||
return ctx.Do(func() error { | ||
info, err := ghw.Host() | ||
fmt.Println(info.String()) | ||
return err | ||
}) | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(readCmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// | ||
// Use and distribution licensed under the Apache license version 2. | ||
// | ||
// See the COPYING file in the root project directory for full text. | ||
// | ||
|
||
package command | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
debug bool | ||
) | ||
|
||
// rootCmd represents the base command when called without any subcommands | ||
var rootCmd = &cobra.Command{ | ||
Use: "ghw-snapshot", | ||
Short: "ghw-snapshot - create and read ghw snapshots.", | ||
Long: ` | ||
__ __ __ | ||
.-----.| |--.--.--.--.______.-----.-----.---.-.-----.-----.| |--.-----.| |_ | ||
| _ || | | | |______|__ --| | _ | _ |__ --|| | _ || _| | ||
|___ ||__|__|________| |_____|__|__|___._| __|_____||__|__|_____||____| | ||
|_____| |__| | ||
Create and read ghw snapshots. | ||
https://github.com/jaypipes/ghw | ||
`, | ||
RunE: doCreate, | ||
} | ||
|
||
// Execute adds all child commands to the root command and sets flags | ||
// appropriately. This is called by main.main(). It only needs to happen once | ||
// to the rootCmd. | ||
func Execute() { | ||
if err := rootCmd.Execute(); err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
func trace(msg string, args ...interface{}) { | ||
if !debug { | ||
return | ||
} | ||
fmt.Printf(msg, args...) | ||
} | ||
|
||
func init() { | ||
rootCmd.PersistentFlags().BoolVar( | ||
&debug, "debug", false, "Enable or disable debug mode", | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,105 +1,16 @@ | ||
//go:build linux | ||
// +build linux | ||
|
||
// | ||
// Use and distribution licensed under the Apache license version 2. | ||
// | ||
// See the COPYING file in the root project directory for full text. | ||
// | ||
|
||
package main | ||
|
||
import ( | ||
"crypto/md5" | ||
"fmt" | ||
"io" | ||
"os" | ||
"runtime" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/jaypipes/ghw/pkg/snapshot" | ||
) | ||
|
||
var ( | ||
// show debug output | ||
debug = false | ||
// output filepath to save snapshot to | ||
outPath string | ||
"github.com/jaypipes/ghw/cmd/ghw-snapshot/command" | ||
) | ||
|
||
// rootCmd represents the base command when called without any subcommands | ||
var rootCmd = &cobra.Command{ | ||
Use: "ghw-snapshot", | ||
Short: "ghw-snapshot - Snapshot filesystem containing system information.", | ||
RunE: execute, | ||
} | ||
|
||
func trace(msg string, args ...interface{}) { | ||
if !debug { | ||
return | ||
} | ||
fmt.Printf(msg, args...) | ||
} | ||
|
||
func systemFingerprint() (string, error) { | ||
hn, err := os.Hostname() | ||
if err != nil { | ||
return "unknown", err | ||
} | ||
m := md5.New() | ||
_, err = io.WriteString(m, hn) | ||
if err != nil { | ||
return "unknown", err | ||
} | ||
return fmt.Sprintf("%x", m.Sum(nil)), nil | ||
} | ||
|
||
func defaultOutPath() (string, error) { | ||
fp, err := systemFingerprint() | ||
if err != nil { | ||
return "unknown", err | ||
} | ||
return fmt.Sprintf("%s-%s-%s.tar.gz", runtime.GOOS, runtime.GOARCH, fp), nil | ||
} | ||
|
||
func execute(cmd *cobra.Command, args []string) error { | ||
scratchDir, err := os.MkdirTemp("", "ghw-snapshot") | ||
if err != nil { | ||
return err | ||
} | ||
defer os.RemoveAll(scratchDir) | ||
|
||
snapshot.SetTraceFunction(trace) | ||
if err = snapshot.CloneTreeInto(scratchDir); err != nil { | ||
return err | ||
} | ||
|
||
if outPath == "" { | ||
outPath, err = defaultOutPath() | ||
if err != nil { | ||
return err | ||
} | ||
trace("using default output filepath %s\n", outPath) | ||
} | ||
|
||
return snapshot.PackFrom(outPath, scratchDir) | ||
} | ||
|
||
func main() { | ||
if err := rootCmd.Execute(); err != nil { | ||
trace("execution failed: %v\n", err) | ||
} | ||
} | ||
|
||
func init() { | ||
rootCmd.PersistentFlags().StringVarP( | ||
&outPath, | ||
"out", "o", | ||
outPath, | ||
"Path to place snapshot. Defaults to file in current directory with name $OS-$ARCH-$HASHSYSTEMNAME.tar.gz", | ||
) | ||
rootCmd.PersistentFlags().BoolVarP( | ||
&debug, "debug", "d", false, "Enable or disable debug mode", | ||
) | ||
command.Execute() | ||
} |