@@ -46,6 +46,7 @@ import (
46
46
"github.com/containerd/nerdctl/v2/pkg/cmd/image"
47
47
"github.com/containerd/nerdctl/v2/pkg/cmd/volume"
48
48
"github.com/containerd/nerdctl/v2/pkg/containerutil"
49
+ "github.com/containerd/nerdctl/v2/pkg/dnsutil/hostsstore"
49
50
"github.com/containerd/nerdctl/v2/pkg/flagutil"
50
51
"github.com/containerd/nerdctl/v2/pkg/idgen"
51
52
"github.com/containerd/nerdctl/v2/pkg/imgutil"
@@ -118,7 +119,7 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa
118
119
119
120
platformOpts , err := setPlatformOptions (ctx , client , id , netManager .NetworkOptions ().UTSNamespace , & internalLabels , options )
120
121
if err != nil {
121
- return nil , nil , err
122
+ return nil , generateRemoveStateDirFunc ( ctx , id , internalLabels ) , err
122
123
}
123
124
opts = append (opts , platformOpts ... )
124
125
@@ -130,7 +131,7 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa
130
131
}
131
132
ocispecPlatforms , err := platformutil .NewOCISpecPlatformSlice (false , platformSS )
132
133
if err != nil {
133
- return nil , nil , err
134
+ return nil , generateRemoveStateDirFunc ( ctx , id , internalLabels ) , err
134
135
}
135
136
rawRef := args [0 ]
136
137
@@ -141,13 +142,13 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa
141
142
142
143
ensuredImage , err = image .EnsureImage (ctx , client , rawRef , options .ImagePullOpt )
143
144
if err != nil {
144
- return nil , nil , err
145
+ return nil , generateRemoveStateDirFunc ( ctx , id , internalLabels ) , err
145
146
}
146
147
}
147
148
148
149
rootfsOpts , rootfsCOpts , err := generateRootfsOpts (args , id , ensuredImage , options )
149
150
if err != nil {
150
- return nil , nil , err
151
+ return nil , generateRemoveStateDirFunc ( ctx , id , internalLabels ) , err
151
152
}
152
153
opts = append (opts , rootfsOpts ... )
153
154
cOpts = append (cOpts , rootfsCOpts ... )
@@ -158,12 +159,12 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa
158
159
159
160
envs , err := flagutil .MergeEnvFileAndOSEnv (options .EnvFile , options .Env )
160
161
if err != nil {
161
- return nil , nil , err
162
+ return nil , generateRemoveStateDirFunc ( ctx , id , internalLabels ) , err
162
163
}
163
164
164
165
if options .Interactive {
165
166
if options .Detach {
166
- return nil , nil , errors .New ("currently flag -i and -d cannot be specified together (FIXME)" )
167
+ return nil , generateRemoveStateDirFunc ( ctx , id , internalLabels ) , errors .New ("currently flag -i and -d cannot be specified together (FIXME)" )
167
168
}
168
169
}
169
170
@@ -174,7 +175,7 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa
174
175
var mountOpts []oci.SpecOpts
175
176
mountOpts , internalLabels .anonVolumes , internalLabels .mountPoints , err = generateMountOpts (ctx , client , ensuredImage , volStore , options )
176
177
if err != nil {
177
- return nil , nil , err
178
+ return nil , generateRemoveStateDirFunc ( ctx , id , internalLabels ) , err
178
179
}
179
180
opts = append (opts , mountOpts ... )
180
181
@@ -186,30 +187,30 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa
186
187
// 3, nerdctl start/restart demo
187
188
logConfig , err := generateLogConfig (dataStore , id , options .LogDriver , options .LogOpt , options .GOptions .Namespace )
188
189
if err != nil {
189
- return nil , nil , err
190
+ return nil , generateRemoveStateDirFunc ( ctx , id , internalLabels ) , err
190
191
}
191
192
internalLabels .logURI = logConfig .LogURI
192
193
193
194
restartOpts , err := generateRestartOpts (ctx , client , options .Restart , logConfig .LogURI , options .InRun )
194
195
if err != nil {
195
- return nil , nil , err
196
+ return nil , generateRemoveStateDirFunc ( ctx , id , internalLabels ) , err
196
197
}
197
198
cOpts = append (cOpts , restartOpts ... )
198
199
199
200
if err = netManager .VerifyNetworkOptions (ctx ); err != nil {
200
- return nil , nil , fmt .Errorf ("failed to verify networking settings: %s" , err )
201
+ return nil , generateRemoveStateDirFunc ( ctx , id , internalLabels ) , fmt .Errorf ("failed to verify networking settings: %s" , err )
201
202
}
202
203
203
204
netOpts , netNewContainerOpts , err := netManager .ContainerNetworkingOpts (ctx , id )
204
205
if err != nil {
205
- return nil , nil , fmt .Errorf ("failed to generate networking spec options: %s" , err )
206
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , fmt .Errorf ("failed to generate networking spec options: %s" , err )
206
207
}
207
208
opts = append (opts , netOpts ... )
208
209
cOpts = append (cOpts , netNewContainerOpts ... )
209
210
210
211
netLabelOpts , err := netManager .InternalNetworkingOptionLabels (ctx )
211
212
if err != nil {
212
- return nil , nil , fmt .Errorf ("failed to generate internal networking labels: %s" , err )
213
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , fmt .Errorf ("failed to generate internal networking labels: %s" , err )
213
214
}
214
215
215
216
envs = append (envs , "HOSTNAME=" + netLabelOpts .Hostname )
@@ -230,37 +231,37 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa
230
231
if runtime .GOOS != "windows" {
231
232
hookOpt , err := withNerdctlOCIHook (options .NerdctlCmd , options .NerdctlArgs )
232
233
if err != nil {
233
- return nil , nil , err
234
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , err
234
235
}
235
236
opts = append (opts , hookOpt )
236
237
}
237
238
238
239
uOpts , err := generateUserOpts (options .User )
239
240
if err != nil {
240
- return nil , nil , err
241
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , err
241
242
}
242
243
opts = append (opts , uOpts ... )
243
244
gOpts , err := generateGroupsOpts (options .GroupAdd )
244
245
if err != nil {
245
- return nil , nil , err
246
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , err
246
247
}
247
248
opts = append (opts , gOpts ... )
248
249
249
250
umaskOpts , err := generateUmaskOpts (options .Umask )
250
251
if err != nil {
251
- return nil , nil , err
252
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , err
252
253
}
253
254
opts = append (opts , umaskOpts ... )
254
255
255
256
rtCOpts , err := generateRuntimeCOpts (options .GOptions .CgroupManager , options .Runtime )
256
257
if err != nil {
257
- return nil , nil , err
258
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , err
258
259
}
259
260
cOpts = append (cOpts , rtCOpts ... )
260
261
261
262
lCOpts , err := withContainerLabels (options .Label , options .LabelFile , ensuredImage )
262
263
if err != nil {
263
- return nil , nil , err
264
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , err
264
265
}
265
266
cOpts = append (cOpts , lCOpts ... )
266
267
@@ -276,25 +277,25 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa
276
277
if options .Name != "" {
277
278
containerNameStore , err = namestore .New (dataStore , options .GOptions .Namespace )
278
279
if err != nil {
279
- return nil , nil , err
280
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , err
280
281
}
281
282
if err := containerNameStore .Acquire (options .Name , id ); err != nil {
282
- return nil , nil , err
283
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , err
283
284
}
284
285
}
285
286
internalLabels .name = options .Name
286
287
internalLabels .pidFile = options .PidFile
287
288
internalLabels .extraHosts = strutil .DedupeStrSlice (netManager .NetworkOptions ().AddHost )
288
289
for i , host := range internalLabels .extraHosts {
289
290
if _ , err := dockercliopts .ValidateExtraHost (host ); err != nil {
290
- return nil , nil , err
291
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , err
291
292
}
292
293
parts := strings .SplitN (host , ":" , 2 )
293
294
// If the IP Address is a string called "host-gateway", replace this value with the IP address stored
294
295
// in the daemon level HostGateway IP config variable.
295
296
if len (parts ) == 2 && parts [1 ] == dockeropts .HostGatewayName {
296
297
if options .GOptions .HostGatewayIP == "" {
297
- return nil , nil , fmt .Errorf ("unable to derive the IP value for host-gateway" )
298
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , fmt .Errorf ("unable to derive the IP value for host-gateway" )
298
299
}
299
300
parts [1 ] = options .GOptions .HostGatewayIP
300
301
internalLabels .extraHosts [i ] = fmt .Sprintf (`%s:%s` , parts [0 ], parts [1 ])
@@ -304,7 +305,7 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa
304
305
// TODO: abolish internal labels and only use annotations
305
306
ilOpt , err := withInternalLabels (internalLabels )
306
307
if err != nil {
307
- return nil , nil , err
308
+ return nil , generateRemoveOrphanedDirsFunc ( ctx , id , dataStore , internalLabels ) , err
308
309
}
309
310
cOpts = append (cOpts , ilOpt )
310
311
@@ -817,6 +818,29 @@ func generateLogConfig(dataStore string, id string, logDriver string, logOpt []s
817
818
return logConfig , nil
818
819
}
819
820
821
+ func generateRemoveStateDirFunc (ctx context.Context , id string , internalLabels internalLabels ) func () {
822
+ return func () {
823
+ if rmErr := os .RemoveAll (internalLabels .stateDir ); rmErr != nil {
824
+ log .G (ctx ).WithError (rmErr ).Warnf ("failed to remove container %q state dir %q" , id , internalLabels .stateDir )
825
+ }
826
+ }
827
+ }
828
+
829
+ func generateRemoveOrphanedDirsFunc (ctx context.Context , id , dataStore string , internalLabels internalLabels ) func () {
830
+ return func () {
831
+ if rmErr := os .RemoveAll (internalLabels .stateDir ); rmErr != nil {
832
+ log .G (ctx ).WithError (rmErr ).Warnf ("failed to remove container %q state dir %q" , id , internalLabels .stateDir )
833
+ }
834
+
835
+ hs , err := hostsstore .New (dataStore , internalLabels .namespace )
836
+ if err != nil {
837
+ log .G (ctx ).WithError (err ).Warnf ("failed to instantiate hostsstore for %q" , internalLabels .namespace )
838
+ } else if err = hs .Delete (id ); err != nil {
839
+ log .G (ctx ).WithError (err ).Warnf ("failed to remove an etchosts directory for container %q" , id )
840
+ }
841
+ }
842
+ }
843
+
820
844
func generateGcFunc (ctx context.Context , container containerd.Container , ns , id , name , dataStore string , containerErr error , containerNameStore namestore.NameStore , netManager containerutil.NetworkOptionsManager , internalLabels internalLabels ) func () {
821
845
return func () {
822
846
if containerErr == nil {
0 commit comments