|
10 | 10 |
|
11 | 11 | from automax.core.models import ExecutionContext, PluginResult |
12 | 12 | from automax.plugins.base import BasePlugin, PluginValidationError |
13 | | -from automax.plugins.remote_utils import CHANGE_MARKER, exec_remote, quote, result_from_remote |
| 13 | +from automax.plugins.remote_utils import CHANGE_MARKER, exec_remote, heredoc_to_file, normalize_env_mapping, quote, render_env_prefix, result_from_remote |
14 | 14 |
|
15 | 15 |
|
16 | 16 | def _sudo(params: Dict[str, Any], default: bool = True) -> str: |
@@ -42,7 +42,7 @@ def _mapping(params: Dict[str, Any], key: str) -> dict[str, str]: |
42 | 42 | raw = params.get(key, {}) or {} |
43 | 43 | if not isinstance(raw, dict) or not raw: |
44 | 44 | raise PluginValidationError(f"{key} must be a non-empty mapping") |
45 | | - return {str(name): str(value) for name, value in raw.items()} |
| 45 | + return normalize_env_mapping(raw) |
46 | 46 |
|
47 | 47 |
|
48 | 48 | class SwapPresentPlugin(BasePlugin): |
@@ -153,7 +153,7 @@ def manual_commands(self, params: Dict[str, Any], context: ExecutionContext) -> |
153 | 153 | path = f"/etc/security/limits.d/{params['name']}.conf" |
154 | 154 | sudo = _sudo(params) |
155 | 155 | temp = "/tmp/automax-limits.$$" |
156 | | - commands = [f"cat > {temp} <<'EOF'\n{content}EOF"] |
| 156 | + commands = [heredoc_to_file(temp, content)] |
157 | 157 | if bool(params.get("backup", True)): |
158 | 158 | commands.append(f"test ! -e {quote(path)} || {sudo}cp -p {quote(path)} {quote(path + str(params.get('backup_suffix', '.bak')))}") |
159 | 159 | commands.append(f"{sudo}install -m 0644 {temp} {quote(path)}") |
@@ -390,7 +390,7 @@ def manual_commands(self, params: Dict[str, Any], context: ExecutionContext) -> |
390 | 390 | path = self._path_for_backend(params) |
391 | 391 | content = self._resolved_content(params) if backend == "systemd-resolved" else self._content(params) |
392 | 392 | temp = "/tmp/automax-resolver.$$" |
393 | | - commands = [f"cat > {temp} <<'EOF'\n{content}EOF"] |
| 393 | + commands = [heredoc_to_file(temp, content)] |
394 | 394 | if backend == "plain-file" and not bool(params.get("force", False)): |
395 | 395 | commands.append("if [ -L /etc/resolv.conf ]; then echo 'refusing to manage symlinked /etc/resolv.conf with backend=plain-file' >&2; exit 1; fi") |
396 | 396 | if bool(params.get("backup", True)): |
@@ -432,7 +432,7 @@ def manual_commands(self, params: Dict[str, Any], context: ExecutionContext) -> |
432 | 432 | path = str(params.get("path", "/etc/chrony.d/99-automax.conf")) |
433 | 433 | sudo = _sudo(params) |
434 | 434 | temp = "/tmp/automax-chrony.$$" |
435 | | - commands = [f"cat > {temp} <<'EOF'\n{content}EOF"] |
| 435 | + commands = [heredoc_to_file(temp, content)] |
436 | 436 | if bool(params.get("backup", True)): |
437 | 437 | commands.append(f"test ! -e {quote(path)} || {sudo}cp -p {quote(path)} {quote(path + str(params.get('backup_suffix', '.bak')))}") |
438 | 438 | commands.append(f"{sudo}install -m 0644 {temp} {quote(path)}") |
@@ -507,13 +507,12 @@ def manual_commands(self, params: Dict[str, Any], context: ExecutionContext) -> |
507 | 507 | variables = _mapping(params, "variables") |
508 | 508 | scope = str(params.get("scope", "step")) |
509 | 509 | if scope == "step": |
510 | | - exports = " ".join(f"{name}={quote(value)}" for name, value in sorted(variables.items())) |
511 | | - return [f"export {exports}"] |
| 510 | + return [f"export {render_env_prefix(variables)}"] |
512 | 511 | content = self._content(params) |
513 | 512 | path = self._path(params) |
514 | 513 | sudo = _sudo(params, default=scope == "global") |
515 | 514 | temp = "/tmp/automax-env.$$" |
516 | | - commands = [f"cat > {temp} <<'EOF'\n{content}EOF"] |
| 515 | + commands = [heredoc_to_file(temp, content)] |
517 | 516 | if bool(params.get("backup", True)): |
518 | 517 | commands.append(f"test ! -e {quote(path)} || {sudo}cp -p {quote(path)} {quote(path + str(params.get('backup_suffix', '.bak')))}") |
519 | 518 | commands.append(f"{sudo}install -m 0644 {temp} {quote(path)}") |
|
0 commit comments