From 996367f223bacd9029bd84c431d05ebde3a7316f Mon Sep 17 00:00:00 2001 From: Felix Bechstein Date: Wed, 28 Feb 2018 10:06:00 +0100 Subject: [PATCH] add locking for credentials file. fixes #9 --- CHANGELOG.md | 4 ++++ swamp.go | 24 ++++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df64f62..16291a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## swamp v0.6 + +* add locking for credentials file (#6) + ## swamp v0.5.2 * enable cgo for default linux build diff --git a/swamp.go b/swamp.go index 4a1b230..618a7a6 100644 --- a/swamp.go +++ b/swamp.go @@ -14,6 +14,7 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sts" "github.com/go-ini/ini" + "github.com/golang-utils/lockfile" ) const ( @@ -63,11 +64,23 @@ func writeProfile(cred *sts.Credentials, targetProfile, region *string) { } awsPath := filepath.Join(usr.HomeDir, ".aws") - filename := filepath.Join(awsPath, "credentials") + credentialsPath := filepath.Join(awsPath, "credentials") + lockPath := filepath.Join(awsPath, ".credentials.lock") - cfg, err := ini.Load(filename) + // get a lock to prevent concurrent writes on credentials file + lock := lockfile.New() + for { + if err := lock.Lock(lockPath); err == nil { + break + } else { + fmt.Printf("Waiting for lock %s\n", lockPath) + time.Sleep(time.Second) + } + } + + cfg, err := ini.Load(credentialsPath) if err != nil { - fmt.Printf("Unable to find credentials file %s. Creating new file.\n", filename) + fmt.Printf("Unable to find credentials file %s. Creating new file.\n", credentialsPath) if err := os.MkdirAll(awsPath, os.ModePerm); err != nil { die("Error creating aws config path", err) @@ -86,10 +99,13 @@ func writeProfile(cred *sts.Credentials, targetProfile, region *string) { updateKey(sec, "aws_secret_access_key", cred.SecretAccessKey) updateKey(sec, "aws_session_token", cred.SessionToken) - if err := cfg.SaveTo(filename); err != nil { + if err := cfg.SaveTo(credentialsPath); err != nil { die("Error writing credentials file", err) } + // release the lock manually + os.Remove(lockPath) + fmt.Printf("Wrote session token for profile %s\n", *targetProfile) fmt.Printf("Token is valid until: %v\n", cred.Expiration) }