Path: blob/main/components/ws-daemon/pkg/controller/workspace_provider.go
2500 views
// Copyright (c) 2023 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 controller56import (7"context"8"fmt"9"path/filepath"10"sync"1112"github.com/gitpod-io/gitpod/common-go/log"13"github.com/gitpod-io/gitpod/common-go/tracing"14"github.com/opentracing/opentracing-go"1516"github.com/gitpod-io/gitpod/ws-daemon/pkg/internal/session"17)1819type WorkspaceFactory func(ctx context.Context, instanceID string) (ws *session.Workspace, err error)2021type WorkspaceProvider struct {22Location string23hooks map[session.WorkspaceState][]session.WorkspaceLivecycleHook24workspaces sync.Map25}2627func NewWorkspaceProvider(location string, hooks map[session.WorkspaceState][]session.WorkspaceLivecycleHook) *WorkspaceProvider {28return &WorkspaceProvider{29Location: location,30hooks: hooks,31}32}3334func (wf *WorkspaceProvider) NewWorkspace(ctx context.Context, instanceID, location string, create WorkspaceFactory) (ws *session.Workspace, err error) {35span, ctx := opentracing.StartSpanFromContext(ctx, "WorkspaceProvider.NewWorkspace")36tracing.ApplyOWI(span, log.OWI("", "", instanceID))37defer tracing.FinishSpan(span, &err)3839ws, err = create(ctx, location)40if err != nil {41return nil, err42}4344if ws.NonPersistentAttrs == nil {45ws.NonPersistentAttrs = make(map[string]interface{})46}4748err = wf.runLifecycleHooks(ctx, ws, session.WorkspaceInitializing)49if err != nil {50return nil, err51}5253wf.workspaces.Store(instanceID, ws)5455return ws, nil56}5758func (wf *WorkspaceProvider) Remove(ctx context.Context, instanceID string) {59span, _ := opentracing.StartSpanFromContext(ctx, "WorkspaceProvider.Remove")60tracing.ApplyOWI(span, log.OWI("", "", instanceID))61defer tracing.FinishSpan(span, nil)6263wf.workspaces.Delete(instanceID)64}6566func (wf *WorkspaceProvider) GetAndConnect(ctx context.Context, instanceID string) (*session.Workspace, error) {67ws, ok := wf.workspaces.Load(instanceID)68if !ok {69// if the workspace is not in memory ws-daemon probabably has been restarted70// in that case we reload it from disk71path := filepath.Join(wf.Location, fmt.Sprintf("%s.workspace.json", instanceID))72loadWs, err := session.LoadWorkspace(ctx, path)73if err != nil {74return nil, err75}7677ws = loadWs78}7980err := wf.runLifecycleHooks(ctx, ws.(*session.Workspace), session.WorkspaceReady)81if err != nil {82return nil, err83}84wf.workspaces.Store(instanceID, ws)8586return ws.(*session.Workspace), nil87}8889func (s *WorkspaceProvider) runLifecycleHooks(ctx context.Context, ws *session.Workspace, state session.WorkspaceState) error {90hooks := s.hooks[state]9192for _, h := range hooks {93err := h(ctx, ws)94if err != nil {95return err96}97}98return nil99}100101102