summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hscript/disk.cc15
-rw-r--r--hscript/meta.cc81
-rw-r--r--hscript/network.cc6
-rw-r--r--hscript/script.cc9
-rw-r--r--hscript/script.hh6
-rw-r--r--hscript/script_e.cc122
-rw-r--r--hscript/script_i.hh3
-rw-r--r--hscript/user.cc30
8 files changed, 165 insertions, 107 deletions
diff --git a/hscript/disk.cc b/hscript/disk.cc
index e1111f6..1f6d3b3 100644
--- a/hscript/disk.cc
+++ b/hscript/disk.cc
@@ -783,7 +783,8 @@ bool Mount::validate() const {
}
bool Mount::execute() const {
- const std::string actual_mount = "/target" + this->mountpoint();
+ const std::string actual_mount(script->targetDirectory() +
+ this->mountpoint());
const char *fstype = nullptr;
#ifdef HAS_INSTALL_ENV
error_code ec;
@@ -853,24 +854,26 @@ bool Mount::execute() const {
"defaults" : this->options());
if(script->options().test(Simulate)) {
if(this->mountpoint() == "/") {
- std::cout << "mkdir -p /target/etc" << std::endl;
+ std::cout << "mkdir -p " << script->targetDirectory() << "/etc"
+ << std::endl;
}
std::cout << "printf '%s\\t%s\\t%s\\t%s\\t0\\t" << pass << "\\"
<< "n' " << this->device() << " " << this->mountpoint()
<< " " << fstype << " " << fstab_opts
- << " >> /target/etc/fstab" << std::endl;
+ << " >> " << script->targetDirectory() << "/etc/fstab"
+ << std::endl;
}
#ifdef HAS_INSTALL_ENV
else {
if(this->mountpoint() == "/") {
- fs::create_directory("/target/etc", ec);
+ fs::create_directory(script->targetDirectory() + "/etc", ec);
if(ec) {
output_error("installfile:" + std::to_string(this->lineno()),
"mount: failed to create /etc for target",
ec.message());
return false;
}
- fs::permissions("/target/etc", rwxr_xr_x,
+ fs::permissions(script->targetDirectory() + "/etc", rwxr_xr_x,
#if defined(FS_IS_STDCXX)
fs::perm_options::replace,
#endif
@@ -881,7 +884,7 @@ bool Mount::execute() const {
ec.message());
}
}
- std::ofstream fstab_f("/target/etc/fstab");
+ std::ofstream fstab_f(script->targetDirectory() + "/etc/fstab");
if(!fstab_f) {
output_error("installfile:" + std::to_string(this->lineno()),
"mount: failure opening /etc/fstab for writing");
diff --git a/hscript/meta.cc b/hscript/meta.cc
index bfaabb3..8fedb32 100644
--- a/hscript/meta.cc
+++ b/hscript/meta.cc
@@ -109,12 +109,13 @@ bool Hostname::execute() const {
output_info("installfile:" + std::to_string(this->lineno()),
"hostname: write '" + actual + "' to /etc/hostname");
if(script->options().test(Simulate)) {
- std::cout << "printf '%s' " << actual << " > /target/etc/hostname"
- << std::endl;
+ std::cout << "printf '%s' " << actual << " > "
+ << script->targetDirectory() << "/etc/hostname" << std::endl;
}
#ifdef HAS_INSTALL_ENV
else {
- std::ofstream hostname_f("/target/etc/hostname", std::ios_base::trunc);
+ std::ofstream hostname_f(script->targetDirectory() + "/etc/hostname",
+ std::ios_base::trunc);
if(!hostname_f) {
output_error("installfile:" + std::to_string(this->lineno()),
"hostname: could not open /etc/hostname for writing");
@@ -131,23 +132,26 @@ bool Hostname::execute() const {
output_info("installfile:" + std::to_string(this->lineno()),
"hostname: set domain name '" + domain + "'");
if(script->options().test(Simulate)) {
- std::cout << "mkdir -p /target/etc/conf.d" << std::endl;
+ std::cout << "mkdir -p " << script->targetDirectory()
+ << "/etc/conf.d" << std::endl;
std::cout << "printf 'dns_domain_lo=\"" << domain
- << "\"\\" << "n' >> /target/etc/conf.d/net" << std::endl;
+ << "\"\\" << "n' >> " << script->targetDirectory()
+ << "/etc/conf.d/net" << std::endl;
}
#ifdef HAS_INSTALL_ENV
else {
- if(!fs::exists("/target/etc/conf.d")) {
+ if(!fs::exists(script->targetDirectory() + "/etc/conf.d")) {
error_code ec;
- fs::create_directory("/target/etc/conf.d", ec);
+ fs::create_directory(script->targetDirectory() +
+ "/etc/conf.d", ec);
if(ec) {
output_error("installfile:" + std::to_string(line),
"hostname: could not create /etc/conf.d "
"directory", ec.message());
}
}
- std::ofstream net_conf_f("/target/etc/conf.d/net",
- std::ios_base::app);
+ std::ofstream net_conf_f(script->targetDirectory() +
+ "/etc/conf.d/net", std::ios_base::app);
if(!net_conf_f) {
output_error("installfile:" + std::to_string(this->lineno()),
"hostname: could not open /etc/conf.d/net for "
@@ -199,12 +203,14 @@ bool Arch::execute() const {
if(script->options().test(Simulate)) {
std::cout << "printf '" << this->value() << "\\" << "n'"
- << " > /target/etc/apk/arch" << std::endl;
+ << " > " << script->targetDirectory() << "/etc/apk/arch"
+ << std::endl;
return true;
}
#ifdef HAS_INSTALL_ENV
- std::ofstream arch_f("/target/etc/apk/arch", std::ios_base::trunc);
+ std::ofstream arch_f(script->targetDirectory() + "/etc/apk/arch",
+ std::ios_base::trunc);
if(!arch_f) {
output_error("installfile:" + std::to_string(line),
"arch: cannot write target CPU architecture information");
@@ -334,20 +340,21 @@ bool Language::execute() const {
if(script->options().test(Simulate)) {
std::cout << "printf '#!/bin/sh\\" << "nexport LANG=\"%s\"\\" << "n' "
- << this->value() << " > /target/etc/profile.d/language.sh"
- << std::endl
- << "chmod a+x /target/etc/profile.d/language.sh"
- << std::endl;
+ << this->value() << " > " << script->targetDirectory()
+ << "/etc/profile.d/00-language.sh" << std::endl
+ << "chmod a+x " << script->targetDirectory()
+ << "/etc/profile.d/00-language.sh" << std::endl;
return true;
}
#ifdef HAS_INSTALL_ENV
- const char *lang_path = "/target/etc/profile.d/language.sh";
+ std::string lang_path = script->targetDirectory() +
+ "/etc/profile.d/00-language.sh";
std::ofstream lang_f(lang_path, std::ios_base::trunc);
error_code ec;
if(!lang_f) {
output_error("installfile:" + std::to_string(this->lineno()),
- "language: could not open /etc/profile.d/language.sh "
+ "language: could not open /etc/profile.d/00-language.sh "
"for writing");
return false;
}
@@ -358,7 +365,7 @@ bool Language::execute() const {
fs::permissions(lang_path, rwxr_xr_x, ec);
if(ec) {
output_error("installfile:" + std::to_string(this->lineno()),
- "language: could not set /etc/profile.d/language.sh "
+ "language: could not set /etc/profile.d/00-language.sh "
"as executable", ec.message());
return false;
}
@@ -402,15 +409,15 @@ BACKSPACE=guess"
"keymap: setting system keyboard map to " + _value);
if(script->options().test(Simulate)) {
- std::cout << "cat >/target/etc/default/keyboard <<-KEYCONF"
- << std::endl;
+ std::cout << "cat >" << script->targetDirectory()
+ << "/etc/default/keyboard <<-KEYCONF" << std::endl;
std::cout << conf << std::endl;
std::cout << "KEYCONF" << std::endl;
return true;
}
#ifdef HAS_INSTALL_ENV
- std::ofstream keyconf("/target/etc/default/keyboard",
+ std::ofstream keyconf(script->targetDirectory() + "/etc/default/keyboard",
std::ios_base::trunc);
if(!keyconf) {
output_error("installfile:" + std::to_string(line),
@@ -494,19 +501,23 @@ bool Timezone::execute() const {
if(script->options().test(Simulate)) {
/* If the target doesn't have tzdata installed, copy the zoneinfo from
* the Horizon environment. */
- std::cout << "([ -f /target/usr/share/zoneinfo/" << this->value()
+ std::cout << "([ -f " << script->targetDirectory()
+ << "/usr/share/zoneinfo/" << this->value()
<< " ] && ln -s /usr/share/zoneinfo/" << this->value()
- << " /target/etc/localtime) || cp /usr/share/zoneinfo/"
- << this->value() << " /target/etc/localtime" << std::endl;
+ << " " << script->targetDirectory() << "/etc/localtime) || "
+ << "cp /usr/share/zoneinfo/" << this->value()
+ << " " << script->targetDirectory() << "/etc/localtime"
+ << std::endl;
return true;
}
#ifdef HAS_INSTALL_ENV
std::string zi_path = "/usr/share/zoneinfo/" + this->value();
- std::string target_zi = "/target" + zi_path;
+ std::string target_zi = script->targetDirectory() + zi_path;
+ std::string target_lt = script->targetDirectory() + "/etc/localtime";
error_code ec;
if(fs::exists(target_zi, ec)) {
- fs::create_symlink(zi_path, "/target/etc/localtime", ec);
+ fs::create_symlink(zi_path, target_lt, ec);
if(ec) {
output_error("installfile:" + std::to_string(this->lineno()),
"timezone: failed to create symbolic link",
@@ -517,7 +528,7 @@ bool Timezone::execute() const {
} else {
/* The target doesn't have tzdata installed. We copy the zoneinfo
* file from the Horizon environment to the target. */
- fs::copy_file(zi_path, "/target/etc/localtime", ec);
+ fs::copy_file(zi_path, target_lt, ec);
if(ec) {
output_error("installfile:" + std::to_string(this->lineno()),
"timezone: failed to prepare target environment",
@@ -554,13 +565,14 @@ bool Repository::execute() const {
"repository: write '" + this->value() +
"' to /etc/apk/repositories");
if(script->options().test(Simulate)) {
- std::cout << "echo '" << this->value() <<
- "' >> /target/etc/apk/repositories" << std::endl;
+ std::cout << "echo '" << this->value()
+ << "' >> " << script->targetDirectory()
+ << "/etc/apk/repositories" << std::endl;
return true;
}
#ifdef HAS_INSTALL_ENV
- std::ofstream repo_f("/target/etc/apk/repositories",
+ std::ofstream repo_f(script->targetDirectory() + "/etc/apk/repositories",
std::ios_base::app);
if(!repo_f) {
output_error("installfile:" + std::to_string(this->lineno()),
@@ -598,13 +610,14 @@ bool SigningKey::execute() const {
/* everything after the last / in the value is the filename */
const std::string name(_value.substr(_value.find_last_of('/') + 1));
- const std::string target("/target/etc/apk/keys/" + name);
+ const std::string target_dir(script->targetDirectory() + "/etc/apk/keys/");
+ const std::string target(target_dir + name);
output_info("installfile:" + std::to_string(line),
"signingkey: trusting " + name + " for repository signing");
if(script->options().test(Simulate)) {
- std::cout << "mkdir -p /target/etc/apk/keys" << std::endl;
+ std::cout << "mkdir -p " << target_dir << std::endl;
if(_value[0] == '/') {
std::cout << "cp " << _value << " " << target << std::endl;
} else {
@@ -615,8 +628,8 @@ bool SigningKey::execute() const {
#ifdef HAS_INSTALL_ENV
error_code ec;
- if(!fs::exists("/target/etc/apk/keys")) {
- fs::create_directory("/target/etc/apk/keys", ec);
+ if(!fs::exists(target_dir)) {
+ fs::create_directory(target_dir, ec);
if(ec) {
output_error("installfile:" + std::to_string(line),
"signingkey: could not initialise target repository "
diff --git a/hscript/network.cc b/hscript/network.cc
index 3741b0c..1750a60 100644
--- a/hscript/network.cc
+++ b/hscript/network.cc
@@ -347,12 +347,14 @@ Key *Nameserver::parseFromData(const std::string &data, int lineno,
bool Nameserver::execute() const {
if(script->options().test(Simulate)) {
std::cout << "printf 'nameserver %s\\" << "n' " << _value
- << " >>/target/etc/resolv.conf" << std::endl;
+ << " >>" << script->targetDirectory() << "/etc/resolv.conf"
+ << std::endl;
return true;
}
#ifdef HAS_INSTALL_ENV
- std::ofstream resolvconf("/target/etc/resolv.conf", std::ios_base::app);
+ std::ofstream resolvconf(script->targetDirectory() + "/etc/resolv.conf",
+ std::ios_base::app);
if(!resolvconf) {
output_error("installfile:" + std::to_string(line),
"nameserver: couldn't write configuration to target");
diff --git a/hscript/script.cc b/hscript/script.cc
index 9073e04..7db3ed0 100644
--- a/hscript/script.cc
+++ b/hscript/script.cc
@@ -168,6 +168,7 @@ bool Script::ScriptPrivate::store_key(const std::string &key_name, Key *obj,
Script::Script() {
internal = new ScriptPrivate;
+ internal->target = "/target";
}
Script::~Script() {
@@ -319,6 +320,14 @@ const Script *Script::load(std::istream &sstream,
}
/* LCOV_EXCL_START */
+const std::string Script::targetDirectory() const {
+ return this->internal->target;
+}
+
+void Script::setTargetDirectory(const std::string &dir) {
+ this->internal->target = dir;
+}
+
const Keys::Key *Script::getOneValue(std::string name) const {
if(name == "network") {
return this->internal->network.get();
diff --git a/hscript/script.hh b/hscript/script.hh
index 8cf6c2a..e664f58 100644
--- a/hscript/script.hh
+++ b/hscript/script.hh
@@ -80,6 +80,12 @@ public:
/*! Executes the HorizonScript. */
bool execute() const;
+ /*! Retrieve the current target directory. */
+ const std::string targetDirectory() const;
+
+ /*! Set the current target directory. */
+ void setTargetDirectory(const std::string &dir);
+
/*! Retrieve the value of a specified key in this HorizonScript.
* @param name The name of the key to retrieve.
* @return The key object, if one exists. nullptr if the key has not been
diff --git a/hscript/script_e.cc b/hscript/script_e.cc
index 8360b28..ea430dc 100644
--- a/hscript/script_e.cc
+++ b/hscript/script_e.cc
@@ -28,25 +28,23 @@ namespace Horizon {
static bool icon_dir_created = false;
-void maybe_create_icon_dir(ScriptOptions opts) {
+void maybe_create_icon_dir(ScriptOptions opts, const std::string &target) {
if(icon_dir_created) return;
icon_dir_created = true;
+ const std::string icon_dir(target + "/var/lib/AccountsService/icons");
+
if(opts.test(Simulate)) {
- std::cout << "mkdir -p /target/var/lib/AccountsService/icons"
- << std::endl
- << "chown root:root /target/var/lib/AccountsService/icons"
- << std::endl
- << "chmod 775 /target/var/lib/AccountsService/icons"
- << std::endl;
+ std::cout << "mkdir -p " << icon_dir << std::endl
+ << "chown root:root " << icon_dir << std::endl
+ << "chmod 775 " << icon_dir << std::endl;
return;
}
#ifdef HAS_INSTALL_ENV
else {
error_code ec;
- if(!fs::exists("/target/var/lib/AccountsService/icons", ec)) {
- fs::create_directories("/target/var/lib/AccountsService/icons",
- ec);
+ if(!fs::exists(icon_dir, ec)) {
+ fs::create_directories(icon_dir, ec);
if(ec) {
output_error("internal", "couldn't create icon dir",
ec.message());
@@ -60,6 +58,7 @@ bool Script::execute() const {
bool success;
error_code ec;
std::set<std::string> ifaces;
+ const std::string targ_etc(targetDirectory() + "/etc");
/* assume create_directory will give us the error if removal fails */
if(fs::exists("/tmp/horizon", ec)) {
@@ -167,12 +166,12 @@ bool Script::execute() const {
/* REQ: Runner.Execute.repository */
if(opts.test(Simulate)) {
- std::cout << "mkdir -p /target/etc/apk" << std::endl;
+ std::cout << "mkdir -p " << targ_etc << "/apk" << std::endl;
}
#ifdef HAS_INSTALL_ENV
else {
- if(!fs::exists("/target/etc/apk", ec)) {
- fs::create_directory("/target/etc/apk", ec);
+ if(!fs::exists(targ_etc + "/apk", ec)) {
+ fs::create_directory(targ_etc + "/apk", ec);
if(ec) {
output_error("internal", "failed to initialise APK");
EXECUTE_FAILURE("pre-metadata");
@@ -221,7 +220,8 @@ bool Script::execute() const {
if(opts.test(Simulate)) {
std::ifstream wpai("/tmp/horizon/wpa_supplicant.conf");
if(wpai) {
- std::cout << "cat >/target/etc/wpa_supplicant/wpa_supplicant.conf "
+ std::cout << "cat >" << targetDirectory()
+ << "/etc/wpa_supplicant/wpa_supplicant.conf "
<< "<<- WPA_EOF" << std::endl
<< wpai.rdbuf() << std::endl
<< "WPA_EOF" << std::endl;
@@ -232,11 +232,12 @@ bool Script::execute() const {
}
#ifdef HAS_INSTALL_ENV
else {
- if(!fs::exists("/target/etc/wpa_supplicant", ec)) {
- fs::create_directory("/target/etc/wpa_supplicant", ec);
+ const std::string wpa_dir(targ_etc + "/wpa_supplicant");
+ if(!fs::exists(wpa_dir, ec)) {
+ fs::create_directory(wpa_dir, ec);
}
fs::copy_file("/tmp/horizon/wpa_supplicant.conf",
- "/target/etc/wpa_supplicant/wpa_supplicant.conf",
+ wpa_dir + "/wpa_supplicant.conf",
fs_overwrite, ec);
if(ec) {
output_error("internal", "cannot save wireless networking "
@@ -280,21 +281,21 @@ bool Script::execute() const {
}
if(opts.test(Simulate)) {
- std::cout << "mkdir -p /target/etc/conf.d" << std::endl;
- std::cout << "cat >>/target/etc/conf.d/net <<- NETCONF_EOF"
+ std::cout << "mkdir -p " << targ_etc << "/conf.d" << std::endl;
+ std::cout << "cat >>/" << targ_etc << "/conf.d/net <<- NETCONF_EOF"
<< std::endl << conf.str() << std::endl
<< "NETCONF_EOF" << std::endl;
}
#ifdef HAS_INSTALL_ENV
else {
- if(!fs::exists("/target/etc/conf.d")) {
- fs::create_directory("/target/etc/conf.d", ec);
+ if(!fs::exists(targ_etc + "/conf.d")) {
+ fs::create_directory(targ_etc + "/conf.d", ec);
if(ec) {
output_error("internal", "could not create /etc/conf.d "
"directory", ec.message());
}
}
- std::ofstream conf_file("/target/etc/conf.d/net",
+ std::ofstream conf_file(targ_etc + "/conf.d/net",
std::ios_base::app);
if(!conf_file) {
output_error("internal", "cannot save network configuration "
@@ -320,11 +321,11 @@ bool Script::execute() const {
const std::string domain(hostname.substr(dot + 1));
if(opts.test(Simulate)) {
std::cout << "printf 'domain " << domain << "\\"
- << "n >>/target/etc/resolv.conf" << std::endl;
+ << "n >>" << targ_etc << "/resolv.conf" << std::endl;
}
#ifdef HAS_INSTALL_ENV
else {
- std::ofstream resolvconf("/target/etc/resolv.conf",
+ std::ofstream resolvconf(targ_etc + "/resolv.conf",
std::ios_base::app);
if(!resolvconf) {
output_error("internal", "failed to open resolv.conf");
@@ -338,14 +339,14 @@ bool Script::execute() const {
if(dhcp) {
if(opts.test(Simulate)) {
- std::cout << "mv /target/etc/resolv.conf "
- << "/target/etc/resolv.conf.head" << std::endl;
+ std::cout << "mv " << targ_etc << "/resolv.conf "
+ << targ_etc << "/resolv.conf.head" << std::endl;
}
#ifdef HAS_INSTALL_ENV
else {
- if(fs::exists("/target/etc/resolv.conf", ec)) {
- fs::rename("/target/etc/resolv.conf",
- "/target/etc/resolv.conf.head", ec);
+ if(fs::exists(targ_etc + "/resolv.conf", ec)) {
+ fs::rename(targ_etc + "/resolv.conf",
+ targ_etc + "/resolv.conf.head", ec);
if(ec) {
output_error("internal",
"cannot save nameserver configuration",
@@ -366,20 +367,22 @@ bool Script::execute() const {
if(opts.test(Simulate)) {
if(do_wpa) {
- std::cout << "cp /target/etc/wpa_supplicant/wpa_supplicant.conf "
+ std::cout << "cp " << targ_etc
+ << "/wpa_supplicant/wpa_supplicant.conf "
<< "/etc/wpa_supplicant/wpa_supplicant.conf"
<< std::endl;
}
- std::cout << "cp /target/etc/conf.d/net /etc/conf.d/net"
+ std::cout << "cp " << targ_etc << "/conf.d/net /etc/conf.d/net"
<< std::endl;
if(!internal->nses.empty()) {
- std::cout << "cp /target/etc/resolv.conf* /etc/" << std::endl;
+ std::cout << "cp " << targ_etc << "/resolv.conf* /etc/"
+ << std::endl;
}
}
#ifdef HAS_INSTALL_ENV
else {
if(do_wpa) {
- fs::copy_file("/target/etc/wpa_supplicant/wpa_supplicant.conf",
+ fs::copy_file(targ_etc + "/wpa_supplicant/wpa_supplicant.conf",
"/etc/wpa_supplicant/wpa_supplicant.conf",
fs_overwrite, ec);
if(ec) {
@@ -388,7 +391,7 @@ bool Script::execute() const {
EXECUTE_FAILURE("network");
}
}
- fs::copy_file("/target/etc/conf.d/net", "/etc/conf.d/net",
+ fs::copy_file(targ_etc + "/conf.d/net", "/etc/conf.d/net",
fs_overwrite, ec);
if(ec) {
output_error("internal", "cannot use networking configuration "
@@ -409,10 +412,10 @@ bool Script::execute() const {
}
if(!internal->nses.empty()) {
if(dhcp) {
- fs::copy_file("/target/etc/resolv.conf.head",
+ fs::copy_file(targ_etc + "/resolv.conf.head",
"/etc/resolv.conf.head", ec);
} else {
- fs::copy_file("/target/etc/resolv.conf",
+ fs::copy_file(targ_etc + "/resolv.conf",
"/etc/resolv.conf", ec);
}
@@ -439,11 +442,13 @@ bool Script::execute() const {
/* REQ: Runner.Execute.pkginstall.APKDB */
output_info("internal", "initialising APK");
if(opts.test(Simulate)) {
- std::cout << "apk --root /target --initdb add" << std::endl;
+ std::cout << "/sbin/apk --root " << targetDirectory() << " --initdb add"
+ << std::endl;
}
#ifdef HAS_INSTALL_ENV
else {
- if(system("apk --root /target --initdb add") != 0) {
+ if(run_command("/sbin/apk",
+ {"--root", targetDirectory(), "--initdb", "add"}) != 0) {
EXECUTE_FAILURE("pkginstall");
return false;
}
@@ -457,22 +462,31 @@ bool Script::execute() const {
/* REQ: Runner.Execute.pkginstall */
output_info("internal", "installing packages to target");
- std::ostringstream pkg_list;
- for(auto &pkg : this->internal->packages) {
- pkg_list << pkg << " ";
- }
if(opts.test(Simulate)) {
- std::cout << "apk --root /target update" << std::endl;
- std::cout << "apk --root /target add " << pkg_list.str() << std::endl;
+ std::ostringstream pkg_list;
+ for(auto &pkg : this->internal->packages) {
+ pkg_list << pkg << " ";
+ }
+
+ std::cout << "apk --root " << targetDirectory() << " update"
+ << std::endl;
+ std::cout << "apk --root " << targetDirectory() << " add "
+ << pkg_list.str() << std::endl;
}
#ifdef HAS_INSTALL_ENV
else {
- if(system("apk --root /target update") != 0) {
+ if(run_command("/sbin/apk",
+ {"--root", targetDirectory(), "update"}) != 0) {
EXECUTE_FAILURE("pkginstall");
return false;
}
- std::string apk_invoc = "apk --root /target add " + pkg_list.str();
- if(system(apk_invoc.c_str()) != 0) {
+
+ std::vector<std::string> params = {"--root", targetDirectory(), "add"};
+ std::copy(this->internal->packages.begin(),
+ this->internal->packages.end(),
+ params.end());
+
+ if(run_command("/sbin/apk", params) != 0) {
EXECUTE_FAILURE("pkginstall");
return false;
}
@@ -489,24 +503,24 @@ bool Script::execute() const {
/* REQ: Runner.Execute.netaddress.OpenRC */
if(opts.test(Simulate)) {
for(auto &iface : ifaces) {
- std::cout << "ln -s /etc/init.d/net.lo /target/etc/init.d/net."
- << iface << std::endl;
+ std::cout << "ln -s /etc/init.d/net.lo " << targ_etc
+ << "/init.d/net." << iface << std::endl;
std::cout << "ln -s /etc/init.d/net." << iface
- << " /target/etc/runlevels/default/net." << iface
- << std::endl;
+ << " " << targ_etc << "/runlevels/default/net."
+ << iface << std::endl;
}
}
#ifdef HAS_INSTALL_ENV
else {
for(auto &iface : ifaces) {
fs::create_symlink("/etc/init.d/net.lo",
- "/target/etc/init.d/net." + iface, ec);
+ targ_etc + "/init.d/net." + iface, ec);
if(ec) {
output_error("internal", "could not set up networking on "
+ iface, ec.message());
} else {
fs::create_symlink("/etc/init.d/net." + iface,
- "/target/etc/runlevels/default/net." +
+ targ_etc + "/runlevels/default/net." +
iface, ec);
if(ec) {
output_error("internal", "could not auto-start "
@@ -544,7 +558,7 @@ bool Script::execute() const {
}
}
if(acct.second->icon) {
- maybe_create_icon_dir(opts);
+ maybe_create_icon_dir(opts, targetDirectory());
EXECUTE_OR_FAIL("usericon", acct.second->icon)
}
}
diff --git a/hscript/script_i.hh b/hscript/script_i.hh
index 9d854eb..0ed362e 100644
--- a/hscript/script_i.hh
+++ b/hscript/script_i.hh
@@ -38,6 +38,9 @@ struct UserDetail {
};
struct Script::ScriptPrivate {
+ /*! Determines the target directory (usually /target) */
+ std::string target;
+
/*! Determines whether or not to enable networking. */
std::unique_ptr<Network> network;
/*! The target system's hostname. */
diff --git a/hscript/user.cc b/hscript/user.cc
index 82d627c..81deafd 100644
--- a/hscript/user.cc
+++ b/hscript/user.cc
@@ -143,17 +143,21 @@ bool RootPassphrase::execute() const {
if(script->options().test(Simulate)) {
std::cout << "(printf '" << root_line << "\\" << "n'; "
- << "cat /target/etc/shadow | sed '1d') > /tmp/shadow"
+ << "cat " << script->targetDirectory() << "/etc/shadow |"
+ << "sed '1d') > /tmp/shadow"
<< std::endl
- << "mv /tmp/shadow /target/etc/shadow" << std::endl
- << "chown root:shadow /target/etc/shadow" << std::endl
- << "chmod 640 /target/etc/shadow" << std::endl;
+ << "mv /tmp/shadow " << script->targetDirectory()
+ << "/etc/shadow" << std::endl
+ << "chown root:shadow " << script->targetDirectory()
+ << "/etc/shadow" << std::endl
+ << "chmod 640 " << script->targetDirectory()
+ << "/etc/shadow" << std::endl;
return true;
}
#ifdef HAS_INSTALL_ENV
/* This was tested on gwyn during development. */
- std::ifstream old_shadow("/target/etc/shadow");
+ std::ifstream old_shadow(script->targetDirectory() + "/etc/shadow");
if(!old_shadow) {
output_error("installfile:" + std::to_string(this->lineno()),
"rootpw: cannot open existing shadow file");
@@ -175,7 +179,8 @@ bool RootPassphrase::execute() const {
old_shadow.close();
- std::ofstream new_shadow("/target/etc/shadow", std::ios_base::trunc);
+ std::ofstream new_shadow(script->targetDirectory() + "/etc/shadow",
+ std::ios_base::trunc);
if(!new_shadow) {
output_error("installfile:" + std::to_string(this->lineno()),
"rootpw: cannot replace target shadow file");
@@ -349,9 +354,10 @@ bool UserIcon::validate() const {
}
bool UserIcon::execute() const {
- const std::string as_path("/target/var/lib/AccountsService/icons/" +
- _username);
- const std::string face_path("/target/home/" + _username + "/.face");
+ const std::string as_path(script->targetDirectory() +
+ "/var/lib/AccountsService/icons/" + _username);
+ const std::string face_path(script->targetDirectory() + "/home/" +
+ _username + "/.face");
output_info("installfile:" + std::to_string(line),
"usericon: setting avatar for " + _username);
@@ -363,8 +369,10 @@ bool UserIcon::execute() const {
std::cout << "curl -LO " << as_path << " " << _icon_path
<< std::endl;
}
- std::cout << "cp " << as_path << " " << face_path << ".icon" << std::endl;
- std::cout << "chown $(hscript-printowner /target/home/" << _username
+ std::cout << "cp " << as_path << " " << face_path << ".icon"
+ << std::endl;
+ std::cout << "chown $(hscript-printowner " << script->targetDirectory()
+ << "/home/" << _username
<< ") " << face_path << ".icon" << std::endl;
std::cout << "ln -s .face.icon " << face_path << std::endl;
return true;