]> git.datanom.net - omvzfs.git/blob - gui/rpc/zfs.inc
Support force create pools.
[omvzfs.git] / gui / rpc / zfs.inc
1 <?php
2
3 require_once("openmediavault/object.inc");
4 require_once("openmediavault/config.inc");
5 require_once("openmediavault/error.inc");
6 require_once("openmediavault/util.inc");
7 require_once("openmediavault/rpcservice.inc");
8 require_once("openmediavault/notify.inc");
9 require_once("zfs/Utils.php");
10 require_once("zfs/Dataset.php");
11 require_once("zfs/Snapshot.php");
12 require_once("zfs/Zvol.php");
13 require_once("zfs/Zpool.php");
14 require_once("zfs/NotifyListener.php");
15
16 class OMVRpcServiceZFS extends OMVRpcServiceAbstract {
17 public function getName() {
18 return "ZFS"; // RPC Service name. Same as in .js files
19 }
20
21 /* Initialize the RPC service. Different methods of the RPC service are declared here*/
22 public function initialize() {
23 $this->registerMethod("addPool");
24 $this->registerMethod("getObjectTree");
25 $this->registermethod("passParam");
26 $this->registermethod("addObject");
27 $this->registermethod("deleteObject");
28 $this->registermethod("getProperties");
29 $this->registermethod("setProperties");
30 $this->registermethod("inherit");
31 $this->registermethod("getSharedParams");
32 $this->registermethod("createShare");
33 }
34
35 public function addPool($params, $context) {
36 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
37 switch ($params['pooltype']) {
38 case "basic":
39 $pooltype = OMVModuleZFSVdevType::OMVMODULEZFSPLAIN;
40 break;
41 case "mirror":
42 $pooltype = OMVModuleZFSVdevType::OMVMODULEZFSMIRROR;
43 break;
44 case "raidz1":
45 $pooltype = OMVModuleZFSVdevType::OMVMODULEZFSRAIDZ1;
46 break;
47 case "raidz2":
48 $pooltype = OMVModuleZFSVdevType::OMVMODULEZFSRAIDZ2;
49 break;
50 case "raidz3":
51 $pooltype = OMVModuleZFSVdevType::OMVMODULEZFSRAIDZ3;
52 break;
53 default:
54 throw new OMVModuleZFSException("Incorrect pool type specified");
55 break;
56 }
57 //Check for user supplied options
58 $opts = "";
59 if ($params['force']) {
60 $opts .= "-f ";
61 }
62 $disks = preg_split("/[,;]/", $params['devices']);
63 $vdev = new OMVModuleZFSVdev($params['name'], $pooltype, $disks);
64 $pool = new OMVModuleZFSZpool($vdev, $opts);
65 //Ugly fix to solve the problem of blkid not displaying info on newly created pools
66 $pool->export();
67 $pool->import($pool->getName());
68 }
69
70 public function getObjectTree($params, $context) {
71 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
72 $objects = OMVModuleZFSUtil::getZFSFlatArray();
73 $new = array();
74 foreach ($objects as $a){
75 $new[$a['parentid']][] = $a;
76 }
77 $tree = OMVModuleZFSUtil::createTree($new, $new['root']);
78 OMVModuleZFSUtil::addMissingOMVMntEnt(); //Adds missing ZFS filesystems to the OMV core
79 return $tree;
80 }
81
82 public function passParam($params, $context) {
83 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
84 //$msg = "Key=" . $params['key'] . ";Value=" . $params['value'] . ";";
85 //throw new OMVModuleZFSException($msg);
86 return array($params['key'] => $params['value']);
87 }
88
89 public function addObject($params, $context) {
90 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
91 switch ($params['type']) {
92 case "filesystem":
93 $name = $params['path'] . "/" . $params['name'];
94 $tmp = new OMVModuleZFSDataset($name);
95 break;
96 case "snapshot":
97 $name = $params['path'] . "@" . $params['name'];
98 $tmp = new OMVModuleZFSSnapshot($name);
99 break;
100 case "volume":
101 $name = $params['path'] . "/" . $params['name'];
102 $tmp = new OMVModuleZFSZvol($name);
103 $tmp->create($params['size']);
104 break;
105 default:
106 throw new OMVModuleZFSException("Illegal type provided: " . $params['type']);
107 break;
108 }
109 }
110
111 public function deleteObject($params, $context) {
112 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
113 switch ($params['type']) {
114 case "Filesystem":
115 case "Clone":
116 $name = $params['name'];
117 $tmp = new OMVModuleZFSDataset($name);
118 $tmp->destroy();
119 break;
120 case "Snapshot":
121 $name = $params['name'];
122 $tmp = new OMVModuleZFSSnapshot($name);
123 $tmp->destroy();
124 break;
125 case "Volume":
126 $name = $params['name'];
127 $tmp = new OMVModuleZFSZvol($name);
128 $tmp->destroy();
129 break;
130 case "Pool":
131 $name = $params['name'];
132 $tmp = new OMVModuleZFSZpool($name);
133 $tmp->destroy();
134 break;
135 default:
136 throw new OMVModuleZFSException("Illegal type provided: " . $params['type']);
137 break;
138 }
139 }
140
141 public function getProperties($params, $context) {
142 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
143 $objects = array();
144 $name = $params['name'];
145 switch ($params['type']) {
146 case "Filesystem":
147 case "Clone":
148 $tmp = new OMVModuleZFSDataset($name);
149 break;
150 case "Snapshot":
151 $tmp = new OMVModuleZFSSnapshot($name);
152 break;
153 case "Volume":
154 $tmp = new OMVModuleZFSZvol($name);
155 break;
156 case "Pool":
157 $tmp = new OMVModuleZFSZpool($name);
158 break;
159 default:
160 throw new OMVModuleZFSException("Illegal type provided: " . $params['type']);
161 break;
162 }
163 $properties = $tmp->getProperties();
164 foreach ($properties as $propertyk => $propertyv) {
165 if (!(strcmp($propertyv['source'], "-") == 0)) {
166 $objects[] = array('property' => $propertyk,
167 'value' => $propertyv['value'],
168 'source' => $propertyv['source'],
169 'modified' => "false");
170 }
171 }
172 return $objects;
173 }
174
175 public function setProperties($params, $context) {
176 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
177 $objects = array();
178 switch ($params['type']) {
179 case "Filesystem":
180 case "Clone":
181 $tmp = new OMVModuleZFSDataset($params['name']);
182 break;
183 case "Snapshot":
184 $tmp = new OMVModuleZFSSnapshot($params['name']);
185 break;
186 case "Volume":
187 $tmp = new OMVModuleZFSZvol($params['name']);
188 break;
189 case "Pool":
190 $tmp = new OMVModuleZFSZpool($params['name']);
191 break;
192 default:
193 throw new OMVModuleZFSException("Illegal type provided: " . $params['type']);
194 break;
195 }
196 foreach ($params['properties'] as $property) {
197 $objects[$property['property']] = $property['value'];
198 }
199 $tmp->setProperties($objects);
200 }
201
202 public function inherit($params, $context) {
203 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
204 // Create a background process.
205 $bgStatusFilename = $this->createBgProcStatus();
206 $pid = $this->fork();
207 if($pid > 0) { // Parent process.
208 $this->initializeBgProcStatus($bgStatusFilename, $pid);
209 return $bgStatusFilename;
210 }
211 // Child process.
212 try {
213 $bgOutputFilename = $this->createBgProcOutput();
214 $this->updateBgProcStatus($bgStatusFilename, "outputfilename", $bgOutputFilename);
215 switch ($params['type']) {
216 case "Filesystem":
217 case "Clone":
218 $tmp = new OMVModuleZFSDataset($params['name']);
219 break;
220 case "Snapshot":
221 $tmp = new OMVModuleZFSSnapshot($params['name']);
222 break;
223 case "Volume":
224 $tmp = new OMVModuleZFSZvol($params['name']);
225 break;
226 case "Pool":
227 $tmp = new OMVModuleZFSZpool($params['name']);
228 break;
229 default:
230 throw new OMVModuleZFSException("Illegal type provided: " . $params['type']);
231 break;
232 }
233 $tmp->inherit($params['property']);
234 $this->finalizeBgProcStatus($bgStatusFilename, $output);
235 exit(0);
236 } catch(Exception $e) {
237 $this->finalizeBgProcStatus($bgStatusFilename, "", $e);
238 exit(1);
239 }
240 }
241
242 public function getSharedParams($params, $context) {
243 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
244 $objects = array();
245 $ds = new OMVModuleZFSDataset($params['name']);
246 $mountpoint = $ds->getMountPoint();
247 return array(
248 "mountpoint" => $mountpoint,
249 "name" => $params['name'],
250 "type" => $params['type']);
251 }
252
253 public function createShare($params, $context) {
254 global $xmlConfig;
255 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
256
257 //Get the UUID of the Pool
258 $pooluuid = OMVModuleZFSUtil::getUUIDbyName($params['name']);
259 preg_match('/^([A-Za-z0-9]+)\/?.*$/', $params['name'], $result);
260 $poolname = $result[1];
261 unset($result);
262
263 //Get the mntent object and fetch it's uuid.
264 $xpath = "//system/fstab/mntent[fsname=" . $pooluuid . "]";
265 $object = $xmlConfig->get($xpath);
266 $mntentref = $object['uuid'];
267
268 // Prepare the configuration object. Use the name of the shared
269 // folder as the relative directory name of the share.
270 switch ($params['type']) {
271 case "Filesystem":
272 $tmp = new OMVModuleZFSDataset($params['name']);
273 break;
274 case "Clone":
275 $tmp = new OMVModuleZFSDataset($params['name']);
276 break;
277 default:
278 throw new OMVModuleZFSException("Illegal type provided: " . $params['type']);
279 break;
280 }
281
282 $uuid = OMVUtil::uuid();
283 $pathName = $tmp->getMountPoint();
284 $subdirs = preg_split('/\//',$pathName);
285 $reldirpath = $subdirs[count($subdirs)-1];
286 $object = array(
287 "uuid" => $uuid,
288 "name" => $params['sharename'],
289 "comment" => $params['comment'],
290 "mntentref" => $mntentref,
291 "reldirpath" => $reldirpath
292 );
293
294 // Set the configuration object.
295 $success = FALSE;
296 // Check uniqueness. The share name must be global unique because
297 // the name is also used when exporting a shared folder via NFS for
298 // example.
299 $xpath = sprintf("//system/shares/sharedfolder[name='%s']",
300 $params['name']);
301 if(TRUE === $xmlConfig->exists($xpath)) {
302 throw new OMVException(OMVErrorMsg::E_CONFIG_OBJECT_UNIQUENESS,
303 gettext("A shared folder with the given name already exists"));
304 }
305
306 // Add empty list of privileges per default.
307 $object['privileges'] = array();
308
309 // Append object to configuration.
310 $success = $xmlConfig->set("//system/shares",
311 array("sharedfolder" => $object));
312 if(FALSE === $success) {
313 throw new OMVException(OMVErrorMsg::E_CONFIG_SET_OBJECT_FAILED);
314 }
315
316 // Append the file mode field to the notification object if set.
317 // Defaults to 775.
318 $object['mode'] = "775";
319 if(array_key_exists("mode", $params)) {
320 $object['mode'] = $params['mode'];
321 }
322
323 // Change group owner of directory to configured default group,
324 // e.g. 'users'.
325 if(FALSE === chgrp($pathName, $GLOBALS['OMV_USERMGMT_DEFAULT_GROUP'])) {
326 throw new OMVException(OMVErrorMsg::E_MISC_FAILURE,
327 sprintf("Failed to set file group to '%s' for '%s'",
328 $GLOBALS['OMV_USERMGMT_DEFAULT_GROUP'], $pathName));
329 }
330
331 // Set the setgid bit. Setting this permission means that all files
332 // created in the folder will inherit the group of the folder rather
333 // than the primary group of the user who creates the file.
334 $mode = fileperms($pathName) | 02000;
335 if(FALSE === chmod($pathName, $mode)) {
336 throw new OMVException(OMVErrorMsg::E_MISC_FAILURE,
337 sprintf("Failed to set file mode to '%o' for '%s'",
338 $mode, $pathName));
339 }
340
341 // Notify configuration changes.
342 $dispatcher = &OMVNotifyDispatcher::getInstance();
343 $dispatcher->notify(OMV_NOTIFY_CREATE,"org.openmediavault.system.shares.sharedfolder", $object);
344 // Return the configuration object.
345 return $object;
346 }
347
348 }
349
350 // Register the RPC service.
351 $rpcServiceMgr = &OMVRpcServiceMgr::getInstance(); // Get the "root" instance for the Services
352 $rpcServiceMgr->registerService(new OMVRpcServiceZFS()); // Register a new instance of the RPC service described above
353 ?>
354
This page took 0.155705 seconds and 6 git commands to generate.