ssh_execute_group
Execute commands simultaneously on multiple servers via SSH. Choose parallel, sequential, or rolling execution strategies with configurable error handling and working directories.
Instructions
Execute command on a group of servers
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| group | Yes | Group name (e.g., "production", "staging", "all") | |
| command | Yes | Command to execute | |
| strategy | No | Execution strategy | |
| delay | No | Delay between servers in ms (for rolling) | |
| stopOnError | No | Stop execution on first error | |
| cwd | No | Working directory |
Implementation Reference
- src/tool-registry.js:57-72 (registration)The tool 'ssh_execute_group' is listed in the TOOL_GROUPS.advanced array, indicating its categorization and registration point for conditional enabling.advanced: [ 'ssh_deploy', 'ssh_execute_sudo', 'ssh_alias', 'ssh_command_alias', 'ssh_hooks', 'ssh_profile', 'ssh_connection_status', 'ssh_tunnel_create', 'ssh_tunnel_list', 'ssh_tunnel_close', 'ssh_key_manage', 'ssh_execute_group', 'ssh_group_manage', 'ssh_history' ]
- src/server-groups.js:18-22 (schema)Defines the execution strategies used by the group execution tool: parallel, sequential, and rolling.export const EXECUTION_STRATEGIES = { PARALLEL: 'parallel', // Execute on all servers at once SEQUENTIAL: 'sequential', // Execute one by one ROLLING: 'rolling' // Execute with delay between servers };
- src/server-groups.js:311-394 (helper)Core helper function that executes the provided executor function across all servers in a specified group, supporting multiple strategies, delays, error handling, and comprehensive result reporting. This is the primary logic for ssh_execute_group tool.async executeOnGroup(groupName, executor, options = {}) { const group = this.getGroup(groupName); const results = []; const strategy = options.strategy || group.strategy || EXECUTION_STRATEGIES.PARALLEL; const delay = options.delay || group.delay || 0; const stopOnError = options.stopOnError !== undefined ? options.stopOnError : group.stopOnError; logger.info('Executing on server group', { group: groupName, servers: group.servers.length, strategy, delay }); switch (strategy) { case EXECUTION_STRATEGIES.PARALLEL: { // Execute on all servers simultaneously const promises = group.servers.map(async (server) => { try { const result = await executor(server); return { server, success: true, result }; } catch (error) { logger.error(`Execution failed on ${server}`, { error: error.message }); return { server, success: false, error: error.message }; } }); const parallelResults = await Promise.all(promises); results.push(...parallelResults); break; } case EXECUTION_STRATEGIES.SEQUENTIAL: case EXECUTION_STRATEGIES.ROLLING: // Execute one by one for (const server of group.servers) { try { const result = await executor(server); results.push({ server, success: true, result }); // Add delay for rolling strategy if (strategy === EXECUTION_STRATEGIES.ROLLING && delay > 0) { logger.debug(`Waiting ${delay}ms before next server`); await new Promise(resolve => setTimeout(resolve, delay)); } } catch (error) { logger.error(`Execution failed on ${server}`, { error: error.message }); results.push({ server, success: false, error: error.message }); // Stop on error if configured if (stopOnError) { logger.warn('Stopping execution due to error', { server }); break; } } } break; default: throw new Error(`Unknown execution strategy: ${strategy}`); } // Summary const successful = results.filter(r => r.success).length; const failed = results.filter(r => !r.success).length; logger.info('Group execution completed', { group: groupName, successful, failed, total: results.length }); return { group: groupName, strategy, results, summary: { total: results.length, successful, failed } }; }
- src/server-groups.js:408-408 (helper)Convenience export for executeOnGroup function, allowing direct usage from other modules including potential tool handlers.export const executeOnGroup = (name, executor, options) => serverGroups.executeOnGroup(name, executor, options);