int tar_pull_start(TarPull *i, const char *url, const char *local, bool force_local, ImportVerify verify) { int r; assert(i); if (!http_url_is_valid(url)) return -EINVAL; if (local && !machine_name_is_valid(local)) return -EINVAL; if (i->tar_job) return -EBUSY; r = free_and_strdup(&i->local, local); if (r < 0) return r; i->force_local = force_local; i->verify = verify; r = pull_job_new(&i->tar_job, url, i->glue, i); if (r < 0) return r; i->tar_job->on_finished = tar_pull_job_on_finished; i->tar_job->on_open_disk = tar_pull_job_on_open_disk; i->tar_job->on_progress = tar_pull_job_on_progress; i->tar_job->calc_checksum = verify != IMPORT_VERIFY_NO; i->tar_job->grow_machine_directory = i->grow_machine_directory; r = pull_find_old_etags(url, i->image_root, DT_DIR, ".tar-", NULL, &i->tar_job->old_etags); if (r < 0) return r; 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->checksum_job) { i->checksum_job->on_progress = tar_pull_job_on_progress; r = pull_job_begin(i->checksum_job); if (r < 0) return r; } if (i->signature_job) { i->signature_job->on_progress = tar_pull_job_on_progress; r = pull_job_begin(i->signature_job); if (r < 0) return r; } return 0; }
int dkr_pull_new( DkrPull **ret, sd_event *event, const char *index_url, const char *image_root, DkrPullFinished on_finished, void *userdata) { _cleanup_(dkr_pull_unrefp) DkrPull *i = NULL; char *e; int r; assert(ret); assert(index_url); if (!http_url_is_valid(index_url)) return -EINVAL; i = new0(DkrPull, 1); if (!i) return -ENOMEM; i->on_finished = on_finished; i->userdata = userdata; i->image_root = strdup(image_root ?: "/var/lib/machines"); if (!i->image_root) return -ENOMEM; i->grow_machine_directory = path_startswith(i->image_root, "/var/lib/machines"); i->index_url = strdup(index_url); if (!i->index_url) return -ENOMEM; e = endswith(i->index_url, "/"); if (e) *e = 0; if (event) i->event = sd_event_ref(event); else { r = sd_event_default(&i->event); if (r < 0) return r; } r = curl_glue_new(&i->glue, i->event); if (r < 0) return r; i->glue->on_finished = pull_job_curl_on_finished; i->glue->userdata = i; *ret = i; i = NULL; return 0; }
int raw_pull_start( RawPull *i, const char *url, const char *local, bool force_local, ImportVerify verify, bool settings, bool roothash) { int r; assert(i); assert(verify < _IMPORT_VERIFY_MAX); assert(verify >= 0); if (!http_url_is_valid(url)) return -EINVAL; if (local && !machine_name_is_valid(local)) return -EINVAL; if (i->raw_job) return -EBUSY; r = free_and_strdup(&i->local, local); if (r < 0) return r; i->force_local = force_local; 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); if (r < 0) return r; i->raw_job->on_finished = raw_pull_job_on_finished; i->raw_job->on_open_disk = raw_pull_job_on_open_disk_raw; i->raw_job->on_progress = raw_pull_job_on_progress; i->raw_job->calc_checksum = verify != IMPORT_VERIFY_NO; i->raw_job->grow_machine_directory = i->grow_machine_directory; r = pull_find_old_etags(url, i->image_root, DT_REG, ".raw-", ".raw", &i->raw_job->old_etags); 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; 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) { 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; } 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; 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->style = VERIFICATION_PER_FILE; 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; } return 0; }
static int pull_tar(int argc, char *argv[], void *userdata) { _cleanup_(tar_pull_unrefp) TarPull *pull = NULL; _cleanup_event_unref_ sd_event *event = NULL; const char *url, *local; _cleanup_free_ char *l = NULL, *ll = NULL; int r; url = argv[1]; if (!http_url_is_valid(url)) { log_error("URL '%s' is not valid.", url); return -EINVAL; } if (argc >= 3) local = argv[2]; else { r = import_url_last_component(url, &l); if (r < 0) return log_error_errno(r, "Failed get final component of URL: %m"); local = l; } if (isempty(local) || streq(local, "-")) local = NULL; if (local) { r = tar_strip_suffixes(local, &ll); if (r < 0) return log_oom(); local = ll; if (!machine_name_is_valid(local)) { log_error("Local image name '%s' is not valid.", local); return -EINVAL; } if (!arg_force) { r = image_find(local, NULL); if (r < 0) return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local); else if (r > 0) { log_error_errno(EEXIST, "Image '%s' already exists.", local); return -EEXIST; } } log_info("Pulling '%s', saving as '%s'.", url, local); } else log_info("Pulling '%s'.", url); r = sd_event_default(&event); if (r < 0) return log_error_errno(r, "Failed to allocate event loop: %m"); assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0); (void) sd_event_add_signal(event, NULL, SIGTERM, interrupt_signal_handler, NULL); (void) sd_event_add_signal(event, NULL, SIGINT, interrupt_signal_handler, NULL); r = tar_pull_new(&pull, event, arg_image_root, on_tar_finished, event); 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); if (r < 0) return log_error_errno(r, "Failed to pull image: %m"); r = sd_event_loop(event); if (r < 0) return log_error_errno(r, "Failed to run event loop: %m"); log_info("Exiting."); return -r; }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_FORCE, ARG_DKR_INDEX_URL, ARG_IMAGE_ROOT, ARG_VERIFY, ARG_SETTINGS, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "force", no_argument, NULL, ARG_FORCE }, { "dkr-index-url", required_argument, NULL, ARG_DKR_INDEX_URL }, { "image-root", required_argument, NULL, ARG_IMAGE_ROOT }, { "verify", required_argument, NULL, ARG_VERIFY }, { "settings", required_argument, NULL, ARG_SETTINGS }, {} }; int c, r; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) switch (c) { case 'h': return help(0, NULL, NULL); case ARG_VERSION: return version(); case ARG_FORCE: arg_force = true; break; case ARG_DKR_INDEX_URL: if (!http_url_is_valid(optarg)) { log_error("Index URL is not valid: %s", optarg); return -EINVAL; } arg_dkr_index_url = optarg; break; case ARG_IMAGE_ROOT: arg_image_root = optarg; break; case ARG_VERIFY: arg_verify = import_verify_from_string(optarg); if (arg_verify < 0) { log_error("Invalid verification setting '%s'", optarg); return -EINVAL; } break; case ARG_SETTINGS: r = parse_boolean(optarg); if (r < 0) return log_error_errno(r, "Failed to parse --settings= parameter '%s'", optarg); arg_settings = r; break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } return 1; }
int tar_pull_start( TarPull *i, const char *url, const char *local, bool force_local, ImportVerify verify, bool settings) { int r; assert(i); assert(verify < _IMPORT_VERIFY_MAX); assert(verify >= 0); if (!http_url_is_valid(url)) return -EINVAL; if (local && !machine_name_is_valid(local)) return -EINVAL; if (i->tar_job) return -EBUSY; r = free_and_strdup(&i->local, local); if (r < 0) return r; i->force_local = force_local; i->verify = verify; i->settings = settings; /* Set up download job for TAR file */ r = pull_job_new(&i->tar_job, url, i->glue, i); if (r < 0) return r; i->tar_job->on_finished = tar_pull_job_on_finished; i->tar_job->on_open_disk = tar_pull_job_on_open_disk_tar; i->tar_job->on_progress = tar_pull_job_on_progress; i->tar_job->calc_checksum = verify != IMPORT_VERIFY_NO; i->tar_job->grow_machine_directory = i->grow_machine_directory; r = pull_find_old_etags(url, i->image_root, DT_DIR, ".tar-", NULL, &i->tar_job->old_etags); if (r < 0) return r; /* Set up download job for the settings file (.nspawn) */ if (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; i->settings_job->on_open_disk = tar_pull_job_on_open_disk_settings; i->settings_job->on_progress = tar_pull_job_on_progress; 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->style = VERIFICATION_PER_FILE; r = pull_job_begin(i->checksum_job); if (r < 0) return r; } if (i->signature_job) { i->signature_job->on_progress = tar_pull_job_on_progress; r = pull_job_begin(i->signature_job); if (r < 0) return r; } return 0; }