The rados module is a thin Python wrapper for librados. The source is available in /src/pybind/rados.py. You may also install it as a package.
To install Python libraries for Ceph, see Getting librados for Python.
You can create your own Ceph client using Python. The following tutorial will show you how to import the Ceph Python module, connect to a Ceph cluster, and perform object operations as a client.admin user.
Note
To use the Ceph Python bindings, you must have access to a running Ceph cluster. To set one up quickly, see Getting Started.
First, create a Python source file for your Ceph client.
sudo vim client.py
Before connecting to the Ceph Storage Cluster, create a cluster handle. By default, the cluster handle assumes a cluster named ceph (i.e., the default for deployment tools, and our Getting Started guides too), and a client.admin user name. You may change these defaults to suit your needs.
To connect to the Ceph Storage Cluster, your application needs to know where to find the Ceph Monitor. Provide this information to your application by specifying the path to your Ceph configuration file, which contains the location of the initial Ceph monitors.
import rados, sys
#Create Handle Examples.
cluster = rados.Rados(conffile='ceph.conf')
cluster = rados.Rados(conffile=sys.argv[1])
cluster = rados.Rados(conffile = 'ceph.conf', conf = dict (keyring = '/path/to/keyring'))
Ensure that the conffile argument provides the path and file name of your Ceph configuration file. You may use the sys module to avoid hard-coding the Ceph configuration path and file name.
Your Python client also requires a client keyring. For this example, we use the client.admin key by default. If you would like to specify the keyring when creating the cluster handle, you may use the conf argument. Alternatively, you may specify the keyring path in your Ceph configuration file. For example, you may add something like the following line to you Ceph configuration file:
keyring = /path/to/ceph.client.admin.keyring
For additional details on modifying your configuration via Python, see Configuration.
Once you have a cluster handle configured, you may connect to the cluster. With a connection to the cluster, you may execute methods that return information about the cluster.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import rados, sys
cluster = rados.Rados(conffile='ceph.conf')
print "\nlibrados version: " + str(cluster.version())
print "Will attempt to connect to: " + str(cluster.conf_get('mon initial members'))
cluster.connect()
print "\nCluster ID: " + cluster.get_fsid()
print "\n\nCluster Statistics"
print "=================="
cluster_stats = cluster.get_cluster_stats()
for key, value in cluster_stats.iteritems():
print key, value
|
By default, Ceph authentication is on. Your application will need to know the location of the keyring. The python-ceph module doesn’t have the default location, so you need to specify the keyring path. The easiest way to specify the keyring is to add it to the Ceph configuration file. The following Ceph configuration file example uses the client.admin keyring you generated with ceph-deploy.
[global]
...
keyring=/path/to/keyring/ceph.client.admin.keyring
When connected to the cluster, the Rados API allows you to manage pools. You can list pools, check for the existence of a pool, create a pool and delete a pool.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | print "\n\nPool Operations"
print "==============="
print "\nAvailable Pools"
print "----------------"
pools = cluster.list_pools()
for pool in pools:
print pool
print "\nCreate 'test' Pool"
print "------------------"
cluster.create_pool('test')
print "\nPool named 'test' exists: " + str(cluster.pool_exists('test'))
print "\nVerify 'test' Pool Exists"
print "-------------------------"
pools = cluster.list_pools()
for pool in pools:
print pool
print "\nDelete 'test' Pool"
print "------------------"
cluster.delete_pool('test')
print "\nPool named 'test' exists: " + str(cluster.pool_exists('test'))
|
Reading from and writing to the Ceph Storage Cluster requries an input/output context (ioctx). You can create an ioctx with the open_ioctx() method of the Rados class. The ioctx_name parameter is the name of the pool you wish to use.
ioctx = cluster.open_ioctx('data')
Once you have an I/O context, you can read/write objects, extended attributes, and perform a number of other operations. After you complete operations, ensure that you close the connection. For example:
print "\nClosing the connection."
ioctx.close()
Once you create an I/O context, you can write objects to the cluster. If you write to an object that doesn’t exist, Ceph creates it. If you write to an object that exists, Ceph overwrites it (except when you specify a range, and then it only overwrites the range). You may read objects (and object ranges) from the cluster. You may also remove objects from the cluster. For example:
1 2 3 4 5 6 7 8 | print "\nWriting object 'hw' with contents 'Hello World!' to pool 'data'."
ioctx.write_full("hw", "Hello World!")
print "\n\nContents of object 'hw'\n------------------------\n"
print ioctx.read("hw")
print "\nRemoving object 'hw'"
ioctx.remove_object("hw")
|
Once you create an object, you can write extended attributes (XATTRs) to the object and read XATTRs from the object. For example:
1 2 3 4 5 | print "\n\nWriting XATTR 'lang' with value 'en_US' to object 'hw'"
ioctx.set_xattr("hw", "lang", "en_US")
print "\n\nGetting XATTR 'lang' from object 'hw'\n"
print ioctx.get_xattr("hw", "lang")
|
If you want to examine the list of objects in a pool, you may retrieve the list of objects and iterate over them with the object iterator. For example:
1 2 3 4 5 6 7 8 9 10 | object_iterator = ioctx.list_objects()
while True :
try :
rados_object = object_iterator.next()
print "Object contents = " + rados_object.read()
except StopIteration :
break
|
The Object class provides a file-like interface to an object, allowing you to read and write content and extended attributes. Object operations using the I/O context provide additional functionality and asynchronous capabilities.
The Rados class provides an interface into the Ceph Storage Daemon.
The Rados class provides methods for getting and setting configuration values, reading the Ceph configuration file, and parsing arguments. You do not need to be connected to the Ceph Storage Cluster to invoke the following methods. See Storage Cluster Configuration for details on settings.
Get the value of a configuration option
Parameters: | option (str) – which option to read |
---|---|
Returns: | str - value of the option or None |
Raises : | TypeError |
Set the value of a configuration option
Parameters: |
|
---|---|
Raises : | TypeError, ObjectNotFound |
Configure the cluster handle using a Ceph config file.
Parameters: | path (str) – path to the config file |
---|
Parse known arguments from args, and remove; returned args contain only those unknown to ceph
Get the version number of the librados C library.
Returns: | a tuple of (major, minor, extra) components of the librados version |
---|
Once you configure your cluster handle, you may connect to the cluster, check the cluster fsid, retrieve cluster statistics, and disconnect (shutdown) from the cluster. You may also assert that the cluster handle is in a particular state (e.g., “configuring”, “connecting”, etc.).
Connect to the cluster.
Disconnects from the cluster.
Get the fsid of the cluster as a hexadecimal string.
Raises : | Error |
---|---|
Returns: | str - cluster fsid |
Read usage info about the cluster
This tells you total space, space used, space available, and number of objects. These are not updated immediately when data is written, they are eventually consistent.
Returns: | dict - contains the following keys:
|
---|
Checks if the Rados object is in a special state
Raises : | RadosStateError |
---|
To use pool operation methods, you must connect to the Ceph Storage Cluster first. You may list the available pools, create a pool, check to see if a pool exists, and delete a pool.
Gets a list of pool names.
Returns: | list - of pool names. |
---|
Create a pool: - with default settings: if auid=None and crush_rule=None - owned by a specific auid: auid given and crush_rule=None - with a specific CRUSH rule: if auid=None and crush_rule given - with a specific CRUSH rule and auid: if auid and crush_rule given
Parameters: |
|
---|---|
Raises : | TypeError, Error |
Checks if a given pool exists.
Parameters: | pool_name (str) – name of the pool to check |
---|---|
Raises : | TypeError, Error |
Returns: | bool - whether the pool exists, false otherwise. |
Delete a pool and all data inside it.
The pool is removed from the cluster immediately, but the actual data is deleted in the background.
Parameters: | pool_name (str) – name of the pool to delete |
---|---|
Raises : | TypeError, Error |
To write data to and read data from the Ceph Object Store, you must create an Input/Output context (ioctx). The Rados class provides a open_ioctx() method. The remaining ioctx operations involve invoking methods of the Ioctx and other classes.
Create an io context
The io context allows you to perform operations within a particular pool.
Parameters: | ioctx_name (str) – name of the pool |
---|---|
Raises : | TypeError, Error |
Returns: | Ioctx - Rados Ioctx object |
Checks if the rados.Ioctx object state is ‘open’
Raises : | IoctxStateError |
---|
Get pool usage statistics
Returns: | dict - contains the following keys:
|
---|
Attempt to change an io context’s associated auid “owner.”
Requires that you have write permission on both the current and new auid.
Raises : | Error |
---|
Return the version of the last object read or written to.
This exposes the internal version number of the last object read or written via this io context
Returns: | version of the last object used |
---|
Close a rados.Ioctx object.
This just tells librados that you no longer need to use the io context. It may not be freed immediately if there are pending asynchronous requests on it, but you should not use an io context again after calling this function on it.
The Ceph Storage Cluster stores data as objects. You can read and write objects synchronously or asynchronously. You can read and write from offsets. An object has a name (or key) and data.
Write data to an object asynchronously
Queues the write and returns.
Parameters: |
|
---|---|
Raises : | Error |
Returns: | completion object |
Asychronously write an entire object
The object is filled with the provided data. If the object exists, it is atomically truncated and then written. Queues the write and returns.
Parameters: |
|
---|---|
Raises : | Error |
Returns: | completion object |
Asychronously append data to an object
Queues the write and returns.
Parameters: |
|
---|---|
Raises : | Error |
Returns: | completion object |
Write data to an object synchronously
Parameters: |
|
---|---|
Raises : | TypeError |
Raises : | LogicError |
Returns: | int - number of bytes written |
Write an entire object synchronously.
The object is filled with the provided data. If the object exists, it is atomically truncated and then written.
Parameters: |
|
---|---|
Raises : | TypeError |
Raises : | Error |
Returns: | int - 0 on success |
Block until all pending writes in an io context are safe
Raises : | Error |
---|
Set the key for mapping objects to pgs within an io context.
The key is used instead of the object name to determine which placement groups an object is put in. This affects all subsequent operations of the io context - until a different locator key is set, all objects in this io context will be placed in the same pg.
Parameters: | loc_key (str) – the key to use as the object locator, or NULL to discard any previously set key |
---|---|
Raises : | TypeError |
Asychronously read data from an object
oncomplete will be called with the returned read value as well as the completion:
oncomplete(completion, data_read)
Parameters: |
|
---|---|
Raises : | Error |
Returns: | completion object |
Read data from an object synchronously
Parameters: |
|
---|---|
Raises : | TypeError |
Raises : | Error |
Returns: | str - data read from object |
Get object stats (size/mtime)
Parameters: | key (str) – the name of the object to get stats from |
---|---|
Raises : | TypeError |
Raises : | Error |
Returns: | (size,timestamp) |
Resize an object
If this enlarges the object, the new area is logically filled with zeroes. If this shrinks the object, the excess data is removed.
Parameters: |
|
---|---|
Raises : | TypeError |
Raises : | Error |
Returns: | int - 0 on success, otherwise raises error |
Delete an object
This does not delete any snapshots of the object.
Parameters: | key (str) – the name of the object to delete |
---|---|
Raises : | TypeError |
Raises : | Error |
Returns: | bool - True on success |
You may set extended attributes (XATTRs) on an object. You can retrieve a list of objects or XATTRs and iterate over them.
Set an extended attribute on an object.
Parameters: |
|
---|---|
Raises : | TypeError |
Raises : | Error |
Returns: | bool - True on success, otherwise raise an error |
Start iterating over xattrs on an object.
Parameters: | oid – the name of the object to get xattrs from |
---|---|
Raises : | TypeError |
Raises : | Error |
Returns: | XattrIterator |
Get the next xattr on the object
Raises : | StopIteration |
---|---|
Returns: | pair - of name and value of the next Xattr |
Get the value of an extended attribute on an object.
Parameters: |
|
---|---|
Raises : | TypeError |
Raises : | Error |
Returns: | str - value of the xattr |
Removes an extended attribute on from an object.
Parameters: |
|
---|---|
Raises : | TypeError |
Raises : | Error |
Returns: | bool - True on success, otherwise raise an error |
From an I/O context, you can retrieve a list of objects from a pool and iterate over them. The object interface provide makes each object look like a file, and you may perform synchronous operations on the objects. For asynchronous operations, you should use the I/O context methods.
Get ObjectIterator on rados.Ioctx object.
Returns: | ObjectIterator |
---|
Get the next object name and locator in the pool
Raises : | StopIteration |
---|---|
Returns: | next rados.Ioctx Object |