Skip to content

Commit 50a59f0

Browse files
k8s-ci-robotsaschagrunert
authored andcommitted
Merge pull request kubernetes-sigs#1462 from saschagrunert/interruptable-image
Make image RPCs interruptable using Ctrl-C Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
2 parents 52a3c8b + c6918de commit 50a59f0

File tree

10 files changed

+1869
-847
lines changed

10 files changed

+1869
-847
lines changed

cmd/crictl/container.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,7 @@ func CreateContainer(
767767

768768
// Try to pull the image before container creation
769769
ann := config.GetImage().GetAnnotations()
770-
if _, err := PullImageWithSandbox(iClient, image, auth, podConfig, ann, opts.pullOptions.timeout); err != nil {
770+
if _, err := PullImageWithSandbox(iClient, image, auth, podConfig, ann, opts.pullOptions.timeout, false, ""); err != nil {
771771
return "", err
772772
}
773773
}

cmd/crictl/image.go

+37-12
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ var pullImageCommand = &cli.Command{
9090
Usage: "Maximum time to be used for pulling the image, disabled if set to 0s",
9191
EnvVars: []string{"CRICTL_PULL_TIMEOUT"},
9292
},
93+
&cli.BoolFlag{
94+
Name: "mount",
95+
Aliases: []string{"m"},
96+
Usage: "Mount the OCI object",
97+
},
98+
&cli.StringFlag{
99+
Name: "mount-label",
100+
Aliases: []string{"l"},
101+
Usage: "Mount label for the OCI object",
102+
},
93103
},
94104
ArgsUsage: "NAME[:TAG|@DIGEST]",
95105
Action: func(c *cli.Context) error {
@@ -127,11 +137,15 @@ var pullImageCommand = &cli.Command{
127137
}
128138
}
129139
timeout := c.Duration("pull-timeout")
130-
r, err := PullImageWithSandbox(imageClient, imageName, auth, sandbox, ann, timeout)
140+
r, err := PullImageWithSandbox(imageClient, imageName, auth, sandbox, ann, timeout, c.Bool("mount"), c.String("mount-label"))
131141
if err != nil {
132142
return fmt.Errorf("pulling image: %w", err)
133143
}
134144
fmt.Printf("Image is up to date for %s\n", r.ImageRef)
145+
146+
if r.Mountpoint != "" {
147+
fmt.Printf("Image mounted to: %s\n", r.Mountpoint)
148+
}
135149
return nil
136150
},
137151
}
@@ -417,7 +431,9 @@ var removeImageCommand = &cli.Command{
417431
}
418432

419433
// Container images
420-
containers, err := runtimeClient.ListContainers(context.TODO(), nil)
434+
containers, err := InterruptableRPC(nil, func(ctx context.Context) ([]*pb.Container, error) {
435+
return runtimeClient.ListContainers(ctx, nil)
436+
})
421437
if err != nil {
422438
return err
423439
}
@@ -641,11 +657,13 @@ func normalizeRepoDigest(repoDigests []string) (string, string) {
641657

642658
// PullImageWithSandbox sends a PullImageRequest to the server, and parses
643659
// the returned PullImageResponse.
644-
func PullImageWithSandbox(client internalapi.ImageManagerService, image string, auth *pb.AuthConfig, sandbox *pb.PodSandboxConfig, ann map[string]string, timeout time.Duration) (*pb.PullImageResponse, error) {
660+
func PullImageWithSandbox(client internalapi.ImageManagerService, image string, auth *pb.AuthConfig, sandbox *pb.PodSandboxConfig, ann map[string]string, timeout time.Duration, mount bool, mountLabel string) (*pb.PullImageResponse, error) {
645661
request := &pb.PullImageRequest{
646662
Image: &pb.ImageSpec{
647663
Image: image,
648664
Annotations: ann,
665+
Mount: mount,
666+
MountLabel: mountLabel,
649667
},
650668
}
651669
if auth != nil {
@@ -669,11 +687,12 @@ func PullImageWithSandbox(client internalapi.ImageManagerService, image string,
669687
defer cancel()
670688
}
671689

672-
res, err := client.PullImage(ctx, request.Image, request.Auth, request.SandboxConfig)
690+
resp, err := InterruptableRPC(ctx, func(ctx context.Context) (*pb.PullImageResponse, error) {
691+
return client.PullImageFullResponse(ctx, request.Image, request.Auth, request.SandboxConfig)
692+
})
673693
if err != nil {
674694
return nil, err
675695
}
676-
resp := &pb.PullImageResponse{ImageRef: res}
677696
logrus.Debugf("PullImageResponse: %v", resp)
678697
return resp, nil
679698
}
@@ -683,7 +702,9 @@ func PullImageWithSandbox(client internalapi.ImageManagerService, image string,
683702
func ListImages(client internalapi.ImageManagerService, image string) (*pb.ListImagesResponse, error) {
684703
request := &pb.ListImagesRequest{Filter: &pb.ImageFilter{Image: &pb.ImageSpec{Image: image}}}
685704
logrus.Debugf("ListImagesRequest: %v", request)
686-
res, err := client.ListImages(context.TODO(), request.Filter)
705+
res, err := InterruptableRPC(nil, func(ctx context.Context) ([]*pb.Image, error) {
706+
return client.ListImages(ctx, request.Filter)
707+
})
687708
if err != nil {
688709
return nil, err
689710
}
@@ -790,7 +811,9 @@ func ImageStatus(client internalapi.ImageManagerService, image string, verbose b
790811
Verbose: verbose,
791812
}
792813
logrus.Debugf("ImageStatusRequest: %v", request)
793-
res, err := client.ImageStatus(context.TODO(), request.Image, request.Verbose)
814+
res, err := InterruptableRPC(nil, func(ctx context.Context) (*pb.ImageStatusResponse, error) {
815+
return client.ImageStatus(ctx, request.Image, request.Verbose)
816+
})
794817
if err != nil {
795818
return nil, err
796819
}
@@ -806,16 +829,18 @@ func RemoveImage(client internalapi.ImageManagerService, image string) error {
806829
}
807830
request := &pb.RemoveImageRequest{Image: &pb.ImageSpec{Image: image}}
808831
logrus.Debugf("RemoveImageRequest: %v", request)
809-
if err := client.RemoveImage(context.TODO(), request.Image); err != nil {
810-
return err
811-
}
812-
return nil
832+
_, err := InterruptableRPC(nil, func(ctx context.Context) (*pb.RemoveImageResponse, error) {
833+
return nil, client.RemoveImage(ctx, request.Image)
834+
})
835+
return err
813836
}
814837

815838
// ImageFsInfo sends an ImageStatusRequest to the server, and parses
816839
// the returned ImageFsInfoResponse.
817840
func ImageFsInfo(client internalapi.ImageManagerService) (*pb.ImageFsInfoResponse, error) {
818-
res, err := client.ImageFsInfo(context.TODO())
841+
res, err := InterruptableRPC(nil, func(ctx context.Context) (*pb.ImageFsInfoResponse, error) {
842+
return client.ImageFsInfo(ctx)
843+
})
819844
if err != nil {
820845
return nil, err
821846
}

cmd/crictl/util.go

+33
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,39 @@ func SetupInterruptSignalHandler() <-chan struct{} {
7070
return signalIntStopCh
7171
}
7272

73+
func InterruptableRPC[T any](
74+
ctx context.Context,
75+
rpcFunc func(context.Context) (T, error),
76+
) (res T, err error) {
77+
if ctx == nil {
78+
ctx = context.Background()
79+
}
80+
ctx, cancel := context.WithCancel(ctx)
81+
defer cancel()
82+
83+
resCh := make(chan T, 1)
84+
errCh := make(chan error, 1)
85+
86+
go func() {
87+
res, err := rpcFunc(ctx)
88+
if err != nil {
89+
errCh <- err
90+
return
91+
}
92+
resCh <- res
93+
}()
94+
95+
select {
96+
case <-SetupInterruptSignalHandler():
97+
cancel()
98+
return res, fmt.Errorf("interrupted: %w", ctx.Err())
99+
case err := <-errCh:
100+
return res, err
101+
case res := <-resCh:
102+
return res, nil
103+
}
104+
}
105+
73106
type listOptions struct {
74107
// id of container or sandbox
75108
id string

go.mod

+6
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ require (
3939
sigs.k8s.io/yaml v1.4.0
4040
)
4141

42+
// TODO: Remove when https://github.com/kubernetes/kubernetes/pull/125659 got merged
43+
replace (
44+
k8s.io/cri-api => github.com/saschagrunert/cri-api v0.0.0-20240624095310-d6041dfe89cd
45+
k8s.io/cri-client => github.com/saschagrunert/cri-client v0.0.0-20240624095412-86c24439265a
46+
)
47+
4248
require (
4349
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
4450
github.com/Microsoft/go-winio v0.6.0 // indirect

go.sum

+4-4
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU
129129
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
130130
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
131131
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
132+
github.com/saschagrunert/cri-api v0.0.0-20240624095310-d6041dfe89cd h1:HMo29GzHbjRmwfc2RhNBa9IAE/zQ2un30Yb8gD+Wmig=
133+
github.com/saschagrunert/cri-api v0.0.0-20240624095310-d6041dfe89cd/go.mod h1:8SzLKTnltnWXG9FMIL4SHWcAnnPGssi5viN/SMMMf4k=
134+
github.com/saschagrunert/cri-client v0.0.0-20240624095412-86c24439265a h1:OnkqJk/OOEn0CUSdshM/jcZza/EqAGJl7ggsmg+KTb8=
135+
github.com/saschagrunert/cri-client v0.0.0-20240624095412-86c24439265a/go.mod h1:jKU9x1FP/k4ktv2mZOA37kJmLjoggWsbJOU9FsOV5RM=
132136
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
133137
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
134138
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
@@ -238,10 +242,6 @@ k8s.io/client-go v0.30.2 h1:sBIVJdojUNPDU/jObC+18tXWcTJVcwyqS9diGdWHk50=
238242
k8s.io/client-go v0.30.2/go.mod h1:JglKSWULm9xlJLx4KCkfLLQ7XwtlbflV6uFFSHTMgVs=
239243
k8s.io/component-base v0.30.2 h1:pqGBczYoW1sno8q9ObExUqrYSKhtE5rW3y6gX88GZII=
240244
k8s.io/component-base v0.30.2/go.mod h1:yQLkQDrkK8J6NtP+MGJOws+/PPeEXNpwFixsUI7h/OE=
241-
k8s.io/cri-api v0.31.0-alpha.0.0.20240528091733-69e407966029 h1:P+TWC7iOMWA2mWiNTLgeCr9z0TKwp22PMHkfF0woFQI=
242-
k8s.io/cri-api v0.31.0-alpha.0.0.20240528091733-69e407966029/go.mod h1:bUzKm5FAhhVPHj344pvpKRIdGJMJ79mBHGrubR3TqZY=
243-
k8s.io/cri-client v0.31.0-alpha.0.0.20240530211015-c9749ee02fc0 h1:A/qaNv8usB/HEZeWRcFe117POP0Sheqc9xnuYrBxYu8=
244-
k8s.io/cri-client v0.31.0-alpha.0.0.20240530211015-c9749ee02fc0/go.mod h1:TarJVY/GTbu+Ht1IqT6eh5QXXxKwMfb2+7TpY/XlAhs=
245245
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
246246
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
247247
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=

0 commit comments

Comments
 (0)