Coverage for drivers/ZFSSR.py : 63%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/env python3
2#
3# Copyright (C) 2020 Vates SAS
4#
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <https://www.gnu.org/licenses/>.
17import SR
18import SRCommand
20import FileSR
22import util
23import xs_errors
25CAPABILITIES = [
26 'SR_UPDATE',
27 'VDI_CREATE',
28 'VDI_DELETE',
29 'VDI_ATTACH',
30 'VDI_DETACH',
31 'VDI_CLONE',
32 'VDI_SNAPSHOT',
33 'VDI_RESIZE',
34 'VDI_MIRROR',
35 'VDI_GENERATE_CONFIG',
36 'ATOMIC_PAUSE',
37 'VDI_CONFIG_CBT',
38 'VDI_ACTIVATE',
39 'VDI_DEACTIVATE',
40 'THIN_PROVISIONING'
41]
43CONFIGURATION = [
44 ['location', 'local ZFS directory path (required)']
45]
47DRIVER_INFO = {
48 'name': 'Local ZFS VHD',
49 'description':
50 'SR plugin which represents disks as VHD files stored on a ZFS disk',
51 'vendor': 'Vates SAS',
52 'copyright': '(C) 2020 Vates SAS',
53 'driver_version': '1.0',
54 'required_api_version': '1.0',
55 'capabilities': CAPABILITIES,
56 'configuration': CONFIGURATION
57}
60def is_zfs_available():
61 import distutils.spawn
62 return distutils.spawn.find_executable('zfs') and \
63 util.pathexists('/sys/module/zfs/initstate')
66def is_zfs_path(path):
67 cmd = ['findmnt', '-o', 'FSTYPE', '-n', path]
68 fs_type = util.pread2(cmd).split('\n')[0]
69 return fs_type == 'zfs'
72class ZFSSR(FileSR.FileSR):
73 DRIVER_TYPE = 'zfs'
75 @staticmethod
76 def handles(type):
77 return type == ZFSSR.DRIVER_TYPE
79 def load(self, sr_uuid):
80 if not is_zfs_available():
81 raise xs_errors.XenError(
82 'SRUnavailable',
83 opterr='zfs is not installed or module is not loaded'
84 )
85 return super(ZFSSR, self).load(sr_uuid)
87 def create(self, sr_uuid, size):
88 if not is_zfs_path(self.remotepath):
89 raise xs_errors.XenError(
90 'ZFSSRCreate',
91 opterr='Cannot create SR, path is not a ZFS mountpoint'
92 )
93 return super(ZFSSR, self).create(sr_uuid, size)
95 def delete(self, sr_uuid):
96 if not self._checkmount():
97 raise xs_errors.XenError(
98 'ZFSSRDelete',
99 opterr='ZFS SR is not mounted or uses an invalid FS type'
100 )
101 return super(ZFSSR, self).delete(sr_uuid)
103 def attach(self, sr_uuid):
104 if not is_zfs_path(self.remotepath):
105 raise xs_errors.XenError(
106 'SRUnavailable',
107 opterr='Invalid ZFS path'
108 )
109 return super(ZFSSR, self).attach(sr_uuid)
111 def detach(self, sr_uuid):
112 return super(ZFSSR, self).detach(sr_uuid)
114 def vdi(self, uuid, loadLocked=False):
115 return ZFSFileVDI(self, uuid)
117 # Ensure _checkmount is overridden to prevent bad behaviors in FileSR.
118 def _checkmount(self):
119 return super(ZFSSR, self)._checkmount() and \
120 is_zfs_path(self.remotepath)
123class ZFSFileVDI(FileSR.FileVDI):
124 def attach(self, sr_uuid, vdi_uuid):
125 if not hasattr(self, 'xenstore_data'):
126 self.xenstore_data = {}
128 self.xenstore_data['storage-type'] = ZFSSR.DRIVER_TYPE
130 return super(ZFSFileVDI, self).attach(sr_uuid, vdi_uuid)
133if __name__ == '__main__': 133 ↛ 134line 133 didn't jump to line 134, because the condition on line 133 was never true
134 SRCommand.run(ZFSSR, DRIVER_INFO)
135else:
136 SR.registerSR(ZFSSR)