pulumi/pkg/backend/updates.go
Chris Smith 4c217fd358
Add "pulumi history" command (#826)
This PR adds a new `pulumi history` command, which prints the update history for a stack.

The local backend stores the update history in a JSON file on disk, next to the checkpoint file. The cloud backend simply provides the update metadata, and expects to receive all the data from a (NYI) `/history` REST endpoint.

`pkg/backend/updates.go` defines the data that is being persisted. The way the data is wired through the system is adding a new `backend.UpdateMetadata` parameter to a Stack/Backend's `Update` and `Destroy` methods.

I use `tests/integration/stack_outputs/` as the simple app for the related tests, hence the addition to the `.gitignore` and fixing the name in the `Pulumi.yaml`.

Fixes #636.
2018-01-24 18:22:41 -08:00

104 lines
3.1 KiB
Go

// Copyright 2018, Pulumi Corporation. All rights reserved.
package backend
import (
"sort"
"github.com/pulumi/pulumi/pkg/engine"
"github.com/pulumi/pulumi/pkg/resource/config"
)
// UpdateMetadata describes optional metadata about an update.
type UpdateMetadata struct {
// Message is an optional message associated with the update.
Message string `json:"message"`
// Environment contains optional data from the deploying environment. e.g. the current
// source code control commit information.
Environment map[string]string `json:"environment"`
}
// UpdateKind is an enum for the type of update performed.
type UpdateKind string
const (
// DeployUpdate is the prototypical Pulumi program update.
DeployUpdate UpdateKind = "update"
// PreviewUpdate is a preview of an update, without impacting resources.
PreviewUpdate = "preview"
// DestroyUpdate is an update which removes all resources.
DestroyUpdate = "destroy"
)
// UpdateResult is an enum for the result of the update.
type UpdateResult string
const (
// InProgressResult is for updates that have not yet completed.
InProgressResult = "in-progress"
// SucceededResult is for updates that completed successfully.
SucceededResult UpdateResult = "succeeded"
// FailedResult is for updates that have failed.
FailedResult = "failed"
)
// Keys we use for values put into UpdateInfo.Environment.
const (
// GitHead is the commit hash of HEAD.
GitHead = "git.head"
// GitDirty ("true", "false") indiciates if there are any unstaged or modified files in the local repo.
GitDirty = "git.dirty"
// GitHubLogin is the user/organization who owns the local repo, if the origin remote is hosted on GitHub.com.
GitHubLogin = "github.login"
// GitHubRepo is the name of the GitHub repo, if the local git repo's remote origin is hosted on GitHub.com.
GitHubRepo = "github.repo"
)
// UpdateInfo describes a previous update.
type UpdateInfo struct {
// Information known before an update is started.
Kind UpdateKind `json:"kind"`
StartTime int64 `json:"startTime"`
// Message is an optional message associated with the update.
Message string `json:"message"`
// Environment contains optional data from the deploying environment. e.g. the current
// source code control commit information.
Environment map[string]string `json:"environment"`
// Config used for the update.
Config config.Map `json:"config"`
// Information obtained from an update completing.
Result UpdateResult `json:"result"`
EndTime int64 `json:"endTime"`
ResourceChanges engine.ResourceChanges `json:"resourceChanges"`
}
// updateSorter implements the sort.Interface interface.
// Sorts by StartTime in *descending* order (more recent first).
type updateSorter struct {
u []UpdateInfo
}
func (us *updateSorter) Len() int {
return len(us.u)
}
func (us *updateSorter) Swap(i, j int) {
us.u[i], us.u[j] = us.u[j], us.u[i]
}
func (us *updateSorter) Less(i, j int) bool {
return us.u[i].StartTime > us.u[j].StartTime
}
// Sort orders the UpdateInfo slice by StartTime descending.
func Sort(updates []UpdateInfo) {
us := updateSorter{u: updates}
sort.Sort(&us)
}