From 53c8e9b67ed9482edd1c03146a55b73b014134b5 Mon Sep 17 00:00:00 2001
From: mattjmcnaughton <mattjmcnaughton@gmail.com>
Date: Mon, 28 May 2018 10:07:33 -0400
Subject: [PATCH] Fix concurrency issues with helm install

Address a race condition that arises when running two `helm install`
commands, both of which specify a namespace that does not already exist.

In this specific instance, attempting to create a `namespace` which
already exists shouldn't be a failure which causes `helm install` to
terminate.
---
 pkg/kube/namespace.go                 | 11 ++++++++++-
 pkg/tiller/environment/environment.go |  2 --
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/pkg/kube/namespace.go b/pkg/kube/namespace.go
index 9d2793d87..6547e4abc 100644
--- a/pkg/kube/namespace.go
+++ b/pkg/kube/namespace.go
@@ -40,7 +40,16 @@ func getNamespace(client internalclientset.Interface, namespace string) (*core.N
 func ensureNamespace(client internalclientset.Interface, namespace string) error {
 	_, err := getNamespace(client, namespace)
 	if err != nil && errors.IsNotFound(err) {
-		return createNamespace(client, namespace)
+		err = createNamespace(client, namespace)
+
+		// If multiple commands which run `ensureNamespace` are run in
+		// parallel, then protect against the race condition in which
+		// the namespace did not exist when `getNamespace` was executed,
+		// but did exist when `createNamespace` was executed. If that
+		// happens, we can just proceed as normal.
+		if errors.IsAlreadyExists(err) {
+			return nil
+		}
 	}
 	return err
 }
diff --git a/pkg/tiller/environment/environment.go b/pkg/tiller/environment/environment.go
index 366fdf522..18518dfc1 100644
--- a/pkg/tiller/environment/environment.go
+++ b/pkg/tiller/environment/environment.go
@@ -98,8 +98,6 @@ type Engine interface {
 type KubeClient interface {
 	// Create creates one or more resources.
 	//
-	// namespace must contain a valid existing namespace.
-	//
 	// reader must contain a YAML stream (one or more YAML documents separated
 	// by "\n---\n").
 	Create(namespace string, reader io.Reader, timeout int64, shouldWait bool) error
-- 
GitLab