-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathdoctor.go
More file actions
111 lines (95 loc) · 2.86 KB
/
doctor.go
File metadata and controls
111 lines (95 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package cmd
import (
"fmt"
"net/http"
"os"
"path/filepath"
"github.com/localstack/lstk/internal/config"
"github.com/localstack/lstk/internal/doctor"
"github.com/localstack/lstk/internal/emulator/aws"
"github.com/localstack/lstk/internal/env"
"github.com/localstack/lstk/internal/log"
"github.com/localstack/lstk/internal/output"
"github.com/localstack/lstk/internal/runtime"
"github.com/localstack/lstk/internal/telemetry"
"github.com/localstack/lstk/internal/ui"
"github.com/spf13/cobra"
)
func newDoctorCmd(cfg *env.Env, tel *telemetry.Client, logger log.Logger) *cobra.Command {
return &cobra.Command{
Use: "doctor",
Short: "Diagnose your LocalStack environment",
Long: "Run read-only checks for configuration, Docker, authentication, and emulator connectivity.",
RunE: commandWithTelemetry("doctor", tel, func(cmd *cobra.Command, args []string) error {
configState, containers, err := loadDoctorConfig(cmd)
if err != nil {
return err
}
rt, rtErr := runtime.NewDockerRuntime(cfg.DockerHost)
opts := doctor.Options{
Config: configState,
Containers: containers,
LocalStackHost: cfg.LocalStackHost,
EnvAuthToken: cfg.AuthToken,
ForceFileKeyring: cfg.ForceFileKeyring,
Logger: logger,
RuntimeInitError: rtErr,
}
awsClient := aws.NewClient(&http.Client{})
if isInteractiveMode(cfg) {
return ui.RunDoctor(cmd.Context(), rt, awsClient, opts)
}
return doctor.Run(cmd.Context(), rt, awsClient, output.NewPlainSink(os.Stdout), opts)
}),
}
}
func loadDoctorConfig(cmd *cobra.Command) (doctor.ConfigState, []config.ContainerConfig, error) {
explicitPath, err := cmd.Flags().GetString("config")
if err != nil {
return doctor.ConfigState{}, nil, err
}
if explicitPath != "" {
return loadDoctorConfigPath(explicitPath)
}
existingPath, found, err := config.ExistingConfigFilePath()
if err != nil {
return doctor.ConfigState{}, nil, err
}
if found {
return loadDoctorConfigPath(existingPath)
}
resolvedPath, err := config.ConfigFilePath()
if err != nil {
return doctor.ConfigState{}, nil, err
}
return doctor.ConfigState{
Path: resolvedPath,
Exists: false,
}, nil, nil
}
func loadDoctorConfigPath(path string) (doctor.ConfigState, []config.ContainerConfig, error) {
absPath, err := filepath.Abs(path)
if err != nil {
return doctor.ConfigState{}, nil, fmt.Errorf("failed to resolve config path: %w", err)
}
state := doctor.ConfigState{
Path: absPath,
Exists: true,
}
if _, err := os.Stat(absPath); err != nil {
state.Exists = false
state.LoadError = err
return state, nil, nil
}
if err := config.InitFromPath(absPath); err != nil {
state.LoadError = err
return state, nil, nil
}
appConfig, err := config.Get()
if err != nil {
state.LoadError = err
return state, nil, nil
}
state.Loaded = true
return state, appConfig.Containers, nil
}