forked from cloudfoundry/bosh-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
concrete_open_iscsi_admin.go
187 lines (162 loc) · 5.03 KB
/
concrete_open_iscsi_admin.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
package openiscsi
import (
"bytes"
"path"
"regexp"
"strings"
"text/template"
bosherr "github.com/cloudfoundry/bosh-utils/errors"
boshlog "github.com/cloudfoundry/bosh-utils/logger"
boshsys "github.com/cloudfoundry/bosh-utils/system"
)
type concreteOpenIscsiAdmin struct {
fs boshsys.FileSystem
runner boshsys.CmdRunner
logger boshlog.Logger
logtag string
}
func NewConcreteOpenIscsiAdmin(fs boshsys.FileSystem, runner boshsys.CmdRunner, logger boshlog.Logger) OpenIscsi {
return concreteOpenIscsiAdmin{
fs: fs,
runner: runner,
logger: logger,
logtag: "OpenIscsiAdmin",
}
}
func (iscsi concreteOpenIscsiAdmin) Setup(iqn, username, password string) (err error) {
iscsi.logger.Info(iscsi.logtag, "Setup Open-iscsi, initializing /etc/iscsi/initiatorname.iscsi,iscsid.conf")
buffer := bytes.NewBuffer([]byte{})
t := template.Must(template.New("Open-iscsi-initiator").Parse(initiatorNameIscsiTemplate))
type initiatorNameArgs struct {
Iqn string
}
err = t.Execute(buffer, initiatorNameArgs{iqn})
if err != nil {
err = bosherr.WrapError(err, "Generating initiatorname.iscsi of Open-iscsi")
return
}
err = iscsi.fs.WriteFile(path.Join("/etc/iscsi", "initiatorname.iscsi"), buffer.Bytes())
if err != nil {
err = bosherr.WrapError(err, "Writing to /etc/iscsi/initiatorname.iscsi")
return
}
buffer.Reset()
type iscsidConfArgs struct {
Username string
Password string
}
t = template.Must(template.New("Open-iscsi-conf").Parse(iscsidConfTemplate))
err = t.Execute(buffer, iscsidConfArgs{username, password})
if err != nil {
err = bosherr.WrapError(err, "Generating iscsid.conf of Open-iscsi")
return
}
err = iscsi.fs.WriteFile(path.Join("/etc/iscsi", "iscsid.conf"), buffer.Bytes())
if err != nil {
err = bosherr.WrapError(err, "Writing to /etc/iscsi/iscsid.conf")
return
}
buffer.Reset()
err = iscsi.Restart()
if err != nil {
err = bosherr.WrapError(err, "Restarting iscsi after modifying the /etc/iscsi/iscsid.conf file")
return
}
_, _, _, err = iscsi.runner.RunCommand("/etc/init.d/multipath-tools", "restart")
if err != nil {
err = bosherr.WrapError(err, "Restarting multipath after restarting open-iscsi")
return
}
return
}
// Open-iscsi initiator file - /etc/iscsi/initiatorname.iscsi
const initiatorNameIscsiTemplate = `InitiatorName={{ .Iqn }}`
// Open-iscsi deamon configuration file - /etc/iscsi/iscsid.conf
const iscsidConfTemplate = `# Generated by bosh-agent
node.startup = automatic
node.session.auth.authmethod = CHAP
node.session.auth.username = {{.Username}}
node.session.auth.password = {{.Password}}
discovery.sendtargets.auth.authmethod = CHAP
discovery.sendtargets.auth.username = {{.Username}}
discovery.sendtargets.auth.password = {{.Password}}
node.session.timeo.replacement_timeout = 120
node.conn[0].timeo.login_timeout = 15
node.conn[0].timeo.logout_timeout = 15
node.conn[0].timeo.noop_out_interval = 10
node.conn[0].timeo.noop_out_timeout = 15
node.session.iscsi.InitialR2T = No
node.session.iscsi.ImmediateData = Yes
node.session.iscsi.FirstBurstLength = 262144
node.session.iscsi.MaxBurstLength = 16776192
node.conn[0].iscsi.MaxRecvDataSegmentLength = 65536
`
func (iscsi concreteOpenIscsiAdmin) Start() (err error) {
iscsi.logger.Info(iscsi.logtag, "Start Open-iscsi deamon")
_, _, _, err = iscsi.runner.RunCommand("/etc/init.d/open-iscsi", "start")
return
}
func (iscsi concreteOpenIscsiAdmin) Stop() (err error) {
iscsi.logger.Info(iscsi.logtag, "Stop Open-iscsi deamon")
_, _, _, err = iscsi.runner.RunCommand("/etc/init.d/open-iscsi", "stop")
return
}
func (iscsi concreteOpenIscsiAdmin) Restart() (err error) {
iscsi.logger.Info(iscsi.logtag, "Restart Open-iscsi deamon")
_, _, _, err = iscsi.runner.RunCommand("/etc/init.d/open-iscsi", "restart")
return
}
func (iscsi concreteOpenIscsiAdmin) Discovery(ipAddress string) (err error) {
iscsi.logger.Info(iscsi.logtag, "Discovering lun against %s", ipAddress)
_, _, _, err = iscsi.runner.RunCommand(
"iscsiadm",
"-m",
"discovery",
"-t",
"sendtargets",
"-p",
ipAddress,
)
return
}
func (iscsi concreteOpenIscsiAdmin) Login() (err error) {
iscsi.logger.Info(iscsi.logtag, "Iscsiadm session login")
_, _, _, err = iscsi.runner.RunCommand(
"iscsiadm",
"-m",
"node",
"-l",
)
return
}
func (iscsi concreteOpenIscsiAdmin) IsLoggedin() (bool, error) {
stdout, stderr, _, err := iscsi.runner.RunCommand(
"iscsiadm",
"-m",
"session",
)
if err != nil {
if strings.Contains(stderr, "No active sessions.") {
return false, nil
}
return false, bosherr.WrapError(err, "Checking all current sessions logged in")
}
r, err := regexp.Compile(`^tcp: \[\d+\]`)
if err != nil {
return false, bosherr.WrapError(err, "There is a problem with your regexp: '^tcp: \\[\\d+\\]'. That is used to check iscsi session(e.g., tcp: [sid] portal target)")
}
if r.MatchString(stdout) {
return true, nil
}
return false, nil
}
func (iscsi concreteOpenIscsiAdmin) Logout() (err error) {
iscsi.logger.Info(iscsi.logtag, "Iscsiadm session logout")
_, _, _, err = iscsi.runner.RunCommand(
"iscsiadm",
"-m",
"node",
"-u",
)
return
}