network: write network units with user units
This allows us to test the network unit generation as well as removing some special-cased code.
This commit is contained in:
		| @@ -169,16 +169,13 @@ func Apply(cfg config.CloudConfig, env *Environment) error { | ||||
| 		case "digitalocean": | ||||
| 			interfaces, err = network.ProcessDigitalOceanNetconf(cfg.NetworkConfig) | ||||
| 		default: | ||||
| 			return fmt.Errorf("Unsupported network config format %q", env.NetconfType()) | ||||
| 			err = fmt.Errorf("Unsupported network config format %q", env.NetconfType()) | ||||
| 		} | ||||
|  | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		if err := system.WriteNetworkdConfigs(interfaces); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		units = append(units, createNetworkingUnits(interfaces)...) | ||||
| 		if err := system.RestartNetwork(interfaces); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -186,7 +183,25 @@ func Apply(cfg config.CloudConfig, env *Environment) error { | ||||
|  | ||||
| 	um := system.NewUnitManager(env.Root()) | ||||
| 	return processUnits(units, env.Root(), um) | ||||
| } | ||||
|  | ||||
| func createNetworkingUnits(interfaces []network.InterfaceGenerator) (units []system.Unit) { | ||||
| 	appendNewUnit := func(units []system.Unit, name, content string) []system.Unit { | ||||
| 		if content == "" { | ||||
| 			return units | ||||
| 		} | ||||
| 		return append(units, system.Unit{Unit: config.Unit{ | ||||
| 			Name:    name, | ||||
| 			Runtime: true, | ||||
| 			Content: content, | ||||
| 		}}) | ||||
| 	} | ||||
| 	for _, i := range interfaces { | ||||
| 		units = appendNewUnit(units, fmt.Sprintf("%s.netdev", i.Filename()), i.Netdev()) | ||||
| 		units = appendNewUnit(units, fmt.Sprintf("%s.link", i.Filename()), i.Link()) | ||||
| 		units = appendNewUnit(units, fmt.Sprintf("%s.network", i.Filename()), i.Network()) | ||||
| 	} | ||||
| 	return units | ||||
| } | ||||
|  | ||||
| // processUnits takes a set of Units and applies them to the given root using | ||||
|   | ||||
| @@ -21,6 +21,7 @@ import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/coreos/coreos-cloudinit/config" | ||||
| 	"github.com/coreos/coreos-cloudinit/network" | ||||
| 	"github.com/coreos/coreos-cloudinit/system" | ||||
| ) | ||||
|  | ||||
| @@ -67,6 +68,86 @@ func (tum *TestUnitManager) UnmaskUnit(u system.Unit) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type mockInterface struct { | ||||
| 	name           string | ||||
| 	filename       string | ||||
| 	netdev         string | ||||
| 	link           string | ||||
| 	network        string | ||||
| 	kind           string | ||||
| 	modprobeParams string | ||||
| } | ||||
|  | ||||
| func (i mockInterface) Name() string { | ||||
| 	return i.name | ||||
| } | ||||
|  | ||||
| func (i mockInterface) Filename() string { | ||||
| 	return i.filename | ||||
| } | ||||
|  | ||||
| func (i mockInterface) Netdev() string { | ||||
| 	return i.netdev | ||||
| } | ||||
|  | ||||
| func (i mockInterface) Link() string { | ||||
| 	return i.link | ||||
| } | ||||
|  | ||||
| func (i mockInterface) Network() string { | ||||
| 	return i.network | ||||
| } | ||||
|  | ||||
| func (i mockInterface) Type() string { | ||||
| 	return i.kind | ||||
| } | ||||
|  | ||||
| func (i mockInterface) ModprobeParams() string { | ||||
| 	return i.modprobeParams | ||||
| } | ||||
|  | ||||
| func TestCreateNetworkingUnits(t *testing.T) { | ||||
| 	for _, tt := range []struct { | ||||
| 		interfaces []network.InterfaceGenerator | ||||
| 		expect     []system.Unit | ||||
| 	}{ | ||||
| 		{nil, nil}, | ||||
| 		{ | ||||
| 			[]network.InterfaceGenerator{ | ||||
| 				network.InterfaceGenerator(mockInterface{filename: "test"}), | ||||
| 			}, | ||||
| 			nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			[]network.InterfaceGenerator{ | ||||
| 				network.InterfaceGenerator(mockInterface{filename: "test1", netdev: "test netdev"}), | ||||
| 				network.InterfaceGenerator(mockInterface{filename: "test2", link: "test link"}), | ||||
| 				network.InterfaceGenerator(mockInterface{filename: "test3", network: "test network"}), | ||||
| 			}, | ||||
| 			[]system.Unit{ | ||||
| 				system.Unit{Unit: config.Unit{Name: "test1.netdev", Runtime: true, Content: "test netdev"}}, | ||||
| 				system.Unit{Unit: config.Unit{Name: "test2.link", Runtime: true, Content: "test link"}}, | ||||
| 				system.Unit{Unit: config.Unit{Name: "test3.network", Runtime: true, Content: "test network"}}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			[]network.InterfaceGenerator{ | ||||
| 				network.InterfaceGenerator(mockInterface{filename: "test", netdev: "test netdev", link: "test link", network: "test network"}), | ||||
| 			}, | ||||
| 			[]system.Unit{ | ||||
| 				system.Unit{Unit: config.Unit{Name: "test.netdev", Runtime: true, Content: "test netdev"}}, | ||||
| 				system.Unit{Unit: config.Unit{Name: "test.link", Runtime: true, Content: "test link"}}, | ||||
| 				system.Unit{Unit: config.Unit{Name: "test.network", Runtime: true, Content: "test network"}}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} { | ||||
| 		units := createNetworkingUnits(tt.interfaces) | ||||
| 		if !reflect.DeepEqual(tt.expect, units) { | ||||
| 			t.Errorf("bad units (%+v): want %#v, got %#v", tt.interfaces, tt.expect, units) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestProcessUnits(t *testing.T) { | ||||
| 	tests := []struct { | ||||
| 		units []system.Unit | ||||
|   | ||||
| @@ -29,10 +29,6 @@ import ( | ||||
| 	"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/dotcloud/docker/pkg/netlink" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	runtimeNetworkPath = "/run/systemd/network" | ||||
| ) | ||||
|  | ||||
| func RestartNetwork(interfaces []network.InterfaceGenerator) (err error) { | ||||
| 	defer func() { | ||||
| 		if e := restartNetworkd(); e != nil { | ||||
| @@ -100,30 +96,3 @@ func restartNetworkd() error { | ||||
| 	_, err := NewUnitManager("").RunUnitCommand(networkd, "restart") | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func WriteNetworkdConfigs(interfaces []network.InterfaceGenerator) error { | ||||
| 	for _, iface := range interfaces { | ||||
| 		filename := fmt.Sprintf("%s.netdev", iface.Filename()) | ||||
| 		if err := writeConfig(filename, iface.Netdev()); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		filename = fmt.Sprintf("%s.link", iface.Filename()) | ||||
| 		if err := writeConfig(filename, iface.Link()); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		filename = fmt.Sprintf("%s.network", iface.Filename()) | ||||
| 		if err := writeConfig(filename, iface.Network()); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func writeConfig(filename string, content string) error { | ||||
| 	if content == "" { | ||||
| 		return nil | ||||
| 	} | ||||
| 	log.Printf("Writing networkd unit %q\n", filename) | ||||
| 	_, err := WriteFile(&File{config.File{Content: content, Path: filename}}, runtimeNetworkPath) | ||||
| 	return err | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user