]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
import: optionally pull .verity + .roothash.p7s data when downloading
authorLennart Poettering <lennart@poettering.net>
Fri, 15 Jan 2021 22:18:54 +0000 (23:18 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 19 Jan 2021 17:29:59 +0000 (18:29 +0100)
We already had support for downlading a .nspawn and a .roothash file,
let's make the set complete, and also download .verity + roothash.p7s if
it exists, as nspawn consumes that.

Since there are now four kinds of additional resources to acquire, let's
introduce a PullFlags flags value for this instead of separate 'bool'
variables, it's just too many to always pass those around on the
function parameter list.

src/import/pull-common.c
src/import/pull-common.h
src/import/pull-raw.c
src/import/pull-raw.h
src/import/pull-tar.c
src/import/pull-tar.h
src/import/pull.c

index faa988b5f2a5000700ab2663c5a88f6167f9803c..8f295090038947aa28899162e44b2bbb51c1a6ce 100644 (file)
@@ -110,7 +110,7 @@ int pull_find_old_etags(
         return 0;
 }
 
-int pull_make_local_copy(const char *final, const char *image_root, const char *local, bool force_local) {
+int pull_make_local_copy(const char *final, const char *image_root, const char *local, PullFlags flags) {
         const char *p;
         int r;
 
@@ -122,7 +122,7 @@ int pull_make_local_copy(const char *final, const char *image_root, const char *
 
         p = prefix_roota(image_root, local);
 
-        if (force_local)
+        if (FLAGS_SET(flags, PULL_FORCE))
                 (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
 
         r = btrfs_subvol_snapshot(final, p,
index a83e9b7e1456d1262ce22dddfa56480e14f6567c..f24093e6e11a9d304a437d6282d38e196adb20c3 100644 (file)
@@ -6,7 +6,19 @@
 #include "import-util.h"
 #include "pull-job.h"
 
-int pull_make_local_copy(const char *final, const char *root, const char *local, bool force_local);
+typedef enum PullFlags {
+        PULL_FORCE              = 1 << 0,  /* replace existing image */
+        PULL_SETTINGS           = 1 << 1,  /* .nspawn settings file */
+        PULL_ROOTHASH           = 1 << 2,  /* only for raw: .roothash file for verity */
+        PULL_ROOTHASH_SIGNATURE = 1 << 3,  /* only for raw: .roothash.p7s file for verity */
+        PULL_VERITY             = 1 << 4,  /* only for raw: .verity file for verity */
+
+        /* The supported flags for the tar and the raw pulling */
+        PULL_FLAGS_MASK_TAR     = PULL_FORCE|PULL_SETTINGS,
+        PULL_FLAGS_MASK_RAW     = PULL_FORCE|PULL_SETTINGS|PULL_ROOTHASH|PULL_ROOTHASH_SIGNATURE|PULL_VERITY,
+} PullFlags;
+
+int pull_make_local_copy(const char *final, const char *root, const char *local, PullFlags flags);
 
 int pull_find_old_etags(const char *url, const char *root, int dt, const char *prefix, const char *suffix, char ***etags);
 
index 69b3c307f62bcef592ff3a814aee4ab394816a50..5b4525d456cd74759a5f26714afb8e743178bce4 100644 (file)
@@ -42,21 +42,22 @@ struct RawPull {
         sd_event *event;
         CurlGlue *glue;
 
+        PullFlags flags;
+        ImportVerify verify;
         char *image_root;
 
         PullJob *raw_job;
-        PullJob *roothash_job;
-        PullJob *settings_job;
         PullJob *checksum_job;
         PullJob *signature_job;
+        PullJob *settings_job;
+        PullJob *roothash_job;
+        PullJob *roothash_signature_job;
+        PullJob *verity_job;
 
         RawPullFinished on_finished;
         void *userdata;
 
         char *local;
-        bool force_local;
-        bool settings;
-        bool roothash;
 
         char *final_path;
         char *temp_path;
@@ -67,7 +68,11 @@ struct RawPull {
         char *roothash_path;
         char *roothash_temp_path;
 
-        ImportVerify verify;
+        char *roothash_signature_path;
+        char *roothash_signature_temp_path;
+
+        char *verity_path;
+        char *verity_temp_path;
 };
 
 RawPull* raw_pull_unref(RawPull *i) {
@@ -75,34 +80,30 @@ RawPull* raw_pull_unref(RawPull *i) {
                 return NULL;
 
         pull_job_unref(i->raw_job);
-        pull_job_unref(i->settings_job);
-        pull_job_unref(i->roothash_job);
         pull_job_unref(i->checksum_job);
         pull_job_unref(i->signature_job);
+        pull_job_unref(i->settings_job);
+        pull_job_unref(i->roothash_job);
+        pull_job_unref(i->roothash_signature_job);
+        pull_job_unref(i->verity_job);
 
         curl_glue_unref(i->glue);
         sd_event_unref(i->event);
 
-        if (i->temp_path) {
-                (void) unlink(i->temp_path);
-                free(i->temp_path);
-        }
-
-        if (i->roothash_temp_path) {
-                (void) unlink(i->roothash_temp_path);
-                free(i->roothash_temp_path);
-        }
-
-        if (i->settings_temp_path) {
-                (void) unlink(i->settings_temp_path);
-                free(i->settings_temp_path);
-        }
+        unlink_and_free(i->temp_path);
+        unlink_and_free(i->settings_temp_path);
+        unlink_and_free(i->roothash_temp_path);
+        unlink_and_free(i->roothash_signature_temp_path);
+        unlink_and_free(i->verity_temp_path);
 
         free(i->final_path);
-        free(i->roothash_path);
         free(i->settings_path);
+        free(i->roothash_path);
+        free(i->roothash_signature_path);
+        free(i->verity_path);
         free(i->image_root);
         free(i->local);
+
         return mfree(i);
 }
 
@@ -169,6 +170,16 @@ static void raw_pull_report_progress(RawPull *i, RawProgress p) {
 
                 percent = 0;
 
+                if (i->checksum_job) {
+                        percent += i->checksum_job->progress_percent * 5 / 100;
+                        remain -= 5;
+                }
+
+                if (i->signature_job) {
+                        percent += i->signature_job->progress_percent * 5 / 100;
+                        remain -= 5;
+                }
+
                 if (i->settings_job) {
                         percent += i->settings_job->progress_percent * 5 / 100;
                         remain -= 5;
@@ -179,14 +190,14 @@ static void raw_pull_report_progress(RawPull *i, RawProgress p) {
                         remain -= 5;
                 }
 
-                if (i->checksum_job) {
-                        percent += i->checksum_job->progress_percent * 5 / 100;
+                if (i->roothash_signature_job) {
+                        percent += i->roothash_signature_job->progress_percent * 5 / 100;
                         remain -= 5;
                 }
 
-                if (i->signature_job) {
-                        percent += i->signature_job->progress_percent * 5 / 100;
-                        remain -= 5;
+                if (i->verity_job) {
+                        percent += i->verity_job->progress_percent * 10 / 100;
+                        remain -= 10;
                 }
 
                 if (i->raw_job)
@@ -294,7 +305,7 @@ static int raw_pull_copy_auxiliary_file(
 
         local = strjoina(i->image_root, "/", i->local, suffix);
 
-        r = copy_file_atomic(*path, local, 0644, 0, 0, COPY_REFLINK | (i->force_local ? COPY_REPLACE : 0));
+        r = copy_file_atomic(*path, local, 0644, 0, 0, COPY_REFLINK | (FLAGS_SET(i->flags, PULL_FORCE) ? COPY_REPLACE : 0));
         if (r == -EEXIST)
                 log_warning_errno(r, "File %s already exists, not replacing.", local);
         else if (r == -ENOENT)
@@ -338,7 +349,7 @@ static int raw_pull_make_local_copy(RawPull *i) {
 
         p = strjoina(i->image_root, "/", i->local, ".raw");
 
-        if (i->force_local)
+        if (FLAGS_SET(i->flags, PULL_FORCE))
                 (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
 
         r = tempfn_random(p, NULL, &tp);
@@ -373,14 +384,26 @@ static int raw_pull_make_local_copy(RawPull *i) {
 
         log_info("Created new local image '%s'.", i->local);
 
-        if (i->roothash) {
+        if (FLAGS_SET(i->flags, PULL_SETTINGS)) {
+                r = raw_pull_copy_auxiliary_file(i, ".nspawn", &i->settings_path);
+                if (r < 0)
+                        return r;
+        }
+
+        if (FLAGS_SET(i->flags, PULL_ROOTHASH)) {
                 r = raw_pull_copy_auxiliary_file(i, ".roothash", &i->roothash_path);
                 if (r < 0)
                         return r;
         }
 
-        if (i->settings) {
-                r = raw_pull_copy_auxiliary_file(i, ".nspawn", &i->settings_path);
+        if (FLAGS_SET(i->flags, PULL_ROOTHASH_SIGNATURE)) {
+                r = raw_pull_copy_auxiliary_file(i, ".roothash.p7s", &i->roothash_signature_path);
+                if (r < 0)
+                        return r;
+        }
+
+        if (FLAGS_SET(i->flags, PULL_VERITY)) {
+                r = raw_pull_copy_auxiliary_file(i, ".verity", &i->verity_path);
                 if (r < 0)
                         return r;
         }
@@ -394,13 +417,17 @@ static bool raw_pull_is_done(RawPull *i) {
 
         if (!PULL_JOB_IS_COMPLETE(i->raw_job))
                 return false;
-        if (i->roothash_job && !PULL_JOB_IS_COMPLETE(i->roothash_job))
+        if (i->checksum_job && !PULL_JOB_IS_COMPLETE(i->checksum_job))
+                return false;
+        if (i->signature_job && !PULL_JOB_IS_COMPLETE(i->signature_job))
                 return false;
         if (i->settings_job && !PULL_JOB_IS_COMPLETE(i->settings_job))
                 return false;
-        if (i->checksum_job && !PULL_JOB_IS_COMPLETE(i->checksum_job))
+        if (i->roothash_job && !PULL_JOB_IS_COMPLETE(i->roothash_job))
                 return false;
-        if (i->signature_job && !PULL_JOB_IS_COMPLETE(i->signature_job))
+        if (i->roothash_signature_job && !PULL_JOB_IS_COMPLETE(i->roothash_signature_job))
+                return false;
+        if (i->verity_job && !PULL_JOB_IS_COMPLETE(i->verity_job))
                 return false;
 
         return true;
@@ -447,12 +474,18 @@ static void raw_pull_job_on_finished(PullJob *j) {
         assert(j->userdata);
 
         i = j->userdata;
-        if (j == i->roothash_job) {
+        if (j == i->settings_job) {
+                if (j->error != 0)
+                        log_info_errno(j->error, "Settings file could not be retrieved, proceeding without.");
+        } else if (j == i->roothash_job) {
                 if (j->error != 0)
                         log_info_errno(j->error, "Root hash file could not be retrieved, proceeding without.");
-        } else if (j == i->settings_job) {
+        } else if (j == i->roothash_signature_job) {
                 if (j->error != 0)
-                        log_info_errno(j->error, "Settings file could not be retrieved, proceeding without.");
+                        log_info_errno(j->error, "Root hash signature file could not be retrieved, proceeding without.");
+        } else if (j == i->verity_job) {
+                if (j->error != 0)
+                        log_info_errno(j->error, "Verity integrity file could not be retrieved, proceeding without. %s", j->url);
         } else if (j->error != 0 && j != i->signature_job) {
                 if (j == i->checksum_job)
                         log_error_errno(j->error, "Failed to retrieve SHA256 checksum, cannot verify. (Try --verify=no?)");
@@ -463,10 +496,8 @@ static void raw_pull_job_on_finished(PullJob *j) {
                 goto finish;
         }
 
-        /* This is invoked if either the download completed
-         * successfully, or the download was skipped because we
-         * already have the etag. In this case ->etag_exists is
-         * true.
+        /* This is invoked if either the download completed successfully, or the download was skipped because
+         * we already have the etag. In this case ->etag_exists is true.
          *
          * We only do something when we got all three files */
 
@@ -492,10 +523,14 @@ static void raw_pull_job_on_finished(PullJob *j) {
                 }
         }
 
-        if (i->roothash_job)
-                i->roothash_job->disk_fd = safe_close(i->roothash_job->disk_fd);
         if (i->settings_job)
                 i->settings_job->disk_fd = safe_close(i->settings_job->disk_fd);
+        if (i->roothash_job)
+                i->roothash_job->disk_fd = safe_close(i->roothash_job->disk_fd);
+        if (i->roothash_signature_job)
+                i->roothash_signature_job->disk_fd = safe_close(i->roothash_signature_job->disk_fd);
+        if (i->verity_job)
+                i->verity_job->disk_fd = safe_close(i->verity_job->disk_fd);
 
         r = raw_pull_determine_path(i, ".raw", &i->final_path);
         if (r < 0)
@@ -610,6 +645,18 @@ static int raw_pull_job_on_open_disk_raw(PullJob *j) {
         return 0;
 }
 
+static int raw_pull_job_on_open_disk_settings(PullJob *j) {
+        RawPull *i;
+
+        assert(j);
+        assert(j->userdata);
+
+        i = j->userdata;
+        assert(i->settings_job == j);
+
+        return raw_pull_job_on_open_disk_generic(i, j, "settings", &i->settings_temp_path);
+}
+
 static int raw_pull_job_on_open_disk_roothash(PullJob *j) {
         RawPull *i;
 
@@ -622,16 +669,28 @@ static int raw_pull_job_on_open_disk_roothash(PullJob *j) {
         return raw_pull_job_on_open_disk_generic(i, j, "roothash", &i->roothash_temp_path);
 }
 
-static int raw_pull_job_on_open_disk_settings(PullJob *j) {
+static int raw_pull_job_on_open_disk_roothash_signature(PullJob *j) {
         RawPull *i;
 
         assert(j);
         assert(j->userdata);
 
         i = j->userdata;
-        assert(i->settings_job == j);
+        assert(i->roothash_signature_job == j);
 
-        return raw_pull_job_on_open_disk_generic(i, j, "settings", &i->settings_temp_path);
+        return raw_pull_job_on_open_disk_generic(i, j, "roothash.p7s", &i->roothash_signature_temp_path);
+}
+
+static int raw_pull_job_on_open_disk_verity(PullJob *j) {
+        RawPull *i;
+
+        assert(j);
+        assert(j->userdata);
+
+        i = j->userdata;
+        assert(i->verity_job == j);
+
+        return raw_pull_job_on_open_disk_generic(i, j, "verity", &i->verity_temp_path);
 }
 
 static void raw_pull_job_on_progress(PullJob *j) {
@@ -649,16 +708,15 @@ int raw_pull_start(
                 RawPull *i,
                 const char *url,
                 const char *local,
-                bool force_local,
-                ImportVerify verify,
-                bool settings,
-                bool roothash) {
+                PullFlags flags,
+                ImportVerify verify) {
 
         int r;
 
         assert(i);
         assert(verify < _IMPORT_VERIFY_MAX);
         assert(verify >= 0);
+        assert(!(flags & ~PULL_FLAGS_MASK_RAW));
 
         if (!http_url_is_valid(url))
                 return -EINVAL;
@@ -673,10 +731,8 @@ int raw_pull_start(
         if (r < 0)
                 return r;
 
-        i->force_local = force_local;
+        i->flags = flags;
         i->verify = verify;
-        i->settings = settings;
-        i->roothash = roothash;
 
         /* Queue job for the image itself */
         r = pull_job_new(&i->raw_job, url, i->glue, i);
@@ -692,7 +748,21 @@ int raw_pull_start(
         if (r < 0)
                 return r;
 
-        if (roothash) {
+        r = pull_make_verification_jobs(&i->checksum_job, &i->signature_job, verify, url, i->glue, raw_pull_job_on_finished, i);
+        if (r < 0)
+                return r;
+
+        if (FLAGS_SET(flags, PULL_SETTINGS)) {
+                r = pull_make_auxiliary_job(&i->settings_job, url, raw_strip_suffixes, ".nspawn", i->glue, raw_pull_job_on_finished, i);
+                if (r < 0)
+                        return r;
+
+                i->settings_job->on_open_disk = raw_pull_job_on_open_disk_settings;
+                i->settings_job->on_progress = raw_pull_job_on_progress;
+                i->settings_job->calc_checksum = verify != IMPORT_VERIFY_NO;
+        }
+
+        if (FLAGS_SET(flags, PULL_ROOTHASH)) {
                 r = pull_make_auxiliary_job(&i->roothash_job, url, raw_strip_suffixes, ".roothash", i->glue, raw_pull_job_on_finished, i);
                 if (r < 0)
                         return r;
@@ -702,26 +772,43 @@ int raw_pull_start(
                 i->roothash_job->calc_checksum = verify != IMPORT_VERIFY_NO;
         }
 
-        if (settings) {
-                r = pull_make_auxiliary_job(&i->settings_job, url, raw_strip_suffixes, ".nspawn", i->glue, raw_pull_job_on_finished, i);
+        if (FLAGS_SET(flags, PULL_ROOTHASH_SIGNATURE)) {
+                r = pull_make_auxiliary_job(&i->roothash_signature_job, url, raw_strip_suffixes, ".roothash.p7s", i->glue, raw_pull_job_on_finished, i);
                 if (r < 0)
                         return r;
 
-                i->settings_job->on_open_disk = raw_pull_job_on_open_disk_settings;
-                i->settings_job->on_progress = raw_pull_job_on_progress;
-                i->settings_job->calc_checksum = verify != IMPORT_VERIFY_NO;
+                i->roothash_signature_job->on_open_disk = raw_pull_job_on_open_disk_roothash_signature;
+                i->roothash_signature_job->on_progress = raw_pull_job_on_progress;
+                i->roothash_signature_job->calc_checksum = verify != IMPORT_VERIFY_NO;
         }
 
-        r = pull_make_verification_jobs(&i->checksum_job, &i->signature_job, verify, url, i->glue, raw_pull_job_on_finished, i);
-        if (r < 0)
-                return r;
+        if (FLAGS_SET(flags, PULL_VERITY)) {
+                r = pull_make_auxiliary_job(&i->verity_job, url, raw_strip_suffixes, ".verity", i->glue, raw_pull_job_on_finished, i);
+                if (r < 0)
+                        return r;
+
+                i->verity_job->on_open_disk = raw_pull_job_on_open_disk_verity;
+                i->verity_job->on_progress = raw_pull_job_on_progress;
+                i->verity_job->calc_checksum = verify != IMPORT_VERIFY_NO;
+        }
 
         r = pull_job_begin(i->raw_job);
         if (r < 0)
                 return r;
 
-        if (i->roothash_job) {
-                r = pull_job_begin(i->roothash_job);
+        if (i->checksum_job) {
+                i->checksum_job->on_progress = raw_pull_job_on_progress;
+                i->checksum_job->on_not_found = pull_job_restart_with_sha256sum;
+
+                r = pull_job_begin(i->checksum_job);
+                if (r < 0)
+                        return r;
+        }
+
+        if (i->signature_job) {
+                i->signature_job->on_progress = raw_pull_job_on_progress;
+
+                r = pull_job_begin(i->signature_job);
                 if (r < 0)
                         return r;
         }
@@ -732,19 +819,20 @@ int raw_pull_start(
                         return r;
         }
 
-        if (i->checksum_job) {
-                i->checksum_job->on_progress = raw_pull_job_on_progress;
-                i->checksum_job->on_not_found = pull_job_restart_with_sha256sum;
-
-                r = pull_job_begin(i->checksum_job);
+        if (i->roothash_job) {
+                r = pull_job_begin(i->roothash_job);
                 if (r < 0)
                         return r;
         }
 
-        if (i->signature_job) {
-                i->signature_job->on_progress = raw_pull_job_on_progress;
+        if (i->roothash_signature_job) {
+                r = pull_job_begin(i->roothash_signature_job);
+                if (r < 0)
+                        return r;
+        }
 
-                r = pull_job_begin(i->signature_job);
+        if (i->verity_job) {
+                r = pull_job_begin(i->verity_job);
                 if (r < 0)
                         return r;
         }
index e1d450d9dfd83d1efc87ca8632492361ec56f637..985bda4762ce8e58d4a5f112a3789f063e061b9d 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "import-util.h"
 #include "macro.h"
+#include "pull-common.h"
 
 typedef struct RawPull RawPull;
 
@@ -15,4 +16,4 @@ RawPull* raw_pull_unref(RawPull *pull);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(RawPull*, raw_pull_unref);
 
-int raw_pull_start(RawPull *pull, const char *url, const char *local, bool force_local, ImportVerify verify, bool settings, bool roothash);
+int raw_pull_start(RawPull *pull, const char *url, const char *local, PullFlags flags, ImportVerify verify);
index 728b0fe68556d12e71378d4b07a1fdc280d49171..1ee0db156048b3ebf5ce819608994d0e00afca1b 100644 (file)
@@ -40,19 +40,19 @@ struct TarPull {
         sd_event *event;
         CurlGlue *glue;
 
+        PullFlags flags;
+        ImportVerify verify;
         char *image_root;
 
         PullJob *tar_job;
-        PullJob *settings_job;
         PullJob *checksum_job;
         PullJob *signature_job;
+        PullJob *settings_job;
 
         TarPullFinished on_finished;
         void *userdata;
 
         char *local;
-        bool force_local;
-        bool settings;
 
         pid_t tar_pid;
 
@@ -61,8 +61,6 @@ struct TarPull {
 
         char *settings_path;
         char *settings_temp_path;
-
-        ImportVerify verify;
 };
 
 TarPull* tar_pull_unref(TarPull *i) {
@@ -75,22 +73,15 @@ TarPull* tar_pull_unref(TarPull *i) {
         }
 
         pull_job_unref(i->tar_job);
-        pull_job_unref(i->settings_job);
         pull_job_unref(i->checksum_job);
         pull_job_unref(i->signature_job);
+        pull_job_unref(i->settings_job);
 
         curl_glue_unref(i->glue);
         sd_event_unref(i->event);
 
-        if (i->temp_path) {
-                (void) rm_rf(i->temp_path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
-                free(i->temp_path);
-        }
-
-        if (i->settings_temp_path) {
-                (void) unlink(i->settings_temp_path);
-                free(i->settings_temp_path);
-        }
+        rm_rf_subvolume_and_free(i->temp_path);
+        unlink_and_free(i->settings_temp_path);
 
         free(i->final_path);
         free(i->settings_path);
@@ -163,11 +154,6 @@ static void tar_pull_report_progress(TarPull *i, TarProgress p) {
 
                 percent = 0;
 
-                if (i->settings_job) {
-                        percent += i->settings_job->progress_percent * 5 / 100;
-                        remain -= 5;
-                }
-
                 if (i->checksum_job) {
                         percent += i->checksum_job->progress_percent * 5 / 100;
                         remain -= 5;
@@ -178,6 +164,11 @@ static void tar_pull_report_progress(TarPull *i, TarProgress p) {
                         remain -= 5;
                 }
 
+                if (i->settings_job) {
+                        percent += i->settings_job->progress_percent * 5 / 100;
+                        remain -= 5;
+                }
+
                 if (i->tar_job)
                         percent += i->tar_job->progress_percent * remain / 100;
                 break;
@@ -230,11 +221,11 @@ static int tar_pull_make_local_copy(TarPull *i) {
         if (!i->local)
                 return 0;
 
-        r = pull_make_local_copy(i->final_path, i->image_root, i->local, i->force_local);
+        r = pull_make_local_copy(i->final_path, i->image_root, i->local, i->flags);
         if (r < 0)
                 return r;
 
-        if (i->settings) {
+        if (FLAGS_SET(i->flags, PULL_SETTINGS)) {
                 const char *local_settings;
                 assert(i->settings_job);
 
@@ -244,7 +235,7 @@ static int tar_pull_make_local_copy(TarPull *i) {
 
                 local_settings = strjoina(i->image_root, "/", i->local, ".nspawn");
 
-                r = copy_file_atomic(i->settings_path, local_settings, 0664, 0, 0, COPY_REFLINK | (i->force_local ? COPY_REPLACE : 0));
+                r = copy_file_atomic(i->settings_path, local_settings, 0664, 0, 0, COPY_REFLINK | (FLAGS_SET(i->flags, PULL_FORCE) ? COPY_REPLACE : 0));
                 if (r == -EEXIST)
                         log_warning_errno(r, "Settings file %s already exists, not replacing.", local_settings);
                 else if (r == -ENOENT)
@@ -264,12 +255,12 @@ static bool tar_pull_is_done(TarPull *i) {
 
         if (!PULL_JOB_IS_COMPLETE(i->tar_job))
                 return false;
-        if (i->settings_job && !PULL_JOB_IS_COMPLETE(i->settings_job))
-                return false;
         if (i->checksum_job && !PULL_JOB_IS_COMPLETE(i->checksum_job))
                 return false;
         if (i->signature_job && !PULL_JOB_IS_COMPLETE(i->signature_job))
                 return false;
+        if (i->settings_job && !PULL_JOB_IS_COMPLETE(i->settings_job))
+                return false;
 
         return true;
 }
@@ -483,15 +474,15 @@ int tar_pull_start(
                 TarPull *i,
                 const char *url,
                 const char *local,
-                bool force_local,
-                ImportVerify verify,
-                bool settings) {
+                PullFlags flags,
+                ImportVerify verify) {
 
         int r;
 
         assert(i);
         assert(verify < _IMPORT_VERIFY_MAX);
         assert(verify >= 0);
+        assert(!(flags & ~PULL_FLAGS_MASK_TAR));
 
         if (!http_url_is_valid(url))
                 return -EINVAL;
@@ -506,9 +497,8 @@ int tar_pull_start(
         if (r < 0)
                 return r;
 
-        i->force_local = force_local;
+        i->flags = flags;
         i->verify = verify;
-        i->settings = settings;
 
         /* Set up download job for TAR file */
         r = pull_job_new(&i->tar_job, url, i->glue, i);
@@ -524,8 +514,13 @@ int tar_pull_start(
         if (r < 0)
                 return r;
 
+        /* Set up download of checksum/signature files */
+        r = pull_make_verification_jobs(&i->checksum_job, &i->signature_job, verify, url, i->glue, tar_pull_job_on_finished, i);
+        if (r < 0)
+                return r;
+
         /* Set up download job for the settings file (.nspawn) */
-        if (settings) {
+        if (FLAGS_SET(flags, PULL_SETTINGS)) {
                 r = pull_make_auxiliary_job(&i->settings_job, url, tar_strip_suffixes, ".nspawn", i->glue, tar_pull_job_on_finished, i);
                 if (r < 0)
                         return r;
@@ -535,21 +530,10 @@ int tar_pull_start(
                 i->settings_job->calc_checksum = verify != IMPORT_VERIFY_NO;
         }
 
-        /* Set up download of checksum/signature files */
-        r = pull_make_verification_jobs(&i->checksum_job, &i->signature_job, verify, url, i->glue, tar_pull_job_on_finished, i);
-        if (r < 0)
-                return r;
-
         r = pull_job_begin(i->tar_job);
         if (r < 0)
                 return r;
 
-        if (i->settings_job) {
-                r = pull_job_begin(i->settings_job);
-                if (r < 0)
-                        return r;
-        }
-
         if (i->checksum_job) {
                 i->checksum_job->on_progress = tar_pull_job_on_progress;
                 i->checksum_job->on_not_found = pull_job_restart_with_sha256sum;
@@ -567,5 +551,11 @@ int tar_pull_start(
                         return r;
         }
 
+        if (i->settings_job) {
+                r = pull_job_begin(i->settings_job);
+                if (r < 0)
+                        return r;
+        }
+
         return 0;
 }
index 78d982cf5a055465af3491b50279e6d8557efa8f..414077549fdd41c77f3c771097b8f73b41a6a9f4 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "import-util.h"
 #include "macro.h"
+#include "pull-common.h"
 
 typedef struct TarPull TarPull;
 
@@ -15,4 +16,4 @@ TarPull* tar_pull_unref(TarPull *pull);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(TarPull*, tar_pull_unref);
 
-int tar_pull_start(TarPull *pull, const char *url, const char *local, bool force_local, ImportVerify verify, bool settings);
+int tar_pull_start(TarPull *pull, const char *url, const char *local, PullFlags flags, ImportVerify verify);
index e80d8abe6f5140a90428aea972b88fe1f5145db6..33e6196f7941779f8f9616f6d57d33b4c0b2d20b 100644 (file)
 #include "verbs.h"
 #include "web-util.h"
 
-static bool arg_force = false;
 static const char *arg_image_root = "/var/lib/machines";
 static ImportVerify arg_verify = IMPORT_VERIFY_SIGNATURE;
-static bool arg_settings = true;
-static bool arg_roothash = true;
+static PullFlags arg_pull_flags = PULL_SETTINGS | PULL_ROOTHASH | PULL_ROOTHASH_SIGNATURE | PULL_VERITY;
 
 static int interrupt_signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
         log_notice("Transfer aborted.");
@@ -77,7 +75,7 @@ static int pull_tar(int argc, char *argv[], void *userdata) {
                                                "Local image name '%s' is not valid.",
                                                local);
 
-                if (!arg_force) {
+                if (!FLAGS_SET(arg_pull_flags, PULL_FORCE)) {
                         r = image_find(IMAGE_MACHINE, local, NULL, NULL);
                         if (r < 0) {
                                 if (r != -ENOENT)
@@ -105,7 +103,7 @@ static int pull_tar(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return log_error_errno(r, "Failed to allocate puller: %m");
 
-        r = tar_pull_start(pull, url, local, arg_force, arg_verify, arg_settings);
+        r = tar_pull_start(pull, url, local, arg_pull_flags & PULL_FLAGS_MASK_TAR, arg_verify);
         if (r < 0)
                 return log_error_errno(r, "Failed to pull image: %m");
 
@@ -163,7 +161,7 @@ static int pull_raw(int argc, char *argv[], void *userdata) {
                                                "Local image name '%s' is not valid.",
                                                local);
 
-                if (!arg_force) {
+                if (!FLAGS_SET(arg_pull_flags, PULL_FORCE)) {
                         r = image_find(IMAGE_MACHINE, local, NULL, NULL);
                         if (r < 0) {
                                 if (r != -ENOENT)
@@ -191,7 +189,7 @@ static int pull_raw(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return log_error_errno(r, "Failed to allocate puller: %m");
 
-        r = raw_pull_start(pull, url, local, arg_force, arg_verify, arg_settings, arg_roothash);
+        r = raw_pull_start(pull, url, local, arg_pull_flags & PULL_FLAGS_MASK_RAW, arg_verify);
         if (r < 0)
                 return log_error_errno(r, "Failed to pull image: %m");
 
@@ -214,6 +212,8 @@ static int help(int argc, char *argv[], void *userdata) {
                "                              'checksum', 'signature'\n"
                "     --settings=BOOL          Download settings file with image\n"
                "     --roothash=BOOL          Download root hash file with image\n"
+               "     --roothash-sigature=BOOL Download root hash signature file with image\n"
+               "     --verity=BOOL            Download verity file with image\n"
                "     --image-root=PATH        Image root directory\n\n"
                "Commands:\n"
                "  tar URL [NAME]              Download a TAR image\n"
@@ -232,16 +232,20 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_VERIFY,
                 ARG_SETTINGS,
                 ARG_ROOTHASH,
+                ARG_ROOTHASH_SIGNATURE,
+                ARG_VERITY,
         };
 
         static const struct option options[] = {
-                { "help",            no_argument,       NULL, 'h'                 },
-                { "version",         no_argument,       NULL, ARG_VERSION         },
-                { "force",           no_argument,       NULL, ARG_FORCE           },
-                { "image-root",      required_argument, NULL, ARG_IMAGE_ROOT      },
-                { "verify",          required_argument, NULL, ARG_VERIFY          },
-                { "settings",        required_argument, NULL, ARG_SETTINGS        },
-                { "roothash",        required_argument, NULL, ARG_ROOTHASH        },
+                { "help",               no_argument,       NULL, 'h'                    },
+                { "version",            no_argument,       NULL, ARG_VERSION            },
+                { "force",              no_argument,       NULL, ARG_FORCE              },
+                { "image-root",         required_argument, NULL, ARG_IMAGE_ROOT         },
+                { "verify",             required_argument, NULL, ARG_VERIFY             },
+                { "settings",           required_argument, NULL, ARG_SETTINGS           },
+                { "roothash",           required_argument, NULL, ARG_ROOTHASH           },
+                { "roothash-signature", required_argument, NULL, ARG_ROOTHASH_SIGNATURE },
+                { "verity",             required_argument, NULL, ARG_VERITY             },
                 {}
         };
 
@@ -261,7 +265,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return version();
 
                 case ARG_FORCE:
-                        arg_force = true;
+                        arg_pull_flags |= PULL_FORCE;
                         break;
 
                 case ARG_IMAGE_ROOT:
@@ -281,7 +285,7 @@ static int parse_argv(int argc, char *argv[]) {
                         if (r < 0)
                                 return log_error_errno(r, "Failed to parse --settings= parameter '%s': %m", optarg);
 
-                        arg_settings = r;
+                        SET_FLAG(arg_pull_flags, PULL_SETTINGS, r);
                         break;
 
                 case ARG_ROOTHASH:
@@ -289,7 +293,27 @@ static int parse_argv(int argc, char *argv[]) {
                         if (r < 0)
                                 return log_error_errno(r, "Failed to parse --roothash= parameter '%s': %m", optarg);
 
-                        arg_roothash = r;
+                        SET_FLAG(arg_pull_flags, PULL_ROOTHASH, r);
+
+                        /* If we were asked to turn off the root hash, implicitly also turn off the root hash signature */
+                        if (!r)
+                                SET_FLAG(arg_pull_flags, PULL_ROOTHASH_SIGNATURE, false);
+                        break;
+
+                case ARG_ROOTHASH_SIGNATURE:
+                        r = parse_boolean(optarg);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse --roothash-signature= parameter '%s': %m", optarg);
+
+                        SET_FLAG(arg_pull_flags, PULL_ROOTHASH_SIGNATURE, r);
+                        break;
+
+                case ARG_VERITY:
+                        r = parse_boolean(optarg);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse --verity= parameter '%s': %m", optarg);
+
+                        SET_FLAG(arg_pull_flags, PULL_VERITY, r);
                         break;
 
                 case '?':