diff --git a/cmd/state-svc/internal/resolver/resolver.go b/cmd/state-svc/internal/resolver/resolver.go index cdfc5d1a99..92b3bba7a5 100644 --- a/cmd/state-svc/internal/resolver/resolver.go +++ b/cmd/state-svc/internal/resolver/resolver.go @@ -10,7 +10,6 @@ import ( "time" "github.com/ActiveState/cli/cmd/state-svc/internal/messages" - "github.com/ActiveState/cli/cmd/state-svc/internal/rtusage" "github.com/ActiveState/cli/cmd/state-svc/internal/rtwatcher" genserver "github.com/ActiveState/cli/cmd/state-svc/internal/server/generated" "github.com/ActiveState/cli/internal/analytics/client/sync" @@ -36,7 +35,6 @@ type Resolver struct { messages *messages.Messages updatePoller *poller.Poller authPoller *poller.Poller - usageChecker *rtusage.Checker projectIDCache *projectcache.ID an *sync.Client anForClient *sync.Client // Use separate client for events sent through service so we don't contaminate one with the other @@ -73,8 +71,6 @@ func New(cfg *config.Instance, an *sync.Client, auth *authentication.Auth) (*Res return nil, nil }) - usageChecker := rtusage.NewChecker(cfg, auth) - // Note: source does not matter here, as analytics sent via the resolver have a source // (e.g. State Tool or Executor), and that source will be used. anForClient := sync.New(anaConsts.SrcStateTool, cfg, auth, nil) @@ -83,7 +79,6 @@ func New(cfg *config.Instance, an *sync.Client, auth *authentication.Auth) (*Res msg, pollUpdate, pollAuth, - usageChecker, projectcache.NewID(), an, anForClient, @@ -235,29 +230,6 @@ func (r *Resolver) ReportRuntimeUsage(_ context.Context, pid int, exec, source s return &graph.ReportRuntimeUsageResponse{Received: true}, nil } -func (r *Resolver) CheckRuntimeUsage(_ context.Context, organizationName string) (*graph.CheckRuntimeUsageResponse, error) { - defer func() { handlePanics(recover(), debug.Stack()) }() - - logging.Debug("CheckRuntimeUsage resolver") - - usage, err := r.usageChecker.Check(organizationName) - if err != nil { - return nil, errs.Wrap(err, "Could not check runtime usage: %s", errs.JoinMessage(err)) - } - - if usage == nil { - return &graph.CheckRuntimeUsageResponse{ - Limit: 1, - Usage: 0, - }, nil - } - - return &graph.CheckRuntimeUsageResponse{ - Limit: int(usage.LimitDynamicRuntimes), - Usage: int(usage.ActiveDynamicRuntimes), - }, nil -} - func (r *Resolver) CheckMessages(ctx context.Context, command string, flags []string) ([]*graph.MessageInfo, error) { defer func() { handlePanics(recover(), debug.Stack()) }() logging.Debug("Check messages resolver") diff --git a/cmd/state-svc/internal/rtusage/rtusage.go b/cmd/state-svc/internal/rtusage/rtusage.go deleted file mode 100644 index a2404ccc62..0000000000 --- a/cmd/state-svc/internal/rtusage/rtusage.go +++ /dev/null @@ -1,84 +0,0 @@ -package rtusage - -import ( - "time" - - "github.com/patrickmn/go-cache" - - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/pkg/platform/api/graphql" - "github.com/ActiveState/cli/pkg/platform/api/graphql/model" - "github.com/ActiveState/cli/pkg/platform/api/graphql/request" - "github.com/ActiveState/cli/pkg/platform/authentication" -) - -const cacheKey = "runtime-usage-" - -// Checker is the struct that we use to do checks with -type Checker struct { - config configurable - cache *cache.Cache - auth *authentication.Auth -} - -// configurable defines the configuration function used by the functions in this package -type configurable interface { - ConfigPath() string - GetTime(key string) time.Time - Set(key string, value interface{}) error - Close() error -} - -// NewChecker returns a new instance of the Checker struct -func NewChecker(configuration configurable, auth *authentication.Auth) *Checker { - checker := &Checker{ - configuration, - cache.New(1*time.Hour, 1*time.Hour), - auth, - } - - return checker -} - -// Check will check the runtime usage for the given organization, it may return a cached result -func (c *Checker) Check(organizationName string) (*model.RuntimeUsage, error) { - if cached, ok := c.cache.Get(cacheKey + organizationName); ok { - return cached.(*model.RuntimeUsage), nil - } - - if err := c.auth.Refresh(); err != nil { - return nil, errs.Wrap(err, "Could not refresh authentication") - } - - if !c.auth.Authenticated() { - // Usage information can only be given to authenticated users, and the API doesn't support authentication errors - // so we just don't even attempt it if not authenticated. - return nil, nil - } - - client := graphql.New() - - orgsResponse := model.Organizations{} - if err := client.Run(request.OrganizationsByName(organizationName), &orgsResponse); err != nil { - return nil, errs.Wrap(err, "Could not fetch organization: %s", organizationName) - } - if len(orgsResponse.Organizations) == 0 { - return nil, errs.New("Could not find organization: %s", organizationName) - } - org := orgsResponse.Organizations[0] - - usageResponse := model.RuntimeUsageResponse{} - if err := client.Run(request.RuntimeUsage(org.ID), &usageResponse); err != nil { - return nil, errs.Wrap(err, "Could not fetch runtime usage information") - } - - if len(usageResponse.Usage) == 0 { - logging.Debug("No runtime usage information found for organization: %s", organizationName) - return nil, nil - } - - c.cache.Set(cacheKey+organizationName, &usageResponse.Usage[0], 0) - - return &usageResponse.Usage[0], nil -} diff --git a/cmd/state-svc/internal/server/generated/generated.go b/cmd/state-svc/internal/server/generated/generated.go index 59cc4344fc..4c20a755d2 100644 --- a/cmd/state-svc/internal/server/generated/generated.go +++ b/cmd/state-svc/internal/server/generated/generated.go @@ -54,11 +54,6 @@ type ComplexityRoot struct { Version func(childComplexity int) int } - CheckRuntimeUsageResponse struct { - Limit func(childComplexity int) int - Usage func(childComplexity int) int - } - ConfigChangedResponse struct { Received func(childComplexity int) int } @@ -81,7 +76,6 @@ type ComplexityRoot struct { AnalyticsEvent func(childComplexity int, category string, action string, source string, label *string, dimensionsJSON string) int AvailableUpdate func(childComplexity int, desiredChannel string, desiredVersion string) int CheckMessages func(childComplexity int, command string, flags []string) int - CheckRuntimeUsage func(childComplexity int, organizationName string) int ConfigChanged func(childComplexity int, key string) int FetchLogTail func(childComplexity int) int Projects func(childComplexity int) int @@ -112,7 +106,6 @@ type QueryResolver interface { Projects(ctx context.Context) ([]*graph.Project, error) AnalyticsEvent(ctx context.Context, category string, action string, source string, label *string, dimensionsJSON string) (*graph.AnalyticsEventResponse, error) ReportRuntimeUsage(ctx context.Context, pid int, exec string, source string, dimensionsJSON string) (*graph.ReportRuntimeUsageResponse, error) - CheckRuntimeUsage(ctx context.Context, organizationName string) (*graph.CheckRuntimeUsageResponse, error) CheckMessages(ctx context.Context, command string, flags []string) ([]*graph.MessageInfo, error) ConfigChanged(ctx context.Context, key string) (*graph.ConfigChangedResponse, error) FetchLogTail(ctx context.Context) (string, error) @@ -175,20 +168,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.AvailableUpdate.Version(childComplexity), true - case "CheckRuntimeUsageResponse.limit": - if e.complexity.CheckRuntimeUsageResponse.Limit == nil { - break - } - - return e.complexity.CheckRuntimeUsageResponse.Limit(childComplexity), true - - case "CheckRuntimeUsageResponse.usage": - if e.complexity.CheckRuntimeUsageResponse.Usage == nil { - break - } - - return e.complexity.CheckRuntimeUsageResponse.Usage(childComplexity), true - case "ConfigChangedResponse.received": if e.complexity.ConfigChangedResponse.Received == nil { break @@ -288,18 +267,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.CheckMessages(childComplexity, args["command"].(string), args["flags"].([]string)), true - case "Query.checkRuntimeUsage": - if e.complexity.Query.CheckRuntimeUsage == nil { - break - } - - args, err := ec.field_Query_checkRuntimeUsage_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.CheckRuntimeUsage(childComplexity, args["organizationName"].(string)), true - case "Query.configChanged": if e.complexity.Query.ConfigChanged == nil { break @@ -479,11 +446,6 @@ type ReportRuntimeUsageResponse { received: Boolean! } -type CheckRuntimeUsageResponse { - limit: Int! - usage: Int! -} - enum MessageRepeatType { Disabled Constantly @@ -519,7 +481,6 @@ type Query { projects: [Project]! analyticsEvent(category: String!, action: String!, source: String!, label: String, dimensionsJson: String!): AnalyticsEventResponse reportRuntimeUsage(pid: Int!, exec: String!, source: String!, dimensionsJson: String!): ReportRuntimeUsageResponse - checkRuntimeUsage(organizationName: String!): CheckRuntimeUsageResponse checkMessages(command: String!, flags: [String!]!): [MessageInfo!]! configChanged(key: String!): ConfigChangedResponse fetchLogTail: String! @@ -650,21 +611,6 @@ func (ec *executionContext) field_Query_checkMessages_args(ctx context.Context, return args, nil } -func (ec *executionContext) field_Query_checkRuntimeUsage_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 string - if tmp, ok := rawArgs["organizationName"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("organizationName")) - arg0, err = ec.unmarshalNString2string(ctx, tmp) - if err != nil { - return nil, err - } - } - args["organizationName"] = arg0 - return args, nil -} - func (ec *executionContext) field_Query_configChanged_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -1024,94 +970,6 @@ func (ec *executionContext) fieldContext_AvailableUpdate_sha256(ctx context.Cont return fc, nil } -func (ec *executionContext) _CheckRuntimeUsageResponse_limit(ctx context.Context, field graphql.CollectedField, obj *graph.CheckRuntimeUsageResponse) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_CheckRuntimeUsageResponse_limit(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Limit, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_CheckRuntimeUsageResponse_limit(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "CheckRuntimeUsageResponse", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _CheckRuntimeUsageResponse_usage(ctx context.Context, field graphql.CollectedField, obj *graph.CheckRuntimeUsageResponse) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_CheckRuntimeUsageResponse_usage(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Usage, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_CheckRuntimeUsageResponse_usage(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "CheckRuntimeUsageResponse", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - func (ec *executionContext) _ConfigChangedResponse_received(ctx context.Context, field graphql.CollectedField, obj *graph.ConfigChangedResponse) (ret graphql.Marshaler) { fc, err := ec.fieldContext_ConfigChangedResponse_received(ctx, field) if err != nil { @@ -1774,63 +1632,6 @@ func (ec *executionContext) fieldContext_Query_reportRuntimeUsage(ctx context.Co return fc, nil } -func (ec *executionContext) _Query_checkRuntimeUsage(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_checkRuntimeUsage(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().CheckRuntimeUsage(rctx, fc.Args["organizationName"].(string)) - }) - if err != nil { - ec.Error(ctx, err) - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*graph.CheckRuntimeUsageResponse) - fc.Result = res - return ec.marshalOCheckRuntimeUsageResponse2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐCheckRuntimeUsageResponse(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query_checkRuntimeUsage(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "limit": - return ec.fieldContext_CheckRuntimeUsageResponse_limit(ctx, field) - case "usage": - return ec.fieldContext_CheckRuntimeUsageResponse_usage(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type CheckRuntimeUsageResponse", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_checkRuntimeUsage_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return - } - return fc, nil -} - func (ec *executionContext) _Query_checkMessages(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Query_checkMessages(ctx, field) if err != nil { @@ -4309,41 +4110,6 @@ func (ec *executionContext) _AvailableUpdate(ctx context.Context, sel ast.Select return out } -var checkRuntimeUsageResponseImplementors = []string{"CheckRuntimeUsageResponse"} - -func (ec *executionContext) _CheckRuntimeUsageResponse(ctx context.Context, sel ast.SelectionSet, obj *graph.CheckRuntimeUsageResponse) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, checkRuntimeUsageResponseImplementors) - out := graphql.NewFieldSet(fields) - var invalids uint32 - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("CheckRuntimeUsageResponse") - case "limit": - - out.Values[i] = ec._CheckRuntimeUsageResponse_limit(ctx, field, obj) - - if out.Values[i] == graphql.Null { - invalids++ - } - case "usage": - - out.Values[i] = ec._CheckRuntimeUsageResponse_usage(ctx, field, obj) - - if out.Values[i] == graphql.Null { - invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch() - if invalids > 0 { - return graphql.Null - } - return out -} - var configChangedResponseImplementors = []string{"ConfigChangedResponse"} func (ec *executionContext) _ConfigChangedResponse(ctx context.Context, sel ast.SelectionSet, obj *graph.ConfigChangedResponse) graphql.Marshaler { @@ -4585,26 +4351,6 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) - case "checkRuntimeUsage": - field := field - - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_checkRuntimeUsage(ctx, field) - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) - } - out.Concurrently(i, func() graphql.Marshaler { return rrm(innerCtx) }) @@ -5620,13 +5366,6 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast return res } -func (ec *executionContext) marshalOCheckRuntimeUsageResponse2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐCheckRuntimeUsageResponse(ctx context.Context, sel ast.SelectionSet, v *graph.CheckRuntimeUsageResponse) graphql.Marshaler { - if v == nil { - return graphql.Null - } - return ec._CheckRuntimeUsageResponse(ctx, sel, v) -} - func (ec *executionContext) marshalOConfigChangedResponse2ᚖgithubᚗcomᚋActiveStateᚋcliᚋinternalᚋgraphᚐConfigChangedResponse(ctx context.Context, sel ast.SelectionSet, v *graph.ConfigChangedResponse) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/cmd/state-svc/schema/schema.graphqls b/cmd/state-svc/schema/schema.graphqls index 1cf1f47a3a..719f36a4eb 100644 --- a/cmd/state-svc/schema/schema.graphqls +++ b/cmd/state-svc/schema/schema.graphqls @@ -31,11 +31,6 @@ type ReportRuntimeUsageResponse { received: Boolean! } -type CheckRuntimeUsageResponse { - limit: Int! - usage: Int! -} - enum MessageRepeatType { Disabled Constantly @@ -71,7 +66,6 @@ type Query { projects: [Project]! analyticsEvent(category: String!, action: String!, source: String!, label: String, dimensionsJson: String!): AnalyticsEventResponse reportRuntimeUsage(pid: Int!, exec: String!, source: String!, dimensionsJson: String!): ReportRuntimeUsageResponse - checkRuntimeUsage(organizationName: String!): CheckRuntimeUsageResponse checkMessages(command: String!, flags: [String!]!): [MessageInfo!]! configChanged(key: String!): ConfigChangedResponse fetchLogTail: String! diff --git a/internal/constants/constants.go b/internal/constants/constants.go index eafa65e54e..c988044d5a 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -169,12 +169,6 @@ const AutostartPathOverrideEnvVarName = "ACTIVESTATE_CLI_AUTOSTARTPATH_OVERRIDE" // AppInstallDirOverrideEnvVarName is used to override the default app installation path of the state tool. const AppInstallDirOverrideEnvVarName = "ACTIVESTATE_CLI_APPINSTALLDIR_OVERRIDE" -// RuntimeUsageOverrideEnvVarName is used to override the default usage of the runtime intended for use in integration testing -const RuntimeUsageOverrideEnvVarName = "ACTIVESTATE_OVERRIDE_RTUSAGE_USAGE" - -// RuntimeUsageSilenceTimeOverrideEnvVarName is used to override the default usage of the runtime intended for use in integration testing -const RuntimeUsageSilenceTimeOverrideEnvVarName = "ACTIVESTATE_OVERRIDE_RTUSAGE_SILENCETIME" - // SvcAuthPollingRateEnvVarName is used to override the default polling rate for syncing the authenticated state with the svc const SvcAuthPollingRateEnvVarName = "ACTIVESTATE_SVC_AUTH_POLLING_RATE" diff --git a/internal/graph/generated.go b/internal/graph/generated.go index 62610a04aa..63ffae0a2e 100644 --- a/internal/graph/generated.go +++ b/internal/graph/generated.go @@ -20,11 +20,6 @@ type AvailableUpdate struct { Sha256 string `json:"sha256"` } -type CheckRuntimeUsageResponse struct { - Limit int `json:"limit"` - Usage int `json:"usage"` -} - type ConfigChangedResponse struct { Received bool `json:"received"` } diff --git a/internal/graph/response.go b/internal/graph/response.go index 390da408ea..358f416b6f 100644 --- a/internal/graph/response.go +++ b/internal/graph/response.go @@ -15,7 +15,3 @@ type AvailableUpdateResponse struct { type CheckMessagesResponse struct { Messages []*MessageInfo `json:"checkMessages"` } - -type CheckRuntimeUsageResponseOuter struct { - Usage CheckRuntimeUsageResponse `json:"checkRuntimeUsage"` -} diff --git a/internal/locale/locales/en-us.yaml b/internal/locale/locales/en-us.yaml index d409e30474..8813a80e7c 100644 --- a/internal/locale/locales/en-us.yaml +++ b/internal/locale/locales/en-us.yaml @@ -2039,19 +2039,6 @@ pjfile_deprecation_msg: {{.V1}} To find out how to update these please read the deprecation information at: [ACTIONABLE]{{.V2}}[/RESET] -runtime_usage_limit_reached: - other: | - [WARNING]Heads up! You've reached your runtime limit for [/RESET][ACTIONABLE]{{.V0}}[/RESET][WARNING].[/RESET] - [WARNING]You can upgrade your plan or enroll in a free trial by visiting: [/RESET][ACTIONABLE]https://platform.activestate.com/upgrade/?org={{.V0}}[/RESET][WARNING].[/RESET] - - [WARNING]You are using [/RESET][ACTIONABLE]{{.V1}}[/RESET][WARNING] out of [/RESET][ACTIONABLE]{{.V2}}[/RESET][WARNING] available runtimes.[/RESET] - -runtime_limit_reached_title: - other: Runtime Limit Reached -runtime_limit_reached_msg: - other: Heads up! You've reached your runtime limit for {{.V0}}. -runtime_limit_reached_action: - other: Upgrade pjfile_deprecation_entry: other: " - '[ACTIONABLE]{{.V0}}[/RESET]' located at byte [ACTIONABLE]{{.V1}}[/RESET]" err_init_authenticated: diff --git a/internal/runbits/requirements/requirements.go b/internal/runbits/requirements/requirements.go index 9c477f32a6..f89281cd54 100644 --- a/internal/runbits/requirements/requirements.go +++ b/internal/runbits/requirements/requirements.go @@ -21,7 +21,6 @@ import ( "github.com/ActiveState/cli/internal/prompt" "github.com/ActiveState/cli/internal/rtutils/ptr" "github.com/ActiveState/cli/internal/runbits" - "github.com/ActiveState/cli/internal/runbits/rtusage" "github.com/ActiveState/cli/pkg/localcommit" bpModel "github.com/ActiveState/cli/pkg/platform/api/buildplanner/model" medmodel "github.com/ActiveState/cli/pkg/platform/api/mediator/model" @@ -144,8 +143,6 @@ func (r *RequirementOperation) ExecuteRequirementOperation(requirementName, requ ns = model.NewNamespacePlatform() } - rtusage.PrintRuntimeUsage(r.SvcModel, out, pj.Owner()) - var validatePkg = operation == bpModel.OperationAdded && (ns.Type() == model.NamespacePackage || ns.Type() == model.NamespaceBundle) if !ns.IsValid() && (nsType == model.NamespacePackage || nsType == model.NamespaceBundle) { pg = output.StartSpinner(out, locale.Tl("progress_pkg_nolang", "", requirementName), constants.TerminalAnimationInterval) diff --git a/internal/runbits/rtusage/rtusage.go b/internal/runbits/rtusage/rtusage.go deleted file mode 100644 index 4292319548..0000000000 --- a/internal/runbits/rtusage/rtusage.go +++ /dev/null @@ -1,100 +0,0 @@ -package rtusage - -import ( - "context" - "os" - "strconv" - "time" - - "github.com/ActiveState/cli/internal/config" - "github.com/ActiveState/cli/internal/constants" - "github.com/ActiveState/cli/internal/errs" - "github.com/ActiveState/cli/internal/graph" - "github.com/ActiveState/cli/internal/locale" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/cli/internal/multilog" - "github.com/ActiveState/cli/internal/notify" - "github.com/ActiveState/cli/internal/output" -) - -const CfgKeyLastNotify = "notify.rtusage.last" - -type dataHandler interface { - CheckRuntimeUsage(ctx context.Context, organizationName string) (*graph.CheckRuntimeUsageResponse, error) -} - -func PrintRuntimeUsage(data dataHandler, out output.Outputer, orgName string) { - if orgName == "" { - return - } - - logging.Debug("Checking to print runtime usage for %s", orgName) - - res, err := data.CheckRuntimeUsage(context.Background(), orgName) - if err != nil { - // Runtime usage is not enforced, so any errors should not interrupt the user either - multilog.Error("Could not check runtime usage: %v", errs.JoinMessage(err)) - return - } - - usage := res.Usage - if override := os.Getenv(constants.RuntimeUsageOverrideEnvVarName); override != "" { - logging.Debug("Overriding usage with %s", override) - usage, _ = strconv.Atoi(override) - } - - if usage > res.Limit { - out.Notice(locale.Tr("runtime_usage_limit_reached", orgName, strconv.Itoa(usage), strconv.Itoa(res.Limit))) - } -} - -func NotifyRuntimeUsage(cfg *config.Instance, data dataHandler, orgName string) { - if orgName == "" { - return - } - - res, err := data.CheckRuntimeUsage(context.Background(), orgName) - if err != nil { - multilog.Error("Soft limit: Failed to check runtime usage in heartbeat handler: %s", errs.JoinMessage(err)) - return - } - - usage := res.Usage - if override := os.Getenv(constants.RuntimeUsageOverrideEnvVarName); override != "" { - logging.Debug("Overriding usage with %s", override) - usage, _ = strconv.Atoi(override) - } - - if usage <= res.Limit { - return - } - - // Override silence time - silenceMs := time.Hour.Milliseconds() - if override := os.Getenv(constants.RuntimeUsageSilenceTimeOverrideEnvVarName); override != "" { - overrideInt, err := strconv.ParseInt(override, 10, 64) - if err != nil { - logging.Error("Failed to parse runtime usage silence time override: %v", err) - } else { - silenceMs = overrideInt - } - } - - // Don't notify if we already notified recently - if time.Now().Sub(cfg.GetTime(CfgKeyLastNotify)).Milliseconds() <= silenceMs { - return - } - - if err := cfg.Set(CfgKeyLastNotify, time.Now()); err != nil { - multilog.Error("Soft limit: Failed to set last notify time: %s", errs.JoinMessage(err)) - return - } - - err2 := notify.Send(locale.T("runtime_limit_reached_title"), - locale.Tr("runtime_limit_reached_msg", orgName), - locale.T("runtime_limit_reached_action"), - "state://platform/upgrade/?org="+orgName) // We have to use the state protocol because https:// is backgrounded by the OS - if err2 != nil { - multilog.Error("Soft limit: Failed to send notification: %s", errs.JoinMessage(err)) - } -} diff --git a/internal/runners/activate/activate.go b/internal/runners/activate/activate.go index 3e1cd8289e..1088ed9698 100644 --- a/internal/runners/activate/activate.go +++ b/internal/runners/activate/activate.go @@ -23,7 +23,6 @@ import ( "github.com/ActiveState/cli/internal/prompt" "github.com/ActiveState/cli/internal/runbits/activation" "github.com/ActiveState/cli/internal/runbits/findproject" - "github.com/ActiveState/cli/internal/runbits/rtusage" "github.com/ActiveState/cli/internal/runbits/runtime" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/virtualenvironment" @@ -106,8 +105,6 @@ func (r *Activate) Run(params *ActivateParams) (rerr error) { } } - rtusage.PrintRuntimeUsage(r.svcModel, r.out, proj.Owner()) - alreadyActivated := process.IsActivated(r.config) if alreadyActivated { if !params.Default { diff --git a/internal/runners/checkout/checkout.go b/internal/runners/checkout/checkout.go index aeaa8b9d4e..2f5b18fec8 100644 --- a/internal/runners/checkout/checkout.go +++ b/internal/runners/checkout/checkout.go @@ -8,7 +8,6 @@ import ( "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" - "github.com/ActiveState/cli/internal/runbits/rtusage" "github.com/ActiveState/cli/internal/runbits/runtime" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/pkg/cmdlets/checker" @@ -78,8 +77,6 @@ func (u *Checkout) Run(params *Params) (rerr error) { return locale.WrapError(err, "err_project_frompath") } - rtusage.PrintRuntimeUsage(u.svcModel, u.out, proj.Owner()) - rti, err := runtime.NewFromProject(proj, target.TriggerCheckout, u.analytics, u.svcModel, u.out, u.auth) if err != nil { return locale.WrapError(err, "err_checkout_runtime_new", "Could not checkout this project.") diff --git a/internal/runners/deploy/deploy.go b/internal/runners/deploy/deploy.go index 695d9a424b..58472b4381 100644 --- a/internal/runners/deploy/deploy.go +++ b/internal/runners/deploy/deploy.go @@ -23,7 +23,6 @@ import ( "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/rtutils" "github.com/ActiveState/cli/internal/runbits" - "github.com/ActiveState/cli/internal/runbits/rtusage" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/subshell/sscommon" "github.com/ActiveState/cli/pkg/platform/authentication" @@ -156,8 +155,6 @@ func (d *Deploy) commitID(namespace project.Namespaced) (strfmt.UUID, error) { func (d *Deploy) install(rtTarget setup.Targeter) (rerr error) { d.output.Notice(output.Title(locale.T("deploy_install"))) - rtusage.PrintRuntimeUsage(d.svcModel, d.output, rtTarget.Owner()) - rti, err := runtime.New(rtTarget, d.analytics, d.svcModel, d.auth) if err == nil { d.output.Notice(locale.Tl("deploy_already_installed", "Already installed")) diff --git a/internal/runners/exec/exec.go b/internal/runners/exec/exec.go index a14db66663..bb0b174ead 100644 --- a/internal/runners/exec/exec.go +++ b/internal/runners/exec/exec.go @@ -23,7 +23,6 @@ import ( "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/rtutils" "github.com/ActiveState/cli/internal/runbits" - "github.com/ActiveState/cli/internal/runbits/rtusage" "github.com/ActiveState/cli/internal/scriptfile" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/virtualenvironment" @@ -121,8 +120,6 @@ func (s *Exec) Run(params *Params, args ...string) (rerr error) { rtTarget = target.NewProjectTarget(proj, nil, trigger) } - rtusage.PrintRuntimeUsage(s.svcModel, s.out, rtTarget.Owner()) - s.out.Notice(locale.Tl("operating_message", "", projectNamespace, projectDir)) rt, err := runtime.New(rtTarget, s.analytics, s.svcModel, s.auth) diff --git a/internal/runners/pull/pull.go b/internal/runners/pull/pull.go index e20eae3560..7d0a96872e 100644 --- a/internal/runners/pull/pull.go +++ b/internal/runners/pull/pull.go @@ -15,7 +15,6 @@ import ( "github.com/ActiveState/cli/internal/prompt" "github.com/ActiveState/cli/internal/runbits" buildscriptRunbits "github.com/ActiveState/cli/internal/runbits/buildscript" - "github.com/ActiveState/cli/internal/runbits/rtusage" "github.com/ActiveState/cli/pkg/cmdlets/commit" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" @@ -84,8 +83,6 @@ func (p *Pull) Run(params *PullParams) error { } p.out.Notice(locale.Tl("operating_message", "", p.project.NamespaceString(), p.project.Dir())) - rtusage.PrintRuntimeUsage(p.svcModel, p.out, p.project.Owner()) - if p.project.IsHeadless() && params.SetProject == "" { return locale.NewInputError("err_pull_headless", "You must first create a project. Please visit {{.V0}} to create your project.", p.project.URL()) } diff --git a/internal/runners/refresh/refresh.go b/internal/runners/refresh/refresh.go index 28c94dcdee..05361977cb 100644 --- a/internal/runners/refresh/refresh.go +++ b/internal/runners/refresh/refresh.go @@ -10,7 +10,6 @@ import ( "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/prompt" "github.com/ActiveState/cli/internal/runbits/findproject" - "github.com/ActiveState/cli/internal/runbits/rtusage" "github.com/ActiveState/cli/internal/runbits/runtime" "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" @@ -64,8 +63,6 @@ func (r *Refresh) Run(params *Params) error { return locale.WrapError(err, "err_refresh_cannot_load_project", "Cannot load project to update runtime for") } - rtusage.PrintRuntimeUsage(r.svcModel, r.out, proj.Owner()) - rti, err := runtime.NewFromProject(proj, target.TriggerRefresh, r.analytics, r.svcModel, r.out, r.auth) if err != nil { return locale.WrapInputError(err, "err_refresh_runtime_new", "Could not update runtime for this project.") diff --git a/internal/runners/run/run.go b/internal/runners/run/run.go index 875c31f1bd..6037ee2042 100644 --- a/internal/runners/run/run.go +++ b/internal/runners/run/run.go @@ -10,7 +10,6 @@ import ( "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" - "github.com/ActiveState/cli/internal/runbits/rtusage" "github.com/ActiveState/cli/internal/scriptrun" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/pkg/cmdlets/checker" @@ -61,7 +60,6 @@ func (r *Run) Run(name string, args []string) error { return locale.NewInputError("err_no_project") } - rtusage.PrintRuntimeUsage(r.svcModel, r.out, r.proj.Owner()) checker.RunUpdateNotifier(r.analytics, r.svcModel, r.out) r.out.Notice(locale.Tl("operating_message", "", r.proj.NamespaceString(), r.proj.Dir())) diff --git a/internal/runners/shell/shell.go b/internal/runners/shell/shell.go index 7ecd8f2a45..00a3077332 100644 --- a/internal/runners/shell/shell.go +++ b/internal/runners/shell/shell.go @@ -12,7 +12,6 @@ import ( "github.com/ActiveState/cli/internal/prompt" "github.com/ActiveState/cli/internal/runbits/activation" "github.com/ActiveState/cli/internal/runbits/findproject" - "github.com/ActiveState/cli/internal/runbits/rtusage" "github.com/ActiveState/cli/internal/runbits/runtime" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/internal/virtualenvironment" @@ -73,8 +72,6 @@ func (u *Shell) Run(params *Params) error { return locale.WrapError(err, "err_shell_cannot_load_project") } - rtusage.PrintRuntimeUsage(u.svcModel, u.out, proj.Owner()) - commitID, err := localcommit.Get(proj.Dir()) if err != nil { return errs.Wrap(err, "Unable to get local commit") diff --git a/internal/runners/swtch/switch.go b/internal/runners/swtch/switch.go index bdb1a6f1ac..1f63120613 100644 --- a/internal/runners/swtch/switch.go +++ b/internal/runners/swtch/switch.go @@ -8,7 +8,6 @@ import ( "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/runbits" - "github.com/ActiveState/cli/internal/runbits/rtusage" "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" "github.com/ActiveState/cli/pkg/platform/authentication" @@ -86,8 +85,6 @@ func (s *Switch) Run(params SwitchParams) error { } s.out.Notice(locale.Tl("operating_message", "", s.project.NamespaceString(), s.project.Dir())) - rtusage.PrintRuntimeUsage(s.svcModel, s.out, s.project.Owner()) - project, err := model.LegacyFetchProjectByName(s.project.Owner(), s.project.Name()) if err != nil { return locale.WrapError(err, "err_fetch_project", "", s.project.Namespace().String()) diff --git a/internal/runners/use/use.go b/internal/runners/use/use.go index 19b5307270..fbf4a09199 100644 --- a/internal/runners/use/use.go +++ b/internal/runners/use/use.go @@ -13,7 +13,6 @@ import ( "github.com/ActiveState/cli/internal/primer" "github.com/ActiveState/cli/internal/prompt" "github.com/ActiveState/cli/internal/runbits/findproject" - "github.com/ActiveState/cli/internal/runbits/rtusage" "github.com/ActiveState/cli/internal/runbits/runtime" "github.com/ActiveState/cli/internal/subshell" "github.com/ActiveState/cli/pkg/cmdlets/checker" @@ -78,8 +77,6 @@ func (u *Use) Run(params *Params) error { return locale.WrapInputError(err, "err_use_cannot_find_local_project", "Local project cannot be found.") } - rtusage.PrintRuntimeUsage(u.svcModel, u.out, proj.Owner()) - commitID, err := localcommit.Get(proj.Dir()) if err != nil { return errs.Wrap(err, "Unable to get local commit") diff --git a/internal/svcctl/comm.go b/internal/svcctl/comm.go index 6d07662837..f02938d153 100644 --- a/internal/svcctl/comm.go +++ b/internal/svcctl/comm.go @@ -18,11 +18,9 @@ import ( "github.com/ActiveState/cli/internal/multilog" "github.com/ActiveState/cli/internal/rtutils/ptr" "github.com/ActiveState/cli/internal/runbits/panics" - "github.com/ActiveState/cli/internal/runbits/rtusage" "github.com/ActiveState/cli/internal/svcctl/svcmsg" "github.com/ActiveState/cli/pkg/platform/runtime/executors/execmeta" "github.com/ActiveState/cli/pkg/platform/runtime/target" - "github.com/ActiveState/cli/pkg/project" ) var ( @@ -75,7 +73,6 @@ func (c *Comm) GetLogFileName(ctx context.Context) (string, error) { type Resolver interface { ReportRuntimeUsage(ctx context.Context, pid int, exec, source string, dimensionsJSON string) (*graph.ReportRuntimeUsageResponse, error) - CheckRuntimeUsage(ctx context.Context, organizationName string) (*graph.CheckRuntimeUsageResponse, error) } type AnalyticsReporter interface { @@ -128,17 +125,6 @@ func HeartbeatHandler(cfg *config.Instance, resolver Resolver, analyticsReporter return } - // Soft limit notification - logging.Debug("Checking runtime usage for %s", metaData.Namespace) - if metaData.Namespace != "" { - ns, err := project.ParseNamespace(metaData.Namespace) - if err != nil { - multilog.Error("Soft limit: Could not parse namespace in heartbeat handler: %s", err) - } else { - rtusage.NotifyRuntimeUsage(cfg, resolver, ns.Owner) - } - } - logging.Debug("Firing runtime usage events for %s", metaData.Namespace) analyticsReporter.EventWithSource(constants.CatRuntimeUsage, constants.ActRuntimeAttempt, constants.SrcExecutor, dims) _, err = resolver.ReportRuntimeUsage(context.Background(), pidNum, hb.ExecPath, constants.SrcExecutor, dimsJSON) diff --git a/internal/testhelpers/tagsuite/tagsuite.go b/internal/testhelpers/tagsuite/tagsuite.go index 5bd97c8838..2fb0fe4783 100644 --- a/internal/testhelpers/tagsuite/tagsuite.go +++ b/internal/testhelpers/tagsuite/tagsuite.go @@ -72,7 +72,6 @@ const ( Commit = "commit" Performance = "performance" Service = "service" - SoftLimit = "softlimit" Executor = "executor" Deprecation = "deprecation" Compatibility = "compatibility" diff --git a/pkg/platform/api/graphql/request/usage.go b/pkg/platform/api/graphql/request/usage.go deleted file mode 100644 index 8b5f9a0d42..0000000000 --- a/pkg/platform/api/graphql/request/usage.go +++ /dev/null @@ -1,40 +0,0 @@ -package request - -import ( - "time" - - "github.com/go-openapi/strfmt" - - "github.com/ActiveState/cli/pkg/platform/api/graphql/model" -) - -// RuntimeUsage reports rtusage for the last 8 days, ensuring we reach into the previous week regardless of timezone. -// The use-case of this function is to get the current rtusage, but in order to do this we have to request the last 78 -// days rather than the current time, because the week field does not have timezone data, and so requesting the current -// date will result in timezone miss-match issues. -// It is then up to the consuming code to use the most recent rtusage week (ie. the first element in the slice) -func RuntimeUsage(organizationID strfmt.UUID) *usage { - return &usage{map[string]interface{}{ - "organization_id": organizationID, - "week": model.Date{time.Now().Add(-(8 * 24 * time.Hour))}, - }} -} - -type usage struct { - vars map[string]interface{} -} - -func (p *usage) Query() string { - return ` - query ($organization_id: uuid!, $week: date) { - organizations_runtime_usage(limit: 1, order_by: [{week_of: desc}], where: {_and: [{organization_id: {_eq: $organization_id}}, {week_of: {_gte: $week}}]}) { - limit_runtimes - active_runtimes - } - } - ` -} - -func (p *usage) Vars() map[string]interface{} { - return p.vars -} diff --git a/pkg/platform/api/svc/request/checkrtusage.go b/pkg/platform/api/svc/request/checkrtusage.go deleted file mode 100644 index 39afd606e4..0000000000 --- a/pkg/platform/api/svc/request/checkrtusage.go +++ /dev/null @@ -1,26 +0,0 @@ -package request - -type CheckRuntimeUsage struct { - organizationName string -} - -func NewCheckRuntimeUsage(organizationName string) *CheckRuntimeUsage { - return &CheckRuntimeUsage{ - organizationName: organizationName, - } -} - -func (e *CheckRuntimeUsage) Query() string { - return `query($organizationName: String!) { - checkRuntimeUsage(organizationName: $organizationName) { - limit - usage - } - }` -} - -func (e *CheckRuntimeUsage) Vars() map[string]interface{} { - return map[string]interface{}{ - "organizationName": e.organizationName, - } -} diff --git a/pkg/platform/model/svc.go b/pkg/platform/model/svc.go index 4a86d8b5f5..40d206614d 100644 --- a/pkg/platform/model/svc.go +++ b/pkg/platform/model/svc.go @@ -119,18 +119,6 @@ func (m *SvcModel) ReportRuntimeUsage(ctx context.Context, pid int, exec, source return nil } -func (m *SvcModel) CheckRuntimeUsage(ctx context.Context, organizationName string) (*graph.CheckRuntimeUsageResponse, error) { - defer profile.Measure("svc:CheckRuntimeUsage", time.Now()) - - r := request.NewCheckRuntimeUsage(organizationName) - u := graph.CheckRuntimeUsageResponseOuter{} - if err := m.request(ctx, r, &u); err != nil { - return nil, errs.Wrap(err, "Error sending check runtime usage event via state-svc") - } - - return &u.Usage, nil -} - func (m *SvcModel) CheckMessages(ctx context.Context, command string, flags []string) ([]*graph.MessageInfo, error) { logging.Debug("Checking for messages") defer profile.Measure("svc:CheckMessages", time.Now()) diff --git a/test/integration/softlimit_int_test.go b/test/integration/softlimit_int_test.go deleted file mode 100644 index 865fec663c..0000000000 --- a/test/integration/softlimit_int_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package integration - -import ( - "testing" - - "github.com/stretchr/testify/suite" - - "github.com/ActiveState/cli/internal/constants" - - "github.com/ActiveState/cli/internal/testhelpers/e2e" - "github.com/ActiveState/cli/internal/testhelpers/tagsuite" -) - -type SoftLimitIntegrationTestSuite struct { - tagsuite.Suite -} - -/* -Test several important paths for the soft limit notification to show. -We're not testing all possible paths as it would be too expensive both in terms of testing time as well as maintenance of those tests. -*/ -func (suite *SoftLimitIntegrationTestSuite) TestCheckout() { - suite.OnlyRunForTags(tagsuite.SoftLimit, tagsuite.Critical) - - ts := e2e.New(suite.T(), true) - defer ts.Close() - - ts.LoginAsPersistentUser() - - cp := ts.SpawnWithOpts( - e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "."), - e2e.OptAppendEnv(constants.RuntimeUsageOverrideEnvVarName+"=999"), - e2e.OptAppendEnv(constants.DisableRuntime+"=true"), // We're testing the usage, not the runtime - ) - cp.Expect("You've reached your runtime limit") - cp.ExpectExitCode(0) - - suite.Run("activate", func() { - cp := ts.SpawnWithOpts( - e2e.OptArgs("activate"), - e2e.OptAppendEnv(constants.RuntimeUsageOverrideEnvVarName+"=999"), - e2e.OptAppendEnv(constants.DisableRuntime+"=true"), - ) - cp.Expect("You've reached your runtime limit") - cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) - cp.ExpectInput() - cp.SendLine("exit 0") - cp.ExpectExitCode(0) - }) - - suite.Run("shell", func() { - cp := ts.SpawnWithOpts( - e2e.OptArgs("shell"), - e2e.OptAppendEnv(constants.RuntimeUsageOverrideEnvVarName+"=999"), - e2e.OptAppendEnv(constants.DisableRuntime+"=true"), - ) - cp.Expect("You've reached your runtime limit") - cp.Expect("Activated", e2e.RuntimeSourcingTimeoutOpt) - cp.ExpectInput() - cp.SendLine("exit 0") - cp.ExpectExitCode(0) - }) -} - -func TestSoftLimitIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(SoftLimitIntegrationTestSuite)) -}