def test_03__replace(self, mock_path): """Test03 ElfPatcher()._replace.""" mock_path.return_value = "/some_contdir" cmd = ("#f", "ls") path = "/bin/" elfp = ElfPatcher(self.local, self.contid) output = elfp._replace(cmd, path) self.assertEqual(output, ["/bin/", "ls"])
def test_18_get_ld_library_path(self, mock_ldconf, mock_ldlib, mock_path): """Test18 ElfPatcher().get_ld_library_path().""" Config().conf['lib_dirs_list_essential'] = "" mock_ldconf.return_value = ["/lib"] mock_ldlib.return_value = ["/usr/lib"] mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) status = elfp.get_ld_library_path() self.assertEqual(status, "/lib:/usr/lib:.")
def test_06_get_original_loader(self, mock_guess, mock_getdata, mock_putdata, mock_exists, mock_path): """Test06 ElfPatcher().get_original_loader().""" mock_path.return_value = "/some_contdir" mock_exists.return_value = False mock_guess.return_value = "ld.so" mock_getdata.return_value.strip.return_value = "ld.so" mock_putdata.return_value = "ld.so" elfp = ElfPatcher(self.local, self.contid) status = elfp.get_original_loader() self.assertEqual(status, "ld.so")
def run(self, container_id): """Execute a Docker container using Fakechroot. This is the main method invoked to run the a container with Fakechroot. * argument: container_id or name * options: many via self.opt see the help """ # warning root execution not supported self._uid_check() # setup execution exec_path = self._run_init(container_id) if not exec_path: return 2 self._run_invalid_options() # execution mode and get patcher xmode = self.exec_mode.get_mode() self._elfpatcher = ElfPatcher(self.localrepo, self.container_id) # verify if container pathnames are correct for this mode if not self._elfpatcher.check_container_path(): Msg().out("Warning: container path mismatch, use setup to convert", l=Msg.WAR) # set basic environment variables self._run_env_set() self._fakechroot_env_set() # if not --hostenv clean the environment self._run_env_cleanup_list() # build the actual command cmd_l = self._set_cpu_affinity() cmd_l.extend([ "env", "-i", ]) cmd_l.extend(self.opt["env"].list()) if xmode in ("F1", "F2"): container_loader = self._elfpatcher.get_container_loader() if container_loader: cmd_l.append(container_loader) cmd_l.extend(self._run_add_script_support(exec_path)) cmd_l.extend(self.opt["cmd"]) Msg().out("CMD =", cmd_l, l=Msg.VER) # execute self._run_banner(self.opt["cmd"][0], '#') cwd = FileUtil(self.container_root).cont2host(self.opt["cwd"], self.opt["vol"]) status = subprocess.call(cmd_l, shell=False, close_fds=True, cwd=cwd) return status
def test_11_patch_binaries(self, mock_chkcont, mock_gcl, mock_select, mock_guess, mock_walk, mock_putdata, mock_exists, mock_path): """Test11 ElfPatcher().patch_binaries().""" mock_exists.return_value = True mock_chkcont.return_value = True mock_walk.return_value = True mock_gcl.return_value = "/usr/bin/ld" mock_select.return_value = "runc-arm" mock_putdata.side_effect = ["10", "/tmp"] mock_guess.return_value = "/usr/bin/ld" mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) elfp._container_root = "/tmp/ROOT" self.assertTrue(elfp.patch_binaries())
def test_12_restore_binaries(self, mock_select, mock_gol, mock_lpath, mock_walk, mock_guess, mock_rm, mock_path): """Test12 ElfPatcher().restore_binaries().""" mock_select.return_value = "runc-arm" mock_gol.return_value = "ld.so" mock_lpath.return_value = "xxx" mock_walk.return_value = "" mock_guess.return_value = "ld.so" mock_rm.return_value = True mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) elfp._container_root = "/tmp/ROOT" self.assertTrue(elfp.restore_binaries()) self.assertTrue(mock_rm.called)
def test_01__init(self, mock_path, mock_hinfo): """Test01 ElfPatcher() constructor.""" mock_path.return_value = "/some_contdir" mock_hinfo.uid = "1000" elfp = ElfPatcher(self.local, self.contid) self.assertTrue(mock_path.callled) self.assertEqual(elfp._uid, "1000")
def test_08_get_patch_last_path(self, mock_getdata, mock_path): """Test08 ElfPatcher().get_patch_last_path().""" mock_getdata.return_value = "" mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) self.assertEqual(elfp.get_patch_last_path(), "") mock_getdata.return_value = "/tmp" mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) self.assertEqual(elfp.get_patch_last_path(), "/tmp")
def test_09_check_container_path(self, mock_lpath, mock_path): """Test09 ElfPatcher().check_container_path().""" mock_lpath.return_value = "" mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) status = elfp.check_container_path() self.assertTrue(status) mock_lpath.return_value = "xxx" mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) status = elfp.check_container_path() self.assertFalse(status)
def test_05_guess_elf_loader(self, mock_spelf, mock_walk, mock_path): """Test05 ElfPatcher().guess_elf_loader().""" mock_spelf.return_value = "ld.so" mock_walk.return_value = "" mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) self.assertEqual(elfp.guess_elf_loader(), "") mock_walk.return_value = "ld.so" mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) self.assertEqual(elfp.guess_elf_loader(), "ld.so")
def test_07_get_container_loader(self, mock_gol, mock_exists, mock_path): """Test07 ElfPatcher().get_container_loader(). Get an absolute pathname to the container ld.so""" mock_gol.return_value = "" mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) self.assertEqual(elfp.get_container_loader(), "") mock_exists.return_value = True mock_gol.return_value = "ld.so" mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) self.assertEqual(elfp.get_container_loader(), elfp._container_root + "/" + "ld.so")
def test_16__find_ld_libdirs(self, mock_walk, mock_access, mock_path, mock_isfile): """Test16 ElfPatcher()._find_ld_libdirs(). search for library directories in container""" mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) status = elfp._find_ld_libdirs() self.assertEqual(status, []) mock_path.return_value = "/some_contdir" mock_walk.return_value = [("libsome.so.0", ["dir"], ["libsome.so.0"]), ] mock_access.return_value = True mock_isfile.return_value = True elfp = ElfPatcher(self.local, self.contid) status = elfp._find_ld_libdirs() self.assertEqual(status, ["libsome.so.0"])
def test_15__get_ld_config(self, mock_upout, mock_dir, mock_path): """Test15 ElfPatcher().get_ld_config().""" mock_upout.return_value = [] mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) status = elfp._get_ld_config() self.assertEqual(status, []) mock_upout.return_value = \ "ld.so.cache => /tmp/ROOT/etc/ld.so.cache\n" \ "ld.so.cache => /tmp/ROOT/etc/ld.so" mock_dir.side_effect = ['/ld.so.cache', '/ld.so'] mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) status = elfp._get_ld_config() self.assertIsInstance(status, list)
def test_14_restore_ld(self, mock_copyto, mock_size, mock_path, mock_gcl, mock_msg): """Test14 ElfPatcher().restore_ld().""" mock_msg.level = 0 mock_size.return_value = -1 mock_path.return_value = "/some_contdir" mock_gcl.return_value = "" elfp = ElfPatcher(self.local, self.contid) self.assertFalse(elfp.restore_ld()) mock_size.return_value = 20 mock_copyto.return_value = True mock_path.return_value = "/some_contdir" mock_gcl.return_value = "" elfp = ElfPatcher(self.local, self.contid) self.assertTrue(elfp.restore_ld())
def test_02_select_patchelf(self, mock_path, mock_find, mock_arch, mock_exists, mock_msg): """Test02 ElfPatcher().select_patchelf().""" mock_msg.level = 0 mock_path.return_value = "/some_contdir" mock_arch.return_value = "arm" mock_find.return_value = "runc-arm" mock_exists.return_value = True elfp = ElfPatcher(self.local, self.contid) output = elfp.select_patchelf() self.assertEqual(output, "runc-arm") mock_path.return_value = "/some_contdir" mock_arch.return_value = "arm" mock_find.return_value = "" mock_exists.return_value = False with self.assertRaises(SystemExit) as epexpt: elfp = ElfPatcher(self.local, self.contid) elfp.select_patchelf() self.assertEqual(epexpt.exception.code, 1)
def test_17_get_ld_libdirs(self, mock_exists, mock_getdata, mock_pudata, mock_findlib, mock_path): """Test17 ElfPatcher().get_ld_libdirs().""" mock_exists.return_value = True mock_getdata.return_value = '/lib:/usr/lib' mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) status = elfp.get_ld_libdirs(False) self.assertEqual(status, ['/lib', '/usr/lib']) mock_exists.return_value = False mock_pudata.return_value = '/lib:/usr/lib' mock_findlib.return_value = ['/lib', '/usr/lib'] mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) status = elfp.get_ld_libdirs(True) self.assertEqual(status, ['/lib', '/usr/lib'])
def test_04__walk_fs(self, mock_path, mock_access, mock_walk, mock_stat, mock_islink, mock_uprocout): """Test04 ElfPatcher()._walk_fs().""" mock_path.return_value = "/some_contdir" mock_walk.return_value = [("/tmp", ["dir"], ["file"]), ] mock_islink.return_value = False mock_access.return_value = False mock_stat.return_value.st_uid = 1000 elfp = ElfPatcher(self.local, self.contid) elfp._uid = 0 status = elfp._walk_fs("cmd", "/tmp", elfp.ABORT_ON_ERROR) self.assertEqual(status, "") mock_path.return_value = "/some_contdir" mock_walk.return_value = [("/tmp", ["dir"], ["file"]), ] mock_islink.return_value = False mock_access.return_value = True mock_stat.return_value.st_uid = 0 mock_uprocout.return_value = "some output" elfp = ElfPatcher(self.local, self.contid) elfp._uid = 0 status = elfp._walk_fs("cmd", "/tmp", elfp.BIN) self.assertTrue(mock_uprocout.called) self.assertEqual(status, "some output")
def set_mode(self, xmode, force=False): """Set execution mode""" status = False prev_xmode = self.get_mode() elfpatcher = ElfPatcher(self.localrepo, self.container_id) filebind = FileBind(self.localrepo, self.container_id) futil_croot = FileUtil(self.container_orig_root) orig_path = futil_croot.getdata('r').strip() if xmode not in self.valid_modes: Msg().err("Error: invalid execmode:", xmode) return status if not (force or xmode != prev_xmode): return True if prev_xmode[0] in ('R', 'S') and xmode[0] != 'R': filebind.restore() if xmode[0] == 'F': if force or prev_xmode[0] in ("P", "R", "S"): futil_cont = FileUtil(self.container_root) status = (futil_cont.links_conv(force, True, orig_path) and elfpatcher.get_ld_libdirs(force)) if xmode in ('P1', 'P2', 'F1', 'R1', 'R2', 'R3', 'S1'): if prev_xmode in ('P1', 'P2', 'F1', 'R1', 'R2', 'R3', 'S1'): status = True elif force or prev_xmode in ("F2", "F3", "F4"): status = ((elfpatcher.restore_ld() or force) and elfpatcher.restore_binaries()) if xmode[0] == 'R': filebind.setup() elif xmode in ("F2", ): if force or prev_xmode in ("F3", "F4"): status = elfpatcher.restore_binaries() if force or prev_xmode in ('P1', 'P2', 'F1', 'R1', 'R2', 'R3', 'S1'): status = elfpatcher.patch_ld() elif xmode in ("F3", "F4"): if force or prev_xmode in ('P1', 'P2', 'F1', 'F2', 'R1', 'R2', 'R3', 'S1'): status = (elfpatcher.patch_ld() and elfpatcher.patch_binaries()) elif prev_xmode in ("F3", "F4"): status = True if xmode[0] in ("P", "R", "S"): if force or (status and prev_xmode.startswith("F")): futil = FileUtil(self.container_root) status = futil.links_conv(force, False, orig_path) if status or force: futil = FileUtil(self.container_execmode) status = futil.putdata(xmode, "w") if status or force: futil = FileUtil(self.container_orig_root) status = futil.putdata(os.path.realpath(self.container_root), "w") if (not status) and (not force): Msg().err("Error: container setup failed") return bool(status)
class FakechrootEngine(ExecutionEngineCommon): """Docker container execution engine using Fakechroot Provides a chroot like environment to run containers. Uses Fakechroot as chroot alternative. Inherits from ContainerEngine class """ def __init__(self, localrepo, exec_mode): super(FakechrootEngine, self).__init__(localrepo, exec_mode) self._fakechroot_so = "" self._elfpatcher = None self._recommend_expand_symlinks = False def select_fakechroot_so(self): """Select fakechroot sharable object library""" image_list = [] if Config.conf['fakechroot_so']: if isinstance(Config.conf['fakechroot_so'], list): image_list = Config.conf['fakechroot_so'] elif is_genstr(Config.conf['fakechroot_so']): image_list = [ Config.conf['fakechroot_so'], ] if "/" in Config.conf['fakechroot_so']: if os.path.exists(Config.conf['fakechroot_so']): return os.path.realpath(Config.conf['fakechroot_so']) elif os.path.exists(self.container_dir + "/libfakechroot.so"): return self.container_dir + "/libfakechroot.so" else: lib = "libfakechroot" deflib = "libfakechroot.so" image_list = [ deflib, ] guest = OSInfo(self.container_root) arch = guest.arch() (distro, version) = guest.osdistribution() if "Alpine" not in distro: version = version.split(".")[0] if arch == "amd64": image_list = [ "%s-%s-%s-x86_64.so" % (lib, distro, version), "%s-%s-x86_64.so" % (lib, distro), "%s-x86_64.so" % (lib), deflib ] elif arch == "i386": image_list = [ "%s-%s-%s-x86.so" % (lib, distro, version), "%s-%s-x86.so" % (lib, distro), "%s-x86.so" % (lib), deflib ] elif arch == "arm64": image_list = [ "%s-%s-%s-arm64.so" % (lib, distro, version), "%s-%s-arm64.so" % (lib, distro), "%s-arm64.so" % (lib), deflib ] elif arch == "arm": image_list = [ "%s-%s-%s-arm.so" % (lib, distro, version), "%s-%s-arm.so" % (lib, distro), "%s-arm.so" % (lib), deflib ] f_util = FileUtil(self.localrepo.libdir) fakechroot_so = f_util.find_file_in_dir(image_list) if not os.path.exists(fakechroot_so): Msg().err("Error: no libfakechroot found", image_list) sys.exit(1) Msg().out("Info: fakechroot_so:", fakechroot_so, l=Msg.DBG) return fakechroot_so def _setup_container_user(self, user): """Override of _setup_container_user()""" return self._setup_container_user_noroot(user) def _uid_check(self): """Check the uid_map string for container run command""" if ("user" in self.opt and (self.opt["user"] == '0' or self.opt["user"] == "root")): Msg().out( "Warning: this engine does not support execution as root", l=Msg.WAR) def _get_volume_bindings(self): """Get the volume bindings string for fakechroot run""" host_volumes_list = [] map_volumes_list = [] map_volumes_dict = dict() for vol in self.opt["vol"]: (host_path, cont_path) = Uvolume(vol).split() if not (host_path and cont_path): continue real_host_path = os.path.realpath(host_path) if (host_path == cont_path and Config.conf['fakechroot_expand_symlinks'] is False): host_volumes_list.append(host_path) elif (host_path == cont_path and host_path in Config.conf['sysdirs_list']): host_volumes_list.append(host_path) elif host_path == cont_path and not os.path.isdir(real_host_path): host_volumes_list.append(host_path) else: map_volumes_dict[cont_path] = real_host_path + '!' + cont_path if host_path != real_host_path or os.path.isdir( real_host_path): self._recommend_expand_symlinks = True for cont_path in sorted(map_volumes_dict, reverse=True): map_volumes_list.append(map_volumes_dict[cont_path]) return (':'.join(host_volumes_list), ':'.join(map_volumes_list)) def _get_access_filesok(self): """ Circunvent mpi init issues when calling access() A list of certain existing files is provided """ file_list = [] for c_path in Config.conf['access_files']: h_file = FileUtil(self.container_root).cont2host( c_path, self.opt["vol"]) if h_file and os.path.exists(h_file): file_list.append(c_path) return ":".join(file_list) def _fakechroot_env_set(self): """fakechroot environment variables to set""" (host_volumes, map_volumes) = self._get_volume_bindings() self._fakechroot_so = self.select_fakechroot_so() access_filesok = self._get_access_filesok() self.opt["env"].append("PWD=" + self.opt["cwd"]) self.opt["env"].append("FAKECHROOT_BASE=" + os.path.realpath(self.container_root)) self.opt["env"].append("LD_PRELOAD=" + self._fakechroot_so) if Config.conf['fakechroot_expand_symlinks'] is None: self.opt["env"].append("FAKECHROOT_EXPAND_SYMLINKS=" + \ str(self._recommend_expand_symlinks).lower()) else: self.opt["env"].append("FAKECHROOT_EXPAND_SYMLINKS=" + \ str(Config.conf['fakechroot_expand_symlinks']).lower()) if not self._is_volume("/tmp"): self.opt["env"].append("FAKECHROOT_AF_UNIX_PATH=" + Config.conf['tmpdir']) if host_volumes: self.opt["env"].append("FAKECHROOT_EXCLUDE_PATH=" + host_volumes) if map_volumes: self.opt["env"].append("FAKECHROOT_DIR_MAP=" + map_volumes) if Msg.level >= Msg.DBG: self.opt["env"].append("FAKECHROOT_DEBUG=true") self.opt["env"].append("LD_DEBUG=libs:files") if access_filesok: self.opt["env"].append("FAKECHROOT_ACCESS_FILESOK=" + access_filesok) # execution mode ld_library_real = self._elfpatcher.get_ld_library_path() xmode = self.exec_mode.get_mode() if xmode == "F1": self.opt["env"].append("FAKECHROOT_ELFLOADER=" + self._elfpatcher.get_container_loader()) self.opt["env"].append("LD_LIBRARY_PATH=" + ld_library_real) elif xmode == "F2": self.opt["env"].append("FAKECHROOT_ELFLOADER=" + self._elfpatcher.get_container_loader()) self.opt["env"].append("FAKECHROOT_LIBRARY_ORIG=" + ld_library_real) self.opt["env"].append("LD_LIBRARY_REAL=" + ld_library_real) self.opt["env"].append("LD_LIBRARY_PATH=" + ld_library_real) elif xmode == "F3": self.opt["env"].append("FAKECHROOT_LIBRARY_ORIG=" + ld_library_real) self.opt["env"].append("LD_LIBRARY_REAL=" + ld_library_real) self.opt["env"].append("LD_LIBRARY_PATH=" + ld_library_real) elif xmode == "F4": self.opt["env"].append("FAKECHROOT_LIBRARY_ORIG=" + ld_library_real) self.opt["env"].append("LD_LIBRARY_REAL=" + ld_library_real) self.opt["env"].append("LD_LIBRARY_PATH=" + ld_library_real) patchelf_exec = self._elfpatcher.select_patchelf() if patchelf_exec: self.opt["env"].append("FAKECHROOT_PATCH_PATCHELF=" + patchelf_exec) self.opt["env"].append("FAKECHROOT_PATCH_ELFLOADER=" + self._elfpatcher.get_container_loader()) self.opt["env"].append("FAKECHROOT_PATCH_LAST_TIME=" + self._elfpatcher.get_patch_last_time()) def _run_invalid_options(self): """check -p --publish -P --publish-all --net-coop""" if self.opt["portsmap"]: Msg().out( "Warning: this execution mode does not support " "-p --publish", l=Msg.WAR) if self.opt["netcoop"]: Msg().out( "Warning: this execution mode does not support " "-P --netcoop --publish-all", l=Msg.WAR) def _run_add_script_support(self, exec_path): """Add an interpreter for non binary executables (scripts)""" filetype = OSInfo(self.container_root).get_filetype(exec_path) if "ELF" in filetype and ("static" in filetype or "dynamic" in filetype): self.opt["cmd"][0] = exec_path return [] env_exec = FileUtil("env").find_exec("/bin:/usr/bin", self.container_root) if env_exec: return [ self.container_root + '/' + env_exec, ] relc_path = exec_path.split(self.container_root, 1)[-1] real_path = FileUtil(self.container_root).cont2host( relc_path, self.opt["vol"]) hashbang = FileUtil(real_path).get1stline() match = re.match("#! *([^ ]+)(.*)", hashbang) if match and not match.group(1).startswith('/'): Msg().err("Error: no such file", match.group(1), "in", exec_path) sys.exit(1) elif match: interpreter = [ self.container_root + '/' + match.group(1), ] if match.group(2): interpreter.extend(match.group(2).strip().split(' ')) self.opt["cmd"][0] = exec_path.split(self.container_root, 1)[-1] return interpreter sh_exec = FileUtil("sh").find_exec(self.opt["env"].getenv("PATH"), self.container_root) if sh_exec: return [ self.container_root + '/' + sh_exec, ] Msg().err("Error: sh not found") sys.exit(1) def run(self, container_id): """Execute a Docker container using Fakechroot. This is the main method invoked to run the a container with Fakechroot. * argument: container_id or name * options: many via self.opt see the help """ # warning root execution not supported self._uid_check() # setup execution exec_path = self._run_init(container_id) if not exec_path: return 2 self._run_invalid_options() # execution mode and get patcher xmode = self.exec_mode.get_mode() self._elfpatcher = ElfPatcher(self.localrepo, self.container_id) # verify if container pathnames are correct for this mode if not self._elfpatcher.check_container_path(): Msg().out("Warning: container path mismatch, use setup to convert", l=Msg.WAR) # set basic environment variables self._run_env_set() self._fakechroot_env_set() # if not --hostenv clean the environment self._run_env_cleanup_list() # build the actual command cmd_l = self._set_cpu_affinity() cmd_l.extend([ "env", "-i", ]) cmd_l.extend(self.opt["env"].list()) if xmode in ("F1", "F2"): container_loader = self._elfpatcher.get_container_loader() if container_loader: cmd_l.append(container_loader) cmd_l.extend(self._run_add_script_support(exec_path)) cmd_l.extend(self.opt["cmd"]) Msg().out("CMD =", cmd_l, l=Msg.VER) # execute self._run_banner(self.opt["cmd"][0], '#') cwd = FileUtil(self.container_root).cont2host(self.opt["cwd"], self.opt["vol"]) status = subprocess.call(cmd_l, shell=False, close_fds=True, cwd=cwd) return status
def test_10_get_patch_last_time(self, mock_getdata, mock_path): """Test10 ElfPatcher().patch_last_time().""" mock_getdata.return_value = "30" mock_path.return_value = "/some_contdir" elfp = ElfPatcher(self.local, self.contid) self.assertEqual(elfp.get_patch_last_time(), "30")
def test_13_patch_ld(self, mock_putdata, mock_getdata, mock_copyto, mock_size, mock_path, mock_gcl): """Test13 ElfPatcher().patch_ld().""" mock_size.return_value = -1 mock_putdata.return_value = False mock_path.return_value = "/some_contdir" mock_gcl.return_value = "" elfp = ElfPatcher(self.local, self.contid) self.assertFalse(elfp.patch_ld()) mock_size.return_value = 20 mock_copyto.return_value = False mock_path.return_value = "/some_contdir" mock_gcl.return_value = "" elfp = ElfPatcher(self.local, self.contid) self.assertFalse(elfp.patch_ld()) mock_size.return_value = 20 mock_copyto.return_value = True mock_getdata.return_value = [] mock_path.return_value = "/some_contdir" mock_gcl.return_value = "" elfp = ElfPatcher(self.local, self.contid) self.assertFalse(elfp.patch_ld()) mock_size.return_value = 20 mock_copyto.return_value = True mock_getdata.return_value = [] mock_path.return_value = "/some_contdir" mock_gcl.return_value = "" elfp = ElfPatcher(self.local, self.contid) self.assertFalse(elfp.patch_ld("OUTPUT_ELF"))