def test_monitor_integration(self): # Checks the monitoring API is called properly from the pipeline runner = detect_host_runner() index = osbuild.meta.Index(os.curdir) pipeline = osbuild.Pipeline("pipeline", runner=runner) noop_info = index.get_module_info("Stage", "org.osbuild.noop") pipeline.add_stage(noop_info, { "isthisthereallife": False }) pipeline.add_stage(noop_info, { "isthisjustfantasy": True }) with tempfile.TemporaryDirectory() as tmpdir: storedir = os.path.join(tmpdir, "store") tape = TapeMonitor() with ObjectStore(storedir) as store: res = pipeline.run(store, tape, libdir=os.path.abspath(os.curdir)) assert res self.assertEqual(tape.counter["begin"], 1) self.assertEqual(tape.counter["finish"], 1) self.assertEqual(tape.counter["stages"], 2) self.assertEqual(tape.counter["stages"], 2) self.assertEqual(tape.counter["result"], 2) self.assertIn(pipeline.stages[0].id, tape.stages) self.assertIn("isthisthereallife", tape.output) self.assertIn("isthisjustfantasy", tape.output)
def test_monitor_integration(self): # Checks the monitoring API is called properly from the pipeline runner = detect_host_runner() pipeline = osbuild.Pipeline(runner=runner) pipeline.add_stage("org.osbuild.noop", {}, { "isthisthereallife": False }) pipeline.add_stage("org.osbuild.noop", {}, { "isthisjustfantasy": True }) pipeline.set_assembler("org.osbuild.noop") with tempfile.TemporaryDirectory() as tmpdir: storedir = os.path.join(tmpdir, "store") outputdir = os.path.join(tmpdir, "output") tape = TapeMonitor() res = pipeline.run(storedir, tape, libdir=os.path.abspath(os.curdir), output_directory=outputdir) assert res self.assertEqual(tape.counter["begin"], 1) self.assertEqual(tape.counter["finish"], 1) self.assertEqual(tape.counter["stages"], 2) self.assertEqual(tape.counter["assembler"], 1) self.assertEqual(tape.counter["stages"], 2) self.assertEqual(tape.counter["result"], 3) self.assertIn(pipeline.stages[0].id, tape.stages) self.assertIn(pipeline.assembler.id, tape.asm) self.assertIn("isthisthereallife", tape.output) self.assertIn("isthisjustfantasy", tape.output)
def test_log_monitor_vfuncs(self): # Checks the basic functioning of the LogMonitor index = osbuild.meta.Index(os.curdir) runner = detect_host_runner() pipeline = osbuild.Pipeline("pipeline", runner=runner) info = index.get_module_info("Stage", "org.osbuild.noop") pipeline.add_stage(info, { "isthisthereallife": False }) with tempfile.TemporaryDirectory() as tmpdir: storedir = os.path.join(tmpdir, "store") logfile = os.path.join(tmpdir, "log.txt") with open(logfile, "w") as log, ObjectStore(storedir) as store: monitor = LogMonitor(log.fileno()) res = pipeline.run(store, monitor, libdir=os.path.abspath(os.curdir)) with open(logfile) as f: log = f.read() assert res self.assertIn(pipeline.stages[0].id, log) self.assertIn("isthisthereallife", log)
def test_bind_mounts(self): runner = detect_host_runner() libdir = os.path.abspath(os.curdir) var = pathlib.Path(self.tmp.name, "var") var.mkdir() rw_data = pathlib.Path(self.tmp.name, "data") rw_data.mkdir() scripts = os.path.join(self.locate_test_data(), "scripts") monitor = NullMonitor(sys.stderr.fileno()) with BuildRoot("/", runner, libdir, var) as root: ro_binds = [f"{scripts}:/scripts"] cmd = ["/scripts/mount_flags.py", "/scripts", "ro"] r = root.run(cmd, monitor, readonly_binds=ro_binds) self.assertEqual(r.returncode, 0) cmd = ["/scripts/mount_flags.py", "/rw-data", "ro"] binds = [f"{rw_data}:/rw-data"] r = root.run(cmd, monitor, binds=binds, readonly_binds=ro_binds) self.assertEqual(r.returncode, 1)
def test_log_monitor_vfuncs(self): # Checks the basic functioning of the LogMonitor runner = detect_host_runner() pipeline = osbuild.Pipeline(runner=runner) pipeline.add_stage("org.osbuild.noop", {}, { "isthisthereallife": False }) pipeline.set_assembler("org.osbuild.noop") with tempfile.TemporaryDirectory() as tmpdir: storedir = os.path.join(tmpdir, "store") outputdir = os.path.join(tmpdir, "output") logfile = os.path.join(tmpdir, "log.txt") with open(logfile, "w") as log: monitor = LogMonitor(log.fileno()) res = pipeline.run(storedir, monitor, libdir=os.path.abspath(os.curdir), output_directory=outputdir) with open(logfile) as f: log = f.read() assert res self.assertIn(pipeline.stages[0].id, log) self.assertIn(pipeline.assembler.id, log) self.assertIn("isthisthereallife", log)
def test_output(tempdir): runner = detect_host_runner() libdir = os.path.abspath(os.curdir) var = pathlib.Path(tempdir, "var") var.mkdir() data = "42. cats are superior to dogs" monitor = NullMonitor(sys.stderr.fileno()) with BuildRoot("/", runner, libdir, var) as root: r = root.run(["/usr/bin/echo", data], monitor) assert r.returncode == 0 assert data in r.output.strip()
def test_output(self): runner = detect_host_runner() libdir = os.path.abspath(os.curdir) var = pathlib.Path(self.tmp.name, "var") var.mkdir() data = "42. cats are superior to dogs" monitor = NullMonitor(sys.stderr.fileno()) with BuildRoot("/", runner, libdir, var) as root: r = root.run(["/usr/bin/echo", data], monitor) self.assertEqual(r.returncode, 0) self.assertIn(data, r.output.strip())
def test_proc_overrides(tempdir): runner = detect_host_runner() libdir = os.path.abspath(os.curdir) var = pathlib.Path(tempdir, "var") var.mkdir() cmdline = "is-this-the-real-world" monitor = NullMonitor(sys.stderr.fileno()) with BuildRoot("/", runner, libdir, var) as root: root.proc.cmdline = cmdline r = root.run(["cat", "/proc/cmdline"], monitor) assert r.returncode == 0 assert cmdline in r.output.strip()
def test_timeout(tempdir): runner = detect_host_runner() libdir = os.path.abspath(os.curdir) var = pathlib.Path(tempdir, "var") var.mkdir() monitor = NullMonitor(sys.stderr.fileno()) with BuildRoot("/", runner, libdir, var) as root: root.run(["/bin/sleep", "1"], monitor, timeout=2) with pytest.raises(TimeoutError): root.run(["/bin/sleep", "1"], monitor, timeout=0.1) with pytest.raises(TimeoutError): root.run(["/bin/sleep", "1"], monitor, timeout=0.1)
def test_basic(self): runner = detect_host_runner() libdir = os.path.abspath(os.curdir) var = pathlib.Path(self.tmp.name, "var") var.mkdir() monitor = NullMonitor(sys.stderr.fileno()) with BuildRoot("/", runner, libdir, var) as root: r = root.run(["/usr/bin/true"], monitor) self.assertEqual(r.returncode, 0) # Test we can use `.run` multiple times r = root.run(["/usr/bin/true"], monitor) self.assertEqual(r.returncode, 0) r = root.run(["/usr/bin/false"], monitor) self.assertNotEqual(r.returncode, 0)
def test_basic(tempdir): runner = detect_host_runner() libdir = os.path.abspath(os.curdir) var = pathlib.Path(tempdir, "var") var.mkdir() monitor = NullMonitor(sys.stderr.fileno()) with BuildRoot("/", runner, libdir, var) as root: r = root.run(["/usr/bin/true"], monitor) assert r.returncode == 0 # Test we can use `.run` multiple times r = root.run(["/usr/bin/true"], monitor) assert r.returncode == 0 r = root.run(["/usr/bin/false"], monitor) assert r.returncode != 0
def test_stage_run(self): index = osbuild.meta.Index(os.curdir) info = index.get_module_info("Stage", "org.osbuild.noop") stage = osbuild.Stage(info, {}, None, None, {}) with tempfile.TemporaryDirectory() as tmpdir: data = pathlib.Path(tmpdir, "data") storedir = pathlib.Path(tmpdir, "store") root = pathlib.Path("/") runner = detect_host_runner() monitor = NullMonitor(sys.stderr.fileno()) libdir = os.path.abspath(os.curdir) store = ObjectStore(storedir) data.mkdir() res = stage.run(data, runner, root, store, monitor, libdir) self.assertEqual(res.success, True) self.assertEqual(res.id, stage.id)
def test_selinuxfs_ro(self): # /sys/fs/selinux must never be writable in the container # because RPM and other tools must not assume the policy # of the host is the valid policy runner = detect_host_runner() libdir = os.path.abspath(os.curdir) var = pathlib.Path(self.tmp.name, "var") var.mkdir() scripts = os.path.join(self.locate_test_data(), "scripts") monitor = NullMonitor(sys.stderr.fileno()) with BuildRoot("/", runner, libdir, var) as root: ro_binds = [f"{scripts}:/scripts"] cmd = ["/scripts/mount_flags.py", "/sys/fs/selinux", "ro"] r = root.run(cmd, monitor, readonly_binds=ro_binds) self.assertEqual(r.returncode, 0)
def test_env_isolation(tempdir): runner = detect_host_runner() libdir = os.path.abspath(os.curdir) var = pathlib.Path(tempdir, "var") var.mkdir() monitor = NullMonitor(sys.stderr.fileno()) ipc = pathlib.Path(tempdir, "ipc") ipc.mkdir() # Set some env variable to make sure it is not leaked into # the container os.environ["OSBUILD_TEST_ENV_ISOLATION"] = "42" with BuildRoot("/", runner, libdir, var) as root: cmd = ["/bin/sh", "-c", "/usr/bin/env > /ipc/env.txt"] r = root.run(cmd, monitor, binds=[f"{ipc}:/ipc"]) assert r.returncode == 0 with open(os.path.join(ipc, "env.txt")) as f: data = f.read().strip() assert data have = dict(map(lambda x: x.split("=", 1), data.split("\n"))) allowed = [ "_", # added by `env` itself "container", "LC_CTYPE", "PATH", "PWD", "PYTHONPATH", "PYTHONUNBUFFERED", "SHLVL", # added by the shell wrapper "TERM", ] for k in have: assert k in allowed