@@ -26,10 +26,12 @@ import (
26
26
"io/ioutil"
27
27
"strings"
28
28
"text/template"
29
+ "time"
29
30
30
31
"github.com/docker/machine/libmachine/log"
31
32
libvirt "github.com/libvirt/libvirt-go"
32
33
"github.com/pkg/errors"
34
+ "k8s.io/minikube/pkg/util/retry"
33
35
)
34
36
35
37
// Replace with hardcoded range with CIDR
@@ -53,6 +55,7 @@ func setupNetwork(conn *libvirt.Connect, name string) error {
53
55
if err != nil {
54
56
return errors .Wrapf (err , "checking network %s" , name )
55
57
}
58
+ defer func () { _ = n .Free () }()
56
59
57
60
// always ensure autostart is set on the network
58
61
autostart , err := n .GetAutostart ()
@@ -75,7 +78,6 @@ func setupNetwork(conn *libvirt.Connect, name string) error {
75
78
return errors .Wrapf (err , "starting network %s" , name )
76
79
}
77
80
}
78
-
79
81
return nil
80
82
}
81
83
@@ -99,8 +101,21 @@ func (d *Driver) ensureNetwork() error {
99
101
100
102
// Start the private network
101
103
log .Infof ("Ensuring network %s is active" , d .PrivateNetwork )
104
+ // retry once to recreate the network, but only if is not used by another minikube instance
102
105
if err := setupNetwork (conn , d .PrivateNetwork ); err != nil {
103
- return err
106
+ log .Debugf ("Network %s is inoperable, will try to recreate it: %v" , d .PrivateNetwork , err )
107
+ if err := d .deleteNetwork (); err != nil {
108
+ return errors .Wrapf (err , "deleting inoperable network %s" , d .PrivateNetwork )
109
+ }
110
+ log .Debugf ("Successfully deleted %s network" , d .PrivateNetwork )
111
+ if err := d .createNetwork (); err != nil {
112
+ return errors .Wrapf (err , "recreating inoperable network %s" , d .PrivateNetwork )
113
+ }
114
+ log .Debugf ("Successfully recreated %s network" , d .PrivateNetwork )
115
+ if err := setupNetwork (conn , d .PrivateNetwork ); err != nil {
116
+ return err
117
+ }
118
+ log .Debugf ("Successfully activated %s network" , d .PrivateNetwork )
104
119
}
105
120
106
121
return nil
@@ -120,13 +135,16 @@ func (d *Driver) createNetwork() error {
120
135
121
136
// network: default
122
137
// It is assumed that the libvirt/kvm installation has already created this network
123
- if _ , err := conn .LookupNetworkByName (d .Network ); err != nil {
138
+ netd , err := conn .LookupNetworkByName (d .Network )
139
+ if err != nil {
124
140
return errors .Wrapf (err , "network %s doesn't exist" , d .Network )
125
141
}
142
+ defer func () { _ = netd .Free () }()
126
143
127
144
// network: private
128
145
// Only create the private network if it does not already exist
129
- if _ , err := conn .LookupNetworkByName (d .PrivateNetwork ); err != nil {
146
+ netp , err := conn .LookupNetworkByName (d .PrivateNetwork )
147
+ if err != nil {
130
148
// create the XML for the private network from our networkTmpl
131
149
tmpl := template .Must (template .New ("network" ).Parse (networkTmpl ))
132
150
var networkXML bytes.Buffer
@@ -141,10 +159,26 @@ func (d *Driver) createNetwork() error {
141
159
}
142
160
143
161
// and finally create it
144
- if err := network .Create (); err != nil {
162
+ log .Debugf ("Trying to create network %s..." , d .PrivateNetwork )
163
+ create := func () error {
164
+ if err := network .Create (); err != nil {
165
+ return err
166
+ }
167
+ active , err := network .IsActive ()
168
+ if err == nil && active {
169
+ return nil
170
+ }
171
+ return errors .Errorf ("retrying %v" , err )
172
+ }
173
+ if err := retry .Local (create , 10 * time .Second ); err != nil {
145
174
return errors .Wrapf (err , "creating network %s" , d .PrivateNetwork )
146
175
}
147
176
}
177
+ defer func () {
178
+ if netp != nil {
179
+ _ = netp .Free ()
180
+ }
181
+ }()
148
182
149
183
return nil
150
184
}
@@ -163,13 +197,13 @@ func (d *Driver) deleteNetwork() error {
163
197
log .Debugf ("Checking if network %s exists..." , d .PrivateNetwork )
164
198
network , err := conn .LookupNetworkByName (d .PrivateNetwork )
165
199
if err != nil {
166
- if libvirtErr , ok := err .(libvirt. Error ); ok && libvirtErr .Code == libvirt .ERR_NO_NETWORK {
200
+ if lvErr ( err ) .Code == libvirt .ERR_NO_NETWORK {
167
201
log .Warnf ("Network %s does not exist. Skipping deletion" , d .PrivateNetwork )
168
202
return nil
169
203
}
170
-
171
204
return errors .Wrapf (err , "failed looking for network %s" , d .PrivateNetwork )
172
205
}
206
+ defer func () { _ = network .Free () }()
173
207
log .Debugf ("Network %s exists" , d .PrivateNetwork )
174
208
175
209
err = d .checkDomains (conn )
@@ -178,15 +212,58 @@ func (d *Driver) deleteNetwork() error {
178
212
}
179
213
180
214
// when we reach this point, it means it is safe to delete the network
215
+
216
+ // cannot destroy an inactive network - try to activate it first
217
+ log .Debugf ("Trying to reactivate network %s first (if needed)..." , d .PrivateNetwork )
218
+ activate := func () error {
219
+ active , err := network .IsActive ()
220
+ if err == nil && active {
221
+ return nil
222
+ }
223
+ if err != nil {
224
+ return err
225
+ }
226
+ // inactive, try to activate
227
+ if err := network .Create (); err != nil {
228
+ return err
229
+ }
230
+ return errors .Errorf ("needs confirmation" ) // confirm in the next cycle
231
+ }
232
+ if err := retry .Local (activate , 10 * time .Second ); err != nil {
233
+ log .Debugf ("Reactivating network %s failed, will continue anyway..." , d .PrivateNetwork )
234
+ }
235
+
181
236
log .Debugf ("Trying to destroy network %s..." , d .PrivateNetwork )
182
- err = network .Destroy ()
183
- if err != nil {
184
- return errors .Wrap (err , "network destroy" )
237
+ destroy := func () error {
238
+ if err := network .Destroy (); err != nil {
239
+ return err
240
+ }
241
+ active , err := network .IsActive ()
242
+ if err == nil && ! active {
243
+ return nil
244
+ }
245
+ return errors .Errorf ("retrying %v" , err )
185
246
}
247
+ if err := retry .Local (destroy , 10 * time .Second ); err != nil {
248
+ return errors .Wrap (err , "destroying network" )
249
+ }
250
+
186
251
log .Debugf ("Trying to undefine network %s..." , d .PrivateNetwork )
187
- err = network .Undefine ()
188
- if err != nil {
189
- return errors .Wrap (err , "network undefine" )
252
+ undefine := func () error {
253
+ if err := network .Undefine (); err != nil {
254
+ return err
255
+ }
256
+ netp , err := conn .LookupNetworkByName (d .PrivateNetwork )
257
+ if netp != nil {
258
+ _ = netp .Free ()
259
+ }
260
+ if lvErr (err ).Code == libvirt .ERR_NO_NETWORK {
261
+ return nil
262
+ }
263
+ return errors .Errorf ("retrying %v" , err )
264
+ }
265
+ if err := retry .Local (undefine , 10 * time .Second ); err != nil {
266
+ return errors .Wrap (err , "undefining network" )
190
267
}
191
268
192
269
return nil
@@ -272,7 +349,6 @@ func (d *Driver) lookupIP() (string, error) {
272
349
if err != nil {
273
350
return "" , errors .Wrap (err , "getting connection and domain" )
274
351
}
275
-
276
352
defer conn .Close ()
277
353
278
354
libVersion , err := conn .GetLibVersion ()
@@ -294,6 +370,7 @@ func (d *Driver) lookupIPFromStatusFile(conn *libvirt.Connect) (string, error) {
294
370
if err != nil {
295
371
return "" , errors .Wrap (err , "looking up network by name" )
296
372
}
373
+ defer func () { _ = network .Free () }()
297
374
298
375
bridge , err := network .GetBridgeName ()
299
376
if err != nil {
0 commit comments