@@ -183,6 +183,48 @@ let process root_dir name x =
183183 let features = List. map ~f: (function
184184 | "VDI_DESTROY" -> " VDI_DELETE"
185185 | x -> x) response.Storage.Plugin.Types. features in
186+ (* Look for executable scripts and automatically add capabilities *)
187+ let rec loop acc = function
188+ | [] -> return (Ok acc)
189+ | (s , capability ) :: rest ->
190+ let open Deferred.Monad_infix in
191+ let script_name = script root_dir name `Volume s in
192+ ( Sys. is_file ~follow_symlinks: true script_name
193+ >> = function
194+ | `No | `Unknown ->
195+ return false
196+ | `Yes ->
197+ ( Unix. access script_name [ `Exec ]
198+ >> = function
199+ | Error exn ->
200+ return false
201+ | Ok () ->
202+ return true
203+ )
204+ ) >> = function
205+ | false -> loop acc rest
206+ | true -> loop (capability :: acc) rest in
207+ loop [] [
208+ " SR.attach" , " SR_ATTACH" ;
209+ " SR.create" , " SR_CREATE" ;
210+ " SR.destroy" , " SR_DELETE" ;
211+ " SR.detach" , " SR_DETACH" ;
212+ " SR.ls" , " SR_SCAN" ;
213+ " SR.stat" , " SR_UPDATE" ;
214+ " Volume.create" , " VDI_CREATE" ;
215+ " Volume.clone" , " VDI_CLONE" ;
216+ " Volume.snapshot" , " VDI_SNAPSHOT" ;
217+ " Volume.resize" , " VDI_RESIZE" ;
218+ " Volume.destroy" , " VDI_DELETE" ;
219+ " Volume.stat" , " VDI_UPDATE" ;
220+ ]
221+ >> = fun x ->
222+ let features = features @ x in
223+ (* Add the features we always have *)
224+ let features = features @ [
225+ " VDI_ATTACH" ; " VDI_DETACH" ; " VDI_ACTIVATE" ; " VDI_DEACTIVATE" ;
226+ " VDI_INTRODUCE"
227+ ] in
186228 let response = {
187229 driver = response.Storage.Plugin.Types. plugin;
188230 name = response.Storage.Plugin.Types. name;
0 commit comments