summaryrefslogtreecommitdiff
path: root/image/backends
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 /image/backends
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.
Diffstat (limited to 'image/backends')
-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
4 files changed, 132 insertions, 8 deletions
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);
+ }
+ });
+}
+
+}
+}