summaryrefslogtreecommitdiff
path: root/image
diff options
context:
space:
mode:
Diffstat (limited to 'image')
-rw-r--r--image/backends/basic.hh22
-rw-r--r--image/backends/iso.cc10
-rw-r--r--image/backends/tar.cc31
-rw-r--r--image/creator.cc30
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;
}
}