summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--image/CMakeLists.txt3
-rw-r--r--image/backends/CMakeLists.txt4
-rw-r--r--image/backends/README.rst12
-rw-r--r--image/backends/backends.hh33
-rw-r--r--image/backends/basic.cc37
-rw-r--r--image/backends/basic.hh54
-rw-r--r--image/creator.cc38
7 files changed, 171 insertions, 10 deletions
diff --git a/image/CMakeLists.txt b/image/CMakeLists.txt
index c978ce6..cbee674 100644
--- a/image/CMakeLists.txt
+++ b/image/CMakeLists.txt
@@ -1,8 +1,11 @@
find_package(Boost REQUIRED COMPONENTS program_options)
include_directories(${Boost_INCLUDE_DIR})
+add_subdirectory(backends)
+
set(IMG_SRCS
creator.cc
+ ${BACKEND_SRCS}
)
add_executable(hscript-image ${IMG_SRCS})
target_link_libraries(hscript-image hscript ${Boost_LIBRARIES})
diff --git a/image/backends/CMakeLists.txt b/image/backends/CMakeLists.txt
new file mode 100644
index 0000000..f3c7f5d
--- /dev/null
+++ b/image/backends/CMakeLists.txt
@@ -0,0 +1,4 @@
+set(BACKEND_SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/basic.cc
+ PARENT_SCOPE
+)
diff --git a/image/backends/README.rst b/image/backends/README.rst
index ca510b9..acb44ef 100644
--- a/image/backends/README.rst
+++ b/image/backends/README.rst
@@ -41,17 +41,19 @@ Design
Image creation backends shall derive from the Horizon::Image::BasicBackend
class. Concrete backends can exist in any namespace. To be used with the
-Image Creation utility, the backend must be registered in the ``backends.hh``
+Image Creation utility, the backend must be registered in the ``basic.cc``
file along with a unique Type Code. This Type Code can then be passed to
the Image Creation utility with the ``-t`` parameter for use.
The Horizon::Image::BasicBackend is an abstract (pure virtual) class that
has a single method that you must implement: ``create()``. This will be
-called on a constructed object of your concrete backend class, with two
-parameters: ``std::string ir_dir``, which is the base directory for the
-installed system (like ``/target`` during a normal installation), and
+called on a constructed object of your concrete backend class, which has two
+instance variables: ``std::string ir_dir``, which is the base directory for
+the installed system (like ``/target`` during a normal installation), and
``std::string out_path``, which is the user's desired output path and file
-name.
+name. You may also implement ``prepare()``, which is called before create,
+and ``finalise()``, which is called after. Default no-op implementations
+are provided for you in BasicBackend.
diff --git a/image/backends/backends.hh b/image/backends/backends.hh
new file mode 100644
index 0000000..3199ee0
--- /dev/null
+++ b/image/backends/backends.hh
@@ -0,0 +1,33 @@
+/*
+ * 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
new file mode 100644
index 0000000..908f1d9
--- /dev/null
+++ b/image/backends/basic.cc
@@ -0,0 +1,37 @@
+/*
+ * basic.cc - Implementation of the abstract Horizon Image Creation backend
+ * 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
+ */
+
+#include "basic.hh"
+#include "backends.hh"
+
+namespace Horizon {
+namespace Image {
+
+std::vector<BackendDescriptor> known_backends = {
+ {"tar", "Create a tarball (.tar)", [](std::string, std::string){ return nullptr; } },
+ {"squashfs", "Create a SquashFS image (.squashfs)", [](std::string, std::string){ return nullptr; } }
+};
+
+int BasicBackend::prepare() {
+ /* The default implementation returns success immediately;
+ * no preparation is required. */
+ return 0;
+}
+
+int BasicBackend::finalise() {
+ /* The default implementation returns success immediately;
+ * no finalisation is required. */
+ return 0;
+}
+
+}
+}
diff --git a/image/backends/basic.hh b/image/backends/basic.hh
new file mode 100644
index 0000000..d39c57e
--- /dev/null
+++ b/image/backends/basic.hh
@@ -0,0 +1,54 @@
+/*
+ * basic.hh - Definition of the abstract Horizon Image Creation backend
+ * 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 <string>
+
+namespace Horizon {
+namespace Image {
+
+class BasicBackend {
+public:
+ /*! Create the backend object.
+ * @param _ir_dir The intermediate directory the image should contain.
+ * @param _out_path The path to write the image.
+ */
+ BasicBackend(const std::string &_ir_dir, const std::string &_out_path) :
+ ir_dir(_ir_dir), out_path(_out_path) {};
+ virtual ~BasicBackend() {};
+
+ /*! Prepare for creating the image.
+ * @returns 0 if preparation succeeded; otherwise, an error code.
+ */
+ virtual int prepare();
+
+ /*! Create the image.
+ * @returns 0 if the image is created successfully; otherwise, an error
+ * code which explains the failure.
+ */
+ virtual int create() = 0;
+
+ /*! Finalise the image.
+ * @returns 0 if the image is finalised; otherwise, an error code.
+ */
+ virtual int finalise();
+
+ /*! The intermediate directory which contains the sysroot the image
+ * should contain. */
+ const std::string &ir_dir;
+ /*! The path at which to write the image. */
+ const std::string &out_path;
+};
+
+}
+}
diff --git a/image/creator.cc b/image/creator.cc
index 3b145de..ce688fa 100644
--- a/image/creator.cc
+++ b/image/creator.cc
@@ -13,19 +13,26 @@
#include <boost/program_options.hpp>
#include <cstdlib> /* EXIT_* */
#include <string>
+#include "backends/backends.hh"
#include "hscript/script.hh"
#include "util/output.hh"
-bool pretty = true;
+bool pretty = true; /*! Controls ASCII colour output */
+
#define DESCR_TEXT "Usage: hscript-image [OPTION]... [INSTALLFILE]\n"\
"Write an operating system image configured per INSTALLFILE"
+/*! Text used at the top of usage output */
+
+/*! Entry-point for the image creation utility. */
int main(int argc, char *argv[]) {
using namespace boost::program_options;
bool needs_help{}, disable_pretty{};
int exit_code = EXIT_SUCCESS;
- std::string if_path{"/etc/horizon/installfile"}, ir_dir{"/target"};
+ std::string if_path{"/etc/horizon/installfile"}, ir_dir{"/target"}, type_code{"tar"};
+ Horizon::ScriptOptions opts;
+ Horizon::Script *my_script;
options_description ui{DESCR_TEXT};
options_description general{"General options"};
@@ -71,17 +78,36 @@ int main(int argc, char *argv[]) {
/* -n/--no-colour, or logging to file */
if(disable_pretty || !isatty(1)) {
pretty = false;
+ } else {
+ opts.set(Horizon::Pretty);
+ }
+
+ if(!vm["type"].empty()) {
+ type_code = vm["type"].as<std::string>();
+ }
+
+ 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;
+ }
+ return EXIT_SUCCESS;
}
if(!vm["installfile"].empty()) {
if_path = vm["installfile"].as<std::string>();
}
- Horizon::Script *my_script;
+ opts.set(Horizon::InstallEnvironment);
+ opts.set(Horizon::ImageOnly);
+
if(if_path == "-") {
- my_script = Horizon::Script::load(std::cin);
+ /* Unix-style stdin specification */
+ my_script = Horizon::Script::load(std::cin, opts);
} else {
- my_script = Horizon::Script::load(if_path);
+ my_script = Horizon::Script::load(if_path, opts);
}
/* if an error occurred during parsing, bail out now */
@@ -93,6 +119,8 @@ int main(int argc, char *argv[]) {
my_script->setTargetDirectory(vm["ir-dir"].as<std::string>());
}
+ my_script->execute();
+
delete my_script;
return exit_code;
}