From: Iker Pedrosa Date: Mon, 8 Sep 2025 14:49:56 +0000 (+0200) Subject: tests/system/framework/roles/shadow.py: implement binding for `chpasswd` X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=b9a9ea62b9742f807707d44701e75c2bd9d1e44c;p=thirdparty%2Fshadow.git tests/system/framework/roles/shadow.py: implement binding for `chpasswd` Signed-off-by: Iker Pedrosa --- diff --git a/tests/system/framework/roles/shadow.py b/tests/system/framework/roles/shadow.py index 4f9d3bf2f..d267feb4e 100644 --- a/tests/system/framework/roles/shadow.py +++ b/tests/system/framework/roles/shadow.py @@ -413,3 +413,24 @@ class Shadow(BaseLinuxRole[ShadowHost]): return self._passwd_as_root(*args, new_password=new_password) else: return self._passwd_as_user(*args, run_as=run_as, old_password=old_password, new_password=new_password) + + def chpasswd(self, *args, passwords_data: str | None = None, file: str | None = None) -> ProcessResult: + """ + Update passwords in batch. + + Updates user passwords in batch by reading username:password pairs. + If `passwords_data` is provided, this data is used to simulate an interactive prompt. + Otherwise, the command reads from a file specified in `file`. + """ + cmd_args = " ".join(args) + + if passwords_data: + self.logger.info(f"Running chpasswd interactively on {self.host.hostname}") + cmd = self.host.conn.run(f"echo '{passwords_data}' | chpasswd {cmd_args}", log_level=ProcessLogLevel.Error) + else: + self.logger.info(f"Running chpasswd from file on {self.host.hostname}") + cmd = self.host.conn.run(f"chpasswd {cmd_args} < {file}", log_level=ProcessLogLevel.Error) + + self.host.discard_file("/etc/shadow") + + return cmd