Skip to content

Commit

Permalink
Fix action plugin
Browse files Browse the repository at this point in the history
Co-authored: Alexandre Domont
  • Loading branch information
laurentdavid committed Jan 29, 2025
1 parent e107ac8 commit 88fbe4f
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 81 deletions.
121 changes: 54 additions & 67 deletions action_plugins/check_moodle.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,79 +7,66 @@
from ansible.errors import AnsibleError
from ansible.plugins.action import ActionBase

TOOL_FILENAME = 'moodletool.php'


class ActionModule(ActionBase):

def run(self, tmp=None, task_vars=None):
# Get the install_dir parameter
install_dir = self._task.args.get('install_dir')
if not install_dir:
return {'failed': True, 'msg': "The 'install_dir' parameter is required."}
"""Handles transferring and executing the tool directly."""
if task_vars is None:
task_vars = {}

# Check first if there is a config.php file in the install_dir
config_file = f"{install_dir}/config.php"
# Check if the file exists on the remote host
stat_result = self._execute_module(
module_name='stat',
module_args={'path': config_file},
task_vars=task_vars or {}
)
# If the file doesn't exist, return a failure message
if not stat_result.get('stat', {}).get('exists', False):
return {
'changed': False,
'moodle_is_installed': False,
'moodle_needs_upgrading': False,
'msg': f"Could not find the config.php file at {config_file} on the remote host."
}
self.TRANSFERS_FILES = True # Ensure temp folder is created
super().run(tmp, task_vars)

is_installed = False
needs_upgrading = False
# Command to run the Moodle CLI config script
command = f"php {install_dir}/admin/cli/upgrade.php --is-pending"
# Run the command on the remote host
rc, stdout, stderr = self._connection.exec_command(command)
remote_tmp = self._connection._shell.tmpdir
remote_path = os.path.join(remote_tmp, TOOL_FILENAME)

# Check for command failure
if rc == 2:
needs_upgrading = True
if rc == 1 and "Config table does not contain the version" in stderr.decode('utf-8'):
return {
'changed': False,
'moodle_is_installed': is_installed,
'moodle_needs_upgrading': needs_upgrading,
'msg': "Moodle is not installed"
}
is_installed = True
# Command to run the Moodle CLI config script
command = f"php {install_dir}/admin/cli/cfg.php --json"
action_plugin_dir = os.path.dirname(__file__)
tool_path = os.path.join(action_plugin_dir, TOOL_FILENAME)

# Run the command on the remote host
rc, stdout, stderr = self._connection.exec_command(command)
install_dir = self._task.args.get('install_dir', '')
if os.path.isfile(tool_path):
# Upload tool to remote machine
self._transfer_file(tool_path, remote_path)

# Check for command failure
if rc != 0:
return {
'failed': True,
'msg': f"Command failed with error: {stderr.strip()}",
'rc': rc
}
# Fix permissions
self._fixup_perms2([remote_path, remote_tmp])

# Run the PHP script directly
# Run the PHP script directly with install_dir argument
result = self._low_level_execute_command(
f"php {remote_path} {install_dir}",
sudoable=True)

# Cleanup the tool after execution
self._low_level_execute_command(f"rm -f {remote_path}")
self.cleanup(True)

# Attempt to parse the JSON output
try:
parsed_output = json.loads(stdout.strip())
except json.JSONDecodeError as e:
return {
'failed': True,
'msg': f"Failed to parse JSON output: {str(e)}",
'raw_output': stdout.strip()
# Return the result from execution
# Try to parse the output as JSON
moodle_output = result.get('stdout', '').strip()
return_value = {
"changed": False,
"failed": False,
}
current_version = parsed_output.get('version')
current_release = parsed_output.get('release')
# Return the parsed JSON output
return {
'changed': False,
'config': parsed_output,
'moodle_is_installed': is_installed,
'moodle_needs_upgrading': needs_upgrading,
'current_version': current_version,
'current_release': current_release,
}
try:
parsed_output = json.loads(moodle_output)
if parsed_output.get('failed'):
return_value.update({
"failed": True,
"msg": parsed_output.get('msg')
})
else:
return_value.update(parsed_output)
except json.JSONDecodeError:
return_value.update({
"failed": True,
"msg": "Failed to parse the output from the Moodle tool: " + moodle_output
})
return return_value
else:
raise AnsibleError(
f"Failed to find the tool ({TOOL_FILENAME}) at path ({tool_path})"
)
51 changes: 51 additions & 0 deletions action_plugins/moodletool.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
define('CLI_SCRIPT', true);

try {
$returnvalue = [];

if (empty($_SERVER['argv'])) {
die('This script is intended to be run from the command line');
}
$rawoptions = $_SERVER['argv'];
$cfgpath = './';
if ($_SERVER['argc'] >= 2) {
$cfgpath = $rawoptions[1];
}

// Check for config.php
if (file_exists($cfgpath . '/config.php')) {
require($cfgpath . '/config.php');
} else {
$returnvalue = [
'failed' => true,
'msg' => 'Config file not found',
'moodle_is_installed' => false,
];
echo json_encode($returnvalue);
exit(0);
}
require_once($CFG->libdir . '/clilib.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/upgradelib.php');

$moodleneedsupgrade = moodle_needs_upgrading();

$returnvalue = [
'failed' => false,
'moodle_is_installed' => true,
'moodle_needs_upgrading' => $moodleneedsupgrade,
'current_version' => $CFG->version,
'current_release' => $CFG->release,
];

echo json_encode($returnvalue);
} catch (Exception $e) {
$returnvalue = [
'failed' => true,
'msg' => $e->getMessage(),
'moodle_is_installed' => false,
];
echo json_encode($returnvalue);
}
exit(0);
1 change: 1 addition & 0 deletions molecule-requirements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
- src: geerlingguy.php-pgsql
- src: geerlingguy.php-mysql
- src: geerlingguy.git
- src: geerlingguy.repo-remi
52 changes: 38 additions & 14 deletions tasks/setup-moodle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,53 @@
owner: "{{ moodle_webserver_user }}"
group: "{{ moodle_webserver_group }}"

# This is using our custom module to check moodle state
- name: Check the state of current moodle
check_moodle:
install_dir: "{{ moodle_src_path }}"
become: true
become_user: "{{ moodle_webserver_user }}"
register: moodle_state
- name: Check Moodle status
block:
- name: Run Moodle status check
check_moodle:
install_dir: "{{ moodle_src_path }}"
become: true
become_user: "{{ moodle_webserver_user }}"
register: moodle_state
failed_when: moodle_state.failed | default(false)

- name: Show Moodle status
debug:
msg: >
Moodle Status:
Installed: {{ moodle_state.moodle_is_installed | default('Unknown') }}
Needs Upgrading: {{ moodle_state.moodle_needs_upgrading | default('Unknown') }}
Version: {{ moodle_state.current_version | default('N/A') }}
Release: {{ moodle_state.current_release | default('N/A') }}
rescue:
- name: Handle failures in Moodle status check
debug:
msg: >
An unexpected error occurred during the Moodle status check.
Please investigate further.
CLI Output: {{ moodle_state.msg | default('N/A') }}
CLI Error Output: {{ moodle_state.msg | default('N/A') }}
- set_fact:
moodle_check_failed: true
always:
- name: Finalize Moodle status check
debug:
msg: "Moodle status check completed."

- name: Install Moodle
include_tasks: commands/moodle-install.yml
when: not moodle_state.moodle_is_installed|bool
when: not (moodle_state.moodle_is_installed | default(false) | bool) and not (moodle_check_failed | default(false) | bool)

# Change password to make sure we are always in sync
# Watch out this will work on Moodle where the reset_password.php command accepts arguments
# Added the cache purge as sometimes old users are cached when db is replaced
- name: Change admin password
import_tasks: commands/moodle-resetpw.yml
when: moodle_state.moodle_is_installed|bool
when: moodle_state.moodle_is_installed | default(false) | bool and not (moodle_check_failed | default(false) | bool)

- name: Launch update (if needed)
import_tasks: commands/moodle-update.yml
when: moodle_state.moodle_is_installed|bool
and moodle_state.moodle_needs_upgrading|bool
when:
- moodle_state.moodle_is_installed | default(false) | bool
- moodle_state.moodle_needs_upgrading | default(false) | bool
- not (moodle_check_failed | default(false) | bool)

- name: Ensure cron is installed (Ubuntu 24.04 or later only)
apt:
Expand Down

0 comments on commit 88fbe4f

Please sign in to comment.