Skip to content

Instantly share code, notes, and snippets.

@maxpeterson
Last active November 9, 2017 23:12
Show Gist options
  • Save maxpeterson/5b7ab137c29d7809aed82d9af93acd15 to your computer and use it in GitHub Desktop.
Save maxpeterson/5b7ab137c29d7809aed82d9af93acd15 to your computer and use it in GitHub Desktop.
Copy a Rackspace image to cloudfiles and back
import requests
import time
def get_tokens(username, apikey):
# Get the auth token
auth_data = {
"auth": {
"RAX-KSKEY:apiKeyCredentials": {
"username": username,
"apiKey": apikey
}
}
}
r = requests.post('https://identity.api.rackspacecloud.com/v2.0/tokens', json=auth_data)
return r.json()['access']
def get_auth_headers(username, apikey):
tokens = get_tokens(username, apikey)
auth_token = tokens['token']['id']
return {'x-auth-token': auth_token}
def wait_for_task(images_url, taskid, headers):
print('Waiting for task {} to complete'.format(taskid))
while True:
r = requests.get(
'{}/{}'.format(images_url, taskid),
headers=headers,
)
status = r.json()['status']
if status not in ['processing', 'pending']:
break
print('{0}\r'.format(status))
time.sleep(1)
return r
# Export the image to cloudFiles
def image_to_cloud(
image_id,
username,
apikey,
tenant,
region='ord',
clouddrive_container='exported-images',
):
headers = get_auth_headers(username, apikey)
images_url = 'https://{}.images.api.rackspacecloud.com/v2/{}/tasks'.format(region, tenant)
data = {
"type": "export",
"input": {
"image_uuid": image_id,
"receiving_swift_container": clouddrive_container
}
}
r = requests.post(images_url, headers=headers, json=data)
taskid_export = r.json()['id']
print('Started export task {}'.format(taskid))
r = wait_for_task(images_url, taskid_export, headers)
if r.json()['status'] != 'success':
print('Failed to export image to cloudfiles')
print(r.text)
return
print('Image exported to cloudfiles')
return r.json()
# Import the
def cloud_to_image(
import_from,
image_properties,
username,
apikey,
tenant,
region='lon',
):
headers = get_auth_headers(username, apikey)
images_url = 'https://{}.images.api.rackspacecloud.com/v2/{}/tasks'.format(region, tenant)
data = {
'type': 'import',
'input': {
'image_properties': image_properties,
'import_from': import_from,
}
}
r = requests.post(images_url, headers=headers, json=data)
taskid_import = r.json()['id']
r = wait_for_task(images_url, taskid_import, headers)
if r.json()['status'] != 'success':
print('Failed to import image')
print(r.text)
print('Cloudfile image imported')
return r
def download_image_DOES_NOT_WORK(
username,
apikey,
tenant,
export_location,
filename,
region='ord',
):
tokens = get_tokens(username_src, apikey_src)
auth_token = tokens['token']['id']
headers = {'x-auth-token': auth_token}
# Download the image
cloudFiles = next(c for c in tokens['serviceCatalog'] if c['name'] == 'cloudFiles')
cloudFiles_endpoint = next(e for e in cloudFiles['endpoints'] if e['region'] == region.upper())['publicURL']
r = requests.get(
cloudFiles_endpoint + '/' + export_location,
headers=headers,
stream=True,
)
with open(filename, 'wb') as fd:
for chunk in r.iter_content(chunk_size=128):
fd.write(chunk)
@maxpeterson
Copy link
Author

  1. Copy an image to cloud files with (in python):
image_to_cloud(image_id, username_src, apikey_src, tenant_src, region_src)
  1. Download the image via the web interface.

  2. Upload the image to a new account via the web interface if it is less that 5G.

If the image is bigger than 5G then use the python-swiftclient (in a shell/terminal)

swift -A https://auth.api.rackspacecloud.com/v1.0 -U <username_dst> -K <apikey_dst> upload -S 1048576 <container> <image_id>.vhd

If swift fails to create a file pointing to the uploaded image then you can create (PUT) a file pointing to the uploaded data. In my case swift put the files in a container called import_segments so I had to created (PUT) a file to import/{image_id}.vhd that pointed (the x-object-manifest) to import_segments/{image_id}.vhd

# Create cloud file for the image that uses the data uploaded by swift (you may need to change the storage_url)
storage_url = 'https://storage101.lon3.clouddrive.com/v1/MossoCloudFS_<tenant_dst>'
headers = get_auth_headers(username_dst, apikey_dst)
headers['x-object-manifest'] = 'import_segments/{}.vhd'.format(image_id) 
r = requests.put('{}/import/{}.vhd'.format(storage_url, image_id), headers=headers)
  1. Create an image from the cloud files (in Python):
import_info = cloud_to_image(
    'import_segments/{}.vhd'.format(image_id),
    {'name': 'imported - ' + server_name},
    username_dst,
    apikey_dst,
    tenant_dst,
    region_dst,
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment