package runner import ( "context" "errors" "fmt" "github.com/openHPI/poseidon/pkg/dto" "github.com/openHPI/poseidon/pkg/logging" "k8s.io/client-go/kubernetes" "time" ) var ( log = logging.GetLogger("runner") ErrUnknownExecutionEnvironment = errors.New("execution environment not found") ErrNoRunnersAvailable = errors.New("no runners available for this execution environment") ErrRunnerNotFound = errors.New("no runner found with this id") ) type KubernetesRunnerManager struct { *AbstractManager clientSet *kubernetes.Clientset } // NewKubernetesRunnerManager creates a new runner manager that keeps track of all runners in Kubernetes. func NewKubernetesRunnerManager(ctx context.Context, clientSet *kubernetes.Clientset) *KubernetesRunnerManager { return &KubernetesRunnerManager{ AbstractManager: NewAbstractManager(ctx), clientSet: clientSet, } } func (k *KubernetesRunnerManager) Claim(id dto.EnvironmentID, duration int) (Runner, error) { environment, ok := k.GetEnvironment(id) if !ok { r, err := k.NextHandler().Claim(id, duration) if err != nil { return nil, fmt.Errorf("kubernetes wrapped: %w", err) } return r, nil } runner, ok := environment.Sample() if !ok { log.Warn("no kubernetes runner available") return nil, ErrNoRunnersAvailable } k.usedRunners.Add(runner.ID(), runner) runner.SetupTimeout(time.Duration(duration) * time.Second) // Here you might want to add Kubernetes-specific logic // For example, updating the pod status or adding labels return runner, nil } func (k *KubernetesRunnerManager) Return(r Runner) error { _, isKubernetesRunner := r.(*KubernetesPodWorkload) if isKubernetesRunner { k.usedRunners.Delete(r.ID()) // Here you might want to add Kubernetes-specific logic // For example, cleaning up the pod or updating its status } else if err := k.NextHandler().Return(r); err != nil { return fmt.Errorf("kubernetes wrapped: %w", err) } return nil }