b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering/***
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering This file is part of systemd.
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering Copyright 2015 Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering systemd is free software; you can redistribute it and/or modify it
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering under the terms of the GNU Lesser General Public License as published by
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering (at your option) any later version.
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering systemd is distributed in the hope that it will be useful, but
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering Lesser General Public License for more details.
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering You should have received a copy of the GNU Lesser General Public License
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering***/
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering#include <getopt.h>
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering#include "sd-event.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "fd-util.h"
f4f15635ec05293ffcc83a5b39f624bbabbd8fd0Lennart Poettering#include "fs-util.h"
25300b5a1fcf54674a69d0f4ab08925be00b0227Lennart Poettering#include "hostname-util.h"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering#include "import-raw.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "import-tar.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "import-util.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "machine-image.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "signal-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "verbs.h"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringstatic bool arg_force = false;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringstatic bool arg_read_only = false;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringstatic const char *arg_image_root = "/var/lib/machines";
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringstatic int interrupt_signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_notice("Transfer aborted.");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering sd_event_exit(sd_event_source_get_event(s), EINTR);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return 0;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering}
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringstatic void on_tar_finished(TarImport *import, int error, void *userdata) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering sd_event *event = userdata;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering assert(import);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (error == 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_info("Operation completed successfully.");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering sd_event_exit(event, abs(error));
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering}
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringstatic int import_tar(int argc, char *argv[], void *userdata) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering _cleanup_(tar_import_unrefp) TarImport *import = NULL;
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_event_unrefp) sd_event *event = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering const char *path = NULL, *local = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering _cleanup_free_ char *ll = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering _cleanup_close_ int open_fd = -1;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering int r, fd;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (argc >= 2)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering path = argv[1];
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (isempty(path) || streq(path, "-"))
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering path = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (argc >= 3)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering local = argv[2];
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering else if (path)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering local = basename(path);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (isempty(local) || streq(local, "-"))
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering local = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (local) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = tar_strip_suffixes(local, &ll);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_oom();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering local = ll;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (!machine_name_is_valid(local)) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error("Local image name '%s' is not valid.", local);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return -EINVAL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (!arg_force) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = image_find(local, NULL);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering else if (r > 0) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error_errno(EEXIST, "Image '%s' already exists.", local);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return -EEXIST;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering } else
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering local = "imported";
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (path) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering open_fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (open_fd < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_error_errno(errno, "Failed to open tar image to import: %m");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering fd = open_fd;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_info("Importing '%s', saving as '%s'.", path, local);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering } else {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering _cleanup_free_ char *pretty = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering fd = STDIN_FILENO;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering (void) readlink_malloc("/proc/self/fd/0", &pretty);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_info("Importing '%s', saving as '%s'.", strna(pretty), local);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = sd_event_default(&event);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_error_errno(r, "Failed to allocate event loop: %m");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
72c0a2c255b172ebbb2a2b7dab7c9aec4c9582d9Lennart Poettering assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
72c0a2c255b172ebbb2a2b7dab7c9aec4c9582d9Lennart Poettering (void) sd_event_add_signal(event, NULL, SIGTERM, interrupt_signal_handler, NULL);
72c0a2c255b172ebbb2a2b7dab7c9aec4c9582d9Lennart Poettering (void) sd_event_add_signal(event, NULL, SIGINT, interrupt_signal_handler, NULL);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = tar_import_new(&import, event, arg_image_root, on_tar_finished, event);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_error_errno(r, "Failed to allocate importer: %m");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = tar_import_start(import, fd, local, arg_force, arg_read_only);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_error_errno(r, "Failed to import image: %m");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = sd_event_loop(event);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_error_errno(r, "Failed to run event loop: %m");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_info("Exiting.");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return -r;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering}
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringstatic void on_raw_finished(RawImport *import, int error, void *userdata) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering sd_event *event = userdata;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering assert(import);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (error == 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_info("Operation completed successfully.");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering sd_event_exit(event, abs(error));
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering}
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringstatic int import_raw(int argc, char *argv[], void *userdata) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering _cleanup_(raw_import_unrefp) RawImport *import = NULL;
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_event_unrefp) sd_event *event = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering const char *path = NULL, *local = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering _cleanup_free_ char *ll = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering _cleanup_close_ int open_fd = -1;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering int r, fd;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (argc >= 2)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering path = argv[1];
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (isempty(path) || streq(path, "-"))
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering path = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (argc >= 3)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering local = argv[2];
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering else if (path)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering local = basename(path);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (isempty(local) || streq(local, "-"))
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering local = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (local) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = raw_strip_suffixes(local, &ll);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_oom();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering local = ll;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (!machine_name_is_valid(local)) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error("Local image name '%s' is not valid.", local);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return -EINVAL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (!arg_force) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = image_find(local, NULL);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering else if (r > 0) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error_errno(EEXIST, "Image '%s' already exists.", local);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return -EEXIST;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering } else
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering local = "imported";
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (path) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering open_fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (open_fd < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_error_errno(errno, "Failed to open raw image to import: %m");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering fd = open_fd;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_info("Importing '%s', saving as '%s'.", path, local);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering } else {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering _cleanup_free_ char *pretty = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering fd = STDIN_FILENO;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering (void) readlink_malloc("/proc/self/fd/0", &pretty);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_info("Importing '%s', saving as '%s'.", pretty, local);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = sd_event_default(&event);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_error_errno(r, "Failed to allocate event loop: %m");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
72c0a2c255b172ebbb2a2b7dab7c9aec4c9582d9Lennart Poettering assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
72c0a2c255b172ebbb2a2b7dab7c9aec4c9582d9Lennart Poettering (void) sd_event_add_signal(event, NULL, SIGTERM, interrupt_signal_handler, NULL);
72c0a2c255b172ebbb2a2b7dab7c9aec4c9582d9Lennart Poettering (void) sd_event_add_signal(event, NULL, SIGINT, interrupt_signal_handler, NULL);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = raw_import_new(&import, event, arg_image_root, on_raw_finished, event);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_error_errno(r, "Failed to allocate importer: %m");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = raw_import_start(import, fd, local, arg_force, arg_read_only);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_error_errno(r, "Failed to import image: %m");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = sd_event_loop(event);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return log_error_errno(r, "Failed to run event loop: %m");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_info("Exiting.");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return -r;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering}
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringstatic int help(int argc, char *argv[], void *userdata) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering printf("%s [OPTIONS...] {COMMAND} ...\n\n"
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering "Import container or virtual machine images.\n\n"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering " -h --help Show this help\n"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering " --version Show package version\n"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering " --force Force creation of image\n"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering " --image-root=PATH Image root directory\n"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering " --read-only Create a read-only image\n\n"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering "Commands:\n"
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering " tar FILE [NAME] Import a TAR image\n"
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering " raw FILE [NAME] Import a RAW image\n",
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering program_invocation_short_name);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return 0;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering}
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering enum {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering ARG_VERSION = 0x100,
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering ARG_FORCE,
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering ARG_IMAGE_ROOT,
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering ARG_READ_ONLY,
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering };
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering static const struct option options[] = {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering { "help", no_argument, NULL, 'h' },
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering { "version", no_argument, NULL, ARG_VERSION },
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering { "force", no_argument, NULL, ARG_FORCE },
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering { "image-root", required_argument, NULL, ARG_IMAGE_ROOT },
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering { "read-only", no_argument, NULL, ARG_READ_ONLY },
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering {}
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering };
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering int c;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering assert(argc >= 0);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering assert(argv);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering switch (c) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering case 'h':
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return help(0, NULL, NULL);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering case ARG_VERSION:
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering return version();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering case ARG_FORCE:
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering arg_force = true;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering break;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering case ARG_IMAGE_ROOT:
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering arg_image_root = optarg;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering break;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering case ARG_READ_ONLY:
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering arg_read_only = true;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering break;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering case '?':
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return -EINVAL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering default:
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering assert_not_reached("Unhandled option");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return 1;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering}
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringstatic int import_main(int argc, char *argv[]) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering static const Verb verbs[] = {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering { "help", VERB_ANY, VERB_ANY, 0, help },
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering { "tar", 2, 3, 0, import_tar },
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering { "raw", 2, 3, 0, import_raw },
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering {}
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering };
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return dispatch_verb(argc, argv, verbs, NULL);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering}
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringint main(int argc, char *argv[]) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering int r;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering setlocale(LC_ALL, "");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_parse_environment();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_open();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = parse_argv(argc, argv);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r <= 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering goto finish;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
ce30c8dcb41dfe9264f79f30c7f51c0e74576638Lennart Poettering (void) ignore_signals(SIGPIPE, -1);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = import_main(argc, argv);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringfinish:
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering}