diff --git a/weed/admin/plugin/config_manager.go b/weed/admin/plugin/config_manager.go new file mode 100644 index 000000000..c0af4cab9 --- /dev/null +++ b/weed/admin/plugin/config_manager.go @@ -0,0 +1,307 @@ +package plugin + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "sync" + "time" + + "github.com/seaweedfs/seaweedfs/weed/pb/plugin_pb" +) + +// ConfigManager handles configuration persistence and retrieval +type ConfigManager struct { + dataDir string + configs map[string]*JobTypeConfig + + mu sync.RWMutex +} + +// NewConfigManager creates a new configuration manager +func NewConfigManager(dataDir string) (*ConfigManager, error) { + cm := &ConfigManager{ + dataDir: filepath.Join(dataDir, "plugins"), + configs: make(map[string]*JobTypeConfig), + } + + // Create plugins directory if it doesn't exist + if err := os.MkdirAll(cm.dataDir, 0755); err != nil { + return nil, fmt.Errorf("failed to create plugin config directory: %w", err) + } + + return cm, nil +} + +// LoadConfig loads a configuration from disk +func (cm *ConfigManager) LoadConfig(jobType string) (*JobTypeConfig, error) { + cm.mu.Lock() + defer cm.mu.Unlock() + + // Check cache first + if config, exists := cm.configs[jobType]; exists { + return config, nil + } + + configPath := filepath.Join(cm.dataDir, jobType+".json") + + // If file doesn't exist, create default config + if _, err := os.Stat(configPath); err != nil { + if os.IsNotExist(err) { + config := &JobTypeConfig{ + JobType: jobType, + Enabled: false, + AdminConfig: make([]*plugin_pb.ConfigFieldValue, 0), + WorkerConfig: make([]*plugin_pb.ConfigFieldValue, 0), + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + CreatedBy: "system", + } + cm.configs[jobType] = config + return config, nil + } + return nil, fmt.Errorf("failed to access config file: %w", err) + } + + // Load from file + data, err := os.ReadFile(configPath) + if err != nil { + return nil, fmt.Errorf("failed to read config file: %w", err) + } + + var configData map[string]interface{} + if err := json.Unmarshal(data, &configData); err != nil { + return nil, fmt.Errorf("failed to parse config file: %w", err) + } + + config := &JobTypeConfig{ + JobType: jobType, + AdminConfig: make([]*plugin_pb.ConfigFieldValue, 0), + WorkerConfig: make([]*plugin_pb.ConfigFieldValue, 0), + } + + // Parse fields + if enabled, ok := configData["enabled"].(bool); ok { + config.Enabled = enabled + } + + if createdBy, ok := configData["created_by"].(string); ok { + config.CreatedBy = createdBy + } + + if createdAt, ok := configData["created_at"].(string); ok { + if t, err := time.Parse(time.RFC3339, createdAt); err == nil { + config.CreatedAt = t + } + } + + if updatedAt, ok := configData["updated_at"].(string); ok { + if t, err := time.Parse(time.RFC3339, updatedAt); err == nil { + config.UpdatedAt = t + } + } + + cm.configs[jobType] = config + return config, nil +} + +// SaveConfig saves a configuration to disk +func (cm *ConfigManager) SaveConfig(config *JobTypeConfig) error { + cm.mu.Lock() + defer cm.mu.Unlock() + + config.UpdatedAt = time.Now() + cm.configs[config.JobType] = config + + configPath := filepath.Join(cm.dataDir, config.JobType+".json") + + // Convert to JSON-serializable format + configData := map[string]interface{}{ + "job_type": config.JobType, + "enabled": config.Enabled, + "created_by": config.CreatedBy, + "created_at": config.CreatedAt.Format(time.RFC3339), + "updated_at": config.UpdatedAt.Format(time.RFC3339), + "admin_config": cm.configValuesToJSON(config.AdminConfig), + "worker_config": cm.configValuesToJSON(config.WorkerConfig), + } + + data, err := json.MarshalIndent(configData, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal config: %w", err) + } + + if err := os.WriteFile(configPath, data, 0644); err != nil { + return fmt.Errorf("failed to write config file: %w", err) + } + + return nil +} + +// GetConfig retrieves a configuration +func (cm *ConfigManager) GetConfig(jobType string) (*JobTypeConfig, error) { + cm.mu.RLock() + if config, exists := cm.configs[jobType]; exists { + cm.mu.RUnlock() + return config, nil + } + cm.mu.RUnlock() + + // Load from disk if not in cache + return cm.LoadConfig(jobType) +} + +// UpdateConfig updates a configuration +func (cm *ConfigManager) UpdateConfig(jobType string, enabled bool, adminConfig, workerConfig []*plugin_pb.ConfigFieldValue, updatedBy string) (*JobTypeConfig, error) { + config, err := cm.GetConfig(jobType) + if err != nil { + return nil, err + } + + config.SetConfig(enabled, adminConfig, workerConfig) + config.CreatedBy = updatedBy + + if err := cm.SaveConfig(config); err != nil { + return nil, err + } + + return config, nil +} + +// ListConfigs lists all configurations +func (cm *ConfigManager) ListConfigs() []*JobTypeConfig { + cm.mu.RLock() + defer cm.mu.RUnlock() + + configs := make([]*JobTypeConfig, 0, len(cm.configs)) + for _, config := range cm.configs { + configs = append(configs, config) + } + return configs +} + +// DeleteConfig deletes a configuration +func (cm *ConfigManager) DeleteConfig(jobType string) error { + cm.mu.Lock() + defer cm.mu.Unlock() + + configPath := filepath.Join(cm.dataDir, jobType+".json") + + if err := os.Remove(configPath); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to delete config file: %w", err) + } + + delete(cm.configs, jobType) + return nil +} + +// configValuesToJSON converts ConfigFieldValue slice to JSON +func (cm *ConfigManager) configValuesToJSON(values []*plugin_pb.ConfigFieldValue) []map[string]interface{} { + result := make([]map[string]interface{}, 0, len(values)) + + for _, val := range values { + item := map[string]interface{}{ + "field_name": val.FieldName, + } + + // Include non-empty values + if val.StringValue != "" { + item["string_value"] = val.StringValue + } + if val.IntValue != 0 { + item["int_value"] = val.IntValue + } + if val.FloatValue != 0 { + item["float_value"] = val.FloatValue + } + if val.BoolValue { + item["bool_value"] = val.BoolValue + } + if val.DurationValue != nil { + item["duration_value"] = val.DurationValue.String() + } + if len(val.MultiselectValues) > 0 { + item["multiselect_values"] = val.MultiselectValues + } + if val.JsonValue != "" { + item["json_value"] = val.JsonValue + } + + result = append(result, item) + } + + return result +} + +// LoadAllConfigs loads all configurations from disk +func (cm *ConfigManager) LoadAllConfigs() error { + cm.mu.Lock() + defer cm.mu.Unlock() + + entries, err := os.ReadDir(cm.dataDir) + if err != nil { + return fmt.Errorf("failed to read config directory: %w", err) + } + + for _, entry := range entries { + if entry.IsDir() { + continue + } + + // Only load .json files + if filepath.Ext(entry.Name()) != ".json" { + continue + } + + jobType := entry.Name()[:len(entry.Name())-5] // Remove .json + + configPath := filepath.Join(cm.dataDir, entry.Name()) + + data, err := os.ReadFile(configPath) + if err != nil { + continue + } + + var configData map[string]interface{} + if err := json.Unmarshal(data, &configData); err != nil { + continue + } + + config := &JobTypeConfig{ + JobType: jobType, + AdminConfig: make([]*plugin_pb.ConfigFieldValue, 0), + WorkerConfig: make([]*plugin_pb.ConfigFieldValue, 0), + } + + // Parse fields + if enabled, ok := configData["enabled"].(bool); ok { + config.Enabled = enabled + } + + if createdBy, ok := configData["created_by"].(string); ok { + config.CreatedBy = createdBy + } + + if createdAt, ok := configData["created_at"].(string); ok { + if t, err := time.Parse(time.RFC3339, createdAt); err == nil { + config.CreatedAt = t + } + } + + if updatedAt, ok := configData["updated_at"].(string); ok { + if t, err := time.Parse(time.RFC3339, updatedAt); err == nil { + config.UpdatedAt = t + } + } + + cm.configs[jobType] = config + } + + return nil +} + +// GetDataDir returns the data directory path +func (cm *ConfigManager) GetDataDir() string { + return cm.dataDir +} diff --git a/weed/admin/plugin/dispatcher.go b/weed/admin/plugin/dispatcher.go new file mode 100644 index 000000000..5caf123c1 --- /dev/null +++ b/weed/admin/plugin/dispatcher.go @@ -0,0 +1,373 @@ +package plugin + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/seaweedfs/seaweedfs/weed/pb/plugin_pb" + "google.golang.org/grpc" +) + +// Dispatcher handles job detection and dispatch to executors +type Dispatcher struct { + registry *Registry + queues map[string]*JobQueue + configMgr *ConfigManager + + mu sync.RWMutex + + // Detection scheduling + detectionIntervals map[string]time.Duration + detectionTickers map[string]*time.Ticker + stopChan chan struct{} + + // Job counter for ID generation + jobCounter uint64 + jobCounterMu sync.Mutex + + // Active streams for execution + executionStreams map[string]*ExecutionStream + streamsMu sync.RWMutex +} + +// ExecutionStream tracks an active job execution stream +type ExecutionStream struct { + JobID string + PluginID string + Connection *grpc.ClientConn + Context context.Context + Cancel context.CancelFunc + StartTime time.Time + LastUpdate time.Time +} + +// NewDispatcher creates a new job dispatcher +func NewDispatcher(registry *Registry, configMgr *ConfigManager) *Dispatcher { + return &Dispatcher{ + registry: registry, + queues: make(map[string]*JobQueue), + configMgr: configMgr, + detectionIntervals: make(map[string]time.Duration), + detectionTickers: make(map[string]*time.Ticker), + stopChan: make(chan struct{}), + executionStreams: make(map[string]*ExecutionStream), + } +} + +// RegisterJobType registers a job type for detection and dispatch +func (d *Dispatcher) RegisterJobType(jobType string, detectionInterval time.Duration) error { + d.mu.Lock() + defer d.mu.Unlock() + + if _, exists := d.queues[jobType]; exists { + return fmt.Errorf("job type %s already registered", jobType) + } + + d.queues[jobType] = NewJobQueue(jobType) + d.detectionIntervals[jobType] = detectionInterval + + return nil +} + +// Start starts the dispatcher with detection scheduling +func (d *Dispatcher) Start() { + d.mu.Lock() + defer d.mu.Unlock() + + for jobType, interval := range d.detectionIntervals { + ticker := time.NewTicker(interval) + d.detectionTickers[jobType] = ticker + go d.detectionLoop(jobType, ticker) + } +} + +// Stop stops the dispatcher +func (d *Dispatcher) Stop() { + close(d.stopChan) + + d.mu.Lock() + defer d.mu.Unlock() + + for _, ticker := range d.detectionTickers { + ticker.Stop() + } +} + +// detectionLoop periodically runs detection for a job type +func (d *Dispatcher) detectionLoop(jobType string, ticker *time.Ticker) { + for { + select { + case <-ticker.C: + d.runDetection(jobType) + case <-d.stopChan: + return + } + } +} + +// runDetection runs detection for a job type and queues detected jobs +func (d *Dispatcher) runDetection(jobType string) { + // Get detector plugin + _, err := d.registry.GetDetectorForJobType(jobType) + if err != nil { + // No detector available, skip + return + } + + // Get job type config + config, err := d.configMgr.GetConfig(jobType) + if err != nil || !config.Enabled { + // Config not found or disabled, skip + return + } + + // TODO: Call detector plugin's DetectJobs method + // For now, this is a placeholder for the gRPC call +} + +// QueueJob adds a job to the queue +func (d *Dispatcher) QueueJob(jobType string, req *plugin_pb.JobRequest, dedupKey string) (*Job, error) { + d.mu.RLock() + queue, exists := d.queues[jobType] + d.mu.RUnlock() + + if !exists { + return nil, fmt.Errorf("job type %s not registered", jobType) + } + + // Generate job ID + jobID := d.generateJobID() + + return queue.AddJob(jobID, req, dedupKey) +} + +// DispatchJob assigns a job to an available executor +func (d *Dispatcher) DispatchJob(jobType string) (*Job, *ConnectedPlugin, error) { + d.mu.RLock() + queue, exists := d.queues[jobType] + d.mu.RUnlock() + + if !exists { + return nil, nil, fmt.Errorf("job type %s not registered", jobType) + } + + // Get next pending job + job, err := queue.GetPendingJob() + if err != nil { + return nil, nil, err + } + + // Get available executor + executor, err := d.registry.GetExecutorForJobType(jobType) + if err != nil { + // Put job back in queue + queue.mu.Lock() + queue.pendingQueue = append(queue.pendingQueue, job) + queue.mu.Unlock() + return nil, nil, err + } + + job.ExecutorID = executor.ID + return job, executor, nil +} + +// GetJob retrieves a job by ID across all queues +func (d *Dispatcher) GetJob(jobID string) (*Job, error) { + d.mu.RLock() + defer d.mu.RUnlock() + + for _, queue := range d.queues { + job, err := queue.GetJob(jobID) + if err == nil { + return job, nil + } + } + + return nil, fmt.Errorf("job %s not found", jobID) +} + +// ListJobs returns jobs of a specific type and status +func (d *Dispatcher) ListJobs(jobType string, status JobState) []*Job { + d.mu.RLock() + queue, exists := d.queues[jobType] + d.mu.RUnlock() + + if !exists { + return nil + } + + return queue.ListJobs(status, 0) +} + +// ListAllJobs returns all jobs across all queues +func (d *Dispatcher) ListAllJobs() []*Job { + d.mu.RLock() + defer d.mu.RUnlock() + + var jobs []*Job + for _, queue := range d.queues { + jobs = append(jobs, queue.ListAllJobs()...) + } + return jobs +} + +// UpdateJobProgress updates job progress +func (d *Dispatcher) UpdateJobProgress(jobID string, percent int32) error { + job, err := d.GetJob(jobID) + if err != nil { + return err + } + + job.SetProgress(percent) + return nil +} + +// CompleteJob marks a job as complete +func (d *Dispatcher) CompleteJob(jobID string, completed *plugin_pb.JobCompleted) error { + job, err := d.GetJob(jobID) + if err != nil { + return err + } + + d.mu.RLock() + queue, exists := d.queues[job.Type] + d.mu.RUnlock() + + if !exists { + return fmt.Errorf("job type %s not found", job.Type) + } + + d.removeExecutionStream(jobID) + return queue.CompleteJob(jobID, completed) +} + +// FailJob marks a job as failed +func (d *Dispatcher) FailJob(jobID string, failed *plugin_pb.JobFailed) error { + job, err := d.GetJob(jobID) + if err != nil { + return err + } + + d.mu.RLock() + queue, exists := d.queues[job.Type] + d.mu.RUnlock() + + if !exists { + return fmt.Errorf("job type %s not found", job.Type) + } + + d.removeExecutionStream(jobID) + _, err = queue.FailJob(jobID, failed) + return err +} + +// CancelJob cancels a job +func (d *Dispatcher) CancelJob(jobID string) error { + job, err := d.GetJob(jobID) + if err != nil { + return err + } + + d.mu.RLock() + queue, exists := d.queues[job.Type] + d.mu.RUnlock() + + if !exists { + return fmt.Errorf("job type %s not found", job.Type) + } + + d.removeExecutionStream(jobID) + return queue.CancelJob(jobID) +} + +// RetryJob retries a failed job +func (d *Dispatcher) RetryJob(jobID string) error { + job, err := d.GetJob(jobID) + if err != nil { + return err + } + + state := job.GetState() + if state != JobStateFailed { + return fmt.Errorf("can only retry failed jobs, job is in %s state", state.String()) + } + + d.mu.RLock() + queue, exists := d.queues[job.Type] + d.mu.RUnlock() + + if !exists { + return fmt.Errorf("job type %s not found", job.Type) + } + + job.SetState(JobStatePending) + job.Retries++ + queue.mu.Lock() + queue.pendingQueue = append(queue.pendingQueue, job) + queue.sortPendingQueue() + queue.mu.Unlock() + + return nil +} + +// generateJobID generates a unique job ID +func (d *Dispatcher) generateJobID() string { + d.jobCounterMu.Lock() + defer d.jobCounterMu.Unlock() + d.jobCounter++ + return fmt.Sprintf("job-%d-%d", time.Now().Unix(), d.jobCounter) +} + +// RegisterExecutionStream registers a new execution stream +func (d *Dispatcher) RegisterExecutionStream(jobID, pluginID string, ctx context.Context) *ExecutionStream { + d.streamsMu.Lock() + defer d.streamsMu.Unlock() + + cancelCtx, cancel := context.WithCancel(ctx) + stream := &ExecutionStream{ + JobID: jobID, + PluginID: pluginID, + Context: cancelCtx, + Cancel: cancel, + StartTime: time.Now(), + LastUpdate: time.Now(), + } + + d.executionStreams[jobID] = stream + return stream +} + +// removeExecutionStream removes an execution stream +func (d *Dispatcher) removeExecutionStream(jobID string) { + d.streamsMu.Lock() + defer d.streamsMu.Unlock() + + stream, exists := d.executionStreams[jobID] + if exists { + stream.Cancel() + delete(d.executionStreams, jobID) + } +} + +// GetStats returns dispatcher statistics +func (d *Dispatcher) GetStats() map[string]interface{} { + d.mu.RLock() + defer d.mu.RUnlock() + + queueStats := make(map[string]interface{}) + for jobType, queue := range d.queues { + queueStats[jobType] = queue.GetStats() + } + + d.streamsMu.RLock() + activeStreams := len(d.executionStreams) + d.streamsMu.RUnlock() + + return map[string]interface{}{ + "queue_stats": queueStats, + "active_streams": activeStreams, + "registered_types": len(d.queues), + } +} diff --git a/weed/admin/plugin/grpc_server.go b/weed/admin/plugin/grpc_server.go new file mode 100644 index 000000000..6f99824a0 --- /dev/null +++ b/weed/admin/plugin/grpc_server.go @@ -0,0 +1,461 @@ +package plugin + +import ( + "context" + "fmt" + "io" + "sync" + + "github.com/seaweedfs/seaweedfs/weed/pb/plugin_pb" + "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/grpc" +) + +// GrpcServer implements the plugin gRPC service +type GrpcServer struct { + plugin_pb.UnimplementedPluginServiceServer + plugin_pb.UnimplementedAdminQueryServiceServer + plugin_pb.UnimplementedAdminCommandServiceServer + + registry *Registry + dispatcher *Dispatcher + configMgr *ConfigManager + + // Active connections + connections map[string]*grpc.ClientStream + connMu sync.RWMutex +} + +// NewGrpcServer creates a new gRPC server +func NewGrpcServer(registry *Registry, dispatcher *Dispatcher, configMgr *ConfigManager) *GrpcServer { + return &GrpcServer{ + registry: registry, + dispatcher: dispatcher, + configMgr: configMgr, + connections: make(map[string]*grpc.ClientStream), + } +} + +// ============================================================================ +// PluginService Implementation +// ============================================================================ + +// Connect handles bidirectional streaming for plugin registration and lifecycle +func (s *GrpcServer) Connect(stream grpc.BidiStreamingServer[plugin_pb.PluginMessage, plugin_pb.AdminMessage]) error { + var pluginID string + + for { + msg, err := stream.Recv() + if err == io.EOF { + // Stream closed normally + if pluginID != "" { + s.registry.UnregisterPlugin(pluginID) + } + return nil + } + if err != nil { + return err + } + + // Handle different message types + switch content := msg.Content.(type) { + case *plugin_pb.PluginMessage_Register: + register := content.Register + pluginID = register.PluginId + _, _ = s.registry.RegisterPlugin(pluginID, register) + if err != nil { + return err + } + + case *plugin_pb.PluginMessage_Heartbeat: + heartbeat := content.Heartbeat + if err := s.registry.UpdateHeartbeat(heartbeat.PluginId, heartbeat); err != nil { + return err + } + + case *plugin_pb.PluginMessage_StatusUpdate: + // Handle job status updates + statusUpdate := content.StatusUpdate + if err := s.handleStatusUpdate(statusUpdate); err != nil { + return err + } + } + + // Send acknowledgment + adminMsg := &plugin_pb.AdminMessage{ + Content: &plugin_pb.AdminMessage_AdminCommand{ + AdminCommand: &plugin_pb.AdminCommand{ + CommandType: plugin_pb.AdminCommand_RELOAD_CONFIG, + }, + }, + } + + if err := stream.Send(adminMsg); err != nil { + if pluginID != "" { + s.registry.UnregisterPlugin(pluginID) + } + return err + } + } +} + +// ExecuteJob handles bidirectional streaming for job execution +func (s *GrpcServer) ExecuteJob(stream grpc.BidiStreamingServer[plugin_pb.JobExecutionMessage, plugin_pb.JobProgressMessage]) error { + var jobID string + + for { + execMsg, err := stream.Recv() + if err == io.EOF { + // Stream closed normally + return nil + } + if err != nil { + return err + } + + jobID = execMsg.JobId + + // Handle different execution message types + switch content := execMsg.Content.(type) { + case *plugin_pb.JobExecutionMessage_JobStarted: + started := content.JobStarted + if err := s.handleJobStarted(jobID, started); err != nil { + return err + } + + case *plugin_pb.JobExecutionMessage_Progress: + progress := content.Progress + if err := s.dispatcher.UpdateJobProgress(jobID, progress.ProgressPercent); err != nil { + return err + } + + case *plugin_pb.JobExecutionMessage_Checkpoint: + checkpoint := content.Checkpoint + // Store checkpoint for resumption + if err := s.storeCheckpoint(jobID, checkpoint); err != nil { + return err + } + + case *plugin_pb.JobExecutionMessage_JobCompleted: + completed := content.JobCompleted + if err := s.dispatcher.CompleteJob(jobID, completed); err != nil { + return err + } + + case *plugin_pb.JobExecutionMessage_JobFailed: + failed := content.JobFailed + if err := s.dispatcher.FailJob(jobID, failed); err != nil { + return err + } + + case *plugin_pb.JobExecutionMessage_LogEntry: + logEntry := content.LogEntry + if err := s.storeLogEntry(jobID, logEntry); err != nil { + return err + } + } + + // Send progress update + progressMsg := &plugin_pb.JobProgressMessage{ + JobId: jobID, + Content: &plugin_pb.JobProgressMessage_Update{ + Update: &plugin_pb.JobProgressUpdate{ + JobId: jobID, + ProgressPercent: 0, + CurrentStep: "processing", + StatusMessage: "Processing job", + Timestamp: nil, + }, + }, + } + + if err := stream.Send(progressMsg); err != nil { + return err + } + } +} + +// ============================================================================ +// AdminQueryService Implementation +// ============================================================================ + +// GetPluginStats returns current plugin system statistics +func (s *GrpcServer) GetPluginStats(ctx context.Context, req *emptypb.Empty) (*plugin_pb.PluginStats, error) { + plugins := s.registry.ListPlugins() + jobs := s.dispatcher.ListAllJobs() + + var totalJobs, pendingJobs, runningJobs, completedJobs, failedJobs int32 + + for _, job := range jobs { + totalJobs++ + switch job.GetState() { + case JobStatePending: + pendingJobs++ + case JobStateRunning: + runningJobs++ + case JobStateCompleted: + completedJobs++ + case JobStateFailed: + failedJobs++ + } + } + + stats := &plugin_pb.PluginStats{ + TotalPlugins: int32(len(plugins)), + ActivePlugins: int32(len(plugins)), + TotalJobs: totalJobs, + PendingJobs: pendingJobs, + RunningJobs: runningJobs, + CompletedJobs: completedJobs, + FailedJobs: failedJobs, + } + + return stats, nil +} + +// ListPlugins returns all connected plugins +func (s *GrpcServer) ListPlugins(ctx context.Context, req *emptypb.Empty) (*plugin_pb.PluginList, error) { + plugins := s.registry.ListPlugins() + pluginInfos := make([]*plugin_pb.PluginInfo, 0, len(plugins)) + + for _, p := range plugins { + info := &plugin_pb.PluginInfo{ + PluginId: p.ID, + Name: p.Name, + Version: p.Version, + ProtocolVersion: p.ProtocolVersion, + Healthy: p.IsHealthy(), + Status: p.GetState().String(), + } + + // Add capabilities + for _, cap := range p.Capabilities { + info.Capabilities = append(info.Capabilities, cap) + } + + pluginInfos = append(pluginInfos, info) + } + + return &plugin_pb.PluginList{Plugins: pluginInfos}, nil +} + +// ListJobs returns jobs filtered by type and status +func (s *GrpcServer) ListJobs(ctx context.Context, req *plugin_pb.ListJobsRequest) (*plugin_pb.JobList, error) { + var state JobState + switch req.Status { + case plugin_pb.ListJobsRequest_PENDING: + state = JobStatePending + case plugin_pb.ListJobsRequest_RUNNING: + state = JobStateRunning + case plugin_pb.ListJobsRequest_COMPLETED: + state = JobStateCompleted + case plugin_pb.ListJobsRequest_FAILED: + state = JobStateFailed + default: + state = JobStatePending + } + + jobs := s.dispatcher.ListJobs(req.JobType, state) + + jobPbs := make([]*plugin_pb.Job, 0, len(jobs)) + for _, job := range jobs { + jobPb := &plugin_pb.Job{ + JobId: job.ID, + JobType: job.Type, + Description: job.Description, + Priority: job.Priority, + CreatedAt: nil, + UpdatedAt: nil, + ExecutorPluginId: job.ExecutorID, + ProgressPercent: job.GetProgress(), + Config: job.Config, + } + jobPbs = append(jobPbs, jobPb) + } + + return &plugin_pb.JobList{ + Jobs: jobPbs, + TotalCount: int32(len(jobPbs)), + ReturnedCount: int32(len(jobPbs)), + }, nil +} + +// GetJob returns detailed job information +func (s *GrpcServer) GetJob(ctx context.Context, req *plugin_pb.GetJobRequest) (*plugin_pb.JobDetail, error) { + job, err := s.dispatcher.GetJob(req.JobId) + if err != nil { + return nil, fmt.Errorf("job not found: %w", err) + } + + jobPb := &plugin_pb.Job{ + JobId: job.ID, + JobType: job.Type, + Description: job.Description, + Priority: job.Priority, + ExecutorPluginId: job.ExecutorID, + ProgressPercent: job.GetProgress(), + Config: job.Config, + } + + detail := &plugin_pb.JobDetail{ + Job: jobPb, + LogEntries: job.LogEntries, + CompletionInfo: job.CompletedInfo, + FailureInfo: job.FailedInfo, + CheckpointIds: job.CheckpointIDs, + } + + return detail, nil +} + +// GetJobExecutionLog returns job execution logs +func (s *GrpcServer) GetJobExecutionLog(req *plugin_pb.GetJobExecutionLogRequest, stream grpc.ServerStreamingServer[plugin_pb.ExecutionLogEntry]) error { + job, err := s.dispatcher.GetJob(req.JobId) + if err != nil { + return fmt.Errorf("job not found: %w", err) + } + + // Send log entries + for _, entry := range job.LogEntries { + if err := stream.Send(entry); err != nil { + return err + } + } + + return nil +} + +// ============================================================================ +// AdminCommandService Implementation +// ============================================================================ + +// UpdateJobTypeConfig updates configuration for a job type +func (s *GrpcServer) UpdateJobTypeConfig(ctx context.Context, req *plugin_pb.UpdateJobTypeConfigRequest) (*plugin_pb.JobTypeConfig, error) { + config := req.Config + + _, err := s.configMgr.UpdateConfig( + config.JobType, + config.Enabled, + config.AdminConfig, + config.WorkerConfig, + "admin", + ) + if err != nil { + return nil, fmt.Errorf("failed to update config: %w", err) + } + + return config, nil +} + +// CreateJob creates a new job +func (s *GrpcServer) CreateJob(ctx context.Context, req *plugin_pb.CreateJobRequest) (*plugin_pb.Job, error) { + jobReq := &plugin_pb.JobRequest{ + JobType: req.JobType, + Description: req.Description, + Priority: req.Priority, + Config: req.Config, + Metadata: req.Metadata, + RequestSource: "admin", + } + + job, err := s.dispatcher.QueueJob(req.JobType, jobReq, "") + if err != nil { + return nil, fmt.Errorf("failed to create job: %w", err) + } + + return &plugin_pb.Job{ + JobId: job.ID, + JobType: job.Type, + Description: job.Description, + Priority: job.Priority, + ProgressPercent: job.GetProgress(), + Config: job.Config, + }, nil +} + +// CancelJob cancels a running job +func (s *GrpcServer) CancelJob(ctx context.Context, req *plugin_pb.CancelJobRequest) (*emptypb.Empty, error) { + if err := s.dispatcher.CancelJob(req.JobId); err != nil { + return nil, fmt.Errorf("failed to cancel job: %w", err) + } + + return &emptypb.Empty{}, nil +} + +// RetryJob retries a failed job +func (s *GrpcServer) RetryJob(ctx context.Context, req *plugin_pb.RetryJobRequest) (*plugin_pb.Job, error) { + if err := s.dispatcher.RetryJob(req.JobId); err != nil { + return nil, fmt.Errorf("failed to retry job: %w", err) + } + + job, err := s.dispatcher.GetJob(req.JobId) + if err != nil { + return nil, fmt.Errorf("job not found: %w", err) + } + + return &plugin_pb.Job{ + JobId: job.ID, + JobType: job.Type, + Description: job.Description, + Priority: job.Priority, + ProgressPercent: job.GetProgress(), + Config: job.Config, + }, nil +} + +// ============================================================================ +// Helper Methods +// ============================================================================ + +// handleStatusUpdate handles execution status updates +func (s *GrpcServer) handleStatusUpdate(update *plugin_pb.ExecutionStatusUpdate) error { + if err := s.dispatcher.UpdateJobProgress(update.JobId, update.ProgressPercent); err != nil { + return err + } + return nil +} + +// handleJobStarted handles job start messages +func (s *GrpcServer) handleJobStarted(jobID string, started *plugin_pb.JobStarted) error { + job, err := s.dispatcher.GetJob(jobID) + if err != nil { + return err + } + + job.SetState(JobStateRunning) + return nil +} + +// storeCheckpoint stores a job checkpoint +func (s *GrpcServer) storeCheckpoint(jobID string, checkpoint *plugin_pb.JobCheckpoint) error { + job, err := s.dispatcher.GetJob(jobID) + if err != nil { + return err + } + + job.mu.Lock() + defer job.mu.Unlock() + + job.CheckpointIDs = append(job.CheckpointIDs, checkpoint.CheckpointId) + return nil +} + +// storeLogEntry stores a log entry for a job +func (s *GrpcServer) storeLogEntry(jobID string, logEntry *plugin_pb.ExecutionLog) error { + job, err := s.dispatcher.GetJob(jobID) + if err != nil { + return err + } + + job.mu.Lock() + defer job.mu.Unlock() + + job.LogEntries = append(job.LogEntries, &plugin_pb.ExecutionLogEntry{ + Timestamp: logEntry.Timestamp, + Level: logEntry.Level, + Message: logEntry.Message, + Context: logEntry.Context, + }) + + return nil +} diff --git a/weed/admin/plugin/job_queue.go b/weed/admin/plugin/job_queue.go new file mode 100644 index 000000000..b9086344f --- /dev/null +++ b/weed/admin/plugin/job_queue.go @@ -0,0 +1,346 @@ +package plugin + +import ( + "fmt" + "sync" + "time" + + "github.com/seaweedfs/seaweedfs/weed/pb/plugin_pb" +) + +// JobQueue manages jobs for a specific job type with priority and deduplication +type JobQueue struct { + jobType string + + // Active jobs by ID + jobs map[string]*Job + + // Priority queue + pendingQueue []*Job + + // Completed jobs history (keeps last 1000) + completedHistory []*Job + maxHistorySize int + + // Deduplication tracking + seenKeys map[string]bool + + mu sync.RWMutex + + // Retry configuration + maxRetries int32 + retryBackoff time.Duration + retryBackoffMax time.Duration +} + +// NewJobQueue creates a new job queue for a job type +func NewJobQueue(jobType string) *JobQueue { + return &JobQueue{ + jobType: jobType, + jobs: make(map[string]*Job), + pendingQueue: make([]*Job, 0), + completedHistory: make([]*Job, 0), + maxHistorySize: 1000, + seenKeys: make(map[string]bool), + maxRetries: 3, + retryBackoff: time.Second, + retryBackoffMax: 5 * time.Minute, + } +} + +// AddJob adds a new job to the queue with deduplication +func (q *JobQueue) AddJob(jobID string, req *plugin_pb.JobRequest, dedupKey string) (*Job, error) { + q.mu.Lock() + defer q.mu.Unlock() + + // Check deduplication + if dedupKey != "" && q.seenKeys[dedupKey] { + return nil, fmt.Errorf("job with key %s already queued", dedupKey) + } + + if _, exists := q.jobs[jobID]; exists { + return nil, fmt.Errorf("job %s already exists", jobID) + } + + job := &Job{ + ID: jobID, + Type: req.JobType, + Description: req.Description, + Priority: req.Priority, + State: JobStatePending, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + Config: req.Config, + Metadata: req.Metadata, + Retries: 0, + } + + q.jobs[jobID] = job + q.pendingQueue = append(q.pendingQueue, job) + + if dedupKey != "" { + q.seenKeys[dedupKey] = true + } + + // Sort by priority (higher priority first) + q.sortPendingQueue() + + return job, nil +} + +// GetPendingJob returns the next job to execute +func (q *JobQueue) GetPendingJob() (*Job, error) { + q.mu.Lock() + defer q.mu.Unlock() + + if len(q.pendingQueue) == 0 { + return nil, fmt.Errorf("no pending jobs") + } + + job := q.pendingQueue[0] + q.pendingQueue = q.pendingQueue[1:] + + job.SetState(JobStateRunning) + + return job, nil +} + +// GetJob retrieves a job by ID +func (q *JobQueue) GetJob(jobID string) (*Job, error) { + q.mu.RLock() + defer q.mu.RUnlock() + + job, exists := q.jobs[jobID] + if !exists { + return nil, fmt.Errorf("job %s not found", jobID) + } + + return job, nil +} + +// CompleteJob marks a job as completed +func (q *JobQueue) CompleteJob(jobID string, completed *plugin_pb.JobCompleted) error { + q.mu.Lock() + defer q.mu.Unlock() + + job, exists := q.jobs[jobID] + if !exists { + return fmt.Errorf("job %s not found", jobID) + } + + job.SetState(JobStateCompleted) + job.CompletedInfo = completed + + q.addToHistory(job) + + return nil +} + +// FailJob marks a job as failed and determines if it should be retried +func (q *JobQueue) FailJob(jobID string, failed *plugin_pb.JobFailed) (*Job, error) { + q.mu.Lock() + defer q.mu.Unlock() + + job, exists := q.jobs[jobID] + if !exists { + return nil, fmt.Errorf("job %s not found", jobID) + } + + job.FailedInfo = failed + + // Check if we should retry + if failed.Retryable && job.Retries < q.maxRetries { + job.Retries++ + job.LastRetryTime = time.Now() + job.SetState(JobStatePending) + + // Add back to queue with exponential backoff for retry + q.pendingQueue = append(q.pendingQueue, job) + q.sortPendingQueue() + + return job, nil + } + + // No retry, mark as failed + job.SetState(JobStateFailed) + q.addToHistory(job) + + return job, nil +} + +// PauseJob pauses a running job +func (q *JobQueue) PauseJob(jobID string) error { + q.mu.Lock() + defer q.mu.Unlock() + + job, exists := q.jobs[jobID] + if !exists { + return fmt.Errorf("job %s not found", jobID) + } + + if job.GetState() != JobStateRunning { + return fmt.Errorf("job %s is not running", jobID) + } + + job.SetState(JobStatePaused) + return nil +} + +// ResumeJob resumes a paused job +func (q *JobQueue) ResumeJob(jobID string) error { + q.mu.Lock() + defer q.mu.Unlock() + + job, exists := q.jobs[jobID] + if !exists { + return fmt.Errorf("job %s not found", jobID) + } + + if job.GetState() != JobStatePaused { + return fmt.Errorf("job %s is not paused", jobID) + } + + job.SetState(JobStateRunning) + return nil +} + +// CancelJob cancels a job +func (q *JobQueue) CancelJob(jobID string) error { + q.mu.Lock() + defer q.mu.Unlock() + + job, exists := q.jobs[jobID] + if !exists { + return fmt.Errorf("job %s not found", jobID) + } + + state := job.GetState() + if state != JobStatePending && state != JobStateRunning && state != JobStatePaused { + return fmt.Errorf("cannot cancel job in %s state", state.String()) + } + + job.SetState(JobStateCancelled) + + // Remove from pending queue if present + for i, j := range q.pendingQueue { + if j.ID == jobID { + q.pendingQueue = append(q.pendingQueue[:i], q.pendingQueue[i+1:]...) + break + } + } + + q.addToHistory(job) + + return nil +} + +// ListJobs returns jobs filtered by status +func (q *JobQueue) ListJobs(status JobState, limit int) []*Job { + q.mu.RLock() + defer q.mu.RUnlock() + + var jobs []*Job + + // Include pending jobs from queue + for _, job := range q.pendingQueue { + if job.GetState() == status { + jobs = append(jobs, job) + } + } + + // Include all active jobs + for _, job := range q.jobs { + if job.GetState() == status { + jobs = append(jobs, job) + } + } + + if limit > 0 && len(jobs) > limit { + jobs = jobs[:limit] + } + + return jobs +} + +// ListAllJobs returns all jobs +func (q *JobQueue) ListAllJobs() []*Job { + q.mu.RLock() + defer q.mu.RUnlock() + + jobs := make([]*Job, 0, len(q.jobs)) + for _, job := range q.jobs { + jobs = append(jobs, job) + } + + // Add completed history + for _, job := range q.completedHistory { + jobs = append(jobs, job) + } + + return jobs +} + +// sortPendingQueue sorts the pending queue by priority (higher first) +func (q *JobQueue) sortPendingQueue() { + for i := 0; i < len(q.pendingQueue)-1; i++ { + for j := i + 1; j < len(q.pendingQueue); j++ { + if q.pendingQueue[j].Priority > q.pendingQueue[i].Priority { + q.pendingQueue[i], q.pendingQueue[j] = q.pendingQueue[j], q.pendingQueue[i] + } + } + } +} + +// addToHistory adds a completed job to history +func (q *JobQueue) addToHistory(job *Job) { + q.completedHistory = append(q.completedHistory, job) + + // Keep only last N entries + if len(q.completedHistory) > q.maxHistorySize { + q.completedHistory = q.completedHistory[len(q.completedHistory)-q.maxHistorySize:] + } + + // Remove from active jobs + delete(q.jobs, job.ID) +} + +// GetPendingCount returns number of pending jobs +func (q *JobQueue) GetPendingCount() int { + q.mu.RLock() + defer q.mu.RUnlock() + return len(q.pendingQueue) +} + +// GetStats returns queue statistics +func (q *JobQueue) GetStats() map[string]interface{} { + q.mu.RLock() + defer q.mu.RUnlock() + + var running, completed, failed, cancelled int + + for _, job := range q.jobs { + switch job.GetState() { + case JobStateRunning: + running++ + case JobStateCompleted: + completed++ + case JobStateFailed: + failed++ + case JobStateCancelled: + cancelled++ + } + } + + completed += len(q.completedHistory) + + return map[string]interface{}{ + "job_type": q.jobType, + "pending": len(q.pendingQueue), + "running": running, + "completed": completed, + "failed": failed, + "cancelled": cancelled, + "total": len(q.jobs) + len(q.completedHistory), + "history_size": len(q.completedHistory), + } +} diff --git a/weed/admin/plugin/manager.go b/weed/admin/plugin/manager.go new file mode 100644 index 000000000..ba6303830 --- /dev/null +++ b/weed/admin/plugin/manager.go @@ -0,0 +1,401 @@ +package plugin + +import ( + "context" + "fmt" + "net" + "sync" + "time" + + "github.com/seaweedfs/seaweedfs/weed/pb/plugin_pb" + "google.golang.org/grpc" +) + +// Manager is the main plugin system manager +type Manager struct { + registry *Registry + dispatcher *Dispatcher + configMgr *ConfigManager + grpcServer *GrpcServer + + // gRPC server + grpcListener net.Listener + grpc *grpc.Server + + // Configuration + listenAddr string + dataDir string + healthCheckInterval time.Duration + + // State + mu sync.RWMutex + running bool + stopChan chan struct{} +} + +// NewManager creates a new plugin manager +func NewManager(listenAddr, dataDir string) (*Manager, error) { + // Create configuration manager + configMgr, err := NewConfigManager(dataDir) + if err != nil { + return nil, fmt.Errorf("failed to create config manager: %w", err) + } + + // Create registry + registry := NewRegistry() + + // Create dispatcher + dispatcher := NewDispatcher(registry, configMgr) + + // Create gRPC server implementation + grpcServer := NewGrpcServer(registry, dispatcher, configMgr) + + return &Manager{ + registry: registry, + dispatcher: dispatcher, + configMgr: configMgr, + grpcServer: grpcServer, + listenAddr: listenAddr, + dataDir: dataDir, + healthCheckInterval: 30 * time.Second, + stopChan: make(chan struct{}), + }, nil +} + +// Start starts the plugin manager and gRPC server +func (m *Manager) Start() error { + m.mu.Lock() + defer m.mu.Unlock() + + if m.running { + return fmt.Errorf("plugin manager already running") + } + + // Start registry health checks + m.registry.Start() + + // Start dispatcher + m.dispatcher.Start() + + // Create gRPC server + m.grpc = grpc.NewServer() + + // Register services + plugin_pb.RegisterPluginServiceServer(m.grpc, m.grpcServer) + plugin_pb.RegisterAdminQueryServiceServer(m.grpc, m.grpcServer) + plugin_pb.RegisterAdminCommandServiceServer(m.grpc, m.grpcServer) + + // Start listening + listener, err := net.Listen("tcp", m.listenAddr) + if err != nil { + return fmt.Errorf("failed to listen on %s: %w", m.listenAddr, err) + } + m.grpcListener = listener + + // Start gRPC server in background + go func() { + if err := m.grpc.Serve(listener); err != nil && err != grpc.ErrServerStopped { + fmt.Printf("gRPC server error: %v\n", err) + } + }() + + m.running = true + + fmt.Printf("Plugin manager started on %s\n", m.listenAddr) + + return nil +} + +// Stop stops the plugin manager and gRPC server +func (m *Manager) Stop() error { + m.mu.Lock() + defer m.mu.Unlock() + + if !m.running { + return fmt.Errorf("plugin manager not running") + } + + close(m.stopChan) + + // Stop dispatcher + m.dispatcher.Stop() + + // Stop registry + m.registry.Stop() + + // Stop gRPC server + if m.grpc != nil { + m.grpc.GracefulStop() + } + + m.running = false + + return nil +} + +// IsRunning returns whether the manager is running +func (m *Manager) IsRunning() bool { + m.mu.RLock() + defer m.mu.RUnlock() + return m.running +} + +// RegisterJobType registers a job type for detection and execution +func (m *Manager) RegisterJobType(jobType string, detectionInterval time.Duration) error { + m.mu.RLock() + running := m.running + m.mu.RUnlock() + + if !running { + return fmt.Errorf("plugin manager not running") + } + + // Register job type + if err := m.dispatcher.RegisterJobType(jobType, detectionInterval); err != nil { + return err + } + + _, err := m.configMgr.LoadConfig(jobType) + if err != nil { + return err + } + + return nil +} + +// QueueJob queues a new job for execution +func (m *Manager) QueueJob(jobType string, description string, priority int64, metadata map[string]string) (*Job, error) { + m.mu.RLock() + running := m.running + m.mu.RUnlock() + + if !running { + return nil, fmt.Errorf("plugin manager not running") + } + + jobReq := &plugin_pb.JobRequest{ + JobType: jobType, + Description: description, + Priority: priority, + Metadata: metadata, + RequestSource: "admin", + } + + return m.dispatcher.QueueJob(jobType, jobReq, "") +} + +// DispatchJob dispatches the next available job +func (m *Manager) DispatchJob(jobType string) (*Job, *ConnectedPlugin, error) { + m.mu.RLock() + running := m.running + m.mu.RUnlock() + + if !running { + return nil, nil, fmt.Errorf("plugin manager not running") + } + + return m.dispatcher.DispatchJob(jobType) +} + +// GetJob retrieves a job by ID +func (m *Manager) GetJob(jobID string) (*Job, error) { + return m.dispatcher.GetJob(jobID) +} + +// ListJobs returns jobs of a specific type and status +func (m *Manager) ListJobs(jobType string, status JobState) []*Job { + return m.dispatcher.ListJobs(jobType, status) +} + +// ListAllJobs returns all jobs +func (m *Manager) ListAllJobs() []*Job { + return m.dispatcher.ListAllJobs() +} + +// ListPlugins returns all connected plugins +func (m *Manager) ListPlugins() []*ConnectedPlugin { + return m.registry.ListPlugins() +} + +// GetPlugin retrieves a plugin by ID +func (m *Manager) GetPlugin(pluginID string) (*ConnectedPlugin, error) { + return m.registry.GetPlugin(pluginID) +} + +// ListPluginsByCapability returns plugins that support a job type +func (m *Manager) ListPluginsByCapability(jobType string) []*ConnectedPlugin { + return m.registry.ListPluginsByCapability(jobType) +} + +// UpdateJobTypeConfig updates configuration for a job type +func (m *Manager) UpdateJobTypeConfig(jobType string, enabled bool, config []*plugin_pb.ConfigFieldValue) (*JobTypeConfig, error) { + return m.configMgr.UpdateConfig(jobType, enabled, config, nil, "admin") +} + +// GetJobTypeConfig retrieves configuration for a job type +func (m *Manager) GetJobTypeConfig(jobType string) (*JobTypeConfig, error) { + return m.configMgr.GetConfig(jobType) +} + +// CancelJob cancels a job +func (m *Manager) CancelJob(jobID string) error { + return m.dispatcher.CancelJob(jobID) +} + +// RetryJob retries a failed job +func (m *Manager) RetryJob(jobID string) error { + return m.dispatcher.RetryJob(jobID) +} + +// GetStats returns system statistics +func (m *Manager) GetStats() map[string]interface{} { + m.mu.RLock() + running := m.running + m.mu.RUnlock() + + stats := map[string]interface{}{ + "running": running, + } + + if running { + stats["registry"] = m.registry.GetStats() + stats["dispatcher"] = m.dispatcher.GetStats() + } + + return stats +} + +// WaitForPluginConnection waits for a plugin to connect with timeout +func (m *Manager) WaitForPluginConnection(timeout time.Duration) error { + deadline := time.Now().Add(timeout) + + for time.Now().Before(deadline) { + plugins := m.registry.ListPlugins() + if len(plugins) > 0 { + return nil + } + time.Sleep(100 * time.Millisecond) + } + + return fmt.Errorf("no plugin connected within %v", timeout) +} + +// CreateTestJob creates a job for testing +func (m *Manager) CreateTestJob(jobType string, description string) (*Job, error) { + return m.QueueJob(jobType, description, 100, map[string]string{ + "test": "true", + }) +} + +// GetHealthStatus returns the health status of the plugin system +func (m *Manager) GetHealthStatus() map[string]interface{} { + m.mu.RLock() + running := m.running + m.mu.RUnlock() + + status := map[string]interface{}{ + "running": running, + } + + if !running { + return status + } + + plugins := m.registry.ListPlugins() + var healthyCount int + for _, p := range plugins { + if p.IsHealthy() { + healthyCount++ + } + } + + jobs := m.dispatcher.ListAllJobs() + var runningJobs, pendingJobs, completedJobs, failedJobs int + + for _, job := range jobs { + switch job.GetState() { + case JobStateRunning: + runningJobs++ + case JobStatePending: + pendingJobs++ + case JobStateCompleted: + completedJobs++ + case JobStateFailed: + failedJobs++ + } + } + + status["plugins"] = map[string]interface{}{ + "total": len(plugins), + "healthy": healthyCount, + } + + status["jobs"] = map[string]interface{}{ + "running": runningJobs, + "pending": pendingJobs, + "completed": completedJobs, + "failed": failedJobs, + "total": len(jobs), + } + + return status +} + +// LoadAllConfigs loads all configurations from disk +func (m *Manager) LoadAllConfigs() error { + return m.configMgr.LoadAllConfigs() +} + +// GetDataDir returns the data directory +func (m *Manager) GetDataDir() string { + return m.configMgr.GetDataDir() +} + +// QueryPluginService queries a plugin service for capabilities +func (m *Manager) QueryPluginService(ctx context.Context, pluginID string, addr string) (*plugin_pb.PluginRegister, error) { + // This would be implemented to connect to a plugin and query its capabilities + // For now, return a placeholder error + return nil, fmt.Errorf("not yet implemented") +} + +// ExecuteDetection triggers detection for a job type +func (m *Manager) ExecuteDetection(ctx context.Context, jobType string) ([]*DetectedJobInfo, error) { + _, err := m.registry.GetDetectorForJobType(jobType) + if err != nil { + return nil, fmt.Errorf("no detector available for job type %s: %w", jobType, err) + } + + // TODO: Call detector plugin's DetectJobs method + // This would require connecting to the plugin and calling its service + + return nil, fmt.Errorf("detection not yet implemented") +} + +// DetectedJobInfo holds information about a detected job +type DetectedJobInfo struct { + Key string + JobType string + Priority int64 + Metadata map[string]string + Timestamp time.Time +} + +// GetListenAddr returns the listen address +func (m *Manager) GetListenAddr() string { + m.mu.RLock() + defer m.mu.RUnlock() + return m.listenAddr +} + +// GetContext returns a context for the manager +func (m *Manager) GetContext() context.Context { + return context.Background() +} + +// Close closes the manager and releases resources +func (m *Manager) Close() error { + if m.IsRunning() { + return m.Stop() + } + return nil +} diff --git a/weed/admin/plugin/registry.go b/weed/admin/plugin/registry.go new file mode 100644 index 000000000..7ef0a684c --- /dev/null +++ b/weed/admin/plugin/registry.go @@ -0,0 +1,333 @@ +package plugin + +import ( + "fmt" + "sync" + "time" + + "github.com/seaweedfs/seaweedfs/weed/pb/plugin_pb" +) + +// Registry manages all connected plugins and their capabilities +type Registry struct { + plugins map[string]*ConnectedPlugin + + // Index by job type and capability (detector/executor) + detectorsByJobType map[string][]*ConnectedPlugin + executorsByJobType map[string][]*ConnectedPlugin + + mu sync.RWMutex + + // Configuration + healthCheckInterval time.Duration + healthCheckTimeout time.Duration + healthCheckTicker *time.Ticker + stopChan chan struct{} +} + +// NewRegistry creates a new plugin registry +func NewRegistry() *Registry { + return &Registry{ + plugins: make(map[string]*ConnectedPlugin), + detectorsByJobType: make(map[string][]*ConnectedPlugin), + executorsByJobType: make(map[string][]*ConnectedPlugin), + healthCheckInterval: 30 * time.Second, + healthCheckTimeout: 90 * time.Second, + stopChan: make(chan struct{}), + } +} + +// RegisterPlugin adds a new plugin to the registry +func (r *Registry) RegisterPlugin(pluginID string, register *plugin_pb.PluginRegister) (*ConnectedPlugin, error) { + r.mu.Lock() + defer r.mu.Unlock() + + if _, exists := r.plugins[pluginID]; exists { + return nil, fmt.Errorf("plugin %s already registered", pluginID) + } + + plugin := &ConnectedPlugin{ + ID: pluginID, + Name: register.Name, + Version: register.Version, + ProtocolVersion: register.ProtocolVersion, + ConnectedAt: time.Now(), + LastHeartbeat: time.Now(), + State: PluginStateConnected, + Healthy: true, + Capabilities: make(map[string]*plugin_pb.JobTypeCapability), + StreamConnected: true, + } + + // Index capabilities + for _, cap := range register.Capabilities { + plugin.Capabilities[cap.JobType] = cap + + if cap.CanDetect { + r.detectorsByJobType[cap.JobType] = append(r.detectorsByJobType[cap.JobType], plugin) + } + if cap.CanExecute { + r.executorsByJobType[cap.JobType] = append(r.executorsByJobType[cap.JobType], plugin) + } + } + + r.plugins[pluginID] = plugin + return plugin, nil +} + +// UnregisterPlugin removes a plugin from the registry +func (r *Registry) UnregisterPlugin(pluginID string) error { + r.mu.Lock() + defer r.mu.Unlock() + + plugin, exists := r.plugins[pluginID] + if !exists { + return fmt.Errorf("plugin %s not found", pluginID) + } + + // Remove from capability indexes + for jobType := range plugin.Capabilities { + r.removePluginFromDetectors(jobType, plugin) + r.removePluginFromExecutors(jobType, plugin) + } + + delete(r.plugins, pluginID) + plugin.SetState(PluginStateDisconnected) + return nil +} + +// removePluginFromDetectors removes plugin from detector index for a job type +func (r *Registry) removePluginFromDetectors(jobType string, plugin *ConnectedPlugin) { + detectors := r.detectorsByJobType[jobType] + for i, p := range detectors { + if p.ID == plugin.ID { + r.detectorsByJobType[jobType] = append(detectors[:i], detectors[i+1:]...) + break + } + } + if len(r.detectorsByJobType[jobType]) == 0 { + delete(r.detectorsByJobType, jobType) + } +} + +// removePluginFromExecutors removes plugin from executor index for a job type +func (r *Registry) removePluginFromExecutors(jobType string, plugin *ConnectedPlugin) { + executors := r.executorsByJobType[jobType] + for i, p := range executors { + if p.ID == plugin.ID { + r.executorsByJobType[jobType] = append(executors[:i], executors[i+1:]...) + break + } + } + if len(r.executorsByJobType[jobType]) == 0 { + delete(r.executorsByJobType, jobType) + } +} + +// GetPlugin retrieves a plugin by ID +func (r *Registry) GetPlugin(pluginID string) (*ConnectedPlugin, error) { + r.mu.RLock() + defer r.mu.RUnlock() + + plugin, exists := r.plugins[pluginID] + if !exists { + return nil, fmt.Errorf("plugin %s not found", pluginID) + } + return plugin, nil +} + +// GetDetectorForJobType returns an available detector plugin for a job type +func (r *Registry) GetDetectorForJobType(jobType string) (*ConnectedPlugin, error) { + r.mu.RLock() + defer r.mu.RUnlock() + + detectors, exists := r.detectorsByJobType[jobType] + if !exists || len(detectors) == 0 { + return nil, fmt.Errorf("no detector available for job type %s", jobType) + } + + // Return the first healthy detector + for _, detector := range detectors { + if detector.IsHealthy() { + return detector, nil + } + } + + return nil, fmt.Errorf("no healthy detector available for job type %s", jobType) +} + +// GetExecutorForJobType returns an available executor plugin for a job type +func (r *Registry) GetExecutorForJobType(jobType string) (*ConnectedPlugin, error) { + r.mu.RLock() + defer r.mu.RUnlock() + + executors, exists := r.executorsByJobType[jobType] + if !exists || len(executors) == 0 { + return nil, fmt.Errorf("no executor available for job type %s", jobType) + } + + // Return the first healthy executor with lowest workload + var bestExecutor *ConnectedPlugin + var minLoad int32 = int32(^uint32(0) >> 1) + + for _, executor := range executors { + if executor.IsHealthy() { + load := executor.PendingJobs + executor.RunningJobs + if load < minLoad { + minLoad = load + bestExecutor = executor + } + } + } + + if bestExecutor == nil { + return nil, fmt.Errorf("no healthy executor available for job type %s", jobType) + } + + return bestExecutor, nil +} + +// ListPlugins returns all connected plugins +func (r *Registry) ListPlugins() []*ConnectedPlugin { + r.mu.RLock() + defer r.mu.RUnlock() + + plugins := make([]*ConnectedPlugin, 0, len(r.plugins)) + for _, plugin := range r.plugins { + plugins = append(plugins, plugin) + } + return plugins +} + +// ListPluginsByCapability returns plugins that support a specific job type +func (r *Registry) ListPluginsByCapability(jobType string) []*ConnectedPlugin { + r.mu.RLock() + defer r.mu.RUnlock() + + detectors := r.detectorsByJobType[jobType] + executors := r.executorsByJobType[jobType] + + // Combine and deduplicate + pluginMap := make(map[string]*ConnectedPlugin) + for _, p := range detectors { + pluginMap[p.ID] = p + } + for _, p := range executors { + pluginMap[p.ID] = p + } + + plugins := make([]*ConnectedPlugin, 0, len(pluginMap)) + for _, p := range pluginMap { + plugins = append(plugins, p) + } + return plugins +} + +// UpdateHeartbeat updates plugin heartbeat and health status +func (r *Registry) UpdateHeartbeat(pluginID string, heartbeat *plugin_pb.PluginHeartbeat) error { + r.mu.Lock() + plugin, exists := r.plugins[pluginID] + r.mu.Unlock() + + if !exists { + return fmt.Errorf("plugin %s not found", pluginID) + } + + plugin.UpdateHeartbeat( + heartbeat.CpuUsagePercent, + heartbeat.MemoryUsageMb, + heartbeat.PendingJobs, + int32(len(plugin.Capabilities)), // rough estimate + ) + + return nil +} + +// Start starts the health check loop +func (r *Registry) Start() { + r.healthCheckTicker = time.NewTicker(r.healthCheckInterval) + go r.healthCheckLoop() +} + +// Stop stops the health check loop +func (r *Registry) Stop() { + close(r.stopChan) + if r.healthCheckTicker != nil { + r.healthCheckTicker.Stop() + } +} + +// healthCheckLoop periodically checks plugin health +func (r *Registry) healthCheckLoop() { + for { + select { + case <-r.healthCheckTicker.C: + r.checkHealth() + case <-r.stopChan: + return + } + } +} + +// checkHealth checks the health of all plugins +func (r *Registry) checkHealth() { + r.mu.RLock() + plugins := make([]*ConnectedPlugin, 0, len(r.plugins)) + for _, p := range r.plugins { + plugins = append(plugins, p) + } + r.mu.RUnlock() + + now := time.Now() + for _, plugin := range plugins { + plugin.mu.RLock() + lastHeartbeat := plugin.LastHeartbeat + plugin.mu.RUnlock() + + timeSinceHeartbeat := now.Sub(lastHeartbeat) + + if timeSinceHeartbeat > r.healthCheckTimeout { + plugin.SetState(PluginStateUnhealthy) + plugin.mu.Lock() + plugin.Healthy = false + plugin.mu.Unlock() + } else if timeSinceHeartbeat > r.healthCheckTimeout/2 { + plugin.SetState(PluginStateUnhealthy) + } else { + plugin.SetState(PluginStateHealthy) + plugin.mu.Lock() + plugin.Healthy = true + plugin.mu.Unlock() + } + } +} + +// GetStats returns registry statistics +func (r *Registry) GetStats() map[string]interface{} { + r.mu.RLock() + defer r.mu.RUnlock() + + stats := map[string]interface{}{ + "total_plugins": len(r.plugins), + "job_types": len(r.detectorsByJobType), + } + + var healthyCount int + for _, p := range r.plugins { + if p.IsHealthy() { + healthyCount++ + } + } + stats["healthy_plugins"] = healthyCount + + jobTypeStats := make(map[string]map[string]interface{}) + for jobType := range r.detectorsByJobType { + jobTypeStats[jobType] = map[string]interface{}{ + "detectors": len(r.detectorsByJobType[jobType]), + "executors": len(r.executorsByJobType[jobType]), + } + } + stats["job_type_stats"] = jobTypeStats + + return stats +} diff --git a/weed/admin/plugin/types.go b/weed/admin/plugin/types.go new file mode 100644 index 000000000..de27ee5c0 --- /dev/null +++ b/weed/admin/plugin/types.go @@ -0,0 +1,227 @@ +package plugin + +import ( + "sync" + "time" + + "github.com/seaweedfs/seaweedfs/weed/pb/plugin_pb" + "google.golang.org/protobuf/types/known/timestamppb" +) + +// JobState represents the current state of a job +type JobState int32 + +const ( + JobStatePending JobState = 0 + JobStateRunning JobState = 1 + JobStateCompleted JobState = 2 + JobStateFailed JobState = 3 + JobStateCancelled JobState = 4 + JobStatePaused JobState = 5 +) + +// String returns string representation of JobState +func (s JobState) String() string { + switch s { + case JobStatePending: + return "pending" + case JobStateRunning: + return "running" + case JobStateCompleted: + return "completed" + case JobStateFailed: + return "failed" + case JobStateCancelled: + return "cancelled" + case JobStatePaused: + return "paused" + default: + return "unknown" + } +} + +// PluginState represents the current state of a plugin connection +type PluginState int32 + +const ( + PluginStateConnecting PluginState = 0 + PluginStateConnected PluginState = 1 + PluginStateHealthy PluginState = 2 + PluginStateUnhealthy PluginState = 3 + PluginStateDisconnected PluginState = 4 +) + +// String returns string representation of PluginState +func (s PluginState) String() string { + switch s { + case PluginStateConnecting: + return "connecting" + case PluginStateConnected: + return "connected" + case PluginStateHealthy: + return "healthy" + case PluginStateUnhealthy: + return "unhealthy" + case PluginStateDisconnected: + return "disconnected" + default: + return "unknown" + } +} + +// Job represents a work unit in the plugin system +type Job struct { + ID string + Type string + Description string + Priority int64 + State JobState + CreatedAt time.Time + UpdatedAt time.Time + ExecutorID string + ProgressPercent int32 + Config []*plugin_pb.ConfigFieldValue + Metadata map[string]string + + // Execution tracking + Retries int32 + LastRetryTime time.Time + CompletedInfo *plugin_pb.JobCompleted + FailedInfo *plugin_pb.JobFailed + CheckpointIDs []string + LogEntries []*plugin_pb.ExecutionLogEntry + + // Lock for thread-safe access + mu sync.RWMutex +} + +// ConnectedPlugin represents a connected plugin worker +type ConnectedPlugin struct { + ID string + Name string + Version string + ProtocolVersion string + ConnectedAt time.Time + LastHeartbeat time.Time + State PluginState + Healthy bool + + // Capabilities indexed by job type + Capabilities map[string]*plugin_pb.JobTypeCapability + + // Current workload + PendingJobs int32 + RunningJobs int32 + + // Resource usage + CPUUsagePercent float32 + MemoryUsageMB float32 + + // Communication stream + StreamConnected bool + + // Lock for thread-safe access + mu sync.RWMutex +} + +// JobTypeConfig holds configuration for a specific job type +type JobTypeConfig struct { + JobType string + Enabled bool + AdminConfig []*plugin_pb.ConfigFieldValue + WorkerConfig []*plugin_pb.ConfigFieldValue + CreatedAt time.Time + UpdatedAt time.Time + CreatedBy string + + mu sync.RWMutex +} + +// GetState safely gets the job state +func (j *Job) GetState() JobState { + j.mu.RLock() + defer j.mu.RUnlock() + return j.State +} + +// SetState safely sets the job state +func (j *Job) SetState(state JobState) { + j.mu.Lock() + defer j.mu.Unlock() + j.State = state + j.UpdatedAt = time.Now() +} + +// GetProgress safely gets progress +func (j *Job) GetProgress() int32 { + j.mu.RLock() + defer j.mu.RUnlock() + return j.ProgressPercent +} + +// SetProgress safely sets progress +func (j *Job) SetProgress(percent int32) { + j.mu.Lock() + defer j.mu.Unlock() + j.ProgressPercent = percent + j.UpdatedAt = time.Now() +} + +// GetState safely gets plugin state +func (p *ConnectedPlugin) GetState() PluginState { + p.mu.RLock() + defer p.mu.RUnlock() + return p.State +} + +// SetState safely sets plugin state +func (p *ConnectedPlugin) SetState(state PluginState) { + p.mu.Lock() + defer p.mu.Unlock() + p.State = state + p.LastHeartbeat = time.Now() +} + +// IsHealthy safely checks if plugin is healthy +func (p *ConnectedPlugin) IsHealthy() bool { + p.mu.RLock() + defer p.mu.RUnlock() + return p.Healthy +} + +// UpdateHeartbeat safely updates heartbeat +func (p *ConnectedPlugin) UpdateHeartbeat(cpu, memory float32, pending, running int32) { + p.mu.Lock() + defer p.mu.Unlock() + p.LastHeartbeat = time.Now() + p.CPUUsagePercent = cpu + p.MemoryUsageMB = memory + p.PendingJobs = pending + p.RunningJobs = running +} + +// GetConfig safely gets configuration +func (c *JobTypeConfig) GetConfig() (*plugin_pb.JobTypeConfig, error) { + c.mu.RLock() + defer c.mu.RUnlock() + + return &plugin_pb.JobTypeConfig{ + JobType: c.JobType, + Enabled: c.Enabled, + AdminConfig: c.AdminConfig, + WorkerConfig: c.WorkerConfig, + CreatedAt: timestamppb.New(c.CreatedAt), + UpdatedAt: timestamppb.New(c.UpdatedAt), + CreatedBy: c.CreatedBy, + }, nil +} + +// SetConfig safely sets configuration +func (c *JobTypeConfig) SetConfig(enabled bool, adminConfig, workerConfig []*plugin_pb.ConfigFieldValue) { + c.mu.Lock() + defer c.mu.Unlock() + c.Enabled = enabled + c.AdminConfig = adminConfig + c.WorkerConfig = workerConfig + c.UpdatedAt = time.Now() +} diff --git a/weed/pb/Makefile b/weed/pb/Makefile index e5db76426..70d75b59b 100644 --- a/weed/pb/Makefile +++ b/weed/pb/Makefile @@ -14,6 +14,7 @@ gen: protoc mq_schema.proto --go_out=./schema_pb --go-grpc_out=./schema_pb --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative protoc mq_agent.proto --go_out=./mq_agent_pb --go-grpc_out=./mq_agent_pb --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative protoc worker.proto --go_out=./worker_pb --go-grpc_out=./worker_pb --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative + protoc plugin.proto --go_out=./plugin_pb --go-grpc_out=./plugin_pb --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative # protoc filer.proto --java_out=../../other/java/client/src/main/java cp filer.proto ../../other/java/client/src/main/proto diff --git a/weed/pb/plugin.proto b/weed/pb/plugin.proto new file mode 100644 index 000000000..dcae728fa --- /dev/null +++ b/weed/pb/plugin.proto @@ -0,0 +1,558 @@ +syntax = "proto3"; + +package seaweed_pb; + +option go_package = "github.com/seaweedfs/seaweedfs/weed/pb/plugin_pb"; + +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/empty.proto"; + +// PluginService: Worker-to-Admin communication service +// Workers establish bidirectional streaming connections to register and execute jobs +service PluginService { + // Connect: Bidirectional stream for plugin registration, heartbeat, and lifecycle + rpc Connect(stream PluginMessage) returns (stream AdminMessage); + + // ExecuteJob: Bidirectional stream for job execution with progress updates + rpc ExecuteJob(stream JobExecutionMessage) returns (stream JobProgressMessage); +} + +// AdminQueryService: Read-only queries for UI and monitoring +service AdminQueryService { + // GetPluginStats: Get current plugin system statistics + rpc GetPluginStats(google.protobuf.Empty) returns (PluginStats); + + // ListPlugins: List all connected plugins with their capabilities + rpc ListPlugins(google.protobuf.Empty) returns (PluginList); + + // ListJobs: List jobs by type and status + rpc ListJobs(ListJobsRequest) returns (JobList); + + // GetJob: Get detailed job information + rpc GetJob(GetJobRequest) returns (JobDetail); + + // GetJobExecutionLog: Stream job execution logs + rpc GetJobExecutionLog(GetJobExecutionLogRequest) returns (stream ExecutionLogEntry); +} + +// AdminCommandService: Write operations for job management +service AdminCommandService { + // UpdateJobTypeConfig: Update configuration for a job type + rpc UpdateJobTypeConfig(UpdateJobTypeConfigRequest) returns (JobTypeConfig); + + // CreateJob: Manually create a job + rpc CreateJob(CreateJobRequest) returns (Job); + + // CancelJob: Cancel a running job + rpc CancelJob(CancelJobRequest) returns (google.protobuf.Empty); + + // RetryJob: Retry a failed job + rpc RetryJob(RetryJobRequest) returns (Job); +} + +// ============================================================================ +// LIFECYCLE AND REGISTRATION MESSAGES +// ============================================================================ + +// PluginMessage: Messages sent by worker to admin +message PluginMessage { + oneof content { + PluginRegister register = 1; + PluginHeartbeat heartbeat = 2; + ExecutionStatusUpdate status_update = 3; + } +} + +// AdminMessage: Messages sent by admin to worker +message AdminMessage { + oneof content { + JobRequest job_request = 1; + ConfigUpdate config_update = 2; + AdminCommand admin_command = 3; + } +} + +// PluginRegister: Initial registration message from worker +message PluginRegister { + string plugin_id = 1; // Unique plugin identifier + string name = 2; // Human-readable plugin name + string version = 3; // Plugin version + string protocol_version = 4; // Protocol version (e.g., "v1") + repeated JobTypeCapability capabilities = 5; // Job types this plugin can handle +} + +// JobTypeCapability: Declares what job type a plugin handles +message JobTypeCapability { + string job_type = 1; // Job type identifier (e.g., "erasure_coding", "vacuum") + bool can_detect = 2; // Plugin can detect jobs of this type + bool can_execute = 3; // Plugin can execute jobs of this type + string version = 4; // Job type version +} + +// PluginHeartbeat: Periodic heartbeat to keep connection alive +message PluginHeartbeat { + string plugin_id = 1; + google.protobuf.Timestamp timestamp = 2; + int64 uptime_seconds = 3; + int32 pending_jobs = 4; + float cpu_usage_percent = 5; + float memory_usage_mb = 6; +} + +// ============================================================================ +// CONFIGURATION SCHEMA MESSAGES +// ============================================================================ + +// ConfigField: Declarative field definition for UI generation +message ConfigField { + enum FieldType { + BOOL = 0; + INT = 1; + FLOAT = 2; + STRING = 3; + DURATION = 4; + SELECT = 5; + MULTISELECT = 6; + SECRET = 7; + TEXTAREA = 8; + JSON = 9; + PERCENTAGE = 10; + BYTES = 11; + CRON = 12; + } + + string name = 1; // Field identifier + string label = 2; // Display label + string description = 3; // Help text + FieldType field_type = 4; // UI control type + bool required = 5; // Is required + string default_value = 6; // Default value + repeated ValidationRule validation_rules = 7; // Validation constraints + repeated ConfigOption options = 8; // For SELECT/MULTISELECT + ConfigField.Options options_msg = 9; // Additional options + + message Options { + string placeholder = 1; + repeated string suggestions = 2; + int32 min_length = 3; + int32 max_length = 4; + int32 min_value = 5; + int32 max_value = 6; + float min_float = 7; + float max_float = 8; + } +} + +// ValidationRule: Constraint for field validation +message ValidationRule { + enum RuleType { + MIN_VALUE = 0; + MAX_VALUE = 1; + PATTERN = 2; + MIN_LENGTH = 3; + MAX_LENGTH = 4; + CUSTOM = 5; + } + + RuleType rule_type = 1; + string value = 2; + string error_message = 3; +} + +// ConfigOption: Selection option for SELECT/MULTISELECT +message ConfigOption { + string value = 1; + string label = 2; + string description = 3; +} + +// ConfigFieldValue: Value for a config field +message ConfigFieldValue { + string field_name = 1; + string string_value = 2; // For STRING, CRON + int64 int_value = 3; // For INT, BYTES + float float_value = 4; // For FLOAT, PERCENTAGE + bool bool_value = 5; // For BOOL + google.protobuf.Duration duration_value = 6; // For DURATION + repeated string multiselect_values = 7; // For MULTISELECT + string json_value = 8; // For JSON +} + +// JobTypeConfig: Configuration for a job type +message JobTypeConfig { + string job_type = 1; + bool enabled = 2; + repeated ConfigFieldValue admin_config = 3; // Admin-managed settings + repeated ConfigFieldValue worker_config = 4; // Worker-managed settings + google.protobuf.Timestamp created_at = 5; + google.protobuf.Timestamp updated_at = 6; + string created_by = 7; +} + +// ConfigUpdateRequest: Request to update job type configuration +message ConfigUpdateRequest { + string job_type = 1; + repeated ConfigFieldValue config_values = 2; +} + +// ============================================================================ +// CONFIGURATION SCHEMA DISCOVERY +// ============================================================================ + +// GetConfigurationSchemaRequest: Request for config schema +message GetConfigurationSchemaRequest { + string job_type = 1; +} + +// JobTypeConfigSchema: Complete configuration schema for a job type +message JobTypeConfigSchema { + string job_type = 1; + string version = 2; + string description = 3; + repeated ConfigField admin_fields = 4; // Fields managed by admin UI + repeated ConfigField worker_fields = 5; // Fields managed by worker + repeated ConfigGroup field_groups = 6; // Field grouping for UI +} + +// ConfigGroup: Grouping of related fields for UI organization +message ConfigGroup { + string name = 1; + string label = 2; + string description = 3; + repeated string field_names = 4; +} + +// ============================================================================ +// JOB DETECTION MESSAGES +// ============================================================================ + +// DetectionRequest: Request to detect jobs +message DetectionRequest { + string job_type = 1; + JobTypeConfig config = 2; // Current configuration + repeated string filter_tags = 3; // Optional filtering +} + +// DetectionResponse: Response from detection +message DetectionResponse { + repeated DetectedJob detected_jobs = 1; + google.protobuf.Timestamp detection_time = 2; + string detector_plugin_id = 3; +} + +// DetectedJob: A job candidate detected by worker +message DetectedJob { + string job_key = 1; // Unique key for deduplication + string job_type = 2; + string description = 3; // Human-readable description + int64 priority = 4; // Higher = higher priority + google.protobuf.Duration estimated_duration = 5; // Estimated execution time + map metadata = 6; // Job-specific metadata + repeated ConfigFieldValue suggested_config = 7; // Suggested overrides +} + +// ============================================================================ +// JOB EXECUTION MESSAGES +// ============================================================================ + +// JobRequest: Request to execute a job +message JobRequest { + string job_id = 1; + string job_type = 2; + string description = 3; + int64 priority = 4; + google.protobuf.Timestamp created_at = 5; + repeated ConfigFieldValue config = 6; // Job-specific config + map metadata = 7; // Job metadata + string request_source = 8; // admin | detection | retry +} + +// JobExecutionMessage: Messages from worker during job execution +message JobExecutionMessage { + string job_id = 1; + oneof content { + JobStarted job_started = 2; + JobProgress progress = 3; + JobCheckpoint checkpoint = 4; + JobCompleted job_completed = 5; + JobFailed job_failed = 6; + ExecutionLog log_entry = 7; + } +} + +// JobStarted: Job execution started +message JobStarted { + google.protobuf.Timestamp started_at = 1; + string executor_id = 2; // Plugin executor ID +} + +// JobProgress: Progress update during execution +message JobProgress { + int32 progress_percent = 1; // 0-100 + string current_step = 2; + string status_message = 3; + google.protobuf.Timestamp updated_at = 4; +} + +// JobCheckpoint: Checkpoint for resuming jobs +message JobCheckpoint { + string checkpoint_id = 1; + bytes checkpoint_data = 2; // Serialized checkpoint + google.protobuf.Timestamp created_at = 3; +} + +// JobCompleted: Job execution completed successfully +message JobCompleted { + google.protobuf.Timestamp completed_at = 1; + string summary = 2; + map output = 3; // Job output data +} + +// JobFailed: Job execution failed +message JobFailed { + string error_code = 1; // Error classification + string error_message = 2; // Human-readable error + bytes error_details = 3; // Detailed error data + bool retryable = 4; // Can this job be retried + google.protobuf.Timestamp failed_at = 5; + int32 retry_count = 6; +} + +// ExecutionLog: Log entry during job execution +message ExecutionLog { + enum LogLevel { + DEBUG = 0; + INFO = 1; + WARNING = 2; + ERROR = 3; + } + + google.protobuf.Timestamp timestamp = 1; + LogLevel level = 2; + string message = 3; + map context = 4; +} + +// JobProgressMessage: Messages from admin to worker +message JobProgressMessage { + string job_id = 1; + oneof content { + JobProgressUpdate update = 2; + ExecutionCommand command = 3; + } +} + +// JobProgressUpdate: Status update for UI +message JobProgressUpdate { + string job_id = 1; + int32 progress_percent = 2; + string current_step = 3; + string status_message = 4; + google.protobuf.Timestamp timestamp = 5; +} + +// ExecutionCommand: Command from admin to worker +message ExecutionCommand { + enum CommandType { + PAUSE = 0; + RESUME = 1; + CANCEL = 2; + GET_STATUS = 3; + } + + string job_id = 1; + CommandType command_type = 2; + map parameters = 3; +} + +// ============================================================================ +// STATUS UPDATE MESSAGES +// ============================================================================ + +// ExecutionStatusUpdate: Status update from worker +message ExecutionStatusUpdate { + string plugin_id = 1; + string job_id = 2; + string status = 3; // running | completed | failed | paused + int32 progress_percent = 4; + google.protobuf.Timestamp timestamp = 5; +} + +// ConfigUpdate: Configuration update message +message ConfigUpdate { + string job_type = 1; + repeated ConfigFieldValue config_values = 2; + google.protobuf.Timestamp updated_at = 3; +} + +// AdminCommand: Admin command to worker +message AdminCommand { + enum CommandType { + RELOAD_CONFIG = 0; + ENABLE_JOB_TYPE = 1; + DISABLE_JOB_TYPE = 2; + SHUTDOWN = 3; + } + + CommandType command_type = 1; + map parameters = 2; +} + +// ============================================================================ +// QUERY/COMMAND REQUEST/RESPONSE MESSAGES +// ============================================================================ + +// ListJobsRequest: Request to list jobs +message ListJobsRequest { + string job_type = 1; + enum StatusFilter { + ALL = 0; + PENDING = 1; + RUNNING = 2; + COMPLETED = 3; + FAILED = 4; + } + + StatusFilter status = 2; + int32 limit = 3; + int32 offset = 4; +} + +// GetJobRequest: Request for specific job +message GetJobRequest { + string job_id = 1; +} + +// GetJobExecutionLogRequest: Request for job logs +message GetJobExecutionLogRequest { + string job_id = 1; + enum LogLevel { + DEBUG = 0; + INFO = 1; + WARNING = 2; + ERROR = 3; + ALL = 4; + } + + LogLevel level = 2; + int32 tail_lines = 3; +} + +// ============================================================================ +// RESPONSE MESSAGES +// ============================================================================ + +// Job: Job information +message Job { + string job_id = 1; + string job_type = 2; + string description = 3; + int64 priority = 4; + enum Status { + PENDING = 0; + RUNNING = 1; + COMPLETED = 2; + FAILED = 3; + CANCELLED = 4; + PAUSED = 5; + } + + Status status = 5; + google.protobuf.Timestamp created_at = 6; + google.protobuf.Timestamp updated_at = 7; + string executor_plugin_id = 8; + int32 progress_percent = 9; + repeated ConfigFieldValue config = 10; +} + +// JobDetail: Detailed job information with execution history +message JobDetail { + Job job = 1; + repeated ExecutionLogEntry log_entries = 2; + JobCompleted completion_info = 3; + JobFailed failure_info = 4; + repeated string checkpoint_ids = 5; +} + +// ExecutionLogEntry: Log entry with metadata +message ExecutionLogEntry { + google.protobuf.Timestamp timestamp = 1; + ExecutionLog.LogLevel level = 2; + string message = 3; + map context = 4; +} + +// JobList: List of jobs +message JobList { + repeated Job jobs = 1; + int32 total_count = 2; + int32 returned_count = 3; +} + +// PluginStats: System-wide statistics +message PluginStats { + int32 total_plugins = 1; + int32 active_plugins = 2; + int32 total_jobs = 3; + int32 pending_jobs = 4; + int32 running_jobs = 5; + int32 completed_jobs = 6; + int32 failed_jobs = 7; + google.protobuf.Timestamp last_update = 8; + map job_type_stats = 9; +} + +// JobTypeStats: Statistics for a job type +message JobTypeStats { + string job_type = 1; + int32 total = 2; + int32 pending = 3; + int32 running = 4; + int32 completed = 5; + int32 failed = 6; + float success_rate = 7; + google.protobuf.Duration avg_execution_time = 8; +} + +// PluginList: List of connected plugins +message PluginList { + repeated PluginInfo plugins = 1; +} + +// PluginInfo: Information about a connected plugin +message PluginInfo { + string plugin_id = 1; + string name = 2; + string version = 3; + string protocol_version = 4; + google.protobuf.Timestamp connected_at = 5; + google.protobuf.Timestamp last_heartbeat = 6; + repeated JobTypeCapability capabilities = 7; + bool healthy = 8; + string status = 9; +} + +// UpdateJobTypeConfigRequest: Request to update config +message UpdateJobTypeConfigRequest { + JobTypeConfig config = 1; +} + +// CreateJobRequest: Request to create a job +message CreateJobRequest { + string job_type = 1; + string description = 2; + int64 priority = 3; + repeated ConfigFieldValue config = 4; + map metadata = 5; +} + +// CancelJobRequest: Request to cancel a job +message CancelJobRequest { + string job_id = 1; +} + +// RetryJobRequest: Request to retry a job +message RetryJobRequest { + string job_id = 1; +} diff --git a/weed/pb/plugin_pb/plugin.pb.go b/weed/pb/plugin_pb/plugin.pb.go new file mode 100644 index 000000000..a9761f75b --- /dev/null +++ b/weed/pb/plugin_pb/plugin.pb.go @@ -0,0 +1,4719 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v6.33.4 +// source: plugin.proto + +package plugin_pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + emptypb "google.golang.org/protobuf/types/known/emptypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ConfigField_FieldType int32 + +const ( + ConfigField_BOOL ConfigField_FieldType = 0 + ConfigField_INT ConfigField_FieldType = 1 + ConfigField_FLOAT ConfigField_FieldType = 2 + ConfigField_STRING ConfigField_FieldType = 3 + ConfigField_DURATION ConfigField_FieldType = 4 + ConfigField_SELECT ConfigField_FieldType = 5 + ConfigField_MULTISELECT ConfigField_FieldType = 6 + ConfigField_SECRET ConfigField_FieldType = 7 + ConfigField_TEXTAREA ConfigField_FieldType = 8 + ConfigField_JSON ConfigField_FieldType = 9 + ConfigField_PERCENTAGE ConfigField_FieldType = 10 + ConfigField_BYTES ConfigField_FieldType = 11 + ConfigField_CRON ConfigField_FieldType = 12 +) + +// Enum value maps for ConfigField_FieldType. +var ( + ConfigField_FieldType_name = map[int32]string{ + 0: "BOOL", + 1: "INT", + 2: "FLOAT", + 3: "STRING", + 4: "DURATION", + 5: "SELECT", + 6: "MULTISELECT", + 7: "SECRET", + 8: "TEXTAREA", + 9: "JSON", + 10: "PERCENTAGE", + 11: "BYTES", + 12: "CRON", + } + ConfigField_FieldType_value = map[string]int32{ + "BOOL": 0, + "INT": 1, + "FLOAT": 2, + "STRING": 3, + "DURATION": 4, + "SELECT": 5, + "MULTISELECT": 6, + "SECRET": 7, + "TEXTAREA": 8, + "JSON": 9, + "PERCENTAGE": 10, + "BYTES": 11, + "CRON": 12, + } +) + +func (x ConfigField_FieldType) Enum() *ConfigField_FieldType { + p := new(ConfigField_FieldType) + *p = x + return p +} + +func (x ConfigField_FieldType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ConfigField_FieldType) Descriptor() protoreflect.EnumDescriptor { + return file_plugin_proto_enumTypes[0].Descriptor() +} + +func (ConfigField_FieldType) Type() protoreflect.EnumType { + return &file_plugin_proto_enumTypes[0] +} + +func (x ConfigField_FieldType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ConfigField_FieldType.Descriptor instead. +func (ConfigField_FieldType) EnumDescriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{5, 0} +} + +type ValidationRule_RuleType int32 + +const ( + ValidationRule_MIN_VALUE ValidationRule_RuleType = 0 + ValidationRule_MAX_VALUE ValidationRule_RuleType = 1 + ValidationRule_PATTERN ValidationRule_RuleType = 2 + ValidationRule_MIN_LENGTH ValidationRule_RuleType = 3 + ValidationRule_MAX_LENGTH ValidationRule_RuleType = 4 + ValidationRule_CUSTOM ValidationRule_RuleType = 5 +) + +// Enum value maps for ValidationRule_RuleType. +var ( + ValidationRule_RuleType_name = map[int32]string{ + 0: "MIN_VALUE", + 1: "MAX_VALUE", + 2: "PATTERN", + 3: "MIN_LENGTH", + 4: "MAX_LENGTH", + 5: "CUSTOM", + } + ValidationRule_RuleType_value = map[string]int32{ + "MIN_VALUE": 0, + "MAX_VALUE": 1, + "PATTERN": 2, + "MIN_LENGTH": 3, + "MAX_LENGTH": 4, + "CUSTOM": 5, + } +) + +func (x ValidationRule_RuleType) Enum() *ValidationRule_RuleType { + p := new(ValidationRule_RuleType) + *p = x + return p +} + +func (x ValidationRule_RuleType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ValidationRule_RuleType) Descriptor() protoreflect.EnumDescriptor { + return file_plugin_proto_enumTypes[1].Descriptor() +} + +func (ValidationRule_RuleType) Type() protoreflect.EnumType { + return &file_plugin_proto_enumTypes[1] +} + +func (x ValidationRule_RuleType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ValidationRule_RuleType.Descriptor instead. +func (ValidationRule_RuleType) EnumDescriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{6, 0} +} + +type ExecutionLog_LogLevel int32 + +const ( + ExecutionLog_DEBUG ExecutionLog_LogLevel = 0 + ExecutionLog_INFO ExecutionLog_LogLevel = 1 + ExecutionLog_WARNING ExecutionLog_LogLevel = 2 + ExecutionLog_ERROR ExecutionLog_LogLevel = 3 +) + +// Enum value maps for ExecutionLog_LogLevel. +var ( + ExecutionLog_LogLevel_name = map[int32]string{ + 0: "DEBUG", + 1: "INFO", + 2: "WARNING", + 3: "ERROR", + } + ExecutionLog_LogLevel_value = map[string]int32{ + "DEBUG": 0, + "INFO": 1, + "WARNING": 2, + "ERROR": 3, + } +) + +func (x ExecutionLog_LogLevel) Enum() *ExecutionLog_LogLevel { + p := new(ExecutionLog_LogLevel) + *p = x + return p +} + +func (x ExecutionLog_LogLevel) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ExecutionLog_LogLevel) Descriptor() protoreflect.EnumDescriptor { + return file_plugin_proto_enumTypes[2].Descriptor() +} + +func (ExecutionLog_LogLevel) Type() protoreflect.EnumType { + return &file_plugin_proto_enumTypes[2] +} + +func (x ExecutionLog_LogLevel) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ExecutionLog_LogLevel.Descriptor instead. +func (ExecutionLog_LogLevel) EnumDescriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{24, 0} +} + +type ExecutionCommand_CommandType int32 + +const ( + ExecutionCommand_PAUSE ExecutionCommand_CommandType = 0 + ExecutionCommand_RESUME ExecutionCommand_CommandType = 1 + ExecutionCommand_CANCEL ExecutionCommand_CommandType = 2 + ExecutionCommand_GET_STATUS ExecutionCommand_CommandType = 3 +) + +// Enum value maps for ExecutionCommand_CommandType. +var ( + ExecutionCommand_CommandType_name = map[int32]string{ + 0: "PAUSE", + 1: "RESUME", + 2: "CANCEL", + 3: "GET_STATUS", + } + ExecutionCommand_CommandType_value = map[string]int32{ + "PAUSE": 0, + "RESUME": 1, + "CANCEL": 2, + "GET_STATUS": 3, + } +) + +func (x ExecutionCommand_CommandType) Enum() *ExecutionCommand_CommandType { + p := new(ExecutionCommand_CommandType) + *p = x + return p +} + +func (x ExecutionCommand_CommandType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ExecutionCommand_CommandType) Descriptor() protoreflect.EnumDescriptor { + return file_plugin_proto_enumTypes[3].Descriptor() +} + +func (ExecutionCommand_CommandType) Type() protoreflect.EnumType { + return &file_plugin_proto_enumTypes[3] +} + +func (x ExecutionCommand_CommandType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ExecutionCommand_CommandType.Descriptor instead. +func (ExecutionCommand_CommandType) EnumDescriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{27, 0} +} + +type AdminCommand_CommandType int32 + +const ( + AdminCommand_RELOAD_CONFIG AdminCommand_CommandType = 0 + AdminCommand_ENABLE_JOB_TYPE AdminCommand_CommandType = 1 + AdminCommand_DISABLE_JOB_TYPE AdminCommand_CommandType = 2 + AdminCommand_SHUTDOWN AdminCommand_CommandType = 3 +) + +// Enum value maps for AdminCommand_CommandType. +var ( + AdminCommand_CommandType_name = map[int32]string{ + 0: "RELOAD_CONFIG", + 1: "ENABLE_JOB_TYPE", + 2: "DISABLE_JOB_TYPE", + 3: "SHUTDOWN", + } + AdminCommand_CommandType_value = map[string]int32{ + "RELOAD_CONFIG": 0, + "ENABLE_JOB_TYPE": 1, + "DISABLE_JOB_TYPE": 2, + "SHUTDOWN": 3, + } +) + +func (x AdminCommand_CommandType) Enum() *AdminCommand_CommandType { + p := new(AdminCommand_CommandType) + *p = x + return p +} + +func (x AdminCommand_CommandType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AdminCommand_CommandType) Descriptor() protoreflect.EnumDescriptor { + return file_plugin_proto_enumTypes[4].Descriptor() +} + +func (AdminCommand_CommandType) Type() protoreflect.EnumType { + return &file_plugin_proto_enumTypes[4] +} + +func (x AdminCommand_CommandType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AdminCommand_CommandType.Descriptor instead. +func (AdminCommand_CommandType) EnumDescriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{30, 0} +} + +type ListJobsRequest_StatusFilter int32 + +const ( + ListJobsRequest_ALL ListJobsRequest_StatusFilter = 0 + ListJobsRequest_PENDING ListJobsRequest_StatusFilter = 1 + ListJobsRequest_RUNNING ListJobsRequest_StatusFilter = 2 + ListJobsRequest_COMPLETED ListJobsRequest_StatusFilter = 3 + ListJobsRequest_FAILED ListJobsRequest_StatusFilter = 4 +) + +// Enum value maps for ListJobsRequest_StatusFilter. +var ( + ListJobsRequest_StatusFilter_name = map[int32]string{ + 0: "ALL", + 1: "PENDING", + 2: "RUNNING", + 3: "COMPLETED", + 4: "FAILED", + } + ListJobsRequest_StatusFilter_value = map[string]int32{ + "ALL": 0, + "PENDING": 1, + "RUNNING": 2, + "COMPLETED": 3, + "FAILED": 4, + } +) + +func (x ListJobsRequest_StatusFilter) Enum() *ListJobsRequest_StatusFilter { + p := new(ListJobsRequest_StatusFilter) + *p = x + return p +} + +func (x ListJobsRequest_StatusFilter) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ListJobsRequest_StatusFilter) Descriptor() protoreflect.EnumDescriptor { + return file_plugin_proto_enumTypes[5].Descriptor() +} + +func (ListJobsRequest_StatusFilter) Type() protoreflect.EnumType { + return &file_plugin_proto_enumTypes[5] +} + +func (x ListJobsRequest_StatusFilter) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ListJobsRequest_StatusFilter.Descriptor instead. +func (ListJobsRequest_StatusFilter) EnumDescriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{31, 0} +} + +type GetJobExecutionLogRequest_LogLevel int32 + +const ( + GetJobExecutionLogRequest_DEBUG GetJobExecutionLogRequest_LogLevel = 0 + GetJobExecutionLogRequest_INFO GetJobExecutionLogRequest_LogLevel = 1 + GetJobExecutionLogRequest_WARNING GetJobExecutionLogRequest_LogLevel = 2 + GetJobExecutionLogRequest_ERROR GetJobExecutionLogRequest_LogLevel = 3 + GetJobExecutionLogRequest_ALL GetJobExecutionLogRequest_LogLevel = 4 +) + +// Enum value maps for GetJobExecutionLogRequest_LogLevel. +var ( + GetJobExecutionLogRequest_LogLevel_name = map[int32]string{ + 0: "DEBUG", + 1: "INFO", + 2: "WARNING", + 3: "ERROR", + 4: "ALL", + } + GetJobExecutionLogRequest_LogLevel_value = map[string]int32{ + "DEBUG": 0, + "INFO": 1, + "WARNING": 2, + "ERROR": 3, + "ALL": 4, + } +) + +func (x GetJobExecutionLogRequest_LogLevel) Enum() *GetJobExecutionLogRequest_LogLevel { + p := new(GetJobExecutionLogRequest_LogLevel) + *p = x + return p +} + +func (x GetJobExecutionLogRequest_LogLevel) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (GetJobExecutionLogRequest_LogLevel) Descriptor() protoreflect.EnumDescriptor { + return file_plugin_proto_enumTypes[6].Descriptor() +} + +func (GetJobExecutionLogRequest_LogLevel) Type() protoreflect.EnumType { + return &file_plugin_proto_enumTypes[6] +} + +func (x GetJobExecutionLogRequest_LogLevel) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use GetJobExecutionLogRequest_LogLevel.Descriptor instead. +func (GetJobExecutionLogRequest_LogLevel) EnumDescriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{33, 0} +} + +type Job_Status int32 + +const ( + Job_PENDING Job_Status = 0 + Job_RUNNING Job_Status = 1 + Job_COMPLETED Job_Status = 2 + Job_FAILED Job_Status = 3 + Job_CANCELLED Job_Status = 4 + Job_PAUSED Job_Status = 5 +) + +// Enum value maps for Job_Status. +var ( + Job_Status_name = map[int32]string{ + 0: "PENDING", + 1: "RUNNING", + 2: "COMPLETED", + 3: "FAILED", + 4: "CANCELLED", + 5: "PAUSED", + } + Job_Status_value = map[string]int32{ + "PENDING": 0, + "RUNNING": 1, + "COMPLETED": 2, + "FAILED": 3, + "CANCELLED": 4, + "PAUSED": 5, + } +) + +func (x Job_Status) Enum() *Job_Status { + p := new(Job_Status) + *p = x + return p +} + +func (x Job_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Job_Status) Descriptor() protoreflect.EnumDescriptor { + return file_plugin_proto_enumTypes[7].Descriptor() +} + +func (Job_Status) Type() protoreflect.EnumType { + return &file_plugin_proto_enumTypes[7] +} + +func (x Job_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Job_Status.Descriptor instead. +func (Job_Status) EnumDescriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{34, 0} +} + +// PluginMessage: Messages sent by worker to admin +type PluginMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *PluginMessage_Register + // *PluginMessage_Heartbeat + // *PluginMessage_StatusUpdate + Content isPluginMessage_Content `protobuf_oneof:"content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PluginMessage) Reset() { + *x = PluginMessage{} + mi := &file_plugin_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PluginMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PluginMessage) ProtoMessage() {} + +func (x *PluginMessage) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PluginMessage.ProtoReflect.Descriptor instead. +func (*PluginMessage) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{0} +} + +func (x *PluginMessage) GetContent() isPluginMessage_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *PluginMessage) GetRegister() *PluginRegister { + if x != nil { + if x, ok := x.Content.(*PluginMessage_Register); ok { + return x.Register + } + } + return nil +} + +func (x *PluginMessage) GetHeartbeat() *PluginHeartbeat { + if x != nil { + if x, ok := x.Content.(*PluginMessage_Heartbeat); ok { + return x.Heartbeat + } + } + return nil +} + +func (x *PluginMessage) GetStatusUpdate() *ExecutionStatusUpdate { + if x != nil { + if x, ok := x.Content.(*PluginMessage_StatusUpdate); ok { + return x.StatusUpdate + } + } + return nil +} + +type isPluginMessage_Content interface { + isPluginMessage_Content() +} + +type PluginMessage_Register struct { + Register *PluginRegister `protobuf:"bytes,1,opt,name=register,proto3,oneof"` +} + +type PluginMessage_Heartbeat struct { + Heartbeat *PluginHeartbeat `protobuf:"bytes,2,opt,name=heartbeat,proto3,oneof"` +} + +type PluginMessage_StatusUpdate struct { + StatusUpdate *ExecutionStatusUpdate `protobuf:"bytes,3,opt,name=status_update,json=statusUpdate,proto3,oneof"` +} + +func (*PluginMessage_Register) isPluginMessage_Content() {} + +func (*PluginMessage_Heartbeat) isPluginMessage_Content() {} + +func (*PluginMessage_StatusUpdate) isPluginMessage_Content() {} + +// AdminMessage: Messages sent by admin to worker +type AdminMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *AdminMessage_JobRequest + // *AdminMessage_ConfigUpdate + // *AdminMessage_AdminCommand + Content isAdminMessage_Content `protobuf_oneof:"content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AdminMessage) Reset() { + *x = AdminMessage{} + mi := &file_plugin_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AdminMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdminMessage) ProtoMessage() {} + +func (x *AdminMessage) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdminMessage.ProtoReflect.Descriptor instead. +func (*AdminMessage) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{1} +} + +func (x *AdminMessage) GetContent() isAdminMessage_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *AdminMessage) GetJobRequest() *JobRequest { + if x != nil { + if x, ok := x.Content.(*AdminMessage_JobRequest); ok { + return x.JobRequest + } + } + return nil +} + +func (x *AdminMessage) GetConfigUpdate() *ConfigUpdate { + if x != nil { + if x, ok := x.Content.(*AdminMessage_ConfigUpdate); ok { + return x.ConfigUpdate + } + } + return nil +} + +func (x *AdminMessage) GetAdminCommand() *AdminCommand { + if x != nil { + if x, ok := x.Content.(*AdminMessage_AdminCommand); ok { + return x.AdminCommand + } + } + return nil +} + +type isAdminMessage_Content interface { + isAdminMessage_Content() +} + +type AdminMessage_JobRequest struct { + JobRequest *JobRequest `protobuf:"bytes,1,opt,name=job_request,json=jobRequest,proto3,oneof"` +} + +type AdminMessage_ConfigUpdate struct { + ConfigUpdate *ConfigUpdate `protobuf:"bytes,2,opt,name=config_update,json=configUpdate,proto3,oneof"` +} + +type AdminMessage_AdminCommand struct { + AdminCommand *AdminCommand `protobuf:"bytes,3,opt,name=admin_command,json=adminCommand,proto3,oneof"` +} + +func (*AdminMessage_JobRequest) isAdminMessage_Content() {} + +func (*AdminMessage_ConfigUpdate) isAdminMessage_Content() {} + +func (*AdminMessage_AdminCommand) isAdminMessage_Content() {} + +// PluginRegister: Initial registration message from worker +type PluginRegister struct { + state protoimpl.MessageState `protogen:"open.v1"` + PluginId string `protobuf:"bytes,1,opt,name=plugin_id,json=pluginId,proto3" json:"plugin_id,omitempty"` // Unique plugin identifier + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // Human-readable plugin name + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` // Plugin version + ProtocolVersion string `protobuf:"bytes,4,opt,name=protocol_version,json=protocolVersion,proto3" json:"protocol_version,omitempty"` // Protocol version (e.g., "v1") + Capabilities []*JobTypeCapability `protobuf:"bytes,5,rep,name=capabilities,proto3" json:"capabilities,omitempty"` // Job types this plugin can handle + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PluginRegister) Reset() { + *x = PluginRegister{} + mi := &file_plugin_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PluginRegister) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PluginRegister) ProtoMessage() {} + +func (x *PluginRegister) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PluginRegister.ProtoReflect.Descriptor instead. +func (*PluginRegister) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{2} +} + +func (x *PluginRegister) GetPluginId() string { + if x != nil { + return x.PluginId + } + return "" +} + +func (x *PluginRegister) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *PluginRegister) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *PluginRegister) GetProtocolVersion() string { + if x != nil { + return x.ProtocolVersion + } + return "" +} + +func (x *PluginRegister) GetCapabilities() []*JobTypeCapability { + if x != nil { + return x.Capabilities + } + return nil +} + +// JobTypeCapability: Declares what job type a plugin handles +type JobTypeCapability struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobType string `protobuf:"bytes,1,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` // Job type identifier (e.g., "erasure_coding", "vacuum") + CanDetect bool `protobuf:"varint,2,opt,name=can_detect,json=canDetect,proto3" json:"can_detect,omitempty"` // Plugin can detect jobs of this type + CanExecute bool `protobuf:"varint,3,opt,name=can_execute,json=canExecute,proto3" json:"can_execute,omitempty"` // Plugin can execute jobs of this type + Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` // Job type version + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobTypeCapability) Reset() { + *x = JobTypeCapability{} + mi := &file_plugin_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobTypeCapability) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobTypeCapability) ProtoMessage() {} + +func (x *JobTypeCapability) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobTypeCapability.ProtoReflect.Descriptor instead. +func (*JobTypeCapability) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{3} +} + +func (x *JobTypeCapability) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *JobTypeCapability) GetCanDetect() bool { + if x != nil { + return x.CanDetect + } + return false +} + +func (x *JobTypeCapability) GetCanExecute() bool { + if x != nil { + return x.CanExecute + } + return false +} + +func (x *JobTypeCapability) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +// PluginHeartbeat: Periodic heartbeat to keep connection alive +type PluginHeartbeat struct { + state protoimpl.MessageState `protogen:"open.v1"` + PluginId string `protobuf:"bytes,1,opt,name=plugin_id,json=pluginId,proto3" json:"plugin_id,omitempty"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + UptimeSeconds int64 `protobuf:"varint,3,opt,name=uptime_seconds,json=uptimeSeconds,proto3" json:"uptime_seconds,omitempty"` + PendingJobs int32 `protobuf:"varint,4,opt,name=pending_jobs,json=pendingJobs,proto3" json:"pending_jobs,omitempty"` + CpuUsagePercent float32 `protobuf:"fixed32,5,opt,name=cpu_usage_percent,json=cpuUsagePercent,proto3" json:"cpu_usage_percent,omitempty"` + MemoryUsageMb float32 `protobuf:"fixed32,6,opt,name=memory_usage_mb,json=memoryUsageMb,proto3" json:"memory_usage_mb,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PluginHeartbeat) Reset() { + *x = PluginHeartbeat{} + mi := &file_plugin_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PluginHeartbeat) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PluginHeartbeat) ProtoMessage() {} + +func (x *PluginHeartbeat) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PluginHeartbeat.ProtoReflect.Descriptor instead. +func (*PluginHeartbeat) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{4} +} + +func (x *PluginHeartbeat) GetPluginId() string { + if x != nil { + return x.PluginId + } + return "" +} + +func (x *PluginHeartbeat) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +func (x *PluginHeartbeat) GetUptimeSeconds() int64 { + if x != nil { + return x.UptimeSeconds + } + return 0 +} + +func (x *PluginHeartbeat) GetPendingJobs() int32 { + if x != nil { + return x.PendingJobs + } + return 0 +} + +func (x *PluginHeartbeat) GetCpuUsagePercent() float32 { + if x != nil { + return x.CpuUsagePercent + } + return 0 +} + +func (x *PluginHeartbeat) GetMemoryUsageMb() float32 { + if x != nil { + return x.MemoryUsageMb + } + return 0 +} + +// ConfigField: Declarative field definition for UI generation +type ConfigField struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Field identifier + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` // Display label + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // Help text + FieldType ConfigField_FieldType `protobuf:"varint,4,opt,name=field_type,json=fieldType,proto3,enum=seaweed_pb.ConfigField_FieldType" json:"field_type,omitempty"` // UI control type + Required bool `protobuf:"varint,5,opt,name=required,proto3" json:"required,omitempty"` // Is required + DefaultValue string `protobuf:"bytes,6,opt,name=default_value,json=defaultValue,proto3" json:"default_value,omitempty"` // Default value + ValidationRules []*ValidationRule `protobuf:"bytes,7,rep,name=validation_rules,json=validationRules,proto3" json:"validation_rules,omitempty"` // Validation constraints + Options []*ConfigOption `protobuf:"bytes,8,rep,name=options,proto3" json:"options,omitempty"` // For SELECT/MULTISELECT + OptionsMsg *ConfigField_Options `protobuf:"bytes,9,opt,name=options_msg,json=optionsMsg,proto3" json:"options_msg,omitempty"` // Additional options + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfigField) Reset() { + *x = ConfigField{} + mi := &file_plugin_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfigField) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigField) ProtoMessage() {} + +func (x *ConfigField) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigField.ProtoReflect.Descriptor instead. +func (*ConfigField) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{5} +} + +func (x *ConfigField) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ConfigField) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *ConfigField) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *ConfigField) GetFieldType() ConfigField_FieldType { + if x != nil { + return x.FieldType + } + return ConfigField_BOOL +} + +func (x *ConfigField) GetRequired() bool { + if x != nil { + return x.Required + } + return false +} + +func (x *ConfigField) GetDefaultValue() string { + if x != nil { + return x.DefaultValue + } + return "" +} + +func (x *ConfigField) GetValidationRules() []*ValidationRule { + if x != nil { + return x.ValidationRules + } + return nil +} + +func (x *ConfigField) GetOptions() []*ConfigOption { + if x != nil { + return x.Options + } + return nil +} + +func (x *ConfigField) GetOptionsMsg() *ConfigField_Options { + if x != nil { + return x.OptionsMsg + } + return nil +} + +// ValidationRule: Constraint for field validation +type ValidationRule struct { + state protoimpl.MessageState `protogen:"open.v1"` + RuleType ValidationRule_RuleType `protobuf:"varint,1,opt,name=rule_type,json=ruleType,proto3,enum=seaweed_pb.ValidationRule_RuleType" json:"rule_type,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + ErrorMessage string `protobuf:"bytes,3,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ValidationRule) Reset() { + *x = ValidationRule{} + mi := &file_plugin_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ValidationRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidationRule) ProtoMessage() {} + +func (x *ValidationRule) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidationRule.ProtoReflect.Descriptor instead. +func (*ValidationRule) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{6} +} + +func (x *ValidationRule) GetRuleType() ValidationRule_RuleType { + if x != nil { + return x.RuleType + } + return ValidationRule_MIN_VALUE +} + +func (x *ValidationRule) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *ValidationRule) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + +// ConfigOption: Selection option for SELECT/MULTISELECT +type ConfigOption struct { + state protoimpl.MessageState `protogen:"open.v1"` + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfigOption) Reset() { + *x = ConfigOption{} + mi := &file_plugin_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfigOption) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigOption) ProtoMessage() {} + +func (x *ConfigOption) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigOption.ProtoReflect.Descriptor instead. +func (*ConfigOption) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{7} +} + +func (x *ConfigOption) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *ConfigOption) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *ConfigOption) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +// ConfigFieldValue: Value for a config field +type ConfigFieldValue struct { + state protoimpl.MessageState `protogen:"open.v1"` + FieldName string `protobuf:"bytes,1,opt,name=field_name,json=fieldName,proto3" json:"field_name,omitempty"` + StringValue string `protobuf:"bytes,2,opt,name=string_value,json=stringValue,proto3" json:"string_value,omitempty"` // For STRING, CRON + IntValue int64 `protobuf:"varint,3,opt,name=int_value,json=intValue,proto3" json:"int_value,omitempty"` // For INT, BYTES + FloatValue float32 `protobuf:"fixed32,4,opt,name=float_value,json=floatValue,proto3" json:"float_value,omitempty"` // For FLOAT, PERCENTAGE + BoolValue bool `protobuf:"varint,5,opt,name=bool_value,json=boolValue,proto3" json:"bool_value,omitempty"` // For BOOL + DurationValue *durationpb.Duration `protobuf:"bytes,6,opt,name=duration_value,json=durationValue,proto3" json:"duration_value,omitempty"` // For DURATION + MultiselectValues []string `protobuf:"bytes,7,rep,name=multiselect_values,json=multiselectValues,proto3" json:"multiselect_values,omitempty"` // For MULTISELECT + JsonValue string `protobuf:"bytes,8,opt,name=json_value,json=jsonValue,proto3" json:"json_value,omitempty"` // For JSON + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfigFieldValue) Reset() { + *x = ConfigFieldValue{} + mi := &file_plugin_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfigFieldValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigFieldValue) ProtoMessage() {} + +func (x *ConfigFieldValue) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigFieldValue.ProtoReflect.Descriptor instead. +func (*ConfigFieldValue) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{8} +} + +func (x *ConfigFieldValue) GetFieldName() string { + if x != nil { + return x.FieldName + } + return "" +} + +func (x *ConfigFieldValue) GetStringValue() string { + if x != nil { + return x.StringValue + } + return "" +} + +func (x *ConfigFieldValue) GetIntValue() int64 { + if x != nil { + return x.IntValue + } + return 0 +} + +func (x *ConfigFieldValue) GetFloatValue() float32 { + if x != nil { + return x.FloatValue + } + return 0 +} + +func (x *ConfigFieldValue) GetBoolValue() bool { + if x != nil { + return x.BoolValue + } + return false +} + +func (x *ConfigFieldValue) GetDurationValue() *durationpb.Duration { + if x != nil { + return x.DurationValue + } + return nil +} + +func (x *ConfigFieldValue) GetMultiselectValues() []string { + if x != nil { + return x.MultiselectValues + } + return nil +} + +func (x *ConfigFieldValue) GetJsonValue() string { + if x != nil { + return x.JsonValue + } + return "" +} + +// JobTypeConfig: Configuration for a job type +type JobTypeConfig struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobType string `protobuf:"bytes,1,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + Enabled bool `protobuf:"varint,2,opt,name=enabled,proto3" json:"enabled,omitempty"` + AdminConfig []*ConfigFieldValue `protobuf:"bytes,3,rep,name=admin_config,json=adminConfig,proto3" json:"admin_config,omitempty"` // Admin-managed settings + WorkerConfig []*ConfigFieldValue `protobuf:"bytes,4,rep,name=worker_config,json=workerConfig,proto3" json:"worker_config,omitempty"` // Worker-managed settings + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + CreatedBy string `protobuf:"bytes,7,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobTypeConfig) Reset() { + *x = JobTypeConfig{} + mi := &file_plugin_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobTypeConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobTypeConfig) ProtoMessage() {} + +func (x *JobTypeConfig) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobTypeConfig.ProtoReflect.Descriptor instead. +func (*JobTypeConfig) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{9} +} + +func (x *JobTypeConfig) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *JobTypeConfig) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *JobTypeConfig) GetAdminConfig() []*ConfigFieldValue { + if x != nil { + return x.AdminConfig + } + return nil +} + +func (x *JobTypeConfig) GetWorkerConfig() []*ConfigFieldValue { + if x != nil { + return x.WorkerConfig + } + return nil +} + +func (x *JobTypeConfig) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *JobTypeConfig) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *JobTypeConfig) GetCreatedBy() string { + if x != nil { + return x.CreatedBy + } + return "" +} + +// ConfigUpdateRequest: Request to update job type configuration +type ConfigUpdateRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobType string `protobuf:"bytes,1,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + ConfigValues []*ConfigFieldValue `protobuf:"bytes,2,rep,name=config_values,json=configValues,proto3" json:"config_values,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfigUpdateRequest) Reset() { + *x = ConfigUpdateRequest{} + mi := &file_plugin_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfigUpdateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigUpdateRequest) ProtoMessage() {} + +func (x *ConfigUpdateRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigUpdateRequest.ProtoReflect.Descriptor instead. +func (*ConfigUpdateRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{10} +} + +func (x *ConfigUpdateRequest) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *ConfigUpdateRequest) GetConfigValues() []*ConfigFieldValue { + if x != nil { + return x.ConfigValues + } + return nil +} + +// GetConfigurationSchemaRequest: Request for config schema +type GetConfigurationSchemaRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobType string `protobuf:"bytes,1,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetConfigurationSchemaRequest) Reset() { + *x = GetConfigurationSchemaRequest{} + mi := &file_plugin_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetConfigurationSchemaRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetConfigurationSchemaRequest) ProtoMessage() {} + +func (x *GetConfigurationSchemaRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetConfigurationSchemaRequest.ProtoReflect.Descriptor instead. +func (*GetConfigurationSchemaRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{11} +} + +func (x *GetConfigurationSchemaRequest) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +// JobTypeConfigSchema: Complete configuration schema for a job type +type JobTypeConfigSchema struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobType string `protobuf:"bytes,1,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + AdminFields []*ConfigField `protobuf:"bytes,4,rep,name=admin_fields,json=adminFields,proto3" json:"admin_fields,omitempty"` // Fields managed by admin UI + WorkerFields []*ConfigField `protobuf:"bytes,5,rep,name=worker_fields,json=workerFields,proto3" json:"worker_fields,omitempty"` // Fields managed by worker + FieldGroups []*ConfigGroup `protobuf:"bytes,6,rep,name=field_groups,json=fieldGroups,proto3" json:"field_groups,omitempty"` // Field grouping for UI + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobTypeConfigSchema) Reset() { + *x = JobTypeConfigSchema{} + mi := &file_plugin_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobTypeConfigSchema) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobTypeConfigSchema) ProtoMessage() {} + +func (x *JobTypeConfigSchema) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobTypeConfigSchema.ProtoReflect.Descriptor instead. +func (*JobTypeConfigSchema) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{12} +} + +func (x *JobTypeConfigSchema) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *JobTypeConfigSchema) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *JobTypeConfigSchema) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *JobTypeConfigSchema) GetAdminFields() []*ConfigField { + if x != nil { + return x.AdminFields + } + return nil +} + +func (x *JobTypeConfigSchema) GetWorkerFields() []*ConfigField { + if x != nil { + return x.WorkerFields + } + return nil +} + +func (x *JobTypeConfigSchema) GetFieldGroups() []*ConfigGroup { + if x != nil { + return x.FieldGroups + } + return nil +} + +// ConfigGroup: Grouping of related fields for UI organization +type ConfigGroup struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + FieldNames []string `protobuf:"bytes,4,rep,name=field_names,json=fieldNames,proto3" json:"field_names,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfigGroup) Reset() { + *x = ConfigGroup{} + mi := &file_plugin_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfigGroup) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigGroup) ProtoMessage() {} + +func (x *ConfigGroup) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigGroup.ProtoReflect.Descriptor instead. +func (*ConfigGroup) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{13} +} + +func (x *ConfigGroup) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ConfigGroup) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *ConfigGroup) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *ConfigGroup) GetFieldNames() []string { + if x != nil { + return x.FieldNames + } + return nil +} + +// DetectionRequest: Request to detect jobs +type DetectionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobType string `protobuf:"bytes,1,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + Config *JobTypeConfig `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` // Current configuration + FilterTags []string `protobuf:"bytes,3,rep,name=filter_tags,json=filterTags,proto3" json:"filter_tags,omitempty"` // Optional filtering + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DetectionRequest) Reset() { + *x = DetectionRequest{} + mi := &file_plugin_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DetectionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DetectionRequest) ProtoMessage() {} + +func (x *DetectionRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DetectionRequest.ProtoReflect.Descriptor instead. +func (*DetectionRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{14} +} + +func (x *DetectionRequest) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *DetectionRequest) GetConfig() *JobTypeConfig { + if x != nil { + return x.Config + } + return nil +} + +func (x *DetectionRequest) GetFilterTags() []string { + if x != nil { + return x.FilterTags + } + return nil +} + +// DetectionResponse: Response from detection +type DetectionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + DetectedJobs []*DetectedJob `protobuf:"bytes,1,rep,name=detected_jobs,json=detectedJobs,proto3" json:"detected_jobs,omitempty"` + DetectionTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=detection_time,json=detectionTime,proto3" json:"detection_time,omitempty"` + DetectorPluginId string `protobuf:"bytes,3,opt,name=detector_plugin_id,json=detectorPluginId,proto3" json:"detector_plugin_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DetectionResponse) Reset() { + *x = DetectionResponse{} + mi := &file_plugin_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DetectionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DetectionResponse) ProtoMessage() {} + +func (x *DetectionResponse) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DetectionResponse.ProtoReflect.Descriptor instead. +func (*DetectionResponse) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{15} +} + +func (x *DetectionResponse) GetDetectedJobs() []*DetectedJob { + if x != nil { + return x.DetectedJobs + } + return nil +} + +func (x *DetectionResponse) GetDetectionTime() *timestamppb.Timestamp { + if x != nil { + return x.DetectionTime + } + return nil +} + +func (x *DetectionResponse) GetDetectorPluginId() string { + if x != nil { + return x.DetectorPluginId + } + return "" +} + +// DetectedJob: A job candidate detected by worker +type DetectedJob struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobKey string `protobuf:"bytes,1,opt,name=job_key,json=jobKey,proto3" json:"job_key,omitempty"` // Unique key for deduplication + JobType string `protobuf:"bytes,2,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // Human-readable description + Priority int64 `protobuf:"varint,4,opt,name=priority,proto3" json:"priority,omitempty"` // Higher = higher priority + EstimatedDuration *durationpb.Duration `protobuf:"bytes,5,opt,name=estimated_duration,json=estimatedDuration,proto3" json:"estimated_duration,omitempty"` // Estimated execution time + Metadata map[string]string `protobuf:"bytes,6,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // Job-specific metadata + SuggestedConfig []*ConfigFieldValue `protobuf:"bytes,7,rep,name=suggested_config,json=suggestedConfig,proto3" json:"suggested_config,omitempty"` // Suggested overrides + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DetectedJob) Reset() { + *x = DetectedJob{} + mi := &file_plugin_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DetectedJob) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DetectedJob) ProtoMessage() {} + +func (x *DetectedJob) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DetectedJob.ProtoReflect.Descriptor instead. +func (*DetectedJob) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{16} +} + +func (x *DetectedJob) GetJobKey() string { + if x != nil { + return x.JobKey + } + return "" +} + +func (x *DetectedJob) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *DetectedJob) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *DetectedJob) GetPriority() int64 { + if x != nil { + return x.Priority + } + return 0 +} + +func (x *DetectedJob) GetEstimatedDuration() *durationpb.Duration { + if x != nil { + return x.EstimatedDuration + } + return nil +} + +func (x *DetectedJob) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *DetectedJob) GetSuggestedConfig() []*ConfigFieldValue { + if x != nil { + return x.SuggestedConfig + } + return nil +} + +// JobRequest: Request to execute a job +type JobRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + JobType string `protobuf:"bytes,2,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Priority int64 `protobuf:"varint,4,opt,name=priority,proto3" json:"priority,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + Config []*ConfigFieldValue `protobuf:"bytes,6,rep,name=config,proto3" json:"config,omitempty"` // Job-specific config + Metadata map[string]string `protobuf:"bytes,7,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // Job metadata + RequestSource string `protobuf:"bytes,8,opt,name=request_source,json=requestSource,proto3" json:"request_source,omitempty"` // admin | detection | retry + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobRequest) Reset() { + *x = JobRequest{} + mi := &file_plugin_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobRequest) ProtoMessage() {} + +func (x *JobRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobRequest.ProtoReflect.Descriptor instead. +func (*JobRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{17} +} + +func (x *JobRequest) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +func (x *JobRequest) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *JobRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *JobRequest) GetPriority() int64 { + if x != nil { + return x.Priority + } + return 0 +} + +func (x *JobRequest) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *JobRequest) GetConfig() []*ConfigFieldValue { + if x != nil { + return x.Config + } + return nil +} + +func (x *JobRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *JobRequest) GetRequestSource() string { + if x != nil { + return x.RequestSource + } + return "" +} + +// JobExecutionMessage: Messages from worker during job execution +type JobExecutionMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + // Types that are valid to be assigned to Content: + // + // *JobExecutionMessage_JobStarted + // *JobExecutionMessage_Progress + // *JobExecutionMessage_Checkpoint + // *JobExecutionMessage_JobCompleted + // *JobExecutionMessage_JobFailed + // *JobExecutionMessage_LogEntry + Content isJobExecutionMessage_Content `protobuf_oneof:"content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobExecutionMessage) Reset() { + *x = JobExecutionMessage{} + mi := &file_plugin_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobExecutionMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobExecutionMessage) ProtoMessage() {} + +func (x *JobExecutionMessage) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobExecutionMessage.ProtoReflect.Descriptor instead. +func (*JobExecutionMessage) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{18} +} + +func (x *JobExecutionMessage) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +func (x *JobExecutionMessage) GetContent() isJobExecutionMessage_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *JobExecutionMessage) GetJobStarted() *JobStarted { + if x != nil { + if x, ok := x.Content.(*JobExecutionMessage_JobStarted); ok { + return x.JobStarted + } + } + return nil +} + +func (x *JobExecutionMessage) GetProgress() *JobProgress { + if x != nil { + if x, ok := x.Content.(*JobExecutionMessage_Progress); ok { + return x.Progress + } + } + return nil +} + +func (x *JobExecutionMessage) GetCheckpoint() *JobCheckpoint { + if x != nil { + if x, ok := x.Content.(*JobExecutionMessage_Checkpoint); ok { + return x.Checkpoint + } + } + return nil +} + +func (x *JobExecutionMessage) GetJobCompleted() *JobCompleted { + if x != nil { + if x, ok := x.Content.(*JobExecutionMessage_JobCompleted); ok { + return x.JobCompleted + } + } + return nil +} + +func (x *JobExecutionMessage) GetJobFailed() *JobFailed { + if x != nil { + if x, ok := x.Content.(*JobExecutionMessage_JobFailed); ok { + return x.JobFailed + } + } + return nil +} + +func (x *JobExecutionMessage) GetLogEntry() *ExecutionLog { + if x != nil { + if x, ok := x.Content.(*JobExecutionMessage_LogEntry); ok { + return x.LogEntry + } + } + return nil +} + +type isJobExecutionMessage_Content interface { + isJobExecutionMessage_Content() +} + +type JobExecutionMessage_JobStarted struct { + JobStarted *JobStarted `protobuf:"bytes,2,opt,name=job_started,json=jobStarted,proto3,oneof"` +} + +type JobExecutionMessage_Progress struct { + Progress *JobProgress `protobuf:"bytes,3,opt,name=progress,proto3,oneof"` +} + +type JobExecutionMessage_Checkpoint struct { + Checkpoint *JobCheckpoint `protobuf:"bytes,4,opt,name=checkpoint,proto3,oneof"` +} + +type JobExecutionMessage_JobCompleted struct { + JobCompleted *JobCompleted `protobuf:"bytes,5,opt,name=job_completed,json=jobCompleted,proto3,oneof"` +} + +type JobExecutionMessage_JobFailed struct { + JobFailed *JobFailed `protobuf:"bytes,6,opt,name=job_failed,json=jobFailed,proto3,oneof"` +} + +type JobExecutionMessage_LogEntry struct { + LogEntry *ExecutionLog `protobuf:"bytes,7,opt,name=log_entry,json=logEntry,proto3,oneof"` +} + +func (*JobExecutionMessage_JobStarted) isJobExecutionMessage_Content() {} + +func (*JobExecutionMessage_Progress) isJobExecutionMessage_Content() {} + +func (*JobExecutionMessage_Checkpoint) isJobExecutionMessage_Content() {} + +func (*JobExecutionMessage_JobCompleted) isJobExecutionMessage_Content() {} + +func (*JobExecutionMessage_JobFailed) isJobExecutionMessage_Content() {} + +func (*JobExecutionMessage_LogEntry) isJobExecutionMessage_Content() {} + +// JobStarted: Job execution started +type JobStarted struct { + state protoimpl.MessageState `protogen:"open.v1"` + StartedAt *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=started_at,json=startedAt,proto3" json:"started_at,omitempty"` + ExecutorId string `protobuf:"bytes,2,opt,name=executor_id,json=executorId,proto3" json:"executor_id,omitempty"` // Plugin executor ID + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobStarted) Reset() { + *x = JobStarted{} + mi := &file_plugin_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobStarted) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobStarted) ProtoMessage() {} + +func (x *JobStarted) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobStarted.ProtoReflect.Descriptor instead. +func (*JobStarted) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{19} +} + +func (x *JobStarted) GetStartedAt() *timestamppb.Timestamp { + if x != nil { + return x.StartedAt + } + return nil +} + +func (x *JobStarted) GetExecutorId() string { + if x != nil { + return x.ExecutorId + } + return "" +} + +// JobProgress: Progress update during execution +type JobProgress struct { + state protoimpl.MessageState `protogen:"open.v1"` + ProgressPercent int32 `protobuf:"varint,1,opt,name=progress_percent,json=progressPercent,proto3" json:"progress_percent,omitempty"` // 0-100 + CurrentStep string `protobuf:"bytes,2,opt,name=current_step,json=currentStep,proto3" json:"current_step,omitempty"` + StatusMessage string `protobuf:"bytes,3,opt,name=status_message,json=statusMessage,proto3" json:"status_message,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobProgress) Reset() { + *x = JobProgress{} + mi := &file_plugin_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobProgress) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobProgress) ProtoMessage() {} + +func (x *JobProgress) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobProgress.ProtoReflect.Descriptor instead. +func (*JobProgress) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{20} +} + +func (x *JobProgress) GetProgressPercent() int32 { + if x != nil { + return x.ProgressPercent + } + return 0 +} + +func (x *JobProgress) GetCurrentStep() string { + if x != nil { + return x.CurrentStep + } + return "" +} + +func (x *JobProgress) GetStatusMessage() string { + if x != nil { + return x.StatusMessage + } + return "" +} + +func (x *JobProgress) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +// JobCheckpoint: Checkpoint for resuming jobs +type JobCheckpoint struct { + state protoimpl.MessageState `protogen:"open.v1"` + CheckpointId string `protobuf:"bytes,1,opt,name=checkpoint_id,json=checkpointId,proto3" json:"checkpoint_id,omitempty"` + CheckpointData []byte `protobuf:"bytes,2,opt,name=checkpoint_data,json=checkpointData,proto3" json:"checkpoint_data,omitempty"` // Serialized checkpoint + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobCheckpoint) Reset() { + *x = JobCheckpoint{} + mi := &file_plugin_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobCheckpoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobCheckpoint) ProtoMessage() {} + +func (x *JobCheckpoint) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobCheckpoint.ProtoReflect.Descriptor instead. +func (*JobCheckpoint) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{21} +} + +func (x *JobCheckpoint) GetCheckpointId() string { + if x != nil { + return x.CheckpointId + } + return "" +} + +func (x *JobCheckpoint) GetCheckpointData() []byte { + if x != nil { + return x.CheckpointData + } + return nil +} + +func (x *JobCheckpoint) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +// JobCompleted: Job execution completed successfully +type JobCompleted struct { + state protoimpl.MessageState `protogen:"open.v1"` + CompletedAt *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=completed_at,json=completedAt,proto3" json:"completed_at,omitempty"` + Summary string `protobuf:"bytes,2,opt,name=summary,proto3" json:"summary,omitempty"` + Output map[string]string `protobuf:"bytes,3,rep,name=output,proto3" json:"output,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // Job output data + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobCompleted) Reset() { + *x = JobCompleted{} + mi := &file_plugin_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobCompleted) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobCompleted) ProtoMessage() {} + +func (x *JobCompleted) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobCompleted.ProtoReflect.Descriptor instead. +func (*JobCompleted) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{22} +} + +func (x *JobCompleted) GetCompletedAt() *timestamppb.Timestamp { + if x != nil { + return x.CompletedAt + } + return nil +} + +func (x *JobCompleted) GetSummary() string { + if x != nil { + return x.Summary + } + return "" +} + +func (x *JobCompleted) GetOutput() map[string]string { + if x != nil { + return x.Output + } + return nil +} + +// JobFailed: Job execution failed +type JobFailed struct { + state protoimpl.MessageState `protogen:"open.v1"` + ErrorCode string `protobuf:"bytes,1,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"` // Error classification + ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` // Human-readable error + ErrorDetails []byte `protobuf:"bytes,3,opt,name=error_details,json=errorDetails,proto3" json:"error_details,omitempty"` // Detailed error data + Retryable bool `protobuf:"varint,4,opt,name=retryable,proto3" json:"retryable,omitempty"` // Can this job be retried + FailedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=failed_at,json=failedAt,proto3" json:"failed_at,omitempty"` + RetryCount int32 `protobuf:"varint,6,opt,name=retry_count,json=retryCount,proto3" json:"retry_count,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobFailed) Reset() { + *x = JobFailed{} + mi := &file_plugin_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobFailed) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobFailed) ProtoMessage() {} + +func (x *JobFailed) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobFailed.ProtoReflect.Descriptor instead. +func (*JobFailed) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{23} +} + +func (x *JobFailed) GetErrorCode() string { + if x != nil { + return x.ErrorCode + } + return "" +} + +func (x *JobFailed) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + +func (x *JobFailed) GetErrorDetails() []byte { + if x != nil { + return x.ErrorDetails + } + return nil +} + +func (x *JobFailed) GetRetryable() bool { + if x != nil { + return x.Retryable + } + return false +} + +func (x *JobFailed) GetFailedAt() *timestamppb.Timestamp { + if x != nil { + return x.FailedAt + } + return nil +} + +func (x *JobFailed) GetRetryCount() int32 { + if x != nil { + return x.RetryCount + } + return 0 +} + +// ExecutionLog: Log entry during job execution +type ExecutionLog struct { + state protoimpl.MessageState `protogen:"open.v1"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Level ExecutionLog_LogLevel `protobuf:"varint,2,opt,name=level,proto3,enum=seaweed_pb.ExecutionLog_LogLevel" json:"level,omitempty"` + Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` + Context map[string]string `protobuf:"bytes,4,rep,name=context,proto3" json:"context,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExecutionLog) Reset() { + *x = ExecutionLog{} + mi := &file_plugin_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExecutionLog) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutionLog) ProtoMessage() {} + +func (x *ExecutionLog) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecutionLog.ProtoReflect.Descriptor instead. +func (*ExecutionLog) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{24} +} + +func (x *ExecutionLog) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +func (x *ExecutionLog) GetLevel() ExecutionLog_LogLevel { + if x != nil { + return x.Level + } + return ExecutionLog_DEBUG +} + +func (x *ExecutionLog) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *ExecutionLog) GetContext() map[string]string { + if x != nil { + return x.Context + } + return nil +} + +// JobProgressMessage: Messages from admin to worker +type JobProgressMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + // Types that are valid to be assigned to Content: + // + // *JobProgressMessage_Update + // *JobProgressMessage_Command + Content isJobProgressMessage_Content `protobuf_oneof:"content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobProgressMessage) Reset() { + *x = JobProgressMessage{} + mi := &file_plugin_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobProgressMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobProgressMessage) ProtoMessage() {} + +func (x *JobProgressMessage) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[25] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobProgressMessage.ProtoReflect.Descriptor instead. +func (*JobProgressMessage) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{25} +} + +func (x *JobProgressMessage) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +func (x *JobProgressMessage) GetContent() isJobProgressMessage_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *JobProgressMessage) GetUpdate() *JobProgressUpdate { + if x != nil { + if x, ok := x.Content.(*JobProgressMessage_Update); ok { + return x.Update + } + } + return nil +} + +func (x *JobProgressMessage) GetCommand() *ExecutionCommand { + if x != nil { + if x, ok := x.Content.(*JobProgressMessage_Command); ok { + return x.Command + } + } + return nil +} + +type isJobProgressMessage_Content interface { + isJobProgressMessage_Content() +} + +type JobProgressMessage_Update struct { + Update *JobProgressUpdate `protobuf:"bytes,2,opt,name=update,proto3,oneof"` +} + +type JobProgressMessage_Command struct { + Command *ExecutionCommand `protobuf:"bytes,3,opt,name=command,proto3,oneof"` +} + +func (*JobProgressMessage_Update) isJobProgressMessage_Content() {} + +func (*JobProgressMessage_Command) isJobProgressMessage_Content() {} + +// JobProgressUpdate: Status update for UI +type JobProgressUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + ProgressPercent int32 `protobuf:"varint,2,opt,name=progress_percent,json=progressPercent,proto3" json:"progress_percent,omitempty"` + CurrentStep string `protobuf:"bytes,3,opt,name=current_step,json=currentStep,proto3" json:"current_step,omitempty"` + StatusMessage string `protobuf:"bytes,4,opt,name=status_message,json=statusMessage,proto3" json:"status_message,omitempty"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobProgressUpdate) Reset() { + *x = JobProgressUpdate{} + mi := &file_plugin_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobProgressUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobProgressUpdate) ProtoMessage() {} + +func (x *JobProgressUpdate) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[26] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobProgressUpdate.ProtoReflect.Descriptor instead. +func (*JobProgressUpdate) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{26} +} + +func (x *JobProgressUpdate) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +func (x *JobProgressUpdate) GetProgressPercent() int32 { + if x != nil { + return x.ProgressPercent + } + return 0 +} + +func (x *JobProgressUpdate) GetCurrentStep() string { + if x != nil { + return x.CurrentStep + } + return "" +} + +func (x *JobProgressUpdate) GetStatusMessage() string { + if x != nil { + return x.StatusMessage + } + return "" +} + +func (x *JobProgressUpdate) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +// ExecutionCommand: Command from admin to worker +type ExecutionCommand struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + CommandType ExecutionCommand_CommandType `protobuf:"varint,2,opt,name=command_type,json=commandType,proto3,enum=seaweed_pb.ExecutionCommand_CommandType" json:"command_type,omitempty"` + Parameters map[string]string `protobuf:"bytes,3,rep,name=parameters,proto3" json:"parameters,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExecutionCommand) Reset() { + *x = ExecutionCommand{} + mi := &file_plugin_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExecutionCommand) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutionCommand) ProtoMessage() {} + +func (x *ExecutionCommand) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[27] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecutionCommand.ProtoReflect.Descriptor instead. +func (*ExecutionCommand) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{27} +} + +func (x *ExecutionCommand) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +func (x *ExecutionCommand) GetCommandType() ExecutionCommand_CommandType { + if x != nil { + return x.CommandType + } + return ExecutionCommand_PAUSE +} + +func (x *ExecutionCommand) GetParameters() map[string]string { + if x != nil { + return x.Parameters + } + return nil +} + +// ExecutionStatusUpdate: Status update from worker +type ExecutionStatusUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + PluginId string `protobuf:"bytes,1,opt,name=plugin_id,json=pluginId,proto3" json:"plugin_id,omitempty"` + JobId string `protobuf:"bytes,2,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + Status string `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` // running | completed | failed | paused + ProgressPercent int32 `protobuf:"varint,4,opt,name=progress_percent,json=progressPercent,proto3" json:"progress_percent,omitempty"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExecutionStatusUpdate) Reset() { + *x = ExecutionStatusUpdate{} + mi := &file_plugin_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExecutionStatusUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutionStatusUpdate) ProtoMessage() {} + +func (x *ExecutionStatusUpdate) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[28] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecutionStatusUpdate.ProtoReflect.Descriptor instead. +func (*ExecutionStatusUpdate) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{28} +} + +func (x *ExecutionStatusUpdate) GetPluginId() string { + if x != nil { + return x.PluginId + } + return "" +} + +func (x *ExecutionStatusUpdate) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +func (x *ExecutionStatusUpdate) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *ExecutionStatusUpdate) GetProgressPercent() int32 { + if x != nil { + return x.ProgressPercent + } + return 0 +} + +func (x *ExecutionStatusUpdate) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +// ConfigUpdate: Configuration update message +type ConfigUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobType string `protobuf:"bytes,1,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + ConfigValues []*ConfigFieldValue `protobuf:"bytes,2,rep,name=config_values,json=configValues,proto3" json:"config_values,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfigUpdate) Reset() { + *x = ConfigUpdate{} + mi := &file_plugin_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfigUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigUpdate) ProtoMessage() {} + +func (x *ConfigUpdate) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[29] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigUpdate.ProtoReflect.Descriptor instead. +func (*ConfigUpdate) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{29} +} + +func (x *ConfigUpdate) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *ConfigUpdate) GetConfigValues() []*ConfigFieldValue { + if x != nil { + return x.ConfigValues + } + return nil +} + +func (x *ConfigUpdate) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +// AdminCommand: Admin command to worker +type AdminCommand struct { + state protoimpl.MessageState `protogen:"open.v1"` + CommandType AdminCommand_CommandType `protobuf:"varint,1,opt,name=command_type,json=commandType,proto3,enum=seaweed_pb.AdminCommand_CommandType" json:"command_type,omitempty"` + Parameters map[string]string `protobuf:"bytes,2,rep,name=parameters,proto3" json:"parameters,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AdminCommand) Reset() { + *x = AdminCommand{} + mi := &file_plugin_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AdminCommand) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdminCommand) ProtoMessage() {} + +func (x *AdminCommand) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[30] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdminCommand.ProtoReflect.Descriptor instead. +func (*AdminCommand) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{30} +} + +func (x *AdminCommand) GetCommandType() AdminCommand_CommandType { + if x != nil { + return x.CommandType + } + return AdminCommand_RELOAD_CONFIG +} + +func (x *AdminCommand) GetParameters() map[string]string { + if x != nil { + return x.Parameters + } + return nil +} + +// ListJobsRequest: Request to list jobs +type ListJobsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobType string `protobuf:"bytes,1,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + Status ListJobsRequest_StatusFilter `protobuf:"varint,2,opt,name=status,proto3,enum=seaweed_pb.ListJobsRequest_StatusFilter" json:"status,omitempty"` + Limit int32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` + Offset int32 `protobuf:"varint,4,opt,name=offset,proto3" json:"offset,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListJobsRequest) Reset() { + *x = ListJobsRequest{} + mi := &file_plugin_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListJobsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListJobsRequest) ProtoMessage() {} + +func (x *ListJobsRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[31] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListJobsRequest.ProtoReflect.Descriptor instead. +func (*ListJobsRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{31} +} + +func (x *ListJobsRequest) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *ListJobsRequest) GetStatus() ListJobsRequest_StatusFilter { + if x != nil { + return x.Status + } + return ListJobsRequest_ALL +} + +func (x *ListJobsRequest) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *ListJobsRequest) GetOffset() int32 { + if x != nil { + return x.Offset + } + return 0 +} + +// GetJobRequest: Request for specific job +type GetJobRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetJobRequest) Reset() { + *x = GetJobRequest{} + mi := &file_plugin_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetJobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetJobRequest) ProtoMessage() {} + +func (x *GetJobRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[32] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetJobRequest.ProtoReflect.Descriptor instead. +func (*GetJobRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{32} +} + +func (x *GetJobRequest) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +// GetJobExecutionLogRequest: Request for job logs +type GetJobExecutionLogRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + Level GetJobExecutionLogRequest_LogLevel `protobuf:"varint,2,opt,name=level,proto3,enum=seaweed_pb.GetJobExecutionLogRequest_LogLevel" json:"level,omitempty"` + TailLines int32 `protobuf:"varint,3,opt,name=tail_lines,json=tailLines,proto3" json:"tail_lines,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetJobExecutionLogRequest) Reset() { + *x = GetJobExecutionLogRequest{} + mi := &file_plugin_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetJobExecutionLogRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetJobExecutionLogRequest) ProtoMessage() {} + +func (x *GetJobExecutionLogRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[33] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetJobExecutionLogRequest.ProtoReflect.Descriptor instead. +func (*GetJobExecutionLogRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{33} +} + +func (x *GetJobExecutionLogRequest) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +func (x *GetJobExecutionLogRequest) GetLevel() GetJobExecutionLogRequest_LogLevel { + if x != nil { + return x.Level + } + return GetJobExecutionLogRequest_DEBUG +} + +func (x *GetJobExecutionLogRequest) GetTailLines() int32 { + if x != nil { + return x.TailLines + } + return 0 +} + +// Job: Job information +type Job struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + JobType string `protobuf:"bytes,2,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Priority int64 `protobuf:"varint,4,opt,name=priority,proto3" json:"priority,omitempty"` + Status Job_Status `protobuf:"varint,5,opt,name=status,proto3,enum=seaweed_pb.Job_Status" json:"status,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + ExecutorPluginId string `protobuf:"bytes,8,opt,name=executor_plugin_id,json=executorPluginId,proto3" json:"executor_plugin_id,omitempty"` + ProgressPercent int32 `protobuf:"varint,9,opt,name=progress_percent,json=progressPercent,proto3" json:"progress_percent,omitempty"` + Config []*ConfigFieldValue `protobuf:"bytes,10,rep,name=config,proto3" json:"config,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Job) Reset() { + *x = Job{} + mi := &file_plugin_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Job) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Job) ProtoMessage() {} + +func (x *Job) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[34] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Job.ProtoReflect.Descriptor instead. +func (*Job) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{34} +} + +func (x *Job) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +func (x *Job) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *Job) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Job) GetPriority() int64 { + if x != nil { + return x.Priority + } + return 0 +} + +func (x *Job) GetStatus() Job_Status { + if x != nil { + return x.Status + } + return Job_PENDING +} + +func (x *Job) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Job) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *Job) GetExecutorPluginId() string { + if x != nil { + return x.ExecutorPluginId + } + return "" +} + +func (x *Job) GetProgressPercent() int32 { + if x != nil { + return x.ProgressPercent + } + return 0 +} + +func (x *Job) GetConfig() []*ConfigFieldValue { + if x != nil { + return x.Config + } + return nil +} + +// JobDetail: Detailed job information with execution history +type JobDetail struct { + state protoimpl.MessageState `protogen:"open.v1"` + Job *Job `protobuf:"bytes,1,opt,name=job,proto3" json:"job,omitempty"` + LogEntries []*ExecutionLogEntry `protobuf:"bytes,2,rep,name=log_entries,json=logEntries,proto3" json:"log_entries,omitempty"` + CompletionInfo *JobCompleted `protobuf:"bytes,3,opt,name=completion_info,json=completionInfo,proto3" json:"completion_info,omitempty"` + FailureInfo *JobFailed `protobuf:"bytes,4,opt,name=failure_info,json=failureInfo,proto3" json:"failure_info,omitempty"` + CheckpointIds []string `protobuf:"bytes,5,rep,name=checkpoint_ids,json=checkpointIds,proto3" json:"checkpoint_ids,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobDetail) Reset() { + *x = JobDetail{} + mi := &file_plugin_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobDetail) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobDetail) ProtoMessage() {} + +func (x *JobDetail) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[35] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobDetail.ProtoReflect.Descriptor instead. +func (*JobDetail) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{35} +} + +func (x *JobDetail) GetJob() *Job { + if x != nil { + return x.Job + } + return nil +} + +func (x *JobDetail) GetLogEntries() []*ExecutionLogEntry { + if x != nil { + return x.LogEntries + } + return nil +} + +func (x *JobDetail) GetCompletionInfo() *JobCompleted { + if x != nil { + return x.CompletionInfo + } + return nil +} + +func (x *JobDetail) GetFailureInfo() *JobFailed { + if x != nil { + return x.FailureInfo + } + return nil +} + +func (x *JobDetail) GetCheckpointIds() []string { + if x != nil { + return x.CheckpointIds + } + return nil +} + +// ExecutionLogEntry: Log entry with metadata +type ExecutionLogEntry struct { + state protoimpl.MessageState `protogen:"open.v1"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Level ExecutionLog_LogLevel `protobuf:"varint,2,opt,name=level,proto3,enum=seaweed_pb.ExecutionLog_LogLevel" json:"level,omitempty"` + Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` + Context map[string]string `protobuf:"bytes,4,rep,name=context,proto3" json:"context,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExecutionLogEntry) Reset() { + *x = ExecutionLogEntry{} + mi := &file_plugin_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExecutionLogEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutionLogEntry) ProtoMessage() {} + +func (x *ExecutionLogEntry) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[36] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecutionLogEntry.ProtoReflect.Descriptor instead. +func (*ExecutionLogEntry) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{36} +} + +func (x *ExecutionLogEntry) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +func (x *ExecutionLogEntry) GetLevel() ExecutionLog_LogLevel { + if x != nil { + return x.Level + } + return ExecutionLog_DEBUG +} + +func (x *ExecutionLogEntry) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *ExecutionLogEntry) GetContext() map[string]string { + if x != nil { + return x.Context + } + return nil +} + +// JobList: List of jobs +type JobList struct { + state protoimpl.MessageState `protogen:"open.v1"` + Jobs []*Job `protobuf:"bytes,1,rep,name=jobs,proto3" json:"jobs,omitempty"` + TotalCount int32 `protobuf:"varint,2,opt,name=total_count,json=totalCount,proto3" json:"total_count,omitempty"` + ReturnedCount int32 `protobuf:"varint,3,opt,name=returned_count,json=returnedCount,proto3" json:"returned_count,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobList) Reset() { + *x = JobList{} + mi := &file_plugin_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobList) ProtoMessage() {} + +func (x *JobList) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[37] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobList.ProtoReflect.Descriptor instead. +func (*JobList) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{37} +} + +func (x *JobList) GetJobs() []*Job { + if x != nil { + return x.Jobs + } + return nil +} + +func (x *JobList) GetTotalCount() int32 { + if x != nil { + return x.TotalCount + } + return 0 +} + +func (x *JobList) GetReturnedCount() int32 { + if x != nil { + return x.ReturnedCount + } + return 0 +} + +// PluginStats: System-wide statistics +type PluginStats struct { + state protoimpl.MessageState `protogen:"open.v1"` + TotalPlugins int32 `protobuf:"varint,1,opt,name=total_plugins,json=totalPlugins,proto3" json:"total_plugins,omitempty"` + ActivePlugins int32 `protobuf:"varint,2,opt,name=active_plugins,json=activePlugins,proto3" json:"active_plugins,omitempty"` + TotalJobs int32 `protobuf:"varint,3,opt,name=total_jobs,json=totalJobs,proto3" json:"total_jobs,omitempty"` + PendingJobs int32 `protobuf:"varint,4,opt,name=pending_jobs,json=pendingJobs,proto3" json:"pending_jobs,omitempty"` + RunningJobs int32 `protobuf:"varint,5,opt,name=running_jobs,json=runningJobs,proto3" json:"running_jobs,omitempty"` + CompletedJobs int32 `protobuf:"varint,6,opt,name=completed_jobs,json=completedJobs,proto3" json:"completed_jobs,omitempty"` + FailedJobs int32 `protobuf:"varint,7,opt,name=failed_jobs,json=failedJobs,proto3" json:"failed_jobs,omitempty"` + LastUpdate *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=last_update,json=lastUpdate,proto3" json:"last_update,omitempty"` + JobTypeStats map[string]*JobTypeStats `protobuf:"bytes,9,rep,name=job_type_stats,json=jobTypeStats,proto3" json:"job_type_stats,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PluginStats) Reset() { + *x = PluginStats{} + mi := &file_plugin_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PluginStats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PluginStats) ProtoMessage() {} + +func (x *PluginStats) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[38] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PluginStats.ProtoReflect.Descriptor instead. +func (*PluginStats) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{38} +} + +func (x *PluginStats) GetTotalPlugins() int32 { + if x != nil { + return x.TotalPlugins + } + return 0 +} + +func (x *PluginStats) GetActivePlugins() int32 { + if x != nil { + return x.ActivePlugins + } + return 0 +} + +func (x *PluginStats) GetTotalJobs() int32 { + if x != nil { + return x.TotalJobs + } + return 0 +} + +func (x *PluginStats) GetPendingJobs() int32 { + if x != nil { + return x.PendingJobs + } + return 0 +} + +func (x *PluginStats) GetRunningJobs() int32 { + if x != nil { + return x.RunningJobs + } + return 0 +} + +func (x *PluginStats) GetCompletedJobs() int32 { + if x != nil { + return x.CompletedJobs + } + return 0 +} + +func (x *PluginStats) GetFailedJobs() int32 { + if x != nil { + return x.FailedJobs + } + return 0 +} + +func (x *PluginStats) GetLastUpdate() *timestamppb.Timestamp { + if x != nil { + return x.LastUpdate + } + return nil +} + +func (x *PluginStats) GetJobTypeStats() map[string]*JobTypeStats { + if x != nil { + return x.JobTypeStats + } + return nil +} + +// JobTypeStats: Statistics for a job type +type JobTypeStats struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobType string `protobuf:"bytes,1,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` + Pending int32 `protobuf:"varint,3,opt,name=pending,proto3" json:"pending,omitempty"` + Running int32 `protobuf:"varint,4,opt,name=running,proto3" json:"running,omitempty"` + Completed int32 `protobuf:"varint,5,opt,name=completed,proto3" json:"completed,omitempty"` + Failed int32 `protobuf:"varint,6,opt,name=failed,proto3" json:"failed,omitempty"` + SuccessRate float32 `protobuf:"fixed32,7,opt,name=success_rate,json=successRate,proto3" json:"success_rate,omitempty"` + AvgExecutionTime *durationpb.Duration `protobuf:"bytes,8,opt,name=avg_execution_time,json=avgExecutionTime,proto3" json:"avg_execution_time,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobTypeStats) Reset() { + *x = JobTypeStats{} + mi := &file_plugin_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobTypeStats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobTypeStats) ProtoMessage() {} + +func (x *JobTypeStats) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[39] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobTypeStats.ProtoReflect.Descriptor instead. +func (*JobTypeStats) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{39} +} + +func (x *JobTypeStats) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *JobTypeStats) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *JobTypeStats) GetPending() int32 { + if x != nil { + return x.Pending + } + return 0 +} + +func (x *JobTypeStats) GetRunning() int32 { + if x != nil { + return x.Running + } + return 0 +} + +func (x *JobTypeStats) GetCompleted() int32 { + if x != nil { + return x.Completed + } + return 0 +} + +func (x *JobTypeStats) GetFailed() int32 { + if x != nil { + return x.Failed + } + return 0 +} + +func (x *JobTypeStats) GetSuccessRate() float32 { + if x != nil { + return x.SuccessRate + } + return 0 +} + +func (x *JobTypeStats) GetAvgExecutionTime() *durationpb.Duration { + if x != nil { + return x.AvgExecutionTime + } + return nil +} + +// PluginList: List of connected plugins +type PluginList struct { + state protoimpl.MessageState `protogen:"open.v1"` + Plugins []*PluginInfo `protobuf:"bytes,1,rep,name=plugins,proto3" json:"plugins,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PluginList) Reset() { + *x = PluginList{} + mi := &file_plugin_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PluginList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PluginList) ProtoMessage() {} + +func (x *PluginList) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[40] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PluginList.ProtoReflect.Descriptor instead. +func (*PluginList) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{40} +} + +func (x *PluginList) GetPlugins() []*PluginInfo { + if x != nil { + return x.Plugins + } + return nil +} + +// PluginInfo: Information about a connected plugin +type PluginInfo struct { + state protoimpl.MessageState `protogen:"open.v1"` + PluginId string `protobuf:"bytes,1,opt,name=plugin_id,json=pluginId,proto3" json:"plugin_id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + ProtocolVersion string `protobuf:"bytes,4,opt,name=protocol_version,json=protocolVersion,proto3" json:"protocol_version,omitempty"` + ConnectedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=connected_at,json=connectedAt,proto3" json:"connected_at,omitempty"` + LastHeartbeat *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=last_heartbeat,json=lastHeartbeat,proto3" json:"last_heartbeat,omitempty"` + Capabilities []*JobTypeCapability `protobuf:"bytes,7,rep,name=capabilities,proto3" json:"capabilities,omitempty"` + Healthy bool `protobuf:"varint,8,opt,name=healthy,proto3" json:"healthy,omitempty"` + Status string `protobuf:"bytes,9,opt,name=status,proto3" json:"status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PluginInfo) Reset() { + *x = PluginInfo{} + mi := &file_plugin_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PluginInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PluginInfo) ProtoMessage() {} + +func (x *PluginInfo) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[41] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PluginInfo.ProtoReflect.Descriptor instead. +func (*PluginInfo) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{41} +} + +func (x *PluginInfo) GetPluginId() string { + if x != nil { + return x.PluginId + } + return "" +} + +func (x *PluginInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *PluginInfo) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *PluginInfo) GetProtocolVersion() string { + if x != nil { + return x.ProtocolVersion + } + return "" +} + +func (x *PluginInfo) GetConnectedAt() *timestamppb.Timestamp { + if x != nil { + return x.ConnectedAt + } + return nil +} + +func (x *PluginInfo) GetLastHeartbeat() *timestamppb.Timestamp { + if x != nil { + return x.LastHeartbeat + } + return nil +} + +func (x *PluginInfo) GetCapabilities() []*JobTypeCapability { + if x != nil { + return x.Capabilities + } + return nil +} + +func (x *PluginInfo) GetHealthy() bool { + if x != nil { + return x.Healthy + } + return false +} + +func (x *PluginInfo) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +// UpdateJobTypeConfigRequest: Request to update config +type UpdateJobTypeConfigRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Config *JobTypeConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateJobTypeConfigRequest) Reset() { + *x = UpdateJobTypeConfigRequest{} + mi := &file_plugin_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateJobTypeConfigRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateJobTypeConfigRequest) ProtoMessage() {} + +func (x *UpdateJobTypeConfigRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[42] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateJobTypeConfigRequest.ProtoReflect.Descriptor instead. +func (*UpdateJobTypeConfigRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{42} +} + +func (x *UpdateJobTypeConfigRequest) GetConfig() *JobTypeConfig { + if x != nil { + return x.Config + } + return nil +} + +// CreateJobRequest: Request to create a job +type CreateJobRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobType string `protobuf:"bytes,1,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Priority int64 `protobuf:"varint,3,opt,name=priority,proto3" json:"priority,omitempty"` + Config []*ConfigFieldValue `protobuf:"bytes,4,rep,name=config,proto3" json:"config,omitempty"` + Metadata map[string]string `protobuf:"bytes,5,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateJobRequest) Reset() { + *x = CreateJobRequest{} + mi := &file_plugin_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateJobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateJobRequest) ProtoMessage() {} + +func (x *CreateJobRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[43] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateJobRequest.ProtoReflect.Descriptor instead. +func (*CreateJobRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{43} +} + +func (x *CreateJobRequest) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *CreateJobRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *CreateJobRequest) GetPriority() int64 { + if x != nil { + return x.Priority + } + return 0 +} + +func (x *CreateJobRequest) GetConfig() []*ConfigFieldValue { + if x != nil { + return x.Config + } + return nil +} + +func (x *CreateJobRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// CancelJobRequest: Request to cancel a job +type CancelJobRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CancelJobRequest) Reset() { + *x = CancelJobRequest{} + mi := &file_plugin_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CancelJobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CancelJobRequest) ProtoMessage() {} + +func (x *CancelJobRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[44] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CancelJobRequest.ProtoReflect.Descriptor instead. +func (*CancelJobRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{44} +} + +func (x *CancelJobRequest) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +// RetryJobRequest: Request to retry a job +type RetryJobRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RetryJobRequest) Reset() { + *x = RetryJobRequest{} + mi := &file_plugin_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RetryJobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetryJobRequest) ProtoMessage() {} + +func (x *RetryJobRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[45] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetryJobRequest.ProtoReflect.Descriptor instead. +func (*RetryJobRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{45} +} + +func (x *RetryJobRequest) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +type ConfigField_Options struct { + state protoimpl.MessageState `protogen:"open.v1"` + Placeholder string `protobuf:"bytes,1,opt,name=placeholder,proto3" json:"placeholder,omitempty"` + Suggestions []string `protobuf:"bytes,2,rep,name=suggestions,proto3" json:"suggestions,omitempty"` + MinLength int32 `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"` + MaxLength int32 `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"` + MinValue int32 `protobuf:"varint,5,opt,name=min_value,json=minValue,proto3" json:"min_value,omitempty"` + MaxValue int32 `protobuf:"varint,6,opt,name=max_value,json=maxValue,proto3" json:"max_value,omitempty"` + MinFloat float32 `protobuf:"fixed32,7,opt,name=min_float,json=minFloat,proto3" json:"min_float,omitempty"` + MaxFloat float32 `protobuf:"fixed32,8,opt,name=max_float,json=maxFloat,proto3" json:"max_float,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfigField_Options) Reset() { + *x = ConfigField_Options{} + mi := &file_plugin_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfigField_Options) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigField_Options) ProtoMessage() {} + +func (x *ConfigField_Options) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[46] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigField_Options.ProtoReflect.Descriptor instead. +func (*ConfigField_Options) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{5, 0} +} + +func (x *ConfigField_Options) GetPlaceholder() string { + if x != nil { + return x.Placeholder + } + return "" +} + +func (x *ConfigField_Options) GetSuggestions() []string { + if x != nil { + return x.Suggestions + } + return nil +} + +func (x *ConfigField_Options) GetMinLength() int32 { + if x != nil { + return x.MinLength + } + return 0 +} + +func (x *ConfigField_Options) GetMaxLength() int32 { + if x != nil { + return x.MaxLength + } + return 0 +} + +func (x *ConfigField_Options) GetMinValue() int32 { + if x != nil { + return x.MinValue + } + return 0 +} + +func (x *ConfigField_Options) GetMaxValue() int32 { + if x != nil { + return x.MaxValue + } + return 0 +} + +func (x *ConfigField_Options) GetMinFloat() float32 { + if x != nil { + return x.MinFloat + } + return 0 +} + +func (x *ConfigField_Options) GetMaxFloat() float32 { + if x != nil { + return x.MaxFloat + } + return 0 +} + +var File_plugin_proto protoreflect.FileDescriptor + +const file_plugin_proto_rawDesc = "" + + "\n" + + "\fplugin.proto\x12\n" + + "seaweed_pb\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1bgoogle/protobuf/empty.proto\"\xdb\x01\n" + + "\rPluginMessage\x128\n" + + "\bregister\x18\x01 \x01(\v2\x1a.seaweed_pb.PluginRegisterH\x00R\bregister\x12;\n" + + "\theartbeat\x18\x02 \x01(\v2\x1b.seaweed_pb.PluginHeartbeatH\x00R\theartbeat\x12H\n" + + "\rstatus_update\x18\x03 \x01(\v2!.seaweed_pb.ExecutionStatusUpdateH\x00R\fstatusUpdateB\t\n" + + "\acontent\"\xd6\x01\n" + + "\fAdminMessage\x129\n" + + "\vjob_request\x18\x01 \x01(\v2\x16.seaweed_pb.JobRequestH\x00R\n" + + "jobRequest\x12?\n" + + "\rconfig_update\x18\x02 \x01(\v2\x18.seaweed_pb.ConfigUpdateH\x00R\fconfigUpdate\x12?\n" + + "\radmin_command\x18\x03 \x01(\v2\x18.seaweed_pb.AdminCommandH\x00R\fadminCommandB\t\n" + + "\acontent\"\xc9\x01\n" + + "\x0ePluginRegister\x12\x1b\n" + + "\tplugin_id\x18\x01 \x01(\tR\bpluginId\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x18\n" + + "\aversion\x18\x03 \x01(\tR\aversion\x12)\n" + + "\x10protocol_version\x18\x04 \x01(\tR\x0fprotocolVersion\x12A\n" + + "\fcapabilities\x18\x05 \x03(\v2\x1d.seaweed_pb.JobTypeCapabilityR\fcapabilities\"\x88\x01\n" + + "\x11JobTypeCapability\x12\x19\n" + + "\bjob_type\x18\x01 \x01(\tR\ajobType\x12\x1d\n" + + "\n" + + "can_detect\x18\x02 \x01(\bR\tcanDetect\x12\x1f\n" + + "\vcan_execute\x18\x03 \x01(\bR\n" + + "canExecute\x12\x18\n" + + "\aversion\x18\x04 \x01(\tR\aversion\"\x86\x02\n" + + "\x0fPluginHeartbeat\x12\x1b\n" + + "\tplugin_id\x18\x01 \x01(\tR\bpluginId\x128\n" + + "\ttimestamp\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\x12%\n" + + "\x0euptime_seconds\x18\x03 \x01(\x03R\ruptimeSeconds\x12!\n" + + "\fpending_jobs\x18\x04 \x01(\x05R\vpendingJobs\x12*\n" + + "\x11cpu_usage_percent\x18\x05 \x01(\x02R\x0fcpuUsagePercent\x12&\n" + + "\x0fmemory_usage_mb\x18\x06 \x01(\x02R\rmemoryUsageMb\"\xc7\x06\n" + + "\vConfigField\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" + + "\x05label\x18\x02 \x01(\tR\x05label\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12@\n" + + "\n" + + "field_type\x18\x04 \x01(\x0e2!.seaweed_pb.ConfigField.FieldTypeR\tfieldType\x12\x1a\n" + + "\brequired\x18\x05 \x01(\bR\brequired\x12#\n" + + "\rdefault_value\x18\x06 \x01(\tR\fdefaultValue\x12E\n" + + "\x10validation_rules\x18\a \x03(\v2\x1a.seaweed_pb.ValidationRuleR\x0fvalidationRules\x122\n" + + "\aoptions\x18\b \x03(\v2\x18.seaweed_pb.ConfigOptionR\aoptions\x12@\n" + + "\voptions_msg\x18\t \x01(\v2\x1f.seaweed_pb.ConfigField.OptionsR\n" + + "optionsMsg\x1a\xff\x01\n" + + "\aOptions\x12 \n" + + "\vplaceholder\x18\x01 \x01(\tR\vplaceholder\x12 \n" + + "\vsuggestions\x18\x02 \x03(\tR\vsuggestions\x12\x1d\n" + + "\n" + + "min_length\x18\x03 \x01(\x05R\tminLength\x12\x1d\n" + + "\n" + + "max_length\x18\x04 \x01(\x05R\tmaxLength\x12\x1b\n" + + "\tmin_value\x18\x05 \x01(\x05R\bminValue\x12\x1b\n" + + "\tmax_value\x18\x06 \x01(\x05R\bmaxValue\x12\x1b\n" + + "\tmin_float\x18\a \x01(\x02R\bminFloat\x12\x1b\n" + + "\tmax_float\x18\b \x01(\x02R\bmaxFloat\"\xa9\x01\n" + + "\tFieldType\x12\b\n" + + "\x04BOOL\x10\x00\x12\a\n" + + "\x03INT\x10\x01\x12\t\n" + + "\x05FLOAT\x10\x02\x12\n" + + "\n" + + "\x06STRING\x10\x03\x12\f\n" + + "\bDURATION\x10\x04\x12\n" + + "\n" + + "\x06SELECT\x10\x05\x12\x0f\n" + + "\vMULTISELECT\x10\x06\x12\n" + + "\n" + + "\x06SECRET\x10\a\x12\f\n" + + "\bTEXTAREA\x10\b\x12\b\n" + + "\x04JSON\x10\t\x12\x0e\n" + + "\n" + + "PERCENTAGE\x10\n" + + "\x12\t\n" + + "\x05BYTES\x10\v\x12\b\n" + + "\x04CRON\x10\f\"\xf0\x01\n" + + "\x0eValidationRule\x12@\n" + + "\trule_type\x18\x01 \x01(\x0e2#.seaweed_pb.ValidationRule.RuleTypeR\bruleType\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value\x12#\n" + + "\rerror_message\x18\x03 \x01(\tR\ferrorMessage\"a\n" + + "\bRuleType\x12\r\n" + + "\tMIN_VALUE\x10\x00\x12\r\n" + + "\tMAX_VALUE\x10\x01\x12\v\n" + + "\aPATTERN\x10\x02\x12\x0e\n" + + "\n" + + "MIN_LENGTH\x10\x03\x12\x0e\n" + + "\n" + + "MAX_LENGTH\x10\x04\x12\n" + + "\n" + + "\x06CUSTOM\x10\x05\"\\\n" + + "\fConfigOption\x12\x14\n" + + "\x05value\x18\x01 \x01(\tR\x05value\x12\x14\n" + + "\x05label\x18\x02 \x01(\tR\x05label\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\"\xc1\x02\n" + + "\x10ConfigFieldValue\x12\x1d\n" + + "\n" + + "field_name\x18\x01 \x01(\tR\tfieldName\x12!\n" + + "\fstring_value\x18\x02 \x01(\tR\vstringValue\x12\x1b\n" + + "\tint_value\x18\x03 \x01(\x03R\bintValue\x12\x1f\n" + + "\vfloat_value\x18\x04 \x01(\x02R\n" + + "floatValue\x12\x1d\n" + + "\n" + + "bool_value\x18\x05 \x01(\bR\tboolValue\x12@\n" + + "\x0eduration_value\x18\x06 \x01(\v2\x19.google.protobuf.DurationR\rdurationValue\x12-\n" + + "\x12multiselect_values\x18\a \x03(\tR\x11multiselectValues\x12\x1d\n" + + "\n" + + "json_value\x18\b \x01(\tR\tjsonValue\"\xdd\x02\n" + + "\rJobTypeConfig\x12\x19\n" + + "\bjob_type\x18\x01 \x01(\tR\ajobType\x12\x18\n" + + "\aenabled\x18\x02 \x01(\bR\aenabled\x12?\n" + + "\fadmin_config\x18\x03 \x03(\v2\x1c.seaweed_pb.ConfigFieldValueR\vadminConfig\x12A\n" + + "\rworker_config\x18\x04 \x03(\v2\x1c.seaweed_pb.ConfigFieldValueR\fworkerConfig\x129\n" + + "\n" + + "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + + "\n" + + "updated_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\x12\x1d\n" + + "\n" + + "created_by\x18\a \x01(\tR\tcreatedBy\"s\n" + + "\x13ConfigUpdateRequest\x12\x19\n" + + "\bjob_type\x18\x01 \x01(\tR\ajobType\x12A\n" + + "\rconfig_values\x18\x02 \x03(\v2\x1c.seaweed_pb.ConfigFieldValueR\fconfigValues\":\n" + + "\x1dGetConfigurationSchemaRequest\x12\x19\n" + + "\bjob_type\x18\x01 \x01(\tR\ajobType\"\xa2\x02\n" + + "\x13JobTypeConfigSchema\x12\x19\n" + + "\bjob_type\x18\x01 \x01(\tR\ajobType\x12\x18\n" + + "\aversion\x18\x02 \x01(\tR\aversion\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12:\n" + + "\fadmin_fields\x18\x04 \x03(\v2\x17.seaweed_pb.ConfigFieldR\vadminFields\x12<\n" + + "\rworker_fields\x18\x05 \x03(\v2\x17.seaweed_pb.ConfigFieldR\fworkerFields\x12:\n" + + "\ffield_groups\x18\x06 \x03(\v2\x17.seaweed_pb.ConfigGroupR\vfieldGroups\"z\n" + + "\vConfigGroup\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" + + "\x05label\x18\x02 \x01(\tR\x05label\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12\x1f\n" + + "\vfield_names\x18\x04 \x03(\tR\n" + + "fieldNames\"\x81\x01\n" + + "\x10DetectionRequest\x12\x19\n" + + "\bjob_type\x18\x01 \x01(\tR\ajobType\x121\n" + + "\x06config\x18\x02 \x01(\v2\x19.seaweed_pb.JobTypeConfigR\x06config\x12\x1f\n" + + "\vfilter_tags\x18\x03 \x03(\tR\n" + + "filterTags\"\xc2\x01\n" + + "\x11DetectionResponse\x12<\n" + + "\rdetected_jobs\x18\x01 \x03(\v2\x17.seaweed_pb.DetectedJobR\fdetectedJobs\x12A\n" + + "\x0edetection_time\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\rdetectionTime\x12,\n" + + "\x12detector_plugin_id\x18\x03 \x01(\tR\x10detectorPluginId\"\x92\x03\n" + + "\vDetectedJob\x12\x17\n" + + "\ajob_key\x18\x01 \x01(\tR\x06jobKey\x12\x19\n" + + "\bjob_type\x18\x02 \x01(\tR\ajobType\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12\x1a\n" + + "\bpriority\x18\x04 \x01(\x03R\bpriority\x12H\n" + + "\x12estimated_duration\x18\x05 \x01(\v2\x19.google.protobuf.DurationR\x11estimatedDuration\x12A\n" + + "\bmetadata\x18\x06 \x03(\v2%.seaweed_pb.DetectedJob.MetadataEntryR\bmetadata\x12G\n" + + "\x10suggested_config\x18\a \x03(\v2\x1c.seaweed_pb.ConfigFieldValueR\x0fsuggestedConfig\x1a;\n" + + "\rMetadataEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x93\x03\n" + + "\n" + + "JobRequest\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\x12\x19\n" + + "\bjob_type\x18\x02 \x01(\tR\ajobType\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12\x1a\n" + + "\bpriority\x18\x04 \x01(\x03R\bpriority\x129\n" + + "\n" + + "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x124\n" + + "\x06config\x18\x06 \x03(\v2\x1c.seaweed_pb.ConfigFieldValueR\x06config\x12@\n" + + "\bmetadata\x18\a \x03(\v2$.seaweed_pb.JobRequest.MetadataEntryR\bmetadata\x12%\n" + + "\x0erequest_source\x18\b \x01(\tR\rrequestSource\x1a;\n" + + "\rMetadataEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x98\x03\n" + + "\x13JobExecutionMessage\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\x129\n" + + "\vjob_started\x18\x02 \x01(\v2\x16.seaweed_pb.JobStartedH\x00R\n" + + "jobStarted\x125\n" + + "\bprogress\x18\x03 \x01(\v2\x17.seaweed_pb.JobProgressH\x00R\bprogress\x12;\n" + + "\n" + + "checkpoint\x18\x04 \x01(\v2\x19.seaweed_pb.JobCheckpointH\x00R\n" + + "checkpoint\x12?\n" + + "\rjob_completed\x18\x05 \x01(\v2\x18.seaweed_pb.JobCompletedH\x00R\fjobCompleted\x126\n" + + "\n" + + "job_failed\x18\x06 \x01(\v2\x15.seaweed_pb.JobFailedH\x00R\tjobFailed\x127\n" + + "\tlog_entry\x18\a \x01(\v2\x18.seaweed_pb.ExecutionLogH\x00R\blogEntryB\t\n" + + "\acontent\"h\n" + + "\n" + + "JobStarted\x129\n" + + "\n" + + "started_at\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\tstartedAt\x12\x1f\n" + + "\vexecutor_id\x18\x02 \x01(\tR\n" + + "executorId\"\xbd\x01\n" + + "\vJobProgress\x12)\n" + + "\x10progress_percent\x18\x01 \x01(\x05R\x0fprogressPercent\x12!\n" + + "\fcurrent_step\x18\x02 \x01(\tR\vcurrentStep\x12%\n" + + "\x0estatus_message\x18\x03 \x01(\tR\rstatusMessage\x129\n" + + "\n" + + "updated_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\"\x98\x01\n" + + "\rJobCheckpoint\x12#\n" + + "\rcheckpoint_id\x18\x01 \x01(\tR\fcheckpointId\x12'\n" + + "\x0fcheckpoint_data\x18\x02 \x01(\fR\x0echeckpointData\x129\n" + + "\n" + + "created_at\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\"\xe0\x01\n" + + "\fJobCompleted\x12=\n" + + "\fcompleted_at\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\vcompletedAt\x12\x18\n" + + "\asummary\x18\x02 \x01(\tR\asummary\x12<\n" + + "\x06output\x18\x03 \x03(\v2$.seaweed_pb.JobCompleted.OutputEntryR\x06output\x1a9\n" + + "\vOutputEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xec\x01\n" + + "\tJobFailed\x12\x1d\n" + + "\n" + + "error_code\x18\x01 \x01(\tR\terrorCode\x12#\n" + + "\rerror_message\x18\x02 \x01(\tR\ferrorMessage\x12#\n" + + "\rerror_details\x18\x03 \x01(\fR\ferrorDetails\x12\x1c\n" + + "\tretryable\x18\x04 \x01(\bR\tretryable\x127\n" + + "\tfailed_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\bfailedAt\x12\x1f\n" + + "\vretry_count\x18\x06 \x01(\x05R\n" + + "retryCount\"\xd1\x02\n" + + "\fExecutionLog\x128\n" + + "\ttimestamp\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\x127\n" + + "\x05level\x18\x02 \x01(\x0e2!.seaweed_pb.ExecutionLog.LogLevelR\x05level\x12\x18\n" + + "\amessage\x18\x03 \x01(\tR\amessage\x12?\n" + + "\acontext\x18\x04 \x03(\v2%.seaweed_pb.ExecutionLog.ContextEntryR\acontext\x1a:\n" + + "\fContextEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"7\n" + + "\bLogLevel\x12\t\n" + + "\x05DEBUG\x10\x00\x12\b\n" + + "\x04INFO\x10\x01\x12\v\n" + + "\aWARNING\x10\x02\x12\t\n" + + "\x05ERROR\x10\x03\"\xa9\x01\n" + + "\x12JobProgressMessage\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\x127\n" + + "\x06update\x18\x02 \x01(\v2\x1d.seaweed_pb.JobProgressUpdateH\x00R\x06update\x128\n" + + "\acommand\x18\x03 \x01(\v2\x1c.seaweed_pb.ExecutionCommandH\x00R\acommandB\t\n" + + "\acontent\"\xd9\x01\n" + + "\x11JobProgressUpdate\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\x12)\n" + + "\x10progress_percent\x18\x02 \x01(\x05R\x0fprogressPercent\x12!\n" + + "\fcurrent_step\x18\x03 \x01(\tR\vcurrentStep\x12%\n" + + "\x0estatus_message\x18\x04 \x01(\tR\rstatusMessage\x128\n" + + "\ttimestamp\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\"\xc5\x02\n" + + "\x10ExecutionCommand\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\x12K\n" + + "\fcommand_type\x18\x02 \x01(\x0e2(.seaweed_pb.ExecutionCommand.CommandTypeR\vcommandType\x12L\n" + + "\n" + + "parameters\x18\x03 \x03(\v2,.seaweed_pb.ExecutionCommand.ParametersEntryR\n" + + "parameters\x1a=\n" + + "\x0fParametersEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"@\n" + + "\vCommandType\x12\t\n" + + "\x05PAUSE\x10\x00\x12\n" + + "\n" + + "\x06RESUME\x10\x01\x12\n" + + "\n" + + "\x06CANCEL\x10\x02\x12\x0e\n" + + "\n" + + "GET_STATUS\x10\x03\"\xc8\x01\n" + + "\x15ExecutionStatusUpdate\x12\x1b\n" + + "\tplugin_id\x18\x01 \x01(\tR\bpluginId\x12\x15\n" + + "\x06job_id\x18\x02 \x01(\tR\x05jobId\x12\x16\n" + + "\x06status\x18\x03 \x01(\tR\x06status\x12)\n" + + "\x10progress_percent\x18\x04 \x01(\x05R\x0fprogressPercent\x128\n" + + "\ttimestamp\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\"\xa7\x01\n" + + "\fConfigUpdate\x12\x19\n" + + "\bjob_type\x18\x01 \x01(\tR\ajobType\x12A\n" + + "\rconfig_values\x18\x02 \x03(\v2\x1c.seaweed_pb.ConfigFieldValueR\fconfigValues\x129\n" + + "\n" + + "updated_at\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\"\xbb\x02\n" + + "\fAdminCommand\x12G\n" + + "\fcommand_type\x18\x01 \x01(\x0e2$.seaweed_pb.AdminCommand.CommandTypeR\vcommandType\x12H\n" + + "\n" + + "parameters\x18\x02 \x03(\v2(.seaweed_pb.AdminCommand.ParametersEntryR\n" + + "parameters\x1a=\n" + + "\x0fParametersEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"Y\n" + + "\vCommandType\x12\x11\n" + + "\rRELOAD_CONFIG\x10\x00\x12\x13\n" + + "\x0fENABLE_JOB_TYPE\x10\x01\x12\x14\n" + + "\x10DISABLE_JOB_TYPE\x10\x02\x12\f\n" + + "\bSHUTDOWN\x10\x03\"\xea\x01\n" + + "\x0fListJobsRequest\x12\x19\n" + + "\bjob_type\x18\x01 \x01(\tR\ajobType\x12@\n" + + "\x06status\x18\x02 \x01(\x0e2(.seaweed_pb.ListJobsRequest.StatusFilterR\x06status\x12\x14\n" + + "\x05limit\x18\x03 \x01(\x05R\x05limit\x12\x16\n" + + "\x06offset\x18\x04 \x01(\x05R\x06offset\"L\n" + + "\fStatusFilter\x12\a\n" + + "\x03ALL\x10\x00\x12\v\n" + + "\aPENDING\x10\x01\x12\v\n" + + "\aRUNNING\x10\x02\x12\r\n" + + "\tCOMPLETED\x10\x03\x12\n" + + "\n" + + "\x06FAILED\x10\x04\"&\n" + + "\rGetJobRequest\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\"\xd9\x01\n" + + "\x19GetJobExecutionLogRequest\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\x12D\n" + + "\x05level\x18\x02 \x01(\x0e2..seaweed_pb.GetJobExecutionLogRequest.LogLevelR\x05level\x12\x1d\n" + + "\n" + + "tail_lines\x18\x03 \x01(\x05R\ttailLines\"@\n" + + "\bLogLevel\x12\t\n" + + "\x05DEBUG\x10\x00\x12\b\n" + + "\x04INFO\x10\x01\x12\v\n" + + "\aWARNING\x10\x02\x12\t\n" + + "\x05ERROR\x10\x03\x12\a\n" + + "\x03ALL\x10\x04\"\x84\x04\n" + + "\x03Job\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\x12\x19\n" + + "\bjob_type\x18\x02 \x01(\tR\ajobType\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12\x1a\n" + + "\bpriority\x18\x04 \x01(\x03R\bpriority\x12.\n" + + "\x06status\x18\x05 \x01(\x0e2\x16.seaweed_pb.Job.StatusR\x06status\x129\n" + + "\n" + + "created_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + + "\n" + + "updated_at\x18\a \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\x12,\n" + + "\x12executor_plugin_id\x18\b \x01(\tR\x10executorPluginId\x12)\n" + + "\x10progress_percent\x18\t \x01(\x05R\x0fprogressPercent\x124\n" + + "\x06config\x18\n" + + " \x03(\v2\x1c.seaweed_pb.ConfigFieldValueR\x06config\"X\n" + + "\x06Status\x12\v\n" + + "\aPENDING\x10\x00\x12\v\n" + + "\aRUNNING\x10\x01\x12\r\n" + + "\tCOMPLETED\x10\x02\x12\n" + + "\n" + + "\x06FAILED\x10\x03\x12\r\n" + + "\tCANCELLED\x10\x04\x12\n" + + "\n" + + "\x06PAUSED\x10\x05\"\x92\x02\n" + + "\tJobDetail\x12!\n" + + "\x03job\x18\x01 \x01(\v2\x0f.seaweed_pb.JobR\x03job\x12>\n" + + "\vlog_entries\x18\x02 \x03(\v2\x1d.seaweed_pb.ExecutionLogEntryR\n" + + "logEntries\x12A\n" + + "\x0fcompletion_info\x18\x03 \x01(\v2\x18.seaweed_pb.JobCompletedR\x0ecompletionInfo\x128\n" + + "\ffailure_info\x18\x04 \x01(\v2\x15.seaweed_pb.JobFailedR\vfailureInfo\x12%\n" + + "\x0echeckpoint_ids\x18\x05 \x03(\tR\rcheckpointIds\"\xa2\x02\n" + + "\x11ExecutionLogEntry\x128\n" + + "\ttimestamp\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\x127\n" + + "\x05level\x18\x02 \x01(\x0e2!.seaweed_pb.ExecutionLog.LogLevelR\x05level\x12\x18\n" + + "\amessage\x18\x03 \x01(\tR\amessage\x12D\n" + + "\acontext\x18\x04 \x03(\v2*.seaweed_pb.ExecutionLogEntry.ContextEntryR\acontext\x1a:\n" + + "\fContextEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"v\n" + + "\aJobList\x12#\n" + + "\x04jobs\x18\x01 \x03(\v2\x0f.seaweed_pb.JobR\x04jobs\x12\x1f\n" + + "\vtotal_count\x18\x02 \x01(\x05R\n" + + "totalCount\x12%\n" + + "\x0ereturned_count\x18\x03 \x01(\x05R\rreturnedCount\"\xef\x03\n" + + "\vPluginStats\x12#\n" + + "\rtotal_plugins\x18\x01 \x01(\x05R\ftotalPlugins\x12%\n" + + "\x0eactive_plugins\x18\x02 \x01(\x05R\ractivePlugins\x12\x1d\n" + + "\n" + + "total_jobs\x18\x03 \x01(\x05R\ttotalJobs\x12!\n" + + "\fpending_jobs\x18\x04 \x01(\x05R\vpendingJobs\x12!\n" + + "\frunning_jobs\x18\x05 \x01(\x05R\vrunningJobs\x12%\n" + + "\x0ecompleted_jobs\x18\x06 \x01(\x05R\rcompletedJobs\x12\x1f\n" + + "\vfailed_jobs\x18\a \x01(\x05R\n" + + "failedJobs\x12;\n" + + "\vlast_update\x18\b \x01(\v2\x1a.google.protobuf.TimestampR\n" + + "lastUpdate\x12O\n" + + "\x0ejob_type_stats\x18\t \x03(\v2).seaweed_pb.PluginStats.JobTypeStatsEntryR\fjobTypeStats\x1aY\n" + + "\x11JobTypeStatsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12.\n" + + "\x05value\x18\x02 \x01(\v2\x18.seaweed_pb.JobTypeStatsR\x05value:\x028\x01\"\x95\x02\n" + + "\fJobTypeStats\x12\x19\n" + + "\bjob_type\x18\x01 \x01(\tR\ajobType\x12\x14\n" + + "\x05total\x18\x02 \x01(\x05R\x05total\x12\x18\n" + + "\apending\x18\x03 \x01(\x05R\apending\x12\x18\n" + + "\arunning\x18\x04 \x01(\x05R\arunning\x12\x1c\n" + + "\tcompleted\x18\x05 \x01(\x05R\tcompleted\x12\x16\n" + + "\x06failed\x18\x06 \x01(\x05R\x06failed\x12!\n" + + "\fsuccess_rate\x18\a \x01(\x02R\vsuccessRate\x12G\n" + + "\x12avg_execution_time\x18\b \x01(\v2\x19.google.protobuf.DurationR\x10avgExecutionTime\">\n" + + "\n" + + "PluginList\x120\n" + + "\aplugins\x18\x01 \x03(\v2\x16.seaweed_pb.PluginInfoR\aplugins\"\xf9\x02\n" + + "\n" + + "PluginInfo\x12\x1b\n" + + "\tplugin_id\x18\x01 \x01(\tR\bpluginId\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x18\n" + + "\aversion\x18\x03 \x01(\tR\aversion\x12)\n" + + "\x10protocol_version\x18\x04 \x01(\tR\x0fprotocolVersion\x12=\n" + + "\fconnected_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\vconnectedAt\x12A\n" + + "\x0elast_heartbeat\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\rlastHeartbeat\x12A\n" + + "\fcapabilities\x18\a \x03(\v2\x1d.seaweed_pb.JobTypeCapabilityR\fcapabilities\x12\x18\n" + + "\ahealthy\x18\b \x01(\bR\ahealthy\x12\x16\n" + + "\x06status\x18\t \x01(\tR\x06status\"O\n" + + "\x1aUpdateJobTypeConfigRequest\x121\n" + + "\x06config\x18\x01 \x01(\v2\x19.seaweed_pb.JobTypeConfigR\x06config\"\xa6\x02\n" + + "\x10CreateJobRequest\x12\x19\n" + + "\bjob_type\x18\x01 \x01(\tR\ajobType\x12 \n" + + "\vdescription\x18\x02 \x01(\tR\vdescription\x12\x1a\n" + + "\bpriority\x18\x03 \x01(\x03R\bpriority\x124\n" + + "\x06config\x18\x04 \x03(\v2\x1c.seaweed_pb.ConfigFieldValueR\x06config\x12F\n" + + "\bmetadata\x18\x05 \x03(\v2*.seaweed_pb.CreateJobRequest.MetadataEntryR\bmetadata\x1a;\n" + + "\rMetadataEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\")\n" + + "\x10CancelJobRequest\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\"(\n" + + "\x0fRetryJobRequest\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId2\xa6\x01\n" + + "\rPluginService\x12B\n" + + "\aConnect\x12\x19.seaweed_pb.PluginMessage\x1a\x18.seaweed_pb.AdminMessage(\x010\x01\x12Q\n" + + "\n" + + "ExecuteJob\x12\x1f.seaweed_pb.JobExecutionMessage\x1a\x1e.seaweed_pb.JobProgressMessage(\x010\x012\xed\x02\n" + + "\x11AdminQueryService\x12A\n" + + "\x0eGetPluginStats\x12\x16.google.protobuf.Empty\x1a\x17.seaweed_pb.PluginStats\x12=\n" + + "\vListPlugins\x12\x16.google.protobuf.Empty\x1a\x16.seaweed_pb.PluginList\x12<\n" + + "\bListJobs\x12\x1b.seaweed_pb.ListJobsRequest\x1a\x13.seaweed_pb.JobList\x12:\n" + + "\x06GetJob\x12\x19.seaweed_pb.GetJobRequest\x1a\x15.seaweed_pb.JobDetail\x12\\\n" + + "\x12GetJobExecutionLog\x12%.seaweed_pb.GetJobExecutionLogRequest\x1a\x1d.seaweed_pb.ExecutionLogEntry0\x012\xa8\x02\n" + + "\x13AdminCommandService\x12X\n" + + "\x13UpdateJobTypeConfig\x12&.seaweed_pb.UpdateJobTypeConfigRequest\x1a\x19.seaweed_pb.JobTypeConfig\x12:\n" + + "\tCreateJob\x12\x1c.seaweed_pb.CreateJobRequest\x1a\x0f.seaweed_pb.Job\x12A\n" + + "\tCancelJob\x12\x1c.seaweed_pb.CancelJobRequest\x1a\x16.google.protobuf.Empty\x128\n" + + "\bRetryJob\x12\x1b.seaweed_pb.RetryJobRequest\x1a\x0f.seaweed_pb.JobB2Z0github.com/seaweedfs/seaweedfs/weed/pb/plugin_pbb\x06proto3" + +var ( + file_plugin_proto_rawDescOnce sync.Once + file_plugin_proto_rawDescData []byte +) + +func file_plugin_proto_rawDescGZIP() []byte { + file_plugin_proto_rawDescOnce.Do(func() { + file_plugin_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_plugin_proto_rawDesc), len(file_plugin_proto_rawDesc))) + }) + return file_plugin_proto_rawDescData +} + +var file_plugin_proto_enumTypes = make([]protoimpl.EnumInfo, 8) +var file_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 56) +var file_plugin_proto_goTypes = []any{ + (ConfigField_FieldType)(0), // 0: seaweed_pb.ConfigField.FieldType + (ValidationRule_RuleType)(0), // 1: seaweed_pb.ValidationRule.RuleType + (ExecutionLog_LogLevel)(0), // 2: seaweed_pb.ExecutionLog.LogLevel + (ExecutionCommand_CommandType)(0), // 3: seaweed_pb.ExecutionCommand.CommandType + (AdminCommand_CommandType)(0), // 4: seaweed_pb.AdminCommand.CommandType + (ListJobsRequest_StatusFilter)(0), // 5: seaweed_pb.ListJobsRequest.StatusFilter + (GetJobExecutionLogRequest_LogLevel)(0), // 6: seaweed_pb.GetJobExecutionLogRequest.LogLevel + (Job_Status)(0), // 7: seaweed_pb.Job.Status + (*PluginMessage)(nil), // 8: seaweed_pb.PluginMessage + (*AdminMessage)(nil), // 9: seaweed_pb.AdminMessage + (*PluginRegister)(nil), // 10: seaweed_pb.PluginRegister + (*JobTypeCapability)(nil), // 11: seaweed_pb.JobTypeCapability + (*PluginHeartbeat)(nil), // 12: seaweed_pb.PluginHeartbeat + (*ConfigField)(nil), // 13: seaweed_pb.ConfigField + (*ValidationRule)(nil), // 14: seaweed_pb.ValidationRule + (*ConfigOption)(nil), // 15: seaweed_pb.ConfigOption + (*ConfigFieldValue)(nil), // 16: seaweed_pb.ConfigFieldValue + (*JobTypeConfig)(nil), // 17: seaweed_pb.JobTypeConfig + (*ConfigUpdateRequest)(nil), // 18: seaweed_pb.ConfigUpdateRequest + (*GetConfigurationSchemaRequest)(nil), // 19: seaweed_pb.GetConfigurationSchemaRequest + (*JobTypeConfigSchema)(nil), // 20: seaweed_pb.JobTypeConfigSchema + (*ConfigGroup)(nil), // 21: seaweed_pb.ConfigGroup + (*DetectionRequest)(nil), // 22: seaweed_pb.DetectionRequest + (*DetectionResponse)(nil), // 23: seaweed_pb.DetectionResponse + (*DetectedJob)(nil), // 24: seaweed_pb.DetectedJob + (*JobRequest)(nil), // 25: seaweed_pb.JobRequest + (*JobExecutionMessage)(nil), // 26: seaweed_pb.JobExecutionMessage + (*JobStarted)(nil), // 27: seaweed_pb.JobStarted + (*JobProgress)(nil), // 28: seaweed_pb.JobProgress + (*JobCheckpoint)(nil), // 29: seaweed_pb.JobCheckpoint + (*JobCompleted)(nil), // 30: seaweed_pb.JobCompleted + (*JobFailed)(nil), // 31: seaweed_pb.JobFailed + (*ExecutionLog)(nil), // 32: seaweed_pb.ExecutionLog + (*JobProgressMessage)(nil), // 33: seaweed_pb.JobProgressMessage + (*JobProgressUpdate)(nil), // 34: seaweed_pb.JobProgressUpdate + (*ExecutionCommand)(nil), // 35: seaweed_pb.ExecutionCommand + (*ExecutionStatusUpdate)(nil), // 36: seaweed_pb.ExecutionStatusUpdate + (*ConfigUpdate)(nil), // 37: seaweed_pb.ConfigUpdate + (*AdminCommand)(nil), // 38: seaweed_pb.AdminCommand + (*ListJobsRequest)(nil), // 39: seaweed_pb.ListJobsRequest + (*GetJobRequest)(nil), // 40: seaweed_pb.GetJobRequest + (*GetJobExecutionLogRequest)(nil), // 41: seaweed_pb.GetJobExecutionLogRequest + (*Job)(nil), // 42: seaweed_pb.Job + (*JobDetail)(nil), // 43: seaweed_pb.JobDetail + (*ExecutionLogEntry)(nil), // 44: seaweed_pb.ExecutionLogEntry + (*JobList)(nil), // 45: seaweed_pb.JobList + (*PluginStats)(nil), // 46: seaweed_pb.PluginStats + (*JobTypeStats)(nil), // 47: seaweed_pb.JobTypeStats + (*PluginList)(nil), // 48: seaweed_pb.PluginList + (*PluginInfo)(nil), // 49: seaweed_pb.PluginInfo + (*UpdateJobTypeConfigRequest)(nil), // 50: seaweed_pb.UpdateJobTypeConfigRequest + (*CreateJobRequest)(nil), // 51: seaweed_pb.CreateJobRequest + (*CancelJobRequest)(nil), // 52: seaweed_pb.CancelJobRequest + (*RetryJobRequest)(nil), // 53: seaweed_pb.RetryJobRequest + (*ConfigField_Options)(nil), // 54: seaweed_pb.ConfigField.Options + nil, // 55: seaweed_pb.DetectedJob.MetadataEntry + nil, // 56: seaweed_pb.JobRequest.MetadataEntry + nil, // 57: seaweed_pb.JobCompleted.OutputEntry + nil, // 58: seaweed_pb.ExecutionLog.ContextEntry + nil, // 59: seaweed_pb.ExecutionCommand.ParametersEntry + nil, // 60: seaweed_pb.AdminCommand.ParametersEntry + nil, // 61: seaweed_pb.ExecutionLogEntry.ContextEntry + nil, // 62: seaweed_pb.PluginStats.JobTypeStatsEntry + nil, // 63: seaweed_pb.CreateJobRequest.MetadataEntry + (*timestamppb.Timestamp)(nil), // 64: google.protobuf.Timestamp + (*durationpb.Duration)(nil), // 65: google.protobuf.Duration + (*emptypb.Empty)(nil), // 66: google.protobuf.Empty +} +var file_plugin_proto_depIdxs = []int32{ + 10, // 0: seaweed_pb.PluginMessage.register:type_name -> seaweed_pb.PluginRegister + 12, // 1: seaweed_pb.PluginMessage.heartbeat:type_name -> seaweed_pb.PluginHeartbeat + 36, // 2: seaweed_pb.PluginMessage.status_update:type_name -> seaweed_pb.ExecutionStatusUpdate + 25, // 3: seaweed_pb.AdminMessage.job_request:type_name -> seaweed_pb.JobRequest + 37, // 4: seaweed_pb.AdminMessage.config_update:type_name -> seaweed_pb.ConfigUpdate + 38, // 5: seaweed_pb.AdminMessage.admin_command:type_name -> seaweed_pb.AdminCommand + 11, // 6: seaweed_pb.PluginRegister.capabilities:type_name -> seaweed_pb.JobTypeCapability + 64, // 7: seaweed_pb.PluginHeartbeat.timestamp:type_name -> google.protobuf.Timestamp + 0, // 8: seaweed_pb.ConfigField.field_type:type_name -> seaweed_pb.ConfigField.FieldType + 14, // 9: seaweed_pb.ConfigField.validation_rules:type_name -> seaweed_pb.ValidationRule + 15, // 10: seaweed_pb.ConfigField.options:type_name -> seaweed_pb.ConfigOption + 54, // 11: seaweed_pb.ConfigField.options_msg:type_name -> seaweed_pb.ConfigField.Options + 1, // 12: seaweed_pb.ValidationRule.rule_type:type_name -> seaweed_pb.ValidationRule.RuleType + 65, // 13: seaweed_pb.ConfigFieldValue.duration_value:type_name -> google.protobuf.Duration + 16, // 14: seaweed_pb.JobTypeConfig.admin_config:type_name -> seaweed_pb.ConfigFieldValue + 16, // 15: seaweed_pb.JobTypeConfig.worker_config:type_name -> seaweed_pb.ConfigFieldValue + 64, // 16: seaweed_pb.JobTypeConfig.created_at:type_name -> google.protobuf.Timestamp + 64, // 17: seaweed_pb.JobTypeConfig.updated_at:type_name -> google.protobuf.Timestamp + 16, // 18: seaweed_pb.ConfigUpdateRequest.config_values:type_name -> seaweed_pb.ConfigFieldValue + 13, // 19: seaweed_pb.JobTypeConfigSchema.admin_fields:type_name -> seaweed_pb.ConfigField + 13, // 20: seaweed_pb.JobTypeConfigSchema.worker_fields:type_name -> seaweed_pb.ConfigField + 21, // 21: seaweed_pb.JobTypeConfigSchema.field_groups:type_name -> seaweed_pb.ConfigGroup + 17, // 22: seaweed_pb.DetectionRequest.config:type_name -> seaweed_pb.JobTypeConfig + 24, // 23: seaweed_pb.DetectionResponse.detected_jobs:type_name -> seaweed_pb.DetectedJob + 64, // 24: seaweed_pb.DetectionResponse.detection_time:type_name -> google.protobuf.Timestamp + 65, // 25: seaweed_pb.DetectedJob.estimated_duration:type_name -> google.protobuf.Duration + 55, // 26: seaweed_pb.DetectedJob.metadata:type_name -> seaweed_pb.DetectedJob.MetadataEntry + 16, // 27: seaweed_pb.DetectedJob.suggested_config:type_name -> seaweed_pb.ConfigFieldValue + 64, // 28: seaweed_pb.JobRequest.created_at:type_name -> google.protobuf.Timestamp + 16, // 29: seaweed_pb.JobRequest.config:type_name -> seaweed_pb.ConfigFieldValue + 56, // 30: seaweed_pb.JobRequest.metadata:type_name -> seaweed_pb.JobRequest.MetadataEntry + 27, // 31: seaweed_pb.JobExecutionMessage.job_started:type_name -> seaweed_pb.JobStarted + 28, // 32: seaweed_pb.JobExecutionMessage.progress:type_name -> seaweed_pb.JobProgress + 29, // 33: seaweed_pb.JobExecutionMessage.checkpoint:type_name -> seaweed_pb.JobCheckpoint + 30, // 34: seaweed_pb.JobExecutionMessage.job_completed:type_name -> seaweed_pb.JobCompleted + 31, // 35: seaweed_pb.JobExecutionMessage.job_failed:type_name -> seaweed_pb.JobFailed + 32, // 36: seaweed_pb.JobExecutionMessage.log_entry:type_name -> seaweed_pb.ExecutionLog + 64, // 37: seaweed_pb.JobStarted.started_at:type_name -> google.protobuf.Timestamp + 64, // 38: seaweed_pb.JobProgress.updated_at:type_name -> google.protobuf.Timestamp + 64, // 39: seaweed_pb.JobCheckpoint.created_at:type_name -> google.protobuf.Timestamp + 64, // 40: seaweed_pb.JobCompleted.completed_at:type_name -> google.protobuf.Timestamp + 57, // 41: seaweed_pb.JobCompleted.output:type_name -> seaweed_pb.JobCompleted.OutputEntry + 64, // 42: seaweed_pb.JobFailed.failed_at:type_name -> google.protobuf.Timestamp + 64, // 43: seaweed_pb.ExecutionLog.timestamp:type_name -> google.protobuf.Timestamp + 2, // 44: seaweed_pb.ExecutionLog.level:type_name -> seaweed_pb.ExecutionLog.LogLevel + 58, // 45: seaweed_pb.ExecutionLog.context:type_name -> seaweed_pb.ExecutionLog.ContextEntry + 34, // 46: seaweed_pb.JobProgressMessage.update:type_name -> seaweed_pb.JobProgressUpdate + 35, // 47: seaweed_pb.JobProgressMessage.command:type_name -> seaweed_pb.ExecutionCommand + 64, // 48: seaweed_pb.JobProgressUpdate.timestamp:type_name -> google.protobuf.Timestamp + 3, // 49: seaweed_pb.ExecutionCommand.command_type:type_name -> seaweed_pb.ExecutionCommand.CommandType + 59, // 50: seaweed_pb.ExecutionCommand.parameters:type_name -> seaweed_pb.ExecutionCommand.ParametersEntry + 64, // 51: seaweed_pb.ExecutionStatusUpdate.timestamp:type_name -> google.protobuf.Timestamp + 16, // 52: seaweed_pb.ConfigUpdate.config_values:type_name -> seaweed_pb.ConfigFieldValue + 64, // 53: seaweed_pb.ConfigUpdate.updated_at:type_name -> google.protobuf.Timestamp + 4, // 54: seaweed_pb.AdminCommand.command_type:type_name -> seaweed_pb.AdminCommand.CommandType + 60, // 55: seaweed_pb.AdminCommand.parameters:type_name -> seaweed_pb.AdminCommand.ParametersEntry + 5, // 56: seaweed_pb.ListJobsRequest.status:type_name -> seaweed_pb.ListJobsRequest.StatusFilter + 6, // 57: seaweed_pb.GetJobExecutionLogRequest.level:type_name -> seaweed_pb.GetJobExecutionLogRequest.LogLevel + 7, // 58: seaweed_pb.Job.status:type_name -> seaweed_pb.Job.Status + 64, // 59: seaweed_pb.Job.created_at:type_name -> google.protobuf.Timestamp + 64, // 60: seaweed_pb.Job.updated_at:type_name -> google.protobuf.Timestamp + 16, // 61: seaweed_pb.Job.config:type_name -> seaweed_pb.ConfigFieldValue + 42, // 62: seaweed_pb.JobDetail.job:type_name -> seaweed_pb.Job + 44, // 63: seaweed_pb.JobDetail.log_entries:type_name -> seaweed_pb.ExecutionLogEntry + 30, // 64: seaweed_pb.JobDetail.completion_info:type_name -> seaweed_pb.JobCompleted + 31, // 65: seaweed_pb.JobDetail.failure_info:type_name -> seaweed_pb.JobFailed + 64, // 66: seaweed_pb.ExecutionLogEntry.timestamp:type_name -> google.protobuf.Timestamp + 2, // 67: seaweed_pb.ExecutionLogEntry.level:type_name -> seaweed_pb.ExecutionLog.LogLevel + 61, // 68: seaweed_pb.ExecutionLogEntry.context:type_name -> seaweed_pb.ExecutionLogEntry.ContextEntry + 42, // 69: seaweed_pb.JobList.jobs:type_name -> seaweed_pb.Job + 64, // 70: seaweed_pb.PluginStats.last_update:type_name -> google.protobuf.Timestamp + 62, // 71: seaweed_pb.PluginStats.job_type_stats:type_name -> seaweed_pb.PluginStats.JobTypeStatsEntry + 65, // 72: seaweed_pb.JobTypeStats.avg_execution_time:type_name -> google.protobuf.Duration + 49, // 73: seaweed_pb.PluginList.plugins:type_name -> seaweed_pb.PluginInfo + 64, // 74: seaweed_pb.PluginInfo.connected_at:type_name -> google.protobuf.Timestamp + 64, // 75: seaweed_pb.PluginInfo.last_heartbeat:type_name -> google.protobuf.Timestamp + 11, // 76: seaweed_pb.PluginInfo.capabilities:type_name -> seaweed_pb.JobTypeCapability + 17, // 77: seaweed_pb.UpdateJobTypeConfigRequest.config:type_name -> seaweed_pb.JobTypeConfig + 16, // 78: seaweed_pb.CreateJobRequest.config:type_name -> seaweed_pb.ConfigFieldValue + 63, // 79: seaweed_pb.CreateJobRequest.metadata:type_name -> seaweed_pb.CreateJobRequest.MetadataEntry + 47, // 80: seaweed_pb.PluginStats.JobTypeStatsEntry.value:type_name -> seaweed_pb.JobTypeStats + 8, // 81: seaweed_pb.PluginService.Connect:input_type -> seaweed_pb.PluginMessage + 26, // 82: seaweed_pb.PluginService.ExecuteJob:input_type -> seaweed_pb.JobExecutionMessage + 66, // 83: seaweed_pb.AdminQueryService.GetPluginStats:input_type -> google.protobuf.Empty + 66, // 84: seaweed_pb.AdminQueryService.ListPlugins:input_type -> google.protobuf.Empty + 39, // 85: seaweed_pb.AdminQueryService.ListJobs:input_type -> seaweed_pb.ListJobsRequest + 40, // 86: seaweed_pb.AdminQueryService.GetJob:input_type -> seaweed_pb.GetJobRequest + 41, // 87: seaweed_pb.AdminQueryService.GetJobExecutionLog:input_type -> seaweed_pb.GetJobExecutionLogRequest + 50, // 88: seaweed_pb.AdminCommandService.UpdateJobTypeConfig:input_type -> seaweed_pb.UpdateJobTypeConfigRequest + 51, // 89: seaweed_pb.AdminCommandService.CreateJob:input_type -> seaweed_pb.CreateJobRequest + 52, // 90: seaweed_pb.AdminCommandService.CancelJob:input_type -> seaweed_pb.CancelJobRequest + 53, // 91: seaweed_pb.AdminCommandService.RetryJob:input_type -> seaweed_pb.RetryJobRequest + 9, // 92: seaweed_pb.PluginService.Connect:output_type -> seaweed_pb.AdminMessage + 33, // 93: seaweed_pb.PluginService.ExecuteJob:output_type -> seaweed_pb.JobProgressMessage + 46, // 94: seaweed_pb.AdminQueryService.GetPluginStats:output_type -> seaweed_pb.PluginStats + 48, // 95: seaweed_pb.AdminQueryService.ListPlugins:output_type -> seaweed_pb.PluginList + 45, // 96: seaweed_pb.AdminQueryService.ListJobs:output_type -> seaweed_pb.JobList + 43, // 97: seaweed_pb.AdminQueryService.GetJob:output_type -> seaweed_pb.JobDetail + 44, // 98: seaweed_pb.AdminQueryService.GetJobExecutionLog:output_type -> seaweed_pb.ExecutionLogEntry + 17, // 99: seaweed_pb.AdminCommandService.UpdateJobTypeConfig:output_type -> seaweed_pb.JobTypeConfig + 42, // 100: seaweed_pb.AdminCommandService.CreateJob:output_type -> seaweed_pb.Job + 66, // 101: seaweed_pb.AdminCommandService.CancelJob:output_type -> google.protobuf.Empty + 42, // 102: seaweed_pb.AdminCommandService.RetryJob:output_type -> seaweed_pb.Job + 92, // [92:103] is the sub-list for method output_type + 81, // [81:92] is the sub-list for method input_type + 81, // [81:81] is the sub-list for extension type_name + 81, // [81:81] is the sub-list for extension extendee + 0, // [0:81] is the sub-list for field type_name +} + +func init() { file_plugin_proto_init() } +func file_plugin_proto_init() { + if File_plugin_proto != nil { + return + } + file_plugin_proto_msgTypes[0].OneofWrappers = []any{ + (*PluginMessage_Register)(nil), + (*PluginMessage_Heartbeat)(nil), + (*PluginMessage_StatusUpdate)(nil), + } + file_plugin_proto_msgTypes[1].OneofWrappers = []any{ + (*AdminMessage_JobRequest)(nil), + (*AdminMessage_ConfigUpdate)(nil), + (*AdminMessage_AdminCommand)(nil), + } + file_plugin_proto_msgTypes[18].OneofWrappers = []any{ + (*JobExecutionMessage_JobStarted)(nil), + (*JobExecutionMessage_Progress)(nil), + (*JobExecutionMessage_Checkpoint)(nil), + (*JobExecutionMessage_JobCompleted)(nil), + (*JobExecutionMessage_JobFailed)(nil), + (*JobExecutionMessage_LogEntry)(nil), + } + file_plugin_proto_msgTypes[25].OneofWrappers = []any{ + (*JobProgressMessage_Update)(nil), + (*JobProgressMessage_Command)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_plugin_proto_rawDesc), len(file_plugin_proto_rawDesc)), + NumEnums: 8, + NumMessages: 56, + NumExtensions: 0, + NumServices: 3, + }, + GoTypes: file_plugin_proto_goTypes, + DependencyIndexes: file_plugin_proto_depIdxs, + EnumInfos: file_plugin_proto_enumTypes, + MessageInfos: file_plugin_proto_msgTypes, + }.Build() + File_plugin_proto = out.File + file_plugin_proto_goTypes = nil + file_plugin_proto_depIdxs = nil +} diff --git a/weed/pb/plugin_pb/plugin_grpc.pb.go b/weed/pb/plugin_pb/plugin_grpc.pb.go new file mode 100644 index 000000000..80c1399f1 --- /dev/null +++ b/weed/pb/plugin_pb/plugin_grpc.pb.go @@ -0,0 +1,658 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v6.33.4 +// source: plugin.proto + +package plugin_pb + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + PluginService_Connect_FullMethodName = "/seaweed_pb.PluginService/Connect" + PluginService_ExecuteJob_FullMethodName = "/seaweed_pb.PluginService/ExecuteJob" +) + +// PluginServiceClient is the client API for PluginService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// PluginService: Worker-to-Admin communication service +// Workers establish bidirectional streaming connections to register and execute jobs +type PluginServiceClient interface { + // Connect: Bidirectional stream for plugin registration, heartbeat, and lifecycle + Connect(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[PluginMessage, AdminMessage], error) + // ExecuteJob: Bidirectional stream for job execution with progress updates + ExecuteJob(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[JobExecutionMessage, JobProgressMessage], error) +} + +type pluginServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewPluginServiceClient(cc grpc.ClientConnInterface) PluginServiceClient { + return &pluginServiceClient{cc} +} + +func (c *pluginServiceClient) Connect(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[PluginMessage, AdminMessage], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &PluginService_ServiceDesc.Streams[0], PluginService_Connect_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[PluginMessage, AdminMessage]{ClientStream: stream} + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type PluginService_ConnectClient = grpc.BidiStreamingClient[PluginMessage, AdminMessage] + +func (c *pluginServiceClient) ExecuteJob(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[JobExecutionMessage, JobProgressMessage], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &PluginService_ServiceDesc.Streams[1], PluginService_ExecuteJob_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[JobExecutionMessage, JobProgressMessage]{ClientStream: stream} + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type PluginService_ExecuteJobClient = grpc.BidiStreamingClient[JobExecutionMessage, JobProgressMessage] + +// PluginServiceServer is the server API for PluginService service. +// All implementations must embed UnimplementedPluginServiceServer +// for forward compatibility. +// +// PluginService: Worker-to-Admin communication service +// Workers establish bidirectional streaming connections to register and execute jobs +type PluginServiceServer interface { + // Connect: Bidirectional stream for plugin registration, heartbeat, and lifecycle + Connect(grpc.BidiStreamingServer[PluginMessage, AdminMessage]) error + // ExecuteJob: Bidirectional stream for job execution with progress updates + ExecuteJob(grpc.BidiStreamingServer[JobExecutionMessage, JobProgressMessage]) error + mustEmbedUnimplementedPluginServiceServer() +} + +// UnimplementedPluginServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedPluginServiceServer struct{} + +func (UnimplementedPluginServiceServer) Connect(grpc.BidiStreamingServer[PluginMessage, AdminMessage]) error { + return status.Errorf(codes.Unimplemented, "method Connect not implemented") +} +func (UnimplementedPluginServiceServer) ExecuteJob(grpc.BidiStreamingServer[JobExecutionMessage, JobProgressMessage]) error { + return status.Errorf(codes.Unimplemented, "method ExecuteJob not implemented") +} +func (UnimplementedPluginServiceServer) mustEmbedUnimplementedPluginServiceServer() {} +func (UnimplementedPluginServiceServer) testEmbeddedByValue() {} + +// UnsafePluginServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PluginServiceServer will +// result in compilation errors. +type UnsafePluginServiceServer interface { + mustEmbedUnimplementedPluginServiceServer() +} + +func RegisterPluginServiceServer(s grpc.ServiceRegistrar, srv PluginServiceServer) { + // If the following call pancis, it indicates UnimplementedPluginServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&PluginService_ServiceDesc, srv) +} + +func _PluginService_Connect_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(PluginServiceServer).Connect(&grpc.GenericServerStream[PluginMessage, AdminMessage]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type PluginService_ConnectServer = grpc.BidiStreamingServer[PluginMessage, AdminMessage] + +func _PluginService_ExecuteJob_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(PluginServiceServer).ExecuteJob(&grpc.GenericServerStream[JobExecutionMessage, JobProgressMessage]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type PluginService_ExecuteJobServer = grpc.BidiStreamingServer[JobExecutionMessage, JobProgressMessage] + +// PluginService_ServiceDesc is the grpc.ServiceDesc for PluginService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var PluginService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "seaweed_pb.PluginService", + HandlerType: (*PluginServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Connect", + Handler: _PluginService_Connect_Handler, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "ExecuteJob", + Handler: _PluginService_ExecuteJob_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "plugin.proto", +} + +const ( + AdminQueryService_GetPluginStats_FullMethodName = "/seaweed_pb.AdminQueryService/GetPluginStats" + AdminQueryService_ListPlugins_FullMethodName = "/seaweed_pb.AdminQueryService/ListPlugins" + AdminQueryService_ListJobs_FullMethodName = "/seaweed_pb.AdminQueryService/ListJobs" + AdminQueryService_GetJob_FullMethodName = "/seaweed_pb.AdminQueryService/GetJob" + AdminQueryService_GetJobExecutionLog_FullMethodName = "/seaweed_pb.AdminQueryService/GetJobExecutionLog" +) + +// AdminQueryServiceClient is the client API for AdminQueryService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// AdminQueryService: Read-only queries for UI and monitoring +type AdminQueryServiceClient interface { + // GetPluginStats: Get current plugin system statistics + GetPluginStats(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*PluginStats, error) + // ListPlugins: List all connected plugins with their capabilities + ListPlugins(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*PluginList, error) + // ListJobs: List jobs by type and status + ListJobs(ctx context.Context, in *ListJobsRequest, opts ...grpc.CallOption) (*JobList, error) + // GetJob: Get detailed job information + GetJob(ctx context.Context, in *GetJobRequest, opts ...grpc.CallOption) (*JobDetail, error) + // GetJobExecutionLog: Stream job execution logs + GetJobExecutionLog(ctx context.Context, in *GetJobExecutionLogRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ExecutionLogEntry], error) +} + +type adminQueryServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAdminQueryServiceClient(cc grpc.ClientConnInterface) AdminQueryServiceClient { + return &adminQueryServiceClient{cc} +} + +func (c *adminQueryServiceClient) GetPluginStats(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*PluginStats, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(PluginStats) + err := c.cc.Invoke(ctx, AdminQueryService_GetPluginStats_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminQueryServiceClient) ListPlugins(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*PluginList, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(PluginList) + err := c.cc.Invoke(ctx, AdminQueryService_ListPlugins_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminQueryServiceClient) ListJobs(ctx context.Context, in *ListJobsRequest, opts ...grpc.CallOption) (*JobList, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(JobList) + err := c.cc.Invoke(ctx, AdminQueryService_ListJobs_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminQueryServiceClient) GetJob(ctx context.Context, in *GetJobRequest, opts ...grpc.CallOption) (*JobDetail, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(JobDetail) + err := c.cc.Invoke(ctx, AdminQueryService_GetJob_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminQueryServiceClient) GetJobExecutionLog(ctx context.Context, in *GetJobExecutionLogRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ExecutionLogEntry], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &AdminQueryService_ServiceDesc.Streams[0], AdminQueryService_GetJobExecutionLog_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[GetJobExecutionLogRequest, ExecutionLogEntry]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type AdminQueryService_GetJobExecutionLogClient = grpc.ServerStreamingClient[ExecutionLogEntry] + +// AdminQueryServiceServer is the server API for AdminQueryService service. +// All implementations must embed UnimplementedAdminQueryServiceServer +// for forward compatibility. +// +// AdminQueryService: Read-only queries for UI and monitoring +type AdminQueryServiceServer interface { + // GetPluginStats: Get current plugin system statistics + GetPluginStats(context.Context, *emptypb.Empty) (*PluginStats, error) + // ListPlugins: List all connected plugins with their capabilities + ListPlugins(context.Context, *emptypb.Empty) (*PluginList, error) + // ListJobs: List jobs by type and status + ListJobs(context.Context, *ListJobsRequest) (*JobList, error) + // GetJob: Get detailed job information + GetJob(context.Context, *GetJobRequest) (*JobDetail, error) + // GetJobExecutionLog: Stream job execution logs + GetJobExecutionLog(*GetJobExecutionLogRequest, grpc.ServerStreamingServer[ExecutionLogEntry]) error + mustEmbedUnimplementedAdminQueryServiceServer() +} + +// UnimplementedAdminQueryServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedAdminQueryServiceServer struct{} + +func (UnimplementedAdminQueryServiceServer) GetPluginStats(context.Context, *emptypb.Empty) (*PluginStats, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPluginStats not implemented") +} +func (UnimplementedAdminQueryServiceServer) ListPlugins(context.Context, *emptypb.Empty) (*PluginList, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListPlugins not implemented") +} +func (UnimplementedAdminQueryServiceServer) ListJobs(context.Context, *ListJobsRequest) (*JobList, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListJobs not implemented") +} +func (UnimplementedAdminQueryServiceServer) GetJob(context.Context, *GetJobRequest) (*JobDetail, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetJob not implemented") +} +func (UnimplementedAdminQueryServiceServer) GetJobExecutionLog(*GetJobExecutionLogRequest, grpc.ServerStreamingServer[ExecutionLogEntry]) error { + return status.Errorf(codes.Unimplemented, "method GetJobExecutionLog not implemented") +} +func (UnimplementedAdminQueryServiceServer) mustEmbedUnimplementedAdminQueryServiceServer() {} +func (UnimplementedAdminQueryServiceServer) testEmbeddedByValue() {} + +// UnsafeAdminQueryServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AdminQueryServiceServer will +// result in compilation errors. +type UnsafeAdminQueryServiceServer interface { + mustEmbedUnimplementedAdminQueryServiceServer() +} + +func RegisterAdminQueryServiceServer(s grpc.ServiceRegistrar, srv AdminQueryServiceServer) { + // If the following call pancis, it indicates UnimplementedAdminQueryServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&AdminQueryService_ServiceDesc, srv) +} + +func _AdminQueryService_GetPluginStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminQueryServiceServer).GetPluginStats(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminQueryService_GetPluginStats_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminQueryServiceServer).GetPluginStats(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _AdminQueryService_ListPlugins_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminQueryServiceServer).ListPlugins(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminQueryService_ListPlugins_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminQueryServiceServer).ListPlugins(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _AdminQueryService_ListJobs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListJobsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminQueryServiceServer).ListJobs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminQueryService_ListJobs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminQueryServiceServer).ListJobs(ctx, req.(*ListJobsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AdminQueryService_GetJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetJobRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminQueryServiceServer).GetJob(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminQueryService_GetJob_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminQueryServiceServer).GetJob(ctx, req.(*GetJobRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AdminQueryService_GetJobExecutionLog_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(GetJobExecutionLogRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(AdminQueryServiceServer).GetJobExecutionLog(m, &grpc.GenericServerStream[GetJobExecutionLogRequest, ExecutionLogEntry]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type AdminQueryService_GetJobExecutionLogServer = grpc.ServerStreamingServer[ExecutionLogEntry] + +// AdminQueryService_ServiceDesc is the grpc.ServiceDesc for AdminQueryService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AdminQueryService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "seaweed_pb.AdminQueryService", + HandlerType: (*AdminQueryServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetPluginStats", + Handler: _AdminQueryService_GetPluginStats_Handler, + }, + { + MethodName: "ListPlugins", + Handler: _AdminQueryService_ListPlugins_Handler, + }, + { + MethodName: "ListJobs", + Handler: _AdminQueryService_ListJobs_Handler, + }, + { + MethodName: "GetJob", + Handler: _AdminQueryService_GetJob_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "GetJobExecutionLog", + Handler: _AdminQueryService_GetJobExecutionLog_Handler, + ServerStreams: true, + }, + }, + Metadata: "plugin.proto", +} + +const ( + AdminCommandService_UpdateJobTypeConfig_FullMethodName = "/seaweed_pb.AdminCommandService/UpdateJobTypeConfig" + AdminCommandService_CreateJob_FullMethodName = "/seaweed_pb.AdminCommandService/CreateJob" + AdminCommandService_CancelJob_FullMethodName = "/seaweed_pb.AdminCommandService/CancelJob" + AdminCommandService_RetryJob_FullMethodName = "/seaweed_pb.AdminCommandService/RetryJob" +) + +// AdminCommandServiceClient is the client API for AdminCommandService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// AdminCommandService: Write operations for job management +type AdminCommandServiceClient interface { + // UpdateJobTypeConfig: Update configuration for a job type + UpdateJobTypeConfig(ctx context.Context, in *UpdateJobTypeConfigRequest, opts ...grpc.CallOption) (*JobTypeConfig, error) + // CreateJob: Manually create a job + CreateJob(ctx context.Context, in *CreateJobRequest, opts ...grpc.CallOption) (*Job, error) + // CancelJob: Cancel a running job + CancelJob(ctx context.Context, in *CancelJobRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // RetryJob: Retry a failed job + RetryJob(ctx context.Context, in *RetryJobRequest, opts ...grpc.CallOption) (*Job, error) +} + +type adminCommandServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAdminCommandServiceClient(cc grpc.ClientConnInterface) AdminCommandServiceClient { + return &adminCommandServiceClient{cc} +} + +func (c *adminCommandServiceClient) UpdateJobTypeConfig(ctx context.Context, in *UpdateJobTypeConfigRequest, opts ...grpc.CallOption) (*JobTypeConfig, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(JobTypeConfig) + err := c.cc.Invoke(ctx, AdminCommandService_UpdateJobTypeConfig_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminCommandServiceClient) CreateJob(ctx context.Context, in *CreateJobRequest, opts ...grpc.CallOption) (*Job, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Job) + err := c.cc.Invoke(ctx, AdminCommandService_CreateJob_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminCommandServiceClient) CancelJob(ctx context.Context, in *CancelJobRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, AdminCommandService_CancelJob_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminCommandServiceClient) RetryJob(ctx context.Context, in *RetryJobRequest, opts ...grpc.CallOption) (*Job, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Job) + err := c.cc.Invoke(ctx, AdminCommandService_RetryJob_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AdminCommandServiceServer is the server API for AdminCommandService service. +// All implementations must embed UnimplementedAdminCommandServiceServer +// for forward compatibility. +// +// AdminCommandService: Write operations for job management +type AdminCommandServiceServer interface { + // UpdateJobTypeConfig: Update configuration for a job type + UpdateJobTypeConfig(context.Context, *UpdateJobTypeConfigRequest) (*JobTypeConfig, error) + // CreateJob: Manually create a job + CreateJob(context.Context, *CreateJobRequest) (*Job, error) + // CancelJob: Cancel a running job + CancelJob(context.Context, *CancelJobRequest) (*emptypb.Empty, error) + // RetryJob: Retry a failed job + RetryJob(context.Context, *RetryJobRequest) (*Job, error) + mustEmbedUnimplementedAdminCommandServiceServer() +} + +// UnimplementedAdminCommandServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedAdminCommandServiceServer struct{} + +func (UnimplementedAdminCommandServiceServer) UpdateJobTypeConfig(context.Context, *UpdateJobTypeConfigRequest) (*JobTypeConfig, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateJobTypeConfig not implemented") +} +func (UnimplementedAdminCommandServiceServer) CreateJob(context.Context, *CreateJobRequest) (*Job, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateJob not implemented") +} +func (UnimplementedAdminCommandServiceServer) CancelJob(context.Context, *CancelJobRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method CancelJob not implemented") +} +func (UnimplementedAdminCommandServiceServer) RetryJob(context.Context, *RetryJobRequest) (*Job, error) { + return nil, status.Errorf(codes.Unimplemented, "method RetryJob not implemented") +} +func (UnimplementedAdminCommandServiceServer) mustEmbedUnimplementedAdminCommandServiceServer() {} +func (UnimplementedAdminCommandServiceServer) testEmbeddedByValue() {} + +// UnsafeAdminCommandServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AdminCommandServiceServer will +// result in compilation errors. +type UnsafeAdminCommandServiceServer interface { + mustEmbedUnimplementedAdminCommandServiceServer() +} + +func RegisterAdminCommandServiceServer(s grpc.ServiceRegistrar, srv AdminCommandServiceServer) { + // If the following call pancis, it indicates UnimplementedAdminCommandServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&AdminCommandService_ServiceDesc, srv) +} + +func _AdminCommandService_UpdateJobTypeConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateJobTypeConfigRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminCommandServiceServer).UpdateJobTypeConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminCommandService_UpdateJobTypeConfig_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminCommandServiceServer).UpdateJobTypeConfig(ctx, req.(*UpdateJobTypeConfigRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AdminCommandService_CreateJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateJobRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminCommandServiceServer).CreateJob(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminCommandService_CreateJob_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminCommandServiceServer).CreateJob(ctx, req.(*CreateJobRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AdminCommandService_CancelJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CancelJobRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminCommandServiceServer).CancelJob(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminCommandService_CancelJob_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminCommandServiceServer).CancelJob(ctx, req.(*CancelJobRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AdminCommandService_RetryJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetryJobRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminCommandServiceServer).RetryJob(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminCommandService_RetryJob_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminCommandServiceServer).RetryJob(ctx, req.(*RetryJobRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// AdminCommandService_ServiceDesc is the grpc.ServiceDesc for AdminCommandService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AdminCommandService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "seaweed_pb.AdminCommandService", + HandlerType: (*AdminCommandServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "UpdateJobTypeConfig", + Handler: _AdminCommandService_UpdateJobTypeConfig_Handler, + }, + { + MethodName: "CreateJob", + Handler: _AdminCommandService_CreateJob_Handler, + }, + { + MethodName: "CancelJob", + Handler: _AdminCommandService_CancelJob_Handler, + }, + { + MethodName: "RetryJob", + Handler: _AdminCommandService_RetryJob_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "plugin.proto", +}