Skip to content

Commit 8516ef8

Browse files
authored
Merge pull request #1462 from saschagrunert/interruptable-image
Make image RPCs interruptable using Ctrl-C
2 parents 52a3c8b + c6918de commit 8516ef8

File tree

2 files changed

+52
-9
lines changed

2 files changed

+52
-9
lines changed

cmd/crictl/image.go

+19-9
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,9 @@ var removeImageCommand = &cli.Command{
417417
}
418418

419419
// Container images
420-
containers, err := runtimeClient.ListContainers(context.TODO(), nil)
420+
containers, err := InterruptableRPC(nil, func(ctx context.Context) ([]*pb.Container, error) {
421+
return runtimeClient.ListContainers(ctx, nil)
422+
})
421423
if err != nil {
422424
return err
423425
}
@@ -669,7 +671,9 @@ func PullImageWithSandbox(client internalapi.ImageManagerService, image string,
669671
defer cancel()
670672
}
671673

672-
res, err := client.PullImage(ctx, request.Image, request.Auth, request.SandboxConfig)
674+
res, err := InterruptableRPC(ctx, func(ctx context.Context) (string, error) {
675+
return client.PullImage(ctx, request.Image, request.Auth, request.SandboxConfig)
676+
})
673677
if err != nil {
674678
return nil, err
675679
}
@@ -683,7 +687,9 @@ func PullImageWithSandbox(client internalapi.ImageManagerService, image string,
683687
func ListImages(client internalapi.ImageManagerService, image string) (*pb.ListImagesResponse, error) {
684688
request := &pb.ListImagesRequest{Filter: &pb.ImageFilter{Image: &pb.ImageSpec{Image: image}}}
685689
logrus.Debugf("ListImagesRequest: %v", request)
686-
res, err := client.ListImages(context.TODO(), request.Filter)
690+
res, err := InterruptableRPC(nil, func(ctx context.Context) ([]*pb.Image, error) {
691+
return client.ListImages(ctx, request.Filter)
692+
})
687693
if err != nil {
688694
return nil, err
689695
}
@@ -790,7 +796,9 @@ func ImageStatus(client internalapi.ImageManagerService, image string, verbose b
790796
Verbose: verbose,
791797
}
792798
logrus.Debugf("ImageStatusRequest: %v", request)
793-
res, err := client.ImageStatus(context.TODO(), request.Image, request.Verbose)
799+
res, err := InterruptableRPC(nil, func(ctx context.Context) (*pb.ImageStatusResponse, error) {
800+
return client.ImageStatus(ctx, request.Image, request.Verbose)
801+
})
794802
if err != nil {
795803
return nil, err
796804
}
@@ -806,16 +814,18 @@ func RemoveImage(client internalapi.ImageManagerService, image string) error {
806814
}
807815
request := &pb.RemoveImageRequest{Image: &pb.ImageSpec{Image: image}}
808816
logrus.Debugf("RemoveImageRequest: %v", request)
809-
if err := client.RemoveImage(context.TODO(), request.Image); err != nil {
810-
return err
811-
}
812-
return nil
817+
_, err := InterruptableRPC(nil, func(ctx context.Context) (*pb.RemoveImageResponse, error) {
818+
return nil, client.RemoveImage(ctx, request.Image)
819+
})
820+
return err
813821
}
814822

815823
// ImageFsInfo sends an ImageStatusRequest to the server, and parses
816824
// the returned ImageFsInfoResponse.
817825
func ImageFsInfo(client internalapi.ImageManagerService) (*pb.ImageFsInfoResponse, error) {
818-
res, err := client.ImageFsInfo(context.TODO())
826+
res, err := InterruptableRPC(nil, func(ctx context.Context) (*pb.ImageFsInfoResponse, error) {
827+
return client.ImageFsInfo(ctx)
828+
})
819829
if err != nil {
820830
return nil, err
821831
}

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

0 commit comments

Comments
 (0)