summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2020-04-02 21:41:11 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2020-04-02 21:41:11 -0500
commitcd52d492ec08810fa0ba2425d5e01618a2e8741a (patch)
tree58597907a0e00d2acd0da28a2d46fb0898917da4
parentb9fa31365c91cfcbc891b36b411d3adc296ff6df (diff)
downloadhorizon-cd52d492ec08810fa0ba2425d5e01618a2e8741a.tar.gz
horizon-cd52d492ec08810fa0ba2425d5e01618a2e8741a.tar.bz2
horizon-cd52d492ec08810fa0ba2425d5e01618a2e8741a.tar.xz
horizon-cd52d492ec08810fa0ba2425d5e01618a2e8741a.zip
image: Truly dynamic backend registration
This allows one backend to provide multiple types. For example, our TarBackend can provide optional .gz, .bz2, and .xz compression.
-rw-r--r--image/CMakeLists.txt3
-rw-r--r--image/backends/CMakeLists.txt16
-rw-r--r--image/backends/basic.cc6
-rw-r--r--image/backends/basic.hh4
-rw-r--r--image/backends/tar.cc114
-rw-r--r--image/creator.cc10
6 files changed, 143 insertions, 10 deletions
diff --git a/image/CMakeLists.txt b/image/CMakeLists.txt
index cbee674..775d38e 100644
--- a/image/CMakeLists.txt
+++ b/image/CMakeLists.txt
@@ -5,8 +5,7 @@ add_subdirectory(backends)
set(IMG_SRCS
creator.cc
- ${BACKEND_SRCS}
)
add_executable(hscript-image ${IMG_SRCS})
-target_link_libraries(hscript-image hscript ${Boost_LIBRARIES})
+target_link_libraries(hscript-image hscript hi-backends ${Boost_LIBRARIES})
install(TARGETS hscript-image DESTINATION bin)
diff --git a/image/backends/CMakeLists.txt b/image/backends/CMakeLists.txt
index f3c7f5d..726d4eb 100644
--- a/image/backends/CMakeLists.txt
+++ b/image/backends/CMakeLists.txt
@@ -1,4 +1,16 @@
set(BACKEND_SRCS
- ${CMAKE_CURRENT_SOURCE_DIR}/basic.cc
- PARENT_SCOPE
+ basic.cc
)
+
+set(BACKEND_LIBS "")
+
+find_package(LibArchive)
+
+if(LibArchive_FOUND)
+ list(APPEND BACKEND_SRCS tar.cc)
+ list(APPEND BACKEND_LIBS ${LibArchive_LIBRARIES})
+endif()
+
+add_library(hi-backends ${BACKEND_SRCS})
+target_link_libraries(hi-backends ${BACKEND_LIBS})
+install(TARGETS hi-backends DESTINATION lib)
diff --git a/image/backends/basic.cc b/image/backends/basic.cc
index bec3e41..0aa1afa 100644
--- a/image/backends/basic.cc
+++ b/image/backends/basic.cc
@@ -15,10 +15,8 @@
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; } }
-};
+std::vector<BackendDescriptor> known_backends
+__attribute__ ((init_priority(200)));
const std::vector<BackendDescriptor> BackendManager::available_backends() {
return known_backends;
diff --git a/image/backends/basic.hh b/image/backends/basic.hh
index 95b94ae..d57a9ac 100644
--- a/image/backends/basic.hh
+++ b/image/backends/basic.hh
@@ -47,9 +47,9 @@ public:
/*! The intermediate directory which contains the sysroot the image
* should contain. */
- const std::string &ir_dir;
+ const std::string ir_dir;
/*! The path at which to write the image. */
- const std::string &out_path;
+ const std::string out_path;
};
struct BackendDescriptor {
diff --git a/image/backends/tar.cc b/image/backends/tar.cc
new file mode 100644
index 0000000..d4ed584
--- /dev/null
+++ b/image/backends/tar.cc
@@ -0,0 +1,114 @@
+/*
+ * tar.cc - Implementation of the tarball 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 <archive.h>
+#include "basic.hh"
+#include "util/output.hh"
+
+namespace Horizon {
+namespace Image {
+
+class TarBackend : public BasicBackend {
+public:
+ enum CompressionType {
+ None,
+ GZip,
+ BZip2,
+ XZ
+ };
+
+private:
+ CompressionType comp;
+ struct archive *a;
+
+public:
+ TarBackend(std::string ir, std::string out, CompressionType _c = None)
+ : BasicBackend(ir, out), comp(_c) {};
+
+ int prepare() override {
+ int res;
+
+ a = archive_write_new();
+ archive_write_set_format_pax_restricted(a);
+
+ switch(comp) {
+ case None:
+ break;
+ case GZip:
+ archive_write_add_filter_gzip(a);
+ break;
+ case BZip2:
+ archive_write_add_filter_bzip2(a);
+ break;
+ case XZ:
+ archive_write_add_filter_xz(a);
+ break;
+ }
+
+ res = archive_write_open_filename(a, this->out_path.c_str()) < ARCHIVE_OK;
+ if(res < ARCHIVE_OK) {
+ if(res < ARCHIVE_WARN) {
+ output_error("tar backend", archive_error_string(a));
+ return res;
+ } else {
+ output_warning("tar backend", archive_error_string(a));
+ }
+ }
+
+ return 0;
+ }
+
+ int create() override {
+ return 0;
+ }
+
+ int finalise() override {
+ archive_write_close(a);
+ archive_write_free(a);
+
+ return 0;
+ }
+};
+
+__attribute__((constructor(400)))
+void register_tar_backend() {
+ BackendManager::register_backend(
+ {"tar", "Create a tarball (.tar)",
+ [](std::string ir_dir, std::string out_path) {
+ return new TarBackend(ir_dir, out_path);
+ }
+ });
+
+ BackendManager::register_backend(
+ {"tgz", "Create a tarball with GZ compression (.tar.gz)",
+ [](std::string ir_dir, std::string out_path) {
+ return new TarBackend(ir_dir, out_path, TarBackend::GZip);
+ }
+ });
+
+ BackendManager::register_backend(
+ {"tbz", "Create a tarball with BZip2 compression (.tar.bz2)",
+ [](std::string ir_dir, std::string out_path) {
+ return new TarBackend(ir_dir, out_path, TarBackend::BZip2);
+ }
+ });
+
+ BackendManager::register_backend(
+ {"txz", "Create a tarball with XZ compression (.tar.xz)",
+ [](std::string ir_dir, std::string out_path) {
+ return new TarBackend(ir_dir, out_path, TarBackend::XZ);
+ }
+ });
+}
+
+}
+}
diff --git a/image/creator.cc b/image/creator.cc
index b16504a..805e13b 100644
--- a/image/creator.cc
+++ b/image/creator.cc
@@ -112,6 +112,14 @@ int main(int argc, char *argv[]) {
output_path = vm["output"].as<std::string>();
}
+ /* Announce our presence */
+ std::cout << "HorizonScript Image Creation Utility version " << VERSTR
+ << std::endl
+ << "Copyright (c) 2020 Adélie Linux and contributors."
+ << std::endl
+ << "This software is licensed to you under the AGPL 3.0, "
+ << "unless otherwise noted." << std::endl << std::endl;
+
/* Load the proper backend. */
for(const auto &candidate : BackendManager::available_backends()) {
if(candidate.type_code == type_code) {
@@ -142,6 +150,8 @@ int main(int argc, char *argv[]) {
} else {
int ret;
+ my_script->setTargetDirectory(ir_dir);
+
if(!my_script->execute()) {
exit_code = EXIT_FAILURE;
goto trouble;