Merge pull request #27786 from hashicorp/alisdair/refresh-empty-diag
backend/local: Return diag for refresh empty state
This commit is contained in:
commit
1301e38caa
|
@ -5,7 +5,6 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
|
@ -66,14 +65,11 @@ func (b *Local) opRefresh(
|
|||
// Set our state
|
||||
runningOp.State = opState.State()
|
||||
if !runningOp.State.HasResources() {
|
||||
if b.CLI != nil {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Warning,
|
||||
"Empty or non-existent state",
|
||||
"There are currently no resources tracked in the state, so there is nothing to refresh.",
|
||||
))
|
||||
b.CLI.Output(b.Colorize().Color(strings.TrimSpace(refreshNoState) + "\n"))
|
||||
}
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Warning,
|
||||
"Empty or non-existent state",
|
||||
"There are currently no resources tracked in the state, so there is nothing to refresh.",
|
||||
))
|
||||
}
|
||||
|
||||
// Perform the refresh in a goroutine so we can be interrupted
|
||||
|
@ -90,7 +86,7 @@ func (b *Local) opRefresh(
|
|||
return
|
||||
}
|
||||
|
||||
// write the resulting state to the running op
|
||||
// Write the resulting state to the running op
|
||||
runningOp.State = newState
|
||||
diags = diags.Append(refreshDiags)
|
||||
if refreshDiags.HasErrors() {
|
||||
|
@ -104,12 +100,7 @@ func (b *Local) opRefresh(
|
|||
op.ReportResult(runningOp, diags)
|
||||
return
|
||||
}
|
||||
|
||||
// Show any remaining warnings before exiting
|
||||
op.ReportResult(runningOp, diags)
|
||||
}
|
||||
|
||||
const refreshNoState = `
|
||||
[reset][bold][yellow]Empty or non-existent state file.[reset][yellow]
|
||||
|
||||
Refresh will do nothing. Refresh does not error or return an erroneous
|
||||
exit status because many automation scripts use refresh, plan, then apply
|
||||
and may not have a state file yet for the first run.
|
||||
`
|
||||
|
|
|
@ -3,6 +3,7 @@ package local
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
|
@ -214,6 +215,42 @@ func TestLocal_refresh_context_error(t *testing.T) {
|
|||
assertBackendStateUnlocked(t, b)
|
||||
}
|
||||
|
||||
func TestLocal_refreshEmptyState(t *testing.T) {
|
||||
b, cleanup := TestLocal(t)
|
||||
defer cleanup()
|
||||
|
||||
p := TestLocalProvider(t, b, "test", refreshFixtureSchema())
|
||||
testStateFile(t, b.StatePath, states.NewState())
|
||||
|
||||
p.ReadResourceFn = nil
|
||||
p.ReadResourceResponse = &providers.ReadResourceResponse{NewState: cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("yes"),
|
||||
})}
|
||||
|
||||
op, configCleanup := testOperationRefresh(t, "./testdata/refresh")
|
||||
defer configCleanup()
|
||||
|
||||
record, playback := testRecordDiagnostics(t)
|
||||
op.ShowDiagnostics = record
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("bad: %s", err)
|
||||
}
|
||||
<-run.Done()
|
||||
|
||||
diags := playback()
|
||||
if diags.HasErrors() {
|
||||
t.Fatalf("expected only warning diags, got errors: %s", diags.Err())
|
||||
}
|
||||
if got, want := diags.ErrWithWarnings().Error(), "Empty or non-existent state"; !strings.Contains(got, want) {
|
||||
t.Errorf("wrong diags\n got: %s\nwant: %s", got, want)
|
||||
}
|
||||
|
||||
// the backend should be unlocked after a run
|
||||
assertBackendStateUnlocked(t, b)
|
||||
}
|
||||
|
||||
func testOperationRefresh(t *testing.T, configDir string) (*backend.Operation, func()) {
|
||||
t.Helper()
|
||||
|
||||
|
|
Loading…
Reference in New Issue