Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add New ExecOutput Function To Support Custom Writers #1331

Merged
merged 11 commits into from
May 4, 2022
Merged

Conversation

ihcsim
Copy link
Contributor

@ihcsim ihcsim commented Mar 25, 2022

Change Overview

This PR introduces a new kube.ExecOutput() library function that can write kube.Exec() outputs to custom writers, allowing callers to provide either buffered writers or async (pipe) writers. This new function delegates the writes operation to a new format.Writer instance that formats the outputs to match the Kanister-style logs, before writing them to the custom writers.

The KubeExec Kanister function has been updated to use kube.ExecOutput(), with os.Stdout and os.Stderr. Other callers in the pkg/app and pkg/function packages remain untouched. By offering both kube.Exec() and kube.ExecAsync(), downstream has the flexibility to decide which output mechanism to use, based on their use cases.

Pull request type

Please check the type of change your PR introduces:

  • 🚧 Work in Progress
  • 🌈 Refactoring (no functional changes, no api changes)
  • 🐹 Trivial/Minor
  • 🐛 Bugfix
  • 🌻 Feature
  • 🗺️ Documentation
  • 🤖 Test

Issues

Follow-up of:

Test Plan

Deploy this timer pod that has a script to tail the current datetime at one second interval:

cat <<EOF | k apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: timer
spec:
  containers:
  - name: timer
    image: ubuntu
    command:
    - /bin/sh
    - "-c"
    - |
      cat <<EOF > /bin/tail_datetime.sh
      for i in \\\$(seq 0 20)
      do
        date +"%m-%d-%Y %H:%M:%S"
        sleep 1s
      done
      EOF

      chmod +x /bin/tail_datetime.sh
      sleep 7200s
EOF

Deploy this blueprint that uses KubeExec to invoke the remote script in the timer pod:

cat <<EOF | k apply -f -
apiVersion: cr.kanister.io/v1alpha1
kind: Blueprint
metadata:
  name: timer
  namespace: kanister
actions:
  tail:
    phases:
    - func: KubeExec
      name: tail
      args:
        namespace: default
        pod: timer
        container: timer
        command:
        - sh
        - "-c"
        - /bin/tail_datetime.sh
EOF

Creates the actionset to trigger the function call:

cat <<EOF | k create -f -
apiVersion: cr.kanister.io/v1alpha1
kind: ActionSet
metadata:
  generateName: timer-
  namespace: kanister
spec:
  actions:
  - name: tail
    blueprint: timer
    object:
      kind: Namespace
      name: default
EOF

Observe the datetime being streamed to the Kanister operator's logs:

$ k -n kanister logs -f kanister-kanister-operator-5964486449-xqv66
#...

{"Container":"timer","File":"pkg/log/log.go","Function":"github.com/kanisterio/kanister/pkg/log.PrintTo","Line":174,"Out":"03-25-2022 05:52:49","Pod":"timer","cluster_name":"8224a31e-876b-4ef2-98c2-ae9cbc5e96b0","hostname":"kanister-kanister-operator-5964486449-xqv66","level":"info","msg":"action update","time":"2022-03-25T05:52:49.060833604Z"}
{"Container":"timer","File":"pkg/log/log.go","Function":"github.com/kanisterio/kanister/pkg/log.PrintTo","Line":174,"Out":"03-25-2022 05:52:50","Pod":"timer","cluster_name":"8224a31e-876b-4ef2-98c2-ae9cbc5e96b0","hostname":"kanister-kanister-operator-5964486449-xqv66","level":"info","msg":"action update","time":"2022-03-25T05:52:50.063202873Z"}
{"ActionSet":"timer-2pkxw","File":"pkg/controller/controller.go","Function":"github.com/kanisterio/kanister/pkg/controller.(*Controller).logAndSuccessEvent","Line":510,"Phase":"tail","cluster_name":"8224a31e-876b-4ef2-98c2-ae9cbc5e96b0","hostname":"kanister-kanister-operator-5964486449-xqv66","level":"info","msg":"Completed phase tail","time":"2022-03-25T05:52:51.077562462Z"}
{"File":"pkg/controller/controller.go","Function":"github.com/kanisterio/kanister/pkg/controller.(*Controller).logAndSuccessEvent","Line":510,"cluster_name":"8224a31e-876b-4ef2-98c2-ae9cbc5e96b0","hostname":"kanister-kanister-operator-5964486449-xqv66","level":"info","msg":"Updated ActionSet 'timer-2pkxw' Status-\u003ecomplete","time":"2022-03-25T05:52:51.081930515Z"}
  • 💪 Manual
  • ⚡ Unit test
  • 💚 E2E

@ihcsim ihcsim changed the title Add New ExecAsync Function To Stream Remote Outputs Add New ExecAsync Function To Stream Inbound Outputs Mar 25, 2022
@shuguet shuguet added this to To do in Kanister via automation Mar 25, 2022
@shuguet shuguet moved this from To do to Review in progress in Kanister Mar 25, 2022
@ihcsim ihcsim force-pushed the exec-async branch 2 times, most recently from f4ac288 to 40e802b Compare March 30, 2022 20:58
@ihcsim ihcsim changed the title Add New ExecAsync Function To Stream Inbound Outputs Add New ExecOutput Function To Stream Inbound Outputs Apr 11, 2022
@ihcsim ihcsim changed the title Add New ExecOutput Function To Stream Inbound Outputs Add New ExecOutput Function To Support Custom Writers Apr 11, 2022
pkg/function/kube_exec.go Show resolved Hide resolved
pkg/kube/exec.go Outdated Show resolved Hide resolved
@ihcsim ihcsim force-pushed the exec-async branch 2 times, most recently from 17c673f to 481a08a Compare May 3, 2022 01:45
tdmanv and others added 10 commits May 2, 2022 18:47
Signed-off-by: Prasad Ghangal <prasad.ghangal@gmail.com>
Signed-off-by: Prasad Ghangal <prasad.ghangal@gmail.com>
Signed-off-by: Prasad Ghangal <prasad.ghangal@gmail.com>
This new library function works like kube.Exec(), except that it writes
the inbound outputs to stdout and stderr immediately. It delegates the
writes to a new format.Writer instance, which formats the outputs to match
the Kanister-style logs, before writing them to either stdout or stderr.

This ensures that the outputs of the remote exec operation is available
to log consumers immediately.

Signed-off-by: Ivan Sim <ivan.sim@kasten.io>
Signed-off-by: Ivan Sim <ivan.sim@kasten.io>
Signed-off-by: Ivan Sim <ivan.sim@kasten.io>
Signed-off-by: Ivan Sim <ivan.sim@kasten.io>
Signed-off-by: Ivan Sim <ivan.sim@kasten.io>
Copy link
Contributor

@pavannd1 pavannd1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Kanister automation moved this from Review Required to Reviewer approved May 3, 2022
@ihcsim ihcsim added the kueue label May 4, 2022
@mergify mergify bot merged commit f3801e7 into master May 4, 2022
Kanister automation moved this from Reviewer approved to Done May 4, 2022
@mergify mergify bot deleted the exec-async branch May 4, 2022 00:50
akankshakumari393 pushed a commit that referenced this pull request May 9, 2022
* Stream output from KubeExec

* Set error in pipe readers instead of a channel

* Fix compile errors

Signed-off-by: Prasad Ghangal <prasad.ghangal@gmail.com>

* Handle returned error by exec stream

Signed-off-by: Prasad Ghangal <prasad.ghangal@gmail.com>

* Don't add error while closing pipe

Signed-off-by: Prasad Ghangal <prasad.ghangal@gmail.com>

* Add a new kube.ExecAsync() function to handle async 'exec' outputs

This new library function works like kube.Exec(), except that it writes
the inbound outputs to stdout and stderr immediately. It delegates the
writes to a new format.Writer instance, which formats the outputs to match
the Kanister-style logs, before writing them to either stdout or stderr.

This ensures that the outputs of the remote exec operation is available
to log consumers immediately.

Signed-off-by: Ivan Sim <ivan.sim@kasten.io>

* Remove merge error

Signed-off-by: Ivan Sim <ivan.sim@kasten.io>

* Fix unit test

Signed-off-by: Ivan Sim <ivan.sim@kasten.io>

* Add stdout and stderr as function params

Signed-off-by: Ivan Sim <ivan.sim@kasten.io>

* Handle phase outputs found in stdout

Signed-off-by: Ivan Sim <ivan.sim@kasten.io>

Co-authored-by: Tom Manville <tom@kasten.io>
Co-authored-by: Prasad Ghangal <prasad.ghangal@gmail.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Development

Successfully merging this pull request may close these issues.

None yet

4 participants