summaryrefslogtreecommitdiff
path: root/src/import/import-raw.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-01-16 20:07:25 +0100
committerLennart Poettering <lennart@poettering.net>2015-01-16 20:09:33 +0100
commitedce2aed3aa93b84f7b4c70412bdb665da2977b0 (patch)
tree6953215eb2e65cc79c417fb5d1d6923ef5a2a9a0 /src/import/import-raw.c
parent49bb233bb734536b9617d838f09a7bf9b8336003 (diff)
import: support importing qcow2 images
With this change the import tool will now unpack qcow2 images into normal raw disk images, suitable for usage with nspawn. This allows has the benefit of also allowing importing Ubuntu Cloud images for usage with nspawn.
Diffstat (limited to 'src/import/import-raw.c')
-rw-r--r--src/import/import-raw.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/import/import-raw.c b/src/import/import-raw.c
index f1b36cbfcc..c15765d51c 100644
--- a/src/import/import-raw.c
+++ b/src/import/import-raw.c
@@ -27,6 +27,7 @@
#include "hashmap.h"
#include "utf8.h"
#include "curl-util.h"
+#include "qcow2-util.h"
#include "import-raw.h"
#include "strv.h"
#include "copy.h"
@@ -235,6 +236,49 @@ finish:
raw_import_finish(f->import, r);
}
+static int raw_import_maybe_convert_qcow2(RawImportFile *f) {
+ _cleanup_close_ int converted_fd = -1;
+ _cleanup_free_ char *t = NULL;
+ int r;
+
+ assert(f);
+ assert(f->disk_fd);
+ assert(f->temp_path);
+
+ r = qcow2_detect(f->disk_fd);
+ if (r < 0)
+ return log_error_errno(r, "Failed to detect whether this is a QCOW2 image: %m");
+ if (r == 0)
+ return 0;
+
+ /* This is a QCOW2 image, let's convert it */
+ r = tempfn_random(f->final_path, &t);
+ if (r < 0)
+ return log_oom();
+
+ converted_fd = open(t, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0644);
+ if (converted_fd < 0)
+ return log_error_errno(errno, "Failed to create %s: %m", t);
+
+ r = qcow2_convert(f->disk_fd, converted_fd);
+ if (r < 0) {
+ unlink(t);
+ return log_error_errno(r, "Failed to convert qcow2 image: %m");
+ }
+
+ unlink(f->temp_path);
+ free(f->temp_path);
+
+ f->temp_path = t;
+ t = NULL;
+
+ safe_close(f->disk_fd);
+ f->disk_fd = converted_fd;
+ converted_fd = -1;
+
+ return 1;
+}
+
static void raw_import_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
RawImportFile *f = NULL;
struct stat st;
@@ -288,6 +332,10 @@ static void raw_import_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result
goto fail;
}
+ r = raw_import_maybe_convert_qcow2(f);
+ if (r < 0)
+ goto fail;
+
if (f->etag)
(void) fsetxattr(f->disk_fd, "user.source_etag", f->etag, strlen(f->etag), 0);
if (f->url)