Skip to content

Commit 8518c64

Browse files
committed
feat: support aigw install/uninstall
Signed-off-by: bitliu <bitliu@tencent.com>
1 parent 45c18d3 commit 8518c64

18 files changed

+2944
-5
lines changed

cmd/aigw/install.go

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
// Copyright Envoy AI Gateway Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
// The full text of the Apache license is available in the LICENSE file at
4+
// the root of the repo.
5+
6+
package main
7+
8+
import (
9+
"context"
10+
"fmt"
11+
"io"
12+
"time"
13+
14+
"github.com/envoyproxy/ai-gateway/cmd/aigw/internal/installer"
15+
"github.com/envoyproxy/ai-gateway/cmd/aigw/internal/ui"
16+
)
17+
18+
// cmdInstall corresponds to `aigw install` command.
19+
type cmdInstall struct {
20+
// Envoy Gateway options
21+
EnvoyGatewayNamespace string `help:"Envoy Gateway installation namespace" default:"envoy-gateway-system"`
22+
EnvoyGatewayVersion string `help:"Envoy Gateway chart version" default:"v0.0.0-latest"`
23+
24+
// AI Gateway options
25+
Namespace string `help:"AI Gateway installation namespace" default:"envoy-ai-gateway-system"`
26+
Version string `help:"AI Gateway chart version" default:"v0.0.0-latest"`
27+
SkipCRDs bool `help:"Skip AI Gateway CRDs installation"`
28+
29+
// Common options
30+
DryRun bool `help:"Show what would be done without executing"`
31+
Force bool `help:"Skip confirmation prompts"`
32+
Debug bool `help:"Enable debug logging"`
33+
Timeout time.Duration `help:"Timeout for installation operations" default:"5m"`
34+
}
35+
36+
// install executes the install command.
37+
func install(ctx context.Context, cmd cmdInstall, stdout, stderr io.Writer) error {
38+
output := ui.NewOutput(stdout, cmd.Debug)
39+
40+
// Print banner
41+
output.Banner("Envoy AI Gateway Installation")
42+
43+
if cmd.DryRun {
44+
output.Info("Running in DRY RUN mode - no changes will be made")
45+
output.EmptyLine()
46+
}
47+
48+
// Show installation options
49+
output.Subheader("Envoy Gateway Installation Options")
50+
envoyOptions := []string{
51+
fmt.Sprintf("Namespace: %s", cmd.EnvoyGatewayNamespace),
52+
fmt.Sprintf("Chart Version: %s", cmd.EnvoyGatewayVersion),
53+
}
54+
output.List(envoyOptions)
55+
output.EmptyLine()
56+
57+
output.Subheader("Envoy AI Gateway Installation Options")
58+
aiOptions := []string{
59+
fmt.Sprintf("Namespace: %s", cmd.Namespace),
60+
fmt.Sprintf("Chart Version: %s", cmd.Version),
61+
fmt.Sprintf("Skip CRDs: %t", cmd.SkipCRDs),
62+
fmt.Sprintf("Timeout: %s", cmd.Timeout),
63+
}
64+
output.List(aiOptions)
65+
output.EmptyLine()
66+
67+
// Confirmation prompt (unless force is specified or dry run)
68+
if !cmd.Force && !cmd.DryRun {
69+
if !output.ConfirmPrompt("Do you want to proceed with the installation?") {
70+
output.Info("Installation cancelled by user")
71+
return nil
72+
}
73+
output.EmptyLine()
74+
}
75+
76+
// Create installation manager
77+
manager, err := installer.NewManager(output, cmd.DryRun)
78+
if err != nil {
79+
return fmt.Errorf("failed to create installation manager: %w", err)
80+
}
81+
82+
// Prepare installation options
83+
installOpts := installer.InstallOptions{
84+
EnvoyGatewayNamespace: cmd.EnvoyGatewayNamespace,
85+
EnvoyGatewayVersion: cmd.EnvoyGatewayVersion,
86+
Namespace: cmd.Namespace,
87+
Version: cmd.Version,
88+
SkipCRDs: cmd.SkipCRDs,
89+
Timeout: cmd.Timeout,
90+
CreateNamespace: true,
91+
}
92+
93+
// Execute installation
94+
err = manager.Install(ctx, installOpts)
95+
if err != nil {
96+
output.Error(fmt.Sprintf("Installation failed: %v", err))
97+
output.EmptyLine()
98+
output.Subheader("Troubleshooting")
99+
output.List([]string{
100+
"Check that your kubeconfig is properly configured",
101+
"Ensure you have sufficient permissions in the cluster",
102+
"Verify that the cluster meets the minimum version requirements (1.29+)",
103+
"Check the cluster has sufficient resources available",
104+
"Run with --debug flag for more detailed output",
105+
})
106+
return err
107+
}
108+
109+
// Show success message and next steps
110+
output.EmptyLine()
111+
output.Success("Installation completed successfully!")
112+
output.EmptyLine()
113+
114+
output.Subheader("Next Steps")
115+
nextSteps := []string{
116+
"Verify the installation: kubectl get pods -n " + cmd.Namespace,
117+
"Check Envoy Gateway: kubectl get pods -n " + cmd.EnvoyGatewayNamespace,
118+
"View the documentation: https://aigateway.envoyproxy.io/docs/latest/getting-started/basic-usage",
119+
"Connect providers: https://aigateway.envoyproxy.io/docs/latest/getting-started/connect-providers",
120+
}
121+
output.NumberedList(nextSteps)
122+
123+
output.EmptyLine()
124+
output.Info("Happy AI Gateway-ing! 🚀")
125+
126+
return nil
127+
}
128+
129+
// showInstallationStatus shows the current installation status.
130+
func showInstallationStatus(ctx context.Context, output *ui.Output, namespace string) error {
131+
output.Subheader("Installation Status")
132+
133+
// This would check the current status of the installation
134+
// For now, we'll just show a placeholder
135+
output.Info("Checking installation status...")
136+
137+
// TODO: Implement status checking
138+
output.Warning("Status checking not implemented yet")
139+
140+
return nil
141+
}
142+
143+
// validateInstallOptions validates the installation options.
144+
func validateInstallOptions(cmd cmdInstall) error {
145+
// Validate namespace name
146+
if cmd.Namespace == "" {
147+
return fmt.Errorf("namespace cannot be empty")
148+
}
149+
150+
// Validate version format
151+
if cmd.Version == "" {
152+
return fmt.Errorf("version cannot be empty")
153+
}
154+
155+
// Validate timeout
156+
if cmd.Timeout <= 0 {
157+
return fmt.Errorf("timeout must be positive")
158+
}
159+
160+
return nil
161+
}
162+
163+
// showPreInstallationInfo shows information before installation.
164+
func showPreInstallationInfo(output *ui.Output, cmd cmdInstall) {
165+
output.Subheader("Pre-Installation Information")
166+
167+
info := []string{
168+
"This will install Envoy AI Gateway and its dependencies",
169+
"Envoy Gateway will be installed in the 'envoy-gateway-system' namespace",
170+
fmt.Sprintf("AI Gateway will be installed in the '%s' namespace", cmd.Namespace),
171+
"Configuration will be applied to integrate the components",
172+
}
173+
174+
if cmd.SkipCRDs {
175+
info = append(info, "CRDs installation will be skipped (ensure they are already installed)")
176+
} else {
177+
info = append(info, "CRDs will be installed automatically")
178+
}
179+
180+
output.List(info)
181+
output.EmptyLine()
182+
183+
output.Subheader("Prerequisites")
184+
prereqs := []string{
185+
"kubectl command-line tool",
186+
"helm package manager",
187+
"Kubernetes cluster version 1.29 or higher",
188+
"Sufficient cluster permissions (cluster-admin recommended)",
189+
}
190+
output.List(prereqs)
191+
output.EmptyLine()
192+
}
193+
194+
// handleInstallationError handles installation errors and provides guidance.
195+
func handleInstallationError(output *ui.Output, err error) {
196+
output.Error(fmt.Sprintf("Installation failed: %v", err))
197+
output.EmptyLine()
198+
199+
output.Subheader("Common Issues and Solutions")
200+
solutions := []string{
201+
"Permission denied: Ensure you have cluster-admin permissions",
202+
"Connection refused: Check your kubeconfig and cluster connectivity",
203+
"Version mismatch: Verify your Kubernetes cluster version is 1.29+",
204+
"Resource conflicts: Check if components are already installed",
205+
"Timeout errors: Increase timeout with --timeout flag",
206+
}
207+
output.List(solutions)
208+
output.EmptyLine()
209+
210+
output.Info("For more help, visit: https://aigateway.envoyproxy.io/docs/latest/getting-started/installation")
211+
}

0 commit comments

Comments
 (0)