1nbdkit-python-plugin(3)             NBDKIT             nbdkit-python-plugin(3)
2
3
4

NAME

6       nbdkit-python-plugin - nbdkit python plugin
7

SYNOPSIS

9        nbdkit python /path/to/plugin.py [arguments...]
10

DESCRIPTION

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

WRITING A PYTHON NBDKIT PLUGIN

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

SEE ALSO

248       nbdkit(1), nbdkit-plugin(3), python(1).
249

AUTHORS

251       Eric Blake
252
253       Richard W.M. Jones
254
256       Copyright (C) 2013-2018 Red Hat Inc.
257

LICENSE

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-22           nbdkit-python-plugin(3)
Impressum