Updating to current ToT
BUG=None
TEST=unit
Change-Id: I700c1f49396f83949e9ec71bb2fad009fc4d20fa
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/3158672
Reviewed-by: Otabek Kasimov <otabek@google.com>
Auto-Submit: Jaques Clapauch <jaquesc@google.com>
Tested-by: Jaques Clapauch <jaquesc@google.com>
Commit-Queue: Jaques Clapauch <jaquesc@google.com>
diff --git a/src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/crosservice/crosservice.go b/src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/crosservice/crosservice.go
index 3337a7e..7d56ef7 100644
--- a/src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/crosservice/crosservice.go
+++ b/src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/crosservice/crosservice.go
@@ -56,6 +56,25 @@
}
/*
+ Constant Variables
+*/
+
+const curlWithRetries = "curl -S -s -v -# -C - --retry 3 --retry-delay 60"
+
+const pipeStatusHandler = `
+pipestatus=("${PIPESTATUS[@]}")
+if [[ "${pipestatus[0]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Fetching %[1]s failed." >&2
+ exit 1
+elif [[ "${pipestatus[1]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Decompressing %[1]s failed." >&2
+ exit 1
+elif [[ "${pipestatus[2]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Writing to %[2]s failed." >&2
+ exit 1
+fi`
+
+/*
The following run specific commands related to CrOS installation.
*/
@@ -172,7 +191,7 @@
return fmt.Errorf("failed to get GS Cache URL, %s", err)
}
fmt.Printf("URL used to install zipped image: %s\n", url)
- _, err = c.connection.RunCmd(ctx, "curl", []string{url, "|", "gzip -d", "|", fmt.Sprintf("dd of=%s obs=2M", outputFile)})
+ _, err = c.connection.RunCmd(ctx, curlWithRetries, []string{url, "|", "gzip -d", "|", fmt.Sprintf("dd of=%s obs=2M", outputFile), fmt.Sprintf(pipeStatusHandler, url, outputFile)})
return err
}
@@ -252,7 +271,7 @@
_, err = c.connection.RunCmd(ctx, "", []string{
fmt.Sprintf("rm -rf %[1]s %[2]s/var_new %[2]s/dev_image_new", info.UpdateStatefulFilePath, info.StatefulPath),
"&&",
- fmt.Sprintf("curl %s | tar --ignore-command-error --overwrite --directory=%s -xzf -", url, info.StatefulPath),
+ fmt.Sprintf(curlWithRetries+" %s | tar --ignore-command-error --overwrite --directory=%s -xzf -", url, info.StatefulPath),
"&&",
fmt.Sprintf("echo -n clobber > %s", info.UpdateStatefulFilePath),
})
@@ -302,7 +321,7 @@
if _, err := c.connection.RunCmd(ctx, "", []string{
"mkdir", "-p", dlcOutputSlotDir,
"&&",
- "curl", "--output", dlcOutputImage, url,
+ curlWithRetries, "--output", dlcOutputImage, url,
}); err != nil {
return fmt.Errorf("failed to provision DLC %s, %s", dlcID, err)
}
diff --git a/src/chromiumos/test/provision/cmd/provisionserver/main.go b/src/chromiumos/test/provision/cmd/provisionserver/main.go
index 54d58d4..6d8cb47 100644
--- a/src/chromiumos/test/provision/cmd/provisionserver/main.go
+++ b/src/chromiumos/test/provision/cmd/provisionserver/main.go
@@ -22,9 +22,9 @@
var Version = "<unknown>"
// createLogFile creates a file and its parent directory for logging purpose.
-func createLogFile() (*os.File, error) {
+func createLogFile(logPath string) (*os.File, error) {
t := time.Now()
- fullPath := filepath.Join("/tmp/provisionservice/", t.Format("20060102-150405"))
+ fullPath := filepath.Join(logPath, t.Format("20060102-150405"))
if err := os.MkdirAll(fullPath, 0755); err != nil {
return nil, fmt.Errorf("failed to create directory %v: %v", fullPath, err)
}
@@ -56,6 +56,9 @@
// Input and output json pb files.
inputPath string
outputPath string
+
+ // log
+ logPath string
}
func (a *args) addCommonFlags(fs *flag.FlagSet) {
@@ -63,6 +66,8 @@
fs.StringVar(&a.dutServiceAddr, "dut-service-address", "", "grcp address for dut-service.")
fs.StringVar(&a.wiringServiceAddr, "wiring-service-address", "", "wiring address TLW.")
+
+ fs.StringVar(&a.logPath, "log-path", "/tmp/provisionservice/", "The path to the log file.")
}
func (a *args) verifyCommon() error {
@@ -109,58 +114,70 @@
return nil
}
+func (a *args) setupLogging() (*log.Logger, error) {
+ logFile, err := createLogFile(a.logPath)
+ if err != nil {
+ return nil, err
+ }
+ logger := newLogger(logFile)
+ logger.Println("Starting provisionservice version ", Version)
+
+ return logger, nil
+}
+
func mainInternal(ctx context.Context) int {
if len(os.Args) < 2 {
log.Fatalln("please provide arguments")
return 2
}
- logFile, err := createLogFile()
- if err != nil {
- log.Fatalln("Failed to create log file: ", err)
- return 1
- }
- defer logFile.Close()
- logger := newLogger(logFile)
- logger.Println("Starting provisionservice version ", Version)
-
a := &args{}
switch os.Args[1] {
case "cli":
if err := a.verifyCLIInput(os.Args[2:]); err != nil {
- logger.Fatalln("Failed verify input: ", err)
+ fmt.Printf("failed verify input: %s", err)
+ return 2
+ }
+ logger, err := a.setupLogging()
+ if err != nil {
+ fmt.Printf("could not set up logging, %s", err)
return 2
}
p, closer, err := newProvision(logger, a.dutName, a.dutServiceAddr, a.wiringServiceAddr)
defer closer()
if err != nil {
- logger.Fatalln("Failed to create provision: ", err)
+ fmt.Printf("failed to create provision, %s", err)
return 2
}
if err := p.runCLI(ctx, a.inputPath, a.outputPath); err != nil {
- logger.Fatalln("Failed to perform provision: ", err)
+ fmt.Printf("failed to perform provision, %s", err)
return 1
}
case "server":
if err := a.verifyServerInput(os.Args[2:]); err != nil {
- logger.Fatalln("Failed verify input: ", err)
+ fmt.Printf("failed verify input, %s", err)
+ return 2
+ }
+ logger, err := a.setupLogging()
+ if err != nil {
+ fmt.Printf("could not set up logging, %s", err)
return 2
}
p, closer, err := newProvision(logger, a.dutName, a.dutServiceAddr, a.wiringServiceAddr)
defer closer()
if err != nil {
- logger.Fatalln("Failed to create provision: ", err)
+ fmt.Printf("failed to create provision, %s", err)
return 2
}
if err := p.startServer(a.serverPort); err != nil {
- logger.Fatalln("Failed to perform provision: ", err)
+ fmt.Printf("failed to perform provision, %s", err)
return 1
}
case "version":
- logger.Printf("Provisionservice version: %s", Version)
+ fmt.Printf("Provisionservice version: %s", Version)
return 0
default:
- logger.Fatalln("Expected 'cli' or 'server' as subcommands.")
+ fmt.Printf("expected 'cli' or 'server' as subcommands.")
return 2
}
return 0
diff --git a/src/chromiumos/test/provision/cmd/provisionserver/provisionserver_test.go b/src/chromiumos/test/provision/cmd/provisionserver/provisionserver_test.go
index aa23a29..f4312e0 100644
--- a/src/chromiumos/test/provision/cmd/provisionserver/provisionserver_test.go
+++ b/src/chromiumos/test/provision/cmd/provisionserver/provisionserver_test.go
@@ -56,8 +56,32 @@
)
// Concurrent portion
sam.EXPECT().CopyData(gomock.Any(), gomock.Any()).Return("1", nil).AnyTimes()
- sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("curl"), gomock.Eq([]string{"1", "|", "gzip -d", "|", "dd of=root_diskroot5 obs=2M"})).Times(1).Return("", nil)
- sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("curl"), gomock.Eq([]string{"1", "|", "gzip -d", "|", "dd of=root_diskroot4 obs=2M"})).Times(1).Return("", nil)
+ sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("curl -S -s -v -# -C - --retry 3 --retry-delay 60"), gomock.Eq([]string{"1", "|", "gzip -d", "|", "dd of=root_diskroot5 obs=2M",
+ `
+pipestatus=("${PIPESTATUS[@]}")
+if [[ "${pipestatus[0]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Fetching 1 failed." >&2
+ exit 1
+elif [[ "${pipestatus[1]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Decompressing 1 failed." >&2
+ exit 1
+elif [[ "${pipestatus[2]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Writing to root_diskroot5 failed." >&2
+ exit 1
+fi`})).Times(1).Return("", nil)
+ sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("curl -S -s -v -# -C - --retry 3 --retry-delay 60"), gomock.Eq([]string{"1", "|", "gzip -d", "|", "dd of=root_diskroot4 obs=2M",
+ `
+pipestatus=("${PIPESTATUS[@]}")
+if [[ "${pipestatus[0]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Fetching 1 failed." >&2
+ exit 1
+elif [[ "${pipestatus[1]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Decompressing 1 failed." >&2
+ exit 1
+elif [[ "${pipestatus[2]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Writing to root_diskroot4 failed." >&2
+ exit 1
+fi`})).Times(1).Return("", nil)
// Serial Portion
gomock.InOrder(
sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq(""), gomock.Eq([]string{
@@ -85,7 +109,7 @@
sam.EXPECT().Restart(gomock.Any()).Return(nil),
sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("stop"), gomock.Eq([]string{"ui"})).Return("", nil),
sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("stop"), gomock.Eq([]string{"update-engine"})).Return("", nil),
- sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq(""), gomock.Eq([]string{"rm -rf /mnt/stateful_partition/.update_available /mnt/stateful_partition/var_new /mnt/stateful_partition/dev_image_new", "&&", "curl 1 | tar --ignore-command-error --overwrite --directory=/mnt/stateful_partition -xzf -", "&&", "echo -n clobber > /mnt/stateful_partition/.update_available"})).Return("", nil),
+ sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq(""), gomock.Eq([]string{"rm -rf /mnt/stateful_partition/.update_available /mnt/stateful_partition/var_new /mnt/stateful_partition/dev_image_new", "&&", "curl -S -s -v -# -C - --retry 3 --retry-delay 60 1 | tar --ignore-command-error --overwrite --directory=/mnt/stateful_partition -xzf -", "&&", "echo -n clobber > /mnt/stateful_partition/.update_available"})).Return("", nil),
sam.EXPECT().Restart(gomock.Any()).Return(nil),
)
@@ -111,7 +135,7 @@
// Concurrent Portion
// Return not verfied so we can test full case:
sam.EXPECT().PathExists(gomock.Any(), "/var/lib/dlcservice/dlc/1/dlc_a/verified").Return(false, nil)
- sam.EXPECT().RunCmd(gomock.Any(), "", []string{"mkdir", "-p", "/var/cache/dlc/1/package/dlc_a", "&&", "curl", "--output", "/var/cache/dlc/1/package/dlc_a/dlc.img", "1"}).Return("", nil)
+ sam.EXPECT().RunCmd(gomock.Any(), "", []string{"mkdir", "-p", "/var/cache/dlc/1/package/dlc_a", "&&", "curl -S -s -v -# -C - --retry 3 --retry-delay 60", "--output", "/var/cache/dlc/1/package/dlc_a/dlc.img", "1"}).Return("", nil)
sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("start"), gomock.Eq([]string{"dlcservice"})).Times(1).Return("", nil)
if err := st.Execute(ctx); err != nil {
@@ -158,8 +182,32 @@
)
// Concurrent portion
sam.EXPECT().CopyData(gomock.Any(), gomock.Any()).Return("1", nil).AnyTimes()
- sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("curl"), gomock.Eq([]string{"1", "|", "gzip -d", "|", "dd of=root_diskroot5 obs=2M"})).Times(1).Return("", nil)
- sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("curl"), gomock.Eq([]string{"1", "|", "gzip -d", "|", "dd of=root_diskroot4 obs=2M"})).Times(1).Return("", nil)
+ sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("curl -S -s -v -# -C - --retry 3 --retry-delay 60"), gomock.Eq([]string{"1", "|", "gzip -d", "|", "dd of=root_diskroot5 obs=2M",
+ `
+pipestatus=("${PIPESTATUS[@]}")
+if [[ "${pipestatus[0]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Fetching 1 failed." >&2
+ exit 1
+elif [[ "${pipestatus[1]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Decompressing 1 failed." >&2
+ exit 1
+elif [[ "${pipestatus[2]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Writing to root_diskroot5 failed." >&2
+ exit 1
+fi`})).Times(1).Return("", nil)
+ sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("curl -S -s -v -# -C - --retry 3 --retry-delay 60"), gomock.Eq([]string{"1", "|", "gzip -d", "|", "dd of=root_diskroot4 obs=2M",
+ `
+pipestatus=("${PIPESTATUS[@]}")
+if [[ "${pipestatus[0]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Fetching 1 failed." >&2
+ exit 1
+elif [[ "${pipestatus[1]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Decompressing 1 failed." >&2
+ exit 1
+elif [[ "${pipestatus[2]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Writing to root_diskroot4 failed." >&2
+ exit 1
+fi`})).Times(1).Return("", nil)
// Serial Portion
gomock.InOrder(
sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq(""), gomock.Eq([]string{
@@ -217,8 +265,32 @@
)
// Concurrent portion
sam.EXPECT().CopyData(gomock.Any(), gomock.Any()).Return("1", nil).AnyTimes()
- sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("curl"), gomock.Eq([]string{"1", "|", "gzip -d", "|", "dd of=root_diskroot5 obs=2M"})).Times(1).Return("", nil)
- sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("curl"), gomock.Eq([]string{"1", "|", "gzip -d", "|", "dd of=root_diskroot4 obs=2M"})).Times(1).Return("", nil)
+ sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("curl -S -s -v -# -C - --retry 3 --retry-delay 60"), gomock.Eq([]string{"1", "|", "gzip -d", "|", "dd of=root_diskroot5 obs=2M",
+ `
+pipestatus=("${PIPESTATUS[@]}")
+if [[ "${pipestatus[0]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Fetching 1 failed." >&2
+ exit 1
+elif [[ "${pipestatus[1]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Decompressing 1 failed." >&2
+ exit 1
+elif [[ "${pipestatus[2]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Writing to root_diskroot5 failed." >&2
+ exit 1
+fi`})).Times(1).Return("", nil)
+ sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("curl -S -s -v -# -C - --retry 3 --retry-delay 60"), gomock.Eq([]string{"1", "|", "gzip -d", "|", "dd of=root_diskroot4 obs=2M",
+ `
+pipestatus=("${PIPESTATUS[@]}")
+if [[ "${pipestatus[0]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Fetching 1 failed." >&2
+ exit 1
+elif [[ "${pipestatus[1]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Decompressing 1 failed." >&2
+ exit 1
+elif [[ "${pipestatus[2]}" -ne 0 ]]; then
+ echo "$(date --rfc-3339=seconds) ERROR: Writing to root_diskroot4 failed." >&2
+ exit 1
+fi`})).Times(1).Return("", nil)
// Serial Portion
gomock.InOrder(
sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq(""), gomock.Eq([]string{
@@ -267,7 +339,7 @@
sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("stop"), gomock.Eq([]string{"ui"})).Return("", nil),
sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq("stop"), gomock.Eq([]string{"update-engine"})).Return("", nil),
sam.EXPECT().CopyData(gomock.Any(), gomock.Eq("path/to/image/stateful.tgz")).Return("url", nil),
- sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq(""), gomock.Eq([]string{"rm -rf /mnt/stateful_partition/.update_available /mnt/stateful_partition/var_new /mnt/stateful_partition/dev_image_new", "&&", "curl url | tar --ignore-command-error --overwrite --directory=/mnt/stateful_partition -xzf -", "&&", "echo -n clobber > /mnt/stateful_partition/.update_available"})).Return("", nil),
+ sam.EXPECT().RunCmd(gomock.Any(), gomock.Eq(""), gomock.Eq([]string{"rm -rf /mnt/stateful_partition/.update_available /mnt/stateful_partition/var_new /mnt/stateful_partition/dev_image_new", "&&", "curl -S -s -v -# -C - --retry 3 --retry-delay 60 url | tar --ignore-command-error --overwrite --directory=/mnt/stateful_partition -xzf -", "&&", "echo -n clobber > /mnt/stateful_partition/.update_available"})).Return("", nil),
sam.EXPECT().Restart(gomock.Any()).Return(nil),
)