Skip to content

Commit 731fcea

Browse files
committed
Merge remote-tracking branch 'upstream/master' into gcp_compute_disk_snapshot
2 parents 0c4e343 + dbdee44 commit 731fcea

691 files changed

Lines changed: 96368 additions & 8977 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.travis.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
1+
dist: trusty
12
sudo: false
23
language: go
34
go:
45
- 1.8
6+
7+
env:
8+
- CONSUL_VERSION=0.7.5 TF_CONSUL_TEST=1 GOMAXPROCS=4
9+
10+
# Fetch consul for the backend and provider tests
11+
before_install:
12+
- curl -sLo consul.zip https://releases.hashicorp.com/consul/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip
13+
- unzip consul.zip
14+
- mkdir ~/bin
15+
- mv consul ~/bin
16+
- export PATH="~/bin:$PATH"
17+
518
install:
619
# This script is used by the Travis build to install a cookie for
720
# go.googlesource.com so rate limits are higher when using `go get` to fetch

CHANGELOG.md

Lines changed: 160 additions & 4 deletions
Large diffs are not rendered by default.

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ plugin-dev: generate
3838
mv $(GOPATH)/bin/$(PLUGIN) $(GOPATH)/bin/terraform-$(PLUGIN)
3939

4040
# test runs the unit tests
41-
test:# fmtcheck errcheck generate
41+
test: fmtcheck errcheck generate
4242
go test -i $(TEST) || exit 1
4343
echo $(TEST) | \
4444
xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Terraform
22
=========
33

4-
- Website: http://www.terraform.io
4+
- Website: https://www.terraform.io
55
- [![Gitter chat](https://badges.gitter.im/hashicorp-terraform/Lobby.png)](https://gitter.im/hashicorp-terraform/Lobby)
66
- Mailing list: [Google Groups](http://groups.google.com/group/terraform-tool)
77

@@ -29,7 +29,7 @@ All documentation is available on the [Terraform website](http://www.terraform.i
2929
Developing Terraform
3030
--------------------
3131

32-
If you wish to work on Terraform itself or any of its built-in providers, you'll first need [Go](http://www.golang.org) installed on your machine (version 1.7+ is *required*). Alternatively, you can use the Vagrantfile in the root of this repo to stand up a virtual machine with the appropriate dev tooling already set up for you.
32+
If you wish to work on Terraform itself or any of its built-in providers, you'll first need [Go](http://www.golang.org) installed on your machine (version 1.8+ is *required*). Alternatively, you can use the Vagrantfile in the root of this repo to stand up a virtual machine with the appropriate dev tooling already set up for you.
3333

3434
For local dev first make sure Go is properly installed, including setting up a [GOPATH](http://golang.org/doc/code.html#GOPATH). You will also need to add `$GOPATH/bin` to your `$PATH`.
3535

backend/local/backend.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func (b *Local) States() ([]string, error) {
127127
// the listing always start with "default"
128128
envs := []string{backend.DefaultStateName}
129129

130-
entries, err := ioutil.ReadDir(DefaultEnvDir)
130+
entries, err := ioutil.ReadDir(b.stateEnvDir())
131131
// no error if there's no envs configured
132132
if os.IsNotExist(err) {
133133
return envs, nil
@@ -166,7 +166,7 @@ func (b *Local) DeleteState(name string) error {
166166
}
167167

168168
delete(b.states, name)
169-
return os.RemoveAll(filepath.Join(DefaultEnvDir, name))
169+
return os.RemoveAll(filepath.Join(b.stateEnvDir(), name))
170170
}
171171

172172
func (b *Local) State(name string) (state.State, error) {
@@ -320,17 +320,12 @@ func (b *Local) StatePaths(name string) (string, string, string) {
320320
name = backend.DefaultStateName
321321
}
322322

323-
envDir := DefaultEnvDir
324-
if b.StateEnvDir != "" {
325-
envDir = b.StateEnvDir
326-
}
327-
328323
if name == backend.DefaultStateName {
329324
if statePath == "" {
330325
statePath = DefaultStateFilename
331326
}
332327
} else {
333-
statePath = filepath.Join(envDir, name, DefaultStateFilename)
328+
statePath = filepath.Join(b.stateEnvDir(), name, DefaultStateFilename)
334329
}
335330

336331
if stateOutPath == "" {
@@ -353,12 +348,7 @@ func (b *Local) createState(name string) error {
353348
return nil
354349
}
355350

356-
envDir := DefaultEnvDir
357-
if b.StateEnvDir != "" {
358-
envDir = b.StateEnvDir
359-
}
360-
361-
stateDir := filepath.Join(envDir, name)
351+
stateDir := filepath.Join(b.stateEnvDir(), name)
362352
s, err := os.Stat(stateDir)
363353
if err == nil && s.IsDir() {
364354
// no need to check for os.IsNotExist, since that is covered by os.MkdirAll
@@ -374,6 +364,15 @@ func (b *Local) createState(name string) error {
374364
return nil
375365
}
376366

367+
// stateEnvDir returns the directory where state environments are stored.
368+
func (b *Local) stateEnvDir() string {
369+
if b.StateEnvDir != "" {
370+
return b.StateEnvDir
371+
}
372+
373+
return DefaultEnvDir
374+
}
375+
377376
// currentStateName returns the name of the current named state as set in the
378377
// configuration files.
379378
// If there are no configured environments, currentStateName returns "default"

backend/local/backend_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ func TestLocal_impl(t *testing.T) {
2020
var _ backend.CLI = new(Local)
2121
}
2222

23+
func TestLocal_backend(t *testing.T) {
24+
b := TestLocal(t)
25+
backend.TestBackend(t, b, b)
26+
}
27+
2328
func checkState(t *testing.T, path, expected string) {
2429
// Read the state
2530
f, err := os.Open(path)

backend/local/testing.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func TestLocal(t *testing.T) *Local {
2121
StatePath: filepath.Join(tempDir, "state.tfstate"),
2222
StateOutPath: filepath.Join(tempDir, "state.tfstate"),
2323
StateBackupPath: filepath.Join(tempDir, "state.tfstate.bak"),
24+
StateEnvDir: filepath.Join(tempDir, "state.tfstate.d"),
2425
ContextOpts: &terraform.ContextOpts{},
2526
}
2627
}

backend/remote-state/consul/backend.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,20 @@ func New() backend.Backend {
5353
Description: "HTTP Auth in the format of 'username:password'",
5454
Default: "", // To prevent input
5555
},
56+
57+
"gzip": &schema.Schema{
58+
Type: schema.TypeBool,
59+
Optional: true,
60+
Description: "Compress the state data using gzip",
61+
Default: false,
62+
},
63+
64+
"lock": &schema.Schema{
65+
Type: schema.TypeBool,
66+
Optional: true,
67+
Description: "Lock state access",
68+
Default: true,
69+
},
5670
},
5771
}
5872

@@ -64,13 +78,18 @@ func New() backend.Backend {
6478
type Backend struct {
6579
*schema.Backend
6680

81+
// The fields below are set from configure
6782
configData *schema.ResourceData
83+
lock bool
6884
}
6985

7086
func (b *Backend) configure(ctx context.Context) error {
7187
// Grab the resource data
7288
b.configData = schema.FromContextBackendConfig(ctx)
7389

90+
// Store the lock information
91+
b.lock = b.configData.Get("lock").(bool)
92+
7493
// Initialize a client to test config
7594
_, err := b.clientRaw()
7695
return err

backend/remote-state/consul/backend_state.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,27 +85,39 @@ func (b *Backend) State(name string) (state.State, error) {
8585
// Determine the path of the data
8686
path := b.path(name)
8787

88+
// Determine whether to gzip or not
89+
gzip := b.configData.Get("gzip").(bool)
90+
8891
// Build the state client
89-
stateMgr := &remote.State{
92+
var stateMgr state.State = &remote.State{
9093
Client: &RemoteClient{
9194
Client: client,
9295
Path: path,
96+
GZip: gzip,
9397
},
9498
}
9599

100+
// If we're not locking, disable it
101+
if !b.lock {
102+
stateMgr = &state.LockDisabled{Inner: stateMgr}
103+
}
104+
105+
// Get the locker, which we know always exists
106+
stateMgrLocker := stateMgr.(state.Locker)
107+
96108
// Grab a lock, we use this to write an empty state if one doesn't
97109
// exist already. We have to write an empty state as a sentinel value
98110
// so States() knows it exists.
99111
lockInfo := state.NewLockInfo()
100112
lockInfo.Operation = "init"
101-
lockId, err := stateMgr.Lock(lockInfo)
113+
lockId, err := stateMgrLocker.Lock(lockInfo)
102114
if err != nil {
103115
return nil, fmt.Errorf("failed to lock state in Consul: %s", err)
104116
}
105117

106118
// Local helper function so we can call it multiple places
107119
lockUnlock := func(parent error) error {
108-
if err := stateMgr.Unlock(lockId); err != nil {
120+
if err := stateMgrLocker.Unlock(lockId); err != nil {
109121
return fmt.Errorf(strings.TrimSpace(errStateUnlock), lockId, err)
110122
}
111123

backend/remote-state/consul/backend_test.go

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,93 @@ package consul
22

33
import (
44
"fmt"
5+
"io/ioutil"
56
"os"
67
"testing"
78
"time"
89

10+
"github.com/hashicorp/consul/testutil"
911
"github.com/hashicorp/terraform/backend"
1012
)
1113

1214
func TestBackend_impl(t *testing.T) {
1315
var _ backend.Backend = new(Backend)
1416
}
1517

16-
func TestBackend(t *testing.T) {
17-
addr := os.Getenv("CONSUL_HTTP_ADDR")
18-
if addr == "" {
19-
t.Log("consul tests require CONSUL_HTTP_ADDR")
18+
func newConsulTestServer(t *testing.T) *testutil.TestServer {
19+
skip := os.Getenv("TF_ACC") == "" && os.Getenv("TF_CONSUL_TEST") == ""
20+
if skip {
21+
t.Log("consul server tests require setting TF_ACC or TF_CONSUL_TEST")
2022
t.Skip()
2123
}
2224

25+
srv := testutil.NewTestServerConfig(t, func(c *testutil.TestServerConfig) {
26+
c.LogLevel = "warn"
27+
28+
if !testing.Verbose() {
29+
c.Stdout = ioutil.Discard
30+
c.Stderr = ioutil.Discard
31+
}
32+
})
33+
34+
return srv
35+
}
36+
37+
func TestBackend(t *testing.T) {
38+
srv := newConsulTestServer(t)
39+
defer srv.Stop()
40+
41+
path := fmt.Sprintf("tf-unit/%s", time.Now().String())
42+
43+
// Get the backend. We need two to test locking.
44+
b1 := backend.TestBackendConfig(t, New(), map[string]interface{}{
45+
"address": srv.HTTPAddr,
46+
"path": path,
47+
})
48+
49+
b2 := backend.TestBackendConfig(t, New(), map[string]interface{}{
50+
"address": srv.HTTPAddr,
51+
"path": path,
52+
})
53+
54+
// Test
55+
backend.TestBackend(t, b1, b2)
56+
}
57+
58+
func TestBackend_lockDisabled(t *testing.T) {
59+
srv := newConsulTestServer(t)
60+
defer srv.Stop()
61+
62+
path := fmt.Sprintf("tf-unit/%s", time.Now().String())
63+
64+
// Get the backend. We need two to test locking.
65+
b1 := backend.TestBackendConfig(t, New(), map[string]interface{}{
66+
"address": srv.HTTPAddr,
67+
"path": path,
68+
"lock": false,
69+
})
70+
71+
b2 := backend.TestBackendConfig(t, New(), map[string]interface{}{
72+
"address": srv.HTTPAddr,
73+
"path": path + "different", // Diff so locking test would fail if it was locking
74+
"lock": false,
75+
})
76+
77+
// Test
78+
backend.TestBackend(t, b1, b2)
79+
}
80+
81+
func TestBackend_gzip(t *testing.T) {
82+
srv := newConsulTestServer(t)
83+
defer srv.Stop()
84+
2385
// Get the backend
2486
b := backend.TestBackendConfig(t, New(), map[string]interface{}{
25-
"address": addr,
87+
"address": srv.HTTPAddr,
2688
"path": fmt.Sprintf("tf-unit/%s", time.Now().String()),
89+
"gzip": true,
2790
})
2891

2992
// Test
30-
backend.TestBackend(t, b)
93+
backend.TestBackend(t, b, nil)
3194
}

0 commit comments

Comments
 (0)