summaryrefslogtreecommitdiff
path: root/image
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2020-04-02 05:08:04 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2020-04-02 05:08:04 -0500
commitc6b0e5fc81d905f57688c696f80e480712f612ab (patch)
tree9b08fec4059ed05becfe85e426ff316cb7a5d381 /image
parent94fc4d46c3f2ebc179b768525a4aad73a655e083 (diff)
downloadhorizon-c6b0e5fc81d905f57688c696f80e480712f612ab.tar.gz
horizon-c6b0e5fc81d905f57688c696f80e480712f612ab.tar.bz2
horizon-c6b0e5fc81d905f57688c696f80e480712f612ab.tar.xz
horizon-c6b0e5fc81d905f57688c696f80e480712f612ab.zip
image: Significantly refactor how backends are registered
Diffstat (limited to 'image')
-rw-r--r--image/backends/backends.hh33
-rw-r--r--image/backends/basic.cc5
-rw-r--r--image/backends/basic.hh13
-rw-r--r--image/creator.cc64
4 files changed, 71 insertions, 44 deletions
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 <functional>
-#include <string>
-#include <vector>
-
-namespace Horizon {
-namespace Image {
-
-class BasicBackend;
-
-struct BackendDescriptor {
- std::string type_code;
- std::string description;
- std::function<BasicBackend *(std::string, std::string)> creation_fn;
-};
-
-extern std::vector<BackendDescriptor> 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<BackendDescriptor> known_backends = {
{"squashfs", "Create a SquashFS image (.squashfs)", [](std::string, std::string){ return nullptr; } }
};
+const std::vector<BackendDescriptor> 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 <functional>
#include <string>
+#include <vector>
namespace Horizon {
namespace Image {
+class BasicBackend;
+
+struct BackendDescriptor {
+ std::string type_code;
+ std::string description;
+ std::function<BasicBackend *(std::string, std::string)> 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<BackendDescriptor> 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 <boost/program_options.hpp>
#include <cstdlib> /* EXIT_* */
#include <string>
-#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<std::string>();
}
+ if(!vm["ir-dir"].empty()) {
+ ir_dir = vm["ir-dir"].as<std::string>();
+ }
+
+ if(!vm["output"].empty()) {
+ output_path = vm["output"].as<std::string>();
+ }
+
+ /* 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<std::string>());
+ 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;
}