services/device/device: Retry upload when already exists
If we try to upload the same binary twice within the same second, the
second attempt will use the same object name and then fail with an
"already exists" error.
There are many ways to fix this problem:
- We could ignore this error and assume that it is indeed the same
binary and we don't need to upload it again.
- We could change the timestamp to have finer granularity.
- We could retry with a slightly different object name.
This change implements the third option.
Change-Id: Ib03108ffdb83387594571f33284f511a6d76ba31
diff --git a/services/device/device/publish.go b/services/device/device/publish.go
index e23c505..fb5b6a9 100644
--- a/services/device/device/publish.go
+++ b/services/device/device/publish.go
@@ -112,8 +112,18 @@
timestamp := time.Now().UTC().Format(time.RFC3339)
binaryVON := naming.Join(binaryService, binaryName, fmt.Sprintf("%s-%s", goosFlag, goarchFlag), timestamp)
binaryFile := filepath.Join(binPath, binaryName)
- binarySig, err := binarylib.UploadFromFile(ctx, binaryVON, binaryFile)
- if err != nil {
+ var binarySig *security.Signature
+ var err error
+ for i := 0; ; i++ {
+ binarySig, err = binarylib.UploadFromFile(ctx, binaryVON, binaryFile)
+ if verror.ErrorID(err) == verror.ErrExist.ID {
+ newTS := fmt.Sprintf("%s-%d", timestamp, i+1)
+ binaryVON = naming.Join(binaryService, binaryName, fmt.Sprintf("%s-%s", goosFlag, goarchFlag), newTS)
+ continue
+ }
+ if err == nil {
+ break
+ }
return err
}
fmt.Fprintf(env.Stdout, "Binary %q uploaded from file %s\n", binaryVON, binaryFile)