/
nfs.go
115 lines (105 loc) · 3.71 KB
/
nfs.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
package upgrade
import (
"context"
"fmt"
"github.com/LINBIT/golinstor/client"
"github.com/LINBIT/linstor-gateway/pkg/iscsi"
"github.com/LINBIT/linstor-gateway/pkg/nfs"
"github.com/LINBIT/linstor-gateway/pkg/reactor"
)
// nfsMigrations defines the operations for upgrading a single version.
// The array index ("n") denotes the starting version; the function at
// index "n" migrates from version "n" to version "n+1".
var nfsMigrations = []func(cfg *reactor.PromoterConfig) error{
0: initialMigrations,
}
// initialMigrations combines two migrations that make up version 1.
func initialMigrations(cfg *reactor.PromoterConfig) error {
if err := removeID(cfg); err != nil {
return err
}
return switchIpAndNfsServer(cfg)
}
// switchIpAndNfsServer changes the order of the resource agents such that
// the service IP is started before the NFS server. This was previously not
// the case, leading to an NFS server that is not limited to the service IP.
func switchIpAndNfsServer(cfg *reactor.PromoterConfig) error {
id := firstResourceId(cfg)
firstResource := cfg.Resources[id]
var serviceIpIndex, nfsServerIndex int
for i, entry := range firstResource.Start {
switch agent := entry.(type) {
case *reactor.ResourceAgent:
if agent.Type == "ocf:heartbeat:IPaddr2" {
serviceIpIndex = i
}
if agent.Type == "ocf:heartbeat:nfsserver" {
nfsServerIndex = i
}
}
}
// slice up the "start" list and create a new one with this order:
// 1. everything before the nfs server
// 2. the service IP
// 3. the NFS server
// 4. all the exportfs entries
// 5. everything after the original service IP index
start := firstResource.Start[:nfsServerIndex]
serviceIpEntry := firstResource.Start[serviceIpIndex]
nfsServerEntry := firstResource.Start[nfsServerIndex]
exportFsEntries := firstResource.Start[nfsServerIndex+1 : serviceIpIndex]
rest := firstResource.Start[serviceIpIndex+1:]
var s []reactor.StartEntry
s = append(s, start...)
s = append(s, serviceIpEntry)
s = append(s, nfsServerEntry)
s = append(s, exportFsEntries...)
s = append(s, rest...)
firstResource.Start = s
cfg.Resources[id] = firstResource
return nil
}
func upgradeNfs(ctx context.Context, linstor *client.Client, name string, forceYes bool, dryRun bool) (bool, error) {
const gatewayConfigPath = "/etc/drbd-reactor.d/linstor-gateway-nfs-%s.toml"
cfg, _, _, _, err := parseExistingConfig(ctx, linstor, fmt.Sprintf(gatewayConfigPath, name))
if err != nil {
return false, err
}
if cfg.Metadata.LinstorGatewaySchemaVersion > iscsi.CurrentVersion {
return false, fmt.Errorf("schema version %d is not supported",
cfg.Metadata.LinstorGatewaySchemaVersion)
}
newCfg, _, _, _, err := parseExistingConfig(ctx, linstor, fmt.Sprintf(gatewayConfigPath, name))
if err != nil {
return false, err
}
for i := cfg.Metadata.LinstorGatewaySchemaVersion; i < nfs.CurrentVersion; i++ {
err := nfsMigrations[i](newCfg)
if err != nil {
return false, fmt.Errorf("failed to migrate from version %d to %d: %w", i, i+1, err)
}
}
newCfg.Metadata.LinstorGatewaySchemaVersion = nfs.CurrentVersion
return maybeWriteNewConfig(ctx, linstor, cfg, newCfg, fmt.Sprintf(nfs.IDFormat, name), forceYes, dryRun)
}
func Nfs(ctx context.Context, linstor *client.Client, name string, forceYes bool, dryRun bool) error {
var didAny bool
didDrbd, err := upgradeDrbdOptions(ctx, linstor, name, forceYes, dryRun)
if err != nil {
return fmt.Errorf("failed to upgrade drbd options: %w", err)
}
if didDrbd {
didAny = true
}
didNfs, err := upgradeNfs(ctx, linstor, name, forceYes, dryRun)
if err != nil {
return fmt.Errorf("failed to upgrade promoter config: %w", err)
}
if didNfs {
didAny = true
}
if !didAny {
fmt.Printf("%s is already up to date.\n", name)
}
return nil
}