import: optionally pull .verity + .roothash.p7s data when downloading
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.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
+170
-82
@@ -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,14 +417,18 @@ 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))
|
||||
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;
|
||||
if (i->roothash_job && !PULL_JOB_IS_COMPLETE(i->roothash_job))
|
||||
return false;
|
||||
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->error != 0)
|
||||
log_info_errno(j->error, "Root hash file could not be retrieved, proceeding without.");
|
||||
} else if (j == i->settings_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->roothash_signature_job) {
|
||||
if (j->error != 0)
|
||||
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,17 +748,11 @@ int raw_pull_start(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (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;
|
||||
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;
|
||||
|
||||
i->roothash_job->on_open_disk = raw_pull_job_on_open_disk_roothash;
|
||||
i->roothash_job->on_progress = raw_pull_job_on_progress;
|
||||
i->roothash_job->calc_checksum = verify != IMPORT_VERIFY_NO;
|
||||
}
|
||||
|
||||
if (settings) {
|
||||
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;
|
||||
@@ -712,26 +762,40 @@ int raw_pull_start(
|
||||
i->settings_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_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;
|
||||
|
||||
i->roothash_job->on_open_disk = raw_pull_job_on_open_disk_roothash;
|
||||
i->roothash_job->on_progress = raw_pull_job_on_progress;
|
||||
i->roothash_job->calc_checksum = verify != IMPORT_VERIFY_NO;
|
||||
}
|
||||
|
||||
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->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;
|
||||
}
|
||||
|
||||
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 (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 = raw_pull_job_on_progress;
|
||||
i->checksum_job->on_not_found = pull_job_restart_with_sha256sum;
|
||||
@@ -749,5 +813,29 @@ int raw_pull_start(
|
||||
return r;
|
||||
}
|
||||
|
||||
if (i->settings_job) {
|
||||
r = pull_job_begin(i->settings_job);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (i->roothash_job) {
|
||||
r = pull_job_begin(i->roothash_job);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (i->roothash_signature_job) {
|
||||
r = pull_job_begin(i->roothash_signature_job);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (i->verity_job) {
|
||||
r = pull_job_begin(i->verity_job);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
+32
-42
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
+41
-17
@@ -19,11 +19,9 @@
|
||||
#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 '?':
|
||||
|
||||
Reference in New Issue
Block a user