-
Notifications
You must be signed in to change notification settings - Fork 950
/
Copy pathupdate_daemon.go
209 lines (172 loc) · 6.64 KB
/
update_daemon.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
package main
import (
"bytes"
"context"
"encoding/json"
"io"
"io/ioutil"
"os"
"github.com/alibaba/pouch/apis/types"
"github.com/alibaba/pouch/daemon/config"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
// daemonUpdateDescription is used to describe updatedaemon command in detail and auto generate command doc.
var daemonUpdateDescription = "Update daemon's configurations, if daemon is stoped, it will just update config file. " +
"Online update just including: image proxy, label, offline update including: manager white list, debug level, " +
"execute root directory, bridge name, bridge IP, fixed CIDR, defaut gateway, iptables, ipforwark, userland proxy. " +
"If pouchd is alive, you can only use --offline=true to update config file"
// DaemonUpdateCommand use to implement 'updatedaemon' command, it modifies the configurations of a container.
type DaemonUpdateCommand struct {
baseCommand
configFile string
offline bool
debug bool
imageProxy string
label []string
managerWhiteList string
execRoot string
disableBridge bool
bridgeName string
bridgeIP string
fixedCIDRv4 string
defaultGatewayv4 string
iptables bool
ipforward bool
userlandProxy bool
homeDir string
snapshotter string
}
// Init initialize updatedaemon command.
func (udc *DaemonUpdateCommand) Init(c *Cli) {
udc.cli = c
udc.cmd = &cobra.Command{
Use: "updatedaemon [OPTIONS]",
Short: "Update the configurations of pouchd",
Long: daemonUpdateDescription,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return udc.daemonUpdateRun(args)
},
Example: daemonUpdateExample(),
}
udc.addFlags()
}
// addFlags adds flags for specific command.
func (udc *DaemonUpdateCommand) addFlags() {
flagSet := udc.cmd.Flags()
flagSet.SetInterspersed(false)
flagSet.StringVar(&udc.configFile, "config-file", "/etc/pouch/config.json", "specified config file for updating daemon")
flagSet.BoolVar(&udc.offline, "offline", false, "just update daemon config file")
flagSet.BoolVar(&udc.debug, "debug", false, "update daemon debug mode")
flagSet.StringVar(&udc.imageProxy, "image-proxy", "", "update daemon image proxy")
flagSet.StringVar(&udc.managerWhiteList, "manager-white-list", "", "update daemon manager white list")
flagSet.StringSliceVar(&udc.label, "label", nil, "update daemon labels")
flagSet.StringVar(&udc.execRoot, "exec-root-dir", "", "update exec root directory for network")
flagSet.BoolVar(&udc.disableBridge, "disable-bridge", false, "disable bridge network")
flagSet.StringVar(&udc.bridgeName, "bridge-name", "", "update daemon bridge device")
flagSet.StringVar(&udc.bridgeIP, "bip", "", "update daemon bridge IP")
flagSet.StringVar(&udc.fixedCIDRv4, "fixed-cidr", "", "update daemon bridge fixed CIDR")
flagSet.StringVar(&udc.defaultGatewayv4, "default-gateway", "", "update daemon bridge default gateway")
flagSet.BoolVar(&udc.iptables, "iptables", true, "update daemon with iptables")
flagSet.BoolVar(&udc.ipforward, "ipforward", true, "udpate daemon with ipforward")
flagSet.BoolVar(&udc.userlandProxy, "userland-proxy", false, "update daemon with userland proxy")
flagSet.StringVar(&udc.homeDir, "home-dir", "", "update daemon home dir")
flagSet.StringVar(&udc.snapshotter, "snapshotter", "", "update daemon snapshotter")
}
// daemonUpdateRun is the entry of updatedaemon command.
func (udc *DaemonUpdateCommand) daemonUpdateRun(args []string) error {
ctx := context.Background()
apiClient := udc.cli.Client()
msg, err := apiClient.SystemPing(ctx)
if !udc.offline && err == nil && msg == "OK" {
// TODO: daemon support more configures for update online, such as debug level.
daemonConfig := &types.DaemonUpdateConfig{
ImageProxy: udc.imageProxy,
Labels: udc.label,
}
err = apiClient.DaemonUpdate(ctx, daemonConfig)
if err != nil {
return errors.Wrap(err, "failed to update alive daemon config")
}
} else {
// offline update config file.
err = udc.updateDaemonConfigFile()
if err != nil {
return errors.Wrap(err, "failed to update daemon config file.")
}
}
return nil
}
// updateDaemonConfigFile is just used to update config file.
func (udc *DaemonUpdateCommand) updateDaemonConfigFile() error {
// read config from file.
contents, err := ioutil.ReadFile(udc.configFile)
if err != nil {
return errors.Wrapf(err, "failed to read config file(%s)", udc.configFile)
}
daemonConfig := &config.Config{}
// do not return error if config file is empty
if err := json.NewDecoder(bytes.NewReader(contents)).Decode(daemonConfig); err != nil && err != io.EOF {
return errors.Wrapf(err, "failed to decode json: %s", udc.configFile)
}
flagSet := udc.cmd.Flags()
if flagSet.Changed("image-proxy") {
daemonConfig.ImageProxy = udc.imageProxy
}
if flagSet.Changed("manager-white-list") {
daemonConfig.TLS.ManagerWhiteList = udc.managerWhiteList
}
// TODO: add parse labels
if flagSet.Changed("exec-root-dir") {
daemonConfig.NetworkConfig.ExecRoot = udc.execRoot
}
if flagSet.Changed("disable-bridge") {
daemonConfig.NetworkConfig.BridgeConfig.DisableBridge = udc.disableBridge
}
if flagSet.Changed("bridge-name") {
daemonConfig.NetworkConfig.BridgeConfig.Name = udc.bridgeName
}
if flagSet.Changed("bip") {
daemonConfig.NetworkConfig.BridgeConfig.IPv4 = udc.bridgeIP
}
if flagSet.Changed("fixed-cidr") {
daemonConfig.NetworkConfig.BridgeConfig.FixedCIDRv4 = udc.fixedCIDRv4
}
if flagSet.Changed("default-gateway") {
daemonConfig.NetworkConfig.BridgeConfig.GatewayIPv4 = udc.defaultGatewayv4
}
if flagSet.Changed("iptables") {
daemonConfig.NetworkConfig.BridgeConfig.IPTables = udc.iptables
}
if flagSet.Changed("ipforward") {
daemonConfig.NetworkConfig.BridgeConfig.IPForward = udc.ipforward
}
if flagSet.Changed("userland-proxy") {
daemonConfig.NetworkConfig.BridgeConfig.UserlandProxy = udc.userlandProxy
}
if flagSet.Changed("home-dir") {
daemonConfig.HomeDir = udc.homeDir
}
if flagSet.Changed("snapshotter") {
daemonConfig.Snapshotter = udc.snapshotter
}
// write config to file
fd, err := os.OpenFile(udc.configFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
return errors.Wrapf(err, "failed to open config file(%s)", udc.configFile)
}
defer fd.Close()
fd.Seek(0, io.SeekStart)
encoder := json.NewEncoder(fd)
encoder.SetIndent("", " ")
err = encoder.Encode(daemonConfig)
if err != nil {
return errors.Wrapf(err, "failed to write config to file(%s)", udc.configFile)
}
return nil
}
// daemonUpdateExample shows examples in updatedaemon command, and is used in auto-generated cli docs.
func daemonUpdateExample() string {
return `$ pouch updatedaemon --debug=true`
}