import.c revision c660bb094288d89762cdbedd08661127988e5548
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering This file is part of systemd.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Copyright 2014 Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering systemd is free software; you can redistribute it and/or modify it
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering under the terms of the GNU Lesser General Public License as published by
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (at your option) any later version.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering systemd is distributed in the hope that it will be useful, but
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Lesser General Public License for more details.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering You should have received a copy of the GNU Lesser General Public License
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic bool arg_force = false;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic const char *arg_image_root = "/var/lib/machines";
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic ImportVerify arg_verify = IMPORT_VERIFY_SIGNATURE;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic const char* arg_dkr_index_url = DEFAULT_DKR_INDEX_URL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic void on_tar_finished(TarImport *import, int error, void *userdata) {
cf0fbc49e67b55f8d346fc94de28c90113505297Thomas Hindoe Paaboel Andersen log_info("Operation completed successfully.");
cf0fbc49e67b55f8d346fc94de28c90113505297Thomas Hindoe Paaboel Andersen log_error_errno(error, "Operation failed: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int strip_tar_suffixes(const char *name, char **ret) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering const char *e;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int pull_tar(int argc, char *argv[], void *userdata) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering _cleanup_(tar_import_unrefp) TarImport *import = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering _cleanup_event_unref_ sd_event *event = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering _cleanup_free_ char *l = NULL, *ll = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("URL '%s' is not valid.", url);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed get final component of URL: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Local image name '%s' is not valid.", local);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering else if (r > 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error_errno(EEXIST, "Image '%s' already exists.", local);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_info("Pulling '%s', saving as '%s'.", url, local);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to allocate event loop: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = tar_import_new(&import, event, arg_image_root, on_tar_finished, event);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to allocate importer: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = tar_import_pull(import, url, local, arg_force);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to pull image: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to run event loop: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic void on_raw_finished(RawImport *import, int error, void *userdata) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_info("Operation completed successfully.");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error_errno(error, "Operation failed: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int strip_raw_suffixes(const char *p, char **ret) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering static const char suffixes[] =
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int pull_raw(int argc, char *argv[], void *userdata) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering _cleanup_(raw_import_unrefp) RawImport *import = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering _cleanup_event_unref_ sd_event *event = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering _cleanup_free_ char *l = NULL, *ll = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("URL '%s' is not valid.", url);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed get final component of URL: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Local image name '%s' is not valid.", local);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering else if (r > 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error_errno(EEXIST, "Image '%s' already exists.", local);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_info("Pulling '%s', saving as '%s'.", url, local);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to allocate event loop: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = raw_import_new(&import, event, arg_image_root, on_raw_finished, event);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to allocate importer: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = raw_import_pull(import, url, local, arg_force, arg_verify);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to pull image: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to run event loop: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic void on_dkr_finished(DkrImport *import, int error, void *userdata) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_info("Operation completed successfully.");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error_errno(error, "Operation failed: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int pull_dkr(int argc, char *argv[], void *userdata) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering _cleanup_(dkr_import_unrefp) DkrImport *import = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering _cleanup_event_unref_ sd_event *event = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Please specify an index URL with --dkr-index-url=");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Imports from dkr do not support image verification, please pass --verify=no.");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Remote name '%s' is not valid.", name);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Tag name '%s' is not valid.", tag);
1b4bb4fdac4dce4e658aa3743153d77c04d1a331Zbigniew Jędrzejewski-Szmek if (!machine_name_is_valid(local)) {
1b4bb4fdac4dce4e658aa3743153d77c04d1a331Zbigniew Jędrzejewski-Szmek log_error("Local image name '%s' is not valid.", local);
1b4bb4fdac4dce4e658aa3743153d77c04d1a331Zbigniew Jędrzejewski-Szmek p = strappenda(arg_image_root, "/", local);
1b4bb4fdac4dce4e658aa3743153d77c04d1a331Zbigniew Jędrzejewski-Szmek log_info("Image '%s' already exists.", local);
1b4bb4fdac4dce4e658aa3743153d77c04d1a331Zbigniew Jędrzejewski-Szmek return log_error_errno(errno, "Can't check if image '%s' already exists: %m", local);
1b4bb4fdac4dce4e658aa3743153d77c04d1a331Zbigniew Jędrzejewski-Szmek log_info("Pulling '%s' with tag '%s', saving as '%s'.", name, tag, local);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_info("Pulling '%s' with tag '%s'.", name, tag);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to allocate event loop: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = dkr_import_new(&import, event, arg_dkr_index_url, arg_image_root, on_dkr_finished, event);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to allocate importer: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = dkr_import_pull(import, name, tag, local, arg_force);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to pull image: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return log_error_errno(r, "Failed to run event loop: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int help(int argc, char *argv[], void *userdata) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering printf("%s [OPTIONS...] {COMMAND} ...\n\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering "Import container or virtual machine image.\n\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " -h --help Show this help\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " --version Show package version\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " --force Force creation of image\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " --verify= Verify downloaded image, one of: 'no', 'sum'\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " 'signature'.\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " --image-root= Image root directory\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " --dkr-index-url=URL Specify index URL to use for downloads\n\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " pull-tar URL [NAME] Download a TAR image\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " pull-raw URL [NAME] Download a RAW image\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " pull-dkr REMOTE [NAME] Download a DKR image\n",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering { "version", no_argument, NULL, ARG_VERSION },
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering { "force", no_argument, NULL, ARG_FORCE },
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering { "dkr-index-url", required_argument, NULL, ARG_DKR_INDEX_URL },
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering { "image-root", required_argument, NULL, ARG_IMAGE_ROOT },
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering { "verify", required_argument, NULL, ARG_VERIFY },
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Index URL is not valid: %s", optarg);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering arg_verify = import_verify_from_string(optarg);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Invalid verification setting '%s'", optarg);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int import_main(int argc, char *argv[]) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return dispatch_verb(argc, argv, verbs, NULL);