-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Expand file tree
/
Copy pathmain.go
More file actions
executable file
·164 lines (147 loc) · 5.19 KB
/
main.go
File metadata and controls
executable file
·164 lines (147 loc) · 5.19 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// Package main is the entry point for the keploy application.
package main
import (
"context"
"fmt"
"os"
"runtime"
"strings"
"go.keploy.io/server/v3/cli"
"go.keploy.io/server/v3/cli/provider"
"go.keploy.io/server/v3/config"
"go.keploy.io/server/v3/pkg/platform/auth"
userDb "go.keploy.io/server/v3/pkg/platform/yaml/configdb/user"
"go.keploy.io/server/v3/utils"
"go.keploy.io/server/v3/utils/log"
"go.uber.org/zap"
"runtime/pprof"
)
// version is the version of the server and will be injected during build by ldflags, same with dsn
// see https://goreleaser.com/customization/build/
var version string
var dsn string
var apiServerURI = "http://localhost:8083"
var gitHubClientID = "Iv23liFBvIVhL29i9BAp"
func main() {
setVersion()
ctx := utils.NewCtx()
start(ctx)
os.Exit(utils.ErrCode)
}
func setVersion() {
if version == "" {
version = "3-dev"
}
utils.Version = version
utils.VersionIdentifier = "version"
}
func start(ctx context.Context) {
logger, logFile, err := log.New()
if err != nil {
fmt.Println("Failed to start the logger for the CLI", err)
return
}
utils.LogFile = logFile
// Early check: If Docker command detected and not running as root, re-exec with sudo
// This must happen before any other initialization to ensure clean process handoff
if utils.ShouldReexecWithSudo() {
utils.ReexecWithSudo(logger)
// ReexecWithSudo calls syscall.Exec which replaces the process, so this line
// is only reached if there's an error (which is handled inside ReexecWithSudo)
return
}
if cpuProfile := os.Getenv("CPU_PROFILE"); cpuProfile != "" {
f, err := os.Create(cpuProfile)
if err != nil {
logger.Error("could not create CPU profile", zap.Error(err))
} else {
if err := pprof.StartCPUProfile(f); err != nil {
logger.Error("could not start CPU profile", zap.Error(err))
f.Close()
} else {
logger.Info("CPU profiling enabled", zap.String("file", cpuProfile))
defer func() {
pprof.StopCPUProfile()
f.Close()
logger.Info("CPU profiling stopped", zap.String("file", cpuProfile))
}()
}
}
}
if heapProfile := os.Getenv("HEAP_PROFILE"); heapProfile != "" {
logger.Info("Heap profiling enabled", zap.String("file", heapProfile))
defer func() {
f, err := os.Create(heapProfile)
if err != nil {
logger.Error("could not create Heap profile", zap.Error(err))
return
}
defer f.Close()
runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
logger.Error("could not write Heap profile", zap.Error(err))
} else {
logger.Info("Heap profile written", zap.String("file", heapProfile))
}
}()
}
defer func() {
inDocker := os.Getenv("KEPLOY_INDOCKER")
if inDocker != "true" {
if utils.LogFile != nil {
err := utils.LogFile.Close()
if err != nil {
utils.LogError(logger, err, "Failed to close Keploy Logs")
}
}
if err := utils.DeleteFileIfNotExists(logger, "keploy-logs.txt"); err != nil {
return
}
if err := utils.DeleteFileIfNotExists(logger, "docker-compose-tmp.yaml"); err != nil {
return
}
}
}()
defer utils.Recover(logger)
// The 'umask' command is commonly used in various operating systems to regulate the permissions of newly created files.
// These 'umask' values subtract from the permissions assigned by the process, effectively lowering the permissions.
// For example, if a file is created with permissions '777' and the 'umask' is '022', the resulting permissions will be '755',
// reducing certain permissions for security purposes.
// Setting 'umask' to '0' ensures that 'keploy' can precisely control the permissions of the files it creates.
// However, it's important to note that this approach may not work in scenarios involving mounted volumes,
// as the 'umask' is set by the host system, and cannot be overridden by 'keploy' or individual processes.
oldMask := utils.SetUmask()
defer utils.RestoreUmask(oldMask)
if dsn != "" {
utils.SentryInit(logger, dsn)
//logger = utils.ModifyToSentryLogger(ctx, logger, sentry.CurrentHub().Client(), configDb)
}
conf := config.New()
conf.APIServerURL = apiServerURI
conf.GitHubClientID = gitHubClientID
// Capture the full command used for test runs (to be stored in report)
conf.Test.CmdUsed = utils.GetFullCommandUsed()
userDb := userDb.New(logger, conf)
conf.InstallationID, err = userDb.GetInstallationID(ctx)
if err != nil {
errMsg := "failed to get installation id"
utils.LogError(logger, err, errMsg)
os.Exit(1)
}
auth := auth.New(conf.APIServerURL, conf.InstallationID, logger, conf.GitHubClientID)
svcProvider := provider.NewServiceProvider(logger, conf, auth)
cmdConfigurator := provider.NewCmdConfigurator(logger, conf)
rootCmd := cli.Root(ctx, logger, svcProvider, cmdConfigurator)
if err := rootCmd.Execute(); err != nil {
if strings.HasPrefix(err.Error(), "unknown command") || strings.HasPrefix(err.Error(), "unknown shorthand") {
fmt.Println("Error: ", err.Error())
fmt.Println("Run 'keploy --help' for usage.")
os.Exit(1)
}
}
// Restore keploy folder ownership if running under sudo (for Docker mode)
// This ensures the next native run doesn't hit permission issues
if conf.Path != "" {
utils.RestoreKeployFolderOwnership(logger, conf.Path)
}
}