Browse code

Merge pull request #35422 from pradipd/lbfix

Move load balancer sandbox creation/deletion into libnetwork

Madhu Venugopal authored on 2017/12/02 07:08:48
Showing 6 changed files
... ...
@@ -3,6 +3,7 @@ package daemon
3 3
 import (
4 4
 	"fmt"
5 5
 	"net"
6
+	"runtime"
6 7
 	"sort"
7 8
 	"strings"
8 9
 	"sync"
... ...
@@ -183,21 +184,14 @@ func (daemon *Daemon) setupIngress(create *clustertypes.NetworkCreateRequest, ip
183 183
 		// Otherwise continue down the call to create or recreate sandbox.
184 184
 	}
185 185
 
186
-	n, err := daemon.GetNetworkByID(create.ID)
186
+	_, err := daemon.GetNetworkByID(create.ID)
187 187
 	if err != nil {
188 188
 		logrus.Errorf("Failed getting ingress network by id after creating: %v", err)
189 189
 	}
190
-
191
-	if err = daemon.createLoadBalancerSandbox("ingress", create.ID, ip, n, libnetwork.OptionIngress()); err != nil {
192
-		logrus.Errorf("Failed creating load balancer sandbox for ingress network: %v", err)
193
-	}
194 190
 }
195 191
 
196 192
 func (daemon *Daemon) releaseIngress(id string) {
197 193
 	controller := daemon.netController
198
-	if err := controller.SandboxDestroy("ingress-sbox"); err != nil {
199
-		logrus.Errorf("Failed to delete ingress sandbox: %v", err)
200
-	}
201 194
 
202 195
 	if id == "" {
203 196
 		return
... ...
@@ -209,13 +203,6 @@ func (daemon *Daemon) releaseIngress(id string) {
209 209
 		return
210 210
 	}
211 211
 
212
-	for _, ep := range n.Endpoints() {
213
-		if err := ep.Delete(true); err != nil {
214
-			logrus.Errorf("Failed to delete endpoint %s (%s): %v", ep.Name(), ep.ID(), err)
215
-			return
216
-		}
217
-	}
218
-
219 212
 	if err := n.Delete(); err != nil {
220 213
 		logrus.Errorf("Failed to delete ingress network %s: %v", n.ID(), err)
221 214
 		return
... ...
@@ -270,34 +257,6 @@ func (daemon *Daemon) CreateNetwork(create types.NetworkCreateRequest) (*types.N
270 270
 	return resp, err
271 271
 }
272 272
 
273
-func (daemon *Daemon) createLoadBalancerSandbox(prefix, id string, ip net.IP, n libnetwork.Network, options ...libnetwork.SandboxOption) error {
274
-	c := daemon.netController
275
-	sandboxName := prefix + "-sbox"
276
-	sb, err := c.NewSandbox(sandboxName, options...)
277
-	if err != nil {
278
-		if _, ok := err.(networktypes.ForbiddenError); !ok {
279
-			return errors.Wrapf(err, "Failed creating %s sandbox", sandboxName)
280
-		}
281
-		return nil
282
-	}
283
-
284
-	endpointName := prefix + "-endpoint"
285
-	ep, err := n.CreateEndpoint(endpointName, libnetwork.CreateOptionIpam(ip, nil, nil, nil), libnetwork.CreateOptionLoadBalancer())
286
-	if err != nil {
287
-		return errors.Wrapf(err, "Failed creating %s in sandbox %s", endpointName, sandboxName)
288
-	}
289
-
290
-	if err := ep.Join(sb, nil); err != nil {
291
-		return errors.Wrapf(err, "Failed joining %s to sandbox %s", endpointName, sandboxName)
292
-	}
293
-
294
-	if err := sb.EnableService(); err != nil {
295
-		return errors.Wrapf(err, "Failed enabling service in %s sandbox", sandboxName)
296
-	}
297
-
298
-	return nil
299
-}
300
-
301 273
 func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string, agent bool) (*types.NetworkCreateResponse, error) {
302 274
 	if runconfig.IsPreDefinedNetwork(create.Name) && !agent {
303 275
 		err := fmt.Errorf("%s is a pre-defined network and cannot be created", create.Name)
... ...
@@ -360,6 +319,15 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string
360 360
 		nwOptions = append(nwOptions, libnetwork.NetworkOptionConfigFrom(create.ConfigFrom.Network))
361 361
 	}
362 362
 
363
+	if agent && driver == "overlay" && (create.Ingress || runtime.GOOS == "windows") {
364
+		nodeIP, exists := daemon.GetAttachmentStore().GetIPForNetwork(id)
365
+		if !exists {
366
+			return nil, fmt.Errorf("Failed to find a load balancer IP to use for network: %v", id)
367
+		}
368
+
369
+		nwOptions = append(nwOptions, libnetwork.NetworkOptionLBEndpoint(nodeIP))
370
+	}
371
+
363 372
 	n, err := c.NewNetwork(driver, create.Name, id, nwOptions...)
364 373
 	if err != nil {
365 374
 		if _, ok := err.(libnetwork.ErrDataStoreNotInitialized); ok {
... ...
@@ -375,18 +343,6 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string
375 375
 	}
376 376
 	daemon.LogNetworkEvent(n, "create")
377 377
 
378
-	if agent && !n.Info().Ingress() && n.Type() == "overlay" {
379
-		nodeIP, exists := daemon.GetAttachmentStore().GetIPForNetwork(id)
380
-		if !exists {
381
-			return nil, fmt.Errorf("Failed to find a load balancer IP to use for network: %v", id)
382
-		}
383
-
384
-		if err := daemon.createLoadBalancerSandbox(create.Name, id, nodeIP, n); err != nil {
385
-			return nil, err
386
-		}
387
-
388
-	}
389
-
390 378
 	return &types.NetworkCreateResponse{
391 379
 		ID:      n.ID(),
392 380
 		Warning: warning,
... ...
@@ -517,43 +473,16 @@ func (daemon *Daemon) DeleteNetwork(networkID string) error {
517 517
 	return daemon.deleteNetwork(networkID, false)
518 518
 }
519 519
 
520
-func (daemon *Daemon) deleteLoadBalancerSandbox(n libnetwork.Network) {
521
-	controller := daemon.netController
522
-
523
-	//The only endpoint left should be the LB endpoint (nw.Name() + "-endpoint")
524
-	endpoints := n.Endpoints()
525
-	if len(endpoints) == 1 {
526
-		sandboxName := n.Name() + "-sbox"
527
-
528
-		info := endpoints[0].Info()
529
-		if info != nil {
530
-			sb := info.Sandbox()
531
-			if sb != nil {
532
-				if err := sb.DisableService(); err != nil {
533
-					logrus.Warnf("Failed to disable service on sandbox %s: %v", sandboxName, err)
534
-					//Ignore error and attempt to delete the load balancer endpoint
535
-				}
536
-			}
537
-		}
538
-
539
-		if err := endpoints[0].Delete(true); err != nil {
540
-			logrus.Warnf("Failed to delete endpoint %s (%s) in %s: %v", endpoints[0].Name(), endpoints[0].ID(), sandboxName, err)
541
-			//Ignore error and attempt to delete the sandbox.
542
-		}
543
-
544
-		if err := controller.SandboxDestroy(sandboxName); err != nil {
545
-			logrus.Warnf("Failed to delete %s sandbox: %v", sandboxName, err)
546
-			//Ignore error and attempt to delete the network.
547
-		}
548
-	}
549
-}
550
-
551 520
 func (daemon *Daemon) deleteNetwork(networkID string, dynamic bool) error {
552 521
 	nw, err := daemon.FindNetwork(networkID)
553 522
 	if err != nil {
554 523
 		return err
555 524
 	}
556 525
 
526
+	if nw.Info().Ingress() {
527
+		return nil
528
+	}
529
+
557 530
 	if runconfig.IsPreDefinedNetwork(nw.Name()) && !dynamic {
558 531
 		err := fmt.Errorf("%s is a pre-defined network and cannot be removed", nw.Name())
559 532
 		return notAllowedError{err}
... ...
@@ -569,10 +498,6 @@ func (daemon *Daemon) deleteNetwork(networkID string, dynamic bool) error {
569 569
 		return notAllowedError{err}
570 570
 	}
571 571
 
572
-	if !nw.Info().Ingress() && nw.Type() == "overlay" {
573
-		daemon.deleteLoadBalancerSandbox(nw)
574
-	}
575
-
576 572
 	if err := nw.Delete(); err != nil {
577 573
 		return err
578 574
 	}
... ...
@@ -11,12 +11,11 @@ import (
11 11
 	"github.com/docker/docker/client"
12 12
 	"github.com/docker/docker/integration-cli/request"
13 13
 	"github.com/gotestyourself/gotestyourself/poll"
14
-	"github.com/stretchr/testify/assert"
15 14
 	"github.com/stretchr/testify/require"
16 15
 	"golang.org/x/net/context"
17 16
 )
18 17
 
19
-func TestCreateWithLBSandbox(t *testing.T) {
18
+func TestCreateServiceMultipleTimes(t *testing.T) {
20 19
 	defer setupTest(t)()
21 20
 	d := newSwarm(t)
22 21
 	defer d.Stop(t)
... ...
@@ -33,9 +32,8 @@ func TestCreateWithLBSandbox(t *testing.T) {
33 33
 	require.NoError(t, err)
34 34
 	overlayID := netResp.ID
35 35
 
36
-	var instances uint64 = 1
36
+	var instances uint64 = 4
37 37
 	serviceSpec := swarmServiceSpec("TestService", instances)
38
-
39 38
 	serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarm.NetworkAttachmentConfig{Target: overlayName})
40 39
 
41 40
 	serviceResp, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{
... ...
@@ -56,14 +54,26 @@ func TestCreateWithLBSandbox(t *testing.T) {
56 56
 	_, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
57 57
 	require.NoError(t, err)
58 58
 
59
-	network, err := client.NetworkInspect(context.Background(), overlayID, types.NetworkInspectOptions{})
60
-	require.NoError(t, err)
61
-	assert.Contains(t, network.Containers, overlayName+"-sbox")
62
-
63 59
 	err = client.ServiceRemove(context.Background(), serviceID)
64 60
 	require.NoError(t, err)
65 61
 
66 62
 	poll.WaitOn(t, serviceIsRemoved(client, serviceID), pollSettings)
63
+	poll.WaitOn(t, noTasks(client), pollSettings)
64
+
65
+	serviceResp, err = client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{
66
+		QueryRegistry: false,
67
+	})
68
+	require.NoError(t, err)
69
+
70
+	serviceID2 := serviceResp.ID
71
+	poll.WaitOn(t, serviceRunningTasksCount(client, serviceID2, instances), pollSettings)
72
+
73
+	err = client.ServiceRemove(context.Background(), serviceID2)
74
+	require.NoError(t, err)
75
+
76
+	poll.WaitOn(t, serviceIsRemoved(client, serviceID2), pollSettings)
77
+	poll.WaitOn(t, noTasks(client), pollSettings)
78
+
67 79
 	err = client.NetworkRemove(context.Background(), overlayID)
68 80
 	require.NoError(t, err)
69 81
 
... ...
@@ -112,6 +122,23 @@ func serviceRunningTasksCount(client client.ServiceAPIClient, serviceID string,
112 112
 	}
113 113
 }
114 114
 
115
+func noTasks(client client.ServiceAPIClient) func(log poll.LogT) poll.Result {
116
+	return func(log poll.LogT) poll.Result {
117
+		filter := filters.NewArgs()
118
+		tasks, err := client.TaskList(context.Background(), types.TaskListOptions{
119
+			Filters: filter,
120
+		})
121
+		switch {
122
+		case err != nil:
123
+			return poll.Error(err)
124
+		case len(tasks) == 0:
125
+			return poll.Success()
126
+		default:
127
+			return poll.Continue("task count at %d waiting for 0", len(tasks))
128
+		}
129
+	}
130
+}
131
+
115 132
 func serviceIsRemoved(client client.ServiceAPIClient, serviceID string) func(log poll.LogT) poll.Result {
116 133
 	return func(log poll.LogT) poll.Result {
117 134
 		filter := filters.NewArgs()
... ...
@@ -30,7 +30,7 @@ github.com/moby/buildkit aaff9d591ef128560018433fe61beb802e149de8
30 30
 github.com/tonistiigi/fsutil dea3a0da73aee887fc02142d995be764106ac5e2
31 31
 
32 32
 #get libnetwork packages
33
-github.com/docker/libnetwork f7d21337cf1eb628ad54eecac0881fa23ec266df
33
+github.com/docker/libnetwork 64ae58878fc8f95e4a167499d654e13fa36abdc7
34 34
 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
35 35
 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
36 36
 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
... ...
@@ -837,11 +837,34 @@ addToStore:
837 837
 	if err = c.updateToStore(network); err != nil {
838 838
 		return nil, err
839 839
 	}
840
+	defer func() {
841
+		if err != nil {
842
+			if e := c.deleteFromStore(network); e != nil {
843
+				logrus.Warnf("could not rollback from store, network %v on failure (%v): %v", network, err, e)
844
+			}
845
+		}
846
+	}()
847
+
840 848
 	if network.configOnly {
841 849
 		return network, nil
842 850
 	}
843 851
 
844 852
 	joinCluster(network)
853
+	defer func() {
854
+		if err != nil {
855
+			network.cancelDriverWatches()
856
+			if e := network.leaveCluster(); e != nil {
857
+				logrus.Warnf("Failed to leave agent cluster on network %s on failure (%v): %v", network.name, err, e)
858
+			}
859
+		}
860
+	}()
861
+
862
+	if len(network.loadBalancerIP) != 0 {
863
+		if err = network.createLoadBalancerSandbox(); err != nil {
864
+			return nil, err
865
+		}
866
+	}
867
+
845 868
 	if !c.isDistributedControl() {
846 869
 		c.Lock()
847 870
 		arrangeIngressFilterRule()
... ...
@@ -199,39 +199,40 @@ func (i *IpamInfo) UnmarshalJSON(data []byte) error {
199 199
 }
200 200
 
201 201
 type network struct {
202
-	ctrlr        *controller
203
-	name         string
204
-	networkType  string
205
-	id           string
206
-	created      time.Time
207
-	scope        string // network data scope
208
-	labels       map[string]string
209
-	ipamType     string
210
-	ipamOptions  map[string]string
211
-	addrSpace    string
212
-	ipamV4Config []*IpamConf
213
-	ipamV6Config []*IpamConf
214
-	ipamV4Info   []*IpamInfo
215
-	ipamV6Info   []*IpamInfo
216
-	enableIPv6   bool
217
-	postIPv6     bool
218
-	epCnt        *endpointCnt
219
-	generic      options.Generic
220
-	dbIndex      uint64
221
-	dbExists     bool
222
-	persist      bool
223
-	stopWatchCh  chan struct{}
224
-	drvOnce      *sync.Once
225
-	resolverOnce sync.Once
226
-	resolver     []Resolver
227
-	internal     bool
228
-	attachable   bool
229
-	inDelete     bool
230
-	ingress      bool
231
-	driverTables []networkDBTable
232
-	dynamic      bool
233
-	configOnly   bool
234
-	configFrom   string
202
+	ctrlr          *controller
203
+	name           string
204
+	networkType    string
205
+	id             string
206
+	created        time.Time
207
+	scope          string // network data scope
208
+	labels         map[string]string
209
+	ipamType       string
210
+	ipamOptions    map[string]string
211
+	addrSpace      string
212
+	ipamV4Config   []*IpamConf
213
+	ipamV6Config   []*IpamConf
214
+	ipamV4Info     []*IpamInfo
215
+	ipamV6Info     []*IpamInfo
216
+	enableIPv6     bool
217
+	postIPv6       bool
218
+	epCnt          *endpointCnt
219
+	generic        options.Generic
220
+	dbIndex        uint64
221
+	dbExists       bool
222
+	persist        bool
223
+	stopWatchCh    chan struct{}
224
+	drvOnce        *sync.Once
225
+	resolverOnce   sync.Once
226
+	resolver       []Resolver
227
+	internal       bool
228
+	attachable     bool
229
+	inDelete       bool
230
+	ingress        bool
231
+	driverTables   []networkDBTable
232
+	dynamic        bool
233
+	configOnly     bool
234
+	configFrom     string
235
+	loadBalancerIP net.IP
235 236
 	sync.Mutex
236 237
 }
237 238
 
... ...
@@ -473,6 +474,7 @@ func (n *network) CopyTo(o datastore.KVObject) error {
473 473
 	dstN.ingress = n.ingress
474 474
 	dstN.configOnly = n.configOnly
475 475
 	dstN.configFrom = n.configFrom
476
+	dstN.loadBalancerIP = n.loadBalancerIP
476 477
 
477 478
 	// copy labels
478 479
 	if dstN.labels == nil {
... ...
@@ -589,6 +591,7 @@ func (n *network) MarshalJSON() ([]byte, error) {
589 589
 	netMap["ingress"] = n.ingress
590 590
 	netMap["configOnly"] = n.configOnly
591 591
 	netMap["configFrom"] = n.configFrom
592
+	netMap["loadBalancerIP"] = n.loadBalancerIP
592 593
 	return json.Marshal(netMap)
593 594
 }
594 595
 
... ...
@@ -699,6 +702,9 @@ func (n *network) UnmarshalJSON(b []byte) (err error) {
699 699
 	if v, ok := netMap["configFrom"]; ok {
700 700
 		n.configFrom = v.(string)
701 701
 	}
702
+	if v, ok := netMap["loadBalancerIP"]; ok {
703
+		n.loadBalancerIP = net.ParseIP(v.(string))
704
+	}
702 705
 	// Reconcile old networks with the recently added `--ipv6` flag
703 706
 	if !n.enableIPv6 {
704 707
 		n.enableIPv6 = len(n.ipamV6Info) > 0
... ...
@@ -799,6 +805,13 @@ func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ip
799 799
 	}
800 800
 }
801 801
 
802
+// NetworkOptionLBEndpoint function returns an option setter for the configuration of the load balancer endpoint for this network
803
+func NetworkOptionLBEndpoint(ip net.IP) NetworkOption {
804
+	return func(n *network) {
805
+		n.loadBalancerIP = ip
806
+	}
807
+}
808
+
802 809
 // NetworkOptionDriverOpts function returns an option setter for any driver parameter described by a map
803 810
 func NetworkOptionDriverOpts(opts map[string]string) NetworkOption {
804 811
 	return func(n *network) {
... ...
@@ -944,6 +957,18 @@ func (n *network) delete(force bool) error {
944 944
 		return &UnknownNetworkError{name: name, id: id}
945 945
 	}
946 946
 
947
+	if len(n.loadBalancerIP) != 0 {
948
+		endpoints := n.Endpoints()
949
+		if force || len(endpoints) == 1 {
950
+			n.deleteLoadBalancerSandbox()
951
+		}
952
+		//Reload the network from the store to update the epcnt.
953
+		n, err = c.getNetworkFromStore(id)
954
+		if err != nil {
955
+			return &UnknownNetworkError{name: name, id: id}
956
+		}
957
+	}
958
+
947 959
 	if !force && n.getEpCnt().EndpointCnt() != 0 {
948 960
 		if n.configOnly {
949 961
 			return types.ForbiddenErrorf("configuration network %q is in use", n.Name())
... ...
@@ -1071,12 +1096,19 @@ func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoi
1071 1071
 		return nil, types.ForbiddenErrorf("endpoint with name %s already exists in network %s", name, n.Name())
1072 1072
 	}
1073 1073
 
1074
-	ep := &endpoint{name: name, generic: make(map[string]interface{}), iface: &endpointInterface{}}
1075
-	ep.id = stringid.GenerateRandomID()
1076
-
1077 1074
 	n.ctrlr.networkLocker.Lock(n.id)
1078 1075
 	defer n.ctrlr.networkLocker.Unlock(n.id)
1079 1076
 
1077
+	return n.createEndpoint(name, options...)
1078
+
1079
+}
1080
+
1081
+func (n *network) createEndpoint(name string, options ...EndpointOption) (Endpoint, error) {
1082
+	var err error
1083
+
1084
+	ep := &endpoint{name: name, generic: make(map[string]interface{}), iface: &endpointInterface{}}
1085
+	ep.id = stringid.GenerateRandomID()
1086
+
1080 1087
 	// Initialize ep.network with a possibly stale copy of n. We need this to get network from
1081 1088
 	// store. But once we get it from store we will have the most uptodate copy possibly.
1082 1089
 	ep.network = n
... ...
@@ -2021,3 +2053,80 @@ func (c *controller) getConfigNetwork(name string) (*network, error) {
2021 2021
 
2022 2022
 	return n.(*network), nil
2023 2023
 }
2024
+
2025
+func (n *network) createLoadBalancerSandbox() error {
2026
+	sandboxName := n.name + "-sbox"
2027
+	sbOptions := []SandboxOption{}
2028
+	if n.ingress {
2029
+		sbOptions = append(sbOptions, OptionIngress())
2030
+	}
2031
+	sb, err := n.ctrlr.NewSandbox(sandboxName, sbOptions...)
2032
+	if err != nil {
2033
+		return err
2034
+	}
2035
+	defer func() {
2036
+		if err != nil {
2037
+			if e := n.ctrlr.SandboxDestroy(sandboxName); e != nil {
2038
+				logrus.Warnf("could not delete sandbox %s on failure on failure (%v): %v", sandboxName, err, e)
2039
+			}
2040
+		}
2041
+	}()
2042
+
2043
+	endpointName := n.name + "-endpoint"
2044
+	epOptions := []EndpointOption{
2045
+		CreateOptionIpam(n.loadBalancerIP, nil, nil, nil),
2046
+		CreateOptionLoadBalancer(),
2047
+	}
2048
+	ep, err := n.createEndpoint(endpointName, epOptions...)
2049
+	if err != nil {
2050
+		return err
2051
+	}
2052
+	defer func() {
2053
+		if err != nil {
2054
+			if e := ep.Delete(true); e != nil {
2055
+				logrus.Warnf("could not delete endpoint %s on failure on failure (%v): %v", endpointName, err, e)
2056
+			}
2057
+		}
2058
+	}()
2059
+
2060
+	if err := ep.Join(sb, nil); err != nil {
2061
+		return err
2062
+	}
2063
+	return sb.EnableService()
2064
+}
2065
+
2066
+func (n *network) deleteLoadBalancerSandbox() {
2067
+	n.Lock()
2068
+	c := n.ctrlr
2069
+	name := n.name
2070
+	n.Unlock()
2071
+
2072
+	endpointName := name + "-endpoint"
2073
+	sandboxName := name + "-sbox"
2074
+
2075
+	endpoint, err := n.EndpointByName(endpointName)
2076
+	if err != nil {
2077
+		logrus.Warnf("Failed to find load balancer endpoint %s on network %s: %v", endpointName, name, err)
2078
+	} else {
2079
+
2080
+		info := endpoint.Info()
2081
+		if info != nil {
2082
+			sb := info.Sandbox()
2083
+			if sb != nil {
2084
+				if err := sb.DisableService(); err != nil {
2085
+					logrus.Warnf("Failed to disable service on sandbox %s: %v", sandboxName, err)
2086
+					//Ignore error and attempt to delete the load balancer endpoint
2087
+				}
2088
+			}
2089
+		}
2090
+
2091
+		if err := endpoint.Delete(true); err != nil {
2092
+			logrus.Warnf("Failed to delete endpoint %s (%s) in %s: %v", endpoint.Name(), endpoint.ID(), sandboxName, err)
2093
+			//Ignore error and attempt to delete the sandbox.
2094
+		}
2095
+	}
2096
+
2097
+	if err := c.SandboxDestroy(sandboxName); err != nil {
2098
+		logrus.Warnf("Failed to delete %s sandbox: %v", sandboxName, err)
2099
+	}
2100
+}
... ...
@@ -256,7 +256,7 @@ retry:
256 256
 			if err := cs.GetObject(datastore.Key(kvObject.Key()...), kvObject); err != nil {
257 257
 				return fmt.Errorf("could not update the kvobject to latest when trying to delete: %v", err)
258 258
 			}
259
-			logrus.Errorf("Error (%v) deleting object %v, retrying....", err, kvObject.Key())
259
+			logrus.Warnf("Error (%v) deleting object %v, retrying....", err, kvObject.Key())
260 260
 			goto retry
261 261
 		}
262 262
 		return err