@@ -45,6 +45,7 @@ import (
4545 "github.com/pkg/errors"
4646 "github.com/samber/lo"
4747 "gopkg.in/yaml.v3"
48+ apierr "k8s.io/apimachinery/pkg/util/errors"
4849 "k8s.io/apimachinery/pkg/util/sets"
4950 "k8s.io/apimachinery/pkg/util/wait"
5051 "k8s.io/klog/v2"
@@ -135,7 +136,8 @@ func (w *executor) Precheck(ctx context.Context) error {
135136 return fmt .Errorf ("remove precheck containers: %s" , err )
136137 }
137138
138- err = w .uploadContainerImages (ctx , w .instance .PrecheckContainers ... )
139+ expectImages := lo .Map (w .instance .PrecheckContainers , func (c model.ContainerDefinition , _ int ) string { return c .Image })
140+ err = w .uploadContainerImages (ctx , expectImages ... )
139141 if err != nil {
140142 return fmt .Errorf ("upload precheck images: %s" , err )
141143 }
@@ -159,15 +161,16 @@ const (
159161// 2. remove operation metadata labels from containerd namespace.
160162// 3. config container runtime.
161163// 4. upload required images to containerd.
162- // 5. remove obsolete containers in the containerd namespace.
163- // 6. start and wait init_containers, kill the container after timeout.
164- // 7. start, run and update containers.
165- // 8. wait for all containers ready.
166- // 9. setup container logging config.
167- // 10. setup container metrics config.
168- // 11. start and wait post_containers, kill the container after timeout.
169- // 12. remove unused images from containerd.
170- // 13. update operation metadata labels into containerd namespace.
164+ // 5. unpack required images in containerd.
165+ // 6. remove obsolete containers in the containerd namespace.
166+ // 7. start and wait init_containers, kill the container after timeout.
167+ // 8. start, run and update containers.
168+ // 9. wait for all containers ready.
169+ // 10. setup container logging config.
170+ // 11. setup container metrics config.
171+ // 12. start and wait post_containers, kill the container after timeout.
172+ // 13. remove unused images from containerd.
173+ // 14. update operation metadata labels into containerd namespace.
171174func (w * executor ) Apply (ctx context.Context ) error {
172175 skip , err := w .needSkipApplyPlugin (ctx )
173176 if skip || err != nil {
@@ -184,11 +187,23 @@ func (w *executor) Apply(ctx context.Context) error {
184187 return fmt .Errorf ("config container runtime: %s" , err )
185188 }
186189
187- err = w .uploadContainerImages (ctx , append (append (w .instance .InitContainers , w .instance .Containers ... ), w .instance .PostContainers ... )... )
190+ expectImages := lo .Union (
191+ lo .Map (w .instance .ExtraRequireImages , func (e model.ExtraRequireImage , _ int ) string { return e .Name }),
192+ lo .Map (w .instance .InitContainers , func (c model.ContainerDefinition , _ int ) string { return c .Image }),
193+ lo .Map (w .instance .Containers , func (c model.ContainerDefinition , _ int ) string { return c .Image }),
194+ lo .Map (w .instance .PostContainers , func (c model.ContainerDefinition , _ int ) string { return c .Image }),
195+ )
196+ err = w .uploadContainerImages (ctx , expectImages ... )
188197 if err != nil {
189198 return fmt .Errorf ("upload container images: %s" , err )
190199 }
191200
201+ unpackImages := lo .FilterMap (w .instance .ExtraRequireImages , func (e model.ExtraRequireImage , _ int ) (string , bool ) { return e .Name , e .Unpack })
202+ err = w .unpackContainerImages (ctx , unpackImages ... )
203+ if err != nil {
204+ return fmt .Errorf ("unpack container images: %s" , err )
205+ }
206+
192207 err = w .removeContainersInNamespaceExcludes (ctx , w .instance .Containers ... )
193208 if err != nil {
194209 return fmt .Errorf ("remove containers: %s" , err )
@@ -224,7 +239,15 @@ func (w *executor) Apply(ctx context.Context) error {
224239 return fmt .Errorf ("start post containers: %s" , err )
225240 }
226241
227- err = w .removeUnusedImages (ctx , w .instance .Containers ... )
242+ inuseImages := lo .Union (
243+ lo .Map (w .instance .ExtraRequireImages , func (e model.ExtraRequireImage , _ int ) string { return e .Name }),
244+ lo .Map (w .instance .PrecheckContainers , func (c model.ContainerDefinition , _ int ) string { return c .Image }),
245+ lo .Map (w .instance .InitContainers , func (c model.ContainerDefinition , _ int ) string { return c .Image }),
246+ lo .Map (w .instance .Containers , func (c model.ContainerDefinition , _ int ) string { return c .Image }),
247+ lo .Map (w .instance .PostContainers , func (c model.ContainerDefinition , _ int ) string { return c .Image }),
248+ lo .Map (w .instance .CleanContainers , func (c model.ContainerDefinition , _ int ) string { return c .Image }),
249+ )
250+ err = w .removeUnusedImages (ctx , inuseImages ... )
228251 if err != nil {
229252 return fmt .Errorf ("remove unused images: %s" , err )
230253 }
@@ -275,7 +298,8 @@ func (w *executor) Remove(ctx context.Context) error {
275298 }
276299
277300 if len (w .instance .CleanContainers ) != 0 {
278- err = w .uploadContainerImages (ctx , w .instance .CleanContainers ... )
301+ expectImages := lo .Map (w .instance .CleanContainers , func (c model.ContainerDefinition , _ int ) string { return c .Image })
302+ err = w .uploadContainerImages (ctx , expectImages ... )
279303 if err != nil {
280304 return fmt .Errorf ("upload cleanup images: %s" , err )
281305 }
@@ -371,13 +395,24 @@ func (w *executor) configContainerRuntime(ctx context.Context) error {
371395 return w .runtime .ConfigRuntime (ctx )
372396}
373397
374- func (w * executor ) uploadContainerImages (ctx context.Context , containers ... model.ContainerDefinition ) error {
375- imageRefs := sets .NewString ()
376- for _ , c := range containers {
377- imageRefs .Insert (c .Image )
398+ func (w * executor ) uploadContainerImages (ctx context.Context , expectImages ... string ) error {
399+ if len (expectImages ) == 0 {
400+ return nil
401+ }
402+ expectImages = lo .Uniq (expectImages )
403+ w .Infof ("uploading images to containerd: %v" , expectImages )
404+ return w .runtime .ImportImages (ctx , expectImages ... )
405+ }
406+
407+ func (w * executor ) unpackContainerImages (ctx context.Context , expectImages ... string ) error {
408+ if len (expectImages ) == 0 {
409+ return nil
378410 }
379- w .Infof ("uploading images to containerd: %v" , imageRefs .List ())
380- return w .runtime .ImportImages (ctx , imageRefs .List ()... )
411+ expectImages = lo .Uniq (expectImages )
412+ w .Infof ("uppacking images in containerd: %v" , expectImages )
413+ return apierr .NewAggregate (lo .Map (expectImages , func (image string , _ int ) error {
414+ return w .runtime .UnpackImage (ctx , image )
415+ }))
381416}
382417
383418func (w * executor ) removeContainersInNamespaceIncludes (ctx context.Context , containers ... model.ContainerDefinition ) error {
@@ -543,7 +578,7 @@ func (w *executor) removeAllInNamespace(ctx context.Context) error {
543578 return nil
544579}
545580
546- func (w * executor ) removeUnusedImages (ctx context.Context , exceptImagesInContainer ... model. ContainerDefinition ) error {
581+ func (w * executor ) removeUnusedImages (ctx context.Context , inuseImages ... string ) error {
547582 images , err := w .runtime .ListImages (ctx )
548583 if err != nil {
549584 return err
@@ -553,10 +588,7 @@ func (w *executor) removeUnusedImages(ctx context.Context, exceptImagesInContain
553588 for _ , i := range images {
554589 imageSet .Insert (i .Name )
555590 }
556-
557- for _ , c := range exceptImagesInContainer {
558- imageSet .Delete (c .Image )
559- }
591+ imageSet .Delete (inuseImages ... )
560592
561593 for _ , image := range imageSet .List () {
562594 w .Infof ("remove image %s from containerd" , image )
0 commit comments