Skip to content

Commit 0bd2f28

Browse files
committed
add xcp83 resource and appropriate patch file for py3 compatibility
1 parent e8828e5 commit 0bd2f28

File tree

4 files changed

+338
-0
lines changed

4 files changed

+338
-0
lines changed

plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscoverer.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import javax.naming.ConfigurationException;
3131
import javax.persistence.EntityExistsException;
3232

33+
import com.cloud.hypervisor.xenserver.resource.XcpServer83Resource;
3334
import com.cloud.hypervisor.xenserver.resource.Xenserver84Resource;
3435
import org.apache.cloudstack.hypervisor.xenserver.XenserverConfigs;
3536
import org.apache.commons.collections.CollectionUtils;
@@ -438,6 +439,8 @@ else if (prodBrand.equals("XenServer") && prodVersion.equals("5.6.0")) {
438439
return new XcpOssResource();
439440
} else if (prodBrand.equals("XenServer") && prodVersion.equals("8.4.0")) {
440441
return new Xenserver84Resource();
442+
} else if (prodBrand.equals("XCP-ng") && (prodVersion.equals("8.3.0"))) {
443+
return new XcpServer83Resource();
441444
} else if (prodBrand.equals("XenServer") || prodBrand.equals("XCP-ng") || prodBrand.equals("Citrix Hypervisor")) {
442445
final String[] items = prodVersion.split("\\.");
443446
if ((Integer.parseInt(items[0]) > 6) ||
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.cloud.hypervisor.xenserver.resource;
2+
3+
public class XcpServer83Resource extends XenServer650Resource {
4+
5+
@Override
6+
protected String getPatchFilePath() {
7+
return "scripts/vm/hypervisor/xenserver/xcpserver83/patch";
8+
}
9+
}
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
#!/usr/bin/env python3
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
# FileSR: local-file storage repository
19+
20+
import SR, VDI, SRCommand, FileSR, util
21+
import errno
22+
import os, re, sys, stat
23+
import time
24+
import xml.dom.minidom
25+
import xs_errors
26+
import nfs
27+
import vhdutil
28+
from lock import Lock
29+
import cleanup
30+
31+
CAPABILITIES = ["SR_PROBE","SR_UPDATE", "SR_CACHING", \
32+
"VDI_CREATE","VDI_DELETE","VDI_ATTACH","VDI_DETACH", \
33+
"VDI_UPDATE", "VDI_CLONE","VDI_SNAPSHOT","VDI_RESIZE", \
34+
"VDI_RESIZE_ONLINE", "VDI_RESET_ON_BOOT", "ATOMIC_PAUSE"]
35+
36+
CONFIGURATION = [ [ 'server', 'hostname or IP address of NFS server (required)' ], \
37+
[ 'serverpath', 'path on remote server (required)' ] ]
38+
39+
40+
DRIVER_INFO = {
41+
'name': 'NFS VHD',
42+
'description': 'SR plugin which stores disks as VHD files on a remote NFS filesystem',
43+
'vendor': 'The Apache Software Foundation',
44+
'copyright': 'Copyright (c) 2012 The Apache Software Foundation',
45+
'driver_version': '1.0',
46+
'required_api_version': '1.0',
47+
'capabilities': CAPABILITIES,
48+
'configuration': CONFIGURATION
49+
}
50+
51+
52+
# The mountpoint for the directory when performing an sr_probe. All probes
53+
PROBE_MOUNTPOINT = "probe"
54+
NFSPORT = 2049
55+
DEFAULT_TRANSPORT = "tcp"
56+
57+
58+
class NFSSR(FileSR.FileSR):
59+
"""NFS file-based storage repository"""
60+
def handles(type):
61+
return type == 'nfs'
62+
handles = staticmethod(handles)
63+
64+
65+
def load(self, sr_uuid):
66+
self.ops_exclusive = FileSR.OPS_EXCLUSIVE
67+
self.lock = Lock(vhdutil.LOCK_TYPE_SR, self.uuid)
68+
self.sr_vditype = SR.DEFAULT_TAP
69+
if not self.dconf.has_key('server'):
70+
raise xs_errors.XenError('ConfigServerMissing')
71+
self.remoteserver = self.dconf['server']
72+
self.path = os.path.join(SR.MOUNT_BASE, sr_uuid)
73+
74+
# Test for the optional 'nfsoptions' dconf attribute
75+
self.transport = DEFAULT_TRANSPORT
76+
if self.dconf.has_key('useUDP') and self.dconf['useUDP'] == 'true':
77+
self.transport = "udp"
78+
79+
80+
def validate_remotepath(self, scan):
81+
if not self.dconf.has_key('serverpath'):
82+
if scan:
83+
try:
84+
self.scan_exports(self.dconf['server'])
85+
except:
86+
pass
87+
raise xs_errors.XenError('ConfigServerPathMissing')
88+
if not self._isvalidpathstring(self.dconf['serverpath']):
89+
raise xs_errors.XenError('ConfigServerPathBad', \
90+
opterr='serverpath is %s' % self.dconf['serverpath'])
91+
92+
def check_server(self):
93+
try:
94+
nfs.check_server_tcp(self.remoteserver)
95+
except nfs.NfsException as exc:
96+
raise xs_errors.XenError('NFSVersion',
97+
opterr=exc.errstr)
98+
99+
100+
def mount(self, mountpoint, remotepath):
101+
try:
102+
nfs.soft_mount(mountpoint, self.remoteserver, remotepath, self.transport)
103+
except nfs.NfsException as exc:
104+
raise xs_errors.XenError('NFSMount', opterr=exc.errstr)
105+
106+
107+
def attach(self, sr_uuid):
108+
self.validate_remotepath(False)
109+
#self.remotepath = os.path.join(self.dconf['serverpath'], sr_uuid)
110+
self.remotepath = self.dconf['serverpath']
111+
util._testHost(self.dconf['server'], NFSPORT, 'NFSTarget')
112+
self.mount_remotepath(sr_uuid)
113+
114+
115+
def mount_remotepath(self, sr_uuid):
116+
if not self._checkmount():
117+
self.check_server()
118+
self.mount(self.path, self.remotepath)
119+
120+
return super(NFSSR, self).attach(sr_uuid)
121+
122+
123+
def probe(self):
124+
# Verify NFS target and port
125+
util._testHost(self.dconf['server'], NFSPORT, 'NFSTarget')
126+
127+
self.validate_remotepath(True)
128+
self.check_server()
129+
130+
temppath = os.path.join(SR.MOUNT_BASE, PROBE_MOUNTPOINT)
131+
132+
self.mount(temppath, self.dconf['serverpath'])
133+
try:
134+
return nfs.scan_srlist(temppath)
135+
finally:
136+
try:
137+
nfs.unmount(temppath, True)
138+
except:
139+
pass
140+
141+
142+
def detach(self, sr_uuid):
143+
"""Detach the SR: Unmounts and removes the mountpoint"""
144+
if not self._checkmount():
145+
return
146+
util.SMlog("Aborting GC/coalesce")
147+
cleanup.abort(self.uuid)
148+
149+
# Change directory to avoid unmount conflicts
150+
os.chdir(SR.MOUNT_BASE)
151+
152+
try:
153+
nfs.unmount(self.path, True)
154+
except nfs.NfsException as exc:
155+
raise xs_errors.XenError('NFSUnMount', opterr=exc.errstr)
156+
157+
return super(NFSSR, self).detach(sr_uuid)
158+
159+
160+
def create(self, sr_uuid, size):
161+
util._testHost(self.dconf['server'], NFSPORT, 'NFSTarget')
162+
self.validate_remotepath(True)
163+
if self._checkmount():
164+
raise xs_errors.XenError('NFSAttached')
165+
166+
# Set the target path temporarily to the base dir
167+
# so that we can create the target SR directory
168+
self.remotepath = self.dconf['serverpath']
169+
try:
170+
self.mount_remotepath(sr_uuid)
171+
except Exception as exn:
172+
try:
173+
os.rmdir(self.path)
174+
except:
175+
pass
176+
raise exn
177+
178+
#newpath = os.path.join(self.path, sr_uuid)
179+
#if util.ioretry(lambda: util.pathexists(newpath)):
180+
# if len(util.ioretry(lambda: util.listdir(newpath))) != 0:
181+
# self.detach(sr_uuid)
182+
# raise xs_errors.XenError('SRExists')
183+
#else:
184+
# try:
185+
# util.ioretry(lambda: util.makedirs(newpath))
186+
# except util.CommandException, inst:
187+
# if inst.code != errno.EEXIST:
188+
# self.detach(sr_uuid)
189+
# raise xs_errors.XenError('NFSCreate',
190+
# opterr='remote directory creation error is %d'
191+
# % inst.code)
192+
self.detach(sr_uuid)
193+
194+
def delete(self, sr_uuid):
195+
# try to remove/delete non VDI contents first
196+
super(NFSSR, self).delete(sr_uuid)
197+
try:
198+
if self._checkmount():
199+
self.detach(sr_uuid)
200+
201+
# Set the target path temporarily to the base dir
202+
# so that we can remove the target SR directory
203+
self.remotepath = self.dconf['serverpath']
204+
self.mount_remotepath(sr_uuid)
205+
newpath = os.path.join(self.path, sr_uuid)
206+
207+
if util.ioretry(lambda: util.pathexists(newpath)):
208+
util.ioretry(lambda: os.rmdir(newpath))
209+
self.detach(sr_uuid)
210+
except util.CommandException as inst:
211+
self.detach(sr_uuid)
212+
if inst.code != errno.ENOENT:
213+
raise xs_errors.XenError('NFSDelete')
214+
215+
def vdi(self, uuid, loadLocked = False):
216+
if not loadLocked:
217+
return NFSFileVDI(self, uuid)
218+
return NFSFileVDI(self, uuid)
219+
220+
def _checkmount(self):
221+
return util.ioretry(lambda: util.pathexists(self.path)) \
222+
and util.ioretry(lambda: util.ismount(self.path))
223+
224+
def scan_exports(self, target):
225+
util.SMlog("scanning2 (target=%s)" % target)
226+
dom = nfs.scan_exports(target)
227+
print >>sys.stderr,dom.toprettyxml()
228+
229+
class NFSFileVDI(FileSR.FileVDI):
230+
def attach(self, sr_uuid, vdi_uuid):
231+
try:
232+
vdi_ref = self.sr.srcmd.params['vdi_ref']
233+
self.session.xenapi.VDI.remove_from_xenstore_data(vdi_ref, \
234+
"vdi-type")
235+
self.session.xenapi.VDI.remove_from_xenstore_data(vdi_ref, \
236+
"storage-type")
237+
self.session.xenapi.VDI.add_to_xenstore_data(vdi_ref, \
238+
"storage-type", "nfs")
239+
except:
240+
util.logException("NFSSR:attach")
241+
pass
242+
return super(NFSFileVDI, self).attach(sr_uuid, vdi_uuid)
243+
244+
def get_mtime(self, path):
245+
st = util.ioretry_stat(lambda: os.stat(path))
246+
return st[stat.ST_MTIME]
247+
248+
def clone(self, sr_uuid, vdi_uuid):
249+
timestamp_before = int(self.get_mtime(self.sr.path))
250+
ret = super(NFSFileVDI, self).clone(sr_uuid, vdi_uuid)
251+
timestamp_after = int(self.get_mtime(self.sr.path))
252+
if timestamp_after == timestamp_before:
253+
util.SMlog("SR dir timestamp didn't change, updating")
254+
timestamp_after += 1
255+
os.utime(self.sr.path, (timestamp_after, timestamp_after))
256+
return ret
257+
258+
259+
if __name__ == '__main__':
260+
SRCommand.run(NFSSR, DRIVER_INFO)
261+
else:
262+
SR.registerSR(NFSSR)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
# This file specifies the files that need
19+
#
20+
# to be transferred over to the XenServer.
21+
# The format of this file is as follows:
22+
# [Name of file]=[source path],[file permission],[destination path]
23+
# [destination path] is required.
24+
# If [file permission] is missing, 755 is assumed.
25+
# If [source path] is missing, it looks in the same
26+
# directory as the patch file.
27+
# If [source path] starts with '/', then it is absolute path.
28+
# If [source path] starts with '~', then it is path relative to management server home directory.
29+
# If [source path] does not start with '/' or '~', then it is relative path to the location of the patch file.
30+
NFSSR.py=/opt/xensource/sm
31+
vmops=../xenserver84/,0755,/etc/xapi.d/plugins
32+
ovstunnel=..,0755,/etc/xapi.d/plugins
33+
vmopsSnapshot=../xenserver84/,0755,/etc/xapi.d/plugins
34+
agent.zip=../../../../../vms,0644,/opt/xensource/packages/resources/
35+
cloud-scripts.tgz=../../../../../vms,0644,/opt/xensource/packages/resources/
36+
patch-sysvms.sh=../../../../../vms,0644,/opt/xensource/packages/resources/
37+
id_rsa.cloud=../../../systemvm,0600,/root/.ssh
38+
network_info.sh=..,0755,/opt/cloud/bin
39+
setupxenserver.sh=..,0755,/opt/cloud/bin
40+
make_migratable.sh=..,0755,/opt/cloud/bin
41+
setup_iscsi.sh=..,0755,/opt/cloud/bin
42+
pingtest.sh=../../..,0755,/opt/cloud/bin
43+
router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin
44+
cloud-setup-bonding.sh=..,0755,/opt/cloud/bin
45+
copy_vhd_to_secondarystorage.sh=..,0755,/opt/cloud/bin
46+
copy_vhd_from_secondarystorage.sh=..,0755,/opt/cloud/bin
47+
setup_heartbeat_sr.sh=..,0755,/opt/cloud/bin
48+
setup_heartbeat_file.sh=..,0755,/opt/cloud/bin
49+
check_heartbeat.sh=..,0755,/opt/cloud/bin
50+
xenheartbeat.sh=..,0755,/opt/cloud/bin
51+
launch_hb.sh=..,0755,/opt/cloud/bin
52+
vhd-util=..,0755,/opt/cloud/bin
53+
vmopspremium=../xenserver84/,0755,/etc/xapi.d/plugins
54+
create_privatetemplate_from_snapshot.sh=..,0755,/opt/cloud/bin
55+
upgrade_snapshot.sh=..,0755,/opt/cloud/bin
56+
cloud-clean-vlan.sh=..,0755,/opt/cloud/bin
57+
cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin
58+
add_to_vcpus_params_live.sh=..,0755,/opt/cloud/bin
59+
60+
###add cloudstack plugin script for XCP
61+
cloudstack_plugins.conf=..,0644,/etc/xensource
62+
cloudstack_pluginlib.py=../xenserver84/,0755,/etc/xapi.d/plugins
63+
cloudlog=..,0644,/etc/logrotate.d
64+
update_host_passwd.sh=../..,0755,/opt/cloud/bin

0 commit comments

Comments
 (0)