diff options
Diffstat (limited to 'image')
-rw-r--r-- | image/backends/basic.hh | 22 | ||||
-rw-r--r-- | image/backends/iso.cc | 10 | ||||
-rw-r--r-- | image/backends/tar.cc | 31 | ||||
-rw-r--r-- | image/creator.cc | 30 |
4 files changed, 68 insertions, 25 deletions
diff --git a/image/backends/basic.hh b/image/backends/basic.hh index d57a9ac..ff92ec8 100644 --- a/image/backends/basic.hh +++ b/image/backends/basic.hh @@ -13,20 +13,25 @@ #pragma once #include <functional> +#include <map> #include <string> #include <vector> namespace Horizon { namespace Image { +using std::string; + 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. + * @param _opts Options, if any. */ - BasicBackend(const std::string &_ir_dir, const std::string &_out_path) : - ir_dir(_ir_dir), out_path(_out_path) {}; + BasicBackend(const string &_ir_dir, const string &_out_path, + const std::map<string, string> &_opts = {}) : + ir_dir{_ir_dir}, out_path{_out_path}, opts{_opts} {}; virtual ~BasicBackend() {}; /*! Prepare for creating the image. @@ -47,15 +52,18 @@ public: /*! The intermediate directory which contains the sysroot the image * should contain. */ - const std::string ir_dir; + const string ir_dir; /*! The path at which to write the image. */ - const std::string out_path; + const string out_path; + /*! Backend-specific configuration options. */ + const std::map<string, string> opts; }; struct BackendDescriptor { - std::string type_code; - std::string description; - std::function<BasicBackend *(std::string, std::string)> creation_fn; + string type_code; + string description; + std::function<BasicBackend *(const string &, const string &, + const std::map<string, string> &)> creation_fn; }; class BackendManager { diff --git a/image/backends/iso.cc b/image/backends/iso.cc index b1d4c43..c3f316e 100644 --- a/image/backends/iso.cc +++ b/image/backends/iso.cc @@ -27,8 +27,9 @@ public: COMMAND_ERROR }; - explicit CDBackend(std::string ir, std::string out) - : BasicBackend(ir, out) {}; + explicit CDBackend(const std::string &ir, const std::string &out, + const std::map<std::string, std::string> &opts) + : BasicBackend(ir, out, opts) {}; int prepare() override { error_code ec; @@ -160,8 +161,9 @@ __attribute__((constructor(400))) void register_cd_backend() { BackendManager::register_backend( {"iso", "Create a CD image (.iso)", - [](std::string ir_dir, std::string out_path) { - return new CDBackend(ir_dir, out_path); + [](const std::string &ir_dir, const std::string &out_path, + const std::map<std::string, std::string> &opts) { + return new CDBackend(ir_dir, out_path, opts); } }); } diff --git a/image/backends/tar.cc b/image/backends/tar.cc index f9309a1..cab25ed 100644 --- a/image/backends/tar.cc +++ b/image/backends/tar.cc @@ -13,6 +13,7 @@ #include <archive.h> #include <archive_entry.h> #include <sys/mman.h> +#include <sys/mount.h> #include <sys/stat.h> #include <errno.h> #include <fcntl.h> @@ -39,8 +40,10 @@ private: struct archive *a; public: - TarBackend(std::string ir, std::string out, CompressionType _c = None) - : BasicBackend(ir, out), comp(_c) {}; + TarBackend(const std::string &ir, const std::string &out, + const std::map<std::string, std::string> &opts, + CompressionType _c = None) + : BasicBackend{ir, out, opts}, comp{_c} {}; int prepare() override { int res; @@ -83,6 +86,10 @@ public: void *buff; std::string target = this->ir_dir + "/target"; + umount((ir_dir + "/target/sys").c_str()); + umount((ir_dir + "/target/proc").c_str()); + umount((ir_dir + "/target/dev").c_str()); + for(const auto& dent : fs::recursive_directory_iterator(target, ec)) { fs::path relpath = dent.path().lexically_relative(target); #define OUTPUT_FAILURE(x) \ @@ -146,29 +153,33 @@ __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); + [](const std::string &ir_dir, const std::string &out_path, + const std::map<std::string, std::string> &opts) { + return new TarBackend(ir_dir, out_path, opts); } }); 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); + [](const std::string &ir_dir, const std::string &out_path, + const std::map<std::string, std::string> &opts) { + return new TarBackend(ir_dir, out_path, opts, 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); + [](const std::string &ir_dir, const std::string &out_path, + const std::map<std::string, std::string> &opts) { + return new TarBackend(ir_dir, out_path, opts, 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); + [](const std::string &ir_dir, const std::string &out_path, + const std::map<std::string, std::string> &opts) { + return new TarBackend(ir_dir, out_path, opts, TarBackend::XZ); } }); } diff --git a/image/creator.cc b/image/creator.cc index 0934f08..046027a 100644 --- a/image/creator.cc +++ b/image/creator.cc @@ -10,9 +10,13 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -#include <boost/program_options.hpp> #include <cstdlib> /* EXIT_* */ +#include <functional> +#include <map> #include <string> +#include <vector> + +#include <boost/program_options.hpp> #include <sys/mount.h> #include "backends/basic.hh" @@ -46,6 +50,7 @@ int main(int argc, char *argv[]) { std::string if_path{"/etc/horizon/installfile"}, ir_dir{"/tmp/horizon-image"}, output_path{"image.tar"}, type_code{"tar"}; BasicBackend *backend = nullptr; + std::map<std::string, std::string> backend_opts; Horizon::ScriptOptions opts; Horizon::Script *my_script; @@ -59,10 +64,14 @@ int main(int argc, char *argv[]) { options_description target{"Target control options"}; target.add_options() ("output,o", value<std::string>()->default_value("image.tar"), "Desired filename for the output file.") - ("type,t", value<std::string>()->default_value("tar"), "Type of output file to generate. Use 'list' for a list of supported types.") ("ir-dir,i", value<std::string>()->default_value("/tmp/horizon-image"), "Where to store intermediate files.") ; - ui.add(general).add(target); + options_description backconfig{"Backend configuration options"}; + backconfig.add_options() + ("type,t", value<std::string>()->default_value("tar"), "Type of output file to generate. Use 'list' for a list of supported types.") + ("backconfig,b", value<std::vector<std::string>>(), "Set a backend configuration option. You may specify this multiple times for multiple options.") + ; + ui.add(general).add(target).add(backconfig); options_description all; all.add(ui).add_options()("installfile", value<std::string>()->default_value(if_path), "The HorizonScript to use for configuring the image."); @@ -128,6 +137,19 @@ int main(int argc, char *argv[]) { output_path = vm["output"].as<std::string>(); } + if(!vm["backconfig"].empty()) { + for(const auto &confpart : + vm["backconfig"].as<std::vector<std::string>>()) { + std::string::size_type equals = confpart.find_first_of("="); + if(equals != std::string::npos) { + backend_opts[confpart.substr(0, equals)] = + confpart.substr(equals + 1); + } else { + backend_opts[confpart] = ""; + } + } + } + /* Announce our presence */ bold_if_pretty(std::cout); std::cout << "HorizonScript Image Creation Utility version " << VERSTR @@ -146,7 +168,7 @@ int main(int argc, char *argv[]) { /* Load the proper backend. */ for(const auto &candidate : BackendManager::available_backends()) { if(candidate.type_code == type_code) { - backend = candidate.creation_fn(ir_dir, output_path); + backend = candidate.creation_fn(ir_dir, output_path, backend_opts); break; } } |