From 98784d18ba1b0e07ac3c3f7ee578e9e67573265e Mon Sep 17 00:00:00 2001 From: fabiankramm Date: Mon, 16 Nov 2020 10:51:57 +0100 Subject: [PATCH 01/12] chore: deprecate -i & fix docs link --- cmd/dev.go | 4 + cmd/init.go | 25 + cmd/root.go | 5 - cmd/set/analytics.go | 56 -- cmd/set/set.go | 1 - docs/pages/guides/interactive-mode.mdx | 22 + hack/build-all.bash | 2 +- pkg/devspace/server/server.go | 6 - pkg/devspace/sync/sync.go | 5 - pkg/devspace/upgrade/upgrade.go | 4 - pkg/util/analytics/analytics.go | 509 ------------------ pkg/util/analytics/cloudanalytics/start.go | 67 --- pkg/util/analytics/sigterm.go | 16 - pkg/util/analytics/sigterm_win.go | 25 - ui/package.json | 3 - .../advanced/SupportChat/SupportChat.tsx | 46 -- .../PageLayout/Header/UserMenu/UserMenu.tsx | 4 +- ui/src/pages/_app.tsx | 2 - 18 files changed, 54 insertions(+), 748 deletions(-) delete mode 100644 cmd/set/analytics.go delete mode 100644 pkg/util/analytics/analytics.go delete mode 100644 pkg/util/analytics/cloudanalytics/start.go delete mode 100644 pkg/util/analytics/sigterm.go delete mode 100644 pkg/util/analytics/sigterm_win.go delete mode 100644 ui/src/components/advanced/SupportChat/SupportChat.tsx diff --git a/cmd/dev.go b/cmd/dev.go index e7225e7e26..b7935b12e6 100644 --- a/cmd/dev.go +++ b/cmd/dev.go @@ -147,6 +147,10 @@ Open terminal instead of logs: // Run executes the command logic func (cmd *DevCmd) Run(f factory.Factory, plugins []plugin.Metadata, cobraCmd *cobra.Command, args []string) error { + if cmd.Interactive { + cmd.log.Warn("Interactive mode flag is deprecated and will be removed in the future. Please take a look at https://devspace.sh/cli/docs/guides/interactive-mode on how to transition to an interactive profile") + } + // Set config root cmd.log = f.GetLog() cmd.configLoader = f.NewConfigLoader(cmd.ToConfigOptions(), cmd.log) diff --git a/cmd/init.go b/cmd/init.go index c125331d14..7c92b67953 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -46,6 +46,9 @@ const ( // The default name for the production profile productionProfileName = "production" + + // The default name for the interactive profile + interactiveProfileName = "interactive" ) // InitCmd is a struct that defines a command call for "init" @@ -452,6 +455,28 @@ func (cmd *InitCmd) addProfileConfig(config *latest.Config) error { Patches: patches, }) } + if ok { + config.Profiles = append(config.Profiles, &latest.ProfileConfig{ + Name: interactiveProfileName, + Patches: []*latest.PatchConfig{ + { + Operation: "add", + Path: "dev.interactive", + Value: map[string]bool{ + "defaultEnabled": true, + }, + }, + { + Operation: "add", + Path: "images." + defaultImageName + ".entrypoint", + Value: []string{ + "sleep", + "9999999999", + }, + }, + }, + }) + } } return nil } diff --git a/cmd/root.go b/cmd/root.go index 5bc605c2d3..b46b0500f4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -17,7 +17,6 @@ import ( "github.com/devspace-cloud/devspace/pkg/devspace/config/loader" "github.com/devspace-cloud/devspace/pkg/devspace/plugin" "github.com/devspace-cloud/devspace/pkg/devspace/upgrade" - "github.com/devspace-cloud/devspace/pkg/util/analytics/cloudanalytics" "github.com/devspace-cloud/devspace/pkg/util/exit" "github.com/devspace-cloud/devspace/pkg/util/factory" flagspkg "github.com/devspace-cloud/devspace/pkg/util/flags" @@ -79,9 +78,6 @@ func Execute() { // disable klog disableKlog() - // report any panics - defer cloudanalytics.ReportPanics() - // create a new factory f := factory.DefaultFactory() @@ -93,7 +89,6 @@ func Execute() { // execute command err := rootCmd.Execute() - cloudanalytics.SendCommandEvent(err) if err != nil { // Check if return code error retCode, ok := errors.Cause(err).(*exit.ReturnCodeError) diff --git a/cmd/set/analytics.go b/cmd/set/analytics.go deleted file mode 100644 index 0a4872d120..0000000000 --- a/cmd/set/analytics.go +++ /dev/null @@ -1,56 +0,0 @@ -package set - -import ( - "github.com/devspace-cloud/devspace/pkg/util/analytics" - "github.com/devspace-cloud/devspace/pkg/util/factory" - - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -type analyticsCmd struct{} - -func newAnalyticsCmd(f factory.Factory) *cobra.Command { - cmd := &analyticsCmd{} - - return &cobra.Command{ - Use: "analytics", - Short: "Update analytics settings", - Long: ` -####################################################### -############### devspace set analytics ################ -####################################################### -Example: -devspace set analytics disabled true -####################################################### - `, - Args: cobra.RangeArgs(1, 2), - RunE: func(cobraCmd *cobra.Command, args []string) error { - return cmd.RunAnalyticsConfig(f, cobraCmd, args) - }, - } -} - -// RunAnalyticsConfig executes the "devspace set analytics" logic -func (*analyticsCmd) RunAnalyticsConfig(f factory.Factory, cobraCmd *cobra.Command, args []string) error { - log := f.GetLog() - analytics, err := analytics.GetAnalytics() - if err != nil { - return errors.Wrap(err, "get analytics config") - } - - if args[0] == "disabled" { - if len(args) == 2 && (args[1] == "false" || args[1] == "0") { - err = analytics.Enable() - } else { - err = analytics.Disable() - } - } - - if err != nil { - return errors.Wrap(err, "set analytics config") - } - - log.Infof("Successfully updated analytics config") - return nil -} diff --git a/cmd/set/set.go b/cmd/set/set.go index 1bc6892110..a060466414 100644 --- a/cmd/set/set.go +++ b/cmd/set/set.go @@ -19,7 +19,6 @@ func NewSetCmd(f factory.Factory, plugins []plugin.Metadata) *cobra.Command { Args: cobra.NoArgs, } - setCmd.AddCommand(newAnalyticsCmd(f)) setCmd.AddCommand(newVarCmd(f)) // Add plugin commands diff --git a/docs/pages/guides/interactive-mode.mdx b/docs/pages/guides/interactive-mode.mdx index 1a06190c23..6d7fd1cb57 100644 --- a/docs/pages/guides/interactive-mode.mdx +++ b/docs/pages/guides/interactive-mode.mdx @@ -3,6 +3,28 @@ title: Interactive Mode sidebar_label: Interactive Mode --- +:::warning Deprecation of interactive mode +Using `devspace dev -i` is deprecated, and the flag will be removed in the future! Make sure to change your `devspace.yaml`'s to have an `interactive` mode profile instead: + +```yaml +... +profiles: +- name: interactive + patches: + - op: add + path: dev.interactive + value: + defaultEnabled: true + - op: add + path: dev.MY_IMAGE.entrypoint + value: + - sleep + - 99999999 +``` + +This profile can be activated via `-p interactive` and has the same functionality as using the flag `-i`. +::: + The development mode of DevSpace can be started using the `-i / --interactive` flag which overrides the `ENTRYPOINT` of an image with `[sleep, 999999]` and opens an interactive terminal session for one of the containers that use the 'sleeping' image. Due to the `ENTRYPOINT` override, the application has not been started within the container and the user can start the application manually through the interactive terminal session. ## Start Interactive Mode diff --git a/hack/build-all.bash b/hack/build-all.bash index 5b39d8bc5d..b5d31e0e76 100755 --- a/hack/build-all.bash +++ b/hack/build-all.bash @@ -25,7 +25,7 @@ if [[ "$(pwd)" != "${DEVSPACE_ROOT}" ]]; then fi GO_BUILD_CMD="go build -a" -GO_BUILD_LDFLAGS="-s -w -X main.commitHash=${COMMIT_HASH} -X main.buildDate=${DATE} -X main.version=${VERSION} -X github.com/devspace-cloud/devspace/pkg/util/analytics.token=${ANALYTICS_TOKEN} -X github.com/devspace-cloud/devspace/pkg/util/analytics.eventEndpoint=${ANALYTICS_ENDPOINT_EVENT} -X github.com/devspace-cloud/devspace/pkg/util/analytics.userEndpoint=${ANALYTICS_ENDPOINT_USER}" +GO_BUILD_LDFLAGS="-s -w -X main.commitHash=${COMMIT_HASH} -X main.buildDate=${DATE} -X main.version=${VERSION}" if [[ -z "${DEVSPACE_BUILD_PLATFORMS}" ]]; then DEVSPACE_BUILD_PLATFORMS="linux windows darwin" diff --git a/pkg/devspace/server/server.go b/pkg/devspace/server/server.go index a8910f9ce8..83f1ed25b8 100644 --- a/pkg/devspace/server/server.go +++ b/pkg/devspace/server/server.go @@ -8,7 +8,6 @@ import ( "github.com/devspace-cloud/devspace/pkg/devspace/kubectl" "github.com/devspace-cloud/devspace/pkg/devspace/kubectl/portforward" "github.com/devspace-cloud/devspace/pkg/devspace/upgrade" - "github.com/devspace-cloud/devspace/pkg/util/analytics" "github.com/devspace-cloud/devspace/pkg/util/kubeconfig" "github.com/devspace-cloud/devspace/pkg/util/log" "github.com/devspace-cloud/devspace/pkg/util/port" @@ -163,11 +162,6 @@ func newHandler(configLoader loader.ConfigLoader, config *latest.Config, generat terminalResizeQueues: make(map[string]TerminalResizeQueue), } - analytics, err := analytics.GetAnalytics() - if err == nil { - handler.analyticsEnabled = analytics.Enabled() - } - // Load raw config if config != nil { handler.rawConfig, err = configLoader.LoadRaw() diff --git a/pkg/devspace/sync/sync.go b/pkg/devspace/sync/sync.go index 58af8f14c6..2dd0b5f933 100644 --- a/pkg/devspace/sync/sync.go +++ b/pkg/devspace/sync/sync.go @@ -1,7 +1,6 @@ package sync import ( - "fmt" "io" "os" "path/filepath" @@ -10,7 +9,6 @@ import ( "time" "github.com/devspace-cloud/devspace/pkg/devspace/config/versions/latest" - "github.com/devspace-cloud/devspace/pkg/util/analytics/cloudanalytics" "github.com/devspace-cloud/devspace/pkg/util/log" "github.com/pkg/errors" @@ -380,9 +378,6 @@ func (s *Sync) Stop(fatalError error) { // This needs to be rethought because we do not always kill the application here, would be better to have an error channel // or runtime error here - sendError := fmt.Errorf("Fatal sync error: %v. For more information check .devspace/logs/sync.log", fatalError) - cloudanalytics.SendCommandEvent(sendError) - if s.Options.SyncError != nil { s.Options.SyncError <- fatalError } diff --git a/pkg/devspace/upgrade/upgrade.go b/pkg/devspace/upgrade/upgrade.go index 7da069dbf8..9867ae134c 100644 --- a/pkg/devspace/upgrade/upgrade.go +++ b/pkg/devspace/upgrade/upgrade.go @@ -9,7 +9,6 @@ import ( "github.com/devspace-cloud/devspace/pkg/util/log" "github.com/blang/semver" - "github.com/devspace-cloud/devspace/pkg/util/analytics/cloudanalytics" "github.com/rhysd/go-github-selfupdate/selfupdate" ) @@ -65,9 +64,6 @@ func SetVersion(verText string) { version = _version rawVersion = verText } - - // Start analytics - cloudanalytics.Start(version) } var ( diff --git a/pkg/util/analytics/analytics.go b/pkg/util/analytics/analytics.go deleted file mode 100644 index 7fe944eac3..0000000000 --- a/pkg/util/analytics/analytics.go +++ /dev/null @@ -1,509 +0,0 @@ -package analytics - -import ( - "bytes" - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "os" - "os/exec" - "os/signal" - "path/filepath" - "regexp" - "runtime" - "runtime/debug" - "strconv" - "strings" - "sync" - "time" - - "github.com/devspace-cloud/devspace/pkg/util/hash" - "github.com/devspace-cloud/devspace/pkg/util/kubeconfig" - "github.com/devspace-cloud/devspace/pkg/util/randutil" - "github.com/devspace-cloud/devspace/pkg/util/yamlutil" - "github.com/google/uuid" - homedir "github.com/mitchellh/go-homedir" - "github.com/pkg/errors" - "github.com/shirou/gopsutil/process" -) - -var token string -var eventEndpoint string -var userEndpoint string -var analyticsConfigFile string -var analyticsInstance *analyticsConfig -var loadAnalyticsOnce sync.Once - -const DEFERRED_REQUEST_COMMAND = "send-deferred-request" - -// Analytics is an interface for sending data to an analytics service -type Analytics interface { - Enabled() bool - Disable() error - Enable() error - SendEvent(eventName string, eventProperties map[string]interface{}, userProperties map[string]interface{}) error - SendCommandEvent(commandArgs []string, commandError error, commandDuration int64) error - ReportPanics() - Identify(identifier string) error - SetVersion(version string) - SetIdentifyProvider(getIdentity func() string) - HandleDeferredRequest() error -} - -type analyticsConfig struct { - DistinctID string `yaml:"distinctId,omitempty"` - Identifier string `yaml:"identifier,omitempty"` - Disabled bool `yaml:"disabled,omitempty"` - LatestUpdate int64 `yaml:"latestUpdate,omitempty"` - LatestSession int64 `yaml:"latestSession,omitempty"` - - version string - identityProvider *func() string - - kubeLoader kubeconfig.Loader -} - -func (a *analyticsConfig) Enabled() bool { - return !a.Disabled -} - -func (a *analyticsConfig) Disable() error { - if !a.Disabled { - identValue := map[string]interface{}{ - "device_id": a.DistinctID, - - "user_properties": map[string]interface{}{ - "enabled": false, - }, - } - - if a.Identifier != "" { - identValue["user_id"] = a.Identifier - } - - requestData := map[string]interface{}{ - "parameters": map[string]interface{}{ - "api_key": token, - "identification": []interface{}{ - identValue, - }, - }, - } - - err := a.sendRequest(userEndpoint, requestData) - if err != nil { - // ignore if request fails - } - - a.Disabled = true - return a.save() - } - return nil -} - -func (a *analyticsConfig) Enable() error { - if a.Disabled { - a.Disabled = false - return a.save() - } - return nil -} - -func (a *analyticsConfig) Identify(identifier string) error { - if identifier != a.Identifier { - if a.Identifier != "" { - // user was logged in, now different user is logging in => RESET DISTINCT ID - _ = a.resetDistinctID() - } - a.Identifier = identifier - - requestData := map[string]interface{}{ - "parameters": map[string]interface{}{ - "api_key": token, - "identification": []interface{}{ - map[string]interface{}{ - "device_id": a.DistinctID, - "user_id": a.Identifier, - }, - }, - }, - } - - return a.sendRequest(userEndpoint, requestData) - } - return nil -} - -func (a *analyticsConfig) SendCommandEvent(commandArgs []string, commandError error, commandDuration int64) error { - executable, _ := os.Executable() - command := strings.Join(commandArgs, " ") - command = strings.Replace(command, executable, "devspace", 1) - - expr := regexp.MustCompile(`^.*\s+(login\s.*--key=?\s*)(.*)(\s.*|$)`) - command = expr.ReplaceAllString(command, `devspace $1[REDACTED]$3`) - - userProperties := map[string]interface{}{ - "app_version": a.version, - } - commandProperties := map[string]interface{}{ - "command": command, - "runtime_os": runtime.GOOS, - "runtime_arch": runtime.GOARCH, - "cli_version": a.version, - } - - if commandError != nil { - commandProperties["error"] = strings.Replace(commandError.Error(), "\n", "\\n", -1) - } - - contextName, err := a.kubeLoader.GetCurrentContext() - if contextName != "" && err == nil { - spaceID, cloudProvider, _ := a.kubeLoader.GetSpaceID(contextName) - - if spaceID != 0 { - commandProperties["space_id"] = spaceID - commandProperties["cloud_provider"] = cloudProvider - userProperties["has_spaces"] = true - } - - kubeConfig, err := a.kubeLoader.LoadRawConfig() - if err == nil { - if context, ok := kubeConfig.Contexts[contextName]; ok { - if cluster, ok := kubeConfig.Clusters[context.Cluster]; ok { - commandProperties["kube_server"] = cluster.Server - } - - commandProperties["kube_namespace"] = hash.String(context.Namespace) - } - } - commandProperties["kube_context"] = hash.String(contextName) - } - - if commandDuration != 0 { - commandProperties["duration"] = strconv.FormatInt(commandDuration, 10) + "ms" - } - - if regexp.MustCompile(`^.*\s+(use\s+space\s.*--get-token((\s*)|$))`).MatchString(command) { - return a.SendEvent("kube-context", commandProperties, userProperties) - } - return a.SendEvent("command", commandProperties, userProperties) -} - -func (a *analyticsConfig) SendEvent(eventName string, eventProperties map[string]interface{}, userProperties map[string]interface{}) error { - if !a.Disabled && token != "" { - now := time.Now() - - insertID, err := randutil.GenerateRandomString(9) - if err != nil { - return errors.Errorf("Couldn't generate random insert_id for analytics: %v", err) - } - eventData := map[string]interface{}{} - eventData["insert_id"] = insertID + strconv.FormatInt(now.Unix(), 16) - eventData["event_type"] = eventName - eventData["ip"] = "$remote" - - if _, ok := eventData["app_version"]; !ok { - eventData["app_version"] = a.version - } - - if _, ok := eventData["session_id"]; !ok { - sessionID, err := a.getSessionID() - if err != nil { - return err - } - eventData["session_id"] = sessionID - } - - if a.identityProvider != nil { - getIdentity := *a.identityProvider - a.Identify(getIdentity()) - } - - userProperties["enabled"] = true - - if a.Identifier != "" { - eventData["user_id"] = a.Identifier - eventData["user_properties"] = userProperties - } else { - eventData["device_id"] = a.DistinctID - } - - // save session and identity - err = a.save() - if err != nil { - // ignore if save fails - } - - eventData["event_properties"] = eventProperties - - requestBody := map[string]interface{}{} - requestBody["api_key"] = token - requestBody["events"] = []interface{}{ - eventData, - } - requestData := map[string]interface{}{ - "body": requestBody, - } - - return a.sendRequest(eventEndpoint, requestData) - } - return nil -} - -func (a *analyticsConfig) getSessionID() (int64, error) { - now := time.Now() - sessionExpired := time.Unix(a.LatestUpdate*int64(time.Millisecond), 0).Add(time.Minute * 30).Before(now) - a.LatestUpdate = now.UnixNano() / int64(time.Millisecond) - - if a.LatestSession == 0 || sessionExpired { - a.LatestSession = a.LatestUpdate - (a.LatestUpdate % (24 * 60 * 60 * 1000)) - } - return a.LatestSession, nil -} - -func (a *analyticsConfig) ReportPanics() { - if r := recover(); r != nil { - err := errors.Errorf("Panic: %v\n%v", r, string(debug.Stack())) - - a.SendCommandEvent(os.Args, err, GetProcessDuration()) - } -} - -func (a *analyticsConfig) SetVersion(version string) { - if version == "" { - version = "dev" - } - a.version = version -} - -func (a *analyticsConfig) SetIdentifyProvider(getIdentity func() string) { - a.identityProvider = &getIdentity -} - -func (a *analyticsConfig) sendRequest(requestURL string, data map[string]interface{}) error { - if !a.Disabled && token != "" { - var err error - jsonRequestBody := []byte{} - requestURL, err := url.Parse(requestURL) - - if requestBody, ok := data["body"]; ok { - jsonRequestBody, err = json.Marshal(requestBody) - if err != nil { - return errors.Errorf("Couldn't marshal analytics data to json: %v", err) - } - } - - if requestParams, ok := data["parameters"]; ok { - params := url.Values{} - paramsMap := requestParams.(map[string]interface{}) - for key := range paramsMap { - paramValueMap, isMap := paramsMap[key].(map[string]interface{}) - paramValueArray, isArray := paramsMap[key].([]interface{}) - if isMap || isArray { - var paramValue interface{} - if isMap { - paramValue = paramValueMap - } - if isArray { - paramValue = paramValueArray - } - jsonParam, err := json.Marshal(paramValue) - if err != nil { - return errors.Errorf("Couldn't marshal analytics data to json: %v", err) - } - params.Add(key, string(jsonParam)) - } else { - params.Add(key, paramsMap[key].(string)) - } - } - requestURL.RawQuery = params.Encode() - } - - headers := map[string][]string{ - "Content-Type": []string{"application/json"}, - "Accept": []string{"*/*"}, - } - jsonHeaders, err := json.Marshal(headers) - if err != nil { - return errors.Errorf("Couldn't marshal analytics headers: %v", err) - } - - args := []string{DEFERRED_REQUEST_COMMAND, "POST", base64.StdEncoding.EncodeToString([]byte(requestURL.String())), base64.StdEncoding.EncodeToString(jsonHeaders), base64.StdEncoding.EncodeToString(jsonRequestBody)} - executable, err := os.Executable() - if err != nil { - executable = os.Args[0] - } - - cmd := exec.Command(executable, args...) - - return cmd.Start() - } - return nil -} - -// HandleDeferredRequest sends a request if args are: executable, DEFERRED_REQUEST_COMMAND -func (a *analyticsConfig) HandleDeferredRequest() error { - if len(os.Args) < 5 || os.Args[1] != DEFERRED_REQUEST_COMMAND { - return nil - } - - httpMethod := os.Args[2] - requestURL, err := base64.StdEncoding.DecodeString(os.Args[3]) - if err != nil { - return errors.Errorf("Couldn't base64.decode request URL: %v", err) - } - - jsonRequestHeaders, err := base64.StdEncoding.DecodeString(os.Args[4]) - if err != nil { - return errors.Errorf("Couldn't base64.decode request headers: %v", err) - } - - requestBody := []byte{} - if len(os.Args) > 5 { - requestBody, err = base64.StdEncoding.DecodeString(os.Args[5]) - if err != nil { - return errors.Errorf("Couldn't base64.decode request body: %v", err) - } - } - - requestHeaders := map[string][]string{} - err = json.Unmarshal([]byte(jsonRequestHeaders), &requestHeaders) - if err != nil { - return errors.Errorf("Couldn't unmarshal request headers: %v", err) - } - - request, err := http.NewRequest(httpMethod, string(requestURL), bytes.NewBuffer(requestBody)) - if err != nil { - return errors.Errorf("Error creating request to analytics endpoint: %v", err) - } - request.Header = requestHeaders - client := &http.Client{} - - response, err := client.Do(request) - if err != nil { - return errors.Errorf("Error sending request to analytics endpoint: %v", err) - } - defer response.Body.Close() - body, _ := ioutil.ReadAll(response.Body) - - if response.StatusCode != 200 { - return fmt.Errorf("Analytics returned HTTP code %d: %s", response.StatusCode, body) - } - - os.Exit(0) - - return nil -} - -func (a *analyticsConfig) resetDistinctID() error { - DistinctID, err := uuid.NewRandom() - if err != nil { - return errors.Errorf("Couldn't create UUID: %v", err) - } - a.DistinctID = DistinctID.String() - - return nil -} - -func (a *analyticsConfig) save() error { - analyticsConfigFilePath, err := a.getAnalyticsConfigFilePath() - if err != nil { - return errors.Errorf("Couldn't determine config file: %v", err) - } - - err = yamlutil.WriteYamlToFile(a, analyticsConfigFilePath) - if err != nil { - return errors.Errorf("Couldn't save analytics config file %s: %v", analyticsConfigFilePath, err) - } - return nil -} - -func (a *analyticsConfig) getAnalyticsConfigFilePath() (string, error) { - homedir, err := homedir.Dir() - if err != nil { - return "", err - } - - return filepath.Join(homedir, analyticsConfigFile), nil -} - -// GetAnalytics retrieves the analytics client -func GetAnalytics() (Analytics, error) { - var err error - - loadAnalyticsOnce.Do(func() { - analyticsInstance = &analyticsConfig{ - kubeLoader: kubeconfig.NewLoader(), - } - - analyticsConfigFilePath, err := analyticsInstance.getAnalyticsConfigFilePath() - if err != nil { - err = errors.Errorf("Couldn't determine config file: %v", err) - return - } - _, err = os.Stat(analyticsConfigFilePath) - if err == nil { - err := yamlutil.ReadYamlFromFile(analyticsConfigFilePath, analyticsInstance) - if err != nil { - err = errors.Errorf("Couldn't read analytics config file %s: %v", analyticsConfigFilePath, err) - return - } - } - - if analyticsInstance.DistinctID == "" { - err = analyticsInstance.resetDistinctID() - if err != nil { - err = errors.Errorf("Couldn't reset analytics distinct id: %v", err) - return - } - - err = analyticsInstance.save() - if err != nil { - err = errors.Errorf("Couldn't save analytics config: %v", err) - return - } - } - - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - go func() { - defer func() { - if r := recover(); r != nil { - // Fail silently - } - }() - - <-c - - analyticsInstance.SendCommandEvent(os.Args, errors.New("interrupted"), GetProcessDuration()) - signal.Stop(c) - - pid := os.Getpid() - sigterm(pid) - }() - }) - return analyticsInstance, err -} - -// SetConfigPath sets the config patch -func SetConfigPath(path string) { - analyticsConfigFile = path -} - -// GetProcessDuration returns the process duration -func GetProcessDuration() int64 { - pid := os.Getpid() - p, err := process.NewProcess(int32(pid)) - if err == nil { - procCreateTime, err := p.CreateTime() - if err == nil { - return time.Now().UnixNano()/int64(time.Millisecond) - procCreateTime - } - } - - return 0 -} diff --git a/pkg/util/analytics/cloudanalytics/start.go b/pkg/util/analytics/cloudanalytics/start.go deleted file mode 100644 index 5bdbd27fda..0000000000 --- a/pkg/util/analytics/cloudanalytics/start.go +++ /dev/null @@ -1,67 +0,0 @@ -package cloudanalytics - -import ( - "github.com/devspace-cloud/devspace/pkg/devspace/config/constants" - "github.com/devspace-cloud/devspace/pkg/util/analytics" - "os" -) - -// ReportPanics resolves a panic -func ReportPanics() { - defer func() { - if r := recover(); r != nil { - // Fail silently - } - }() - - a, err := analytics.GetAnalytics() - if err != nil { - return - } - - a.ReportPanics() -} - -// SendCommandEvent sends a new event to the analytics provider -func SendCommandEvent(commandErr error) { - defer func() { - if r := recover(); r != nil { - // Fail silently - } - }() - - a, err := analytics.GetAnalytics() - if err != nil { - return - } - - a.SendCommandEvent(os.Args, commandErr, analytics.GetProcessDuration()) -} - -// Start initializes the analytics -func Start(version string) { - defer func() { - if r := recover(); r != nil { - // Fail silently - } - }() - - analytics.SetConfigPath(constants.DefaultHomeDevSpaceFolder + "/analytics.yaml") - - analytics, err := analytics.GetAnalytics() - if err != nil { - return - } - - analytics.SetVersion(version) - analytics.SetIdentifyProvider(getIdentity) - err = analytics.HandleDeferredRequest() - if err != nil { - // ignore error - } -} - -// getIdentity return the cloud identifier -func getIdentity() string { - return "" -} diff --git a/pkg/util/analytics/sigterm.go b/pkg/util/analytics/sigterm.go deleted file mode 100644 index 374379cd23..0000000000 --- a/pkg/util/analytics/sigterm.go +++ /dev/null @@ -1,16 +0,0 @@ -// +build !windows - -package analytics - -import ( - "os" -) - -func sigterm(pid int) { - p, err := os.FindProcess(pid) - if err != nil { - return - } - - p.Signal(os.Interrupt) -} diff --git a/pkg/util/analytics/sigterm_win.go b/pkg/util/analytics/sigterm_win.go deleted file mode 100644 index 44c60b4ee6..0000000000 --- a/pkg/util/analytics/sigterm_win.go +++ /dev/null @@ -1,25 +0,0 @@ -// +build windows - -package analytics - -import ( - "os" - "syscall" -) - -func sigterm(pid int) { - d, e := syscall.LoadDLL("kernel32.dll") - if e != nil { - return - } - - p, e := d.FindProc("GenerateConsoleCtrlEvent") - if e != nil { - return - } - - r, _, _ := p.Call(uintptr(syscall.CTRL_C_EVENT), uintptr(pid)) - if r != 0 { - os.Exit(1) - } -} diff --git a/ui/package.json b/ui/package.json index 77961a0644..fdd36f19c2 100644 --- a/ui/package.json +++ b/ui/package.json @@ -67,9 +67,6 @@ "whatwg-fetch": "2.0.3", "xterm": "4.1.0" }, - "optionalDependencies": { - "@devspace/react-components": "0.1.5" - }, "scripts": { "start": "cross-env NODE_ENV=development node scripts/start.js", "build": "node scripts/build.js" diff --git a/ui/src/components/advanced/SupportChat/SupportChat.tsx b/ui/src/components/advanced/SupportChat/SupportChat.tsx deleted file mode 100644 index 0ba5bbf9ab..0000000000 --- a/ui/src/components/advanced/SupportChat/SupportChat.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import withDevSpaceConfig, { DevSpaceConfigContext } from 'contexts/withDevSpaceConfig/withDevSpaceConfig'; - -interface Props extends DevSpaceConfigContext {} -interface State {} - -class SupportChat extends React.PureComponent { - - render() { - let optionalComponent; - - try { - const Chat = require("@devspace/react-components").Chat; - const Analytics = require("@devspace/react-components").Analytics; - - optionalComponent = ( -
- - {this.props.devSpaceConfig.analyticsEnabled && - - } -
- ); - } catch (e) { - console.log("Not loading optional components in dev mode.") - } - - return ( -
- - {optionalComponent} - -