@@ -185,41 +185,91 @@ type BondParameters struct {
185
185
Primary string `yaml:"primary,omitempty"`
186
186
}
187
187
188
- // BridgeDeviceById takes a deviceId and creates a bridge with this device
188
+ // BridgeEthernetById takes a deviceId and creates a bridge with this device
189
189
// using this devices config
190
190
func (np * Netplan ) BridgeEthernetById (deviceId string , bridgeName string ) (err error ) {
191
191
ethernet , ok := np .Network .Ethernets [deviceId ]
192
192
if ! ok {
193
- return errors .NotFoundf ("Device with id %q for bridge %q" , deviceId , bridgeName )
193
+ return errors .NotFoundf ("ethernet device with id %q for bridge %q" , deviceId , bridgeName )
194
194
}
195
+ shouldCreate , err := np .shouldCreateBridge (deviceId , bridgeName )
196
+ if ! shouldCreate {
197
+ // err may be nil, but we shouldn't continue creating
198
+ return errors .Trace (err )
199
+ }
200
+ np .createBridgeFromInterface (bridgeName , deviceId , & ethernet .Interface )
201
+ np .Network .Ethernets [deviceId ] = ethernet
202
+ return nil
203
+ }
204
+
205
+ // BridgeVLANById takes a deviceId and creates a bridge with this device
206
+ // using this devices config
207
+ func (np * Netplan ) BridgeVLANById (deviceId string , bridgeName string ) (err error ) {
208
+ vlan , ok := np .Network .VLANs [deviceId ]
209
+ if ! ok {
210
+ return errors .NotFoundf ("VLAN device with id %q for bridge %q" , deviceId , bridgeName )
211
+ }
212
+ shouldCreate , err := np .shouldCreateBridge (deviceId , bridgeName )
213
+ if ! shouldCreate {
214
+ // err may be nil, but we shouldn't continue creating
215
+ return errors .Trace (err )
216
+ }
217
+ np .createBridgeFromInterface (bridgeName , deviceId , & vlan .Interface )
218
+ np .Network .VLANs [deviceId ] = vlan
219
+ return nil
220
+ }
221
+
222
+ // BridgeBondById takes a deviceId and creates a bridge with this device
223
+ // using this devices config
224
+ func (np * Netplan ) BridgeBondById (deviceId string , bridgeName string ) (err error ) {
225
+ bond , ok := np .Network .Bonds [deviceId ]
226
+ if ! ok {
227
+ return errors .NotFoundf ("bond device with id %q for bridge %q" , deviceId , bridgeName )
228
+ }
229
+ shouldCreate , err := np .shouldCreateBridge (deviceId , bridgeName )
230
+ if ! shouldCreate {
231
+ // err may be nil, but we shouldn't continue creating
232
+ return errors .Trace (err )
233
+ }
234
+ np .createBridgeFromInterface (bridgeName , deviceId , & bond .Interface )
235
+ np .Network .Bonds [deviceId ] = bond
236
+ return nil
237
+ }
238
+
239
+ // shouldCreateBridge returns true only if it is clear the bridge doesn't already exist, and that the existing device
240
+ // isn't in a different bridge.
241
+ func (np * Netplan ) shouldCreateBridge (deviceId string , bridgeName string ) (bool , error ) {
195
242
for bName , bridge := range np .Network .Bridges {
196
243
for _ , i := range bridge .Interfaces {
197
244
if i == deviceId {
198
- // The device is already properly bridged, we're not doing anything
245
+ // The device is already properly bridged, nothing to do
199
246
if bridgeName == bName {
200
- return nil
247
+ return false , nil
201
248
} else {
202
- return errors .AlreadyExistsf ("Device %q is already bridged in bridge %q instead of %q " , deviceId , bName , bridgeName )
249
+ return false , errors .AlreadyExistsf ("cannot create bridge %q, device %q in bridge %q" , bridgeName , deviceId , bName )
203
250
}
204
251
}
205
252
}
206
253
if bridgeName == bName {
207
- return errors .AlreadyExistsf ("Cannot bridge device %q on bridge %q - bridge named %q" , deviceId , bridgeName , bridgeName )
254
+ return false , errors .AlreadyExistsf (
255
+ "cannot create bridge %q with device %q - bridge %q w/ interfaces %q" ,
256
+ bridgeName , deviceId , bridgeName , strings .Join (bridge .Interfaces , ", " ))
208
257
}
209
258
}
210
- // copy aside and clear the IP settings from the original Ethernet device, except for MTU
211
- intf := ethernet .Interface
212
- ethernet .Interface = Interface {MTU : intf .MTU }
213
- // create a bridge
259
+ return true , nil
260
+ }
261
+
262
+ // createBridgeFromInterface will create a bridge stealing the interface details, and wiping the existing interface
263
+ // except for MTU so that IP Address information is never duplicated.
264
+ func (np * Netplan ) createBridgeFromInterface (bridgeName , deviceId string , intf * Interface ) {
214
265
if np .Network .Bridges == nil {
215
266
np .Network .Bridges = make (map [string ]Bridge )
216
267
}
217
268
np .Network .Bridges [bridgeName ] = Bridge {
218
269
Interfaces : []string {deviceId },
219
- Interface : intf ,
270
+ Interface : * intf ,
220
271
}
221
- np .Network .Ethernets [deviceId ] = ethernet
222
- return nil
272
+ * intf = Interface {MTU : intf .MTU }
223
273
}
224
274
225
275
func Unmarshal (in []byte , out interface {}) (err error ) {
@@ -410,14 +460,14 @@ func (np *Netplan) FindBondByMAC(mac string) (device string, err error) {
410
460
return id , nil
411
461
}
412
462
}
413
- return "" , errors .NotFoundf ("Bond device with MAC %q" , mac )
463
+ return "" , errors .NotFoundf ("bond device with MAC %q" , mac )
414
464
}
415
465
416
466
func (np * Netplan ) FindBondByName (name string ) (device string , err error ) {
417
467
if _ , ok := np .Network .Bonds [name ]; ok {
418
468
return name , nil
419
469
}
420
- return "" , errors .NotFoundf ("Bond device with name %q" , name )
470
+ return "" , errors .NotFoundf ("bond device with name %q" , name )
421
471
}
422
472
423
473
type DeviceType string
0 commit comments