Skip to content

Commit

Permalink
Merge pull request #33 from inteon/pass_context
Browse files Browse the repository at this point in the history
Pass context through cmd and use RunE instead of Run
  • Loading branch information
jetstack-bot authored Mar 7, 2024
2 parents d1669e5 + 1404ca1 commit 9ead175
Show file tree
Hide file tree
Showing 32 changed files with 159 additions and 182 deletions.
1 change: 1 addition & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func NewCertManagerCtlCommand(ctx context.Context, in io.Reader, out, err io.Wri
return logf.ValidateAndApply(logOptions)
},
SilenceErrors: true, // Errors are already logged when calling cmd.Execute()
SilenceUsage: true, // Don't print usage when an error occurs
}
cmds.SetUsageTemplate(usageTemplate())

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ require (
github.com/fatih/camelcase v1.0.0 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
Expand Down
36 changes: 0 additions & 36 deletions internal/util/context.go

This file was deleted.

22 changes: 12 additions & 10 deletions internal/util/signal.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package util

import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
Expand All @@ -40,35 +42,35 @@ const (
)

// SetupExitHandler:
// A stop channel is returned which is closed on receiving a shutdown signal (SIGTERM
// A context is returned which is canceled on receiving a shutdown signal (SIGTERM
// or SIGINT). If a second signal is caught, the program is terminated directly with
// exit code 130.
// SetupExitHandler also returns an exit function, this exit function calls os.Exit(...)
// if there is a exit code in the errorExitCodeChannel.
// The errorExitCodeChannel receives exit codes when SetExitCode is called or when
// a shutdown signal is received (only if exitBehavior is AlwaysErrCode).
func SetupExitHandler(exitBehavior ExitBehavior) (<-chan struct{}, func()) {
func SetupExitHandler(parentCtx context.Context, exitBehavior ExitBehavior) (context.Context, func()) {
close(onlyOneSignalHandler) // panics when called twice

stop := make(chan struct{})
ctx, cancel := context.WithCancelCause(parentCtx)
c := make(chan os.Signal, 2)
signal.Notify(c, shutdownSignals...)
go func() {
// first signal. Close stop chan and pass exit code to exitCodeChannel.
exitCode := 128 + int((<-c).(syscall.Signal))
// first signal. Cancel context and pass exit code to errorExitCodeChannel.
signalInt := int((<-c).(syscall.Signal))
if exitBehavior == AlwaysErrCode {
errorExitCodeChannel <- exitCode
errorExitCodeChannel <- signalInt
}
close(stop)
cancel(fmt.Errorf("received signal %d", signalInt))
// second signal. Exit directly.
<-c
os.Exit(130)
}()

return stop, func() {
return ctx, func() {
select {
case signal := <-errorExitCodeChannel:
os.Exit(signal)
case signalInt := <-errorExitCodeChannel:
os.Exit(128 + signalInt)
default:
// Do not exit, there are no exit codes in the channel,
// so just continue and let the main function go out of
Expand Down
8 changes: 5 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,21 @@ import (
"strings"

cmdutil "k8s.io/kubectl/pkg/cmd/util"
ctrl "sigs.k8s.io/controller-runtime"

logf "github.com/cert-manager/cert-manager/pkg/logs"
ctlcmd "github.com/cert-manager/cmctl/v2/cmd"
"github.com/cert-manager/cmctl/v2/internal/util"
)

func main() {
stopCh, exit := util.SetupExitHandler(util.AlwaysErrCode)
ctx, exit := util.SetupExitHandler(context.Background(), util.AlwaysErrCode)
defer exit() // This function might call os.Exit, so defer last

logf.InitLogs()
defer logf.FlushLogs()
ctrl.SetLogger(logf.Log)
ctx = logf.NewContext(ctx, logf.Log, "cmctl")

// In cmctl, we are using cmdutil.CheckErr, a kubectl utility function that creates human readable
// error messages from errors. By default, this function will call os.Exit(1) if it receives an error.
Expand All @@ -56,10 +59,9 @@ func main() {
runtime.Goexit() // Do soft exit (handle all defers, that should set correct exit code)
})

ctx := util.ContextWithStopCh(context.Background(), stopCh)
cmd := ctlcmd.NewCertManagerCtlCommand(ctx, os.Stdin, os.Stdout, os.Stderr)

if err := cmd.Execute(); err != nil {
if err := cmd.ExecuteContext(ctx); err != nil {
cmdutil.CheckErr(err)
}
}
15 changes: 8 additions & 7 deletions pkg/approve/approve.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"

Expand Down Expand Up @@ -68,18 +67,20 @@ func newOptions(ioStreams genericclioptions.IOStreams) *Options {
}
}

func NewCmdApprove(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
func NewCmdApprove(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := newOptions(ioStreams)

cmd := &cobra.Command{
Use: "approve",
Short: "Approve a CertificateRequest",
Long: `Mark a CertificateRequest as Approved, so it may be signed by a configured Issuer.`,
Example: example,
ValidArgsFunction: factory.ValidArgsListCertificateRequests(ctx, &o.Factory),
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Validate(args))
cmdutil.CheckErr(o.Run(ctx, args))
ValidArgsFunction: factory.ValidArgsListCertificateRequests(&o.Factory),
PreRunE: func(cmd *cobra.Command, args []string) error {
return o.Validate(args)
},
RunE: func(cmd *cobra.Command, args []string) error {
return o.Run(cmd.Context(), args)
},
}

Expand All @@ -88,7 +89,7 @@ func NewCmdApprove(ctx context.Context, ioStreams genericclioptions.IOStreams) *
cmd.Flags().StringVar(&o.Message, "message", fmt.Sprintf("manually approved by %q", build.Name()),
"The message to give as to why this CertificateRequest was approved.")

o.Factory = factory.New(ctx, cmd)
o.Factory = factory.New(cmd)

return cmd
}
Expand Down
13 changes: 7 additions & 6 deletions pkg/check/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/cli-runtime/pkg/genericclioptions"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"

Expand Down Expand Up @@ -83,22 +82,24 @@ func (o *Options) Complete() error {
}

// NewCmdCheckApi returns a cobra command for checking creating cert-manager resources against the K8S API server
func NewCmdCheckApi(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
func NewCmdCheckApi(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewOptions(ioStreams)

cmd := &cobra.Command{
Use: "api",
Short: "Check if the cert-manager API is ready",
Long: checkApiDesc,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete())
cmdutil.CheckErr(o.Run(ctx))
PreRunE: func(cmd *cobra.Command, args []string) error {
return o.Complete()
},
RunE: func(cmd *cobra.Command, args []string) error {
return o.Run(cmd.Context())
},
}
cmd.Flags().DurationVar(&o.Wait, "wait", 0, "Wait until the cert-manager API is ready (default 0s = poll once)")
cmd.Flags().DurationVar(&o.Interval, "interval", 5*time.Second, "Time between checks when waiting, must include unit, e.g. 1m or 10m")

o.Factory = factory.New(ctx, cmd)
o.Factory = factory.New(cmd)

return cmd
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/check/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ import (
)

// NewCmdCheck returns a cobra command for checking cert-manager components.
func NewCmdCheck(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
func NewCmdCheck(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
cmds := NewCmdCreateBare()
cmds.AddCommand(api.NewCmdCheckApi(ctx, ioStreams))
cmds.AddCommand(api.NewCmdCheckApi(setupCtx, ioStreams))

return cmds
}
Expand Down
5 changes: 2 additions & 3 deletions pkg/completion/bash.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package completion
import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/kubectl/pkg/cmd/util"

"github.com/cert-manager/cmctl/v2/pkg/build"
)
Expand All @@ -39,8 +38,8 @@ Bash:
$ {{.BuildName}} completion bash > /usr/local/etc/bash_completion.d/{{.BuildName}}
`),
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
util.CheckErr(cmd.Root().GenBashCompletion(ioStreams.Out))
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Root().GenBashCompletion(ioStreams.Out)
},
}
}
2 changes: 1 addition & 1 deletion pkg/completion/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions"
)

func NewCmdCompletion(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
func NewCmdCompletion(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
cmds := &cobra.Command{
Use: "completion",
Short: "Generate completion scripts for the cert-manager CLI",
Expand Down
5 changes: 2 additions & 3 deletions pkg/completion/fish.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package completion
import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/kubectl/pkg/cmd/util"

"github.com/cert-manager/cmctl/v2/pkg/build"
)
Expand All @@ -35,8 +34,8 @@ func newCmdCompletionFish(ioStreams genericclioptions.IOStreams) *cobra.Command
$ {{.BuildName}} completion fish > ~/.config/fish/completions/{{.BuildName}}.fish
`),
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
util.CheckErr(cmd.Root().GenFishCompletion(ioStreams.Out, true))
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Root().GenFishCompletion(ioStreams.Out, true)
},
}
}
5 changes: 2 additions & 3 deletions pkg/completion/powershell.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package completion
import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/kubectl/pkg/cmd/util"

"github.com/cert-manager/cmctl/v2/pkg/build"
)
Expand All @@ -36,8 +35,8 @@ func newCmdCompletionPowerShell(ioStreams genericclioptions.IOStreams) *cobra.Co
# and source this file from your PowerShell profile.
`),
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
util.CheckErr(cmd.Root().GenPowerShellCompletion(ioStreams.Out))
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Root().GenPowerShellCompletion(ioStreams.Out)
},
}
}
5 changes: 2 additions & 3 deletions pkg/completion/zsh.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package completion
import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/kubectl/pkg/cmd/util"

"github.com/cert-manager/cmctl/v2/pkg/build"
)
Expand All @@ -38,8 +37,8 @@ func newCmdCompletionZSH(ioStreams genericclioptions.IOStreams) *cobra.Command {
# You will need to start a new shell for this setup to take effect.
`),
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
util.CheckErr(cmd.Root().GenZshCompletion(ioStreams.Out))
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Root().GenZshCompletion(ioStreams.Out)
},
}
}
10 changes: 6 additions & 4 deletions pkg/convert/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func NewOptions(ioStreams genericclioptions.IOStreams) *Options {
}

// NewCmdConvert returns a cobra command for converting cert-manager resources
func NewCmdConvert(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
func NewCmdConvert(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewOptions(ioStreams)

cmd := &cobra.Command{
Expand All @@ -94,9 +94,11 @@ func NewCmdConvert(ctx context.Context, ioStreams genericclioptions.IOStreams) *
Long: longDesc,
Example: example,
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete())
cmdutil.CheckErr(o.Run())
PreRunE: func(cmd *cobra.Command, args []string) error {
return o.Complete()
},
RunE: func(cmd *cobra.Command, args []string) error {
return o.Run()
},
}

Expand Down
15 changes: 8 additions & 7 deletions pkg/create/certificaterequest/certificaterequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"

Expand Down Expand Up @@ -103,7 +102,7 @@ func NewOptions(ioStreams genericclioptions.IOStreams) *Options {
}

// NewCmdCreateCR returns a cobra command for create CertificateRequest
func NewCmdCreateCR(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
func NewCmdCreateCR(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewOptions(ioStreams)

cmd := &cobra.Command{
Expand All @@ -112,10 +111,12 @@ func NewCmdCreateCR(ctx context.Context, ioStreams genericclioptions.IOStreams)
Short: "Create a cert-manager CertificateRequest resource, using a Certificate resource as a template",
Long: long,
Example: example,
ValidArgsFunction: factory.ValidArgsListCertificateRequests(ctx, &o.Factory),
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Validate(args))
cmdutil.CheckErr(o.Run(ctx, args))
ValidArgsFunction: factory.ValidArgsListCertificateRequests(&o.Factory),
PreRunE: func(cmd *cobra.Command, args []string) error {
return o.Validate(args)
},
RunE: func(cmd *cobra.Command, args []string) error {
return o.Run(cmd.Context(), args)
},
}
cmd.Flags().StringVar(&o.InputFilename, "from-certificate-file", o.InputFilename,
Expand All @@ -129,7 +130,7 @@ func NewCmdCreateCR(ctx context.Context, ioStreams genericclioptions.IOStreams)
cmd.Flags().DurationVar(&o.Timeout, "timeout", 5*time.Minute,
"Time before timeout when waiting for CertificateRequest to be signed, must include unit, e.g. 10m or 1h")

o.Factory = factory.New(ctx, cmd)
o.Factory = factory.New(cmd)

return cmd
}
Expand Down
Loading

0 comments on commit 9ead175

Please sign in to comment.