Skip to content

Commit a5f1f20

Browse files
author
gitlab
committed
Merge branch 'fv-bm-expon-63318@@3' into '5.1.0'
<feature>[expon]: support expon block volume for baremetal2 See merge request zstackio/zstack-utility!4652
2 parents e26a127 + 3de0fb9 commit a5f1f20

8 files changed

Lines changed: 232 additions & 34 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "2.0.5"
1+
__version__ = "2.0.6"

bm-instance-agent/bm_instance_agent/systems/linux/driver.py

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def _check_initiator_config(instance_uuid):
4040
stdout, stderr = processutils.trycmd(cmd, shell=True)
4141
if stderr:
4242
LOG.info("get iscsid status failed, try to restart iscsid service")
43-
cmd = 'systemctl restart iscsid'
43+
cmd = 'systemctl restart iscsid || service iscsid restart'
4444
processutils.execute(cmd, shell=True)
4545

4646
conf_path = '/etc/iscsi/initiatorname.iscsi'
@@ -82,6 +82,36 @@ def _check_multi_path_config():
8282
processutils.execute(cmd, shell=True)
8383

8484

85+
def rescan_sids_target_name(target_name):
86+
cmd = "iscsiadm -m session | grep {} | awk '{{print $2}}' | tr -d '[]'".format(target_name)
87+
LOG.info(cmd)
88+
stdout, stderr = processutils.trycmd(cmd, shell=True)
89+
if stderr:
90+
LOG.info("iscsiadm -m session grep %s failed, because %s" % (target_name, stderr))
91+
return
92+
session_ids = stdout.strip().split('\n')
93+
for session_id in session_ids:
94+
if not session_id:
95+
continue
96+
rescan_cmd = 'iscsiadm -m session -r %s --rescan' % session_id
97+
LOG.info(rescan_cmd)
98+
stdout, stderr = processutils.trycmd(rescan_cmd, shell=True)
99+
if stderr:
100+
LOG.info("iscsiadm -m session -r %s --rescan fail, because %s" % (session_id, stderr))
101+
102+
103+
def rescan_for_detach(volume_obj):
104+
volume_iqn = volume_obj.iscsi_path.replace('iscsi://', '').split("/")[1].strip()
105+
if volume_iqn:
106+
LOG.info("skip rescan for detach")
107+
return
108+
109+
stdout, stderr = processutils.trycmd("timeout 30 iscsiadm -m session -R", shell=True)
110+
if stderr:
111+
LOG.info("timeout 30 iscsiadm -m session -R failed, because %s" % stderr)
112+
return
113+
114+
85115
class LinuxDriver(base.SystemDriverBase):
86116
driver_name = 'linux'
87117

@@ -120,7 +150,7 @@ def discovery_target(self, instance_obj):
120150
stdout, stderr = processutils.trycmd(cmd, shell=True)
121151
if not stderr:
122152
LOG.info("iscsi target:%s has logged" % target_name)
123-
return target_name
153+
return
124154

125155
discovery_cmd = 'iscsiadm -m discovery -t sendtargets -p {address}:{port}'.format(
126156
address=instance_obj.gateway_ip,
@@ -140,10 +170,9 @@ def discovery_target(self, instance_obj):
140170
processutils.execute(target_login_cmd, shell=True)
141171
else:
142172
LOG.info("discovered targets not contains %s, skip login" % target_name)
143-
return target_name
144173
except processutils.ProcessExecutionError:
145174
LOG.info("no iscsi target found, skip login")
146-
return None
175+
rescan_sids_target_name(target_name)
147176

148177
def discovery_volume_target(self, instance_obj, volume_obj, volume_access_path_gateway_ips):
149178
if not volume_obj.iscsi_path:
@@ -153,12 +182,14 @@ def discovery_volume_target(self, instance_obj, volume_obj, volume_access_path_g
153182

154183
def discovery_target_through_access_path_gateway_ips(self, target_name, volume_access_path_gateway_ips):
155184
for gateway_ip in volume_access_path_gateway_ips:
185+
if not target_name:
186+
discovery_cmd = "timeout 5 iscsiadm -m discovery -t sendtargets -p {address}:{port} | awk '{{print $2}}'".format(address=gateway_ip, port=3260)
187+
stdout, stderr = processutils.trycmd(discovery_cmd, shell=True)
188+
if stderr:
189+
raise Exception("discovered targets fail, %s" % stderr)
190+
target_name = stdout.strip()
156191
self.login_target(target_name, gateway_ip)
157-
158-
cmd = 'iscsiadm -m session --rescan'
159-
stdout, stderr = processutils.trycmd(cmd, shell=True)
160-
if stderr:
161-
LOG.info("iscsiadm -m session --rescan fail, because %s" % (stderr))
192+
rescan_sids_target_name(target_name)
162193

163194
def login_target(self, target_name, address_ip, port=3260):
164195
LOG.info("start login_target:%s by ip %s" % (target_name, address_ip))
@@ -196,25 +227,11 @@ def attach_volume(self, instance_obj, volume_obj, volume_access_path_gateway_ips
196227
First check the /etc/iscsi/initiatorname.iscsi whether corrent, if
197228
not, corrent the configuration, then rescan the iscsi session.
198229
"""
199-
target_name = self.discovery_target(instance_obj)
230+
self.discovery_target(instance_obj)
200231
self.discovery_volume_target(instance_obj, volume_obj, volume_access_path_gateway_ips)
201232
_check_initiator_config(instance_obj.uuid)
202233
_check_multi_path_config()
203234

204-
if not target_name:
205-
raise Exception("instance[%s] target name is not exist, can not rescan session" % instance_obj)
206-
cmd = "iscsiadm -m session | grep {} | awk '{{print $2}}' | tr -d '[]'".format(target_name)
207-
LOG.info(cmd)
208-
stdout, stderr = processutils.trycmd(cmd, shell=True)
209-
if stderr:
210-
LOG.info("iscsiadm -m session grep %s failed, because %s" % (target_name, stderr))
211-
return
212-
rescan_cmd = 'iscsiadm -m session -r %s --rescan' % stdout.strip()
213-
LOG.info(rescan_cmd)
214-
stdout, stderr = processutils.trycmd(rescan_cmd, shell=True)
215-
if stderr:
216-
LOG.info("iscsiadm -m session --rescan fail, because %s" % stderr)
217-
218235
def detach_volume(self, instance_obj, volume_obj, volume_access_path_gateway_ips):
219236
""" Detach a given iSCSI lun
220237
@@ -238,11 +255,14 @@ def detach_volume(self, instance_obj, volume_obj, volume_access_path_gateway_ips
238255
"""
239256
for volume_access_path_gateway_ip in volume_access_path_gateway_ips:
240257
self.detach_volume_for_target_ip(instance_obj, volume_obj, volume_access_path_gateway_ip)
258+
rescan_for_detach(volume_obj)
241259

242260
def detach_volume_for_target_ip(self, instance_obj, volume_obj, target_ip):
243261
# Get the session id
244262
sid = None
245263
volume_iqn = volume_obj.iscsi_path.replace('iscsi://', '').split("/")[1]
264+
if not volume_iqn:
265+
return
246266
if instance_obj.custom_iqn:
247267
iqn = instance_obj.custom_iqn
248268
elif volume_iqn:

bm-instance-agent/tools/install.sh

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ popd
3232
sed -i '/SELINUX=/s/enforcing/permissive/g' /etc/selinux/config >/dev/null 2>&1 || true
3333
setenforce 0 >/dev/null 2>&1 || true
3434

35-
mkdir -p /usr/lib/systemd/system/
36-
cat << EOF > /usr/lib/systemd/system/zstack-baremetal-instance-agent.service
35+
if which systemctl &> /dev/null; then
36+
mkdir -p /usr/lib/systemd/system/
37+
cat << EOF > /usr/lib/systemd/system/zstack-baremetal-instance-agent.service
3738
[Unit]
3839
Description=ZStack baremetal instance agent
3940
After=network.target
@@ -54,9 +55,90 @@ ExecStart=/var/lib/zstack/baremetalv2/bm-instance-agent/bm-instance-agent.pex
5455
WantedBy=multi-user.target
5556
EOF
5657

57-
systemctl daemon-reload \
58-
&& systemctl enable zstack-baremetal-instance-agent \
59-
&& systemctl restart zstack-baremetal-instance-agent
58+
systemctl daemon-reload \
59+
&& systemctl enable zstack-baremetal-instance-agent \
60+
&& systemctl restart zstack-baremetal-instance-agent
61+
else
62+
cat << 'EOF' > /etc/init.d/zstack-baremetal-instance-agent
63+
#!/bin/bash
64+
# chkconfig: 2345 77 22
65+
# description: ZStack Baremetal Agent Service
66+
67+
# return value
68+
RETVAL=0
69+
server_dir="/var/lib/zstack/baremetalv2/bm-instance-agent"
70+
server_name="zstack-baremetal-instance-agent"
71+
72+
73+
start() {
74+
echo -n "Starting ${server_name}:"
75+
/bin/sh -c "/sbin/iptables -t filter -C INPUT -p tcp --dport=7090 -j ACCEPT 2>/dev/null || /sbin/iptables -t filter -I INPUT -p tcp --dport=7090 -j ACCEPT || true"
76+
/bin/sh -c "/sbin/iptables -t filter -C INPUT -p tcp --dport=4200 -j ACCEPT 2>/dev/null || /sbin/iptables -t filter -I INPUT -p tcp --dport=4200 -j ACCEPT || true"
77+
PIDS=`ps -ef |grep .pex/unzipped_pexes |grep -v grep | awk '{print $2}'`
78+
if [ "$PIDS" != "" ]; then
79+
echo "${server_name} is runing!"
80+
else
81+
nohup /var/lib/zstack/baremetalv2/bm-instance-agent/bm-instance-agent.pex >> /nohup.log 2>&1 &
82+
echo ".... SUCCESS"
83+
fi
84+
}
85+
86+
87+
stop(){
88+
echo -n "Stopping ${server_name}:"
89+
PIDS=`ps -ef |grep .pex/unzipped_pexes |grep -v grep | awk '{print $2}'`
90+
if [ "$PIDS" == "" ];then
91+
echo "No pids exist, is ${server_name} running?"
92+
else
93+
for pid in $PIDS; do
94+
kill -9 "$pid"
95+
sleep 5
96+
done
97+
echo ".... SUCCESS"
98+
fi
99+
}
100+
101+
status(){
102+
PIDS=`ps -ef |grep .pex/unzipped_pexes |grep -v grep | awk '{print $2}'`
103+
if [ "$PIDS" != "" ];then
104+
echo "${server_name} is running"
105+
else
106+
echo "${server_name} is stopped"
107+
fi
108+
}
109+
110+
case "$1" in
111+
start)
112+
start
113+
;;
114+
stop)
115+
stop
116+
;;
117+
status)
118+
status
119+
;;
120+
restart)
121+
stop
122+
status
123+
start
124+
sleep 5
125+
status
126+
RETVAL=$?
127+
;;
128+
*)
129+
echo $"Usage: $0 {start|stop|status|restart}"
130+
exit 1
131+
esac
132+
133+
exit $RETVAL
134+
EOF
135+
136+
cd /etc/init.d/
137+
chkconfig --add zstack-baremetal-instance-agent
138+
chkconfig --level 2345 zstack-baremetal-instance-agent on
139+
chmod +x zstack-baremetal-instance-agent
140+
bash zstack-baremetal-instance-agent restart
141+
fi
60142

61143
chmod +x /var/lib/zstack/baremetalv2/bm-instance-agent/zwatch-vm-agent-`uname -m`
62144
/var/lib/zstack/baremetalv2/bm-instance-agent/zwatch-vm-agent-`uname -m` -i

kvmagent/kvmagent/plugins/baremetal_v2_gateway_agent.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,8 @@ def _create_import_data_config(self, volume_driver, cmd):
951951
chassis_port=cmd.chassisInfo.port,
952952
api_id=cmd.threadContext.api,
953953
task_name=cmd.threadContext["task-name"],
954-
provision_mac=instance_obj.provision_mac
954+
provision_mac=instance_obj.provision_mac,
955+
instance_uuid=instance_obj.uuid
955956
)
956957

957958
with open(ks_config_path, 'w') as f:

kvmagent/kvmagent/plugins/bmv2_gateway_agent/object.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ class VolumeObj(Base):
155155
'token': 'token',
156156
'tpTimeout': 'tpTimeout',
157157
'monIp': 'monIp',
158-
'iscsiPath': 'iscsiPath'
158+
'iscsiPath': 'iscsiPath',
159+
'targetIqn': 'targetIqn'
159160
}
160161

161162
@classmethod

kvmagent/kvmagent/plugins/bmv2_gateway_agent/templates/import-data.ks.j2

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,17 @@ def get_dest_dev(dest_wwn):
6565
raise Exception("Failed to find dest disk[%s]" % dest_wwn)
6666

6767
def get_src_dev():
68+
cmd = "mkdir -p /etc/iscsi && touch /etc/iscsi/initiatorname.iscsi && echo 'InitiatorName=iqn.2015-01.io.zstack:initiator.instance.{{instance_uuid}}' > /etc/iscsi/initiatorname.iscsi"
69+
shell_cmd(cmd)
70+
cmd = "systemctl restart iscsid"
71+
shell_cmd(cmd)
72+
time.sleep(1)
6873
cmd = "iscsiadm -m discovery -t sendtargets -p {{gateway_ip}}:3260"
6974
shell_cmd(cmd)
7075
time.sleep(1)
76+
cmd = "iscsiadm --mode node --targetname {{iqn_name}} -p {{gateway_ip}}:3260 --login -o new"
77+
shell_cmd(cmd)
78+
time.sleep(1)
7179
cmd = "iscsiadm --mode node --targetname {{iqn_name}} -p {{gateway_ip}}:3260 --login"
7280
shell_cmd(cmd)
7381
time.sleep(3)

kvmagent/kvmagent/plugins/bmv2_gateway_agent/volume/__init__.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,35 @@
22
from kvmagent.plugins.bmv2_gateway_agent.volume import ceph
33
from kvmagent.plugins.bmv2_gateway_agent.volume import sharedblock
44
from kvmagent.plugins.bmv2_gateway_agent.volume import thirdparty_ceph
5+
from kvmagent.plugins.bmv2_gateway_agent.volume import expon
56

67
mapping = {
78
'ceph': ceph.CephVolume,
89
'sharedblock': sharedblock.SharedBlockVolume,
9-
'thirdpartyCeph': thirdparty_ceph.ThirdPartyCephVolume
10+
'thirdpartyCeph': thirdparty_ceph.ThirdPartyCephVolume,
11+
'expon': expon.ExponVolume
1012
}
1113

1214

1315
def get_driver(instance_obj, volume_obj):
1416
ps_type = volume_obj.primary_storage_type.lower()
1517
if is_third_party_ceph(volume_obj):
1618
ps_type = 'thirdpartyCeph'
19+
if is_third_party_addon(ps_type):
20+
ps_type = get_type_from_third_party_addon(volume_obj)
1721
if ps_type not in mapping:
1822
raise exception.PrimaryStorageTypeNotSupport(
1923
primary_storage_type=ps_type)
2024
return mapping.get(ps_type)(instance_obj, volume_obj)
2125

2226

2327
def is_third_party_ceph(token_object):
24-
return hasattr(token_object, "token") and token_object.token
28+
return hasattr(token_object, "token") and token_object.token
29+
30+
31+
def is_third_party_addon(ps_type):
32+
return ps_type == "addon"
33+
34+
35+
def get_type_from_third_party_addon(volume_obj):
36+
return volume_obj.path.split(":")[0]
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
from kvmagent.plugins.bmv2_gateway_agent.volume import base
2+
3+
from zstacklib.utils import shell, linux
4+
5+
6+
class ExponVolume(base.BaseVolume):
7+
8+
def __init__(self, *args, **kwargs):
9+
super(ExponVolume, self).__init__(*args, **kwargs)
10+
11+
def check_exist(self):
12+
pass
13+
14+
@property
15+
def nbd_backend(self):
16+
return self.real_path
17+
18+
@property
19+
def iscsi_backend(self):
20+
return self.nbd_dev
21+
22+
@property
23+
def iscsi_target(self):
24+
return self.volume_obj.targetIqn
25+
26+
@property
27+
def real_path(self):
28+
return self.volume_obj.path.replace('expon://', '')
29+
30+
def attach(self):
31+
pass
32+
33+
def detach(self):
34+
pass
35+
36+
def detach_volume(self):
37+
pass
38+
39+
# monIp: 172.27.16.181,172.27.16.99,...
40+
def prepare_instance_resource(self):
41+
instance_gateway_ip = self.instance_obj.gateway_ip
42+
mon_ip = self.volume_obj.monIp
43+
dev_name = linux.find_route_interface_by_destination_ip(mon_ip)
44+
shell.run("iptables -t nat -A PREROUTING -s %s -d %s -p tcp --dport 3260 -j DNAT --to-destination %s:3260" %
45+
(self.instance_obj.provision_ip, instance_gateway_ip, mon_ip))
46+
shell.run("iptables -t nat -A POSTROUTING -s %s -o %s -j SNAT --to-source %s" % (
47+
self.instance_obj.provision_ip, dev_name, mon_ip))
48+
49+
def destroy_instance_resource(self):
50+
instance_gateway_ip = self.instance_obj.gateway_ip
51+
mon_ip = self.volume_obj.monIp
52+
dev_name = linux.find_route_interface_by_destination_ip(mon_ip)
53+
shell.run("iptables -t nat -D PREROUTING -s %s -d %s -p tcp --dport 3260 -j DNAT --to-destination %s:3260" %
54+
(self.instance_obj.provision_ip, instance_gateway_ip, mon_ip))
55+
shell.run("iptables -t nat -D POSTROUTING -s %s -o %s -j SNAT --to-source %s" % (
56+
self.instance_obj.provision_ip, dev_name, mon_ip))
57+
58+
def pre_take_volume_snapshot(self):
59+
pass
60+
61+
def post_take_volume_snapshot(self, src_vol):
62+
pass
63+
64+
def resume(self):
65+
pass
66+
67+
def rollback_volume_snapshot(self, src_vol):
68+
pass
69+
70+
def get_lun_id(self):
71+
pass
72+
73+
def roll_back_attach_volume(self):
74+
self.detach_volume()

0 commit comments

Comments
 (0)