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 manager_enumerate_machines(Manager *m) { _cleanup_closedir_ DIR *d = NULL; struct dirent *de; int r = 0; assert(m); r = manager_add_host_machine(m); if (r < 0) return r; /* Read in machine data stored on disk */ d = opendir("/run/systemd/machines"); if (!d) { if (errno == ENOENT) return 0; return log_error_errno(errno, "Failed to open /run/systemd/machines: %m"); } FOREACH_DIRENT(de, d, return -errno) { struct Machine *machine; int k; if (!dirent_is_file(de)) continue; /* Ignore symlinks that map the unit name to the machine */ if (startswith(de->d_name, "unit:")) continue; if (!machine_name_is_valid(de->d_name)) continue; k = manager_add_machine(m, de->d_name, &machine); if (k < 0) { r = log_error_errno(k, "Failed to add machine by file name %s: %m", de->d_name); continue; } machine_add_to_gc_queue(machine); k = machine_load(machine); if (k < 0) r = k; } return r; }
int raw_import_start(RawImport *i, int fd, const char *local, bool force_local, bool read_only) { int r; assert(i); assert(fd >= 0); assert(local); if (!machine_name_is_valid(local)) return -EINVAL; if (i->input_fd >= 0) return -EBUSY; r = fd_nonblock(fd, true); if (r < 0) return r; r = free_and_strdup(&i->local, local); if (r < 0) return r; i->force_local = force_local; i->read_only = read_only; if (fstat(fd, &i->st) < 0) return -errno; r = sd_event_add_io(i->event, &i->input_event_source, fd, EPOLLIN, raw_import_on_input, i); if (r == -EPERM) { /* This fd does not support epoll, for example because it is a regular file. Busy read in that case */ r = sd_event_add_defer(i->event, &i->input_event_source, raw_import_on_defer, i); if (r < 0) return r; r = sd_event_source_set_enabled(i->input_event_source, SD_EVENT_ON); } if (r < 0) return r; i->input_fd = fd; return r; }
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 import_tar(int argc, char *argv[], void *userdata) { _cleanup_(tar_import_unrefp) TarImport *import = NULL; _cleanup_event_unref_ sd_event *event = NULL; const char *path = NULL, *local = NULL; _cleanup_free_ char *ll = NULL; _cleanup_close_ int open_fd = -1; int r, fd; if (argc >= 2) path = argv[1]; if (isempty(path) || streq(path, "-")) path = NULL; if (argc >= 3) local = argv[2]; else if (path) local = basename(path); 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; } } } else local = "imported"; if (path) { open_fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY); if (open_fd < 0) return log_error_errno(errno, "Failed to open tar image to import: %m"); fd = open_fd; log_info("Importing '%s', saving as '%s'.", path, local); } else { _cleanup_free_ char *pretty = NULL; fd = STDIN_FILENO; (void) readlink_malloc("/proc/self/fd/0", &pretty); log_info("Importing '%s', saving as '%s'.", strna(pretty), local); } 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_import_new(&import, event, arg_image_root, on_tar_finished, event); if (r < 0) return log_error_errno(r, "Failed to allocate importer: %m"); r = tar_import_start(import, fd, local, arg_force, arg_read_only); if (r < 0) return log_error_errno(r, "Failed to import 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 pull_dck(int argc, char *argv[], void *userdata) { _cleanup_(dck_import_unrefp) DckImport *import = NULL; _cleanup_event_unref_ sd_event *event = NULL; const char *name, *tag, *local; int r; tag = strchr(argv[1], ':'); if (tag) { name = strndupa(argv[1], tag - argv[1]); tag++; } else { name = argv[1]; tag = "latest"; } if (argc >= 3) local = argv[2]; else { local = strchr(name, '/'); if (local) local++; else local = name; } if (streq(local, "-") || isempty(local)) local = NULL; if (!dck_name_is_valid(name)) { log_error("Remote name '%s' is not valid.", name); return -EINVAL; } if (!dck_tag_is_valid(tag)) { log_error("Tag name '%s' is not valid.", tag); return -EINVAL; } if (local) { const char *p; if (!machine_name_is_valid(tag)) { log_error("Local image name '%s' is not valid.", local); return -EINVAL; } p = strappenda("/var/lib/container/", local); if (laccess(p, F_OK) >= 0) { if (!arg_force) { log_info("Image '%s' already exists.", local); return 0; } } else if (errno != ENOENT) return log_error_errno(errno, "Can't check if image '%s' already exists: %m", local); log_info("Pulling '%s' with tag '%s', saving as '%s'.", name, tag, local); } else log_info("Pulling '%s' with tag '%s'.", name, tag); 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, SIGTERM, SIGINT, -1) == 0); sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL); sd_event_add_signal(event, NULL, SIGINT, NULL, NULL); r = dck_import_new(&import, event, on_finished, event); if (r < 0) return log_error_errno(r, "Failed to allocate importer: %m"); r = dck_import_pull(import, name, tag, local, arg_force); 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 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 pull_dkr(int argc, char *argv[], void *userdata) { _cleanup_(dkr_pull_unrefp) DkrPull *pull = NULL; _cleanup_event_unref_ sd_event *event = NULL; const char *name, *reference, *local, *digest; int r; if (!arg_dkr_index_url) { log_error("Please specify an index URL with --dkr-index-url="); return -EINVAL; } if (arg_verify != IMPORT_VERIFY_NO) { log_error("Pulls from dkr do not support image verification, please pass --verify=no."); return -EINVAL; } digest = strchr(argv[1], '@'); if (digest) { reference = digest + 1; name = strndupa(argv[1], digest - argv[1]); } else { reference = strchr(argv[1], ':'); if (reference) { name = strndupa(argv[1], reference - argv[1]); reference++; } else { name = argv[1]; reference = "latest"; } } if (!dkr_name_is_valid(name)) { log_error("Remote name '%s' is not valid.", name); return -EINVAL; } if (!dkr_ref_is_valid(reference)) { log_error("Tag name '%s' is not valid.", reference); return -EINVAL; } if (argc >= 3) local = argv[2]; else { local = strchr(name, '/'); if (local) local++; else local = name; } if (isempty(local) || streq(local, "-")) local = NULL; if (local) { 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' with reference '%s', saving as '%s'.", name, reference, local); } else log_info("Pulling '%s' with reference '%s'.", name, reference); 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 = dkr_pull_new(&pull, event, arg_dkr_index_url, arg_image_root, on_dkr_finished, event); if (r < 0) return log_error_errno(r, "Failed to allocate puller: %m"); r = dkr_pull_start(pull, name, reference, local, arg_force, DKR_PULL_V2); 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; }
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; }