Path: blob/main/components/ee/agent-smith/pkg/agent/actions.go
2501 views
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package agent56import (7"context"89wsk8s "github.com/gitpod-io/gitpod/common-go/kubernetes"10"github.com/gitpod-io/gitpod/common-go/log"11protocol "github.com/gitpod-io/gitpod/gitpod-protocol"12wsmanapi "github.com/gitpod-io/gitpod/ws-manager/api"1314"golang.org/x/sys/unix"15"golang.org/x/xerrors"16corev1 "k8s.io/apimachinery/pkg/apis/meta/v1"17"k8s.io/client-go/util/retry"18)1920// all functions in this file deal directly with Kubernetes and make several assumptions21// how workspace pods look like. This code should eventually be moved to ws-manager or22// call one of ws-manager's libraries.2324// stopWorkspace stops a workspace25func (agent *Smith) stopWorkspace(supervisorPID int, instanceID string) error {26req := &wsmanapi.StopWorkspaceRequest{27Id: instanceID,28// Stop workspace without grace period.29Policy: wsmanapi.StopWorkspacePolicy_IMMEDIATELY,30}31_, err := agent.wsman.StopWorkspace(context.Background(), req)32if err == nil {33return nil34}3536log.WithError(err).WithField("instanceID", instanceID).Warn("error stopping workspace through ws-manager, killing supervisor directly")37return unix.Kill(supervisorPID, unix.SIGKILL)38}3940// stopWorkspaceAndBlockUser stops a workspace and blocks the user (who would have guessed?)41func (agent *Smith) stopWorkspaceAndBlockUser(supervisorPID int, ownerID, workspaceID, instanceID string) error {42err := agent.stopWorkspace(supervisorPID, instanceID)43if err != nil {44log.WithError(err).WithField("owner", ownerID).WithField("workspaceID", workspaceID).Warn("error stopping workspace")45}46err = agent.blockUser(ownerID, workspaceID)47return err48}4950func (agent *Smith) blockUser(ownerID, workspaceID string) error {51if agent.GitpodAPI == nil {52return xerrors.Errorf("not connected to Gitpod API")53}5455if len(ownerID) == 0 {56return xerrors.Errorf("cannot block user as user id is empty")57}5859log.Infof("Blocking user %s - workspace %v", ownerID, workspaceID)6061req := protocol.AdminBlockUserRequest{62UserID: ownerID,63IsBlocked: true,64}65return agent.GitpodAPI.AdminBlockUser(context.Background(), &req)66}6768func (agent *Smith) limitCPUUse(podname string) error {69if agent.Kubernetes == nil {70return xerrors.Errorf("not connected to Kubernetes - cannot limit CPU usage")71}72if agent.Config.Enforcement.CPULimitPenalty == "" {73return xerrors.Errorf("no CPU limit penalty specified - cannot limit CPU usage")74}7576ctx := context.Background()77retry.RetryOnConflict(retry.DefaultBackoff, func() error {78pods := agent.Kubernetes.CoreV1().Pods(agent.Config.KubernetesNamespace)79pod, err := pods.Get(ctx, podname, corev1.GetOptions{})80if err != nil {81return err82}8384pod.Annotations[wsk8s.WorkspaceCpuMinLimitAnnotation] = agent.Config.Enforcement.CPULimitPenalty85pod.Annotations[wsk8s.WorkspaceCpuBurstLimitAnnotation] = agent.Config.Enforcement.CPULimitPenalty86_, err = pods.Update(ctx, pod, corev1.UpdateOptions{})87if err != nil {88return err89}9091return nil92})9394return nil95}969798