On coral devices futility leaves the EC in RO
Add a reboot into the futility.py script in case we lose the ethernet
and don't get it back by the time futility finishes.
BUG=b:331205004
TEST=On leased duts
Change-Id: Ie075e5e209a5288aa1bc959c3f9ddd3113afa57c
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/5545058
Commit-Queue: Kshitij Shah <tij@google.com>
Auto-Submit: Jeremy Bettis <jbettis@chromium.org>
Commit-Queue: Jeremy Bettis <jbettis@chromium.org>
Reviewed-by: Kshitij Shah <tij@google.com>
Tested-by: Jeremy Bettis <jbettis@chromium.org>
diff --git a/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/README.md b/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/README.md
index b2227a3..63270d8 100644
--- a/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/README.md
+++ b/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/README.md
@@ -25,7 +25,7 @@
```
BOARD=myBoard
MODEL=myModel
-D=192.168.0.0
+DUT_HOSTNAME=192.168.0.0
```
Outside chroot
@@ -52,9 +52,14 @@
Then run the local-cft binary to run the cros-dut server.
```
-./chroot/usr/bin/local-cft -board ${BOARD?} -host ${D?} -stayalive -port cros-dut=8123
+./chroot/usr/bin/local-cft -board ${BOARD?} -host ${DUT_HOSTNAME?} -stayalive -port cros-dut=8123
# If you made changes in another service like cros-dut run
-# ./chroot/usr/bin/local-cft -board ${BOARD?} -host ${D?} -stayalive -port cros-dut=8123 --chroot ~/chromiumos/chroot --localservices cros-dut
+# ./chroot/usr/bin/local-cft -board ${BOARD?} -host ${DUT_HOSTNAME?} -stayalive -port cros-dut=8123 --chroot ~/chromiumos/chroot --localservices cros-dut
+```
+
+To find the cache server on a lab machine:
+```
+ssh $DUT_HOSTNAME 'for devserver in 192.168.100.1 100.115.168.190 10.128.176.210 100.115.21.212 100.115.245.199 100.115.245.200 100.115.219.131 100.115.219.132 100.115.219.133 100.115.219.134 100.115.219.137; do if curl -f --connect-timeout 3 "http://${devserver?}:8082/check_health" >/dev/null ; then echo CACHE_SERVER=${devserver?} ; fi; done'
```
Inside chroot
diff --git a/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/cros_fw_provision_test.go b/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/cros_fw_provision_test.go
index d76981f..be21849 100644
--- a/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/cros_fw_provision_test.go
+++ b/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/cros_fw_provision_test.go
@@ -440,7 +440,7 @@
"with open(\"/var/tmp/someTempDir/futility.log\", \"wb\", buffering=0) as outFile:\n"+
" rc = subprocess.run([\"futility\", %s], stdout=outFile, stderr=outFile, check=False, bufsize=0)\n"+
" outFile.write(f\"EXIT CODE: {rc.returncode}\\n\".encode(\"utf-8\"))\n outFile.flush()\n"+
- "subprocess.run([\"sync\", \"-d\", \"/var/tmp\", \"/usr/local/tmp\"])\n", expectedFutilityPyArgs)),
+ " subprocess.run([\"sync\", \"-d\", \"/var/tmp\", \"/usr/local/tmp\"])\n subprocess.run([\"reboot\"])\n", expectedFutilityPyArgs)),
}}).Return(newResponse(&api.ExecCommandResponse{ExitInfo: &api.ExecCommandResponse_ExitInfo{}}), nil),
dsc.EXPECT().ExecCommand(gomock.Any(), &rpcMsg{msg: &api.ExecCommandRequest{
Command: "bash",
@@ -533,14 +533,18 @@
Command: "rm",
Args: []string{"-rf", "/var/tmp/someTempDir"},
}}).Return(newResponse(&api.ExecCommandResponse{ExitInfo: &api.ExecCommandResponse_ExitInfo{}}), nil),
- dsc.EXPECT().Restart(gomock.Any(), gomock.Any()).Return(&longrunning.Operation{Done: true}, nil),
- dsc.EXPECT().ExecCommand(gomock.Any(), &rpcMsg{msg: &api.ExecCommandRequest{
- Command: "true",
- }}).Return(nil, fmt.Errorf("ssh timeout")),
- dsc.EXPECT().ExecCommand(gomock.Any(), &rpcMsg{msg: &api.ExecCommandRequest{
- Command: "true",
- }}).Return(newResponse(&api.ExecCommandResponse{ExitInfo: &api.ExecCommandResponse_ExitInfo{}}), nil),
)
+ if !testCase.ec_ro || testCase.updateRw {
+ gomock.InOrder(
+ dsc.EXPECT().Restart(gomock.Any(), gomock.Any()).Return(&longrunning.Operation{Done: true}, nil),
+ dsc.EXPECT().ExecCommand(gomock.Any(), &rpcMsg{msg: &api.ExecCommandRequest{
+ Command: "true",
+ }}).Return(nil, fmt.Errorf("ssh timeout")),
+ dsc.EXPECT().ExecCommand(gomock.Any(), &rpcMsg{msg: &api.ExecCommandRequest{
+ Command: "true",
+ }}).Return(newResponse(&api.ExecCommandResponse{ExitInfo: &api.ExecCommandResponse_ExitInfo{}}), nil),
+ )
+ }
if testCase.updateRo && testCase.updateRw {
gomock.InOrder(
dsc.EXPECT().ExecCommand(gomock.Any(), &rpcMsg{msg: &api.ExecCommandRequest{
diff --git a/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/service/firmwareservice.go b/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/service/firmwareservice.go
index 0473b22..4c29c09 100644
--- a/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/service/firmwareservice.go
+++ b/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/service/firmwareservice.go
@@ -80,6 +80,9 @@
CacheServer url.URL
ExpectedVersions FirmwareVersions
+
+ // RestartRequired indicates that a firmware update was performed, but the DUT has not yet rebooted.
+ RestartRequired bool
}
type versionJSON struct {
@@ -561,6 +564,7 @@
// TODO(sfrolov): extra args from fw-config.json
}
+ fws.RestartRequired = true
connection := fws.GetConnectionToFlashingDevice()
if ecImagePath != "" {
// If we are flashing EC, we might lose SSH access, so use nohup to run futility in a temporary python script, and poll for results
@@ -583,7 +587,8 @@
scriptBody.WriteString(`], stdout=outFile, stderr=outFile, check=False, bufsize=0)
outFile.write(f"EXIT CODE: {rc.returncode}\n".encode("utf-8"))
outFile.flush()
-subprocess.run(["sync", "-d", "/var/tmp", "/usr/local/tmp"])
+ subprocess.run(["sync", "-d", "/var/tmp", "/usr/local/tmp"])
+ subprocess.run(["reboot"])
`)
_, _, err := RunDUTCommand(ctx, fws.DUTServer, time.Minute, "cat", []string{">", pyScript}, []byte(scriptBody.String()))
if err != nil {
@@ -610,6 +615,7 @@
if m != nil {
log.Printf("Futility output:\n%s", buf)
if m[1] == "0" {
+ fws.RestartRequired = false
return nil
}
return errors.Errorf("futility failed: %q", buf)
diff --git a/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/state-machine/postinstallstate.go b/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/state-machine/postinstallstate.go
index 0b0be39..87d2dec 100644
--- a/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/state-machine/postinstallstate.go
+++ b/src/go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/state-machine/postinstallstate.go
@@ -8,9 +8,10 @@
import (
"context"
- firmwareservice "go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/service"
"log"
+ firmwareservice "go.chromium.org/chromiumos/test/provision/v2/cros-fw-provision/service"
+
"github.com/pkg/errors"
"go.chromium.org/chromiumos/config/go/test/api"
)
@@ -24,9 +25,11 @@
func (s FirmwarePostInstallState) Execute(ctx context.Context, log *log.Logger) (*api.FirmwareProvisionResponse, api.InstallResponse_Status, error) {
fwMetadata := s.service.GetVersions()
s.service.DeleteArchiveDirectories()
- err := s.service.RestartDut(ctx, false)
- if err != nil {
- return fwMetadata, api.InstallResponse_STATUS_DUT_UNREACHABLE_POST_FIRMWARE_UPDATE, firmwareservice.UnreachablePostProvisionErr(err)
+ if s.service.RestartRequired {
+ err := s.service.RestartDut(ctx, false)
+ if err != nil {
+ return fwMetadata, api.InstallResponse_STATUS_DUT_UNREACHABLE_POST_FIRMWARE_UPDATE, firmwareservice.UnreachablePostProvisionErr(err)
+ }
}
versions, err := s.service.ActiveFirmwareVersions(ctx)