github.com/jenkins-x/jx/v2@v2.1.155/pkg/cmd/logs.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 6 "github.com/jenkins-x/jx/v2/pkg/cmd/helper" 7 8 "github.com/jenkins-x/jx/v2/pkg/cmd/opts" 9 "github.com/jenkins-x/jx/v2/pkg/cmd/templates" 10 "github.com/jenkins-x/jx/v2/pkg/kube" 11 "github.com/jenkins-x/jx/v2/pkg/util" 12 "github.com/spf13/cobra" 13 14 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 15 ) 16 17 type LogsOptions struct { 18 *opts.CommonOptions 19 20 Container string 21 Namespace string 22 Environment string 23 Filter string 24 Label string 25 EditEnvironment bool 26 } 27 28 var ( 29 logs_long = templates.LongDesc(` 30 Tails the logs of the newest pod for a Deployment. 31 32 `) 33 34 logs_example = templates.Examples(` 35 # Tails the log of the latest pod in deployment myapp 36 jx logs myapp 37 38 # Tails the log of the container foo in the latest pod in deployment myapp 39 jx logs myapp -c foo 40 `) 41 ) 42 43 func NewCmdLogs(commonOpts *opts.CommonOptions) *cobra.Command { 44 options := &LogsOptions{ 45 CommonOptions: commonOpts, 46 } 47 cmd := &cobra.Command{ 48 Use: "logs [deployment]", 49 Short: "Tails the log of the latest pod for a deployment", 50 Long: logs_long, 51 Example: logs_example, 52 Aliases: []string{"log"}, 53 Run: func(cmd *cobra.Command, args []string) { 54 options.Cmd = cmd 55 options.Args = args 56 err := options.Run() 57 helper.CheckErr(err) 58 }, 59 } 60 cmd.Flags().StringVarP(&options.Container, "container", "c", "", "The name of the container to log") 61 cmd.Flags().StringVarP(&options.Namespace, "namespace", "n", "", "the namespace to look for the Deployment. Defaults to the current namespace") 62 cmd.Flags().StringVarP(&options.Environment, "env", "e", "", "the Environment to look for the Deployment. Defaults to the current environment") 63 cmd.Flags().StringVarP(&options.Filter, "filter", "f", "", "Filters the available deployments if no deployment argument is provided") 64 cmd.Flags().StringVarP(&options.Label, "label", "l", "", "The label to filter the pods if no deployment argument is provided") 65 cmd.Flags().BoolVarP(&options.EditEnvironment, "edit", "d", false, "Use my Edit Environment to look for the Deployment pods") 66 return cmd 67 } 68 69 func (o *LogsOptions) Run() error { 70 args := o.Args 71 72 client, curNs, err := o.KubeClientAndNamespace() 73 if err != nil { 74 return err 75 } 76 jxClient, devNs, err := o.JXClientAndDevNamespace() 77 if err != nil { 78 return err 79 } 80 81 ns := o.Namespace 82 if ns == "" { 83 env := o.Environment 84 if env != "" { 85 ns, err = kube.GetEnvironmentNamespace(jxClient, devNs, env) 86 if err != nil { 87 return err 88 } 89 } 90 if ns == "" && o.EditEnvironment { 91 ns, err = kube.GetEditEnvironmentNamespace(jxClient, devNs) 92 if err != nil { 93 return err 94 } 95 } 96 } 97 if ns == "" { 98 ns = curNs 99 } 100 names, err := kube.GetDeploymentNames(client, ns, o.Filter) 101 if err != nil { 102 return fmt.Errorf("Could not find deployments in namespace %s with filter %s: %s", ns, o.Filter, err) 103 } 104 if len(names) == 0 { 105 if o.Filter == "" { 106 return fmt.Errorf("There are no Deployments") 107 } else { 108 return fmt.Errorf("There are no Deployments matching filter: " + o.Filter) 109 } 110 } 111 name := "" 112 if len(args) == 0 { 113 if o.Label == "" { 114 n, err := util.PickName(names, "Pick Deployment:", "", o.GetIOFileHandles()) 115 if err != nil { 116 return err 117 } 118 name = n 119 } 120 } else { 121 name = args[0] 122 if util.StringArrayIndex(names, name) < 0 { 123 return util.InvalidArg(name, names) 124 } 125 } 126 127 for { 128 pod := "" 129 if o.Label != "" { 130 selector, err := parseSelector(o.Label) 131 if err != nil { 132 return err 133 } 134 pod, err = o.WaitForReadyPodForSelectorLabels(client, ns, selector, false) 135 if err != nil { 136 return err 137 } 138 if pod == "" { 139 return fmt.Errorf("No pod found for namespace %s with selector %s", ns, o.Label) 140 } 141 } else { 142 pod, err = o.WaitForReadyPodForDeployment(client, ns, name, names, false) 143 if err != nil { 144 return err 145 } 146 if pod == "" { 147 return fmt.Errorf("No pod found for namespace %s with name %s", ns, name) 148 } 149 } 150 err = o.TailLogs(ns, pod, o.Container) 151 if err != nil { 152 return nil 153 } 154 } 155 } 156 157 func parseSelector(selectorText string) (map[string]string, error) { 158 selector, err := metav1.ParseToLabelSelector(selectorText) 159 if err != nil { 160 return nil, err 161 } 162 return selector.MatchLabels, nil 163 }