From c6b0e5fc81d905f57688c696f80e480712f612ab Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Thu, 2 Apr 2020 05:08:04 -0500 Subject: image: Significantly refactor how backends are registered --- image/backends/backends.hh | 33 ------------------------ image/backends/basic.cc | 5 +++- image/backends/basic.hh | 13 ++++++++++ image/creator.cc | 64 ++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 71 insertions(+), 44 deletions(-) delete mode 100644 image/backends/backends.hh (limited to 'image') diff --git a/image/backends/backends.hh b/image/backends/backends.hh deleted file mode 100644 index 3199ee0..0000000 --- a/image/backends/backends.hh +++ /dev/null @@ -1,33 +0,0 @@ -/* - * backends.hh - Horizon Image Creation backend table - * image, the image processing utilities for - * Project Horizon - * - * Copyright (c) 2020 Adélie Linux and contributors. All rights reserved. - * This code is licensed under the AGPL 3.0 license, as noted in the - * LICENSE-code file in the root directory of this repository. - * - * SPDX-License-Identifier: AGPL-3.0-only - */ - -#pragma once - -#include -#include -#include - -namespace Horizon { -namespace Image { - -class BasicBackend; - -struct BackendDescriptor { - std::string type_code; - std::string description; - std::function creation_fn; -}; - -extern std::vector known_backends; - -} -} diff --git a/image/backends/basic.cc b/image/backends/basic.cc index 908f1d9..dbe387c 100644 --- a/image/backends/basic.cc +++ b/image/backends/basic.cc @@ -11,7 +11,6 @@ */ #include "basic.hh" -#include "backends.hh" namespace Horizon { namespace Image { @@ -21,6 +20,10 @@ std::vector known_backends = { {"squashfs", "Create a SquashFS image (.squashfs)", [](std::string, std::string){ return nullptr; } } }; +const std::vector BasicBackend::available_backends() { + return known_backends; +} + int BasicBackend::prepare() { /* The default implementation returns success immediately; * no preparation is required. */ diff --git a/image/backends/basic.hh b/image/backends/basic.hh index d39c57e..3181f69 100644 --- a/image/backends/basic.hh +++ b/image/backends/basic.hh @@ -12,11 +12,21 @@ #pragma once +#include #include +#include namespace Horizon { namespace Image { +class BasicBackend; + +struct BackendDescriptor { + std::string type_code; + std::string description; + std::function creation_fn; +}; + class BasicBackend { public: /*! Create the backend object. @@ -43,6 +53,9 @@ public: */ virtual int finalise(); + /*! Returns a list of available backends. */ + static const std::vector available_backends(); + /*! The intermediate directory which contains the sysroot the image * should contain. */ const std::string &ir_dir; diff --git a/image/creator.cc b/image/creator.cc index ce688fa..70571fa 100644 --- a/image/creator.cc +++ b/image/creator.cc @@ -13,7 +13,7 @@ #include #include /* EXIT_* */ #include -#include "backends/backends.hh" +#include "backends/basic.hh" #include "hscript/script.hh" #include "util/output.hh" @@ -28,9 +28,13 @@ bool pretty = true; /*! Controls ASCII colour output */ /*! Entry-point for the image creation utility. */ int main(int argc, char *argv[]) { using namespace boost::program_options; + using namespace Horizon::Image; + bool needs_help{}, disable_pretty{}; int exit_code = EXIT_SUCCESS; - std::string if_path{"/etc/horizon/installfile"}, ir_dir{"/target"}, type_code{"tar"}; + std::string if_path{"/etc/horizon/installfile"}, ir_dir{"/target"}, + output_path{"image.tar"}, type_code{"tar"}; + BasicBackend *backend = nullptr; Horizon::ScriptOptions opts; Horizon::Script *my_script; @@ -89,9 +93,9 @@ int main(int argc, char *argv[]) { if(type_code == "list") { std::cout << "Type codes known by this build of Image Creation:" << std::endl << std::endl; - for(auto &backend : Horizon::Image::known_backends) { - std::cout << std::setw(10) << std::left << backend.type_code - << backend.description << std::endl; + for(const auto &candidate : BasicBackend::available_backends()) { + std::cout << std::setw(10) << std::left << candidate.type_code + << candidate.description << std::endl; } return EXIT_SUCCESS; } @@ -100,6 +104,27 @@ int main(int argc, char *argv[]) { if_path = vm["installfile"].as(); } + if(!vm["ir-dir"].empty()) { + ir_dir = vm["ir-dir"].as(); + } + + if(!vm["output"].empty()) { + output_path = vm["output"].as(); + } + + /* Load the proper backend. */ + for(const auto &candidate : BasicBackend::available_backends()) { + if(candidate.type_code == type_code) { + backend = candidate.creation_fn(ir_dir, output_path); + break; + } + } + if(backend == nullptr) { + output_error("command-line", "unsupported backend or internal error", + type_code); + return EXIT_FAILURE; + } + opts.set(Horizon::InstallEnvironment); opts.set(Horizon::ImageOnly); @@ -112,15 +137,34 @@ int main(int argc, char *argv[]) { /* if an error occurred during parsing, bail out now */ if(!my_script) { - return EXIT_FAILURE; - } + exit_code = EXIT_FAILURE; + goto early_trouble; + } else { + int ret; - if(!vm["ir-dir"].empty()) { - my_script->setTargetDirectory(vm["ir-dir"].as()); + if(!my_script->execute()) { + exit_code = EXIT_FAILURE; + goto trouble; + } + +#define RUN_PHASE_OR_TROUBLE(_PHASE, _FRIENDLY) \ + ret = backend->_PHASE();\ + if(ret != 0) {\ + output_error("internal", "error during output " _FRIENDLY,\ + std::to_string(ret));\ + exit_code = EXIT_FAILURE;\ + goto trouble;\ } - my_script->execute(); + RUN_PHASE_OR_TROUBLE(prepare, "preparation"); + RUN_PHASE_OR_TROUBLE(create, "creation"); + RUN_PHASE_OR_TROUBLE(finalise, "finalisation"); + } +trouble: /* delete the Script and exit */ delete my_script; +early_trouble: /* no script yet */ + delete backend; + return exit_code; } -- cgit v1.2.3-60-g2f50