Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example restore object from Glacier doesn't work #1422

Closed
lendoly opened this issue Jan 18, 2018 · 11 comments
Closed

Example restore object from Glacier doesn't work #1422

lendoly opened this issue Jan 18, 2018 · 11 comments
Assignees
Labels
documentation This is a problem with documentation. guidance Question that needs advice or information.

Comments

@lendoly
Copy link

lendoly commented Jan 18, 2018

I was trying to retrieve some elements from glacier, for that I was using the example on the documentation

I tried few configurations but no one of them works so I will keep it as simpler as possible, the code:

import boto3
BUCKET = 'bucket-glacier'

s3 = boto3.resource('s3')
bucket = s3.Bucket(BUCKET)
for obj_sum in bucket.objects.all():
    if 'ls' in obj_sum.key:
        obj = s3.Object(obj_sum.bucket_name, obj_sum.key)
        if obj.storage_class == 'GLACIER':
            # Try to restore the object if the storage class is glacier and
            # the object does not have a completed or ongoing restoration
            # request.
            if obj.restore is None:
                print('Submitting restoration request: %s' % obj.key)
                obj.restore_object()
            # Print out objects whose restoration is on-going
            elif 'ongoing-request="true"' in obj.restore:
                print('Restoration in-progress: %s' % obj.key)
            # Print out objects whose restoration is complete
            elif 'ongoing-request="false"' in obj.restore:
                print('Restoration complete: %s' % obj.key)

I'm having problems in the obj.restore_object() (which is the most important part)

is showing to me the next error:
*** botocore.exceptions.ClientError: An error occurred (MissingRequestBodyError) when calling the RestoreObject operation: Request Body is empty

I tried also to configure the RestoreRequest like in the doc of the method but it also didn't work
*** botocore.exceptions.ClientError: An error occurred (MalformedXML) when calling the RestoreObject operation: The XML you provided was not well-formed or did not validate against our published schema

Versions:
Python: 3.5
Boto 3: 1.5.18
botocore: 1.8.32

@jamestwebber
Copy link

I am having this problem as well, the following code:

client = boto3.client('s3')

restore_request = {
    'OutputLocation': {
        'S3': {
            'BucketName': 'destination-bucket',
            'Prefix': 'destination-prefix',
        }
    }
}
client.restore_object(Bucket='bucket-name', Key=file_key,
                      RestoreRequest=restore_request)

gets me the same MalformedXML error. Not sure what it's complaining about, and I can't find the relevant schema to verify what boto3 is sending.

@jamestwebber
Copy link

It appears that my problem is that restore_request is ill-formed somehow, but I can't figure out how or why. I believe I'm following the docs correctly, and the bucket name is valid.

When my RestoreRequest is {'Days': 1} the code works.

@lendoly
Copy link
Author

lendoly commented Jan 31, 2018

with the client.restore_object and {'Days': 1} also works for me

@joguSD
Copy link
Contributor

joguSD commented Jan 31, 2018

Looking into this, it might take me some time to reproduce this.

@joguSD joguSD added the investigating This issue is being investigated and/or work is in progress to resolve the issue. label Jan 31, 2018
@joguSD joguSD self-assigned this Jan 31, 2018
@joguSD
Copy link
Contributor

joguSD commented Feb 2, 2018

I've reproduced this and can definitely confirm that the operation will fail with a MissingRequestBodyError if you don't pass any arguments. According to the API's documentation it would seem that you need to provide at least RestoreRequest={'Days': days} (or some other configuration depending on your goal).

It would seem that this has always been the case as well so I'm not entirely certain that example ever worked. I'll send a PR to update the documentation to include the RestoreRequest.

PR: #1439

@jamestwebber
Copy link

Hm it's strange that the Days parameter is necessary when RestoreLocation is specified–I thought the latter meant that the files would be restored to a new location on S3 and would not expire.

@arnonki
Copy link

arnonki commented Feb 3, 2018

EDIT:

Had to upgrade botocore, some service jsons were outdated

@joguSD
Copy link
Contributor

joguSD commented Feb 6, 2018

The RestoreLocation is used to store the output of your S3 select query.

From the API Docs:
OutputLocation: Describes the location that receives the results of the select restore request.

If you need more help with the usage of a service I would suggest reaching out on the service forum.

Closing the issue out here as we merged the changes to update the example client code.

@joguSD joguSD closed this as completed Feb 6, 2018
@joguSD joguSD added documentation This is a problem with documentation. guidance Question that needs advice or information. and removed investigating This issue is being investigated and/or work is in progress to resolve the issue. labels Feb 6, 2018
@cfurst
Copy link

cfurst commented Jul 26, 2020

@joguSD Where does it say that?.. according to the boto3 docs it says "OutputLocation (dict) --
Describes the location where the restore job's output is stored."
Which is very misleading, IMO, as it doesn't specify that its only for select requests.
Even in AWS's api docs for RestoreObject, it says that exact same thing.

@gjvc
Copy link

gjvc commented Dec 5, 2022

@jamestwebber I know it's been a while, but I bumped into the same problem as you, but managed to crack it. Here's some example code that works.

def restore_item( s3, source_bucket_name, source_key, restore_days, glacier_job_tier ):
    restore_request = {
        'Days': restore_days,
        'GlacierJobParameters': {
            'Tier': glacier_job_tier
        }
    }

    try:
        print( f'{source_bucket_name} {source_key}' )
        response = s3.restore_object(
            Bucket=source_bucket_name,
            Key=source_key,
            RestoreRequest=restore_request
        )
        print( response )
    except botocore.exceptions.ClientError as e:
        print( f'{source_bucket_name} {source_key} {e}' )
    except Exception as e:
        print( e )

@sotosoul
Copy link

It's been a while but I'm still facing an issue similar to what @jamestwebber was facing. Not sure exactly what the problem is but it won't work unless I pass days. Interestingly, the current Boto3 documentation seems incoherent in some places; possibly wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation This is a problem with documentation. guidance Question that needs advice or information.
Projects
None yet
Development

No branches or pull requests

7 participants