|
|
@@ -554,7 +554,7 @@ func (a *Agent) DeletePod(namespace string, name string) error {
|
|
|
}
|
|
|
|
|
|
// GetPodLogs streams real-time logs from a given pod.
|
|
|
-func (a *Agent) GetPodLogs(namespace string, name string, showPreviousLogs bool, selectedContainer string, rw *websocket.WebsocketSafeReadWriter) error {
|
|
|
+func (a *Agent) GetPodLogs(namespace string, name string, selectedContainer string, rw *websocket.WebsocketSafeReadWriter) error {
|
|
|
// get the pod to read in the list of contains
|
|
|
pod, err := a.Clientset.CoreV1().Pods(namespace).Get(
|
|
|
context.Background(),
|
|
|
@@ -593,7 +593,6 @@ func (a *Agent) GetPodLogs(namespace string, name string, showPreviousLogs bool,
|
|
|
Follow: true,
|
|
|
TailLines: &tails,
|
|
|
Container: container,
|
|
|
- Previous: showPreviousLogs,
|
|
|
}
|
|
|
|
|
|
req := a.Clientset.CoreV1().Pods(namespace).GetLogs(name, &podLogOpts)
|
|
|
@@ -656,6 +655,79 @@ func (a *Agent) GetPodLogs(namespace string, name string, showPreviousLogs bool,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// GetPodLogs streams real-time logs from a given pod.
|
|
|
+func (a *Agent) GetPreviousPodLogs(namespace string, name string, selectedContainer string) (string, error) {
|
|
|
+ // get the pod to read in the list of contains
|
|
|
+ pod, err := a.Clientset.CoreV1().Pods(namespace).Get(
|
|
|
+ context.Background(),
|
|
|
+ name,
|
|
|
+ metav1.GetOptions{},
|
|
|
+ )
|
|
|
+
|
|
|
+ if err != nil && errors.IsNotFound(err) {
|
|
|
+ return "", IsNotFoundError
|
|
|
+ } else if err != nil {
|
|
|
+ return "", fmt.Errorf("Cannot get logs from pod %s: %s", name, err.Error())
|
|
|
+ }
|
|
|
+
|
|
|
+ // see if container is ready and able to open a stream. If not, wait for container
|
|
|
+ // to be ready.
|
|
|
+ err, _ = a.waitForPod(pod)
|
|
|
+
|
|
|
+ if err != nil && goerrors.Is(err, IsNotFoundError) {
|
|
|
+ return "", IsNotFoundError
|
|
|
+ } else if err != nil {
|
|
|
+ return "", fmt.Errorf("Cannot get logs from pod %s: %s", name, err.Error())
|
|
|
+ }
|
|
|
+
|
|
|
+ container := pod.Spec.Containers[0].Name
|
|
|
+
|
|
|
+ if len(selectedContainer) > 0 {
|
|
|
+ container = selectedContainer
|
|
|
+ }
|
|
|
+
|
|
|
+ tails := int64(400)
|
|
|
+
|
|
|
+ // follow logs
|
|
|
+ podLogOpts := v1.PodLogOptions{
|
|
|
+ Follow: true,
|
|
|
+ TailLines: &tails,
|
|
|
+ Container: container,
|
|
|
+ Previous: true,
|
|
|
+ }
|
|
|
+
|
|
|
+ req := a.Clientset.CoreV1().Pods(namespace).GetLogs(name, &podLogOpts)
|
|
|
+
|
|
|
+ podLogs, err := req.Stream(context.TODO())
|
|
|
+
|
|
|
+ // in the case of bad request errors, such as if the pod is stuck in "ContainerCreating",
|
|
|
+ // we'd like to pass this through to the client.
|
|
|
+ if err != nil && errors.IsBadRequest(err) {
|
|
|
+ return "", &BadRequestError{err.Error()}
|
|
|
+ } else if err != nil {
|
|
|
+ return "", fmt.Errorf("Cannot open log stream for pod %s: %s", name, err.Error())
|
|
|
+ }
|
|
|
+
|
|
|
+ defer podLogs.Close()
|
|
|
+
|
|
|
+ r := bufio.NewReader(podLogs)
|
|
|
+ logs := ""
|
|
|
+
|
|
|
+ for {
|
|
|
+ line, err := r.ReadString('\n')
|
|
|
+ logs += line + "\n"
|
|
|
+
|
|
|
+ if err == io.EOF {
|
|
|
+ break
|
|
|
+ } else if err != nil {
|
|
|
+
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return logs, nil
|
|
|
+}
|
|
|
+
|
|
|
// StopJobWithJobSidecar sends a termination signal to a job running with a sidecar
|
|
|
func (a *Agent) StopJobWithJobSidecar(namespace, name string) error {
|
|
|
jobPods, err := a.GetJobPods(namespace, name)
|