@@ -18,13 +18,15 @@ package modules
1818
1919import (
2020 "context"
21+ "errors"
2122 "fmt"
2223 "io"
2324 "os"
2425 "path/filepath"
2526 "time"
2627
2728 dkplog "github.com/deckhouse/deckhouse/pkg/log"
29+ "github.com/deckhouse/deckhouse/pkg/registry/client"
2830
2931 "github.com/deckhouse/deckhouse-cli/internal"
3032 "github.com/deckhouse/deckhouse-cli/internal/mirror/chunked"
@@ -33,17 +35,18 @@ import (
3335 "github.com/deckhouse/deckhouse-cli/pkg/libmirror/bundle"
3436 "github.com/deckhouse/deckhouse-cli/pkg/libmirror/layouts"
3537 "github.com/deckhouse/deckhouse-cli/pkg/libmirror/util/log"
36- "github.com/deckhouse/deckhouse-cli/pkg/libmirror/validation"
3738 registryservice "github.com/deckhouse/deckhouse-cli/pkg/registry/service"
3839)
3940
4041type Service struct {
42+ workingDir string
43+
4144 // modulesService handles Deckhouse platform registry operations
4245 modulesService * registryservice.ModulesService
4346 // layout manages the OCI image layouts for different components
44- layout * ImageLayouts
45- // downloadList manages the list of images to be downloaded
46- downloadList * ImageDownloadList
47+ layout * ModulesImageLayouts
48+ // modulesDownloadList manages the list of images to be downloaded
49+ modulesDownloadList * ModulesDownloadList
4750 // pullerService handles the pulling of images
4851 pullerService * puller.PullerService
4952
@@ -64,36 +67,28 @@ func NewService(
6467) * Service {
6568 userLogger .Infof ("Creating OCI Image Layouts for Modules" )
6669
67- tmpDir := filepath .Join (workingDir , "modules" )
68-
69- layout , err := createOCIImageLayoutsForModules (tmpDir )
70- if err != nil {
71- //TODO: handle error
72- userLogger .Warnf ("Create OCI Image Layouts: %v" , err )
73- }
74-
7570 rootURL := registryService .GetRoot ()
7671
7772 return & Service {
78- modulesService : registryService . ModuleService () ,
79- layout : layout ,
80- downloadList : NewImageDownloadList (rootURL ),
81- pullerService : puller .NewPullerService (logger , userLogger ),
82- rootURL : rootURL ,
83- logger : logger ,
84- userLogger : userLogger ,
73+ workingDir : workingDir ,
74+ modulesService : registryService . ModuleService () ,
75+ modulesDownloadList : NewModulesDownloadList (rootURL ),
76+ pullerService : puller .NewPullerService (logger , userLogger ),
77+ rootURL : rootURL ,
78+ logger : logger ,
79+ userLogger : userLogger ,
8580 }
8681}
8782
8883// PullModules pulls the Deckhouse modules
8984// It validates access to the registry and pulls the module images
90- func (svc * Service ) PullModules (ctx context.Context , modules [] string ) error {
85+ func (svc * Service ) PullModules (ctx context.Context ) error {
9186 err := svc .validateModulesAccess (ctx )
9287 if err != nil {
9388 return fmt .Errorf ("validate modules access: %w" , err )
9489 }
9590
96- err = svc .pullModules (ctx , modules )
91+ err = svc .pullModules (ctx )
9792 if err != nil {
9893 return fmt .Errorf ("pull modules: %w" , err )
9994 }
@@ -110,56 +105,96 @@ func (svc *Service) validateModulesAccess(ctx context.Context) error {
110105 ctx , cancel := context .WithTimeout (ctx , 15 * time .Second )
111106 defer cancel ()
112107
113- modulesRepo := filepath .Join (svc .rootURL , internal .ModulesSegment )
114- validator := validation .NewRemoteRegistryAccessValidator ()
115- err := validator .ValidateListAccessForRepo (ctx , modulesRepo , []validation.Option {}... ) // TODO: add options
108+ // For specific tags, check if the tag exists
109+ _ , err := svc .modulesService .ListTags (ctx )
110+ if errors .Is (err , client .ErrImageNotFound ) {
111+ svc .userLogger .Warnf ("Skipping pull of modules: %v" , err )
112+
113+ return nil
114+ }
115+
116116 if err != nil {
117- return fmt .Errorf ("modules registry is not accessible : %w" , err )
117+ return fmt .Errorf ("failed to check modules lists : %w" , err )
118118 }
119119
120120 return nil
121121}
122122
123- func (svc * Service ) pullModules (ctx context.Context , modules [] string ) error {
123+ func (svc * Service ) pullModules (ctx context.Context ) error {
124124 logger := svc .userLogger
125125
126- // Fill download list with modules images
127- svc .downloadList .FillModulesImages (modules )
128-
129- // Pull modules images
130- err := logger .Process ("Pull Modules" , func () error {
131- config := puller.PullConfig {
132- Name : "Modules" ,
133- ImageSet : svc .downloadList .Modules ,
134- Layout : svc .layout .Modules ,
135- AllowMissingTags : true , // Allow missing module images
136- GetterService : svc .modulesService ,
137- }
126+ tmpDir := filepath .Join (svc .workingDir , "modules" )
138127
139- return svc .pullerService .PullImages (ctx , config )
140- })
128+ modules , err := svc .modulesService .ListTags (ctx )
141129 if err != nil {
142- return err
130+ return fmt .Errorf ("list modules: %w" , err )
131+ }
132+
133+ for _ , module := range modules {
134+ logger .Infof ("Module found: %s" , module )
135+ }
136+
137+ moduleImagesLayout , err := createOCIImageLayoutsForModules (tmpDir , modules )
138+ if err != nil {
139+ return fmt .Errorf ("create OCI image layouts for modules: %w" , err )
143140 }
141+ svc .layout = moduleImagesLayout
142+
143+ // Fill download list with modules images
144+ svc .modulesDownloadList .FillModulesImages (modules )
145+
146+ err = logger .Process ("Pull Modules" , func () error {
147+ for _ , module := range modules {
148+ config := puller.PullConfig {
149+ Name : module + " release channels" ,
150+ ImageSet : svc .modulesDownloadList .Module (module ).ModuleReleaseChannels ,
151+ Layout : svc .layout .Module (module ).ModulesReleaseChannels ,
152+ AllowMissingTags : true ,
153+ GetterService : svc .modulesService .Module (module ).ReleaseChannels (),
154+ }
155+
156+ err = svc .pullerService .PullImages (ctx , config )
157+ if err != nil {
158+ return err
159+ }
160+
161+ // TODO:
162+ // we must extract module images tags from release channels before pulling module images
163+
164+ // Pull modules images
165+ config = puller.PullConfig {
166+ Name : module ,
167+ ImageSet : svc .modulesDownloadList .Module (module ).Module ,
168+ Layout : svc .layout .Module (module ).Modules ,
169+ AllowMissingTags : true , // Allow missing module images
170+ GetterService : svc .modulesService .Module (module ),
171+ }
172+
173+ err := svc .pullerService .PullImages (ctx , config )
174+ if err != nil {
175+ return err
176+ }
177+
178+ config = puller.PullConfig {
179+ Name : module + " extra" ,
180+ ImageSet : svc .modulesDownloadList .Module (module ).ModuleExtra ,
181+ Layout : svc .layout .Module (module ).ModulesExtra ,
182+ AllowMissingTags : true ,
183+ GetterService : svc .modulesService .Module (module ).Extra (),
184+ }
144185
145- // Pull modules release channels
146- err = logger .Process ("Pull Modules Release Channels" , func () error {
147- config := puller.PullConfig {
148- Name : "Modules Release Channels" ,
149- ImageSet : svc .downloadList .ModulesReleaseChannels ,
150- Layout : svc .layout .ModulesReleaseChannels ,
151- AllowMissingTags : true ,
152- GetterService : svc .modulesService ,
186+ err = svc .pullerService .PullImages (ctx , config )
187+ if err != nil {
188+ return err
189+ }
153190 }
154191
155- return svc . pullerService . PullImages ( ctx , config )
192+ return nil
156193 })
157194 if err != nil {
158195 return err
159196 }
160197
161- // TODO: Pull modules extra images if needed
162-
163198 err = logger .Process ("Processing modules image indexes" , func () error {
164199 for _ , l := range svc .layout .AsList () {
165200 err = layouts .SortIndexManifests (l )
@@ -204,6 +239,25 @@ func (svc *Service) pullModules(ctx context.Context, modules []string) error {
204239
205240func createOCIImageLayoutsForModules (
206241 rootFolder string ,
242+ modules []string ,
243+ ) (* ModulesImageLayouts , error ) {
244+ layouts := NewModulesImageLayouts (rootFolder )
245+
246+ for _ , moduleName := range modules {
247+ moduleLayouts , err := createOCIImageLayoutsForModule (
248+ filepath .Join (rootFolder , moduleName ),
249+ )
250+ if err != nil {
251+ return nil , fmt .Errorf ("create OCI image layouts for module %s: %w" , moduleName , err )
252+ }
253+ layouts .list [moduleName ] = moduleLayouts
254+ }
255+
256+ return layouts , nil
257+ }
258+
259+ func createOCIImageLayoutsForModule (
260+ rootFolder string ,
207261) (* ImageLayouts , error ) {
208262 layouts := NewImageLayouts (rootFolder )
209263
0 commit comments