Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(148)

Side by Side Diff: environs/local/network.go

Issue 6099051: Go port for local provider networking
Patch Set: Go port for local provider networking Created 5 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 package local
2
3 import (
4 "encoding/xml"
5 "io/ioutil"
6 "os"
7 "os/exec"
8 "strings"
9 "text/template"
10 )
11
12 // networks represents a local virtual network.
niemeyer 2012/05/24 16:31:35 s/networks/network/
13 type network struct {
14 XMLName xml.Name `xml:"network"`
15 Name string `xml:"name"`
16 Bridge bridge `xml:"bridge"`
17 Ip ip `xml:"ip"`
18 Subnet int
19 }
20
21 // ip represents an ip with the given address and netmask.
22 type ip struct {
23 Ip string `xml:"address,attr"`
24 Mask string `xml:"netmask,attr"`
25 }
26
27 // bridge represents a briddge with the given name.
28 type bridge struct {
29 Name string `xml:"name,attr"`
30 }
31
32 // newNetwork returns a started network.
33 func newNetwork(name string, subnet int) (*network, error) {
34 n := network{Name: name, Subnet: subnet}
35 err := n.start()
36 if err != nil {
37 return nil, err
38 }
39 err = n.loadAttributes()
40 if err != nil {
41 return nil, err
42 }
43 return &n, nil
44 }
45
46 // loadAttributes loads the attributes for a network.
47 func (n *network) loadAttributes() error {
48 output, err := exec.Command("virsh", "net-dumpxml", n.Name).Output()
49 if err != nil {
50 return err
51 }
52 return xml.Unmarshal(output, &n)
53 }
54
55 // running returns true if network name is in the
56 // list of networks and is active.
57 func (n *network) running() (bool, error) {
58 networks, err := listNetworks()
59 if err != nil {
60 return false, err
61 }
62 return networks[n.Name], nil
63 }
64
65 // exists returns true if network name is in the
66 // list of networks.
67 func (n *network) exists() (bool, error) {
68 networks, err := listNetworks()
69 if err != nil {
70 return false, err
71 }
72 _, exists := networks[n.Name]
73 return exists, nil
74 }
75
76 // virsh replaces %d with an auto increment
77 // number to make the bridge name unique
78 var libVirtNetworkTemplate = template.Must(template.New("").Parse(`
79 <network>
80 <name>{{.Name}}</name>
81 <bridge name='vbr-{{.Name}}-%d' />
82 <forward/>
83 <ip address='192.168.{{.Subnet}}.1' netmask='255.255.255.0'>
84 <dhcp>
85 <range start='192.168.{{.Subnet}}.2' end='192.168.{{.Subnet}}.254' />
86 </dhcp>
87 </ip>
88 </network>
89 `))
90
91 // start ensures that the network is started.
92 // If network name does not exist, it is created.
rog 2012/05/24 14:07:04 s/network/the network/
93 func (n *network) start() error {
94 exists, err := n.exists()
95 if err != nil {
96 return err
97 }
98 if exists {
99 running, err := n.running()
100 if err != nil {
101 return err
102 }
103 if running {
104 return nil
105 }
106 return exec.Command("virsh", "net-start", n.Name).Run()
107 }
108 file, err := ioutil.TempFile(os.TempDir(), "network")
109 if err != nil {
110 return err
111 }
112 defer file.Close()
113 defer os.Remove(file.Name())
114 err = libVirtNetworkTemplate.Execute(file, n)
115 if err != nil {
116 return err
117 }
118 err = exec.Command("virsh", "net-define", file.Name()).Run()
119 if err != nil {
120 return err
121 }
122 return exec.Command("virsh", "net-start", n.Name).Run()
123 }
124
125 // listNetworks returns a map from network name to active status.
126 func listNetworks() (map[string]bool, error) {
127 output, err := exec.Command("virsh", "net-list", "--all").Output()
128 if err != nil {
129 return nil, err
130 }
131 // Remove the header.
132 networks := map[string]bool{}
133 lines := strings.Split(string(output), "\n")
134 if len(lines) < 3 {
135 return networks, nil
136 }
137 lines = lines[2:]
138 for _, line := range lines {
139 if line == "" {
140 continue
141 }
142 fields := strings.Fields(line)
143 if len(fields) > 2 {
144 networks[fields[0]] = fields[1] == "active"
145 }
146 }
147 return networks, nil
148 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld 204d58d