Path: blob/main/components/local-app/cmd/workspace-stop.go
2497 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 cmd56import (7"context"8"log/slog"9"time"1011"github.com/bufbuild/connect-go"12v1 "github.com/gitpod-io/gitpod/components/public-api/go/experimental/v1"13"github.com/gitpod-io/local-app/pkg/prettyprint"14"github.com/spf13/cobra"15)1617var stopDontWait = false1819// workspaceStopCommand stops to a given workspace20var workspaceStopCommand = &cobra.Command{21Use: "stop <workspace-id>",22Short: "Stop a given workspace",23Args: cobra.ExactArgs(1),24RunE: func(cmd *cobra.Command, args []string) error {25cmd.SilenceUsage = true26workspaceID := args[0]2728ctx, cancel := context.WithTimeout(cmd.Context(), 5*time.Minute)29defer cancel()3031gitpod, err := getGitpodClient(ctx)32if err != nil {33return err34}3536slog.Debug("stopping workspace...")37wsInfo, err := gitpod.Workspaces.StopWorkspace(ctx, connect.NewRequest(&v1.StopWorkspaceRequest{WorkspaceId: workspaceID}))38if err != nil {39return err40}4142wsPhase := wsInfo.Msg.GetResult().Status.Instance.Status.Phase43switch wsPhase {44case v1.WorkspaceInstanceStatus_PHASE_STOPPED:45slog.Info("workspace is already stopped")46return nil47case v1.WorkspaceInstanceStatus_PHASE_STOPPING:48slog.Info("workspace is already stopping")49return nil50}5152if stopDontWait {53slog.Info("workspace stopping")54return nil55}5657stream, err := gitpod.Workspaces.StreamWorkspaceStatus(ctx, connect.NewRequest(&v1.StreamWorkspaceStatusRequest{WorkspaceId: workspaceID}))58if err != nil {59return err60}6162// See EXP-90963// defer stream.Close()6465slog.Info("waiting for workspace to stop...")6667previousStatus := ""68for stream.Receive() {69msg := stream.Msg()70if msg == nil {71slog.Debug("no message received")72continue73}7475wsPhase = msg.GetResult().Instance.Status.Phase76switch wsPhase {77case v1.WorkspaceInstanceStatus_PHASE_STOPPED:78{79slog.Info("workspace stopped")80return nil81}82case v1.WorkspaceInstanceStatus_PHASE_RUNNING:83// Skip reporting the "running" status as it is often the initial state and seems confusing to the user.84// There is some delay between requesting a workspace to stop and it actually stopping, so we don't want85// to report "running" in the meantime.86break87default:88{89currentStatus := prettyprint.FormatWorkspacePhase(wsPhase)90if currentStatus != previousStatus {91slog.Info("workspace status: " + currentStatus)92previousStatus = currentStatus93}94}95}96}9798if err := stream.Err(); err != nil {99return err100}101102return nil103},104}105106func init() {107workspaceCmd.AddCommand(workspaceStopCommand)108workspaceStopCommand.Flags().BoolVarP(&stopDontWait, "dont-wait", "d", false, "do not wait for workspace to fully stop, only initialize")109}110111112