summaryrefslogtreecommitdiff
path: root/image/creator.cc
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2020-05-28 10:05:23 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2020-05-28 10:05:23 -0500
commit30b9f32d7a544f50f5e06ef930525d620a028db1 (patch)
tree1c5ba88d16c0fb8d8801e5329251700583754e4e /image/creator.cc
parenta52fcf56f737c6fc962c12efad1b637521cc5685 (diff)
downloadhorizon-30b9f32d7a544f50f5e06ef930525d620a028db1.tar.gz
horizon-30b9f32d7a544f50f5e06ef930525d620a028db1.tar.bz2
horizon-30b9f32d7a544f50f5e06ef930525d620a028db1.tar.xz
horizon-30b9f32d7a544f50f5e06ef930525d620a028db1.zip
image: Put target inside ir_dir, add WIP ISO backend
ir_dir used to be the target; now the target is inside ir_dir so backends have the choice of making other directories inside ir_dir if needed.
Diffstat (limited to 'image/creator.cc')
-rw-r--r--image/creator.cc50
1 files changed, 47 insertions, 3 deletions
diff --git a/image/creator.cc b/image/creator.cc
index 8a6cc73..0934f08 100644
--- a/image/creator.cc
+++ b/image/creator.cc
@@ -13,13 +13,24 @@
#include <boost/program_options.hpp>
#include <cstdlib> /* EXIT_* */
#include <string>
+#include <sys/mount.h>
+
#include "backends/basic.hh"
+#include "hscript/meta.hh"
#include "hscript/script.hh"
+#include "util/filesystem.hh"
#include "util/output.hh"
bool pretty = true; /*! Controls ASCII colour output */
+const std::string arch_xlate(const std::string &arch) {
+ if(arch == "pmmx") return "i386";
+ if(arch == "armv7") return "arm";
+ return arch;
+}
+
+
#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 */
@@ -32,7 +43,7 @@ int main(int argc, char *argv[]) {
bool needs_help{}, disable_pretty{}, version_only{};
int exit_code = EXIT_SUCCESS;
- std::string if_path{"/etc/horizon/installfile"}, ir_dir{"/target"},
+ std::string if_path{"/etc/horizon/installfile"}, ir_dir{"/tmp/horizon-image"},
output_path{"image.tar"}, type_code{"tar"};
BasicBackend *backend = nullptr;
Horizon::ScriptOptions opts;
@@ -49,7 +60,7 @@ int main(int argc, char *argv[]) {
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("/target"), "Where to store intermediate files.")
+ ("ir-dir,i", value<std::string>()->default_value("/tmp/horizon-image"), "Where to store intermediate files.")
;
ui.add(general).add(target);
@@ -109,6 +120,10 @@ int main(int argc, char *argv[]) {
ir_dir = vm["ir-dir"].as<std::string>();
}
+ if(fs::path(ir_dir).is_relative()) {
+ ir_dir = fs::absolute(ir_dir).string();
+ }
+
if(!vm["output"].empty()) {
output_path = vm["output"].as<std::string>();
}
@@ -169,18 +184,47 @@ int main(int argc, char *argv[]) {
RUN_PHASE_OR_TROUBLE(prepare, "preparation");
- my_script->setTargetDirectory(ir_dir);
+ /* Attempt to make images work cross-architecture.
+ * This requires binfmt_misc to be configured properly.
+ * It also requires qemu-user to be installed to /usr/bin on the host.
+ * It may not work all the time, so we ignore errors.
+ * But we try anyway, because it can work and make things easier.
+ */
+ const Horizon::Keys::Key *archkey = my_script->getOneValue("arch");
+ std::string qpath;
+ if(archkey) {
+ const Horizon::Keys::Arch *arch =
+ dynamic_cast<const Horizon::Keys::Arch *>(archkey);
+ qpath = "/usr/bin/qemu-" + arch_xlate(arch->value());
+ error_code ec;
+ if(fs::exists(qpath, ec)) {
+ fs::create_directories(ir_dir + "/target/usr/bin", ec);
+ if(!ec) fs::copy_file(qpath, ir_dir + "/target/" + qpath, ec);
+ }
+ }
+
+ my_script->setTargetDirectory(ir_dir + "/target");
if(!my_script->execute()) {
exit_code = EXIT_FAILURE;
goto trouble;
}
+ if(!qpath.empty() && fs::exists(ir_dir + "/target" + qpath)) {
+ error_code ec;
+ fs::remove(ir_dir + "/target" + qpath, ec);
+ }
+
RUN_PHASE_OR_TROUBLE(create, "creation");
RUN_PHASE_OR_TROUBLE(finalise, "finalisation");
}
trouble: /* delete the Script and exit */
+ /* ensure that our target mounts are unmounted */
+ umount((ir_dir + "/target/sys").c_str());
+ umount((ir_dir + "/target/proc").c_str());
+ umount((ir_dir + "/target/dev").c_str());
+
delete my_script;
early_trouble: /* no script yet */
delete backend;