@@ -18,6 +18,7 @@ package container
18
18
19
19
import (
20
20
"context"
21
+ "encoding/json"
21
22
"fmt"
22
23
"os"
23
24
"strings"
@@ -26,10 +27,15 @@ import (
26
27
"github.com/containerd/containerd"
27
28
"github.com/containerd/containerd/cio"
28
29
"github.com/containerd/containerd/errdefs"
30
+ gocni "github.com/containerd/go-cni"
29
31
"github.com/containerd/log"
30
32
"github.com/containerd/nerdctl/v2/pkg/api/types"
31
33
"github.com/containerd/nerdctl/v2/pkg/containerutil"
32
34
"github.com/containerd/nerdctl/v2/pkg/idutil/containerwalker"
35
+ "github.com/containerd/nerdctl/v2/pkg/labels"
36
+ "github.com/containerd/nerdctl/v2/pkg/netutil"
37
+ "github.com/containerd/nerdctl/v2/pkg/netutil/nettype"
38
+ "github.com/containerd/nerdctl/v2/pkg/portutil"
33
39
"github.com/moby/sys/signal"
34
40
)
35
41
@@ -50,6 +56,9 @@ func Kill(ctx context.Context, client *containerd.Client, reqs []string, options
50
56
if found .MatchCount > 1 {
51
57
return fmt .Errorf ("multiple IDs found with provided prefix: %s" , found .Req )
52
58
}
59
+ if err := cleanupNetwork (ctx , found .Container , options .GOptions ); err != nil {
60
+ return fmt .Errorf ("unable to cleanup network for container: %s, %q" , found .Req , err )
61
+ }
53
62
if err := killContainer (ctx , found .Container , parsedSignal ); err != nil {
54
63
if errdefs .IsNotFound (err ) {
55
64
fmt .Fprintf (options .Stderr , "No such container: %s\n " , found .Req )
@@ -106,3 +115,75 @@ func killContainer(ctx context.Context, container containerd.Container, signal s
106
115
}
107
116
return nil
108
117
}
118
+
119
+ // cleanupNetwork removes cni network setup, specifically the forwards
120
+ func cleanupNetwork (ctx context.Context , container containerd.Container , globalOpts types.GlobalCommandOptions ) error {
121
+ // retrieve info to get current active port mappings
122
+ info , err := container .Info (ctx , containerd .WithoutRefreshedMetadata )
123
+ if err != nil {
124
+ return err
125
+ }
126
+ ports , portErr := portutil .ParsePortsLabel (info .Labels )
127
+ if portErr != nil {
128
+ return fmt .Errorf ("no oci spec: %q" , portErr )
129
+ }
130
+ portMappings := []gocni.NamespaceOpts {
131
+ gocni .WithCapabilityPortMap (ports ),
132
+ }
133
+
134
+ // retrieve info to get cni instance
135
+ spec , err := container .Spec (ctx )
136
+ if err != nil {
137
+ return err
138
+ }
139
+ networksJSON := spec .Annotations [labels .Networks ]
140
+ var networks []string
141
+ if err := json .Unmarshal ([]byte (networksJSON ), & networks ); err != nil {
142
+ return err
143
+ }
144
+ netType , err := nettype .Detect (networks )
145
+ if err != nil {
146
+ return err
147
+ }
148
+
149
+ switch netType {
150
+ case nettype .Host , nettype .None , nettype .Container :
151
+ // NOP
152
+ case nettype .CNI :
153
+ e , err := netutil .NewCNIEnv (globalOpts .CNIPath , globalOpts .CNINetConfPath , netutil .WithDefaultNetwork ())
154
+ if err != nil {
155
+ return err
156
+ }
157
+ cniOpts := []gocni.Opt {
158
+ gocni .WithPluginDir ([]string {globalOpts .CNIPath }),
159
+ }
160
+ netMap , err := e .NetworkMap ()
161
+ if err != nil {
162
+ return err
163
+ }
164
+ for _ , netstr := range networks {
165
+ net , ok := netMap [netstr ]
166
+ if ! ok {
167
+ return fmt .Errorf ("no such network: %q" , netstr )
168
+ }
169
+ cniOpts = append (cniOpts , gocni .WithConfListBytes (net .Bytes ))
170
+ }
171
+ cni , err := gocni .New (cniOpts ... )
172
+ if err != nil {
173
+ return err
174
+ }
175
+
176
+ var namespaceOpts []gocni.NamespaceOpts
177
+ namespaceOpts = append (namespaceOpts , portMappings ... )
178
+ namespace := spec .Annotations [labels .Namespace ]
179
+ fullID := namespace + "-" + container .ID ()
180
+ if err := cni .Remove (ctx , fullID , "" , namespaceOpts ... ); err != nil {
181
+ log .L .WithError (err ).Errorf ("failed to call cni.Remove" )
182
+ return err
183
+ }
184
+ return nil
185
+ default :
186
+ return fmt .Errorf ("unexpected network type %v" , netType )
187
+ }
188
+ return nil
189
+ }
0 commit comments