diff options
author | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2020-05-28 10:05:23 -0500 |
---|---|---|
committer | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2020-05-28 10:05:23 -0500 |
commit | 30b9f32d7a544f50f5e06ef930525d620a028db1 (patch) | |
tree | 1c5ba88d16c0fb8d8801e5329251700583754e4e /image/creator.cc | |
parent | a52fcf56f737c6fc962c12efad1b637521cc5685 (diff) | |
download | horizon-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.cc | 50 |
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; |