fmartingr
/
jeeves
Archived
1
0
Fork 0
This repository has been archived on 2021-02-14. You can view files and clone it, but cannot push or open issues or pull requests.
jeeves/jeeves/core/actions/shell.py

70 lines
2.0 KiB
Python

import os
import tempfile
import subprocess
from typing import Text
import pydantic
from jeeves.core.objects import Result
from .base import Action
class ScriptAction(Action):
"""
Executes the provided script direcly on the system.
The script is written into a temporary file that is then executed.
If no shebang is provided, a default of ``#!/bin/bash -e`` will be used, if
the provided shebang interpreter is not found on the system the action will fail.
.. automethod:: _get_script
"""
DEFAULT_SHEBANG = "#!/bin/bash"
id = "contrib/script"
verbose_name = "Execute script"
class Parameters(pydantic.BaseModel):
"""
+----------------+------+-----------+---------------------------+
| Parameter name | Type | Mandatory | Description |
+================+======+===========+===========================+
| ``script`` | text | yes | The script to be executed |
+----------------+------+-----------+---------------------------+
"""
script: Text
def _get_script(self):
"""
Returns the script defined in the parameters, checking for a shebang.
If no shebang is defined, :any:`ScriptAction.DEFAULT_SHEBANG` with be used.
"""
if not self.parameters.script.startswith("#!"):
return f"{self.DEFAULT_SHEBANG}{os.linesep}{self.parameters.script}"
return self.parameters.script
def execute(self):
script = self._get_script()
# Write the script to a temporary file
script_file = tempfile.NamedTemporaryFile(mode="w", delete=False)
with script_file as handler:
handler.write(script)
# Read/Execute only for owner
os.chmod(script_file.name, mode=0o500)
process = subprocess.run(
script_file.name, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
)
os.unlink(script_file.name)
return Result(
success=process.returncode == 0, output=process.stdout.decode("utf-8")
)