How can I upload a tar.bz2 file to OpenStack swift object storage container using the Python swift client?

Joined
Mar 22, 2024
Messages
1
Reaction score
0
I wrote a Python script that included the python-swiftclient module to connect to the OpenStack Object Storage and upload some files to the container after reading the python-swiftclient documentation: https://docs.openstack.org/python-swiftclient/latest/client-api.html

It works great if I upload a file that ends with the extension .gz however, I'm getting some errors when it comes to the compressed file that ends with the extension .tar.bz2.

I've included the Python script and the errors I get after running it. Please show me where I'm wrong, and I would like some assistance in solving this issue.



Python:
from keystoneauth1 import session
from keystoneauth1.identity import v3
from swiftclient.client import Connection
from swiftclient.client import ClientException
import gzip
import tarfile

# Create a password auth plugin
auth = v3.Password(auth_url='https://cloud.company.com:5000/v3/',
                   username='myaccount',
                   password='mypassword',
                   user_domain_name='Default',
                   project_name='myproject',
                   project_domain_name='Default')

# Create session
keystone_session = session.Session(auth=auth)

# Create swiftclient Connection
swift_conn = Connection(session=keystone_session)

# Create a new object with the contents of Netbox database backup
with gzip.open('/var/backup/netbox_backups/netbox_2024-03-16.psql.gz', 'rb') as file:
    swift_conn.put_object(
        container,
        'object_netbox_2024-03-16.psql.gz',
        contents=file,
        content_type='application/gzip'
    )

# Confirm the presence of the object holding the Netbox database backup
obj1 = 'object_netbox_2024-03-16.psql.gz'
container = 'netbox-backups'
try:
    resp_headers = swift_conn.head_object(container, obj1)
    print("The object " + obj1 + " was successfully created")
except ClientException as e:
    if e.http_status == '404':
        print("The object " + obj1 + " was not found!")
    else:
        print("An error occurred checking for the existence of the object " + obj1)

# Create a new object with the contents of the compressed Netbox media backup
with tarfile.open("/var/backup/netbox_backups/netbox_media_2024-03-16.tar.bz2", "r:bz2") as file_tar_bz2:
    swift_conn.put_object(
        container,
        'object_netbox_media_2024-03-16.tar.bz2',
        contents=file_tar_bz2,
        content_type='application/x-tar'
    )

# Confirm the presence of the object holding the compressed Netbox media backup
obj2 = 'object_netbox_media_2024-03-16.tar.bz2'
container = 'netbox-backups'
try:
    resp_headers = swift_conn.head_object(container, obj2)
    print("The object " + obj2 + " was successfully created")
except ClientException as e:
    if e.http_status == '404':
        print("The object " + obj2 + " was not found!")
    else:
        print("An error occurred checking for the existence of the object " + obj2)

Below are the errors I'm getting after running the script

Code:
(venv) [root@scs-sandbox01 backups]# python netbox_backups_transfer.py

The object object_netbox_2024-03-16.psql.gz was successfully created
Traceback (most recent call last):
  File "/opt/scripts/netbox_backups_transfer.py", line 52, in <module>
    swift_conn.put_object(
  File "/opt/netbox/venv/lib64/python3.9/site-packages/swiftclient/client.py", line 1963, in put_object
    return self._retry(reset_func, put_object, container, obj, contents,
  File "/opt/netbox/venv/lib64/python3.9/site-packages/swiftclient/client.py", line 1797, in _retry
    rv = func(self.url, self.token, *args,
  File "/opt/netbox/venv/lib64/python3.9/site-packages/swiftclient/client.py", line 1421, in put_object
    conn.request('PUT', path, contents, headers)
  File "/opt/netbox/venv/lib64/python3.9/site-packages/swiftclient/client.py", line 416, in request
    self.resp = self._request(method, url, headers=headers, data=data,
  File "/opt/netbox/venv/lib64/python3.9/site-packages/swiftclient/client.py", line 400, in _request
    return self.request_session.request(*arg, **kwarg)
  File "/opt/netbox/venv/lib64/python3.9/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
  File "/opt/netbox/venv/lib64/python3.9/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
  File "/opt/netbox/venv/lib64/python3.9/site-packages/requests/adapters.py", line 486, in send
    resp = conn.urlopen(
  File "/opt/netbox/venv/lib64/python3.9/site-packages/urllib3/connectionpool.py", line 790, in urlopen
    response = self._make_request(
  File "/opt/netbox/venv/lib64/python3.9/site-packages/urllib3/connectionpool.py", line 496, in _make_request
    conn.request(
  File "/opt/netbox/venv/lib64/python3.9/site-packages/urllib3/connection.py", line 399, in request
    for chunk in chunks:
  File "/opt/netbox/venv/lib64/python3.9/site-packages/swiftclient/utils.py", line 443, in iter_wrapper
    if len(chunk) == 0:
TypeError: object of type 'TarInfo' has no len()
 
Joined
Nov 23, 2023
Messages
56
Reaction score
3
The swiftclient.put_object function expects a file-like object with a read() method. When you directly pass the tarfile.TarFile object to contents, it doesn't work because TarFile doesn't have a built-in read() method to iterate through the entire archive.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top