Rework polling (#531)
Rework the polling code for `pulumi` when targeting hosted scenarios. (i.e. absorb https://github.com/pulumi/pulumi-service/pull/282.) We now return an `updateID` for update, preview, and destroy. And use bake that into the URL. This PR also silently ignores 504 errors which are now returned from the Pulumi Service if the PPC request times out. Combined, this should ameliorate some of the symptoms we see from https://github.com/pulumi/pulumi-ppc/issues/60. Though we'll continue to try to identify and fix the root cause.
This commit is contained in:
parent
fbb3887343
commit
5085c7eef8
|
@ -96,16 +96,16 @@ func (b *pulumiCloudPulumiBackend) Preview(stackName tokens.QName, debug bool, o
|
|||
return err
|
||||
}
|
||||
|
||||
var updateResponse apitype.PreviewUpdateResponse
|
||||
var response apitype.PreviewUpdateResponse
|
||||
path := fmt.Sprintf("/orgs/%s/programs/%s/%s/stacks/%s/preview",
|
||||
projID.Owner, projID.Repository, projID.Project, string(stackName))
|
||||
if err = pulumiRESTCall("POST", path, &updateRequest, &updateResponse); err != nil {
|
||||
if err = pulumiRESTCall("POST", path, &updateRequest, &response); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Previewing update to Stack '%s'...\n", string(stackName))
|
||||
|
||||
// Wait for the update to complete.
|
||||
status, err := waitForUpdate(fmt.Sprintf("%s/%s", path, updateResponse.PreviewID))
|
||||
status, err := waitForUpdate(fmt.Sprintf("%s/%s", path, response.UpdateID))
|
||||
fmt.Println() // The PPC's final message we print to STDOUT doesn't include a newline.
|
||||
|
||||
if err != nil {
|
||||
|
@ -128,15 +128,15 @@ func (b *pulumiCloudPulumiBackend) Update(stackName tokens.QName, debug bool, op
|
|||
return err
|
||||
}
|
||||
|
||||
var updateResponse apitype.UpdateProgramResponse
|
||||
var response apitype.UpdateProgramResponse
|
||||
path := fmt.Sprintf("/orgs/%s/programs/%s/%s/stacks/%s/update", projID.Owner, projID.Repository, projID.Project, string(stackName))
|
||||
if err = pulumiRESTCall("POST", path, &updateRequest, &updateResponse); err != nil {
|
||||
if err = pulumiRESTCall("POST", path, &updateRequest, &response); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Updating Stack '%s' to version %d...\n", string(stackName), updateResponse.Version)
|
||||
fmt.Printf("Updating Stack '%s' to version %d...\n", string(stackName), response.Version)
|
||||
|
||||
// Wait for the update to complete.
|
||||
status, err := waitForUpdate(path)
|
||||
status, err := waitForUpdate(fmt.Sprintf("%s/%s", path, response.UpdateID))
|
||||
fmt.Println() // The PPC's final message we print to STDOUT doesn't include a newline.
|
||||
|
||||
if err != nil {
|
||||
|
@ -164,15 +164,15 @@ func (b *pulumiCloudPulumiBackend) Destroy(stackName tokens.QName, debug bool, o
|
|||
return err
|
||||
}
|
||||
|
||||
var response apitype.DestroyProgramResponse
|
||||
path := fmt.Sprintf("/orgs/%s/programs/%s/%s/stacks/%s/destroy", projID.Owner, projID.Repository, projID.Project, string(stackName))
|
||||
|
||||
if err = pulumiRESTCall("POST", path, &updateRequest, nil /*destroy does not return data upon success*/); err != nil {
|
||||
if err = pulumiRESTCall("POST", path, &updateRequest, &response); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Destroying Stack '%s'...\n", string(stackName))
|
||||
|
||||
// Wait for the update to complete.
|
||||
status, err := waitForUpdate(path)
|
||||
status, err := waitForUpdate(fmt.Sprintf("%s/%s", path, response.UpdateID))
|
||||
fmt.Println() // The PPC's final message we print to STDOUT doesn't include a newline.
|
||||
|
||||
if err != nil {
|
||||
|
@ -315,7 +315,13 @@ func waitForUpdate(path string) (apitype.UpdateStatus, error) {
|
|||
var updateResults apitype.UpdateResults
|
||||
pathWithIndex := fmt.Sprintf("%s?afterIndex=%s", path, eventIndex)
|
||||
if err := pulumiRESTCall("GET", pathWithIndex, nil, &updateResults); err != nil {
|
||||
return "", err
|
||||
// If our request to the Pulumi Service returned a 504 (Gateway Timeout), ignore it
|
||||
// and keep continuing.
|
||||
// TODO(pulumi/pulumi-ppc/issues/60): Elminate these timeouts all together.
|
||||
if errResp, ok := err.(*apitype.ErrorResponse); ok && errResp.Code == 504 {
|
||||
time.Sleep(5 * time.Second)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
for _, event := range updateResults.Events {
|
||||
|
|
|
@ -31,13 +31,6 @@ func (err ErrorResponse) Error() string {
|
|||
return fmt.Sprintf("[%d] %s", err.Code, err.Message)
|
||||
}
|
||||
|
||||
// PreviewUpdateResponse is returned when previewing a potential update.
|
||||
// Since multiple previews can be running concurrently, the caller must keep
|
||||
// track of the opaque preview ID for future requests.
|
||||
type PreviewUpdateResponse struct {
|
||||
PreviewID string `json:"previewID"`
|
||||
}
|
||||
|
||||
// UpdateProgramRequest is the request type for updating (aka deploying) a Pulumi program.
|
||||
type UpdateProgramRequest struct {
|
||||
// Properties from the Project file.
|
||||
|
@ -51,11 +44,23 @@ type UpdateProgramRequest struct {
|
|||
Config map[tokens.ModuleMember]string `json:"config"`
|
||||
}
|
||||
|
||||
// PreviewUpdateResponse is returned when previewing a potential update.
|
||||
type PreviewUpdateResponse struct {
|
||||
UpdateID string `json:"updateID"`
|
||||
}
|
||||
|
||||
// UpdateProgramResponse is the response type when updating a Pulumi program.
|
||||
type UpdateProgramResponse struct {
|
||||
UpdateID string `json:"updateID"`
|
||||
// Version is the program's new version being updated to.
|
||||
Version int `json:"version"`
|
||||
}
|
||||
|
||||
// DestroyProgramResponse is the response type when destroying a Pulumi program's resources.
|
||||
type DestroyProgramResponse struct {
|
||||
UpdateID string `json:"updateID"`
|
||||
}
|
||||
|
||||
// UpdateEventKind is an enum for the type of update events.
|
||||
type UpdateEventKind string
|
||||
|
||||
|
|
Loading…
Reference in a new issue