forked from canonical/microcloud
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlxd_config.go
310 lines (265 loc) · 9.16 KB
/
lxd_config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
package service
import (
"bufio"
"fmt"
"net"
"os"
"strconv"
"strings"
"github.com/canonical/lxd/shared/api"
)
const (
// DefaultFANNetwork is the name of the default FAN network.
DefaultFANNetwork = "lxdfan0"
// DefaultUplinkNetwork is the name of the default OVN uplink network.
DefaultUplinkNetwork = "UPLINK"
// DefaultOVNNetwork is the name of the default OVN network.
DefaultOVNNetwork = "default"
// DefaultZFSPool is the name of the default ZFS storage pool.
DefaultZFSPool = "local"
// DefaultCephPool is the name of the default Ceph storage pool.
DefaultCephPool = "remote"
// DefaultCephFSPool is the name of the default CephFS storage pool.
DefaultCephFSPool = "remote-fs"
// DefaultCephFSOSDPool is the default OSD pool name used for the CephFS storage pool.
DefaultCephFSOSDPool = "lxd_cephfs"
// DefaultCephOSDPool is the default OSD pool name used for the Ceph storage pool.
DefaultCephOSDPool = "lxd_remote"
// DefaultCephFSDataOSDPool is the default OSD pool name used for the CephFS's underlying data pool.
DefaultCephFSDataOSDPool = "lxd_cephfs_data"
// DefaultCephFSMetaOSDPool is the default OSD pool name used for the CephFS's underlying metadata pool.
DefaultCephFSMetaOSDPool = "lxd_cephfs_meta"
// DefaultMgrOSDPool is the reserved .mgr OSD pool created by Ceph.
DefaultMgrOSDPool = ".mgr"
)
// DefaultPendingFanNetwork returns the default Ubuntu Fan network configuration when
// creating a pending network on a specific cluster member target.
func (s LXDService) DefaultPendingFanNetwork() api.NetworksPost {
return api.NetworksPost{Name: DefaultFANNetwork, Type: "bridge"}
}
// FanNetworkUsable checks if the current host is capable of using a Fan network.
// It actually checks if there is a default IPv4 gateway available.
func FanNetworkUsable() (available bool, ifaceName string, err error) {
file, err := os.Open("/proc/net/route")
if err != nil {
return false, "", err
}
defer func() { _ = file.Close() }()
scanner := bufio.NewReader(file)
for {
line, _, err := scanner.ReadLine()
if err != nil {
break
}
fields := strings.Fields(string(line))
if len(fields) < 8 {
break
}
if fields[1] == "00000000" && fields[7] == "00000000" {
ifaceName = fields[0]
break
}
}
if ifaceName == "" {
return false, "", nil // There is no default gateway for IPv4
}
return true, ifaceName, nil
}
// DefaultFanNetwork returns the default Ubuntu Fan network configuration when
// creating the finalized network.
func (s LXDService) DefaultFanNetwork() (api.NetworksPost, error) {
underlay, _, err := s.defaultGatewaySubnetV4()
if err != nil {
return api.NetworksPost{}, fmt.Errorf("Could not determine Fan overlay subnet: %w", err)
}
underlaySize, _ := underlay.Mask.Size()
if underlaySize != 16 && underlaySize != 24 {
// Override to /16 as that will almost always lead to working Fan network.
underlay.Mask = net.CIDRMask(16, 32)
underlay.IP = underlay.IP.Mask(underlay.Mask)
}
return api.NetworksPost{
NetworkPut: api.NetworkPut{
Config: map[string]string{
"bridge.mode": "fan",
"fan.underlay_subnet": underlay.String(),
},
Description: "Default Ubuntu fan powered bridge",
},
Name: DefaultFANNetwork,
Type: "bridge",
}, nil
}
// DefaultPendingOVNNetwork returns the default OVN uplink network configuration when
// creating a pending network on a specific cluster member target.
func (s LXDService) DefaultPendingOVNNetwork(parent string) api.NetworksPost {
return api.NetworksPost{
NetworkPut: api.NetworkPut{Config: map[string]string{"parent": parent}},
Name: DefaultUplinkNetwork,
Type: "physical",
}
}
// DefaultOVNNetworkJoinConfig returns the default OVN uplink network configuration when
// joining an existing cluster.
func (s LXDService) DefaultOVNNetworkJoinConfig(parent string) api.ClusterMemberConfigKey {
return api.ClusterMemberConfigKey{
Entity: "network",
Name: DefaultUplinkNetwork,
Key: "parent",
Value: parent,
}
}
// DefaultOVNNetwork returns the default OVN network configuration when
// creating the finalized network.
// Returns both the finalized uplink configuration as the first argument,
// and the default OVN network configuration as the second argument.
func (s LXDService) DefaultOVNNetwork(ipv4Gateway string, ipv4Range string, ipv6Gateway string, dnsServers string) (api.NetworksPost, api.NetworksPost) {
finalUplinkCfg := api.NetworksPost{
NetworkPut: api.NetworkPut{
Config: map[string]string{},
Description: "Uplink for OVN networks"},
Name: DefaultUplinkNetwork,
Type: "physical",
}
if ipv4Gateway != "" && ipv4Range != "" {
finalUplinkCfg.Config["ipv4.gateway"] = ipv4Gateway
finalUplinkCfg.Config["ipv4.ovn.ranges"] = ipv4Range
}
if ipv6Gateway != "" {
finalUplinkCfg.Config["ipv6.gateway"] = ipv6Gateway
}
if dnsServers != "" {
finalUplinkCfg.Config["dns.nameservers"] = dnsServers
}
ovnNetwork := api.NetworksPost{
NetworkPut: api.NetworkPut{Config: map[string]string{"network": DefaultUplinkNetwork}, Description: "Default OVN network"},
Name: DefaultOVNNetwork,
Type: "ovn",
}
return finalUplinkCfg, ovnNetwork
}
// DefaultPendingZFSStoragePool returns the default local storage configuration when
// creating a pending pool on a specific cluster member target.
func (s LXDService) DefaultPendingZFSStoragePool(wipe bool, path string) api.StoragePoolsPost {
cfg := map[string]string{"source": path}
if wipe {
cfg["source.wipe"] = strconv.FormatBool(wipe)
}
return api.StoragePoolsPost{
Name: DefaultZFSPool,
Driver: "zfs",
StoragePoolPut: api.StoragePoolPut{
Config: cfg,
Description: "Local storage on ZFS",
},
}
}
// DefaultZFSStoragePool returns the default local storage configuration when
// creating the finalized pool.
func (s LXDService) DefaultZFSStoragePool() api.StoragePoolsPost {
return api.StoragePoolsPost{
Name: DefaultZFSPool,
Driver: "zfs",
StoragePoolPut: api.StoragePoolPut{
Description: "Local storage on ZFS",
},
}
}
// DefaultZFSStoragePoolJoinConfig returns the default local storage configuration when
// joining an existing cluster.
func (s LXDService) DefaultZFSStoragePoolJoinConfig(wipe bool, path string) []api.ClusterMemberConfigKey {
wipeDisk := api.ClusterMemberConfigKey{
Entity: "storage-pool",
Name: DefaultZFSPool,
Key: "source.wipe",
Value: "true",
}
sourceTemplate := api.ClusterMemberConfigKey{
Entity: "storage-pool",
Name: DefaultZFSPool,
Key: "source",
}
sourceTemplate.Value = path
joinConfig := []api.ClusterMemberConfigKey{sourceTemplate}
if wipe {
joinConfig = append(joinConfig, wipeDisk)
}
return joinConfig
}
// DefaultPendingCephStoragePool returns the default remote storage configuration when
// creating a pending pool on a specific cluster member target.
func (s LXDService) DefaultPendingCephStoragePool() api.StoragePoolsPost {
return api.StoragePoolsPost{
Name: DefaultCephPool,
Driver: "ceph",
StoragePoolPut: api.StoragePoolPut{
Config: map[string]string{
"source": DefaultCephOSDPool,
},
},
}
}
// DefaultCephStoragePool returns the default remote storage configuration when
// creating the finalized pool.
func (s LXDService) DefaultCephStoragePool() api.StoragePoolsPost {
return api.StoragePoolsPost{
Name: DefaultCephPool,
Driver: "ceph",
StoragePoolPut: api.StoragePoolPut{
Config: map[string]string{
"ceph.rbd.du": "false",
"ceph.rbd.features": "layering,striping,exclusive-lock,object-map,fast-diff,deep-flatten",
},
Description: "Distributed storage on Ceph",
},
}
}
// DefaultCephStoragePoolJoinConfig returns the default remote storage configuration when
// joining an existing cluster.
func (s LXDService) DefaultCephStoragePoolJoinConfig() api.ClusterMemberConfigKey {
return api.ClusterMemberConfigKey{
Entity: "storage-pool",
Name: DefaultCephPool,
Key: "source",
Value: DefaultCephOSDPool,
}
}
// DefaultPendingCephFSStoragePool returns the default cephfs storage configuration when
// creating a pending pool on a specific cluster member target.
func (s LXDService) DefaultPendingCephFSStoragePool() api.StoragePoolsPost {
return api.StoragePoolsPost{
Name: DefaultCephFSPool,
Driver: "cephfs",
StoragePoolPut: api.StoragePoolPut{
Config: map[string]string{
"source": DefaultCephFSOSDPool,
},
},
}
}
// DefaultCephFSStoragePool returns the default cephfs storage configuration when
// creating the finalized pool.
func (s LXDService) DefaultCephFSStoragePool() api.StoragePoolsPost {
return api.StoragePoolsPost{
Name: DefaultCephFSPool,
Driver: "cephfs",
StoragePoolPut: api.StoragePoolPut{
Config: map[string]string{
"cephfs.create_missing": "true",
"cephfs.meta_pool": DefaultCephFSMetaOSDPool,
"cephfs.data_pool": DefaultCephFSDataOSDPool,
},
Description: "Distributed file-system storage using CephFS",
},
}
}
// DefaultCephFSStoragePoolJoinConfig returns the default cephfs storage configuration when
// joining an existing cluster.
func (s LXDService) DefaultCephFSStoragePoolJoinConfig() api.ClusterMemberConfigKey {
return api.ClusterMemberConfigKey{
Entity: "storage-pool",
Name: "remote-fs",
Key: "source",
Value: DefaultCephFSOSDPool,
}
}