diff --git a/backend/controller/controller.go b/backend/controller/controller.go index 8c3babbd52..654b1e2dd2 100644 --- a/backend/controller/controller.go +++ b/backend/controller/controller.go @@ -1531,7 +1531,7 @@ func (s *Service) watchModuleChanges(ctx context.Context, sendChange func(respon moduleRemoved := mostRecentDeploymentByModule[name] == deletion.String() response = &ftlv1.PullSchemaResponse{ ModuleName: name, - DeploymentKey: deletion.String(), + DeploymentKey: proto.String(deletion.String()), ChangeType: ftlv1.DeploymentChangeType_DEPLOYMENT_REMOVED, ModuleRemoved: moduleRemoved, } @@ -1571,7 +1571,7 @@ func (s *Service) watchModuleChanges(ctx context.Context, sendChange func(respon } response = &ftlv1.PullSchemaResponse{ ModuleName: moduleSchema.Name, - DeploymentKey: message.Key.String(), + DeploymentKey: proto.String(message.Key.String()), Schema: moduleSchema, ChangeType: changeType, ModuleRemoved: moduleRemoved, @@ -1581,7 +1581,7 @@ func (s *Service) watchModuleChanges(ctx context.Context, sendChange func(respon mostRecentDeploymentByModule[message.Schema.Name] = message.Key.String() response = &ftlv1.PullSchemaResponse{ ModuleName: moduleSchema.Name, - DeploymentKey: message.Key.String(), + DeploymentKey: proto.String(message.Key.String()), Schema: moduleSchema, ChangeType: ftlv1.DeploymentChangeType_DEPLOYMENT_ADDED, More: initialCount > 1, diff --git a/backend/controller/scaling/k8sscaling/deployment_provisioner.go b/backend/controller/scaling/k8sscaling/deployment_provisioner.go index 45f5ad8db2..5762d2f6dd 100644 --- a/backend/controller/scaling/k8sscaling/deployment_provisioner.go +++ b/backend/controller/scaling/k8sscaling/deployment_provisioner.go @@ -39,6 +39,7 @@ import ( ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" schemapb "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/schema" "github.com/TBD54566975/ftl/internal/log" + "github.com/TBD54566975/ftl/internal/model" ) const thisDeploymentName = "ftl-controller" @@ -54,7 +55,7 @@ type DeploymentProvisioner struct { MyDeploymentName string Namespace string // Map of known deployments - KnownDeployments *xsync.Map + KnownDeployments *xsync.MapOf[string, bool] FTLEndpoint string IstioSecurity optional.Option[istioclient.Clientset] } @@ -106,22 +107,26 @@ func (r *DeploymentProvisioner) handleSchemaChange(ctx context.Context, msg *ftl if !msg.More { defer r.deleteMissingDeployments(ctx) } - if msg.DeploymentKey == "" { + if msg.DeploymentKey == nil { // Builtins don't have deployments return nil } logger := log.FromContext(ctx) logger = logger.Module(msg.ModuleName) ctx = log.ContextWithLogger(ctx, logger) - logger.Debugf("Handling schema change for %s", msg.DeploymentKey) + deploymentKey, err := model.ParseDeploymentKey(msg.GetDeploymentKey()) + if err != nil { + return fmt.Errorf("failed to parse deployment key %s: %w", msg.GetDeploymentKey(), err) + } + logger.Debugf("Handling schema change for %s", deploymentKey) deploymentClient := r.Client.AppsV1().Deployments(r.Namespace) - deployment, err := deploymentClient.Get(ctx, msg.DeploymentKey, v1.GetOptions{}) + deployment, err := deploymentClient.Get(ctx, deploymentKey.String(), v1.GetOptions{}) deploymentExists := true if err != nil { if errors.IsNotFound(err) { deploymentExists = false } else { - return fmt.Errorf("failed to get deployment %s: %w", msg.DeploymentKey, err) + return fmt.Errorf("failed to get deployment %s: %w", deploymentKey, err) } } @@ -131,12 +136,12 @@ func (r *DeploymentProvisioner) handleSchemaChange(ctx context.Context, msg *ftl // Note that a change is now currently usually and add and a delete // As it should really be called a module changed, not a deployment changed // This will need to be fixed as part of the support for rolling deployments - r.KnownDeployments.Store(msg.DeploymentKey, true) + r.KnownDeployments.Store(deploymentKey.String(), true) if deploymentExists { - logger.Debugf("Updating deployment %s", msg.DeploymentKey) + logger.Debugf("Updating deployment %s", deploymentKey) return r.handleExistingDeployment(ctx, deployment, msg.Schema) } else { - return r.handleNewDeployment(ctx, msg.Schema, msg.DeploymentKey) + return r.handleNewDeployment(ctx, msg.Schema, deploymentKey.String()) } case ftlv1.DeploymentChangeType_DEPLOYMENT_REMOVED: if deploymentExists { @@ -145,9 +150,9 @@ func (r *DeploymentProvisioner) handleSchemaChange(ctx context.Context, msg *ftl // Nasty hack, we want all the controllers to have updated their route tables before we kill the runner // so we add a slight delay here time.Sleep(time.Second * 10) - r.KnownDeployments.Delete(msg.DeploymentKey) + r.KnownDeployments.Delete(deploymentKey.String()) logger.Debugf("Deleting service %s", msg.ModuleName) - err = r.Client.CoreV1().Services(r.Namespace).Delete(ctx, msg.DeploymentKey, v1.DeleteOptions{}) + err = r.Client.CoreV1().Services(r.Namespace).Delete(ctx, deploymentKey.String(), v1.DeleteOptions{}) if err != nil { if !errors.IsNotFound(err) { logger.Errorf(err, "Failed to delete service %s", msg.ModuleName) diff --git a/backend/controller/scaling/k8sscaling/k8s_scaling.go b/backend/controller/scaling/k8sscaling/k8s_scaling.go index 1e0547a19f..5bcc6a0460 100644 --- a/backend/controller/scaling/k8sscaling/k8s_scaling.go +++ b/backend/controller/scaling/k8sscaling/k8s_scaling.go @@ -61,7 +61,7 @@ func (k k8sScaling) Start(ctx context.Context, controller url.URL, leaser leases deploymentReconciler := &DeploymentProvisioner{ Client: clientset, Namespace: namespace, - KnownDeployments: xsync.NewMap(), + KnownDeployments: xsync.NewMapOf[string, bool](), FTLEndpoint: controller.String(), IstioSecurity: optional.Ptr(sec), } diff --git a/backend/controller/scaling/localscaling/local_scaling.go b/backend/controller/scaling/localscaling/local_scaling.go index 323816a9c5..d1a150e918 100644 --- a/backend/controller/scaling/localscaling/local_scaling.go +++ b/backend/controller/scaling/localscaling/local_scaling.go @@ -50,8 +50,9 @@ type localScaling struct { } type devModeRunner struct { - uri url.URL - deploymentKey string + uri url.URL + // Set to None under mysterious circumstances... + deploymentKey optional.Option[model.DeploymentKey] debugPort int } @@ -113,7 +114,7 @@ type deploymentInfo struct { runner optional.Option[runnerInfo] module string replicas int32 - key string + key model.DeploymentKey language string exits int } @@ -149,24 +150,28 @@ func NewLocalScaling(portAllocator *bind.BindAllocator, controllerAddresses []*u } func (l *localScaling) handleSchemaChange(ctx context.Context, msg *ftlv1.PullSchemaResponse) error { - if msg.DeploymentKey == "" { + if msg.DeploymentKey == nil { // Builtins don't have deployments return nil } + deploymentKey, err := model.ParseDeploymentKey(msg.GetDeploymentKey()) + if err != nil { + return fmt.Errorf("failed to parse deployment key: %w", err) + } l.lock.Lock() defer l.lock.Unlock() logger := log.FromContext(ctx).Scope("localScaling").Module(msg.ModuleName) ctx = log.ContextWithLogger(ctx, logger) - logger.Debugf("Handling schema change for %s", msg.DeploymentKey) + logger.Debugf("Handling schema change for %s", deploymentKey) moduleDeployments := l.runners[msg.ModuleName] if moduleDeployments == nil { moduleDeployments = map[string]*deploymentInfo{} l.runners[msg.ModuleName] = moduleDeployments } - deploymentRunners := moduleDeployments[msg.DeploymentKey] + deploymentRunners := moduleDeployments[deploymentKey.String()] if deploymentRunners == nil { - deploymentRunners = &deploymentInfo{runner: optional.None[runnerInfo](), key: msg.DeploymentKey, module: msg.ModuleName, language: msg.Schema.Runtime.Language} - moduleDeployments[msg.DeploymentKey] = deploymentRunners + deploymentRunners = &deploymentInfo{runner: optional.None[runnerInfo](), key: deploymentKey, module: msg.ModuleName, language: msg.Schema.Runtime.Language} + moduleDeployments[deploymentKey.String()] = deploymentRunners } switch msg.ChangeType { @@ -174,7 +179,7 @@ func (l *localScaling) handleSchemaChange(ctx context.Context, msg *ftlv1.PullSc deploymentRunners.replicas = msg.Schema.Runtime.MinReplicas case ftlv1.DeploymentChangeType_DEPLOYMENT_REMOVED: deploymentRunners.replicas = 0 - delete(moduleDeployments, msg.DeploymentKey) + delete(moduleDeployments, deploymentKey.String()) } return l.reconcileRunners(ctx, deploymentRunners) } @@ -203,7 +208,7 @@ func (l *localScaling) reconcileRunners(ctx context.Context, deploymentRunners * return nil } -func (l *localScaling) startRunner(ctx context.Context, deploymentKey string, info *deploymentInfo) error { +func (l *localScaling) startRunner(ctx context.Context, deploymentKey model.DeploymentKey, info *deploymentInfo) error { select { case <-ctx.Done(): // In some cases this gets called with an expired context, generally after the lease is released @@ -217,11 +222,11 @@ func (l *localScaling) startRunner(ctx context.Context, deploymentKey string, in debugPort := 0 if devEndpoint != nil { devURI = optional.Some(devEndpoint.uri) - if devEndpoint.deploymentKey == deploymentKey { + if devKey, ok := devEndpoint.deploymentKey.Get(); ok && devKey.Equal(deploymentKey) { // Already running, don't start another return nil } - devEndpoint.deploymentKey = deploymentKey + devEndpoint.deploymentKey = optional.Some(deploymentKey) debugPort = devEndpoint.debugPort } else if ide, ok := l.ideSupport.Get(); ok { var debug *localdebug.DebugInfo @@ -282,7 +287,7 @@ func (l *localScaling) startRunner(ctx context.Context, deploymentKey string, in l.lock.Lock() defer l.lock.Unlock() if devEndpoint != nil { - devEndpoint.deploymentKey = "" + devEndpoint.deploymentKey = optional.None[model.DeploymentKey]() } // Don't count context.Canceled as an a restart error if err != nil && !errors.Is(err, context.Canceled) { diff --git a/backend/cron/service.go b/backend/cron/service.go index 3f405866ec..dc2e05e4a6 100644 --- a/backend/cron/service.go +++ b/backend/cron/service.go @@ -171,7 +171,7 @@ func updateCronJobs(ctx context.Context, cronJobs map[string][]cronJob, resp *ft // We see the new state of the module before we see the removed deployment. // We only want to actually remove if it was not replaced by a new deployment. if !resp.ModuleRemoved { - logger.Debugf("Not removing cron jobs for %s as module is still present", resp.DeploymentKey) + logger.Debugf("Not removing cron jobs for %s as module is still present", resp.GetDeploymentKey()) return nil } logger.Debugf("Removing cron jobs for module %s", resp.ModuleName) diff --git a/backend/ingress/service.go b/backend/ingress/service.go index e1958d25d6..94fbf1cdf1 100644 --- a/backend/ingress/service.go +++ b/backend/ingress/service.go @@ -103,7 +103,7 @@ func Start(ctx context.Context, config Config, pullSchemaClient PullSchemaClient // We see the new state of the module before we see the removed deployment. // We only want to actually remove if it was not replaced by a new deployment. if !resp.ModuleRemoved { - logger.Debugf("Not removing ingress for %s as it is not the current deployment", resp.DeploymentKey) + logger.Debugf("Not removing ingress for %s as it is not the current deployment", resp.GetDeploymentKey()) return nil } for i := range existing.Modules { diff --git a/backend/protos/xyz/block/ftl/v1/schemaservice.pb.go b/backend/protos/xyz/block/ftl/v1/schemaservice.pb.go index fb7b1e2237..88fc481a68 100644 --- a/backend/protos/xyz/block/ftl/v1/schemaservice.pb.go +++ b/backend/protos/xyz/block/ftl/v1/schemaservice.pb.go @@ -192,8 +192,9 @@ type PullSchemaResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - DeploymentKey string `protobuf:"bytes,1,opt,name=deployment_key,json=deploymentKey,proto3" json:"deployment_key,omitempty"` - ModuleName string `protobuf:"bytes,2,opt,name=module_name,json=moduleName,proto3" json:"module_name,omitempty"` + // Will not be set for builtin modules. + DeploymentKey *string `protobuf:"bytes,1,opt,name=deployment_key,json=deploymentKey,proto3,oneof" json:"deployment_key,omitempty"` + ModuleName string `protobuf:"bytes,2,opt,name=module_name,json=moduleName,proto3" json:"module_name,omitempty"` // For deletes this will not be present. Schema *schema.Module `protobuf:"bytes,4,opt,name=schema,proto3,oneof" json:"schema,omitempty"` // If true there are more schema changes immediately following this one as part of the initial batch. @@ -235,8 +236,8 @@ func (*PullSchemaResponse) Descriptor() ([]byte, []int) { } func (x *PullSchemaResponse) GetDeploymentKey() string { - if x != nil { - return x.DeploymentKey + if x != nil && x.DeploymentKey != nil { + return *x.DeploymentKey } return "" } @@ -294,54 +295,55 @@ var file_xyz_block_ftl_v1_schemaservice_proto_rawDesc = []byte{ 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x13, 0x0a, 0x11, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0xa9, 0x02, 0x0a, 0x12, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x70, 0x6c, + 0x74, 0x22, 0xc1, 0x02, 0x0a, 0x12, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x0e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0d, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x12, - 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, - 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, - 0x65, 0x48, 0x00, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x88, 0x01, 0x01, 0x12, 0x12, - 0x0a, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x6d, 0x6f, - 0x72, 0x65, 0x12, 0x47, 0x0a, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2a, 0x5c, 0x0a, - 0x14, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x45, 0x50, 0x4c, 0x4f, 0x59, 0x4d, - 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x44, - 0x45, 0x50, 0x4c, 0x4f, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, - 0x44, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x45, 0x50, 0x4c, 0x4f, 0x59, 0x4d, 0x45, 0x4e, - 0x54, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x02, 0x32, 0x96, 0x02, 0x0a, 0x0d, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, 0x0a, - 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x59, 0x0a, 0x09, 0x47, 0x65, 0x74, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x22, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x78, 0x79, 0x7a, - 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x03, 0x90, 0x02, 0x01, 0x12, 0x5e, 0x0a, 0x0a, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x12, 0x23, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, - 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, - 0x02, 0x01, 0x30, 0x01, 0x42, 0x44, 0x50, 0x01, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x42, 0x44, 0x35, 0x34, 0x35, 0x36, 0x36, 0x39, 0x37, 0x35, - 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x73, 0x2f, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, - 0x6c, 0x2f, 0x76, 0x31, 0x3b, 0x66, 0x74, 0x6c, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x48, 0x00, 0x52, 0x0d, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, + 0x79, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, + 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x48, 0x01, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x88, 0x01, 0x01, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x12, 0x47, 0x0a, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x78, + 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x64, 0x65, 0x70, 0x6c, + 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2a, 0x5c, 0x0a, 0x14, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, + 0x10, 0x44, 0x45, 0x50, 0x4c, 0x4f, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x45, 0x50, 0x4c, 0x4f, 0x59, 0x4d, 0x45, 0x4e, + 0x54, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x44, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x44, + 0x45, 0x50, 0x4c, 0x4f, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, + 0x44, 0x10, 0x02, 0x32, 0x96, 0x02, 0x0a, 0x0d, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x2e, + 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, + 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, + 0x01, 0x12, 0x59, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x22, + 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, + 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x5e, 0x0a, 0x0a, + 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x23, 0x2e, 0x78, 0x79, 0x7a, + 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, + 0x6c, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x30, 0x01, 0x42, 0x44, 0x50, 0x01, + 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x42, 0x44, + 0x35, 0x34, 0x35, 0x36, 0x36, 0x39, 0x37, 0x35, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x62, 0x61, 0x63, + 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, 0x79, 0x7a, 0x2f, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x76, 0x31, 0x3b, 0x66, 0x74, 0x6c, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/backend/protos/xyz/block/ftl/v1/schemaservice.proto b/backend/protos/xyz/block/ftl/v1/schemaservice.proto index 3c4ec691ee..8489badefd 100644 --- a/backend/protos/xyz/block/ftl/v1/schemaservice.proto +++ b/backend/protos/xyz/block/ftl/v1/schemaservice.proto @@ -21,7 +21,8 @@ enum DeploymentChangeType { message PullSchemaRequest {} message PullSchemaResponse { - string deployment_key = 1; + // Will not be set for builtin modules. + optional string deployment_key = 1; string module_name = 2; // For deletes this will not be present. optional schema.Module schema = 4; diff --git a/backend/runner/runner.go b/backend/runner/runner.go index 732dfbc2d2..c6d36fd7ff 100644 --- a/backend/runner/runner.go +++ b/backend/runner/runner.go @@ -59,7 +59,7 @@ type Config struct { DeploymentKeepHistory int `help:"Number of deployments to keep history for." default:"3"` HeartbeatPeriod time.Duration `help:"Minimum period between heartbeats." default:"3s"` HeartbeatJitter time.Duration `help:"Jitter to add to heartbeat period." default:"2s"` - Deployment string `help:"The deployment this runner is for." env:"FTL_DEPLOYMENT"` + Deployment model.DeploymentKey `help:"The deployment this runner is for." env:"FTL_DEPLOYMENT"` DebugPort int `help:"The port to use for debugging." env:"FTL_DEBUG_PORT"` Registry artefacts.RegistryConfig `embed:"" prefix:"oci-"` ObservabilityConfig ftlobservability.Config `embed:"" prefix:"o11y-"` @@ -133,14 +133,7 @@ func Start(ctx context.Context, config Config) error { devEndpoint: config.DevEndpoint, } - deploymentKey, err := model.ParseDeploymentKey(config.Deployment) - if err != nil { - observability.Deployment.Failure(ctx, optional.None[string]()) - svc.cancelFunc() - return connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid deployment key: %w", err)) - } - - module, err := svc.getModule(ctx, deploymentKey) + module, err := svc.getModule(ctx, config.Deployment) if err != nil { return fmt.Errorf("failed to get module: %w", err) } @@ -160,7 +153,7 @@ func Start(ctx context.Context, config Config) error { case <-ctx.Done(): return ctx.Err() default: - return svc.startDeployment(ctx, deploymentKey, module) + return svc.startDeployment(ctx, config.Deployment, module) } }) @@ -194,7 +187,7 @@ func newIdentityStore(ctx context.Context, config Config, key model.RunnerKey, c return nil, fmt.Errorf("failed to create controller verifier: %w", err) } - identityStore, err := identity.NewStoreNewKeys(identity.NewRunner(key, config.Deployment)) + identityStore, err := identity.NewStoreNewKeys(identity.NewRunner(key, config.Deployment.String())) if err != nil { return nil, fmt.Errorf("failed to create identity store: %w", err) } @@ -333,7 +326,7 @@ func (s *Service) Ping(ctx context.Context, req *connect.Request[ftlv1.PingReque } func (s *Service) getModule(ctx context.Context, key model.DeploymentKey) (*schema.Module, error) { - gdResp, err := s.controllerClient.GetDeployment(ctx, connect.NewRequest(&ftlv1.GetDeploymentRequest{DeploymentKey: s.config.Deployment})) + gdResp, err := s.controllerClient.GetDeployment(ctx, connect.NewRequest(&ftlv1.GetDeploymentRequest{DeploymentKey: s.config.Deployment.String()})) if err != nil { observability.Deployment.Failure(ctx, optional.Some(key.String())) return nil, fmt.Errorf("failed to get deployment: %w", err) @@ -518,7 +511,7 @@ func (s *Service) registrationLoop(ctx context.Context, send func(request *ftlv1 Key: s.key.String(), Endpoint: s.config.Bind.String(), Labels: s.labels, - Deployment: s.config.Deployment, + Deployment: s.config.Deployment.String(), }) if err != nil { s.registrationFailure.Store(optional.Some(err)) diff --git a/frontend/cli/cmd_schema_get.go b/frontend/cli/cmd_schema_get.go index e1158c1222..29c99df8a8 100644 --- a/frontend/cli/cmd_schema_get.go +++ b/frontend/cli/cmd_schema_get.go @@ -67,7 +67,7 @@ func (g *getSchemaCmd) Run(ctx context.Context, client ftlv1connect.SchemaServic } } case ftlv1.DeploymentChangeType_DEPLOYMENT_REMOVED: - fmt.Printf("deployment %s removed\n", msg.DeploymentKey) + fmt.Printf("deployment %s removed\n", msg.GetDeploymentKey()) } } diff --git a/frontend/console/src/protos/xyz/block/ftl/v1/schemaservice_pb.ts b/frontend/console/src/protos/xyz/block/ftl/v1/schemaservice_pb.ts index 0bb6498fa3..c0e10fbf52 100644 --- a/frontend/console/src/protos/xyz/block/ftl/v1/schemaservice_pb.ts +++ b/frontend/console/src/protos/xyz/block/ftl/v1/schemaservice_pb.ts @@ -137,9 +137,11 @@ export class PullSchemaRequest extends Message { */ export class PullSchemaResponse extends Message { /** - * @generated from field: string deployment_key = 1; + * Will not be set for builtin modules. + * + * @generated from field: optional string deployment_key = 1; */ - deploymentKey = ""; + deploymentKey?: string; /** * @generated from field: string module_name = 2; @@ -181,7 +183,7 @@ export class PullSchemaResponse extends Message { static readonly runtime: typeof proto3 = proto3; static readonly typeName = "xyz.block.ftl.v1.PullSchemaResponse"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ - { no: 1, name: "deployment_key", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 1, name: "deployment_key", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, { no: 2, name: "module_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 4, name: "schema", kind: "message", T: Module, opt: true }, { no: 3, name: "more", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, diff --git a/internal/identity/identity.go b/internal/identity/identity.go index 7ef72391eb..eb62add2c6 100644 --- a/internal/identity/identity.go +++ b/internal/identity/identity.go @@ -33,19 +33,19 @@ var _ Identity = Runner{} // Runner identity // TODO: Maybe use KeyType[T any, TP keyPayloadConstraint[T]]? type Runner struct { - Key model.RunnerKey - Module string + Key model.RunnerKey + Deployment string } func NewRunner(key model.RunnerKey, module string) Runner { return Runner{ - Key: key, - Module: module, + Key: key, + Deployment: module, } } func (r Runner) String() string { - return fmt.Sprintf("%s:%s", r.Key, r.Module) + return fmt.Sprintf("%s:%s", r.Key, r.Deployment) } func Parse(s string) (Identity, error) { diff --git a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/schemaservice_pb2.py b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/schemaservice_pb2.py index 99a82b8ab0..ff616dbea3 100644 --- a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/schemaservice_pb2.py +++ b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/schemaservice_pb2.py @@ -26,7 +26,7 @@ from xyz.block.ftl.v1.schema import schema_pb2 as xyz_dot_block_dot_ftl_dot_v1_dot_schema_dot_schema__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$xyz/block/ftl/v1/schemaservice.proto\x12\x10xyz.block.ftl.v1\x1a\x1axyz/block/ftl/v1/ftl.proto\x1a$xyz/block/ftl/v1/schema/schema.proto\"\x12\n\x10GetSchemaRequest\"L\n\x11GetSchemaResponse\x12\x37\n\x06schema\x18\x01 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.SchemaR\x06schema\"\x13\n\x11PullSchemaRequest\"\xa9\x02\n\x12PullSchemaResponse\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12\x1f\n\x0bmodule_name\x18\x02 \x01(\tR\nmoduleName\x12<\n\x06schema\x18\x04 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.ModuleH\x00R\x06schema\x88\x01\x01\x12\x12\n\x04more\x18\x03 \x01(\x08R\x04more\x12G\n\x0b\x63hange_type\x18\x05 \x01(\x0e\x32&.xyz.block.ftl.v1.DeploymentChangeTypeR\nchangeType\x12%\n\x0emodule_removed\x18\x06 \x01(\x08R\rmoduleRemovedB\t\n\x07_schema*\\\n\x14\x44\x65ploymentChangeType\x12\x14\n\x10\x44\x45PLOYMENT_ADDED\x10\x00\x12\x16\n\x12\x44\x45PLOYMENT_REMOVED\x10\x01\x12\x16\n\x12\x44\x45PLOYMENT_CHANGED\x10\x02\x32\x96\x02\n\rSchemaService\x12J\n\x04Ping\x12\x1d.xyz.block.ftl.v1.PingRequest\x1a\x1e.xyz.block.ftl.v1.PingResponse\"\x03\x90\x02\x01\x12Y\n\tGetSchema\x12\".xyz.block.ftl.v1.GetSchemaRequest\x1a#.xyz.block.ftl.v1.GetSchemaResponse\"\x03\x90\x02\x01\x12^\n\nPullSchema\x12#.xyz.block.ftl.v1.PullSchemaRequest\x1a$.xyz.block.ftl.v1.PullSchemaResponse\"\x03\x90\x02\x01\x30\x01\x42\x44P\x01Z@github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1;ftlv1b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$xyz/block/ftl/v1/schemaservice.proto\x12\x10xyz.block.ftl.v1\x1a\x1axyz/block/ftl/v1/ftl.proto\x1a$xyz/block/ftl/v1/schema/schema.proto\"\x12\n\x10GetSchemaRequest\"L\n\x11GetSchemaResponse\x12\x37\n\x06schema\x18\x01 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.SchemaR\x06schema\"\x13\n\x11PullSchemaRequest\"\xc1\x02\n\x12PullSchemaResponse\x12*\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tH\x00R\rdeploymentKey\x88\x01\x01\x12\x1f\n\x0bmodule_name\x18\x02 \x01(\tR\nmoduleName\x12<\n\x06schema\x18\x04 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.ModuleH\x01R\x06schema\x88\x01\x01\x12\x12\n\x04more\x18\x03 \x01(\x08R\x04more\x12G\n\x0b\x63hange_type\x18\x05 \x01(\x0e\x32&.xyz.block.ftl.v1.DeploymentChangeTypeR\nchangeType\x12%\n\x0emodule_removed\x18\x06 \x01(\x08R\rmoduleRemovedB\x11\n\x0f_deployment_keyB\t\n\x07_schema*\\\n\x14\x44\x65ploymentChangeType\x12\x14\n\x10\x44\x45PLOYMENT_ADDED\x10\x00\x12\x16\n\x12\x44\x45PLOYMENT_REMOVED\x10\x01\x12\x16\n\x12\x44\x45PLOYMENT_CHANGED\x10\x02\x32\x96\x02\n\rSchemaService\x12J\n\x04Ping\x12\x1d.xyz.block.ftl.v1.PingRequest\x1a\x1e.xyz.block.ftl.v1.PingResponse\"\x03\x90\x02\x01\x12Y\n\tGetSchema\x12\".xyz.block.ftl.v1.GetSchemaRequest\x1a#.xyz.block.ftl.v1.GetSchemaResponse\"\x03\x90\x02\x01\x12^\n\nPullSchema\x12#.xyz.block.ftl.v1.PullSchemaRequest\x1a$.xyz.block.ftl.v1.PullSchemaResponse\"\x03\x90\x02\x01\x30\x01\x42\x44P\x01Z@github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1;ftlv1b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -40,8 +40,8 @@ _globals['_SCHEMASERVICE'].methods_by_name['GetSchema']._serialized_options = b'\220\002\001' _globals['_SCHEMASERVICE'].methods_by_name['PullSchema']._loaded_options = None _globals['_SCHEMASERVICE'].methods_by_name['PullSchema']._serialized_options = b'\220\002\001' - _globals['_DEPLOYMENTCHANGETYPE']._serialized_start=543 - _globals['_DEPLOYMENTCHANGETYPE']._serialized_end=635 + _globals['_DEPLOYMENTCHANGETYPE']._serialized_start=567 + _globals['_DEPLOYMENTCHANGETYPE']._serialized_end=659 _globals['_GETSCHEMAREQUEST']._serialized_start=124 _globals['_GETSCHEMAREQUEST']._serialized_end=142 _globals['_GETSCHEMARESPONSE']._serialized_start=144 @@ -49,7 +49,7 @@ _globals['_PULLSCHEMAREQUEST']._serialized_start=222 _globals['_PULLSCHEMAREQUEST']._serialized_end=241 _globals['_PULLSCHEMARESPONSE']._serialized_start=244 - _globals['_PULLSCHEMARESPONSE']._serialized_end=541 - _globals['_SCHEMASERVICE']._serialized_start=638 - _globals['_SCHEMASERVICE']._serialized_end=916 + _globals['_PULLSCHEMARESPONSE']._serialized_end=565 + _globals['_SCHEMASERVICE']._serialized_start=662 + _globals['_SCHEMASERVICE']._serialized_end=940 # @@protoc_insertion_point(module_scope)