Skip to content

Commit 9ead175

Browse files
authored
Merge pull request #33 from inteon/pass_context
Pass context through cmd and use RunE instead of Run
2 parents d1669e5 + 1404ca1 commit 9ead175

File tree

32 files changed

+159
-182
lines changed

32 files changed

+159
-182
lines changed

cmd/cmd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ func NewCertManagerCtlCommand(ctx context.Context, in io.Reader, out, err io.Wri
4747
return logf.ValidateAndApply(logOptions)
4848
},
4949
SilenceErrors: true, // Errors are already logged when calling cmd.Execute()
50+
SilenceUsage: true, // Don't print usage when an error occurs
5051
}
5152
cmds.SetUsageTemplate(usageTemplate())
5253

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ require (
6565
github.com/fatih/camelcase v1.0.0 // indirect
6666
github.com/fatih/color v1.15.0 // indirect
6767
github.com/felixge/httpsnoop v1.0.4 // indirect
68+
github.com/fsnotify/fsnotify v1.7.0 // indirect
6869
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
6970
github.com/go-errors/errors v1.4.2 // indirect
7071
github.com/go-gorp/gorp/v3 v3.1.0 // indirect

internal/util/context.go

Lines changed: 0 additions & 36 deletions
This file was deleted.

internal/util/signal.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package util
1818

1919
import (
20+
"context"
21+
"fmt"
2022
"os"
2123
"os/signal"
2224
"syscall"
@@ -40,35 +42,35 @@ const (
4042
)
4143

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

53-
stop := make(chan struct{})
55+
ctx, cancel := context.WithCancelCause(parentCtx)
5456
c := make(chan os.Signal, 2)
5557
signal.Notify(c, shutdownSignals...)
5658
go func() {
57-
// first signal. Close stop chan and pass exit code to exitCodeChannel.
58-
exitCode := 128 + int((<-c).(syscall.Signal))
59+
// first signal. Cancel context and pass exit code to errorExitCodeChannel.
60+
signalInt := int((<-c).(syscall.Signal))
5961
if exitBehavior == AlwaysErrCode {
60-
errorExitCodeChannel <- exitCode
62+
errorExitCodeChannel <- signalInt
6163
}
62-
close(stop)
64+
cancel(fmt.Errorf("received signal %d", signalInt))
6365
// second signal. Exit directly.
6466
<-c
6567
os.Exit(130)
6668
}()
6769

68-
return stop, func() {
70+
return ctx, func() {
6971
select {
70-
case signal := <-errorExitCodeChannel:
71-
os.Exit(signal)
72+
case signalInt := <-errorExitCodeChannel:
73+
os.Exit(128 + signalInt)
7274
default:
7375
// Do not exit, there are no exit codes in the channel,
7476
// so just continue and let the main function go out of

main.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,21 @@ import (
2424
"strings"
2525

2626
cmdutil "k8s.io/kubectl/pkg/cmd/util"
27+
ctrl "sigs.k8s.io/controller-runtime"
2728

2829
logf "github.com/cert-manager/cert-manager/pkg/logs"
2930
ctlcmd "github.com/cert-manager/cmctl/v2/cmd"
3031
"github.com/cert-manager/cmctl/v2/internal/util"
3132
)
3233

3334
func main() {
34-
stopCh, exit := util.SetupExitHandler(util.AlwaysErrCode)
35+
ctx, exit := util.SetupExitHandler(context.Background(), util.AlwaysErrCode)
3536
defer exit() // This function might call os.Exit, so defer last
3637

3738
logf.InitLogs()
3839
defer logf.FlushLogs()
40+
ctrl.SetLogger(logf.Log)
41+
ctx = logf.NewContext(ctx, logf.Log, "cmctl")
3942

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

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

62-
if err := cmd.Execute(); err != nil {
64+
if err := cmd.ExecuteContext(ctx); err != nil {
6365
cmdutil.CheckErr(err)
6466
}
6567
}

pkg/approve/approve.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"github.com/spf13/cobra"
2525
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2626
"k8s.io/cli-runtime/pkg/genericclioptions"
27-
cmdutil "k8s.io/kubectl/pkg/cmd/util"
2827
"k8s.io/kubectl/pkg/util/i18n"
2928
"k8s.io/kubectl/pkg/util/templates"
3029

@@ -68,18 +67,20 @@ func newOptions(ioStreams genericclioptions.IOStreams) *Options {
6867
}
6968
}
7069

71-
func NewCmdApprove(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
70+
func NewCmdApprove(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
7271
o := newOptions(ioStreams)
7372

7473
cmd := &cobra.Command{
7574
Use: "approve",
7675
Short: "Approve a CertificateRequest",
7776
Long: `Mark a CertificateRequest as Approved, so it may be signed by a configured Issuer.`,
7877
Example: example,
79-
ValidArgsFunction: factory.ValidArgsListCertificateRequests(ctx, &o.Factory),
80-
Run: func(cmd *cobra.Command, args []string) {
81-
cmdutil.CheckErr(o.Validate(args))
82-
cmdutil.CheckErr(o.Run(ctx, args))
78+
ValidArgsFunction: factory.ValidArgsListCertificateRequests(&o.Factory),
79+
PreRunE: func(cmd *cobra.Command, args []string) error {
80+
return o.Validate(args)
81+
},
82+
RunE: func(cmd *cobra.Command, args []string) error {
83+
return o.Run(cmd.Context(), args)
8384
},
8485
}
8586

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

91-
o.Factory = factory.New(ctx, cmd)
92+
o.Factory = factory.New(cmd)
9293

9394
return cmd
9495
}

pkg/check/api/api.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"k8s.io/apimachinery/pkg/runtime"
2727
"k8s.io/apimachinery/pkg/util/wait"
2828
"k8s.io/cli-runtime/pkg/genericclioptions"
29-
cmdutil "k8s.io/kubectl/pkg/cmd/util"
3029
"k8s.io/kubectl/pkg/util/i18n"
3130
"k8s.io/kubectl/pkg/util/templates"
3231

@@ -83,22 +82,24 @@ func (o *Options) Complete() error {
8382
}
8483

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

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

101-
o.Factory = factory.New(ctx, cmd)
102+
o.Factory = factory.New(cmd)
102103

103104
return cmd
104105
}

pkg/check/check.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ import (
2626
)
2727

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

3333
return cmds
3434
}

pkg/completion/bash.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package completion
1919
import (
2020
"github.com/spf13/cobra"
2121
"k8s.io/cli-runtime/pkg/genericclioptions"
22-
"k8s.io/kubectl/pkg/cmd/util"
2322

2423
"github.com/cert-manager/cmctl/v2/pkg/build"
2524
)
@@ -39,8 +38,8 @@ Bash:
3938
$ {{.BuildName}} completion bash > /usr/local/etc/bash_completion.d/{{.BuildName}}
4039
`),
4140
DisableFlagsInUseLine: true,
42-
Run: func(cmd *cobra.Command, args []string) {
43-
util.CheckErr(cmd.Root().GenBashCompletion(ioStreams.Out))
41+
RunE: func(cmd *cobra.Command, args []string) error {
42+
return cmd.Root().GenBashCompletion(ioStreams.Out)
4443
},
4544
}
4645
}

pkg/completion/completion.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
"k8s.io/cli-runtime/pkg/genericclioptions"
2424
)
2525

26-
func NewCmdCompletion(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
26+
func NewCmdCompletion(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
2727
cmds := &cobra.Command{
2828
Use: "completion",
2929
Short: "Generate completion scripts for the cert-manager CLI",

0 commit comments

Comments
 (0)