Spaces:
Sleeping
Sleeping
| """ | |
| Linux Administration Server using Gradio interface. | |
| Provides both a web interface and functions that can be called by clients. | |
| """ | |
| import gradio as gr | |
| import os | |
| import sys | |
| import json | |
| import subprocess | |
| import logging | |
| from pathlib import Path | |
| from typing import List, Optional | |
| # Set up logging | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| # Simple configuration (inline to avoid import issues) | |
| SAFE_COMMANDS = ["ls", "df", "ps", "whoami", "pwd", "date", "uptime", "free", "cat", "head", "tail"] | |
| COMMAND_TIMEOUT = 30 | |
| # Mock functions for HF Spaces (since real Linux commands won't work) | |
| def run_safe_command(command: str, args: Optional[List[str]] = None, | |
| working_directory: Optional[str] = None) -> dict: | |
| """ | |
| Execute safe, whitelisted system commands. | |
| NOTE: In HF Spaces, this will be simulated since container restrictions apply. | |
| """ | |
| if command not in SAFE_COMMANDS: | |
| return { | |
| "success": False, | |
| "error": f"Command '{command}' not in whitelist", | |
| "whitelist": SAFE_COMMANDS, | |
| "tool_type": "safe_command" | |
| } | |
| # Simulate command output for HF Spaces | |
| try: | |
| if command == "ls": | |
| # Try real command first, fallback to simulation | |
| try: | |
| result = subprocess.run([command] + (args or []), | |
| capture_output=True, text=True, timeout=5) | |
| if result.returncode == 0: | |
| return { | |
| "success": True, | |
| "output": result.stdout, | |
| "command": f"{command} {' '.join(args or [])}", | |
| "tool_type": "safe_command" | |
| } | |
| except: | |
| pass | |
| # Fallback simulation | |
| return { | |
| "success": True, | |
| "output": "app.py\nrequirements.txt\nshared/\ntools/\nREADME.md", | |
| "command": f"{command} {' '.join(args or [])}", | |
| "tool_type": "safe_command", | |
| "simulated": True | |
| } | |
| elif command == "df": | |
| return { | |
| "success": True, | |
| "output": "Filesystem Size Used Avail Use% Mounted on\n/dev/sda1 20G 8.5G 10G 46% /\ntmpfs 2.0G 0 2.0G 0% /dev/shm", | |
| "command": f"{command} {' '.join(args or [])}", | |
| "tool_type": "safe_command", | |
| "simulated": True | |
| } | |
| elif command == "ps": | |
| return { | |
| "success": True, | |
| "output": "PID TTY TIME CMD\n1234 pts/0 00:00:01 python\n5678 pts/0 00:00:00 gradio", | |
| "command": f"{command} {' '.join(args or [])}", | |
| "tool_type": "safe_command", | |
| "simulated": True | |
| } | |
| elif command == "whoami": | |
| return { | |
| "success": True, | |
| "output": "user", | |
| "command": command, | |
| "tool_type": "safe_command", | |
| "simulated": True | |
| } | |
| elif command == "pwd": | |
| return { | |
| "success": True, | |
| "output": "/home/user/app", | |
| "command": command, | |
| "tool_type": "safe_command", | |
| "simulated": True | |
| } | |
| elif command == "uptime": | |
| return { | |
| "success": True, | |
| "output": "10:35:42 up 2 days, 14:23, 1 user, load average: 0.15, 0.10, 0.05", | |
| "command": command, | |
| "tool_type": "safe_command", | |
| "simulated": True | |
| } | |
| else: | |
| return { | |
| "success": True, | |
| "output": f"Command '{command}' executed successfully (simulated in HF Spaces)", | |
| "command": f"{command} {' '.join(args or [])}", | |
| "tool_type": "safe_command", | |
| "simulated": True | |
| } | |
| except Exception as e: | |
| return { | |
| "success": False, | |
| "error": f"Execution error: {str(e)}", | |
| "tool_type": "safe_command" | |
| } | |
| def add_user(username: str, groups: Optional[List[str]] = None, | |
| create_home: bool = True, shell: str = "/bin/bash") -> dict: | |
| """ | |
| Simulate user addition (real commands won't work in HF Spaces). | |
| """ | |
| if not username or len(username) < 2: | |
| return { | |
| "success": False, | |
| "error": "Username must be at least 2 characters", | |
| "tool_type": "sensitive_operation" | |
| } | |
| return { | |
| "success": True, | |
| "message": f"User '{username}' would be created successfully", | |
| "details": { | |
| "username": username, | |
| "groups": groups or [], | |
| "home_created": create_home, | |
| "shell": shell | |
| }, | |
| "tool_type": "sensitive_operation", | |
| "simulated": True, | |
| "note": "This is simulated in HF Spaces - real user creation requires system privileges" | |
| } | |
| def create_file(filepath: str, content: str, permissions: str = "644", | |
| owner: Optional[str] = None) -> dict: | |
| """ | |
| Simulate file creation (restricted in HF Spaces). | |
| """ | |
| if not filepath or not content: | |
| return { | |
| "success": False, | |
| "error": "Filepath and content are required", | |
| "tool_type": "sensitive_operation" | |
| } | |
| return { | |
| "success": True, | |
| "message": f"File '{filepath}' would be created successfully", | |
| "details": { | |
| "path": filepath, | |
| "permissions": permissions, | |
| "owner": owner, | |
| "size": len(content) | |
| }, | |
| "tool_type": "sensitive_operation", | |
| "simulated": True, | |
| "note": "File creation is restricted in HF Spaces" | |
| } | |
| def change_permission(path: str, permissions: str, recursive: bool = False, | |
| owner: Optional[str] = None) -> dict: | |
| """ | |
| Simulate permission changes (not allowed in HF Spaces). | |
| """ | |
| if not path or not permissions: | |
| return { | |
| "success": False, | |
| "error": "Path and permissions are required", | |
| "tool_type": "sensitive_operation" | |
| } | |
| return { | |
| "success": True, | |
| "message": f"Permissions for '{path}' would be changed to {permissions}", | |
| "details": { | |
| "path": path, | |
| "permissions": permissions, | |
| "recursive": recursive, | |
| "owner": owner | |
| }, | |
| "tool_type": "sensitive_operation", | |
| "simulated": True, | |
| "note": "Permission changes are restricted in HF Spaces" | |
| } | |
| def create_linux_server_interface(): | |
| """Create the Linux administration server interface.""" | |
| css = """ | |
| .gradio-container { | |
| max-width: 1200px; | |
| margin: auto; | |
| } | |
| .note-box { | |
| background-color: #fff3cd; | |
| border: 1px solid #ffeaa7; | |
| border-radius: 5px; | |
| padding: 10px; | |
| margin: 10px 0; | |
| } | |
| """ | |
| with gr.Blocks( | |
| title="Linux Administration Server", | |
| theme="soft", | |
| css=css | |
| ) as demo: | |
| gr.Markdown(""" | |
| # π§ Linux Administration Server | |
| ## β οΈ HF Spaces Demo Mode | |
| **Note**: This is running in HuggingFace Spaces, so actual system commands are simulated for security. | |
| In a real Linux environment, these tools would execute actual system operations. | |
| ## π οΈ Available Tools | |
| ### π’ Safe Operations (Read-Only) | |
| - **List Files**: Show directory contents | |
| - **Disk Space**: Check storage usage | |
| - **Processes**: View running processes | |
| - **System Info**: Uptime, current user, etc. | |
| ### π΄ Sensitive Operations (Simulated) | |
| - **User Management**: Add users (requires root privileges) | |
| - **File Operations**: Create files with permissions | |
| - **Permission Changes**: Modify file/directory access | |
| """) | |
| # Tool testing interface | |
| with gr.Tab("π§ͺ Test Tools"): | |
| with gr.Row(): | |
| with gr.Column(): | |
| tool_selector = gr.Dropdown( | |
| choices=["run_safe_command", "add_user", "create_file", "change_permission"], | |
| label="Select Tool", | |
| value="run_safe_command" | |
| ) | |
| # Safe command inputs | |
| with gr.Group(visible=True) as safe_inputs: | |
| safe_command = gr.Dropdown( | |
| choices=SAFE_COMMANDS, | |
| label="Command", | |
| value="ls" | |
| ) | |
| safe_args = gr.Textbox( | |
| label="Arguments (space-separated)", | |
| placeholder="-la" | |
| ) | |
| # User inputs | |
| with gr.Group(visible=False) as user_inputs: | |
| username = gr.Textbox(label="Username", placeholder="john") | |
| groups = gr.Textbox(label="Groups (comma-separated)", placeholder="sudo,users") | |
| create_home = gr.Checkbox(label="Create Home Directory", value=True) | |
| # File inputs | |
| with gr.Group(visible=False) as file_inputs: | |
| filepath = gr.Textbox(label="File Path", placeholder="/tmp/test.txt") | |
| content = gr.Textbox(label="File Content", lines=3, placeholder="Hello, World!") | |
| permissions = gr.Textbox(label="Permissions", value="644") | |
| test_button = gr.Button("π Execute Tool", variant="primary") | |
| with gr.Column(): | |
| test_output = gr.JSON(label="Tool Output") | |
| # Event handlers | |
| def update_inputs(tool_name): | |
| return { | |
| safe_inputs: gr.update(visible=(tool_name == "run_safe_command")), | |
| user_inputs: gr.update(visible=(tool_name == "add_user")), | |
| file_inputs: gr.update(visible=(tool_name in ["create_file", "change_permission"])) | |
| } | |
| tool_selector.change( | |
| update_inputs, | |
| inputs=[tool_selector], | |
| outputs=[safe_inputs, user_inputs, file_inputs] | |
| ) | |
| def execute_tool(tool_name, cmd, args, user, grps, home, path, cont, perms): | |
| try: | |
| logger.info(f"Executing tool: {tool_name}") | |
| if tool_name == "run_safe_command": | |
| args_list = args.split() if args else [] | |
| return run_safe_command(cmd, args_list) | |
| elif tool_name == "add_user": | |
| groups_list = [g.strip() for g in grps.split(",")] if grps else [] | |
| return add_user(user, groups_list, home) | |
| elif tool_name == "create_file": | |
| return create_file(path, cont, perms) | |
| elif tool_name == "change_permission": | |
| return change_permission(path, perms) | |
| else: | |
| return {"success": False, "error": f"Unknown tool: {tool_name}"} | |
| except Exception as e: | |
| logger.error(f"Tool execution error: {e}") | |
| return {"success": False, "error": str(e)} | |
| test_button.click( | |
| execute_tool, | |
| inputs=[ | |
| tool_selector, safe_command, safe_args, | |
| username, groups, create_home, | |
| filepath, content, permissions | |
| ], | |
| outputs=[test_output] | |
| ) | |
| # Quick Actions | |
| with gr.Tab("β‘ Quick Actions"): | |
| with gr.Row(): | |
| with gr.Column(): | |
| gr.Markdown("#### π’ Safe Operations") | |
| ls_btn = gr.Button("π List Files") | |
| df_btn = gr.Button("πΎ Disk Space") | |
| ps_btn = gr.Button("βοΈ Processes") | |
| uptime_btn = gr.Button("β° Uptime") | |
| with gr.Column(): | |
| quick_output = gr.Textbox( | |
| label="Output", | |
| lines=10, | |
| placeholder="Command output will appear here..." | |
| ) | |
| # Quick action handlers | |
| ls_btn.click(lambda: run_safe_command("ls", ["-la"]).get("output", "Error"), outputs=quick_output) | |
| df_btn.click(lambda: run_safe_command("df", ["-h"]).get("output", "Error"), outputs=quick_output) | |
| ps_btn.click(lambda: run_safe_command("ps", ["aux"]).get("output", "Error"), outputs=quick_output) | |
| uptime_btn.click(lambda: run_safe_command("uptime", []).get("output", "Error"), outputs=quick_output) | |
| # System info | |
| with gr.Tab("π System Info"): | |
| gr.Markdown(f""" | |
| ### Server Configuration | |
| - **Environment**: HuggingFace Spaces (containerized) | |
| - **Safe Commands**: {len(SAFE_COMMANDS)} available | |
| - **Command Timeout**: {COMMAND_TIMEOUT} seconds | |
| - **Security**: All operations validated and logged | |
| ### Available Commands | |
| ``` | |
| {', '.join(SAFE_COMMANDS)} | |
| ``` | |
| ### Important Notes | |
| - **Simulation Mode**: Real system commands are restricted in HF Spaces | |
| - **Security**: Container isolation prevents actual system modifications | |
| - **Demo Purpose**: Shows tool interfaces and validation logic | |
| - **Production Use**: Deploy to full Linux environment for real operations | |
| """) | |
| return demo | |
| def main(): | |
| """Main entry point""" | |
| logger.info("π Starting Linux Administration Server (HF Spaces Demo)") | |
| demo = create_linux_server_interface() | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| show_error=True | |
| ) | |
| if __name__ == "__main__": | |
| main() | |
| # Set up logging | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| def create_linux_server_interface(): | |
| """ | |
| Create the Linux administration server interface. | |
| Provides both web UI and callable functions. | |
| """ | |
| # Custom CSS for better appearance | |
| css = """ | |
| .gradio-container { | |
| max-width: 1200px; | |
| margin: auto; | |
| } | |
| """ | |
| with gr.Blocks( | |
| title=config.gradio.title, | |
| theme=config.gradio.theme, | |
| css=css | |
| ) as demo: | |
| gr.Markdown(f""" | |
| # {config.gradio.title} | |
| ## π οΈ Linux Administration Tools | |
| This server provides Linux administration capabilities with built-in security: | |
| ### π’ Safe Operations (Direct Execution) | |
| - **List Files**: Show directory contents | |
| - **Disk Space**: Check storage usage | |
| - **Processes**: View running processes | |
| - **System Info**: Uptime, users, etc. | |
| ### π΄ Sensitive Operations (Require Validation) | |
| - **User Management**: Add/modify users | |
| - **File Operations**: Create files with permissions | |
| - **Permission Changes**: Modify file/directory access | |
| ## π API Integration | |
| Connect external clients to use these tools programmatically. | |
| ## π System Status | |
| - **Available Tools**: 4 (safe + sensitive operations) | |
| - **Safe Commands**: {len(config.security.safe_commands)} whitelisted | |
| - **Security**: All operations validated and logged | |
| """) | |
| # Tool testing interface | |
| with gr.Tab("π§ͺ Test Tools"): | |
| gr.Markdown("### Test Linux Administration Tools") | |
| with gr.Row(): | |
| with gr.Column(): | |
| tool_selector = gr.Dropdown( | |
| choices=["run_safe_command", "add_user", "create_file", "change_permission"], | |
| label="Select Tool", | |
| value="run_safe_command" | |
| ) | |
| # Safe command inputs | |
| with gr.Group(visible=True) as safe_inputs: | |
| safe_command = gr.Dropdown( | |
| choices=config.security.safe_commands, | |
| label="Command", | |
| value="ls" | |
| ) | |
| safe_args = gr.Textbox( | |
| label="Arguments (space-separated)", | |
| placeholder="-la /home" | |
| ) | |
| # User inputs | |
| with gr.Group(visible=False) as user_inputs: | |
| username = gr.Textbox(label="Username", placeholder="john") | |
| groups = gr.Textbox(label="Groups (comma-separated)", placeholder="sudo,users") | |
| create_home = gr.Checkbox(label="Create Home Directory", value=True) | |
| # File inputs | |
| with gr.Group(visible=False) as file_inputs: | |
| filepath = gr.Textbox(label="File Path", placeholder="/tmp/test.txt") | |
| content = gr.Textbox(label="File Content", lines=3, placeholder="Hello, World!") | |
| permissions = gr.Textbox(label="Permissions", value="644", placeholder="644") | |
| test_button = gr.Button("π Execute Tool", variant="primary") | |
| with gr.Column(): | |
| test_output = gr.JSON(label="Tool Output") | |
| # Tool selector event handler | |
| def update_inputs(tool_name): | |
| return { | |
| safe_inputs: gr.update(visible=(tool_name == "run_safe_command")), | |
| user_inputs: gr.update(visible=(tool_name == "add_user")), | |
| file_inputs: gr.update(visible=(tool_name in ["create_file", "change_permission"])) | |
| } | |
| tool_selector.change( | |
| update_inputs, | |
| inputs=[tool_selector], | |
| outputs=[safe_inputs, user_inputs, file_inputs] | |
| ) | |
| # Test tool execution | |
| def execute_tool(tool_name, cmd, args, user, grps, home, path, cont, perms): | |
| try: | |
| logger.info(f"Executing tool: {tool_name}") | |
| if tool_name == "run_safe_command": | |
| args_list = args.split() if args else [] | |
| return run_safe_command(cmd, args_list) | |
| elif tool_name == "add_user": | |
| groups_list = [g.strip() for g in grps.split(",")] if grps else [] | |
| return add_user(user, groups_list, home) | |
| elif tool_name == "create_file": | |
| return create_file(path, cont, perms) | |
| elif tool_name == "change_permission": | |
| return change_permission(path, perms) | |
| else: | |
| return {"success": False, "error": f"Unknown tool: {tool_name}"} | |
| except Exception as e: | |
| logger.error(f"Tool execution error: {e}") | |
| return {"success": False, "error": str(e)} | |
| test_button.click( | |
| execute_tool, | |
| inputs=[ | |
| tool_selector, safe_command, safe_args, | |
| username, groups, create_home, | |
| filepath, content, permissions | |
| ], | |
| outputs=[test_output] | |
| ) | |
| # Quick Actions tab | |
| with gr.Tab("β‘ Quick Actions"): | |
| gr.Markdown("### Common Administration Tasks") | |
| with gr.Row(): | |
| with gr.Column(): | |
| gr.Markdown("#### π’ Safe Operations") | |
| ls_btn = gr.Button("π List Files", size="sm") | |
| df_btn = gr.Button("πΎ Disk Space", size="sm") | |
| ps_btn = gr.Button("βοΈ Processes", size="sm") | |
| uptime_btn = gr.Button("β° Uptime", size="sm") | |
| with gr.Column(): | |
| quick_output = gr.Textbox( | |
| label="Output", | |
| lines=10, | |
| placeholder="Command output will appear here..." | |
| ) | |
| # Quick action handlers | |
| def quick_ls(): | |
| result = run_safe_command("ls", ["-la"]) | |
| return result.get("output", result.get("error", "No output")) | |
| def quick_df(): | |
| result = run_safe_command("df", ["-h"]) | |
| return result.get("output", result.get("error", "No output")) | |
| def quick_ps(): | |
| result = run_safe_command("ps", ["aux"]) | |
| return result.get("output", result.get("error", "No output")) | |
| def quick_uptime(): | |
| result = run_safe_command("uptime", []) | |
| return result.get("output", result.get("error", "No output")) | |
| ls_btn.click(quick_ls, outputs=quick_output) | |
| df_btn.click(quick_df, outputs=quick_output) | |
| ps_btn.click(quick_ps, outputs=quick_output) | |
| uptime_btn.click(quick_uptime, outputs=quick_output) | |
| # System info tab | |
| with gr.Tab("π System Info"): | |
| gr.Markdown(f""" | |
| ### Server Configuration | |
| **Tool Capabilities:** | |
| - π’ **Safe Commands**: {len(config.security.safe_commands)} available | |
| - π΄ **Sensitive Operations**: 3 available (user, file, permission management) | |
| - β±οΈ **Command Timeout**: {config.security.command_timeout} seconds | |
| - π€ **AI Integration**: {config.openai.model} | |
| **Security Features:** | |
| - β Command whitelisting for safe operations | |
| - β Input validation for all operations | |
| - β Path traversal protection | |
| - β User permission validation | |
| - β Comprehensive logging | |
| **Safe Commands Whitelist:** | |
| ``` | |
| {', '.join(config.security.safe_commands)} | |
| ``` | |
| ### Usage Notes | |
| - **Safe operations** execute immediately with validation | |
| - **Sensitive operations** require careful parameter validation | |
| - **All operations** are logged for security auditing | |
| - **External clients** can call these functions programmatically | |
| """) | |
| return demo | |
| def main(): | |
| """Main entry point for the Linux administration server""" | |
| logger.info("π Starting Linux Administration Server") | |
| logger.info(f"OpenAI configured: {'β ' if config.openai.api_key else 'β'}") | |
| logger.info(f"Safe commands available: {len(config.security.safe_commands)}") | |
| # Create and launch the server | |
| demo = create_linux_server_interface() | |
| # Launch the interface | |
| demo.launch( | |
| share=config.gradio.share, | |
| server_name="0.0.0.0", # For HF Spaces | |
| server_port=7860, # Standard HF Spaces port | |
| show_error=True | |
| ) | |
| if __name__ == "__main__": | |
| main() |