Skip to content
This repository was archived by the owner on Jan 21, 2020. It is now read-only.

Commit 9f0bdd5

Browse files
kaufersDavid Chung
authored andcommitted
Update terraform file system lock to use a mutex (#761)
Signed-off-by: Steven Kaufer <[email protected]>
1 parent 9715fd4 commit 9f0bdd5

File tree

12 files changed

+18
-438
lines changed

12 files changed

+18
-438
lines changed

pkg/provider/terraform/instance/apply.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,7 @@ type tfFuncs struct {
144144
// Once these steps are done then "terraform apply" can execute without the
145145
// file system lock.
146146
func (p *plugin) handleFiles(fns tfFuncs) error {
147-
if err := p.fsLock.TryLock(); err != nil {
148-
log.Infof("In handleFiles, cannot acquire file lock")
149-
return err
150-
}
147+
p.fsLock.Lock()
151148
defer p.fsLock.Unlock()
152149

153150
// Refresh resources and get updated resources names

pkg/provider/terraform/instance/plugin.go

Lines changed: 17 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"github.com/docker/infrakit/pkg/template"
2424
"github.com/docker/infrakit/pkg/types"
2525
"github.com/docker/infrakit/pkg/util/exec"
26-
"github.com/nightlyone/lockfile"
2726
"github.com/spf13/afero"
2827
)
2928

@@ -63,7 +62,7 @@ var instNameRegex = regexp.MustCompile("(.*)(instance-[0-9]+)")
6362
type plugin struct {
6463
Dir string
6564
fs afero.Fs
66-
fsLock lockfile.Lockfile
65+
fsLock sync.Mutex
6766
applying bool
6867
applyLock sync.Mutex
6968
pretend bool // true to actually do terraform apply
@@ -98,14 +97,10 @@ type ImportOptions struct {
9897
// NewTerraformInstancePlugin returns an instance plugin backed by disk files.
9998
func NewTerraformInstancePlugin(dir string, pollInterval time.Duration, standalone bool, envs []string, importOpts *ImportOptions) instance.Plugin {
10099
log.Debugln("terraform instance plugin. dir=", dir)
101-
fsLock, err := lockfile.New(filepath.Join(dir, "tf-apply.lck"))
102-
if err != nil {
103-
panic(err)
104-
}
105100

106101
var pluginLookup func() discovery.Plugins
107102
if !standalone {
108-
if err = local.Setup(); err != nil {
103+
if err := local.Setup(); err != nil {
109104
panic(err)
110105
}
111106
plugins, err := local.NewPluginDiscovery()
@@ -119,7 +114,6 @@ func NewTerraformInstancePlugin(dir string, pollInterval time.Duration, standalo
119114
p := plugin{
120115
Dir: dir,
121116
fs: afero.NewOsFs(),
122-
fsLock: fsLock,
123117
pollInterval: pollInterval,
124118
pluginLookup: pluginLookup,
125119
envs: envs,
@@ -952,16 +946,9 @@ func (p *plugin) Provision(spec instance.Spec) (*instance.ID, error) {
952946
// we simply look for vm instance and merge in the tags, and user init, etc.
953947

954948
// Hold the fs lock for the duration since the file is written at the end
955-
var name string
956-
for {
957-
if err := p.fsLock.TryLock(); err == nil {
958-
defer p.fsLock.Unlock()
959-
name = ensureUniqueFile(p.Dir)
960-
break
961-
}
962-
log.Infoln("Can't acquire fsLock on Provision, waiting")
963-
time.Sleep(time.Second)
964-
}
949+
p.fsLock.Lock()
950+
defer p.fsLock.Unlock()
951+
name := ensureUniqueFile(p.Dir)
965952
id := instance.ID(name)
966953

967954
// Decode the given spec and find the VM resource
@@ -1003,14 +990,8 @@ func (p *plugin) Provision(spec instance.Spec) (*instance.ID, error) {
1003990

1004991
// Label labels the instance
1005992
func (p *plugin) Label(instance instance.ID, labels map[string]string) error {
1006-
// Acquire lock
1007-
for {
1008-
if err := p.fsLock.TryLock(); err == nil {
1009-
defer p.fsLock.Unlock()
1010-
break
1011-
}
1012-
time.Sleep(time.Second)
1013-
}
993+
p.fsLock.Lock()
994+
defer p.fsLock.Unlock()
1014995

1015996
tf, filename, err := p.parseFileForInstanceID(instance)
1016997
if err != nil {
@@ -1041,27 +1022,21 @@ func (p *plugin) Label(instance instance.ID, labels map[string]string) error {
10411022

10421023
// Destroy terminates an existing instance.
10431024
func (p *plugin) Destroy(instID instance.ID, context instance.Context) error {
1025+
// Acquire Lock outside of recursive doDestroy function
1026+
p.fsLock.Lock()
1027+
defer p.fsLock.Unlock()
1028+
10441029
processAttach := true
10451030
if context == instance.RollingUpdate {
10461031
// Do not destroy related resources since this instance will be re-provisioned
10471032
processAttach = false
10481033
}
1049-
err := p.doDestroy(instID, processAttach, true)
1050-
return err
1034+
return p.doDestroy(instID, processAttach, true)
10511035
}
10521036

10531037
// doDestroy terminates an existing instance and optionally terminates any related
10541038
// resources
10551039
func (p *plugin) doDestroy(inst instance.ID, processAttach, executeTfApply bool) error {
1056-
// Acquire lock
1057-
for {
1058-
if err := p.fsLock.TryLock(); err == nil {
1059-
defer p.fsLock.Unlock()
1060-
break
1061-
}
1062-
time.Sleep(time.Second)
1063-
}
1064-
10651040
tf, filename, err := p.parseFileForInstanceID(inst)
10661041
if err != nil {
10671042
return err
@@ -1159,13 +1134,8 @@ func parseAttachTag(tf *TFormat) ([]string, error) {
11591134
func (p *plugin) DescribeInstances(tags map[string]string, properties bool) ([]instance.Description, error) {
11601135
log.Debugln("describe-instances", tags)
11611136
// Acquire lock since we are reading all files and potentially running "terraform show"
1162-
for {
1163-
if err := p.fsLock.TryLock(); err == nil {
1164-
defer p.fsLock.Unlock()
1165-
break
1166-
}
1167-
time.Sleep(time.Second)
1168-
}
1137+
p.fsLock.Lock()
1138+
defer p.fsLock.Unlock()
11691139

11701140
// localSpecs are what we told terraform to create - these are the generated files.
11711141
localSpecs, err := p.scanLocalFiles()
@@ -1309,16 +1279,9 @@ type importFns struct {
13091279
// .tf.json.new file based on the given spec
13101280
func (p *plugin) importResources(fns importFns, resources []*ImportResource, spec *instance.Spec) error {
13111281
// Acquire lock since we are creating a tf.json.new file and updating terraform state
1312-
var vmResName string
1313-
for {
1314-
if err := p.fsLock.TryLock(); err == nil {
1315-
defer p.fsLock.Unlock()
1316-
vmResName = ensureUniqueFile(p.Dir)
1317-
break
1318-
}
1319-
log.Infoln("Can't acquire fsLock on importResource, waiting")
1320-
time.Sleep(time.Second)
1321-
}
1282+
p.fsLock.Lock()
1283+
defer p.fsLock.Unlock()
1284+
vmResName := ensureUniqueFile(p.Dir)
13221285

13231286
// Parse the instance spec
13241287
tf := TFormat{}

vendor.conf

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.0
9393
github.com/mitchellh/go-ps 4fdf99ab29366514c69ccccddab5dc58b8d84062
9494
github.com/mitchellh/mapstructure cc8532a
9595
github.com/moby/hyperkit/go 32c1b23
96-
github.com/nightlyone/lockfile 1d49c98
9796
github.com/onsi/ginkgo v1.4.0
9897
github.com/onsi/gomega v1.2.0
9998
github.com/opencontainers/runc v1.0.0-rc2-137-g43c4300
@@ -176,4 +175,3 @@ github.com/micdoher/terraform-provider-ucs/ucsclient 50940f9
176175
github.com/micdoher/terraform-provider-ucs/ucsclient/ucsinternal e82c113
177176
github.com/micdoher/GoUtils 799bb49
178177
gopkg.in/xmlpath.v2 860cbec
179-

vendor/github.com/nightlyone/lockfile/.gitignore

Lines changed: 0 additions & 27 deletions
This file was deleted.

vendor/github.com/nightlyone/lockfile/.gitmodules

Lines changed: 0 additions & 3 deletions
This file was deleted.

vendor/github.com/nightlyone/lockfile/.travis.yml

Lines changed: 0 additions & 14 deletions
This file was deleted.

vendor/github.com/nightlyone/lockfile/LICENSE

Lines changed: 0 additions & 19 deletions
This file was deleted.

vendor/github.com/nightlyone/lockfile/README.md

Lines changed: 0 additions & 52 deletions
This file was deleted.

vendor/github.com/nightlyone/lockfile/appveyor.yml

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)