Skip to content

Run Action

The run action actions allows to either run a script or a command. The corresponding code is automatically appended to <profile>.postinst. This script or command is executed by root by default. However, it's also possible to have another user execute the command. The script may contain jinja variables, that are substituted using provided substition variables.

Info

It's not possible to combine a script and command in one single run action. In other words, the command and script keywords are mutually exclusive.

Usage

Click on the to learn more about the action's options.

Run Action (command)
{% set username=username or "user" -%}

actions:
  - action: run
    description: Add {{username}} to sudoers #(1)!
    variables: #(2)!
      username: {{username}}
    script: scripts/add_sudoer.sh  #(3)!
  1. [Optional] Description, for documentation purposes
  2. [Optional] Substition variables
  3. [Required] Relative link to the script file. Mutually exclusive with the command keyword.
Run Action (script)
  - action: run
    description: Make sure debian UEFI file is registered as boot entry #(1)!
    user: {{username}} # (2)!
    command: | # (3)!
      grub-install --efi-directory /boot/efi --force-extra-removable --recheck
      && update-grub
  1. [Optional] Description, for documentation purposes
  2. [Optional] User that executes the command. If omitted, the command is executed by root.
  3. [Required] The command to be executed. Mutually exclusive with the script keyword.

Implementation

RunAction

Bases: Action

Run action

Source code in simple_cdd_yaml/actions.py
class RunAction(Action):
    """ Run action """
    action_out = 'postinst'

    def script(self, props):
        """ Shell commands to run a script """
        description = props.get('description', 'Run script')
        script = self._read_substitute(props['script'],
                                       props.get('variables', {}))
        script = re.sub(r'#!/bin/.*?sh\n', '', script)
        return f'\n# {description}\n{script}\n'

    def command(self, props):
        """ Shell code to run a command """
        description = props.get('description', 'Run command')
        template = jinja2.Template(props['command'])
        command = template.render(props.get('variables', {}))
        if user:= props.get('user'):
            command = f"su - {user} << 'EOF'\n{command}\nEOF"
        return f'\n# {description}\n{command}\n'

    def create_run_script(self, props):
        """ Create script from run action """
        if all(x in props for x in ['script', 'command']):
            raise ActionError('Too many keywords: script and command found!')
        if 'script' in props:
            return self.script(props)
        if 'command' in props:
            return self.command(props)
        raise ActionError('Missing script or command keyword!')

    def perform_action(self, props):
        return self.create_run_script(props)

    def perform_debos_action(self, props):
        if 'postprocess' in props:
            self.append_result(props)
            return
        script_str = '#!/bin/sh' + self.create_run_script(props)
        filename = self.unique_filename(description=props.get('description'))
        output_file = self.debos_output_dir / 'scripts' / filename
        with open(output_file, mode='w', encoding='utf-8') as file:
            file.write(script_str)
        debos_action = dict(SCRIPT_TEMPLATE_DICT,
            description=props.get('description', 'Script'),
            script='scripts/'+filename,
        )
        self.append_result(debos_action)