fw_lab_triage_helper: DUT attribute discovery
Restores most DUT attribute functionality except for that which has
been sufficiently obviated by dashboarding.
TEST=ran utility (with the default of the faft-cr50 pool) and inspected
output
BUG=b:146062376
Change-Id: I8054ad6b60e4a2599d11bd7bbda37667292dde5c
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crostestutils/+/1961992
Tested-by: Kevin Shelton <kmshelton@chromium.org>
Commit-Queue: Kevin Shelton <kmshelton@chromium.org>
Reviewed-by: Greg Edelston <gredelston@google.com>
diff --git a/go/src/firmware/fw_lab_triage_helper.go b/go/src/firmware/fw_lab_triage_helper.go
index d204bdc..e41b825 100644
--- a/go/src/firmware/fw_lab_triage_helper.go
+++ b/go/src/firmware/fw_lab_triage_helper.go
@@ -13,8 +13,6 @@
"log"
"os"
"os/exec"
- "reflect"
- "regexp"
"strconv"
"strings"
"text/tabwriter"
@@ -30,11 +28,11 @@
"pgrep --list-full update_engine; " +
"printf \"\n\";"
-const warningMessage = `This utility assumes many things, like that you have atest in the environment
-in which it is run and that you have cros in your DNS search path. This is just
-a convenience utility for firmware qual test environment health triage. Feel
-free and encouraged to extend and enhance it, but in the long term, it should be
-mostly obviated by monitoring and alerting.
+const warningMessage = `This utility assumes many things, like that you have the skylab utility in the
+environment in which it is run and that you have cros in your DNS search path.
+This is a convenience utility for firmware qual test environment health triage.
+Feel free and encouraged to extend and enhance it: it should generally
+complement monitoring and alerting efforts and any other longer term efforts.
`
// This is the TCP Port number on which an ssh server listens (in the test image).
@@ -50,7 +48,7 @@
}
type dut struct {
- Hostname, Port, Labstation, Board, Model, Status, LockStatus, LockReason string
+ Hostname, Port, Labstation, Board, Model string
}
func sanitizeGobCurlOutput(output *[]byte) {
@@ -83,30 +81,39 @@
func newDut(hostname string) dut {
d := dut{Hostname: hostname}
- regexMap := map[string]string{
- "Port": `servo_port : (?P<Port>.*)`,
- "Labstation": `servo_host : (?P<Labstation>.*)`,
- "Board": `board:(?P<Board>.*)`,
- "Model": `model:(?P<Model>.*)`,
- "Status": `Status: (?P<Status>.*)`,
- "LockStatus": `Locked: (?P<LockStatus>.*)`,
- "LockReason": `Lock Reason: (?P<LockReason>.*)`,
+ cmd := exec.Command("skylab", "dut-info", "-json", hostname)
+ cmdOut, _ := cmd.Output()
+
+ type skylabResponse struct {
+ Common struct {
+ Attributes []struct {
+ Key string `json:"key"`
+ Value string `json:"value"`
+ } `json:"attributes"`
+ Labels struct {
+ Board string `json:"board"`
+ Model string `json:"model"`
+ } `json:"labels"`
+ } `json:"common"`
+ }
+ var s skylabResponse
+ err := json.Unmarshal(cmdOut, &s)
+ if err != nil {
+ log.Fatalf("json.Unmarshal encountered: %s", err)
}
- cmd := exec.Command("atest", "host", "stat", hostname)
- out, _ := cmd.Output()
-
- for field, re := range regexMap {
- match := regexp.MustCompile(re).FindStringSubmatch(string(out))
- // The LockReason field can be empty if the DUT is not locked.
- if len(match) != 2 && field != "LockReason" {
- log.Printf("Skipping %s on %s. This could be ok if a DUT is only partially through the deployment checklist.", field, hostname)
- continue
- } else {
- reflect.ValueOf(&d).Elem().FieldByName(field).SetString(match[1])
+ for _, attribute := range s.Common.Attributes {
+ if attribute.Key == "servo_port" {
+ d.Port = attribute.Value
+ }
+ if attribute.Key == "servo_host" {
+ d.Labstation = attribute.Value
}
}
+ d.Board = s.Common.Labels.Board
+ d.Model = s.Common.Labels.Model
+
return d
}
@@ -172,15 +179,16 @@
fmt.Println(warningMessage)
- log.Print("Gathering DUT info via atest...")
+ log.Print("Gathering DUT info via the skylab utility...")
- cmd := exec.Command("atest", "host", "list", "--hostnames-only", "--label=pool:"+*poolPtr)
+ cmd := exec.Command("skylab", "dut-list", "-pool", *poolPtr)
out, err := cmd.Output()
if err != nil {
- log.Fatalf("<atest host list> encountered: %s", err)
+ log.Fatalf("<skylab dut-list> encountered: %s", err)
}
- // Removing hostnames that don't begin with "chromeos1-" removes those that are not in the firmware lab.
+ // Only operating on hostnames that begin with "chromeos1-" ensures DUTs that are not in the firmware lab
+ // are not operated on.
for _, hostname := range strings.Fields(string(out)) {
if strings.HasPrefix(hostname, "chromeos1-") {
duts = append(duts, newDut(hostname))
@@ -189,10 +197,10 @@
log.Print("Summarizing DUT info...")
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
- fmt.Fprintln(w, "Hostname\tBoard\tModel\tStatus\tLabstation\tPort\tLockStatus\tLockReason")
+ fmt.Fprintln(w, "Hostname\tBoard\tModel\tLabstation\tPort")
for _, dut := range duts {
- fmt.Fprintln(w, dut.Hostname+"\t"+dut.Board+"\t"+dut.Model+"\t"+dut.Status+"\t"+dut.Labstation+"\t"+
- dut.Port+"\t"+dut.LockStatus+"\t"+dut.LockReason+"\t")
+ fmt.Fprintln(w, dut.Hostname+"\t"+dut.Board+"\t"+dut.Model+"\t"+dut.Labstation+"\t"+
+ dut.Port+"\t")
}
w.Flush()