Enhance deployment system with retry functionality and improved UX
Major Improvements: - Added retry deployment buttons in machine list for failed deployments - Added retry button in SSH console modal footer for enhanced UX - Enhanced deployment process with comprehensive cleanup of existing services - Improved binary installation with password-based sudo authentication - Updated configuration generation to include all required sections (agent, ai, network, security) - Fixed deployment verification and error handling Security Enhancements: - Enhanced verifiedStopExistingServices with thorough cleanup process - Improved binary copying with proper sudo authentication - Added comprehensive configuration validation UX Improvements: - Users can retry deployments without re-running machine discovery - Retry buttons available from both machine list and console modal - Real-time deployment progress with detailed console output - Clear error states with actionable retry options Technical Changes: - Modified ServiceDeployment.tsx with retry button components - Enhanced api/setup_manager.go with improved deployment functions - Updated main.go with command line argument support (--config, --setup) - Added comprehensive zero-trust security validation system 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -380,10 +380,10 @@ export default function ServiceDeployment({
|
||||
|
||||
const getStatusIcon = (status: string) => {
|
||||
switch (status) {
|
||||
case 'connected': return <CheckCircleIcon className="h-5 w-5 text-green-500" />
|
||||
case 'connected': return <CheckCircleIcon className="h-5 w-5 text-eucalyptus-600" />
|
||||
case 'failed': return <XCircleIcon className="h-5 w-5 text-red-500" />
|
||||
case 'testing': return <ArrowPathIcon className="h-5 w-5 text-blue-500 animate-spin" />
|
||||
case 'running': return <CheckCircleIcon className="h-5 w-5 text-green-500" />
|
||||
case 'running': return <CheckCircleIcon className="h-5 w-5 text-eucalyptus-600" />
|
||||
case 'installing': return <ArrowPathIcon className="h-5 w-5 text-blue-500 animate-spin" />
|
||||
case 'error': return <XCircleIcon className="h-5 w-5 text-red-500" />
|
||||
case 'stopped': return <StopIcon className="h-5 w-5 text-yellow-500" />
|
||||
@@ -585,12 +585,24 @@ export default function ServiceDeployment({
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => deployToMachine(machine.id)}
|
||||
className="text-green-600 hover:text-green-900"
|
||||
className="text-eucalyptus-600 hover:text-eucalyptus-600"
|
||||
>
|
||||
Install
|
||||
</button>
|
||||
)}
|
||||
|
||||
{machine.sshStatus === 'connected' && machine.deployStatus === 'error' && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => deployToMachine(machine.id)}
|
||||
className="text-amber-600 hover:text-amber-700 mr-2"
|
||||
title="Retry deployment"
|
||||
>
|
||||
<ArrowPathIcon className="h-4 w-4 inline mr-1" />
|
||||
Retry
|
||||
</button>
|
||||
)}
|
||||
|
||||
{machine.deployStatus !== 'not_deployed' && (
|
||||
<>
|
||||
<button
|
||||
@@ -684,7 +696,7 @@ export default function ServiceDeployment({
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
<div className="bg-gray-900 text-green-400 p-4 rounded font-mono text-sm max-h-64 overflow-y-auto">
|
||||
<div className="bg-gray-900 text-eucalyptus-600 p-4 rounded font-mono text-sm max-h-64 overflow-y-auto">
|
||||
{deploymentLogs[showLogs]?.map((log, index) => (
|
||||
<div key={index}>{log}</div>
|
||||
)) || <div>No logs available</div>}
|
||||
@@ -699,7 +711,7 @@ export default function ServiceDeployment({
|
||||
<div className="bg-gray-900 rounded-lg overflow-hidden max-w-4xl w-full max-h-[80vh] flex flex-col">
|
||||
<div className="bg-gray-800 px-4 py-3 flex justify-between items-center border-b border-gray-700">
|
||||
<div className="flex items-center">
|
||||
<ComputerDesktopIcon className="h-5 w-5 text-green-400 mr-2" />
|
||||
<ComputerDesktopIcon className="h-5 w-5 text-eucalyptus-600 mr-2" />
|
||||
<h3 className="text-lg font-medium text-white">
|
||||
SSH Console - {machines.find(m => m.id === showConsole)?.hostname}
|
||||
</h3>
|
||||
@@ -711,7 +723,7 @@ export default function ServiceDeployment({
|
||||
<div className="flex items-center space-x-1">
|
||||
<div className="w-2 h-2 bg-red-500 rounded-full"></div>
|
||||
<div className="w-2 h-2 bg-yellow-500 rounded-full"></div>
|
||||
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
|
||||
<div className="w-2 h-2 bg-eucalyptus-500 rounded-full"></div>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setShowConsole(null)}
|
||||
@@ -722,7 +734,7 @@ export default function ServiceDeployment({
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 p-4 font-mono text-sm overflow-y-auto bg-gray-900">
|
||||
<div className="text-green-400 space-y-1">
|
||||
<div className="text-eucalyptus-600 space-y-1">
|
||||
{consoleLogs[showConsole]?.length > 0 ? (
|
||||
consoleLogs[showConsole].map((log, index) => (
|
||||
<div key={index} className="whitespace-pre-wrap">{log}</div>
|
||||
@@ -734,10 +746,26 @@ export default function ServiceDeployment({
|
||||
<div className="inline-block w-2 h-4 bg-green-400 animate-pulse"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-gray-800 px-4 py-2 border-t border-gray-700">
|
||||
<div className="bg-gray-800 px-4 py-2 border-t border-gray-700 flex justify-between items-center">
|
||||
<div className="text-xs text-gray-400">
|
||||
💡 This console shows real-time deployment progress and SSH operations
|
||||
</div>
|
||||
{(() => {
|
||||
const machine = machines.find(m => m.id === showConsole)
|
||||
return machine?.sshStatus === 'connected' && machine?.deployStatus === 'error' && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
deployToMachine(showConsole!)
|
||||
}}
|
||||
className="ml-4 px-3 py-1 bg-amber-600 hover:bg-amber-700 text-white text-xs rounded-md flex items-center space-x-1 transition-colors"
|
||||
title="Retry deployment"
|
||||
>
|
||||
<ArrowPathIcon className="h-3 w-3" />
|
||||
<span>Retry Deployment</span>
|
||||
</button>
|
||||
)
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user