def test_apply_commands(self): fstab_lines = "\\n".join( [ "", "# name (originally device)", "device\\tnone\\tswap\\tdefaults\\t0\\t0", ] ) expected = [ Command( [ "mkswap", "device", "--label=label", "--pagesize=pagesize", "--uuid=uuid", ] ), Command(["swapon", "device"]), Command( [ "shell", "-c", "'echo -e \"{}\" >> tmp_dir/etc/fstab'".format(fstab_lines), ] ), ] self.assertListEqual( expected, list(self.specification.apply(self.context)), )
def __call__(self, context: CommandContext) -> Iterator[Command]: file_path = context.graph.resolve_path(self.specification.name) if not file_path: raise ValueError("Failed to find file path {}".format( self.specification.name)) media_file_path = context.config.media_path(file_path) yield mkdir(os.path.dirname(media_file_path)) if self.specification.size: yield Command([ "fallocate", "--length", self.specification.size, quote_argument(media_file_path), ]) else: yield Command(["touch", quote_argument(media_file_path)]) if self.specification.owner or self.specification.group: yield chown( self.specification.owner, self.specification.group, media_file_path, ) if self.specification.mode: yield chmod(self.specification.mode, media_file_path)
def test_run(self, make_mode, make_action): spec1 = TestSpecification("spec1", [Command(["1"]), Command(["2"])]) spec2 = TestSpecification("spec2", [Command(["3"]), Command(["4"])]) config = Configuration( shell="", dd_bs="", random_device="", media_dir="", tmp_dir="", ) graph = Graph([spec1, spec2]) mode = MagicMock() action = MagicMock() make_mode.return_value = mode make_action.return_value = action run(config, graph, "action", "mode") action.assert_called_once_with(mode, AnyIter([spec1, spec2])) make_action.assert_called_once_with("action", AnyType()) make_mode.assert_called_once_with("mode")
def test_apply_commands(self): crypttab_lines = "\\n".join([ "", "# name (originally device)", "name\\tdevice\\t/keyfile\\topt,ions", ]) expected = [ Command([ "cryptsetup", "--batch-mode", "--key-file=/keyfile", "open", "device", "name", "--type=type", ]), Command([ "shell", "-c", "'echo -e \"{}\" >> tmp_dir/etc/crypttab'".format( crypttab_lines), ]), ] self.assertListEqual( expected, list(self.specification.apply(self.context)), )
def test_apply_commands(self): fstab_lines = "\\n".join([ "", "# name (originally device)", "device\\tmountpoint\\ttype\\topt,ions\\t1\\t2", ]) expected = [ Command([ "mount", "--types", "type", "-o", "opt,ions", "device", "media_dir/mountpoint", ]), Command([ "shell", "-c", "'echo -e \"{}\" >> tmp_dir/etc/fstab'".format(fstab_lines), ]), ] self.assertListEqual( expected, list(self.specification.apply(self.context)), )
def _format_crypt( context: CommandContext, device: str, keyfile: str, type: str, password: Optional[str], ) -> Iterator[Command]: yield Command( _cryptsetup( f"--key-file={quote_argument(keyfile)}", "luksFormat", f"--type={type}", quote_argument(device), )) if password: add_key_cmd = " ".join( _cryptsetup( f"--key-file={quote_argument(keyfile)}", "luksAddKey", quote_argument(device), )) yield Command([ quote_argument(context.config.shell), "-c", quote_subcommand(f"echo {password} | {add_key_cmd}"), ])
def _randomize_device( name: str, device: str, context: CommandContext, ) -> Iterator[Command]: cryptname = f"randomize_{name}" yield Command( _open_crypt( cryptname, device, context.config.random_device, "plain", )) dd_cmd = " ".join( _dd( "if=/dev/zero", f"of={quote_argument(_crypt_device(cryptname))}", f"bs={context.config.dd_bs}", )) yield Command( [context.config.shell, "-c", quote_subcommand(f"{dd_cmd} || true")]) yield Command(["sync"]) yield Command(_close_crypt(cryptname))
def test_apply_commands(self): expected = [ Command(["mkdir", "--parents", "media_dir/name"]), Command(["chown", "owner:group", "media_dir/name"]), Command(["chmod", "mode", "media_dir/name"]), ] self.assertListEqual( expected, list(self.specification.apply(self.context)), )
def __call__(self, context: CommandContext) -> Iterator[Command]: yield mkdir(context.config.tmp_path("/etc")) tmp_fstab_path = context.config.tmp_path("/etc/fstab") yield Command(["truncate", "--size=0", tmp_fstab_path]) yield chmod("0644", tmp_fstab_path) yield chown("root", "root", tmp_fstab_path) tmp_crypttab_path = context.config.tmp_path("/etc/crypttab") yield Command(["truncate", "--size=0", tmp_crypttab_path]) yield chmod("0644", tmp_crypttab_path) yield chown("root", "root", tmp_crypttab_path)
def __call__(self, context: CommandContext) -> Iterator[Command]: device_path = context.graph.resolve_device(self.specification.device) if not device_path: raise ValueError("Failed to find device path {}".format( self.specification.device)) yield Command(["pvcreate", quote_argument(device_path)])
def __call__(self, context: CommandContext) -> Iterator[Command]: lvm_physical_volume_paths = [ _lvm_physical_volume_path(lvm_physical_volume, context) for lvm_physical_volume in self.specification.lvm_physical_volumes ] cmd = [ "lvcreate", f"--name={self.specification.name}", ] if self.specification.size: cmd.append(f"--size={self.specification.size}") if self.specification.extents: cmd.append(f"--extents={self.specification.extents}") if self.specification.type: cmd.append(f"--type={self.specification.type}") if self.specification.lvm_poolmetadata_volume: cmd.append( f"--poolmetadata={self.specification.lvm_poolmetadata_volume}", ) if self.specification.lvm_cachepool_volume: cmd.append(f"--cachepool={self.specification.lvm_cachepool_volume}") if self.specification.lvm_thinpool_volume: cmd.append(f"--thinpool={self.specification.lvm_thinpool_volume}") cmd += self.specification.args cmd.append(self.specification.lvm_volume_group) cmd += [quote_argument(path) for path in lvm_physical_volume_paths] yield Command(cmd)
def test_apply_commands(self): expected = [ Command([ "parted", "--script", "--", "partition_table", "mkpart", "type", "start", "end", "name", "1", "label", "unit", "unit", "set", "1", "flags", "on", ]), ] self.assertListEqual( expected, list(self.specification.apply(self.context)), )
def test_up_commands(self): expected = [ Command(["mdadm", "--assemble", "/dev/md/name", "device"]), ] self.assertListEqual( expected, list(self.specification.up(self.context)), )
def test_apply_commands(self): expected = [ Command(["vgcreate", "name", "lvm_physical_volume"]), ] self.assertListEqual( expected, list(self.specification.apply(self.context)), )
def test_apply_commands(self): expected = [ Command(["parted", "--script", "--", "device", "mklabel", "type"]), ] self.assertListEqual( expected, list(self.specification.apply(self.context)), )
def test_down_commands(self): expected = [ Command(["umount", "media_dir/mountpoint"]), ] self.assertListEqual( expected, list(self.specification.down(self.context)), )
def test_up_commands(self): handler = MagicMock() UpAction(self.context)(handler, self.generators) handler.on_begin.assert_called_once_with(self.context) handler.on_generator.assert_has_calls([ call(self.context, TestActionCommandGenerator("gen_1")), call(self.context, TestActionCommandGenerator("gen_2")), ]) handler.on_command.assert_has_calls([ call(self.context, Command(["up_1"])), call(self.context, Command(["up_2"])), call(self.context, Command(["up_3"])), call(self.context, Command(["up_4"])), ]) handler.on_end.assert_called_once_with(self.context)
def test_down_commands(self): expected = [ Command(["losetup", "--detach", '"$loop_device_name"']), ] self.assertListEqual( expected, list(self.specification.down(self.context)), )
def test_apply_commands(self): expected = [ Command(["mkfs", "--type", "type", "opt", "ions", "device"]), ] self.assertListEqual( expected, list(self.specification.apply(self.context)), )
def test_apply_commands(self): expected = [ Command(["pvcreate", "device"]), ] self.assertListEqual( expected, list(self.specification.apply(self.context)), )
def test_down_commands(self): expected = [ Command(["vgchange", "--activate", "n", "name"]), ] self.assertListEqual( expected, list(self.specification.down(self.context)), )
def test_down_commands(self): expected = [ Command(["swapoff", "device"]), ] self.assertListEqual( expected, list(self.specification.down(self.context)), )
def test_down_commands(self): expected = [ Command(["mdadm", "--stop", "/dev/md/name"]), ] self.assertListEqual( expected, list(self.specification.down(self.context)), )
def __call__(self, context: CommandContext) -> Iterator[Command]: lvm_physical_volume_paths = [ _lvm_physical_volume_path(lvm_physical_volume, context) for lvm_physical_volume in self.specification.lvm_physical_volumes ] yield Command( ["vgcreate", self.specification.name] + [quote_argument(path) for path in lvm_physical_volume_paths])
def __call__(self, context: CommandContext) -> Iterator[Command]: file_path = _file_path(self.specification.file, context) media_file_path = context.config.media_path(file_path) cmd = [ context.config.shell, "-c", quote_subcommand(_find_loop_device(media_file_path)), ] yield Command(cmd, capture=self.specification.capture)
def test_up_commands(self): expected = [ Command( cmd=["losetup", "args", "--find", "--show", "media_dir/file"], capture="loop_device_name", ), ] self.assertListEqual( expected, list(self.specification.up(self.context)), )
def test_post_apply_commands(self): expected = [ Command(["mkdir", "--parents", "media_dir/etc"]), Command([ "cp", "tmp_dir/etc/fstab", "media_dir/etc/fstab", "--preserve=mode,ownership", ]), Command([ "cp", "tmp_dir/etc/crypttab", "media_dir/etc/crypttab", "--preserve=mode,ownership", ]), ] self.assertListEqual( expected, list(self.specification.post_apply(self.context)), )
def __call__(self, context: CommandContext) -> Iterator[Command]: _, media_device_path = _device_path(self.specification.device, context) type = (self.specification.type if self.specification.ephemeral_keyfile() else None) yield Command( _open_crypt( self.specification.name, media_device_path, self.specification.tmp_keyfile_path(context), type, ))
def __call__(self, context: CommandContext) -> Iterator[Command]: file_path = _file_path(self.specification.file, context) media_file_path = context.config.media_path(file_path) cmd = [ "losetup", *self.specification.args, "--find", "--show", quote_argument(media_file_path), ] yield Command(cmd, capture=self.specification.capture)
def _create_keyfile( keyfile: str, keysize: str, context: CommandContext, ) -> Iterator[Command]: yield mkdir(os.path.dirname(keyfile)) yield Command( _dd( f"if={quote_argument(context.config.random_device)}", f"of={quote_argument(keyfile)}", f"bs={keysize}", "count=1", ))