]> git.datanom.net - omvzfs.git/blob - src/Utils.php
Added method to add ZFS pool to OMV mountpoint backend.
[omvzfs.git] / src / Utils.php
1 <?php
2 require_once("Exception.php");
3 require_once("openmediavault/util.inc");
4 require_once("Dataset.php");
5
6 /**
7 * Helper class for ZFS module
8 */
9 class OMVModuleZFSUtil {
10
11 /**
12 * Get UUID of ZFS pool by name
13 *
14 * @return string UUID of the pool
15 */
16 public static function getUUIDbyName($name) {
17 preg_match('/^([A-Za-z0-9]+)\/?.*$/', $name, $result);
18 $name = $result[1];
19 unset($result);
20 $cmd = "blkid -o full";
21 OMVModuleZFSUtil::exec($cmd, $out, $res);
22 foreach($out as $line) {
23 if(preg_match('/^.*LABEL=\"' . $name . '\" UUID=\"([A-Za-z0-9]+)\".*TYPE=\"zfs_member\"$/', $line, $result)) {
24 return($result[1]);
25 }
26 }
27 return null;
28 }
29
30 /**
31 * Add any missing ZFS pool to the OMV backend
32 *
33 */
34 public static function addMissingOMVMntEnt() {
35 global $xmlConfig;
36 $msg = "";
37 $cmd = "zpool list -H -o name";
38 OMVModuleZFSUtil::exec($cmd, $out, $res);
39 foreach($out as $name) {
40 $pooluuid = OMVModuleZFSUtil::getUUIDbyName($name);
41 $xpath = "//system/fstab/mntent[fsname=" . $pooluuid . "]";
42 $object = $xmlConfig->get($xpath);
43 if(is_null($object)) {
44 $uuid = OMVUtil::uuid();
45 $ds = new OMVModuleZFSDataset($name);
46 $dir = $ds->getMountPoint();
47 $object = array(
48 "uuid" => $uuid,
49 "fsname" => $pooluuid,
50 "dir" => $dir,
51 "type" => "zfs",
52 "opts" => "rw,relatime,xattr",
53 "freq" => "0",
54 "passno" => "2"
55 );
56 $xmlConfig->set("//system/fstab",array("mntent" => $object));
57 $dispatcher = &OMVNotifyDispatcher::getInstance();
58 $dispatcher->notify(OMV_NOTIFY_CREATE,"org.openmediavault.system.fstab.mntent", $object);
59 }
60 }
61 return null;
62 }
63
64 /**
65 * Get an array with all ZFS objects
66 *
67 * @return An array with all ZFS objects
68 */
69 public static function getZFSFlatArray() {
70 $prefix = "root/pool-";
71 $objects = array();
72 $cmd = "zfs list -H -t all -o name,type 2>&1";
73 $expanded = true;
74 OMVModuleZFSUtil::exec($cmd,$out,$res);
75 foreach ($out as $line) {
76 $parts = preg_split('/\t/',$line);
77 $path = $parts[0];
78 $type = $parts[1];
79 $subdirs = preg_split('/\//',$path);
80 $root = $subdirs[0];
81 $tmp = array();
82
83 switch ($type) {
84 case "filesystem":
85 if (strpos($path,'/') === false) {
86 //This is a Pool, thus create both the Pool entry and a Filesystem entry corresponding to the Pool.
87 $tmp = array('id'=>$prefix . $path,
88 'parentid'=>'root',
89 'name'=>$path,
90 'type'=>'Pool',
91 'icon'=>'images/raid.png',
92 'expanded'=>$expanded,
93 'path'=>$path);
94 array_push($objects,$tmp);
95 $tmp = array('id'=>$prefix . $path . '/' . $path,
96 'parentid'=>$prefix . $path,
97 'name'=>$path,
98 'type'=>'Filesystem',
99 'icon'=>'images/filesystem.png',
100 'path'=>$path,
101 'expanded'=>$expanded);
102 array_push($objects,$tmp);
103 } else {
104 //This is a Filesystem other than the Pool
105 preg_match('/(.*)\/(.*)$/', $path, $result);
106 $tmp = array('id'=>$prefix . $root . "/" . $path,
107 'parentid'=>$prefix . $root . "/" . $result[1],
108 'name'=>$result[2],
109 'icon'=>"images/filesystem.png",
110 'path'=>$path,
111 'expanded'=>$expanded);
112 $ds = new OMVModuleZFSDataset($path);
113 if ($ds->isClone()) {
114 //This is a cloned Filesystem
115 $tmp['type'] = "Clone";
116 $tmp['origin'] = $ds->getOrigin();
117 } else {
118 //This is a standard Filesystem.
119 $tmp['type']= ucfirst($type);
120 }
121 array_push($objects,$tmp);
122 }
123 break;
124
125 case "volume":
126 preg_match('/(.*)\/(.*)$/', $path, $result);
127 $tmp = array('id'=>$prefix . $root . "/" . $path,
128 'parentid'=>$prefix . $root . "/" . $result[1],
129 'name'=>$result[2],
130 'type'=>ucfirst($type),
131 'icon'=>"images/zfs_disk.png",
132 'path'=>$path,
133 'expanded'=>$expanded);
134 array_push($objects,$tmp);
135 break;
136
137 case "snapshot":
138 preg_match('/(.*)\@(.*)$/', $path, $result);
139 $subdirs = preg_split('/\//',$result[1]);
140 $root = $subdirs[0];
141 $tmp = array('id'=>$prefix . $root . "/" . $path,
142 'parentid'=>$prefix . $root . "/" . $result[1],
143 'name'=>$result[2],
144 'type'=>ucfirst($type),
145 'icon'=>'images/zfs_snap.png',
146 'path'=>$path,
147 'expanded'=>$expanded);
148 array_push($objects,$tmp);
149 break;
150
151 default:
152 break;
153 }
154 }
155 return $objects;
156 }
157
158 /**
159 * Create a tree structured array
160 *
161 * @param &$list The flat array to convert to a tree structure
162 * @param $parent Root node of the tree to create
163 * @return Tree structured array
164 *
165 */
166 public static function createTree(&$list, $parent){
167 $tree = array();
168 foreach ($parent as $k=>$l){
169 if(isset($list[$l['id']])){
170 $l['leaf'] = false;
171 $l['children'] = OMVModuleZFSUtil::createTree($list, $list[$l['id']]);
172 } else {
173 $l['leaf'] = true;
174 }
175 $tree[] = $l;
176 }
177 return $tree;
178 }
179
180 /**
181 * Get all Datasets as objects
182 *
183 * @return An array with all the Datasets
184 */
185 public static function getAllDatasets() {
186 $datasets = array();
187 $cmd = "zfs list -H -t filesystem -o name 2>&1";
188 OMVModuleZFSUtil::exec($cmd, $out, $res);
189 foreach ($out as $name) {
190 $ds = new OMVModuleZFSDataset($name);
191 array_push($datasets, $ds);
192 }
193 return $datasets;
194 }
195
196 /**
197 * Helper function to execute a command and throw an exception on error
198 * (requires stderr redirected to stdout for proper exception message).
199 *
200 * @param string $cmd Command to execute
201 * @param array &$out If provided will contain output in an array
202 * @param int &$res If provided will contain Exit status of the command
203 * @return string Last line of output when executing the command
204 * @throws OMVModuleZFSException
205 * @access public
206 */
207 public static function exec($cmd, &$out = null, &$res = null) {
208 $tmp = OMVUtil::exec($cmd, $out, $res);
209 if ($res) {
210 throw new OMVModuleZFSException(implode("\n", $out));
211 }
212 return $tmp;
213 }
214
215 }
216
217
218 ?>
This page took 0.083304 seconds and 6 git commands to generate.