(source InstanceServer, pool string, req api.StorageVolumePost, urls []string)
| 504 | } |
| 505 | |
| 506 | func (r *ProtocolIncus) tryMigrateStoragePoolVolume(source InstanceServer, pool string, req api.StorageVolumePost, urls []string) (RemoteOperation, error) { |
| 507 | if len(urls) == 0 { |
| 508 | return nil, errors.New("The source server isn't listening on the network") |
| 509 | } |
| 510 | |
| 511 | rop := remoteOperation{ |
| 512 | chDone: make(chan bool), |
| 513 | } |
| 514 | |
| 515 | operation := req.Target.Operation |
| 516 | |
| 517 | // Forward targetOp to remote op |
| 518 | go func() { |
| 519 | success := false |
| 520 | var errors []remoteOperationResult |
| 521 | for _, serverURL := range urls { |
| 522 | req.Target.Operation = fmt.Sprintf("%s/1.0/operations/%s", serverURL, url.PathEscape(operation)) |
| 523 | |
| 524 | // Send the request |
| 525 | top, err := source.MigrateStoragePoolVolume(pool, req) |
| 526 | if err != nil { |
| 527 | errors = append(errors, remoteOperationResult{URL: serverURL, Error: err}) |
| 528 | continue |
| 529 | } |
| 530 | |
| 531 | rop := remoteOperation{ |
| 532 | targetOp: top, |
| 533 | chDone: make(chan bool), |
| 534 | } |
| 535 | |
| 536 | for _, handler := range rop.handlers { |
| 537 | _, _ = rop.targetOp.AddHandler(handler) |
| 538 | } |
| 539 | |
| 540 | err = rop.targetOp.Wait() |
| 541 | if err != nil { |
| 542 | errors = append(errors, remoteOperationResult{URL: serverURL, Error: err}) |
| 543 | |
| 544 | if localtls.IsConnectionError(err) { |
| 545 | continue |
| 546 | } |
| 547 | |
| 548 | break |
| 549 | } |
| 550 | |
| 551 | success = true |
| 552 | break |
| 553 | } |
| 554 | |
| 555 | if !success { |
| 556 | rop.err = remoteOperationError("Failed storage volume creation", errors) |
| 557 | } |
| 558 | |
| 559 | close(rop.chDone) |
| 560 | }() |
| 561 | |
| 562 | return &rop, nil |
| 563 | } |
no test coverage detected