From 2d90d50fbcbb549d61fd8276785ba801ed819d51 Mon Sep 17 00:00:00 2001 From: Rob Brockbank Date: Tue, 1 Nov 2016 15:34:43 +0000 Subject: [PATCH 1/2] Avoid race conditions on profile creation --- driver/network_driver.go | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/driver/network_driver.go b/driver/network_driver.go index f0d853d..0a0b0a3 100644 --- a/driver/network_driver.go +++ b/driver/network_driver.go @@ -139,32 +139,25 @@ func (d NetworkDriver) CreateEndpoint(request *network.CreateEndpointRequest) (* // Now that we know the network name, set it on the endpoint. endpoint.Spec.Profiles = append(endpoint.Spec.Profiles, networkData.Name) - // Check if the profile already exists. - exists := true - if _, err = d.client.Profiles().Get(api.ProfileMetadata{Name: networkData.Name}); err != nil { - _, ok := err.(libcalicoErrors.ErrorResourceDoesNotExist) - if ok { - exists = false - } else { - err = errors.Wrapf(err, "Profile %v getting error", networkData.Name) - d.logger.Println(err) - return nil, err - } - } - // If a profile for the network name doesn't exist then it needs to be created. - if !exists { - profile := api.NewProfile() - profile.Metadata.Name = networkData.Name - profile.Spec.Tags = []string{networkData.Name} - profile.Spec.EgressRules = []api.Rule{{Action: "allow"}} - profile.Spec.IngressRules = []api.Rule{{Action: "allow", Source: api.EntityRule{Tag: networkData.Name}}} - if _, err := d.client.Profiles().Create(profile); err != nil { + // We always attempt to create the profile and rely on the datastore to reject + // the request if the profile already exists. + profile := api.Profile{ + Metadata: api.ProfileMetadata{Name: networkData.Name}, + Spec: api.ProfileSpec{ + Tags: []string{networkData.Name}, + EgressRules: []api.Rule{{Action: "allow"}}, + IngressRules: []api.Rule{{Action: "allow", Source: api.EntityRule{Tag: networkData.Name}}}, + }, + } + if _, err := d.client.Profiles().Create(profile); err != nil { + if _, ok := err.(libcalicoErrors.ErrorResourceAlreadyExists); !ok { log.Println(err) return nil, err } } + // Create the endpoint _, err = d.client.WorkloadEndpoints().Create(endpoint) if err != nil { err = errors.Wrapf(err, "Workload endpoints creation error, data: %+v", endpoint) From 4b138f0989ee095add5d681be1ec37c00badad11 Mon Sep 17 00:00:00 2001 From: Rob Brockbank Date: Tue, 1 Nov 2016 16:11:48 +0000 Subject: [PATCH 2/2] Profile should be pointer --- driver/network_driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver/network_driver.go b/driver/network_driver.go index 0a0b0a3..2ef2552 100644 --- a/driver/network_driver.go +++ b/driver/network_driver.go @@ -142,7 +142,7 @@ func (d NetworkDriver) CreateEndpoint(request *network.CreateEndpointRequest) (* // If a profile for the network name doesn't exist then it needs to be created. // We always attempt to create the profile and rely on the datastore to reject // the request if the profile already exists. - profile := api.Profile{ + profile := &api.Profile{ Metadata: api.ProfileMetadata{Name: networkData.Name}, Spec: api.ProfileSpec{ Tags: []string{networkData.Name},