Commit c89622cd authored by Jose A. Lopes's avatar Jose A. Lopes
Browse files

Helper function that downloads an image and dumps it to disk

* Add constant that holds the curl binary.

* Add '_DownloadAndDumpDevice' which downloads a file (e.g., OS image)
  through curl and dumps it to a disk device (e.g., an instance disk).
Signed-off-by: default avatarJose A. Lopes <>
Reviewed-by: default avatarHrvoje Ribicic <>
parent 229fb4ea
...@@ -42,6 +42,7 @@ import errno ...@@ -42,6 +42,7 @@ import errno
import logging import logging
import os import os
import os.path import os.path
import pycurl
import random import random
import re import re
import shutil import shutil
...@@ -52,6 +53,7 @@ import time ...@@ -52,6 +53,7 @@ import time
import zlib import zlib
from ganeti import errors from ganeti import errors
from ganeti import http
from ganeti import utils from ganeti import utils
from ganeti import ssh from ganeti import ssh
from ganeti import hypervisor from ganeti import hypervisor
...@@ -2267,6 +2269,58 @@ def _DumpDevice(source_path, target_path, offset, size): ...@@ -2267,6 +2269,58 @@ def _DumpDevice(source_path, target_path, offset, size):
result.fail_reason, result.output) result.fail_reason, result.output)
def _DownloadAndDumpDevice(source_url, target_path, size):
"""This function images a device using a downloaded image file.
@type source_url: string
@param source_url: URL of image to dump to disk
@type target_path: string
@param target_path: path of the device to image
@type size: int
@param size: maximum size in MiB to write (data source might be smaller)
@rtype: NoneType
@return: None
@raise RPCFail: in case of download or write failures
class DDParams(object):
def __init__(self, current_size, total_size):
self.current_size = current_size
self.total_size = total_size
self.image_size_error = False
def dd_write(ddparams, out):
if ddparams.current_size < ddparams.total_size:
ddparams.current_size += len(out)
ddparams.image_size_error = True
return -1
target_file = open(target_path, "w")
ddparams = DDParams(0, 1024 * 1024 * size)
curl = pycurl.Curl()
curl.setopt(pycurl.VERBOSE, True)
curl.setopt(pycurl.NOSIGNAL, True)
curl.setopt(pycurl.USERAGENT, http.HTTP_GANETI_VERSION)
curl.setopt(pycurl.URL, source_url)
curl.setopt(pycurl.WRITEFUNCTION, lambda out: dd_write(ddparams, out))
except pycurl.error:
if ddparams.image_size_error:
_Fail("Disk image larger than the disk")
def BlockdevWipe(disk, offset, size): def BlockdevWipe(disk, offset, size):
"""Wipes a block device. """Wipes a block device.
...@@ -294,7 +294,7 @@ cpuPinningAllXen = "0-63" ...@@ -294,7 +294,7 @@ cpuPinningAllXen = "0-63"
cpuPinningAllKvm :: Int cpuPinningAllKvm :: Int
cpuPinningAllKvm = 0xFFFFFFFF cpuPinningAllKvm = 0xFFFFFFFF
-- * Wipe -- * Image and wipe
ddCmd :: String ddCmd :: String
ddCmd = "dd" ddCmd = "dd"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment