github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/client/cli/cmd/leave.go (about) 1 package cmd 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 8 "github.com/spf13/cobra" 9 "google.golang.org/grpc/codes" 10 "google.golang.org/grpc/status" 11 12 "github.com/datawire/dlib/dlog" 13 "github.com/telepresenceio/telepresence/rpc/v2/connector" 14 "github.com/telepresenceio/telepresence/rpc/v2/manager" 15 "github.com/telepresenceio/telepresence/v2/pkg/client/cli/ann" 16 "github.com/telepresenceio/telepresence/v2/pkg/client/cli/connect" 17 "github.com/telepresenceio/telepresence/v2/pkg/client/cli/daemon" 18 "github.com/telepresenceio/telepresence/v2/pkg/client/cli/intercept" 19 "github.com/telepresenceio/telepresence/v2/pkg/client/docker" 20 "github.com/telepresenceio/telepresence/v2/pkg/errcat" 21 ) 22 23 func leave() *cobra.Command { 24 return &cobra.Command{ 25 Use: "leave [flags] <intercept_name>", 26 Args: cobra.ExactArgs(1), 27 28 Short: "Remove existing intercept", 29 Annotations: map[string]string{ 30 ann.Session: ann.Required, 31 }, 32 RunE: func(cmd *cobra.Command, args []string) error { 33 if err := connect.InitCommand(cmd); err != nil { 34 return err 35 } 36 return removeIntercept(cmd.Context(), strings.TrimSpace(args[0])) 37 }, 38 ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { 39 shellCompDir := cobra.ShellCompDirectiveNoFileComp 40 if len(args) != 0 { 41 return nil, shellCompDir 42 } 43 if err := connect.InitCommand(cmd); err != nil { 44 return nil, shellCompDir | cobra.ShellCompDirectiveError 45 } 46 ctx := cmd.Context() 47 userD := daemon.GetUserClient(ctx) 48 resp, err := userD.List(ctx, &connector.ListRequest{Filter: connector.ListRequest_INTERCEPTS}) 49 if err != nil { 50 return nil, shellCompDir | cobra.ShellCompDirectiveError 51 } 52 if len(resp.Workloads) == 0 { 53 return nil, shellCompDir 54 } 55 56 var completions []string 57 for _, intercept := range resp.Workloads { 58 for _, ii := range intercept.InterceptInfos { 59 name := ii.Spec.Name 60 if strings.HasPrefix(name, toComplete) { 61 completions = append(completions, name) 62 } 63 } 64 } 65 return completions, shellCompDir 66 }, 67 } 68 } 69 70 func removeIntercept(ctx context.Context, name string) error { 71 userD := daemon.GetUserClient(ctx) 72 ic, err := userD.GetIntercept(ctx, &manager.GetInterceptRequest{Name: name}) 73 if err != nil { 74 if st, ok := status.FromError(err); ok && st.Code() == codes.NotFound { 75 // User probably misspelled the name of the intercept 76 return errcat.User.Newf("Intercept named %q not found", name) 77 } 78 return err 79 } 80 handlerContainer, stopContainer := ic.Environment["TELEPRESENCE_HANDLER_CONTAINER_NAME"] 81 if stopContainer { 82 // Stop the intercept handler's container. The daemon is most likely running in another 83 // container, and won't be able to. 84 err = docker.StopContainer(docker.EnableClient(ctx), handlerContainer) 85 if err != nil { 86 dlog.Error(ctx, err) 87 } 88 } 89 if err := intercept.Result(userD.RemoveIntercept(ctx, &manager.RemoveInterceptRequest2{Name: name})); err != nil { 90 if stopContainer && strings.Contains(err.Error(), fmt.Sprintf("%q not found", name)) { 91 // race condition between stopping the intercept handler, which causes the intercept to leave, and this call 92 err = nil 93 } 94 } 95 return err 96 }