along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/* chroot layout used with the _2_2 postfix commands
+ * call with e2-su-2.2 <command> <path> ...
+ * path/emlix-chroot - chroot marker file
+ * path/ - chroot environment
+ *
+ * This layout is broken: the chroot marker file can be deleted in chroot
+ * and early when removing chroot is not fully done.
+ * In that case e2factory refuses to use and even delete the chroot
+ * environment, leaving the user with a chroot environment that only
+ * root may delete.
+ *
+ * The new chroot layout fixes this:
+ *
+ * chroot layout used with the _2_3 postfix commands
+ * call with e2-su-2.2 <command> <base> ...
+ * base/e2factory-chroot - chroot marker file
+ * base/chroot/ - chroot environment
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
return;
}
+void assert_chroot_environment_2_3(char *base)
+{
+ char name[PATH_MAX];
+ snprintf(name, sizeof(name), "%s/e2factory-chroot", base);
+ name[sizeof(name)-1]=0;
+ if(access(name, R_OK)) {
+ perr("not a chroot environment");
+ }
+ return;
+}
+
int main(int argc, char *argv[])
{
int rc;
perr("too many arguments");
}
char *cmd = argv[1];
- char *path = argv[2];
- assert_chroot_environment(path);
if(!strcmp(cmd, "chroot_2_2")) {
/* chroot_2_2 <path> ... */
int i;
if(argc < 3) {
perr("too few arguments");
}
+ char *path = argv[2];
+ assert_chroot_environment(path);
arg[0] = basename(chroot_tool);
arg[1] = path;
for (i=3; i < argc; i++) {
if(argc != 5) {
perr("wrong number of arguments");
}
+ char *path = argv[2];
+ assert_chroot_environment(path);
char *tartype = argv[3];
char *file = argv[4];
char *tararg = NULL;
if(argc != 3) {
perr("wrong number of arguments");
}
+ char *path = argv[2];
+ assert_chroot_environment(path);
arg[0] = basename(chown_tool);
arg[1] = "root:root";
arg[2] = path;
if(argc != 3) {
perr("wrong number of arguments");
}
+ char *path = argv[2];
+ assert_chroot_environment(path);
+ arg[0] = basename(rm_tool);
+ arg[1] = "-r";
+ arg[2] = "-f";
+ arg[3] = path;
+ arg[4] = NULL;
+ print_arg(arg);
+ setuid_root();
+ rc = execv(rm_tool, arg);
+ perror("can't exec");
+ exit(99);
+ } else if(!strcmp(cmd, "chroot_2_3")) {
+ /* chroot_2_3 <base> ... */
+ int i;
+ char *arg[256];
+ if(argc < 3) {
+ perr("too few arguments");
+ }
+ char *base = argv[2];
+ char path[PATH_MAX];
+ snprintf(path, sizeof(path), "%s/chroot", base);
+ path[sizeof(path)-1] = 0;
+ assert_chroot_environment_2_3(base);
+ arg[0] = basename(chroot_tool);
+ arg[1] = path;
+ for (i=3; i < argc; i++) {
+ arg[i-1] = argv[i];
+ }
+ arg[i-1] = 0;
+ print_arg(arg);
+ setuid_root();
+ rc = execv(chroot_tool, arg);
+ perror("can't exec");
+ exit(99);
+ } else if(!strcmp(cmd, "extract_tar_2_3")) {
+ /* extract_tar_2_3 <base> <tartype> <file> */
+ char *arg[256];
+ if(argc != 5) {
+ perr("wrong number of arguments");
+ }
+ char *base = argv[2];
+ assert_chroot_environment_2_3(base);
+ char path[PATH_MAX];
+ snprintf(path, sizeof(path), "%s/chroot", base);
+ path[sizeof(path)-1] = 0;
+ char *tartype = argv[3];
+ char *file = argv[4];
+ char *tararg = NULL;
+ if(!strcmp(tartype, "tar.gz")) {
+ tararg = "-xzf";
+ } else if(!strcmp(tartype, "tar.bz2")) {
+ tararg = "-xjf";
+ } else if(!strcmp(tartype, "tar")) {
+ tararg = "-xf";
+ } else {
+ perr("wrong tararg argument");
+ }
+ arg[0] = basename(tar_tool);
+ arg[1] = "-C";
+ arg[2] = path;
+ arg[3] = tararg;
+ arg[4] = file;
+ arg[5] = NULL;
+ print_arg(arg);
+ setuid_root();
+ rc = execv(tar_tool, arg);
+ perror("can't exec");
+ exit(99);
+ } else if(!strcmp(cmd, "set_permissions_2_3")) {
+ /* set_permissions_2_3 <base> */
+ char *arg[256];
+ if(argc != 3) {
+ perr("wrong number of arguments");
+ }
+ char *base = argv[2];
+ assert_chroot_environment_2_3(base);
+ char path[PATH_MAX];
+ snprintf(path, sizeof(path), "%s/chroot", base);
+ path[sizeof(path)-1] = 0;
+ arg[0] = basename(chown_tool);
+ arg[1] = "root:root";
+ arg[2] = path;
+ arg[3] = NULL;
+ print_arg(arg);
+ setuid_root();
+ rc = execv(chown_tool, arg);
+ perror("can't exec");
+ exit(99);
+ } else if(!strcmp(cmd, "remove_chroot_2_3")) {
+ /* remove_chroot_2_3 <base> */
+ char *arg[256];
+ if(argc != 3) {
+ perr("wrong number of arguments");
+ }
+ char *base = argv[2];
+ assert_chroot_environment_2_3(base);
+ char path[PATH_MAX];
+ snprintf(path, sizeof(path), "%s/chroot", base);
+ path[sizeof(path)-1] = 0;
arg[0] = basename(rm_tool);
arg[1] = "-r";
arg[2] = "-f";
-- @field mode table: the build mode policy
-- @field release id string: the release name
-- @field info table: the info table
+-- @field base string: path to the build directory
-- @field c string: path to the chroot
+-- @field chroot_marker string: path to chroot marker file
-- @field T string: absolute path to the temporary build directory
-- inside chroot
-- @field Tc string: same as c.T but relative to c
tab.mode = nil -- XXX
tab.location = nil -- XXX info.project_location
tab.release_id = nil -- XXX release_id
- tab.c = string.format("%s/%s/%s/chroot", tmpdir, project, r)
+ tab.base = string.format("%s/%s/%s", tmpdir, project, r)
+ tab.c = string.format("%s/chroot", tab.base)
+ tab.chroot_marker = string.format("%s/e2factory-chroot", tab.base)
tab.T = string.format("%s/%s/%s/chroot/%s", tmpdir, project, r, builddir)
tab.Tc = string.format("/%s", builddir)
tab.r = string.format("%s", r)
if not rc then
return false, e:cat(re)
end
- local rc, re = e2lib.touch(res.build_config.c .. "/emlix-chroot")
+ local rc, re = e2lib.touch(res.build_config.chroot_marker)
if not rc then
return false, e:cat(re)
end
- -- e2-su set_permissions_2_2 <chroot_path>
- local args = string.format("set_permissions_2_2 '%s'",
- res.build_config.c)
+ -- e2-su set_permissions_2_3 <chroot_path>
+ local args = string.format("set_permissions_2_3 '%s'",
+ res.build_config.base)
local rc, re = e2lib.e2_su_2_2(args)
if not rc then
return false, e:cat(re)
e:append("unknown archive type for chroot file: %s", path)
return false, e
end
- -- e2-su extract_tar_2_2 <path> <tartype> <file>
- local args = string.format("extract_tar_2_2 '%s' '%s' '%s'",
- res.build_config.c, tartype, path)
+ -- e2-su extract_tar_2_3 <path> <tartype> <file>
+ local args = string.format("extract_tar_2_3 '%s' '%s' '%s'",
+ res.build_config.base, tartype, path)
local rc, re = e2lib.e2_su_2_2(args)
if not rc then
return false, e:cat(re)
e2lib.log(4, "entering playground for " .. r .. " ...")
local term = e2lib.terminal
local e2_su = transport.get_tool("e2-su-2.2")
- local cmd = string.format("%s %s chroot_2_2 '%s' %s",
+ local cmd = string.format("%s %s chroot_2_3 '%s' %s",
res.build_config.chroot_call_prefix, e2_su,
- res.build_config.c, chroot_command)
+ res.build_config.base, chroot_command)
os.execute(cmd)
-- return code depends on user commands. Ignore.
return true, nil
local rc, re
local e = new_error("fixing permissions failed")
e2lib.log(3, "fix permissions")
- local args = string.format("chroot_2_2 '%s' chown -R root:root '%s'",
- res.build_config.c, res.build_config.Tc)
+ local args = string.format("chroot_2_3 '%s' chown -R root:root '%s'",
+ res.build_config.base, res.build_config.Tc)
rc, re = e2lib.e2_su_2_2(args)
if not rc then
return false, e:cat(re)
end
- local args = string.format("chroot_2_2 '%s' chmod -R u=rwX,go=rX '%s'",
- res.build_config.c, res.build_config.Tc)
+ local args = string.format("chroot_2_3 '%s' chmod -R u=rwX,go=rX '%s'",
+ res.build_config.base, res.build_config.Tc)
rc, re = e2lib.e2_su_2_2(args)
if not rc then
return false, e:cat(re)
res.build_config.Tc, res.build_config.scriptdir,
res.build_config.build_driver_file)
local e2_su = transport.get_tool("e2-su-2.2")
- local cmd = string.format("%s %s chroot_2_2 '%s' %s",
+ local cmd = string.format("%s %s chroot_2_3 '%s' %s",
res.build_config.chroot_call_prefix, e2_su,
- res.build_config.c, runbuild)
+ res.build_config.base, runbuild)
-- the build log is written to an external logfile
local out = luafile.open(res.build_config.buildlog, "w")
local function logto(output)
if res.keep_chroot then
return true, nil
end
- local args = string.format("remove_chroot_2_2 '%s'", res.build_config.c)
+ local args = string.format("remove_chroot_2_3 '%s'", res.build_config.base)
local rc, re = e2lib.e2_su_2_2(args)
if not rc then
return e:cat(re)
end
+ rc, re = e2lib.rm(res.build_config.chroot_marker)
+ if not rc then
+ return false, e:cat(re)
+ end
local f = string.format("%s/playground", info.root)
local s = e2util.stat(f)
if s and s.type == "symbolic-link" then
-- @return bool
function e2build.chroot_exists(info, r)
local res = info.results[r]
- local f = string.format("%s/emlix-chroot", res.build_config.c)
- return e2lib.isfile(f)
+ return e2lib.isfile(res.build_config.chroot_marker)
end
function e2build.sources(info, r, return_flags)