1nbdkit-python-plugin(3) NBDKIT nbdkit-python-plugin(3)
2
3
4
6 nbdkit-python-plugin - nbdkit python plugin
7
9 nbdkit python /path/to/plugin.py [arguments...]
10
12 "nbdkit-python-plugin" is an embedded Python interpreter for nbdkit(1),
13 allowing you to write nbdkit plugins in Python.
14
15 If you have been given an nbdkit Python plugin
16 Assuming you have a Python script which is an nbdkit plugin, you run it
17 like this:
18
19 nbdkit python /path/to/plugin.py
20
21 You may have to add further "key=value" arguments to the command line.
22 Read the Python script to see if it requires any.
23
25 For an example plugin written in Python, see:
26 https://github.com/libguestfs/nbdkit/blob/master/plugins/python/example.py
27
28 Broadly speaking, Python nbdkit plugins work like C ones, so you should
29 read nbdkit-plugin(3) first.
30
31 To write a Python nbdkit plugin, you create a Python file which
32 contains at least the following required functions (in the top level
33 "__main__" module):
34
35 def open(readonly):
36 # see below
37 def get_size(h):
38 # see below
39 def pread(h, count, offset):
40 # see below
41
42 Note that the subroutines must have those literal names (like "open"),
43 because the C part looks up and calls those functions directly. You
44 may want to include documentation and globals (eg. for storing global
45 state). Any other top level statements are run when the script is
46 loaded, just like ordinary Python.
47
48 Python 2 and Python 3
49 The Python plugin has to be compiled for either Python 2 or Python 3
50 when building nbdkit. You can set the "PYTHON" environment variable to
51 the desired interpreter, otherwise nbdkit will use the interpreter
52 called "python" on the current $PATH. For example:
53
54 PYTHON=/usr/bin/python3 ./configure
55
56 To find out which version the Python plugin was compiled for, use the
57 --dump-plugin option, eg:
58
59 $ nbdkit python --dump-plugin
60 ...
61 python_version=3.7.0
62 python_pep_384_abi_version=3
63
64 Executable script
65 If you want you can make the script executable and include a "shebang"
66 at the top:
67
68 #!/usr/sbin/nbdkit python
69
70 See also "Shebang scripts" in nbdkit(1).
71
72 These scripts can also be installed in the $plugindir. See "WRITING
73 PLUGINS IN OTHER PROGRAMMING LANGUAGES" in nbdkit-plugin(3).
74
75 Methods
76 Your script may use "import nbdkit" to have access to the following
77 methods in the "nbdkit" module:
78
79 nbdkit.set_error(err)
80
81 Record "err" as the reason you are about to throw an exception. "err"
82 should correspond to usual errno values, where it may help to "import
83 errno".
84
85 Exceptions
86 Python callbacks should throw exceptions to indicate errors. Remember
87 to use "nbdkit.set_error" if you need to control which error is sent
88 back to the client; if omitted, the client will see an error of "EIO".
89
90 Python callbacks
91 This just documents the arguments to the callbacks in Python, and any
92 way that they differ from the C callbacks. In all other respects they
93 work the same way as the C callbacks, so you should go and read
94 nbdkit-plugin(3).
95
96 "dump_plugin"
97 (Optional)
98
99 There are no arguments or return value.
100
101 "config"
102 (Optional)
103
104 def config(key, value):
105 # no return value
106
107 "config_complete"
108 (Optional)
109
110 There are no arguments or return value.
111
112 "open"
113 (Required)
114
115 def open(readonly):
116 # return handle
117
118 You can return any non-NULL Python value as the handle. It is
119 passed back in subsequent calls.
120
121 "close"
122 (Optional)
123
124 def close(h):
125 # no return value
126
127 After "close" returns, the reference count of the handle is
128 decremented in the C part, which usually means that the handle and
129 its contents will be garbage collected.
130
131 "get_size"
132 (Required)
133
134 def get_size(h):
135 # return the size of the disk
136
137 "can_write"
138 (Optional)
139
140 def can_write(h):
141 # return a boolean
142
143 "can_flush"
144 (Optional)
145
146 def can_flush(h):
147 # return a boolean
148
149 "is_rotational"
150 (Optional)
151
152 def is_rotational(h):
153 # return a boolean
154
155 "can_trim"
156 (Optional)
157
158 def can_trim(h):
159 # return a boolean
160
161 "pread"
162 (Required)
163
164 def pread(h, count, offset):
165 # construct a bytearray of length count bytes and return it
166
167 The body of your "pread" function should construct a buffer of
168 length (at least) "count" bytes. You should read "count" bytes
169 from the disk starting at "offset".
170
171 NBD only supports whole reads, so your function should try to read
172 the whole region (perhaps requiring a loop). If the read fails or
173 is partial, your function should throw an exception, optionally
174 using "nbdkit.set_error" first.
175
176 "pwrite"
177 (Optional)
178
179 def pwrite(h, buf, offset):
180 length = len (buf)
181 # no return value
182
183 The body of your "pwrite" function should write the "buf" string to
184 the disk. You should write "count" bytes to the disk starting at
185 "offset".
186
187 NBD only supports whole writes, so your function should try to
188 write the whole region (perhaps requiring a loop). If the write
189 fails or is partial, your function should throw an exception,
190 optionally using "nbdkit.set_error" first.
191
192 "flush"
193 (Optional)
194
195 def flush(h):
196 # no return value
197
198 The body of your "flush" function should do a sync(2) or
199 fdatasync(2) or equivalent on the backing store.
200
201 If the flush fails, your function should throw an exception,
202 optionally using "nbdkit.set_error" first.
203
204 "trim"
205 (Optional)
206
207 def trim(h, count, offset):
208 # no return value
209
210 The body of your "trim" function should "punch a hole" in the
211 backing store. If the trim fails, your function should throw an
212 exception, optionally using "nbdkit.set_error" first.
213
214 "zero"
215 (Optional)
216
217 def zero(h, count, offset, may_trim):
218 # no return value
219
220 The body of your "zero" function should ensure that "count" bytes
221 of the disk, starting at "offset", will read back as zero. If
222 "may_trim" is true, the operation may be optimized as a trim as
223 long as subsequent reads see zeroes.
224
225 NBD only supports whole writes, so your function should try to
226 write the whole region (perhaps requiring a loop). If the write
227 fails or is partial, your function should throw an exception,
228 optionally using "nbdkit.set_error" first. In particular, if you
229 would like to automatically fall back to "pwrite" (perhaps because
230 there is nothing to optimize if "may_trim" is false), use
231 "nbdkit.set_error(errno.EOPNOTSUPP)".
232
233 Missing callbacks
234 Missing: "load" and "unload"
235 These are not needed because you can just use ordinary Python
236 constructs.
237
238 Missing: "name", "version", "longname", "description", "config_help"
239 These are not yet supported.
240
241 Threads
242 The thread model for Python callbacks currently cannot be set from
243 Python. It is hard-coded in the C part to
244 "NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS". This may change or be
245 settable in future.
246
248 nbdkit(1), nbdkit-plugin(3), python(1).
249
251 Eric Blake
252
253 Richard W.M. Jones
254
256 Copyright (C) 2013-2018 Red Hat Inc.
257
259 Redistribution and use in source and binary forms, with or without
260 modification, are permitted provided that the following conditions are
261 met:
262
263 · Redistributions of source code must retain the above copyright
264 notice, this list of conditions and the following disclaimer.
265
266 · Redistributions in binary form must reproduce the above copyright
267 notice, this list of conditions and the following disclaimer in the
268 documentation and/or other materials provided with the
269 distribution.
270
271 · Neither the name of Red Hat nor the names of its contributors may
272 be used to endorse or promote products derived from this software
273 without specific prior written permission.
274
275 THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ANY
276 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
277 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
278 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR CONTRIBUTORS BE
279 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
280 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
281 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
282 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
283 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
284 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
285 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286
287
288
289nbdkit-1.12.3 2019-05-21 nbdkit-python-plugin(3)